Verilog Nonblocking Assignments With Delays,
Myths & Mysteries
Clifford E. Cummings
Sunburst Design, Inc.
cliffc@sunburst-design.com
ABSTRACT
There is a common misconception that coding sequential logic with nonblocking assignments does
not simulate correctly unless a #1 delay is added to the right hand side of the nonblocking
assignment operator. This is not true. This paper will explain how delays and nonblocking
assignments impact the Verilog event queue. This paper will also detail both good and bad
reasons for adding delays to nonblocking assignments and include guidelines for good RTL
coding styles that permit mixed RTL and gate-level simulation.
SNUG-2002
Boston, MA
Voted Best Paper
2
nd
Place
SNUG Boston 2002 Verilog Nonblocking Assignments
Rev 1.4 With Delays, Myths & Mysteries
2
1.0 Introduction
In his book Writing Testbenches[7], Functional Verification of HDL Models, Janick Bergeron
claims that VHDL and Verilog both have the same area under the learning curve[8]. Due to the
misinformation that has been spread through numerous Verilog books and training courses, I am
afraid Bergeron may be right.
When Verilog is taught correctly, I believe the area under the Verilog learning curve is much
smaller and Verilog simulations run much faster than comparable VHDL simulations.
This paper details functionality and important guidelines related to nonblocking assignments and
nonblocking assignments with delays. Before discussing nonblocking assignment functionality and
recommendations, a quick review of the definition of nonblocking assignments is in order:
A nonblocking assignment is a Verilog procedural assignment that uses the "<=" operator inside
of a procedural block. It is illegal to use a nonblocking assignment in a continuous assignment
statement or in a net declaration.
A nonblocking assignment can be viewed as a 2-step assignment. At the beginning of a simulation
time step, the right-hand-side (RHS) of the nonblocking assignment is (1) evaluated and at the
end of the nonblocking assignment the left-hand-side (LHS) variable is (2) updated. A
nonblocking assignment does not "block" other assignments from being executed between the
evaluation and update steps of a nonblocking assignment; hence, the name "nonblocking."
Despite complaints from commercial document spell-checking software, nonblocking is spelled
without a hyphen, as noted in both IEEE Verilog Standards[4][5] and the pending IEEE Verilog
Synthesis Standard[6].
SNUG Boston 2002 Verilog Nonblocking Assignments
Rev 1.4 With Delays, Myths & Mysteries
3
2.0 The Verilog event queue
The Verilog event queue described in this paper is an algorithmic description. The exact
implementation is not defined in the Verilog Standard but the outcome must duplicate the
functionality of the description.
Section 5.4 of both IEEE Verilog Standards documents, IEEE Std 1364-1995[4] and IEEE Std
1364-2001[5], describes "The Verilog simulation reference model." The reference model is shown
below:
In all the examples that follow, T refers to the current simulation time, and all events are held
in the event queue, ordered by simulation time.
while (there are events) {
if (no active events) {
if (there are inactive events) {
activate all inactive events;
} else if (there are nonblocking assign update events) {
activate all nonblocking assign update events;
} else if (there are monitor events) {
activate all monitor events;
} else {
advance T to the next event time;
activate all inactive events for time T;
}
}
E = any active event;
if (E is an update event) {
update the modified object;
add evaluation events for sensitive processes to event queue;
} else { /* shall be an evaluation event */
evaluate the process;
add update events to the event queue;
}
}
Figure 1 - The Verilog simulation reference model
A simplified and restructured version of this algorithm can be examined if #0 delays (inactive
events) are not used. The model can be further simplified if $monitor and $strobe commands
are removed from the algorithm. Note that $monitor and $strobe commands do not trigger
evaluation events and they are always executed last in the current time step. The algorithm has
been reworded in an attempt to add clarification to the algorithm execution process.
SNUG Boston 2002 Verilog Nonblocking Assignments
Rev 1.4 With Delays, Myths & Mysteries
4
Think of T as an integer that tracks the simulation time. At the beginning of a simulation, T is set
to 0, all nets are set to HiZ (z) and all variables are set to unknown (x). All procedural blocks
(initial and always blocks) then become active. In Verilog-2001, variables may be initialized
in their respective declarations and this initialization is permitted either before or after the
procedural blocks become active at time 0.
while (there are events) {
if (there are active events) {
E = any active event;
if (E is an update event) {
update the modified object;
add evaluation events for sensitive processes to event queue;
}
else { // this is an evaluation event, so ...
evaluate the process;
add update events to the event queue;
}
}
else if (there are nonblocking update events) {
activate all nonblocking update events;
}
else {
advance T to the next event time;
activate all inactive events for time T;
}
}
Figure 2 - Modified Verilog simulation reference model
Activating the nonblocking events means to take all of the events from the nonblocking update
events queue and put them in the active events queue. When these activated events are executed,
they may cause additional processes to trigger and cause more active events and more
nonblocking update events to be scheduled in the same time step. Activity in the current time step
continues to iterate until all events in the current time step have been executed and no more
processes, that could cause more events to be scheduled, can be triggered. At this point, all of the
$monitor and $strobe commands would display their respective values and then the
simulation time T can be advanced.
SNUG Boston 2002 Verilog Nonblocking Assignments
Rev 1.4 With Delays, Myths & Mysteries
5
2.1 Event scheduling and re-triggering
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.
Figure 3 - The Verilog "stratified event queue"
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 variables of nonblocking assignments are not updated in the active
events queue but instead are placed in the nonblocking assign update events queue, where they
remain until they are activated (moved into the active events queue).
As shown in Figure 4, active events such as blocking assignments and contiuous assignments can
trigger additional assignments and procedural blocks causing more active events and nonblocking
assign update events to be scheduled in the same time step. Under these circumstances, the new
active events would be executed before activating any of the nonblocking assign update events.
As shown in Figure 5, after the nonblocking assign updates events are activated, the LHS of the
nonblocking assignments are updated, which can trigger additional assignments and procedural
blocks, causing more active events and nonblocking assign update events to be scheduled in the
same time step. As described in the modified simulation reference model of Figure 2, simulation
time does not advance while there are still active events and nonblocking assign update events to
be processed in the current simulation time.