Tengo una pregunta sobre el envío de una señal de corta duración de un dominio de reloj más rápido a un dominio de reloj más lento. Estoy intentando implementar un búfer de marco dual en una memoria RAM de doble puerto (reloj dual). Una vez que se ha almacenado un Frame completo, el lado del reloj de escritura afirma el registro FrameFull. Al final de cada marco de visualización actual, la pantalla solicita un nuevo marco, que si está disponible, establece el puntero de lectura para la RAM en consecuencia y también se usa para volver a colocar la señal FrameFull para que se pueda cargar un nuevo marco mientras se muestra el más reciente.
El lado de lectura está operando a 50 MHz.
El lado de escritura está operando a 27 MHz.
Para sincronizar la señal FrameFull desde el dominio de escritura, he leído que es mejor usar un par de flip flops de sincronización y como FrameFull permanece activo hasta que se cambia el búfer, creo que esto no es muy problemático ( porque la señal FrameFull no se puede perder). La señal SwitchSuccesful se afirma en el dominio de reloj de lectura cuando se solicita un nuevo Frame y FrameFull es 1, lo que indica el intercambio de búfer. Ahora, este SwitchSuccesful debe ser muestreado por el dominio de escritura para que FrameFull pueda restablecerse a 0 y luego pueda comenzar a almacenar un nuevo marco. Lo pensé y decidí usar un registro de desplazamiento de 16 bits que, cuando se cambian los búferes, se restablecerá a 16'hFF y luego se desplazará a la izquierda con un cero concatenado. resultado del bit a bit O con Flip Flops en el dominio de escritura antes de muestrear la señal. ¿Será esto suficiente para evitar perder el interruptor de éxito y la metastabilidad?
CÓDIGO:
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