I have a question regarding sending a short duration signal from a faster clock domain to a slower clock domain. I am trying to implement a dual frame buffer in a dual port (dual clock) RAM. Once an entire Frame has been stored, the write clock side asserts the FrameFull register. At the end of each current display frame, the display requests a new frame, which if available, sets the read pointer for the RAM accordingly and is also used to deassert the FrameFull Signal so that a new frame can be loaded while this most recent one is being displayed.
The read side is operating at 50 MHz.
The write side is operating at 27 MHz.
In order to synchronize the FrameFull Signal from the write domain, I have read that its best to use a couple of synchronizing flip flops and since the FrameFull remains asserted until the buffer is switched, I think this isn't very problematic (because the FrameFull signal can't be missed). The SwitchSuccesful signal is asserted in the read clock domain when a new Frame is requested and the FrameFull is 1, indicating buffer exchange. Now, this SwitchSuccesful needs to be sampled by the write domain so that FrameFull can be reset to 0 and can then start storing a new frame. I have thought about it and decided to use a 16-bit shift register, which, when buffers are switched, will reset to 16'hFF and then shift left with a zero being concatenated.I could then use a bitwise OR, and synchronize the result of the bitwise OR with Flip Flops in the write domain before sampling the signal. Will this be sufficient to prevent missing the SuccesfulSwitch and metastability?
CODE :
always @ (posedge read_clock)
begin
if(SwitchRequest) begin
case (Frame_FullSync1, Frame_Read)
2'b00 : begin rd_ptr <= /*Some Value*/ Frame_Read <= 0; end //Restore to Previous 0.
2'b01 : begin rd_ptr <= /*Some Value*/ Frame_Read <= 1; end //Restore to Previous 1.
2'b10 : begin rd_ptr <= /*Some Value*/ Frame_Read <= 1; LE <= 1; end //Load new ----- 0 to 1.
2'b11 : begin rd_ptr <= /*Some Value*/ Frame_Read <= 0; LE <= 1; end //Load new ----- 1 to 0.
endcase
end
if(LE) LE <= 0;
end
always @ (posedge read_clock) begin
//Frame Full Synchronization from write domain to read domain
Frame_FullSync1 <= Frame_FullSync0;
Frame_FullSync0 <= FrameFull;
//LE was asserted for 1 clock cycle when buffer switch was succesful
if(LE) Sync <= 16'hFF;
else Sync <= Sync {Sync[15 : 1],1'b0};
end
assign SwitchSuccesful = |Sync;
always @ (posedge write_clock) begin
//Synchronization of bitwise OR
SwitchSuccesfulSync0 <= SwitchSuccesful;
SwitchSuccesfulSync1 <= SwitchSuccesfulSync0;
end