VHDL Notes
VHDL Notes
MODULE -4
BEHAVIORAL MODELING
4.1 Objectives
• To Explain the significance of structured procedures always and initial in behavioral modeling.
• To Define blocking and nonblocking procedural assignments.
• To Understand delay-based timing control mechanism in behavioral modeling. Use regular delays,
intra-assignment delays, and zero delays.
• To Describe event-based timing control mechanism in behavioral modeling. Use regular event
control, named event control, and event OR control.
• To Use level-sensitive timing control mechanism in behavioral modeling.
• To Explain conditional statements using if and else.
• To Describe multiway branching, using case, casex, and casez statements.
• To Understand looping statements such as while, for, repeat, and forever.
• To Define sequential and parallel blocks.
There are two structured procedure statements in Verilog: always and initial. These statements are the two most
basic statements in behavioral modeling. All other behavioral statements can appear only inside these structured
procedure statements. Verilog is a concurrent programming language unlike the C programming language,
which is sequential in nature.
Activity flows in Verilog run in parallel rather than in sequence. Each always and initial statement represents a
separate activity flow in Verilog. Each activity flow starts at simulation time 0. The statements always and
initial cannot be nested. The fundamental difference between the two statements is explained in the following
sections
All statements inside an initial statement constitute an initial block. An initial block starts at time 0, executes
exactly once during a simulation, and then does not execute again. If there are multiple initial blocks, each
block starts to execute concurrently at time 0. Each block finishes execution independently of other blocks.
Multiple behavioral statements must be grouped, typically using the keywords begin and end. If there is only
one behavioral statement, grouping is not necessary. This is similar to the begin-end blocks in Pascal
programming language or the { } grouping in the C programming language. Example 4.1 illustrates the use of
the initial statement.
module stimulus;
initial
initial
begin
#25 b = 1'b0;
end
initial
begin
#10 x = 1'b0;
#25 y = 1'b1;
end
initial
128
#50 $finish;
endmodule
In the above example, the three initial statements start to execute in parallel at time 0. If a delay #<delay> is
seen before a statement, the statement is executed <delay> time units after the current simulation time. Thus,
the execution sequence of the statements inside the initial blocks will be as follows.
time statement executed
0 m = 1'b0;
5 a = 1'b1;
10 x = 1'b0;
30 b = 1'b0;
35 y = 1'b1;
50 $finish;
The initial blocks are typically used for initialization, monitoring, waveforms and other processes that must be
executed only once during the entire simulation run. The following subsections discussion how to initialize
values using alternate shorthand syntax. The use of such shorthand syntax has the same effect as an initial block
combined with a variable declaration.
Variables can be initialized when they are declared. Example 4-2 shows such a declaration.
reg clock;
initial clock = 0;
reg clock = 0;
The combined port/data declaration can also be combined with an initialization. Example 4-3 shows such a
declaration.
input [7:0] a, b;
input ci;
--
--
endmodule
ANSI C style port declaration can also be combined with an initialization. Example 4-4 shows such a
declaration.
input [7:0] a, b,
input ci
);
--
--
endmodule
All behavioral statements inside an always statement constitute an always block. The always statement starts at
time 0 and executes the statements in the always block continuously in a looping fashion. This statement is used
to model a block of activity that is repeated continuously in a digital circuit. An example is a clock generator
module that toggles the clock signal every half cycle. In real circuits, the clock generator is active from time 0
to as long as the circuit is powered on. Example 4-5 illustrates one method to model a clock generator in
Verilog.
initial
clock = 1'b0;
always
initial
#1000 $finish;
endmodule
In Example 4-5, the always statement starts at time 0 and executes the statement clock = ~clock every 10 time
units. Notice that the initialization of clock has to be done inside a separate initial statement. If we put the
initialization of clock inside the always block, clock will be initialized every time the always is entered. Also,
the simulation must be halted inside an initial statement. If there is no $stop or $finish statement to halt the
simulation, the clock generator will run forever. C programmers might draw an analogy between the always
block and an infinite loop.
But hardware designers tend to view it as a continuously repeated activity in a digital circuit starting from
power on. The activity is stopped only by power off ($finish) or by an interrupt ($stop).
Procedural assignments update values of reg, integer, real, or time variables. The value placed on a variable will
remain unchanged until another procedural assignment updates the variable with a different value. These are
unlike continuous assignments, Dataflow Modeling, where one assignment statement can cause the value of
the right-hand-side expression to be continuously placed onto the left-hand-side net. The
The left-hand side of a procedural assignment <lvalue> can be one of the following:
The right-hand side can be any expression that evaluates to a value. In behavioral modeling, all operators can be
used in behavioral expressions.
There are two types of procedural assignment statements: blocking and nonblocking.
Blocking assignment statements are executed in the order they are specified in a sequential block. A blocking
assignment will not block execution of statements that follow in a parallel block. The = operator is used to
specify blocking assignments.
reg x, y, z;
integer count;
initial
begin
x = 0; y = 1; z = 1; //Scalar assignments
end
In Example 4-6, the statement y = 1 is executed only after x = 0 is executed. The behavior in a particular block
is sequential in a begin-end block if blocking statements are used, because the statements can execute only in
sequence. The statement count = count + 1 is executed last. The simulation times at which the statements are
executed are as follows:
• Since there is a delay of 15 and 10 in the preceding statements, count = count + 1 will be executed at time = 25
units
Note that for procedural assignments to registers, if the right-hand side has more bits than the register variable,
the right-hand side is truncated to match the width of the register variable. The least significant bits are selected
and the most significant bits are discarded. If the right-hand side has fewer bits, zeros are filled in the most
significant bits of the register variable.
Nonblocking assignments allow scheduling of assignments without blocking execution of the statements that
follow in a sequential block. A <= operator is used to specify nonblocking assignments. Note that this operator
has the same symbol as a relational operator, less_than_equal_to. The operator <= is interpreted as a relational
operator in an expression and as an assignment operator in the context of a nonblocking assignment. To
illustrate the behavior of nonblocking statements and its difference from blocking statements, let us consider
Example 4-7, where we convert some blocking assignments to nonblocking assignments, and observe the
behavior.
reg x, y, z;
integer count;
initial
begin
x = 0; y = 1; z = 1; //Scalar assignments
end
In this example, the statements x = 0 through reg_b = reg_a are executed sequentially at time 0. Then the three
nonblocking assignments are processed at the same simulation time.
2. reg_b[15:13] = {x, y, z} is scheduled to execute after 10 time units (i.e., time = 10)
3. count = count + 1 is scheduled to be executed without any delay (i.e., time = 0) Thus, the simulator schedules
a nonblocking assignment statement to execute and continues to the next statement in the block without waiting
for the nonblocking statement to complete execution. Typically, nonblocking assignment statements are
executed last in the time step in which they are scheduled, that is, after all the blocking assignments in that time
step are executed.
In the example above, we mixed blocking and nonblocking assignments to illustrate their behavior. However, it
is recommended that blocking and nonblocking assignments not be mixed in the same always block.
Having described the behavior of nonblocking assignments, it is important to understand why they are used in
digital design. They are used as a method to model several concurrent data transfers that take place after a
common event. Consider the following example where three concurrent data transfers take place at the positive
edge of clock.
begin
end
At each positive edge of clock, the following sequence takes place for the nonblocking assignments.
1. A read operation is performed on each right-hand-side variable, in1, in2, in3, and reg1, at the positive edge of
clock. The right-hand-side expressions are evaluated, and the results are stored internally in the simulator.
2. The write operations to the left-hand-side variables are scheduled to be executed at the time specified by the
intra-assignment delay in each assignment, that is, schedule "write" to reg1 after 1 time unit, to reg2 at the next
negative edge of clock, and to reg3 after 1 time unit.
3. The write operations are executed at the scheduled time steps. The order in which the write operations are
executed is not important because the internally stored right-hand-side expression values are used to assign to
the left-hand-side values. For example, note that reg3 is assigned the old value of reg1 that was stored after the
read operation, even if the write operation wrote a new value to reg1 before the write operation to reg3 was
executed.
Thus, the final values of reg1, reg2, and reg3 are not dependent on the order in which the assignments are
processed.
To understand the read and write operations further, consider Example 4-8, which is intended to swap the
values of registers a and b at each positive edge of clock, using two concurrent always blocks.
//statements
a = b;
b = a;
135
//statements
a <= b;
b <= a;
In Example 4-8, in Illustration 1, there is a race condition when blocking statements are used. Either a = b
would be executed before b = a, or vice versa, depending on the simulator implementation. Thus, values of
registers a and b will not be swapped. Instead, both registers will get the same value (previous value of a or b),
based on the Verilog simulator implementation.
However, nonblocking statements used in Illustration 2 eliminate the race condition. At the positive edge of
clock, the values of all right-hand-side variables are "read," and the right-hand-side expressions are evaluated
and stored in temporary variables. During the write operation, the values stored in the temporary variables are
Dept.of ECE/ATMECE, Mysuru Page 82
Verilog HDL [15EC53]
assigned to the left-handside variables. Separating the read and write operations ensures that the values of
registers a and b are swapped correctly, regardless of the order in which the write operations are performed.
Example 4-9 shows how nonblocking assignments shown in Illustration 2 could be emulated using blocking
assignments.
begin
//Read operation
temp_a = a;
temp_b = b;
//Write operation
a = temp_b;
b = temp_a;
end
For digital design, use of nonblocking assignments in place of blocking assignments is highly recommended in
places where concurrent data transfers take place after a common event. In such cases, blocking assignments
can potentially cause race conditions because the final result depends on the order in which the assignments are
evaluated. Nonblocking assignments can be used effectively to model concurrent data transfers because the
final result is not dependent on the order in which the assignments are evaluated. Typical applications of
nonblocking assignments include pipeline modeling and modeling of several mutually exclusive data transfers.
On the downside, nonblocking assignments can potentially cause degradation in the simulator performance and
increase in memory usage.
Various behavioral timing control constructs are available in Verilog. In Verilog, if there are no timing control
statements, the simulation time does not advance. Timing controls provide a way to specify the simulation time
at which procedural statements will execute.
There are three methods of timing control: delay-based timing control, event-based timing control, and level-
sensitive timing control.
Delay-based timing control in an expression specifies the time duration between when the statement is
encountered and when it is executed. We used delay-based timing control statements when writing few modules
in the preceding chapters but did not explain them in detail. In this section, we will discuss delay-based timing
control statements. Delays are specified by the symbol #. Syntax for the delay-based timing control statement is
shown below.
delay_value ] ] )
delay_value ::=
unsigned_number
| parameter_identifier
| specparam_identifier
| mintypmax_expression
Delay-based timing control can be specified by a number, identifier, or a mintypmax_expression. There are
three types of delay control for procedural assignments: regular delay control, intra-assignment delay control,
and zero delay control.
Regular delay control is used when a non-zero delay is specified to the left of a procedural assignment. Usage of
regular delay control is shown in Example 4-10.
//define parameters
parameter delta = 2;
reg x, y, z, p, q;
initial
begin
x = 0; // no delay control
// y = 1 by 10 units
units
end
In Example 4-10, the execution of a procedural assignment is delayed by the number specified by the delay
control. For begin-end groups, delay is always relative to time when the statement is encountered. Thus, y =1 is
executed 10 units after it is encountered in the activity flow.
Instead of specifying delay control to the left of the assignment, it is possible to assign a delay to the right of the
assignment operator. Such delay specification alters the flow of activity in a different manner. Example 4-11
shows the contrast between intra-assignment delays and regular delays.
reg x, y, z;
initial
begin
x = 0; z = 0;
end
initial
begin
x = 0; z = 0;
temp_xz = x + z;
//store it in a temporary variable. Even though x and z might change between 0 and 5,
end
Note the difference between intra-assignment delays and regular delays. Regular delays defer the execution of
the entire assignment. Intra-assignment delays compute the righthand- side expression at the current time and
defer the assignment of the computed value to the left-hand-side variable. Intra-assignment delays are like using
regular delays with a temporary variable to store the current value of a right-hand-side expression.
Procedural statements in different always-initial blocks may be evaluated at the same simulation time. The order
of execution of these statements in different always-initial blocks is nondeterministic. Zero delay control is a
method to ensure that a statement is executed last, after all other statements in that simulation time are executed.
This is used to eliminate race conditions. However, if there are multiple zero delay statements, the order
between them is nondeterministic. Example 4-12 illustrates zero delay control.
initial
begin
x = 0;
y = 0;
end
initial
begin
#0 y = 1;
end
An event is the change in the value on a register or a net. Events can be utilized to trigger execution of a
statement or a block of statements. There are four types of event-based timing control: regular event control,
named event control, event OR control, and level sensitive timing control.
The @ symbol is used to specify an event control. Statements can be executed on changes in signal value or at a
positive or negative transition of the signal value. The keyword posedge is used for a positive transition, as
shown in Example 4-13.
// x to 1, z to 1 )
//x to 0, z to 0)
Verilog provides the capability to declare an event and then trigger and recognize the occurrence of that event
(see Example 4-14). The event does not hold any data. A named event is declared by the keyword event. An
event is triggered by the symbol ->. The triggering of the event is recognized by the symbol @.
begin
end
data_pkt[3]};
Event OR Control
Sometimes a transition on any one of multiple signals or events can trigger the execution of a statement or a
block of statements. This is expressed as an OR of events or signals. The list of events or signals expressed as
an OR is also known as a sensitivity list. The keyword or is used to specify multiple triggers, as shown in
Example 4-15.
change
begin
q = 1'b0;
q = d;
end
Sensitivity lists can also be specified using the "," (comma) operator instead of the or operator. Example 4-16
shows how the above example can be rewritten using the comma operator. Comma operators can also be
applied to sensitivity lists that have edge-sensitive triggers.
change
begin
q = 1'b0;
q = d;
end
if(!reset)
q <=0;
else
q <=d;
When the number of input variables to a combination logic block are very large, sensitivity lists can become
very cumbersome to write. Moreover, if an input variable is missed from the sensitivity list, the block will not
behave like a combinational logic block. To solve this problem, Verilog HDL contains two special symbols: @*
and @(*). Both symbols exhibit identical behavior. These special symbols are sensitive to a change on any
signal that may be read by the statement group that follows this symbol
Example 4-17 shows an example of this special symbol for combinational logic sensitivity lists.
IEEE Standard Verilog Hardware Description Language document for details and restrictions on the @* and
@(*) symbols.
always @(a or b or c or d or e or f or g or h or p or m)
begin
end
//sensitivity list.
always @(*)
begin
end
Event control discussed earlier waited for the change of a signal value or the triggering of an event. The symbol
@ provided edge-sensitive control. Verilog also allows level sensitive timing control, that is, the ability to wait
for a certain condition to be true before a statement or a block of statements is executed. The keyword wait is
used for level sensitive constructs.
always
In the above example, the value of count_enable is monitored continuously. If count_enable is 0, the statement
is not entered. If it is logical 1, the statement count = count + 1 is executed after 20 time units. If count_enable
stays at 1, count will be incremented every 20 time units.
Conditional statements are used for making decisions based upon certain conditions. These conditions are used
to decide whether or not a statement should be executed. Keywords if and else are used for conditional
statements. There are three types of conditional statements. Usage of conditional statements is shown below.
if (<expression>) true_statement ;
if (<expression1>) true_statement1 ;
else default_statement ;
The <expression> is evaluated. If it is true (1 or a non-zero value), the true_statement is executed. However, if it
is false (zero) or ambiguous (x), the false_statement is executed. The <expression> can contain any operators.
Each true_statement or false_statement can be a single statement or a block of multiple statements. A block
must be grouped, typically by using keywords begin and end. A single statement need not be grouped.
//Type 1 statements
//Type 2 statements
begin
data_queue = data;
number_queued = number_queued + 1;
end
else
//Type 3 statements
if (alu_control == 0)
y = x + z;
else if(alu_control == 1)
y = x - z;
else if(alu_control == 2)
y = x * z;
else
$display("Invalid ALU control signal");
Conditional Statements, there were many alternatives, from which one was chosen. The nested if-else-if can
become unwieldy if there are too many alternatives. A shortcut to achieve the same result is to use the case
statement.
The keywords case, endcase, and default are used in the case statement..
case (expression)
alternative1: statement1;
alternative2: statement2;
alternative3: statement3;
...
...
default: default_statement;
endcase
Each of statement1, statement2 , default_statement can be a single statement or a block of multiple statements.
A block of multiple statements must be grouped by keywords begin and end. The expression is compared to the
alternatives in the order they are written. For the first alternative that matches, the corresponding statement or
block is executed. If none of the alternatives matches, the default_statement is executed. The default_statement
is optional. Placing of multiple default statements in one case statement is not allowed. The case statements can
be nested. The following Verilog code implements the type 3 conditional statement in Example 4-18.
...
...
case (alu_control)
2'd0 : y = x + z;
2'd1 : y = x - z;
2'd2 : y = x * z;
endcase
The case statement can also act like a many-to-one multiplexer. To understand this, let us model the 4-to-1
multiplexer, using case statements. The I/O ports are unchanged. Notice that an 8-to-1 or 16-to-1 multiplexer
can also be easily implemented by case statements.
output out;
reg out;
endcase
endmodule
The case statement compares 0, 1, x, and z values in the expression and the alternative bit for bit. If the
expression and the alternative are of unequal bit width, they are zero filled to match the bit width of the widest
of the expression and the alternative. In Example 4- 20, we will define a 1-to-4 demultiplexer for which outputs
are completely specified, that is, definitive results are provided even for x and z values on the select signal.
input in;
1'bz; end
1'bz; end
1'bz; end
in; end
begin
end
begin
end
endcase
endmodule
In the demultiplexer shown above, multiple input signal combinations such as 2'bz0, 2'bz1, 2,bzz, 2'b0z, and
2'b1z that cause the same block to be executed are put together with a comma (,) symbol.
There are two variations of the case statement. They are denoted by keywords, casex and casez.
• casez treats all z values in the case alternatives or the case expression as don't cares. All bit positions with z
can also represented by ? in that position.
• casex treats all x and z values in the case item or the case expression as don't cares.
The use of casex and casez allows comparison of only non-x or -z positions in the case expression and the case
alternatives. Example 4-21 illustrates the decoding of state bits in a finite state machine using a casex statement.
The use of casez is similar. Only one bit is considered to determine the next state and the other bits are ignored.
integer state;
4'b1xxx : next_state = 3;
4'bx1xx : next_state = 2;
4'bxx1x : next_state = 1;
4'bxxx1 : next_state = 0;
default : next_state = 0;
endcase
4.7 Loops
There are four types of looping statements in Verilog: while, for, repeat, and forever. The syntax of these loops
is very similar to the syntax of loops in the C programming language. All looping statements can appear only
inside an initial or always block. Loops may contain delay expressions.
The keyword while is used to specify this loop. The while loop executes until the while expression is not true. If
the loop is entered when the while-expression is not true, the loop is not executed at all. Each expression can
contain the operators. Any logical expression can be specified with these operators. If multiple statements are to
be executed in the loop, they must be grouped typically using keywords begin and end. Example 4-22 illustrates
the use of the while loop.
integer count;
initial
begin
count = 0;
begin
count = count + 1;
end
end
variable)
reg continue;
initial
begin
i = 0;
continue = 'TRUE;
148
begin
if (flag[i])
begin
continue = 'FALSE;
end
i = i + 1;
end
end
The keyword for is used to specify this loop. The for loop contains three parts:
• An initial condition
The counter described in Example 4-22 can be coded as a for loop (Example 4-23). The initialization condition
and the incrementing procedural assignment are included in the for loop and do not need to be specified
separately. Thus, the for loop provides a more compact loop structure than the while loop. Note, however, that
the while loop is more general-purpose than the for loop. The for loop cannot be used in place of the while loop
in all situations.
integer count;
initial
for loops can also be used to initialize an array or memory, as shown below.
'define MAX_STATES 32
0:31
integer i;
initial
begin
state[i] = 0;
state[i] = 1;
end
for loops are generally used when there is a fixed beginning and end to the loop. If the loop is simply looping on
a certain condition, it is better to use the while loop.
The keyword repeat is used for this loop. The repeat construct executes the loop a fixed number of times. A
repeat construct cannot be used to loop on a general logical expression. A while loop is used for that purpose. A
repeat construct must contain a number, which can be a constant, a variable or a signal value. However, if the
number is a variable or signal value, it is evaluated only when the loop starts and not during the loop execution.
The counter in Example 4-22 can be expressed with the repeat loop, as shown in
Illustration 1 in Example 4-24. Illustration 2 shows how to model a data buffer that latches data at the positive
edge of clock for the next eight cycles after it receives a data start signal.
integer count;
initial
begin
count = 0;
repeat(128)
begin
count = count + 1;
end
end
parameter cycles = 8;
input data_start;
input clock;
integer i;
150
begin
begin
i = 0;
//cycles
begin
i = i + 1;
end
end
end
endmodule
The keyword forever is used to express this loop. The loop does not contain any expression and executes
forever until the $finish task is encountered. The loop is equivalent to a while loop with an expression that
always evaluates to true, e.g., while (1). A forever loop can be exited by use of the disable statement.
A forever loop is typically used in conjunction with timing control constructs. If timing control constructs are
not used, the Verilog simulator would execute this statement infinitely without advancing simulation time and
the rest of the design would never be executed. Example 4-25 explains the use of the forever statement.
reg clock;
initial
begin
clock = 1'b0;
end
//clock
reg clock;
reg x, y;
initial
Block statements are used to group multiple statements to act together as one. In previous examples, we used
keywords begin and end to group multiple statements. Thus, we used sequential blocks where the statements in
the block execute one after another. In this section we discuss the block types: sequential blocks and parallel
blocks. We also discuss three special features of blocks: named blocks, disabling named blocks, and nested
blocks.
There are two types of blocks: sequential blocks and parallel blocks.
Sequential blocks
The keywords begin and end are used to group statements into sequential blocks.
• The statements in a sequential block are processed in the order they are specified. A statement is executed
only after its preceding statement completes execution (except for nonblocking assignments with intra-
assignment timing control).
• If delay or event control is specified, it is relative to the simulation time when the previous statement in the
block completed execution.
We have used numerous examples of sequential blocks in this book. Two more examples of sequential blocks
are given in Example 4-26. Statements in the sequential block execute in order. In Illustration 1, the final values
are x = 0, y= 1, z = 1, w = 2 at simulation time 0. In Illustration 2, the final values are the same except that the
simulation time is 35 at the end of the block.
reg [1:0] z, w;
initial
begin
x = 1'b0;
y = 1'b1;
z = {x, y};
w = {y, x};
end
//Illustration 2: Sequential blocks with delay.
reg x, y;
reg [1:0] z, w;
initial
begin
end
Parallel blocks
Parallel blocks, specified by keywords fork and join, provide interesting simulation features. Parallel blocks
have the following characteristics:
• Ordering of statements is controlled by the delay or event control assigned to each statement.
• If delay or event control is specified, it is relative to the time the block was entered.
Notice the fundamental difference between sequential and parallel blocks. All statements in a parallel block
start at the time when the block was entered. Thus, the order in which the statements are written in the block is
not important.
Let us consider the sequential block with delay in Example 4-26 and convert it to a parallel block. The
converted Verilog code is shown in Example 4-27. The result of simulation remains the same except that all
statements start in parallel at time 0. Hence, the block finishes at time 20 instead of time 35.
reg x, y;
reg [1:0] z, w;
initial
fork
join
Parallel blocks provide a mechanism to execute statements in parallel. However, it is important to be careful
with parallel blocks because of implicit race conditions that might arise if two statements that affect the same
variable complete at the same time. Shown below is the parallel version of Illustration 1 from Example 4-26.
Race conditions have been deliberately introduced in this example. All statements start at simulation time 0.
The order in which the statements will execute is not known. Variables z and w will get values 1 and 2 if x =
1'b0 and y = 1'b1 execute first. Variables z and w will get values 2'bxx and 2'bxx if x = 1'b0 and y = 1'b1
execute last. Thus, the result of z and w is nondeterministic and dependent on the simulator implementation. In
simulation time, all statements in the fork-join block are executed at once. However, in reality, CPUs running
simulations can execute only one statement at a time. Different simulators execute statements in different order.
Thus, the race condition is a limitation of today's simulators, not of the fork-join block.
reg x, y;
reg [1:0] z, w;
initial
fork
x = 1'b0;
y = 1'b1;
z = {x, y};
w = {y, x};
join
The keyword fork can be viewed as splitting a single flow into independent flows. The keyword join can be
seen as joining the independent flows back into a single flow. Independent flows operate concurrently.
We discuss three special features available with block statements: nested blocks, named blocks, and disabling of
named blocks.
Nested blocks
Blocks can be nested. Sequential and parallel blocks can be mixed, as shown in Example 4-28.
//Nested blocks
initial
begin
x = 1'b0;
154
fork
#5 y = 1'b1;
join
end
Named blocks
• Named blocks are a part of the design hierarchy. Variables in a named block can be accessed by using
hierarchical name referencing.
//Named blocks
module top;
initial
...
...
end
initial
The keyword disable provides a way to terminate the execution of a named block. Disable can be used to get
out of loops, handle error conditions, or control execution of pieces of code, based on a control signal. Disabling
a block causes the execution control to be passed to the statement immediately succeeding the block. For C
programmers, this is very similar to the break statement used to exit a loop.
4.9: Outcomes
After completion of the module the students are able to:
Explain the significance of structured procedures always and initial in behavioral modeling.
Define blocking and nonblocking procedural assignments.
Understand delay-based timing control mechanism in behavioral modeling. Use regular delays, intra-
assignment delays, and zero delays.
Describe event-based timing control mechanism in behavioral modeling. Use regular event control,
named event control, and event OR control.
Use level-sensitive timing control mechanism in behavioral modeling.
Explain conditional statements using if and else.
Describe multiway branching, using case, casex, and casez statements.
Understand looping statements such as while, for, repeat, and forever.
Define sequential and parallel blocks.