0% found this document useful (0 votes)
36 views

FPGA Based System Design PPT End Sem - Student - Updated

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

FPGA Based System Design PPT End Sem - Student - Updated

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

19ECE343 FPGA Based System Design

19ECE343 FPGA Based System Design- Book Chapter detail

Text Book
Book1 -Samir Palnitkar, “Verilog HDL”, First Edition, Printice Hall India Private Limited,2003
Book2-Wayne Wolf, “FPGA-Based System Design”, First Edition, Prentice Hall India Private Limited,2004
Book3-Clive Maxfield, “The Design Warrior's Guide to FPGAs”, Newnes, 2004.

• Book1- (Samir Palnitkar, “Verilog HDL”, First Edition, Printice Hall India Private Limited,2003)
• Chapter 1, 2,3, 4, 5,6, 7
• Chapter 14.1, 14.3, 14.6.1
• Book2- (Wayne Wolf, “FPGA-Based System Design”, First Edition, Prentice Hall India Private Limited,2004)
• Chapter- 3.2, 3.3, 3.3.2, 3.4, 3.4.1, 3.4.2, 3.4.3
3.6.1, 4.7.1, 4.7.2 ( Only refer slide)

• Book3- (Clive Maxfield, “The Design Warrior's Guide to FPGAs”, Newnes, 2004)
Chapter-14
Slide number only for understanding
• 455, 458, 461, 463, 465, 469, 471, 473, 488, 491, 494, 496, 498 and
501.
1.1 Evolution of Computer Aided Digital Design

• VLSI systems are much smaller and consume less power than the
discrete components used to build electronic systems before the
1960s.
• 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.
1.1 Evolution of Computer Aided Digital Design

• SSI (Small Scale Integration) chips where the gate count was very small.
• MSI (Medium Scale Integration) chips-(100 gates)
• LSI (Large Scale Integration)-( thousands of gates)
• VLSI (Very Large Scale Integration) technology, designers could design
single chips with more than 100,000 transistors.
Moore’s Law.
Evolution of Computer Aided Digital Design
• Because of the complexity of these circuits, it was not possible to
verify these circuits on a breadboard.
• Computer-Aided Design (CAD) tools
• EDA tools.
• HDL Languages
1.2 Emergence of HDLs

• 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.
Hardware description languages
• Verilog HDL - (Hardware description language)
• VHDL –(Very high-speed integrated circuit hardware description
language)

• Digital circuits could be described at a register transfer level (RTL) by


use of an HDL.
• The details of gates and their interconnections to implement the
circuit were automatically extracted by logic synthesis tools from the
RTL description
Logic synthesis
• Thus, logic synthesis pushed the HDLs to 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.
1.3 Typical Design Flow
• Unshaded blocks- level of
design representation
• shaded blocks - processes in
the design flow.
1.4 Importance of HDLs
• 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 any
fabrication technology.
1.6 Trends in HDLs
Trends in HDLs
(Behavioral synthesis )
2. Hierarchical Modeling
Concepts
2.3 Modules
Modules

module <module_name> T-flipflop could be defined as a


(<module_terminal_list>); module as follows:
.. module T_FF (q, clock, reset);
<module internals> .
... .
... <functionality of T-flipflop>
endmodule .
.
endmodule
Verilog Different level of abstraction
or Modeling
• Gate level
• Dataflow level
• Behavioral or algorithmic level
• Switch level
Gate level Modeling
• 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.
and gate design using Gate level modeling

module andgate(c,a,b);
// Port declarations from the I/O diagram
input a,b;
output c;
• // Specify the function of a design
and a1(c,a,b);
endmodule
l-bit Full Adder design using gate-level modeling
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
// Port declarations from the I/O diagram
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c1;
// Specify the function of a design
xor (s1, a, b);
and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
endmodule
4-to-1 Multiplexer design using gate level modeling
Logic Diagram for Multiplexer
Logic Diagram for Multiplexer

module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);


output out;
input i0, i1, i2, i3;
input s1, s0;
wire s1n, s0n;
wire y0, y1, y2, y3;
not (s1n, s1);
not (s0n, s0);
and (y0, i0, s1n, s0n);
and (y1, i1, s1n, s0);
and (y2, i2, s1, s0n);
and (y3, i3, s1, s0);
or (out, y0, y1, y2, y3);
endmodule
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
output out; // Port declarations from the I/O diagram
input i0, i1, i2, i3;
input s1, s0;
wire s1n, s0n; // internal nets
wire y0, y1, y2, y3; // internal nets
Verilog Description of Multiplexer
not (s1n, s1); // Functionality of the design
not (s0n, s0);
and (y0, i0, s1n, s0n);
and (y1, i1, s1n, s0);
and (y2, i2, s1, s0n);
and (y3, i3, s1, s0);
or (out, y0, y1, y2, y3);
endmodule
Dataflow level modeling
• 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.

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


// Port declarations from the I/O diagram
output sum;
output c_out;
Input a, b;
input c_in;
// Specify the function of a full adder
assign {c_out, sum} = a + b + c_in;
endmodule
1-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
// Port declarations from the I/O diagram
output sum;
output c_out;
Input a, b;
input c_in;
// Specify the function of a full adder
assign {c_out, sum} = a + b + c_in;
endmodule
4-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
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
2x1 mux design using data flow modeling

module mux_2x1 ( y, in, s);


output wire y;
input [1:0]in;
input s;
assign y = s ? in[1] : in[0];
endmodule
4x1 mux design using data flow modeling

module mux_4x1 ( y,in,s);


output wire y;
input [3:0]in;
input [1:0]s;
assign y = s[1] ? (s[0] ? in[3] : in[2]) : (s[0] ? in[1] : in[0]);
endmodule
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.
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
reg out;
always @(s1 or s0 or i0 or i1 or i2 or i3)
case ({s1, s0}) //Switch based on concatenation of control
signals
2’b00 : out = i0;
2’b01 : out = i1;
2’b10 : out = i2;
2’d11 : out = i3;
default: $display("Invalid control signals");
endcase
endmodule
4-to-1 Multiplexer design using Behavioral modeling

module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);


// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
reg out;
always @(s1 or s0 or i0 or i1 or i2 or i3)
case ({s1, s0}) //Switch based on concatenation of control signals
2'd0 : out = i0;
2'd1 : out = i1;
2'd2 : out = i2;
2'd3 : out = i3;
default: $display("Invalid control signals");
endcase
endmodule
4-bit Full Adder design using gate-level
modeling
l-bit Full Adder design using gate-level modeling
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c1;

xor (s1, a, b);


and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
4-bit Full Adder design using gate-level modeling
4-bit Ripple Carry Full
// Define a 4-bit full adder Adder
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
output c_out;
input[3:0] a, b;
input c_in;
// Internal nets
wire c1, c2, c3;
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
2.4 Instances
Instances, instantiation
// Define a 1-bit full adder
• The process of creating objects from a module module fulladd(sum, c_out, a, b, c_in);
template is called instantiation, and the output sum, c_out;
objects are called instances input a, b, c_in;
// Internal nets
wire s1, s2, c2;

fulladd fa0(sum[0], c1, a[0], b[0], c_in);


xor (s1, a, b);
fulladd fa1(sum[1], c2, a[1], b[1], c1); and (c1, a, b);
xor (sum, s1, c_in);
fulladd fa2(sum[2], c3, a[2], b[2], c2); and (s2, s1, c_in);
fulladd fa3(sum[3], c_out, a[3], b[3], or (c_out, s2, c1);
c3); endmodule
2.1 Design Methodologies
Design Methodologies
• There are two basic types of digital design methodologies:
• A top-down design methodology
• bottom-up design methodology.
A top-down 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.
A top-down design methodology
bottom-up 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.
bottom-up design methodology.
2.2 4-bit Ripple Carry Counter
2.2 4-bit Ripple Carry Counter
• To illustrate these hierarchical modeling concepts, let us consider the
design of a negative edge-triggered 4-bit ripple carry counter
4-bit Ripple Carry Counter
T-flipflop
Design Hierarchy
4-bit Ripple Carry Counter
module ripple-carry-counter(q, clk,
reset);
output [3:0] q;
input clk, reset;
T-FF tffO(q[0],clk,reset);
T-FF tff1(q[1] ,q[0], reset); module T-FF(q, clk, reset) ;
output q;
T-FF tff2 (q[2] ,q[1], reset) ; input clk, reset;
wire d;
T-FF tff3(q[3] ,q[2], reset) ; D-FF dff0 (q, d, clk, reset) ;
not nl(d, q);
endmodule endmodule
T-Flip Flop
module T-FF(q, clk, reset) ;
output q;
input clk, reset;
wire d; module D-FF(q, d, clk, reset) ;
output q;
D-FF dff0 (q, d, clk, reset) ; input d, clk, reset;
reg q;
not nl(d, q); always @(posedge reset or negedge clk)
if (reset)
endmodule q = 1'bO;
else
q = d;
endmodule
D-Flip Flop
module D-FF(q, d, clk, reset) ;
output q;
input d, clk, reset;
reg q;
always @(posedge reset or negedge clk)
if (reset)
q = 1'b0;
else
q = d;
endmodule
2.5 Components of a Simulation
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 is also
commonly called a test bench.
Stimulus Block
module andgate (c,a,b); module stimulus;
reg at;
input a,b; reg bt;
output c; wire ct;
// instantiate the design block
and a1(c,a,b);
andgate t1(ct, at, bt);
initial
endmodule begin
#5 at = 1'b0; bt=1’b0;
#10 at = 1'b0; bt=1’b1;
#5 at = 1'b1; bt=1’b0;
#5 at = 1'b1; bt=1’b1;
end
endmodule
Stimulus Block
module ripple-carry-counter(q, clk, reset) ;
output [3:0] q;
input clk, reset;

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[3l ,q[2], reset

endmodule
Stimulus Block

module stimulus;
reg clk;
reg reset;
wire[3:0] q;
// instantiate the design block
ripple-carry-counter rl(q, clk, reset);
// Control the clk signal that drives the design block.Cycle time = 10ns
initial
clk = 1'b0; //set clk to 0
always
#5 clk = -clk; //toggle clk every 5 time units
Stimulus Block
// Control the reset signal that drives the design block

initial
begin
reset = 1'b1;
#15 reset = 1'b0;
#180 reset = 1'b1;
#10 reset = 1'b0;
#20 $finish; //terminate the simulation
end
// Monitor the outputs
initial
$monitor ($time, " Output q = %d" , q) ;
endmodule
initial
begin
reset = 1'b1;
#15 reset = 1'b0;
#180 reset = 1'b1;
#10 reset = 1'b0;
#20 $finish; //terminate the simulation
end
// Monitor the outputs
initial
$monitor ($time, " Output q = %d" , q) ;
endmodule
initial
begin
reset = 1'b1;
#15 reset = 1'b0;
#180 reset = 1'b1;
#10 reset = 1'b0;
#20
$finish; //terminate the simulation
end
// Monitor the outputs
initial
$monitor ($time, " Output q = %d" , q) ;
endmodule
Modelsim Invoking step
vlip work

vmap work work


3. Basic Concepts
Basic Concepts

• Verilog Conventions module stimulus;


• The basic conventions used by reg clk;
Verilog HDL are similar to those in reg reset;
the C programming language. wire[3:0] q;
• Verilog contains a stream of tokens. // instantiate the design block
• Tokens can be comments, numbers, ripple-carry-counter rl(q, clk, reset);
strings, identifiers, and keywords. // Control the clk signal that drives the design
• Verilog HDL is a case-sensitive block.Cycle time = 10ns
language. All keywords are in initial
lowercase. clk = 1'b0; //set clk to 0
always
#5 clk = -clk; //toggle clk every 5 time units
Whitespace
• Blank spaces (\b) , tabs (\t) and newlines (\n)
• Whitespace is ignored by Verilog except when it separates tokens.
Whitespace is not ignored in strings.
Comments
• Comments can be inserted in the code for a = b && c; // This is a one-line comment
readability and documentation. There are
two ways to write comments.
• A one-line comment starts with "//". /* This is a multiple line comment */
Verilog skips from that point to the end
of line. /* This is /* an illegal */ comment */
• A multiple-line comment starts with "/*“ /* This is //a legal comment */
and ends with "*/".
• Multiple-line comments cannot be
nested.
• However, one-line comments can be
embedded in multiple-line comments.
Operators
a = ~b; // ~ is a unary operator. b is the operand
• Operators are of three types, unary,
binary, and ternary.
• Unary operators precede the operand. a = b && c; // && is a binary operator. b and c are operands
• Binary operators appear between two
operands. a = b ? c : d; // ?: is a ternary operator. b, c and d are operands
• Ternary operators have two separate
operators that separate three operands.
Number Specification
• There are two types of number specification in Verilog:
sized and unsized.
Sized numbers
• Sized numbers are represented as <size> 4'b1111 // This is a 4-bit
<base format> <number> binary number
• <size> is written only in decimal and 12‘habc // This is a 12-bit
specifies the number of bits in the number.
hexadecimal number
• Legal base formats are decimal ('d or 'D),
hexadecimal ('h or 'H), binary ('b or 'B) and 16'd255 // This is a 16-bit
octal (‘o or ‘O) decimal number.
• 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.
Unsized numbers
• Numbers that are specified without a 23456 // This is a 32-bit decimal number by
<base format> specification are default
decimal numbers by default.
'hc3 // This is a 32-bit hexadecimal number
• Numbers that are written without a
<size> specification have a default '021 // This is a 32-bit octal number
number of bits that is simulator- and
machine-specific (must be at least 32).
X or Z values
• Verilog has two symbols for 12'h13x // This is a 12-bit hex number; 4
unknown and high impedance least significant bits unknown
values 6'hx //This is a 6-bit hex number
• These values are very important
for modelling real circuits.
• An unknown value is denoted by
an X
• A high impedance value is
denoted by z.
X or Z values

• 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.
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 // 8-bit negative number stored as 2's complement of 3


4'd-2 // 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
12'b1111_0000_1010// Use of underline characters for readability
Strings
• A string is a sequence of characters that are enclosed by double
quotes.

"Hello Verilog World" // is a string


Identifiers and Keywords
reg value; // reg is a keyword; value is an identifier
input clk; // input is a keyword, clk is an identifier

• Keywords are special identifiers reserved to define the language


constructs.
• Keywords are in lowercase.
Identifiers and Keywords

• 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
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
3.2 Data Types
Value Set
• Verilog supports four values and eight strengths to model
the functionality of real hardware.
four values
Strength levels
• In addition to logic values, strength levels are often used to
resolve conflicts between drivers of different strengths in digital
circuits.
Value levels o and 1 can have the strength levels
Nets
• Nets represent connections between hardware elements.
• Nets are declared primarily with the keyword wire.
• The default value of a net is z
wire a; // Declare net a
wire b,c; // Declare two wires b,c
wire d = 1'bO; // Net d is fixed to logic value 0 at declaration.
Nets
• 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.
Registers
• Registers represent data storage elements. Registers retain
value until another value is placed onto them.
• Register data types are commonly declared by the keyword
reg. The default value for a reg data type is X
reg reset; // declare a variable reset that can hold its value
initial // this construct will be discussed later
begin
reset = 1'b1; //initialize reset to 1 to reset the digital circuit.
#l00 reset = l'bO; // after 100 time units reset is deasserted.
end
Vectors
• Nets or reg data types can be declared as vectors (multiple bit widths).
• If bit width is not specified, the default is scalar (1-bit).
Vectors

• wire a; // scalar net variable, default


• wire [7:0] bus; // 8-bit bus
• wire [31:0] busA,busB,busC; // 3 buses of 32-bit width.
• reg clock; // scalar register, default
• reg [0 : 40] virtual-addr; // vector register, virtual address 41 bits wide
• 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.
Vector Part Select
• it is possible to address bits or parts of vectors. • wire a; // scalar net variable,
• bus A[7] // bit 7 of vector bus default
A
• bus[2:0] // Three least • wire [7:0] bus; // 8-bit bus
significant bits of vector bus,
• // using bus[0:2] is illegal
• wire [31:0] busA,busB,busC; // 3
because the significant bit buses of 32-bit width.
should
• reg clock; // scalar register,
• // always be on the left of a
range specification default
• virtual-addr [0:1] //Two most • reg [0 : 40] virtual-addr; //
significant bits of vector
virtual-addr vector register, virtual address
41 bits wide
Variable Vector Part Select
• Another ability provided in Verilog HDL is to have variable part selects of a
vector. This allows part selects to be put in for loops to select various parts of
the vector.
• There are two special part-select operators:
[<starting_bit>+:width] - part-select increments from starting bit
Variable Vector Part Select
• reg [255:0] data1; //Little endian notation
• reg [0:255] data2; //Big endian notation
• reg [7:0] byte;
• //Using a variable part select, one can choose parts
• byte = data1[31-:8]; //starting bit = 31, width =8 => data[31:24]
• byte = data1[24+:8]; //starting bit = 24, width =8 => data[31:24]
• byte = data2[31-:8]; //starting bit = 31, width =8 => data[24:31]
• byte = data2[24+:8]; //starting bit = 24, width =8 => data[24:31]
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.
Integer
• integer counter; // general purpose variable used as a counter.
initial
counter = -1; // A negative one is stored in the counter
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>.
reg [4:0] a;
a=-5'd3 // 8-bit negative number stored as 2's complement of 3
4'd-2 // Illegal specification
Real
• Real number constants and real register data types are declared with the
keyword real.
• They can be specified in decimal notation (e.g., 3.14) or in scientific
notation (e.g., 3e6, which is 3 X10^6 ).
• Real numbers cannot have a range declaration, and their default value is
0.
• When a real value is assigned to an integer, the real number is rounded
off to the nearest integer.
Real
real delta; // Define a real variable called delta
initial
begin

delta = 4e10; // delta is assigned in scientific
.

notation
delta = 2.13; // delta is assigned a value 2.13
end
integer i; // Define an integer i
initial
i = delta; // 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
time save-sim-time; // Define a time variable save-sim-time
initial
save-sim-time = $time; // Save the current simulation time
Stimulus Block
// Control the reset signal that drives the design block

initial
begin
reset = 1'b1;
#15 reset = 1'b0;
#180 reset = 1'b1;
#10 reset = 1'b0;
#20 $finish; //terminate the simulation
end
// Monitor the outputs
initial
$monitor ($time, " Output q = %d" , q) ;
endmodule
One dimensional Arrays wire [7:0] bus; // 8-bit bus
Two dimensional Arrays
Arrays
Vector Vs Arrays
Vector: Arrays:
• A vector is a single
• arrays are multiple elements
element that is n-bits
wide. that are 1-bit or n-bits wide.
Arrays
• Arrays are allowed in Verilog for net, reg, integer, time, real and vector
register data types.
• Multi-dimensional arrays can also be declared with any
number of dimensions.
integer count[0:7]; // An array of 8 count variables
reg bool[31:0]; // Array of 32 one-bit boolean register variables
time chk_point[1:100]; // Array of 100 time checkpoint variables
Arrays
wire [7:0] w_array2 [5:0]; // Declare an array of 8 bit vector wire
reg [4:0] port_id[0:7]; // Array of 8 port_ids; each
port_id is 5 bits wide

wire w_array1[7:0][5:0]; // Declare an array of


single bit wires
integer matrix[4:0][0:255]; // Two dimensional array of integers
reg [63:0] array_4d [15:0][7:0][7:0][255:0]; //Four dimensional array
reg array_4d [6:0][4:0][2:0][2:0]; //Four dimensional array
Assignments to elements of arrays
integer count[0:7]; count[5] = 0;
time chk_point[1:100]; chk_point[100] = 0;
reg [4:0] port_id[0:7];
port_id[3] = 0; //5 bits
--------------------
port_id = 0; //Illegal syntax
integer matrix[4:0][0:255];
matrix[1][0] = 33559;
Accessing Elements of Multi dimensional Array
Memories
• Memories are modeled in Verilog simply as a one-dimensional
array of registers.
• Each element of the array is known as an element or word
• reg mem1bit[0:1023]; // Memory mem1bit with 1K 1-
bit words
• reg [7:0] membyte[0:1023]; // Memory membyte with
1K 8-bit words(bytes)
• membyte[511] // Fetches 1 byte word whose address
is 511.
Parameters
• Verilog allows constants to be defined in a module by
the keyword parameter.
• Parameters cannot be used as variables.
parameter port_id = 5; // Defines a constant port_id
parameter cache_line_width = 256;
Parameters
module ripple-carry-counter(q, clk, reset);
parameter countout = 3;
output [countout:0] q;
input clk, reset;

T-FF tff0(q[0] ,clk, reset)


T-FF tff1(q[l] ,q[0], reset
T-FF tff2 (q[2] ,q[1], reset
T-FF tff3 (q[3l ,q[2], reset

endmodule
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 register width is smaller than the string width,
Verilog truncates the leftmost bits of the string.
Strings
reg [8*18:1] string_value; // Declare a variable that is 18 bytes wide
initial
string_value = "Hello Verilog World"; // String can be stored // in
variable
System Tasks and
Compiler Directives
System Tasks
• Verilog provides standard system tasks for 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.
System Tasks
• Displaying information
• Monitoring information
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(p1, p2, p3,....., pn);
• p1, 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.
Displaying information

//Display the string in quotes


$display("Hello Verilog World");
-- Hello Verilog World
//Display value of current simulation time 230
$display($time);
-- 230
Time
time save-sim-time; // Define a time variable save-sim-time
initial
save-sim-time = $time; // Save the current simulation time
String Format Specifications
String Format Specifications
//Display value of 41-bit virtual address 1fe0000001c at time 200
reg [0:40] virtual_addr;
$display("At time %d virtual address is %h", $time, virtual_addr);
-- At time 200 virtual address is 1fe0000001c
String Format Specifications
//Display value of port_id 5 in binary
reg [4:0] port_id;
$display("ID of the port is %b", port_id);
-- ID of the port is 00101
Special characters
Special characters

//Display special characters, newline and %


$display("This is a \n multiline string with a %% sign");

-- This is a
-- multiline string with a % sign
Monitoring information
• Verilog provides a mechanism to monitor a signal
when its value changes.
• This facility is provided by the $monitor task.
Usage: $monitor(p1,p2,p3,....,pn);
• $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.
Monitoring information
//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," Value of signals clock = %b reset = %b", clock,reset);
end
Partial output of the monitor statement:
-- 0 Value of signals clock = 0 reset = 1
-- 5 Value of signals clock = 1 reset = 1
-- 10 Value of signals clock = 0 reset = 0
Monitoring information
• Unlike $display, $monitor needs to be invoked only
once.
• 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;
Stopping and finishing in a simulation
• 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.
Stopping and finishing in a simulation
// Stop at time 100 in the simulation and examine the results
// Finish the simulation at time 1000.
initial // to be explained later. time = 0
begin
clock = 0;
reset = 1;
#100 $stop; // This will suspend the simulation at time = 100
#900 $finish; // This will terminate the simulation at time = 1000
end
Compiler Directives

• Compiler directives are provided in Verilog. All


compiler directives are defined by using the
`<keyword> construct.
`define
`include
`define
• The `define directive is used to define text
macros in Verilog
• This is similar to the #define construct in C.
//define a text macro that defines default word size
//Used as 'WORD_SIZE in the code
'define WORD_SIZE 32
//define an alias. A $stop will be substituted wherever 'S
appears
'define S $stop;
`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.
`include
// Include the file header.v, which contains declarations in the
// main verilog file design.v.
• 'include header.v
• ...
• ...
• <Verilog code in file design.v>
• ...
• ...
Chapter 4. Modules and Ports
4.1 Modules
Components of a Verilog Module
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.
Components of a Verilog Module

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 any place in the module
definition.
Components of a Verilog Module

• 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.
SR Latch
SR Latch
• // Module name and port list
• // SR_latch module
• module SR_latch(Q, Qbar, Sbar, Rbar);
• //Port declarations
• output Q, Qbar;
• input Sbar, Rbar;
• // Instantiate lower-level modules
• // In this case, instantiate Verilog primitive nand gates
• // Note, how the wires are connected in a cross-coupled
fashion.
• nand n1(Q, Sbar, Qbar);
• nand n2(Qbar, Rbar, Q);
• // endmodule statement
• endmodule
SR Latch

• In the SR latch definition module SR_latch(Q, Qbar, Sbar,


above , notice that all Rbar);
components need not be output Q, Qbar;
present in a module.
input Sbar, Rbar;
• We do not find variable
declarations, dataflow (assign) nand n1(Q, Sbar, Qbar);
statements, or behavioral nand n2(Qbar, Rbar, Q);
blocks (always or initial).
endmodule
• // Stimulus module
• // Module name and port list is not present
• module Top;
• // Declarations of wire, reg, and other variables
• 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 m1(q, qbar, ~set, ~reset);
• // Behavioral block, initial
initial
Begin
$monitor($time, " set = %b, reset= %b, q= %b\n", set, reset, q);
• set = 0; reset = 0;
• #5 reset = 1;
• #5 reset = 0;
• #5 set = 1;
end
// endmodule statement
endmodule
SR Latch-Stimulus block
module Top;
• However, the stimulus block for wire q, qbar;
the SR latch contains module reg set, reset;
name, wire, reg.
SR_latch m1(q, qbar, ~set, ~reset);
• instantiation of lower level initial
modules, Begin
• behavioral block (initial), and $monitor($time, " set = %b, reset= %b, q= %b\n", set, reset,
endmodule statement q);
• but does not contain port list, port set = 0; reset = 0;
declarations, and data flow #5 reset = 1;
(assign) statements. #5 reset = 0;
• Thus module, module #5 set = 1;
end
name, and endmodule endmodule
are must
4.2 Ports
Ports
• Ports provide the interface by which a module can
communicate with its environment.
• For example, the input/output pins of an IC chip are its
ports. The environment can interact with the module
only through its ports.
List of Ports
• Input
• Output
• Inout
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.
I/O Ports for Top and Full Adder
I/O Ports for Top and Full Adder

• module fulladd4(sum, c_out, a, b, c_in); • the module Top is a top-level module.


//Module with a list of ports • The module fulladd4 is instantiated
below Top.
• module Top; // No list of ports, top-level • The module fulladd4 takes input on
module in simulation 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.
Port Declaration
• All ports in the list of ports must be declared in the
module.
Port Declaration
• Each port in the port list is defined as input, output, or inout, based on the
direction of the port signal.

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
Port Declaration

• Note that all port declarations are implicitly declared as wire


in Verilog.
• input or inout ports are normally declared as wires.
Port Declaration

• However, if output ports hold their value, they must be


declared as reg.
• For example, in the definition of DFF
module DFF(q, d, clk, reset);
output q;
reg q; // Output port q holds value; therefore it is declared as reg.
input d, clk, reset;
...
...
endmodule
Port Declaration
• Ports of the type input and inout cannot be declared as
reg
Port Declaration
• the module fulladd4 can be declared using an ANSI C
style
module fulladd4(output reg [3:0] sum, output reg c_out,
input [3:0] a, b, //wire by default
input c_in); //wire by default
...
<module internals>
...
endmodule
Reg data type rule
• Any output or any variable value is assigned inside the always or initial
block(Behavioral block)that must be assigned as a register by the key
word reg
module D-FF(q, d, clk, reset) ;
output q;
input d, clk, reset;
reg q;
always @(posedge reset or negedge clk)
if (reset)
q = 1'b0;
else
q = d;
endmodule
4-to-1 Multiplexer design using Behavioral modeling

module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);


// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
reg out;
always @(s1 or s0 or i0 or i1 or i2 or i3)
case ({s1, s0}) //Switch based on concatenation of control signals
2'd0 : out = i0;
2'd1 : out = i1;
2'd2 : out = i2;
2'd3 : out = i3;
default: $display("Invalid control signals");
endcase
endmodule
Port Connection Rules

• One can visualize a port as consisting of two units, one


unit that is internal to the module and another that is
external to the module.
• internal to the module- design
• external to the module –test bench
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.
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.
Stimulus Block

module stimulus;
reg clk;
reg reset;
wire[3:0] q;
// instantiate the design block
ripple-carry-counter rl(q, clk, reset);
// Control the clk signal that drives the design block.Cycle time = 10ns
initial
clk = 1'b0; //set clk to 0
always
4-bit Full adder design using 1-bit full adder

// Define a 1-bit full adder // Define a 4-bit full adder


module fulladd(sum, c_out, a, b, c_in); module fulladd4(sum, c_out, a, b, c_in);
output sum, c_out; output [3:0] sum;
input a, b, c_in; output c_out;
// Internal nets input[3:0] a, b;
wire s1, s2, c1; input c_in;
// Internal nets
xor (s1, a, b); wire c1, c2, c3;
and (c1, a, b); fulladd fa0(sum[0], c1, a[0], b[0], c_in);
xor (sum, s1, c_in); fulladd fa1(sum[1], c2, a[1], b[1], c1);
and (s2, s1, c_in); fulladd fa2(sum[2], c3, a[2], b[2], c2);
or (c_out, s2, c1); fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule endmodule
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c1;

xor (s1, a, b);


and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
4-bit Ripple Carry Full
// Define a 4-bit full adder Adder
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
output c_out;
input[3:0] a, b;
input c_in;
// Internal nets
wire c1, c2, c3;
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
Port Connection Rules

inouts
• Internally, inout ports
must always be of the
type net.
• Externally, inout ports
must always be connected
to a net.
Port Connection Rules
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.
fulladd4 fa0(SUM, , A, B, C_IN); // Output port c_out is unconnected
Example of illegal port connection
module Top;
• //Declare connection variables
reg [3:0]A,B;
reg C_IN;
reg [3:0] SUM;
wire C_OUT;
//Instantiate fulladd4, call it fa0
fulladd4 fa0(SUM, C_OUT, A, B, C_IN);
//Illegal connection because output port sum in module fulladd4
//is connected to a register variable SUM in module Top.
<stimulus>
• endmodule
Example of illegal port connection
This problem is rectified if the variable SUM is declared as a net (wire).
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.
• Connecting by ordered list
• Connecting ports by name
Connecting by ordered list
• 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.
4-bit Full adder design using 1-bit full adder

// Define a 1-bit full adder // Define a 4-bit full adder


module fulladd(sum, c_out, a, b, c_in); module fulladd4(sum, c_out, a, b, c_in);
output sum, c_out; output [3:0] sum;
input a, b, c_in; output c_out;
// Internal nets input[3:0] a, b;
wire s1, s2, c1; input c_in;
// Internal nets
xor (s1, a, b); wire c1, c2, c3;
and (c1, a, b); fulladd fa0(sum[0], c1, a[0], b[0], c_in);
xor (sum, s1, c_in); fulladd fa1(sum[1], c2, a[1], b[1], c1);
and (s2, s1, c_in); fulladd fa2(sum[2], c3, a[2], b[2], c2);
or (c_out, s2, c1); fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule endmodule
Connecting by ordered list
• module Top;
• module fulladd4(sum, c_out, a, • //Declare connection variables
b, c_in); • reg [3:0]A,B;
• output[3:0] sum; • reg C_IN;
• wire [3:0] SUM;
• output c_cout; • wire C_OUT;
• input [3:0] a, b; • //Instantiate fulladd4, call it
fa_ordered.
• input c_in; • //Signals are connected to ports in
• ... order (by position)
• fulladd4 fa_ordered(SUM, C_OUT, A,
• <module internals> B, C_IN);
• ...
• ...
• <stimulus>
• endmodule • ...
• endmodule
Connecting by ordered list
• module fulladd4(sum, c_out, a, b, c_in);
• fulladd4 fa_ordered(SUM, C_OUT, A, B, C_IN);
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
• Verilog provides the capability to connect external
signals to ports by the port names, rather than by
position.
• // 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),);
Connecting by ordered list
• module Top;
• module fulladd4(sum, c_out, a, • //Declare connection variables
b, c_in); • reg [3:0]A,B;
• output[3:0] sum; • reg C_IN;
• wire [3:0] SUM;
• output c_cout; • wire C_OUT;
• input [3:0] a, b; • //Instantiate fulladd4, call it
fa_ordered.
• input c_in; • //Signals are connected to ports in
order (by position)
• ... • fulladd4
fa_byname(.c_out(C_OUT), .sum(SUM), .b
• <module internals> (B), .c_in(C_IN), .a(A),);

• ... ...
• <stimulus>
• endmodule • ...
• endmodule
Chapter 5. Gate-Level
Modeling
Gate-Level Modeling

• At gate level, the circuit is described in terms of


gates (e.g., and, nand).
• Hardware design at this level requires basic
knowledge of digital logic design
Gate Types

• Verilog supports basic logic gates as predefined


primitives.
• These primitives are instantiated like modules
• They are predefined in Verilog and do not need a
module definition.
• There are two classes of basic gates:
and/or gates
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.
and or xor
nand nor xnor
And/Or Gates
And/Or Gates
Gate Instantiation of And/Or Gates

wire OUT, IN1, IN2;


// basic gate instantiations.
and a1(OUT, IN1, IN2);
nand na1(OUT, IN1, IN2);
or or1(OUT, IN1, IN2);
nor nor1(OUT, IN1, IN2);
xor x1(OUT, IN1, IN2);
xnor nx1(OUT, IN1, IN2);
Gate Instantiation of And/Or Gates

// More than two inputs; 3 input nand gate


nand na1_3inp(OUT, IN1, IN2, IN3);
// gate instantiation without instance name
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 provided in Verilog.
buf not
Not Gates
Buf Gates
Gate Instantiations of Buf/Not Gates

// basic gate instantiations.


buf b1(OUT1, IN);
not n1(OUT1, IN);
// More than two outputs
buf b1_2out(OUT1, OUT2, IN);
// gate instantiation without instance name
not (OUT1, IN); // legal gate instantiation
Bufif/notif
• Gates with an additional control signal on buf
and not gates
• These gates propagate only if their control signal
is asserted. They propagate z if their control
signal is deasserted.

bufif1 notif1
bufif0 notif0
bufif1 bufif0
notif0
notif1
Gate Instantiations of Bufif/Notif
Gates
//Instantiation of bufif gates.
bufif1 b1 (out, in, ctrl);
bufif0 b0 (out, in, ctrl);
//Instantiation of notif gates
notif1 n1 (out, in, ctrl);
notif0 n0 (out, in, ctrl);
Array of Instances
• There are many situations when repetitive instances
are required.
• These instances differ from each other only by the
index of the vector to which they are connected.
• To simplify specification of such instances, Verilog
HDL allows an array of primitive instances to be
defined.
Simple Array of Primitive Instances
wire [7:0] OUT, IN1, IN2;
// basic gate instantiations.
nand n_gate[7:0](OUT, IN1, IN2);
// This is equivalent to the following 8 instantiations
nand n_gate0(OUT[0], IN1[0], IN2[0]);
nand n_gate1(OUT[1], IN1[1], IN2[1]);
nand n_gate2(OUT[2], IN1[2], IN2[2]);
nand n_gate3(OUT[3], IN1[3], IN2[3]);
nand n_gate4(OUT[4], IN1[4], IN2[4]);
nand n_gate5(OUT[5], IN1[5], IN2[5]);
nand n_gate6(OUT[6], IN1[6], IN2[6]);
nand n_gate7(OUT[7], IN1[7], IN2[7]);
4-to-1 Multiplexer
Logic Diagram for Multiplexer
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
output out;
input i0, i1, i2, i3;
Verilog Description of Multiplexer
input s1, s0;
wire s1n, s0n;
wire y0, y1, y2, y3;
not (s1n, s1);
not (s0n, s0);
and (y0, i0, s1n, s0n);
and (y1, i1, s1n, s0);
and (y2, i2, s1, s0n);
and (y3, i3, s1, s0);
or (out, y0, y1, y2, y3);
endmodule
Stimulus for Multiplexer
module stimulus;
reg IN0, IN1, IN2, IN3;
reg S1, S0;
wire OUTPUT;
mux4_to_1 mymux(OUTPUT, IN0, IN1, IN2, IN3, S1, S0);
initial
begin
IN0 = 1; IN1 = 0; IN2 = 1; IN3 = 0;
#5 S1 = 0; S0 = 0;
#5 S1 = 0; S0 = 1;
#5 S1 = 1; S0 = 0;
#5 S1 = 1; S0 = 1;
end
endmodule
The output of the simulation
• 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
• S1 = 1, S0 = 1, OUTPUT = 0
• 4-bit Ripple Carry Full Adder
Verilog Description for l-bit Full Adder
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c2;

xor (s1, a, b);


and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
endmodule
// Define a 4-bit full adder
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
output c_out;
input[3:0] a, b;
4-bit Ripple Carry Full
Adder
input c_in;
// Internal nets
wire c1, c2, c3;
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
Stimulus for 4-bit Ripple Carry Full Adder
module stimulus;
// Set up variables
reg [3:0] A, B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
fulladd4 FA1_4(SUM, C_OUT, A, B, C_IN);
Initial
begin
A = 4'd0; B = 4'd0; C_IN = 1'b0;
#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 = 4'd10; B = 4'd5; C_IN = 1'b1;
end
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
endmodule
The output of the simulation is shown below.

0 A= 0000, B=0000, C_IN= 0, --- C_OUT= 0, SUM= 0000 A = 4'd0; B = 4'd0; C_IN = 1'b0;
5 A= 0011, B=0100, C_IN= 0, --- C_OUT= 0, SUM= 0111 #5 A = 4'd3; B = 4'd4;
10 A= 0010, B=0101, C_IN= 0, --- C_OUT= 0, SUM= 0111 #5 A = 4'd2; B = 4'd5;
15 A= 1001, B=1001, C_IN= 0, --- C_OUT= 1, SUM= 0010 #5 A = 4'd9; B = 4'd9;
20 A= 1010, B=1111, C_IN= 0, --- C_OUT= 1, SUM= 1001
#5 A = 4'd10; B = 4'd15;
25 A= 1010, B=0101, C_IN= 1 --- C_OUT= 1, SUM= 0000
#5 A = 4'd10; B = 4'd5; C_IN = 1'b1;
Gate Delays

• In real circuits, logic gates have delays associated


with them.
• Rise, Fall, and Turn-off Delays
Rise delay

• The rise delay is associated with a gate output transition


to a 1 from another value.
Fall delay
• The fall delay is associated with a gate output transition
to a 0 from another value.
Turn-off delay
• The turn-off delay is associated with a gate output
transition to the high impedance value (z) from another
value
Types of Delay Specification
• If the value changes to x, the minimum of the three delays is considered.
• 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.
Types of Delay Specification
// Delay of delay_time for all transitions
and #(delay_time) a1(out, i1, i2);
// Rise and Fall Delay Specification.
and #(rise_val, fall_val) a2(out, i1, i2);
// Rise, Fall, and Turn-off Delay Specification
bufif0 #(rise_val, fall_val, turnoff_val) b1 (out, in, control);
Examples of delay specification are shown
below.
and #(5) a1(out, i1, i2); //Delay of 5 for all transitions
and #(4,6) a2(out, i1, i2); // Rise = 4, Fall = 6
bufif0 #(3,4,5) b1 (out, in, control); // Rise = 3, Fall = 4, Turn-off= 5
Min/Typ/Max Values

• For each type of delay rise, fall, and turn-off three


values, min, typ, and max, can be specified.
• Any one value can be chosen at the start of the simulation.
• Min/typ/max values are used to model devices whose delays
vary within a minimum and maximum range because of the IC
fabrication process variations.
• Method of choosing a min/typ/max value may vary for different
simulators or operating systems.
• The designer can experiment with delay values without
modifying the design.
Min, Max, and Typical Delay Values
• // One delay
• // if +mindelays, delay= 4
• // if +typdelays, delay= 5
• // if +maxdelays, delay= 6
and #(4:5:6) a1(out, i1, i2);
// Two delays

• // 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)
and #(3:4:5, 5:6:7) a2(out, i1, i2);
// Three delays

• // 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
and #(2:3:4, 3:4:5, 4:5:6) a3(out, i1,i2);
Examples of invoking the Verilog-XL simulator
//invoke simulation with maximum delay
> verilog test.v +maxdelays
//invoke simulation with minimum delay
> verilog test.v +mindelays
//invoke simulation with typical delay
> verilog test.v +typdelays
Delay Example
Verilog Definition for Module D with
Delay
module D (out, a, b, c);
output out;
input a,b,c;
wire e;
// Instantiate primitive gates to build the
circuit
and #(5) a1(e, a, b); //Delay of 5 on gate a1
or #(4) o1(out, e,c); //Delay of 4 on gate o1
endmodule
Stimulus for Module D with Delay

module stimulus;
reg A, B, C;
wire OUT;
// Instantiate the module D
D d1( OUT, A, B, C);
Stimulus for Module D with Delay
initial
begin
A= 1'b0; B= 1'b0; C= 1'b0;
#10 A= 1'b1; B= 1'b1; C= 1'b1;
#10 A= 1'b1; B= 1'b0; C= 1'b0;
#20 $finish;
end
endmodule
Waveforms for Delay Simulation

and #(5) a1(e, a,


b); //Delay of 5 on
gate a1
or #(4) o1(out,
e,c); //Delay of 4 on
gate o1

A= 1'b0; B= 1'b0; C= 1'b0;


#10 A= 1'b1; B= 1'b1; C= 1'b1;
#10 A= 1'b1; B= 1'b0; C= 1'b0;
#20 $finish;
Gate level Modeling
Data types
Net data types
Variables
Hierarchical Names
• Verilog supports a hierarchical design
methodology.
• Every module instance, signal, or variable is
defined with an identifier.
• A hierarchical name is a list of identifiers
separated by dots (".") 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.
SR Latch
SR Latch
• // Module name and port list
• // SR_latch module
• module SR_latch(Q, Qbar, Sbar, Rbar);
• //Port declarations
• output Q, Qbar;
• input Sbar, Rbar;
• // Instantiate lower-level modules
• // In this case, instantiate Verilog primitive nand gates
• // Note, how the wires are connected in a cross-coupled fashion.
• nand n1(Q, Sbar, Qbar);
• nand n2(Qbar, Rbar, Q);
• // endmodule statement
• endmodule
SR Latch
• // Stimulus module
• // Module name and port list is not present
• module Top;
• // Declarations of wire, reg, and other variables
• 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 m1(q, qbar, ~set, ~reset);
Design Hierarchy for SR Latch Simulation

module Top;
wire q, qbar;
reg set, reset;
SR_latch m1(q, qbar, ~set, ~reset);
-----------------------------------------
module SR_latch(Q, Qbar,
Sbar, Rbar);
output Q, Qbar;
input Sbar, Rbar;
nand n1(Q, Sbar, Qbar);
nand n2(Qbar, Rbar, Q);
endmodule
Hierarchical Names

• stimulus
stimulus.q
• stimulus.qbar
stimulus.set
• stimulus.reset
stimulus.m1
• stimulus.m1.Q
stimulus.m1.Qbar
• stimulus.m1.S
stimulus.m1.R
• stimulus.m1.n1
stimulus.m1.n2
Chapter 6. Dataflow
Modeling
6.1 Continuous Assignments
Continuous Assignments
• A continuous assignment is the most basic statement // Continuous assign. out is a net. i1
in dataflow modeling, used to drive a value onto a net. and i2 are nets.
assign out = i1 & i2;
• The assignment statement starts with the keyword
assign. The syntax of an assign statement is as follows. // Continuous assign for vector nets.
addr is a 16-bit vector net
// addr1 and addr2 are 16-bit vector
continuous_assign ::= assign [ drive_strength ] [ delay3 ] list_of_net_assignments ; registers.
list_of_net_assignments ::= net_assignment { , net_assignment } assign addr[15:0] = addr1_bits[15:0] ^
addr2_bits[15:0];
net_assignment ::= net_lvalue = expression
// Concatenation. Left-hand side is a
Notice that drive strength is optional concatenation of a scalar
• The default value for drive strength is strong1 and // net and a vector net.
• The delay value is also optional and can be used to specify delay on the
strong0.
assign statement. assign {c_out, sum[3:0]} = a[3:0] + b[3:0] +
c_in;
• This is like specifying delays for gates.
Continuous assignments have the following characteristics:

1. The left hand side of an assignment // Continuous assign. out is a net. i1 and i2 are nets.
must always be a scalar or vector net or assign out = i1 & i2;
a concatenation of scalar and vector // Continuous assign for vector nets. addr is a 16-bit vector
nets.It cannot be a scalar or vector net
register. // addr1 and addr2 are 16-bit vector registers.

2. Continuous assignments are always assign addr[15:0] = addr1_bits[15:0] ^ addr2_bits[15:0];


active.The assignment expression is // Concatenation. Left-hand side is a concatenation of a
scalar
evaluated as soon as one of the right-
hand-side operands changes and the // net and a vector net.
value is assigned to the left-hand-side assign {c_out, sum[3:0]} = a[3:0] + b[3:0] + c_in;
net.
Continuous assignments have the following characteristics:

3. The operands on the right- // Continuous assign. out is a net. i1 and i2


hand side can be registers or are nets.
assign out = i1 & i2;
nets or function calls.
// Continuous assign for vector nets. addr is a
Registers or nets can be scalars 16-bit vector net
or vectors. // addr1 and addr2 are 16-bit vector registers.
4. Delay values can be assign addr[15:0] = addr1_bits[15:0] ^
addr2_bits[15:0];
specified for assignments in // Concatenation. Left-hand side is a
terms of time units. This concatenation of a scalar
feature is similar to specifying // net and a vector net.
delays for gates. assign {c_out, sum[3:0]} = a[3:0] + b[3:0] +
c_in;
Implicit Continuous Assignment

• Instead of declaring a net //Regular continuous


and then writing a assignment
continuous assignment on wire out;
the net,
assign out = in1 & in2;
• Verilog provides a shortcut
by which a continuous //Same effect is achieved
assignment can be placed by an implicit continuous
on a net when it is assignment
declared. wire out = in1 & in2;
Implicit Net Declaration

• If a signal name is used to the left of the continuous


assignment, an implicit net declaration will be inferred
for that signal name.
// Continuous assign. out is a net.
wire i1, i2;
assign out = i1 & i2; //Note that out was not declared as a wire
//but an implicit wire declaration for out
//is done by the simulator
6.2 Delays
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.
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.

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 unit.
Regular Assignment Delay
• If in1 or in2 changes value again • assign #10 out = in1 &
before 10 time units when the in2; // Delay in a
result propagates to out, the continuous assign
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.
inertial delay.

A pulse of width less than the specified assignment delay is not propagated to the output.
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;
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 Delays
wire # 10 out;
assign out = in1 & in2;
//The above statement has the same effect as the following.
wire out;
assign #10 out = in1 & in2;
6.3 Expressions, Operators, and Operands
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.
Expressions

• Expressions are constructs that combine operators and


operands to produce a result.
// Examples of expressions. Combines operands
and operators
a ^ b
addr1[20:17] + addr2[20:17]
in1 | in2
Operands

• Operands can be any one of integer count, final_count;


the data types. final_count = count + 1;//count is an
• Operands can be integer operand
constants, integers, real real a, b, c;
numbers, nets, registers, times,
c = a - b; //a and b are real operands
bit-select (one bit of vector net
or a vector register), reg [15:0] reg1, reg2;
part-select (selected bits of the reg [3:0] reg_out;
vector net or register vector), reg_out = reg1[3:0] ^ reg2[3:0];
and memories or function calls
//reg1[3:0] and reg2[3:0] are
//part-select register operands
Operators
• Operators act on the operands to produce desired results.
d1 && d2 // && is an operator on operands d1 and d2
!a[0] // ! is an operator on operand a[0]
B >> 1 // >> is an operator on operands B and 1
Operator types

• Verilog provides many different operator types.


• arithmetic,
• logical,
• relational,
• equality,
• bitwise,
• reduction,
• shift,
• concatenation,
• conditional.
Arithmetic
Logical
Bitwise
Reduction
Relational
Equality
Shift
Concatenation, Replication, Conditional Operators
Arithmetic Operators
• Two types of arithmetic operators:
binary and unary
Binary operators
• Binary arithmetic operators are multiply (*), divide (/), add (+),
subtract (-), power (**), and modulus (%).
• Binary operators take two operands.
Binary operators
A = 4'b0011; B = 4'b0100; // A and B are register vectors
D = 6; E = 4; F=2; // D and E are integers
A * B // Multiply A and B. Evaluates to 4'b1100
D / E // Divide D by E. Evaluates to 1. Truncates any fractional part.
A + B // Add A and B. Evaluates to 4'b0111
B - A // Subtract A from B. Evaluates to 4'b0001
F = E ** F; //E to the power F, yields 16
Binary operators
• If any operand bit has a value x, then the result of the entire expression
is x.

in1 = 4'b101x;
in2 = 4'b1010;
sum = in1 + in2; // sum will be evaluated to the value 4'bx
Binary operators
• Modulus operators produce the remainder from the division of two
numbers.
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 +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 // Negative 4
+5 // Positive 5
Unary operators
• 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.
//Advisable to use integer or real numbers
-10 / 5// Evaluates to -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 conditions:

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


or x.
2. If an operand is not equal to zero, it is equivalent to a
logical 1 (true condition).
If any operand bit is x or z, it is equivalent to x and is
normally treated by simulators as a false condition.
3. Logical operators take variables or expressions as
operands.
Logical operators
// Logical operations
A = 3; B = 0;
A && B // Evaluates to 0. Equivalent to (logical-1 && logical-0)
A || B // Evaluates to 1. Equivalent to (logical-1 || logical-0)
!A // Evaluates to 0. Equivalent to not(logical-1)
!B // Evaluates to 1. Equivalent to not(logical-0)
Logical operators
A = 3; B = 0;
A && B
A || B
!A
!B
Logical operators
// Unknowns
A = 2'b0x; B = 2'b10;
A && B // Evaluates to x. Equivalent to (x && logical 1)
// Expressions
(a == 2) && (b == 3) // Evaluates to 1 if both a == 2 and b == 3 are true.
// Evaluates to 0 if either is false.
Logical operators
// Unknowns
A = 2'b0x; B = 2'b10;
A && B // Evaluates to x. Equivalent to (x && logical 1)
// Expressions
(a == 2) && (b == 3) // Evaluates to 1 if both a == 2 and b == 3 are true.
// Evaluates to 0 if either is false.
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.
Bitwise
Bitwise Operators
• A z is treated as an x in a bitwise operation.
• Unary negation operator (~), which takes only one operand
and operates on the bits of the single operand.
Truth Tables for Bitwise Operators
Truth Tables for Bitwise Operators
Examples of bitwise operators
// X = 4'b1010, Y = 4'b1101
// Z = 4'b10x1
~X // Negation. Result is 4'b0101
X & Y // Bitwise and. Result is 4'b1000
X | Y // Bitwise or. Result is 4'b1111
X ^ Y // Bitwise xor. Result is 4'b0111
X ^~ Y // Bitwise xnor. Result is 4'b1000
X & Z // Result is 4'b10x0
Difference
• It is important to distinguish bitwise operators ~, &, and |
from logical operators !, &&, ||.
• 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.
Difference
// X = 4'b1010, Y = 4'b0000

X | Y // bitwise operation. Result is 4'b1010


X || Y // logical operation. Equivalent to 1 || 0. Result is 1.
Reduction
Reduction Operators
• Reduction operators are and (&), nand (~&), or (|), nor (~|),
xor (^), and xnor (~^, ^~).
• Reduction operators take only one operand.
• Reduction operators perform a bitwise operation on a single
vector operand and yield a 1-bit result.
• 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
// X = 4'b1010
• Reduction operators work bit by bit
from right to left. &X //Equivalent to 1 & 0 & 1 & 0. Results in 1'b0
• Reduction nand, reduction nor, and |X//Equivalent to 1 | 0 | 1 | 0. Results in 1'b1
reduction xnor are computed by ^X//Equivalent to 1 ^ 0 ^ 1 ^ 0. Results in 1'b0
inverting the result of the reduction
and, reduction or, and reduction xor,
//A reduction xor or xnor can be used for even or odd
respectively. parity generation of a vector.
Reduction Operators

• The use of a similar set of symbols for logical (!, &&, ||),
bitwise (~, &, |, ^), and reduction operators (&, |, ^) is
somewhat confusing initially.
• The difference lies in the number of operands each operator
takes
Relational Operators

Relational operators are // A = 4, B = 3


greater-than (>), less-than (<), greater-than- // X = 4'b1010, Y = 4'b1101, Z =
or-equal-to (>=), and 4'b1xxx
less-than-or-equal-to (<=).
A <= B // Evaluates to a logical 0
• If relational operators are used in an
expression, the expression returns a A > B // Evaluates to a logical 1
logical value of 1 if the expression is true
and 0 if the expression is false. Y >= X // Evaluates to a logical 1
• If there are any unknown or z bits in the Y < Z // Evaluates to an x
operands, the expression takes a value x.
• These operators function exactly as the
corresponding operators in the C
programming language.
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.
• It is important to note the difference between the logical equality operators (==, !=) and case
equality operators (===, !==).
• The logical equality operators (==, !=) will yield an x if either operand has x or z in its bits.
• However, the case equality operators ( ===, !== ) 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 0 if the operands do not match exactly. Case equality operators never result in an x.
Equality Operators
Equality Operators
// A = 4, B = 3
// X = 4'b1010, Y = 4'b1101
// 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 // 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 // Results in logical 1
Shift Operators
• Shift operators are right shift ( >>), left shift (<<), arithmetic right shift
(>>>), and arithmetic left shift (<<<).
• Regular shift operators shift a vector operand to the right or the left by
a specified number of bits.
• The operands are the vector.
• When the bits are shifted, the vacant bit positions are filled with zeros.
• arithmetic right shift (>>>) - shift right specified number of bits, fill with
value of sign bit if expression is signed, otherwise fill with zero
• arithmetic left shift (<<<) - shift left specified number of bits, fill with
zero.
Shift Operators
// X = 4'b1100
Y = X >> 1; //Y is 4'b0110. Shift right 1 bit. 0 filled in MSB position.
Y = X << 1; //Y is 4'b1000. Shift left 1 bit. 0 filled in LSB position.
Y = X << 2; //Y is 4'b0000. Shift left 2 bits.
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.
Concatenation Operator

// A = 1'b1, B = 2'b00, C = 2'b10, D = 3'b110


Y = {B , C} // Result Y is 4'b0010
Y = {A , B , C , D , 3'b001} // Result Y is 11'b10010110001
Y = {A , B[0], C[1]} // Result Y is 3'b101
Concatenation Operator
• 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.
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 ( { } ).
Replication Operator
reg A;
reg [1:0] B, C;
reg [2:0] D;
A = 1'b1; B = 2'b00; C = 2'b10; D = 3'b110;
Y = { 4{A} } // Result Y is 4'b1111
Y = { 4{A} , 2{B} } // Result Y is 8'b11110000
Y = { 4{A} , 2{B} , C } // Result Y is 8'b1111000010
Conditional Operator
• The conditional operator(?:) takes three operands.
Usage:
condition_expr ? true_expr : false_expr ;
Conditional Operator

//model functionality of a 2-to-1 mux


assign out = control ? in1 : in0;
Operator Precedence
4-to-1 Multiplexer (Logical operation)
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
output out;
input i0, i1, i2, i3;
input s1, s0;
//Logic equation for out
assign out = (~s1 & ~s0 & i0)|
(~s1 & s0 & i1) |
(s1 & ~s0 & i2) |
(s1 & s0 & i3) ;
endmodule
Multiplexer, Using Conditional Operators

module multiplexer4_to_1 (out, i0, i1, i2, i3, s1, s0);


// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
// Use nested conditional operator
assign out = s1 ? ( s0 ? i3 : i2) : (s0 ? i1 : i0) ;
endmodule
4-bit Full Adder, Using Dataflow Operators
module fulladd4(sum, c_out, a, b, c_in);
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
4-bit Ripple Carry Counter
Negative Edge-Triggered D-flipflop with Clear

• A latch is level sensitive.

• An edge-sensitive flip-flop is implemented by using 3 SR latches.


Negative Edge-Triggered D-flipflop with Clear
Verilog Code for Edge-Triggered D-flipflop

module edge_dff(q, qbar, d, clk, clear);


output q,qbar;
input d, clk, clear;
wire s, sbar, r, rbar,cbar;
assign cbar = ~clear;

assign sbar = ~(rbar & s),


s = ~(sbar & cbar & ~clk),
r = ~(rbar & ~clk & s),
rbar = ~(r & cbar & d);
assign q = ~(s & qbar),
qbar = ~(q & r & cbar);
endmodule
D-flipflop
• The characteristic equation of D flip-flop is given by Q(n+1) = D
D-Flip Flop
module D-FF(q, d, clk, reset) ;
output q;
input d, clk, reset;
reg q;
always @(posedge reset or negedge clk)
if (reset)
q = 1'b0;
else
q = d;
endmodule
T-flipflop
module T_FF(q, clk, clear);
output q;
input clk, clear;
edge_dff ff1(q, ,~q, clk, clear);
endmodule
4-bit Ripple Carry Counter
module counter(Q , clock, clear);
output [3:0] Q;
input clock, clear;
// Instantiate the T flipflops
T_FF tff0(Q[0], clock, clear);
T_FF tff1(Q[1], Q[0], clear);
T_FF tff2(Q[2], Q[1], clear);
T_FF tff3(Q[3], Q[2], clear);
endmodule
7. Behavioral Modeling
Structured Procedures,

• There are two structured procedure statements in Verilog:


• always and initial.
• These statements are the two most basic statements in behavioral
modeling.
• All other behavioral statements can appear only inside these
structured procedure statements.
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.
• Multiple behavioral statements must be grouped, typically using the
keywords begin and end.
• If there is only one behavioral statement, grouping is not necessary.
initial Statement
module stimulus; time
reg x,y, a,b, m; statement executed
initial 0
m = 1'b0; m = 1'b0;
initial 5 a
begin = 1'b1;
#5 a = 1'b1; 10 x
#25 b = 1'b0; = 1'b0;
end
30
initial b = 1'b0;
begin
35
#10 x = 1'b0;
y = 1'b1;
#25 y = 1'b1;
end
50
$finish;
initial
#50 $finish;
endmodule
always Statement module clock_gen (output reg clock);
• All behavioral statements inside an //Initialize clock at time zero
always statement constitute an always initial
block.
clock = 1'b0;
• The always statement starts at time 0
//Toggle clock every half-cycle (time
and executes the statements in the
period = 20)
always block continuously in a looping
fashion. always
• This statement is used to model a block #10 clock = ~clock;
of activity that is repeated continuously initial
in a digital circuit.
#1000 $finish;
• An example is a clock generator module
endmodule
that toggles the clock signal every half
cycle.
Procedural Assignments
• Procedural assignments update values of reg, integer, real, or time variables.
• The
• syntax for the simplest form of procedural assignment is shown below.
assignment ::= variable_lvalue = [ delay_or_event_control ]
expression

• 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[0])
• A part select of these variables (e.g., addr[31:16])
• A concatenation of any of the above
Blocking Assignments

reg x, y, z; All statements x = 0 through


reg [15:0] reg_a, reg_b; reg_b = reg_a are executed at
integer count;
initial
time 0
begin Statement reg_a[2] = 1 at time
x = 0; y = 1; z = 1; = 15
count = 0;
reg_a = 16'b0; reg_b = reg_a; //initialize vectors Statement reg_b[15:13] = {x, y,
#15 reg_a[2] = 1'b1; //Bit select assignment with delay z} at time = 25
#10 reg_b[15:13] = {x, y, z}
count = count + 1; //Assignment to an integer (increment)
Statement count = count + 1 at
end time = 25
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.


Nonblocking Assignments
reg x, y, z;
1. reg_a[2] = 0 is scheduled to
reg [15:0] reg_a, reg_b;
integer count;
execute after 15 units (i.e., time =
//All behavioral statements must be inside an initial or 15)
always block
initial 2. reg_b[15:13] = {x, y, z} is
begin scheduled to execute after 10
x = 0; y = 1; z = 1; //Scalar assignments
count = 0; //Assignment to integer variables
time units (i.e.,time = 10)
reg_a = 16'b0; reg_b = reg_a; //Initialize vectors 3. count = count + 1 is scheduled
reg_a[2] <= #15 1'b1; //Bit select assignment with delay
reg_b[15:13] <= #10 {x, y, z}; //Assign result of concatenation
to be executed without any delay
//to part select of a vector (i.e., time = 0)
count <= count + 1; //Assignment to an integer (increment)
end
Application of nonblocking assignments

always @(posedge clock)


begin
reg1 <= #1 in1;
reg2 <= @(negedge clock) in2 ^ in3;
reg3 <= #1 reg1; //The old value of reg1
end
Nonblocking Statements to Eliminate Race Conditions a=1
b=5

//Illustration 1: Two concurrent


//Illustration 2: Two concurrent always
always blocks with blocking
blocks with nonblocking
//statements
//statements
always @(posedge clock)
always @(posedge clock)
a = b;
a <= b;
always @(posedge clock)
always @(posedge clock)
b = a;
b <= a;
Implementing Nonblocking Assignments using Blocking a=1
Assignments b=5

always @(posedge clock)


begin
//Read operation
//store values of right-hand-side expressions in temporary
variables
temp_a = a;
temp_b = b;
//Write operation
//Assign values of temporary variables to left-hand-side
variables
a = temp_b;
b = temp_a;
end
Timing Controls

• Timing controls provide a way to specify the simulation time at which


procedural statements will execute.
• There are three methods of timing control:
• delay-based timing control,
• event-based timing control,
• and level-sensitive timing control.
Delay-Based Timing Control
• Delay-based timing control in an expression specifies the
time duration between when the statement is
encountered and when it is executed.

• 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 x = 0; // no delay control
non-zero delay is specified to the left
#10 y = 1; // delay control with a number.
of a procedural assignment.
Delay execution of // y = 1 by 10 units
#latency z = 0; // Delay control with
//define parameters identifier. Delay of 20 units
parameter latency = 20; #(latency + delta) p = 1; // Delay control
parameter delta = 2; with expression
//define register variables #y x = x + 1; // Delay control with identifier.
reg x, y, z, p, q; Take value of y.
initial #(4:5:6) q = 0; // Minimum, typical and
begin maximum delay values.
end
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.
• //define register variables
• reg x, y, z;
• //intra assignment delays
• initial
• begin
• x = 0; z = 0;
• y = #5 x + z; //Take value of x and z at the time=0, evaluate
• //x + z and then wait 5 time units to assign value
• //to y.
• end
Zero delay control

• Zero delay control is a method to ensure that a • initial


statement is executed last, after all other • begin
statements in that simulation time are • x = 0;
executed. • y = 0;
• This is used to eliminate race conditions. • end
• However, if there are multiple zero delay • initial
statements, the order between them is
• begin
nondeterministic.
• #0 x = 1; //zero delay control
• #0 y = 1;
• end
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.
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 posedge is used for a positive transition,
Regular event control
• @(clock) q = d; //q = d is executed whenever signal clock changes value
• @(posedge clock) q = d; //q = d is executed whenever signal clock does
• //a positive transition ( 0 to 1,x or z,
• // x to 1, z to 1 )
• @(negedge clock) q = d; //q = d is executed whenever signal clock does
• //a negative transition ( 1 to 0,x or z,
• //x to 0, z to 0)
• q = @(posedge clock) d; //d is evaluated immediately and assigned
• //to q 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
• 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 @.
Named event control
//This is an example of a data buffer storing data after the
//last packet of data has arrived.
event received_data; //Define an event called received_data
always @(posedge clock) //check at each positive clock edge
begin
if(last_data_packet) //If this is the last data packet
->received_data; //trigger the event received_data
end
Named event control
always @(received_data) //Await triggering of event received_data
//When event is triggered, store all four
//packets of received data in data buffer
//use concatenation operator { }
• data_buf = {data_pkt[0], data_pkt[1], data_pkt[2],data_pkt[3]};
Event OR Control
• Sometimes a transition on any one of multiple signals or
events can trigger the execution of a statement or a
block of statements.
• This is expressed as an OR of events or signals.
• The list of events or signals expressed as an OR is also
known as a sensitivity list.
• The keyword or is used to specify multiple triggers
Event OR Control
• always @( reset or clock or d) always @( reset or clock )
begin begin
if (reset) //if reset signal is high, if (reset) //if reset signal is high, set q to 0.
set q to 0.
q = 1'b0;
q = 1'b0;
else if //if clock is high, latch input
else if(clock) //if clock is high,
latch input q = d;
q = d; end
end
D-Latch

• module dlatch(q, clock, reset, d);


• input clock, reset,d;
• output q;
• reg q;
• always @( reset or clock or d)
• begin
• if (reset) //if reset signal is high, set q to 0.
• q = 1'b0;
• else if(clock) //if clock is high, latch input
• q = d;
• end
• endmodule
D-Latch
• module dlatch(q, clock, reset, d);
• module dlatch(q, clock, reset, d); • input clock, reset,d;
• input clock, reset,d; • output q;
• output q; • reg q;
• reg q; • always @( reset or clock or d)
• always @( reset or clock or d) • begin
• begin • if (reset) //if reset signal is high, set q to 0.
• if (reset) //if reset signal is high, set q to 0. • q = 1'b0;
• q = 1'b0; • else if //if clock is high, latch input
• else if(clock) //if clock is high, latch input • q = d;
• q = d; • end
• end • endmodule
• endmodule
D-Latch
Sensitivity List with Comma Operator

//A level-sensitive latch with asynchronous reset


always @( reset, clock, d)
//Wait for reset or clock or d to change
begin
if (reset) //if reset signal is high, set q to0
q = 1'b0;
else if(clock) //if clock is high, latch input
q = d;
end
//A positive edge triggered D flipflop with asynchronous falling
//reset can be modeled as shown below

• always @(posedge clk, negedge reset) //Note use of comma operator


• if(!reset)
• q <=0;
• else
• q <=d;
//A positive edge triggered D flipflop with asynchronous falling
//reset can be modeled as shown below

• module dflipflop(q, clk, reset, d);


• input clk, reset,d;
• output q;
• reg q;
• always @(posedge clk, negedge reset) //Note use of comma operator
• if(!reset)
• q <=0;
• else
• q <=d;
• endmodule
A positive edge triggered D flipflop with
asynchronous falling
//reset can be modeled as shown below
//A positive edge triggered D flipflop with synchronous
//reset can be modeled as shown below

• always @(posedge clk )


• if(!reset)
• q <=0;
• else
• q <=d;
//A positive edge triggered D flipflop with synchronous
//reset can be modeled as shown below

• module dflipflop(q, clk, reset, d);


• input clk, reset,d;
• output q;
• reg q;
• always @(posedge clk) //Note use of comma operator
• if(!reset)
• q <=0;
• else
• q <=d;
• endmodule
//A positive edge triggered D flipflop with synchronous
//reset can be modeled as shown below
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.
Level-Sensitive Timing Control

always
wait (count_enable) #20 count = count + 1;
Conditional Statements
//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 ;
Conditional Statements
//Type 3 conditional statement. Nested if-else-if.
//Choice of multiple statements. Only one is executed.
• if (<expression1>) true_statement1 ;
• else if (<expression2>) true_statement2 ;
• else if (<expression3>) true_statement3 ;
• else default_statement ;
Conditional Statements
//Type 1 statements
if(!lock) buffer = data;
if(enable) out = in;
//Type 2 statements
if (number_queued < MAX_Q_DEPTH)
begin
data_queue = data;
number_queued = number_queued + 1;
end
else
$display("Queue Full. Try again");
Conditional Statements

• //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");
Multiway Branching
• case Statement
The keywords case, endcase, and default are used in the case statement..
case (expression)
alternative1: statement1;
alternative2: statement2;
alternative3: statement3;
...
...
default: default_statement;
endcase
Multiway Branching
//Execute statements based on the ALU control signal
reg [1:0] alu_control;
...
...
case (alu_control)
2'd0 : y = x + z;
2'd1 : y = x - z;
2'd2 : y = x * z;
default : $display("Invalid ALU control signal");
endcase
4-to-1 Multiplexer with Case Statement
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
reg out;
always @(s1 or s0 or i0 or i1 or i2 or i3)
case ({s1, s0}) //Switch based on concatenation of control signals
2'd0 : out = i0;
2'd1 : out = i1;
2'd2 : out = i2;
2'd3 : out = i3;
default: $display("Invalid control signals");
endcase
endmodule
Case Statement
• 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.
casex, casez Difference
• casez treats all z, ?values in the case alternatives or
the case expression as don't cares.
• casex treats all x and z values in the case item or the
case expression as don't cares.
casex, casez Keywords
reg [3:0] encoding;
integer state;
casex (encoding) //logic value x represents a don't care bit.
4'b1xxx : next_state = 3;
4'bx1xx : next_state = 2;
4'bxx1x : next_state = 1;
4'bxxx1 : next_state = 0;
default : next_state = 0;
endcase

Only one bit is considered to determine the next state and the other bits are ignored.
Thus, an input encoding = 4'b10xz would cause next_state = 3 to be executed.
While Loop

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


• The keyword while is used count 128.
to specify this loop. The • //Display the count variable.
while loop executes until integer count;
the while expression is not
initial
true.
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
For Loop
integer count;
• The keyword for is used to
specify this loop. initial
• The for loop contains three for ( count=0; count < 128; count = count + 1)
parts: $display("Count = %d", count);
• An initial condition
• A check to see if the for loops can also be used to initialize an
terminating condition is true array or memory
• A procedural assignment to
change value of the control
variable
for loops can also be used to initialize an array or
memory
initial
begin
for(i = 0; i < 32; i = i + 2) //initialize all even locations with 0
state[i] = 0;
for(i = 1; i < 32; i = i + 2) //initialize all odd locations with 1
state[i] = 1;
end
Repeat Loop

The keyword repeat is used for this loop. //Illustration 1 : increment and
The repeat construct executes the loop a display count from 0 to 127
fixed number of times. integer count;
A repeat construct cannot be used to loop initial
on a general logical expression
• begin
A repeat construct must contain a
number, which can be a constant, a • count = 0;
variable or a signal value. • repeat(128)
• begin
• $display("Count = %d", count);
• count = count + 1;
• end
• end
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.
//Example 1: Clock generation
//Use forever loop instead of always block
reg clock;
initial
begin
clock = 1'b0;
forever #10 clock = ~clock; //Clock with period of 20 units
end
Behavioral 4-bit Counter Description
//4-bit Binary counter
module counter(Q , clock, clear);
output [3:0] Q;
input clock, clear;
reg [3:0] Q;
always @( posedge clear or negedge clock)
begin
if (clear)
Q <= 4'd0; //Nonblocking assignments are recommended
//for creating sequential logic such as flipflops
else
Q <= Q + 1;

end
endmodule
Behavioral 4-bit Counter Description
//4-bit Binary counter
module counter(Q , clock, clear);
output [3:0] Q;
input clock, clear;
reg [3:0] Q;
always @( negedge clear or posedge clock)
begin
if (clear)
Q <= Q + 1; //Nonblocking assignments are recommended
//for creating sequential logic such as flipflops
else
Q <= 0;

end
endmodule
Sequential 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 intra-assignment timing
control).
• If delay or event control is specified, it is relative to the simulation
time when the previous statement in the block completed execution.
Nonblocking Assignments
reg x, y, z;
1. reg_a[2] = 0 is scheduled to
reg [15:0] reg_a, reg_b;
integer count;
execute after 15 units (i.e., time =
//All behavioral statements must be inside an initial or 15)
always block
initial 2. reg_b[15:13] = {x, y, z} is
begin scheduled to execute after 10
x = 0; y = 1; z = 1; //Scalar assignments
count = 0; //Assignment to integer variables
time units (i.e.,time = 10)
reg_a = 16'b0; reg_b = reg_a; //Initialize vectors 3. count = count + 1 is scheduled
reg_a[2] <= #15 1'b1; //Bit select assignment with delay
reg_b[15:13] <= #10 {x, y, z}; //Assign result of concatenation
to be executed without any delay
//to part select of a vector (i.e., time = 0)
count <= count + 1; //Assignment to an integer (increment)
end
//Illustration 1: Sequential block without
delay
reg x, y;
reg [1:0] z, w;
initial
begin
x = 1'b0;
y = 1'b1;
z = {x, y};
w = {y, x};
end
//Illustration 2: Sequential blocks with delay.
reg x, y;
reg [1:0] z, w;
initial
begin
x = 1'b0; //completes at simulation time 0
#5 y = 1'b1; //completes at simulation time 5
#10 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.
fundamental difference
• 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.
//Example 1: Parallel blocks with delay.
reg x, y;
reg [1:0] z, w;
initial
fork
x = 1'b0; //completes at simulation time 0
#5 y = 1'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
Special Features of Blocks
• 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,
//Nested blocks
initial
begin
x = 1'b0;
fork
#5 y = 1'b1;
#10 z = {x, y};
join
#20 w = {y, x};
end
fork….,join Nested Blocks
initial
begin
clk =0;
#5
fork
#5 a = 0;
#10 b = 0;
join // executes any all process inside the fork
clk= 1; // clk becomes 1 at t=15
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.
Named Blocks
• //Named blocks
module top;
initial
begin: block1 //sequential block named block1
integer i; //integer i is static and local to block1
// can be accessed by hierarchical name, top.block1.i
...
end
initial
fork: block2 //parallel block named block2
• reg i; // register i is static and local to block2
// 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
named block. Disable can be used to get out of loops,
• //Illustration: Find the first bit with a value 1 in flag (vector //variable)
reg [15:0] flag;
integer i; //integer to keep count
initial
begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
begin: block1 //The 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; //disable block1 because you found true bit.
end
i = i + 1;
end
end
end
Up down counter

module upordown_counter(Clk, reset,UpOrDown, Count );


input Clk,reset,UpOrDown;
output [3 : 0] Count;
reg [3 : 0] Count = 0;
always @(negedge(Clk) or posedge(reset))
begin
if(reset == 1)
Count <= 0;
else
if(UpOrDown == 1)
Count <= Count + 1;
else
Count <= Count - 1;
end
endmodule
Up down counter

module upordown_counter(Clk,
reset,UpOrDown, Count ); else //Down mode selected
input Clk,reset,UpOrDown; if(Count == 0)
output [3 : 0] Count; Count <= 15;
reg [3 : 0] Count = 0; else
always @(negedge(Clk) or posedge(reset))
Count <= Count - 1; //Decrement counter
begin
if(reset == 1)
end
Count <= 0; endmodule
else
if(UpOrDown == 1) //Up mode selected
if(Count == 15)
Count <= 0;
else
Count <= Count + 1;
Priorty Encoder

module priorityencode(en,in,op); casex(in)


8'b00000001:op=3'b000;
input en; 8'b0000001x:op=3'b001;
input [7:0]in; 8'b000001xx:op=3'b010;
output [2:0]op; 8'b00001xxx:op=3'b011;
8'b0001xxxx:op=3'b100;
reg [2:0]op; 8'b001xxxxx:op=3'b101;
always @ (in or en) 8'b01xxxxxx:op=3'b110;
begin 8'b1xxxxxxx:op=3'b111;
default:op=3'bxxx;
if(~en) endcase
op=3'bxxx; end
else end
begin endmodule
1K Memory

module onekb(a,ctrl,reset,clk); begin


input ctrl,reset,clk; for(i=0;i<1024;i=i+2)
output reg [1023:0]a; a[i]=1;
integer i; end
always @(posedge clk) else
if(reset) begin
begin for(i=1;i<1024;i=i+2)
for(i=0;i<1024;i=i+1) a[i]=1;
a[i]=0; end
end end
else endmodule
begin
if(ctrl)
Chapter 14
Logic Synthesis with Verilog
HDL
Logic Synthesis with Verilog HDL
• Advances in logic synthesis have pushed HDLs into the
forefront of digital design technology.
• Logic synthesis tools have cut design cycle times significantly.
• Designers can design at a high level of abstraction and thus
reduce design time.
14.1 What Is Logic Synthesis?
• Simply speaking, logic synthesis is the process of
converting a high-level description of the design into
an optimized gate-level representation,
• Given a standard cell library and specific design
constraints.
Standard cell library
• A standard cell library can have simple cells, such as basic logic gates
like and, or, & nor, or macro cells, such as adders, muxes, and special
flipflops.
• A standard cell library is also known as the technology library.
computer-aided logic
synthesis
computer-aided logic synthesis
computer-aided logic synthesis

• The advent of computer-aided logic synthesis tools has


automated the process of converting the high-level
description to logic gates.
• Instead of trying to perform logic synthesis in their minds,
designers can now concentrate on the architectural trade-
offs, high-level description of the design, accurate design
constraints, and optimization of cells in the standard cell
library.
• These are fed to the computer-aided logic synthesis
tool, which performs several iterations internally and
generates the optimized gate-level description.
Computer-aided logic synthesis
• Also, instead of drawing the high-level description on a screen or a
piece of paper, designers describe the high-level design in terms of
HDLs.
• Verilog HDL has become one of the popular HDLs for the writing of
high-level descriptions.
computer-aided logic synthesis
• Automated logic synthesis has significantly reduced time for
conversion from high-level design representation to gates.
• This has allowed designers to spend more time on designing at a
higher level of representation, because less time is required for
converting the design to gates.
14.3 Verilog HDL Synthesis
Verilog HDL Synthesis
• For the purpose of logic synthesis, designs are currently
written in an HDL at a register transfer level (RTL).
• The term RTL is used for an HDL description style that utilizes
a combination of data flow and behavioral constructs.
• Logic synthesis tools take the register transfer-level HDL
description and convert it to an optimized gate-level netlist.
• Verilog and VHDL are the two most popular HDLs used to
describe the functionality at the RTL level.
Verilog Constructs
• A list of constructs that are typically accepted by logic
synthesis
Verilog Constructs
Verilog Constructs
• Remember that we are providing a cycle-by-cycle RTL description of
the circuit.
• Hence, there are restrictions on the way these constructs are used for
the logic synthesis tool.
• For example, the while and forever loops must be broken by a @
(posedge clock) or @ (negedge clock) statement to enforce cycle-by-
cycle behavior and to prevent combinational feedback.
Verilog Constructs
• Another restriction is that logic synthesis ignores all timing
• delays specified by #<delay> construct. Therefore, pre- and
post-synthesis Verilog simulation results may not match. The
designer must use a description style that eliminates these
mismatches.
• Also, the initial construct is not supported by logic synthesis
tools. Instead, the designer must use a reset mechanism to
initialize the signals in the circuit.
Verilog Operators
• Almost all operators in Verilog are allowed for logic synthesis.
• Only operators such as === and !== that are related to x and
z are not allowed, because equality with x and z does not
have much meaning in logic synthesis.
• While writing expressions, it is recommended that you use
parentheses to group logic the way you want it to appear.
• If you rely on operator precedence, logic synthesis tools
might produce an undesirable logic structure.
Verilog HDL Operators for Logic Synthesis
Verilog HDL Operators for Logic Synthesis
Verilog HDL Operators for Logic
Synthesis
Verilog HDL Operators for Logic
Synthesis
Verilog HDL Operators for Logic
Synthesis
Interpretation of a Few Verilog Constructs
The assign statement
The assign construct is the most fundamental construct used to describe
combinational logic at an RTL level.
assign out = (a & b) | c;
The assign statement

• If a, b, c, and out are 2-bit vectors [1:0], then the above assign
statement will frequently translate to two identical circuits for each
bit.
Arithmetic operators
• If arithmetic operators are used, each arithmetic operator is
implemented in terms of arithmetic hardware blocks available to the
logic synthesis tool.
• A 1-bit full adder
assign {c_out, sum} = a + b + c_in;
arithmetic operators
• If a multiple-bit adder is synthesized, the synthesis tool will perform
optimization and the designer might get a result that looks different
from the above figure.
conditional operator ?
• If a conditional operator ? is used, a multiplexer circuit is inferred.
assign out = (s) ? i1 : i0;
The if-else statement
• Single if-else statements translate to multiplexers where the control
signal is the signal or variable in the if clause.
if(s)
out = i1;
else
out = i0;
The if-else statement
• In general, multiple if-else-if statements do not synthesize to large
multiplexers.
The case statement
• The case statement also can used to infer multiplexers.
case (s)
1'b0 : out = i0;
1'b1 : out = i1;
endcase
The case statement
• Large case statements may be used to infer large multiplexers.
for loops
• The for loops can be used to build cascaded combinational logic. For
example, the following for loop builds an 8-bit full adder:
c = c_in;
for(i=0; i <=7; i = i + 1)
{c, sum[i]} = a[i] + b[i] + c; // builds an 8-bit ripple adder
c_out = c;
The always statement
• The always statement can be used to infer sequential and combinational
logic.
• For sequential logic, the always statement must be controlled by the
change in the value of a clock signal clk.
positive edge-triggered D-flipflop

always @(posedge clk)


q <= d;
level-sensitive latch:

always @(clk or d)
if (clk)
q <= d;
combinational logic
• For combinational logic, the always statement must be triggered by a
signal other than the clk, reset, or preset.
• For example, the following block will be interpreted as a 1-bit full adder:
always @(a or b or c_in)
{c_out, sum} = a + b + c_in;
14.6 Modeling Tips for Logic
Synthesis
Modeling Tips for Logic Synthesis
• The Verilog RTL design style used by the designer affects the
final gate-level netlist produced by logic synthesis.
• Logic synthesis can produce efficient or inefficient gate level
netlists, based on the style of RTL descriptions.
• Hence, the designer must be aware of techniques used to write
efficient circuit descriptions.
14.6.1 Verilog Coding Style
Code for a gated D latch
• module D_latch (D, Clk, Q);
• input D, Clk;
• output reg Q;
• always @(D, Clk)
• if (Clk)
• Q = D;
• endmodule
Code for a 2:1 mux
• module D_latch (D, Clk, Q);
• input D, Clk;
• output reg Q;
• always @(D, Clk)
• if (Clk)
• Q = D;
• Else
• Q=0;
• endmodule
Synthesis of Flip Flops
Code for a D flip-flop.
• module flipflop (D, Clock, Q);
• input D, Clock;
• output reg Q;
• always @(posedge Clock)
• Q = D;
• endmodule
Synthesis of Flip Flops
D flip-flop with asynchronous reset.
• module flipflop (D, rst, Clock, Q);
• input D, Clock,rst ;
• output reg Q;
• always @(posedge Clock, negedge rst)
• if(!rst)
• Q = 0;
• else
• Q = D;
• endmodule
Synthesis of Flip Flops
D flip-flop with synchronous reset.

• module flipflop (D, rst, Clock, Q);


• input D, Clock,rst ;
• output reg Q;
• always @(posedge Clock)
• if(!rst)
• Q = 0;
• else
• Q = D;
• endmodule
Synthesis of Flip Flops
D flip-flop with synchronous reset.

• module flipflop (D, rst, Clock, Q);


• input D, Clock,rst ;
• output reg Q;
• always @(posedge Clock)
• if(rst)
• Q = 0;
• else
• Q = D;
• endmodule
Synthesis of Flip Flops
Code for an n-bit register with asynchronous clear .

• module regn (D, Clock, Resetn, Q);


• parameter n = 16;
• input [n –1:0] D;
• input Clock, Resetn;
• output reg [n –1:0] Q;
• always @(negedge Resetn, posedge Clock)
• if (!Resetn)
• Q <= 0;
• else
• Q <= D;
• endmodule
Synthesis of Flip Flops
Code for a D flip-flop with a 2-to-1 multiplexer on the D input.

• module muxdff (D0, D1, Sel, Clock, Q);


• input D0, D1, Sel, Clock;
• output reg Q;
• always @(posedge Clock)
• if (!Sel)
• Q <= D0;
• else
• Q <= D1;
• endmodule
Alternative code for a D flip-flop with a 2-to-1
multiplexer on the D input.
• module muxdff (D0, D1, Sel, Clock, Q);
• input D0, D1, Sel, Clock;
• output reg Q;
• wire D;
• assign D = Sel ? D1 : D0;
• always @(posedge Clock)
• Q <= D;
• endmodule
Synthesis of Flip Flops
Incorrect code for two cascaded flip-flops.

• module example5_3 (D, Clock, Q1, Q2);


• input D, Clock;
• output reg Q1, Q2;
• always @(posedge Clock)
• begin
• Q1 = D;
• Q2 = Q1;
• end
• endmodule
Synthesis of Flip Flops
Code for two cascaded flip-flops.

• module example5_4 (D, Clock, Q1, Q2);


• input D, Clock;
• output reg Q1, Q2;
• always @(posedge Clock)
• begin
• Q1 < = D;
• Q2 < = Q1;
• end
• endmodule
Synthesis of Flip Flops
Incorrect code for two cascaded flip-flops.

• module example5_5 (x1, x2, x3, Clock, f, g);


• input x1, x2, x3, Clock;
• output reg f, g;
• always @(posedge Clock)
• begin
• f = x1 & x2;
• g = f | x3;
• end
• endmodule
Synthesis of Flip Flops
correct code for two cascaded flip-
flops.
• module example5_6 (x1, x2, x3, Clock, f, g);
• input x1, x2, x3, Clock;
• output reg f, g;
• always @(posedge Clock)
• begin
• f < = x1 & x2;
• g < = f | x3;
• end
• endmodule
Code for a four-bit up-counter

• module upcount (Resetn, Clock, E, Q);


• input Resetn, Clock, E;
• output reg [3:0] Q;
• always @(negedge Resetn, posedge
Clock)
• if (!Resetn)
• Q <= 0;
• else if (E)
• Q <= Q + 1;
• endmodule
Use meaningful names for signals and variables
• Names of signals and variables should be meaningful so that the code
becomes self-commented and readable.
Avoid mixing positive and negative edge-
triggered flipflops
• Mixing positive and negative edge-triggered flipflops may introduce
inverters and buffers into the clock tree.
• This is often undesirable because clock skews are introduced in the
circuit.
Use basic building blocks vs. use continuous
assign statements
• Trade-offs exist between using basic building blocks versus using
continuous assign statements in the RTL description.
• Continuous assign statements are a very concise way of representing
the functionality and they generally do a good job of generating
random logic. However, the final logic structure is not necessarily
symmetrical.
• Instantiation of basic building blocks creates symmetric designs,
l-bit Full Adder design using gate-level modeling
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c2;

xor (s1, a, b);


and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
// Define a 1-bit full adder
Define a 4-bit full adder
// Define a 4-bit full adder
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
4-bit Ripple Carry Full
output c_out;
Adder
input[3:0] a, b;
input c_in;
// Internal nets
wire c1, c2, c3;
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
// Define a 4-bit full adder- netlist
Data flow Realization–
Adders
4-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
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
Data flow Realization–Adders
Behavioral Realization–
Adders
Behavioral Realization–Adders
•module fulladd4for(sum, c_out, a, b, c_in);
•output [3:0] sum;
•output c_out;
•input[3:0] a, b;
•input c_in;
•integer i;
•reg c, c_out;
•reg [3:0] sum;
•always@(a, b, c_in)
•begin
•c = c_in;
•for(i=0; i <=4; i = i + 1)
•{c, sum[i]} = a[i] + b[i] + c; // builds an 8-bit ripple adder
•c_out = c;
•end
•endmodule
Behavioral Realization–Adders
8-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
output [7:0] sum;
output c_out;
input[7:0] a, b;
input c_in;
// Specify the function of a full adder
assign {c_out, sum} = a + b + c_in;
endmodule
8-bit Full Adder, Using Dataflow modeling
Behavioral Realization–Adders
module fulladd8for(sum, c_out, a, b, c_in);
output [7:0] sum;
output c_out;
input[7:0] a, b;
input c_in;
integer i;
reg c, c_out;
reg [7:0] sum;
always@(a, b, c_in)
begin
c = c_in;
for(i=0; i <=7; i = i + 1)
{c, sum[i]} = a[i] + b[i] + c; // builds an 8-bit ripple adder
c_out = c;
end
endmodule
Behavioral Realization–8-bit-Adders
Instantiate multiplexers vs. Use if-else or case
statements
• if-else and case statements are frequently synthesized to multiplexers
in hardware.
• If a structured implementation is needed, it is better to implement a
block directly by using multiplexers, because if-else or case
statements can cause undesired random logic to be generated by the
synthesis tool.
• Instantiating a multiplexer gives better control and faster synthesis,
Code for a 2:1 mux

• module D_latch (D, Clk, Q);


• input D, Clk;
• output reg Q;
• always @(D, Clk)
• if (Clk)
• Q = D;
• Else
• Q=0;
• endmodule
Code for a 4:1 mux

• module mux4to1if(x1, x2, x3, x4, y, sel);


• input x1, x2, x3, x4;
• output reg y;
• input [1:0] sel;
• always@(x1, x2, x3, x4, sel)
• begin
• if ( sel== 0)
• y = x1;
• else if (sel== 1)
• y = x2;
• else if (sel == 2)
• y = x3;
• else
• y= x4;
• end
• endmodule
Code for a 4:1 mux
Code for a 4:1 mux with default statement
• module mux4to1if(x1, x2, x3, x4, y, sel);
• input x1, x2, x3, x4;
• output reg y;
• input [1:0] sel;
• always@(x1, x2, x3, x4, sel)
• begin
• if ( sel== 0)
• y = x1;
• else if (sel== 1)
• y = x2;
• else if (sel == 2)
• y = x3;
• else if (sel ==3)
• y= x4;
• else
• $display("Invalid control signal");
• end
• endmodule
Code for a 4:1 mux with default statement
Code for a 4:1 mux using case statement

• module mux4to1if(x, y, sel);


• input [7:0]x;
• output reg y;
• input [2:0] sel;
• always@(x, sel)
• begin
• case (sel)
• 3'd0 : y = x[0];
• 3'd1 : y = x[1];
• 3'd2 : y = x[2];
• 3’d3 : y = x4;
• 3’d4 : y = x1;
• 3’d5 : y = x2;
• 3’d6 : y = x3;
• 3’d7 : y = x4;

• default : $display("Invalid control signal");


• endcase
• end
• endmodule
Code for a 4:1 mux using case statement
Use parentheses to optimize logic structure

• The designer can control the final structure of logic by using


parentheses to group logic.
• Using parentheses also improves readability of the Verilog
description.
Use parentheses to optimize logic
structure
//translates to 3 adders in series
• out = a + b + c + d;
//translates to 2 adders in parallel with one final adder to sum results
• out = (a + b) + (c + d) ;
Be careful with multiple assignments to the
same variable
• Multiple assignments to the same variable can cause undesired logic to be
generated. The previous assignment might be ignored, and only the last
assignment would be used.
//two assignments to the same variable
always @(posedge clk)
if(load1) q <= a1;
always @(posedge clk)
if(load2) q <= a2;
• The synthesis tool infers two flip-flops with the outputs anded together to
produce the q output.
Define if-else or case statements
explicitly
//latch is inferred; incomplete specification.
//whenever control = 1, out = a which implies a latch behavior.
//no branch for control = 0
always @(control or a)
if (control)
out <= a;
Code for a gated D latch
• module D_latch (D, Clk, Q);
• input D, Clk;
• output reg Q;
• always @(D, Clk)
• if (Clk)
• Q = D;
• endmodule
Define if-else or case statements explicitly
• //multiplexer is inferred. complete specification for all values of
• //control
always @(control or a or b)
if (control)
out = a;
else
out = b;
• module variableassign(clk, load1, load2, a1,a2, q);
• input load1, load2, a1, a2, clk;
• output reg q;

• //two assignments to the same variable


• always @(posedge clk)
• if(load1) q <= a1;
• always @(posedge clk)
• if(load2) q <= a2;

• endmodule
Code for a 2:1 mux
• module D_latch (D, Clk, Q);
• input D, Clk;
• output reg Q;
• always @(D, Clk)
• if (Clk)
• Q = D;
• Else
• Q=0;
• endmodule
Structural Realization–
Adders
l-bit Full Adder design using gate-level modeling
// Define a 1-bit full adder
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
// Internal nets
wire s1, s2, c2;

xor (s1, a, b);


and (c1, a, b);
xor (sum, s1, c_in);
and (s2, s1, c_in);
or (c_out, s2, c1);
// Define a 1-bit full adder
Define a 4-bit full adder
// Define a 4-bit full adder
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
4-bit Ripple Carry Full
output c_out;
Adder
input[3:0] a, b;
input c_in;
// Internal nets
wire c1, c2, c3;
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
// Define a 4-bit full adder- netlist
Data flow Realization–
Adders
4-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
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
Data flow Realization–Adders
Behavioral Realization–
Adders
Behavioral Realization–Adders
•module fulladd4for(sum, c_out, a, b, c_in);
•output [3:0] sum;
•output c_out;
•input[3:0] a, b;
•input c_in;
•integer i;
•reg c, c_out;
•reg [3:0] sum;
•always@(a, b, c_in)
•begin
•c = c_in;
•for(i=0; i <=4; i = i + 1)
•{c, sum[i]} = a[i] + b[i] + c; // builds an 8-bit ripple adder
•c_out = c;
•end
•endmodule
Behavioral Realization–Adders
8-bit Full Adder, Using Dataflow modeling
module fulladd4(sum, c_out, a, b, c_in);
output [7:0] sum;
output c_out;
input[7:0] a, b;
input c_in;
// Specify the function of a full adder
assign {c_out, sum} = a + b + c_in;
endmodule
8-bit Full Adder, Using Dataflow modeling
Behavioral Realization–Adders
module fulladd8for(sum, c_out, a, b, c_in);
output [7:0] sum;
output c_out;
input[7:0] a, b;
input c_in;
integer i;
reg c, c_out;
reg [7:0] sum;
always@(a, b, c_in)
begin
c = c_in;
for(i=0; i <=7; i = i + 1)
{c, sum[i]} = a[i] + b[i] + c; // builds an 8-bit ripple adder
c_out = c;
end
endmodule
Behavioral Realization–8-bit-Adders
A four-bit comparator circuit
A four-bit comparator circuit- data
flow
//Module magnitude comparator
module magnitude_comparator(A_gt_B, A_lt_B, A_eq_B, A, B);
//Comparison output
output A_gt_B, A_lt_B, A_eq_B;
//4-bits numbers input
input [3:0] A, B;
assign A_gt_B = (A > B); //A greater than B
assign A_lt_B = (A < B); //A less than B
assign A_eq_B = (A == B); //A equal to B
endmodule
A four-bit comparator circuit- data
flow
Gate-Level Description for the Magnitude
Comparator
• module magnitude_comparator ( A_gt_B, A_lt_B, A_eq_B, A, B );
• input [3:0] A;
• input [3:0] B;
• output A_gt_B, A_lt_B, A_eq_B;
• wire n60, n61, n62, n50, n63, n51, n64, n52, n65, n40, n53,
• n41, n54, n42, n55, n43, n56, n44, n57, n45, n58, n46,
• n59, n47, n48, n49, n38, n39;
• VAND U7 ( .in0(n48), .in1(n49), .out(n38) );
• VAND U8 ( .in0(n51), .in1(n52), .out(n50) );
Final, Optimized, Gate-Level Description
• VAND U9 ( .in0(n54), .in1(n55), .out(n53) );
• VNOT U30 ( .in(A[2]), .out(n62) );
• VNOT U31 ( .in(A[1]), .out(n59) );
• VNOT U32 ( .in(A[0]), .out(n60) );
• VNAND U20 ( .in0(B[2]), .in1(n62), .out(n45) );
• VNAND U21 ( .in0(n61), .in1(n45), .out(n63) );
• VNAND U22 ( .in0(n63), .in1(n42), .out(n41) );
• VAND U10 ( .in0(n55), .in1(n52), .out(n47) );
• VOR U23 ( .in0(n60), .in1(B[0]), .out(n57) );
• VAND U11 ( .in0(n56), .in1(n57), .out(n49) );
• VNAND U24 ( .in0(n57), .in1(n52), .out(n54) );
• VAND U12 ( .in0(n40), .in1(n42), .out(n48) );
• VNAND U25 ( .in0(n53), .in1(n44), .out(n64) );
• VOR U13 ( .in0(n58), .in1(B[3]), .out(n42) );
Final, Optimized, Gate-Level Description
• VOR U26 ( .in0(n62), .in1(B[2]), .out(n46) );
• VNAND U14 ( .in0(B[3]), .in1(n58), .out(n40) );
• VNAND U27 ( .in0(n64), .in1(n46), .out(n65) );
• VNAND U15 ( .in0(B[1]), .in1(n59), .out(n55) );
• VNAND U28 ( .in0(n65), .in1(n40), .out(n43) );
• VOR U16 ( .in0(n59), .in1(B[1]), .out(n52) );
• VNOT U29 ( .in(A[3]), .out(n58) );
• VNAND U17 ( .in0(B[0]), .in1(n60), .out(n56) );
• VNAND U18 ( .in0(n56), .in1(n55), .out(n51) );
• VNAND U19 ( .in0(n50), .in1(n44), .out(n61) );
• VAND U2 ( .in0(n38), .in1(n39), .out(A_eq_B) );
• VNAND U3 ( .in0(n40), .in1(n41), .out(A_lt_B) );
• VNAND U4 ( .in0(n42), .in1(n43), .out(A_gt_B) );
• VAND U5 ( .in0(n45), .in1(n46), .out(n44) );
• VAND U6 ( .in0(n47), .in1(n44), .out(n39) );
• endmodule
• Verilog Code for Sequence Detector "101101"
Verilog Code for Sequence Detector "101101"
module sequence detector(rst,clk,ip,op);

output reg op;


input clk, rst, ip;

reg [2:0] state;


reg [2:0] next_state;

parameter [2:0] s0=3'b000;


parameter [2:0] s1=3'b001;
parameter [2:0] s2=3'b010;
parameter [2:0] s3=3'b011;
parameter [2:0] s4=3'b100;
parameter [2:0] s5=3'b101;
always @(posedge clk, posedge rst)
begin
if (rst)
state=s0;
else
state=next_state;
end
always @(state , ip)
begin
case(state)
s0:
if (ip)
Begin
next_state=s1;
op=1’b0;
end
else
begin
next_state=s0;
op=1'b0;
end
s1:
if (ip)
Begin
next_state=s1;
op=1'b0;
end
else
begin
next_state=s2;
op=1'b0;
end
s2:
if (ip)
begin
next_state=s3;
op=1'b0;
end
else
begin
next_state=s0;
op=1'b0;
end
s3:
if (ip)
begin
next_state=s4;
op=1'b0;
end
else
begin
next_state=s2;
op=1'b0;
end
s4:
if (ip)
begin
next_state=s1;
op=1'b0;
end
else
begin
next_state=s5;
op=1'b0;
end
s5:
if (ip)
begin
next_state=s1;
op=1'b1;
end
else
begin
next_state=s0;
op=1'b0;
end
default:
begin
next_state=s0;
op=1'b0;
end
endcase
Up down counter

module upordown_counter(Clk, reset,UpOrDown, Count );


input Clk,reset,UpOrDown;
output [3 : 0] Count;
reg [3 : 0] Count = 0;
always @(negedge(Clk) or posedge(reset))
begin
if(reset == 1)
Count <= 0;
else
if(UpOrDown == 1)
Count <= Count + 1;
else
Count <= Count - 1;
end
endmodule
Up counter
• module upordown_counter(Clk, reset, Count );
• input Clk,reset;
• output [3 : 0] Count;
• reg [3 : 0] Count = 0;
• always @(negedge(Clk) or posedge(reset))
• begin
• if(reset == 1)
• Count <= 0;
• else
• Count <= Count + 1;
• end
• endmodule
Up down counter

module upordown_counter(Clk,
reset,UpOrDown, Count ); else //Down mode selected
input Clk,reset,UpOrDown; if(Count == 0)
output [3 : 0] Count; Count <= 15;
reg [3 : 0] Count = 0; else
always @(negedge(Clk) or posedge(reset))
Count <= Count - 1; //Decrement counter
begin
if(reset == 1)
end
Count <= 0; endmodule
else
if(UpOrDown == 1) //Up mode selected
if(Count == 15)
Count <= 0;
else
Count <= Count + 1;
4-bit Johnson counter
4-bit Johnson counter

• module johnson_counter(clk,rst,count); • begin


• input clk,rst; • if (~rst)
• parameter width =4; • count =4'b0000;
• output reg[width-1:0]count; • else
• always @(posedge clk) • count = {count[2:0],~count[3]};
• end
• endmodule
32 – bit, 16 locations RAM

•module RAM32(clk,data_in,data_out,addr,wr_rd,rst); • begin


•input clk,wr_rd,rst; • if(rst)
•input [3:0] addr; • data_out = 31’b0;
• else if(wr_rd)
•input [31:0]data_in;
• mem[addr] = data_in;
•output reg [31:0] data_out;
• else
•reg [31:0] mem [15:0];
• data_out = mem[addr];
•always @(posedge clk)
• end
• endmodule
ALU Design
• module ALU_MAIN(A,B,out,c,select); • And : out = A&B;
• input [1:0]A,B; • Or : out = A|B;
• output reg c; • Xor : out = A^B;
• output reg [3:0]out; • Not : out = !A;
• input [3:0]select; • rs : out = B>>2;
• parameter add= 4'b0000, sub= 4'b0001, mul= 4'b0010,
And= 4'b0100, Or= 4'b0101,Xor=4'b0110, • ls : out = A<<2;
Not=4'b0111;parameter rs = 4'b1000, ls=4'b1001, • Nand : out = ~(A&B);
Nand= 4'b1010, Nor=4'b1100, XNor=4'b1101;
• Nor : out = ~(A|B);
• always @(select)
• begin • XNor : out = A~^B;
• case (select) • endcase
• add : {c,out}= A+B; • end
• sub : {c,out}= A-B; • endmodule
• mul : out = A*B;
PISO
PISO
• module piso(clk,clr,pi,so); • tmp<=pi;
• output reg so;
• end
• input clk,clr;
• else
• input [3:0]pi;
• reg [3:0]tmp;
• begin
• always @ (posedge clk) • so<=tmp[0];
• begin • tmp<=tmp>>1'b1;
• if(clr==1'b1) • end
• begin • end
• so<=1'b0; • endmodule
SISO
SISO

•module siso_non(q, din, clk, rst); • begin


•output reg q; • w[2]<=din;
•input clk,din,rst; • w[1]<=w[2];
•reg [2:0]w; • w[0]<=w[1];
•always @(posedge clk) • q<=w[0];
•begin • end
•if(rst) • end
•q<=4'b0; • endmodule
•else
SIPO
SIPO
• module sipo(q,din,clk,clr); • begin
• output reg [3:0]q; • q[3]<=din;
• input din,clk,clr; • q[2]<=q[3];
• always @(posedge clk) • q[1]<=q[2];
• begin • q[0]<=q[1];
• if(!clr) • end
• q<=4'b0000; • end
• else • endmodule
3. FPGA Fabrics
FPGA
• SRAM-based FPGAS
• Permanently Programmer FPGAs.(Antifuse)
3.2 FPGA Architectures
Generic structure of an FPGA fabric.
FPGA Architectures

• In general, FPGAs require three


major types of elements:
• combinational logic;
• interconnect;
• I/O pins.

These three elements are mixed


together to form an FPGA fabric.
FPGA architectures(CLBs).

• The combinational logic is


divided into relatively small units
which may be known as logic
elements (LEs) or combinational
logic blocks (CLBs).
• The LE or CLB can usually form
the function of several typical
logic gates but it is still small
compared to the typical
combinational logic block found
in a large design.
FPGA architectures
FPGA architectures---interconnections

• The interconnections are made


between the logic elements using
programmable interconnect.
• The interconnect may be logically
organized into channels or other
units.
• FPGAs typically offer several types of
interconnect depending on the
distance between the combinational
logic blocks that are to be connected;
• clock signals are also provided with
their own interconnection networks.
FPGA architectures---I/O blocks

• The I/O pins may be referred to


as I/O blocks (IOBs).
• They are generally
programmable to be inputs or
outputs and often provide other
features such as low-power or
high-speed connections.
FPGA interconnect
FPGA interconnect
• An FPGA designer must rely on
pre-designed wiring, unlike a
custom VLSI designer who can
design wires as needed to make
connections.
• The interconnection system of an
FPGA is one of its most complex
aspects because wiring is a global
property of a logic design.
connection paths

• We therefore need to make connections


not just between LEs and wires but also
between the wires themselves.
• Wires are typically organized in wiring
channels or routing channels that run
horizontally and vertically through the chip.
• Each channel contains several wires;
• the human designer or a program chooses
which wire will be used in each channel to
carry a signal.
• Connections must be made between wires
in order to carry a signal from one point to
another.
segmented wiring
segmented wiring

• In order to allow a logic designer to make


all the required connections between
logic elements, the FPGA channels must
provide wires of a variety of lengths.
• Because the logic elements are organized
in a regular array, we can arrange wires
going from one LE to another.
• The figure shows connections of varying
length as measured in units of Les.
• the top signal of length 1 goes to the next
LE, the second signal goes to the second
LE, and so on. This organization is known
as a segmented wiring structure
FPGA configuration
• All FPGAs need to be programmed or configured.
• There are three major circuit technologies for configuring an FPGA:
SRAM, antifuse, and flash.
• No matter what circuits are used, all the major elements of the FPGA
—the logic, the interconnect, and the I/O pins—need to be
configured.
• The details of these elements vary greatly depending on how the
FPGA elements are to be programmed.
Design of FPGA architectures
• Some questions of interest to the person who designs the FPGA itself
include:
• How many logic elements should the FPGA have?
• How large should each logic element be?
• How much interconnect should it have?
• How many types of interconnection structures should it have?
• How long should each type of interconnect be?
• How many pins should it have?
fine-grain vs. coarsegrain
• fine-grained FPGAs—their logic elements can implement fairly small
pieces of logic.
• Coarsegrained FPGAs that are built from large blocks.
3.3 SRAM-Based FPGAs
SRAM-Based FPGAs
• Static memory is the most widely used method of configuring FPGAs.
SRAM-Based FPGAs
characteristics of SRAM-based FPGAs
• SRAM-based FPGAs hold their configurations in static memory
• The output of the memory cell is directly connected to another circuit
and the state of the memory cell continuously controls the circuit
being configured.
static memory advantages:
• The FPGA can be easily reprogrammed. Because the chips can be
reused, and generally reprogrammed without removing them from
the circuit, SRAM-based FPGAs are the generally accepted choice for
system prototyping.
• The FPGA can be reprogrammed during system operation, providing
dynamically reconfigurable systems.
static memory advantages:
• The circuits used in the FPGA can be fabricated with standard VLSI
processes.
SRAM-based FPGAs also have some disadvantages:
• The SRAM configuration memory burns a noticeable amount of
power, even when the program is not changed.
.
3.3.2 Logic Elements
Logic Elements
FPGA architectures
lookup tables
• The basic method used to build a
combinational logic block (CLB)—also
called a logic element or LE—in an SRAM-
based FPGA is the lookup table (LUT).
• the lookup table is an SRAM that is used to
implement a truth table.
• Each address in the SRAM represents a
combination of inputs to the logic element.
• The value stored at that address represents
the value of the function for that input
combination.
• An n-input function requires an SRAM with
2^n locations.
lookup tables
• Because a basic SRAM is not clocked,
• the lookup table LE operates much as any other logic gate—as its
inputs change, its output changes after some delay.
programming a lookup table
• Unlike a typical logic gate, the function represented by the LE can be
changed by changing the values of the bits stored in the SRAM.
• A typical logic element has four inputs.
• The delay through the lookup table is independent of the bits stored
in the SRAM, so the delay through the logic element is the same for
all functions.
programming a lookup table
• This means that, for example, a lookup table based LE will exhibit the
same delay for a 4-input XOR and a 4-input NAND.
• In contrast, a 4-input XOR built with static CMOS logic is considerably
slower than a 4-input NAND.
A flip-flop in a logic element.
FPGA architectures
A flip-flop in a select logic element.
• Logic elements generally contain registers
—flip-flops and latches—as well as
combinational logic.
• A flip-flop or latch is small compared to
the combinational logic element
• Using a separate cell for the memory
element would simply take up routing
resources
• the memory element is connected to the
output; whether it stores a given value is
controlled by its clock and enable inputs.
complex logic elements
• More complex logic blocks are also
possible.
• For example, many logic elements also
contain special circuitry for addition.
• Many FPGAs also incorporate
specialized adder logic in the logic
element.
• The critical component of an adder is
the carry chain, which can be
implemented much more efficiently in
specialized logic than it can using
standard lookup table techniques.
Xilinx Spartan-II combinational logic block
Xilinx Spartan-II CLB Slice
• The basic building block of the Spartan-II
FPGA CLB is the logic cell (LC).
• Each Spartan-II FPGA CLB contains four
LCs, organized in two similar slices; a
single slice is shown in Figure .
• An LC includes a 4-input function
generator, carry logic, and storage
element.
Spartan-II FPGA Family Members
Spartan-II CLB Slice
Xilinx Spartan-II combinational logic block
• A slice includes two logic cells
(LCs).
• The foundation of a logic cell is the
pair of four-bit lookup tables. Their
inputs are F1-F4 and G1-G4.
• Each lookup table can also be
used as a 16-bit synchronous RAM
or as a 16-bit shift register.
Xilinx Spartan-II combinational logic block
• Each slice also contains carry logic for each LUT so
that additions can be performed.
• A carry in to the slice enters the CIN input, goes
through the two bits of carry chain, and out
through COUT.
• The arithmetic logic also includes an XOR gate.
• To build an adder, the XOR is used to generate the
sum and the LUT is used for the carry computation.

• The critical component of an adder is the carry


chain, which can be implemented much more
efficiently in specialized logic than it can using
standard lookup table techniques.
Xilinx Spartan-II combinational logic block
• Each slice includes a multiplexer that is
used to combine the results of the two
function generators (LUT) in a slice.
• Another multiplexer combines the outputs
of the multiplexers in the two slices,
generating a result for the entire CLB.
• The registers can be configured either as
D-type flip-flops or as latches.
• Each register has clock and clock enable
signals.
• Each CLB also contains two three-state
drivers (known as BUFTs) that can be used
to drive on-chip busses.
ALTERA Cyclone II Architecture
Cyclone II Device Block Diagram
Cyclone II Device Block Diagram
• Cyclone® II devices contain a two-
dimensional row- and column-based
architecture
• Column and row interconnects of varying
speeds provide signal interconnects between
logic array blocks (LABs), embedded memory
blocks, and embedded multipliers.

• The logic array consists of LABs, with 16 logic elements


(LEs) in each LAB.
• An LE is a small unit of logic providing efficient
implementation of user logic functions.
• LABs are grouped into rows and columns across the
device.
• Cyclone II devices range in density from 4,608 to 68,416
LEs.
Cyclone II Device Block Diagram
• Cyclone II devices provide a global clock network
and up to four phase-locked loops (PLLs).
• The global clock network consists of up to 16
global clock lines that drive throughout the entire
device.
• The global clock network can provide clocks for all
resources within the device, such as input/output
elements (IOEs), LEs, embedded multipliers, and
embedded memory blocks.
Cyclone II Device Block Diagram
• M4K memory blocks are true dual-port
memory blocks with 4K bits of memory plus
parity (4,608 bits).
• These blocks provide dedicated true dual-
port, simple dual-port, or single-port memory
up to 36-bits wide at up to 260 MHz.
• These blocks are arranged in columns across
the device in between certain LABs.
• Cyclone II devices offer between 119 to 1,152
Kbits of embedded memory.
Cyclone II Device Block Diagram
• Each embedded multiplier block can
implement up to either two 9 × 9-bit
multipliers, or one 18 × 18-bit multiplier
with up to 250-MHz performance.
• Embedded multipliers are arranged in
columns across the device.
Cyclone II LAB Structure
Cyclone II LAB Structure

• ■ 16 LEs
• ■ LAB control signals
• ■ LE carry chains
• ■ Register chains
• ■ Local interconnect
Cyclone II LE
Cyclone II LE
• The smallest unit of logic in the Cyclone II
architecture, the LE, is compact and provides
advanced features with efficient logic
utilization.
Cyclone II LE
• Each LE features:
• A four-input look-up table (LUT), which is
a function generator that can implement
any function of four variables
■ A programmable register
■ A carry chain connection
■ A register chain connection
Cyclone II LE

• Each LE’s programmable register can be


configured for D, T, JK, or SR operation.
• Each register has data, clock, clock enable,
and clear inputs.
• For combinational functions, the LUT output
bypasses the register and drives directly to the
LE outputs.
LE Operating Modes

• ■ Normal mode
• ■ Arithmetic mode
LE Operating Modes
Normal mode
Normal Mode

• The normal mode is suitable for


general logic applications and
combinational functions.
• In normal mode, four data inputs from
the LAB local interconnect are inputs
to a four-input LUT .
• The Quartus II Compiler automatically
selects the carry-in or the data3 signal
as one of the inputs to the LUT.
Arithmetic Mode
Arithmetic Mode

• The arithmetic mode is ideal for


implementing adders, counters,
accumulators, and comparators.
• An LE in arithmetic mode implements a
2-bit full adder and basic carry chain
3.4 Permanently Programmed FPGAs
Permanently Programmed FPGAs

• SRAM-based FPGAs have to be configured at power-up.


• There are two technologies used to build FPGAs that need to be
configured only once: antifuses and flash.
3.4.1 Antifuses
Antifuses
Antifuses

• An antifuse is fabricated as a normally


open disconnection.
• When a programming voltage is applied
across the antifuse, it makes a connection
between the metal line above it and the
via to the metal line below.
• An antifuse has a resistance on the order
of 100Ω, which is more resistance than a
standard via.
• The antifuse has several advantages over a
fuse, a major one being that most
connections in an FPGA should be open, so
the antifuse leaves most programming
points in the proper state.
Antifuses
• An antifuse is programmed by putting a voltage across it.
• Each antifuse must be programmed separately.
• The FPGA must include circuitry that allows each antifuse to be
separately addressed and the programming voltage applied.
3.4.2 Flash Configuration
Flash Configuration
• Flash memory is a high-quality
programmable read-only
memory.
• Flash uses a floating gate
structure in which a low-leakage
capacitor holds a voltage that
controls a transistor gate.
• This memory cell can be used to
control programming transistors.
Flash Configuration
Flash Configuration
Flash Configuration
Flash Configuration
Flash Configuration
• The memory cell controls two
transistors.
• One is the programmable
connection point. It can be used
for interconnect electrical nodes
in interconnect or logic.
• The other allows read-write
access to the cell.
3.4.3 Logic Blocks
Logic Blocks

• The logic blocks in antifuse-


programmed FPGAs are
generally based upon
multiplexing,
• since that function can be
implemented by making or
breaking connections and
routing signals.
A single multiplexer used as a logic element.
A logic element built from several multiplexers.
Actel Axcelerator family logic elements
3.6 Circuit Design of FPGA Fabrics

• Logic Elements
• The logic element of an FPGA is considerably more complex than a
standard CMOS gate.
A logic element built from a multiplexer
Programming the mux-based logic element
Shannon’s Expansion Theorem

We can use the Shannon expansion theorem to expand


F =A·F(A='1’) + A'·F(A='0’)

Example: F =A'·B + A·B·C' + A'·B'·C = A·(B·C') + A'·(B + B'·C)


Shannon’s Expansion Theorem

• F=(A·B) + (B'·C) + D
• Expand F wrt B: F=B·(A + D) + B'·(C + D) =B·F2 + B’·F1
• Expand F2 wrt A, and F1 wrt C:
• F2=A + D=(A·1) + (A'·D);
• F1=C + D=(C·1) + (C'·D)
Shannon’s Expansion Theorem
4.7.1 Syntax-Directed Translation
Translating a logical expression in an HDL description.
Translating a conditional in an HDL description.
Book3- Chapter17-Intellectual
Property
Intellectual Property
• Any existing functional blocks are typically referred to as IP.
Three main sources of such IP are
(1) Internally created blocks from Previous design
(2) FPGA Vendors
(3) Third Party IP providers
Handcrafted IP

• One scenario is that the IP provider


has handcrafted an IP block starting
with an RTL description.
• Three are several ways in which the
end user might purchase and use
such a block.
1) IP at the Unencrypted RTL level
2) IP at the encrypted RTL level
3) IP at the unplaced and unrouted
netlist level
4) IP at the placed and routed netlist
level
Intellectual Property
IP at the Unencrypted RTL level

• FPGA designers can purchase IP at the


RTL level as blocks of unencrypted
source code.
• These blocks are then be integrated
into the RTL code for the body of the
design.
• Note that the IP provider would
already have simulated, synthesized
and verified the IP blocks before
handing over the RTL source code
IP at the encrypted RTL level

• Companies like Altera and Xilinx


to develop their own encryption
schemes and tools.
IP at the unplaced and unrouted netlist level

• Perhaps the most common


scenario is for FPGA designers to
purchase IP at the unplaced and
unrouted LUT/CLB netlist level.
• Such netlist are typically
provided in encrypted form,
either as encrypted EDIF or using
some FPGA vendor-specific
format.
IP at the placed and routed netlist level

• The FPGA designer may


purchase IP at the placed and
routed LUT/CLB netlist level
• Such netlist are typically
provided in encrypted form,
either as encrypted EDIF or using
some FPGA vendor specific
format.
Book2- 4.7.2 Logic Implementation by
Macro
Logic Implementation by Macro

• Macros are a form of design using intellectual property (IP).


• The macro is a predesigned element that can be incorporated into a larger design.
• Macros may be hard macros or soft macros, depending on whether they include
layout information.
• A hard macro describes where elements are placed
• A soft macro only describes logic and interconnections.
• Hard macros generally provide the highest performance because they describe physical
relationships designed to minimize wire lengths.
• Some macros may specify placement of logic but not interconnections.
• However, physical restrictions may limit the applicability of use of the hard macro.
• Soft macros may provide less dramatic improvements but may be useful in more
situations.
• Thank You

You might also like