
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.
the verification components are split into following blocks
- Base Object
- Transaction Generator8
- E testbench top
- HDL Testbench top
Base Object
1 <'
2 struct mem_base_object {
3 addr : byte;
4 data : byte;
5 // Read = 0, Write = 1
6 rd_wr: bool;
7 };
8 '>
Transaction Generator
1 <'
2 struct mem_txgen {
3 mem_object : mem_base_object;
4 mem_driver : mem_driver;
5
6 num_cmds : int;
7
8 keep soft num_cmds == 3;
9 event clk is rise('memory_tb.clk') @sim;
10
11 gen_cmds()@clk is {
12
13 };
14 };
15 '>
Driver
1 <'
2 struct mem_driver {
3 mem_object : mem_base_object;
4 event clk is rise('memory_tb.clk') @sim;
5
6 drive_mem (object : mem_base_object) @clk is {
7 wait cycle;
8 'memory_tb.address' = object.addr;
9 'memory_tb.chip_en' = 1;
10 'memory_tb.read_write' = object.rd_wr;
11 'memory_tb.data_in' = (object.rd_wr) ? object.data : 0;
12 if (object.rd_wr) {
13 outf("Driver : Memory write access-> Address : %x Data : %x\n",
14 object.addr,object.data);
15 } else {
16 outf("Driver : Memory read access-> Address : %x\n",
17 object.addr);
18 };
19 wait cycle;
20 'memory_tb.address' = 0;
21 'memory_tb.chip_en' = 0;
22 'memory_tb.read_write' = 0;
23 'memory_tb.data_in' = 0;
24 };
25 };
26 '>
Input Monitor
1 <'
2 struct mem_ip_monitor {
3 mem_object : mem_base_object;
4 mem_scoreboard : mem_scoreboard;
5 event clk is fall('memory_tb.clk') @sim;
6
7 input_monitor()@clk is {
8 while (TRUE) {
9 wait cycle;
10 if (('memory_tb.chip_en' == 1) && ('memory_tb.read_write' == 1)) {
11 outf("input_monitor : Memory wr access-> Address : %x Data : %x\n",
12 'memory_tb.address','memory_tb.data_in');
13 mem_object.addr = 'memory_tb.address';
14 mem_object.data = 'memory_tb.data_in';
15 mem_scoreboard.post_input(mem_object);
16 };
17 };
18 };
19 };
20 '>
Output Monitor
1 <'
2 struct mem_op_monitor {
3 mem_object : mem_base_object;
4 mem_scoreboard : mem_scoreboard;
5 event clk is fall('memory_tb.clk') @sim;
6
7 output_monitor()@clk is {
8 while (TRUE) {
9 wait cycle;
10 if (('memory_tb.chip_en' == 1) && ('memory_tb.read_write' == 0)) {
11 outf("Output_monitor : Memory rd access-> Address : %x Data : %x\n",
12 'memory_tb.address','memory_tb.data_out');
13 mem_object.addr = 'memory_tb.address';
14 mem_object.data = 'memory_tb.data_out';
15 mem_scoreboard.post_output(mem_object);
16 };
17 };
18 };
19 };
20 '>
Scoreboard
1 <'
2 struct mem_scoreboard {
3 // Create a keyed list to store the written data
4 // Key to the list is address of write access
5 ! mem_object: list(key:addr) of mem_base_object;
6 // post_input method is used for storing write data
7 // at write address
8 post_input (input_object : mem_base_object) is {
9 mem_object.add(input_object);
10 };
11 // post_output method is used by the output monitor to
12 // compare the output of memory with expected data
13 post_output (output_object : mem_base_object) is {
14 if mem_object.key_exists(output_object.addr) then {
15 outf("scoreboard : Found Address %x in list\n",output_object.addr);
16 if (output_object.data ! = mem_object.key(output_object.addr).data)
17 then {
18 out ("Scoreboard : Error : Exp data and Got data don't match");
19 outf( "Expected -> %x\n",
20 mem_object.key(output_object.addr).data);
21 outf( "Got -> %x\n",
22 output_object.data);
23 } else {
24 out("Scoreboard : Exp data and Got data match");
25 };
26 };
27 };
28 };
29 '>
Bạn Có Đam Mê Với Vi Mạch hay Nhúng - Bạn Muốn Trau Dồi Thêm Kĩ Năng
Mong Muốn Có Thêm Cơ Hội Trong Công Việc
Và Trở Thành Một Người Có Giá Trị Hơn
Mong Muốn Có Thêm Cơ Hội Trong Công Việc
Và Trở Thành Một Người Có Giá Trị Hơn