You are on page 1of 35

Introduction to Verilog Design Test bench

by: Dr. Hau Yuan Wen

VLSI-eCAD (VeCAD) Research Laboratory Faculty of Electrical Engineering, Universiti Teknologi Malaysia, 81310 Skudai, Johor. Malaysia Tel: +607-5535268 Email: hauyuanwen@gmail.com

2010 Jasmine Hau Yuan Wen

Design Flow
RTL (.v) Testbench (.v)

Frontend
ASIC / FPGA Library

Pre-synthesis Simulation

Synthesis
Intermediate Netlist / Post-layout model (.v)

Post-synthesis Simulation

Performance Analysis (Area, Timing, Power)

2010 Jasmine Hau Yuan Wen

HDL Language
HDL Language (VHDL / Verilog)

Synthesis

Simulation

Synthesizable Circuit (design)

Simulation Testbench (verification)

A HDL code that can be simulated correctly does not mean it is synthesizable!!!
2010 Jasmine Hau Yuan Wen 3

Testbench (Test Fixture)


An environment which surrounds a design under test (DUT) to verify its functionality by: Apply input test vectors (stimulus) to DUT. Observe the output vectors
waveform recorded in an output vector file compared within test bench against the expected values. Testbench (top-level module)
Input port(s) Output port(s)

stimulus

Design Under Test

monitor

Normally testbench does not have I/O ports

2010 Jasmine Hau Yuan Wen

Simulation
Testbench (top-level module) Design Under Test

stimulus

monitor

HDL (.v / .vhd)

HDL (.v / .vhd) and /or RTL Description

HDL (.v / .vhd)

+
Testbench

Netlist / post-layout model

Simulation software
2010 Jasmine Hau Yuan Wen 5

Example: 4-bit adder and testbench


1. Use Quartus II or any text editor to create following 2 HDL files, assumed you stored in c:\TB\ directory:
a) adder4.v
module adder4 (A, B, C); input output [3:0] [4:0] A, B; C;

b) adder4_tb.v
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin //a verilog process which only executed once for (i=0; i < 10; i=i+1) begin inputA = i; inputB = i + 5; #10; // wait 10 time unit end // testbench

assign C = A + B; endmodule

end

If you compile your design in Quartus II, you will get following error: Error: Can't synthesize current design -Top partition does not contain any logic
2010 Jasmine Hau Yuan Wen

//DUT adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule

Modelsim: HDL Simulator


1. Windows start menu: All Programs >> Modelsim <SE/PE/AE/XE> <ver>. 2. Skip the Welcome screen and enter to ModelSim main window.

2010 Jasmine Hau Yuan Wen

Modelsim: Create a New Project


1. Menu bar: File >> New >> Project, a Create Project window pops up. 2. Key in the information as diagram below, then click OK.

Project Name, without any space Browse to your working directory, in this example is c:/TB. Make sure dont have any space in the directory path

2010 Jasmine Hau Yuan Wen

Modelsim: Adding HDL Files


1. Click OK on Create Project window, a Add Items to the Project window pops up. 2. Click on Add Existing File, a Add file to Project pops up. 3. Click on Browse button and navigate to the c:\TB working directory. 4. Select the files adder4.v and adder4_tb.v. 5. Click OK and then Close.

5 5

2010 Jasmine Hau Yuan Wen

Modelsim: Main Window after Loading of Existing Verilog File

2010 Jasmine Hau Yuan Wen

10

Modelsim: Compile HDL Files


1. Menu bar: Compile >> Compile All. 2. If your design files are error-free, a sign is appear on the status.

You can double-click any .v file to view the file content or correct the syntax error.

2010 Jasmine Hau Yuan Wen

11

Modelsim: Simulate the Design


1. Menu bar: Simulate >> Start Simulation, a start simulation window pops up.

2010 Jasmine Hau Yuan Wen

12

Modelsim: Select Simulation File


1. 2. 3. 4. The compiled verilog files are stored in work library. Expand the + beside work to see the contents. Choose adder4_tb.v, which is the top-level file for simulation Un-check the Enable optimization and click OK to load the design.

2010 Jasmine Hau Yuan Wen

13

Modelsim: After File Loading

The testbench (adder4_tb) and its DUT (adder4_inst) are loaded into simulator The signals within the testbench module

2010 Jasmine Hau Yuan Wen

14

Modelsim: Adding Signals into Simulation Waveform


1. Menu bar: Add >> To Wave >> All Items in Region, the waveform window pops up.

2010 Jasmine Hau Yuan Wen

15

Modelsim: Running the Simulation


1. Menu bar: Simulate >> Run >> Run All. 2. Click on to zoom the waveform window. 3. You can change the radix by right-click on the signals, select Properties, then change the radix from default to unsigned.

2010 Jasmine Hau Yuan Wen

16

Testbench Verilog Syntax


1. Lot use of: compiler directive - `<keyword> system tasks - $<keyword> Time delay - #<delay> Loops - forever, for, while, repeat. Other keywords initial, etc.

2010 Jasmine Hau Yuan Wen

17

Testbench Verilog Syntax


1. A testbench is normally without input/output port.
2. Signals that send the input stimulus to DUV: reg Signals that monitor the output vector: wire 3. To generate a set of input stimulus, we need process(es), which only executed once: initial
module adder4_tb(); // no input/output port //input stimulus: reg //output vector: wire reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin

Testbench (top-level module)


Input port(s) Output port(s)

Stimulus (reg)

Design Under Test

monitor (wire)
end

//a verilog process which only executed once for (i=0; i < 10; i=i+1) begin inputA = i; inputB = i + 5; #10; // wait 10 time unit end

adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule


2010 Jasmine Hau Yuan Wen 18

Testbench Verilog Syntax


1. To generate a complete set of input stimulus: make use of { }.
(a) sub-set of stimulus value:
module adder4_tb(); // no input/output port reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin //a verilog process which only executed once for (i=0; i < 10; i=i+1) begin inputA = i; inputB = i + 5; #10; // wait 10 time unit end end adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule endmodule

(b) Complete set of stimulus


module adder4_tb(); // no input/output port reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 256; i=i+1) begin // 8-bit data range {inputA, inputB} = i; #10; end end adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC));

2010 Jasmine Hau Yuan Wen

19

Testbench Verilog Syntax


1. To generate a random input stimulus: $random
(a) Fixed-value stimulus
module adder4_tb(); // no input/output port reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin //a verilog process which only executed once for (i=0; i < 10; i=i+1) begin inputA = i; inputB = i + 5; #10; // wait 10 time unit end end adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule

(b) random-generated stimulus


module adder4_tb(); // no input/output port reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin //a verilog process which only executed once for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; // wait 10 time unit end end adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule

2010 Jasmine Hau Yuan Wen

20

Testbench Verilog Syntax


1. $display : To display the value of variable or strings
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; $display("At time %d: A = %d, B = %d, C = %d", $time, inputA, inputB, outputC); end end adder4 adder4_inst ( endmodule
2010 Jasmine Hau Yuan Wen 21

.A (inputA), .B (inputB), .C(outputC));

Testbench Verilog Syntax


1. $monitor : Display the values of the specified signals during simulation whenever the signal values change.
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; end end adder4 adder4_inst ( initial begin $monitor ("inputA = %d inputB = %d outputC = %d", inputA, inputB, outputC); end endmodule
2010 Jasmine Hau Yuan Wen 22

.A (inputA), .B (inputB), .C(outputC));

Testbench Verilog Syntax


1. #<delay>: delay the simulation time of <delay> time units 2. The default time unit is 1 ns.
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin 10 time units = 10 ns for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; // delay 10 time units = 10 ns $display("At time %d: A = %d, B = %d, C = %d", $time, inputA, inputB, outputC); end end adder4 adder4_inst ( endmodule
2010 Jasmine Hau Yuan Wen 23

.A (inputA), .B (inputB), .C(outputC));

Testbench Verilog Syntax


1. `timescale<reference_time_unit>/<time_precision>: to re-define time unit <referene_time_unit> - specify the unit of measurement for times and delays. <time_precision> - specify the precision to which the delays are rounded off during simulation
`timescale 10ns/1ns // reference time unit = 10ns, precision = 1ns module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 10; i=i+1) begin 10 time units = 100 ns inputA = $random; inputB = $random; #10; // delay 10 time units = 100 ns $display("At time %d: A = %d, B = %d, C = %d", $time, inputA, inputB, outputC); end end adder4 adder4_inst ( .A (inputA), .B (inputB), .C(outputC)); endmodule
2010 Jasmine Hau Yuan Wen 24

Testbench Verilog Syntax


1. forever : a loop that execute forever until the $finish task is encountered. 2. Normally used in conjunction with timing control constructs, such as generate a clock signal.
`timescale 10ns/1ns module clkgen_tb(); reg clk; // reference time unit = 10ns, precision = 1ns

initial begin clk = 1'b0; forever #1 clk = ~clk; end endmodule


2010 Jasmine Hau Yuan Wen

clock period = 20 ns

// initialize the clk signal start from 0 //clock with period 20 ns

If there is no $finish in testbench module, the simulation will run forever


25

Testbench Verilog Syntax


1. $stop : To suspend the simulation time and examine the values of signals in the design. 2. $finish: To terminate the simulation.
`timescale 10ns/1ns module clkgen_tb(); reg clk; initial begin clk = 1'b0; forever #1 clk = ~clk; //clock with period 20 ns end initial begin #10 $stop; // suspend the simulation at 100ns #10 $stop; // suspend the simulation at 200ns #50 $finish; // terminate the simulation at 700 ns end endmodule
2010 Jasmine Hau Yuan Wen 26

// reference time unit = 10ns

If the simulator is suspended due to $stop, you can continue the simulation by: Menu bar: simulate >> run >> continue

Example Design Spec.


Simple example, which covers:
Asynchronous reset signal Clk signal Input/output data signal
rst clk A d q B d q

rst

op

ALU

C
2010 Jasmine Hau Yuan Wen 27

Example HDL Code


(a) Design under test
module simple_design (clk, rst, op, A, B, C); Input input input output reg clk, rst; op; A, B; C; reg_A, reg_B;

(b) Testbench
`timescale 10ns/1ns module simple_tb(); reg reg reg reg [3:0] wire [4:0] integer initial begin clk = 1'b0; forever #1 clk = ~clk; end initial begin rst = 1'b1; end initial begin for (i=0; i < 10; i=i+1) begin op = $random; #2; inputA = $random; inputB = $random; //rst signal #2; rst = 0'b0; //clock with period 20 ns clk; rst; op; inputA, inputB; outputC; i; //clk generator

[3:0] [4:0] [3:0]

//regA always @ (posedge rst or posedge clk) begin if (rst) reg_A <= 4'b0000; else reg_A <= A; end //regB always @ (posedge rst or posedge clk) begin if (rst) reg_B <= 4'b0000; else reg_B <= B; end //adder/subtractor assign C = op? {2'b00, reg_A[3:1]} : reg_A + reg_B; endmodule

$display(Time %d: A = %d, B = %d, C = %d", $time, inputA, inputB, outputC); end $stop; end simple_design DUT ( .clk (clk), .rst (rst),.op (op),.A (inputA),.B (inputB),.C(outputC)); endmodulle

2010 Jasmine Hau Yuan Wen

28

Example Output

2010 Jasmine Hau Yuan Wen

Testbench Verilog Syntax


More useful syntax: Compiler directive: `define, `ifdef, `include, `ifdef, `else, `endif Loops: for, while, repeat Value Change Dump File (VCD): $dumpvars, $dumpfile, $dumpon, $dumpoff, $dumpall Memory initialization: $readmemb, $readmemh Monitoring: $strobe, $monitor, $monitoron, $monitoroff File operation: $fopen, $fdisplay, $fwrite, $fscanf, $fclose

2010 Jasmine Hau Yuan Wen

30

Example Write the Output to a File


(a) Design under test
module adder4 (A, B, C); input output [3:0] [4:0] A, B; C;

(b) Testbench
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i, file1; initial begin file1 = $fopen("file.out"); for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; //open a file

assign C = A + B; endmodule

// declare a file handler

adder4_tb inputA inputB

A B adder4 C

outputC
end

$fdisplay(file1, "inputA = %d inputB = %d outputC = %d", inputA, inputB, outputC);

$fclose(file1); end adder4 adder4_inst (


2010 Jasmine Hau Yuan Wen

//close a file

.A (inputA), .B (inputB), .C(outputC));


31

endmodule

Example Memory Initialization


(a) Design under test
module adder4 (A, B, C); input output [3:0] [4:0] A, B; C;

(b) Testbench
module adder4_tb(); integer i; reg [3:0] inputA, inputB; wire [4:0] outputC; reg [3:0] memA [0:15]; reg[3:0] memB [0:15];

assign C = A + B; endmodule

// declare memory for input A // declare memory for input B

adder4_tb memA memB A B adder4 C outputC

initial begin $readmemh("memA.vec", memA); $readmemh("memB.vec", memB); end initial begin for (i=0; i < 16; i=i+1) begin inputA = memA[i]; inputB = memB[i]; #10;

// initialize memA // initialize memB

// load the value from memA // load the value from memB

$display(%d: inputA = %d inputB = %d outputC = %d", i, inputA, inputB, outputC); end end adder4 adder4_inst ( endmodule .A (inputA), .B (inputB), .C(outputC));

2010 Jasmine Hau Yuan Wen

32

Example Memory Initialization


(c) memA.vec
//Comments are allowed @0 // from address 0 3 // address 0 = 0x3 5 // address 1 = 0x5 A // address 2 = 0xA 2 // address 3 = 0x2 B // address 4 = 0xB @5 // from address 5 1 // address 5 = 0x1 2 // address 6 = 0x2 3 // address 7 = 0x3 4 // address 8 = 0x4 5 // address 9 = 0x5 @D // Jump to new address 13 8 // address 13 = 0x8 7 // address 14 = 0x7 C // address 15 = 0xC

(d) memB.vec
//Comments are allowed @0 // from address 0 5 // address 0 = 0x5 9 // address 1 = 0x9 C // address 2 = 0xC 3 // address 3 = 0x3 D // address 4 = 0xD @5 // from address 5 6 // address 5 = 0x6 7 // address 6 = 0x7 8 // address 7 = 0x8 9 // address 8 = 0x9 A // address 9 = 0xA @A 8 7 C 8 7 C // from address 10 // address 10 = 0x8 // address 11 = 0x7 // address 12 = 0xC // address 13 = 0x8 // address 14 = 0x7 // address 15 = 0xC

(e) Output

Due to address 10 to address 12 of memA are uninitialized, the outputs are undetermined

2010 Jasmine Hau Yuan Wen

33

Example Dump file for post-analysis


(a) Design under test
module adder4 (A, B, C); input output [3:0] [4:0] A, B; C;

(b) Testbench
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; $display("%d: inputA = %d inputB = %d outputC = %d", i, inputA, inputB, outputC); $dumpflush;

assign C = A + B; endmodule

adder4_tb inputA inputB

A B adder4 C

outputC

end end initial begin $dumpfile ("adder4.vcd"); $dumpvars(0, adder4_tb); end adder4 adder4_inst ( endmodule .A (inputA), .B (inputB), .C(outputC));
34

2010 Jasmine Hau Yuan Wen

Example Dump file for post-analysis


(a) Design under test
module adder4 (A, B, C); input output [3:0] [4:0] A, B; C;

(b) Testbench
module adder4_tb(); reg [3:0] inputA, inputB; wire [4:0] outputC; integer i; initial begin for (i=0; i < 10; i=i+1) begin inputA = $random; inputB = $random; #10; $display("%d: inputA = %d inputB = %d outputC = %d", i, inputA, inputB, outputC); $dumpflush;

assign C = A + B; endmodule

adder4_tb inputA inputB

A B adder4 C

outputC

end end initial begin $dumpfile ("adder4.vcd"); $dumpvars(0, adder4_tb); end adder4 adder4_inst ( endmodule .A (inputA), .B (inputB), .C(outputC));
35

2010 Jasmine Hau Yuan Wen

You might also like