|
|
In Vera and E (Specman), it is possible to writing Drivers (BFM), independant fo the signal names used by DUV, This is done with usage of "ports" in Vera. This ports are bind to DUT through a interface. |
|
|
1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // Declare memory interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 interface memory (input bit clk);
5 wire [7:0] addr;
6 wire [7:0] data_i;
7 wire [7:0] data_o;
8 wire rw;
9 wire ce;
10 //==============================================
11 // Define the DUT modport
12 //==============================================
13 modport dut (input addr, data_i, rw, ce, clk, output data_o);
14 //==============================================
15 // Define the Testbench Driver modport
16 //==============================================
17 modport tb (output addr, data_i, rw, ce, input data_o, clk);
18 //==============================================
19 // Define the Testbench Monitor modport
20 //==============================================
21 modport mon (input addr, data_i, rw, ce, clk, data_o);
22 endinterface
23 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 // Simple memory model
25 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 module ram(memory.dut mif);
27
28 reg [7:0] memr [0:255];
29 //==============================================
30 // Memory read operation
31 //==============================================
32 assign mif.data_o = (~mif.rw && mif.ce) ?
33 memr[mif.addr] : 8'b0;
34 //==============================================
35 // Memory write operation
36 //==============================================
37 always @ (posedge mif.clk)
38 if (mif.ce && mif.rw)
39 memr[mif.addr] = mif.data_i;
40
41 endmodule
42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43 // Top level of memory model
44 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
45 module ram_top(memory.dut mif0,memory.dut mif1,memory.dut mif2);
46
47 ram U_ram0(mif0);
48 ram U_ram1(mif1);
49 ram U_ram2(mif2);
50
51 endmodule
52 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53 // Memory top level with DUT and testbench
54 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55 module mem_tb();
56 logic clk = 0;
57 always #1 clk = ~clk;
58 //==============================================
59 // interface with clock connected
60 //==============================================
61 memory mem_if0(clk);
62 memory mem_if1(clk);
63 memory mem_if2(clk);
64 //==============================================
65 // Connect the DUT
66 //==============================================
67 ram_top U_ram_top(
68 .mif0(mem_if0.dut),
69 .mif1(mem_if1.dut),
70 .mif2(mem_if2.dut)
71 );
72 //==============================================
73 // Connect the testbench
74 //==============================================
75 test U_test(
76 .tbf0(mem_if0),
77 .tbf1(mem_if1),
78 .tbf2(mem_if2)
79 );
80 endmodule
81 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82 // Testbench top level program
83 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 program test(memory tbf0,memory tbf1,memory tbf2);
85 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
86 // Driver class
87 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
88 class driver;
89 virtual memory.tb ports;
90 //==============================================
91 // Constructor
92 //==============================================
93 function new(virtual memory.tb ports);
94 this.ports = ports;
95 endfunction
96 //==============================================
97 // Test vector generation
98 //==============================================
99 task run_t();
100 integer i = 0;
101 for (i= 0; i < 4; i ++) begin
102 @ (posedge ports.clk);
103 $display("Writing address %0d with data %0d",i,i);
104 ports.addr = i;
105 ports.data_i = i;
106 ports.ce = 1;
107 ports.rw = 1;
108 @ (posedge ports.clk);
109 ports.addr = 0;
110 ports.data_i = 0;
111 ports.ce = 0;
112 ports.rw = 0;
113 end
114 for (i= 0; i < 4; i ++) begin
115 @ (posedge ports.clk);
116 $display("Read address %0d",i);
117 ports.addr = i;
118 ports.data_i = i;
119 ports.ce = 1;
120 ports.rw = 0;
121 @ (posedge ports.clk);
122 ports.addr = 0;
123 ports.data_i = 0;
124 ports.ce = 0;
125 ports.rw = 0;
126 end
127 endtask
128 endclass
129 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
130 // Monitor class
131 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
132 class monitor;
133 reg [7:0] tbmem [255];
134 virtual memory.mon ports;
135 //==============================================
136 // Constructor
137 //==============================================
138 function new(virtual memory.mon ports);
139 this.ports = ports;
140 endfunction
141 //==============================================
142 // Monitor method
143 //==============================================
144 task run_t();
145 while(1) begin
146 @ (negedge ports.clk);
147 if (ports.ce) begin
148 if (ports.rw) begin
149 tbmem[ports.addr] = ports.data_i;
150 end else begin
151 if (ports.data_o ! = tbmem[ports.addr]) begin
152 $display("Error : Expected %0x Got %0x",
153 tbmem[ports.addr],ports.data_o);
154 end else begin
155 $display("Pass : Expected %0x Got %0x",
156 tbmem[ports.addr],ports.data_o);
157 end
158 end
159 end
160 end
161 endtask
162 endclass
163 //==============================================
164 // Initial block to start the testbench
165 //==============================================
166 initial begin
167 driver tb_driver0 = new(tbf0.tb);
168 monitor tb_monitor0 = new(tbf0.mon);
169 driver tb_driver1 = new(tbf1.tb);
170 monitor tb_monitor1 = new(tbf1.mon);
171 driver tb_driver2 = new(tbf2.tb);
172 monitor tb_monitor2 = new(tbf2.mon);
173 fork
174 begin
175 tb_monitor0.run_t();
176 end
177 begin
178 tb_monitor1.run_t();
179 end
180 begin
181 tb_monitor2.run_t();
182 end
183 join_none
184 fork
185 begin
186 tb_driver0.run_t();
187 end
188 begin
189 #100 tb_driver1.run_t();
190 end
191 begin
192 #200 tb_driver2.run_t();
193 end
194 join
195 #10 $finish;
196 end
197 endprogram
You could download file if_modport_multi.sv here
|