Behavioural Modelling & Timing in Verilog: Blocking Assignments
Behavioural Modelling & Timing in Verilog: Blocking Assignments
During simulation of behavioral model, all the flows defined by the ‘always’
and ‘initial’ statements start together at simulation time ‘zero’. The initial
statements are executed once, and the always statements are executed
repetitively. In this model, the register variables a and b are initialized to
binary 1 and 0 respectively at simulation time ‘zero’. The initial statement is
then completed and is not executed again during that simulation run. This
initial statement is containing a begin-end block (also called a sequential
block) of statements. In this begin-end type block, a is initialized first
followed by b.
Blocking Assignments
Syntax
The syntax for a blocking procedural assignment is as follows −
<lvalue> = <timing_control> <expression>
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
Midterm Lecture Week 7
Example
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
Syntax
The syntax for a non-blocking procedural assignment is as follows −
<lvalue> <= <timing_control> <expression>
Where lvalue is a data type that is valid for a procedural assignment
statement, <= is the non-blocking assignment operator, and timing control
is the optional intra-assignment timing control. The timing control delay can
be either a delay control or an event control (for example, @(posedge clk)).
The expression is the right-hand side value the simulator assigns to the left-
hand side. The non-blocking assignment operator is the same operator the
simulator uses for the less-than-orequal relational operator. The simulator
interprets the <= operator to be a relational operator when you use it in an
expression, and interprets the <= operator to be an assignment operator
when you use it in a non-blocking procedural assignment construct.
The simulator evaluates the right-hand side and schedules the assignment of the
new value to take place at a time specified by a procedural timing control. The
simulator evaluates the right-hand side and schedules the assignment of the
new value to take place at a time specified by a procedural timing control.
At the end of the time step, in which the given delay has expired or the
appropriate event has taken place, the simulator executes the assignment by
assigning the value to the left-hand side.
Example
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
Conditions
<statement>
::= if ( <expression> ) <statement_or_null>
Midterm Lecture Week 7
::= <statement>
||= ;
For example, the following two statements express the same logic −
if (expression)
if (expression != 0)
Since, 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.
Example
if (index > 0)
if (rega > regb)
result = rega;
else // else applies to preceding if
result = regb;
If that association is not what you want, use a begin-end block statement
to force the proper association
if (index > 0)
begin
Example
if (<expression>)
<statement>
else if (<expression>)
<statement>
else if (<expression>)
<statement>
else
<statement>
This sequence of if’s (known as an if-else-if construct) is the most general
way of writing a multi-way decision. The expressions are evaluated in
order; if any expression is true, the statement associated with it is
executed, and this terminates the whole chain. Each statement is either a
single statement or a block of statements.
The last else part of the if-else-if construct handles the ‘none of the above’
or default case where none of the other conditions was satisfied. Sometimes
there is no explicit action for the default; in that case, the trailing else can
be omitted or it can be used for error checking to catch an impossible
condition.
Case Statement
The case statement is a special multi-way decision statement that tests
whether an expression matches one of a number of other expressions, and
branches accordingly. The case statement is useful for describing, for
example, the decoding of a microprocessor instruction. The case statement
has the following syntax −
Example
<statement>
::= case ( <expression> ) <case_item>+ endcase
||= casez ( <expression> ) <case_item>+ endcase
||= casex ( <expression> ) <case_item>+ endcase
<case_item>
::= <expression> <,<expression>>* : <statement_or_null>
||= default : <statement_or_null>
||= default <statement_or_null>
Midterm Lecture Week 7
The case expressions are evaluated and compared in the exact order in
which they are given. During the linear search, if one of the case item
expressions matches the expression in parentheses, then the statement
associated with that case item is executed. If all comparisons fail, and the
default item is given, then the default item statement is executed. If the
default statement is not given, and all of the comparisons fail, then none of
the case item statements is executed.
Apart from syntax, the case statement differs from the multi-way if-else-if
construct in two important ways −
The conditional expressions in the if-else-if construct are more general than
comparing one expression with several others, as in the case statement.
The case statement provides a definitive result when there are x and z values in
an expression.
Looping Statements
o Evaluates an expression—if the result is zero, the for loop exits, and if it
is not zero, the for loop executes its associated statement(s) and then
performs step 3
The following are the syntax rules for the looping statements −
Example
<statement>
::= forever <statement>
||=forever
begin
<statement>+
end
<Statement>
::= repeat ( <expression> ) <statement>
||=repeat ( <expression> )
begin
<statement>+
end
<statement>
::= while ( <expression> ) <statement>
||=while ( <expression> )
begin
<statement>+
end
<statement>
begin
<statement>+
end
Delay Controls
Delay Control
The execution of a procedural statement can be delay-controlled by using
the following syntax −
<statement>
::= <delay_control> <statement_or_null>
<delay_control>
::= # <NUMBER>
||= # <identifier>
||= # ( <mintypmax_expression> )
Midterm Lecture Week 7
The next three examples provide an expression following the number sign
(#). Execution of the assignment delays by the amount of simulation time
specified by the value of the expression.
Event Control
The execution of a procedural statement can be synchronized with a value
change on a net or register, or the occurrence of a declared event, by using
the following event control syntax −
Example
<statement>
::= <event_control> <statement_or_null>
<event_control>
::= @ <identifier>
||= @ ( <event_expression> )
<event_expression>
::= <expression>
||= posedge <SCALAR_EVENT_EXPRESSION>
||= negedge <SCALAR_EVENT_EXPRESSION>
||= <event_expression> <or <event_expression>>
*<SCALAR_EVENT_EXPRESSION> is an expression that resolves to a one
bit value.
Value changes on nets and registers can be used as events to trigger the
execution of a statement. This is known as detecting an implicit event.
Verilog syntax also allows you to detect change based on the direction of
the change—that is, toward the value 1 (posedge) or toward the value 0
(negedge). The behaviour of posedge and negedge for unknown expression
values is as follows
Midterm Lecture Week 7
Initial Blocks
The syntax for the initial statement is as follows −
<initial_statement>
::= initial <statement>
The following example illustrates the use of the initial statement for
initialization of variables at the start of simulation.
Initial
Begin
Areg = 0; // initialize a register
For (index = 0; index < size; index = index + 1)
Memory [index] = 0; //initialize a memory
Word
End
Another typical usage of the initial Blocks is specification of waveform
descriptions that execute once to provide stimulus to the main part of the
circuit being simulated.
Midterm Lecture Week 7
Initial
Begin
Inputs = ’b000000;
// initialize at time zero
#10 inputs = ’b011001; // first pattern
#10 inputs = ’b011011; // second pattern
#10 inputs = ’b011000; // third pattern
#10 inputs = ’b001000; // last pattern
End
Always Blocks
The ‘always’ statement repeats continuously throughout the whole
simulation run. The syntax for the always statement is given below
<always_statement>
::= 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;