|
|
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
23 endinterface
24 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25 // Simple memory model
26 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 module ram(memory.dut mif);
28
29 reg [7:0] memr [0:255];
30 //==============================================
31 // Memory read operation
32 //==============================================
33 assign mif.data_o = (~mif.rw && mif.ce) ?
34 memr[mif.addr] : 8'b0;
35 //==============================================
36 // Memory write operation
37 //==============================================
38 always @ (posedge mif.clk)
39 if (mif.ce && mif.rw)
40 memr[mif.addr] = mif.data_i;
41
42 endmodule
43 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44 // Top level of memory model
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 module ram_top(memory mif[1:3]);
47
48 ram U_ram0(mif[1].dut);
49 ram U_ram1(mif[2].dut);
50 ram U_ram2(mif[3].dut);
51
52 endmodule
53 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54 // Memory top level with DUT and testbench
55 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 module mem_tb();
57 logic clk = 0;
58 always #1 clk = ~clk;
59 //==============================================
60 // interface with clock connected
61 //==============================================
62 memory mem_if[1:3](clk);
63 //==============================================
64 // Connect the DUT
65 //==============================================
66 ram_top U_ram_top(mem_if);
67 //==============================================
68 // Connect the testbench
69 //==============================================
70 test U_test(mem_if);
71 endmodule
72 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
73 // Testbench top level program
74 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
75 program test(memory tbf[1:3]);
76 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
77 // Driver class
78 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
79 class driver;
80 virtual memory.tb ports[1:3];
81 //==============================================
82 // Constructor
83 //==============================================
84 function new(virtual memory.tb ports[1:3]);
85 this.ports = ports;
86 endfunction
87 //==============================================
88 // Test vector generation
89 //==============================================
90 task run_t(integer portno);
91 integer i = 0;
92 for (i= 0; i < 4; i ++) begin
93 @ (posedge ports[portno].clk);
94 $display("Writing address %0d with data %0d",i,i);
95 ports[portno].addr = i;
96 ports[portno].data_i = i;
97 ports[portno].ce = 1;
98 ports[portno].rw = 1;
99 @ (posedge ports[portno].clk);
100 ports[portno].addr = 0;
101 ports[portno].data_i = 0;
102 ports[portno].ce = 0;
103 ports[portno].rw = 0;
104 end
105 for (i= 0; i < 4; i ++) begin
106 @ (posedge ports[portno].clk);
107 $display("Read address %0d",i);
108 ports[portno].addr = i;
109 ports[portno].data_i = i;
110 ports[portno].ce = 1;
111 ports[portno].rw = 0;
112 @ (posedge ports[portno].clk);
113 ports[portno].addr = 0;
114 ports[portno].data_i = 0;
115 ports[portno].ce = 0;
116 ports[portno].rw = 0;
117 end
118 endtask
119 endclass
120 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
121 // Monitor class
122 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123 class monitor;
124 reg [7:0] tbmem [255];
125 virtual memory.mon ports[1:3];
126 //==============================================
127 // Constructor
128 //==============================================
129 function new(virtual memory.mon ports[1:3]);
130 this.ports = ports;
131 endfunction
132 //==============================================
133 // Monitor method
134 //==============================================
135 task run_t(integer portno);
136 while(1) begin
137 @ (negedge ports[portno].clk);
138 if (ports[portno].ce) begin
139 if (ports[portno].rw) begin
140 tbmem[ports[portno].addr] = ports[portno].data_i;
141 end else begin
142 if (ports[portno].data_o ! = tbmem[ports[portno].addr]) begin
143 $display("Error : Expected %0x Got %0x",
144 tbmem[ports[portno].addr],ports[portno].data_o);
145 end else begin
146 $display("Pass : Expected %0x Got %0x",
147 tbmem[ports[portno].addr],ports[portno].data_o);
148 end
149 end
150 end
151 end
152 endtask
153 endclass
154 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155 // Wrapper for monitor and driver
156 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
157 class tb_shell;
158 driver tb_driver ;
159 monitor tb_monitor ;
160 //==============================================
161 // Constructor
162 //==============================================
163 function new (virtual memory tbfl[1:3]);
164 tb_driver = new(tbfl);
165 tb_monitor = new(tbfl);
166 endfunction
167 //==============================================
168 // Method to fork of Monitor and Drivers
169 //==============================================
170 task run_t();
171 for (int portno = 1; portno <= 3; portno++) begin
172 automatic int portno_t = portno;
173 fork
174 tb_monitor.run_t(portno_t);
175 join_none
176 end
177 for (int portno = 1; portno <= 3; portno++) begin
178 automatic int portno_t = portno;
179 fork
180 tb_monitor.run_t(portno_t);
181 join_none
182 end
183 fork
184 begin
185 tb_driver.run_t(1);
186 end
187 begin
188 #100 tb_driver.run_t(2);
189 end
190 begin
191 #200 tb_driver.run_t(3);
192 end
193 join
194 endtask
195 endclass
196 //==============================================
197 // Initial block to start the testbench
198 //==============================================
199 initial begin
200 tb_shell shell = new(tbf);
201 shell.run_t();
202 #10 $finish;
203 end
204 endprogram
You could download file if_modport_array_class.sv here
|