Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
470 views

Verilog HDL - Text Book

Verilog Hdl - Samir Palnitkar

Uploaded by

Lalith Krishnan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
470 views

Verilog HDL - Text Book

Verilog Hdl - Samir Palnitkar

Uploaded by

Lalith Krishnan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 158

Verilog HDL

A guide to Digital Design


and Synthesis
Samir Palnitkar

SunSoft Press
1996

PART 1 BASIC VERILOG TOPICS


1
Overview of Digital Design with Verilog HDL
2
Hierarchical Modeling Concepts
3
Basic Concepts
4
Modules and Ports
5
Gate-Level Modeling
6
Dataflow Modeling
7
Behavioral Modeling
8
Tasks and Functions
9
Useful Modeling Techniques
PART 2 Advance Verilog Topics
10 Timing and Delays
11 Switch- Level Modeling
12 User-Defined Primitives
13 Programming Language Interface
14 Logic Synthesis with Verilog HDL
PART3 APPENDICES
A
Strength Modeling and Advanced Net Definitions
B
List of PLI Rountines
C
List of Keywords, System Tasks, and Compiler Directives
D
Formal Syntax Definition
E
Verilog Tidbits
F
Verilog Examples

1
3
11
27
47
61
85
115
157
169
191
193
213
229
249
275
319
321
327
343
345
363
367

Part 1 Basic Verilog Topics

[j

Overview of Digital Design with Verilog HDL


Evolution of CAD, emergence of HDLs, typical HDL-based design flow, why
Verilog HDL?, trends in HDLs.

LJ

Hierarchical Modeling Concepts


Top-down and bottom-up design methodology, differences between
modules and module instances, parts of a simulation, design block, stimulus
block.

LJ

[j
[j
[j
[j
[J
[J

Basic Concepts
Lexical conventions, data types, system tasks, compiler directives.

Modules and Ports


Module definition, port declaration, connecting ports, hierarchical name
referencing.
Gate-Level Modeling
Modeling using basic Verilog gate primitives, description of and/or and
buf/not type gates, rise, fall and tum-off delays, min, max, and typical
delays.
Dataflow Modeling
Continuous assignments, delay specification, expressions, operators,
operands, operator types.
Behavioral Modeling
Structured procedures, initial and always, blocking and nonblocking
statements, delay control, event control, conditional statements, multiway
branching, loops, sequential and parallel blocks.
Tasks and Functions
Differences between tasks and functions, declaration, invocation.

Useful Modeling Techniques


Procedural continuous assignments, overriding parameters, conditional
compilation and execution, useful system tasks.

Overview of Digital Design

with Verilog HDL

1.1 Evolution of Computer Aided Digital Design


Digital circuit design has evolved rapidly over the last 25 years. The earliest
digital circuits were designed with vacuum tubes and transistors. Integrated
circuits were then invented where logic gates were placed on a single chip. The
first integrated circuit (IC) chips were 55I (Small Scale Integration) chips where the
gate count was very small. As technologies became sophisticated, designers were
able to place circuits with hundreds of gates on a chip. These chips were called
M5I (Medium Scale Integration) chips. With the advent of LSI (Large Scale
Integration), designers could put thousands of gates on a single chip. At this point,
design processes started getting very complicated, and designers felt the need to
automate these processes. Computer Aided Design (CAD)1 techniques began to
evolve. Chip designers began to use circuit and logic simulation techniques to
verify the functionality of building blocks of the order of about 100 transistors.
The circuits were still tested on the breadboard, and the layout was done on
paper or by hand on a graphic computer terminal.
With the advent of VLSI (Very Large Scale Integration) technology, designers could
design single chips with more than 100,000 transistors. Because of the complexity
of these circuits, it was not possible to verify these circuits on a breadboard.
Computer-aided techniques became critical for verification and design of VL5I
digital circuits. Computer programs to do automatic placement and routing of
circuit layouts also became popular. The designers were now building gate-level
digital circuits manually on graphic terminals. They would build small building
blocks and then derive higher-level blocks from them. This process would

1. Technically, the term Computer-Aided Design (CAD) tools refers to back-end tools that perform functions related
to place and route, and layout of the chip. The term Computer-Aided Engineering (CAE) tools refers to tools that
are used for front-end processes such HDL simulation, logic synthesis and timing analysis. However, designers
use the term CAD and CAE interchangeably. For the sake of simplicity, in this book, we will refer to all design
tools as CAD tools.

continue until they had built the top-level block. Logic simulators came into
existence to verify the functionality of these circuits before they were fabricated
on chip.
As designs got larger and more complex, logic simulation assumed an important
role in the design process. Designers could iron out functional bugs in the
architecture before the chip was designed further.

1.2 Emergence of HOLs


For a long time, programming languages such as FORTRAN, Pascal, and C were
being used to describe computer programs that were sequential in nature.
Similarly, in the digital design field, designers felt the need for a standard
language to describe digital circuits. Thus, Hardware Description Languages (HDLs)
came into existence. HDLs allowed the designers to model the concurrency of
processes found in hardware elements. Hardware description languages such as
Verilog HDL and VHDL became popular. Verilog HDL originated in 1983 at
Gateway Design Automation. Later, VHDL was developed under contract from
DARPA. Both Verilog and VHDL simulators to simulate large digital circuits
quickly gained acceptance from designers.
Even though HDLs were popular for logic verification, designers had to manually
translate the HDL-based design into a schematic circuit with interconnections
between gates. The advent of logic synthesis in the late 1980s changed the design
methodology radically. Digital circuits could be described at a register transfer level
(RTL) by use of an HDL. Thus, the designer had to specify how the data flows
between registers and how the design processes the data. The details of gates and
their interconnections to implement the circuit were automatically extracted by
logic synthesis tools from the RTL description.
Thus, logic synthesis pushed the HDLs into the forefront of digital design.
Designers no longer had to manually place gates to build digital circuits. They
could describe complex circuits at an abstract level in terms of functionality and
data flow by designing those circuits in HDLs. Logic synthesis tools would
implement the specified functionality in terms of gates and gate interconnections.
HDLs also began to be used for system-level design. HDLs were used for
simulation of system boards, interconnect buses, FPGAs (Field Programmable
Gate Arrays), and PALs (Programmable Array Logic). A common approach is to
design each IC chip, using an HDL, and then verify system functionality via
simulation.

Verilog HDL: A Guide to Digital Design and Synthesis

1.3 Typical Design Flow


A typical design flow for designing VLSI Ie circuits is shown in Figure I-I.
Unshaded blocks show the level of design representation; shaded blocks show
processes in the design flow.
Design Specification

Behavioral Description

c:

RTL Description (HDL) 1-4--,


'------,----

Gate-Level Netlist

Figure 1-1

Typical Design Flow

Overview of Digital Design with Verilog HDL

The design flow shown in Figure 1-1 is typically used by designers who use
HDLs. In any design, specifications are written first. Specifications describe
abstractly the functionality, interface, and overall architecture of the digital circuit
to be designed. At this point, the architects do not need to think about how they
will implement this circuit. A behavioral description is then created to analyze the
design in terms of functionality, performance, compliance to standards, and other
high-level issues. Behavioral descriptions can be written with HDLs.
The behavioral description is manually converted to an RTL description in an
HDL. The designer has to describe the data flow that will implement the desired
digital circuit. From this point onward, the design process is done with the
assistance of Computer-Aided Design (CAD) tools.
Logic synthesis tools convert the RTL description to a gate-level netlist. A gatelevel netlist is a description of the circuit in terms of gates and connections
between them. The gate-level netlist is input to an Automatic Place and Route
tool, which creates a layout. The layout is verified and then fabricated on chip.
Thus, most digital design activity is concentrated on manually optimizing the
RTL description of the circuit. After the RTL description is frozen, CAD tools are
available to assist the designer in further processes. Designing at RTL level has
shrunk design cycle times from years to a few months. It is also possible to do
many design iterations in a short period of time.
Behavioral synthesis tools have begun to emerge recently. These tools can create
RTL descriptions from a behavioral or algorithmic description of the circuit. As
these tools mature, digital circuit design will become similar to high-level
computer programming. Designers will simply implement the algorithm in an
HDL at a very abstract level. CAD tools will help the designer convert the
behavioral description to a final IC chip.
It is important to note that although CAD tools are available to automate the

processes and cut design cycle times, the designer is still the person who controls
how the tool will perform. CAD tools are also susceptible to the "GIGO: Garbage
In Garbage Out" phenomenon. If used improperly, CAD tools will lead to
inefficient designs. Thus, the designer still needs to understand the nuances of
design methodologies, using CAD tools to obtain an optimized design.

1.4 Importance of HDLs


HDLs have many advantages compared to traditional schematic-based design.
Designs can be described at a very abstract level by use of HDLs. Designers
can write their RTL description without choosing a specific fabrication
technology. Logic synthesis tools can automatically convert the design to

Verilog HDL: A Guide to Digital Design and Synthesis

any fabrication technology. If a new technology emerges, designers do not


need to redesign their circuit. They simply input the RTL description to the
logic synthesis tool and create a new gate-level netlist, using the new
fabrication technology. The logic synthesis tool will optimize the circuit in
area and timing for the new technology.
By describing designs in HDLs, functional verification of the design can be
done early in the design cycle. Since designers work at the RTL level, they
can optimize and modify the RTL description until it meets the desired
functionality. Most design bugs are eliminated at this point. This cuts down
design cycle time significantly because the probability of hitting a functional
bug at a later time in the gate-level netlist or physical layout is minimized.
Designing with HDLs is analogous to computer programming. A textual
description with comments is an easier way to develop and debug circuits.
This also provides a concise representation of the design, compared to gatelevel schematics. Gate-level schematics are almost incomprehensible for very
complex designs.
HDLs are most certainly a trend of the future. With rapidly increasing
complexities of digital circuits and increasingly sophisticated CAD tools, HDLs
will probably be the only method for large digital designs. No digital circuit
designer can afford to ignore HDL-based design.

Popularity of Verilog HDL


Verilog HDL has evolved as a standard hardware description language. Verilog
HDL offers many useful features for hardware design.
Verilog HDL is a general-purpose hardware description language that is
easy to learn and easy to use. It is similar in syntax to the C programming
language. Designers with C programming experience will find it easy to
learn Verilog HDL.
Verilog HDL allows different levels of abstraction to be mixed in the same
model. Thus, a designer can define a hardware model in terms of switches,
gates, RTL, or behavioral code. Also, a designer needs to learn only one
language for stimulus and hierarchical design.
Most popular logic synthesis tools support Verilog HDL. This makes it the
language of choice for designers.

Overview of Digital Design with VerilogBHDL

All fabrication vendors provide Verilog HDL libraries for postlogic synthesis
simulation. Thus, designing a chip in Verilog HDL allows the widest choice
of vendors.
The Programming Language Interface (PLI) is a powerful feature that allows
the user to write custom C code to interact with the internal data structures
of Verilog. Designers can customize a Verilog HDL simulator to their needs
with the PLI.

1.6 Trends in HDLs


The speed and complexity of digital circuits has increased rapidly. Designers have
responded by designing at higher levels of abstraction. Designers have to think
only in terms of functionality. CAD tools take care of the implementation details.
With designer assistance, CAD tools have become sophisticated enough to do a
close-to-optimum implementation.
The most popular trend currently is to design in HDL at an RTL level, because
logic synthesis tools can create gate-level netlists from RTL level design.
Behavioral synthesis has recently emerged. As these tools improve, designers will
be able to design directly in terms of algorithms and the behavior of the circuit,
and then use CAD tools to do the translation and optimization in each phase of
the design. Behavioral modeling will be used more and more as behavioral
synthesis matures. Until then, RTL design will remain very popular.

Formal verification techniques are also appearing on the horizon. Formal


verification applies formal mathematical techniques to verify the correctness of
Verilog HDL descriptions and to establish equivalency between RTL and gatelevel netlists. However, the need to describe a design in Verilog HDL will not go
away.
For very high speed and timing-critical circuits like microprocessors, the gatelevel netlist provided by logic synthesis tools is not optimal. In such cases,
designers often mix gate-level description directly into the RTL description to
achieve optimum results. This practice is opposite to the high-level design
paradigm, yet it is frequently used for high-speed designs because designers need
to squeeze the last bit of timing out of circuits and CAD tools sometimes prove to
be insufficient to achieve the desired results.
A trend that is emerging for system-level design is a mixed bottom-up
methodology where the designers use either existing Verilog HDL modules, basic
building blocks, or vendor-supplied core blocks to quickly bring up their system
simulation. This is done to reduce development costs and compress design
schedules. For example, consider a system that has a CPU, graphics chip, I/O

Verilog HDL: A Guide to Digital Design and Synthesis

chip, and a system bus. The CPU designers would build the next-generation CPU
themselves at an RTL level, but they would use behavioral models for the
graphics chip and the I/O chip and would buy a vendor-supplied model for the
system bus. Thus, the system-level simulation for the CPU could be up and
running very quickly and long before the RTL descriptions for the graphics chip
and the I/O chip are completed.

Overview afDigital Design with Verilog HDL

10

Verilog HDL: A Guide to Digital Design and Synthesis

Hierarchical Modeling
Concepts
Before we discuss the details of the Verilog language, we must first
understand basic hierarchical modeling concepts in digital design. The
designer must use a "good" design methodology to do efficient Verilog HDLbased design. In this chapter, we discuss typical design methodologies and
illustrate how these concepts are translated to Verilog. A digital simulation is
made up of various components. We talk about the components and their
interconnections.

Learning Objectives
Understand top-down and bottom-up design methodologies for digital
design.
Explain differences between modules and module instances i*n Verilog.
Describe four levels of abstraction-behavioral,
switch level-to represent the same module.

data flow, gate level, and

Describe components required for the simulation of a digital design. Define


a stimulus block and a design block. Explain two methods of applying
stimulus.

2.1 Design Methodologies


There are two basic types of digital design methodologies: a top-down design
methodology and a bottom-up design methodology. In a top-down design
methodology, we define the top-level block and identify the sub-blocks necessary
to build the top-level block. We further subdivide the sub-blocks until we come to
leaf cells, which are the cells that cannot further be divided. Figure 2-1 shows the
top-down design process.

=2

Figure 2-1

Top-down Design Methodology

In a bottom-up design methodology, we first identify the building blocks that are
available to us. We build bigger cells, using these building blocks. These cells are
then used for higher-level blocks until we build the top-level block in the design.
Figure 2-2 shows the bottom-up design process.

Figure 2-2

Bottom-up Design Methodology

Typically, a combination of top-down and bottom-up flows is used. Design


architects define the specifications of the top-level block. Logic designers decide
how the design should be structured by breaking up the functionality into blocks
and sub-blocks. At the same time, circuit designers are designing optimized
circuits for leaf-level cells. They build higher-level cells by using these leaf cells.

12

Verilog HDL: A Guide to Digital Design and Synthesis

The flow meets at an intermediate point where the switch-level circuit designers
have created a library of leaf cells by using switches, and the logic level designers
have designed from top-down until all modules are defined in terms of leaf cells.
To illustrate these hierarchical modeling concepts, let us consider the design of a
negative edge-triggered 4-bit ripple carry counter described in Section 2.2, 4-bit

Ripple Carry Counter.

2.2 4-bit Ripple Carry Counter


Ripple
Carry
Count er

qO

ql

r--- 1------

clock

I
I
I

I
I
I
reset

-- - - - --

r-

..,

d
q q
q r--l...c
q ~~
f-L-c
~ T_FF
T_FF
~ T_FF
~ T_FF
tff3
tffO
tffl
tff2

I
L

Figure 2-3

q3

q2

____ _

_ _ ..J

Ripple Carry Counter

The ripple carry counter shown in Figure 2-3 is made up of negative edgetriggered toggle flip-flops (TJF). Each of the TJFs can be made up from
negative edge-triggered D-flipflops CD_FF) and inverters (assuming q_bar output
is not available on the D_FF), as shown in Figure 2-4.

Hierarchical Modeling Concepts

13

reset

'In

'In+l

r---

-,

cloG:l-....---a

reset
Figure 2-4

T-flipflop

Thus, the ripple carry counter is built in a hierarchical fashion by using building
blocks. The diagram for the design hierarchy is shown in Figure 2-5.

TFF
(tIro)

TFF

(tIm

Inverter
gate

Figure 2-5

Inverter
gate

T FF

TFF

(tff2)

(tff3)

Inverter
gate

Inverter
gate

Design Hierarchy

In a top-down design methodology, we first have to specify the functionality of


the ripple carry counter, which is the top-level block. Then, we implement the
counter with T_FFs. We build the T_FFs from the D_FF and an additional inverter
gate. Thus, we break bigger blocks into smaller building sub-blocks until we
decide that we cannot break up the blocks any further. A bottom-up methodology
flows in the opposite direction. We combine small building blocks and build

14

Verilog HDL: A Guide to Digital Design and Synthesis

bigger blocks; e.g., we could build DJF from and and or gates, or we could
build a custom D_FF from transistors. Thus, the bottom-up flow meets the topdown flow at the level of the D_FF.

2.3 Modules
We now relate these hierarchical modeling concepts to Verilog. Verilog provides
the concept of a module. A module is the basic building block in Verilog. A
module can be an element or a collection of lower-level design blocks. Typically,
elements are grouped into modules to provide common functionality that is used
at many places in the design. A module provides the necessary functionality to
the higher-level block through its port interface (inputs and outputs), but hides
the internal implementation. This allows the designer to modify module internals
without affecting the rest of the design.
In Figure 2-5, ripple carry counter, T_FF, D_FF are examples of modules. In Verilog,
a module is declared by the keyword module. A corresponding keyword
endmodule must appear at the end of the module definition. Each module must
have a module_name, which is the identifier for the module, and a
module_terminaClist, which describes the input and output terminals of the
module.
module <module_name> module_terminal_list;

<module internals>

endmodule

Specifically, the T-flipflop could be defined as a module as follows:


module T_FF (q, clock, reset);

<functionality of T-flipflop>

endmodule

Hierarchical Modeling Concepts

15

Verilog is both a behavioral and a structural language. Internals of each module


can be defined at four levels of abstraction, depending on the needs of the design.
The module behaves identically with the external environment irrespective of the
level of abstraction at which the module is described. The internals of the module
are hidden from the environment. Thus, the level of abstraction to describe a
module can be changed without any change in the environment. These levels will
be studied in detail in separate chapters later in the book. The levels are defined
below.
Behavioral or algorithmic level
This is the highest level of abstraction provided by Verilog HDL. A module
can be implemented in terms of the desired design algorithm without
concern for the hardware implementation details. Designing at this level is
very similar to C programming.
Dataflow level
At this level the module is designed by specifying the data flow. The
designer is aware of how data flows between hardware registers and how
the data is processed in the design.
Gate level
The module is implemented in terms of logic gates and interconnections
between these gates. Design at this level is similar to describing a design in
terms of a gate-level logic diagram.
Switch level
This is the lowest level of abstraction provided by Verilog. A module can be
implemented in terms of switches, storage nodes, and the interconnections
between them. Design at this level requires knowledge of switch-level
implementation details.
Verilog allows the designer to mix and match all four levels of abstractions in a
design. In the digital design community, the term register transfer level (RTL) is
frequently used for a Verilog description that uses a combination of behavioral
and dataflow constructs and is acceptable to logic synthesis tools.
If a design contains four modules, Verilog allows each of the modules to be
written at a different level of abstraction. As the design matures, most modules
are replaced with gate-level implementations.
Normally, the higher the level of abstraction, the more flexible and technology
independent the design. As one goes lower toward switch-level design, the
design becomes technology dependent and inflexible. A small modification can
cause a significant number of changes in the design. Consider the analogy with C
programming and assembly language programming. It is easier to program in a

16

Verilog HDL: A Guide to Digital Design and Synthesis

higher-level language such as C. The program can be easily ported to any


machine. However, if you design at the assembly level, the program is specific for
that machine and cannot be easily ported to another machine.

2.4 Instances
A module provides a template from which you can create actual objects. When a
module is invoked, Verilog creates a unique object from the template. Each object
has its own name, variables, parameters and I/O interface. The process of
creating objects from a module template is called instantiation, and the objects are
called instances. In Example 2-1, the top-level block creates four instances from the
T-flipflop (TJF) template. Each TJF instantiates a DJF and an inverter gate.
Each instance must be given a unique name. Note that II is used to denote
single-line comments.
Example 2-1

Module Instantiation

II Define the top-level module called ripple carry


II counter. It instantiates 4 T-flipflops. Interconnections are
II shown in Section 2.2, 4-bit Ripple Carry Counter.
module ripple_carry_counter(q, clk, reset);
output [3:0] q; 111/0 signals and vector declarations
Ilwill be explained later.
input clk, reset; 111/0 signals will be explained later.

IIFour instances of the module T_FF are created. Each has a unique
Ilname.Each instance is passed a set of signals. Notice, that
Ileach instance is a copy of the module T_FF.
T_FF tffO(q[O] ,clk, reset);
T_FF tffl(q[l],q[O], reset);
T_FF tff2(q[2] ,q[l], reset);
T_FF tff3(q[3] ,q[2], reset);
endmodule

II Define the module T_FF. It instantiates a D-flipflop. We assumed


II that module D-flipflop is defined elsewhere in the design. Refer
II to Figure 2-4 for interconnections.
module T_FF(q, clk, reset);
IIDeclarations to be explained later
output q;

Hierarchical Modeling Concepts

17

Example 2-1

Module Instantiation (Continued)

input clk, reset;


wire d;
D_FF dffO(q, d, clk, reset); II Instantiate D_FF. Call it dffO.
not nl(d, q); II not gate is a Verilog primitive. Explained later.
endmodule

In Verilog, it is illegal to nest modules. One module definition cannot contain


another module definition within the module and endmodule statements. Instead,
a module definition can incorporate copies of other modules by instantiating
them. It is important not to confuse module definitions and instances of a
module. Module definitions simply specify how the module will work, its
internals, and its interface. Modules must be instantiated for use in the design.
Example 2-2 shows an illegal module nesting where the module T _FF is defined
inside the module definition of the ripple carry counter.
Example 2-2

Illegal Module Nesting

II
II

Define the top-level module called ripple carry counter.


It is illegal to define the module T_FF inside this module.
module ripple_carry_counter(q, clk, reset);
output [3:0] q;
input clk, reset;
module T_FF(q, clock, reset);11 ILLEGAL MODULE NESTING
<module T_FF internals>
endmodule

II

END OF ILLEGAL MODULE NESTING

endmodule

2.5 Components of a Simulation


Once a design block is completed, it must be tested. The functionality of the
design block can be tested by applying stimulus and checking results. We call
such a block the stimulus block. It is good practice to keep the stimulus and
design blocks separate. The stimulus block can be written in Verilog. A separate

18

Verilog HDL: A Guide to Digital Design and Synthesis

language is not required to describe stimulus. The stimulus block is also


commonly called a test bench. Different test benches can be used to thoroughly test
the design block.
Two styles of stimulus application are possible. In the first style, the stimulus
block instantiates the design block and directly drives the signals in the design
block. In Figure 2-6, the stimulus block becomes the top-level block. It
manipulates signals elk and reset, and it checks and displays output signal q.

(Stimulus block)
elk
reset
(Design Block)
Ripple Carry
Counter

q
Figure 2-6

Stimulus Block Instantiates Design Block

The second style of applying stimulus is to instantiate both the stimulus and
design blocks in a top-level dummy module. The stimulus block interacts with
the design block only through the interface. This style of applying stimulus is
shown in Figure 2-7. The stimulus module drives the signals d_elk and dJeset,
which are connected to the signals elk and reset in the design block. It also checks
and displays signal c_q, which is connected to the signal q in the design block.
The function of top-level block is simply to instantiate the design and stimulus
blocks.

Hierarchical Modeling Concepts

19

Top-Level Block
d_elk
Stimulus
Block
d_reset

c_q

Figure 2-7

---

-....
-

elk
reset Design Blod<
Ripple Carry
Counter
q

Stimulus and Design Blocks Instantiated in a Dummy Top-Level Module

Either stimulus style can be used effectively.

2.6 Example
To illustrate the concepts discussed in the previous sections, let us build the
complete simulation of a ripple carry counter. We will define the design block and
the stimulus block. We will apply stimulus to the design block and monitor the
outputs. As we develop the Verilog models, you do not need to understand the
exact syntax of each construct at this stage. At this point, you should simply try to
understand the design process. We discuss the syntax in much greater detail in
the later chapters.

2.6.1

Design Block

We use a top-down design methodology. First, we write the Verilog description of


the top-level design block (Example 2-3), which is the ripple carry counter (see
Section 2.2, 4-bit Ripple Carry Counter).
Example 2-3

Ripple Carry Counter Top Block

module ripple_carry_counter(q, clk, reset);


output [3:0] q;
input clk, reset;

20

Verilog HDL: A Guide to Digital Design and Synthesis

2=
Example 2-3
T_FF
T_FF
T_FF
T_FF

Ripple Carry Counter Top Block (Continued)

tffO(q[O],clk,
tffl(q[l],q[O],
tff2(q[2] ,q[l],
tff3(q[3],q[2],

reset);
reset);
reset);
reset);

endmodu.le

In the above module, four instances of the module TJF (T-flipflop) are used.
Therefore, we must now define (Example 2-4) the internals of the module T_FF,
which was shown in Figure 2-4.
Example 2-4

Flip-flop TJF

modu.le T_FF(q, clk,

reset);

output q;
input clk, reset;
wire d;
D_FF dffO(q, d, clk, reset);
not nl(d, q); II not is a Veri log-provided primitive. case sensitive
endmodule

Since T_FF instantiates D_FF, we must now define (Example 2-5) the internals of
module D_FF. We assume asynchronous reset for the D_FF.F
Example 2-5

Flip-flop D J

/1 module D FF with synchronous reset


module D_FF(q, d, clk, reset);
output q;
input d, clk, reset;
reg q;
// Lots of new constructs. Ignore the functionality of the constructs.
/ I Concentrate on how the design block is built in a top-down fashion.
always @(posedge reset or negedge clk)
i f (reset)
q = l'bO;

Hierarchical Modeling Concepts

21

Flip-flop D J

Example 2-5

(Continued)

II module D_FF with synchronous reset


else
q = d;
endmodule

All modules have been defined down to the lowest-level leaf cells in the design
methodology. The design block is now complete.

2.6.2

Stimulus Block

We must now write the stimulus block to check if the ripple carry counter design
is functioning correctly. In this case, we must control the signals elk and reset so
that the regular function of the ripple carry counter and the asynchronous reset
mechanism are both tested. We use the waveforms shown in Figure 2-8 to test the
design. Waveforms for elk, reset, and 4-bit output q are shown. The cycle time for
elk is 10 units; the reset signal stays up from time 0 to 15 and then goes up again
from time 195 to 205. Output q counts from 0 to 15.

clk

reset

Figure 2-8

22

L------~HI----

Stimulus and Output Waveforms

Verilog HDL: A Guide to Digital Design and Synthesis

We are now ready to write the stimulus block (see Example 2-4) that will create
the above waveforms. We will use the stimulus style shown in Figure 2-6. Do not
worry about the Verilog syntax at this point. Simply concentrate on how the
design block is instantiated in the stimulus block.
Example 2-4

Stimulus Block

module stimulus;
reg elk;
reg reset;
wire[3:0] q;
II instantiate the design block
ripple_carry_counter rl(q, clk, reset);
I I Control the clk signal that drives the design block. Cycle time = 10
initial
clk = l'bO; Iiset elk to 0
always
#5 elk = -clk; Iitoggle clk every 5 time units
II Control the reset signal that drives the design block

II reset is asserted from 0 to 20 and from 200 to 220.


initial
begin
reset = l'bl;
#15 reset = l'bO;
#180 reset = l'bl;
#10 reset = l'bO;
#20 $finish; Iiterminate the simulation
end
II Monitor the outputs
initial
$monitor($time, " Output q

%d",

q);

endmodule

Hierarchical Modeling Concepts

23

Once the stimulus block is completed, we are ready to run the simulation and
verify the functional correctness of the design block. The output obtained when
stimulus and design blocks are simulated is shown in Example 2-6.
Example 2-6

Output of the Simulation


0
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
195
210
220

Output
Output
Output
Output
Output
Output
Output
Output
Output
output
output
Output
Output
Output
Output
Output
Output
Output
Output
Output
Output
Output

q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q
q

= 1
= 2
= 3
= 4
= 5
= 6
= 7
= 8
= 9
= 10
= 11
=

12

= 13
= 14
= 15
= 0
= 1
= 2
=

=
=

0
1
2

2.7 Summary
In this chapter we discussed the following concepts.
Two kinds of design methodologies are used for digital design: top-down
and bottom-up. A combination of these two methodologies is used in
today's digital designs. As designs become very complex, it is important to
follow these structured approaches to manage the design process.

Verilog HDL: A Guide to Digital Design and Synthesis

Modules are the basic building blocks in Verilog. Modules are used in a
design by instantiation. An instance of a module has a unique identity and
is different from other instances of the same module. Each instance has an
independent copy of the internals of the module. It is important to
understand the difference between modules and instances.
There are two distinct components in a simulation: a design block and a
stimulus block. A stimulus block is used to test the design block. The
stimulus block is usually the top-level block. There are two different styles
of applying stimulus to a design block.
The example of the ripple carry counter explains the step-by-step process of
building all the blocks required in a simulation.
This chapter is intended to give an understanding of the design process and how
Verilog fits into the design process. The details of Verilog syntax are not important
at this stage and will be dealt with in later chapters.

2.8 Exercises
1. An interconnect switch (IS) contains the following components, a shared
memory (MEM), a system controller (SC) and a data crossbar (Xbar).

a. Define the modules MEM, SC, and Xbar, using the module/endmodule
keywords. You do not need to define the internals. Assume that the
modules have no terminal lists.
b. Define the module IS, using the module/endmodule keywords.
Instantiate the modules MEM, SC, Xbar and call the instances rnernl, scl,
and xbarl, respectively. You do not need to define the internals. Assume
that the module IS has no terminals.
c. Define a stimulus block (Top), using the module/endmodule keywords.
Instantiate the design block IS and call the instance isl. This is the final
step in building the simulation environment.
2. A Cbit ripple carry adder (Ripple-Add) contains four l-bit full adders (FA).
a. Define the module FA. Do not define the internals or the terminal list.
b. Define the module Ripple-Add. Do not define the internals or the
terminal list. Instantiate four full adders of the type FA in the module
Ripple-Add and call them faO, fal, fa2, and fa3.

Hierarchical Modeling Concepts

=2

26

Verilog HDL: A Guide to Digital Design and Synthesis

Basic Concepts
In this chapter, we discuss the basic constructs and conventions in Verilog. These
conventions and constructs are used throughout the later chapters. These
conventions provide the necessary framework for Verilog HDL. Data types in
Verilog model actual data storage and switch elements in hardware very closely.
This chapter may seem dry, but understanding these concepts is a necessary
foundation for the successive chapters.

Learning Objectives
Understand lexical conventions for operators, comments, whitespace,
numbers, strings, and identifiers.
Define the logic value set and data types such as nets, registers, vectors,
numbers, simulation time, arrays, parameters, memories, and strings.
Identify useful system tasks for displaying and monitoring information, and
for stopping and finishing the simulation.
Learn basic compiler directives to define macros and include files.

3.1 Lexical Conventions


The basic lexical conventions used by Verilog HDL are similar to those in the C
programming language. Verilog contains a stream of tokens. Tokens can be
comments, delimiters, numbers, strings, identifiers, and keywords. Verilog HDL
is a case-sensitive language. All keywords are in lowercase.

3.1.1

Whitespace

Blank spaces (\b) ,tabs (\t) and newlines (\n) comprise the whitespace.
Whitespace is ignored by Verilog except when it separates tokens. Whitespace is
not ignored in strings.

3.1.2

Comments

Comments can be inserted in the code for readability and documentation. There
are two ways to write comments. A one-line comment starts with" //". Verilog
skips from that point to the end of line. A multiple-line comment starts with "/*"
and ends with "*/". Multiple-line comments cannot be nested.
a

=b

&& c; II This is a one-line comment

1* This is a multiple line


comment *1

1* This is 1* an illegal *1 comment *1

3.1.3

Operators

Operators are of three types, unary, binary, and ternary. Unary operators precede
the operand. Binary operators appear between two operands. Ternary operators
have two separate operators that separate three operands.
a
a
a

3.1.4

- b; II - is a unary operator. b is the operand


b && c; II && is a binary operator. band c are operands
b? c : d; II ?: is a ternary operator. b , c and d are operands

Number Specification

There are two types of number specification in Verilog: sized and unsized.

Sized numbers
Sized numbers are represented as <size> <base format> <number>.
I

<size> is written only in decimal and specifies the number of bits in the number.
Legal base formats are decimal ('d or 'D), hexadecimal ('h or 'H), binary ('b or 'B)
and octal ('0 or '0). The number is specified as consecutive digits from 0, 1, 2, 3,
4,5, 6, 7, 8, 9, a, b, c, d, e, f. Only a subset of these digits is legal for a particular
base. Uppercase letters are legal for number specification.

28

Veri/og HDL: A Guide to Digital Design and Synthesis

4'b1111
12'habc
16'd255

II
II
II

This is a 4-bit
This is a 12-bit
This is a 16-bit

binary number
hexadecimal number
decimal number.

Unsized numbers
Numbers that are specified without a <base format> specification are decimal
numbers by default. Numbers that are written without a <size> specification have
a default number of bits that is simulator- and machine-specific (must be at least
32).

23456 II This is a 32-bit


'hc3 II This is a 32-bit
'021 II This is a 32-bit

decimal number by default


hexadecimal number
octal number

XorZvalues
Verilog has two symbols for unknown and high impedance values. These values
are very important for modeling real circuits. An unknown value is denoted by
an x. A high impedance value is denoted by z.
12' h13x II This is a 12-bi t hex number; 4 least significant bits unknown
6'hx II This is a 6-bit hex number
32'bz II This is a 32-bit high impedance number

An x or z sets four bits for a number in the hexadecimal base, three bits for a
number in the octal base, and one bit for a number in the binary base. If the most
significant bit of a number is 0, x, or z, the number is automatically extended to
fill the most significant bits, respectively, with 0, x, or z. This makes it easy to
assign x or z to whole vector. If the most significant digit is 1, then it is also zero
extended.

Basic Concepts

29

Negative numbers
Negative numbers can be specified by putting a minus sign before the size for a
constant number. Size constants are always positive. It is illegal to have a minus
sign between <base format> and <number>.
-6'd3
4'd-2

II 8-bit
negative number stored as 2's complement of 3
II Illegal specification

Underscore characters and question marks


An underscore character
is allowed anywhere in a number except the first
character. Underscore characters are allowed only to improve readability of
numbers and are ignored by Verilog.
is the Verilog HDL alternative for z in the context of
A question mark
numbers. The? is used to enhance readability in the casex and casez statements
discussed in Chapter 7, Behavioral Modeling, where the high impedance value is a
don't care condition. (Note that? has a different meaning in the context of userdefined primitives, which are discussed in Chapter 12, User-Defined Primitives.)
/1_/1

/I?/I

12'bllll_OOOO_1010 II Use of underline characters for readability


4'blO?? II Equivalent of a 4'blOzz

3.1.5

Strings

A string is a sequence of characters that are enclosed by double quotes. The


restriction on a string is that it must be contained on a single line, that is, without
a carriage return. It cannot be on multiple lines. Strings are treated as a sequence
of one-byte ASCII values.
"Hello Verilog World" II is a string
"a I b" II is a string

3.1.6

Identifiers and Keywords

Keywords are special identifiers reserved to define the language constructs.


Keywords are in lowercase. A list of all keywords in Verilog is contained in
Appendix C, List of Keywords, System Tasks, and Compiler Directives.
30

Verilog HDL: A Guide to Digital Design and Synthesis

Identifiers are names given to objects so that they can be referenced in the design.
Identifiers are made up of alphanumeric characters, the underscore ( _ ) and the
dollar sign ( $ ) and are case sensitive. Identifiers start with an alphabetic
character or an underscore. They cannot start with a number or a $ sign (The $
sign as the first character is reserved for system tasks, which are explained later in
the book).
reg value; II reg is a keyword; value is an identifier
input elk; II input is a keyword, elk is an identifier

3.1.7

Escaped Identifiers

Escaped identifiers begin with the backslash ( \ ) character and end with
whitespace (space, tab, or newline). All characters between backslash and
whitespace are processed literally. Any printable ASCII character can be included
in escaped identifiers. The backslash or whitespace is not considered a part of the
identifier.

I \\**my_name**
..
b-c

3.2 Data Types


This section discusses the data types used in Verilog.

3.2.1

Value Set

Verilog supports four values and eight strengths to model the functionality of real
hardware. The four value levels are listed in Table 3-1.
Table 3-1

Value Levels

Value Level

Condition in Hardware Circuits


Logic zero, false condition

Logic one, true condition

Unknown value

High impedance, floating state

Basic Concepts

31

In addition to logic values, strength levels are often used to resolve conflicts
between drivers of different strengths in digital circuits. Value levels 0 and 1 can
have the strength levels listed in Table 3-2.
Table 3-2 Strength Levels

Strength Level

Type

supply

Driving

strong

Driving

pull

Driving

large

Storage

weak

Driving

medium

Storage

small

Storage

highz

High Impedance

Degree
strongest

weakest

If two signals of unequal strengths are driven on a wire, the stronger signal

prevails. For example, if two signals of strength strongl and weakO contend, the
result is resolved as a strongl. If two signals of equal strengths are driven on a
wire, the result is unknown. If two signals of strength strongl and strongO
conflict, the result is an x. Strength levels are particularly useful for accurate
modeling of signal contention, MOS devices, dynamic MOS, and other low-level
devices. Only trireg nets can have storage strengths large, medium, and small.
Detailed information about strength modeling is provided in Appendix A,
Strength Modeling and Advanced Net Definitions.

3.2.2

Nets

Nets represent connections between hardware elements. Just as in real circuits, nets
have values continuously driven on them by the outputs of devices that they are
connected to. In Figure 3-1 net a is connected to the output of and gate gi. Net a
will continuously assume the value computed at the output of gate gi, which is b &
c.

Figure 3-1

32

Example of Nets

Verilog HDL: A Guide to Digital Design and Synthesis

Nets are declared primarily with the keyword wire. Nets are one-bit values by
default unless they are declared explicitly as vectors. The terms wire and net are
often used interchangeably. The default value of a net is z (except the trireg net,
which defaults to x). Nets get the output value of their drivers. If a net has no
driver, it gets the value z.
wire a; II Declare net a for the above circuit
wire b,c; II Declare two wires b,c for the above circuit
wire d = l'bO; II Net d is fixed to logic value 0 at declaration.

Note that net is not a keyword but represents a class of data types such as wire,
wand, wor, tri, triand, trior, trireg, etc. The wire declaration is used most
frequently. Other net declarations are discussed in Appendix A, Strength Modeling
and Advanced Net Definitions.

3.2.3

Registers

Registers represent data storage elements. Registers retain value until another
value is placed onto them. Do not confuse the term registers in Verilog with
hardware registers built from edge-triggered flip-flops in real circuits. In Verilog,
the term register merely means a variable that can hold a value. Unlike a net, a
register does not need a driver. Verilog registers do not need a clock as hardware
registers do. Values of registers can be changed anytime in a simulation by
assigning a new value to the register.
Register data types are commonly declared by the keyword reg. The default
value for a reg data type is x. An example of how registers are used is shown
Example 3-1.
Example 3-1

Example of Register

reg reset; II declare a variable reset that can hold its value
initial II this construct will be discussed later
begin
reset = l'b1; Ilinitialize reset to 1 to reset the digital circuit.
#100 reset = l'bO; II after 100 time units reset is deasserted.
end

Basic Concepts

33

3.2.4

Vectors

Nets or reg data types can be declared as vectors (multiple bit widths). If bit
width is not specified, the default is scalar (I-bit).
wire a; II scalar net variable, default
wire [7:0] bus; II 8-bit
bus
wire [31:0] busA,busB,busC; II 3 buses of 32-bit width.
reg clock; II scalar register, default
reg [0:40] virtual_addr; //Vector register,virtual address 4lbitswide

Vectors can be declared at [high# : low#] or [low# : high#], but the left number in
the squared brackets is always the most significant bit of the vector. In the
example shown above, bit 0 is the most significant bit of vector virtuaCaddr.
For the vector declarations shown above, it is possible to address bits or parts of
vectors.
busA[7] II bit # 7 of vector busA
bus[2:0] II Three least significant bits of vector bus,
II using bus[0:2] is illegal because the significant bit should
II always be on the left of a range specification
virtual_addr[O:l] //Two most significant bits of vector virtual_addr

3.2.5

Integer, Real, and Time Register Data Types

Integer, real, and time register data types are supported in Verilog.

Integer

An integer is a general purpose register data type used for manipulating


quantities. Integers are declared by the keyword integer. Although it is possible
to use reg as a general-purpose variable, it is more convenient to declare an
integer variable for purposes such as counting. The default width for an integer
is the host-machine word size, which is implementation specific but is at least 32
bits. Registers declared as data type reg store values as unsigned quantities,
whereas integers store values as signed quantities.

34

Verilog HDL: A Guide to Digital Design and Synthesis

integer counter;
initial
counter = -1;

II

general purpose variable used as a counter.

II

A negative one is stored in the counter

Real

Real number constants and real register data types are declared with the keyword
decimal notation (e.g., 3.14) or in scientific notation
(e.g., 3e6, which is 3 x 106 ). Real numbers cannot have a range declaration, and
their default value is o. When a real value is assigned to an integer, the real
number is rounded off to the nearest integer.
real. They can be specified in

real delta; II Define a real variable called delta


initial
begin
4elO; II delta is assigned in scientific notation
delta
delta
2.13; II delta is assigned a value 2.13
end
integer i; II Define an integer i
initial
i = delta; II i gets the value 2 (rounded value of 2.13)

Time

Verilog simulation is done with respect to simulation time. A special time register
data type is used in Verilog to store simulation time. A time variable is declared
with the keyword time. The width for time register data types is implementation
specific but is at least 64 bits.The system function $time is invoked to get the
current simulation time.
time save_sim_time; II Define a time variable save_sim_time
initial
save_sim_time = $time; II Save the current simulation time

Simulation time is measured in terms of simulation seconds. The unit is denoted by


s, the same as real time. However, the relationship between real time in the digital
circuit and simulation time is left to the user. This is discussed in detail in Section
9.4, Time Scales.

Basic Concepts

35

3.2.6

Arrays

Arrays are allowed in Verilog for reg, integer, time, and vector register data
types. Arrays are not allowed for real variables. Arrays are accessed by
<array_name> [<subscript>]. Multidimensional arrays are not permitted in Verilog.
integer count [0: 7] ; I I An array of 8 count variables
reg bool[31:0]; II Array of 32 one-bit boolean register variables
time chk-point[1:100]; II Array of 100 time checkpoint variables
reg [4: 0] port_id [0: 7 J ; j j Array of 8 port_ids; each port_id is 5 bi ts wide
integer matrix[4:0] [4:0J; Ilrllegaldeclaration.Multidimensional
array
count[5] II 5th element of array of count variables
chk-point[100J jj100th time check point value
port_id[3J 113rd element of port_id array. This is a 5-bit value.

It is important not to confuse arrays with net or register vectors. A vector is a


single element that is n-bits wide. On the other hand, arrays are multiple
elements that are I-bit or n-bits wide.

3.2.7

Memories

In digital simulation, one often needs to model register files, RAMs, and ROMs.
Memories are modeled in Verilog simply as an array of registers. Each element of
the array is known as a word. Each word can be one or more bits. It is important
to differentiate between n l-bit registers and one n-bit register. A particular word
in memory is obtained by using the address as a memory array subscript.
reg mem1bit [0: 1023] ; I I Memory mem1bit with 1K 1-bit words
reg [7:0J membyte[0:1023J;IIMemory membyte with 1K8-bitwords(bytes)
membyte [511J II Fetches 1 byte word whose address is 511.

36

Verilog HDL: A Guide to Digital Design and Synthesis

3=
3.2.8

Parameters

Verilog allows constants to be defined in a module by the keyword parameter.


Parameters cannot be used as variables. Parameter values for each module
instance can be overridden individually at compile time. This allows the module
instances to be customized. This aspect is discussed later.
parameter port_id = 5; //Defines a constant port_id
parameter cache_Iine_width = 256; / / Constant defines width of cache line

Module definitions may be written in terms of parameters. Hardcoded numbers


should be avoided. Parameters can be changed at module instantiation or by
using the defparam statement, which is discussed in detail in Chapter 9, Useful
Modeling Techniques. Thus, use of parameters makes the module definition
flexible. Module behavior can be altered simply by changing the value of a
parameter.

3.2.9

Strings

Strings can be stored in reg. The width of the register variables must be large
enough to hold the string. Each character in the string takes up 8 bits (1 byte). If
the width of the register is greater than the size of the string, Verilog fills bits to
the left of the string with zeros. If the register width is smaller than the string
width, Verilog truncates the leftmost bits of the string. It is always safe to declare
a string that is slightly wider than necessary.
reg [8*18: 1] string_value; / / Declare a variable that is 18 bytes
wide
initial
string_value
"Hello Verilog World"; II String can be stored
II in variable

Basic Concepts

37

Special characters serve a special purpose in displaying strings, such as newline,


tabs and displaying argument values. Special characters can be displayed in
strings only when they are preceded by escape characters, as shown in Table 3-3.
Table 3-3 Special Characters

Escaped Characters

Character Displayed

\n

newline

\t

tab

%%

\\

\"
\000

Character written in 1-3 octal digits

3.3 System Tasks and Compiler Directives


In this section we introduce two special concepts used in Verilog: system tasks
and compiler directives.

3.3.1

System Tasks

Verilog provides standard system tasks to do certain routine operations. All


system tasks appear in the form $ <keyword>. Operations such as displaying on
the screen, monitoring values of nets, stopping, and finishing are done by system
tasks. We will discuss only the most useful system tasks. Other tasks are listed in
Verilog manuals provided by your simulator vendor or in the Verilog HDL

Language Reference Manual.


Displaying information
$display is the main system task for displaying values of variables or strings or
expressions. This is one of the most useful tasks in Verilog.

Usage: $display(pl, p2, p3, ..... , pn);


pl, p2, p3, ... , pn can be quoted strings or variables or expressions. The format of
$display is very similar to printf in C. A $display inserts a newline at the end
of the string by default. A $display without any arguments produces a newline.

38

Verilog HDL: A Guide to Digital Design and Synthesis

Strings can be formatted by using the format specifications listed in Table 3-4. For
more detailed format specifications, see Verilog HDL Language Reference Manual.
Table 3-4 String Format Specifications

Display

Format
%dor %D

Display variable in decimal

%b or %B

Display variable in binary

%s or %5

Display string

%h or %H

Display variable in hex

%c or %C

Display ASCII character

%mor%M

Display hierarchical name (no argument required)

%v or %V

Display strength

%0

or %0

Display variable in octal

%t or %T

Display in current time format

%e or %E

Display real number in scientific format (e.g., 3e10)

%f or %F

Display real number in decimal format (e.g., 2.13)

%g or %G

Display real number in scientific or decimal, whichever is shorter

Example 3-2 shows some examples of the $display task. If variables contain x or
z values they are printed in the displayed string as x or z.
Example 3-2

$display Task

//Display the string in quotes


$display ("Hello Verilog World") ;
-- Hello Verilog World
I/Display value of current simulation time 230
$display ( $ time) ;
-- 230
//Display value of 41-bit virtual address IfeOOOOOOlc and time 200
reg [0:40] virtual_addr;
$displaY("At time %d virtual address is %h", $time, virtual_addr);
-- At time 200 virtual address is IfeOOOOOOlc
//Display value of port_id 5 in binary
reg [4:0] port_id;

Basic Concepts

39

Example 3-2

$display Task (Continued)

$display (" ID of the port is %b", port_id);


-- ID of the port is 00101

IIDisplay x characters
IIDisplay value of 4-bit bus 10xx (signal contention) in binary
reg [3:0] bus;
$display ("Bus value is %b", bus);
-- Bus value is 10xx
//Display the hierarchical name of instance p1 instantiated under
lithe highest-level module called top. No argument is required. This
Ilis a useful feature)
$display("This string is displayed from %m level of hierarchy");
-- This string is displayed from top.p1 level of hierarchy

Special characters are discussed in Section 3.2.9, Strings. Examples of displaying


special characters in strings as discussed are shown in Example 3-3.
Example 3-3

Special Characters

IIDisplay special characters, newline and %


$display( "This is a \n multiline string with a %% sign");
This is a
-- multiline string with a % sign
IIDisplay other special characters

Monitoring information
Verilog provides a mechanism to monitor a signal when its value changes. This
facility is provided by the $moni tor task.

Usage: $monitor(pl,p2,p3, .... ,pn);


The parameters pI, p2, ... ,pn can be variables, signal names, or quoted strings. A
format similar to the $display task is used in the $monitor task. $monitor
continuously monitors the values of the variables or signals specified in the
parameter list and displays all parameters in the list whenever the value of any
one variable or signal changes. Unlike $display, $monitor needs to be invoked
only once.

40

Verilog HDL: A Guide to Digital Design and Synthesis

Only one monitoring list can be active at a time. If there is more than one
$monitor statement in your simulation, the last $monitor statement will be the
active statement. The earlier $monitor statements will be overridden.
Two tasks are used to switch monitoring on and off.

Usage: $monitoron;
$monitoroff;

The $monitoron tasks enables monitoring, and the $monitoroff task disables
monitoring during a simulation. Monitoring is turned on by default at the
beginning of the simulation and can be controlled during the simulation with the
$monitoron and $monitoroff tasks. Examples of monitoring statements are
given in Example 3-4. Note the use of $time in the $monitor statement.
Example 3-4

Monitor Statement

//Monitor time and value of the signals clock and reset


;/Clock toggles every 5 time units and reset goes down at 10 time units
initial
begin
$monitor($time,
%b", clock,reset);
" Value of signals clock
%b reset
end

Partial output of the monitor statement:

o Value of signals clock = 0 reset = 1


5 Value of signals clock = 1 reset = 1
10 Value of signals clock = 0 reset = 0
Stopping and finishing in a simulation
The task $stop is provided to stop during a simulation.

Usage: $stop;
The $stop task puts the simulation in an interactive mode. The designer can then
debug the design from the interactive mode. The $stop task is used whenever the
designer wants to suspend the simulation and examine the values of signals in
the design.
The $finish task terminates the simulation.
Usage: $finish;
Examples of $stop and $finish are shown in Example 3-5.

Basic Concepts

41

Example 3-5

Stop and Finish Tasks

II
II

Stop at time 100 in the simulation and examine the results


Finish the simulation at time.
initial II to be explained later. time = 0
begin
clock = 0;
reset = 1;
#100 $stop; II This will suspend the simulation at time = 100
#900 $finish; II This will terminate the simulation at time = 1000
end

3.3.2

Compiler Directives

Compiler directives are provided in Verilog. All compiler directives are defined
by using the '<keyword> construct. We deal with the two most useful compiler
directives.
'define

The 'define directive is used to define text macros in Verilog (see Example 3-6).
This is similar to the #define construct in C. The defined constants or text macros
are used in the Verilog code by preceding them with a ' (back tick). The Verilog
compiler substitutes the text of the macro wherever it encounters a
, <macro_name>.
Example 3-6

'define Directive

Iidefine a text macro that defines default word size


as 'WORD_SIZE in the code
'define WORD_SIZE 32

IIUsed

Iidefine an alias. A $stop will be substituted wherever'S appears


'define S $stop;

1:
Iidefine a frequently used text string
'define WORD_REG reg [31:0]
II you can then define a 32-bit register as 'WORD_REG reg32;

42

Verilog HDL: A Guide to Digital Design and Synthesis

'include
The ' include directive allows you to include entire contents of a Verilog source
file in another Verilog file during compilation. This works similarly to the #include
in the C programming language. This directive is typically used to include header
files, which typically contain global or commonly used definitions (see Example
Example 3-7

'include Directive

/ / Include the file header.^, which contains declarations in the


/ / main verilog file design.^.

'include header.^

...
...
<Verilog code in file design.vz

Two other directives, ' ifdef and ' timescale, are used frequently. They are
discussed in Chapter 9, Useful Modeling Techniques.

3.4 Summary
We discussed the basic concepts of Verilog in this chapter. These concepts lay the
foundation for the material discussed in the further chapters.
Verilog is similar in syntax to the C programming language . Hardware
designers with previous C programming experience will find Verilog easy to
learn.
Lexical conventions for operators, comments, whitespace, numbers, strings,
and identifiers were discussed.
Various data types are available in Verilog. There are four logic vaIues, each
with different strength levels. Available data types include nets, registers,
vectors, numbers, simulation time, arrays, memories, parameters, and
strings. Data types represent actual hardware elements very closely.
Verilog provides useful system tasks to do functions like displaying,
monitoring, suspending, and finishing a simulation.

Basic Concepts

Compiler directive 'define is used to define text macros, and ' include is
used to include other Verilog files.

3.5 Exercises
1. Practice writing the following numbers
a. Decimal number 123 as a sized 8-bit number in binary. Use
readability.
b. A 16-bit hexadecimal unknown number with all X'S.

for

c. A 4-bit negative 2 in decimal . Write the 2's complement form for this
number.
d. An unsized hex number 1234.
2. Are the following legal strings? If not, write the correct strings.
a. "This is a string displaying the % sign"

b. "out = in1 + in2"


c. "Please ring a bell \007"
d. "This is a backslash \ character\nU
3. Are these legal identifiers?

d. exec$
4. Declare the following variables in Verilog.
a. An &bit vector net called a-in.
b. A 32-bit storage register called address. Bit 31 must be the most
significant bit. Set the value of the register to a 32-bit decimal number
equal to 3.
c. An integer called count.
d. A time variable called snap-shot.
e. An array called delays. Array contains 20 elements of the type integer.
f. A memory MEM containing 256 words of 64 bits each.
g. A parameter cache-size equal to 512.

Verilog HDL: A Guide to Digital Design and Synthesis

5. What would be the output/ effect of the following statements?


a. latch = 4'd12;
$display("The current value of latch
b. inJeg =3'd2;
$monitor($time, " In register value

= %b\n", latch);

= %b\n", inJeg[2:0});

c. 'define MEM_SIZE 1024


$display("The maximum memory size is %h", 'MEM_SIZE);

Basic Concepts

45

46

Verilog HDL: A Guide to Digital Design and Synthesis

Modules and Ports


In the previous chapters, we acquired an understanding of the fundamental
hierarchical modeling concepts, basic conventions, and Verilog constructs. In this
chapter, we take a closer look at modules and ports from the Verilog language
point of view.

Learning Objectives
Identify the components of a Verilog module definition, such as module
names, port lists, parameters, variable declarations, dataflow statements,
behavioral statements, instantiation of other modules, and tasks or
functions.
Understand how to define the port list for a module and declare it in
Verilog.
Describe the port connection rules in a module instantiation.
Understand how to connect ports to external signals, by ordered list, and by
name.
Explain hierarchical name referencing of Verilog identifiers.

4.1 Modules
We discussed how a module is a basic building block in Chapter 2, Hierarchical
Modeling Concepts. We ignored the internals of modules and concentrated on how
modules are defined and instantiated. In this section we analyze the internals of
the module in greater detail.
A module in Verilog consists of distinct parts, as shown in Figure 4-1.

Module Name,
Port List, Port Declarations (if ports present)
Parameters(optional),

Declarations of wires,
regs and other variables

Instantiation of lower
level modules

Data flow statements


(assign)

always and initial blocks.

All behavioral statements


go in these blocks.

Tasks and functions

endmodule statement
Figure 4-1

Components of a Verilog Module

A module definition always begins with the keyword module. The module name,
port list, port declarations, and optional parameters must come first in a module
definition. Port list and port declarations are present only if the module has any
ports to interact with the external environment.The five components within a
module are - variable declarations, dataflow statements, instantiation of lower modules,
behavioral blocks, and tasks or functions. These components can be in any order and
at an'{ ~lace in the module definition. The endm.odul.e statement must alwa~s
come last in a module definition. All components except module, module name,
and endmodule are optional and can be mixed and matched as per design needs.
Verilog allows multiple modules to be defined in a single file. The modules can be
defined in any order in the file.
To understand the components of a module shown above, let us consider a simple
example of an SR latch, as shown in Figure 4-2.

48

Verilog HDL: A Guide to Digital Design and Synthesis

r------------,
Sbar
(set)

Rbar
(reset)

Figure 4-2

I
b---.,..-I;...- Q

P--~---LI-

Qbar

L. ___________ J

SR Latch

The SR latch has 5 and R as the input ports and Q and Qbar as the output ports.
The SR latch and its stimulus can be modeled as shown in Example 4-1.
Example 4-1

Components of SR Latch

II This example illustrates the different components of a module


II Module name and port list
II SR_latch module
module SR_latch(Q, Qbar, Sbar, Rbar);

IIPort declarations
output Q, Qbar;
input Sbar, Rbar;
II Instantiate lower-level modules
II In this case, instantiate Verilog primitive nand gates
II Note, how the wires are connected in a cross-coupled fashion.
nand nl(Q, Sbar, Qbar);
nand n2(Qbar, Rbar, Q);

II endmodule statement
endmodule
II Module name and port list
II Stimulus module
module Top;

II Declarations of wire, reg, and other variables


Modules and Ports

49

Example 4-1

Components of SR Latch (Continued)

wire q, qbar;
reg set, reset;
/ / Instantiate lower-level modules
/ / In this case, instantiate SR-latch
/ / Feed inverted set and reset signals to the SR latch

SR-latch ml(q, qbar, -set, -reset);


/ / Behavioral block, initial
initial
begin
$monitor($time, " set = %b, reset= %b, q= %b\nU,set,reset,q);
set = 0; reset = 0;
# 5 reset = 1;
#5 reset = 0;
#5 set = 1;
end
/ / endmodule statement
endmodule

Notice the following characteristics about the modules defined above.


In the SR latch definition above , notice that all components described in

Figure 4-1 need not be present in a module. We do not find variable


declarations, dataflow ( a s s i g n ) statements, or bekavioral blocks (always or
initial).

However, the stimulus block for the SR latch contains module name, wire, reg,
and variable declarations, instantiation of lower level modules, bekavioral block
( i n i t i a l ) , and endmodule statement but does not contain port list, port
declarations, and data flow ( a s s i g n ) statements.
Thus, all parts except module, module name, and endmodule are optional and
can be mixed and matched as per design needs.

Verilog HDL: A Guide to Digital Design and Synthesis

4.2 Ports
Ports provide the interface by which a module can communicate with its
environment. For example, the input/output pins of an Ie chip are its ports. The
environment can interact with the module only through its ports. The internals of
the module are not visible to the environment. This provides a very powerful
flexibility to the designer. The internals of the module can be changed without
affecting the environment as long as the interface is not modified. Ports are also
referred to as terminals.

4.2.1

List of Ports

A module definition contains an optional list of ports. If the module does not
exchange any signals with the environment, there are no ports in the list.
Consider a 4-bit full adder that is instantiated inside a top-level module Top. The
diagram for the input/ output ports is shown in Figure 4-3.

Top
full
adder
(4 bit)
fulladd4

Figure 4-3

--'sum

I/O Ports for Top and Full Adder

Notice that in the above figure, the module Top is a top-level module. The module
fulladd4 is instantiated below Top. The module fulladd4 takes input on ports a, b,
and c_in and produces an output on ports sum and c_out. Thus, module fulladd4
performs an addition for its environment. The module Top is a top-level module
in the simulation and does not need to pass signals to or receive signals from the
environment. Thus, it does not have a list of ports. The module names and port
lists for both module declarations in Verilog are as shown in Example 4-2.
Example 4-2

List of Ports

module fulladd4(sUID, c_out, a, b, c_in); //Module with a list of ports


module Top; II No list of ports, top-level module in simulation

Modules and Ports

51

4.2.2

Port Declaration

All ports in the list of ports must be declared in the module. Ports can be declared
as follows:
Verilog Keyword
input
output
inout

Type of Port
Input port
Output port
Bidirectional port

Each port in the port list is defined as input, output, or inout, based on the
direction of the port signal. Thus, for the example of the fulladd4 in Example 4-2,
the port declarations will be as shown in Example 4-3.
Example 4-3

Port Declarations

module fulladd4(sum, c_out, a, b, c_in);


//Begin port declarations section
output[3:0] sum;
output c_cout;
input [3:0] a, b;
input c_in;
//End port declarations section
<module internals>
endmodule

Note that all port declarations are implicitly declared as wire in Verilog. Thus, if
a port is intended to be a wire, it is sufficient to declare it as output, input, or
inout. Input or inout ports are normally declared as wires. However, if output
ports hold their value, they must be declared as reg. For example, in the
definition of DFF, in Example 2-5, we wanted the output q to retain its value until
the next clock edge. The port declarations for DFF will look as shown in Example
4-4.

52

Verilog HDL: A Guide to Digital Design and Synthesis

4=
Example 4-4

Port Declarations for DFF

module DFF(q, d, elk, reset);


output q;
reg q; II Output port q holds value; therefore it is declared as reg.
input d, elk, reset;

endmodule

Ports of the type input and inout cannot be declared as reg because reg
variables store values and input ports should not store values but simply reflect
the changes in the external signals they are connected to.

4.2.3

Port Connection Rules

One can visualize a port as consisting of two units, one unit that is internal to the
module another that is external to the module. The internal and external units are
connected. There are rules governing port connections when modules are
instantiated within other modules. The Verilog simulator complains if any port
connection rules are violated. These rules are summarized in Figure 4-4.
net ~~

net

inout

"
reg or net

Figure 4-4

..

...

input

output
reg or net

--..

net

Port Connection Rules

Inputs

Internally, input ports must always be of the type net. Externally, the inputs can
be connected to a variable which is a reg or a net.

Modules and Ports

53

Outputs
Internally, outputs ports can be of the type reg or net. Externally, outputs must
always be connected to a net. They cannot be connected to a reg.
Inouts
Internally, in out ports must always be of the type net. Externally, inout ports must
always be connected to a net.
Width matching
It is legal to connect internal and external items of different sizes when making
inter-module port connections. However, a warning is typically issued that the
widths do not match.

Unconnected ports
Verilog allows ports to remain unconnected. For example, certain output ports
might be simply for debugging, and you might not be interested in connecting
them to the external signals. You can let a port remain unconnected by
instantiating a module as shown below.
fulladd4 faO(SUM,

, A, B, C_IN); II Output port c_out is unconnected

Example of illegal port connection


To illustrate port connection rules, assume that the module fulladd4 in Example 43 is instantiated in the stimulus block Top. An example of an illegal port
connection is shown in Example 4-5.
Example 4-5

Illegal Port Connection

module Top;

IIDeclare connection variables


reg [3:0]A,B;
reg C_IN;
reg [3:0] SUM;
wire C_OUT;
IIInstantiate fulladd4, call it faO
fulladd4 faO(SUM, C_OUT, A, B, C_IN);
IIIllegal connection because output port sum in module fulladd4
Ilis connected to a register variable SUM in module Top.

54

Verilog HDL: A Guide to Digital Design and Synthesis

Example 4-5

Illegal Port Connection (Continued)

<stimulus>

endmodule

This problem is rectified if the variable SUM is declared as a net (wire). A similar
problem would occur if an input port were declared as a reg.

4.2.4

Connecting Ports to External Signals

There are two methods of making connections between signals specified in the
module instantiation and the ports in a module definition. The two methods
cannot be mixed.
Connecting by ordered list
Connecting by ordered list is the most intuitive method for most beginners. The
signals to be connected must appear in the module instantiation in the same order
as the ports in the port list in the module definition. Once again, consider the
module fulladd4 defined in Example 4-3. To connect signals in module Top by
ordered list, the Verilog code is shown in Example 4-6. Notice that the external
signals SUM, C_OUT, A, B, and CjN appear in exactly the same order as the
ports sum, c_out, a, b, and cin in module definition of fulladd4.
Example 4-6

Connection by Ordered List

module Top;
//Declare connection variables
reg [3:0]A,B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
//Instantiate fulladd4, call it fa_ordered.
//Signals are connected to ports in order (by position)
fulladd4 fa_ordered (SUM, C_OUT, A, B, C_IN);
<stimulus>

Modules and Ports

55

Example 4-6

Connection by Ordered List (Continued)

endmodule

module fulladd4(sum, c_out, a, b, c_in);


output [3: 0] sum;
output c_cout;
input [3:0] a, b;
input c_in;
<module internals>
endmodule

Connecting ports by name


For large designs where modules have, say, 50 ports, remembering the order of
the ports in the module definition is impractical and error prone. Verilog provides
the capability to connect external signals to ports by the port names, rather than
by position. We could connect the ports by name in Example 4-6 above by
instantiating the module fulladd4, as follows. Note that you can specify the port
connections in any order as long as the port name in the module definition
correctly matches the external signal.
II Instantiate module fa_byname and connect signals to ports by name
fulladd4 fa_byname(.c_out(C_OUT), . sum (SUM) , .b(B), .c_in(C_IN),
.a(A),) ;

Note that only those ports that


specified in port connection by
example, if the port c_out were
fulladd4 would look as follows.
list.

are to be connected to external signals must be


name. Unconnected ports can be dropped. For
to be kept unconnected, the instantiation of
The port c_out is simply dropped from the port

II Instantiate module fa_byname and connect signals to ports by name


fulladd4 fa_byname(.sum(SUM), .b(B), .c_in(C_IN), .a(A) ,);

56

Verilog HDL: A Guide to Digital Design and Synthesis

4=
Another advantage of connecting ports by name is that as long as the port name
is not changed, the order of ports in the port list of a module can be rearranged
without changing the port connections in module instantiations.

4.3 Hierarchical Names


We described earlier that Verilog supports a hierarchical design methodology.
Every module instance, signal, or variable is defined with an identifier. A
particular identifier has a unique place in the design hierarchy. Hierarchical name
referencing allows us to denote every identifier in the design hierarchy with a
unique name. A hierarchical name is a list of identifiers separated by dots (/I ./1) for
each level of hierarchy. Thus, any identifier can be addressed from any place in
the design by simply specifying the complete hierarchical name of that identifier.
The top-level module is called the root module because it is not instantiated
anywhere. It is the starting point. To assign a unique name to an identifier, start
from the top-level module and trace the path along the design hierarchy to the
desired identifier. To clarify this process, let us consider the simulation of SR latch
in Example 4-1. The design hierarchy is shown in Figure 4-5.

stimulus
(Root level)

q, qbar,
set, reset
(variables)

nl
(nand)

Figure 4-5

~
~

Q, Qbar
S, R
(signals)

Design Hierarchy for SR Latch Simulation

For this simulation, stimulus is the top-level module. Since the top-level module is
not instantiated anywhere, it is called the root module. The identifiers defined in
this module are q, qbar, set, and reset. The root module instantiates ml, which is a
module of type SR_Iatch. The module ml instantiates nand gates nl and n2. Q,
Qbar, S, and R are port signals in instance ml. Hierarchical name referencing

Modules and Ports

57

assigns a unique name to each identifier. To assign hierarchical names, use the
module name for root module and instance names for all module instances below
the root module. Example 4-7 shows hierarchical names for all identifiers in the
above simulation. Notice that there is a dot ( .) for each level of hierarchy from the
root module to the desired identifier.
Example 4-7

Hierarchical Names

stimulus
stimulus.qbar
stimulus.reset
stimu1us.ml.Q
stimu1us.ml.S
stimulus.nl

Each identifier in the design is uniquely specified by its hierarchical path name.
To display the level of hierarchy, use the special character %m in the $display
task. See Table 3-4, String Format Specifications, for details.

4.4 Summary
In this chapter we discussed the following aspects of Verilog
Module definitions contain various components. Keywords module and
endmodule are mandatory. Other components-port list, port declarations,
variable and signal declarations, dataflow statements, behavioral blocks, lower-level
module instantiations, and tasks or functions-are optional and can be added
as needed.
Ports provide the module with a means to communicate with other modules
or its environment. A module can have a port list. Ports in the port list must
be declared as input, output, or inout. When instantiating a module, port
connection rules are enforced by the Verilog simulator.
Ports can be connected by name or by ordered list.
Each identifier in the design has a unique hierarchical name. Hierarchical
names allow us to address any identifier in the design from any other level
of hierarchy in the design.

Verilog HDL: A Guide to Digital Design and Synthesis

4.5 Exercises
1. What are the basic components of a module? Which components are

mandatory?
2. Does a module that does not interact with its environment have any I/O
ports? Does it have a port list in the module definition?
3. A 4-bit parallel shift register has I/O pins as shown in the figure below.
Write the module definition for this module shiftJeg. Include the list of
ports and port declarations. You do not need to show the internals.

shiftJeg

---. reg_out
[3:0]

(4 bit)

4. Declare a top-level module stimulus. Define REGjN (4 bit) and CLK (1 bit)
as reg register variables and REG_OUT (4 bit) as wire. Instantiate the
module shiftJeg and call it sr1. Connect the ports by ordered list.
5. Connect the ports in Step 4 by name.
6. Write the hierarchical names for variables REGjN, CLK, and REG_OUT.
7. Write the hierarchical name for the instance sr1. Write the hierarchical names
for its ports clock and reg_in.

Modules and Ports

59

60

Verilog HDL: A Guide to Digital Design and Synthesis

Gate-Level Modeling
In the earlier chapters, we laid the foundations of Verilog design by discussing
design methodologies, basic conventions and constructs, modules and port
interfaces. In this chapter, we get into modeling actual hardware circuits in
Verilog.
We discussed the four levels of abstraction used to describe hardware. In this
chapter, we discuss a design at a low level of abstraction-gate level. Most digital
design is now done at gate level or higher levels of abstraction. At gate level, the
circuit is described in terms of gates (e.g., and, nand). Hardware design at this
level is intuitive for a user with a basic knowledge of digital logic design because
it is possible to see a one-to-one correspondence between the logic circuit diagram
and the Verilog description. Hence, in this book, we chose to start with gate-level
modeling and move to higher levels of abstraction in the succeeding chapters.
Actually, the lowest level of abstraction is switch- (transistor-) level modeling.
However, with designs getting very complex, very few hardware designers work
at switch level. Therefore, we will defer switch-level modeling to Chapter 11,
Switch-Level Modeling, in Part 2 of this book.

Learning Objectives
Identify logic gate primitives provided in Verilog.
Understand instantiation of gates, gate symbols and truth tables for andlor
and buflnot type gates.
Understand how to construct a Verilog description from the logic diagram of
the circuit.
Describe rise, fall, and turn-off delays in the gate-level design.
Explain min, max, and typ delays in the gate-level design.

=5
5.1 Gate Types

A logic circuit can be designed by use of logic gates. Verilog supports basic logic
gates as predefined primitives. These primitives are instantiated like modules
except that they are predefined in Verilog and do not need a module definition.
All logic circuits can be designed by using basic gates. There are two classes of
basic gates: and/or gates and but/not gates.

5.1.1

And/Or Gates

And/ or gates have one scalar output and multiple scalar inputs. The first terminal
in the list of gate terminals is an output and the other terminals are inputs. The
output of a gate is evaluated as soon as one of the inputs changes. The and/or
gates available in Verilog are shown below.

I nand
=d

or
nor

xor
xnor

The corresponding logic symbols for these gates are shown in Figure 5-1. We
consider gates with two inputs. The output terminal is denoted by out. Input
terminals are denoted by il and i2.

and

nand

or

nor

'1=L>~

12

xor
Figure 5-1

62

out

xnor

Basic Gates

Verilog HDL: A Guide to Digital Design and Synthesis

5=
These gates are instantiated to build logic circuits in Verilog. Examples of gate
instantiations are shown below. In Example 5-1, for all instances, OUT is
connected to the output out, and INl and IN2 are connected to the two inputs i1
and i2 of the gate primitives. Note that the instance name does not need to be
specified for primitives. This lets the designer instantiate hundreds of gates
without giving them a name.

More than two inputs can be specified in a gate instantiation. Gates with more
than two inputs are instantiated by simply adding more input ports in the gate
instantiation (see Example 5-1). Verilog automatically instantiates the appropriate
gate.
Example 5-1

Gate Instantiation of And/Or Gates

wire OUT, IN1, IN2;


II basic gate instantiations.
and al(OUT, IN1, IN2);
nand nal(OUT, IN1, IN2);
or orl(OUT, IN1, IN2);
nor norl(OUT, IN1, IN2);
xor xl (OUT, IN1, IN2);
xnor nxl(OUT, IN1, IN2);
II More than two inputs; 3 input nand gate
nand nal_3inp(OUT, IN1, IN2, IN3);
II gate instantiation without instance name
and (OUT, IN1, IN2); II legal gate instantiation

The truth tables for these gates define how outputs for the gates are computed
from the inputs. Truth tables are defined assuming two inputs. The truth tables
for these gates are shown in Table 5-1. Outputs of gates with more than two
inputs are computed by applying the truth table iteratively.

Gate-Level Modeling

63

--

Table 5-1

Truth Tables for And/Or Gates


i1

a
a a
a
1
x
a
z
a

and

i2

i1

a
a a
x
a
a
x

nand

i2

il

i2

i1

a
a a

nor

x
1

or

i2

a
1

i1

a
a a

x
x

xor

i2

5.1.2

i1

x
x

xnor

i2

Buf/Not Gates

Buf/not gates have one scalar input and one or more scalar outputs. The last
terminal in the port list is connected to the input. Other terminals are connected
to the outputs. We will discuss gates that have one input and one output.

64

Verilog HDL: A Guide to Digital Design and Synthesis

5=
Two basic buf/not gate primitives are provided in Verilog.
not

The symbols for these logic gates are shown in Figure 5-2.

.-,[>>--__

in __

out

in ---[>o_----::out

buf
Figure 5-2

not

Buf and Not gates

These gates are instantiated in Verilog as shown Example 5-2. Notice that these
gates can have multiple outputs but exactly one input, which is the last terminal
in the port list.
Gate Instantiations of Buf/Not Gates

Example 5-2

II basic gate instantiations.


buf bl(OUT1, IN);
not nl(OUT1, IN);
II More than two outputs
buf bl_2out(OUT1, OUT2, IN);
II gate instantiation without instance name
not (OUT1, IN); II legal gate instantiation

The truth tables for these gates are very simple. Truth tables for gates with one
input and one output are shown in Table 5-2.
Table 5-2

Truth Tables for Buf/Not gates

buf

in

out

not

in

out

Gate-Level Modeling

65

=5
Bufif/notif

Gates with an additional control signal on buf and not gates are also available.

I bufif1
bufifO

notifl
notifO

These gates propagate only if their control signal is asserted. They propagate z if
their control signal is deasserted. Symbols for bufif/notif are shown in Figure 5-3.
in

ctr1J?

out

in
ctrl

bufifl

in

ctr1}?
bufifO

Figure 5-3

notifl

out

out

in
ctrl

notifO

Gates Bufif and Notif

The truth tables for these gates are shown in Table 5-3.

66

out

Verilog HDL: A Guide to Digital Design and Synthesis

5
Table 5-3

Truth Tables for Bufif/Notif Gates

ctrl
x
1

ctrl
x
1

bufifl

in

notifl

in

bufifO 0

ctrl
x
1

ctrl
x
1

in

notifO

in

--

These gates are used when a signal is to be driven only when the control signal is
asserted. Such a situation is applicable when multiple drivers drive the signal.
These drivers are designed to drive the signal on mutually exclusive control
signals. Example 5-3 shows examples of instantiation of bufif and notif gates.
Example 5-3

Gate Instantiations of Bufif/Notif Gates

//Instantiation of bufif gates.


bufifl bl (out, in, ctrl) ;
bufifO bO (out, in, ctrl) ;
/ !Instantiation of notif gates
notifl nl (out, in, ctrl) ;
notifO nO (out, in, ctrl) ;

Gate-Level Modeling

67

=5
5.1.3

Examples

Having understood the various types of gates available in Verilog, we will discuss
a real example that illustrates design of gate-level digital circuits.
Gate-level multiplexer
We will design a 4-to-1 multiplexer with 2 select signals. Multiplexers serve a
useful purpose in logic design. They can connect two or more sources to a single
destination. They can also be used to implement boolean functions. We will
assume for this example that signals 51 and sO do not get the value x or z. The
I/O diagram and the truth table for the multiplexer are shown in Figure 5-4. The
I/O diagram will be useful in setting up the port list for the multiplexer.
iO
i1

i2

4-to-1
Mux

i3

sl
Figure 5-4

--..out

sl

sO

out

10

II

12

13

sO

4-to-l Multiplexer

We will implement the logic for the multiplexer using basic logic gates. The logic
diagram for the multiplexer is shown in Figure 5-5.

68

Verilog HDL: A Guide to Digital Design and Synthesis

5=
iO

r--------------------------~

yO

---1..._ _ _ _ _ _ _---1

I
I
I
I

I
I
I
I
I
I
I

i1 -+-----+------~--~

out

y3

s1n

sOn

s1 -;-......- .....

L__________________________

sO~--------~--~

Figure 5-5

Logic Diagram for Multiplexer

The logic diagram has a one-to-one correspondence with the Verilog description.
The Verilog description for the multiplexer is shown in Example 5-4. Two
intermediate nets, sOn and sl n, are created; they are complements of input signals
51 and sO. Internal nets yO, yl, y2, y3 are also required. Note that instance names
are not specified for primitive gates, not, and, and or. Instance names are
optional for Verilog primitives but are mandatory for instances of user-defined
modules.
Example 5-4

Verilog Description of Multiplexer

II Module 4-to-1 multiplexer. Port list is taken exactly from


II the IIO diagram.
module mux4_to_1 (out, iO, i1, i2, i3, s1, sO);

II Port declarations from the


output out;
input iO, i1, i2, i3;
input s1, sO;

IIO diagram

Gate-Level Modeling

69

=5
Verilog Description of Multiplexer (Continued)

Example 5-4

II Internal wire declarations


wire sin, sOn;
wire yO, yl, y2, y3;
II Gate instantiations
II Create sin and sOn signals.
not (sin, sl);
not (sOn, sO);
II 3-input and gates instantiated
and
and
and
and

(yO,
(yl,
(y2,
(y3,

iO,
ii,
i2,
i3,

sin,
sin,
sl,
sl,

sOn);
sO);
sOn);
sO);

II 4-input or gate instantiated


or (out, yO, yl, y2, y3);
endmodule

This multiplexer can be tested with the stimulus shown in Example 5-5. The
stimulus checks that each combination of select signals connects the appropriate
input to the output. The signal OUTPUT is displayed one time unit after it
changes. System task $monitor could also be used to display the signals when
they change values.
Example 5-5

Stimulus for Multiplexer

II Define the stimulus module (no ports)


module stimulus;
II Declare variables to be connected
II to inputs
reg INO, IN1, IN2, IN3;
reg Sl, SO;

II Declare output wire


wire OUTPUT;
II Instantiate the multiplexer
mux4 to_l mymux(OUTPUT, INO, IN1, IN2, IN3, Sl, SO);

70

Verilog HDL: A Guide to Digital Design and Synthesis

5=
Example 5-5

Stimulus for Multiplexer (Continued)

II Define the stimulus module (no ports)


II Stimulate the inputs
initial
begin
II set input lines
INa = 1; IN1 = 0; IN2 = 1; IN3 = 0;
#1 $display( "INO= %b, IN1= %b, IN2= %b, IN3=
%b\n",INO,IN1,IN2,IN3);
II choose INa
Sl = 0; so = 0;
#1 $display ( "Sl

%b, SO

%b, OUTPUT

%b \n", Sl, SO, OUTPUT);

II choose IN1
Sl = 0; SO = 1;
#1 $display ( "Sl

%b, SO

%b, OUTPUT

%b \n", Sl, SO, OUTPUT);

II choose IN2
Sl = 1; SO = 0;
#1 $display ( "Sl

%b, SO

%b, OUTPUT

%b \n", S1, SO, OUTPUT);

%b, SO

%b, OUTPUT

%b \n", S1, SO, OUTPUT);

II choose IN3
Sl = 1; so = 1;
#1 $display (" Sl
end
endmodule

The output of the simulation is shown below. Each combination of the select
signals is tested.
INO- 1, IN1- 0, IN2- 1, IN3- a
Sl

0,

so

0, OUTPUT

Sl

0,

so

1, OUTPUT

Sl

1,

so

0, OUTPUT

Sl

1,

so

1, OUTPUT

Gate-Level Modeling

71

=5
4-bit full adder

In this example, we design a 4-bit full adder whose port list was defined in
Section 4.2.1, List of Ports. We use primitive logic gates, and we apply stimulus to
the 4-bit full adder to check functionality. For the sake of simplicity, we will
implement a ripple carry adder. The basic building block is a I-bit full adder. The
mathematical equations for a I-bit full adder are shown below.
sum= (a ffi b ffi cin)
cout

(a b) + cin . (a ffi b)

The logic diagram for a I-bit full adder is shown in Figure 5-6.

r-----------------------------l
a

s1

I
sum

c_in

L _____________________________

Figure 5-6

I
I
I

l-bit Full Adder

This logic diagram for the I-bit full adder is converted to a Verilog description,
shown in Example 5-6.
Example 5-6

Verilog Description for l-bit Full Adder

II Define a 1-bit full adder


module fulladd(sum, c_out, a, b, c_in);
II 1/0 port declarations
output sum, c_out;
input a, b, c_in;
II Internal nets
wire sl, c1, c2;

72

Verilog HDL: A Guide to Digital Design and Synthesis

5=
Verilog Description for l-bit Full Adder (Continued)

Example 5-6

II Instantiate logic gate primitives


xor (51, a, b);
and (cl, a, b);

xor (sum, 51, c_in);


and (c2, 51, c_in);
or

(c_out, c2, cl);

endmodule

A 4-bit ripple carry full adder can be constructed from four I-bit full adders, as
shown in Figure 5-7. Notice that faD, fal, fa2, and fa3 are instances of the module
fulladd (I-bit full adder).
a[O] b[O]

a[1] b[1]

-l-- i-

full
c1
adder
faO

-.-

a[2] b[2]

full
c2
adder
fal

a[3] b[3]
-.- I

full
c3
adder
fa2

L_

...J

sum [0]
Figure 5-7

c_out

full
adder
fa3

sum[1]

sum[2]

sum[3]

4-bit Full Adder

This structure can be translated to Verilog as shown in Example 5-7. Note that the
port names used in a I-bit full adder and a 4-bit full adder are the same but they
represent different elements. The element sum in a I-bit adder is a scalar quantity
and the element sum in the 4-bit full adder is a 4-bit vector quantity. Verilog keeps
names local to a module. Names are not visible outside the module unless fullpath, hierarchical name referencing is used. Also note that instance names must
be specified when defined modules are instantiated, but when instantiating
Verilog primitives, the instance names are optional.

Gate-Level Modeling

73

=5
Example 5-7

Verilog Description for 4-bit Full Adder

II Define a 4-bit full adder


module fulladd4(sum, c_out, a, b, c_in);
II 110 port declarations
output [3:0] sum;
output c_out;
input[3:0] a, b;
input c_in;
II Internal nets
wire cl, c2, c3;
II Instantiate four
fulladd faO(sum[O],
fulladd fal(sum[l],
fulladd fa2(sum[2],
fulladd fa3(sum[3],

I-bit full adders.


cl, a[O], b[O], c_in);
c2, a[l], b[l], cl);
c3, a[2], b[2], c2);
c_out, a[3], b[3], c3);

endmodule

Finally, the design must be checked by applying stimulus, as shown in Example


5-8. The module stimulus stimulates the 4-bit full adder by applying a few input
combinations and monitors the results.
Example 5-8

Stimulus for 4-bit Full Adder

II Define the stimulus (top level module)


module stimulus;
II Set up variables
reg [3:0] A, B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
II Instantiate the 4-bit full adder. call it FAl_4
fulladd4 FAl_4(SUM, C_OUT, A, B, C_IN);
II Setup the monitoring for the signal values

74

Verilog HDL: A Guide to Digital Design and Synthesis

5=
Example 5-8

Stimulus for 4-bit Full Adder (Continued)

initial
begin
$monitor($time," A= %b, B=%b, C_IN= %b, --- C_OUT= %b, SUM=: %b\n" ,
A, B, C_IN, C_OUT, SUM);
end

II Stimulate inputs
initial
begin
A = 4'dO; B = 4'dO; C_IN

l'bO;

#5 A

4' d3; B

4'd4;

#5 A

4'd2; B

4'd5;

#5 A

4 'd9; B

4 'd9;

#5 A

4'd10; B

4'd15;

#5 A
end

4'd10; B

4 'd5; C IN

l'b1;

endmodule

The output of the simulation is shown below.


0 A= 0000, B=OOOO, C- IN= 0,

C- OUT= 0, SUM=: 0000

5 A= 0011, B=0100, C- IN= 0,

C- OUT= 0, SUM= 0111

10 A= 0010, B=0101, C- IN= 0,

C- OUT=: 0, SUM=: 0111

15 A= 1001, B=1001, C- IN= 0,

C- OUT=: 1, SUM= 0010

20 A=: 1010, B=l1l1 , C- IN= 0,

C- OUT= 1, SUM= 1001

25 A= 1010, B=0101, C- IN= 1, , C- OUT= 1, SUM= 0000

Gate-Level Modeling

75

=5
5.2 Gate Delays

Until now, we described circuits without any delays (i.e., zero delay). In real
circuits, logic gates have delays associated with them. Gate delays allow the
Verilog user to specify delays through the logic circuits. Pin-to-pin delays can also
be specified in Verilog. They are discussed in Chapter 10, Timing and Delays.

5.2.1

Rise, Fall, and Turn-off Delays

There are three types of delays from the inputs to the output of a primitive gate.
Rise delay
The rise delay is associated with a gate output transition to a
value.

from another

0, x

or z

Fall delay
The fall delay is associated with a gate output transition to a 0 from another
value.
1, x

or z

Turn-off delay
The turn-off delay is associated with a gate output transition to the high
impedance value (z) from another value.
If the value changes to x, the minimum of the three delays is considered.

76

Verilog HDL: A Guide to Digital Design and Synthesis

5=
Three types of delay specifications are allowed. If only one delay is specified, this
value is used for all transitions. If two delays are specified, they refer to the rise
and fall delay values. The turn-off delay is the minimum of the two delays. If all
three delays are specified, they refer to rise, fall, and turn-off delay values. If no
delays are specified, the default value is zero. Examples of delay specification are
shown in Example 5-9.
Example 5-9

Types of Delay Specification

II Delay of delay_time for all transitions


and # (delay_time) al(out, il, i2);
II Rise and Fall Delay Specification.
and # (rise_val, fall_val) a2(out, il, i2);
II Rise, Fall, and Turn-off Delay Specification
bufifO # (rise_val, fall_val, turnoff_vall bl (out, in, control);
Examples of delay specification are shown below.
and #(5) al(out, il, i2); IIDelay of 5 for all transitions
and #(4,6) a2(out, il, i2); II Rise = 4, Fall = 6
bufifO # (3,4,5) bl (out, in, control) ; / / Rise = 3, Fall = 4, Turn-off

5.2.2

Min/Typ/Max Values

Verilog provides an additional level of control for each type of delay mentioned
above. For each type of delay-rise, fall, and turn-off-three values, min, typ, and
max, can be specified. Anyone value can be chosen at the start of the simulation.
Mini typ I max values are used to model devices whose delays vary within a
minimum and maximum range because of the Ie fabrication process variations.
Min value
The min value is the minimum delay value that the designer expects the gate to
have.
Typval
The typ value is the typical delay value that the designer expects the gate to have.

Gate-Level Modeling

77

=5
Max value

The max value is the maximum delay value that the designer expects the gate to
have.
Min, typ, or max values can be chosen at Verilog run time. Method of choosing a
min/typ/max value may vary for different simulators or operating systems. (For
Verilog-XUM, the values are chosen by specifying options +maxdelays,
+typdelay, and +mindelays at run time. If no option is specified, the typical delay
value is the default). This allows the designers the flexibility of building three
delay values for each transition into their design. The designer can experiment
with delay values without modifying the design.
Examples of min, typ, and max value specification for Verilog-XL are shown in
Example 5-10.
Example 5-10

Min, Max and Typical Delay Values

II One delay
II i f +mindelays, delay=
II i f +typdelays, delay=
II i f +maxdelays, delay=
and #(4:5:6) al(out, il,

4
5
6
i2) ;

II
II
II
II

Two delays
if +mindelays, rise= 3,
if +typdelays, rise= 4,
if +maxdelays, rise= 5,
and #(3:4:5,5:6:7) a2(out,

II
II
II
II

Three delays
if +mindelays, rise= 2
if +typdelays, rise= 3
if +maxdelays, rise= 4
and #(2:3:4, 3:4:5, 4:5:6)

min(3,5)
min(4,6)
min(5,7)

fall= 5, turn-off
fall= 6, turn-off
fall= 7, turn-off
il, i2);

fall= 3
fall= 4
fall= 5
a3(out,

turn-off
turn-off
turn-off
il,i2);

4
5
6

Examples of invoking the Verilog-XL simulator with the command-line options


are shown below. Assume that the module with delays is declared in the file test.v.
Ilinvoke simulation with maximum delay
> verilog test.v +maxdelays

Ilinvoke simulation with minimum delay

78

Verilog HDL: A Guide to Digital Design and Synthesis

5=
> verilog test.v +mindelays

Ilinvoke simulation with typical delay


> verilog test.v +typdelays

5.2.3

Delay Example

Let us consider a simple example to illustrate the use of gate delays to model
timing in the logic circuits. A simple module called D implements the following
logic equations:
out= (a b) + c

The gate-level implementation is shown in Module D (Figure 5-8). The module


contains two gates with delays of 5 and 4 time units.
D
,------------,

I
I
I
I

a
b

Figure 5-8

I
I

out

I
L ____________ J

Module D

The module D is defined in Verilog as shown in Example 5-11.


Example 5-11

Verilog Definition for Module D with Delay

II Define a simple combination module called D


module D (out, a, b, c);
II 1/0 port declarations
output out;
input a,b,c;
II Internal nets
wire e;
II Instantiate primitive gates to build the circuit
and #(5) al(e, a, b); IIDelay of 5 on gate al

Gate-Level Modeling

79

=5
Example 5-11
or

Verilog Definition for Module D with Delay (Continued)

#(4) ol(out, e,c);

IIDelay of 4 on gate 01

endmodule

This module is tested by the stimulus file shown in Example 5-12.


Example 5-12

Stimulus for Module D with Delay

II Stimulus (top-level module)


module stimulus;
II Declare variables
reg A, B, C;
wire OUT;
II Instantiate the module D
D d1( OUT, A, B, C);
II Stimulate the inputs. Finish the simulation at 40 time units.
initial
begin
A= l'bO; B= l'bO; C= l'bO;
#10 A= l'b1; B= l'b1; C= l'b1;
#10 A= l'b1; B= l'bO; C= l'bO;
#20 $finish;
end
endmodule

The waveforms from the simulation are shown in Figure 5-9 to illustrate the effect
of specifying delays on gates. The waveforms are not drawn to scale. However,
simulation time at each transition is specified below the transition.

80

Verilog HDL: A Guide to Digital Design and Synthesis

5=

A
B

XXX~

OUT XXXXXXX

I""

I""

~I

I""

Time 0

Figure 5-9

Waveforms for Delay Simulation

9 10

14 15

~I

I""

20

~L

25

29

1. The outputs E and OUT are initially unknown.

2. At time 10, after A, B, and C all transition to


delay of 4 time units and E changes value to

1, OUT
1

transitions to
after 5 time units.

after a

3. At time 20, Band C transition to o. E changes value to 0 after 5 time units,


and OUT transitions to 0,4 time units after E changes.
It is a useful exercise to understand how the timing for each transition in the
above waveform corresponds to the gate delays shown in Module D.

5.3 Summary
In this chapter we discussed how to model gate-level logic in Verilog. We
discussed different aspects of gate-level design.
Basic types of gates are and, or, xor, buf, and not. Each gate has a logic
symbol, truth table, and a corresponding Verilog primitive. Primitives are
instantiated like modules except that they are predefined in Verilog. Output
of a gate is evaluated as soon as one of its inputs changes.

Gate-Level Modeling

81

For gate-level design, start with the logic diagram, write the Verilog
description for the logic by using gate primitives, provide stimulus, and
look at the output. Two design examples, a 4-to-1 multiplexer and a 4-bit full
adder, were discussed. Each step of the design process was explained.
Three types of delays are associated with gates, rise, fall, and turn-off. Verilog
allows specification of one, two, or three delays for each gate. Values of rise,
fall, and turn-off delays are computed by Verilog, based on the one, two, or
three delays specified.
For each type of delay, a minimum, typical, and maximum value can be
specified. The user can choose which value to apply at simulation time. This
provides the flexibility to experiment with three delay values without
changing the Verilog code.
The effect of propagation delay on waveforms was explained by the simple,
two-gate logic example. For each gate with a delay of t, the output changes t
time units after any of the inputs change.

5.4 Exercises
1. Create your own 2-input Verilog gates called my-or, my-and and my-not from
2-input nand gates. Check the functionality of these gates with a stimulus
module.
2. A 2-input x o r gate can be built from my-and, my-or and my-not gates.
Construct an x o r module in Verilog that realizes the logic function, z = xy' +
x'y. Inputs are X and y, and z is the output. Write a stimulus module that
exercises all four combinations of X and y inputs.

3. The l-bit full adder described in the chapter can be expressed in a sum of
products form.
sum = a.b.c-in + a'.b.c-in' + a'.b'.c-in + a.b'.c-in'
c-out = a.b + b.c-in + a.c-in
Assuming a, b, c-in are the inputs and sum and c-out are the outputs, design
a logic circuit to implement the l-bit full adder, using only and, not, and o r
gates. Write the Verilog description for the circuit. You may use up to 4-input
Verilog primitive and and o r gates. Write the stimulus for the full adder and
check the functionality for all input combinations.

Verilog HDL: A Guide to Digital Design and Synthesis

5=
4. The logic diagram for an RS latch with delay is shown below.

r------------,
reset

set

I
p--r.....,Ir-- q

P----">---!-I- qbar

__________ --.J

(reset)

Write the Verilog description for the RS latch. Include delays of 1 unit when
instantiating the nor gates. Write the stimulus module for the RS latch,
using the following table, and verify the outputs.
set

reset

qn+l

o
o

'In

Gate-Level Modeling

83

=5
5. Design a 2-to-I multiplexer using
r -

bufifO

and

bufifl

gates as shown below.

-,

bufifI
inI

-..,...--l

out

inO

bI
bufifO

L___

.J

The delay specification for gates bl and b2 are as follows.


Min

Typ

Max

Rise

Fall

Turnoff

Apply stimulus and test the output values.

84

Verilog HDL: A Guide to Digital Design and Synthesis

Dataflow Modeling
For small circuits, the gate-level modeling approach works very well because the
number of gates is limited and the designer can instantiate and connect every
gate individually. Also, gate-level modeling is very intuitive to a designer with a
basic knowledge of digital logic design. However, in complex designs the number
of gates is very large. Thus, designers can design more effectively if they
concentrate on implementing the function at a level of abstraction higher than
gate level. Dataflow modeling provides a powerful way to implement a design.
Verilog allows a circuit to be designed in terms of the data flow between registers
and how a design processes data rather than instantiation of individual gates.
Later in this chapter, the benefits of dataflow modeling will become more
apparent.
With gate densities on chips increasing rapidly, dataflow modeling has assumed
great importance. No longer can companies devote engineering resources to
handcrafting entire designs with gates. Currently, automated tools are used to
create a gate-level circuit from a dataflow design description. This process is
called logic synthesis. Dataflow modeling has become a popular design approach
as logic synthesis tools have become sophisticated. This approach allows the
designer to concentrate on optimizing the circuit in terms of data flow. For
maximum flexibility in the design process, designers typically use a Verilog
description style that combines the concepts of gate-level, data flow, and
behavioral design. In the digital design community , the term RTL (Register
Transfer Level) design is commonly used for a combination of dataflow modeling
and behavioral modeling.

Learning Objectives
Describe the continuous assignment (assign) statement, restrictions on the
assign statement, and the implicit continuous assignment statement.
Explain assignment delay, implicit assignment delay, and net declaration
delay for continuous assignment statements.
Define expressions, operators, and operands.

List operator types for all possible operations-arithmetic, logical, relational,


equality, bitwise, reduction, shift, concatenation, and conditional.
Use dataflow constructs to model practical digital circuits in Verilog.

6.1 Continuous Assignments


A continuous assignment is the most basic statement in dataflow modeling, used to
drive a value onto a net. A continuous assignment replaces gates in the
description of the circuit and describes the circuit at a higher level of abstraction.
A continuous assignment statement starts with the keyword assign. The syntax
of an assign statement is as follows.
//Syntax of assign statement in the simplest form
~continuous~assign~
. .. = assign <drive-strength>?<delay>? <list-of-assignments>;

Notice that drive strength is optional and can be specified in terms of strength
levels discussed in Section 3.2.1, Value Set. We will not discuss drive strength
specification in this chapter. The default value for drive strength is strong1 and
strongo.The delay value is also optional and can be used to specify delay on the
a s s i m statement. This is like specifying delays for gates. Delay specification is
discussed in this chapter. Continuous assignments have the following
characteristics.

1. The left hand side of an assignment must always be a scalar or vector net or
a concatenation of scalar and vector nets. It cannot be a scalar or vector
register. Concatenations are discussed in Section 6.4.8, Concatenation
Operator.
2. Continuous assignments are always active. The assignment expression is
evaluated as soon as one of the right-hand-side operands changes and the
value is assigned to the left-hand-side net.
3. The operands on the right-hand side can be registers or nets or function
calls. Registers or nets can be scalars or vectors.
4. Delay values can be specified for assignments in terms of time units. Delay
values are used to control the time when a net is assigned the evaluated
value. This feature is similar to specifying delays for gates. It is very useful
in modeling timing behavior in real circuits.

Verilog HDL: A Guide to Digital Design and Synthesis

Examples of continuous assignments are shown below. Operators such as &, /\, I,
{, } and + used in the examples are explained in Section 6.4, Operator Types. At this
point, concentrate on how the assign statements are specified.
Example 6-1

Examples of Continuous Assignment

II Continuous assign.
assign out = il & i2;

out is a net. i1 and i2 are nets.

II Continuous assign for vector nets. addr is a 16-bit vector net


II addr1 and addr2 are 16-bit vector registers.
assign addr[15:01

= addrl_bits[15:01

addr2_bits[15:01;

II Concatenation. Left-hand side is a concatenation of a scalar


II net and a vector net.
assign {c_out, sum[3:01}

= a[3:01

+ b[3:0]

+ c_in;

We now discuss a shorthand method of placing a continuous assignment on a net.

6.1.1

Implicit Continuous Assignment

Instead of declaring a net and then writing a continuous assignment on the net,
Verilog provides a shortcut by which a continuous assignment can be placed on a
net when it is declared. There can be only one implicit declaration assignment per
net because a net is declared only once.

In the example below, an implicit continuous assignment is contrasted with a


regular continuous assignment.
IIRegular continuous assignment
wire out;
assign out

inl & in2;

/ISame effect is achieved by an implicit continuous assignment


wire out = inl & in2;

Dataflow Modeling

87

=6
6.2 Delays

Delay values control the time between the change in a right-hand-side operand
and when the new value is assigned to the left-hand side. Three ways of
specifying delays in continuous assignment statements are regular assignment
delay, implicit continuous assignment delay, and net declaration delay.

6.2.1

Regular Assignment Delay

The first method is to assign a delay value in a continuous assignment statement.


The delay value is specified after the keyword assign. Any change in values of
inl or in2 will result in a delay of 10 time units before recomputation of the
expression inl & in2, and the result will be assigned to out. If inl or in2 changes
value again before 10 time units when the result propagates to out, the values of inl
and in2 at the time of recomputation are considered. This property is called inertial
delay. An input pulse that is shorter than the delay of the assignment statement
does not propagate to the output.
assign #10 out

in1 & in2; II Delay in a continuous assign

The waveform in Figure 6-1 is generated by simulating the above assign


statement. It shows the delay on signal out. Note the following changes.
1. When signals inl and in2 go high at time 20, out goes to a high 10 time units
later (time = 30).
2. When inl goes low at 60, out changes to low at 70.
3. However, inl changes to high at 80, but it goes down to low before 10 time
units have elapsed.
4. Hence, at the time of recomputation, 10 units after time 80, inl is o. Thus, out
gets the value O. A pulse of width less than the specified assignment delay is
not propagated to the output.

88

Verilog HDL: A Guide tv Digital Design and Synthesis

ll-

in!
I
I
I
I

in2
out

xxxxxi
I

time
Figure 6-1

10

I
I
I

20

30

60

70

8085

Delays

Inertial delays also apply to gate delays, discussed in Chapter 5, Gate-Level


Modeling.

6.2.2

Implicit Continuous Assignment Delay

An equivalent method is to use an implicit continuous assignment to specify both


a delay and an assignment on the net.
//implicit continuous assignment delay
wire #10 out = in1 & in2;
//same as
wire out;
assign #10 out

in1 & in2;

The declaration above has the same effect as defining a wire out and declaring a
continuous assignment on out.

6.2.3

Net Declaration Delay

A delay can be specified on a net when it is declared without putting a


continuous assignment on the net. If a delay is specified on a net out, then any
value change applied to the net out is delayed accordingly. Net declaration delays
can also be used in gate-level modeling.

Dataflow Modeling

89

IINet Delays
wire # 10 out;
assign out = in1 & in2;

liThe above statement has the same effect as the following.


wire out;
assign #10 out = in1 & in2;

Having discussed continuous assignments and delays, let us take a closer look at
expressions, operators, and operands that are used inside continuous
assignments.

6.3 Expressions, Operators, and Operands


Dataflow modeling describes the design in terms of expressions instead of
primitive gates. Expressions, operators, and operands form the basis of dataflow
modeling.

6.3.1

Expressions

Expressions are constructs that combine operators and operands to produce a


result.
II Examples of expressions. Combines operands and operators
a A b
addr1[20:17] + addr2[20:17]
in1 I in2

90

Verilog HDL: A Guide to Digital Design and Synthesis

6.3.2

Operands

Operands can be anyone of the data types defined in Section 3.2, Data Types.
Some constructs will take only certain types of operands. Operands can be
constants, integers, real numbers, nets, registers, times, bit-select (one bit of vector net
or a vector register), part-select (selected bits of the vector net or register vector),
memories or function calls (functions are discussed later).
integer count, final_count;
final_count = count + 1;llcount is an integer operand
real a, b , C;
c = a - b; Iia and b are real operands

reg [15:0) reg1, reg2;


reg [3:0) reg_out;
reg_out = reg1[3:0) A reg2[3:0);llreg1[3:0) and reg2[3:0) are
Ilpart-select register operands
reg ret_value;
ret_value
calculate-parity(A, B);llcalculate-parity is a
Ilfunction type operand

6.3.3

Operators

Operators act on the operands to produce desired results. Verilog provides


various types of operators. Operator types are discussed in detail in Section 6.4,

Operator Types.
d1 && d2 II && is an operator on operands d1 and d2
!a[O) II ! is an operator on operand a[O)
B 1 II is an operator on operands Band 1

Dataflow Modeling

91

=6
6.4 Operator Types

Verilog provides many different operator types. Operators can be arithmetic,


logical, relational, equality, bitwise, reduction, shift, concatenation, or conditional. Some
of these operators are similar to the operators used in the C programming
language. Each operator type is denoted by a symbol. Table 6-1 shows the
complete listing of operator symbols classified by category.
Table 6-1

Operator Types and Symbols

Operator
Type

Operator
Symbol

Arithmetic

*
/
+

Operation
Performed

Number of
Operands

multiply
divide
add
subtract
modulus

two
two
two
two
two
one
two
two

II

logical negation
logical and
logical or

Relational

>
<
>=
<=

greater than
less than
greater than or equal
less than or equal

two
two
two
two

Equality

==

equality
inequality
case equality
case inequality

two
two
two
two

bitwise
bitwise
bitwise
bitwise
bitwise

one
two
two
two
two

Logical

&:&:

!=

===
!==

Bitwise

&:

I
A
A_

or

_/\

&:
-&:

Reduction

I
-I
A
A_

92

or

_A

negation
and
or
xor
xnor

reduction and
reduction nand
reduction or
red uction nor
red uction xor
reduction xnor

Veri/og HDL: A Guide to Digital Design and Synthesis

one
one
one
one
one
one

Operator Types and Symbols (Continued)

Table 6-1

Operator
Type

Operation
Performed

Operator
Symbol

Shift
Concatenation
Replication
Conditional

?:

Number of
Operands

Right shift
Left shift

two
two

Concatenation

any number

Replication

any number

Conditional

three

Let us now discuss each operator type in detail.

6.4.1

Arithmetic Operators

There are two types of arithmetic operators: binary and unary.


Binary operators
Binary arithmetic operators are multiply (*), divide (t), add (+), subtract (-) and
modulus (%). Binary operators take two operands.
A
D

4'b0011; B = 4'b0100; II A and B are register vectors


6; E = 4; II D and E are integers

A * B II Multiply A and B. Evaluates to 4'b1100


DIE II Divide D by E.Evaluates to 1. Truncates any fractional part.
A + B II Add A and B. Evaluates to 4'b0111
B - A II Subtract A from B. Evaluates to 4'b0001

If any operand bit has a value x, then the result of the entire expression is x. This
seems intuitive because if an operand value is not known precisely, the result
should be an unknown.
in1
in2
sum

4'b101x;
4'b1010;
inl + in2;

II sum will be evaluated to the value 4'bx

Dataflow Modeling

93

=6
Modulus operators produce the remainder from the division of two numbers. They
operate similarly to the modulus operator in the C programming language.
13 % 3
16 % 4
-7 % 2
7 % -2

1/
1/
II
1/

Evaluates
Evaluates
Evaluates
Evaluates

to
to
to
to

1
0
-1, takes sign of the first operand
+1, takes sign of the first operand

Unary operators
The operators + and - can also work as unary operators. They are used to specify
the positive or negative sign of the operand. Unary + or - operators have higher
precedence than the binary + or - operators.

~4

II Negative 4
_ +5 II Positive 5

Negative numbers are represented as 2's complement internally in Verilog. It is


advisable to use negative numbers only of the type integer or real in expressions.
Designers should avoid negative numbers of the type <sss> '<base> <nnn> in
expressions because they are converted to unsigned 2's complement numbers and
hence yield unexpected results.
IIAdvisable to use integer or real numbers
-10 I 511 Evaluates to -2
liDo not use numbers of type <sss> '<base> <nnn>
-'d10 I 511 Is equivalent (2's complement of 10)/5 = (2 32
II where 32 is the default machine word width.
II This evaluates to an incorrect and unexpected result

6.4.2

10)/5

Logical Operators

Logical operators are logical-and (&:&:), logical-or (II) and logical-not (I). Operators
and I I are binary operators. Operator I is a unary operator. Logical operators
follow these conditions:
&:&:

94

Verilog HDL: A Guide to Digital Design and Synthesis

1. Logical operators always evaluate to a I-bit value, 0 (false), 1 (true), or x

(ambiguous).
2. If an operand is not equal to zero, it is equivalent to a logical 1 (true
condition). If it is equal to zero, it is equivalent to a logical 0 (false
condition). If any operand bit is x or z, it is equivalent to x (ambiguous
condition) and is normally treated by simulators as a false condition.
3. Logical operators take variables or expressions as operands.
Use of parentheses to group logical operations is highly recommended to improve
readability. Also, the user does not have to remember the precedence of operators.

II Logical operations
A = 3; B = 0;
A && B II Evaluates to O. Equivalent to (logical-1 && logical-OJ
A I I B II Evaluates to 1. Equivalent to (logical-1 I I logical-O)
!AII Evaluates to O. Equivalent to not(logical-1)
!BII Evaluates to 1. Equivalent to not(logical-O)
II Unknowns
A = 2'bOx; B = 2'b10;
A && B II Evaluates to x. Equivalent to (x && logical 1)
II Expressions
(a == 2) && (b == 3) II Evaluates to 1 if both a
are true.
II Evaluates to 0 if either is false.

6.4.3

2 and b

Relational Operators

Relational operators are greater-than (, less-than ), greater-than-or-equal-to (>=),


and less-than-or-equal-to =). If relational operators are used in an expression, the
expression returns a logical value of 1 if the expression is true and 0 if the
expression is false. If there are any unknown or z bits in the operands, the
expression takes a value x. These operators function exactly as the corresponding
operators in the C programming language.

II A
II X

4, B

4'b1010, Y

4'b1101, Z

4'b1xxx

A <= B II Evaluates to a logical 0


A > B II Evaluates to a logical 1

Dataflow Modeling

95

=6
y

>=

x II Evaluates to a logical 1
II Evaluates to an x

y < Z

6.4.4

Equality Operators

Equality operators are logical equality (==), logical inequality (I"), case equality (===),
and case inequality (I ==). When used in an expression, equality operators return
logical value 1 if true, if false. These operators compare the two operands bit by
bit, with zero filling if the operands are of unequal length. Table 6-2 lists the
operators.

Table 6-2

Equality Operators

Expression

Description

Possible Logical
Value

a == b

a equal to b, result unknown if x or z in a or b

0,1, x

a != b

a not equal to b, result unknown if x or z in a or b

O,l,x

a === b

a equal to b, including x and z

0,1

a !== b

a not equal to b, including x and z

0,1

It is important to note the difference between the logical equality operators (_ .. ,


1=) and case equality operators (===, I."), The logical equality operators (... , 1=)
will yield an x if either operand has x or z in its bits. However, the case equality
operators ( .... =, 1 == ) compare both operands bit by bit and compare all bits,
including x and z. The result is 1 if the operands match exactly, including x and z
bits. The result is if the operands do not match exactly. Case equality operators
never result in an x.

II A
II x
II Z

4, B

4'bl010, Y
4'blxxz, M

4'bllOl
4'blxxz, N

4'blxxx

A
B II Results in logical 0
X != Y II Results in logical 1
X
Z II Results in x
Z === M //Results in logical 1 (all bits match, including x and z)
Z === N / / Results in logical 0 (least significant bit does not match)
M !== N II Results in logical 1

96

Verilog HDL: A Guide to Digital Design and Synthesis

6.4.5

Bitwise Operators

Bitwise operators are negation (-), and(&), or (I), xor (A), xnor (1._, _A). Bitwise
operators perform a bit-by-bit operation on two operands. They take each bit in
one operand and perform the operation with the corresponding bit in the other
operand. If one operand is shorter than the other, it will be bit extended with
zeros to match the length of the longer operand. Logic tables for the bit-by-bit
computation are shown in Table 6-3. A z is treated as an x in a bitwise operation.
The exception is the unary negation operator (-), which takes only one operand
and operates on the bits of the single operand.
Table 6-3

Truth Tables for Bitwise Operators

bitwise and 0

bitwise or

0
x

x
1

bitwise xnor

x
x

bitwise xor

bitwise
ne ation

Result

Examples of bitwise operators are shown below.

II x
II Z

4'bl010, Y
4'blOxl

-x

II
II
II
II

X &Y
X I Y
X A Y

4'bllOl

Negation. Result is 4'b010l


Bitwise and. Result is 4'blOOO
Bitwise or. Result is 4'bllll
Bitwise xor. Result is 4'bOlll

Dataflow Modeling

97

X A_ Y
X & Z

II
II

Bitwise xnor. Result is 4'b1000


Result is 4'b10xO

It is important to distinguish bitwise operators -, &:, and


I,

I from logical operators

&:&:, II. Logical operators always yield a logical value 0, 1, x, whereas bitwise

operators yield a bit-by-bit value. Logical operators perform a logical operation,


not a bit-by-bit operation.

II x =

4'b1010, Y

4'bOOOO

I Y II bitwise operation. Result is 4'b1010


X I I Y II logical operation. Equivalent to 1 I I O. Result is 1.

6.4.6

Reduction Operators

Reduction operators are and (&:), nand (-&:), or (I), nor (-I), xor (A), and xnor(_A,
A_). Reduction operators take only one operand. Reduction operators perform a
bitwise operation on a single vector operand and yield a I-bit result. The logic
tables for the operators are the same as shown in Section 6.4.5, Bitwise Operators.
The difference is that bitwise operations are on bits from two different operands,
whereas reduction operations are on the bits of the same operand. Reduction
operators work bit by bit from right to left. Reduction nand, reduction nor, and
reduction xnor are computed by inverting the result of the reduction and, reduction
or, and reduction xor, respectively.

II x =

4'b1010

&X IIEquivalent to 1 & 0 & 1 & O. Results in 1'bO


IXIIEquivalent to 1 I
I 1 I O. Results in 1'b1
AXIIEquivalent to 1 A 0 A 1 A O. Results in 1'bO
IIA reduction xor or xnor can be used for even or odd parity
Ilgeneration of a vector.

The use of a similar set of symbols for logical (I, &:&:, I I), bitwise (-, &:, I, A), and
reduction operators (&:, I, A) is somewhat confusing initially. The difference lies in
the number of operands each operator takes and also the value of result
computed.

98

Verilog HDL: A Guide to Digital Design and Synthesis

6.4.7

Shift Operators

Shift operators are right shift ( ) and left shift (<<). These operators shift a vector
operand to the right or the left by a specified number of bits. The operands are
the vector and the number of bits to shift. When the bits are shifted, the vacant bit
positions are filled with zeros. Shift operations do not wrap around.

II x = 4'bllOO
y
Y
Y

x
X
X

1;
1;
2;

I Iy is 4'bOllO. Shift right 1 bit.O filled inMSB position.


IIYis 4'b1000.Shift left 1 bit. 0 filled inLSB position.
Ily is 4'bOOOO.Shift left 2 bits.

Shift operators are useful because they allow the designer to model shift
operations, shift-and-add algorithms for rimltiplication, and other useful
operations.

6.4.8

Concatenation Operator

The concatenation operator ( {, } ) provides a mechanism to append multiple


operands. The operands must be sized. Unsized operands are not allowed
because the size of each operand must be known for computation of the size of
the result.
Concatenations are expressed as operands within braces, with commas separating
the operands. Operands can be scalar nets or registers, vector nets or registers,
bit-select, part-select, or sized constants.

II A = l'bl, B = 2'bOO, C = 2'blO, D


Y
Y
Y

{B
{A
{A

3'bllO

C} II Result Y is 4'bOOlO
B, C , D , 3'bOOl} II Result Y is ll'b100l011000l
B[G], C[l]} II Result Y is 3'blG1

Dataflow Modeling

99

6.4.9

Replication Operator

Repetitive concatenation of the same number can be expressed by using a


replication constant. A replication constant specifies how many times to replicate
the number inside the brackets ( { } ).
reg
reg
reg
A
y
y
y

A;
[1:0] B, C;
[2: 0] D;
l'bl; B = 2'bOO; C

4{A}
4{A}
4{A}

2'bl0; D

3'bll0;

II Result Y is 4'bllll
2{B} } II Result Y is 8'bllll0000
2{B} , C } II Result Y is 8'bllll000010

6.4.10 Conditional Operator


The conditional operator(?:) takes three operands.

Usage: condition_expr ? true_expr : false_expr ;


The condition expression (condition_expr) is first evaluated. If the result is true
(logical 1), then the true_expr is evaluated. If the result is false (logical 0), then the
false_expr is evaluated. If the result is x (ambiguous), then both true_expr and
false_expr are evaluated and their results are compared, bit by bit, to return for
each bit position an x if the bits are different and the value of the bits if they are
the same.
The action of a conditional operator is similar to a multiplexer. Alternately, it can
be compared to the if-else expression.

2-to-l
multiplexer -----. Out
true_expr -----. 1

t
100

Verilog HDL: A Guide to Digital Design and Synthesis

6=
Conditional operators are frequently used in dataflow modeling to model
conditional assignments. The conditional expression acts as a switching control.
Ilrnodel functionality of a tristate buffer
assign addr_bus = drive_enable ? addr_out

36 'bz;

Ilrnodel functionality of a 2-to-l rnux


assign out = control? inl : inO;

Conditional operations can be nested. Each true_expr or false_expr can itself be a


conditional operation. In the example that follows, convince yourself that (A==3)
and control are the two select signals of 4-to-l multiplexer with n, m, y, x as the
inputs and out as the output signal.
assign out = (A == 3) ? ( control? x

y):

( control? rn

n)

6.4.11 Operator Precedence


Having discussed the operators, it is now important to discuss operator
precedence. If no parentheses are used to separate parts of expressions, Verilog
enforces the following precedence. Operators listed in Table 6-4 are in order from
highest precedence to lowest precedence. It is recommended that parentheses be
used to separate expressions except in case of unary operators or when there is no
ambiguity.
Table 6-4 Operator Precedence

Operators

Operator Symbols
+ -

Unary
Multiply, Divide, Modulus

* I

Add, Subtract

Shift

Relational
Equality

< <=
--

Precedence
Highest precedence

> >=

!= ---

!==

Dataflow Modeling

101

Table 6-4 Operator Precedence

Operators

Operator Symbols

Precedence

&, -&

Reduction

I, -I
A

Logical

&&

II
Conditional

?:

Lowest precedence

6.S Examples
A design can be represented in terms of gates, data flow, or a behavioral
description. In this section we consider the 4-to-l multiplexer and 4-bit full adder
described in Section 5.1.3, Examples. Previously, these designs were directly
translated from the logic diagram into a gate-level Verilog description. Here, we
describe the same designs in terms of data flow. We also discuss two additional
examples: a 4-bit full adder using carry lookahead and a 4-bit counter using negative
edge-triggered D-flipflops.

6.5.1

4-to-1 Multiplexer

Gate-level modeling of a 4-to-l multiplexer is discussed in Section 5.1.3, Examples.


The logic diagram for the multiplexer is given in Figure 5-5 on page 69 and the
gate-level Verilog description is shown in Example 5-4 on page 69. We describe
the multiplexer, using dataflow statements. Compare it with the gate-level
description. We show two methods to model the multiplexer by using dataflow
statements.
Method 1: logic equation

We can use assignment statements instead of gates to model the logic equations of
the multiplexer (see Example 6-2). Notice that everything is same as the gate-level
Verilog description except that computation of out is done by specifying one logic
equation by using operators instead of individual gate instantiations. I/O ports

102

Verilog HDL: A Guide to Digital Design and Synthesis

6=
remain the same. This is important so that the interface with the environment does
not change. Only the internals of the module change. Notice how concise the
description is compared to the gate-level description.
Example 6-2

4-to-l Multiplexer, Using Logic Equations

II Module 4-to-l multiplexer using data flow. logic equation


II Compare to gate-level model
module mux4_to_l (out, iO, il, i2, i3, sl, sO);
II Port declarations from the 1/0 diagram
output out;
input iO, il, i2, i3;
input s1, sO;

IlLogic equation for out


assign out =
(-sl & -sO & iO) I
(-sl & sO & il)
(sl & -sO & i2)
(sl & sO & i3) ;
endmodule

Method 2: conditional operator

There is a more concise way to specify the 4-to-1 multiplexers. In Section 6.4.10,
Conditional Operator, we described how a conditional statement corresponds to a
multiplexer operation. We will use this operator to write a 4-to-l multiplexer.
Convince yourself that this description (Example 6-3) correctly models a
multiplexer.
Example 6-3

4-to-l Multiplexer, Using Conditional Operators

II Module 4-to-l multiplexer using data flow. Conditional operator.


II Compare to gate-level model
module multiplexer4_to_1 (out, iO, i1, i2, i3, sl, sO);
II Port declarations from the 1/0 diagram
output out;
input iO, i1, i2, i3;
input s1, sO;

II Use nested conditional operator

Dataflow Modeling

103

Example 6-3
assign out

4-to-l Multiplexer, Using Conditional Operators


s1 ? ( sO ? i3 : i2)

(sO ? i1 : iO)

endmodule

In the simulation of the multiplexer, the gate-level module in Example 5-4 on


page 69 can be substituted with the dataflow multiplexer modules described
above. The stimulus module will not change. The simulation results will be
identical. By encapsulating functionality inside a module, we can replace the
gate-level module with a dataflow module without affecting the other modules in
the simulation. This is a very powerful feature of Verilog.

6.5.2

4-bit Full Adder

The 4-bit full adder in Section 5.1.3, Examples, was designed by using gates; the
logic diagram is shown in Figure 5-7 on page 73 and Figure 5-6 on page 72. In this
section, we write the dataflow description for the 4-bit adder. Compare it with the
gate-level description in Figure 5-7. In gates, we had to first describe a 1-bit full
adder. Then we built a 4-bit full ripple carry adder. We again illustrate two
methods to describe a 4-bit full adder by means of dataflow statements.

Method 1: dataflow operators


A concise description of the adder (Example 6-4) is defined with the + and { }
operators.
Example 6-4

4-bit Full Adder, Using Dataflow Operators

// Define a 4-bit full adder by using dataflow statements.


module fulladd4(sum, c_out, a, b, c_in);

// I/O port declarations


output [3:0] sum;
output c_out;
input[3:0] a, b;
input c_in;
// Specify the function of a full adder
assign {c_out, sum} = a + b + c_in;
endmodule

104

Verilog HDL: A Guide to Digital Design and Synthesis

If we substitute the gate-level 4-bit full adder with the dataflow 4-bit full adder,
the rest of the modules will not change. The simulation results will be identical.

Method 2: full adder with carry lookahead


In ripple carry adders, the carry must propagate through the gate levels before
the sum is available at the output terminals. An n-bit ripple carry adder will have
2n gate levels. The propagation time can be a limiting factor on the speed of the
circuit. One of the most popular methods to reduce delay is to use a carry
lookahead mechanism. Logic equations for implementing the carry lookahead
mechanism can be found in any logic design book. The propagation delay is
reduced to four gate levels, irrespective of the number of bits in the adder. The
Verilog description for a carry lookahead adder is shown in Example 6-5. This
module can be substituted in place of the full adder modules described before
without changing any other component of the simulation. The simulation results
will be unchanged.
Example 6-5

4-bit Full Adder With Carry Lookahead

module fulladd4(sum, c_out, a, b, c_in);


II Inputs and outputs
output [3:0] sum;
output c_out;
input [3:0] a,b;
input c_in;

II Internal wires
wire pO,gO, pl,gl, p2,g2, p3,g3;
wire c4, c3, c2, cl;
II compute the p for each stage
b[O],
assign pO
a[O]
b[l],
pI
a[l]
b[2],
p2
a[2]
b [3] ;
p3
a[3]
A
A
A

II compute the g for each stage


assign gO
a[O] & b[O],
gl
a[1] & b[l],
g2
a[2] & b[2],
g3
a[3] & b[3];
II compute the carry for each stage
II Note that c in is equivalent cO in the arithmetic equation for

Dataflow Modeling

105

Example 6-5

4-bit Full Adder With Carry Lookahead (Continued)

II carry lookahead computation


assign cl = gO I (pO & c_in) ,
c2 = gl I (pi & gO) I (pi & pO & c_in) ,
c3 = g2 I (p2 & gl) I (p2 & pi & gO) I (p2 & pi & pO & c_in) ,
c4 = g3 I (p3 & g2) I (p3 & p2 & gl) I (p3 & p2 & pi & gO) I
(p3 & p2 & pi & pO & c_in);
II Compute Sum
assign sum[O]
pO A c _in,
sum[l]
pi A cl,
p2 A c2,
sum[2]
p3 A c3;
sum[3]
II Assign carry output
assign c_out = c4;
endmodule

6.5.3

Ripple Counter

We now discuss an additional example that was not discussed in the gate-level
modeling chapter. We design a 4-bit ripple counter by using negative edgetriggered flip-flops. This example was discussed at a very abstract level in
Chapter 2, Hierarchical Modeling Concepts. We design it using Verilog dataflow
statements and test it with a stimulus module. The diagrams for the 4-bit ripple
carry counter modules are shown below.

106

Verilog HDL: A Guide to Digital Design and Synthesis

6=
Figure 6-2 shows the counter being built with four T-flipflops.

qO
r----

I
I
I

clock

clea

,
-

ql

- -

--

~ T]~~L.c I) T FFi---Lc ~
q

tffO

tffl

q3

q2

- q
T_FF
tff2

1------

f-"L..c )

q~
T_FF
tff3

I
I
I

_...J

Figure 6-2

4-bit Ripple Carry Counter

Figure 6-3 shows that the T-flipflop is built with one D-flipflop and an inverter gate.
TFF
q
r -

clock

"1

--r--O

reset
Figure 6-3

T-flipflop

Dataflow Modeling

107

Finally, Figure 6-4 shows the D-flipflop constructed from basic logic gates.

r--------------------------.
I
I
I
I
I
I

clear

cbar

I
I
I
I
I
I

elk
):>-""'"--ir--

Figure 6-4

q bar

I
I
I
I
I
I
I
I
L __________________________ JI

Negative Edge-Triggered D-flipflop with clear

Given the above diagrams, we write the corresponding Verilog, using dataflow
statements in a top-down fashion. First we design the module counter. The code is
shown in Figure 6-6. The code contains instantiation of four T_FF modules.
Example 6-6

Verilog Code for Ripple Counter

II Ripple counter
module counter(Q , clock, clear);
II I/O ports
output [3:0] Q;
input clock, clear;
II Instantiate
T_FF tffO(Q[O],
T_FF tffl(Q[l],
T_FF tff2(Q[2],
T_FF tff3(Q[3],

the T flipflops
clock, clear);
Q[O], clear);
Q[l], clear);
Q[2], clear);

endmodule

108

Verilog HDL: A Guide to Digital Design and Synthesis

Next, we write the Verilog description for T_FF (Example 6-7). Notice that instead
of the not gate, a dataflow operator - negates the signal q, which is fed back.
Example 6-7

Verilog Code for T-flipflop

II
II

Edge-triggered T-flipflop. Toggles every clock


cycle.
module T_FF(g, elk, clear};

II 1/0 ports
output g;
input elk, clear;
II
II
II

Instantiate the edge-triggered DFF


Complement of output g is fed back.
Notice gbar not needed. Unconnected port.
edge_dff ffl(g, ,-g, elk, clear};
endmodule

Finally, we define the lowest level module D _FF (edge_dff), using dataflow
statements (Example 6-8). The dataflow statements correspond to the logic
diagram shown in Figure 6-4. The nets in the logic diagram correspond exactly to
the declared nets.
Example 6-8

Verilog Code for Edge-Triggered D-flipflop

II Edge-triggered D flipflop
module edge_dff(g, qbar, d, elk, clear};
II Inputs and outputs
output g,gbar;
input d, elk, clear;
II Internal variables
wire s, sbar, r, rbar,cbar;
II dataflow statements
IICreate a complement of
assign cbar

II
II

signal clear

= -clear;

Input latches; A latch is level sensitive. An edge-sensitive


flip-flop is implemented by using 3 SR latches.

Dataflow Modeling

109

=6
Example 6-8
assign

Verilog Code for Edge-Triggered D-flipflop (Continued)


sbar = -(rbar & s) ,
s = -(sbar & cbar & -clk) ,
r = -(rbar & -clk & s) ,
rbar = -(r & cbar & d) ;

II Output latch
assign q = -(s & qbar) ,
qbar = -(q & r & cbar);
endrnodule

The design block is now ready. Now we must instantiate the design block inside
the stimulus block to test the design. The stimulus block is shown in
Example 6-9. The clock has a time period of 20 with a 50% duty cycle.
Example 6-9

Stimulus Module for Ripple Counter

II Top level stimulus module


module stimulus;
II Declare variables for stimulating input
reg CLOCK, CLEAR;
wire [3:0] Q;
initial
$monitor($time,

"Count Q = %b Clear= %b",

II Instantiate the design block counter


counter c1(Q, CLOCK, CLEAR);
II Stimulate the Clear Signal
initial
begin
CLEAR = l'b1;
#34 CLEAR = l'bO;
#200 CLEAR = l'b1;
#50 CLEAR = l'bO;
end
II Set up the clock to toggle every 10 time units
initial
begin

110

Verilog HDL: A Guide to Digital Design and Synthesis

Q[3:0]'CLEAR);

Stimulus Module for Ripple Counter (Continued)

Example 6-9

CLOCK = l'bO;
forever #10 CLOCK

-CLOCK;

end
II Finish the simulation at time 400
initial
begin
#400 $finish;
end

endmodule

The output of the simulation is shown below. Note that the clear signal resets the
count to zero.
0
34
40
60
80
100
120
140
160
180
200
220
234
284
300
320
340
360
380

Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count

Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q
Q

0000
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
0000
0000
0001
0010
0011
0100
0101

Clear=
C1ear=
Clear=
Clear=
Clear=
C1ear=
Clear=
Clear=
Clear=
Clear=
Clear=
Clear=
Clear=
Clear=
C1ear=
Clear=
Clear=
Clear=
C1ear=

Dataflow Modeling

1
0
0
0
0
0
0
0
0

a
0
0
1
0

a
0
0
0
0

111

6.6 Summary
Continuous assignment is one of the main constructs used in dataflow
modeling. A continuous assignment is always active and the assignment
expression is evaluated as soon as one,of the right-hand-side variables
changes. The left-hand side of a contiduous assignment must be a net. Any
logic function can be realized with continuous assignments.
Delay values control the time between the change in a right-hand-side
variable and when the new value is assigned to the left-hand side. Delays on
a net can be defined in the assign statement, implicit continuous
assignment, or net declaration.
Assignment statements contain expressions, operators, and operands.
The operator types are arithmetic, logical, relational, equality, bitwise, reduction,
shift, concatenation, replication, and conditional. Unary operators require one
operand, binary operators require two operands, and ternary require three
operands. The concatenation operator can take any number of operands.
The conditional operator behaves like a multiplexer in hardware or like the ifthen-else statement in programming languages.
Dataflow description of a circuit is more concise than a gate-level
description. The 4-to-1 multiplexer and the 4-bit full adder discussed in the
gate-level modeling chapter can also be designed by use of dataflow
statements. Two dataflow implementations for both circuits were discussed.
A 4-bit ripple counter using negative edge-triggered D-flipflops was
designed.

6.7 Exercises
1. A full subtractor has three l-bit inputs X , y, and z (previous borrow) and two
l-bit outputs D (difference) and B (borrow). The logic equations for D and B
are as follows:

Verilog HDL: A Guide to Digital Design and Synthesis

Write the full Verilog description for the full subtractor module, including
I/O ports (Remember that + in logic equations corresponds to a logical or
operator (II) in dataflow). Instantiate the subtractor inside a stimulus block
and test all eight possible combinations of x, y, and z given in the following
truth table.
x

0
0

2. A magnitude comparator checks if one number is greater than or equal to or


less than another number. A 4-bit magnitude comparator takes two 4-bit
numbers, A and B, as input. We write the bits in A and B as follows.
Leftmost bit is the most significant bit.
A

= A(3) A(2) A(l) A(O)

B = B(3) B(2) B(l) B(O)


The magnitude can be compared by comparing the numbers bit by bit,
starting with the most significant bit. If any bit mismatches, the number
with bit a is the lower number. To realize this functionality in logic
equations, let us define an intermediate variable. Notice that the function
below is an xnor function.
x(i) = A(i).B(i) + A(i)'.B(i)'

The three outputs of the magnitude comparator are A-$t_B, A_lt_B, A_eq_B.
They are defined with the following logic equations.
A-$t_B = A(3).B(3)' + x(3).A(2).B(2/ + x(3).x(2).A(l).B(1/ +
x(3).x(2).x(l).A(O).B(O)'
A_lt_B = A(3)'.B(3) + x(3).A(2)'.B(2) + x(3).x(2).A(l)'.B(l) +
x(3).x(2).x(1).A(O)'.B(O)
A_eq_B

= x(3).x(2).x(1).x(O)

Dataflow Modeling

113

=6
Write the Verilog description of the module magnitude_comparator. Instantiate
the magnitude comparator inside the stimulus module and tryout a few
combinations of A and B.

3. A synchronous counter can be designed by using master-slave JK flip-flops.


Design a 4-bit synchronous counter. Circuit diagrams for the synchronous
counter and the JK flip-flop are given bellow. Clear signal is active low. Data
gets latched on the positive edge of clock, and the output of the flip-flop
appears on the negative edge of clock. Counting is disabled when
count_enable signal is low. Write the dataflow description for the
synchronous counter. Write a stimulus file that exercises clear and
count_enable. Display the output count Q[3:0}.
J----l

clear --+-+---~.--"*---+-----,

+-- qbar

IO-".....

K--t--l

clock --+-------1 __...J


cbar
Figure 6-5

Master-Slave IK-flipflop

0[0]

0[1]

0[3]

0[2]

o
K
clear-~~~r-t--r-i~~-t-~-i-+~~-r-+--+~~

clock -----1-t--+-+---+-+--+-+---I-+--+-+----1---1

count ----1~--+---l
enable
Figure 6-6

114

4-bit Synchronous Counter with clear and count_enable

Verilog HDL: A Guide to Digital Design and Synthesis

Behavioral Modeling
With the increasing complexity of digital design, it has become vitally important
to make wise design decisions early in a project. Designers need to be able to
evaluate the trade-offs of various architectures and algorithms before they decide
on the optimum architecture and algorithm to implement in hardware. Thus,
architectural evaluation takes place at an algorithmic level where the designers do
not necessarily think in terms of logic gates or data flow but in terms of the
algorithm they wish to implement in hardware. They are more concerned about
the behavior of the algorithm and its performance. Only after the high-level
architecture and algorithm are finalized, do designers start focusing on building
the digital circuit to implement the algorithm.
Verilog provides designers the ability to describe design functionality in an
algorithmic manner. In other words, the designer describes the behavior of the
circuit. Thus, behavioral modeling represents the circuit at a very high level of
abstraction. Design at this level resembles C programming more than it resembles
digital circuit design. Behavioral Verilog constructs are similar to C language
constructs in many ways. Verilog is rich in behavioral constructs that provide the
designer with a great amount of flexibility.
Learning Objectives
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 i f 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.
Understand naming of blocks and disablin of named blocks.
Use behavioral modeling statements in practical examples.

7.1 Structured Procedures


There are two structured procedure statements in Verilog: always and i n i t i a l .
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 i n i t i a l statement represents a
separate activity flow in Verilog. Each activity flow starts at simulation time 0.
The statements always and i n i t i a l cannot be nested. The fundamental
difference between the two statements is explained in the following sections.

7.1.1

initial Statement

All statements inside an i n i t i a l statement constitute an i n i t i a l block. An


i n i t i a l block starts at time 0, executes exactly once during a simulation, and
then does not execute again. If there are multiple i n i t i a l 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 I 1 grouping in the C programming
language. Example 7-1 illustrates the use of the i n i t i a l statement.
Example 7-1

initial Statement

module stimulus;
reg x,y, a,b, m;

initial

116

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-1
m

initial Statement
l'bO; //sing1e statement; does not need to be grouped

initial
begin
#5 a = l'b1; //mu1tip1e statements; need to be grouped
#25 b = l'bO;
end
initial
begin
#lOx
#25 y
end

l'bO;
l'b1;

initial
#50 $finish;
endmodule

In the above example, the three initial statements start to execute in parallel at time
O. 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
0
5
10
30
35
50

statement executed
m
l'bO;
a = l'b1;
x = l'bO;
b
l'bO;
l'bl;
Y
$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.

Behavioral Modeling

117

=7
7.1.2

always Statement

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 7-2 illustrates one method to model a clock generator in Verilog.
Example 7-2

always Statement

module clock_gen;
reg clock;
//Initialize clock at time zero
initial
clock = l'bO;
//Toggle clock every half-cycle (time period
always
#10 clock = -clock;

20)

initial
#1000 $finish;
endmodule

In Example 7-2, 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).

118

Verilog HDL: A Guide to Digital Design and Synthesis

7.2 Procedural Assignments


Procedural assignments update values of reg, integer, real, or t i m e 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 discussed in Chapter 6, 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 syntax for the simplest form
of procedural assignment is shown below.

The left-hand side of a procedural assignment <lvalue> can be one of the


following:
A reg, integer, real, or time register variable or a memory element
A bit select of these variables (e.g., addr[Ol)

A part select of these variables (e.g., addr[31:161)


A concatenation of any of the above
The right-hand side can be any expression that evaluates to a value. In behavioral
modeling all operators listed in Table 6-1 on page 92 can be used in behavioral
expressions.
There are two types of procedural assignment statements: blocking and
nonblocking.

7.2.1

Blocking assignments

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. Both parallel and sequential blocks are discussed in
Section 7.7, Sequential and Parallel Blocks, The = operator is used to specify
blocking assignments.
Example 7-3

Blocking Statements

reg X, y, z ;
reg r15: 01 reg-a, reg-b;
integer count;

Behavioral Modeling

119

Example 7-3

Blocking Statements (Continued)

//All behavioral statements must be inside an initial or always bloc:


initial
begin
x = O ; y = l ; z = 1; //Scalar assignments
count = 0; //Assignment to integer variables
reg-a = 16'bO; reg-b = reg-a; //initialize vectors
#l5 reg-a[21 = l r b l ; //Bit select assignment with delay
#l0 reg-b[15:131 = { X , y, z) //Assign result of concatenation tc
/ / part select of a vector
count = count + 1; //Assignment to an integer (increment)
end

In Example 7-3, 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:
All statements X = 0 through reg-b = reg-a are executed at time 0
Statement regal21 = 0 at time = 15
Statement reg-bl15:131 = {X, y, zl at time = 25
Statement count = count + 1 at time = 25
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 right-hand side has fewer bits, zeros are filled in
the most significant bits of the register variable.

7.2.2

Nonblocking Assignments

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

120

Verilog HDL: A Guide to Digital Design and Synthesis

7=
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 7-4, convert some blocking assignments to nonblocking assignments,
and observe the behavior.
Example 7-4

Nonblocking Assignments

reg x, y, z;
reg [15:0] reg_a, reg_b;
integer count;

IIAII behavioral statements must be inside an initial or always block


initial
begin
x = 0; y = 1; z = 1; IIScalar assignments
count
0; IIAssignment to integer variables
reg_a = 16'bO; reg_b = reg_a; IIInitialize vectors
reg_a[2j <= #15 l'bl; IIBit select assignment with delay
reg_b[15:13] <= #10 {x, y, z}; IIAssign result of concatenation
lito part select of a vector
count <= count + 1; IIAssignment to an integer (increment)
end

In this example the statements x = 0 through reg_b = reg_a are executed


sequentially at time O. Then, the three nonblocking assignments are processed at
the same simulation time.
1. reg_a[2] = 0 is scheduled to execute after 15 units (i.e., time = 15)
2. reg_b[15:13] = {x,
10)

y, zj is scheduled to execute after 10 time units (i.e., time =

3. count = count + 1 is scheduled to be executed without any delay (i.e., time

0)
Thus, the simulator schedules a non blocking 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.

Behavioral Modeling

121

=7
Application of nonblocking assignments

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.
always @(posedge clock)
begin
reg1 <= #1 in1;
reg2 <= @(negedge clock) in2 A in3;
reg3 <= #1 reg1; liThe old value of reg1
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, inl, in2, in3,
and regl, 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 regl 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 regl that was stored after the read operation, even if the write operation
wrote a new value to regl before the write operation to reg3 was executed.
Thus, the final values of regl, 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 7-5, which
is intended to swap the values of registers a and b at each positive edge of clock,
using two concurrent always blocks.

122

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-5

Nonblocking Statements to Eliminate Race Conditions

//I11ustration 1: Two concurrent always blocks with blocking


//statements
always @(posedge clock)
a = b;
always @(posedge clock)
b = a;

//I11ustration 2: Two concurrent always blocks with nonblocking


//statements
always @(posedge clock)
a <= b;
always @(posedge clock)
b <= a;

In Example 7-5, 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 assigned to the left-hand-side 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 7-6 shows how nonblocking assignments in illustration 2 might be
processed by a simulator.
Example 7-6

Processing of Nonblocking Assignments

//Process nonblocking assignments by using temporary variables


always @(posedge clock)
begin
//Read operation
/ /storevalues of right-hand-side expressions in temporary variables
temp_a
a;
temp_b = b;

Behavioral Modeling

123

=7
Example 7-6

Processing of Nonblocking Assignments (Continued)

IIWrite operation
IIAssign values of temporary variables to left-hand-side variables
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 a degradation in the simulator
performance and increase in memory usage.

7.3 Timing Controls


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.

7.3.1

Delay-Based 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>

: :=

#<NUMBER>
11= #<identifier>
11= #mintypmax_expression> <,<mintypmax_expression*)

124

Verilog HDL: A Guide to Digital Design and Synthesis

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

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 7-7.
Example 7-7

Regular Delay Control

Iidefine parameters
parameter latency
20;
parameter delta = 2;
Iidefine register variables
reg x, y, z, p, q;
initial
begin
x = 0; II no delay control
#10 y = 1; II delay control with a number. Delay execution of
II y = 1 by 10 units
#latency z = 0; //Delay control with identifier. Delay of 20 units
# (latency + delta) p = 1; II Delay control with expression
#y x

=x

+ 1;

#(4:5:6) q

II Delay control with identifier. Take value of y.

= 0;

II Minimum, typical and maximum delay values.


//Discussed in gate-level modeling chapter.

end

In Example 7-7, 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.

Behavioral Modeling

125

Intra-assignment delay control


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 7-8 shows the contrast
between intra-assignment delays and regular delays.
Example 7-8

Intra-assignment Delays

Iidefine register variables


reg x, y, z;
Ilintra assignment delays
initial
begin
x = 0; z = 0;
y = #5 x + z; IITake value of x and z at the time=O, evaluate
Ilx + z and then wait 5 time units to assign value
lito y.
end
,

IIEquivalent method with temporary variables and regular delay control


initial
begin
x = 0; z = 0;
temp_xz = x + z;
#5 y = temp_xz; IITake value of x + z at the current time and
Iistore it in a temporary variable. Even though x and z
Ilmight change between 0 and 5,
lithe value assigned to y at time 5 is unaffected.
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 right-hand-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.

126

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Zero delay control

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 7-9 illustrates zero delay control.
Zero Delay Control

Example 7-9
initial
begin
x = 0;
Y

0;

end
initial
begin
#0 x
#0 y
end

1; //zero delay control


1;

In Example 7-9, four statements-x = 0, y = 0, x = I, Y = I-are to be executed at


simulation time O. However, since x = 1 and y = 1 have #0, they will be executed
last. Thus, at the end of time 0, x will have value 1 and y will have value 1. The
order in which x = 1 and y = 1 are executed is not deterministic.
The above example was used as an illustration. The practice of assigning two
different values to a variable in a single time step is generally not recommended
and may cause race conditions in the design. However, #0 provides a useful
mechanism to control the order of execution of statements in a simulation.

7.3.2

Event-Based Timing Control

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.

Behavioral Modeling

127

=7
Regular event 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 po.edge is used for a negative transition, as shown in
Example 7-10.
Example 7-10

Regular Event Control

@(clock) g = d; Ilg = d is executed whenever signal clock changes value


@(posedge clock) g = d; Ilg = d is executed whenever signal clock does
Iia positive transition ( 0 to 1,x or z,
II x to 1, z to 1 )
@(negedge clock) g
d; Ilg = d is executed whenever signal clock does
Iia negative transition ( 1 to O,X or z,
Ilx to 0, z to 0)
g
@(posedge clock) d; lid is evaluated immediately and assigned
lito g at the positive edge of clock

Named event control

Verilog provides the capability to declare an event and then trigger and recognize
the occurrence of that event (see Example 7-11). 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 @.
Example 7-11

Named Event Control

IIThis is an example of a data buffer storing data after the


Illast packet of data has arrived.
event received_data;

IIDefine an event called received_data

always @(posedge clock) Ilcheck at each positive clock edge


begin
if (last_data-packet) IIIf this is the last data packet
->received_data; Iitrigger the event received_data
end
always @(received_data)

128

IIAwait triggering of event received_data


IIWhen event is triggered, store all four

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Named Event Control (Continued)

Example 7-11

/Ipackets of received data in data buffer


/Iuse concatenation operator { }
data_buf={data-pkt[O] , data-pkt[l] , data-pkt[2] , data-pkt[3]};

Event OR control

Sometimes a transition on anyone 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 7-12.
Example 7-12

Event OR Control

//A level-sensitive latch with asynchronous reset


always @( reset or clock or d)
/IWait for reset or clock or d to change
begin
if (reset)
I l i f reset signal is high, set q to O.
q = 1 'bO;
else
if(clock)
/Iif clock is high, latch input
q = d;
end

7.3.3

Level-Sensitive Timing Control

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
wait (count_enable) #20 count

count + 1;

Behavioral Modeling

129

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 I, count will be
incremented every 20 time units.

7.4 Conditional Statements


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 i f and else are used for conditional statements.
There are three types of conditional statements. Usage of conditional statements
is shown below. For formal syntax, see Appendix D, Formal Syntax Definition.
//Type 1 conditional statement. No else statement.
//Statement executes or does not execute.
if expression true_statement;
//Type 2 conditional statement. One else statement
//Either true_statement or false_statement is evaluated
if expression true_statement; else false_statement
//Type 3 conditional statement. Nested if-else-if.
//Choice of multiple statements. Only one is executed.
if expressionl true_statementl ;
else if expression2 true_statement2
else if expression3 true_statement3
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 or z), the
false_statement is executed. The <expression> can contain any operators mentioned
in Table 6-1 on page 92. 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.
Example 7-13

Conditional Statement Examples

//Type 1 statements
if(!lock) buffer = data;
if (enable) out = in;

130

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-13

Conditional Statement Examples (Continued)

//Type 2 statements
if (number_queued < MAX_Q_DEPTH)
begin
data_queue = data;
number_queued = number_queued + 1;
end
else
$di splay ( "Queue Full. Try again");
//Type 3 statements
//Execute statements based on ALU control signal.
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");

7.S Multiway Branching


In type 3 conditional statement in Section 7.4, 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.

Behavioral Modeling

131

=7
7.5.1

case Statement

The keywords case, endcase, and defaul t are used in the case statement. .
case (expression)
alternativel: statementl;
alternative2: statement2;
alternative3: statement3;

default: default_statement;
endcase

Each of statementl, 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 match, 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 7-13.
//Execute statements based on the ALU control signal
reg [1:0] alu_control;

case (alu_control)
2'dO
y
x + z;
2'd1 : y = x - z;
2'd2 : y = X * z;
default: $display("Invalid ALU control signal");
endcase

132

Verilog HDL: A Guide to Digital Design and Synthesis

The case statement can also act like a many-to-one multiplexer. To understand
this, let us model the 4-to-1 multiplexer in Section 6.5, Examples, on page 102,
using case statements. The I/O ports are unchanged. Notice that an 8-to-1 or 16to-1 multiplexer can also be easily implemented by case statements.
Example 7-14

4-to-1 Multiplexer with case Statement

module mux4_to_1 (out, iO, i1, i2, i3, sl, sO);


II Port declarations from the I/O diagram
output out;
input iO, i1, i2, i3;
input s1. sO;
reg out;

always @(sl or sO or iO or i1 or i2 or i3)


case ({sl, sO}) //Switch based on concatenation of control signals
2'dO
out
iO;
2'd1
out
i1;
2'd2
out
i2;
2'd3
out
i3;
default: $display("Invalid control signals");
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 7-15, 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.
Example 7-15

Case Statement with x and z

module demultiplexerl_to_4 (outO, outl, out2, out3, in, sl, sO);


II Port declarations from the I/O diagram
output outO, out1, out2, out3;
reg outO,
out1,
out2,
out3;
input in;
input sl, sO;

Behavioral Modeling

133

Example 7-15

Case Statement with X and z (Continued)

ilways @(sl or SO or in)


:ase ({sl, SO)) //Switch based on control signals
2 'b00 : begin outO = in; outl = l'bz; out2 = l'bz;out3 =
2'bOl : begin outO = l'bz; outl = in; out2 = l'bz;out3 =
2'blO : begin outO = l'bz; outl = l'bz; out2 = in; out3 =
2'bll : begin outO = l'bz; outl = l'bz; out2 = l'bz; out3

l'bz;enc
l'bz;enc
l'bz; enc
= in; enc

//Account for unknown signals on select. If any select signal is >


//then outputs are X. If any select signal is z, outputs are z.
//If one is X and the other is z, X gets higher priority.
2'bx0, 2'bxl, 2'bxz, 2'bxx, 2'bOx, 2'blx, 2'bzx :
begin
out0 = l'bx; outl = l'bx; out2 = l'bx; out3 = l'bx;
end
2'bz0, 2'bzl, 2'bzz, 2'bOz, 2'blz :
begin
outO = l'bz; outl = l'bz; out2 = l'bz; out3 = l'bz;
end
default: $display("Unspecified control signals");
ndcase

In the demultiplexer shown above, multiple input signal combinations such as


2'bz0,2'bzl, 2,bzz, 2'bOz, and 2'bIz that cause the same block to be executed are
put together with a comma (,) symbol.

7.5.2

casex, casez Keywords

There are two variations of the


casex and casez.

case

statement. They are denoted by keywords,

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
don't cares.

values in the case item or the case expression as

Verilog HDL: A Guide to Digital Design and Synthesis

7=
The use of casex and casez allows comparison of only non-x or -z positions in
the case expression and the case alternatives. Example 7-16 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.
Example 7-16

casex Use

reg [3:0) encoding;


integer state;
casex (encoding) Illogic value x represents a don't care bit.
3;
4'blxxx
next _state
next _state
4'bx1xx
2;
4'bxx1x
next _state
1;
4'bxxxi
next state
0;
default
next _state
0;
endcase

Thus, an input encoding = 4'blOxz would cause next_state = 3 to be executed.

7.6 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.

7.6.1

While Loop

The keyword while is used to specify this loop. The while loop executes until the
while-expression becomes false. If the loop is entered when the while-expression is
false, the loop is not executed at all. Each expression can contain the operators in
Table 6-1 on page 92. 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 7-17 illustrates the
use of the while loop.

Behavioral Modeling

135

=7
Example 7-17

While Loop

//Illustration 1: Increment count from 0 to 127. Exit at count 128.


//Display the count variable.
integer count;
initial
begin
count

0;

while (count < 128) //Execute loop till count is 127.


//exit at count 128
begin
$display("Count = %d", count);
count = count + 1;
end
end

//Illustration 2: Find the first bit with a value 1 in flag (vector


variable)
'define TRUE l'b1';
'define FALSE l'bO;
reg [15:0] flag;
integer i; //integer to keep count
reg continue;
initial
begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
continue
'TRUE;
while((i < 16) && continue) //Multiple conditions using
operators.
begin
i f (flag[i])
begin
$display("Encountered a TRUE bit at element number %d", i);
continue = 'FALSE;
end
i = i + 1;
end
end

136

Verilog HDL: A Guide to Digital Design and Synthesis

7.6.2

For Loop

The keyword for is used to specify this loop. The for loop contains three parts:
An initial condition
A check to see if the terminating condition is true
A procedural assignment to change value of the control variable
The counter described in Example 7-17 can be coded as a for loop (Example 718). 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. p
Example 7-18

For Loop

integer count;
initial
for

count=O; count < 128; count = count + 1)


$display("Count = %do, count);

for loops can also be used to initialize an array or memory, as shown below.

//Initialize array elements


'define MAX-STATES 32
integer state [O: 'MAX-STATES-l]; //~ntegerarray state with elements 0:31
integer i;
initial
begin
for(i = 0; i < 32; i = i + 2) //initialize all even locations with C
state[il = 0;
for(i = 1; i < 32; i = i + 2) //initialize all odd locations with 1
state[il = 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
Ioop.

Behaz~ioralModeling

7.6.3

Repeat 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 7-17 can be expressed with the repeat loop, as shown in
Illustration 1 in Example 7-19. 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.
Example 7-19

Repeat Loop

//Illustration 1 : increment and display count from


integer count;
initial
begin
count = 0;
repeat(128)
begin
$display("Count = %d", count);
count = count + 1;
end
end
//Illustration 2 : Data buffer module example
//After it receives a data_start signal.
//Reads data for next 8 cycles.
module data_buffer (data_start, data, clock);
parameter cycles = 8;
input data_start;
input [15:0] data;
input clock;
reg [15:0] buffer [0:7];
integer i;
always @(posedge clock)
begin

138

Verilog HDL: A Guide to Digital Design and Synthesis

to 127

7=
Example 7-19

Repeat Loop (Continued)

if (data_start) Iidata start signal is true


begin
i = 0;
repeat (cycles) IIStore data at the posedge of next 8 clock

Ilcycies
begin
@(posedge clock) buffer[i]
i
end
end
end

=i

data;

Ilwaits till next

II posedge to latch data


+ 1;

endmodule

7.6.4

Forever loop

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 7-20 explains the use of the forever
statement.
Example 7-20

Forever Loop

IIExample 1: Clock generation


//Use forever loop instead of always block
reg clock;
initial
begin
clock = l'bO;
forever #10 clock

-clock; //Clock with period of 20 units

end

Behavioral Modeling

139

Example 7-20

Forever Loop

//Example 2: Synchronize two register values at every positive edge of


//clock
reg clock;
reg X, Y;
initial
forever @(posedge clock)

X =

y;

7.7 Sequential and Parallel Blocks


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.

7.7.1

Block Types

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.
Sequential blocks have the following characteristics:
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 intraassignment 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 7-21. 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.

Verilog HDL: A Guide to Digital Design and Synthesis

Example 7-21

Sequential Blocks

//Illustration 1: Sequential block without delay


reg X, Y;
reg [1:0] z , W;
initial
begin
l'bO;
y = l'bl;
z = {X, y};
W = I Y , x3;
X =

end
//Illustration 2: Sequential blocks with delay.
re9 X, Y;
reg [1:0] z , W;
initial
begin
= l'bO; //completes at simulation time 0
#5 y = l'bl; //completes at simulation time 5
#l0 z = {X, y}; //completes at simulation time 15
#20 W = {y, X ) ; //completes at simulation time 35

end

Parallel blocks
Parallel blocks, specified by keywords fork and join, provide interesting
simulation features. Parallel blocks have the following characteristics.
Statements in a parallel block are executed concurrently.
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.

Behavioral Modeling

=7
Let us consider the sequential block with delay in Example 7-21 and convert it to
a parallel block. The converted Verilog code is shown in Example 7-22. The result
of simulation remains the same except that all statements start in parallel at time O.
Hence, the block finishes at time 20 instead of time 35.
Example 7-22

Parallel Blocks

//Example 1: Parallel blocks with delay.


reg x, y;
reg [ 1 : 0 ] z, w;
initial
fork
x = l'bO; //completes at simulation time 0
#5 y = l'b1; //completes at simulation time 5
#10 z
{x, y}; //completes at simulation time 10
#20 w = {y, x}; //completes at simulation time 20
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 7-21. Race conditions have been deliberately introduced in this
example. All statements start at simulation time O. The order in which the
statements will execute is not known. Variables z and w will get values 1 and 2 if
x = l'bO and y = 1'bl execute first. Variables z and w will get values 2'bxx and
2'bxx if x = l'bO and y = 1'bl 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.
//Parallel blocks with deliberate race condition
reg x, y;
reg [1:0] z, w;
initial
fork
x
y

142

l'bO;
l'b1;

Verilog HDL: A Guide to Digital Design and Synthesis

7=
z = {x,
w
{y,

I join

y};
x};

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.

7.7.2

Special Features of Blocks

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 7-23.
Example 7-23

Nested Blocks

/ !Nested blocks
initial
begin
x = 1 'bO;
fork
#5 Y = l'b1;
#10 z = {x, y};
join
{y, x};
#20 w
end

Named blocks
Blocks can be given names.
Local variables can be declared for the named block.
Named blocks are a part of the design hierarchy. Variables in a named block
can be accessed by using hierarchical name referencing.
Named blocks can be disabled, i.e., their execution can be stopped.

Behavioral Modeling

143

=7
Example 7-24 shows naming of blocks and hierarchical naming of blocks.
Example 7-24

Named Blocks

IINamed blocks
module top;
initial
begin: blockl Iisequential block named block1
integer i; Ilinteger i is static and local to block1
II can be accessed by hierarchical name, top.block1.i

end
initial
fork: block2 Ilparallel block named block2
reg i; II register i is static and local to block2
II can be accessed by hierarchical name, top.block2.i

join

Disabling named blocks


The keyword disable provides a way to terminate the execution of a 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. The difference is that a break statement can break the current loop only,
whereas the keyword disable allows disabling of any named block in the design.
Consider the illustration in Example 7-17 on page 136, which looks for the first
true bit in the flag. The while loop can be recoded, using the disable statement as
shown in Example 7-25. The disable statement terminates the while loop as soon
as a true bit is seen.
Example 7-25

Disabling Named Blocks

//Illustration:Find the first bit with a value 1 in flag (vector


Ilvariable)
reg [15:0] flag;
integer i; Ilinteger to keep count

144

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-25

Disabling Named Blocks

initial
begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
begin: block1 liThe main block inside while is named block1
while (i < 16)
begin
if (flag[i])
begin
$display( "Encountered a TRUE bit at element number %d", i);
disable block1; Iidisable block1 because you found true bit.
end
i = i + 1;
end
end
end

7.8 Examples
In order to illustrate the use of behavioral constructs discussed earlier in this
chapter, we consider three examples in this section. The first two, 4-to-l
multiplexer and 4-bit counter are taken from Section 6.5, Examples. Earlier, these
circuits were designed by using dataflow statements. We will model these circuits
with behavioral statements. The third example is a new example. We will design
a traffic signal controller, using behavioral constructs, and simulate it.

7.S.1

4-to-1 Multiplexer

We can define a 4-to-l multiplexer with the behavioral case statement. This
multiplexer was defined, in Section 6.5.1, 4-to-l Multiplexer, by dataflow
statements. It is described in Example 7-26 by behavioral constructs. The
behavioral multiplexer can be substituted for the dataflow multiplexer; the
simulation results will be identical.
Example 7-26

Behavioral 4-to-l Multiplexer

II 4-to-1 multiplexer. Port list is taken exactly from


II the 1/0 diagram.
module mux4_to_1 (out, iO, i1, i2, i3, sl, sO);

Behavioral Modeling

145

=7
Example 7-26

Behavioral 4-to-l Multiplexer (Continued)

II Port declarations from the 1/0 diagram


output out;
input iO, i1, i2, i3;
input sl, sO;
Iioutput declared as register
reg out;
Ilrecompute the signal out if any input signal changes.
IIAII input signals that cause a recomputation of out to
Iloccur must go into the always @( ... ) sensitivity list.
always @(sl or sO or iO or i1 or i2 or i3)
begin
case ({sl, sO})
2'bOO: out
iO;
2'b01: out
i1;
2'b10: out
i2;
2'bll: out
i3;
default: out = l'bx;
endcase
end
endmodule

7.8.2

4-bit Counter

In Section 6.5.3, Ripple Counter, we designed a 4-bit ripple carry counter. We will
now design the 4-bit counter by using behavioral statements. At dataflow or gate
level, the counter might be designed in hardware as ripple carry, synchronous
counter, etc. But, at a behavioral level, we work at a very high level of abstraction
and do not care about the underlying hardware implementation. We will only
design functionality. The counter can be designed by using behavioral constructs,
as shown in Example 7-27. Notice how concise the behavioral counter description
is compared to its dataflow counterpart. If we substitute the counter in place of
the dataflow counter, the simulation results will be exactly same, assuming that
there are no x and z values on the inputs.

146

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-27

Behavioral 4-bit Counter Description

//4-bit Binary counter


module counter(Q , clock, clear);
/ / I/O ports
output [3:0] Q;
input clock, clear;
//output defined as register
reg [3: 0] Q;
always @( posedge clear
begin
i f (clear)
Q
4 'dO;
else
Q
(Q + 1) % 16;
end

or negedge clock)

endmodule

7.8.3

Traffic Signal Controller

This example is fresh and has not been discussed before in the book. We will
design a traffic signal controller, using a finite state machine approach.
Specification
Consider a controller for traffic at the intersection of a main highway and a
country road.

________~I ] ~I________
Main Highway

Ifl
o

The following specifications must be considered.

Behavioral Modeling

147

The traffic signal for the main highway gets highest priority because cars are
continuously present on the main highway. Thus, the main highway signal
remains green by default.
Occasionally, cars from the country road arrive at the traffic signal. The
traffic signal for the country road must turn green only long enough to let
the cars on the country road go.
As soon as there are no cars on the country road, the country road traffic
signal turns yellow and then red and the traffic signal on the main highway
turns green again.
There is a sensor to detect cars waiting on the country road. The sensor
sends a signal X as input to the controller. X = 1 if there are cars on the
country road; otherwise, X= 0 .
There are delays on transitions from S1 to 52, from S2 to S3, and from S4 to
SO. The delays must be controllable.
The state machine diagram and the state definitions for the traffic signal
controller are shown in Figure 7-1.

State
SO
S1
S2
S3
S4

Signals
Hwy = G Cntry = R
Hwy = Y Cntry = R
Hwy = R Cntry = R
Hwy=RCntry=G
Hwy=RCntry=Y

Figure 7-1

148

FSM for Traffic Signal Controller

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Verilog description
The traffic signal controller module can be designed with behavioral Verilog
constructs, as shown in Example 7-28.
Example 7-28
'define
'define
'define
'define
'define

Traffic Signal Controller

TRUE l'b1
FALSE l'bO
RED
2'dO
YELLOW 2'd1
GREEN 2'd2

HWY
I I GREEN
I I YELLOW
IIRED
IIRED
IIRED

IIState definition
'define
'define
'define
'define
'define

so
Sl
S2
S3
S4

3' dO
3 'd1
3 'd2
3' d3
3 'd4

eNTRY
RED
RED
RED
GREEN
YELLOW

IIDe1ays
'define Y2RDELAY
'define R2GDELAY

3 IIYe1low to red delay


2 IIRed to green delay

module sig_control
(hwy, cntry, X, clock, clear);

111/0 ports
output [1:0] hwy, cntry;
112-bit output for 3 states of signal
IIGREEN, YELLOW, RED;
reg [1:0] hwy, cntry;
Iideclared output signals are registers
input X;

Ilif TRUE, indicates that there is car on


lithe country road, otherwise FALSE
input clock, clear;

Illnternal state variables


reg [2:0] state;
reg [2:0] next_state;
IISignal controller starts in SO state

Behavioral Modeling

149

Example 7-28

Traffic Signal Controller (Continued)

initial
begin
state = 'SO;
next_state = 'SO;
hwy = 'GREEN;
cntry = 'RED;
end
//state changes only at positive edge of clock
always @(posedge clock)
state = next_state;
//Compute values of main signal and country signal
always @(state)
begin
case(state)
'SO: begin
hwy
'GREEN;
cntry = 'RED;
end
'Sl: begin
'YELLOW;
hwy
cntry = 'RED;
end
'S2: begin
hwy
'RED;
cntry = 'RED;
end
'S3: begin
hwy
'RED;
cntry = 'GREEN;
end
'S4: begin
hwy
'RED;
cntry = 'YELLOW;
end
endcase
end
//State machine using case statements
always @(state or clear or X)
begin
i f (clear)

150

Verilog HDL: A Guide to Digital Design and Synthesis

7=
Example 7-28

Traffic Signal Controller (Continued)

next_state = 'SO;
else
case (state)
'SO: if( X)
next_state
'Sl;
else
next_state
'SO;
'Sl: begin //delay some positive edges of clock
repeat('Y2RDELAY) @(posedge clock) ;
next_state = 'S2;
end
'S2: begin //delay some positive edges of clock
repeat ('R2GDELAY) @(posedge clock)
next_state = '83;
end
'S3: if( X)
next_state
'S3;
else
next_state
'S4;
'S4: begin //delay some positive edges of clock
repeat ('Y2RDELAY) @(posedge clock) ;
next_state = 'SO;
end
default: next_state = 'SO;
endcase
end
endmodule

Stimulus

Stimulus can be applied to check if the traffic signal transitions correctly when
cars arrive on the country road. The stimulus file in Example 7-29 instantiates the
traffic signal controller and checks all possible states of the controller.
Example 7-29

Stimulus for Traffic Signal Controller

//Stimulus Module
module stimulus;
wire [l:0J MAIN_SIG, CNTRY_8IG;
reg CAR_ON_CNTRY_RD;

Behavioral Modeling

151

=7
Example 7-29

Stimulus for Traffic Signal Controller (Continued)

Ilif TRUE, indicates that there is car on


lithe country road
reg CLOCK, CLEAR;
IIInstantiate signal controller
sig_control SC(MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD, CLOCK, CLEAR);

IISet up monitor
initial
$monitor ($time, "Main Sig = %b Country Sig = %b Car_on_cntry = %b",
MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD);
IISet up clock
initial
begin
CLOCK
'FALSE;
forever #5 CLOCK
end

-CLOCK;

Ilcontrol clear signal


initial
begin
CLEAR = 'TRUE;
repeat (5) @(negedge CLOCK);
CLEAR = 'FALSE;
end
Ilapply stimulus
initial
begin
CAR_ON CNTRY RD

'FALSE;

#200 CAR_ON_CNTRY_RD
#100 CAR_ON_CNTRY_RD

'TRUE;
'FALSE;

#200 CAR_ON_CNTRY_RD
#100 CAR_ON_CNTRY_RD

'TRUE;
'FALSE;

#200 CAR_ON_CNTRY_RD
#100 CAR_ON_CNTRY_RD

'TRUE;
'FALSE;

#100 $stop;

152

Verilog HDL: A Guide to Digital Design and Synthesis

Example 7-29

Stimulusfov Tufic51gn.d C ~ n h l I e(Continued)


~

end
endmodule

Note that we designed only the behavior of the controller without worrying
about how it will be implemented in hardware.

7.9 Summary
We discussed digital circuit design with behavioral Verilog constructs.
A behavioral description expresses a digital circuit in terms of the
algorithms it implements. A behavioral description does not necessarily
include the hardware implementation details. Behavioral modeling is used
in the initial stages of a design process to evaluate various design-related
trade-offs. Behavioral modeling is similar to C programming in many ways.
Structured procedures initial and always form the basis of behavioral
modeling. All other behavioral statements can appear only inside initial
or always blocks. An initial block executes once; an always block executes
continuously until simulation ends.
Procedural assignments are used in behavioral modeling to assign values to
register variables. Blocking assignments must complete before the succeeding
statement can execute. Nonblocking assignments schedule assignments to be
executed and continue processing to the succeeding statement.

Delay-based timing control, event-based timing control, and level-sensitive timing


control are three ways to control timing and execution order of statements in
Verilog. Regular delay, zero delay, and intra-assignment delay are three types of
delay-based timing control. Regular event, named event, and event OR are
three types of event-based timing control. The wait statement is used to
model level-sensitive timing control.
Conditional statements are modeled in behavioral Verilog with if and else
statements. If there are multiple branches, use of case statements is
recommended. casex and casez are special cases of the case statement.
Keywords while, for, repeat, and forever are used for four types of
looping statements in Verilog.

Behavioral Modeling

Sequential and parallel are two types of blocks. Sequential blocks are specified
by keywords begin and end . Parallel blocks are expressed by keywords
fork and join.Blocks can be nested and named. If a block is named, the
execution of the block can be disabled from anywhere in the design. Named
blocks can be referenced by hierarchical names.

7.10 Exercises
1. Declare a register called oscillate. Initialize it to 0 and make it toggle every 30
time units. Do not use always statement (Hint: Use the forever loop).
2. Design a clock with time period = 40 and a duty cycle of 25% by using the
always and initial statements. The value of clock at time = 0 should be
initialized to 0.
3. Given below is an initial block with blocking procedural assignments. At
what simulation time is each statement executed? What are the intermediate
and final values of a, b, c, d?
initial
begin
a = l'bO;
b = #l0 l'bl;
c = #5 l'b0;
d = #20 {a, b, cl;
end

4. Repeat exercise 3 if nonblocking procedural assignments were used.

5. What is the order of execution of statements in the following Verilog code?


Is there any ambiguity in the order of execution? What are the final values of
a, b, c, d?
initial
begin
a = l'bO;
#O c = b;
end
initial
begin
b = l'bl;
#O d = a;
end

154

Verilog HDL: A Guide to Digital Design and Synthesis

7=
6. What is the final value of d in the following example. (Hint: See intraassignment delays).
initial
begin
b = l'bl; c = l'bO;
#10 b = l'bO;
initial
begin
d

#25

(b

c);

end

7. Design a negative edge-triggered D-flipflop (D JF) with synchronous clear,


active high (D JF clears only at a negative edge of clock when clear is high).
Use behavioral statements only. (Hint: Output q of DJF must be declared as
reg). Design a clock with a period of 10 units and test the DJF.
8. Design the D-flipflop in exercise 7 with asynchronous clear (D_FF clears
whenever clear goes high. It does not wait for next negative edge). Test the
DJF.
9. Using the wait statement, design a level-sensitive latch that takes clock and d
as inputs and q as output. q = d whenever clock = 1.
10. Design the 4-to-l multiplexer in Example 7-14 by using i f and else
statements. The port interface must remain the same.
11. Design the traffic signal controller discussed in this chapter by using if and
else statements.
12. Using a case statement, design an 8-function ALU that takes 4-bit inputs a
and b and a 3-bit input signal select, and gives a 5-bit output out. The ALU
implements the following functions based on a 3-bit input signal select.
Ignore any overflow or underflow bits.

Select Signal
3'bOOO
3'bOOl
3'bOlO
3'bOll
3'blOO
3'b101
3'bllO
3'bll1

Function
out = a
out = a + b
out = a - b
out = a / b
out = a % b (remainder)
out = a 1
out = a 1
out = (a> b) (magnitude compare)

Behavioral Modeling

155

=7
13. Using a while loop, design a clock generator. Initial value of clock is O. Time
period for the clock is 10.
14. Using the for loop, initialize locations 0 to 1023 of a 4-bit register array
cache_var to O.
15. Using a forever statement, design a clock with time period = 10 and duty
cycle = 40%. Initial value of clock is O.
16. Using the repeat loop, delay the statement a = a + 1 by 20 positive edges of
clock.
17. Below is a block with nested sequential and parallel blocks. When does the
block finish and what is the order of execution of events? At what
simulation times does each statement finish execution?
initial
begin

x = 1 'bO;
#5 y
l'b1;
fork
#20 a
#15 b
join
#40 x
l'b1;
fork
#10 p
begin

x;
y;

x;
#10 a
#30 b

end
#5 m

y;
x;

y;

join
end

18. Design an 8-bit counter by using a forever loop, named block, and disabling of
named block. The counter starts counting at count = 5 and finishes at count =
67. The count is incremented at positive edge of clock. The clock has a time
period of 10. The counter counts through the loop only once and then is
disabled. (Hint: Use the disable statement).

156

Verilog HDL: A Guide to Digital Design and Synthesis

You might also like