UNIT-III BEHAVIORAL MODELING

INTRODUCTION

            Design descriptions at data flow level and gate level are close to the circuit. At every stage of the design description process, one can relate the modules and the instantiations with the corresponding logic or sequential blocks and their interconnections. The approach is practical and effective as long as the gate count remains within a few hundred. An increase in gate count may still be accommodated, if it is due to an increase in vector size -for example, when a system designed and tested at the 8-bit level is being scaled up to a 16- or 32-bit level. But with many of the VLSI’s of today, one has to work at a different dimension – the circuit can have a million gates. The increase in vector size may still be accommodated at the data flow level (e.g., 32- or 64-bit systems), since it calls only for scaling of a smaller design. But increase in terms of functional complexity makes the approach almost intractable for many designs.
            Behavioral level modeling constitutes design description at an abstract level. One can visualize the circuit in terms of its key modular functions and their behavior; it can be described at a functional level itself instead of getting bogged down with implementation details. The description is carried out essentially with constructs similar to those in “C” language; the design itself is similar to programming in “C”, For example, one can describe an FFT or a digital filter routine in terms of these constructs. The design can be simulated, debugged, and finalized. This completes the system level structure for the design. Subsequently, one can expand the design by describing the modules in terms of components
closer to the data flow and gate level models. One can simulate and debug each such component module, check it for its functionality, integrate it with the main design and test conformity. Constructs for such layered expansion of design are available in behavioral modeling. Proceeding with the layered expansion of design, one can have the final design description at the RTL level itself. However, we may add here that such a top-down activity is more in the realm of design.
            The constructs available in behavioral modeling aim at the system level description. Here direct description of the design is not a primary consideration in the Verilog standard. Rather, flexibility and versatility in describing the design are in focus. One should be able to describe the design and simulate it for its functionality. Hence the constructs aim essentially at these two aspects of the design. Synthesis tools available from different vendors can synthesize most of the constructs at the data flow as well as the gate levels, but not all constructs or combinations possible at the behavioral level can be synthesized. The extent to which the constructs at the behavioral level are accommodated in synthesis varies with vendors. The synthesized circuit need not guarantee optimum or near- optimum realization either. These limitations are in line with the basic purpose of behavioral level modeling mentioned above – that is, to complete an error or bug- free description and identify the
functional modules required. Their synthesis is more often done following a more detailed design description at the RTL level.

OPERATIONS AND ASSIGNMENTS

The design description at the behavioral level is done through a sequence of
assignments. These are called ‘procedural assignments’ – in contrast to the continuous
assignments at the data flow level.
The procedure assignment is characterized by the following:
 The assignment is done through the “=” symbol (or the “<=” symbol) as was the case
with the continuous assignment earlier.
 An operation is carried out and the result assigned through the “=” operator to an
operand specified on the left side of the “=” sign – for example,
N= ~N;
Here the content of reg N is complemented and assigned to the reg N itself. The
assignment is essentially an updating activity.
 The operation on the right can involve operands and operators. The operands can be
of different types – logical variables, numbers – real or integer and so on.
 The operands on the right side can be of the net or variable type. They can be scalars
or vectors.
 It is necessary to maintain consistency of the operands in the operation expression –
e.g.,
N= m | l;
Here m and l have to be same types of quantities – specifically a reg, integer, time,
real, realtime, or memory type of data – declared in advance.
 The operand to the left of the “=” operator has to be of the variable (e.g., reg) type. It
has to be specifically declared accordingly. It can be a scalar, a vector, a part vector,
or a concatenated vector.
 Procedural assignments are very much like sequential statements in C. Normally they
are carried out one at a time sequentially. As soon as a specified operation on the
right is carried out, the result is assigned to the quantity on the left – for example
N = m +l;
N1=N* N;
 The above form a set of two procedures placed within an always block. Generally
they are carried out sequentially in the order specified; that is, first m and l are added
and the result assigned to N. Then the square of N is assigned to N1.
 The sequential nature of the assignments requires the operands on the left of the
assignment to be of reg (variable) type. The basic sequential nature of assignments
here is in direct contrast to the concurrent nature of assignments at the data flow level.

FUNCTIONAL BIFURCATION

Design description at the behavioral level is done in terms of procedures of two types;
one involves functional description and interlinks of functional units. It is carried out through
a series of blocks under an “always” banner. The second concerns simulation – its starting
point, steering the simulation flow, observing the process variables, and stopping of the
simulation process; all these can be carried out under the “always” banner, an “initial”
banner, or their combinations.
However, each always and each initial block initiates an activity flow during
simulation. In general, the activity with all such blocks starts at the simulation time and
flows concurrently during the whole simulation process. The concurrent flow of activity with
all processes is characteristic of any behavioral level module. A procedure-block of either
type – initial or always – can have a structure shown in Fig.101.

Pending : Fig. 101 Structure of a typical procedural block

A block starts with the declaration of the type of block – that is, initial or always. It
may be followed by the definition of a triggering activity and then the body of the block. The
body may be a single procedural assignment or a group of procedural assignments. In the
latter case the block appears within a “begin – end” or similar blocks. The initial and
always blocks have distinct characteristics.

begin — end Construct

If a procedural block has only one assignment to be carried out, it can be specified as
below:
initial #2 a=0;
The above statement assigns the value 0 to variable a at the simulation time of 2 ns. It is
possibly the simplest initial block. More often more than one procedural assignment is to be
carried out in an initial block. All such assignments are grouped together between “begin”
and “end” declarations. Functionally, the construct is similar to the begin end construct in
Pascal or the { } construct in C language. The following are to be noted here:
• Every begin declaration must have its associated end declaration.
• begin – end constructs can be nested as many times as desired.
• For clarity in description and to avoid mistakes, nested begin – end blocks are separated
suitably as shown in Fig.102.

Pending : Fig.102 Nesting of begin – end Blocks

Name of the Block

Any block can be assigned a name, but it is not mandatory. Only the blocks which are
to be identified and referred by the simulator need be named. Needless to say the names
assigned to different blocks have to be different. Names chosen should conform to the rules
for the selection of names to variables. Assigning names to blocks serves different purposes:
• Registers declared within a block are local to it and are not available outside. However,
during simulation they can be accessed for simulation, etc., by proper dereferencing.
• Named blocks can be disabled selectively when desired.

Local Variables

Variables used exclusively within a block can be declared within it. Such a variable
need not be declared outside, in the module encompassing the block. Such local declarations
conserve memory and offer other benefits too. Regs declared and used within a block are
static by nature. They retain their values at the time of leaving the block. The values are
modified only at the next entry to the block

INITIAL CONSTRUCT

A set of procedural assignments within an initial construct are executed only once –
and, that too, at the times specified for the respective assignments.

Pending : Fig.103 Typical initial Block

Consider the initial process shown in Fig.103. It is characterized by the following:
• In any assignment statement the left-hand side has to be a storage type of element. It can
be a reg, integer, or real type of variable. The right-hand side can be a storage type of
variable or a net.
• The context decides whether the assignment is of a continuous type or procedural type. In
the latter case it is present within an always or an initial construct.

All the procedural assignments are executed sequentially – in the same order as they
appear in the design description. The waveforms of a and b conforming to the
assignments in the block are shown in Fig.104.

Pending : Fig.104 Output waveforms for the given initial block

• Initially (at time t = 0 ns), a and b are set equal to zero. At time 2 ns a is made equal to 1.
After 3 more nanoseconds – that is, at the 5th ns — b is made equal to 1.
• After one more ns – that is, at the 6th ns – a is made equal to 0.
• $stop is a system task. 100 ns later – that is, at the 106th ns – the simulation comes to an
end.
Integer values have been used here to decide time delay values. In a more general
case the delay value can be a constant expression. It is evaluated and decided dynamically as
the simulation proceeds.
The initial block above does three controlling activities during the simulation run.
 Initialize the selected set of reg’s at the start.
 Change values of reg’s at predetermined instances of time. These form the inputs to the
module under test and test it for a desired test sequence.
 Stop simulation at the specified time.
Specific system tasks available in Verilog can be used to tabulate the values of
selected variables. Providing such output display in a desired or preferred format is the
activity of the simulation run. Two system tasks are useful here – $display & $monitor.
By way of illustration consider the simulation routine in Fig.105. It incorporates the
block Fig.103 and two system tasks. The result of the simulation is shown in Fig.106.

Pending : Fig. 105 Typical module with an initial block

Pending : Fig. 106 Output for the test bench

The $display task is a one-time activity. It is executed when encountered. At that
instant in simulation the values of a and b are zero and the same are displayed. In contrast,
Smonitor is a repeated activity. It need be present only once in a simulation routine – all the
specified variables will be monitored. If multiple Smonitor tasks are present in the routine,
only the last one will be active. All others will be ignored. In contrast, the $display task may
appear any number of times in a module. It is executed every time it is encountered.
Simulators have the facility to observe the waveforms and changes in the magnitudes
of different variables with simulation time. The necessary facility is provided with the help
of user-friendly menus and icons. Waveforms of a and b obtained with the test bench of
Fig.105 are shown in Fig.107; they can be seen to be consistent with their values shown in
Fig.106.

Pending : Fig. 107 Output waveforms

Multiple initial Blocks

A module can have as many initial blocks as desired. All of them are activated at the
start of simulation. The time delays specified in one initial block are exclusive of those in
any other block. Consider the module in Fig.108 which is a modified version of that in
Fig.105. It has four initial blocks. The Smonitor task is declared separately. The simulated
results are shown in Fig.109.

Pending : Fig. 108 A Typical module with multiple initial blocks

Pending : Fig. 109 Output for multiple initial blocks

Observations:
 All changes in a are brought about in one initial block.
 Changes to b are specified in two blocks, and both these blocks are executed
concurrently.
 The progress of simulation time in different blocks is concurrent. However, those in
one block are sequential. Changes in b are consistent with this.
 The $stop task is in an independent initial block. Hence simulation is terminated at
100 ns.
 More than one activity may be scheduled for execution at one time instant. Those in
one initial block are executed in the same order as they appear – that is, sequentially.
Thus, the two events a = 1’b0; b = 1’b0;
are executed in the same sequential order – that is, b is set to 0 after a is set to 0,
although both the activities are scheduled for execution at the same time.
 At 2 ns a changes to 1 and b changes to 0. These two activities are to be done
concurrently. They are in different initial blocks. The order of their execution
depends upon the implementation. This does not cause any anomaly in the present
case. But it can be a potential source of problem in more involved designs and their
simulation.

ALWAYS CONSTRUCT

The always process signifies activities to be executed on an “always basis.” It’s
essential characteristics are:
 Any behavioral level design description is done using an always block.
 The process has to be flagged off by an event or a change in a net or a reg. Otherwise
it ends in a stalemate.
 The process can have one assignment statement or multiple assignment statements. In
the latter case all the assignments are grouped together within a “begin – end” construct.
 Normally the statements are executed sequentially in the order they appear. 

Event Control

The always block is executed repeatedly and endlessly. It is necessary to specify a
condition or a set of conditions, which will steer the system to the execution of the block.
Alternately such a flagging-off can be done by specifying an event preceded by the symbol
“0”. The event can be a change in the variable specified in either direction or a change in a
specified direction. For example,
 @(negedge elk) :
executes the following block at the negative edge of the reg (variable) elk.
 @(posedge elk) :
executes the following block at the positive edge of the reg (variable) elk.
 @clk:
executes the following block at both the edges of elk.
The event can be a combination as well.
 @(prt or clr) :
With the above event the block is executed whenever either of the variables prt or clr
undergoes a change.
 @(posedge clk1 or negedge clk2) :
With the above event the block is executed in two cases – whenever the clock clkl
changes from 0 to 1 state or the clock clk2 changes from 1 to 0. One can specify more
elaborate events by OR’ing individual ones. The following are to be noted:
 The events can be changes in reg, integer, real or a signal on a net. These should be
declared beforehand.
 No algebra or logic operation is permitted as an event. The OR’ing signifies “execute the
block if any one of the events takes place.”
 The edge transition on each event is to be specified separately
 Note the difference between the following:
 (posedge clk1 or clk2): means “execute the block following if clk1 goes to 1 state
or clk2 changes state (whether 0 to 1 or 1 to 0).”
 (posedge clk1 or posedge clk2): means “execute the block following if clk1 goes
to 1 state or clk2 goes to 1 state.”
 The positive transition for a reg type single bit variable is a change from 0 tol. For a logic variable it is a transition from false to true.
 The “posedge” transition for a signal on a net can be of three different types:
 0 to 1
 0 to x or z
 x or z to 1
 The “negedge” transition for a signal on a net can be of three different types :-
 1 to 0
 1 to x or z
 x or z to 0
 If the event specified is in terms of a multibit reg, only its least significant bit is
considered for the transition. Changes in the other bits are ignored.
 The event-based flagging-off of a block is applicable only to the always block.
 According to the recent version of the LRM, the comma operator (,) plays the same role
as the keyword or. The two can be used interchangeably or in a mixed form. Thus the
following are identical:
@ (a or b or C)
@ (a or b, C)
@ (a, b, c)
@ (a, b or c) 

EXAMPLES

Example 17 A Versatile Counter
We consider a versatile up-down counter module with the following facilities:
 Clear input If it goes high, the counter is cleared and reset to zero.
 U/D input If it goes high, the counter counts up; if it goes down, the
counter counts down.
 The counter counts at the negative edge of the clock.
The counter counts up or down between 0 and N where N is any 4-bit hex number.
The above counter design specifications are implemented in stages. The module in Fig.110 is
an up counter which counts up repeatedly from 0 to a preset number N. A test-bench for the
counter is also shown in the figure. N is an input to the module. The count advances at every
negative edge of the clock. When the count reaches the value N, the count value a is reset to 0. The simulation results are shown as waveforms in Fig.111.
The periodic clock waveform, the incrementing of a at every negative edge of the
clock and counting of a from 0 to the set value of N can be seen from the figure. The
synthesized circuit of the counter is shown in Fig.112. It has a versatile counter block and a
comparator. The comparator compares the value of a with the set value of N and resets the
counter when the two are equal. 

Pending : Fig.110 An UP Counter Module

Pending : Fig.111 Simulation waveforms

Pending : Fig.112 Synthesized Circuit for UP Counter

Pending : Fig.113 DOWN Counter Module

The module of Fig.113 is a down counter. The count a decrements at the negative
edge of the clock – clk. The counter counts down from N to zero. As soon as the count
reaches the value 0, it is set back to N. The simulation results are shown tabulated in Fig.114
and as waveforms in Fig.115; these can be seen to be consistent with the design module. The
synthesized circuit is shown in Fig.116. The basic blocks – namely versatile counter,
comparator and buffer for the clock – are the same as those for the up counter of Fig.112. The
comparator output loads the value of N back into the counter every time a reaches the set
value of N

Pending : Fig. 114 Results for DOWN Counter

Pending : Fig.115 Simulation Results

Pending : Fig.116 Synthesized Circuit for DOWN Counter

The up and down modes of counting have been combined in the up down counter of
Fig.117. A test bench is also shown in the figure. The test results are tabulated in Fig.119 and
also shown as waveforms in Fig.118.
Fig.120 shows the synthesized circuit; the counter block remains the same as in the
last two cases; the mode control part of the circuit has been changed to meet the enhanced
needs. The counting can be seen to be changing from “up” to the “down” type, when the
mode control input u_d changes.

Pending : Fig. 117 An UP / DOWN Counter

Pending : Fig. 118 Simulation Results

Pending : Fig. 119 Test Bench Results

Pending : Fig. 120 Synthesized Circuit for UP / DOWN Counter

Example 18 Shift Register
Figure 121 shows an 8-bit shift register module along with a test bench for the same.
The register shifts by one bit to the right if r_l = 1 and to the left by one bit otherwise. The
whole shift register is described in a single line of procedural assignment, namely
always@(negedge clk) a=(r_l)?(a>>1’b1 ):(a<< 1’b1);
The simulation resultsare given in tabular form in Fig.122 and as waveforms in Fig.123.

Pending : Fig.121 8-bit Shift Register

Pending : Fig.122 Test Bench Results

Pending : Fig.123 Simulation Results

Example 19 Clocked Flip-Flop
The module for a clocked flip-flop is shown in Fig.124. A test bench for the flip-flop
is also included in the figure. The test results are shown in Fig.125 and Fig.126 as waveforms
and in tabular form, respectively. The input can be seen to be sensed, latched, and presented
as output at every negative edge of the clock. Otherwise the output remains frozen at the last
latched value. The synthesized circuit of the flip-flop is shown in Fig.127.

Pending : Fig.124 A D Flip-Flop Module

Pending : Fig.125 Simulation Results

Pending : Fig.126 Test Bench Results

ASSIGNMENTS WITH DELAYS

Specific delays can be associated with procedural assignments. The delay refers to the
specific activity it qualifies. A variety of possibilities of specifying delays to assignments
exist.
Consider the assignment always #3 b = a;
simulator encounters this at zero time and posts the entire activity to be done 3 ns
later. Further, by virtue of the always nature of the activity, the assignment is scheduled to be
repeated every 3 ns, irrespective of whether a changes in the meantime. Values of a at the
3rd, 6th, 9th, etc., ns are sampled and assigned to b. Fig.127 shows the waveforms of a and b
with the above assignment and execution of the module in Fig.128. Changes in the values of
a lasting less than 3 ns may be ignored. Specifically, in this case, a took the value of 1 during
the interval 4th ns to the 5th ns which is not passed on to b.

Pending : Fig.127 Clock Waveform using always block

Pending : Fig.128 A module to illustrate delayed assignment

Pending : Fig.129 Waveforms of a & b

The module of fig.130 is a modified version of that in Fig.128. The activities within
the always block (of a single statement) are carried out whenever the value of a changes.
The sole activity is that of assigning the value of a to b with a delay of 2 ns – that is, 2
ns after a changes sign. The waveform assigned to a as well as the resulting waveform of b is
shown in Fig.131. If a were to remain invariant, b will have no assignment here.

Pending : Fig.130 A module to illustrate delayed assignments

Pending : Fig.131 Waveforms of a & b

Intra-assignment Delays

An assignment delay of the type discussed above, delays execution of the whole
assignment by the specified time duration. In contrast, the “intra-assignment” delay carries
out the assignment in two parts. An assignment with an intra- assignment has the form
A = # dl expression;
Here the expression is scheduled to be evaluated as soon as it is encountered.
However, the result of the evaluation is assigned to the right-hand side quantity a
after a delay specified by dl. dl can be an integer or a constant expression. Consider the example
in Fig.132 b is assigned the value of a with an intra-assignment delay of 2 ns. The value of a is
sensed at zero ns and assigned to b after 2 ns. Until that time, b retains its old value. Again at
the 2nd ns, a is sensed and b is assigned the new value of a at the 4th ns, and so on. Partial
results of simulation are shown in Table 24. The following points are to be noted here:
• The value of a is sensed at time instants 2, 4, 6, etc.

• Values at other instants of time are not sensed.
• All assignments are carried out with a delay of 2 ns.
• Changes in a which do not last for 2 ns may be ignored.

Pending : Fig.132 A module to illustrate delayed assignment

Pending : Table 24 Simulation Results

Delay Assignments

In all the illustrations above, delay was specified as a number. It may be a variable or
a constant expression. In case it is an expression, it is evaluated and execution delayed by the
number of time steps. If the number evaluates to a negative quantity, the same is interpreted
as a 2’s complement value. In the statement
always #b a = a + 1 ;
a and b are variables. The execution incrementing a is scheduled at b ns. If b changes, the
execution time also changes accordingly. As another example consider the procedural
assignment
always #(b + c) a = a + 1 ;
Here a, b, and c are variables. The algebraic addition of variables b and c is to be done.
The scheduler schedules the incrementing of 3 and reassigning the incremented values
back to 3 with a time delay of (b + c) ns. As an additional example consider the
assignment below with an intra-assignment delay.

always # (a + b) a = # (b + c) a +1;
Here the simulator evaluates (a + b) during simulation. After a lapse of (a + b) ns, execution
of the statement is taken up; (a + 1) is evaluated and assigned as the new value of 3 – but the
assignment is delayed by (b + c) ns.

Zero Delay

A delay of 0 ns does not really cause any delay. However, it ensures that the
assignment following is executed last in the concerned time slot. Often it is used to avoid
indecision in the precedence of execution of assignments.
8. wait CONSTRUCT
The wait construct makes the simulator wait for the specified expression to be true
before proceeding with the following assignment or group of assignments. Its syntax has the
form
wait (alpha) assignmentl;
alpha can be a variable, the value on a net, or an expression involving them. If alpha is an
expression, it is evaluated; if true, assignmentl is carried out. One can also have a group of
assignments within a block in place of assignmentl. The activity is level-sensitive in
nature, in contrast to the edge-sensitive nature of event specified through @. Specifically the
procedural assignment
@ clk a = b;
assigns the value of b to a when elk changes; if the value of b changes when elk is steady,
the value of a remains unaltered. In contrast, with
wait (clk) #2 a = b;
the simulator waits for the clock to be high and then assigns b to a with a delay of 2 ns. The
assignment will be refreshed as long as the elk remains high.
Example 20: A rudimentary serial transmitter module
Fig.133 shows a rudimentary and crude version of a serial receiver module and its test
bench. Simulation results are shown in Fig.134. The module receives serial data on the di
line. The data are synchronized to the clock clk. The sequence of operations carried out by
the module is as follows:
• Wait for recv input to go high.
• Once recv=l, latch the next 4 successive bits of incoming data into respective bit
positions of the do register.• Once the above nibble receipt is accomplished, set acknowledgment flag high.
• If recv continues to remain high, the subsequent serial bits will be loaded into the do
nibble, again and again in groups of 4 bits.
• If at any time recv goes low, the receipt and the serial to parallel conversion will come to
a stop.

Pending : Fig.133 A rudimentary serial transmitter module

Pending : Fig.134 Simulation Results 

MULTIPLE ALWAYS BLOCKS

All the activities within an always block are scheduled for sequential execution. The
activities can be of a combinational nature, a clocked sequential nature, or a combination of
these two. A design description involving such combinations is conventionally called the
‘Register Transfer Level’ description. Basically, any circuit block whose end-to-end operation
can be described as a continuous sequence can be described within an always block. A
typical circuit block conforming to the above description is shown in Fig.135. It has three
activities termed Al, A2, and A3. These three are to be done in that order. Activity A1
accepts x as input and it generates output B and p. p and y form inputs to activity A2.
Similarly activity A2 generates outputs c and q after activity Al is completed. q and z form
outputs of A2. After activity A2 is completed, activity A3 is scheduled. It accepts z and q as
inputs and generates D as output. Here if Al, A2, and A3 are logical activities, the whole
block can be synthesized as a combinational logic unit. If one or more of these are clocked
events, execution may be sequential. The design examples considered so far are broadly of
this category.

Pending ; Fig.135 Sequentially connected always blocks

In a comparatively bigger IC, the activity flow can be more complex. One with an
additional level of complexity is shown in Fig.136. The activities are marked A1-A2-A3 and
B1-B2-B3, These are the two streams in the circuit. It is possible that the intermediate results
of one may affect the flow of the other. Functioning of two timers – dependent on each other
-is a typical example. A processor servicing serial reception and serial transmission
simultaneously is another example. In all these cases, each sequential activity is described in
a separate always block.
A design of the type in Fig.136 can be described with two always blocks. In some
others, three or more always blocks may be called for.

Pending : Fig.136 Sequentially connected always blocks for concurrent execution 

Activities within one always block are normally sequential. If necessary, they can be
made selectively concurrent. But when designs are spread out in two or more always blocks,
they are necessarily concurrent. Thus the blocks P and Q in Fig.136 are concurrent while the
“sub-blocks” within each (namely Al, A2, and A3 within block P and Bl, B2, and B3 within
block Q) are sequential. In short, with behavioral level descriptions, one can organize the
activities to be in concurrent form, in sequential form, or in combinations. In contrast, all
design descriptions involving constructs at gate and data flow levels are necessarily
concurrent.

DESIGNS AT BEHAVIORAL LEVEL

All simple algebraic as well as logical expressions can be described at the behavioral
level. One can also mix them with blocks at the gate level as well as the data flow level to
form composite as well as more involved modules.

Pending : Fig.137 A-O-I gate at behavioral level modeling and its test bench

Pending : Fig.138 Simulation Results

Pending : Fig.139 Synthesized circuit

Alternative methods for A-O-I gate design:

Pending : Fig.140 Alternative 1

Pending : Fig.141 Alternative 2

Pending : Fig.142 Alternative 3

Pending : Fig.143 Alternative 4

BLOCKING AND NONBLOCKING ASSIGNMENTS

All assignment within an initial or an always block considered so far are done through
an equality (“=”) operator. These are executed sequentially – that is, one statement is
executed, and only then the following one is executed. Such assignments block the execution
of the following lot of assignments at any time step. Hence they are called “blocking
assignments”. Further, when such a blocking assignment has time delays associated with it,
the delay is applicable to the following assignment or activity also.
One comes across situations where assignments are to be effected concurrently. A
facility called the “nonblocking assignment” is available for such situations. The symbol
“<=” signifies a non-blocking assignment. The same symbol signifies the “less than or equal
to” operator in the context of an operation. The context decides the role of the symbol. The
main characteristic of a non- blocking assignment is that its execution is concurrent with that
of the following assignment or activity.
Consider the set of nonblocking assignments in Fig.144. All three assignments are
executed concurrently – that is, A, B, and C are assigned the values 00 01 and 11
concurrently and not sequentially. Fig.145 shows the same non-blocking assignments with
time delays. All three assignments are taken up for execution concurrently.

Pending : Fig. 144 Non Blocking Assignments Fig. 145 Non Blocking Assignments with delays

Nonblocking assignments are essentially two-step affairs. For all the non-blocking
assignments in a block, the right-hand sides are evaluated first. Subsequently the specified
assignments are scheduled. Consider the block of assignments in Fig.146. First A is assigned
the binary value 00, and then B is assigned the value 01. These two assignments are
sequential. The subsequent two assignments are concurrent.

The assignment A <= b “reads” the value of B, stores it separately, and then assigns it
to A. The new value of a is 01. The assignment takes the value of A- i.e., 00 – stores it
separately and assigns it to B. Thus the new value of B is 00. After the block is executed, A
has the value 01 while B has the value 00. Contrast this with the set of blocking assignments
in Fig.147. All four assignments here are sequential in nature. The third one, namely
A= B;
assigns the value 01 to a; subsequently the fourth and following assignment
B = A;
assigns the present value of A (i.e., 01) to b; the value of b remains at 01 itself.

Pending : Fig.146 Non Blocking Assignments Fig. 145 Blocking Assignments

Pending : Fig.148 Module with blocking and non blocking assignments

Consider the block of Fig.148. It has three nonblocking assignments. The sequence of
execution of the three assignments is as follows:
 At the positive edge of the clock, values of A, B, and C are read and stored and B &(~C)
are computed.
• A is assigned the stored value of B (=1); this and the activity in (1) above are carried out
concurrently in the same time step.
• At the next negative elk edge, C is assigned the value of B & (~C) evaluated and stored
earlier (=1) — mentioned in (1) above.

• Two nanoseconds after the positive edge of elk (i.e., after the entiy to the block), B is
assigned the value of C stored earlier (=0).
In the segment in Fig.149, two always blocks do assignments concurrently; both of
these are of the blocking variety. The values assigned to A and B are decided by the structure
of the simulator. The block has the potential to create a race condition. In contrast, in the
segment of Fig.150, the two assignments are of the nonblocking type; A is assigned the
previous value of B, while B is assigned the previous value of A. The race condition is
avoided here.

Pending : Fig.149 A set of assignments with potential Fig.150 A set of assignments to avoid
race condition race condition

Although blocking and nonblocking assignment can be mixed in a block, many
synthesis tools may not support such combinations.

Nonblocking Assignments and Delays

Delays – of the assignment type and the intra-assignment type – can be associated with
nonblocking assignments also. The principle of their operation is similar to that with
blocking assignments. The delay values can be constant expressions. Blocking and
nonblocking assignments, together with assignment and intra-assignment delays, open up a
variety of possibilities. They can be used individually and in combinations to suit different
situations.
12. THE case STATEMENT
The case statement is an elegant and simple construct for multiple branching in a
module. The keywords case, endcase, and default are associated with the case construct.
Format of the case construct is shown in Fig.151. First expression is evaluated. If the
evaluated value matches refl, statementl is executed; and the simulator exits the block; else
expression is compared with ref2 and in case of a match, Statement2 is executed, and so on.
If none of the refl, ref2, t’/c., matches the value of expression, the default statement is
executed.

Pending : Fig. 151 Syntax of case statement

Observations:
 A statement or a group of statements is executed if and only if there is an exact – bit
by bit – match between the evaluated expression and the specified refl, ref2, etc.
 For any of the matches, one can have a block of statements defined for execution. The
block should appear within the begin-end construct.
 There can be only one default statement or default block. It can appear anywhere in
the case statement.
 One can have multiple signal combination values specified for the same statement for
execution. Commas separate all of them.
Example 20: 4×1 MUX
module mux4_1(a,s,y);
input [3:0] a;
input [1:0] s;
output y;
reg y;
always @ (s)
begin
case (s)
2’b00: y = a[0];
2’b01: y = a[1];
2’b10: y = a[2];
2’b11: y = a[3];
default: y = 1’bz;
endcase
end
endmodule
module mux4_1_test;
reg [3:0] a;
reg [1:0] s;
wire y;
mux4_1(a,s,y);

initial
begin
a = 4’b0000;
s = 2’b00;
end
always
begin
#2 a = 4’b1101;
#2 s = 2’b01;
#2 s = 2’b10;
#2 s = 2’b11;
end
initial $monitor ($time, “a=%b, s=%b, y=%b”,a,s,y);
initial #10 $stop;
endmodule
Simulation Results:
0 a=0000, s=00, y=0
2 a=0010, s=00, y=0
4 a=0010, s=01, y=1
6 a=0010, s=10, y=0
8 a=0010, s=11, y=0
Example 21: ALU
module alu (a,b,m,ci,y,co);
input [3:0] a,b;
input [1:0] m;
input ci;
output [3:0] y;
output co;
reg [3:0] y;
reg co;
always @ (m)
begin
case (m)
2’b00: {co,y} = (a+b+ci);
2’b01: y = ~a;
2’b10: y = a&b;
2’b11: y = a^b;;
default: begin
$display (“No Operation”);
y = 4’bzzzz;
end
endcase
end
endmodule

module alu_test;
reg [3:0] a,b;
reg [1:0] m;
reg ci;
wire [3:0] y;
wire co;
alu (a,b,m,ci,y,co);
initial
begin
a = 4’b1011;
b = 4’b1101;
ci = 1’b0;
m = 2’b00;
end
always
begin
#2 m = 2’b01;
#2 m = 2’b10;
#2 m = 2’b11;
end
initial $monitor ($time, “a=%b, b=%b, ci=%b, m=%b, co=%b, y=%b”,
a,b,ci,m,co,y);
initial #11 $stop;
endmodule
Simulation Results:
0 a=1011, b=1101, ci=0, m=00, co=1, y=1000
2 a=1011, b=1101, ci=0, m=01, co=1, y=0100
4 a=1011, b=1101, ci=0, m=10, co=1, y=1001
6 a=1011, b=1101, ci=0, m=11, co=1, y=0110
No Operation
8 a=1011, b=1101, ci=0, m=1x, co=1, y=zzzz
No Operation
10 a=1011, b=1101, ci=0, m=z0, co=1, y=zzzz

 

Casex and Casez

The case statement executes a multiway branching where every bit of the case
expression contributes to the branching decision. The statement has two variants where some
of the bits of the case expression can be selectively treated as don’t cares – that is, ignored.
Casez allows z to be treated as a don’t care. “?” character also can be used in place of z.
casex treats x or z as a don’t care.

SIMULATION FLOW

Different constructs for design description and simulation have been dealt with so far.
These can be at different levels of abstraction – gate, data flow, or behavioral level. The
constructs to be discussed in the following chapters add to the variety and flexibility. Such
elements in different combinations make up the design and simulation modules in Verilog.
Further, as an HDL, Verilog has to be an inherently parallel processing language. The fact
that all the elements of a digital circuit function and interact continuously conforming to their
interconnections demands parallel processing.
• Simulation is carried out in simulation time. The simulator functions with simulation
time advancing in (equal) discrete steps.
• At every simulation step a number of active events are sequentially carried out.
• The simulator maintains an event queue – called the “Stratified Event Queue” – with an
active segment at its top. The top most event in the active segment of the queue is taken
up for execution next.
• The active event can be of an update type or evaluation type.
The evaluation event can be for evaluation of variables, values on nets, expressions, etc.
Refreshing the queue and rearranging it constitutes the update event.
• Any updating can call for a subsequent evaluation and vice versa.
• Only after all the active events in a time step are executed, the simulation advances to the
next time step.
Completion of the sequence of operations above at any time step signifies the parallel
nature of the HDL.
A number of active events can be present for execution at any simulation time step; all
may vie for “attention”. Amongst these, an event specified at #0 time is scheduled for
execution at the end – that is, before simulation advances to the next time step. The order, in
which the other events are executed, is essentially simulator-dependent

Stratified Event Queue

The events being carried out at any instant give rise to other events – inherent in the
execution process.
All such events can be grouped into the following 5 types:
• Active events
• Inactive events – The inactive events are the events lined up for execution immediately
after the execution of the active events. Events specified with zero delay are all inactive
events.
• Blocking Assignment Events – Operations and processes carried out at previous time
steps with results to be updated at the current time step are of this category.
• Monitor Events – The Monitor events at the current time step – $monitor and $strobe -are to be processed after the processing of the active events, inactive events, and
nonblocking assignment events.
• Future events – Events scheduled to occur at some future simulation time are the future
events.

Pending : Fig. 152 Simulation Flow

if AND if-else CONSTRUCTS

…………….
assignment1;
If (condition) assignment2;
assignment3;
assignment4;
……………..
The if construct checks a specific condition and decides execution based on the
result.. After execution of assignmentl, the condition specified is checked. If it is satisfied,
assignment2 is executed; if not, it is skipped. In either case the execution continues through
assignment3, assignments etc. Execution of assignment2 alone is dependent on the condition.
The rest of the sequence remains.
The flowchart equivalent of the execution is shown in Fig.153. If the number of
assignments associated with the if condition is more than 1, the whole set of them can be
grouped within a begin-end block.

Pending : Fig.153 Flow chart of if statement

The if- else construct is more common and turns out to be more useful than the if
construct taken alone. Fig.154 shows the same in flowchart form. The design description has
two branches; the alternative taken is decided by the condition.
• After the execution of assignmentl, if the condition is satisfied, alternative1 is followed
and assignment2 and assignments are executed. Assignment4 and assignment 5 are
skipped and execution proceeds with assignment6.

• If the condition is not satisfied, assignment2 and assignments are skipped and
assignment4 and assignments are executed. Then execution continues with
assignment6.
…………….
assignment1;
If (condition)
begin
assignment2;
assignment3;
end
else
begin
assignment4;
assignment5;
end
……………..

Pending : Fig. 154 Flow chart of if-else statement

Example 22: 1X4 Demultiplexer
module demux1_4 (a,y,s);
input a;
input [1:0] s;
output [3:0] y;
reg [3:0] y;
always@ (a or s)
begin
if(s=2’b00)
begin
y[0] = a;
y[3:1] = 3’bzzz;
end
else if (s=2’b01)
begin
y[1] = a;
{y[3],y[2],y[0]} = 3’bzzz;
end
else if (s=2’b10)
begin
y[2] = a;
{y[3],y[1],y[0]} = 3’bzzz;
else (s=2’b11)
begin
y[3] = a;
y[2:0] = 3’bzzz;
end
end
endmodule
// Test Bench
module demux1_4_test;
reg a;
reg [1:0] s;
wire [3:0] y;
initial
begin
a=1’b1; s=2’b00; y=4’b0000;
end
always
begin
#2 s=2’b01;
#2 s=2’b10;
#2 s=2’b11;
end
demux1_4 M1 (a,y,s);
initial $monitor ($time, “s = %b, a = %b, y = %b”, s,a,y);
initial #10 $stop;
endmodule

assign-deassign CONSTRUCT

A behavior block is activated by the event at the beginning. A proper operation
demands that all variables with assignments within the block are to be included in the
sensitivity list.
The assign — deassign constructs allow continuous assignments within a behavioral
block. By way of illustration, consider the following simple block:
always@(posedge clk) a = b;
By way of execution, at the positive edge of elk the value of b is assigned to variable a, and a
remains frozen at that value until the next positive edge of elk. Changes in b in the interval
are ignored.
As an alternative, consider the block
always@(posedge clk) assign C = d;
Here at the positive edge of elk, C is assigned the value of d in a continuous manner;
subsequent changes in d are directly reflected as changes in variable C: The assignment here
is akin to a direct (one way) electrical connection to C from d established at the positive edge
of clk.
Again consider an enhanced version of the above block as
always
begin
@(posedge clk) assign C = d;
@(negedge clk) deassign C;
end
The above block signifies two activities:
(i) At the positive edge of clk, C is assigned the value of d in a continuous manner.
(ii) At the following negative edge of clk, the continuous assignment to C is removed;
subsequent changes to d are not passed on to C; it is as though C is electrically
disconnected from d.
The above sequence of twin activities is repeated cyclically. In short, assign allows a
variable or a net change in the sensitivity list to mandate a subsequent continuous assignment
within, deassign terminates the assignment done through the assign-based statement. The
assignment to C in the above two cases is referred to as a “Procedural Continuous
Assignment”

Example 23: D Latch
module dlatch (d,clr,pr,q,en);
input d,clr,pr,en;
output q;
reg q;
always @ (clr or pr or en or d)
begin
if (clr) assign q = 1’b0;
else if (pr) assign q = 1’b1;
else if (en) assign q = d;
else deassign q;
end
endmodule

repeat CONSTRUCT

The repeat construct is used to repeat a specified block a specified number of times.
The typical format is
………………
repeat (a)
begin
assignment1;
asignement2;
……………
end
……………..
The quantity a can be a number or an expression evaluated to a number. As soon as
the repeat statement is encountered, a is evaluated. The following block is executed
“a” times. If “a” evaluates to 0 or x or z, the block is not executed.
Example 24: Design of a Memory
module memory ();
reg [7:0] mem [9:0];
integer i;
reg clk;
always
begin
repeat (10)
begin
@negedge clk
mem[i] = i*4;
i = i+1;
end
repeat (10)

begin
@negedge clk
i = i-1;
$display (“t = %0d, mem[%0d] = %0d”, $time, i, mem[i]);
end
initial
begin
clk = 1’b0;
i=0;
#42 $stop;
end
always #2 clk = ~clk;
endmodule

for LOOP

The for loop in Verilog is quite similar to the for loop in C. The typical format is
………………….
for (assignment1; expression; assignment2)
loop statements;
………………….

Pending : Fig. 155 Flow chart of for loop 

It has four parts; the sequence of execution is as follows:
• Execute assignment1.
• Evaluate expression.
• If the expression evaluates to the true state (1), carry out statement. Go to step 5.
• If expression evaluates to the false state (0), exit the loop.
• Execute assignment2. Go to step 2.

Operation of the loop is shown in Fig.155 in flowchart form. In general, whenever
one has to accommodate alternatives for execution, the if and if-else constructs are preferred.
Whenever a sequence of assignments is to be done repeatedly with an index for termination,
the for construct is preferred.
Example 25: Design of a Memory
module memory ();
reg [7:0] mem [9:0];
integer i;
reg clk;
always
begin
for (i=0; i<10;i=i+1)
begin
@negedge clk
mem[i] = i*4;
end
for (i=0; i<10;i=i+1)
begin
@negedge clk
$display (“t = %0d, mem[%0d] = %0d”, $time, i, mem[i]);
end
initial
begin
clk = 1’b0;
#42 $stop;
end
always #2 clk = ~clk;
endmodule

THE disable CONSTRUCT

There can be situations where one has to break out of a block or loop. The disable
statement terminates a named block or task. Control is transferred to the statement
immediately following the block. Conditional termination of a loop, interrupt servicing, etc.,
are typical contexts for its use. Often the disabling is carried out from within the block itself.
The disable construct is functionally similar to the break in C.
Observations:
 The disable statement has to have a block (or task) identifier tagged to it – in this respect
it differs from “break” in C.
 Once encountered, it terminates execution of the block; the following statements within
the block are not executed.
 Typically it can be used to handle exceptions to regularly assigned activities for example,
Interrupt, Hold, Reset, etc.

while LOOP

The typical format for while loop is
while (expression) statement;
The Boolean expression is evaluated. If it is true, the statement (or block of
statements) is executed and expression evaluated and checked. If the expression evaluates to
false, the loop is terminated and the following statement is taken for execution. If the
expression evaluates to true, execution of statement (block of statements) is repeated. Thus
the loop is terminated and broken only if the expression evaluates to false. The flowchart for
the while loop is shown in Fig.156.

Pending : Fig.156 Flow chart of while loop

Observations:
 Whenever the while construct is used, event or time-based activity flow within the block
has to be ensured.
 With the while construct the expression associated with the keyword while must become
false through the execution of assignments inside the block. Otherwise we end up with an
endless looping within the block, causing a deadlock.
 There may be situations where we have to wait in a loop while an event external to it
changes to trigger an activity. The wait construct is to be used for such situations and not
while. With the wait construct the activity is scheduled and execution continued with the
other activities. With the while construct until the associated loop is not complete, other
activities are not taken up.
Example 26: Design of a Memory
module memory ();
reg [7:0] mem [9:0];
integer i;
reg clk;
always
begin

while (i<10)
begin
@negedge clk
mem[i] = i*4;
i = i+1;
end
while (i<10)
begin
@negedge clk
i = i-1;
$display (“t = %0d, mem[%0d] = %0d”, $time, i, mem[i]);
end
initial
begin
clk = 1’b0;
i = 0;
#42 $stop;
end
always #2 clk = ~clk;
endmodule

forever LOOP

Repeated execution of a block in an endless manner is best done with the forever
loop (compare with repeat where the repetition is for a fixed number of times).
Example 27: Design of a Memory
module memory ();
reg [7:0] mem [9:0];
integer i;
reg clk;
always
begin: mem_write
forever@negedge clk
begin
if (i>=10) disable mem_write;
mem[i] = i*4;
i = i+1;
end
end
always
begin: mem_read
forever@negedge clk
begin
if (i>=20) disable mem_read;
$display (“t = %0d, mem[%0d] = %0d”, $time, i, mem[i]);
i = i+1;

end
end
initial
begin
clk = 1’b0;
i = 0;
#42 $stop;
end
forever #2 clk = ~clk;
endmodule

PARALLEL BLOCKS

All the procedural assignments within a begin-end block are executed sequentially.
The fork-join block is an alternate one where all the assignments are carried out
concurrently (The nonblocking assignments too can be used for the purpose.). One can use a
fork-join block within a begin-end block or vice versa.

Pending : Fig. 157 (a) begin-end block and simulation results (b) fork-join block and simulation results

Pending : Fig.158 (a) fork-join block within begin-end block (b) begin-end block within fork-join block

Force-release CONSTRUCT

When debugging a design with a number of instantiations, one may be stuck with an
unexpected behavior in a localized area. Tracing the paths of individual signals and
debugging the design may prove to be too tedious or difficult. In such cases suspect blocks
may be isolated, tested, and debugged and status quo ante established. The force-release
construct is for such a localized isolation for a limited period. Figure 8.53 shows the use of a
force-release construct in a test bench. The assignment
force a = 1’bO;
forces the variable a to take the value 0.
force b = c&d;
forces the variable b to the value obtained by evaluating the expression c&d. Subsequently a
few assignments are made in the test bench. At a later part of the test bench, a and b are
released that is, their original assignments are restored. The assignments here have specific
characteristics:
force a = 1 ‘bO;
force b = c&d;
assignmentl;

assignment2;
release a;
release b;

Pending : Fig.159 An example circuit to illustrate force-release construct

Observations:
 The force-release construct is similar to the assign-deassign construct. The latter construct
is for conditional assignment in a design description. The force-release construct is for
“short time” assignments in a test-bench. Synthesis tools will not support the forcerelease constructs.
 The force-release construct is equally valid for net-type variables and reg-type variables.
The net-type variables revert to their normal values on release. With reg-type variables
the value forced remains until another assignment to the reg.
 The variable, on which the values are forced during testing, must be properly
dereferenced.
 In the illustration above, each variable was forced one at a time. It was done only to
simplify the illustration sequence and focus attention on the possible use of the construct.
In practice, different variables can be forced together before the special debug sequence.
Their release too can be together.

EVENT

The keyword event allows an abstract event to be declared. The event is not a data
type with any specific values; it is not a variable (reg) or a net. It signifies a change that can
be used as a trigger to communicate between modules or to synchronize events in different
modules. One typical example for event is
……………
event change
……………
always
……………..
…… change
…………….
always @ change
……………..
change has been declared as an event. In the course of execution of an always block,
the event is triggered. The operator signifies the triggering. Subsequently, another activity
can be started in the module by the event change. The always@(change) block activates this.
The event change can be used in other modules also by proper dereferencing; with such
usage an activity in a module can be synchronized to an event in another module.
The event construct is quite useful, especially in the early stages of a design. It can be
used to establish the functionality of a design at the behavioral level; it allows
communication amongst different instantiated modules without associated inputs or outputs.

Pending : Fig. 160 A module to illustrate event construct

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top