Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / cmp / vera / classes / utilsClass.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: utilsClass.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 <std_display_defines.vri>
37#include <ccxDevicesDefines.vri>
38
39#include <globals.vri>
40
41#include <baseParamsClass.vrh>
42#include <sparcParams.vrh>
43#include <baseUtilsClass.vrh>
44#include <sparcBenchUtils.vrh>
45#include <std_display_class.vrh>
46#include <basePktClass.vrh>
47#include <cpxPktClass.vrh>
48#include <pcxPktClass.vrh>
49#include <ccxDevBaseBFM.vrh>
50#include <ccxDevMemBFM.vrh>
51#include <ccxDevSpcBFM.vrh>
52#include <memArray.vrh>
53#include <ccx_tag_class.vrh>
54
55#ifdef CMP_BENCH
56#include <MCUStub_class.vrh>
57#endif
58
59
60#include <ccxPktMon.vrh>
61
62#define CLASSNAME Utils
63#define CLASSNAMEQ "Utils"
64
65class CLASSNAME extends SparcBenchUtils {
66
67 local string className = "UtilsClass";
68 local StandardDisplay dbg;
69 local integer clockPeriod;
70
71 // rands
72 local randc reg [5:0] startThread;
73 // end rands
74
75// local integer count = 0;
76
77
78 task new(StandardDisplay dbgHndl, integer clockPeriod = 100);
79 task initTB(integer useMCUbfms = 0,
80 reg useL1Tags = 0,
81 reg useL2bfms = 0,
82 reg loadOnlyIOmem = 1);
83 task resetDut();
84 task initDut(integer wait = 0);
85// local task enableL2(bit [7:0] enable=8'hff, reg [5:0] useThread=63);
86 //local task sendPOR(reg [31:0] resetThis=0, integer sendPort = DEV_NCU);
87 task sendIntrLoop(integer sendPort = DEV_NCU);
88 task sendIntr(reg [5:0] tid,
89 reg [1:0] type,
90 reg [5:0] vect,
91 integer sendPort = DEV_NCU);
92
93 task randEvict();
94
95}
96
97
98task CLASSNAME::new(StandardDisplay dbgHndl, integer clockPeriod = 100) {
99 super.new(dbgHndl, clockPeriod);
100 srandom(gSeed,this);
101 this.dbg = dbgHndl;
102 void = randomize(); // keep!
103}
104
105task CLASSNAME::resetDut()
106{
107 super.resetDut();
108}
109
110
111// useMCUbfms 0=no, 1=yes, 2=monitor
112task CLASSNAME::initTB(integer useMCUbfms = 0,
113 reg useL1Tags = 0,
114 reg useL2bfms = 0,
115 reg loadOnlyIOmem = 1) { // do not load vera array if !using it
116
117 integer i;
118 VeraRandomState rstate;
119
120
121#ifndef CMP0
122 if (gParam.asmDiagName != null) {
123 // mem array.
124 // 3rd param will return random data (in place of 0) from mem if set.
125 gMem = new(0,gDbg,0);
126 // Initialize main memory from mem.image
127 gMem.loadMem("mem.image", loadOnlyIOmem, gParam.hash_on, this);
128 }
129#endif
130
131 // Put all binds into global handles so that various objects
132 // will have access to HW.
133
134 // SPC
135 gPcxPort[DEV_SPC0] = pcxBindDEV_SPC0;
136 gCpxPort[DEV_SPC0] = cpxBindDEV_SPC0;
137 gPcxPort[DEV_SPC1] = pcxBindDEV_SPC1;
138 gCpxPort[DEV_SPC1] = cpxBindDEV_SPC1;
139 gPcxPort[DEV_SPC2] = pcxBindDEV_SPC2;
140 gCpxPort[DEV_SPC2] = cpxBindDEV_SPC2;
141 gPcxPort[DEV_SPC3] = pcxBindDEV_SPC3;
142 gCpxPort[DEV_SPC3] = cpxBindDEV_SPC3;
143 gPcxPort[DEV_SPC4] = pcxBindDEV_SPC4;
144 gCpxPort[DEV_SPC4] = cpxBindDEV_SPC4;
145 gPcxPort[DEV_SPC5] = pcxBindDEV_SPC5;
146 gCpxPort[DEV_SPC5] = cpxBindDEV_SPC5;
147 gPcxPort[DEV_SPC6] = pcxBindDEV_SPC6;
148 gCpxPort[DEV_SPC6] = cpxBindDEV_SPC6;
149 gPcxPort[DEV_SPC7] = pcxBindDEV_SPC7;
150 gCpxPort[DEV_SPC7] = cpxBindDEV_SPC7;
151
152 // L2
153#ifndef RTL_NO_BNK01
154 gPcxPort[DEV_MEM0] = pcxBindDEV_MEM0;
155 gCpxPort[DEV_MEM0] = cpxBindDEV_MEM0;
156 gPcxPort[DEV_MEM1] = pcxBindDEV_MEM1;
157 gCpxPort[DEV_MEM1] = cpxBindDEV_MEM1;
158#endif
159#ifndef RTL_NO_BNK23
160 gPcxPort[DEV_MEM2] = pcxBindDEV_MEM2;
161 gCpxPort[DEV_MEM2] = cpxBindDEV_MEM2;
162 gPcxPort[DEV_MEM3] = pcxBindDEV_MEM3;
163 gCpxPort[DEV_MEM3] = cpxBindDEV_MEM3;
164#endif
165#ifndef RTL_NO_BNK45
166 gPcxPort[DEV_MEM4] = pcxBindDEV_MEM4;
167 gCpxPort[DEV_MEM4] = cpxBindDEV_MEM4;
168 gPcxPort[DEV_MEM5] = pcxBindDEV_MEM5;
169 gCpxPort[DEV_MEM5] = cpxBindDEV_MEM5;
170#endif
171#ifndef RTL_NO_BNK67
172 gPcxPort[DEV_MEM6] = pcxBindDEV_MEM6;
173 gCpxPort[DEV_MEM6] = cpxBindDEV_MEM6;
174 gPcxPort[DEV_MEM7] = pcxBindDEV_MEM7;
175 gCpxPort[DEV_MEM7] = cpxBindDEV_MEM7;
176#endif
177
178 // ncu
179 gPcxPort[DEV_NCU] = pcxBindDEV_NCU;
180 gCpxPort[DEV_NCU] = cpxBindDEV_NCU;
181
182 // basic probes
183 gProbesPort = probesBind;
184
185#ifdef CMP_BENCH
186 if (useMCUbfms) {
187 // MCU binds
188#ifndef RTL_NO_BNK01
189 gMcuPort[0] = mcu_bind_0;
190 gMcuPort[1] = mcu_bind_1;
191 gMcuDataPort[0] = mcu_bind_data_01;
192 gMcuDataPort[1] = mcu_bind_data_01;
193#endif
194#ifndef RTL_NO_BNK23
195 gMcuPort[2] = mcu_bind_2;
196 gMcuPort[3] = mcu_bind_3;
197 gMcuDataPort[2] = mcu_bind_data_23;
198 gMcuDataPort[3] = mcu_bind_data_23;
199#endif
200#ifndef RTL_NO_BNK45
201 gMcuPort[4] = mcu_bind_4;
202 gMcuPort[5] = mcu_bind_5;
203 gMcuDataPort[4] = mcu_bind_data_45;
204 gMcuDataPort[5] = mcu_bind_data_45;
205#endif
206#ifndef RTL_NO_BNK67
207 gMcuPort[6] = mcu_bind_6;
208 gMcuPort[7] = mcu_bind_7;
209 gMcuDataPort[6] = mcu_bind_data_67;
210 gMcuDataPort[7] = mcu_bind_data_67;
211#endif
212 }
213#endif
214
215#ifdef NOL2RTL
216 // these are used when L2 is BFMs, not RTL
217 gLdStSyncPort[8] = ldStSync_bind_b0;
218 gLdStSyncPort[9] = ldStSync_bind_b1;
219 gLdStSyncPort[10] = ldStSync_bind_b2;
220 gLdStSyncPort[11] = ldStSync_bind_b3;
221 gLdStSyncPort[12] = ldStSync_bind_b4;
222 gLdStSyncPort[13] = ldStSync_bind_b5;
223 gLdStSyncPort[14] = ldStSync_bind_b6;
224 gLdStSyncPort[15] = ldStSync_bind_b7;
225#endif
226 gLdStSyncPort[16] = ldStSync_bind_b8;
227
228
229 @(negedge CLOCK);
230
231 // Always Initialize ncu BFM/stub as ACTIVE
232 gCcxDevMem[DEV_NCU] = new(DEV_NCU); // gCcxDevMem[15] #8 mem device
233 gCcxDevice[DEV_NCU] = gCcxDevMem[DEV_NCU]; // generic handle gCcxDevice[16] = gCcxDevMem[8]
234
235 // Always Initialize core BFMs/stubs if enabled & no real core on port
236 for (i=DEV_SPC0;i<=DEV_SPC7; i++) { // 0-7
237 if (gParam.enableSpcBFM[i])
238 if (gParam.coreAvilable[i]) gCcxDevSpc[i] = new(i,1,0);
239 else gCcxDevSpc[i] = new(i,0,0);
240 else gCcxDevSpc[i] = null;
241 gCcxDevice[i] = gCcxDevSpc[i]; // generic handle 0-7
242 }
243
244 // Always Initialize L1 duplicate tags, one pair for each core
245 for (i=0;i<8;i++) {
246 if ((useL1Tags || useL2bfms) && gParam.coreAvilable[i]) {
247 dtag[i] = new (DATA_TAG, 127, 3, i);
248 itag[i] = new (INSTR_TAG, 63, 7, i);
249 }
250 else {
251 dtag[i] = null;
252 itag[i] = null;
253 }
254 }
255
256
257
258 // Initialize L2 BFMs/stubs 8-15
259 // can access as gCcxDevice[8-15]
260 if (useL2bfms) {
261
262
263 getstate(rstate, this);
264 vera_save_rng_state(this);
265
266#ifndef RTL_NO_BNK01
267 i = 8;
268 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
269 else gCcxDevMem[i] = null;
270 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
271 i = 9;
272 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
273 else gCcxDevMem[i] = null;
274 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
275#endif
276#ifndef RTL_NO_BNK23
277 i = 10;
278 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
279 else gCcxDevMem[i] = null;
280 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
281 i = 11;
282 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
283 else gCcxDevMem[i] = null;
284 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
285#endif
286#ifndef RTL_NO_BNK45
287 i = 12;
288 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
289 else gCcxDevMem[i] = null;
290 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
291 i = 13;
292 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
293 else gCcxDevMem[i] = null;
294 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
295#endif
296#ifndef RTL_NO_BNK67
297 i = 14;
298 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
299 else gCcxDevMem[i] = null;
300 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
301 i = 15;
302 if (gParam.enableMemBFM[i-8]) gCcxDevMem[i] = new(i, ~useL2bfms); // (instance, passive)
303 else gCcxDevMem[i] = null;
304 gCcxDevice[i] = gCcxDevMem[i]; // generic handle gCcxDevice[8] = gCcxDevMem[8]
305#endif
306
307
308 setstate(rstate);
309 vera_restore_rng_state(this);
310 }
311
312
313 // Initialize MCU BFMs/stubs (CMP bench)
314 if (useMCUbfms) {
315
316 getstate(rstate);
317 vera_save_rng_state(this);
318
319#ifndef RTL_NO_BNK01
320 gMcuDev[0] = new(gMcuPort[0], gMcuDataPort[0], 0);
321 gMcuDev[1] = new(gMcuPort[1], gMcuDataPort[1], 1);
322#endif
323
324#ifndef RTL_NO_BNK23
325 gMcuDev[2] = new(gMcuPort[2], gMcuDataPort[2], 2);
326 gMcuDev[3] = new(gMcuPort[3], gMcuDataPort[3], 3);
327#endif
328
329#ifndef RTL_NO_BNK45
330 gMcuDev[4] = new(gMcuPort[4], gMcuDataPort[4], 4);
331 gMcuDev[5] = new(gMcuPort[5], gMcuDataPort[5], 5);
332#endif
333
334#ifndef RTL_NO_BNK67
335 gMcuDev[6] = new(gMcuPort[6], gMcuDataPort[6], 6);
336 gMcuDev[7] = new(gMcuPort[7], gMcuDataPort[7], 7);
337#endif
338
339
340 setstate(rstate);
341 vera_restore_rng_state(this);
342 }
343
344
345 // optional packet printing
346 if (gParam.ccxPktPrintOn) {
347 CCXpktMon pktMon[17];
348
349
350 getstate(rstate);
351 vera_save_rng_state(this);
352
353 for (i=DEV_SPC0;i<=DEV_SPC7; i++) { // 0-7
354 if (gParam.coreAvilable[i]) pktMon[i] = new(i, gPcxPort[i], gCpxPort[i]);
355 else pktMon[i] = null;
356 }
357 for (i=DEV_MEM0;i<=DEV_MEM7; i++) {
358 if (gParam.banksMask[i-8]) pktMon[i] = new(i, gPcxPort[i], gCpxPort[i]);
359 else pktMon[i] = null;
360 }
361 pktMon[DEV_NCU] = new(DEV_NCU, gPcxPort[DEV_NCU], gCpxPort[DEV_NCU]);
362
363
364 setstate(rstate);
365 vera_restore_rng_state(this);
366 }
367
368
369
370}
371
372
373task CLASSNAME::initDut(integer wait = 0) {
374
375 // wait for reset done
376 if (gProbesPort.$rst_l == 0) @(posedge gProbesPort.$rst_l);
377
378 repeat (wait) @(posedge CLOCK);
379
380 // obsolete
381 //this.enableL2();
382
383}
384
385/////////////////////////////////////////////////////////////////////////////////
386// This task enables each L2 bank by
387// writing the Control Status Register of that bank.
388// Send a diag store PCX packet
389// review to use boot code
390/////////////////////////////////////////////////////////////////////////////////
391// task CLASSNAME::enableL2(bit [7:0] enable=8'hff, reg [5:0] useThread=63) {
392//
393// PcxPkt sndPkt;
394// bit [3:0] i;
395//
396// if (gCcxDevSpc[useThread[5:3]] == null)
397// error("Utils::enableL2 Can't find SPC BFM requested!!!\n");
398//
399// for(i=0; i<=7; i++) {
400// if(enable[i]) {
401//
402// sndPkt = new();
403// sndPkt.sendPort = useThread[5:3];
404// sndPkt.recvPorts = 1 << i;
405// sndPkt.valid = 1;
406// sndPkt.rqtyp = PCX_DIAG_ST;
407// sndPkt.nc = 1;
408// sndPkt.cpuId = useThread[5:3];
409// sndPkt.tid = useThread[2:0];
410// sndPkt.inv = 1;
411// sndPkt.pf = 1;
412// sndPkt.l1wayBis = 1;
413// sndPkt.l1wayMMUid = 3;
414// sndPkt.size = 8'hff;
415// sndPkt.addr = 40'ha9_0000_0000;
416// sndPkt.data = 0;
417// sndPkt.send();
418//
419// } // if
420// } // for
421//
422//
423// }
424
425
426
427
428// loop to send periodic interrupt packets like spc2 bench
429task CLASSNAME::sendIntrLoop(integer sendPort = DEV_NCU)
430{
431 reg [5:0] tid, nextTid;
432 CpxPkt reqPkt;
433 integer maxTid = 0;
434 reg [7:0] tmp;
435
436 if (gParam.intr_en == 0) return;
437
438 fork {
439
440 tmp = gParam.coreEnable;
441 repeat (8) {
442 if (tmp[0]) maxTid += 8;
443 tmp = tmp >> 1;
444 }
445 maxTid--;
446
447 // # clocks before Intr packets start
448 repeat (gParam.intr_wait) @(posedge CLOCK);
449
450 // 1st TID that get Interrupt packet
451 if (gParam.intr_tid == -1) {
452 tid = urandom_range(maxTid,0);
453 while (gParam.intr_en[tid] == 0) tid = urandom_range(maxTid,0);
454 }
455 else tid = gParam.intr_tid;
456
457 while (1) {
458 // send intr
459 PR_NORMAL (className, MON_NORMAL,
460 psprintf("Interrupt to thread T%0d (type/vec %b/%b)",
461 tid,gParam.intr_type,gParam.intr_vect));
462
463 this.sendIntr(tid,gParam.intr_type,gParam.intr_vect); // INTR_RESET,INTR_POR
464
465 // delay
466 repeat (gParam.intr_delay) @(posedge CLOCK); // # clocks between Intr packets
467
468 // pick next tid
469 tid = urandom_range(maxTid,0);
470 while (gParam.intr_en[tid] == 0) tid = urandom_range(maxTid,0);
471 }
472 } join none
473}
474
475// generic call to send intr from NCU port. for $EV user events
476task CLASSNAME::sendIntr(reg [5:0] tid,
477 reg [1:0] type,
478 reg [5:0] vect,
479 integer sendPort = DEV_NCU)
480{
481 CpxPkt reqPkt;
482
483 reqPkt = new();
484 reqPkt.createIntr(tid,type,vect); // INTR_RESET,INTR_POR
485 reqPkt.sendPorts = 1 << sendPort;
486 reqPkt.targetPorts = 1 << tid[5:3];
487 PR_NORMAL(CLASSNAMEQ, MON_NORMAL,
488 psprintf ("Send Interrupt to C%0d T%0d type=%b vector=%b",
489 tid[5:3],tid[2:0],type,vect));
490 reqPkt.send(1);
491}
492
493
494
495// random evictor for the CMP bench
496// Any L2 BFM can send the eviction packet(s).
497// Requires that the L2$ BFMs be in use!
498task CLASSNAME::randEvict() {
499
500 reg [3:0] sendPort = 15;
501 integer wait;
502 reg [63:0] evictPA;
503 reg [2:0] cidUsed;
504 reg whichCache;
505
506
507 if (!gParam.inval_rate) return;
508
509 wait = 100;
510 fork {
511 // not too soon
512 repeat (500) @(posedge CLOCK);
513
514 while (1) {
515 repeat (wait) @(posedge CLOCK);
516
517 // odds of doing an evict this time
518 randcase {
519 (10000-gParam.inval_rate): continue; // no
520 (gParam.inval_rate): {
521 evictPA = evictAddr(gParam.coreEnable,
522 cidUsed, // return
523 *, // reg [3:0] cid = 4'hf,
524 *); // integer dCacheWeight = 60) // 100 % based
525
526 if (evictPA !== 64'hffffffffffffffff) {
527 sendPort = whichBank(evictPA) + 8; // have to use right bank for this address!!!
528 gCcxDevMem[sendPort].enqueueEvict(gParam.coreEnable,
529 evictPA, // evict_pa
530 cidUsed, // cid
531 whichCache);
532 }
533 }
534 } // rc
535 } // while
536 } join none
537
538}