Digital Design with the Verilog HDL
Chapter 3: Hierarchy & Simulation
Binh Tran-Thanh
Department of Computer Engineering
Faculty of Computer Science and Engineering
Ho Chi Minh City University of Technology
January 5, 2022
1 / 34
Module Port List
Multiple ways to declare the ports of a module.
module Add_half(c_out, sum, a, b);
output sum, c_out;
input a, b;
endmodule
module Add_half(output c_out, sum, input a, b);
endmodule
2 / 34
Module Port List
Multiple ways to declare the ports of a module.
module xor_8bit(out, a, b);
output[7:0] out;
input[7:0] a, b;
endmodule
module xor_8bit(output[7:0] out, input[7:0] a, b);
endmodule
3 / 34
Structural Design Tip
If a design is complex, draw a block diagram!
Label the signals connecting the blocks
Label ports on blocks if not primitives/obvious.
Easier to double-check your code!
Don’t bother with 300-gate design ...
But if that big, probably should use hierarchy!
4 / 34
Example: Hierarchy Multiplexer
mux_8_to_1(output out,
input in0, in1, in2, in3, in4, in5, in6, in7,
input[2:0] select);
5 / 34
Example: Hierarchy Multiplexer
module mux_2_to_1(output out,
input in0, in1,
input select);
wire n0, n1, n2;
endmodule
6 / 34
Interface: Hierarchical Multiplexer
module mux_8_to_1(output out,
input in0, in1, in2, in3, in4, in5, in6, in7,
input[2:0] select);
wire n0, n1, n2, n3, n4, n5;
endmodule
7 / 34
Timing Controls For Simulation
Can put “delays” in a Verilog design
Gates, wires, even behavioral statements!
SIMULATION
Used to approximate “real” operation while simulating.
Used to control testbench
SYNTHESIS
Synthesis tool IGNORES these timing controls
Cannot tell a gate to wait 1.5 nanoseconds!
Delay is a result of physical properties!
Only timing (easily) controlled is on clock-cycle basis
Can tell synthesizer to attempt to meet cycle-time restriction
8 / 34
Zero Delay vs. Unit Delay
When no timing controls specified: zero delay
Unrealistic –even electrons take time to move
OUT is updated same time A and/or B change:
and (OUT, A, B)
Unit delay often used
Not accurate either, but closer...
“Depth” of circuit does affect speed!
Easier to see how changes propagate through circuit
OUT is updated 1 “unit” after A and/or B change:
and #1 A0(OUT, A, B);
9 / 34
Zero/Unit Delay Example
Zero Delay Unit Delay
A
T A B C Y Z
T A B C Y Z 0 0 1 0 x x B
0 0 0 0 0 0 1 0 1 0 0 x Z
1 0 0 1 0 0 2 0 1 0 0 0 C
Y
2 0 1 0 0 0 3 0 1 1 0 0
3 0 1 1 1 1 4 0 1 1 1 0 Zero Delay: Y and Z
4 1 0 0 0 1 5 0 1 1 1 1 change at same
5 1 0 1 0 1 6 1 0 0 1 1 “time” as A, B, and
6 1 1 0 0 1 7 1 0 0 0 1
7 1 1 1 1 1 8 1 1 1 0 1
C!
8 0 0 0 0 0 9 1 1 1 1 1 Unit Delay: Y
9 0 0 1 0 0 10 1 0 0 1 1 changes 1 unit after
10 0 1 0 0 0 11 1 0 0 0 1
11 0 1 1 1 1 12 0 1 0 0 1
B, C
12 1 0 0 0 1 13 0 1 0 0 0 Unit Delay: Z
13 1 0 1 0 1 14 0 1 1 0 0 changes 1 unit after
14 1 1 0 0 1 15 0 1 1 1 0
15 1 1 1 0 1 A, Y
16 0 1 1 1 1
10 / 34
Types Of Delays
Inertial Delay (Gates)
Suppresses pulses shorter than delay amount
In reality, gates need to have inputs held a certain time before output is
accurate
This models that behavior
Transport Delay (Nets)
“Time of flight” from source to sink
Short pulses transmitted
Not critical for most of class
May need to know when debugging
Good to know for building very accurate simulation
11 / 34
Delay Examples
wire #5 net_1; // 5 units transport delay
and #4 (z_out, x_in, y_in); // 4 units inertial delay
assign #3 z_out= a & b; // 3 units inertial delay
wire #2 z_out; // 2 units transport delay
and #3 (z_out, x_in, y_in); // 3 for gate, 2 for wire
wire #3 c; // 3 units transport delay
assign #5 c = a & b; // 5 for assign, 3 for wire
12 / 34
Delays In Testbenches
Most common use in class
Single testbench tests many possibilities
Need to examine each case separately
Spread them out over “time”
Use to generate a clock signal
Example later in lecture
13 / 34
Simulation
Update only if changed
0 0
1 1
0 1 0 1
1 1 1 0 0 1
1 1
1 1
1 1
0 0
Some circuits are very large
Updating every signal ⇒ very slow simulation
Event-driven simulation is much faster!
14 / 34
Simulation of Verilog
Need to verify your design
“Unit Under Test” (UUT)
Use a “testbench”!
Special Verilog module with no ports
Generates or routes inputs to the UUT
Outputs information about the results
Stimulus
Inputs Outputs Inputs Outputs
UUT UUT
(Response) (Response)
Testbench Testbench
15 / 34
Simulation Example
module adder4b (sum, c_out, a, b, c_in);
input[3:0] a, b;
input c_in;
output[3:0] sum;
output c_out;
assign {c_out, sum} = a + b + c_in;
endmodule
4
a[3:0] 4
4 sum[3:0]
b[3:0] adder4b
Cout
Cin
16 / 34
Simulation Example
t adder4b
4
a[3:0] 4
4 sum[3:0]
b[3:0] adder4b
Cout
Cin
Testbenches frequently named (should NOT mix style)
t < UUT name>
tb < UUT name>
< UUT name> t
< UUT name> tb
17 / 34
Example
not an apostrophe!
`timescale 1ns /1ns // time_unit/time_precision
module t_adder4b;
reg[8:0] stim; // inputs to UUT are regs
wire[3:0] S; // outputs of UUT are wires
wire C4;
all inputs grouped into
UUT
// instantiate UUT single vector (not
adder4b a1(S, C4, stim[8:5], stim[4:1], stim[0]); required)
// stimulus generation
initial begin
stim = 9'b000000000; // at 0 ns
#10 stim = 9'b111100001; // at 10 ns see “response” to
Behav. #10 stim = 9'b000011111; // at 20 ns each of these input
Verilog: #10 stim = 9'b111100010; // at 30 ns vectors
“do this #10 stim = 9'b000111110; // at 40 ns
once” #10 $stop; // at 50 ns – stops simulation
end timing control for
endmodule simulation
18 / 34
Testbench Requirements
Instantiate the unit being tested (UUT)
Provide input to that unit
Usually a number of different input combinations!
Watch the “results” (outputs of UUT)
Can watch ModelSimWave window...
Can print out information to the screen or to a file
19 / 34
Output Test Info
Several different system calls to output info
$monitor
Output the given values whenever one changes
Can use when simulating Structural, RTL, and/or Behavioral
$display, $strobe
Output specific information as if printf or coutin a program
Used in Behavioral Verilog
Can use formatting strings with these commands
Only means anything in simulation
Ignored by synthesizer
20 / 34
Output Format Strings
Formatting string
%h, %H hex
%d, %D decimal
%o, %O octal
%b, %B binary
%t time
$monitor("%t: %b %h %h %h %b\n", $time, c_out, sum, a,
b, c_in);
Can get more details from Verilog standard
21 / 34
Output Example
`timescale 1ns /1ns // time_unit/time_precision
module t_adder4b;
reg[8:0] stim; // inputs to UUT are regs
wire[3:0] S; // outputs of UUT are wires
wire C4;
All values will run together,
// instantiate UUT easier to read with formatting
adder4b(S, C4, stim[8:5], stim[4:1], stim[0]); string
// monitor statement
initial $monitor(“%t: %b %h %h %h %b\n”, $time, C4, S, stim[8:5],
stim[4:1], stim[0]);
// stimulus generation
initial begin
stim = 9'b000000000; // at 0 ns
#10 stim = 9'b111100001; // at 10 ns
#10 stim = 9'b000011111; // at 20 ns
#10 stim = 9'b111100010; // at 30 ns
#10 stim = 9'b000111110; // at 40 ns
#10 $stop; // at 50 ns – stops simulation
end
endmodule
22 / 34
Exhaustive Testing
For combinational designs w/ up to 8 or 9 inputs
Test ALL combinations of inputs to verify output
Could enumerate all test vectors, but don’t ...
Generate them using a “for” loop!
reg[4:0] x;
initial begin
for(x = 0; x < 16; x = x + 1)
#5// need a delay here!
end
Need to use “reg” type for loop variable? Why?
23 / 34
Why Loop Vector Has Extra Bit
Want to test all vectors 0000 to 1111
reg[3:0] x;
initial begin
for(x = 0; x < 16; x = x + 1)
#5 // need a delay here!
end
If x is 4 bits, it only gets up to 1111 = 15
1100 ⇒ 1101 ⇒ 1110 ⇒ 1111 ⇒ 0000 ⇒ 0001
x is never ≥ 16 ... so loop goes forever!
24 / 34
Example: UUT
module Comp_4_str(A_gt_B, A_lt_B, A_eq_B, A, B);
output A_gt_B, A_lt_B, A_eq_B;
input [3:0] A, B;
// Code to compare A to B
// and set A_gt_B, A_lt_B, A_eq_Baccordingly
endmodule
25 / 34
Example: Testbench
module t_Comp_4_str();
wire A_gt_B, A_lt_B, A_eq_B;
reg [4:0] A, B; // sized to prevent loop wrap around
wire [3:0] A_bus, B_bus;
assign A_bus = A[3:0]; // display 4 bit values
assign B_bus = B[3:0];
Comp_4_str M1 (A_gt_B, A_lt_B, A_eq_B, A[3:0], B[3:0]); // UUT
initial $monitor(“%t A: %h B: %h AgtB: %b AltB: %b AeqB: %b”,
$time, A_bus, B_bus, A_gt_B, A_lt_B, A_eq_B);
initial #2000 $finish; // end simulation, quit program
initial begin
#5 for (A = 0; A < 16; A = A + 1) begin // exhaustive test of valid inputs
for (B = 0; B < 16; B = B + 1) begin #5; // may want to test x’s and z’s
end // first for
end // second for note multiple initial
end // initial blocks
endmodule
26 / 34
Combinational Testbench
module comb(output d, e, input a, b, c);
and(d, a, b);
nor(e, a, b, c);
endmodule
module t_comb();
wire d, e;
reg [3:0] abc;
comb CMD(d, e, abc[2], abc[1], abc[0]); // UUT
initial $monitor("%t a: %b b: %b c: %b d: %b e: %b",
$time, abc[2], abc[1], abc[0], d, e);
initial #2000 $finish;// end simulation, quit program
// exhaustive test of valid inputs
initial begin
for(abc= 0; abc< 8; abc= abc+ 1) begin #5; end// for
end// initial
endmodule
27 / 34
Generating Clocks
Wrong way:
initial begin
#5 clk= 0;
#5 clk= 1;
#5 clk= 0;
... //(repeat hundreds of times)
end
Right way:
initial begin
initial clk= 0;
clk= 0;
always @ (clk)
forever #5 clk= ˜clk;
clk= #5 ˜clk;
end
LESS TYPING
Easier to read, harder to make mistake
28 / 34
FSM Testing
Response to input vector depends on state
For each state:
Check all transitions
For Moore, check output at each state
For Mealy, check output for each transition
This includes any transitions back to same state!
Can be time consuming to traverse FSM repeatedly. . .
29 / 34
Example : Gray Code Counter –Test1
Write a testbench to test the gray code counter we have been
developing in class.
module gray_counter(out, clk, rst);
Remember that in this example, rst is treated as an input to the
combinational logic.
Initially reset the counter and then test all states, but do not test
reset in each state.
30 / 34
Solution: Gray Code Counter –Test1
module t1_gray_counter();
wire[2:0] out;
reg clk, rst;
gray_counter GC(out, clk, rst); // UUT
initial $monitor("%t out: %b rst: %b ", $time, out, rst);
// no clock
initial #100 $finish;// end simulation, quit program
initial begin
clk= 0;
forever #5 clk= ˜clk; // What is the clock period?
end
initial begin
rst= 1;
#10 rst= 0;
end// initial
endmodule
31 / 34
Solution: Gray Code Counter –Test1
# 00 out: xxx rst: 1 // reset system
# 05 out: 000 rst: 1 // first positive edge
# 10 out: 000 rst: 0 // release reset
# 15 out: 001 rst: 0 // traverse states
# 25 out: 011 rst: 0
# 35 out: 010 rst: 0
# 45 out: 110 rst: 0
# 55 out: 111 rst: 0
# 65 out: 101 rst: 0
# 75 out: 100 rst: 0
# 85 out: 000 rst: 0
# 95 out: 001 rst: 0
32 / 34
Force/Release In Testbenches
Allows you to ”override” value FOR SIMULATION
Doesn’t do anything in ”real life”
No fair saying ”if 2+2 == 5, then force to 4” Synthesizer won’t allow
force...release anyway
How does this help testing?
Can help to pinpoint bug
Can use with FSMs to override state
Force to a state
Test all edges/outputs for that state
Force the next state to be tested, and repeat
Can also use simulator force functionality
33 / 34
Force/Release Example
C
assign y = a & b; B
assign z = y | c;
Z
initial begin A
Y
a = 0; b = 0; c = 0;
#5 a = 0; b = 1; c = 0; Time a b c y z
#5 force y = 1;
0 0 0 0 0 0
#5 b = 0;
5 0 1 0 0 0
#5 release y;
10 0 1 0 1 1
#5 $stop;
15 0 0 0 1 1
end
20 0 0 0 0 0
34 / 34