|
|
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 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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(
67 .mif(mem_if)
68 );
69 //==============================================
70 // Connect the testbench
71 //==============================================
72 test U_test(
73 .tbf(mem_if)
74 );
75
76 endmodule
77 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
78 // Testbench top level program
79 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
80 program test(memory tbf[1:3]);
81 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82 // Driver class
83 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 class driver;
85 virtual memory.tb ports;
86 //==============================================
87 // Constructor
88 //==============================================
89 function new(virtual memory.tb ports);
90 this.ports = ports;
91 endfunction
92 //==============================================
93 // Test vector generation
94 //==============================================
95 task run_t();
96 integer i = 0;
97 for (i= 0; i < 4; i ++) begin
98 @ (posedge ports.clk);
99 $display("Writing address %0d with data %0d",i,i);
100 ports.addr = i;
101 ports.data_i = i;
102 ports.ce = 1;
103 ports.rw = 1;
104 @ (posedge ports.clk);
105 ports.addr = 0;
106 ports.data_i = 0;
107 ports.ce = 0;
108 ports.rw = 0;
109 end
110 for (i= 0; i < 4; i ++) begin
111 @ (posedge ports.clk);
112 $display("Read address %0d",i);
113 ports.addr = i;
114 ports.data_i = i;
115 ports.ce = 1;
116 ports.rw = 0;
117 @ (posedge ports.clk);
118 ports.addr = 0;
119 ports.data_i = 0;
120 ports.ce = 0;
121 ports.rw = 0;
122 end
123 endtask
124 endclass
125 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
126 // Monitor class
127 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
128 class monitor;
129 reg [7:0] tbmem [255];
130 virtual memory.mon ports;
131 //==============================================
132 // Constructor
133 //==============================================
134 function new(virtual memory.mon ports);
135 this.ports = ports;
136 endfunction
137 //==============================================
138 // Monitor method
139 //==============================================
140 task run_t();
141 while(1) begin
142 @ (negedge ports.clk);
143 if (ports.ce) begin
144 if (ports.rw) begin
145 tbmem[ports.addr] = ports.data_i;
146 end else begin
147 if (ports.data_o ! = tbmem[ports.addr]) begin
148 $display("Error : Expected %0x Got %0x",
149 tbmem[ports.addr],ports.data_o);
150 end else begin
151 $display("Pass : Expected %0x Got %0x",
152 tbmem[ports.addr],ports.data_o);
153 end
154 end
155 end
156 end
157 endtask
158 endclass
159 //==============================================
160 // Initial block to start the testbench
161 //==============================================
162 initial begin
163 driver tb_driver0 = new(tbf[1].tb);
164 monitor tb_monitor0 = new(tbf[1].mon);
165 driver tb_driver1 = new(tbf[2].tb);
166 monitor tb_monitor1 = new(tbf[2].mon);
167 driver tb_driver2 = new(tbf[3].tb);
168 monitor tb_monitor2 = new(tbf[3].mon);
169 fork
170 begin
171 tb_monitor0.run_t();
172 end
173 begin
174 tb_monitor1.run_t();
175 end
176 begin
177 tb_monitor2.run_t();
178 end
179 join_none
180 fork
181 begin
182 tb_driver0.run_t();
183 end
184 begin
185 #100 tb_driver1.run_t();
186 end
187 begin
188 #200 tb_driver2.run_t();
189 end
190 join
191 #10 $finish;
192 end
193 endprogram
You could download file if_modport_array.sv here
|