Verilog HDL Part I
Verilog HDL Part I
• Developed in 1984
B h i l
Behavioral
Gate
Layout
ayou (V
(VLSI)
S)
• Concurrency
• Structure
• Procedural
P d l Statements
St t t
• Time
• /* Multiple line
comment */
<size>’<radix> <value>
Binary
Bi → b or B
No of
Octal → o or O Consecutive chars
bits
Decimal → d or D 0-f, x, z
Hexadecimal → h or H
– 8’h ax = 1010xxxx
– 12
12’o
o 3zx7 = 011zzzxxx111
• Bit extension
– MS bit = 0, x or z ⇒ extend this
• 4’b x1 = 4’b xx_x1
• If size is ommitted it
– is inferred from the value or
– takes the simulation specific number of
bits or
– takes the machine specific number of
bits
• If radix is ommitted too .. decimal is assumed
– 15 = <size>’d 15
wand Y; // declaration
assign
i Y = A
A;
A assign Y = B;
Y
B
wor Y; // declaration
assign Y = A;
assign Y = B;
dr
tri Y; // declaration
A Y
assign Y = (dr) ? A : z;
• Represent buses
wire [
[3:0]
] busA;
reg [1:4] busB;
reg [1:0] busC;
• Left number is MS bit
• Slice management
• Declaration
integer i, k;
real r;
• Use as registers (inside procedures)
i = 1; // assignments occur inside procedure
r = 2.9;
.9;
k = r; // k is rounded to 3
• Integers are not initialized!!
• Reals
R l are iinitialized
iti li d tto 0.0
00
y_time;
time my ;
• Use inside procedure
• Syntax
integer count[1:5]; // 5 integers
reg var[-15:16]; // 32 1-bit regs
reg [7:0] mem[0:1023]; // 1024 8-bit
8 bit regs
• Accessing array elements
– Entire element: mem[10] = 8’b 10101010;
– Element subfield (needs temp
storage):
reg [7:0] temp;
..
temp = mem[10];
var[6] = temp[2];
but C&&B=0
c = ~a; c = a & b;
• a = 4’b1010;
b = 4’b1100;
c = a ^ b;
• a = 4’b1010;
b = 2’b11;
• & → AND
• | → OR
• ^ → XOR
• ~& → NAND
• ~| → NOR
• ~^ or ^~ → XNOR
filled
a = 4’b1010
4’b1010;
...
d = a >> 2; // d = 0010
c = a << 1;
1 // c = 0100
1 > 0 →1
’b1x1 <
<= 0 →x
10 < z →x
• == → logical equality
Return 0, 1 or x
• != → logical inequality
• === → case equality
• !== → case inequality Return 0 or 1
A
1
Y
Y = (sel)? A : B;
B 0
sel
• +, -, *, /, %
• If any operand is x the result is x
• Negative registers:
• Negative integers:
Use parentheses
U th tto
enforce your
priority
Top Level
E.g.
Module
Full Adder
Sub-Module Sub-Module
1 2
module my_module(out1,
my module(out1 .., inN);
f .. // declarations
inN outM .. // description of f (maybe
.. // sequential)
endmodule
assign S = A ^ B;
A S
Half assign C = A & B;
B Adder C
endmodule
d d l
ccin
module full_adder(sum, cout, in1, in2, cin);
output sum, cout;
input in1, in2, cin;
endmodule
FALL2010 ECE301 – VLSI System Design 39
Hierarchical Names
ha2.A
cin
module
• Inputs
I reg or net net
module
module
net net
• Inouts
• Usage:
U
nand (out, in1, in2); 2-input NAND without delay
and #2 (out, in1, in2, in3); 3-input AND with 2 t.u.
d l
delay
not #1 N1(out, in); NOT with 1 t.u. delay and instance
name
xor X1(out in1, in2); 2-input XOR with instance name
X1(out, in1
• Write them inside module, outside procedures
initial
$display(“I’m first”);
Will be displayed
initial begin at sim time 0
#50;
$display(“Really?”);
Will be displayed
end
at sim time 50
endmodule
• wait (expr)
always begin
wait (ctrl)
#10 cnt = cnt + 1;
#10 cnt2 = cnt2 + 2; execution loops every
time ctrl = 1 (level
end
sensitive timing
g control))
d
initial begin
g
#5 c = 1; c
#5 b = 0;
#5 d = c; b
end
0 5 10 15
Time
Each assignment
g is
blocked by its previous one
d
initial begin
g
fork c
#5 c = 1;
#5 b = 0; b
#5 d = c;
join 0 5 10 15
end Time
Assignments are
not blocked here
reg out;
else if (expr2) wire [3:0] in;
wire [1:0] sel;
true_stmt2;
.. always @(in or sel)
if (sel == 0)
else out = in[0];
def_stmt; else if (sel == 1)
out = in[1];
else if (sel == 2)
out = in[2];
else
out = in[3];
endmodule
reg [3:0] Y;
wire start;
integer i;
initial
Y = 0;
E.g.
module count(Y, start);
output [3:0]
[3 0] Y;
input start;
reg [3:0] Y;
wire
i start;
t t
integer i;
while (expr) stmt;
initial
Y = 0
0;
E.g.
module count(Y, start);
output [3:0] Y;
i
input
t start;
t t
initial
Can be either an Y = 0;
integer or a variable
always
l @(
@(posedge
d start)
t t)
repeat (4) #10 Y = Y + 1;
endmodule
Typical example:
clock generation in test modules
module test;
endmodule
reg Y;
wire c, clk, res;
res wire n;
c n Y not(n, c); // gate-level
clk
always @(res or posedge clk)
if (
(res)
)
Y = 0;
else
Y = n;
endmodule
50ns
in[3:0] p_in[3:0]
out[2:0]
A. Implelementation
wu
without parameters
wd
clk module
d l dff2bit(Q
dff2bit(Q, D,
D clk);
lk)
module dff4bit(Q, D, clk); output [1:0] Q;
output [3:0] Q; input [1:0] D;
p
input [
[3:0]] D; input clk;
input clk;
reg [1:0] Q;
reg [3:0] Q; wire [1:0] D;
wire [
[3:0]] D;
; wire clk;
wire clk;
always @(posedge clk)
always @(posedge clk) Q = D;
Q = D;
;
endmodule
endmodule
FALL2010 ECE301 – VLSI System Design 65
Parameters (ii)
module top(out, in, clk);
A. Implelementation output [1:0] out;
without parameters (cont.) input [3:0] in;
input clk;
wire [
[3:0]
] p_
p in; // internal nets
wire wu, wd;
endmodule
FALL2010 ECE301 – VLSI System Design 66
Parameters (iii)
module top(out, in, clk);
B. Implelementation p
output [1:0] out;
input [3:0] in;
with parameters input clk;
wire [1:0] out;
module
d l dff(
dff(Q, D, clk);
lk) wire [3:0] in;
parameter WIDTH = 4; wire clk;
output [WIDTH-1:0] Q; wire [3:0] p_in;
input [WIDTH-1:0] D; wire wu,
, wd;
;
input clk;
assign wu = p_in[3] & p_in[2];
reg [WIDTH-1:0] Q; assign wd = p_in[1] & p_in[0];
wire [WIDTH-1:0] D;
wire clk; dff instA(p
instA(p_in,
in in
in, clk)
clk);
// WIDTH = 4, from declaration
always @(posedge clk) dff instB(out, {wu, wd}, clk);
Q = D; p
defparam instB.WIDTH = 2;
;
// We changed WIDTH for instB only
endmodule
FALL2010 ECE301 –endmodule
VLSI System Design 67
Testing
g Your Modules
module top_test;
wire [
[1:0]
] t_out;; // Top’s
p signals
g
reg [3:0] t_in;
reg clk;
endmodule
FALL2010 ECE301 – VLSI System Design 68