Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: N2fcilupeuIngressDmaWrStr.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 "l2_packet.vrh" | |
36 | #include "ios_l2_stub.vrh" | |
37 | #include "fc_top.if.vrh" | |
38 | ||
39 | extern VeraList_l2_packet l2_list0; | |
40 | extern VeraList_l2_packet l2_list1; | |
41 | extern VeraList_l2_packet l2_list2; | |
42 | extern VeraList_l2_packet l2_list3; | |
43 | extern VeraList_l2_packet l2_list4; | |
44 | extern VeraList_l2_packet l2_list5; | |
45 | extern VeraList_l2_packet l2_list6; | |
46 | extern VeraList_l2_packet l2_list7; | |
47 | extern ios_l2_stub l2_stub[]; | |
48 | ||
49 | extern StandardDisplay dbg; | |
50 | ||
51 | ||
52 | class N2fcDmaWrPEUStr extends PEUStrBase { | |
53 | ||
54 | local bit [63:0] N2fcSAddr; | |
55 | local bit [63:0] N2fcEAddr; | |
56 | local bit N2fcAddrSpecified; | |
57 | local bit [31:0] length; | |
58 | local bit [31:0] dat; | |
59 | bit [511:0] write_data = 0; | |
60 | bit [63:0] start_data = 0; | |
61 | bit msi_dma = 0; | |
62 | N2fcIommuMgr MMU; | |
63 | bit [7:0] bus_id; | |
64 | ||
65 | integer f_len; // The packet's payload length | |
66 | bit[3:0] f_firstDWBE; // It's "first DWBE" field | |
67 | bit[3:0] f_lastDWBE; // It's "last DWBE" field | |
68 | integer f_bndy; // The address' boundary | |
69 | bit f_lenSpecified; // Was a length specified? | |
70 | bit f_firstSpecified; // Was a "firstDWBE" specified? | |
71 | bit f_lastSpecified; // Was a "lastDWBE" specified? | |
72 | bit f_bndySpecified; // Was an addr bndy specified? | |
73 | integer f_tc; // The packet's traffic class | |
74 | ||
75 | function bit [63:0] hashpa (bit [63:0] pa) { | |
76 | if (probe_if.hashing && ~pa[39]) | |
77 | hashpa = {pa[63:18], pa[32:28] ^ pa[17:13], pa[19:18] ^ pa[12:11], pa[10:0]}; | |
78 | else | |
79 | hashpa = pa; | |
80 | } | |
81 | ||
82 | task new( PEUTestEnv a_env) { | |
83 | bit [3:0] index; | |
84 | ||
85 | super.new( a_env ); | |
86 | ||
87 | if (!msi_dma){ | |
88 | if (!get_plus_arg(CHECK, "DISABLE_L2_CHECKER")) { | |
89 | for ( index=0; index <8; index++){ | |
90 | l2_stub[index].enable_l2_checker = 1; | |
91 | l2_stub[index].enable_l2_wr_checker = 1; | |
92 | } | |
93 | } | |
94 | } | |
95 | f_lenSpecified = 0; | |
96 | f_firstSpecified = 0; | |
97 | f_lastSpecified = 0; | |
98 | f_bndySpecified = 0; | |
99 | N2fcAddrSpecified = 0; | |
100 | f_tc = -1; | |
101 | MMU = new(); | |
102 | ||
103 | printf ("%0d- N2fcDmaWrPEUStr:new first random # = %0h\n", get_time(LO), random() ); | |
104 | } | |
105 | ||
106 | task SetLen( integer a_len ) | |
107 | { | |
108 | f_len = a_len; | |
109 | f_lenSpecified = 1; | |
110 | } | |
111 | task SetFirstDWBE( bit[3:0] a_dwbe ) | |
112 | { | |
113 | f_firstDWBE = a_dwbe; | |
114 | f_firstSpecified = 1; | |
115 | } | |
116 | task SetLastDWBE( bit[3:0] a_dwbe ) | |
117 | { | |
118 | f_lastDWBE = a_dwbe; | |
119 | f_lastSpecified = 1; | |
120 | } | |
121 | task SetAddrBndy( integer a_bndy ) | |
122 | { | |
123 | f_bndy = a_bndy; | |
124 | f_bndySpecified = 1; | |
125 | } | |
126 | ||
127 | task N2fcSetAddr( bit [63:0] i_saddr, bit [63:0] i_eaddr ) | |
128 | { | |
129 | N2fcAddrSpecified = 1; | |
130 | N2fcSAddr = i_saddr; | |
131 | N2fcEAddr = i_eaddr; | |
132 | } | |
133 | ||
134 | //------------------------------------------------------------------- | |
135 | // Method Name: | |
136 | // Description: | |
137 | //------------------------------------------------------------------- | |
138 | function bit[31:0] gen_4bytes_exp_data (bit [31:0] data, bit [3:0] bytemask){ | |
139 | integer index; | |
140 | ||
141 | for (index =0; index < 4; index++){ | |
142 | if (bytemask[3-index]) { | |
143 | gen_4bytes_exp_data[31-8*index:32-8*(index+1)] = data[31-8*index:32-8*(index+1)]; | |
144 | } else { | |
145 | gen_4bytes_exp_data[31-8*index:32-8*(index+1)] = 8'hx; | |
146 | } | |
147 | } | |
148 | } | |
149 | ||
150 | //------------------------------------------------------------------- | |
151 | // Method Name: | |
152 | // Description: | |
153 | //------------------------------------------------------------------- | |
154 | task gen_exp_l2_pkt8bytes( | |
155 | bit [31:0] dma_dword_len, | |
156 | var bit [63:0] address, | |
157 | bit bypass_first_word, | |
158 | bit bypass_last_word, | |
159 | var integer ingressData, | |
160 | bit [7:0] ingressTag | |
161 | ){ | |
162 | integer i, j; | |
163 | bit [7:0] bytemask; | |
164 | l2_packet l2_pkt = new("L2Expect", dbg); | |
165 | bit last_packet = 0; | |
166 | bit [2:0] bank_number; | |
167 | reg [3:0] pbank = {probe_if.ba67, probe_if.ba45, probe_if.ba23, probe_if.ba01}; | |
168 | integer index; | |
169 | write_data = 0; | |
170 | for (j = 0; j < dma_dword_len; j++) { | |
171 | bit [31:0] tmp_data; | |
172 | ||
173 | ||
174 | if (j==0 && address[2]){ | |
175 | index = 1; | |
176 | } else if (j == 0 ){ | |
177 | index = 0; | |
178 | } | |
179 | if (index%2 == 0){ | |
180 | bytemask = 8'hff; | |
181 | } | |
182 | tmp_data = f_env.nextPayloadDW( ingressData ); | |
183 | ||
184 | if (j == 0 && !bypass_first_word){ // modify for first words | |
185 | if (address[2]){ | |
186 | bytemask [3:0] = {f_firstDWBE[0],f_firstDWBE[1],f_firstDWBE[2],f_firstDWBE[3]}; | |
187 | bytemask [7:4] = 0; | |
188 | } else { | |
189 | bytemask [7:4] = {f_firstDWBE[0],f_firstDWBE[1],f_firstDWBE[2],f_firstDWBE[3]}; | |
190 | if (dma_dword_len == 1){ | |
191 | bytemask [3:0] = 0; | |
192 | } | |
193 | } | |
194 | } else if (j == dma_dword_len-1 && !bypass_last_word){ // modify for last words | |
195 | if (address[2]){ | |
196 | // bytemask[7:4] = 0; | |
197 | bytemask[3:0] = {f_lastDWBE[0], f_lastDWBE[1], f_lastDWBE[2], f_lastDWBE[3]}; | |
198 | } else { | |
199 | bytemask[7:4] = {f_lastDWBE[0], f_lastDWBE[1], f_lastDWBE[2], f_lastDWBE[3]}; | |
200 | bytemask [3:0] = 0; | |
201 | } | |
202 | } | |
203 | ||
204 | ||
205 | if (index%2 == 0){ | |
206 | write_data[63:32] = gen_4bytes_exp_data(tmp_data, bytemask[7:4]); | |
207 | if (j == dma_dword_len-1){ | |
208 | write_data[31:0] = gen_4bytes_exp_data(tmp_data, bytemask[3:0]); | |
209 | } | |
210 | } else { | |
211 | write_data[31:0] = gen_4bytes_exp_data(tmp_data, bytemask[3:0]); | |
212 | if (j == 0 ){ | |
213 | write_data[63:32] = gen_4bytes_exp_data(tmp_data, bytemask[7:4]); | |
214 | ||
215 | } | |
216 | } | |
217 | ||
218 | last_packet = ((j == dma_dword_len - 1) || (address[5:2] == 4'b1111)); | |
219 | ||
220 | if(index%2 == 1 || j == dma_dword_len -1 ){ | |
221 | ||
222 | l2_pkt.set("tag", ingressTag); | |
223 | l2_pkt.set("address", hashpa({address[63:3], 3'h0}) ); | |
224 | l2_pkt.set("data", write_data); | |
225 | l2_pkt.set("bytemask", bytemask); | |
226 | l2_pkt.set("opes", 4'b1101); | |
227 | // printf("last_packet is %0b", last_packet); | |
228 | l2_pkt.set("last_packet", last_packet); | |
229 | //bank_number = address[8:6]; | |
230 | bank_number = address[8:6]; | |
231 | if (probe_if.pm === 1'b1) | |
232 | bank_number = pbank_sel(pbank, bank_number); | |
233 | ||
234 | l2_pkt.set("bank_number", bank_number); | |
235 | l2_pkt.display("Putting a packet on the L2 Expect Queue"); | |
236 | case (bank_number) { | |
237 | 0: l2_list0.push_back(l2_pkt.copy()); | |
238 | 1: l2_list1.push_back(l2_pkt.copy()); | |
239 | 2: l2_list2.push_back(l2_pkt.copy()); | |
240 | 3: l2_list3.push_back(l2_pkt.copy()); | |
241 | 4: l2_list4.push_back(l2_pkt.copy()); | |
242 | 5: l2_list5.push_back(l2_pkt.copy()); | |
243 | 6: l2_list6.push_back(l2_pkt.copy()); | |
244 | 7: l2_list7.push_back(l2_pkt.copy()); | |
245 | } | |
246 | } | |
247 | address = address + 4; | |
248 | index++; | |
249 | } | |
250 | } | |
251 | ||
252 | //------------------------------------------------------------------- | |
253 | // Method Name: | |
254 | // Description: | |
255 | //------------------------------------------------------------------- | |
256 | task Execute() | |
257 | { | |
258 | bit [63:0] address = 64'b0; // Virtual address | |
259 | bit [39:0] pa = 40'b0; // Physical address | |
260 | bit [63:0] response = 64'b0; | |
261 | bit [5:0] start_add; | |
262 | ||
263 | l2_packet l2_pkt; | |
264 | ||
265 | bit [7:0] bytemask; | |
266 | bit [2:0] bank_number; | |
267 | ||
268 | bit last_packet; | |
269 | ||
270 | bit[PEC_PCI__HDR] ingressHdr; // The ingress TLP's header | |
271 | integer ingressData; // A payload descriptor | |
272 | bit[7:0] ingressTag; // The tag for the TLP | |
273 | reg [3:0] pbank = {probe_if.ba67, probe_if.ba45, probe_if.ba23, probe_if.ba01}; | |
274 | ||
275 | if (N2fcAddrSpecified == 1) { | |
276 | address = N2fcSAddr; | |
277 | } | |
278 | else { | |
279 | error ("N2fcDmaWrPEUStr::Execute() : the start and end address must be specifed\n"); | |
280 | } | |
281 | ||
282 | // First, get in line for a DMA tag... | |
283 | f_env.allocDmaTag( ingressTag ); | |
284 | ||
285 | // Then build a TLP | |
286 | if ( f_lenSpecified ) | |
287 | f_env.genIngressWrReq( ingressTag, ingressHdr, ingressData, f_len ); | |
288 | else | |
289 | error ("N2fcDmaWrPEUStr::Execute() : the length must be specifed\n"); | |
290 | ||
291 | if( address[63:32] != 32'h00000000 ) { | |
292 | ingressHdr[PEC_PCI__FMT_4DW] = 1; // 4DW hdr fmt, 64-bit address | |
293 | ingressHdr[PEC_PCI__ADDR] = address; | |
294 | } | |
295 | else { | |
296 | ingressHdr[PEC_PCI__FMT_4DW] = 0; // 3DW hdr fmt, 32-bit address | |
297 | ingressHdr[PEC_PCI__ADDR32] = address[31:0]; | |
298 | } | |
299 | ||
300 | // set the Traffic Class | |
301 | if( f_tc != -1 ) { | |
302 | ingressHdr[PEC_PCI__TC] = f_tc; | |
303 | } | |
304 | ||
305 | printf ("%0d- UDEBUG N2fcDmaWrPEUStr:Execute Address = %0h Byp = %0h, Len = 'd%0d\n", | |
306 | get_time(LO), address, address[63:39], f_len); | |
307 | ||
308 | // ...and set fields as requested | |
309 | // by the caller. | |
310 | ||
311 | if ( f_bndySpecified ) | |
312 | f_env.setAddrBndy( ingressHdr, f_bndy, 4 ); | |
313 | ||
314 | if ( f_firstSpecified ) | |
315 | ingressHdr[PEC_PCI__FIRST_DWBE] = f_firstDWBE; | |
316 | if ( f_lastSpecified ) | |
317 | ingressHdr[PEC_PCI__LAST_DWBE] = f_lastDWBE; | |
318 | ||
319 | // add for MSI data | |
320 | if (msi_dma) { | |
321 | ingressData = start_data; | |
322 | } | |
323 | // add for MSI data | |
324 | ||
325 | ||
326 | f_env.drivePCIE( ingressHdr, ingressData, *,*,*,*,*,1 ); | |
327 | ||
328 | bus_id = ingressHdr[ILUPEU_TLP_HDR_REQ_BUS_NUM_BITS]; | |
329 | if (msi_dma) { | |
330 | gen_msi_exp_data(address, ingressData, ingressTag, ingressHdr[PEC_PCI__REQ_ID]); | |
331 | } | |
332 | else if ((f_len > 1) || | |
333 | ((f_len == 1) && ingressHdr[PEC_PCI__FIRST_DWBE])) { | |
334 | integer index; | |
335 | bit bypass_first_word = 0; | |
336 | bit do_cache_line; | |
337 | ||
338 | l2_pkt = new("L2Expect", dbg); | |
339 | ||
340 | if (MMU.get_physical_address(address, pa, bus_id, 1)) { | |
341 | address = pa; // use the physical address from here on | |
342 | } | |
343 | else { | |
344 | printf("N2fcDmaWrPEUStr:Execute problem found during translation, so no L2 expects will be setup.\n"); | |
345 | return; | |
346 | } | |
347 | ||
348 | start_add = address[5:0] ; | |
349 | ||
350 | if ((f_len >(64-start_add+3)/4 ) && (start_add !==0)){ | |
351 | gen_exp_l2_pkt8bytes((64-start_add+3)/4, address, 0,1, ingressData,ingressTag); | |
352 | ||
353 | bypass_first_word = 1; | |
354 | f_len = f_len - (64-start_add+3)/4 ; | |
355 | address[5:0] = 0; | |
356 | } // align to catch line start address | |
357 | ||
358 | ||
359 | if (f_len > 16 && (address[5:0] == 0)){ | |
360 | do_cache_line =1; | |
361 | } else if (f_len === 16 && (address[5:0] == 0)){ | |
362 | if (&f_lastDWBE){ | |
363 | do_cache_line = 1; | |
364 | } else { | |
365 | do_cache_line = 0; | |
366 | } | |
367 | } else { | |
368 | do_cache_line = 0; | |
369 | } | |
370 | ||
371 | while (do_cache_line){ // f_len is dword length | |
372 | bytemask = 8'h0; | |
373 | write_data = 0; | |
374 | for (index=0; index <64/4; index++){ | |
375 | write_data[511-32*index:512-32*(index+1)] = f_env.nextPayloadDW( ingressData ); | |
376 | ||
377 | } | |
378 | //last_packet = (f_len == 64/4); | |
379 | last_packet = 1; | |
380 | ||
381 | l2_pkt.set("tag", ingressTag); | |
382 | l2_pkt.set("address", hashpa(address) ); | |
383 | l2_pkt.set("data", write_data); | |
384 | l2_pkt.set("bytemask", bytemask); | |
385 | l2_pkt.set("opes", 4'b1101); | |
386 | //printf("last_packet is %0b", last_packet); | |
387 | l2_pkt.set("last_packet", last_packet); | |
388 | bank_number = address[8:6]; | |
389 | if (probe_if.pm === 1'b1) | |
390 | bank_number = pbank_sel(pbank, bank_number); | |
391 | l2_pkt.set("bank_number", bank_number); | |
392 | l2_pkt.display("Putting catch line packet on the L2 Expect Queue"); | |
393 | case (bank_number) { | |
394 | 0: l2_list0.push_back(l2_pkt.copy()); | |
395 | 1: l2_list1.push_back(l2_pkt.copy()); | |
396 | 2: l2_list2.push_back(l2_pkt.copy()); | |
397 | 3: l2_list3.push_back(l2_pkt.copy()); | |
398 | 4: l2_list4.push_back(l2_pkt.copy()); | |
399 | 5: l2_list5.push_back(l2_pkt.copy()); | |
400 | 6: l2_list6.push_back(l2_pkt.copy()); | |
401 | 7: l2_list7.push_back(l2_pkt.copy()); | |
402 | } | |
403 | address = address + 64; | |
404 | response = response + 64; | |
405 | f_len = f_len - 64/4; | |
406 | if (f_len > 16 && (address[5:0] == 0)){ | |
407 | do_cache_line =1; | |
408 | } else if (f_len === 16 && (address[5:0] == 0)){ | |
409 | if (&f_lastDWBE){ | |
410 | do_cache_line = 1; | |
411 | } else { | |
412 | do_cache_line = 0; | |
413 | } | |
414 | } else { | |
415 | do_cache_line = 0; | |
416 | } | |
417 | ||
418 | ||
419 | bypass_first_word = 1; | |
420 | } | |
421 | if (f_len >0) { | |
422 | gen_exp_l2_pkt8bytes(f_len, address, bypass_first_word,0,ingressData,ingressTag); | |
423 | } | |
424 | } | |
425 | ||
426 | f_env.freeDmaTag( ingressTag ); | |
427 | ||
428 | } /* end Execute */ | |
429 | ||
430 | //------------------------------------------------------------------- | |
431 | // Method Name: pbank_sel | |
432 | // Description: Calculate the bank number based on the partial bank | |
433 | // controls. | |
434 | //------------------------------------------------------------------- | |
435 | function reg[2:0] pbank_sel(reg[3:0] pbank, reg[2:0] bank_sel) | |
436 | { | |
437 | reg [2:0] result = bank_sel; | |
438 | ||
439 | case (pbank) { | |
440 | 4'b0001: result[2:1] = 2'b00; | |
441 | 4'b0010: result[2:1] = 2'b01; | |
442 | 4'b0011: result[2] = 1'b0; | |
443 | 4'b0100: result[2:1] = 2'b10; | |
444 | 4'b0101: result[2:1] = {bank_sel[1], 1'b0}; | |
445 | 4'b0110: result[2:1] = {bank_sel[1], ~bank_sel[1]}; | |
446 | 4'b1000: result[2:1] = 2'b11; | |
447 | 4'b1001: result[2:1] = {bank_sel[1], bank_sel[1]}; | |
448 | 4'b1010: result[2:1] = {bank_sel[1], 1'b1}; | |
449 | 4'b1100: result[2:1] = {1'b1, bank_sel[1]}; | |
450 | 4'b1111: result = bank_sel; | |
451 | default: | |
452 | error ("ERROR! illegal partial bank selection: %0b\n", pbank); | |
453 | } | |
454 | ||
455 | pbank_sel = result; | |
456 | } | |
457 | ||
458 | //------------------------------------------------------------------- | |
459 | // Method Name: gen_msi_exp_data | |
460 | // Description: Generate the expected L2 write packet for an MSI msg. | |
461 | //------------------------------------------------------------------- | |
462 | task gen_msi_exp_data (bit [63:0] msiaddress, | |
463 | bit [31:0] msidata, | |
464 | bit [ 7:0] ingressTag, | |
465 | bit [15:0] rid) | |
466 | { | |
467 | integer MSI_num = msidata[7:0]; | |
468 | integer EQ_num; | |
469 | bit [63:0] address; | |
470 | bit [39:0] pa = 40'b0; // Physical address | |
471 | bit [63:0] word0, word1; | |
472 | bit [7:0] bytemask = 0; | |
473 | bit [2:0] bank_number; | |
474 | reg [3:0] pbank = {probe_if.ba67, probe_if.ba45, probe_if.ba23, probe_if.ba01}; | |
475 | bit [6:0] tmpEQTail; | |
476 | ||
477 | l2_packet l2_pkt; | |
478 | ||
479 | // Figure out if the MSI is mapped | |
480 | if( !PiuCsrs.MsiIsValid(MSI_num) ) return; | |
481 | ||
482 | // If an MSI has been sent to the EQ, but not cleared, | |
483 | // we can't do it again | |
484 | if( PiuCsrs.MsiIsEqWr(MSI_num) ) return; | |
485 | EQ_num = PiuCsrs.GetMsiEqNum(MSI_num); | |
486 | ||
487 | //if( PiuCsrs.EQBaseAddr[63:39] != 25'b1111_1111_1111_1100_0000_0000_0) { | |
488 | // error("ERROR: N2fcDmaWrPEUStr::gen_msi_exp_data - a non-bypass EQ BASE address is not supported!"); | |
489 | //} | |
490 | ||
491 | // check if the EQ table is full | |
492 | tmpEQTail = PiuCsrs.EQTail[EQ_num] + 1; | |
493 | if (tmpEQTail == PiuCsrs.EQHead[EQ_num]) { | |
494 | printf("Not writting to EQ[%d] for MSI %d because it is full\n", EQ_num, MSI_num); | |
495 | return; | |
496 | } | |
497 | ||
498 | // all seems well ... | |
499 | address = PiuCsrs.EQBaseAddr[63:0] + (EQ_num * 8*1024) + (PiuCsrs.EQTail[EQ_num] * 64); | |
500 | ||
501 | MMU.set_msi(1); | |
502 | if (MMU.get_physical_address(address, pa, bus_id, 1)) { | |
503 | address = pa; // use the physical address from here on | |
504 | } | |
505 | else { | |
506 | printf("N2fcDmaWrPEUStr:gen_msi_exp_data problem found during translation, so no L2 expects will be setup.\n"); | |
507 | MMU.set_msi(0); | |
508 | return; | |
509 | } | |
510 | MMU.set_msi(0); | |
511 | ||
512 | PiuCsrs.SetMsiEqWr(MSI_num); | |
513 | PiuCsrs.EQTail[EQ_num]++; | |
514 | ||
515 | // set up the msi data that will be sent | |
516 | msidata[15: 8] = msidata[7:0] + 1; | |
517 | msidata[23:16] = msidata[7:0] + 2; | |
518 | msidata[31:24] = msidata[7:0] + 3; | |
519 | ||
520 | // set up expected data (from table 16-19 of the PRM) | |
521 | word0[63] = 0; | |
522 | word0[62:56] = (msiaddress[63:32]==0) ? 7'b1011000 : 7'b1111000; // FMT/TYPE | |
523 | word0[55:46] = 1; // LENGTH in DW | |
524 | word0[45:32] = msiaddress[15:2]; // ADDR[15:2] | |
525 | word0[31:16] = rid; word0[15: 0] = msidata[15:0]; // DATA | |
526 | ||
527 | word1[63:16] = msiaddress[63:16]; // ADDR[63:16] | |
528 | word1[15: 0] = msidata[31:16]; // DATA | |
529 | ||
530 | write_data[511-64*0:512-64*1] = word0; | |
531 | write_data[511-64*1:512-64*2] = word1; | |
532 | write_data[511-64*2:512-64*3] = 0; | |
533 | write_data[511-64*3:512-64*4] = 0; | |
534 | write_data[511-64*4:512-64*5] = 0; | |
535 | write_data[511-64*5:512-64*6] = 0; | |
536 | write_data[511-64*6:512-64*7] = 0; | |
537 | write_data[511-64*7:512-64*8] = 0; | |
538 | ||
539 | l2_pkt = new("L2Expect", dbg); | |
540 | ||
541 | l2_pkt.set("tag", ingressTag); | |
542 | l2_pkt.set("address", hashpa(address) ); | |
543 | l2_pkt.set("data", write_data); | |
544 | l2_pkt.set("bytemask", bytemask); | |
545 | l2_pkt.set("opes", 4'b1101); | |
546 | l2_pkt.set("last_packet", 1); | |
547 | bank_number = address[8:6]; | |
548 | if (probe_if.pm === 1'b1) | |
549 | bank_number = pbank_sel(pbank, bank_number); | |
550 | l2_pkt.set("bank_number", bank_number); | |
551 | l2_pkt.display("Putting cache line packet on the L2 Expect Queue"); | |
552 | case (bank_number) { | |
553 | 0: l2_list0.push_back(l2_pkt.copy()); | |
554 | 1: l2_list1.push_back(l2_pkt.copy()); | |
555 | 2: l2_list2.push_back(l2_pkt.copy()); | |
556 | 3: l2_list3.push_back(l2_pkt.copy()); | |
557 | 4: l2_list4.push_back(l2_pkt.copy()); | |
558 | 5: l2_list5.push_back(l2_pkt.copy()); | |
559 | 6: l2_list6.push_back(l2_pkt.copy()); | |
560 | 7: l2_list7.push_back(l2_pkt.copy()); | |
561 | } | |
562 | ||
563 | } | |
564 | ||
565 | } |