Verilog - Problema extraño de bloqueo / no bloqueo

0

En el primer bloque del siguiente código recibo un error extraño cada vez que uso una asignación no bloqueante / El estado_SENDSYNC dura dos ciclos, aunque se supone que solo dura un ciclo. Cambiar a la asignación de bloqueo soluciona el problema, pero estoy desconcertado en cuanto a por qué. ¿No debería inferirse un mux de cualquier manera?

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

always @(posedge clk) begin
nextState = currentState;
case( currentState )
    State_IDLE: begin
        if( laneOpen ) begin
            nextState = State_SENDSYNC;
        end
    end
    State_SENDSYNC: begin
        nextState = State_SENDDATA;
    end
    State_SENDDATA: begin
        if( !laneOpen ) begin
            nextState = State_IDLE;
        end
    end
    default: begin
        nextState = State_IDLE;
    end
endcase
end
    
pregunta ballaw

3 respuestas

1

nextState debe ser una lógica de combinación (es decir, sin reloj). Lo que tiene infiere un mux con un flip flop de 2 etapas. Para corregir su diseño, elimine nextState <= State_IDLE; y reemplace always @(posedge clk) begin con always @(*) begin

La razón por la que un no bloqueo está retrasando el estado tiene que ver con la programación. Ejemplo:

a = 1;
b = a;
#1; // a is 1 and b is 1 (a is updated before assigning b)
a = 3;
b <= a;
#1; // a is 3 and b is 3 (a is updated before sampling for b)
a <= 4;
b <= a;
#1; // a is 4 and b is 3 (a is NOT updated before sampling for b)
a <= 5;
b = a;
#1; // a is 5 and b is 4 (a is NOT be updated before assigning b)
    
respondido por el Greg
0

Es mucho más claro tener un valor impulsado por no más de un proceso, lo que obliga al diseñador a resolver explícitamente las prioridades de los controladores, en lugar de confiar en las reglas implícitas de programación de procesos. La guía de lenguaje Verilog probablemente detalla algo como de arriba hacia abajo por orden de proceso, pero no es el tipo de cosa en la que confiaría.

También está combinando las asignaciones de bloqueo y no bloqueo en el mismo registro, lo que generalmente significa que el diseñador no tiene una idea clara del hardware al que está dirigido: el registro o la función combinatoria.

    
respondido por el shuckc
0

Combina ambos bloques siempre en un bloque siempre. No mezcle asignaciones de bloqueo y no bloqueo para una señal. ¡Además, el simulador no tiene un orden garantizado en el que estos bloques se ejecutan durante un flanco ascendente!

    
respondido por el Floko

Lea otras preguntas en las etiquetas