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

Verilog HDL 2022

This document provides an introduction to Verilog HDL. It discusses that HDLs are used to describe digital logic circuits without being tied to specific hardware. It also describes different levels of abstraction from behavioral to gate-level and different design tools used for simulation and synthesis. Key concepts of Verilog like modules, ports, wires, registers, continuous assignments and concurrency are introduced.

Uploaded by

Alex Pérez
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
124 views

Verilog HDL 2022

This document provides an introduction to Verilog HDL. It discusses that HDLs are used to describe digital logic circuits without being tied to specific hardware. It also describes different levels of abstraction from behavioral to gate-level and different design tools used for simulation and synthesis. Key concepts of Verilog like modules, ports, wires, registers, continuous assignments and concurrency are introduced.

Uploaded by

Alex Pérez
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 122

VERILOG HDL

SERDAR DURAN
ITU EMBEDDED SYSTEM DESIGN LABORATORY

1 gstl.itu.edu.tr
Introduction

2 gstl.itu.edu.tr
Introduction
• Hardware Description Languages (HDLs) are used to describe digital logic circuits
without being tied to a specific electronic technology.

• HDLs uses Register-transfer level (RTL) abstraction model.


• Register-transfer level (RTL) means the flow of digital signals (data) between hardware
registers and logical operators.
• RTL is a high-level represantation of a digital circuit.
• RTL does not consider the physical hardware (real hardware).

• The details of gates and their interconnections (Gate-Level Netlist) are extracted
by logic synthesis tools (e.g. Vivado, Genus) from the RTL description.

3 gstl.itu.edu.tr
Behavioral Simulate Test • Coding HDL, C - C++, MATLAB or Python.
Algorithm Results • Describing the behavior of the circuit.
• Textual represantation.

Simulate • High-level represantation of the circuit.


Register Test
• Describing registers and combinatorial logic.
Transfer Level Results • Schematical represantation at high-level.

Simulate • Generating gates and their interconnections


Test using synthesis tools.
Gate Level Netlist Results • Schematical represantation.

• Generate the layout (physical chip/circuit) by


Place + Route using placement/routing tools.
• Physical represantation.

4 gstl.itu.edu.tr
Behavioral Simulate
Test
Algorithm Results
Manual ❖ HDL tools are used for
Simulate automatic translation.
Register Test
Transfer Level Results ❖ In each step we need to
Logic Synthesis simulate and verify our
Simulate design.
Test
Gate Level Results ▪ Behavioral Simulation
▪ RTL Sim.
Auto Place + Route
▪ Post Synthesis Sim.
Simulate
Test ▪ Post Imp Sim.
Results

5 gstl.itu.edu.tr
RTL Description
Verilog Code
module and2( output z, input x, input y);

assign z = x&y;

endmodule

Layout
Gate-Level Netlist

Taken from Vivado, Xilinx Nexsys 4 DDR FPGA Chip


Artix-7 XC7A100T-1CSG324C

6 gstl.itu.edu.tr
HDLs
• The most commonly used HDLs are Verilog HDL and VHDL.
• VHDL is used more common in FPGA Designs.
• Verilog is used more common in ASIC Designs.

• For simulation and Verification:


• VHDL
• SystemVerilog
• Verilog
• UVM
• UVVM

7 gstl.itu.edu.tr
Design Tools
• Intel Altera FPGAs: Quartus, Modelsim (old)
• Xilinx FPGAs: Vitis-Vivado

• For Asic Designs: Cadence Virtuoso


• Xcelium (RTL Sim)
• Genus (Synthesis)
• Innovus (Place/Route)
• Calibre (DRC Check), Quantus(Noise), Tempus(Temperature), Voltus(Power Integrity) and
others.

8 gstl.itu.edu.tr
Key Points
• Verilog is NOT a programming language.
• Verilog ONLY describes the behavior of digital circuits.
• Verilog code is inherently concurrent contrary to regular programming
languages, which are sequential ( C, C++, Python ).

9 gstl.itu.edu.tr
Concurrency
• Due to the physical limitations of the transistors size, the semiconductor and
microprocessor technologies is not developing fast compared to the past
decades.
• Therefore, there is an increasing focus on parallelization and concurrency for the
real time systems including communications, radar systems, video processing,
avionic systems etc.

• Concurrency means performing multiple operations at the same time.

10 gstl.itu.edu.tr
Concurrency
• Concurrency means lower latency.
• There are several options to deal with the latency:
o Multi Thread Computing
o FPGAs
o ASICs
o SoCs
o Heterogeneous hardware ( containing co-processors, FPGAs apart from the microprocessors
and peripherals in a board)

11 gstl.itu.edu.tr
Basics of Verilog

12 gstl.itu.edu.tr
Value Set
• Verilog supports four different values.

13 gstl.itu.edu.tr
Modules & Ports
• A module is the basic building block in Verilog and it implements a certain logic
behavior.
• A Verilog module has a name and a port list.
• Ports provide the interface by which a module can communicate with other
modules.

// Syntax:
module module_name ( <port_list> );
.
<logic behavior>
.
endmodule

14 gstl.itu.edu.tr
Continuous Assignments
• It is used to drive a value onto a wire.
• Continuous assignments are always active ,the assignment expression is
evaluated as soon as the right-hand-side operands changes!

// Continuous assign. out is a net. i1 and i2 are nets.


// Whenever i1 or i2 changes, out value is updated.
assign out = i1 & i2;

15 gstl.itu.edu.tr
ANSI C Style PORT Declaration:

module AND( output Q, module AND( Q, A, B );


input A ,
input B );
output Q;
input A, B;
assign Q = A & B;
assign Q = A & B;
endmodule
endmodule

16 gstl.itu.edu.tr
Wires/Nets
• Wires represent connections between hardware elements. Just as in real circuits,
wires have values continuously driven on them.
• Ports are wires by default.

wire A; // Declare net a for the above circuit


wire B; // Declare two wires b,c for the above circuit

17 gstl.itu.edu.tr
Both codes are same!
module AND( output wire Q, module AND( output Q,
input wire A , input A ,
input wire B ); input B );

assign Q = A & B; assign Q = A & B;

endmodule endmodule

18 gstl.itu.edu.tr
Registers
• Registers represent data storage elements. Registers retain value until another
value is placed onto them.
• Registers are mostly used to describe the sequential circuits in Verilog.
• Do not CONFUSE the term registers in Verilog with hardware registers in real
circuits.
• The term register merely means a variable that can hold a value.

19 gstl.itu.edu.tr
module AND( output reg Q, continous assignment cannot be used
input A ,
input B );
for the output Q.
. Because Q is not a wire!
<functionality>
.
To assign a value to register Q,
endmodule you need to use an always block (in the next
chapters).

20 gstl.itu.edu.tr
Verilog HDL vs C Language
• Verilog is a concurrent language unlike the C programming language that is
sequential.
• In other words, Verilog run in parallel but C run in sequence.
// Runs in parallel // Runs in sequence
module test( output Q, int main()
output Qbar, {
input A, bool A, B, Q, Qbar;
input B );
Q = A %% B;
assign Q = A & B; Qbar = !(A %% B);

assign Qbar = ~( A & B); return 0;


}
endmodule

21 gstl.itu.edu.tr
Verilog HDL vs C Language
• Using always and initial module AND( output reg Q, input A , input B );
statement, sequential blocks
can be created. initial
begin
• The statements inside an .
always or initial block is <initialization>
.
executed sequentially! end
• Multiple behavioral
always @( ..signal_list.. )
statements must be grouped, begin
typically using the keywords .
begin and end ( similar to {} in <functionality>
C ). .
end
endmodule

22 gstl.itu.edu.tr
Initial Block

• An initial block executes exactly module AND( output reg Q,


once. input A ,
input B );
• The initial blocks are typically
used for initialization. initial
Q = 0; // single statement no need
• Inizialized values are NOT // for begin and end
synthesizable by logic tools!
always @( ..signal_list.. )
begin
.
<functionality>
.
end
endmodule

23 gstl.itu.edu.tr
Always Block

• An always block executes the module AND( output reg Q,


statements continuously in a input A ,
looping fashion. input B );
initial
• The @ symbol is used to specify Q = 0;
an event control. Statements can
be executed when the signal value // whenever the A or B values are changed
is changed. // Q value will be updated
always @(A, B)
• Mostly used for sequential circuits Q = A & B;
but also combinational circuits.
endmodule

24 gstl.itu.edu.tr
module AND( output reg Q,
input A ,
input B );
initial
Q = 0;

// whenever the A or B values are changed


// Q value will be updated
always @(A, B)
Q = A & B;

endmodule

25 gstl.itu.edu.tr
Behavioral Statements
• All behavioral statements must be inside an initial or always block.
• Behavioral statements are:
o Blocking and Nonblocking assignments
o If-Else conditional statements
o Case statement
o For, While loops
• If there are multiple initial or always blocks, each block starts to execute
concurrently!

26 gstl.itu.edu.tr
If – Else Statement Case Statement
//Type 1 conditional statement. No else statement.
if (<expression>) case (<expression>)
true_statement ;
<alternative1>: statement1;
<alternative2>: statement2;
//Type 2 conditional statement. One else statement <alternative3>: statement3;
if (<expression>) ...
true_statement ; ...
else default: default_statement; // optional
false_statement ;
endcase
//Type 3 conditional statement. Nested if-else-if.
if (<expression1>)
true_statement1 ;
else if (<expression2>) • You must combine multiple assigments
true_statement2 ; using begin - end keywords.
else if (<expression3>)
true_statement3 ;
else
default_statement ;

27 gstl.itu.edu.tr
For Loop
for ( <initialization> ; <condition> ; <step_assignment> )
begin
.
statements
.
end

While Loop
while ( <condition> )
begin
.
statements
.
end

28 gstl.itu.edu.tr
Initialization
• Variables ( registers, integers etc.) can be initialized when they are declared.
• Initialization can be just used in test codes (NOT synthesizable).

module AND( output reg Q = 0,


input A ,
input B );

// whenever the A or B values are changed


// Q value will be updated
always @(A, B)
Q = A & B;

endmodule

29 gstl.itu.edu.tr
@* Operator
• Two special symbols: @* and @(*) are sensitive to a change on any signal inside
the block.

module AND( output reg Q,


input A ,
input B );

// whenever the A or B values are changed


// Q value will be updated
always @(*)
Q = A & B;

endmodule

30 gstl.itu.edu.tr
Modules & Instantiation

31 gstl.itu.edu.tr
Modules&Instances
• A module is the basic unit of a hierarchy.
• It can be a single element or a collection of lower level instances (modules).

A B

adder FA FA FA FA

cout S

Top Module Lower level modules


inside the Top Module

32 gstl.itu.edu.tr
Modules&Instances
• Creating objects from a module is called instantiation, and the objects are called
instances.

module <upper_module_name> (<module_ports>)


. Instantiation
.
<module_name> <instance_name> (<ports>)
.
. • The order of the statements (incuding
<module_internals> instantiations) are not important.
.
• Remember that the code is executed
. parallel rather than in sequence!
endmodule

33 gstl.itu.edu.tr
A B

adder FA FA FA FA

cout S

module adder( input [3:0] A, B,


output cout, Vectors (data type)
output [3:0] S );

wire c0 = 0;
wire c1, c2, c3;

FA fa0( A[0], B[0], c0, c1, S[0] );


FA fa1( A[1], B[1], c1, c2, S[1] ); Instantiations
FA fa2( A[2], B[2], c2, c3, S[2] );
FA fa3( A[3], B[3], c3, cout, S[3] ); Full adder is an another module and must be
defined in the same project.
endmodule

34 gstl.itu.edu.tr
A B

adder FA FA FA FA
cout S

Top Module Lower Module


module adder( input [3:0] A, B,
module FA( input a, b, c_in,
output cout,
output c_out, sum );
output [3:0] S );
wire c0, c1, c2, c3;
assign sum = a ^ b ^ c_in;
FA fa0( A[0], B[0], 0, c1, S[0] ); assign c_out = ( c_in & ( a ^ b ) ) | ( a & b );
FA fa1( A[1], B[1], c1, c2, S[1] );
FA fa2( A[2], B[2], c2, c3, S[2] ); endmodule;
FA fa3( A[3], B[3], c3, cout, S[3] );

endmodule

35 gstl.itu.edu.tr
Port Connection Rules

Upper Block

• Inputs: internally must always be of type net, externally the inputs can be connected to a variable of type
reg or net.
• Outputs: internally can be of type net or reg, externally the outputs must be connected to a variable of
type net.
• Inouts: internally or externally must always be type net, can only be connected to a variable net type.

36 gstl.itu.edu.tr
module adder_tb; module adder( input [3:0] A, B, // internal inputs
output cout, // internal output
reg [3:0] A, B; // external inputs output [3:0] S ); // internal output
wire [3:0] SUM; // external output
wire COUT; // external output wire c0 = 0;
wire c1, c2, c3;
// instance of adder
adder AD( A, B, COUT, SUM );
FA fa0( A[0], B[0], c0, c1, S[0] );
initial FA fa1( A[1], B[1], c1, c2, S[1] );
$monitor( $time, " A=%d B=%d | FA fa2( A[2], B[2], c2, c3, S[2] );
COUT=%d SUM=%d ",A,B,COUT,SUM ); FA fa3( A[3], B[3], c3, cout, S[3] );

initial endmodule
begin
A=0; B=0;
#10 A=4'b0001; B=4'b1001;
adder_tb
#10 A=4'b0101; B=4'b1011;
#10 A=4'b0101; B=4'b1101; adder
#10 $finish;
end
A net net S
reg net
B net net cout
reg net

37 gstl.itu.edu.tr
Connecting by Ordered List

module adder( input [3:0] A, B,


output cout, module FA( input a, b, c_in,
output [3:0] S ); output c_out, sum );
wire c0 = 0;
wire c1, c2, c3;
Order: a , b , c_in , c_out , sum
FA fa0( A[0], B[0], c0, c1, S[0] );
FA fa1( A[1], B[1], c1, c2, S[1] );
FA fa2( A[2], B[2], c2, c3, S[2] );
FA fa3( A[3], B[3], c3, cout, S[3] );

endmodule

38 gstl.itu.edu.tr
Connecting by Port’s Name
module FA( input a, b, c_in,
output c_out, sum );

module adder( input [3:0] A, B,


output cout,
output [3:0] S );

wire c0 = 0;
wire c1, c2, c3;

FA fa0( .c_out(c1), .sum(S[0]), .a(A[0]), .b(B[0]), .c_in(c0) );


FA fa1( .c_out(c2), .sum(S[1]), .a(A[1]), .b(B[1]), .c_in(c1) );
FA fa2( .c_out(c3), .sum(S[2]), .a(A[2]), .b(B[2]), .c_in(c2) );
FA fa3( .c_out(cout), .sum(S[3]), .a(A[3]), .b(B[3]), .c_in(c3) );

endmodule

39 gstl.itu.edu.tr
Modeling Concepts

40 gstl.itu.edu.tr
Modeling Concepts
• There are three different modelling concepts:
• Structural Modelling
• Dataflow Modelling
• Behavioral Modelling

• These modeling concepts can be mixed to create more complex modules.

41 gstl.itu.edu.tr
Structural Modelling
• The structural modelling is obtained by using logic gates.
• It can be considered as a textual representation of logic circuit diagrams.
• Primitive gates are used for structural modelling.

42 gstl.itu.edu.tr
Primitive Gates

43 gstl.itu.edu.tr
wire OUT, IN1, IN2;

// basic gate instantiations. • Instance names do not need to be


and a1(OUT, IN1, IN2); specified for primitives.
nand na1(OUT, IN1, IN2);
• More than two inputs can be specified
or or1(OUT, IN1, IN2);
nor nor1(OUT, IN1, IN2);
for those primitive gates.

xor x1(OUT, IN1, IN2);


xnor nx1(OUT, IN1, IN2);

// More than two inputs: 3 input nand gate


nand na1_3inp(OUT, IN1, IN2, IN3);

// gate instantiation without instance name


and (OUT, IN1, IN2);

44 gstl.itu.edu.tr
// basic gate instantiations.
buf b1(OUT1, IN); • More than two outputs can be
not n1(OUT1, IN); specified for these primitive gates.
// More than one outputs
buf b1_2out(OUT1, OUT2, IN);

// gate instantiation without instance name


not (OUT1, IN);

45 gstl.itu.edu.tr
4-bit MULTIPLEXER Structural Design
module mux4( out, i0, i1, i2, i3, s1,
s0);

output out;
input i0, i1, i2, i3;
input s0, s1;
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

46 gstl.itu.edu.tr
Dataflow Modelling
• Dataflow modeling style is mainly used to describe combinational circuits.
• The basic mechanism is the continuous assignment ( keyword assign ).
• Verilog operators are used to implement the combinational circuits.

47 gstl.itu.edu.tr
Verilog Operators
Dataflow Design
4-bit MULTIPLEXER module mux4_to_1( out, i0, i1, i2, i3, s1, s0 );

output out;
input i0, i1, i2, i3;
input s1, s0;

assign out = s1 ? ( s0 ? i3 : i2 ) : ( s0 ? i1 : i0 );

endmodule

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

output out;
input i0, i1, i2, i3;
input s1, s0;

assign out = ( ~s1 & ~s0 & i0 ) | ( ~s1 & s0 & i1 )


| ( s1 & ~s0 & i2 ) | ( s1 & s0 & i3 );

endmodule

49 gstl.itu.edu.tr
Behavioral Modelling
• Behavioral modeling is primarily used to model sequential circuits, but can also be
used to model pure combinatorial circuits.
• Behavioral statements (if-else, case, for-while loops) are used for behavioral
modelling.
• Remember that behavioral statements can only be used in Initial and always blocks.

50 gstl.itu.edu.tr
4-bit MULTIPLEXER Behavioral Design
module mux4( output reg out,
input i0,
input i1,
input i2,
input i3,
input s1,
input s0 );

always @( s1, s0, i0, i1, i2, i3 )


case ( {s1, s0} )
0 : out = i0;
1 : out = i1;
2 : out = i2;
3 : out = i3;
default : $display("Invalid control signals");
endcase
endmodule

51 gstl.itu.edu.tr
Data Types & Numbers

52 gstl.itu.edu.tr
Number Represantation

<size> '<base format> <number>

Number

Base format
(d, b, o, h)

Decimal number
representing size in bits

53 gstl.itu.edu.tr
Sized Numbers
<size> '<base format> <number>

• <size> is written only in decimal and specifies the number of bits in the number.

• Base formats are decimal ('d or 'D), hexadecimal ('h or 'H), binary ('b or 'B) and
octal ('o or 'O).

4'b1111 // This is a 4-bit binary number


12'habc // This is a 12-bit hexadecimal number
16'd255 // This is a 16-bit decimal number.

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

23456 // This is a 32-bit decimal number by default


'hc3 // This is a 32-bit hexadecimal number
'o21 // This is a 32-bit octal number

55 gstl.itu.edu.tr
Negative Numbers
• Negative numbers can be specified by putting a minus sign before the size for a
constant number.
• Negative numbers are always specified as 2’s complement form of the
corresponding number.

-6'd3 // 6-bit negative number stored as 2's complement of 3


// 111101 => -3

56 gstl.itu.edu.tr
X and Z Values
• Verilog has two symbols for unknown and high impedance values. An unknown
value is denoted by an X. A high impedance value is denoted by Z.
• If the most significant bit of a number is 0, x, or z, the number is automatically
extended to fill the most significant bits, respectively, with 0, x, or z.

12'h13x // This is a 12-bit hex number; 4 least significant bits unknown


6'hx // This is a 6-bit unknown hex number
32'bz // This is a 32-bit high impedance number

57 gstl.itu.edu.tr
Underscore «_»
• 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

58 gstl.itu.edu.tr
Strings
• A string is a sequence of characters that are enclosed by double quotes.

"Hello Verilog World" // is a string


"a / b" // is a string

• Blank spaces (\b) , tabs (\t) and newlines (\n) are whitespace characters.

59 gstl.itu.edu.tr
DATA TYPES
• Wires (Nets)
• Registers
• Integers
• Real Numbers

• Vectors
• Arrays
• Strings

60 gstl.itu.edu.tr
Integers
• An integer is a 32-bits signed number.
• Registers store values as unsigned quantities, whereas integers store values as
signed quantities.

integer counter; // general purpose variable used as a counter.


initial
counter = -1; // A negative one is stored in the counter

61 gstl.itu.edu.tr
Real Numbers (Floating Point)
• They can be specified in // real
decimal notation (e.g., 3.14) or real delta; // Define a real variable called delta
initial
in scientific notation (e.g., 3e6, begin
delta = 4e10; // delta is assigned in scientific
which is 3 x 106 ). // notation
delta = 2.13; // delta is assigned a value 2.13
• When a real value is assigned end
to an integer, the real number
integer i; // Define an integer i
is rounded off to the nearest initial
i = delta; // i gets the value 2 (rounded value
integer.
of 2.13)
end

62 gstl.itu.edu.tr
Vectors
• Wires or reg data types can be declared as vectors (multiple bit widths).
• If bit width is not specified, the default is a scalar (1-bit).

// DECLARATION:
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, 41 bits wide

// ACCESSING:
busA[7] // bit # 7 of vector busA
bus[2:0] // Three least significant bits of vector bus,
virtual_addr[0:1] // Two most significant bits of vector virtual_addr

63 gstl.itu.edu.tr
Arrays
• Multi-dimensional arrays can also be declared with any number of dimensions.
• Do NOT confuse arrays with vectors!
• A vector is a single element that is n-bits wide. On the other hand, arrays are
multiple elements that are 1-bit or n-bits wide.
• Ports can not be declared as arrays.

<data_type> <[vector]> <name> <[array]> <[array]> <[array]> ...

wire, register, vectoral size, array size of the dimensions


integer etc. scalar default

64 gstl.itu.edu.tr
// DECLARATION:
integer count[0:7]; // An array of 8 count variables
reg bool[31:0]; // Array of 32 one-bit boolean register variables

reg [4:0] port_id[0:7]; // Array of 8 port_ids; each port_id is 5 bits wide


wire [7:0] w_array2 [5:0]; // Declare an array of 8 bit vector wire

integer matrix[4:0][0:255]; // Two dimensional array of integers


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

reg [63:0] array_4d [15:0][7:0][7:0][255:0]; //Four dimensional array

// ACCESSING:
count[5] = 0; // Reset 5th element of array of count variables
chk_point[100] = 0; // Reset 100th time check point value
port_id[3] = 0; // Reset 3rd element (a 5-bit value) of port_id array.
matrix[1][0] = 33559; // Set value of element indexed by [1][0] to

array_4d[0][0][0][0][15:0] = 0; // Clear bits 15:0 of the register


// Accessed by indices [0][0][0][0]
port_id = 0; // Illegal syntax - Attempt to write the entire array
matrix [1] = 0; // Illegal syntax - Attempt to write [1][0]..[1][255]

65 gstl.itu.edu.tr
Verilog Operators
Concatenation Operator
• Concatenation operator appends multiple operands.

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

67 gstl.itu.edu.tr
Replication Operator
• Repetitive concatenation of the same number.

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

68 gstl.itu.edu.tr
Conditional Operator
• It is the same as in the C language.

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


assign out = control ? in1 : in0;

69 gstl.itu.edu.tr
Blocking & Nonblocking
Assignments

70 gstl.itu.edu.tr
Blocking Assignment
• Blocking assignment statements are executed in the order they are specified in a
sequential block.

reg x, y, z;

initial
begin
x = 0; y = 0; z = 0; // x = 0, y = 0, z = 0 are executed at time 0

#15 x = 1; // x = 1 at time = 15
#10 y = 1; // y = 1 at time = 25
z = 1; // z = 1 at time = 25 but after the statement above
end

71 gstl.itu.edu.tr
Non-Blocking Assignment
• Nonblocking assignments allow scheduling of assignments without blocking
execution of the statements that follow in a sequential block.
• In nonblocking assignments read and write operations are separated.
• Nonblocking assignments is used for concurrent data transfers in a sequential
block.
• A “ <= “ operator is used to specify nonblocking assignments.

72 gstl.itu.edu.tr
reg x, y, z;

initial
begin
x = 0; y = 0; z = 0;

// x = 1 is scheduled to execute after 15 units: at time = 15


#15 x <= 1;

// y = 1 is scheduled after 10 time units: at time = 10


#10 y <= 1;

// z = 1 is scheduled without any delay: at time = 0


z <= 1;
end

73 gstl.itu.edu.tr
• Nonblocking Assignments:
always @( posedge clock )
begin
// Read the data a and b, after that
// write them to A and B
A <= a;
B <= b;
end

• Implementing Nonblocking Assignments using Blocking Assignments:


always @( posedge clock )
begin
// Read Operation
temp_a = a;
temp_b = b; ❖ In Nonblocking assignments
read and write operations are
// Write Operation separated.
A = temp_a;
B = temp_b;
end

74 gstl.itu.edu.tr
Non-Blocking Assignment
• While Blocking assignments are order dependent, Non-blocking assignments are
order independent.
• Blocking assignments can have race conditions, to avoid race conditions Non-
blocking assignments can be used.
• Generally, Non-blocking assignments are used to implement sequential logic,
whereas Blocking assignments are used to implement combinatorial logic.

75 gstl.itu.edu.tr
Blocking Non-Blocking
module block(Q1, Q2, D, clk); module non_block(Q1, Q2, D, clk);
output reg Q1,Q2; output reg Q1,Q2;
input D, clk; input D, clk;

always@(posedge clk) always@(posedge clk)


begin begin
Q2 = Q1; Q1 <= D;
Q1 = D; Q2 <= Q1;
end end
endmodule endmodule

Q1(t+1) = D(t) Q1(t+1) = D(t)


Q2(t+1) = Q1(t) Q2(t+1) = Q1(t)

76 gstl.itu.edu.tr
Blocking Non-Blocking
module block(Q1, Q2, D, clk); module non_block(Q1, Q2, D, clk);
output reg Q1,Q2; output reg Q1,Q2;
input D, clk; input D, clk;

always@(posedge clk) always@(posedge clk)


begin begin
Q1 = D; Q1 <= D;
Q2 = Q1; Q2 <= Q1;
end end
endmodule endmodule

Q1(t+1) = D(t) Q1(t+1) = D(t)


Q2(t+1) = Q1(t+1) Q2(t+1) = Q1(t)

77 gstl.itu.edu.tr
• For the example below, there is a race condition.
• Either x = y would be executed before y = x, or vice versa, depending on the simulator
implementation.
• To eliminate race conditions, Nonblocking assignments can be used.

// Blocking Assignments
always @( posedge clock )
x = y;

always @( posedge clock )


y = x;
// Nonblocking Assignments to Eliminate Race Conditions
always @(posedge clock)
x <= y;

always @(posedge clock) Race Condition


y <= x;

78 gstl.itu.edu.tr
Parameters &
Generate Blocks

79 gstl.itu.edu.tr
Parameters
• Verilog allows constants to be defined in a module by the keyword parameter.
• Parameters cannot be used as variables. They are just constants.
• Parameters values can be changed at module instantiation.
• Parameters allow flexible code design.

parameter PORT_ID = 5; // Defines a constant


parameter SIZE = 256;

80 gstl.itu.edu.tr
Parameter Declaration

module hello_world #(parameter id_num = 0)(); module hello_word();

initial parameter id_num = 0;


$display("Displaying hello_world
id number = %d", id_num); initial
$display("Displaying hello_word
endmodule id number = %d", id_num );
endmodule

ANSI C Style Declaration

81 gstl.itu.edu.tr
Parameter Overriding
• Parameter values can be overridden when a module is instantiated.

module hello_world #(parameter id_num = 0); module top;


// Parameter value assignment by ordered list
initial hello_world #(1) w1;
$display("Displaying hello_world
id number = %d", id_num); //Parameter value assignment by name
hello_world #(.id_num(2)) w2;
endmodule
endmodule

82 gstl.itu.edu.tr
Parameter Overriding
• Defparam statement and the hierarchical name of the instance can be used to
override parameter values.
module hello_word; module top;

parameter id_num = 0; //change parameter values in the instantiated modules


defparam w1.id_num = 1, w2.id_num = 2;
initial
$display("Displaying hello_word hello_word w1();
id number = %d", id_num ); hello_word w2();
endmodule
endmodule

/*
Output:
Displaying hello_world id number = 1
Displaying hello_world id number = 2
*/

83 gstl.itu.edu.tr
Generate Loop
• Generate statements are convenient when the same module instance is
repeated.
module bitwise_xor( out, i0, i1 );

parameter N = 32;

output [N-1:0] out;


input [N-1:0] i0, i1;

genvar j; // temp loop variable, used only ❖ Creating 32 XOR primitives


// in the evaluation of the generate blocks using generate block
generate
for( j=0; j<N; j=j+1 )
begin : xor_loop
xor g1( out[j], i0[j], i1[j] );
end
endgenerate

84 gstl.itu.edu.tr
Generate Conditional
• Generate conditional is used for conditionally instantiation, allowing flexible code
design.
module multiplier( product, a0, a1 );

parameter a0_width = 8;
parameter a1_width = 8;
parameter product_width = a0_width + a1_width;

output [product_width-1:0] product;


input [a0_width-1:0] a0;
input [a1_width-1:0] a1;

// Instantiate the type of multiplier conditionally.


generate
if( a0_width < 8) || (a1_width < 8) )
cla_multiplier #(a0_width, a1_width) m0 (product, a0, a1);
else
tree_multiplier #(a0_width, a1_width) m0 (product, a0, a1);
endgenerate
endmodule

85 gstl.itu.edu.tr
Generate Case
module adder( co, sum, a0, a1, ci );
parameter N = 4;

output co; output [N-1:0] sum;


input [N-1:0] a0, a1; input ci;

// Instantiate the appropriate adder based on the width of the bus.


// This is based on parameter N that can be redefined at
// instantiation time.
generate
case(N)
1: adder_1bit adder1( c0, sum, a0, a1, ci );
2: adder_2bit adder2( c0, sum, a0, a1, ci );
default: adder_cla #(N) adder3(c0, sum, a0, a1, ci);
endcase
endgenerate

endmodule

86 gstl.itu.edu.tr
Ring Oscillator
• A ring oscillator is composed of an odd number of NOT gates. Its
output oscillates between two voltage levels.

87 gstl.itu.edu.tr
module ring_oscillator #( parameter size = 100) ( input E, output O );

(* dont_touch="true" *) wire [size-1:0]w;

genvar i;

generate
for(i=0; i<size-1; i=i+1)
begin
NOT notk(.I(w[i]), .O(w[i+1]));
end
endgenerate

TRI tr1(.I(w[size-1]), .E(E), .O(w[0]));


assign O = w[size/2 -1];

endmodule

88 gstl.itu.edu.tr
Simulation &
System Tasks

89 gstl.itu.edu.tr
Simulation
• When using Verilog to design digital circuits, testbench codes are also created to
simulate the design code and ensure that it functions as expected.
• A testbench is simply a Verilog module. But it is different from the design
modules.
• A testbench is not implemented as a circuit, it is just used for the simulation of a
design code. Therefore, design modules must be synthesizable, whereas a
testbench module need not be synthesizable.

90 gstl.itu.edu.tr
Simulation
• In testbenches, delay units are necessary to test possible inputs.
• The # character followed by a number are used to model delays.
• Time unit is determined by ‘timescale command.

• There are also some useful inbuilt tasks and functions to use in a testbench (e.g.
$display, $monitor, $finish).

91 gstl.itu.edu.tr
Testbench Code
`timescale 1ns / 1ps // Timescale of the simulation
// 1 time unit= 1ns
module AND_tb(); // Testbench module
wire Q;
reg A,B;
and2 A1(Q, A, B); // Intantiate top Module of the design

initial
begin
Design Code // monitor and show the values of A,B,Q in the console
$monitor(" A=%b B=%b | Q = %b",A,B,Q);
module AND( output Q,
input A , A = 0; B = 0; // initial values of A,B
input B ); #10 A = 0; B = 1; // change the values A,B after 10 time unit
#10 A = 1; B = 0; // change the values A,B after 10 time unit
#10 A = 1; B = 1; // change the values A,B after 10 time unit
assign Q = A & B; #10 $finish; // finish the simulation after 10 time unit
end
endmodule
endmodule

Output in the console

92 gstl.itu.edu.tr
• Using a simulation tool which allows for waveforms to be viewed directly is very
useful to verify your design.

And Gate

Waveform is taken from


Vivado

93 gstl.itu.edu.tr
Simulation
• For sequential circuits, the clock signals are essential for its functioning. Hence, a
virtual clock is necessary in the testbench to simulate the sequential circuits.
• posedge and negedge keywords are used to refer rising edge and falling
edge of the corresponding signal respectively.

// Virtual Clock:
initial CLK = 1;
always #10 CLK = ~CLK;

94 gstl.itu.edu.tr
Design Code
module dff( clk, rst, d, q, qbar );

input clk,rst,d;
output reg q, qbar;

// "posedge: rising edge", "negedge: falling edge"


// of the corresponding signal
always@(posedge clk)
begin
if(rst == 1)
begin
q <= 0;
qbar <= 1;
end
else
begin
q <= d;
qbar <= ~d;
end
end
endmodule

95 gstl.itu.edu.tr
Testbench Code
`timescale 1ns / 1ps

module dff_tb();

reg CLK = 0;
reg D,RST;
wire Q,QBAR;

dff DFF(.clk(CLK), .rst(RST), .d(D), .q(Q), .qbar(QBAR));


Output in the console
always // Virtual Clock:
#10 CLK = ~CLK;

initial
begin
$monitor("simetime = %g, CLK = %b, RST =%b, D = %b, Q
=%b, QBAR =%b", $time, CLK,RST,D,Q,QBAR);
D=0; RST = 1;
#20 RST = 0;
#20 D = 0;
#20 D = 1;
#40 $finish;
end
endmodule

96 gstl.itu.edu.tr
Waveform

97 gstl.itu.edu.tr
Timing Control & 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.
• Delays are not synthesizable! Timing control is used for simulations and
verification.
• Timing control can be made for both continuous assignments and procedural
assignments.

98 gstl.itu.edu.tr
Delays
• For continuous assignments, timing control can be made by:

// Any change in values of in1 or in2 will result in a delay of 10 time units
assign #10 out = in1 & in2;

// An equivalent method
wire #10 out = in1 & in2;

//same as
wire out;
assign #10 out = in1 & in2;

99 gstl.itu.edu.tr
Delays
• For procedural assignments timing control can be made by:

initial
begin
x = 0; z = 0;

#5 y = x + z; // wait 5 time units, take value of x and z at the time=5,


// evaluate x + z and then assign value to y
end

100 gstl.itu.edu.tr
Display
• $display is used for displaying values, strings or expressions. Like printf in C.
• Syntax:
$display(p1, p2, p3,....., pn);

101 gstl.itu.edu.tr
//Display the string in quotes

$display("Hello Verilog World");

-- Hello Verilog World

//Display value of current simulation time 230

$display($time);

-- 230

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

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

102 gstl.itu.edu.tr
Hierarchical Name of Instances
• Verilog allows the displaying values of lower level instances.

module Z; module tb;


reg [1:0] c=2;
Y y1(); //instance Z z1();
endmodule
initial
begin
module Y; $display("value of a in instance x1 is %d", z1.y1.x1.a );
reg b=1; $display("value of b in instance y1 is %d", z1.y1.b );
X x1(); //instance $display("value of c in instance z1 is %d", z1.c );
endmodule
end
endmodule
module X;
reg a=0;
endmodule

103 gstl.itu.edu.tr
Monitor
• $monitor continuously monitors the values of the variables or signals whereas
$display displays the values exactly once.

//Monitor time and value of the signals clock and


reset
Log:
module tb();
-- 0 Value of signals CLK = 0 RST = 1
wire CNT; -- 5 Value of signals CLK = 1 RST = 1
reg CLK = 0; reg RST = 1; -- 10 Value of signals CLK = 0 RST = 0
counter C1( CNT, CLK, RST );

initial
$monitor($time, " Value of signals clock = %b
reset = %b", CLK,RST);

always #5 CLK = ~CLK;

initial #10 RST = ~RST;


endmodule

104 gstl.itu.edu.tr
Stop and Finish
• $stop suspends the simulation.
• $finish terminates the simulation.

// Stop at time 100 in the simulation and examine the results


// Finish the simulation at time 1000.
initial
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

105 gstl.itu.edu.tr
Timescale
• Verilog simulation depends on how time is defined because the simulator needs
to know what a #1.
• Syntax:
`timescale <reference_time_unit> / <time_precision>

• The time precision specifies how delay values are rounded off. Delays in the
circuit are rounded according to the precision value.

106 gstl.itu.edu.tr
Timescale

• Example:
'timescale 1ns/1ps
'timescale 10us/100ns
'timescale 10ns/1ns

107 gstl.itu.edu.tr
Time and Realtime
• $time and $realtime system functions return the current time of the
simulation.
• $time round offs the time to nearby integer whereas $realtime does not.
So $realtime uses real valued delays and $time integer valued delays.

108 gstl.itu.edu.tr
'timescale 1ns/1ns Log:
module tb;
reg val;
T=1 at time #1
initial T=1 at time #0.49
begin T=2 at time #0.50
val = 0;
#1 $display("T=%t at time #1", $realtime); T=3 at time #0.51

val = 1;
#0.49 $display("T=%t at time #0.49", $realtime); // rounded to the 0ns (precision)

val = 0;
#0.5 $display("T=%t at time #0.50", $realtime); // rounded to the 1ns (precision)

val = 1;
#0.51 $display("T=%t at time #0.51", $realtime); // rounded to the 1ns (precision)

#5 $finish;
end
endmodule

109 gstl.itu.edu.tr
'timescale 10ns/1ns Log:
module tb;
reg val;
T=10 at time #1
initial T=15 at time #0.49
begin T=20 at time #0.50
val = 0;
#1 $display("T=%t at time #1", $realtime); T=25 at time #0.51

val = 1;
#0.49 $display("T=%t at time #0.49", $realtime); // rounded to the 5ns (precision)

val = 0;
#0.5 $display("T=%t at time #0.50", $realtime);

val = 1;
#0.51 $display("T=%t at time #0.51", $realtime); // rounded to the 5ns (precision)

#5 $finish;
end
endmodule

110 gstl.itu.edu.tr
Directives &
Functions

111 gstl.itu.edu.tr
Define Directive - Macros
• The `define directive is used to define text macros.

// Define a size
'define WORD_SIZE 32

// Define a data type


'define WORD_REG reg [31:0]

// Define a function
'define add(A,B) A+B

// define an alias for a system task.


// $stop will be substituted with ’S
'define S $stop;

112 gstl.itu.edu.tr
Define Directive - Macros

'define val 10
'define add(A,B) A+B

module example();

integer var_a, var_b;

var_a = 'val + 45; // val_a = 55


var_b = 'add(var_a, 45); // var_b = 100

endmodule

113 gstl.itu.edu.tr
Define Directive - Macros
• Multiline macros:

'define CALC(VAL1, VAL2, RESULT, EXPR) \


RESULT = VAL1 EXPR VAL2; \
$display("Result is %d, RESULT);

module example();
int a=15, b=7;
int c;

initial
begin
'CALC( a,b,c,+ ); // c = a + b
end
endmodule

114 gstl.itu.edu.tr
Conditional Compilation
• A particular portion of a testbench code can be compiled by using compiler
directives:
• `ifdef, 'ifndef,
• `else, `elsif,`endif

• Conditional compilation can be useful to conditionally output the debug


messages on the terminal or an output file.

115 gstl.itu.edu.tr
Conditional Compilation

module tb;

initial
begin
'ifndef MACRO1
$display("This is for MACRO1");
'elseif MACRO2
$display("This is MACRO2");
'endif
end
endmodule

116 gstl.itu.edu.tr
Conditional Compilation-Instantiation
module top;

bus_master b1(); //instantiate module unconditionally


// b2 is instantiated conditionally if text macro ADD_B2 is defined
'ifdef ADD_B2
bus_master b2();

// b3 is instantiated conditionally if text macro ADD_B3 is defined


'elsif ADD_B3
bus_master b3();
//b4 is instantiate by default
'else
bus_master b4();
'endif

endmodule

117 gstl.itu.edu.tr
Functions
• There can be repetitive pieces of code exist inside a design. In such cases,
functions can be used in order to reduce the amount of code.
• Functions in Verilog are very similar to functions in C.

// Function Definition // ANSI C Style:


function calc_parity; function calc_parity (input [31:0] address);

input [31:0] address; begin


begin //internal register calc_parity.
//internal register calc_parity. calc_parity = ^address;
calc_parity = ^address; // return end
end
endfunction endfunction

118 gstl.itu.edu.tr
Functions
• At least one input argument must be defined for a function.
• There are no output arguments for functions because the implicit register
function_identifer contains the output value.
• We can define an optional range or type specifies the width of the internal
register. The default bit width is 1.
// ANSI C Style: module Parity_check;
function calc_parity (input [31:0] address);
reg [31:0] addr;
begin reg parity;
//internal register calc_parity.
calc_parity = ^address; always @(addr)
end Begin
// function call, 1 bit output
endfunction parity = calc_parity(addr);
end

119 gstl.itu.edu.tr
Automatic (Recursive) Functions
• If a function is called concurrently from two locations, the results are non-deterministic
because both calls operate on the same variable space!
• The keyword automatic can be used to declare a recursive (automatic) function where all
function declarations are allocated dynamically for each recursive calls.
• Each call to an automatic function operates in an independent variable space.
function automatic integer factorial; // output is integer type

input [31:0] oper;


integer i;

begin
if ( oper >= 2 )
// recursive call
factorial = factorial( oper - 1 ) * oper;
else
factorial = 1;
end
endfunction

120 gstl.itu.edu.tr
References
For further information, the following textbook is a good option:
➢Verilog HDL: A Guide to Digital Design and Synthesis, Second Edition, Samir Palnitkar

• Useful online resources about Verilog:


➢ https://www.chipverify.com
➢ https://reference.digilentinc.com/start
➢ https://www.xilinx.com/support/university.html

121 gstl.itu.edu.tr
Thank you for listening!
ITU EMBEDDED SYSTEM DESIGN LABORATORY

122 gstl.itu.edu.tr

You might also like