1 votos

Transiciones de estado curiosas en la simulación RTL de máquinas de estado

Tengo una simple máquina de estados como parte de mi módulo Verilog:

localparam State_IDLE = 3'b000,
           State_WRITETOLANE1 = 3'b001;

reg [2:0] currentState;
reg [2:0] nextState;

always @(posedge TxByteClk) begin
if( rst ) begin
    currentState <= State_IDLE;
end else begin
    currentState <= nextState;
end
end

always @(*) begin
nextState = currentState;
case( currentState )
    State_IDLE: begin
        if( TxSync ) begin
            nextState = State_WRITETOLANE1;
        end
    end
    State_WRITETOLANE1: begin
        nextState = State_IDLE;
    end
endcase
end

TxSync es una señal de entrada. El comportamiento extraño que estoy viendo es que en el borde positivo del reloj cuando TxSync es alto, currentState se establece en State_WRITETOLANE1 y como resultado nextState se establece en State_IDLE. ¡Pero nextState nunca fue puesto a State_WRITETOLANE1 en primer lugar! ¿Por qué currentState obtiene un valor que ni siquiera estaba presente en nextState? ¿La línea currentState <= nextState; no implica que currentState es la versión retrasada de nextState?

4voto

djpercent Puntos 86

Me adelanté e hice un banco de pruebas para ver el comportamiento del circuito. Por favor, haz clic con el botón derecho del ratón en la imagen para verla con más claridad.

enter image description here

Según mi simulación, no hay nada inesperado o extraño en la forma de onda. El estado se inicializa correctamente con el reset. Cuando TxSync es alto el estado cambia una vez cada ciclo de reloj. Cuando TxSync es deasserted el estado mantiene un valor constante.

También he utilizado un comprobador de pelusas y no hay grandes problemas con la RTL. Debo concluir que el circuito está simulando exactamente como se especifica en la RTL. Si esperabas algo diferente, deberías aclararlo más, y te diré cómo cambiar el modelo.

Algunas notas sobre la simulación:

  1. El registro currentState guarda el valor de nextState en el flanco ascendente de TxByteClk
  2. La lógica de nextState se actualiza tras una unidad de tiempo infinitesimal después del flanco de subida de TxByteClk (o TxSync), ya que se trata de un modelo de retardo 0
  3. Puede parecer que el currentState y el nextState cambian simultáneamente, pero el currentState se actualiza primero

Trampa: Si tu banco de pruebas actualiza la entrada TxSync exactamente en el flanco de subida del reloj, sólo tendrás un fallo en nextState. Tu simulador puede eliminar este fallo, haciendo que parezca que nextState nunca entró en State_WRITETOLANE1, cuando en realidad lo hizo, sólo por un momento muy breve. Esto haría que pareciera que currentState enganchó un valor que nextState nunca tuvo.

Remedio: No actualizar las entradas exactamente en el flanco de subida del reloj. Añade algún pequeño retraso para que la simulación se entienda mejor. En mi caso, actualicé la entrada en el flanco descendente del reloj. Pero el tiempo de actualización es arbitrario si estás haciendo una simulación con retardo 0.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X