SYSDFV---Verification Example
Verification with SystemVerilog
Verification Of Memory
In this example, we verify a simple single port RAM. Of course in real life
we really don't get to verify a memory model.
As usual our testbench will look as shown in figure below.
So the verification components are split into following blocks
Base Object
Transaction Generator
Driver
Input Monitor
Output Monitor
Scoreboard
SV testbench top
Ports File
HDL Testbench top
So the verification components are split into following blocks
Base Object
1 `ifndef MEM_BASE_OBJECT_SV
2 `define MEM_BASE_OBJECT_SV
3 class mem_base_object;
4 bit [7:0] addr;
5 bit [7:0] data;
6 // Read = 0, Write = 1
7 bit rd_wr;
8 endclass
9 `endif
第 1 页 /共 63 页
SYSDFV---Verification Example
Transaction Generator
1 `ifndef MEM_TXGEN_SV
2 `define MEM_TXGEN_SV
3 class mem_txgen;
4 mem_base_object mem_object;
5 mem_driver mem_driver;
6
7 integer num_cmds;
8
9 function new(virtual mem_ports ports);
10 begin
11 num_cmds = 3;
12 mem_driver = new(ports);
13 end
14 endfunction
15
16
17 task gen_cmds();
18 begin
19 integer i = 0;
20 for (i=0; i < num_cmds; i ++ ) begin
21 mem_object = new();
22 mem_object.addr = $random();
23 mem_object.data = $random();
24 mem_object.rd_wr = 1;
25 mem_driver.drive_mem(mem_object);
26 mem_object.rd_wr = 0;
27 mem_driver.drive_mem(mem_object);
28 end
29 end
30 endtask
31
32 endclass
33 `endif
Driver
1 `ifndef MEM_DRIVER_SV
2 `define MEM_DRIVER_SV
3
4 class mem_driver;
5 virtual mem_ports ports;
6
7 function new(virtual mem_ports ports);
第 2 页 /共 63 页
SYSDFV---Verification Example
8 begin
9 this.ports = ports;
10 ports.address = 0;
11 ports.chip_en = 0;
12 ports.read_write = 0;
13 ports.data_in = 0;
14 end
15 endfunction
16
17 task drive_mem (mem_base_object object);
18 begin
19 @ (posedge ports.clock);
20 ports.address = object.addr;
21 ports.chip_en = 1;
22 ports.read_write = object.rd_wr;
23 ports.data_in = (object.rd_wr) ? object.data : 0;
24 if (object.rd_wr) begin
25 $display("Driver : Memory write access-> Address : %x
Data : %x\n",
26 object.addr,object.data);
27 end else begin
28 $display("Driver : Memory read access-> Address : %x\n",
29 object.addr);
30 end
31 @ (posedge ports.clock);
32 ports.address = 0;
33 ports.chip_en = 0;
34 ports.read_write = 0;
35 ports.data_in = 0;
36 end
37 endtask
38
39 endclass
40 `endif
41
Input Monitor
1 `ifndef MEM_IP_MONITOR_SV
2 `define MEM_IP_MONITOR_SV
3 class mem_ip_monitor;
4 mem_base_object mem_object;
5 mem_scoreboard sb;
6 virtual mem_ports ports;
7
第 3 页 /共 63 页
SYSDFV---Verification Example
8 function new (mem_scoreboard sb,virtual mem_ports ports);
9 begin
10 this.sb = sb;
11 this.ports = ports;
12 end
13 endfunction
14
15
16 task input_monitor();
17 begin
18 while (1) begin
19 @ (posedge ports.clock);
20 if ((ports.chip_en == 1) && (ports.read_write == 1)) begin
21 mem_object = new();
22 $display("input_monitor : Memory wr access->
Address : %x Data : %x",
23 ports.address,ports.data_in);
mem_object.addr = ports.address;
24
25
mem_object.data = ports.data_in;
26 sb.post_input(mem_object);
27 end
28 end
29 end
30 endtask
31
32 endclass
33
34 `endif
Output Monitor
1 `ifndef MEM_OP_MONITOR_SV
2 `define MEM_OP_MONITOR_SV
3
4 class mem_op_monitor;
5 mem_base_object mem_object;
6 mem_scoreboard sb;
7 virtual mem_ports ports;
8
9 function new (mem_scoreboard sb,virtual mem_ports ports);
10 begin
11 this.sb = sb;
12 this.ports = ports;
13 end
14 endfunction
第 4 页 /共 63 页
SYSDFV---Verification Example
15
16
17 task output_monitor();
18 begin
19 while (1) begin
20 @ (negedge ports.clock);
21 if ((ports.chip_en == 1) && (ports.read_write == 0)) begin
22 mem_object = new();
23 $display("Output_monitor : Memory rd access->
Address : %x Data : %x",
24 ports.address,ports.data_out);
25 mem_object.addr = ports.address;
26 mem_object.data = ports.data_out;
27 sb.post_output(mem_object);
28 end
29 end
30 end
31 endtask
32
33
34 endclass
35
36 `endif
Scoreboard
1 `ifndef MEM_SCOREBOARD_SV
2 `define MEM_SCOREBOARD_SV
3
4 class mem_scoreboard;
5 // Create a keyed list to store the written data
6 // Key to the list is address of write access
7 mem_base_object mem_object [*];
8
9 // post_input method is used for storing write data
10 // at write address
11 task post_input (mem_base_object input_object);
12 begin
13 mem_object[input_object.addr] = input_object;
14 end
15 endtask
16 // post_output method is used by the output monitor to
17 // compare the output of memory with expected data
18 task post_output (mem_base_object output_object);
19 begin
第 5 页 /共 63 页
SYSDFV---Verification Example
20 // Check if address exists in scoreboard
21 if (mem_object[output_object.addr] ! = null) begin
22 mem_base_object in_mem = mem_object[output_object.addr];
23 $display("scoreboard : Found Address %x in
list",output_object.addr);
24 if (output_object.data ! = in_mem.data) begin
25 $display ("Scoreboard : Error : Exp data and Got data don't
match");
26 $display(" Expected -> %x",
27 in_mem.data);
28 $display(" Got -> %x",
29 output_object.data);
30 end else begin
31 $display("Scoreboard : Exp data and Got data match");
32 end
33 end
34 end
35 endtask
36
37 endclass
38
39 `endif
Device Under Test
1 module memory(
2 address,
3 data_in,
4 data_out,
5 read_write,
6 chip_en
7 );
8
9 input wire [7:0] address, data_in;
10 output reg [7:0] data_out;
11 input wire read_write, chip_en;
12
13 reg [7:0] mem [0:255];
14
15 always @ (address or data_in or read_write or chip_en)
16 if (read_write == 1 && chip_en == 1) begin
17 mem[address] = data_in;
18 end
19
20 always @ (read_write or chip_en or address)
第 6 页 /共 63 页
SYSDFV---Verification Example
21 if (read_write == 0 && chip_en)
22 data_out = mem[address];
23 else
24 data_out = 0;
25
26 endmodule
HDL Testbench Top
1 `include "memory.sv"
2
3 module memory_tb();
4
5 wire [7:0] address, data_in;
6 wire [7:0] data_out;
7 wire read_write, chip_en;
8 reg clk;
9
10 // Connect the interface
11 mem_ports ports(
12 .clock (clk),
13 .address (address),
14 .chip_en (chip_en),
15 .read_write (read_write),
16 .data_in (data_in),
17 .data_out (data_out)
18 );
19
20 // Connect the program
21 memory_top top (ports);
22
23 initial begin
24 clk = 0;
25 end
26
27 always #1 clk = ~clk;
28
29 memory U_memory(
30 .address (address),
31 .data_in (data_in),
32 .data_out (data_out),
33 .read_write (read_write),
34 .chip_en (chip_en)
35 );
36 endmodule
第 7 页 /共 63 页
SYSDFV---Verification Example
SystemVerilog Testbench Top
1
2 `include "mem_ports.sv"
3
4 program memory_top(mem_ports ports);
5 `include "mem_base_object.sv"
6 `include "mem_driver.sv"
7 `include "mem_txgen.sv"
8 `include "mem_scoreboard.sv"
9 `include "mem_ip_monitor.sv"
10 `include "mem_op_monitor.sv"
11 mem_txgen txgen;
12 mem_scoreboard sb;
13 mem_ip_monitor ipm;
14 mem_op_monitor opm;
15
16 initial begin
17 sb = new();
18 ipm = new (sb, ports);
19 opm = new (sb, ports);
20 txgen = new(ports);
21 fork
22 ipm.input_monitor();
23 opm.output_monitor();
24 join_none
25 txgen.gen_cmds();
26 repeat (20) @ (posedge ports.clock);
27 end
28
29 endprogram
Interface File
1 `ifndef MEM_PORTS_SV
2 `define MEM_PORTS_SV
3
4 interface mem_ports(
5 input wire clock,
6 output logic [7:0] address,
7 output logic chip_en,
8 output logic read_write,
9 output logic [7:0] data_in,
10 input logic [7:0] data_out
11 );
第 8 页 /共 63 页