Computer Architecture
Supplements: Introduction to Verilog
Jaewoong Sim
Electrical and Computer Engineering
Seoul National University
• Let’s briefly look at Verilog HDL J
• Hardware Description Languages
• Lexical Conventions in Verilog
• Data Types & Ports
• Module Modeling Levels
• Simulation
• What’s important?
• Wire vs Reg
• Continuous Assignment vs Procedural Assignment vs Procedural Continuous Assignment
• Procedural Assignment
} Blocking vs Non-Blocking Assignment
2
Two common hardware description languages
Verilog
• Developed by Gateway Design Automation in 1984; Gateway was acquired by
Cadence in 1990
• Became an IEEE Standard (IEEE 1364) in 1995
} Verilog-95, Verilog 2001, Verilog 2005 (minor revision), SystemVerilog (Industry)
VHDL (VHSIC-HDL: Very High Speed Integrated Circuit Hardware
Description Language)
• Developed by the US Department of Defense in 1983
• Became an IEEE Standard (1076-1987) in 1987
} Several revisions in 1993/2000/2002/2008
We will use Verilog HDL in this course and labs
3
• Look at other Verilog code examples
• Do write code a lot!
• What prevents us from practicing Verilog?
• Oh.. Testbenches…
• HDLBits
• https://hdlbits.01xz.net/wiki/Main_Page
• Highly recommend solving the problem sets there
• Created by my former colleague Henry Wong
} His Stanford seminar about x86 on FPGA is also interesting!
https://www.youtube.com/watch?v=vhHR6fNHyG8
• Verilog Tutorial & Language Reference Manual
• https://www.chipverify.com/verilog/verilog-tutorial
• Verilog 1364-2005 LRM -- https://ieeexplore.ieee.org/document/1620780
• Online Verilog Simulators
} https://www.tutorialspoint.com/compile_verilog_online.php
} https://www.edaplayground.com/ 4
A module is the main building block in Verilog!
• Every block of hardware with inputs and outputs is a module
• (e.g., AND/OR gates, multiplexer, decoder, …)
Each module consists of
• A core circuit (called internal or body) – performs the required function
• An interface (called ports) – carries out the required communication
between the core circuit and outside
a
y
b
Module
5
module name
input/output ports
module test (input a,
input b,
output y); don’t forget a semicolon here!
module definition
// describe our circuit here!
endmodule
Format
module module_name (module interface list);
[list of interface ports]
...
[net and variable declarations]
Items enclosed in square
...
brackets are optional
[functional specification of module]
...
endmodule
6
• The following two Verilog codes are functionally identical
• Follow the ANSI-C style from now on! (easier to read & reduces typos!)
Old Verilog-95 Style Verilog-2001 ANSI-Style
module test (a, b, y); module test (input a,
input a; input b,
input b; output y);
output y;
// describe our circuit here!
// describe our circuit here!
endmodule endmodule
Old C Style ANSI-C Style
double old_style(a, real) double new_style(int a, double *real)
double *real; {
int a; return (*real + a);
{ }
return (*real + a);
}
7
• Software Programming Languages
• SW code executes statements in program order on given hardware
• Hardware Description Languages
• HDL code is more like a text form that describes a given circuit
module test (input a,
a input b,
x output x,
output y);
y
// describe our circuit here!
b assign x = a;
assign y = b;
Module
endmodule
assign => describes ‘connections’ between things where data flows
from RHS to LHS; not the action of copying from RHS to LHS
8
• Synthesis: HDL Code è Logic Gates & Wires (netlists)
• To map Verilog code onto hardware, the Verilog code must be
synthesizable!
• Not all Verilog constructs are synthesizable!
• https://link.springer.com/content/pdf/bbm%3A978-81-322-2791-5%2F1.pdf
9
Lexical Conventions
10
• Verilog uses almost the same lexical conventions as C language
• Identifiers consists of alphanumeric characters, _, and $
• Verilog is case-sensitive (just like C)
• First character can be a letter, _ or $ (cannot start with numbers)
• ex) counter, four_bit_adder, a, b, _4b_adder
• White space: blank space (\b), tabs (\t), and new line (\n)
• Keywords: some identifiers are reserved in Verilog
• and, assign, begin, case, else, end, nand, nor, not, or, repeat, …
• Comments
• // ç used for single line comments
• /* ….*/ ç used for multi-line comments
11
Number Representation
Format: <size>’<base>value ex) 16’b0101110000001101
• “<>” can be omitted
• size: size in terms of the exact number of bits
• If not given, 32-bit type assumed
• ’: single quote (not backtick)
• base: Binary (b or B), Octal (o or O), Decimal (d or D), Hexadecimal (h or
H)
• If omitted, it defaults to decimal
• value: constant value
• What if the value does not match the given size?
• Size is too small: MSBs are truncated (ex: 4’b11110010 è 4’b0010)
• Size is too large:
} Leftmost '0' or '1' are filled with ‘0’
} Leftmost ’X’ or 'Z' are filled with ‘X’ or ‘Z’, respectively 12
Number Representation
Sized number: <size>’<base>value
• 4’b1001 - a 4-bit binary number
• 16’habcd - a 16-bit hexadecimal number
Unsized number: ’<base>value è 32-bit by default
• 2007 - a 32-bit decimal number by default
• ‘habc - a 32-bit hexadecimal number
Negative number: -<size>’<base>value
• 2’s complement format by default
• -4’b1001 - a 4-bit binary number
• -16’habcd - a 16-bit hexadecimal number
13
Number Representation
• ”_” and “?”
• _ only for readability è 16’b0101_1001_1110_0000
• ? equivalent to z è 8’b01??_11?? = 8’b01zz_11zz
• x and z values: x denotes an unknown value; z denotes a
high impedance value
• Digital logic produces only 0 or 1
• Four-value logic system: 0, 1, x, z
14
Number Representation - Examples
Integer Stored as
1 00000000000000000000000000000001
8'hAA 10101010
6'b10_0011 100011
'hF 00000000000000000000000000001111
6'hCA 001010
6'hA 001010
16'bZ zzzzzzzzzzzzzzzz
8'bx xxxxxxxx
15
Number Representation – Negative Values
module signed_number;
reg [31:0] a;
initial begin
a = 14'h1234;
$display ("Current Value of a = %h", a);
a = -14'h1234;
$display ("Current Value of a = %h", a);
a = 32'hDEAD_BEEF;
$display ("Current Value of a = %h", a);
a = -32'hDEAD_BEEF;
$display ("Current Value of a = %h", a);
#10 $finish;
end
endmodule
Current Value of a = 00001234
Current Value of a = ffffedcc
Current Value of a = deadbeef
Current Value of a = 21524111
16
• Other data types
• String: “Back to School and Have a Nice Semester”
• Real number: 3.4, 294.872, 1.44E(or e)9
} Decimal and scientific notations accepted
} At least one digit on each side of the decimal point
¨ .2 (illegal)
17
Data Types & Ports
18
• 0 and 1 represent logic values low and high, respectively
• z indicates the high-impedance condition of a node or net
• x indicates an unknown value of a net or node
Value Meaning
0 Logic 0, false condition
1 Logic 1, true condition
x Unknown logic value
z High impedance
19
• Nets mean any hardware connection points (cannot store value!)
• Variables represent any data storage elements
• wire and reg are the most commonly used types
Nets Variables
wire supply0 reg
tri supply1 integer
wand tri0 real
wor tri1 time
triand trireg realtime
trior
Verilog’s wire is directional
Verilog’s reg does not necessarily correspond to the physical register!
20
• Nets
• Can be referenced anywhere in a module
• Must be driven by a primitive, continuous assignment, force … release, or
module port
• Variables
• Can be referenced anywhere in a module
• Can be assigned value only within a procedural statement, task, or function
• Cannot be an input or inout port in a module
• Arrays and Vectors
• An array is a collection of objects with the same attributes
• A vector is a one-dimensional array of bit signals
• More on this later
21
• There are three forms of assignments in Verliog
• Continuous Assignments
• Drive a value into a net
• Used to model combinational logic
• (Explicit) Use assign keyword
} wire temp;
assign temp = a | b;
• (Implicit) combine declaration and assignment
} wire temp = a | b;
• Procedural Assignments
• Assign values to variables declared as regs in always blocks/tasks/functions
• Usually used to model registers and FSMs
• Procedural Continuous Assignments
• Assign & Deassign: Override all procedural assignments to a variable
22
• Ports connect a module to the outside world
Module
net or var net net or var net
net
input port output port
net inout port
• input [net_type] [signed] [range] list_of_names;
• inout [net_type] [signed] [range] list_of_names;
• output [net_type or var_type] [signed] [range] list_of_names;
• Ports are by default considered as nets of type wire
• Ports are by default unsigned
23
• Port connection by ordered list (not recommended unless necessary)
• port_expr1, …, port_expn
• Port connection by name (recommended)
• .port_id1(port_expr1),
.port_id2(port_expr2), …
• The order is irrelevant
• It is recommended to put each port connection in a separate line
• Each port_expr can be
• Identifier (a net or a variable)
• Bit-select or part-select of a vector
• Concatenation of the above
• Expression for input ports
• Unconnected/Floating ports: inputs are driven to z, outputs are floating
24
module half_adder (x, y, s, c);
input x, y;
output s, c;
// -- half adder body-- //
// instantiate primitive gates
xor xor1 (s, x, y); Can only be connected by using positional association
and and1 (c, x, y);
endmodule
Instance name is optional
module full_adder (x, y, cin, s, cout);
input x, y, cin;
output s, cout;
wire s1,c1,c2; // outputs of both half adders
// -- full adder body-- // Connecting by using positional association
// instantiate the half adder
half_adder ha_1 (x, y, s1, c1); Connecting by using named association
half_adder ha_2 (.x(cin), .y(s1), .s(s), .c(c2));
or (cout, c1, c2);
Instance name is necessary
endmodule
25
Similar to the ones in
C language
26
Module Modeling Levels
• Structural Modeling
• Dataflow Modeling
• Behavioral Modeling
27
• Structural Level
• Gate level description of the circuit
• Connect built-in primitives, user-defined primitives, or other modules using
wires
• Describe a hierarchy
• Dataflow Level
• Describe hardware in terms of dataflow from inputs to outputs
• Use operators (+, -, &, |, …) that act on operands
• Use continuous assignment statements (keyword assign)
• Behavioral Level
• Typically used for sequential logic (but it can be used for combinational logic)
• Use procedural statements (keyword always)
• The target in procedural assignment statements must be a reg type
28
• Mixed Level
• Mix use of above three modeling levels
• Commonly used in modeling large designs
• In industry, RTL (register-transfer level) means
• RTL = synthesizable behavioral + dataflow constructs
29
// gate-level description of half adder
module half_adder(input x,
• Half Adder: S = X⨁Y, C = XY input y,
output s,
X Y SUM CARRY output c);
0 0 0 0 // half adder body
// instantiate primitive gates
0 1 1 0 xor (s, x, y);
1 0 1 0 and (c, x, y);
1 1 0 1 endmodule
pre-defined in Verilog
// gate-level description of full adder
• Full Adder module full_adder(input x,
input y,
input c_in,
Full Adder output sum,
output c_out);
c_in sum // internal nodes
Half // outputs of both half adders
Adder wire s1, c1, c2;
x s1 c2
c_out // full adder body
Half
// instantiate the half adder
y Adder c1 half_adder ha_1 (x, y, s1, c1);
half_adder ha_2 (c_in, s1, sum, c2);
or (c_out, c1, c2);
endmodule 30
• combinational logic
module full_adder_dataflow(input x,
input y,
input c_in,
output sum,
output c_out);
// specify the function of a full adder
assign #5 {c_out, sum} = x + y + c_in;
continuous assignment endmodule
continuously driven
by something
Full Adder
c_in sum
Half
x s1 Adder c2 - Use operators to compute sum and c_out
c_out
Half - Use continuous assignment to drive
y Adder c1 values onto nets
31
• sequential & combinational logic
always block
Whenever the event in the sensitivity list occurs,
the always block is activated
module full_adder_behavioral(input x,
input y,
input c_in,
output reg sum,
output reg c_out);
// specify the function of a full adder
// can also use always @(*) or always@(x or y or c_in)
always @(x, y, c_in)
#5 {c_out, sum} = x + y + c_in;
endmodule
32
module full_adder_mixed_style(input x,
input y,
input c_in,
output sum,
output reg c_out);
wire s1, c1, c2;
// structural modeling of HA 1.
xor xor_ha1(s1, x, y);
and and_ha1(c1, x, y);
// dataflow modeling of HA 2.
assign sum = c_in ^ s1;
assign c2 = c_in & s1;
// behavioral modeling of output OR gate.
always @(c1, c2) // can also use always @(*)
c_out = c1 | c2;
Full Adder endmodule
c_in sum
Half
Adder
x s1 2 c2
Half c_out
Adder
y c1
1
33
Verilog Simulation
34
• Use a separate testbench for simulation
Stimulus Block
Stimulus
Module Under Test
Response
Top-Level Block
Stimulus
Stimulus Block Module Under Test
Response
35
• $display displays values of variables, string, or expressions
• $display(ep1, ep2, …, epn);
• ep1, ep2, …, epn: quoted strings, variables, expressions
• $monitor monitors signals when their values change
• $monitor(ep1, ep2, …, epn);
• $monitoton enables monitoring operation
• $monitotoff disables monitoring operation
• $stop suspends the simulation
• $finish terminates the simulation
36
• Time scale compiler directive:
`timescale time_unit / time_precision
• The time_precision must not exceed the time_unit
• For instance, with a timescale 1ns/1ps, the delay specification #15
corresponds to 15ns
• It uses the same time unit in both behavioral and gate-level
modeling
• For FPGA designs, it is suggested to use ns as the time unit
37
Clock Generation
• [delay] statement;
module tb;
reg clk;
// clock generation
// starts at time 0ns and loops after every 5ns
always #5 clk = ~clk;
// initial block : process starts at time 0ns
initial begin
// Print out the signal values whenever they change
$monitor("Time = %0t clk = %0d", $time, clk);
#5 clk = 0; // assign clk to 0 at time 5ns
#80 $finish; // finish simulation at time 85ns
end
endmodule
38
/**
* SNU ECE Digital Systems Design
* encoder4to2.v: encoder4to2 module
*
* 4 to 2 encoder: (Y3, Y2, Y1, Y0) => (A1, A0)
*
* (1, 0, 0, 0) => 3
* (0, 1, 0, 0) => 2
/** * (0, 0, 1, 0) => 1
* SNU ECE Digital Systems Design * (0, 0, 0, 1) => 0
* encoder4to2_tb.v: encoder4to2 testbench * everything else => 0
*/
*/
// note that the default port type is 'wire'
// compiler directive module encoder4to2(
// time unit: 1ns & precision: 100ps input Y0,
input Y1,
`timescale 1ns / 100ps input Y2,
input Y3,
module encoder4to2_tb; output reg [1:0] A
reg [3:0] din; );
…
wire [1:0] dout;
endmodule
// instantiate the encoder4to2 module
// look at how to map internal & external ports
encoder4to2 encoder(
.Y0(din[0]), .Y1(din[1]), .Y2(din[2]), .Y3(din[3]), .A(dout)
);
initial begin
$monitor("Time = %0t din = %0b dout = %0b", $realtime, din, dout);
#5 din = 4'b1000; // assign din to b1000 at time 5ns
#10 din = 4'b0100; // assign din to b0100 at time 15ns
#20 din = 4'b0010; // assign din to b0010 at time 35ns
#15 din = 4'b0001; // assign din to b0001 at time 50ns
#1 din = 4'b1000; // assign din to b0001 at time 51ns
// advance by 0.5 time unit
#0.5 din = 4'b0100; // assign din to b1000 at time 51.5ns
// advance by 0.15 time unit
// 51.65ns; this gets rounded to 51.7ns
#0.15 din = 4'b0010; // assign din to b1000 at time 51.7ns (100 ps resolution)
#10 $finish; // finish simulation at time 61.7ns
end
endmodule 39
Time = 0 din = xxxx dout = xx
Time = 5000 din = 1000 dout = 11
Time = 15000 din = 100 dout = 10
Time = 35000 din = 10 dout = 1
Time = 50000 din = 1 dout = 0
Time = 51000 din = 1000 dout = 11
Time = 51500 din = 100 dout = 10
Time = 51700 din = 10 dout = 1
$finish called at time : 61700 ps : File "Z:/code/lab1/encoder4to2_tb.v" Line 34
40
Computer Architecture
Supplements: Introduction to Verilog
Jaewoong Sim
Electrical and Computer Engineering
Seoul National University