26

I was reading this page http://www.asic-world.com/verilog/verilog_one_day3.html when I came across the following:

We normally have to reset flip-flops, thus every time the clock makes the transition from 0 to 1 (posedge), we check if reset is asserted (synchronous reset), then we go on with normal logic. If we look closely we see that in the case of combinational logic we had "=" for assignment, and for the sequential block we had the "<=" operator. Well, "=" is blocking assignment and "<=" is nonblocking assignment. "=" executes code sequentially inside a begin / end, whereas nonblocking "<=" executes in parallel.

I was fairly sure that nonblocking assignments were sequential while blocking assignments were parallel. After all, you can make blocking assignments with assign statements outside of always blocks, and those all run in parallel. Is this a mistake, or is the behavior different inside an always block? And, if the behavior IS different inside an always block, can nonblocking assignments be made outside an always block?

Void Star
  • 1,461
  • 1
  • 14
  • 26

3 Answers3

28

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.

The Photon
  • 126,425
  • 3
  • 159
  • 304
  • So what about assign statements? Are they just in a whole class of their own? – Void Star Nov 24 '13 at 04:25
  • 6
    Yes, `assign` statements occur outside of always blocks and are generally used to describe to combinatorial (un-latched) logic (while always blocks, with some exceptions, describe sequential logic). AFAIK, `assign` statements always execute "in parallel" whenever their LHS has a value change. – The Photon Nov 24 '13 at 04:28
  • Okay... I'm starting to get the impression that Verilog just isn't the most elegantly designed language. This is gonna be like learning C was. – Void Star Nov 24 '13 at 05:30
  • 2
    Verilog was designed to "describe" hardware that already exists. Using it as a language to design (synthesize) hardware is a hack. – The Photon Nov 24 '13 at 06:02
  • 6
    if Verilog "like learning C" is a problem, take a look at VHDL. Some people have fairly strong preferences for one or the other. To some, VHDL is just too verbose. To me, it's much better thought out. (signal/variable assignment semantics are much clearer than blocking/non for example). http://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 and http://www.sigasi.com/content/vhdls-crown-jewel You may prefer it or hate it. But it's worth a look. –  Nov 24 '13 at 10:20
  • Yeah, don't get me wrong, I love C, but it's nice to have options. I will look into VHDL, thanks. – Void Star Nov 24 '13 at 20:32
  • The main difference between VHDL and verilog is that VHDL has a much stricter type system and has the "entity/architecture" mess. The principles of RTL design such as the difference between blocking and nonblocking assignments and the use of specific behavioural formulations to describe sequential behaviour in a way synthesis tools can understand apply equally in both languages. – Peter Green Mar 30 '17 at 12:59
11

Assign statements are neither "blocking" or "nonblocking", they are "continuous". The output of an assign statement is always equal to the specified function of it's inputs. "blocking" and "nonblocking" assignments only exist within always blocks.

A blocking assignment takes affect immediately it is processed. A nonblocking assignment takes place at the end of processing the current "time delta".

always blocks can be used to model either combinatorial or sequential logic (systemverilog has always_comb and always_ff to make this explicit). When modeling combinatorial logic it's usually more efficient to use = but it typically doesn't really matter.

When modelling sequential logic (e.g. always @(posedge clk) ) you normally use nonblocking assingments. This allows you to deterime the "state after the clock edge" in terms of "the state before the clock edge".

It is sometimes useful to use blocking assignments in sequential always blocks as "variables". If you do this then there are two key rules to bear in mind.

  1. Do not access a reg that is set with blocking assignments inside a sequential always block from outside the always block it is assigned in.
  2. Do not mix blocking and nonblocking assignments to the same reg.

Breaking these rules is likely to result in synthesis failures and/or behaviour differences between simulation and synthesis.

Peter Green
  • 21,158
  • 1
  • 38
  • 76
  • ""Do not access a reg that is set with blocking assignments inside a sequential always block from outside the always block it is assigned in."" Can you please explain it? – user125575 Oct 04 '16 at 06:44
  • 1
    Different sequential always blocks do not have a defined order. So reading a "reg" set with a blocking assingment in one always block from another always block will lead to unpredicable behaviour. – Peter Green Oct 04 '16 at 15:23
  • And even if it appears to work in simulation, a synthesis tool should look at that and say "nope". I use local regs for those intermediate vars, and make sure that they are always assigned to on every clock before being read, so that no 'storage' is implied. – greggo Mar 30 '17 at 11:57
  • IIRC at least in quartus it is only considered a warning not an error. – Peter Green Mar 30 '17 at 11:59
  • You should not be using nonblocking assignment in combinational logic, it can lock up the simulation. For more details, refer this answer: https://electronics.stackexchange.com/a/506047/238188 – Shashank V M Oct 05 '20 at 14:55
9

The term Blocking assignment confuses people because the word blocking would seem to suggest time-sequential logic. But in synthesized logic it does not mean this, because everything operates in parallel.

Perhaps a less confusing term would be immediate assignment, which would still differentiate the intermediate results of combinational logic from the inputs to non-transparent memory elements (for example clocked registers), which can have delayed assignment.

From a legalistic standpoint, it all works out very nicely. You can, in fact, consider the = to be a blocking (time-sequential) operation even within always_comb sequences. However, the distinction between time-sequential and parallel makes absolutely no difference in this case because the always_comb block is defined to repeat until the instruction sequence converges on a stable state -- which is exactly what the hardware circuitry will do (if it meets the timing requirements).

The synthesizable subset of Verilog (and especially SystemVerilog) is extremely simple and easy to use -- once you know the necessary idioms. You just have to get past the clever use of terminology associated with the so-called behavioral elements in the language.

Brent Bradburn
  • 355
  • 3
  • 10
  • In *behavioral* coding styles ([as compared to RTL](http://electronics.stackexchange.com/questions/63682/difference-between-rtl-and-behavioral-verilog)), the distinction between blocking and non-blocking can be relevant. In some cases, the synthesis tool may be able to infer functionally equivalent RTL from behavioral component designs. – Brent Bradburn Jul 21 '15 at 17:28
  • Of course the [*procedural*](http://www.asic-world.com/systemverilog/procedure_ctrl1.html) mode of SystemVerilog, applicable especially to `initial` statements within `program` blocks, uses (time-sequential) *blocking assignment* exclusively. This is useful for *testbench* design, but generally not for RTL specification. – Brent Bradburn Dec 18 '15 at 18:58