|
|
|
|
|
|
|
|
|
|
|
|
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
- VERA testbench top
- Interface File
- Ports File
- Ports - Interface Bind File
- HDL Testbench top
|
|
|
|
|
|
Base Object
|
|
|
|
|
|
1 #ifndef MEM_BASE_OBJECT_VRH
2 #define MEM_BASE_OBJECT_VRH
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 }
9 #endif
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
Transaction Generator
|
|
|
|
|
|
1 class mem_txgen {
2 mem_base_object mem_object;
3 mem_driver mem_driver;
4
5 integer num_cmds;
6
7 task gen_cmds();
8 task new(mem_ports ports);
9 }
10
11 task mem_txgen::new(mem_ports ports) {
12 num_cmds = 3;
13 mem_driver = new(ports);
14 }
15
16 task mem_txgen::gen_cmds() {
17 integer i = 0;
18 for (i=0; i < num_cmds; i ++ ) {
19 mem_object = new();
20 mem_object.addr = random();
21 mem_object.data = random();
22 mem_object.rd_wr = 1;
23 mem_driver.drive_mem(mem_object);
24 mem_object.rd_wr = 0;
25 mem_driver.drive_mem(mem_object);
26 }
27 }
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Driver
|
|
|
|
|
|
1 class mem_driver {
2 mem_ports ports;
3 task new(mem_ports ports);
4 task drive_mem (mem_base_object object);
5 }
6
7 task mem_driver::new(mem_ports ports) {
8 this.ports = ports;
9 }
10
11 task mem_driver::drive_mem (mem_base_object object) {
12 @ (posedge ports.$clock);
13 ports.$address = object.addr;
14 ports.$chip_en = 1;
15 ports.$read_write = object.rd_wr;
16 ports.$data_in = (object.rd_wr) ? object.data : 0;
17 if (object.rd_wr) {
18 printf("Driver : Memory write access-> Address : %x Data : %x\n",
19 object.addr,object.data);
20 } else {
21 printf("Driver : Memory read access-> Address : %x\n",
22 object.addr);
23 }
24 @ (posedge ports.$clock);
25 ports.$address = 0;
26 ports.$chip_en = 0;
27 ports.$read_write = 0;
28 ports.$data_in = 0;
29 }
30
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
Input Monitor
|
|
|
|
|
|
1
2 class mem_ip_monitor {
3 mem_base_object mem_object;
4 mem_scoreboard sb;
5 mem_ports ports;
6
7 task new (mem_scoreboard sb,mem_ports ports) {
8 this.sb = sb;
9 this.ports = ports;
10 fork {
11 input_monitor();
12 } join none
13 }
14
15 task input_monitor() {
16 while (1) {
17 @ (posedge ports.$clock);
18 if ((ports.$chip_en == 1) && (ports.$read_write == 1)) {
19 mem_object = new();
20 printf("input_monitor : Memory wr access-> Address : %x Data : %x\n",
21 ports.$address,ports.$data_in);
22 mem_object.addr = ports.$address;
23 mem_object.data = ports.$data_in;
24 sb.post_input(mem_object);
25 }
26 }
27 }
28 }
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
Output Monitor
|
|
|
|
|
|
1 class mem_op_monitor {
2 mem_base_object mem_object;
3 mem_scoreboard sb;
4 mem_ports ports;
5
6 task new (mem_scoreboard sb,mem_ports ports) {
7 this.sb = sb;
8 this.ports = ports;
9 fork {
10 output_monitor();
11 } join none
12 }
13
14
15 task output_monitor() {
16 while (1) {
17 @ (posedge ports.$clock);
18 if ((ports.$chip_en == 1) && (ports.$read_write == 0)) {
19 mem_object = new();
20 printf("Output_monitor : Memory rd access-> Address : %x Data : %x\n",
21 ports.$address,ports.$data_out);
22 mem_object.addr = ports.$address;
23 mem_object.data = ports.$data_out;
24 sb.post_output(mem_object);
25 }
26 }
27 }
28 }
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
Scoreboard
|
|
|
|
|
|
1 class mem_scoreboard {
2 // Create a keyed list to store the written data
3 // Key to the list is address of write access
4 mem_base_object mem_object [integer];
5 // post_input method is used for storing write data
6 // at write address
7 task post_input (mem_base_object input_object) {
8 mem_object[input_object.addr] = input_object;
9 }
10 // post_output method is used by the output monitor to
11 // compare the output of memory with expected data
12 task post_output (mem_base_object output_object) {
13 // Check if address exists in scoreboard
14 if (mem_object[output_object.addr] ! = null) {
15 mem_base_object in_mem = mem_object[output_object.addr];
16 printf("scoreboard : Found Address %x in list\n",output_object.addr);
17 if (output_object.data ! = in_mem.data) {
18 printf ("Scoreboard : Error : Exp data and Got data don't match\n");
19 printf( "Expected -> %x\n",
20 in_mem.data);
21 printf( "Got -> %x\n",
22 output_object.data);
23 } else {
24 printf("Scoreboard : Exp data and Got data match\n");
25 }
26 }
27 }
28 }
You could download file vera_examples here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright © 1998-2014 |
Deepak Kumar Tala - All rights reserved |
Do you have any Comment? mail me at:deepak@asic-world.com
|
|