Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / ccxDevices / cpxPktClass.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: cpxPktClass.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#include <cmp.vri>
39// #include <defines.vri>
40
41// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
42// To use this class, you must have in your bench a files called globals.vri
43// that has all global extern declerations in it.
44#include <globals.vri>
45
46#include <std_display_class.vrh>
47#include <basePktClass.vrh>
48#include <pcxPktClass.vrh>
49#include <ccxDevBaseBFM.vrh>
50#include <ccxDevMemBFM.vrh>
51#include <ccxDevSpcBFM.vrh>
52#include <baseParamsClass.vrh>
53#include <sparcParams.vrh>
54
55#define MON_CCXPKT 24
56
57
58//----------------------------------------------------------
59// CPX Packet
60
61////////////////////////////////////////////////////////////////////////////////////////////////
62// CpxPacket Format
63// 145 | 144:141 | 140 | 139:138 | 137 | 136:134 | 133 | 132:131 | 130 | 129 | 127:0
64// ---------------------------------------------------------------------------------------------
65// valid | rtntyp | l2miss | err | nc | tid | wv | wayMMUid | wayf4b | atmIf2 | data
66////////////////////////////////////////////////////////////////////////////////////////////////
67
68class CpxPkt extends BasePkt{
69
70 // cpx vector
71 public reg valid = 1;
72 // in base public reg [3:0] rtntyp = 0;
73 public reg l2miss = 0; // will be randomized by code
74 public reg [1:0] err = 0;
75 public reg nc = 0;
76 // in base public reg [2:0] tid = 0;
77 public reg wv = 0;
78 public reg [1:0] wayMMUid = 0;
79 public reg wayf4b = 0;
80 public reg atmIf2 = 0;
81 public reg pf = 0;
82 public reg [127:0] data = 0;
83 // end cpx vector
84
85 public reg io = 0;
86
87 local reg [145:0] pktVec = 0;
88 local integer printCount = 0;
89 local CpxPkt receivedPkt = null;
90
91 // for multicast checking (one pkt becomes many). create first destination pkt.
92 // in it, store all handles to twin destination packets. On checking, if
93 // twin list not null, make sure all twins are identical.
94 public CpxPkt twinList [8];
95
96 // bench knobs
97 // hitRateParm;
98 // hitDelayMinParm;
99 // hitDelayMaxParm;
100 // missDelayMinParm;
101 // missDelayMaxParm;
102 // pkt2DelayMinParm;
103 // pkt2DelayMaxParm;
104
105 // randoms for L2 BFM use
106 public rand bit hit; // "hit" latencies are used
107 public rand integer responseDelay; // value of latency for response to this pkt
108 public rand integer pkt2Delay; // value of latency for second pkt of pair
109
110 constraint hit_c
111 {
112 hit dist {0 := 100 - gParam.hitRate, 1 := gParam.hitRate};
113 }
114
115 constraint responseDelay_c
116 {
117 if (hit == 1)
118 { responseDelay >= gParam.hitDelayMin;
119 responseDelay <= gParam.hitDelayMax; }
120 else
121 { responseDelay >= gParam.missDelayMin;
122 responseDelay <= gParam.missDelayMax; }
123 }
124
125 constraint pkt2Delay_c
126 {
127 pkt2Delay >= gParam.pkt2DelayMin;
128 pkt2Delay <= gParam.pkt2DelayMax;
129 }
130
131
132 task new(PcxPkt reqPkt = null);
133 task loadPkt(reg [145:0] data, integer atPort=99);
134 function reg [145:0] getVector();
135 task print(integer atPort);
136 task send(integer fastResp=0);
137 function reg [145:0] makeSignature();
138 task recv();
139 task createIntr (reg [5:0] thread, // 64 virtual cores
140 reg [1:0] type,
141 reg [5:0] vect);
142
143 local task printHeader();
144 task post_randomize();
145}
146
147
148 task CpxPkt::new (PcxPkt reqPkt = null) {
149
150 // in base
151 name = "CpxPkt";
152 super.reqId = 0;
153 super.reqTime = 0;
154 super.pktArrived = 0;
155
156 if (reqPkt !== null) {
157 // Default init Values for responding to request
158 targetPorts = 1 << reqPkt.cpuId;
159 valid = reqPkt.valid;
160 nc = reqPkt.nc;
161 tid = reqPkt.tid;
162 ccxSourced = reqPkt.ccxSourced;
163 ccxSourced2 = reqPkt.ccxSourced2;
164 addr = reqPkt.addr; //for ldst sync
165
166// #ifdef PKT_DEBUG
167// reqTime = reqPkt.reqTime; // time of request
168// #endif
169// #ifdef CCXDEVMEMBFM_DEBUG
170// reqTime = reqPkt.reqTime; // time of request
171// #endif
172 }
173 }
174
175
176 // load this pkt from a vector
177 task CpxPkt::loadPkt (reg [145:0] dataIn, integer atPort=99) {
178 pktVec = dataIn;
179 '{valid,rtntyp,l2miss,err,nc,tid,wv,wayMMUid,wayf4b,atmIf2,pf,data} = pktVec;
180 arrivalPort = atPort;
181 if (atPort == DEV_NCU) io = 1;
182 }
183
184 function reg [145:0] CpxPkt::getVector() {
185 getVector = {valid,rtntyp,l2miss,err,nc,tid,wv,wayMMUid,wayf4b,atmIf2,pf,data};
186 }
187
188
189 task CpxPkt::print(integer atPort)
190 {
191 reg vack = 0;
192 reg [8:0] req;
193 integer vcore = 0;
194 integer line = 999;
195
196 if (atPort < 8) vcore = tid + (8*atPort);
197 else
198 {
199 // will not work well for multicast pkts, look at req
200 if (this.req_wire === 9'bxxxxxxxxx) vcore = 99;
201 else {
202 req = this.req_wire;
203 while (req[0] !== 1 && req !== 0) {
204 vcore++;
205 req = req >> 1;
206 }
207 vcore = tid + (8*vcore);
208 }
209 }
210
211
212 printHeader () ;
213
214 printf ("%9d:", get_time(LO)) ;
215 printf ("|%2d", vcore) ;
216 printf ("|CPX") ;
217 printf ("|%2d", atPort) ;
218 if (req_wire === 9'bxxxxxxxxx) printf ("|---");
219 else printf ("|%3h", req_wire) ;
220// printf ("|%3h", req_wire) ;
221// printf ("|%3h", atm_wire) ;
222 printf ("|%1b", valid) ;
223
224 case (rtntyp)
225 {
226 CPX_LD,CPX_PREF,CPX_DIAG_LD,CPX_CAS_RTN,CPX_SWAP_RTN: { // 0000
227 if (pf) printf ("|PREFETCH RTN");
228 else if (nc & atmIf2) printf ("|SWAP/CAS RTN");
229 else printf ("|LOAD/DIA RTN");
230 line = addr[10:4]; tag = addr[39:11];
231 }
232 CPX_NCU_LD: printf ("|LOAD RTN NCU") ; // 1000
233 CPX_NCU_IFILL: printf ("|IFILL RTN NC"); // 1001
234 CPX_IFILL:
235 if (atmIf2) printf ("|IFILL RTN 2 ");
236 else printf ("|IFILL RTN 1 ");
237 CPX_STR_LD: // 0010
238 {
239 printf ("|STRM LD RTN ") ;
240 vack = 1;
241 }
242 CPX_EVICT : { // 0011
243 printf ("|EVICT INVAL ") ;
244 line = addr[10:4]; tag = addr[39:11];
245 }
246 CPX_ST,CPX_DIAG_ST,CPX_CAS_ACK,CPX_SWAP_ACK,CPX_D_INVAL,CPX_I_INVAL: // 0100
247 {
248 if (atmIf2) printf ("|SWAP/CAS ACK");
249 else if (data[124:123] == 2'b11) printf ("|ERROR IVAK!!");
250 else if (data[124] == 1) printf ("|I$ INV ACK ");
251 else if (data[123] == 1) printf ("|D$ INV ACK ");
252 else printf ("|STORE/DI ACK");
253 vack = 1;
254 line = addr[10:4]; tag = addr[39:11];
255 }
256 CPX_MMU_RTN : printf ("|MMU LD RTN "); // 0101
257 CPX_STR_ST : {
258 printf ("|STRM ST ACK "); // 0110
259 vack = 1;
260 }
261 CPX_INTR : printf ("|INTERRUPT "); // 0111
262 CPX_ERROR_L2 : printf ("|ERR L2 "); // 1100
263 CPX_ERROR_SOC : printf ("|ERR SOC "); // 1101
264 default : printf ("|????????????") ;
265 }
266
267 printf ("|%3b", l2miss) ;
268 printf ("|%2b", err);
269 printf ("|%2b", nc);
270 printf ("|%1d", tid);
271 printf ("|%2b", wv) ;
272 printf ("|%5b", wayMMUid) ;
273 printf ("|%5b", wayf4b) ;
274 printf ("|%5b", atmIf2) ;
275 printf ("|%2b", pf) ;
276 printf ("|%h_%h", data[127:64],data[63:0]) ;
277#ifdef CCXDEVMEMBFM_DEBUG
278 printf ("|%3d", reqId);
279 printf ("|%10h", addr);
280 printf ("|%2h/%8h/%1h", line,tag,lineWay);
281// printf ("|%8d", reqTime);
282#endif
283 printf ("\n") ;
284
285 if (vack) printf ("%9d:|--|CPX|Vack -> CPU=%0d, addr[11:0]=%h, invVec=%h, mask=%h, invI/D=%h, BIS/MAid=%0b\n",
286 get_time(LO),data[120:118],{data[117:112],data[122:121],data[104],3'b000},
287 data[95:64],data[103:96],data[124:123],data[125]);
288 else printf("\n");
289
290 printCount++ ;
291 }
292
293 task CpxPkt::printHeader()
294 {
295 printf ("\n%9d:", get_time(LO)) ;
296 printf ("|VC") ;
297 printf ("|CPX");
298 printf ("|At") ;
299 printf ("|Req");
300// printf ("|Atm");
301 printf ("|V") ;
302 printf ("|Type ") ;
303 printf ("|Mis");
304 printf ("|Er");
305 printf ("|NC") ;
306 printf ("|T") ;
307 printf ("|WV") ;
308 printf ("|WayMM") ;
309 printf ("|Way4b") ;
310 printf ("|AtmI2") ;
311 printf ("|Pf") ;
312 printf ("|Data ") ;
313#ifdef CCXDEVMEMBFM_DEBUG
314 printf ("|RID");
315 printf ("|Req Addr ");
316 printf ("|DL/Tag/Way");
317// printf ("|Req Time");
318#endif
319 printf ("\n") ;
320 }
321
322
323 task CpxPkt::send(integer fastResp=0) {
324 integer i;
325 pktVec = {valid,rtntyp,l2miss,err,nc,tid,wv,wayMMUid,wayf4b,atmIf2,pf,data};
326 if (rtntyp == CPX_IFILL) {
327 if (atmIf2 == 0) atomic = 1;
328 else atomic = 2;
329 }
330
331 for (i=8;i<=16;i++) {
332 if (sendPorts[i]) {
333 if (gCcxDevice[i] == null)
334 error("Can't send packet from a nonExistant BFM! \n");
335 gCcxDevice[i].send(this,fastResp);
336 }
337 }
338 }
339
340
341 // makeSignature returns certain concatinated fields of the packet.
342 // called by BFM that needs it.
343 function reg [145:0] CpxPkt::makeSignature() {
344 makeSignature = {10'b0,valid,rtntyp,tid,data[127:0]};
345 }
346
347
348 // BFM knows everything that it needs from this packet,
349 // especially the signature for packet matching.
350 // This packet has the signature and recvPorts.
351 // Note that recvPkt call inside the receiving BFM may be blocking review
352 task CpxPkt::recv() {
353
354 if (manyHot(this.targetPorts) !== 1)
355 error("Need to set a single target port in targetPorts var! \n");
356
357 // hand off
358 gCcxDevice[whichHot(this.targetPorts)].recv(this);
359 }
360
361
362
363 //This task will call the cancelRecv in the BFMS
364// task cancelRecv(integer revcPortIn)
365// {
366// gCcxDevice[recvPortIn].cancelRecv(this);
367// }
368
369
370
371 // Create Interrupt Pkt
372 task CpxPkt::createIntr (reg [5:0] thread, // 64 virtual cores
373 reg [1:0] type,
374 reg [5:0] vect) {
375
376 targetPorts = 1 << thread[5:3];
377 valid = 1'b1;
378 rtntyp = CPX_INTR;
379 l2miss = 0;
380 err = 0;
381 nc = 0;
382 tid = thread[2:0];
383 wv = 0;
384 wayMMUid = 0;
385 wayf4b = 0;
386 atmIf2 = 0;
387 pf = 0;
388 data[63:0] = {48'b0,type,thread[5:0],2'b0,vect};
389 //printf("%0d CpxPkt createIntr done, data = %0h\n", get_cycle(), data);
390
391 }
392
393// // can't refer to array indexes when weighting constraints
394// // so have to play this game first. lame!
395// task CpxPkt::pre_randomize() {
396// this.hitRateParm = gParam.hitRate[sendPort-8];
397// this.hitDelayMinParm = gParam.hitDelayMin[sendPort-8];
398// this.hitDelayMaxParm = gParam.hitDelayMax[sendPort-8];
399// this.missDelayMinParm = gParam.missDelayMin[sendPort-8];
400// this.missDelayMaxParm = gParam.missDelayMax[sendPort-8];
401// this.pkt2DelayMinParm = gParam.pkt2DelayMin[sendPort-8];
402// this.pkt2DelayMaxParm = gParam.pkt2DelayMax[sendPort-8];
403// }
404
405 task CpxPkt::post_randomize() {
406 // always set this if we "miss"
407 // May clear it later for certain return types
408 l2miss = ~hit;
409 }
410
411