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
asked Jul 19, 2013 at 16:49
\$\endgroup\$

3 Answers 3

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)
answered Jul 19, 2013 at 18:23
\$\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.

answered Jul 19, 2013 at 18:30
\$\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!

answered Sep 28, 2014 at 8:47
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.