Verilog HDL 2022

Download as pdf or txt
Download as pdf or txt
You are on page 1of 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