Transiciones de estado curioso en la simulación RTL de la máquina de estados

1

Tengo una máquina de estado simple 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 límite positivo del reloj cuando TxSync está alto, currentState se establece en State_WRITETOLANE1 y, como resultado, nextState se establece en State_IDLE. ¡Pero nextState nunca se estableció en State_WRITETOLANE1 en primer lugar! ¿Por qué currentState obtiene un valor que ni siquiera estaba presente en nextState? ¿La línea currentState < = nextState? ¿implica que currentState es la versión retrasada de nextState?

    
pregunta ballaw

1 respuesta

4

Seguí adelante e hice un banco de pruebas para ver el comportamiento del circuito. Haga clic con el botón derecho en la imagen para verla más claramente.

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

También usé un comprobador de pelusas y no hay problemas importantes 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 encierra el valor de nextState en el borde ascendente de TxByteClk
  2. La lógica nextState se actualiza después de una unidad infinitamente pequeña de tiempo después del flanco ascendente de TxByteClk (o TxSync), ya que este es un modelo de retardo 0
  3. Puede parecer que el estado actual y el siguiente estado cambian simultáneamente, pero el estado actual se actualiza primero

Pitfall: Si tu banco de pruebas actualiza la entrada TxSync exactamente en el borde ascendente del reloj, solo tendrás un error en el siguiente estado. Su simulador puede eliminar esta falla, por lo que parece que nextState nunca ingresó en State_WRITETOLANE1, cuando en realidad lo hizo, solo por un breve momento. Esto haría que pareciera que currentState guardó un valor que nunca tuvo nextState.

Solución: No actualice las entradas exactamente en el borde ascendente del reloj. Agregue un poco de retraso para que la simulación pueda entenderse más claramente. En mi caso, actualicé la entrada en el flanco descendente del reloj. Pero el tiempo de actualización es arbitrario si está haciendo una simulación de retardo 0.

    
respondido por el travisbartley

Lea otras preguntas en las etiquetas