Understanding Non-Blocking Procedural Assignments in Verilog, Assignments of Humanities

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

Pre 2010

Uploaded on 11/08/2009

koofers-user-79l
koofers-user-79l 🇺🇸

10 documents

1 / 48

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
June 1995 Behavioral Modeling 8-1
Table of Contents Close
Menus User Guide Go Back
Index 1 of 48
8
Behavioral Modeling
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:
Section 8.1 provides a brief overview of a behavioral model to provide
a context for understanding the behavioral constructs detailed in this
chapter.
Section 8.2 discusses the two statements used to describe procedures
(always and initial).
Section 8.3 discusses procedural assignment statements.
Section 8.4 describes conditional statements (if and if-else).
Section 8.5 describes multi-way decision statements (if-else-if
and case).
Section 8.6 describes loop statements (forever,repeat,while, and
for).
Section 8.7 discusses procedural timing controls.
Section 8.8 describes sequential block statements (begin-end) and
parallel block statements (fork-join).
Section 8.9 contains two complete behavioral model examples that
illustrate the behavioral constructs introduced in this chapter.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30

Partial preview of the text

Download Understanding Non-Blocking Procedural Assignments in Verilog and more Assignments Humanities in PDF only on Docsity!

June 1995 Behavioral Modeling 8-

Behavioral Modeling

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-

Behavioral Model Overview

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-

Structured Procedures

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-

Procedural Assignments

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: = <timing_control>

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:

  1. Evaluate the right-hand side of all assignment statements in the current time slot.
  2. Execute all blocking procedural assignments and non-blocking procedural assignments that have no timing controls. At the same time, non-blocking procedural assignments with timing controls are set aside for processing.
  3. Check for procedures that have timing controls and execute if timing control is set for the current time unit.
  4. Advance the simulation clock.

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 follows the if, and a semicolon is an essential part of the syntax of 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

::= case ( ) <case_item>+ endcase ||= casez ( ) <case_item>+ endcase ||= casex ( ) <case_item>+ endcase <case_item> ::= <,>* : <statement_or_null> ||= default : <statement_or_null> ||= default <statement_or_null>