Electronic – What happens if we use non-blocking assignment <= inside of always @* block

verilog

In verilog, we are supposed to use blocking assignment = in conjunction with always@( * ) to build combinational logic, but what happens if we use non-blocking assignment <= inside of always @* block? For example,

always @ ( * ) begin
   x <= a & b;
   y <= x | c;
end

What is the behavior of this code and what kind of circuit we will end up getting?

According to the example in this slide, we will have y = 1 instead of 0 in the end, because the non blocking assignment uses the old value of x, which is 1, to update y.enter image description here

But according to my experiment, I still get the desired result of y, which is 0. My guess is that, the difference of blocking and non blocking is very subtle when they are used inside of always @* block. The always @* will be triggered again at the line of x<= a & b, so that the next line sees the updated x value.
enter image description here

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 by x. This may degrade the simulation performance. This could have been avoided if it was x = 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