9.
Misc Constructs
Program Block
Dynamic Casting
Packages
Commandline Input
File Operations
Scope Resolution Operator
SystemVerilog Callback
10. Functional Coverage
Functional Coverage
Covergroup & Coverpoint
Coverpoint bins
11. Assertions
Introduction
Immediate Assertion
Concurrent Assertion
$rose, $fell, $stable
Assertion Time delay ##
12. Testbench Examples
Testbench Example 1
Testbench Example 2
Testbench Example Adder
SystemVerilog Testbench
Example 1
In a previous article, concepts and components of a simple
testbench was discussed. Let us look at a practical SystemVerilog
testbench example with all those verification components and
how concepts in SystemVerilog has been used to create a
reusable environment.
Design
1 // Note that in this protocol, write data is prov
2 // in a single clock along with the address while
3 // data is received on the next clock, and no tra
4 // can be started during that time indicated by "
5 // signal.
6
7 module reg_ctrl
8 # (
9 parameter ADDR_WIDTH = 8,
10 parameter DATA_WIDTH = 16,
11 parameter DEPTH = 256,
12 parameter RESET_VAL = 16'h1234
13 )
14 ( input clk,
15 input rstn,
16 input [ADDR_WIDTH-1:0] addr,
17 input sel,
18 input wr,
19 input [DATA_WIDTH-1:0] wdata,
20 output reg [DATA_WIDTH-1:0] rdata,
21 output reg ready);
22
23 // Some memory element to store data for each
24 reg [DATA_WIDTH-1:0] ctrl [DEPTH];
25
26 reg ready_dly;
27 wire ready_pe;
28
29 // If reset is asserted, clear the memory eleme
30 // Else store data to addr for valid writes
31 // For reads, provide read data back
32 always @ (posedge clk) begin
33 if (!rstn) begin
34 for (int i = 0; i < DEPTH; i += 1) begin
35 ctrl[i] <= RESET_VAL;
36 end
37 end else begin
38 if (sel & ready & wr) begin
39 ctrl[addr] <= wdata;
40 end
41
42 if (sel & ready & !wr) begin
43 rdata <= ctrl[addr];
44 end else begin
45 rdata <= 0;
46 end
47 end
48 end
49
50 // Ready is driven using this always block
51 // During reset, drive ready as 1
52 // Else drive ready low for a clock low
53 // for a read until the data is given back
54 always @ (posedge clk) begin
55 if (!rstn) begin
56 ready <= 1;
57 end else begin
58 if (sel & ready_pe) begin
59 ready <= 1;
60 end
61 if (sel & ready & !wr) begin
62 ready <= 0;
63 end
64 end
65 end
66
67 // Drive internal signal accordingly
68 always @ (posedge clk) begin
69 if (!rstn) ready_dly <= 1;
70 else ready_dly <= ready;
71 end
72
73 assign ready_pe = ~ready & ready_dly;
74 endmodule
Transaction Object
1 class reg_item;
2 // This is the base transaction object that wil
3 // in the environment to initiate new transacti
4 // capture transactions at DUT interface
5 rand bit [7:0] addr;
6 rand bit [15:0] wdata;
7 bit [15:0] rdata;
8 rand bit wr;
9
10 // This function allows us to print contents of
11 // so that it is easier to track in a logfile
12 function void print(string tag="");
13 $display ("T=%0t [%s] addr=0x%0h wr=%0d wdata
14 $time, tag, addr, wr, wda
15 endfunction
16 endclass
Driver
1 // The driver is responsible for driving transact
2 // All it does is to get a transaction from the m
3 // available and drive it out into the DUT interf
4 class driver;
5 virtual reg_if vif;
6 event drv_done;
7 mailbox drv_mbx;
8
9 task run();
10 $display ("T=%0t [Driver] starting ...", $tim
11 @ (posedge vif.clk);
12
13 // Try to get a new transaction every time an
14 // packet contents to the interface. But do t
15 // design is ready to accept new transactions
16 forever begin
17 reg_item item;
18
19 $display ("T=%0t [Driver] waiting for item
20 drv_mbx.get(item);
21 item.print("Driver");
22 vif.sel <= 1;
23 vif.addr <= item.addr;
24 vif.wr <= item.wr;
25 vif.wdata <= item.wdata;
26 @ (posedge vif.clk);
27 while (!vif.ready) begin
28 $display ("T=%0t [Driver] wait until read
29 @(posedge vif.clk);
30 end
31
32 // When transfer is over, raise the done ev
33 vif.sel <= 0;
34 ->drv_done;
35 end
36 endtask
37 endclass
Monitor
1 // The monitor has a virtual interface handle wit
2 // the events happening on the interface. It sees
3 // captures information into a packet and sends i
4 // using another mailbox.
5 class monitor;
6 virtual reg_if vif;
7 mailbox scb_mbx; // Mailbox connected to s
8
9 task run();
10 $display ("T=%0t [Monitor] starting ...", $ti
11
12 // Check forever at every clock edge to see i
13 // valid transaction and if yes, capture info
14 // object and send it to the scoreboard when
15 // is over.
16 forever begin
17 @ (posedge vif.clk);
18 if (vif.sel) begin
19 reg_item item = new;
20 item.addr = vif.addr;
21 item.wr = vif.wr;
22 item.wdata = vif.wdata;
23
24 if (!vif.wr) begin
25 @(posedge vif.clk);
26 item.rdata = vif.rdata;
27 end
28 item.print("Monitor");
29 scb_mbx.put(item);
30 end
31 end
32 endtask
33 endclass
Scoreboard
1 // The scoreboard is responsible to check data in
2 // stores data it receives for each address, scor
3 // same data is received when the same address is
4 // in time. So the scoreboard has a "memory" elem
5 // internally for every write operation.
6 class scoreboard;
7 mailbox scb_mbx;
8
9 reg_item refq[256];
10
11 task run();
12 forever begin
13 reg_item item;
14 scb_mbx.get(item);
15 item.print("Scoreboard");
16
17 if (item.wr) begin
18 if (refq[item.addr] == null)
19 refq[item.addr] = new;
20
21 refq[item.addr] = item;
22 $display ("T=%0t [Scoreboard] Store addr=
23 end
24
25 if (!item.wr) begin
26 if (refq[item.addr] == null)
27 if (item.rdata != 'h1234)
28 $display ("T=%0t [Scoreboard] ERR
29
30 else
31 $display ("T=%0t [Scoreboard] PAS
32
33 else
34 if (item.rdata != refq[item.addr].wda
35 $display ("T=%0t [Scoreboard] ERROR
36 $time, item.addr, refq[it
37 else
38 $display ("T=%0t [Scoreboard] PASS!
39 $time, item.addr, refq[ite
40 end
41 end
42 endtask
43 endclass
Environment
1 // The environment is a container object simply t
2 // components together. This environment can then
3 // components in it would be automatically connec
4 // This is an environment without a generator.
5 class env;
6 driver d0; // Driver to desi
7 monitor m0; // Monitor from d
8 scoreboard s0; // Scoreboard con
9 mailbox scb_mbx; // Top level mail
10 virtual reg_if vif; // Virtual interf
11
12 // Instantiate all testbench components
13 function new();
14 d0 = new;
15 m0 = new;
16 s0 = new;
17 scb_mbx = new();
18 endfunction
19
20 // Assign handles and start all components so t
21 // they all become active and wait for transact
22 // available
23 virtual task run();
24 d0.vif = vif;
25 m0.vif = vif;
26 m0.scb_mbx = scb_mbx;
27 s0.scb_mbx = scb_mbx;
28
29 fork
30 s0.run();
31 d0.run();
32 m0.run();
33 join_any
34 endtask
35 endclass
Test
1 // an environment without the generator and hence
2 // written in the test.
3 class test;
4 env e0;
5 mailbox drv_mbx;
6
7 function new();
8 drv_mbx = new();
9 e0 = new();
10 endfunction
11
12 virtual task run();
13 e0.d0.drv_mbx = drv_mbx;
14
15 fork
16 e0.run();
17 join_none
18
19 apply_stim();
20 endtask
21
22 virtual task apply_stim();
23 reg_item item;
24
25 $display ("T=%0t [Test] Starting stimulus ...
26 item = new;
27 item.randomize() with { addr == 8'haa; wr ==
28 drv_mbx.put(item);
29
30 item = new;
31 item.randomize() with { addr == 8'haa; wr ==
32 drv_mbx.put(item);
33 endtask
34 endclass
Interface
1 // The interface allows verification components t
2 // using a virtual interface handle
3 interface reg_if (input bit clk);
4 logic rstn;
5 logic [7:0] addr;
6 logic [15:0] wdata;
7 logic [15:0] rdata;
8 logic wr;
9 logic sel;
10 logic ready;
11 endinterface
Testbench Top
1 // Top level testbench contains the interface, DU
2 // can be used to start test components once the
3 // the reset can also be a part of the test class
4 // to do is start the test's run method.
5 module tb;
6 reg clk;
7
8 always #10 clk = ~clk;
9 reg_if _if (clk);
10
11 reg_ctrl u0 ( .clk (clk),
12 .addr (_if.addr),
13 .rstn(_if.rstn),
14 .sel (_if.sel),
15 .wr (_if.wr),
16 .wdata (_if.wdata),
17 .rdata (_if.rdata),
18 .ready (_if.ready));
19
20 initial begin
21 new_test t0;
22
23 clk <= 0;
24 _if.rstn <= 0;
25 _if.sel <= 0;
26 #20 _if.rstn <= 1;
27
28 t0 = new;
29 t0.e0.vif = _if;
30 t0.run();
31
32 // Once the main stimulus is over, wait for s
33 // until all transactions are finished and th
34 // simulation. Note that $finish is required
35 // there are components that are running fore
36 // the background like clk, monitor, driver,
37 #200 $finish;
38 end
39
40 // Simulator dependent system tasks that can be
41 // dump simulation waves.
42 initial begin
43 $dumpvars;
44 $dumpfile("dump.vcd");
45 end
46 endmodule
Interview Questions