Nonblocking Assignments in Verilog Synthesis Codin
Nonblocking Assignments in Verilog Synthesis Codin
net/publication/238283056
CITATIONS READS
16 2,097
1 author:
Clifford E. Cummings
Sunburst Design, Inc.
28 PUBLICATIONS 496 CITATIONS
SEE PROFILE
All content following this page was uploaded by Clifford E. Cummings on 21 January 2015.
SNUG-2000
San Jose, CA
Clifford E. Cummings Voted Best Paper
1st Place
ABSTRACT
One of the most misunderstood constructs in the Verilog language is the nonblocking
assignment. Even very experienced Verilog designers do not fully understand how nonblocking
assignments are scheduled in an IEEE compliant Verilog simulator and do not understand when
and why nonblocking assignments should be used. This paper details how Verilog blocking and
nonblocking assignments are scheduled, gives important coding guidelines to infer correct
synthesizable logic and details coding styles to avoid Verilog simulation race conditions.
1.0 Introduction
Two well known Verilog coding guidelines for modeling logic are:
• Guideline: Use blocking assignments in always blocks that are written to generate
combinational logic [1].
• Guideline: Use nonblocking assignments in always blocks that are written to generate
sequential logic [1].
But why? In general, the answer is simulation related. Ignoring the above guidelines can still
infer the correct synthesized logic, but the pre-synthesis simulation might not match the behavior
of the synthesized circuit.
To understand the reasons behind the above guidelines, one needs to have a full understanding of
the functionality and scheduling of Verilog blocking and nonblocking assignments. This paper
will detail the functionality and scheduling of blocking and nonblocking assignments.
The IEEE Verilog Standard [2] defines: which statements have a guaranteed order of execution
("Determinism", section 5.4.1), and which statements do not have a guaranteed order of
execution ("Nondeterminism", section 5.4.2 & "Race conditions", section 5.5).
A Verilog race condition occurs when two or more statements that are scheduled to execute in
the same simulation time-step, would give different results when the order of statement execution
is changed, as permitted by the IEEE Verilog Standard.
To avoid race conditions, it is important to understand the scheduling of Verilog blocking and
nonblocking assignments.
The blocking assignment operator is an equal sign ("="). A blocking assignment gets its name
because a blocking assignment must evaluate the RHS arguments and complete the assignment
without interruption from any other Verilog statement. The assignment is said to "block" other
assignments until the current assignment has completed. The one exception is a blocking
assignment with timing delays on the RHS of the blocking operator, which is considered to be a
poor coding style [3].
A blocking assignment "blocks" trailing assignments in the same always block from occurring
until after the current assignment has been completed
A problem with blocking assignments occurs when the RHS variable of one assignment in one
procedural block is also the LHS variable of another assignment in another procedural block and
both equations are scheduled to execute in the same simulation time step, such as on the same
clock edge. If blocking assignments are not properly ordered, a race condition can occur. When
blocking assignments are scheduled to execute in the same time step, the order execution is
unknown.
According to the IEEE Verilog Standard, the two always blocks can be scheduled in any order. If
the first always block executes first after a reset, both y1 and y2 will take on the value of 1. If the
second always block executes first after a reset, both y1 and y2 will take on the value 0. This
clearly represents a Verilog race condition.
The nonblocking assignment operator is the same as the less-than-or-equal-to operator ("<="). A
nonblocking assignment gets its name because the assignment evaluates the RHS expression of a
nonblocking statement at the beginning of a time step and schedules the LHS update to take
place at the end of the time step. Between evaluation of the RHS expression and update of the
LHS expression, other Verilog statements can be evaluated and updated and the RHS expression
of other Verilog nonblocking assignments can also be evaluated and LHS updates scheduled. The
nonblocking assignment does not block other Verilog statements from being evaluated.
Nonblocking assignments are only made to register data types and are therefore only permitted
inside of procedural blocks, such as initial blocks and always blocks. Nonblocking assignments
are not permitted in continuous assignments.
Again, according to the IEEE Verilog Standard, the two always blocks can be scheduled in any
order. No matter which always block starts first after a reset, both nonblocking RHS expressions
will be evaluated at the beginning of the time step and then both nonblocking LHS variables will
be updated at the end of the same time step. From a users perspective, the execution of these two
nonblocking statements happen in parallel.
Before giving further explanation and examples of both blocking and nonblocking assignments,
it would be useful to outline eight guidelines that help to accurately simulate hardware, modeled
using Verilog. Adherence to these guidelines will also remove 90-100% of the Verilog race
conditions encountered by most Verilog designers.
Guideline #3: When modeling combinational logic with an always block, use blocking
assignments.
Guideline #4: When modeling both sequential and combinational logic within the same always
block, use nonblocking assignments.
Guideline #5: Do not mix blocking and nonblocking assignments in the same always block.
Guideline #6: Do not make assignments to the same variable from more than one always block.
Guideline #7: Use $strobe to display values that have been assigned using nonblocking
assignments.
Reasons for these guidelines are given throughout the rest of this paper. Designers new to
Verilog are encouraged to memorize and use these guidelines until their underlying functionality
is fully understood. Following these guidelines will help to avoid "death by Verilog!"
An examination of the Verilog "stratified event queue" (see Figure 1) helps to explain how
Verilog blocking and nonblocking assignments function. The "stratified event queue" is a fancy
name for the different Verilog event queues that are used to schedule simulation events.
The "stratified event queue" as described in the IEEE Verilog Standard is a conceptual model.
Exactly how each vendor implements the event queues is proprietary, helps to determine the
efficiency of each vendor's simulator and is not detailed in this paper.
As defined in section 5.3 of the IEEE 1364-1995 Verilog Standard, the "stratified event queue" is
logically partitioned into four distinct queues for the current simulation time and additional
queues for future simulation times.
Inactive Events
#0 blocking assignments
The active events queue is where most Verilog events are scheduled, including blocking
assignments, continuous assignments, $display commands, evaluation of instance and primitive
inputs followed by updates of primitive and instance outputs, and the evaluation of nonblocking
RHS expressions. The LHS of nonblocking assignments are not updated in the active events
queue.
Events are added to any of the event queues (within restrictions imposed by the IEEE Standard)
but are only removed from the active events queue. Events that are scheduled on the other event
queues will eventually become "activated," or promoted into the active events queue. Section 5.4
of the IEEE 1364-1995 Verilog Standard lists an algorithm that describes when the other event
queues are "activated."
Two other commonly used event queues in the current simulation time are the nonblocking
assign updates event queue and the monitor events queue, which are described below.
The nonblocking assign updates event queue is where updates to the LHS expression of
nonblocking assignments are scheduled. The RHS expression is evaluated in random order at the
beginning of a simulation time step along with the other active events described above.
The monitor events queue is where $strobe and $monitor display command values are scheduled.
$strobe and $monitor show the updated values of all requested variables at the end of a
simulation time step, after all other assignments for that simulation time step are complete.
The "stratified event queue" of Figure 1 will be frequently referenced to explain the behavior of
Verilog code examples shown later in this paper. The event queues will also be referenced to
justify the eight coding guidelines given in section 5.0.
In general, a Verilog always block cannot trigger itself. Consider the oscillator example in
Example 3. This oscillator uses blocking assignments. Blocking assignments evaluate their RHS
expression and update their LHS value without interruption. The blocking assignment must
complete before the @(clk) edge-trigger event can be scheduled. By the time the trigger event
has been scheduled, the blocking clk assignment has completed; therefore, there is no trigger
event from within the always block to trigger the @(clk) trigger.
In contrast, the oscillator in Example 4 uses nonblocking assignments. After the first @(clk)
trigger, the RHS expression of the nonblocking assignment is evaluated and the LHS value
scheduled into the nonblocking assign updates event queue. Before the nonblocking assign
updates event queue is "activated," the @(clk) trigger statement is encountered and the always
block again becomes sensitive to changes on the clk signal. When the nonblocking LHS value is
updated later in the same time step, the @(clk) is again triggered. The osc2 example is self-
triggering (which is not necessarily a recommended coding style).
Figure 2 shows a block diagram for a simple sequential pipeline register. Example 5 - Example 8
show four different ways that an engineer might choose to model this pipeline using blocking
assignments.
d q1 q2 q3
clk
In the pipeb1, Example 5 code, the sequentially ordered blocking assignments will cause the
input value, d, to be placed on the output of every register on the next posedge clk. On every
clock edge, the input value is transferred directly to the q3-output without delay. This clearly
does not model a pipeline register and will actually synthesize to a single register! (See Figure 3).
In the pipeb2 example, the blocking assignments have been carefully ordered to cause the
simulation to correctly behave like a pipeline register. This model also synthesizes to the pipeline
register shown in Figure 2.
In the pipeb3 example, the blocking assignments have been split into separate always blocks.
Verilog is permitted to simulate the always blocks in any order, which might cause this pipeline
simulation to be wrong. This is a Verilog race condition! Executing the always blocks in a
different order yields a different result. However, this Verilog code will synthesize to the correct
pipeline register. This means that there might be a mismatch between the pre-synthesis and post-
synthesis simulations. The pipeb4 example, or any other ordering of the same always block
statements will also synthesize to the correct pipeline logic, but might not simulate correctly.
Although, if confined to one always block with carefully sequenced assignments, it was possible
to code the pipeline logic using blocking assignments. On the other hand, it was easy to code the
same pipeline logic using nonblocking assignments; indeed, the nonblocking assignment coding
styles all would work for both synthesis and simulation.
There are many Verilog and Verilog synthesis books that show simple sequential examples that
are successfully coded using blocking assignments. Example 13 shows a flipflop model that
appears in most Verilog text books.
If an engineer is willing to limit all modules to a single always block, blocking assignments can
be used to correctly model, simulate and synthesize the desired logic. Unfortunately this
reasoning leads to the habit of placing blocking assignments in other, more complex sequential
always blocks that will exhibit the race conditions already detailed in this paper.
It is better to develop the habit of coding all sequential always blocks, even simple single-block
modules, using nonblocking assignments as shown in Example 14.
Now consider a more complex piece of sequential logic, a Linear Feedback Shift-Register or
LFSR.
A Linear Feedback Shift-Register (LFSR) is a piece of sequential logic with a feedback loop. The
feedback loop poses a problem for engineers attempting to code this piece of sequential logic
with correctly ordered blocking assignments as shown in Example 15.
assign n1 = q1 ^ q3;
There is no way to order the assignments in Example 15 to model the feedback loop unless a
temporary variable is used.
If the blocking assignments in Example 15 and Example 16 are replaced with nonblocking
assignments as shown in Example 17 and Example 18, all simulations function as would be
expected from an LFSR.
assign n1 = q1 ^ q3;
Based on the pipeline examples of section 8.0 and the LFSR examples of section 10.0, it is
recommended to model all sequential logic using nonblocking assignments. A similar analysis
would show that it is also safest to use nonblocking assignments to model latches
There are many ways to code combinational logic using Verilog, but when the combinational
logic is coded using an always block, blocking assignments should be used.
If only a single assignment is made in the always block, using either blocking or nonblocking
assignments will work; but in the interest of developing good coding habits one should always
using blocking assignments to code combinational logic.
It has been suggested by some Verilog designers that nonblocking assignments should not only
be used for coding sequential logic, but also for coding combinational logic. For coding simple
combinational always blocks this would work, but if multiple assignments are included in the
always block, such as the and-or code shown in Example 19, using nonblocking assignments
with no delays will either simulate incorrectly, or require additional sensitivity list entries and
multiple passes through the always block to simulate correctly. The latter would be inefficient
from a simulation time perspective.
The code shown in Example 19 builds the y-output from three sequentially executed statements.
Since nonblocking assignments evaluate the RHS expressions before updating the LHS variables,
the values of tmp1 and tmp2 were the original values of these two variables upon entry to this
always block and not the values that will be updated at the end of the simulation time step. The
y-output will reflect the old values of tmp1 and tmp2, not the values calculated in the current pass
of the always block.
The code shown in Example 20 is identical to the code shown in Example 19, except that tmp1
and tmp2 have been added to the sensitivity list. As describe in section 7.0, when the
nonblocking assignments update the LHS variables in the nonblocking assign update events
queue, the always block will self-trigger and update the y-outputs with the newly calculated tmp1
and tmp2 values. The y-output value will now be correct after taking two passes through the
always block. Multiple passes through an always block equates to degraded simulation
performance and should be avoided if a reasonable alternative exists.
The code in Example 21 is identical to the code in Example 19, except that the nonblocking
assignments have been replaced with blocking assignments, which will guarantee that the y-
output assumes the correct value after only one pass through the always block; hence the
following guideline:
Guideline #3: When modeling combinational logic with an always block, use blocking
assignments.
The same logic that is implemented in Example 22 could also be implemented as two separate
always blocks, one with purely combinational logic coded with blocking assignments and one
with purely sequential logic coded with nonblocking assignments as shown in Example 23.
always @(a or b)
y = a ^ b;
Guideline #4: When modeling both sequential and combinational logic within the same always
block, use nonblocking assignments.
Verilog permits blocking and nonblocking assignments to be freely mixed inside of an always
block. In general, mixing blocking and nonblocking assignments in the same always block is a
poor coding style, even if Verilog permits it.
The code in Example 24 will both simulate and synthesize correctly because the blocking
assignment is not made to the same variable as the nonblocking assignments. Although this will
work, the author discourages this coding style.
The code in Example 25 will most likely simulate correctly most of the time, but Synopsys tools
will report a syntax error because the blocking assignment is assigned to the same variable as one
of the nonblocking assignments. This code must be modified to be synthesizable.
As a matter of forming good coding habits, the author encourages adherence to the following:
Guideline #5: Do not mix blocking and nonblocking assignments in the same always block.
Making multiple assignments to the same variable from more than one always block is a Verilog
race condition, even when using nonblocking assignments.
In Example 26, two always blocks are making assignments to the q-output, both using
nonblocking assignments. Since these always blocks can be scheduled in an order, the simulation
output is a race condition.
When Synopsys tools read this type of coding example, the following warning message is issued:
Guideline #6: Do not make assignments to the same variable from more than one always block.
Myth: “Using the $display command with nonblocking assignments does not work”
module display_cmds;
reg a;
initial begin
$strobe ("\$strobe : a = %b", a);
a = 0;
a <= 1;
$display ("\$display: a = %b", a);
#1 $finish;
end
endmodule
The below output from the above simulation shows that the $display command was executed in
the active events queue, before the nonblocking assign update events were executed.
$display: a = 0
$monitor: a = 1
$strobe : a = 1
module nb_schedule1;
reg a, b;
initial begin
a = 0;
b = 1;
a <= b;
b <= a;
#1 $finish;
end
endmodule
The below output from the simulation on the previous page shows that the #0-delay command
was executed in the inactive events queue, before the nonblocking assign update events were
executed.
Guideline #7: Use $strobe to display values that have been assigned using nonblocking
assignments.
Myth: “Making multiple nonblocking assignments to the same variable in the same always block
is undefined”
Truth: Making multiple nonblocking assignments to the same variable in the same always block
is defined by the Verilog Standard. The last nonblocking assignment to the same variable wins!
Quoting from the IEEE 1364-1995 Verilog Standard [2], pg. 47, section 5.4.1 - Determinism
"Nonblocking assignments shall be performed in the order the statements were executed.
Consider the following example:
initial begin
a <= 0;
a <= 1;
end
When this block is executed, there will be two events added to the nonblocking assign
update queue. The previous rule requires that they be entered on the queue in source
order; this rule requires that they be taken from the queue and performed in source order
as well. Hence, at the end of time-step 1, the variable a will be assigned 0 and then 1."
Guideline #3: When modeling combinational logic with an always block, use blocking
assignments.
Guideline #4: When modeling both sequential and combinational logic within the same always
block, use nonblocking assignments.
Guideline #5: Do not mix blocking and nonblocking assignments in the same always block.
Guideline #6: Do not make assignments to the same variable from more than one always block.
Guideline #7: Use $strobe to display values that have been assigned using nonblocking
assignments.
Conclusion: Following the above guidelines will accurately model synthesizable hardware while
eliminating 90-100% of the most common Verilog simulation race conditions.
The word nonblocking is frequently misspelled as "non-blocking." The author believes this is the
Microsoftization of the word. Engineers have inserted a dash between "non" and "blocking" to
satisfy Microsoft, as well as other, spell checkers. The correct spelling of the word as noted in the
IEEE 1364-1995 Verilog Standard is in fact: nonblocking.
References
[1] IEEE P1364.1 Draft Standard For Verilog Register Transfer Level Synthesis
[2] IEEE Standard Hardware Description Language Based on the Verilog Hardware
Description Language, IEEE Computer Society, IEEE Std 1364-1995
[3] Clifford Cummings, "Correct Methods For Adding Delays To Verilog Behavioral
Models," International HDL Conference 1999 Proceedings, pp. 23-29, April 1999.
Cliff Cummings, President of Sunburst Design, Inc., is an independent EDA consultant and
trainer with 18 years of ASIC, FPGA and system design experience and eight years of Verilog,
synthesis and methodology training experience.
Mr. Cummings, a member of the IEEE 1364 Verilog Standards Group (VSG) since 1994,
currently chairs the VSG Behavioral Task Force, which is charged with proposing enhancements
to the Verilog language. Mr. Cummings is also a member of the IEEE Verilog Synthesis
Interoperability Working Group.
Mr. Cummings holds a BSEE from Brigham Young University and an MSEE from Oregon State
University.