Introduction To Verilog Hardware Description Language
Introduction To Verilog Hardware Description Language
Introduction To Verilog Hardware Description Language
2
The best way to describe a circuit?
4
helloWorld.v
Input
Circuit
X Wire
Y Output
Z
O
05/25/12 6
Module declaration
Module
Input
Circuit
X Wire
Y Output
Z
O
Module name
input X,Y,Z;
output O;
05/25/12 endmodule 7
Typical Module Components
Diagram
Module name, Port list (optional, if there are ports)
Port declarations
Parameter list
endmodule declaration
Lexicography
• Comments:
Two Types:
• // Comment
• /* These comments extend
over multiple lines. Good
for commenting out code */
• Character Set:
0123456789ABCD..YZabcd...yz_$
Cannot start with a number or $
9
systemCalls.v
module systemCalls(clk);
input clk;
clockGenerator cg(clk);
Compile with the clockGenerator.v module.
initial
begin
Suspends simulation – enters interactive mode.
#25 $stop;
#50 $finish;
end
Terminates simulation.
initial
begin
Similar output calls except
$write("$write does not "); $display adds a new line.
$write("add a new line\n");
$display("$display does");
$display("add a new line");
$monitor produces output
each time a variable changes
$monitor("Clock = %d", cg.clk); end value.
endmodule
Data Types
• Nets and Registers
• Vectors
• Integer, Real, and Time Register Data Types
• Arrays
• Memories
• Parameters
• Strings
count[5]
chk_point[100]
port_id[3]
• Note the difference between vectors and arrays
19 2005 Verilog HDL
Memories
• RAM, ROM, and register-files used many times in digital
systems
• Memory = array of registers in Verilog
• Word = an element of the array
Can be one or more bits
• Examples:
reg membit[0:1023];
reg [7:0] membyte[0:1023];
membyte[511]
• Note the difference (as in arrays):
reg membit[0:127];
reg [0:127] register;
21
4valuedLogic.v
module fourValues( a , b, c, d );
output a, b, c, d ;
Conflict or race
condition.
assign a = 1; Remember this is
assign b = 0; not a procedural
assign c = a; (i.e., sequential)
assign c = b; block! These are 4-valued logic:
endmodule continuous assign- 0 – low
ments. 1 – high
module stimulus; x – unknown
fourValues X(a, b, c, d); z – undriven wire
Now explain output!
initial
begin
#1 $display("a = %d b = %d, c = %d, d = %d", a, b, c, d);
$finish;
end
endmodule
Data Values
• Numbers:
Numbers are defined by number of • Parameters:
bits
Value of 23: parameter n=4;
5’b10111 // Binary
wire [n-1:0] t, d;
5’d23 // Decimal
5’h17 // Hex
`define Reset_state = 0, state_B =1,
• Constants: Run_state =2, finish_state = 3;
wire [3:0] t,d; if(state==`Run_state)
assign t = 23;
assign d= 4’b0111;
23
numbers.v
module numbers;
integer i, j; Register array.
reg[3:0] x, y;
y = 4'd7;
$display( "decimal y = %d, binary y = %b", y, y );
$display( "octal y = %o, hex y = %h", y, y );
25
Operators
module sample (a, b, c, d);
• Reduction Operators:
input [2:0] a, b;
Unary operations returns single-bit values
output [2;0] c, d;
• & : and
wire z,y;
• | :or
• ~& : nand
assign z = ~| a;
• ~| : nor
c = a * b;
• ^ : xor
If(a==b) d = 1; else d =0;
• ~^ :xnor
• Shift Operators d = a ~^ b;
Shift Left: <<
Shift right: >> if ((a>=b) && (z)) y=1;
• Concatenation Operator else y = !x;
{ } (concatenation)
{ n{item} } (n fold replication of an item) assign d << 2; //shift left twice
• Conditional Operator assign {carry, d} = a + b;
assign c = {2{carry},2{1’b0}};
Implements if-then-else statement
// c = {carry,carry,0,0}
(cond) ? (result if cond true) : (result if cond false)
assign c= (inc==2)? a+1:a-1;
26
clockGenerator.v
Port list. Ports can be of three types: input,
output, inout. Each must be declared.
module clockGenerator(clk);
output clk; Internal register.
reg clk;
Register reg data type can have one of
four values: 0, 1, x, z. Registers store a
initial
value till the next assignment. Registers
begin are assigned values in procedural blocks.
clk = 0;
end If this module is run stand-alone make
sure to add a $finish statement here or
always simulation will never complete!
#5 clk = ~clk;
endmodule
The delay is half the clock period.
Verilog Structure
• Modules cannot be A2
contained
module in another
two_gates(Z2,A2,B2,C2) C2
input A2,B2,C2; B2
module
output Z2;
gate gate_1(G2,A2,B2,C2); Z
B2
gate gate_2(Z2,G2,A2,B2); A2
endmodule
28
Structural Vs Procedural
Structural Procedural
• textual description of circuit • Think like C code
• order does not matter
• Order of statements are
• Starts with assign important
statements • Starts with initial or always
statement
• Harder to code
• Need to work out logic • Easy to code
• Can use case, if, for
reg c, d;
always@ (a or b or c)
wire c, d;
begin
assign c =a & b;
c =a & b;
assign d = c |b;
d = c |b;
end 29
Structural Vs Procedural
Procedural Structural
reg [3:0] Q;
wire [3:0]Q;
wire [1:0] y;
wire [1:0]y;
always@(y)
begin assign
Q=4’b0000; Q[0]=(~y[1])&(~y[0]),
case(y) begin Q[1]=(~y[1])&y[0],
2’b00: Q[0]=1; Q[2]=y[1]&(~y[0]),
2’b01: Q[1]=1;
Q[3]=y[1]&y[0];
2’b10: Q[2]=1;
2’b11: Q[3]=1;
endcase Q[0]
end
Q[1]
30
Blocking Vs Non-Blocking
Blocking Non-blocking
<variable> = <statement> <variable> <= <statement>
32
blockingVSnba1.v
module blockingVSnba1;
integer i, j, k, l;
initial
begin Blocking (procedural) assignment: the whole statement
must execute before control is released, as in traditional
#1 i = 3;
programming languages.
#1 i = i + 1;
j = i +1;
#1 $display( "i = %d, j = %d", i, j );
Non-blocking (procedural) assignment: all the RHSs for the
#1 i = 3; current time instant are evaluated (and stored transparently
#1 i <= i + 1; in temporaries) first and, subsequently, the LHSs are updated
j <= i + 1; at the end of the time instant.
#1 $display( "i = %d, j = %d", i, j );
$finish;
end
endmodule
blockingVSnba2.v
module blockingVSnba2(clk);
input clk; Compile with clockGenerator.v.
clockGenerator cg(clk);
integer i, j; An application of non-blocking assignments
to solve a race problem.
initial
begin
i = 10;
#50 $finish; With blocking assignments we get different output
depending on the order these two statements are
end
executed by the simulator, though they are both
supposed to execute “simultaneously” at posedge clk
always @(posedge clk) - race problem.
i = i + 1; // i <= i + 1;
always @(posedge clk) Race problem is solved if the non-blocking
j = i; // j <= i; assignments (after the comments) are used instead
- output is unique.
always @(negedge clk)
$display("i = %d, j = %d", i, j);
endmodule
blockingVSnba3.v
The most important application of
module blockingVSnba3; non-blocking assignments is to
reg[7:0] dataBuf, dataCache, instrBuf, instrCache; model concurrency in hardware
systems at the behavioral level.
initial
begin
dataCache = 8'b11010011; Both loads from dataCache to dataBuf and
instrCache = 8'b10010010; instrCache to instrBuf happen concurrently
in the 20-21 clock cycle.
#20;
$display("Time = %d, dataBuf = %b, instrBuf = %b", $time, dataBuf, instrBuf);
dataBuf <= #1 dataCache;
instrBuf <= #1 instrCache;
#1 $display("Time = %d, dataBuf = %b, instrBuf = %b", $time, dataBuf, instrBuf);
2005 37
Verilog HDL
System Tasks (cont’d)
• $display: displays values of variables, strings, expressions.
Syntax: $display(p1, p2, p3, …, pn);
p1,…, pn can be quoted string, variable, or expression
Adds a new-line after displaying pn by default
Format specifiers:
%d, %b, %h, %o: display variable respectively in decimal, binary, hex,
octal
%c, %s: display character, string
%e, %f, %g: display real variable in scientific, decimal, or whichever
smaller notation
%v: display strength
%t: display in current time format
%m: display hierarchical name of this module
2005 38
Verilog HDL
System Tasks (cont’d)
• $display examples:
$display(“Hello Verilog World!”);
Output: Hello Verilog World!
$display($time);
Output: 230
2005 39
Verilog HDL
System Tasks (cont’d)
• reg [4:0] port_id;
• $display(“ID of the port is %b”, port_id);
Output: ID of the port is 00101
2005 40
Verilog HDL
System Tasks (cont’d)
• $monitor: monitors a signal when its value changes
• Syntax: $monitor(p1, p2, p3, …, pn);
p1,…, pn can be quoted string, variable, or signal names
Format specifiers just as $display
Continuously monitors the values of the specified variables or
signals, and displays the entire list whenever any of them
changes.
$monitor needs to be invoked only once (unlike $display)
Only one $monitor (the latest one) can be active at any time
$monitoroff to temporarily turn off monitoring
$monitoron to turn monitoring on again
2005 41
Verilog HDL
System Tasks (cont’d)
• $monitor Examples:
initial
begin
$monitor($time, “Value of signals clock=%b, reset=
%b”, clock, reset);
end
Output:
0 value of signals clock=0, reset=1
5 value of signals clock=1, reset=1
10 value of signals clock=0, reset=0
2005 42
Verilog HDL
System Tasks (cont’d)
• $stop: stops simulation
Simulation enters interactive mode when reaching a $stop system
task
Most useful for debugging
• $finish: terminates simulation
• Examples:
initial
begin
clock=0;
reset=1;
#100 $stop;
#900 $finish;
end
2005 43
Verilog HDL
Compiler Directives
• General syntax:
`<keyword>
• `define: similar to #define in C, used to define
macros
• `<macro_name> to use the macro defined by
`define
• Examples:
`define WORD_SIZE 32
`define S $stop
2005 45
Verilog HDL
Behavior Modeling
simpleBehavioral.v
Sensitivity trigger: when any of a, b or c changes.
Replace this statement with “initial”. Output?!
if (expression)
begin
...statements...
end
else if (expression)
begin
...statements...
end
...more else if blocks
else
begin
...statements...
end
50
Case Statements
Syntax
case (expression)
case_choice1:
begin
...statements...
end
case_choice2:
begin
...statements...
end
default:
begin
...statements...
end
endcase
51
For loops
Syntax
52
Component Inference
Flip-Flops
always@(posedge clk)
begin
a<=b;
a<=b&c;
end
C B D
B
Q A
clk CLK
54
D Flip-Flop with Asynchronous Reset
always@(posedge clk or negedge rst)
begin rst
if (!rst) a<=0;
clr
else a<=b; B D
end Q A
clk CLK
55
D Flip-flop with Synchronous reset and
Enable
always@(posedge clk)
begin
if (rst) a<=0; rst D
B
else if (enable) a<=b;
enable EN Q A
end
clk CLK
56
Shift Registers
reg[3:0] Q;
always@(posedge clk or
posedge rset )
begin
if (rset) Q<=0;
else begin
D Q D Q D Q D Q
Q <=Q << 1;
Q[0]<=Q[3]; CLK CLK CLK CLK
end clk
57
Multiplexers
Method 1
assign a = (select ? b : c);
Method 2 c 0
always@(select or b or c) begin
if(select) a=b;
b 1 a
else a=c;
end SL
Method 2b
case(select)
1’b1: a=b; select
1’b0: a=c;
endcase 58
Counters
reg [7:0] count;
wire enable;
rst
always@(posedge clk or negedge rst) clr
enable EN
begin
if (rst) count<=0;
else if (enable)
count
count<=count+1;
end
59
Step by Step
4-bit adder
4-bit Adder
• Step 1: build a 1-bit full adder as a module
S = (a) XOR (b) XOR (Cin ) ; ( S = a^b^Cin)
Cout = (a&b) |(Cin&(a+b))
module FA_1bit (S,Cout,a,b,Cin);
begin
input a,b,Cin;
Output S, Cout;
endmodule
61
4-bit Adder
• Step 2: initiate 4 instances of FA_1bit module
B3 A3 A B A B2 A2 B1 1 0 0
S3 S2 S1 S0
module FA_4bits (S,Cout,A,B,Cin); The inputs and the output are
begin
input [3:0] A, B;
4-bits wide
input Cin; we need wires to propagate
output [3:0] S;
output Cout
the carry from one stage to
wire Cout0, Cout1, Cout2 the next
Write a test_bench to
A[3:0] 4
initial
Integer data type: other types are
begin time, real and realtime (same as real).
i = 0;
j = 3;
$display( "i = %d, j = %d", i, j ); One initial procedural block.
$finish;
end
endmodule
blocksTime2.v
module blocksTime2;
integer i, j;
initial
begin Important Verilog is a discrete event simulator:
#2 i = 0; events are executed in a time-ordered queue.
#5 j = i;
$display( "time = %d, i = %d, j = %d", $time, i, j );
end
initial
begin
#3 i = 2;
#2 j = i;
$display( "time = %d, i = %d, j = %d", $time, i, j ); Multiple initial blocks.
#1 j = 8; Predict output before
$display( "time = %d, i = %d, j = %d", $time, i, j ); you run!
end
initial
#10 $finish;
endmodule
blocksTime4.v
module blocksTime4;
integer i, j;
initial
Always block is an infinite loop. Following are same:
begin
i = 0; always initial initial
j = 3; begin begin begin
end … while(1) forever
end begin begin
initial … …
#10 $finish; end end
end end
always
begin
#1 Comment out this delay.
i = i + 1; Run. Explain the problem!
j = j + 1;
$display( "i = %d, j = %d", i, j );
end
endmodule
clockGenerator.v
Port list. Ports can be of three types: input,
output, inout. Each must be declared.
module clockGenerator(clk);
output clk; Internal register.
reg clk;
Register reg data type can have one of
four values: 0, 1, x, z. Registers store a
initial
value till the next assignment. Registers
begin are assigned values in procedural blocks.
clk = 0;
end If this module is run stand-alone make
sure to add a $finish statement here or
always simulation will never complete!
#5 clk = ~clk;
endmodule
The delay is half the clock period.
useClock.v
initial
#50 $finish; Event trigger.
initial
begin
i = 0;
j = 5; Comment out the delay.
end Run. Explain what happens!
initial
#10 $finish;
endmodule
blocksTime6.v
module blocksTime6;
integer i, j; Intra-assignment delay: RHS is computed and
stored in a temporary (transparent to user) and
initial LHS is assigned the temporary after the delay.
begin
#2 i = 0;
j = #5 i;
$display( "time = %d, i = %d, j = %d", $time, i, j );
end
initial
#3 i = 2; Compare output with blocksTime2.v.
initial
#10 $finish;
endmodule
simpleDataflow.v
not(q, b);
Wire data type can have one of four values: 0, 1, x, z.
or(p, a, q); Wires cannot store values – they are continuously
or(d, p, c); driven.
endmodule
or (out, w, x, y, z);
endmodule
multiplexor4_1Stimulus.v
(Folder Multiplexor)
module muxstimulus;
Stimulus code that generates
reg IN1, IN2, IN3, IN4, CNTRL1, CNTRL2; test vectors.
wire OUT;
initial
begin
IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0;
$display("Initial arbitrary values");
#0 $display("input1 = %b, input2 = %b, input3 = %b, input4 = %b\n",
IN1, IN2, IN3, IN4);
Concatenation.
{CNTRL1, CNTRL2} = 2'b00;
#1 $display("cntrl1=%b, cntrl2=%b, output is %b", CNTRL1, CNTRL2, OUT);
multiplexor4_1Stimulus.v (cont.)
assign out = (in1 & ~cntrl1 & ~cntrl2) | RTL (dataflow) code using
continuous assignments rather
(in2 & ~cntrl1 & cntrl2) | than a gate list.
(in3 & cntrl1 & ~cntrl2) |
(in4 & cntrl1 & cntrl2);
endmodule
multiplexor4_1Conditional.v
(Folder Multiplexor)
module multiplexor4_1(out, in1, in2, in3, in4, cntrl1, cntrl2);
output out;
input in1, in2, in3, in4, cntrl1, cntrl2;
Input Output
D7 D6 D5 D4 D3 D2 D1 D0 A2 A1 A0
0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 1 0 0 0 1 0
0 0 0 0 1 0 0 0 0 1 1
0 0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 1 0 1
0 1 0 0 0 0 0 0 1 1 0
1 0 0 0 0 0 0 0 1 1 1
8-to-3 encoder (Folder Encoder)
Following are four different Verilog implementations of the same encoder.
Each has its own stimulus module.
encoder8_3Behavioral.v
module encoder8_3( encoder_out , enable, encoder_in );
output[2:0] encoder_out;
input enable; Sensitivity list.
input[7:0] encoder_in;
reg[2:0] encoder_out;
always @ (enable or encoder_in) Simple behavioral code using the
begin case statement.
if (enable)
case ( encoder_in )
8'b00000001 : encoder_out = 3'b000;
8'b00000010 : encoder_out = 3'b001;
8'b00000100 : encoder_out = 3'b010;
8'b00001000 : encoder_out = 3'b011;
8'b00010000 : encoder_out = 3'b100;
8'b00100000 : encoder_out = 3'b101;
8'b01000000 : encoder_out = 3'b110;
8'b10000000 : encoder_out = 3'b111;
default : $display("Check input bits.");
endcase
end
endmodule
encoder8_3BehavioralStimulus.v
module stimulus;
wire[2:0] encoder_out;
reg enable; Stimulus for the behavioral code.
reg[7:0] encoder_in;
encoder8_3 enc( encoder_out, enable, encoder_in );
initial
begin
enable = 1; encoder_in = 8'b00000010;
#1 $display("enable = %b, encoder_in = %b, encoder_out = %b",
enable, encoder_in, encoder_out);
Remove this delay. #1 enable = 0; encoder_in = 8'b00000001;
Run. Explain! #1 $display("enable = %b, encoder_in = %b, encoder_out = %b",
enable, encoder_in, encoder_out);
#1 enable = 1; encoder_in = 8'b00000001;
#1 $display("enable = %b, encoder_in = %b, encoder_out = %b",
enable, encoder_in, encoder_out);
#1 $finish;
end
endmodule
8-to-3 encoder logic equations
A0 = D1 + D3 + D5 + D7
A1 = D2 + D3 + D6 + D7
A2 = D4 + D5 + D6 + D7
encoder8_3structural.v
(Folder Encoder)
initial
begin
encoder_in = 8'b00000010;
#1 $display("encoder_in = %b, encoder_out = %b", encoder_in, encoder_out);
#1 encoder_in = 8'b00000001;
#1 $display("encoder_in = %b, encoder_out = %b", encoder_in, encoder_out);
#1 $finish;
end
endmodule
encoder8_3Mixed.v
module encoder8_3( encoder_out , enable, encoder_in );
output[2:0] encoder_out;
input enable; Mixed structural-behavioral code. Goal was
input[7:0] encoder_in; to modify structural code to have an enable
reg[2:0] encoder_out; wire, which requires register output for
storage.
wire b0, b1, b2;
initial
begin
Output is puzzling! Explain!
enable = 1; encoder_in = 8'b00000010;
#1 $display("enable = %b, encoder_in = %b, encoder_out = %b",
enable, encoder_in, encoder_out);
#1 $finish;
end
endmodule
Comparator modules scheme
comparator.v
Parameters that may be set Comparator makes the comparison A ? B
when the module is instantiated. where ? Is determined by the input
greaterNotLess and returns true(1) or false(0).
endmodule
stimulus.v
Stimulus for the comparator.
module system;
wire greaterNotLess; // sense of comparison
wire [15:0] A, B; // comparand values - 16 bit
wire result; // comparison result
// Module instances
comparator #(16, 2) comp (result, A, B, greaterNotLess);
testGenerator tg (A, B, greaterNotLess, result);
endmodule
Parameters being set at module instantiation.
testGen.v
module testGenerator (A, B, greaterNotLess, result);
output [15:0] A, B;
output greaterNotLess; Module that generates test vectors for
input result; the comparator and checks correctness
parameter del = 5; of output.
reg [15:0] A, B;
reg greaterNotLess;
task check;
input shouldBe; Task definition: a task is exactly like a procedure
in a conventional programming language.
begin
if (result != shouldBe)
$display("Error! %d %s %d, result = %b", A, greaterNotLess?">":"<",
B, result);
end
endtask
101
Example
module myFSM (clk, x, z) // NEXT STATE CALCULATIONS
input clk, x; always @(state or x)
output z; begin
// state flip-flops case (state)
reg [2:0] state, nxt_st; S0: if(x) nxt_st=S1;
// state definition else nxt_st=S0;
S1: if(x) nxt_st=S3;
parameter
S0=0,S1=1,S2=2,S3=3,S7=7 else nxt_st=S2;
S2: if(x) nxt_st=S0;
else nxt_st=S7;
// REGISTER DEFINITION S3: if(x) nxt_st=S2;
always @(posedge clk) else nxt_st=S7;
begin S7: nxt_st=S0;
state<=nxt_st; default: nxt_st = S0;
end endcase
end
// OUTPUTCALCULATIONS
assign z = (state==S7); endmodule
102
0111 Sequence Detector
1
1 S0 0
z=0
S4 0 S1 0
z=1 z=0
0
1 0 1
S3 S2
z=0 z=0
103
Test Benches
System tasks
• Used to generate input and output during simulation. Start
with $ sign.
• Display Selected Variables:
$display (“format_string”,par_1,par_2,...);
$monitor(“format_string”,par_1,par_2,...);
Example: $display(“Output z: %b”, z);
• Writing to a File:
$fopen, $fdisplay, $fmonitor and $fwrite
• Random number generator: $random (seed)
• Query current simulation time: $time
105
Test Benches
Overview Approach
106
Example
‘timescale1 ns /100 ps
// timeunit =1ns; precision=1/10ns; /****SPECIFY THE INPUT WAVEFORM x ****/
module my_fsm_tb; Initial begin
reg clk, rst, x; #1 x=0;
wire z; #400 x=1;
$display(“Output z: %b”, z);
/**** DESIGN TO SIMULATE (my_fsm) #100 x=0;
INSTANTIATION ****/ @(posedge clk) x=1;
myfsm dut1(clk, rst, x, z);
#1000 $finish; //stop simulation
/****RESET AND CLOCK SECTION****/ //without this, it will not stop
Initial end
begin endmodule
clk=0;
rst=0;
#1rst=1; /*The delay gives rst a posedge for sure.*/
#200 rst=0; //Deactivate reset after two clock cycles
+1ns*/
end
always #50clk=~clk; /* 10MHz clock (50*1ns*2) with
50% duty-cycle */
107
Modelsim Demonstration