0
\$\begingroup\$

In the rst block in the following code I get a strange error whenever I use non-blocking assignment/ The State_SENDSYNC last for two cycles even though it's supposed to only last one cycle. Changing to blocking assignment fixes the problem, but I am baffled as to why. Shouldn't a mux get inferred either way?

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
\$\endgroup\$
1
\$\begingroup\$

nextState should be combination logic (i.e. no clock). What it have infers a mux with a 2 stage flip flop. To correct your design remove nextState <= State_IDLE; and replace always @(posedge clk) begin with always @(*) begin

The reason a non-blocking is delaying the state has to do with scheduling. Example:

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)
\$\endgroup\$
0
\$\begingroup\$

It is much clearer to have a value driven by no more than one process, which forces the designer to explicitly resolve driver priorities, rather than rely on implicit process scheduling rules. Verilog language guide probably details something like top-down by process order but It's not the kind of thing I would rely on.

You are also mixing blocking and non-blocking assignment to the same reg, which generally means the designer hasn't got a clear idea of the hardware being targeted: either register or combinatorial function.

\$\endgroup\$
0
\$\begingroup\$

Combine both always blocks into one always block. Don't mix blocking and non-blocking assignments for one signal. Also the simulator doesn't have a garantued order in which these blocks are executed during a rising edge!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.