Ejemplo de restablecimiento de Verilog dentro del ejemplo de cruce de dominio de reloj

0

Estoy intentando entender el problema de los CDC y estudiar algunos ejemplos con el sitio de referencia. Actualmente, estoy haciendo referencia a enlace

Especialmente, no puedo tener ninguna señal funcionando correctamente.

module Flag_CrossDomain(
    input clkA,
    input FlagIn_clkA,   // this is a one-clock pulse from the clkA domain
    input clkB,
    output FlagOut_clkB   // from which we generate a one-clock pulse in clkB domain
);

reg FlagToggle_clkA;
always @(posedge clkA) FlagToggle_clkA <= FlagToggle_clkA ^ FlagIn_clkA;  // when flag is asserted, this signal toggles (clkA domain)

reg [2:0] SyncA_clkB;
always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};  // now we cross the clock domains

assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);  // and create the clkB flag
endmodule

Entonces, solo pensé que faltaba reiniciar ese módulo. Así que lo agregué como a continuación. pero no estoy seguro de si lo modifico correctamente o no. Quiero decir que realmente necesito restablecer la señal?

module Flag_CrossDomain(
   reset_n,                 
   clkA,
   FlagIn_clkA,
   clkB,
   FlagOut_clkB
);

input reset_n;
input clkA;
input FlagIn_clkA;        
input clkB;
output   FlagOut_clkB ;      

reg FlagToggle_clkA;
always @(posedge clkA or negedge reset_n)
if(!reset_n)
FlagToggle_clkA <= 0;
else
FlagToggle_clkA <= FlagToggle_clkA ^ FlagIn_clkA;

reg [2:0] SyncA_clkB; 
always @(posedge clkB or negedge reset_n)                               
if(!reset_n)
 SyncA_clkB <=0;
else
 SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};

assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);
endmodule 
    
pregunta start01

2 respuestas

0

Este código no necesita ser reiniciado. Si desea restablecerlo, debe hacerse correctamente, lo más probable es que con una señal de restablecimiento para cada dominio de reloj. Pero esto no es realmente necesario, todo lo que debe hacer para simular es inicializar todos los registros internos a algo que no sea x, y luego debería funcionar correctamente. Por lo tanto, reemplazar

reg FlagToggle_clkA;

con

reg FlagToggle_clkA = 0;

y deberías estar listo para ir.

    
respondido por el alex.forencich
0

Sin reiniciar, todos los registros tienen un estado inicial de 1'bX . El código al principio (sin reinicio) no funcionará ya que 1'bX ^ SIGNAL produjo 1'bX independientemente del valor de SIGNAL. Además, los datos de cambio SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA} comenzarán como 3'bXXX y solo cambiarán X-es hacia adentro. Por lo tanto, permanecerán en 3'bXXX.

Con el restablecimiento de los registros, todos comienzan en 0 y el sistema funciona.

    
respondido por el Oldfart

Lea otras preguntas en las etiquetas