1
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ So you are proposing to create an always block for each parallel signal assignment? I would say thanks, but no. \$\endgroup\$ – Eugene Sh. Jun 14 at 17:48
  • 2
    \$\begingroup\$ In your example, it doesn't matter if you use blocking or non-blocking assignment. But what if you had a<=b; c<=a;? \$\endgroup\$ – The Photon Jun 14 at 17:57
  • \$\begingroup\$ @The photon I can still do it with two separate always blocks, right? (Assuming that you want to assign the initial value of a to c and initial value of b to a) \$\endgroup\$ – Abhishek Tyagi Jun 17 at 8:07
  • \$\begingroup\$ You could, but it might make your code harder to understand. \$\endgroup\$ – The Photon Jun 17 at 14:54
  • \$\begingroup\$ Yeah true. I understand that non-blocking statements does things in more intuitive manner, whereas it would have taken more than a few lines of code to do the same with blocking statements. My only doubt is that is there any thing that you can do with only non-blocking statements or is it just to make coding in Verilog much effective/elegant? \$\endgroup\$ – Abhishek Tyagi Jun 17 at 15:23
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Great examples. I’d add that as a practical matter, sequential logic must use the always posedge/negedge with nonblocking assignment <= pattern, or else the synthesis tool will not produce sequential logic in the hardware. \$\endgroup\$ – MarkU Jun 14 at 21:23
  • \$\begingroup\$ @MarkU for novice and moderate must is a very good practice. Those with advance experience know of the limited special exceptions, hence I leave it as should \$\endgroup\$ – Greg Jun 14 at 23:01
0
\$\begingroup\$

Verilog is a hardware description language first. Non-blocking assignment is required to describe the action of real hardware circuits acting in parallel. There are commonly used patterns that the hardware synthesis tool recognizes as flip-flops, multiplexers, lookup tables, etc. If non-blocking assignment was not included in the language, it would be more difficult to adequately describe these structures. Blocking assignment inherently determines the order in which operations happen. Note that the other major hardware description language, VHDL, also has this fundamental language feature. This is also one of the most confusing aspects of HDL for those who see verilog/VHDL as programming languages.

\$\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.