Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / ccxDevices / irritator.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: irritator.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#include <baseCCXtrans.vrh>
55
56#define CLASSNAME Irritator
57#define CLASSNAMEQ "Irritator"
58
59
60//gCcxDevice[] 0-16 !== null
61
62class CLASSNAME extends BaseCCXtrans {
63
64 local string className = "Irritator";
65
66 // rands
67
68 // end rands
69
70
71 task new(StandardDisplay dbgHndl, reg l2BFMs);
72 task decker();
73 task evictFlood();
74 task bufferFlood();
75 task randStores();
76 task randStLd();
77 task randLoads();
78}
79
80
81task CLASSNAME::new(StandardDisplay dbgHndl, reg l2BFMs) {
82 super.new(dbgHndl, l2BFMs);
83 srandom(gSeed,this);
84
85 // void = randomize();
86
87 anyMemPort = gCpxPort[0];
88 anySpcPort = gPcxPort[0];
89
90 fork {
91 evictFlood();
92 bufferFlood();
93 randStores();
94 randStLd();
95 randLoads();
96 } join none
97
98}
99
100
101
102//////////////////////////////////////////////////////
103// higher level tasks
104//////////////////////////////////////////////////////
105
106// enqueue a bunch of noop evictions for directed coverage.
107// every source sends to every FloodTarget. No checking.
108// +evictFloodAmount, +evictFloodFreq, +evictFloodTargets
109task CLASSNAME::evictFlood()
110{
111
112 integer amount;
113
114 if (! gParam.evictFloodFreq ||
115 ! gParam.evictFloodAmount ||
116 ! gParam.evictFloodTargets) return;
117
118 if (gCcxDevice[8] == null || gCcxDevice[16] == null)
119 PR_ERROR(CLASSNAMEQ, MON_ERROR,
120 psprintf ("evictFlood task needs L2 BFMs and NCU BFM!"));
121
122 amount = gParam.evictFloodAmount;
123 repeat (500) @(posedge anyMemPort.$clk);
124 while (amount) {
125 repeat (gParam.evictFloodFreq) @(posedge anyMemPort.$clk);
126 repeat (2) bogusEvict(gParam.evictFloodTargets, 8'hff);
127 repeat (2) super.sendIntr(0, 3, 0);
128 amount--;
129 }
130}
131
132
133// For CCX coverage activity. 2 ifill resp followed by 1 eviction. (ncu does 3 interrupts)
134// Will enqueue a bunch of ifill responses and noop evictions for directed coverage.
135// Every source sends to ONE FloodTarget, all at once. No checking.
136//
137// bufferFloodFreq = getParam(DEC, "bufferFloodFreq", 0, 100000, 0);
138// bufferFloodAmount = getParam(DEC, "bufferFloodAmount", 1, 100, 10);
139// bufferFloodTarget = getParam(HEX, "bufferFloodTarget", 1, 7, 7);
140task CLASSNAME::bufferFlood()
141{
142
143 integer amount;
144
145 if (! gParam.bufferFloodFreq ||
146 ! gParam.bufferFloodAmount ||
147 ! gParam.bufferFloodTarget) return;
148
149 if (gCcxDevice[8] == null || gCcxDevice[16] == null)
150 PR_ERROR(CLASSNAMEQ, MON_ERROR,
151 psprintf ("bufferFlood task needs L2 BFMs and NCU BFM!"));
152
153 amount = gParam.bufferFloodAmount;
154 repeat (500) @(posedge anyMemPort.$clk);
155 while (amount) {
156 repeat (gParam.bufferFloodFreq) @(posedge anyMemPort.$clk);
157 bogusEvict(1<<gParam.bufferFloodTarget, 8'h0C);
158 @(posedge anyMemPort.$clk);
159 bogusEvict(1<<gParam.bufferFloodTarget, 8'h30);
160 super.sendIntr(gParam.bufferFloodTarget<<3, 3, 0);
161 @(posedge anyMemPort.$clk);
162 super.sendIntr(gParam.bufferFloodTarget<<3, 3, 0);
163 super.sendIntr(gParam.bufferFloodTarget<<3, 3, 0);
164 // pre pkt
165 ifillPair(gParam.bufferFloodTarget, 8'hff,
166 {urandom(),urandom()},{urandom(),urandom()});
167 bogusEvict(1<<gParam.bufferFloodTarget, 8'hff);
168 bogusEvict(1<<gParam.bufferFloodTarget, 8'hff);
169 amount--;
170 }
171}
172
173
174
175
176// From all L2 ports, broadcast 1 eviction packet (with unique signature
177// for each source) to every core. All core targets should have the exact
178// packet stream coming out at the exact same time. Each send packet will
179// go to 8 cores, each core will receive 8 packets. Will be 64 destination
180// packets from 8 source packets.
181task CLASSNAME::decker() {
182
183 CpxPkt sndPkt[8];
184 CpxPkt recvPkt[8][8];
185 CpxPkt finalOrder[8][8];
186 integer startTime;
187 shadow integer sp,rp;
188 reg [127:0] rand128, tmp128;
189
190
191 // create array of 8 unique source packets
192 for (sp=0;sp<8;sp++) {
193 sndPkt[sp] = new();
194 rand128 = {urandom(),urandom(),urandom(),urandom()};
195 sndPkt[sp].tid = rand128[2:0];
196 sndPkt[sp].sendPorts = 1 << 8+sp;
197 sndPkt[sp].rtntyp = CPX_EVICT;
198 sndPkt[sp].rtntypU = U_CPX_EVICT;
199 sndPkt[sp].addr = rand128[39:0];
200 sndPkt[sp].targetPorts = 8'hff;
201 sndPkt[sp].data = rand128;
202 }
203
204 // register the 8 unique source packets
205 // at each destination. 64 total.
206 for (sp=0;sp<8;sp++) {
207 for (rp=0;rp<8;rp++) {
208 recvPkt[sp][rp] = new();
209 recvPkt[sp][rp].signature = sndPkt[sp].makeSignature();
210 recvPkt[sp][rp].targetPorts = 1<<rp;
211 recvPkt[sp][rp].recv(); // register arrival w/ BFM
212 }
213 }
214
215
216 // initiator, 8 unique packets
217 for (sp=0;sp<8;sp++) {
218 sndPkt[sp].send(1); // let fly
219 PR_NORMAL(CLASSNAMEQ, MON_NORMAL,
220 psprintf ("Sending random EVICTION pkt from 0b%b to 0b%b, vec=0x%h",
221 sndPkt[sp].sendPorts, sndPkt[sp].targetPorts,
222 sndPkt[sp].getVector()));
223 }
224
225 // for checker. Collect packets at destination.
226 // for each send port, collect 8 destination pkts.
227 for (sp=0;sp<8;sp++) { // for each send port
228 for (rp=0;rp<8;rp++) { // wait on/collect 8 packets in a row
229 fork {
230 wait_var(recvPkt[sp][rp].pktArrived); // 64 of these
231 // compare sndPkt[sp] to recvPkt[sp][rp]
232 if (recvPkt[sp][rp].makeSignature() !== sndPkt[sp].makeSignature())
233 PR_ERROR(CLASSNAMEQ, MON_ERROR,
234 psprintf ("mismatch error, pkt from port %0d, to port %0d", sp, rp));
235 finalOrder[sp][rp] = recvPkt[sp][rp];
236 } join none
237 }
238 }
239 wait_child(); // wait for 64 pkts to arrive
240
241
242 // now make sure that every recv port got the same packets in
243 // the same order at the same time. Order is implied in the finalOrder array.
244 // Time is stored in the recieved packets. Compare time along with order.
245 for (rp=0;rp<8;rp++) { // for each recv port
246 for (sp=0;sp<7;sp++) { // make sure all packest are same for that clock
247
248 // arrivial times (as loaded into finalOrder array) must inc by one,
249 // or dec by one depending on arb direction.
250 if (sp == 0 && rp == 0) startTime = finalOrder[rp][sp].arrivalTime;
251
252 if (finalOrder[rp][sp].getVector() !== finalOrder[rp][sp+1].getVector() ||
253 finalOrder[rp][sp].arrivalTime !== finalOrder[rp][sp+1].arrivalTime ||
254 (finalOrder[rp][sp].arrivalTime !== startTime+rp && finalOrder[rp][sp].arrivalTime !== startTime-rp))
255 PR_ERROR(CLASSNAMEQ, MON_ERROR,
256 psprintf ("decker ORDER/TIME mismatch error, [%0d][%0d] not == to [%0d][%0d]", rp, sp, rp, sp+1));
257 printf("pkt sp=%0d,rp=%0d: vec=%h, time=%0d\n", rp, sp, finalOrder[rp][sp].getVector(), finalOrder[rp][sp].arrivalTime);
258 }
259 printf("pkt sp=%0d,rp=%0d: vec=%h, time=%0d\n", rp, sp, finalOrder[rp][sp].getVector(), finalOrder[rp][sp].arrivalTime);
260 }
261
262}
263
264
265// send a bunch of store packets
266// irritStFreq
267// irritStAdr1
268// irritStAdr2
269task CLASSNAME::randStores() {
270
271 integer i;
272
273// if (! gParam.irritStFreq) return;
274// spcCheck("randStores");
275
276
277}
278
279
280// send a bunch of load packets. This will mess up a real
281// L2/core if the packet core is incorrect (same as real core)!
282// irritLdFreq
283// irritLdAdr1
284// irritLdAdr2
285task CLASSNAME::randLoads() {
286
287 integer i;
288 PcxPkt pkt;
289 reg [31:0] rnd;
290
291
292// // if (! gParam.irritLdFreq) return;
293// spcCheck("randLoads");
294//
295// rnd = urandom();
296//
297// // create load pkt
298// pkt = new();
299//
300// pickCore(pkt.cpuId, pkt.sendPorts);
301// pkt.nc = 0;
302// pkt.inv = 0;
303// pkt.pf = 0;
304// pkt.l1wayBis = rnd[2:0];
305// pkt.l1wayMMUid = rnd[5:3];
306// pkt.size = ;
307// pkt.tid = random();
308// pkt.rqtyp =
309// pkt.rqtypU =
310// pkt.addr =
311// pkt.targetPorts =
312//
313// // end to end checking
314// // pktRecv.signature = pkt.makeSignature();
315// // pktRecv.targetPorts =
316// // pktRecv.recv();
317//
318//
319// pkt.send(1); // doit
320//
321// PR_NORMAL(CLASSNAMEQ, MON_NORMAL,
322// psprintf ("Sending bogus EVICTION pkt to targets=0b%b, a=0x%h, vec=0x%h",
323// pkt.targetPorts,0,0));
324
325}
326
327
328// send a bunch of checked st -> ld packet pairs
329// irritLdStFreq
330// irritLdStAdr1
331// irritLdStAdr2
332task CLASSNAME::randStLd() {
333
334 integer i;
335
336// if (! gParam.irritLdStFreq) return;
337// spcCheck("randStLd");
338
339
340}