200 likes | 335 Views
Chapter 15:Introduction to Verilog Testbenches. Objectives In this section,you will learn about designing a testbench: Creating clocks Including files Strategic use of tasks and concurrent statements Controlling and observing the design Reporting warnings and errors.
E N D
Chapter 15:Introduction to Verilog Testbenches Objectives In this section,you will learn about designing a testbench: • Creating clocks • Including files • Strategic use of tasks and concurrent statements • Controlling and observing the design • Reporting warnings and errors
The Simulation Environment This is a simplified picture of the overall simulation environment. This section concentrates on testbench development strategies. design source model libraries testbench source simulator compile file input: stimulus,response simulate file output: test pats,reports
Creating Clocks Example 1 You can define the clock in either the design or its testbench. You can define the clock either behaviorally or structurally. Here are examples of a symmetric clock: clk 0 10 30 50 reg clk; always begin #10 clk = 1; #10 clk = 0; end reg start; nand #10 (clk,clk,start); initial begin start = 0; #10 start = 1; end
Creating Clocks clk Example 2 Here are examples of a symmetric clock with delayed startup: 0 20 40 60 reg clk; initial begin #20 clk = 1; forever begin #10 clk = 0; #10 clk = 1; end end reg start; nand #10 (clk,clk,start); initial begin #10 start = 0; #10 start = 1; end
Creating Clocks clk Example 3 Here are examples of an asymmetric clock with delayed startup: 0 20 40 60 reg clk; initial begin #20 clk = 1; forever begin #5 clk = 0; #15 clk = 1; end end reg start; nand #(15,5) (clk,clk,start); initial begin #5 start = 0; #15 start = 1; end
Designing Your Testbench You can make your testbench as simple or as comolex as you want. A comolex testbench would perform response berifivation “on-the-fly”. simple testbench control design sophisticated testbench control observe design
Using Include Files Use `include files to ensure project-wide consistency of common source. `include “defines.inc” module clkgen (clk); output clk; reg clk; always begin #(`PERIOD/2) clk = 0; #(`PERIOD/2) clk = 1; end initial begin #(`TIMEOUT) $display(“TIMEOUT ERROR”); $finish; end endmodule //defines.inc `timescale 1 ns / 10 ps `define PERIOD 20 `define TIMEOUT 10000000
Using Verilog Tasks clk Use Verilog tasks in your testbench to encapsulate repeated operations. data_valid data_read data_read task cpu_read; begin #30 data_valid = 1; wait (data_read = = 1); #20 cpu_data = data_in; wait (data_read = = 0); #20 cpu_data = 8`hzz; #30 data_valid = 0; end endtask
Using Concurrent Statements monitor initialize fork join Use fork-join blocks in your testbench to concurrently activate parallel tasks. execute module inline_tb; //declare variables //instantiate designs initial begin initialize_design; fork monitor_data; monitor_error; monitor_timeout; run_test; join end endmodule
Applying Stimulus Some common stimulus application techniques include: • In-line stimulus,applied from an initial block • Stimulus applied from a loop or always block • Stimulus applied from an array of vectors or integers • Stimulus that is recorded during one simulation and played back in another simulation
In-Line Stimulus In-line stimulus has the following characteristics: • You list the variables only when their values change • You can easily define complex timing relationships between signals • The testbench can become very long for tests of real designs module inline_tb; wire [7:0] results; reg [7:0] data_bus,addr; DUT u1 (results,data_bus,addr); initial fork #10 addr = 8`h01; #10 data_bus = 8`h23; #20 data_bus = 8`h45; #30 addr = 8`h67; #30 data_bus = 8`h89; #40 data_bus = 8`hAB; #45 $finish; join endmodule
Stimulus From Loops Stimulus applied from a loop has the following characteristics: • For each iteration you assign a new stimulus vector • The timing relationships between signals are regular in nature • The testbench is compact module loop_tb; wrie [7:0] response; reg [7:0] stimulus; reg clk; integer i; DUT u1 (response,stimulus); inititial clk = 0; always begin #10 clk = 1; #10 clk = 0; end initial begin for (i = 0;i <= 255;i=i + 1) @(negedge clk) stimulus = i; #20 $finish; end endmodule
Stimulus From Arrays Stimulus applied from an array has the following characteristics: • You can load the stimulus from a data file directly into the array • For each iteration you read a new stimulus vector from the array module array_tb; wire [7:0] response; reg [7:0] stimulus,stim_array[0:15]; integer i; DUT u1 (response,stimulus); initial begin $readmemb(“datafile”,stim_array); for (i = 0;i <= 15;i = i + 1); #20 stimulus = stim_array[i]; #20 $finish; end endmodule
Vector Capture and Playback You can capture manufacturing test vectors at the boundary of a device model. parameter period = 20 wire [7:0] response; reg [7:0] stimulus; DUT u1 (response,stimulus); always apply (stimulus); always verify (response); task capture_tb; integer MCDR,MCDS; begin MCDR = $fopen(“response.dat”);if (!MCDR) $finish; MCDS = $fopen(“stimulus.dat”);if (!MCDS) $finish; forever @(posedge clk) #(period - 1) begin $fdisplayb (MCDR, “ %b”,response); $fdisplayb (MCDS, “ %b”,stimulus); end end endtask
Vector Capture and Playback parameter MAX_VECTOR = 255; wire [7:0] response; reg [7:0] stimulus,stim_array[0:255],resp_arry[0:255]; DUT u1 (response,stimulus); task playback_tb; integer MCDR,MCDS,i; begin $readmemb(“response.dat”,resp_array); $readmemb(“stimulus.dat”,stim_array); @(negedge clk) //synchronize to inactive clock stimulus = stim_array[0]; //apply 1st stimulus for (i = 0;i <=MAX_VECTOR;i = i + 1) @(negedge clk) begin if (response != = resp_array[i]) begin //check response $display(“ERROR:response is %b,should be %b”, response,resp_array[i], “\nTEST FALLED”); $finish; end if (i = = MAX_VECTOR) begin $display(“TEST PASSED”);$finish; end stimulus = stim_array[i + 1]; //apply next stimulus end end endtask You can play back the saved stimulus and response vectors.
Forcing Stimulus You can make two types of procedural continuous assignments: • You can assign and deassign a register assign <lvalue> = <expression> This overrides any procedural assignment to the register initial begin #10 assign top.dut.fsm1.state_reg = `init_state; #20 deassign top.dut.fsm1.state_reg; end • You can force and release a register or net This overrides all drivers of the signal initial begin #10 force top.dut.counter.scan_reg.q = 0; #20 release top.dut.counter.scan_reg.q; end
Reporting Warnings and Errors Use file output system tasks to report errors and warnings. A more sophisticated testbench would: • Report an error to a centralized error handler • Modify the test flow,depending upon the errors encountered • Maintain error statistics,and report them at the end of the test task par_err_task; forever @(posedge par_err) err_handle_task (`NONFATAL,`PARITY); endtask task cor_err_task; forever @(posedge cor_err) err_handle_task (`NONFATAL,`CORRECTABLE); endtask
Summary In this section,you learned about designing a testbench: • Creating clocks • Including files • Strategic use of tasks and concurrent statements • Controlling and observing the design • Reporting warnings and errors
Review • What are some characteristics of a sophisticated testbench? • For what purpose might you define a Verilog task in your testbench? • What is the difference between a begin-end block and a fork-join block? • How can you efficienly generate regular stimulus? • What data type would you use to read stimulus from a file?
About Lab 8 This lab is in two parts. The objective of the first part is to use behavioral constructs to model a small combinational Arithmetic Logic Unit (ALU). In this part,you will: • Model an ALU at the behavioral level • Test the ALU with the proveded testbench The objective of the second part is to create a model of a 5-bit counter using Verilog behavioral constructs. In this part,you will: • Model a 5-bit counter at the behavioral level • Write a testbench for your xounter design