Verilog Nonblocking Assignments Demystified Clifford E. Cummings Sunburst Design, Inc. 15870 SW Breccia Drive Beaverton, OR 97007
[email protected]
Abstract Nonblocking assignments are an important construct to accurately model hardware both for behavioral and RTL simulation; however, there are many misunderstandings surrounding how nonblocking assignments work. This paper will examine many of the misunderstandings surrounding nonblocking assignments and how nonblocking assignments are appropriately used in behavioral and RTL-synthesis modeling.
1. IEEE Copyright Authors who submit papers for publication in IEEE Conference Proceedings are required to sign an agreement assigning all copyrights for the submitted work to The Institute of Electrical and Electronics Engineers. The copyright agreement [1] states that "authors/employers must request permission from the IEEE Copyrights Office to reproduce or authorize the reproduction of the work or material extracted verbatim from the work, including figures and tables." It was Mr. Cummings' intent to share materials, including diagrams, Verilog source-code examples and figures that he currently uses or intends to use in Verilog synthesis training courses and publications for profit. Due to concerns over the restrictive nature of the IEEE copyright, Mr. Cummings has withdrawn most of the more interesting figures and code segments in order to preserve his right to use these materials for profit in the future. Readers are invited to freely download a more informative and complete treatment of Verilog nonblocking assignments from the Sunburst Design web page at www.sunburst-design.com. The IVC conference presentation and down-loaded paper will include more
examples, better examples and additional information not included in this paper.
2. Introduction This paper will detail some common misconceptions surrounding Verilog nonblocking assignments.
3. Scheduling semantics The order of execution of assignments within the Verilog language is described in the IEEE 1364-1995 Standard [2], section 5.3. This section defines the Verilog event queue. The queue is divided into "five regions." From IEEE Std 1364-1995 [2], pg. 46, section 5.3, The stratified event queue: "1) Events that occur at the current simulation time and can be processed in any order. These are the active events." This includes all continuous assignments and procedural assignments using the blocking-assignment operator. This also includes values displayed using the $display command. "2) Events that occur at the current simulation time, but shall be processed after all the active events are processed. These are the inactive events." This includes "explicit delay zero (#0)" procedural assignments using the blocking-assignment operator. "3) Events that have been evaluated during some previous simulation time, but shall be assigned at this simulation time after all the active and inactive
Authorized licensed use limited to: NATIONAL INSTITUTE OF TECHNOLOGY DURGAPUR. Downloaded on July 17, 2009 at 11:17 from IEEE Xplore. Restrictions apply.
events are processed. These are the nonblocking assign update events." This includes procedural assignments using the nonblocking-assignment operator. "4) Events that shall be processed after all the active, inactive, and nonblocking assign update events are processed. These are the monitor events." This includes values displayed using either the $monitor or $strobe commands. "5) Events that occur at some future simulation time. These are the future events. Future events are divided into future inactive events, and future nonblocking assignment update events."
5. $strobe and $monitor commands To show values after making nonblocking assignments, use either the $strobe command or the $monitor command, both of which execute after a nonblocking assignment has completed execution. $strobe example: module strobe_ivc; reg a; initial begin a = 0; a <= 1; $strobe("$strobe: a = %b", a); #1 $finish; end endmodule
4. $display command Output display: Verilog users often become confused when trying to display values after making assignments using nonblocking assignments. In the earlier section describing scheduling semantics, it is clear that if both a $display command and a nonblocking assignment are scheduled in the same simulation time-step, the $display command will complete before the nonblocking assignment has completed. This can be confusing if a $display command was placed immediately after a nonblocking assignment since the displayed value will be the value before the nonblocking assignment has completed. $display example: module display_ivc; reg a; initial begin a = 0; a <= 1; $display("$display: a = %b", a); #1 $finish; end endmodule
Output display:
$strobe: a = 1
The value displayed by the $strobe command is the value that was assigned by the nonblocking assignment, a <= 1; $monitor example: module monitor_ivc; reg a; initial begin a = 0; a <= 1; $monitor("$monitor: a = %b", a); #1 $finish; end endmodule
Output display: $monitor: a = 1
The value displayed by the $monitor command is the value that was assigned by the nonblocking assignment, a <= 1;
$display: a = 0
6. #0 delays The value displayed by the $display command is the value that was assigned by the blocking assignment, a = 0; not the updated value from the nonblocking assignment.
An over-used and generally poor Verilog coding style is to make assignments with #0 delays. #0 is generally believed to force assignments to occur at the end of a simulation time-step and is most frequently used in
Authorized licensed use limited to: NATIONAL INSTITUTE OF TECHNOLOGY DURGAPUR. Downloaded on July 17, 2009 at 11:17 from IEEE Xplore. Restrictions apply.
Verilog models that make assignments to the same variable from more than one procedural block. This concept is flawed and the practice is over used. #0 causes assignments to occur later in one of the assignment queues. Example: module delay0_ivc; reg a; initial begin #0 a = 0; $display("#0 $display: a = %b", a); end initial a = 1; initial a <= 1'bx; initial $display("$display: a = %b", a); initial $strobe("$strobe: a = %b", a); initial #1 $finish; endmodule
Output display: $display: a = 1 #0 $display: a = 0 $strobe: a = x
The value displayed by the second $display command was the value that was assigned by the blocking assignment, a = 1;. The value displayed by the first $display command was the value that was assigned by the #0 blocking assignment, #0 a = 0;. The value displayed by the $strobe command was the value that was assigned by the nonblocking assignment, a <= 1'bx; therefore, the #0 command only insured that the #0-blocking assignment was executed at the end of the blocking assignment queue, but before the nonblocking assignment was executed. In general, it is poor coding practice to make assignments to the same variable from multiple always blocks. To compensate for this poor coding practise, engineers use the #0 delay in an attempt to coerce assignment-order to the same variable from multiple always blocks or to delay a specific assignment from occurring until after the assignment input variable has been updated by another always block. This coding practice is one source of Verilog race conditions and should be discouraged.
7. Assignments in the same always block A common misconception concerning nonblocking assignments is that if multiple nonblocking assignments are made to the same variable, in the same procedural block, during the same simulation time-step, that this behavior is undefined in the Verilog language. This is not true. From IEEE Std 1364-1995 [2], pg. 47, section 5.4.1 Determinism "2) 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." It is good synthesis and model coding style to make an initial default assignment in an always block to output variables using nonblocking assignments, and then to update specific assignments within the block as functionally appropriate. This coding style, in general, makes model-code more compact and easy to follow, since the default output assignments are at the beginning of the always block and it is easy to scan the rest of the block to see where a specific output is assigned.
References [1] IEEE Copyright Form, http://www.ieee.org/copyright [2] IEEE Standard Hardware Description Language Based on the Verilog Hardware Description Language, IEEE Computer Society, IEEE Std 1364-1995
Authorized licensed use limited to: NATIONAL INSTITUTE OF TECHNOLOGY DURGAPUR. Downloaded on July 17, 2009 at 11:17 from IEEE Xplore. Restrictions apply.