








































Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
How non-blocking procedural assignments are evaluated and executed in the verilog simulator. It covers the concept of procedural assignments, the behavior of non-blocking assignments, and the potential indeterminacy of scheduling multiple non-blocking assignments to the same register. It also provides examples of non-blocking assignments and their impact on simulation time.
Typology: Assignments
1 / 48
This page cannot be seen from the preview
Don't miss anything!









































June 1995 Behavioral Modeling 8-
The language constructs introduced so far allow hardware to be described at a relatively detailed level. Modeling a circuit with logic gates and continuous assignments reflects quite closely the logic structure of the circuit being modeled; however, these constructs do not provide the power of abstraction necessary for describing complex high level aspects of a system. The procedural constructs described in this chapter are well suited to tackling problems such as describing a microprocessor or implementing complex timing checks.
This chapter covers the following topics: n Section 8.1 provides a brief overview of a behavioral model to provide a context for understanding the behavioral constructs detailed in this chapter. n Section 8.2 discusses the two statements used to describe procedures (always and initial). n Section 8.3 discusses procedural assignment statements. n Section 8.4 describes conditional statements (if and if-else). n Section 8.5 describes multi-way decision statements (if-else-if and case). n Section 8.6 describes loop statements (forever, repeat, while, and for). n Section 8.7 discusses procedural timing controls. n Section 8.8 describes sequential block statements (begin-end) and parallel block statements (fork-join). n Section 8.9 contains two complete behavioral model examples that illustrate the behavioral constructs introduced in this chapter.
Behavioral Model Overview
June 1995 Behavioral Modeling 8-
Verilog behavioral models contain procedural statements that control the simulation and manipulate variables of the data types previously described. These statements are contained within procedures. Each procedure has an activity flow associated with it.
The activity starts at the control constructs initial and always. Each initial statement and each always statement starts a separate activity flow. All of the activity flows are concurrent, allowing you to model the inherent concurrence of hardware.
Example 8-1 is a complete Verilog behavioral model.
Example 8-1: Example of a behavioral model
During simulation of this model, all of the flows defined by the initial and always statements start together at simulation time zero. The initial statements execute once, and the always statements execute repetitively.
module behave; reg [1:0]a,b; initial begin a = ’b1; b = ’b0; end always begin #50 a = ~a; end always begin #100 b = ~b; end endmodule
Structured Procedures
June 1995 Behavioral Modeling 8-
All procedures in Verilog are specified within one of the following four statements: n always statement n initial statement n task n function
Tasks and functions are procedures that are enabled from one or more places in other procedures. Tasks and functions are covered in detail in Chapter 9, Tasks and Functions.
The initial and always statements are enabled at the beginning of simulation. The initial statement executes only once and its activity dies when the statement has finished. The always statement executes repeatedly. Its activity dies only when the simulation is terminated. There is no limit to the number of initial and always blocks that can be defined in a module.
The always statement repeats continuously throughout the whole simulation run. Syntax 8-1 shows the syntax for the always statement.
Syntax 8-1: Syntax for always statement
The always statement, because of its looping nature, is only useful when used in conjunction with some form of timing control. If an always statement provides no means for time to advance, the always statement creates a simulation deadlock condition. The following code, for example, creates an infinite zero-delay loop: always areg = ~areg;
always Statement
<always_statement> ::= always
Structured Procedures
June 1995 Behavioral Modeling 8-
Providing a timing control to this code creates a potentially useful description—as in the following example: always #half_period areg = ~areg;
The initial statement is similar to the always statement, except that it is executed only once. The syntax for the initial statement is as follows:
Syntax 8-2: Syntax for initial statement
Example 8-2 illustrates use of the initial statement for initialization of variables at the start of simulation.
Example 8-2: Use of initial statement
Another typical usage of the initial statement is specification of waveform descriptions that execute once to provide stimulus to the main part of the circuit being simulated. Example 8-3 illustrates this usage.
initial Statement
<initial_statement> ::= initial
initial begin areg = 0; // initialize a register for (index = 0; index < size; index = index + 1) memory[index] = 0; //initialize a memory word end
Procedural Assignments
June 1995 Behavioral Modeling 8-
As described in Chapter 5, Assignments , procedural assignments are for updating reg, integer, time, and memory variables.
There is a significant difference between procedural assignments and continuous assignments, as described below: n Continuous assignments drive net variables and are evaluated and updated whenever an input operand changes value. n Procedural assignments update the value of register variables under the control of the procedural flow constructs that surround them.
The right-hand side of a procedural assignment can be any expression that evaluates to a value. However, part-selects on the right-hand side must have constant indices. The left-hand side indicates the variable that receives the assignment from the right-hand side. The left-hand side of a procedural assignment can take one of the following forms: n register, integer, real, or time variable: An assignment to the name reference of one of these data types. n bit-select of a register, integer, real, or time variable: An assignment to a single bit that leaves the other bits untouched. n part-select of a register, integer, real, or time variable: A part-select of two or more contiguous bits that leaves the rest of the bits untouched. For the part-select form, only constant expressions are legal. n memory element: A single word of a memory. Note that bit-selects and part-selects are illegal on memory element references. n concatenation of any of the above: A concatenation of any of the previous four forms can be specified, which effectively partitions the result of the right-hand side expression and assigns the partition parts, in order, to the various parts of the concatenation.
Note: Assignment to a register differs from assignment to a real, time, or integer variable when the right-hand side evaluates to fewer bits than the left-hand side. Assignment to a register does not sign-extend. Registers are unsigned; if you assign a register to an integer, real, or time variable, the variable will not sign-extend.
Procedural Assignments
June 1995 Behavioral Modeling 8-
The Verilog HDL contains two types of procedural assignment statements: n blocking procedural assignment statements n non-blocking procedural assignment statements
Blocking and non-blocking procedural assignment statements specify different procedural flow in sequential blocks.
A blocking procedural assignment statement must be executed before the execution of the statements that follow it in a sequential block (see Section 8.8.1 on page 8-39). A blocking procedural assignment statement does not prevent the execution of statements that follow it in a parallel block (see Section 8.8.2 on page 8-41).
Syntax:
The syntax for a blocking procedural assignment is as follows:
Where lvalue is a data type that is valid for a procedural assignment statement, = is the assignment operator, and timing_control is the optional intra-assignment delay. The timing_control delay can be either a delay control (for example, #6) or an event control (for example, @(posedge clk)). The expression is the right-hand side value the simulator assigns to the left-hand side.
Example 8-4 shows examples of blocking procedural assignments.
Example 8-4: Examples of blocking procedural assignments
Blocking Procedural Assignments
rega = 0; rega[3] = 1; // a bit-select rega[3:5] = 7; // a part-select mema[address] = 8’hff; // assignment to a memory // element {carry, acc} = rega + regb; // a concatenation
Procedural Assignments
June 1995 Behavioral Modeling 8-
Example 8-5: How the simulator evaluates non-blocking procedural assignments
At the end of the time step means that the non-blocking assignments are the last assignments executed in a time step—with one exception. Non-blocking assignment events can create blocking assignment events. The simulator processes these blocking assignment events after the scheduled non-blocking events.
Unlike a regular event or delay control, the non-blocking assignment does not block the procedural flow. The non-blocking assignment evaluates and schedules the assignment, but does not block the execution of subsequent statements in a begin-end block, as shown in Example 8-6.
module evaluates2(out);
output out; reg a, b, c;
initial begin a = 0; b = 1; c = 0; end
always c = #5 ~c;
always @(posedge c) begin a <= b; b <= a; end endmodule
The simulator evaluates the right-hand side of the non-blocking assignments and schedules the assignments of the new values at posedge c.
Step 1:
a = 0
b = 1
Step 2: At posedge c, the simulator updates the left-hand side of each non-blocking assignment statement.
non-blocking assignment scheduled changes at time 5
a = 1
b = 0
assignment values are:
evaluates, schedules, and executes in two steps
Procedural Assignments
June 1995 Behavioral Modeling 8-
Example 8-6: Non-blocking assignments do not block execution of sequential statements
Note: As shown in Example 8-7, the simulator evaluates and schedules assignments for the end of the current time step and can perform swapping operations with non-blocking procedural assignments.
//non_block1.v module non_block1(out,); //input output out; reg a, b, c, d, e, f;
//blocking assignments initial begin a = #10 1; b = #2 0; c = #4 1; end //non-blocking assignments initial begin d <= #10 1; e <= #2 0; f <= #4 1; end
initial begin $monitor ($time, ,"a = %b b = %b c = %b d = %b e = %b f = %b", a,b, c, d,e, f); #100 $finish; end endmodule
The simulator assigns 1 to register a at simulation time 10 , assigns 0 to register b at simulation time 12 , and assigns 1 to register c at simulation time 16.
scheduled changes at time 2
e = 0
f = 1
d = 1
non-blocking assignment lists
scheduled changes at time 4
scheduled changes at time 10
The simulator assigns 1 to register d at simulation time 10 , assigns 0 to register e at simulation time 2 , and assigns 1 to register f at simulation time 4.
Procedural Assignments
June 1995 Behavioral Modeling 8-
If the simulator executes two procedural blocks concurrently, and these procedural blocks contain non-blocking assignment operators, the final value of the register is indeterminate. For example, in Example 8-9 the value of register a is indeterminate.
Example 8-9: Processing two procedural assignments concurrently
When multiple non-blocking assignments with timing controls are made to the same register, the assignments can be made without cancelling previous non-blocking assignments. In Example 8-10, the simulator evaluates the value of i[0] to r1 and schedules the assignments to occur after each time delay.
module multiple3(out); output out; reg a;
initial a <= #4 0; initial a <= #4 1; endmodule
a = 0 a = 1
non-blocking assignment current time list
a =???
assigned value is:
The register’s assigned value is indeterminate.
Procedural Assignments
June 1995 Behavioral Modeling 8-
Example 8-10: Multiple non-blocking assignments with timing controls
For each time slot during simulation, blocking and non-blocking procedural assignments are processed in the following way:
r1 = 0
r1 = 0
r1 = 1
r1 = 0
r1 = 1
r1 = 1
module multiple; reg r1; reg [2:0] i;
initial begin // starts at time 0 doesn’t hold the block for (i = 0; i <= 5; i = i+1) r1 <= # (i*10) i[0]; end endmodule
scheduled changes at time 50
scheduled changes at time 40
scheduled changes at time 30
scheduled changes at time 20
scheduled changes at time
scheduled changes at time
r
0 10 20 30 40 50
Make the assignments to r1 without cancelling previous non-blocking assignments.
How the Simulator Processes Blocking and Non-Blocking Procedural Assignments
Conditional Statement
June 1995 Behavioral Modeling 8-
Because the else part of an if-else is optional, there can be confusion when an else is omitted from a nested if sequence. This is resolved by always associating the else with the closest previous if that lacks an else. In Example 8-11, the else goes with the inner if, as we have shown by indentation.
Example 8-11: Association of else in nested if
If that association is not what you want, use a begin-end block statement to force the proper association, as shown in Example 8-12.
Example 8-12: Forcing correct association of else with if
Begin-end blocks left out inadvertently can change the logic behavior being expressed, as shown in Example 8-13.
Example 8-13: Erroneous association of else with if
if (index > 0) if (rega > regb) result = rega; else // else applies to preceding if result = regb;
if (index > 0) begin if (rega > regb) result = rega; end else result = regb;
if (index > 0) for (scani = 0; scani < index; scani = scani + 1) if (memory[scani] > 0) begin $display("..."); memory[scani] = 0; end else /* WRONG */ $display("error - index is zero");
Conditional Statement
June 1995 Behavioral Modeling 8-
The indentation in Example 8-13 shows unequivocally what you want, but the compiler does not get the message and associates the else with the inner if. This kind of bug can be very hard to find. (One way to find this kind of bug is to use the $list system task, which indents according to the logic of the description).
Notice that in Example 8-14, there is a semicolon after result = rega. This is because a
Example 8-14: Use of semicolon in if statement
For Verilog-XL to behave predictably in interactive mode, each conditional statement must conform to one or both of the following rules: n The conditional statement must be in a sequential (begin-end) procedural block or a parallel (fork-join) procedural block. n The conditional statement must include an else statement.
if (rega > regb) result = rega; else result = regb;
Multi-Way Decision Statements
June 1995 Behavioral Modeling 8-
The module fragment in Example 8-15 uses the if-else statement to test the variable index to decide whether one of three modify_segn registers must be added to the memory address, and which increment is to be added to the index register. The first ten lines declare the registers and parameters.
Example 8-15: Use of if-else-if construct
Example
// Declare registers and parameters reg [31:0] instruction, segment_area[255:0]; reg [7:0] index; reg [5:0] modify_seg1, modify_seg2, modify_seg3; parameter segment1 = 0, inc_seg1 = 1, segment2 = 20, inc_seg2 = 2, segment3 = 64, inc_seg3 = 4, data = 128; // Test the index variable if (index < segment2) begin instruction = segment_area [index + modify_seg1]; index = index + inc_seg1; end else if (index < segment3) begin instruction = segment_area [index + modify_seg2]; index = index + inc_seg2; end else if (index < data) begin instruction = segment_area [index + modify_seg3]; index = index + inc_seg3; end else instruction = segment_area [index];
Multi-Way Decision Statements
June 1995 Behavioral Modeling 8-
The case statement is a special multi-way decision statement that tests whether an expression matches one of several other expressions, and branches accordingly. For example, the case statement is useful for describing the decoding of a microprocessor instruction. The syntax of the case statement is shown in Syntax 8-5.
Syntax 8-5: Syntax for case statement
The default statement is optional. Use of multiple default statements in one case statement is illegal syntax.
A simple example of the case statement is the decoding of register rega to produce a value for result as shown in Example 8-16.
case Statement