was fairly sure that nonblocking assignments were sequential while blocking assignments were parallel.
Blocking assignment executes "in series" because a blocking assignment blocks execution of the next statement until it completes. Therefore the results of the next statement may depend on the first one being completed.
Non-blocking assignment executes in parallel because it describes assignments that all occur at the same time. The result of a statement on the 2nd line will not depend on the results of the statement on the 1st line. Instead, the 2nd line will execute as if the 1st line had not happened yet.
1) I am not able to understand how the changing from blocking to non-blocking
The example code posted was for a combinatorial block, changing all blocking (=
) to non-blocking (<=
) may affect simulation but will not affect synthesis. This results in a RTL to gate level mismatch. It is an incorrect place to use the non-blocking assignment, do not use it in a combinatorial section.
To summarise for the other question non-blocking simulates that data changing just after an event such as the posedge of a clock. This allows correct simulation of a flip-flop.
this implies for testbenches:
initial begin
#31 rx_data_out = 255;
At time 31 the assignment happens.
initial begin
#31 rx_data_out <= 255;
Just after time 31 the assignment happens. Try both in parallel with a
initial begin
#31 $display(rx_data_out);
end
For the first example you actually have a race condition both happen at the same time, you should get 255 printed out. For the second example you will always have x
printed because the assignment happens just after the time 31 event, not on it.
non blocking can be useful for testbenches were you want to mimic data being driven by flip-flops, i.e. it changes just after the event. for example releasing a power on reset.
initial begin
@(posedge clk);
@(posedge clk);
rst_n <= 1'b0;
end
Imagine we had a series of flip-flops (a,b,c) creating a delay line, they each have d input and q output.
if the assignments were chained with :
c = b = a
Data would rush through from a to c instantly. but if we have
c <= b <= a
we have a pipeline, and each flip-flop can hold its value.
Actual code:
always @(posedge clk) begin
c = b;
b = a;
a = in;
end
versus:
always @(posedge clk) begin
c <= b;
b <= a;
a <= in;
end
This is why for question 2 with only one assignment it does not matter. but if there are multiple assignments that rely on each other it really does matter because you're controlling if it is driven from a flip-flop (<=
) or a block of combinatorial logic (=
).
My rules of thumb:
Use blocking (=
) for combinatorial logic and non-blocking (<=
) for sequential (flip-flops)
Best Answer
For this particular example, you are right. Both synthesis and simulation yield the same results. However, since you were using non-blocking assignment, the simulator had to enter the
always
block twice, as an event was triggered byx
. This may degrade the simulation performance. This could have been avoided if it wasx = a & b ;
This is one of the reasons why using blocking assignment for combinatorial logic has become a coding guideline in Verilog.
Reference: Section 11.0 of this Cummings Paper