Electronic – Why we need non-blocking assignments in Verilog

hdlverilog

I understand the basics of blocking and non-blocking assignments in verilog.
I understand that blocking assignments execute in a sequential manner,whereas it is possible to assign values concurrently using non-blocking statements.

My question is, why was non-blocking assignments included in Verilog. I can think of the following example to give weight to my statement.

Using blocking assignment:

always@(posedge)
   a = b;

always@(posedge)
   c = d;

Using non-blocking assignments:

always@(posedge)
   a <= b;
   c <= d;

So the two pieces of code above carry out the same process (parallel assignment of b to a and d to c, ignoring the race condition in case of blocking assignment). Similarly, if we take the case of swapping two variables in verilog, it is possible to do it with both non-blocking and blocking assignments.

But I am not able to find some example which will showcase that it is not possible to do it with non-blocking assignment and can only be done with blocking assignments.

I hope somebody can throw some light on the same.

Best Answer

Lets simplify things by assuming a and b have initial values 1'b1 and 1'b0 respectively.

  1. One always block with blocking assignment:

    always @(posedge clk) begin
      a = b;
      b = a;
    end

    a and b will be 1'b0 after any clock event

  2. Two always blocks with blocking assignment:

    always @(posedge clk)
      a = b;
    always @(posedge clk)
      b = a;

    The simulator can choose which always block to evaluate first per the non-determinism specifically allowed by the IEEE1364 (Verilog) and IEEE1800 (SystemVerilog). a and b will both be 1'b0 or both be 1'b1 and will stay that value for any future clock event.

  3. One always block with non-blocking assignment:

    always @(posedge clk) begin
      a <= b;
      b <= a;
    end

    After the first clock, a will be 1'b0 and b will be 1'b1. After the second clock, a and b will be assign back to their initial values; 1'b1 and 1'b0 respectively. They will continue to flop every clock. This is the desired behavior and will match hardware.

  4. Two always blocks with non-blocking assignment:

    always @(posedge clk)
      a <= b;
    always @(posedge clk)
      b <= a;

    The simulator can choose which always block to evaluate first per the non-determinism specifically allowed by the IEEE1364 (Verilog) and IEEE1800 (SystemVerilog). Regardless, after the first clock, a will be 1'b0 and b will be 1'b1. After the second clock, a and b will be assign back to their initial values; 1'b1 and 1'b0 respectively. They will continue to flop every clock. This is the desired behavior and will match hardware.


Blocking assignments (=) means evaluate and update immediately. This is ideal for combinational logic (assigned in always @*).
Non-blocking assignments (<=) means evaluate immediately and postpone the updates until all other planed evaluations in the same time step has been completed. Sequential logic (assigned in always @(posedge clk)) should use non-blocking assignments.