Notes - HDL 1 63
Notes - HDL 1 63
Emergence of HDLs
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. HDLs allowed the designers to model
the concurrency of processes found in hardware elements
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
Design Flow
A typical design flow for designing VLSI IC circuits is shown in the following Figure.
1
Page
Design Specification:
Behavioural description:
In a bottom-up design methodology, the building blocks that are available are identified. Bigger cells
are built, using these building blocks. These cells are then used for higher-level blocks until the top-
level block in the design is built.
Typically, a combination of top-down and bottom-up flows is used.
4
Page
Example:
Consider a negative edge-triggered 4 bit ripple carry counter. The circuit diagram is as shown below
The ripple carry counter shown in Figure is made up of negative edge triggered toggle flip-flops (T-
FF). Each of the T-FFs can be made up from negative edge-triggered D-flip-flops (D-FF) and
inverters. Thus, the ripple carry counter is built in a hierarchical fashion by using building blocks.
The diagram for the design hierarchy is shown below.
In a top-down design methodology, the functionality of the top-level block i.e., the ripple carry
counter is specified. Then, the counter with T-FFs.is implemented which is built with the T-FFs from
the D-FF and an additional inverter gate. Thus, bigger blocks are broken into smaller building sub-
blocks until the blocks cannot be broken further.
The bottom-up methodology flows in the opposite direction. The top-level building blocks are built
using small building blocks.
e.g., D-FF is built from and and or gates, and T-FFs are built using D-FF and inverter gates.
Modules
A module is the basic building block in Verilog. 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-
5
terminal-list, which describes the input and output terminals of the module.
Page
The Syntax is
module<module-name> (<module-terminal-list>)
<module internals>
Endmodule
Example:
Consider T- FF. The module for T-FF is as shown below.
module T-FF (q, clock, reset);
.
.
<functionality of T-flip-flop>
endmodule
Internals of each module can be defined at four levels of abstraction, depending on the needs of the
design. They are
2. Dataflow level
3. Gate level
4. Switch level
Behavioural or algorithmic level :
Instances:
A module provides a template from which actual objects are created. When a module is invoked,
Verilog creates a unique object from the template. Each object has its own name, variables,
parameters and Input/output interface. The process of creating objects from a module template is
called instantiation, and the objects are called instances
{Explanation:
The difference between these two can be summed up as follows: A module position is a container in
which you can assign modules so they appear on the front end. A module instance is a single module,
injected directly into a specific place in the page}
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
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. Such a block is called the stimulus block. The
stimulus block is also commonly called a test bench.
There are two distinct components in a simulation:
Stimulus block and
. Design block
A stimulus block is used to test the design block. The stimulus block is usually the top-level block.
There are two styles of stimulus application.
7
Page
In the first style, the stimulus block instantiates the design block and directly drives the signals in
the design block. The block diagram is as shown below.
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 below.
The function of top-level block is simply to instantiate the design and stimulus blocks.
Example:
Consider ripple carry counter. The design block and the stimulus block are defined. The stimulus is applied to
the design block and the outputs are monitored. The circuit is as shown below
Design Block
Let us consider top-down design methodology. First, the Verilog description of Ripple carry counter
which is the top-level design block is written.
Module ripple-carry-counter(q, clk, reset) ;
8
output [3:0]q;
Page
Now the stimulus block is written to check if the ripple carry counter design is functioning correctly.
In this case, the signals clk and reset are controlled so that the regular function of the ripple carry
counter and the asynchronous reset mechanism are both tested. The wave forms are as shown below.
9
Page
Now the stimulus block is written to know how the design block is instantiated in the stimulus block
that will create the above waveforms
Here the cycle time for clk 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.
module stimulus;
reg clk;
reg reset;
wire [3:0] q;
// instantiate the design block
ripple-carry-counterrl (q, clk, reset);
// Control the clk signal that drives the design block.Cycle time = l0 initial
clk = l'b0; //set clk to 0
always
#5 clk = ~clk;
//toggle clk every 5 time units
// Control the reset signal that drives the design block
// reset is asserted from 0 to 20 and from 200 to 220 initial
begin
reset = l'bl;
#l5 reset = l'b0;
#l80 reset = l'bl;
#l0 reset = l'b0;
#20 $finish; //terminate the simulation
end
// Monitor the outputs
endmodule
10
Page
3. Basic concepts:
The digital circuits can be represented in textual form in Verilog. The code written in textual form is
called source code. The source code is created with the combinations of character and words which
are called KEYWORDS and SYNTAX / SEMANTICS. These are called Lexical tokens.
Combination of more than one lexical tokens forms LEXICAL CONVENTIOINS
LEXICAL CONVENTIOINS
Lexical tokens in Verilog HDL are given below.
White space String
Comment Identifier
Operator Keyword
Number
White space (Blank spaces):
White space is a term used to represent the characters for spaces, tabs, newlines .White spaces
are used in stings which can be incorporated using double quotes (“). The semantics for white
spaces in the string is as shown below:
Escape string Character produced by escape string
\b Blank space
\t Tab character
\\ \ character
\” “ character
Comments:
There are two ways to write comments in Verilog. A single line comment starts with // and tells Verilog
compiler to treat everything after this point to the end of the line as a comment. A multiple-line comment
starts with /* and ends with */ and cannot be nested.
Comments are used to increase the readability of code. Comments are ignored by the simulator.
Example:
a = b &&c; // This is a one-line comment
/ * This is a multiple line
comment* /
/ * This is / * an illegal Binary operator – which worsl* / comment * /
Operators:
The operation which is to be performed is decided by operators. There are three kinds of operators
available in Verilog. They are
11
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.
Example:
Data Types:
A data type in Verilog is designed to represent the data storage and transmission. The 10 data types
used in Verilog are –
Value Set
Verilog supports four values and eight strengths to model the functionality of real hardware. The four
value levels are
2. If two signals of equal strengths are driven on a wire, the result is unknown.
Example:
If two signals of strength strong l and strong 0 conflicts, the result is an X.
Nets:
The nets variables represent the physical connection between structural entities. They do not store
values. They have the value of their drivers.
Example:
In the Figure net a is connected to the output of and gate gl. Net awill
continuously assume the value computed at the input of gate gl, which is
b&c
Registers:
Registers are data storage elements. They retain value until another value is placed onto them.
15
Arrays
Arrays are used in Verilog for reg, integer, time and vector register data types. Arrays are not
used for real variables.
Each element of the array can be used as a scalar or vector net.
Arrays are accessed by
<array-name> [<subscript>l.
Multidimensional arrays are not permitted in Verilog.
The difference between a vector and an array is - vector is a single element that is n-bits
wide but arrays are multiple elements that are l-bit or n-bits wide.
Example:
integer count[0:7]; //an array of 8 count variables
Memories
In digital simulation, register files, RAMS, and ROMs are modeled .
Memories are modeled in Verilog as one dimensional array of registers.
Each element of the array is known as a word.
Each word can be one or more bits.
Depth of memory should be declared by specifying a range following the memory identifier
Example: the memory reg [5:0]
Parameters
Constants in Verilog are defined in a module by the keyword parameter.
Parameters cannot be used as variables.
Module instances can be altered by changing the value of a parameter.
Example:
parameter port-id = 5; //Defines a constant port-id
parameter cache_line_width = 256; //constant defines width of cache line
Strings
In Verilog, string literals are just packed arrays of bits (or a bit-vector).
Strings are the characters stored in reg data type.
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.
Example:
17
System Tasks
Verilog contains the pre-defined system tasks and functions which provide common operations .All
system tasks appear in the form $<keyword>. Operations such as displaying onthe screen, monitoring
values, stopping, and finishing are done by system tasks.
Task Function
To display on screen $display
For monitoring values $monitor
Stopping and finishing simulation $time
Terminate simulation $finish
Compiler Directives
All compiler directives are defined by using the ' <keyword>construct. Compiler directives begin
with "`" an accent grave. The compiler directives tell the compiler the method of processing its
input. Some of the complier directives are-
1. `define
2. `include
The 'define directive is used to define text macros in Verilog. The defined constants or text macros
are used in the Verilog code by preceding them with a ' (back tick).
Example:
//define a text macro that defines default word size
//Used as 'WORD-SIZE in the code
'define WORD-SIZE 32
'define WORD-REG reg [31:0]
The ' include directive includes the entire contents of Verilog source file in another Verilog file
during compilation. It is used to include header files, which contain global or commonly used
definitions
Eg:
// Include the file header.v, which contains declarations in the
// main verilog file design.v.
'include header.v
18
Page
4. Modules and Ports
A module is a block of Verilog code that implements certain functionality. The module name, port
list, port declaration, and optional parameters must appear first in a module definition. Port list and
port declarations are present only if the module has a ports to interact with the external environment.
The block diagram of components in a Verilog module is as shown below.
These components can be in any order and at any place in the module definition. The endmodule
statement must always 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.
Example:
Consider the S R latch as shown below.
The SR latch has S and R as the input ports and Q and Qbaras the
output ports.
The SR latch and its stimulus can be modeled as shown in Example
//Port declarations
output Q, Qbar;
// endmodule statement
endmodule
The S R latch stimulus can be modeled as shown
// Module name and port list(No ports are there)
// Stimulus module
module Top;
// Declarations of wire, req, and other variables
wire q, qbar;
reg set, reset;
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 need not be present
in a module. We do not find variable declarations, dataflow (assign) statements, or behavioral blocks
(always or initial).
However, the stimulus block for the SR latch contains module name, wire, reg, and variable
20
declarations, instantiation of lower level modules, behavioral block (initial), and endmodule
statement but does not contain port list, port declarations, and data flow (assign) statements.
Page
Thus, all parts except module, module name, and endmodule are optional and can be mixed and
matched as per design needs.]
Ports:
Port is an essential component of the Verilog module. Ports are used to communicate for a module
with the external world through input and output. Ports define the interface of a Verilog module to
the outside world.
Example:
The input output pins of IC are its ports
List of Ports
A module definition contains an optional list of ports.
Example:
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.
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 below.
Example:
module fulladd4(sum, c-out, a, b, c-in); //module with a list ofports
module Top; // No list of ports, top-level module in simulation
Port Declaration
All ports in the list of ports must be declared in the module. Ports can be declared as follows:
21
Example:
Input list of ports/terminals ; Input s,r; Input[7:0] s,r;
Output list of ports/terminals ;Output y,z; Output [3:0] y,z
Inout list of ports/terminals ;Inout a,b;Inpit[15:0] a,b;
Example1 : 4 bit full adder
module fulladd4(sum, c-out, a, b, c-in);
//Begin port declarations section
output [3 : 0] sum; // 4 bit full adder hence the vector [3: 0] which is 4 bit
output c-out;
input [3:0] a, b;
input c-in;
.....
//End port declarations section
Endmodule
All ports declarations are implicitly declared as w i r e in Verilog. Thus, if a port is intended to be a
wire, it is sufficient to declare it as output, input, or inout.
However, if output ports hold their value, they must be declared as reg.
module full_add4(output reg[3:0] sum; output reg cout; input [3:0] a,b; input cin);
A port consists of two units - one unit that is internal to the module and another that is external to
the module
The block diagram of the rules that are governing port connections when modules are instantiated
within other modules are summarized below.
22
Page
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.
Outputs
Internally, outputs ports can be of the type reg or net. Externally, outputs must always be connected
to a net.
Inouts
Internally, inout 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. A warning is issued when the widths do not match.
Unconnected ports
Verilog allows ports to remain unconnected. A port can remain unconnected by instantiating a
module as shown below.
module Top;
//Declare connection variables
reg [3:O]A,B;
reg C-IN;
reg [3:0] SUM; // this is the output. The output should be always net or wire.
//Hence illegal
wire C-OUT;
There are two methods of making connections between signals specified in the module instantiation
and the ports in a module definition. They are
Connecting by ordered list
23
In this method 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.
Example:
Consider 4 bit full adder with Top module. The Verilog code is
.....
<stimulus>
....
Endmodule
consider the module fulladd4 To connect signals in module Top by ordered list, 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 c-in
in module definition of fulladd4.
Connecting ports by name
Verilog provides the capability to connect external signals to ports by the port names.
Example: consider Full – adder 4
...
<module internals>
Page
...
endmodule
module Top;
//Declare connection variables
reg [3:O]A,B;
reg C-IN;
wire [3:0] SUM;
wire C-OUT;
.....
<stimulus>
....
Endmodule
fulladd4 fa1 (.c-out(C-OUT), .sum(SUM), .b(B), .c-in(C-IN), .a(A) ,);
Hierarchical Names
Every module instance, signal, or variable is defined with an identifier. Hierarchical name
referencing allows to denote every identifier in the design hierarchy with a unique name. A
hierarchical name is a list of identifiers separated by dots (" ."). The advantages of mentioning the
hierarchical name is 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 instantiate. 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 anywhere.
Example:
Consider S R latch. The design hierarchy is shown in Figure
.
Page
Example:
stimulus stimulus.q
stimulus.qbar stimulus.set
stimulus.reset stimu1us.ml.Qbar
stimulus.ml.Q stimu1us.ml.R
stimulus.ml.S stimulus.n2
stimulus.nl
Each identifier in the design is uniquely specified by its hierarchical path name
Stimulus
(Root level)
q, qbar
m1 set, reset
(SR_latch) (variables)
n1 n2 Q, Qbar
(nand) (nand) S,R
(signals)
26
Page
Behavioral Modeling
In behavioural modelling the digital design is carried out in terms of algorithm and its performance.
Structured Procedures
Structured procedures provide a means of modeling blocks of procedural statements. There are two
structured procedure statements in Verilog: always and initial
initial Statement
All statements inside an initial statement constitute an initial block. An initial block starts at time 0,
executes exactly once during a simulation and then does not execute again. If there are multiple
initial blocks, each block starts to execute concurrently at time 0. Each block finishes execution
independently of other blocks
Example:
module stimulus;
reg x,y, a,b, m;
initial
m = l’b0 //single statement; does not need to be grouped
initial
begin
#5 c //multiple statements; need to be grouped
#25 b = l’b0;
end
initial
begin
#l0 X = l’b0;
#25 y = l'bl;
end
initial
#50 $finish; Time Statement executed
endmodule
0 m = l’b0 ;
5 a = l’b0 ;
10 x = l'b0
30 b = l'b0;
35 y = l'bl;
50 $finish;
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
Example:
Consider a clock generator module that toggles the clock signal every half cycle
module clock-gen;
reg clock
In the above Example 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. 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.
Procedural Assignments
Procedural assignments update values of reg, integer, real, or time variables. The value placed on a
variable will remain unchanged until another procedural assignment updates the variable with a
different value. The syntax for the simplest form of procedural assignment is
<assignment> : : = < 1value> = <expression>
There are two types of procedural assignment statements: blocking and nonblocking.
Blocking assignments
Verilog supports blocking and non-blocking assignments statements within the always block with
their different behaviours.
Blocking assignment statements are executed in the order they are specified in a sequential
block.
A blocking assignment will not block execution of statements that follow in a parallel block.
The ‘ = ‘ operator is used to specify the Blocking assignments .
Example:
reg x, y, z;
reg [15: 0] reg-a, reg-b;
integer count;
initial
begin
x=0; y=l; z = 1; //Scalar assignments
count = 0; //Assignment to integer variables
reg-a = 16'b0; reg-b = reg-a; //initialize vectors
#l5 reg-a[2] = lrbl; //Bit select assignment with delay
#l0 reg-b[15:13] = (x, y, z) //Assign result of concatenation to part select of a vector
count = count + 1; //Assignment to an integer (increment)
end
Nonblocking Assignments
Non-blocking assignment statements are allowed to be scheduled without blocking the execution of
the following statements and is specified by a (<=) symbol.
Example:
reg x, y, z;
reg [15:0] reg-a, reg-b;
integer count;
//All behavioral statements must be inside an initial or always block
initial
begin
x= 0; y = 1; z = 1; //Scalar assignments
count = 0; //Assignment to integer variables
reg-a = 16'b0; reg-b = reg-a; //Initialize vectors
reg-a[2] <= #l5 l'bl; //Bit select assignment with delay
reg-b[15: 13] <= #l0 {x, y, z); //Assign result of concatenation
//to part select of a vector
count <= count + 1; //Assignment to an integer (increment)
end
The statements x = 0 through reg-b = reg-a are executed sequentially at time 0.
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, y, z} is scheduled to execute after 10 time units (i.e., time = 10)
3. count = count + 1 is scheduled to be executed without any delay (i.e., time = 0)
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.
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.
1. if statement
2. if – else statement
3. if-else- if statement.
1. In if statement - Statement executes or does not execute.
Syntax:
if (<expression>) true-statement ;
Example:
If (!lock) buffer = data;
If (enab1e) out = in;
2. In if – else statement -either true-statement or false-statement is evaluated
Syntax :
if (<expression>) true-statement ; else false-statement ;
Example:
if (reset)
begin
dff <= 0;
end
else
begin
dff <= din;
end
3. In if-else- if statement - Choice of multiple statements. Only one is executed.
Syntax:
if (<expressionl>) true-statement1 ;
else if (<expression2>) true-statement2 ;
else if (cexpression3>) true-statement3 ;
else default-statement ;
Example:
if (alu-control = = 0)
l y=x + z;
else if(a1u-control = = 1)
y=x - z;
else if (a1u-control = = 2)
y=x*z;
else
$display ("Invalid ALU control signal");
Multiway Branching
The nested if-else-if can become unwieldy if there are too many alternatives. A shortcut to achieve
the same result is to use the case statement.
The keywords case, endcase, and default are used in the case statement
Syntax:
case ( expression)
alternativel: statement l;
alternative2: statement 2;
alternative3: statement 3;
...
...
Default: default-statement;
endcase
1. Each of statement 1, statement2 ..., default-statement can be a single statement or a block of
multiple statements.
2. The expression is compared to the alternatives in the order they are written.
3. For the first alternative that matches, the corresponding statement or block is executed.
4. If none of the alternatives match, the default-statement is executed.
Example:
reg [1:0] alu-control;
...
...
case (alu-control)
2'd0 : y = x + z;
2'dl : y = x - z;
2'd2 : y = x* z;
default : $display("Inva1id ALU control signal");
endcase
4 : 1 Multiplexer
1 : 4 Demultiplexer
There are two variations of the case statement. They are denoted by keywords, casex and casez.
casez treats all z values in the case alternatives or the case expression as don't cares. All bit
positions with z can also represented by ? in that position.
casex treats all x and z values in the case item or the case expression as don't cares.
The use of casex and casez allows comparison of only non-X or -z positions in the case expression
and the case alternatives.
Example:
reg [3 : 0] encoding;
integer state;
casex (encoding) //logic value X represents a don't care bit
4'blxxx : next-state = 3;
4'bxlxx : next-state = 2;
4'bxxlx : next-state = 1;
4'bxxxl : next-state = 0;
default : next-state = 0;
endcase
Thus, an input encoding = 4'bl0xz would cause next-state = 3 to be executed.
Loops
There are four types of looping statements
while
for
repeat and
Forever
While Loop
The keyword while is used to specify this loop. The while loop executes until the while-
expression becomes false. If multiple statements are to be executed in the loop, they must be
grouped typically using keywords begin and end.
Example:
Example 1: Increment count from 0 to 127. Exit at count 128.
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
Example 2: Find the first bit with a value 1 in flag
'define TRUE l'bl';
'define FALSE l'b0;
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
if ( flag [i] )
begin
$display("Encountered a TRUE bit at element number %d", i);
continue = 'FALSE;
end
i=i+l;
end
end
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
Example:
integer count;
initial
for ( count=O; count < 128; count = count + 1)
$display("Count = %do, count);
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 repeat
construct must contain a number, which can be a constant, a variable or a signal value.
Example:
//Example1 : incrernent and display count from 0 to 127
integer count;
initial
begin
count = 0;
repeat (128)
begin
$display("Count = %d", count);
count = count + 1;
end
end
Dataflow modeling describes hardware in terms of the flow of data from input to output.
Continuous Assignment
The continuous assignment statement is the main construct of dataflow modeling and is used to assign
value to the net. It starts with the keyword assign.
Continuous assignments are always active. That is the LHS net value changes as soon as the
value of any operand in the RHS changes.
The LHS of an assignment should be either scalar or vector nets or a concatenation of both.
Registers are not applicable on the LHS.
The RHS of the assignment can be register, net, or function calls of scalar or vector type.
Delays can be specified.
Examples of Continuous Assignment
1. // Continuous assign. out is a net. il and i2 are nets
assign out = il & i2;
2. // Continuous assign for vector nets. addr is a 16-bit vector net
assign addr[l5:0] = addrl_bits[l5:0] ^ addr2_bits[l5:0];
3. // Concatenation. Left-hand side is a concatenation of a scalar
assign {c-out, sum[3:0]) = a[3:0] + b[3:01 + c-in;
Implicit Continuous Assignment
Instead of declaring a net and then writing a continuous assignment on the net, a continuous
assignment can be placed on a net when it is declared.
Example:
//Regular continuous assignment
wire out;
assign out = in1 & in2;
//Same effect is achieved by an implicit continuous assignment
wire out = in1 & in2;
Delays
Three ways of specifying delays in continuous assignment statements are
1. Regular assignment delay,
2. implicit continuous assignment delay, and
3. net declaration delay.
Regular Assignment Delay
A delay value in the continuous assignment statement is assigned first. The delay value is specified
after the keyword assign.
Example:
assign #10 out = in1 & in2; // Delay in a continuous assign
Any change in values of in1 or in2 will result in a delay of 10 time units before recomputation
of the expression in1 & in2, and the result will be assigned to out.
If in1 or in2 changes value again before 10 time units when the result propagates to out, the
values of in1 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.
In1
In2
out
Time 85
10 20 30 60 70 80
Expressions:
Expressions are constructs that combine operators and operands to produce a result.
Examples:
a&b
addr1[20:17] + addr2[20:17]
in1 | in2
Operands:
Operands can be any one of the data types. They can be constants, integers, real numbers, nets,
registers, times, bit-select etc.,
Example:
1. integer count, final-count;
final-count = count + 1
2. real a, b, c;
c = a - b; etc.,
Operators
Verilog has Ten different types of operators. They are
1. Arithmetic 6. Reduction
2. Logical 7. Shift operators
3. Relational 8. Concatenation
4. Equality 9. Replication
5. Bitwise logical 10. Conditional
1. Arithmetic Operators
There are two types of arithmetic operators:
binary and
Unary.
Binary arithmetic operators are
Example:
1. Multiply (*), If A = 4'b00ll; B = 4'b0l00; D = 6; E = 4; determine
2. divide (/),
a) A * B (Ans: 4'bll00)
3. add (+), b) D / E (Ans: Evaluates to 1)
4. subtract (-) and c) A + B (Ans: 4'b0lll)
5. modulus (%). d) B – A (Ans: 4'b000l)
If any operand bit has a value x, then the result of the entire expression is x.
Example:
in1 = 4'bl0lx;
in2 = 4'bl0l0;
sum = in1 + in2; // sum will be evaluated to the value 4'bx
Modulus operators produce the remainder from the division of two numbers.
Example:
13 % 3 // Evaluates to 1
16 % 4 // Evaluates to 0
-7 % 2 // Evaluates to -1, takes sign of the first operand
7 % -2 // Evaluates to +l, 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
Example:
-4 // Negative 4
+5 // Positive 5
2. Logical Operators
Logical operators are logical-and (&&), logical-or ( | | ) and logical-not ( ! ). Operators && and
| | are binary operators. Operator ! is a unary operator.
Logical operators follow the following conditions –
Logical operators always evaluate to a l-bit value, 0 (false), 1 (true), or X
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).
Example:
I. A = 4’b0011; B = 4’b0000;
a) A && B // Evaluates to 0.
b) A || B // Evaluates to 1.
c) ! A / / Evaluates to 0.
d) !B// Evaluates to 1
II. A = 2'b0x; B = 2'bl0;
A && B // Evaluates to X.
III. (a = = 2) && (b = = 3) // Evaluates to 1 if both a = = 2 and b = = 3 are true.
// Evaluates to 0 if either is false.
3. Relational Operators
Relational operators are -
greater-than (>),
less-than (<)
greater-than-or-equal-to (>= ) and
less-than-or-equal-to (<=)
Example:
If A=4, B=3
X = 4'b1010, Y = 4'b1101, Z = 4'blxxx then evaluate
a) A <= B // Evaluates to a logical 0
b) A > B // Evaluates to a logical 1
c) Y >= X // Evaluates to a logical 1
d) Y < Z // Evaluates to an X
4. Equality Operators
Equality operators are logical equality (==), logical inequality ( != =),case equality (===), and case
inequality (!= =) When used in an expression, equality operators return logical value 1 if true, 0 if
false. These operators compare the two operands bit by bit, with zero filling if the operands are of
unequal length.
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 0, 1, 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
Problems:
A=4,B=3
X = 4’b1010 ; Y = 4’b1011;
Z = 4’b1xxz ; M = 4’b1xxz ; N = 4’b1xxx;
A == B // Results in logical 0
X != Y // Results in logical 1
X == Z // Results in X
Z === M //~esults in logical l (all bits match, including X and z)
z === N //~esults in logical 0 (least significant bit does not match)
M !== N // Results in logical 1
5. Bitwise Operators
Bitwise operators are
negation (~),
and(&),
or ( | )
xor ( ^ )
xnor ( ^ ~ , ~^)).
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.
Example:
X = 4’ b1010; Y = 4’ b1101; Z = 4’ b10x1;
~X // Negation. Result is 4'b0l0l
X&Y // Bitwise and. Result is 4'bl000
X|Y // Bitwise or. Result is 4'bllll
X^Y // Bitwise xor. Result is 4'b0lll
X ^~ Y // Bitwise xnor. Result is 4'bl000
X&Z // Result is 4'bl0x0
6. Reduction Operators
Example:
X = 4’b 1100
8. Concatenation Operator
The concatenation operator ( {, ) provides a mechanism to append multiple operands. The operands
must be sized. Concatenations are expressed as operands within braces, with commas separating the
operands.
Example:
If A = l'bl, B = 2'b00, C = 2'b10, D = 3'bll0
Then what is
Y = {B , C} // Result Y is 4'b00l0
Y = {A , B , C , D , 3'b00l) // Result Y is 11'b10010110001
Y = {A , B[0], C[1] 1} // Result Y is 3'bl0l
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 ( { } ).
Example:
Let reg A;
reg [1:0] B, C;
reg [2:0] D;
A = l'bl; B = 2'b00; C = 2'bl0; D = 3'bll0;
Y = { 4{A) } // Result Y is 4'bllll
Y = { 4{A} , 2{B} } // Result Y is 8'b11110000
Y = { 4{A} , 2{B} , C } // Result Y is 10'b1111000010
Example:
Consider 4 – to – 1 multiplexer.
Let (A==3) and control are the two select signals of 4-to-1 multiplexer with n, m, y, x as the inputs and
out as the output signal.
Then assign out = (A == 3) ? ( control ? x : y ): ( control ? m : n) ;
Example:
Write the Verilog code for 4-to-1 Multiplexer, Using Conditional Operators
module multiplexer4-to-l (out, i0, il, i2, i3, sl, s0);
output out;
input i0, il, i2, i3;
input sl, s0;
assign out = sl ? ( S0 ? i3 : i2) : (SO ? il : i0);
endmodule ;
S1 S0
S1n S0n
y0
i0
y1
i1 OUT
y2
i2
y3
D3
assign out = (~sl & ~s0 & i0) | (~sl & s0 & il) | (sl & ~s0 & i2) | (sl & s0 & i3) ;
endmodule.
Write Verilog code for 4 Bit Full Adder using data flow modelling
Method 1: Using Dataflow Operators
Gate-Level Modelling
In gate level modelling the circuit is described in terms of gates (e.g., and, nand).
Gate Types
A logic circuit can be designed by use of logic gates. In Verilog the basic logic gates are defined as
predefined primitives. There are two types of basic gates:
And / or gates and
Buf / not gates.
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 inbuilt gate primitives are
and nand xnor
or nor
not xor
The logic symbol and truth table of these gates are as shown below:
I2 I2
and 0 1 x z nand 0 1 x z
0 0 0 0 0 0 1 1 1 1
I1 1 0 1 x x I1 1 1 0 x x
x 0 x x x x 1 x x x
z 0 x x x z 1 x x x
I2 I2
or 0 1 x z nor 0 1 x z
0 0 1 x x 0 1 0 x x
I1 1 1 1 1 1 I1 1 0 0 0 0
x x 1 x x x x 0 x x
z x 1 x x z x 0 x x
pg. 1
xor gate xnor gate
I2 I2
xor 0 1 x z xnor 0 1 x z
0 0 1 x x 0 1 0 x x
I1 1 1 0 x x I1 1 0 1 x x
x x x x x x x x x x
z x x x x z x x x x
These gates are instantiated to build logic circuits in Verilog. Examples of gate instantiations are
shown below. In this example, for all instances, OUT is connected to the output out, and IN1 and IN2
are connected to the two inputs il and i2 of the gate primitives.
wire OUT, IN1, IN2;
// basic gate instantiations.
and al (OUT, IN1, IN2);
nand nal (OUT, IN1, IN2 ) ;
or orl (OUT, IN1, IN2);
nor nor1 (OUT, IN1, IN2 ) ;
xor xl (OUT, IN1, IN2 ) ;
xnor nxl (OUT, IN1, IN2 ) ;
The instance name does not need to be specified for primitives
.
Example:
and (OUT, IN1, IN2); // legal gate instantiation
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.
Two basic buf / not gate primitives are –
buf
not
The symbols and truth tables are as shown below
not in out
buf in out
0 1
0 0
1 0
1 1
x x
x x
z x
pg. 2 z z
bufif / notif
Gates with an additional control signal on buf and not gates are also available. The primitives are
Bufif 1 notif 1
bufif0 notif0
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 below
pg. 3
Examples of instantiation of bufif and notif gates.
The 1/O diagram and the truth table for the multiplexer are shown
pg. 4
The logic diagram for the multiplexer is shown below.
S1 S0
S1n S0n
y0
i0
y1
i1 OUT
y2
i2
y3
D3
pg. 5
// Define the stimulus module (no ports)
module stimulus;
// Declare variables to be connected to inputs
reg IN0, IN1, IN2, IN3;
reg S1, S0;
// Declare output wire
wire OUTPUT;
// Instantiate the multiplexer
mux4-to-1 mymux (OUTPUT, INO, IN1, IN2, IN3, S1, SO) ;
// define the stimulus module (no ports)
// Stimulate the inputs
initial
begin
// set input lines
IN0 = 1; IN1 = 0; IN2 = 1; IN3 = 0;
#l $display("IN0= %b, IN1= %b, IN2= %b, IN3= %b\n , IN0, IN1, IN2, IN3);
// choose IN0
S1 = 0; S0 = 0;
#l $display("Sl = %b, S0= %b, OUTPUT = %b/n, S1, S0, OUTPUT);
// choose IN1
S1 = 0; S0 = 1;
#l $display ("Sl = %b, S0 = %b, OUTPUT = %b \n", S1, S0, OUTPUT);
// choose IN2
S1 = l; S0 = 0;
#l $display("Sl = %b, S0 = %b, OUTPUT = %b \n , S1, S0, OUTPUT);
// choose IN3
S1 = l; SO = 1;
#l $display("Sl = %b, S0 = %b, OUTPUT = %b \n , S1, S0, OUTPUT);
End
endmodule
The output of the simulation is displayed as shown below
IN0= 1, IN1= 0, IN2= 1, IN3= 0
S1 = 0, S0 = 0, OUTPUT = 1
S1 = 0, S0 = 1, OUTPUT = 0
S1 = 1, S0 = 0, OUTPUT = 1
pg. 6
S1 = 1, S0 = 1, OUTPUT = 0
A0, A1, A2 and A3 are instances of the module full add. The Verilog code for the above circuit is as
shown below.
pg. 7
output c-out;
input [3 : 01 a, b;
input c-in;
// Internal nets
wire cl, c2, c3;
// Instantiate four l-bit full adders.
#5 A = 4’d3, B = 4’d4;
#5 A = 4’d2, B = 4’d5;
#5 A = 4’d9, B = 4’d9;
pg. 8
#5 A = 4’d10, B = 4’d15;
end
endmodule
The output of the simulation is shown below.
Gate Delays
In real circuits, logic gates have delays associated with them.
There are three types of delays from the inputs to the output of a primitive gate.
Rise delay
Fall delay
Turn-off delay
Rise delay
The time taken for the output of a
gate to change from some value to 1
is called a rise delay.
Fall delay
The time taken for the output of a
gate to change from some value to 0
is called a fall delay
Turn-off delay:
The time taken for the output of a
gate to change from some value to
high impedance (z) is called turn-off
delay.
pg. 9
If the value changes to X, the minimum of the three delays is considered, Three types of delay
specifications are allowed.
If only one delay is specified, this value is used for all transitions.
Example:
Delay of delay-time for all transitions,
Syntax:
and #(delay-time) al (out, il, i2);
and #(5) al (out, il, i2); //Delay of 5 for all transitions
If two delays are specified, they refer to the rise and fall delay values.
Example:
Rise and Fall Delay Specification.
Syntax
and # (rise-val, fall-val) a2 (out, il, i2)
and #(4,6) a2(out, il, i2); // Rise = 4, Fall = 6;
If a11 three delays are specified, they refer to rise, fall, and turn-off delay values.
Example:
// Rise, Fall, and Turn-off Delay Specification
Syntax
Bufif0 #(rise-val, fall-val, turnoff-val) bl (out, in, control);
buf if0 # (3,4,5)b l (out,i n, control); // ~ise= 3, Fall = 4, Turn-off = 5
// Two delays
and #(3:4:5, 5:6:7) a2(out, il, i2);
// if +mindelays, rise= 3, fall= 5, turn-off = min (3,5)
// if +typdelays, rise= 4, fall= 6, turn-off = min (4,6)
// if +maxdelays, rise= 5, fall= 7, turn-off = min (5,7)
// Three delays
and #(2:3:4, 3:4:5, 4:5:6) a3(out, il,i2);
// if +mindelays, rise= 2 fall= 3 turn-off = 4
// if +typdelays, rise= 3 fall= 4 turn-off = 5
// if +maxdelays, rise= 4 fall= 5 turn-off = 6
Delay Example
Consider the equation
out = ( a . b) + c
The logic diagram for the above equation is as shown below. The gate-level implementation is shown
below.
pg. 11
initial
begin
A= l'bO; B= l'bO; C= l'bO;
#l0 A= l'bl; B= l'bl; C= l'bl;
#l0 A= l'bl; B= l'bO; C= l'bO;
#20 $finish;
end
endmodule
pg. 12