Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: ios_l2_stub.vr | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | #include <vera_defines.vrh> | |
36 | #include <VeraListProgram.vrh> | |
37 | #include <ListMacros.vrh> | |
38 | #include "ios_l2_stub.if.vrh" | |
39 | #include "ios_l2_stub_ports_binds.vrh" | |
40 | #include "std_display_class.vrh" | |
41 | #include "l2_packet.vrh" | |
42 | ||
43 | ExternVeraList(l2_packet); | |
44 | extern VeraList_l2_packet l2_list0; | |
45 | extern VeraList_l2_packet l2_list1; | |
46 | extern VeraList_l2_packet l2_list2; | |
47 | extern VeraList_l2_packet l2_list3; | |
48 | extern VeraList_l2_packet l2_list4; | |
49 | extern VeraList_l2_packet l2_list5; | |
50 | extern VeraList_l2_packet l2_list6; | |
51 | extern VeraList_l2_packet l2_list7; | |
52 | ||
53 | //extern bit [63:0] IOSMemoryAddress[8]; | |
54 | //extern event IOSMemorySync[8]; | |
55 | ||
56 | ||
57 | #define REQ_WRI 3'b100 | |
58 | #define REQ_WR8 3'b010 | |
59 | #define REQ_RDD 3'b001 | |
60 | ||
61 | #define REQ_TYPE_FIELD 26:24 | |
62 | ||
63 | #define IOS_MIN_DEQ_DELAY 0 | |
64 | #define IOS_MIN_WIB_DELAY 0 | |
65 | #define IOS_MIN_CTAG_DELAY 0 | |
66 | #define IOS_MAX_DELAY 100 | |
67 | ||
68 | class ios_l2_stub { | |
69 | bit [511:0] l2_mem[]; | |
70 | l2_stub_port l2; | |
71 | ||
72 | // for dispmon | |
73 | StandardDisplay dbg; | |
74 | local string myname; | |
75 | local integer receive_count; | |
76 | local integer response_count; | |
77 | ||
78 | l2_packet transaction_in; | |
79 | bit [511:0] sent_read_data = 0; | |
80 | local event expect_data_received; | |
81 | local bit [2:0] bank_number; | |
82 | local bit matched_packet = 0; | |
83 | bit enable_l2_checker = 0; | |
84 | bit enable_l2_wr_checker = 0; | |
85 | bit enable_l2_rd_checker = 0; | |
86 | local bit dump_expects = 0; | |
87 | ||
88 | // for delay | |
89 | local integer deq_delay; | |
90 | local integer wib_delay; | |
91 | local integer ctag_delay; | |
92 | local integer enable_tracking; | |
93 | ||
94 | local integer check_semph_id; | |
95 | ||
96 | VeraList_l2_packet l2_list; | |
97 | ||
98 | task new(l2_stub_port l2, integer bank, StandardDisplay dbg, VeraList_l2_packet l2_list); | |
99 | task start_l2_stub(); | |
100 | function bit[6:0] gen_ecc(bit[31:0] data); | |
101 | function bit[1:0] gen_parity(bit[31:0] data); | |
102 | task check_packet(l2_packet received_packet); | |
103 | function bit expect(l2_packet expected_packet, integer timeout = 100000); | |
104 | task look_for_packets(); | |
105 | task set_packet_expect(l2_packet l2_pkt[16], integer total); | |
106 | ||
107 | } | |
108 | ||
109 | task ios_l2_stub::new(l2_stub_port l2_stub, | |
110 | integer bank, | |
111 | StandardDisplay dbg, | |
112 | VeraList_l2_packet l2_list) | |
113 | { | |
114 | // for dispmon | |
115 | myname = "FC_L2stub"; | |
116 | this.dbg = dbg; | |
117 | this.l2_list = l2_list; | |
118 | receive_count = 0; | |
119 | bank_number = bank; | |
120 | ||
121 | // for delay | |
122 | deq_delay = IOS_MIN_DEQ_DELAY; | |
123 | wib_delay = IOS_MIN_WIB_DELAY; | |
124 | ctag_delay = IOS_MIN_CTAG_DELAY; | |
125 | ||
126 | enable_tracking = 1; | |
127 | ||
128 | l2 = l2_stub; | |
129 | transaction_in = new("Inbound L2 Packet", dbg); | |
130 | ||
131 | check_semph_id = alloc(SEMAPHORE, 0, 1,1); | |
132 | ||
133 | fork { | |
134 | start_l2_stub(); | |
135 | look_for_packets(); | |
136 | } join none | |
137 | ||
138 | } | |
139 | ||
140 | task ios_l2_stub::start_l2_stub() | |
141 | { | |
142 | bit [39:0] addr; | |
143 | bit [15:0] tag; | |
144 | bit [3:0] opes; | |
145 | bit [31:0] req_cmd_1, req_cmd_2, req_data; | |
146 | bit [7:0] bytemask; | |
147 | bit [511:0] wri_data; | |
148 | ||
149 | bit [511:0] rdd_data, deq_data512, ret_data512; | |
150 | bit [511:0] tmp_rdd_data; | |
151 | bit [127:0] rdd_data0, rdd_data1, rdd_data2, rdd_data3, rdd_data4, rdd_data5, rdd_data6, rdd_data7; | |
152 | bit [127:0] tmp_rdd_data0, tmp_rdd_data1, tmp_rdd_data2, tmp_rdd_data3, tmp_rdd_data4, tmp_rdd_data5, tmp_rdd_data6, tmp_rdd_data7; | |
153 | bit [63:0] wr8_data,data64; | |
154 | bit [76:0] req_to_deq_data, deq_to_ret_data, ret_to_ack_data; | |
155 | bit last_rdd = 0, curr_rdd = 0; | |
156 | bit [6:0] ecc; | |
157 | bit [6:0] ctag_ecc; | |
158 | integer i; | |
159 | ||
160 | integer mbox_req_to_deq = alloc(MAILBOX, 0, 1), mbox_deq_to_ret = alloc(MAILBOX, 0, 1); | |
161 | ||
162 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d] Starting ... ", bank_number)); | |
163 | ||
164 | fork | |
165 | { | |
166 | while (1) { | |
167 | @(posedge l2.$clk); | |
168 | if (enable_l2_checker) { | |
169 | transaction_in.reset(); | |
170 | if (l2.$req_vld) { | |
171 | case (l2.$req[REQ_TYPE_FIELD]) { | |
172 | ||
173 | REQ_WRI: { | |
174 | if (enable_l2_wr_checker) { | |
175 | req_cmd_1 = l2.$req; | |
176 | ctag_ecc = l2.$ecc; | |
177 | tag = req_cmd_1[23:8]; | |
178 | opes = req_cmd_1[30:27]; | |
179 | dbg.dispmon(myname, MON_NORMAL, | |
180 | psprintf("[%1d] recv REQ_WRI tag=%x", bank_number, tag)); | |
181 | ||
182 | @(posedge l2.$clk); | |
183 | req_cmd_2 = l2.$req; | |
184 | addr = {req_cmd_1[7:0],req_cmd_2}; | |
185 | bytemask = 0; | |
186 | ||
187 | if (addr[39] === 1'b1) | |
188 | { | |
189 | addr[39] = 1'b0; | |
190 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x pa[39] is set!", bank_number, addr)); | |
191 | } | |
192 | if (opes[1] === 1'b1) | |
193 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x E bit is set!", bank_number, addr)); | |
194 | ||
195 | @(posedge l2.$clk); | |
196 | req_data = l2.$req; wri_data[511:480] = req_data; | |
197 | //ecc = l2.$ecc; | |
198 | // if (gen_ecc(req_data) !== ecc) { | |
199 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 0 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
200 | // } | |
201 | ||
202 | @(posedge l2.$clk); | |
203 | req_data = l2.$req; | |
204 | wri_data[479:448] = req_data; | |
205 | //ecc = l2.$ecc; | |
206 | // if (gen_ecc(req_data) !== ecc) { | |
207 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 1 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
208 | // } | |
209 | ||
210 | @(posedge l2.$clk); | |
211 | req_data = l2.$req; | |
212 | wri_data[447:416] = req_data; | |
213 | //ecc = l2.$ecc; | |
214 | // if (gen_ecc(req_data) !== ecc) { | |
215 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 2 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
216 | // } | |
217 | ||
218 | @(posedge l2.$clk); | |
219 | req_data = l2.$req; | |
220 | wri_data[415:384] = req_data; | |
221 | //ecc = l2.$ecc; | |
222 | // if (gen_ecc(req_data) !== ecc) { | |
223 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 3 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
224 | // } | |
225 | ||
226 | @(posedge l2.$clk); | |
227 | req_data = l2.$req; | |
228 | wri_data[383:352] = req_data; | |
229 | //ecc = l2.$ecc; | |
230 | // if (gen_ecc(req_data) !== ecc) { | |
231 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 4 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
232 | // } | |
233 | ||
234 | @(posedge l2.$clk); | |
235 | req_data = l2.$req; | |
236 | wri_data[351:320] = req_data; | |
237 | //ecc = l2.$ecc; | |
238 | // if (gen_ecc(req_data) !== ecc) { | |
239 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 5 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
240 | // } | |
241 | ||
242 | @(posedge l2.$clk); | |
243 | req_data = l2.$req; | |
244 | wri_data[319:288] = req_data; | |
245 | //ecc = l2.$ecc; | |
246 | // if (gen_ecc(req_data) !== ecc) { | |
247 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 6 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
248 | // } | |
249 | ||
250 | @(posedge l2.$clk); | |
251 | req_data = l2.$req; | |
252 | wri_data[287:256] = req_data; | |
253 | //ecc = l2.$ecc; | |
254 | // if (gen_ecc(req_data) !== ecc) { | |
255 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 7 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
256 | // } | |
257 | ||
258 | @(posedge l2.$clk); | |
259 | req_data = l2.$req; | |
260 | wri_data[255:224] = req_data; | |
261 | //ecc = l2.$ecc; | |
262 | // if (gen_ecc(req_data) !== ecc) { | |
263 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 8 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
264 | // } | |
265 | ||
266 | @(posedge l2.$clk); | |
267 | req_data = l2.$req; | |
268 | wri_data[223:192] = req_data; | |
269 | //ecc = l2.$ecc; | |
270 | // if (gen_ecc(req_data) !== ecc) { | |
271 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 9 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
272 | // } | |
273 | ||
274 | @(posedge l2.$clk); | |
275 | req_data = l2.$req; | |
276 | wri_data[191:160] = req_data; | |
277 | //ecc = l2.$ecc; | |
278 | // if (gen_ecc(req_data) !== ecc) { | |
279 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 10 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
280 | // } | |
281 | ||
282 | @(posedge l2.$clk); | |
283 | req_data = l2.$req; | |
284 | wri_data[159:128] = req_data; | |
285 | //ecc = l2.$ecc; | |
286 | // if (gen_ecc(req_data) !== ecc) { | |
287 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 11 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
288 | // } | |
289 | ||
290 | @(posedge l2.$clk); | |
291 | req_data = l2.$req; | |
292 | wri_data[127:96] = req_data; | |
293 | //ecc = l2.$ecc; | |
294 | // if (gen_ecc(req_data) !== ecc) { | |
295 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 12 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
296 | // } | |
297 | ||
298 | @(posedge l2.$clk); | |
299 | req_data = l2.$req; | |
300 | wri_data[95:64] = req_data; | |
301 | //ecc = l2.$ecc; | |
302 | // if (gen_ecc(req_data) !== ecc) { | |
303 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 13 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
304 | // } | |
305 | ||
306 | @(posedge l2.$clk); | |
307 | req_data = l2.$req; | |
308 | wri_data[63:32] = req_data; | |
309 | //ecc = l2.$ecc; | |
310 | // if (gen_ecc(req_data) !== ecc) { | |
311 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 14 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
312 | // } | |
313 | ||
314 | @(posedge l2.$clk); | |
315 | req_data = l2.$req; | |
316 | wri_data[31:0] = req_data; | |
317 | //ecc = l2.$ecc; | |
318 | // if (gen_ecc(req_data) !== ecc) { | |
319 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WRI request data 15 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
320 | // } | |
321 | ||
322 | l2_mem[addr[39:9]] = wri_data; | |
323 | ||
324 | // Fu 4/19/05 for Rx checker: mark memory | |
325 | // for (i=0; i<8; i++) { | |
326 | // IOSMemoryAddress[bank_number] = (addr + 8*i); | |
327 | ||
328 | // dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d] inform call back tag=%x, addr=", bank_number, tag, IOSMemoryAddress[bank_number])); | |
329 | //trigger(IOSMemorySync[bank_number]); | |
330 | //sync(ALL,IOSMemorySync[bank_number]); | |
331 | //trigger(OFF,IOSMemorySync); | |
332 | // } | |
333 | // mark memory end | |
334 | ||
335 | transaction_in.set("address", addr); | |
336 | transaction_in.set("tag", tag); | |
337 | transaction_in.set("bytemask", bytemask); | |
338 | transaction_in.set("opes", opes); | |
339 | transaction_in.set("data", wri_data); | |
340 | transaction_in.set("bank_number", bank_number); | |
341 | check_packet(transaction_in); | |
342 | ||
343 | dbg.dispmon(myname, MON_NORMAL, | |
344 | psprintf("[%1d] REQ_WRI complete tag=%x, addr=%0h, data=%0h", bank_number, tag, addr, wri_data)); | |
345 | // mail addr and tag to mbox_req_to_deq | |
346 | mailbox_put(mbox_req_to_deq, {ctag_ecc, REQ_WRI, opes, bytemask, tag, addr}); | |
347 | ||
348 | } | |
349 | } | |
350 | REQ_WR8: { | |
351 | if (enable_l2_wr_checker) { | |
352 | req_cmd_1 = l2.$req; | |
353 | ctag_ecc = l2.$ecc; | |
354 | ||
355 | tag = 0; | |
356 | dbg.dispmon(myname, MON_NORMAL, | |
357 | psprintf("[%1d] recv REQ_WR8 tag=%x", bank_number, tag)); | |
358 | ||
359 | @(posedge l2.$clk); | |
360 | req_cmd_2 = l2.$req; | |
361 | addr = {req_cmd_1[7:0],req_cmd_2}; | |
362 | bytemask = req_cmd_1[15:8]; | |
363 | opes = req_cmd_1[30:27]; | |
364 | ||
365 | if (addr[39] === 1'b1) | |
366 | { | |
367 | addr[39] = 1'b0; | |
368 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x pa[39] is set!", bank_number, addr)); | |
369 | } | |
370 | if (opes[1] === 1'b1) | |
371 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x E bit is set!", bank_number, addr)); | |
372 | ||
373 | @(posedge l2.$clk); | |
374 | req_data = l2.$req; | |
375 | wr8_data[63:32] = req_data; | |
376 | //ecc = l2.$ecc; | |
377 | // if (gen_ecc(req_data) !== ecc) { | |
378 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WR8 request data 0 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
379 | // } | |
380 | ||
381 | @(posedge l2.$clk); | |
382 | req_data = l2.$req; | |
383 | wr8_data[31:0] = req_data; | |
384 | //ecc = l2.$ecc; | |
385 | // if (gen_ecc(req_data) !== ecc) { | |
386 | // dbg.dispmon(myname, MON_ERR, psprintf ("IOS_L2_STUB: ECC mismatch for WR8 request data 1 %h. Expect = %h, Actual = %h",req_data,gen_ecc(req_data),ecc)); | |
387 | // } | |
388 | ||
389 | wri_data = l2_mem[{addr[39:6],6'h00}]; | |
390 | ||
391 | case (addr[5:3]) { | |
392 | 3'd0: data64 = wri_data[511:448]; | |
393 | 3'd1: data64 = wri_data[447:384]; | |
394 | 3'd2: data64 = wri_data[383:320]; | |
395 | 3'd3: data64 = wri_data[319:256]; | |
396 | 3'd4: data64 = wri_data[255:192]; | |
397 | 3'd5: data64 = wri_data[191:128]; | |
398 | 3'd6: data64 = wri_data[127:64]; | |
399 | 3'd7: data64 = wri_data[63:0]; | |
400 | } | |
401 | ||
402 | if (bytemask[0]) data64[7:0] = wr8_data[7:0]; | |
403 | if (bytemask[1]) data64[15:8] = wr8_data[15:8]; | |
404 | if (bytemask[2]) data64[23:16] = wr8_data[23:16]; | |
405 | if (bytemask[3]) data64[31:24] = wr8_data[31:24]; | |
406 | if (bytemask[4]) data64[39:32] = wr8_data[39:32]; | |
407 | if (bytemask[5]) data64[47:40] = wr8_data[47:40]; | |
408 | if (bytemask[6]) data64[55:48] = wr8_data[55:48]; | |
409 | if (bytemask[7]) data64[63:56] = wr8_data[63:56]; | |
410 | ||
411 | case (addr[5:3]) { | |
412 | 3'd0: wri_data[511:448] = data64; | |
413 | 3'd1: wri_data[447:384] = data64; | |
414 | 3'd2: wri_data[383:320] = data64; | |
415 | 3'd3: wri_data[319:256] = data64; | |
416 | 3'd4: wri_data[255:192] = data64; | |
417 | 3'd5: wri_data[191:128] = data64; | |
418 | 3'd6: wri_data[127:64] = data64; | |
419 | 3'd7: wri_data[63:0] = data64; | |
420 | } | |
421 | ||
422 | l2_mem[{addr[39:6],6'h00}] = wri_data; | |
423 | ||
424 | transaction_in.set("address", addr); | |
425 | transaction_in.set("tag", tag); | |
426 | transaction_in.set("bytemask", bytemask); | |
427 | transaction_in.set("opes", opes); | |
428 | transaction_in.set("data", data64); | |
429 | transaction_in.set("bank_number", bank_number); | |
430 | check_packet(transaction_in); | |
431 | // mail addr and tag to mbox_req_to_deq | |
432 | mailbox_put(mbox_req_to_deq, {ctag_ecc, REQ_WR8, opes, bytemask, tag, addr}); | |
433 | ||
434 | } | |
435 | } | |
436 | REQ_RDD: { | |
437 | if (enable_l2_rd_checker) { | |
438 | req_cmd_1 = l2.$req; | |
439 | ctag_ecc = l2.$ecc; | |
440 | tag = req_cmd_1[23:8]; | |
441 | opes = req_cmd_1[30:27]; | |
442 | dbg.dispmon(myname, MON_NORMAL, | |
443 | psprintf("[%1d] recv REQ_WR8 tag=%x", bank_number, tag)); | |
444 | ||
445 | @(posedge l2.$clk); | |
446 | req_cmd_2 = l2.$req; | |
447 | @(posedge l2.$clk); | |
448 | @(posedge l2.$clk); | |
449 | addr = {req_cmd_1[7:0],req_cmd_2}; | |
450 | ||
451 | if (addr[39] === 1'b1) | |
452 | { | |
453 | addr[39] = 1'b0; | |
454 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x pa[39] is set!", bank_number, addr)); | |
455 | } | |
456 | if (opes[1] === 1'b1) | |
457 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d]-RAS recv addr=%x E bit is set!", bank_number, addr)); | |
458 | ||
459 | bytemask = 0; | |
460 | ||
461 | tmp_rdd_data = l2_mem[addr[39:9]]; | |
462 | ||
463 | tmp_rdd_data0[127:0] = tmp_rdd_data[127:0]; | |
464 | tmp_rdd_data1[127:0] = tmp_rdd_data[255:128]; | |
465 | tmp_rdd_data2[127:0] = tmp_rdd_data[383:256]; | |
466 | tmp_rdd_data3[127:0] = tmp_rdd_data[511:384]; | |
467 | rdd_data0[127:0] = {tmp_rdd_data0[7:0], tmp_rdd_data0[15:8], tmp_rdd_data0[23:16], tmp_rdd_data0[31:24], tmp_rdd_data0[39:32], tmp_rdd_data0[47:40], tmp_rdd_data0[55:48], tmp_rdd_data0[63:56], tmp_rdd_data0[71:64], tmp_rdd_data0[79:72], tmp_rdd_data0[87:80], tmp_rdd_data0[95:88], tmp_rdd_data0[103:96], tmp_rdd_data0[111:104], tmp_rdd_data0[119:112], tmp_rdd_data0[127:120]}; | |
468 | rdd_data1[127:0] = {tmp_rdd_data1[7:0], tmp_rdd_data1[15:8], tmp_rdd_data1[23:16], tmp_rdd_data1[31:24], tmp_rdd_data1[39:32], tmp_rdd_data1[47:40], tmp_rdd_data1[55:48], tmp_rdd_data1[63:56], tmp_rdd_data1[71:64], tmp_rdd_data1[79:72], tmp_rdd_data1[87:80], tmp_rdd_data1[95:88], tmp_rdd_data1[103:96], tmp_rdd_data1[111:104], tmp_rdd_data1[119:112], tmp_rdd_data1[127:120]}; | |
469 | rdd_data2[127:0] = {tmp_rdd_data2[7:0], tmp_rdd_data2[15:8], tmp_rdd_data2[23:16], tmp_rdd_data2[31:24], tmp_rdd_data2[39:32], tmp_rdd_data2[47:40], tmp_rdd_data2[55:48], tmp_rdd_data2[63:56], tmp_rdd_data2[71:64], tmp_rdd_data2[79:72], tmp_rdd_data2[87:80], tmp_rdd_data2[95:88], tmp_rdd_data2[103:96], tmp_rdd_data2[111:104], tmp_rdd_data2[119:112], tmp_rdd_data2[127:120]}; | |
470 | rdd_data3[127:0] = {tmp_rdd_data3[7:0], tmp_rdd_data3[15:8], tmp_rdd_data3[23:16], tmp_rdd_data3[31:24], tmp_rdd_data3[39:32], tmp_rdd_data3[47:40], tmp_rdd_data3[55:48], tmp_rdd_data3[63:56], tmp_rdd_data3[71:64], tmp_rdd_data3[79:72], tmp_rdd_data3[87:80], tmp_rdd_data3[95:88], tmp_rdd_data3[103:96], tmp_rdd_data3[111:104], tmp_rdd_data3[119:112], tmp_rdd_data3[127:120]}; | |
471 | ||
472 | ||
473 | rdd_data[511:0] = {rdd_data3[127:0], rdd_data2[127:0], rdd_data1[127:0], rdd_data0[127:0]}; | |
474 | ||
475 | case (addr[5:2]) { | |
476 | 4'd0: {} | |
477 | 4'd1: rdd_data = {rdd_data[479:0],rdd_data[511:480]}; | |
478 | 4'd2: rdd_data = {rdd_data[447:0],rdd_data[511:448]}; | |
479 | 4'd3: rdd_data = {rdd_data[415:0],rdd_data[511:416]}; | |
480 | 4'd4: rdd_data = {rdd_data[383:0],rdd_data[511:384]}; | |
481 | 4'd5: rdd_data = {rdd_data[351:0],rdd_data[511:352]}; | |
482 | 4'd6: rdd_data = {rdd_data[319:0],rdd_data[511:320]}; | |
483 | 4'd7: rdd_data = {rdd_data[287:0],rdd_data[511:288]}; | |
484 | 4'd8: rdd_data = {rdd_data[255:0],rdd_data[511:256]}; | |
485 | 4'd9: rdd_data = {rdd_data[223:0],rdd_data[511:224]}; | |
486 | 4'd10: rdd_data = {rdd_data[191:0],rdd_data[511:192]}; | |
487 | 4'd11: rdd_data = {rdd_data[159:0],rdd_data[511:160]}; | |
488 | 4'd12: rdd_data = {rdd_data[127:0],rdd_data[511:128]}; | |
489 | 4'd13: rdd_data = {rdd_data[95:0],rdd_data[511:96]}; | |
490 | 4'd14: rdd_data = {rdd_data[63:0],rdd_data[511:64]}; | |
491 | 4'd15: rdd_data = {rdd_data[31:0],rdd_data[511:32]}; | |
492 | } | |
493 | ||
494 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d] REQ_RDD addr=%0h tag=%x data=%0h", bank_number, addr, tag, rdd_data)); | |
495 | if((&rdd_data[31:0]) === 1'bx) rdd_data[31:0] = 32'b11111111111111111111111111111111; | |
496 | if((&rdd_data[63:32]) === 1'bx ) rdd_data[63:32] = 32'b11111111111111111111111111111111; | |
497 | if((&rdd_data[95:64]) === 1'bx) rdd_data[95:64] = 32'b11111111111111111111111111111111; | |
498 | if((&rdd_data[127:96]) === 1'bx) rdd_data[127:96] = 32'b11111111111111111111111111111111; | |
499 | if((&rdd_data[159:128]) === 1'bx ) rdd_data[159:128] = 32'b11111111111111111111111111111111; | |
500 | if((&rdd_data[191:160]) === 1'bx) rdd_data[191:160] = 32'b11111111111111111111111111111111; | |
501 | if((&rdd_data[223:192]) === 1'bx) rdd_data[223:192] = 32'b11111111111111111111111111111111; | |
502 | if((&rdd_data[255:224]) === 1'bx) rdd_data[255:224] = 32'b11111111111111111111111111111111; | |
503 | if((&rdd_data[287:256]) === 1'bx) rdd_data[287:256] = 32'b11111111111111111111111111111111; | |
504 | if((&rdd_data[319:288]) === 1'bx) rdd_data[319:288] = 32'b11111111111111111111111111111111; | |
505 | if((&rdd_data[351:320]) === 1'bx) rdd_data[351:320] = 32'b11111111111111111111111111111111; | |
506 | if((&rdd_data[383:352]) === 1'bx) rdd_data[383:352] = 32'b11111111111111111111111111111111; | |
507 | if((&rdd_data[415:384]) === 1'bx) rdd_data[415:384] = 32'b11111111111111111111111111111111; | |
508 | if((&rdd_data[447:416]) === 1'bx) rdd_data[447:416] = 32'b11111111111111111111111111111111; | |
509 | if((&rdd_data[479:448]) === 1'bx) rdd_data[479:448] = 32'b11111111111111111111111111111111; | |
510 | if((&rdd_data[511:480]) === 1'bx) rdd_data[511:480] = 32'b11111111111111111111111111111111; | |
511 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[63:0] = 0x%0h", rdd_data[63:0])); | |
512 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[127:64] = 0x%0h", rdd_data[127:64])); | |
513 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[191:128] = 0x%0h", rdd_data[191:128])); | |
514 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[255:192] = 0x%0h", rdd_data[255:192])); | |
515 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[319:256] = 0x%0h", rdd_data[319:256])); | |
516 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[383:320] = 0x%0h", rdd_data[383:320])); | |
517 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[447:384] = 0x%0h", rdd_data[447:384])); | |
518 | dbg.dispmon(myname, MON_INFO, psprintf(" REQ_RDD data[511:448] = 0x%0h", rdd_data[511:448])); | |
519 | ||
520 | transaction_in.set("address", addr); | |
521 | transaction_in.set("tag", tag); | |
522 | transaction_in.set("bytemask", bytemask); | |
523 | transaction_in.set("opes", opes); | |
524 | transaction_in.set("bank_number", bank_number); | |
525 | check_packet(transaction_in); | |
526 | if (opes[0]) { | |
527 | rdd_data = sent_read_data; | |
528 | printf("Setting read_data to %0h\n", rdd_data); | |
529 | } | |
530 | ||
531 | // mail addr and tag to mbox_req_to_deq | |
532 | mailbox_put(mbox_req_to_deq, {ctag_ecc, REQ_RDD, opes, bytemask, tag, addr}); | |
533 | mailbox_put(mbox_req_to_deq, rdd_data); | |
534 | ||
535 | dbg.dispmon(myname, MON_INFO, psprintf("[%1d] recv process REQ_RDD addr=%0h tag=%x data=%0h", bank_number, addr, tag, rdd_data)); | |
536 | ||
537 | } | |
538 | } | |
539 | default: { } | |
540 | } | |
541 | } | |
542 | } | |
543 | } | |
544 | } | |
545 | ||
546 | join none | |
547 | } | |
548 | ||
549 | function reg[1:0] ios_l2_stub::gen_parity(bit [31:0] data) | |
550 | { | |
551 | gen_parity = { (data[16] ^ data[17] ^ data[18] ^ data[19] | |
552 | ^ data[20] ^ data[21] ^ data[22] ^ data[23] | |
553 | ^ data[24] ^ data[25] ^ data[26] ^ data[27] | |
554 | ^ data[28] ^ data[29] ^ data[30] ^ data[31] ), | |
555 | (data[0] ^ data[1] ^ data[2] ^ data[3] | |
556 | ^ data[4] ^ data[5] ^ data[6] ^ data[7] | |
557 | ^ data[8] ^ data[9] ^ data[10] ^ data[11] | |
558 | ^ data[12] ^ data[13] ^ data[14] ^ data[15] ) }; | |
559 | ||
560 | } | |
561 | ||
562 | ||
563 | ||
564 | /// function to generate 7-bit ecc from 32 bit data, need to verify the algorithm | |
565 | function bit[6:0] ios_l2_stub::gen_ecc(bit [31:0] data) | |
566 | { | |
567 | bit [6:0] temp_ecc; | |
568 | temp_ecc[0] = data[0] ^ data[1] ^ data[3] ^ data[4] ^ data[6] ^ data[8] ^ | |
569 | data[10] ^ data[11] ^ data[13] ^ data[15] ^ data[17] ^ data[19] ^ | |
570 | data[21] ^ data[23] ^ data[25] ^ data[26] ^ data[28] ^ data[30]; | |
571 | ||
572 | temp_ecc[1] = data[0] ^ data[2] ^ data[3] ^ data[5] ^ data[6] ^ data[9] ^ | |
573 | data[10] ^ data[12] ^ data[13] ^ data[16] ^ data[17] ^ data[20] ^ | |
574 | data[21] ^ data[24] ^ data[25] ^ data[27] ^ data[28] ^ data[31]; | |
575 | ||
576 | temp_ecc[2] = data[1] ^ data[2] ^ data[3] ^ data[7] ^ data[8] ^ data[9] ^ | |
577 | data[10] ^ data[14] ^ data[15] ^ data[16] ^ data[17] ^ data[22] ^ | |
578 | data[23] ^ data[24] ^ data[25] ^ data[29] ^ data[30] ^ data[31]; | |
579 | ||
580 | temp_ecc[3] = data[4] ^ data[5] ^data[6] ^data[7] ^data[8] ^data[9] ^ | |
581 | data[10] ^ data[18] ^data[19] ^data[20] ^data[21] ^data[22] ^ | |
582 | data[23] ^ data[24] ^ data[25]; | |
583 | ||
584 | temp_ecc[4] = data[11] ^ data[12] ^ data[13] ^ data[14] ^ data[15] ^ | |
585 | data[16] ^ data[17] ^ data[18] ^ data[19] ^ data[20] ^ | |
586 | data[21] ^ data[22] ^ data[23] ^ data[24] ^ data[25]; | |
587 | ||
588 | temp_ecc[5] = data[26] ^ data[27] ^ data[28] ^ data[29] ^ data[30] ^ | |
589 | data[31]; | |
590 | ||
591 | temp_ecc[6] = ^{temp_ecc[5:0],data[31:0]}; | |
592 | gen_ecc = temp_ecc; | |
593 | } | |
594 | ||
595 | task ios_l2_stub::check_packet(l2_packet packet_received) { | |
596 | ||
597 | bit [3:0] opes; | |
598 | ||
599 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d] checker: examin a packet ", bank_number)); | |
600 | dump_expects = 0; | |
601 | trigger(ONE_BLAST, expect_data_received); | |
602 | @ (posedge l2.$clk); | |
603 | opes = packet_received.get("opes"); | |
604 | if (!matched_packet) { | |
605 | dump_expects = 1; | |
606 | trigger(ONE_BLAST, expect_data_received); | |
607 | if (opes[0]) { | |
608 | packet_received.display("Got Unexpected L2 Packet", 1); | |
609 | } else { | |
610 | packet_received.display("Warning: Got Unexpected L2 Packet"); | |
611 | } | |
612 | } else { | |
613 | packet_received.display("L2 Packet Expect Satisfied"); | |
614 | } | |
615 | matched_packet = 0; | |
616 | } | |
617 | ||
618 | function bit ios_l2_stub::expect(l2_packet expected_packet, integer timeout = 100000) { | |
619 | ||
620 | integer timer = 0; | |
621 | bit not_matched = 1; | |
622 | l2_packet packet; | |
623 | ||
624 | packet = expected_packet; | |
625 | fork | |
626 | { | |
627 | while (timeout > timer) { | |
628 | @ (posedge l2.$clk); | |
629 | timer++; | |
630 | } | |
631 | if (not_matched) { | |
632 | packet.display("Expected packet timeout", 1); | |
633 | not_matched = 0; | |
634 | } | |
635 | } | |
636 | { | |
637 | while (not_matched) { | |
638 | sync(ANY, expect_data_received); | |
639 | semaphore_get(WAIT, check_semph_id, 1); | |
640 | if (!matched_packet) { | |
641 | if (dump_expects) { | |
642 | packet.display("Dumping expect"); | |
643 | } | |
644 | if (transaction_in.compare(packet)) { | |
645 | matched_packet = 1; | |
646 | not_matched = 0; | |
647 | timer = timeout; | |
648 | //sent_read_data = packet.get("read_data"); | |
649 | //printf("Got read data of %0h", sent_read_data); | |
650 | //printf("--- Packet Matched! ---\n"); | |
651 | } | |
652 | } | |
653 | semaphore_put(check_semph_id, 1); | |
654 | @ (posedge l2.$clk); | |
655 | } | |
656 | } | |
657 | join any | |
658 | } | |
659 | ||
660 | task ios_l2_stub::look_for_packets() { | |
661 | ||
662 | l2_packet l2_pkt[16]; | |
663 | integer total = 0; | |
664 | ||
665 | dbg.dispmon(myname, MON_NORMAL, psprintf("[%1d] Starting to look for packets ", bank_number)); | |
666 | while (1) { | |
667 | @ (posedge l2.$clk); | |
668 | if (enable_l2_checker){ | |
669 | if (!l2_list.empty()) { | |
670 | l2_pkt[total] = l2_list.front(); | |
671 | l2_pkt[total].display("Pulled L2 Packet off list"); | |
672 | if (l2_pkt[total].get("last_packet")) { | |
673 | //printf("Got Last Packet\n"); | |
674 | set_packet_expect(l2_pkt, total); | |
675 | //printf("Setting total to 0\n"); | |
676 | total = 0; | |
677 | } else { | |
678 | total = total + 1; | |
679 | //printf("Incrementing total to %0d\n", total); | |
680 | } | |
681 | l2_list.pop_front(); | |
682 | } | |
683 | } | |
684 | } | |
685 | } | |
686 | ||
687 | task ios_l2_stub::set_packet_expect(l2_packet l2_pkt[16], integer total) { | |
688 | ||
689 | integer i; | |
690 | ||
691 | fork { | |
692 | for (i = 0; i <= total; i++) { | |
693 | l2_pkt[i].display("Setting Expect for L2 Packet"); | |
694 | void = expect(l2_pkt[i].copy()); | |
695 | //printf("i is %0d and total is %0d\n", i, total); | |
696 | } | |
697 | //printf("Got the Last packet of this group\n"); | |
698 | } join none | |
699 | } | |
700 |