Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2str / ilupeuErrCplPEUStr.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ilupeuErrCplPEUStr.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#define _INFO_MSG_ERR_CPL(msg) printf( "ErrCplPEUStr (cyc %0d) %s\n", get_cycle(), msg )
36
37class ErrCplPEUStr extends PEUStrBase
38{
39 local bit f_typeSpecified; // Was a bad-boy type supplied?
40 local bit [4:0] f_type; // The bad type
41 local bit f_write; // Is it a PIO write?
42 local bit f_wrongData; // Send CplD when Cpl expected?
43 local bit [2:0] f_wrongStatus; // Status other than SC for Rd?
44 local integer f_adjustLen; // The delta to the true length
45 local bit f_cplLk; // Send CplLk instead of Cpl?
46 local bit f_crs; // Send Cpl with CRS status?
47 local integer f_adjustCount; // The delta to the true bcount
48 local integer f_adjustAddr; // The delta to the true laddr
49 local bit [15:0] f_reqID; // The req-ID to be used
50 local bit [7:0] f_tagMask; // A mask for polluting the tag
51 local bit [2:0] f_TC; // The TC to be used
52 local bit [1:0] f_Attr; // The "Attr" to be used
53 local bit f_sendReq; // Send the PIO request?
54 local bit f_sendValid; // Send a correct Cpl(D) after?
55 local integer f_errQueue; // A mailbox for bad pkt headers
56 local bit f_badCpl; // Was a bad Cpl method called?
57 local bit f_errCpl; // Was an erroneous Cpl called?
58 local bit[2:0] f_badStatus;
59 local bit f_sendCpl;
60
61 task new( PEUTestEnv a_env )
62 {
63 super.new( a_env );
64
65 f_typeSpecified = 0;
66 f_adjustLen = 0;
67 f_wrongData = 0;
68 f_wrongStatus = 0;
69 f_cplLk = 0;
70 f_crs = 0;
71 f_sendValid = 1;
72 f_sendReq = 1;
73 f_adjustCount = 0;
74 f_adjustAddr = 0;
75 f_reqID = 0;
76 f_tagMask = 0;
77 f_TC = 0;
78 f_Attr = 0;
79 f_errQueue = 0;
80 f_badCpl = 0;
81 f_errCpl = 0;
82 f_badStatus = 3'b000;
83 f_sendCpl = 0;
84 } /* end new */
85
86 task SetType( bit [4:0] a_type, bit a_write )
87 {
88 f_typeSpecified = 1;
89 f_type = a_type;
90 f_write = a_write;
91 } /* end SetType */
92
93 task BadStatus( (bit[2:0] a_status = 3'b0) )
94 {
95 if ( a_status == 3'b000 )
96 f_badStatus = (urandom()%2) ? PEC_PCI__CPL_STATUS_CA
97 : PEC_PCI__CPL_STATUS_UR;
98 else
99 f_badStatus = a_status;
100 } /* end SetType */
101
102 task AdjustLen( integer a_lengthDelta )
103 {
104 f_adjustLen = a_lengthDelta;
105 f_errCpl = 1;
106 } /* end AdjustLen */
107
108 task WrongData( (bit [2:0] a_status = 3'b0) )
109 {
110 f_wrongData = 1;
111 f_errCpl = 1;
112 } /* end WrongData */
113
114 task WrongStatus( (bit [2:0] a_status = 3'b0) )
115 {
116 if ( a_status == 3'b0 )
117 f_wrongStatus = urandom()%7 + 1;
118 else
119 f_wrongStatus = a_status;
120 if ( f_wrongStatus == PEC_PCI__CPL_STATUS_CRS )
121 f_wrongStatus = PEC_PCI__CPL_STATUS_UR;
122
123 f_errCpl = 1;
124 } /* end WrongStatus */
125
126 task SendCplLk()
127 {
128 f_cplLk = 1;
129 f_badCpl = 1;
130 } /* end SendCplLk */
131
132 task CRS()
133 {
134 f_crs = 1;
135 } /* end CRS */
136
137 task TimeOut()
138 {
139 f_sendValid = 0;
140 } /* end TimeOut */
141
142 task NoRequest()
143 {
144 f_sendReq = 0;
145 } /* end NoRequest */
146
147 task AdjustCount( integer a_delta )
148 {
149 f_adjustCount = a_delta;
150 f_errCpl = 1;
151 } /* end AdjustCount */
152
153 task AdjustAddr( integer a_delta )
154 {
155 f_adjustAddr = a_delta;
156 f_errCpl = 1;
157 } /* end AdjustAddr */
158
159 task BadReqID( (bit[15:0] a_id = 16'b0) )
160 {
161 if ( a_id == 16'b0 )
162 f_reqID = urandom() % 65535 + 1;
163 else
164 f_reqID = a_id;
165 f_badCpl = 1;
166 } /* end BadReqID */
167
168 task BadTag( (bit[7:0] a_mask = 8'b0) )
169 {
170 if ( a_mask == 8'b0 )
171 f_tagMask = (urandom() % 7 + 1) << 5;
172 else
173 f_tagMask = a_mask;
174 f_badCpl = 1;
175 } /* end BadReqID */
176
177 task BadTC( (bit[2:0] a_tc = 3'b0) )
178 {
179 if ( a_tc == 3'b0 )
180 f_TC = urandom() % 7 + 1;
181 else
182 f_TC = a_tc;
183 f_errCpl = 1;
184 } /* end BadTC */
185
186 task BadAttr( (bit[1:0] a_attr = 2'b0) )
187 {
188 if ( a_attr == 2'b0 )
189 f_Attr = urandom() % 3 + 1;
190 else
191 f_Attr = a_attr;
192 f_errCpl = 1;
193 } /* end BadAttr */
194
195 task SetErrQueue( integer a_queue )
196 {
197 f_errQueue = a_queue;
198 } /* end SetErrQueue */
199
200 task SendCpl()
201 {
202 f_sendCpl = 1;
203 } /* end SendCpl */
204
205 task Execute()
206 {
207 bit [ 7:0 ] reqTag; // The tag for the PIO request
208 bit [ PEC_PCI__HDR ] reqHdr; // The request TLP's header
209 bit [ 7:0 ] reqAddr; // The DOU address for a write-request
210 integer reqData; // The request's payload
211 integer reqLen; // The request's length (if adjusted)
212 bit [ PEC_PCI__HDR ] cplHdr; // The completion TLP's header
213 bit [ PEC_PCI__HDR ] badCplHdr; // The corrupted completion TLP's header
214 integer cplData; // The completion's payload
215 PEC_ERRtype err; // The sort of error we're generating
216 bit [ 63:0 ] tluCtl;
217 bit quick; // Does good Cpl follow on heels of bad?
218 event quickDone; // Announces receipt of good Cpl
219 integer maxLen;
220 bit [ 31:0 ] cplDatah;
221 bit [ 63:0 ] diagCsr = 0;
222 bit disableErrCheck = 0;
223 bit CfgRdCpl = 0; //If set the env will flip the completion byte order
224 // since Denali does it automatically so DMUXtr doesn't
225 // need to store an array for the payload
226
227 // If nothing bad was specified, then
228 // we should pick something...
229 if ( !f_badCpl && !f_errCpl && !f_crs )
230 {
231 randcase
232 {
233 1: { f_adjustLen = 1; f_errCpl = 1; }
234 1: { f_wrongData = 1; f_errCpl = 1; }
235 1: { f_crs = 1; }
236 1: { f_adjustCount = 1; f_errCpl = 1; }
237 1: { f_adjustAddr = 1; f_errCpl = 1; }
238 1: { f_tagMask = 8'b00010000 << (urandom() % 4); f_badCpl = 1; }
239 1: { f_reqID = 1 << (urandom() % 16); f_badCpl = 1; }
240 1: { f_sendReq = 0; f_badCpl = 1; }
241 1: { f_TC = 1; f_errCpl = 1; }
242 1: { f_Attr = 1; f_errCpl = 1; }
243 1: { f_cplLk = 1; f_badCpl = 1; }
244 }
245 }
246
247 // A negative length adjustment demands
248 // a memory-read request.
249 if ( f_adjustLen < 0 )
250 {
251 f_typeSpecified = 1;
252 f_type = PEC_PCI__TYPE_MEM;
253 }
254
255 // If no type was specified, pick one.
256 if ( !f_typeSpecified )
257 {
258 f_write = urandom()%2;
259 randcase
260 {
261 1: f_type = PEC_PCI__TYPE_MEM;
262 1: f_type = PEC_PCI__TYPE_CFG0; //Since data gets flipped around
263 1: f_type = PEC_PCI__TYPE_CFG1; //lets just use mem and IO for random
264 1: f_type = PEC_PCI__TYPE_IO;
265 }
266 }
267 //N2 review - Only allow CFG1 Writes so Denali doesn't get messed up
268 if( f_write && f_type == PEC_PCI__TYPE_CFG0 ){
269 f_type = PEC_PCI__TYPE_CFG1;
270 }
271 if( f_badCpl && (f_type === PEC_PCI__TYPE_CFG0 ||
272 f_type === PEC_PCI__TYPE_CFG1)){
273 randcase
274 {
275 1: f_type = PEC_PCI__TYPE_MEM;
276 1: f_type = PEC_PCI__TYPE_IO;
277 }
278 }
279 // It only makes sense to adjust the
280 // length of a CplD ("read" response)
281 // and a MEM-write is posted!
282 // And a "wrong status" only makes
283 // sense for a completion with data!
284 if ( f_adjustLen
285 || f_type == PEC_PCI__TYPE_MEM
286 || f_wrongStatus != 0 ) f_write = 0;
287 if ( (f_wrongStatus != 0 || f_crs) && f_badStatus != 0 )
288 {
289 _INFO_MSG_ERR_CPL( "BadStatus supplied, but ignored due to other status req" );
290 f_badStatus = 0;
291 }
292 if ( f_wrongData && f_badStatus != 0 )
293 {
294 _INFO_MSG_ERR_CPL( "BadStatus supplied, but ignored due to incorrect data bit" );
295 f_badStatus = 0;
296 }
297
298 // Get in line for a PIO tag
299 reqAddr = 0;
300 if ( f_write )
301 f_env.allocWrTag( reqTag, reqAddr );
302 else
303 f_env.allocRdTag( reqTag );
304
305 // Then build a TLP.
306 if ( f_write )
307 f_env.genEgressWrReq( reqTag, reqHdr, reqData, *, f_type );
308 else if ( f_adjustLen < 0 )
309 f_env.genEgressRdReq( reqTag, reqHdr, reqData, 1-f_adjustLen, f_type );
310// else if ( f_adjustLen > 0 && f_type == PEC_PCI__TYPE_MEM )
311// {
312// reqLen = f_env.getMaxPayloadSize()/4;
313// if ( reqLen <= f_adjustLen ) f_adjustLen = reqLen - 1;
314// reqLen = urandom() % ( reqLen - f_adjustLen ) + 1;
315// f_env.genEgressRdReq( reqTag, reqHdr, reqData, reqLen, f_type );
316// }
317 else
318 f_env.genEgressRdReq( reqTag, reqHdr, reqData, *, f_type );
319
320 // ...and the correct completion.
321 f_env.genIngressCpl( reqHdr, cplHdr, cplData );
322
323 // If a positive length-adjustment was
324 // given, make sure the result does not
325 // exceed the max payload size.
326 maxLen = f_env.getMaxPayloadSize() / 4;
327 if ( f_adjustLen > 0 )
328 {
329 if ( reqHdr[PEC_PCI__LEN] + f_adjustLen > maxLen )
330 {
331 f_adjustLen = maxLen - reqHdr[PEC_PCI__LEN];
332 if ( f_adjustLen == 0 ) f_adjustLen = -1;
333 }
334 }
335
336 _INFO_MSG_ERR_CPL( "-----------------------" );
337 _INFO_MSG_ERR_CPL( psprintf( "%s %s tag=%h",
338 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_IO ? "IO" :
339 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG0 ? "CFG0" :
340 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG1 ? "CFG1" : "MEM",
341 f_write ? "Write" : "Read", reqTag ) );
342 _INFO_MSG_ERR_CPL( psprintf( "adjustLen=%0d", f_adjustLen ) );
343 _INFO_MSG_ERR_CPL( psprintf( "wrongData=%0d", f_wrongData ) );
344 _INFO_MSG_ERR_CPL( psprintf( "wrongStatus='b%b", f_wrongStatus ) );
345 _INFO_MSG_ERR_CPL( psprintf( "badStatus='b%b", f_badStatus ) );
346 _INFO_MSG_ERR_CPL( psprintf( "CRS=%0d", f_crs ) );
347 _INFO_MSG_ERR_CPL( psprintf( "adjustCount=%0d", f_adjustCount ) );
348 _INFO_MSG_ERR_CPL( psprintf( "adjustAddr=%0d", f_adjustAddr ) );
349 _INFO_MSG_ERR_CPL( psprintf( "tagMask=%b", f_tagMask ) );
350 _INFO_MSG_ERR_CPL( psprintf( "reqID=%h", f_reqID ) );
351 _INFO_MSG_ERR_CPL( psprintf( "sendReq=%b", f_sendReq ) );
352 _INFO_MSG_ERR_CPL( psprintf( "cplLk=%b", f_cplLk ) );
353 _INFO_MSG_ERR_CPL( psprintf( "TC=%b", f_TC ) );
354 _INFO_MSG_ERR_CPL( psprintf( "Attr=%b", f_Attr ) );
355 _INFO_MSG_ERR_CPL( psprintf( "Req ID=%h tag=%h len=%d DWBE=%h/%h addr=%h",
356 reqHdr[PEC_PCI__REQ_ID], reqHdr[PEC_PCI__TLP_TAG],
357 reqHdr[PEC_PCI__LEN], reqHdr[PEC_PCI__FIRST_DWBE],
358 reqHdr[PEC_PCI__LAST_DWBE],
359 reqHdr[PEC_PCI__FMT_4DW] ? reqHdr[PEC_PCI__ADDR]
360 : reqHdr[PEC_PCI__ADDR32] ) );
361 _INFO_MSG_ERR_CPL( psprintf( "Cpl ID=%h tag=%h len=%d lowaddr=%h byteCount=%h",
362 cplHdr[PEC_PCI__CPL_REQ_ID], cplHdr[PEC_PCI__CPL_TAG],
363 cplHdr[PEC_PCI__LEN], cplHdr[PEC_PCI__LOWADDR],
364 cplHdr[PEC_PCI__BYTECOUNT] ) );
365 _INFO_MSG_ERR_CPL( "-----------------------" );
366
367 // Now, pollute the completion based on
368 // the user's requirement(s).
369 badCplHdr = cplHdr;
370 badCplHdr[PEC_PCI__LEN] = cplHdr[PEC_PCI__LEN] + f_adjustLen;
371 if ( f_wrongData )
372 {
373 badCplHdr[PEC_PCI__FMT_DATA] = ~cplHdr[PEC_PCI__FMT_DATA];
374 if ( badCplHdr[PEC_PCI__FMT_DATA] )
375 badCplHdr[PEC_PCI__LEN] = reqHdr[PEC_PCI__LEN];
376 else
377 badCplHdr[PEC_PCI__LEN] = 0;
378 }
379 if ( f_cplLk ) badCplHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CPL_LK;
380 if ( f_crs ) badCplHdr[PEC_PCI__CPL_STATUS] = PEC_PCI__CPL_STATUS_CRS;
381 if ( f_wrongStatus ) badCplHdr[PEC_PCI__CPL_STATUS] = f_wrongStatus;
382 if ( f_badStatus ) badCplHdr[PEC_PCI__CPL_STATUS] = f_badStatus;
383 if ( f_badStatus ) badCplHdr[PEC_PCI__FMT_DATA] = 0;
384 badCplHdr[PEC_PCI__BYTECOUNT] = cplHdr[PEC_PCI__BYTECOUNT] + f_adjustCount;
385 badCplHdr[PEC_PCI__LOWADDR] = cplHdr[PEC_PCI__LOWADDR] + f_adjustAddr;
386 badCplHdr[PEC_PCI__CPL_REQ_ID] = cplHdr[PEC_PCI__CPL_REQ_ID] ^ f_reqID;
387 badCplHdr[PEC_PCI__CPL_TAG] = cplHdr[PEC_PCI__CPL_TAG] ^ f_tagMask;
388 badCplHdr[PEC_PCI__TC] = f_TC;
389 badCplHdr[PEC_PCI__ATTR] = f_Attr;
390
391 //Determine if this is a Config Read
392 CfgRdCpl = (reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG0 ||
393 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG1) && !f_write;
394
395 // Send the request, if we should.
396 if ( f_sendReq )
397 {
398 _INFO_MSG_ERR_CPL( psprintf( "Send nonposted request (tag=%h) type=%h CfgRdCpl=%0d", reqTag,reqHdr[PEC_PCI__TYPE], CfgRdCpl ) );
399 f_env.driveILU( reqHdr, reqAddr, reqData );
400 _INFO_MSG_ERR_CPL( psprintf( "Expect nonposted request (tag=%h)", reqTag ) );
401 f_env.expectPCIE( reqHdr, reqData );
402 }
403
404 // A legit "retry" completion must not
405 // have any data!
406 if ( f_crs && !f_badCpl && !f_errCpl
407 && ( f_type == PEC_PCI__TYPE_CFG0 || f_type == PEC_PCI__TYPE_CFG1 ) )
408 {
409 badCplHdr[PEC_PCI__FMT_DATA] = 1'b0;
410 /* The length-field is reserved */
411 }
412
413 // If we never sent the original request
414 // or if we dorked with the req-ID, then
415 // this is an unexpected completion.
416 // Just wait for the packet to make it
417 // through the TLU.
418 if ( !f_sendReq || f_badCpl )
419 {
420 err = e_ERR_ue_uc;
421 }
422
423 // If the completion is only a CSR
424 // response to a config request, then
425 // we expect a "retry" error.
426 else if ( f_crs && !f_badCpl && !f_errCpl
427 && ( f_type == PEC_PCI__TYPE_CFG0 || f_type == PEC_PCI__TYPE_CFG1 ) )
428 {
429 err = e_ERR_oe_crs;
430 }
431
432 // Anything else is a malformed cpl'n
433 else
434 {
435//N2 0.83 PRM err = e_ERR_ue_mfp;
436 err = e_ERR_oe_mfc;
437 }
438
439 // Maybe send in a good completion
440 // immediately after the bad...
441 // To do this, we'll plug up the egress
442 // pipeline and send in our completions
443 // as "high priority".
444 quick = 0;
445 if ( f_sendReq )
446 {
447 if ( err == e_ERR_ue_uc )
448 quick = !( urandom() % 3); // One of three is "quick"
449 else
450 quick = f_sendCpl;
451 }
452 if ( quick ) f_env.suspendIngressPipeline();
453
454 // Send the bad-boy completion...
455 _INFO_MSG_ERR_CPL( psprintf( "Sending %s completion (bad tag=%h) (good tag=%h)",
456 (err == e_ERR_ue_uc) ? "unexpected" :
457 (err == e_ERR_oe_crs) ? "retry" : "erroneous",
458 badCplHdr[ PEC_PCI__CPL_TAG ] ,
459 cplHdr[ PEC_PCI__CPL_TAG ] ) );
460 //Since the bad packet should be dropped change the data
461 cplDatah = cplData;
462
463 //Disable the DENALI checks
464 if ( (f_badStatus && !f_write) ||
465 (f_crs && !f_badCpl && !f_errCpl &&
466 ( f_type == PEC_PCI__TYPE_CFG0 || f_type == PEC_PCI__TYPE_CFG1 ) )){
467 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlLenRsv0 ); //Erroneous TLP [Cpl] - Non-0 Length field (1), which is Reserved and should be 0
468 }
469 if( (f_type === PEC_PCI__TYPE_MEM || f_type === PEC_PCI__TYPE_IO ) &&
470 badCplHdr[PEC_PCI__CPL_STATUS] === PEC_PCI__CPL_STATUS_CRS ){
471 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_CplCRS ); //Malformed TLP - Completion (Cpl) has Configuration Request Retry Status (CRS), but its corresponding Request (IOWr) is not a Configuration Request
472 }
473 if( f_Attr != 0 ){
474 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_MRd64_2 );
475 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_MRd32_2 );
476 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_IORd_2 );
477 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_IOWr_2 );
478 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgRd0_2 );
479 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgRd1_2 );
480 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgWr0_2 );
481 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgWr1_2 );
482 }
483 if( f_TC != 0 ){
484 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_MRd64_2 );
485 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_MRd32_2 );
486 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_IORd_2 );
487 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_IOWr_2 );
488 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgRd0_2 );
489 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgRd1_2 );
490 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgWr0_2 );
491 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgWr1_2 );
492 }
493 if( f_adjustCount != 0 ){
494 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_MRd64_2 );
495 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_MRd32_2 );
496 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_IORd_1 );
497 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_IORd_2 );
498 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLEN_MRd64 );
499 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLEN_MRd32 );
500 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgRd0_1 );
501 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgRd1_1 );
502 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgWr0_1 );
503 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgWr1_1 );
504 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
505 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
506 }
507 if( f_adjustAddr != 0 ){
508 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_MRd64_2 );
509 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_MRd32_2 );
510 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA64_MRd64_1 );
511 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA64_MRd32_1 );
512 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IORd_1 );
513 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IORd_2 );
514 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IOWr_1 );
515 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgRd0_1 );
516 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgRd1_1 );
517 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgWr0_1 );
518 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgWr1_1 );
519 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
520 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
521 }
522 if( f_cplLk != 0 ){
523 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlLkEP );
524 }
525 if( f_wrongStatus != 0 ){
526 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlCplSt );
527 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_CPLD );
528 }
529 if( f_adjustLen != 0 ){
530 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlSizeTotal );
531 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
532 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
533 }
534
535
536 f_env.drivePCIE( badCplHdr, {cplDatah[31:8],(cplDatah[7:0]-1)}, *, *, quick, super.f_abortErrTlp, CfgRdCpl );
537
538 //Enable the DENALI check
539 if ( (f_badStatus && !f_write) ||
540 (f_crs && !f_badCpl && !f_errCpl &&
541 ( f_type == PEC_PCI__TYPE_CFG0 || f_type == PEC_PCI__TYPE_CFG1 ) )){
542 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlLenRsv0 );
543 }
544 if( (f_type === PEC_PCI__TYPE_MEM || f_type === PEC_PCI__TYPE_IO ) &&
545 badCplHdr[PEC_PCI__CPL_STATUS] === PEC_PCI__CPL_STATUS_CRS ){
546 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_CplCRS );
547 }
548
549 if( f_Attr != 0 ){
550 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_MRd64_2
551);
552 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_MRd32_2
553);
554 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_IORd_2 )
555;
556 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_IOWr_2 )
557;
558 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgRd0_2
559 );
560 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgRd1_2
561 );
562 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgWr0_2
563 );
564 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLATTR_CfgWr1_2
565 );
566 }
567 if( f_TC != 0 ){
568 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_MRd64_2 );
569 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_MRd32_2 );
570 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_IORd_2 );
571 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_IOWr_2 );
572 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgRd0_2 )
573;
574 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgRd1_2 )
575;
576 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgWr0_2 )
577;
578 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLTC_CfgWr1_2 )
579;
580 }
581 if( f_adjustCount != 0 ){
582 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_MRd64_2 );
583 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_MRd32_2 );
584 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_IORd_1 );
585 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_IORd_2 );
586 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLEN_MRd64 );
587 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLEN_MRd32 );
588 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgRd0_1 );
589 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgRd1_1 );
590 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgWr0_1 );
591 f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLBC_CfgWr1_1 );
592 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
593 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
594 }
595 if( f_adjustAddr != 0 ){
596 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_MRd64_2 );
597 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_MRd32_2 );
598 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA64_MRd32_1 );
599 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA64_MRd64_1 );
600 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IORd_1 );
601 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IORd_2 );
602 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_IOWr_1 );
603 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgRd0_1 );
604 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgRd1_1 );
605 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgWr0_1 );
606 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLLA_CfgWr1_1 );
607 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
608 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
609 }
610 if( f_cplLk != 0 ){
611 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlLkEP );
612 }
613 if( f_wrongStatus != 0 ){
614 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlCplSt );
615 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_CPLD );
616 }
617 if( f_adjustLen != 0 ){
618 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlSizeTotal );
619 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd32_3 );
620 f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_CPLRCB_MRd64_3 );
621 }
622
623 //Check to see if any of the optional checks are disabled
624 // If they are then the transaction has to pass like a good packet
625 diagCsr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_tlu_diag ) );
626
627 if( err === e_ERR_oe_mfc &&
628 ( f_TC && diagCsr[41] ) ||
629 ( f_Attr && diagCsr[42] ) ||
630 ( f_adjustCount && diagCsr[43] ) ||
631 ( f_adjustAddr && diagCsr[44] ) ||
632 ( f_crs && diagCsr[40] ) ){
633
634
635 //Nonconfig CRS errors will be logged as WUC or RUC if the crs check
636 // is disabled
637 if( f_crs ){
638 if( f_write )
639 err = e_ERR_oe_wuc;
640 if( !f_write )
641 err = e_ERR_oe_ruc;
642
643 badCplHdr[PEC_PCI__CPL_STATUS] = PEC_PCI__CPL_STATUS_UR;
644 f_env.expectILU( badCplHdr, {cplDatah[31:8],(cplDatah[7:0]-1)} );
645 }
646 if( !f_crs ){
647 f_env.expectILU( badCplHdr, {cplDatah[31:8],(cplDatah[7:0]-1)} );
648 }
649
650 disableErrCheck = 1;
651 //Only check errors if this was a crs
652 if( f_crs ){
653 repeat( 10 ) @(posedge CLOCK);
654 //The header capture gets the status before its changed
655 badCplHdr[PEC_PCI__CPL_STATUS] = PEC_PCI__CPL_STATUS_CRS;
656 if( f_errQueue != 0 ){
657 mailbox_put( f_errQueue, e_ERR_none );
658 mailbox_put( f_errQueue, -1 );
659 mailbox_put( f_errQueue, reqHdr );
660 mailbox_put( f_errQueue, err );
661 mailbox_put( f_errQueue, badCplHdr );
662 }
663 }
664 }
665
666 // ...immediately followed by the good
667 // completion if we're being "quick".
668 // Or if we aborted the bad-boy and
669 // must answer a PIO request.
670 trigger( OFF, quickDone );
671 //If the error check is disabled then we're done
672 if( !disableErrCheck ){
673 if ( quick || (super.f_abortErrTlp && f_sendReq) ){
674 fork
675 {
676 if( CfgRdCpl && ( err == e_ERR_ue_uc || super.f_abortErrTlp )){
677 if( cplHdr[PEC_PCI__CPL_TAG] === badCplHdr[PEC_PCI__CPL_TAG] &&
678 cplHdr[PEC_PCI__CPL_REQ_ID] === badCplHdr[PEC_PCI__CPL_REQ_ID]){
679
680 CfgRdCpl = 0;
681 }else if(
682 cplHdr[PEC_PCI__CPL_TAG] !== badCplHdr[PEC_PCI__CPL_TAG] &&
683 cplHdr[PEC_PCI__CPL_REQ_ID] === badCplHdr[PEC_PCI__CPL_REQ_ID] &&
684 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG0){
685
686 CfgRdCpl = 0;
687 }else{
688 CfgRdCpl = 1;
689 }
690 }
691
692
693/*
694 if( CfgRdCpl && ( ( err == e_ERR_ue_uc || super.f_abortErrTlp ) &&
695 (( cplHdr[PEC_PCI__CPL_TAG] !== badCplHdr[PEC_PCI__CPL_TAG] ) &&
696 ( cplHdr[PEC_PCI__CPL_REQ_ID] !== badCplHdr[PEC_PCI__CPL_REQ_ID]))) )){
697 CfgRdCpl = 1;
698 }else{
699 CfgRdCpl = 0;
700 }
701
702*/
703 _INFO_MSG_ERR_CPL( psprintf( "Send %s Cpl (tag=%h) quick=%0d CfgRdCpl=%0d",
704 err==e_ERR_ue_uc ? "valid" : "unexpected valid",
705 cplHdr[PEC_PCI__CPL_TAG] , quick, CfgRdCpl ) );
706 f_env.drivePCIE( cplHdr, cplData, *, *, 1,*,CfgRdCpl );
707 if ( quick ) f_env.resumeIngressPipeline();
708 if ( err == e_ERR_ue_uc || super.f_abortErrTlp )
709 {
710 _INFO_MSG_ERR_CPL( psprintf( "Expect valid Cpl (tag=%h)",
711 cplHdr[PEC_PCI__CPL_TAG] ) );
712 f_env.expectILU( cplHdr, cplData );
713 }
714 else f_env.waitIngressLatency( cplHdr );
715 trigger( ON, quickDone );
716 }
717 join none
718 }
719
720
721 // We have to wait for the bad Cpl
722 // to take effect. The TLU just drops
723 // an unexpected completion. The ILU
724 // produces a "time-out" response for
725 // all other cases.
726 if ( err == e_ERR_ue_uc || super.f_abortErrTlp )
727 {
728 _INFO_MSG_ERR_CPL( psprintf( "Wait for Cpl to enter TLU (tag=%h)",
729 badCplHdr[PEC_PCI__CPL_TAG]) );
730 f_env.waitIngressLatency( cplHdr );
731 }
732 else
733 {
734 _INFO_MSG_ERR_CPL( psprintf( "Wait for timeout (tag=%h)",
735 cplHdr[PEC_PCI__CPL_TAG] ) );
736 f_env.expectTimeoutCpl( reqHdr );
737 }
738
739 // If we sent an unexpected valid
740 // completion, then wait for it to
741 // pass through the TLU.
742 if ( quick || (super.f_abortErrTlp && f_sendReq) )
743 {
744 sync( ANY, quickDone );
745 }
746
747 // Tell the error-checker (if any)
748 // about our problem.
749 if ( f_errQueue != 0 )
750 {
751 if ( err != e_ERR_ue_uc && quick ) // We sent in a "valid" cpl'n
752 {
753 mailbox_put( f_errQueue, e_ERR_none );
754 mailbox_put( f_errQueue, 2 );
755 mailbox_put( f_errQueue, e_ERR_ue_uc );
756 mailbox_put( f_errQueue, cplHdr );
757 }
758 if ( err != e_ERR_ue_uc )
759 {
760 mailbox_put( f_errQueue, e_ERR_none );
761 mailbox_put( f_errQueue, -1 );
762 mailbox_put( f_errQueue, reqHdr );
763 }
764 mailbox_put( f_errQueue, err );
765 mailbox_put( f_errQueue, badCplHdr );
766 }
767
768 // If we sent a PIO request and the
769 // "bad" completion was unexpected, then
770 // we have to send a good completion.
771 if ( !quick && !super.f_abortErrTlp && f_sendReq && err == e_ERR_ue_uc )
772 {
773 //Since a bad completion was already sent if tags don't match Denali flip data bytes
774
775 if( CfgRdCpl ){
776 if( cplHdr[PEC_PCI__CPL_TAG] === badCplHdr[PEC_PCI__CPL_TAG] &&
777 cplHdr[PEC_PCI__CPL_REQ_ID] === badCplHdr[PEC_PCI__CPL_REQ_ID]){
778
779 CfgRdCpl = 0;
780 }else if(
781 cplHdr[PEC_PCI__CPL_TAG] !== badCplHdr[PEC_PCI__CPL_TAG] &&
782 cplHdr[PEC_PCI__CPL_REQ_ID] === badCplHdr[PEC_PCI__CPL_REQ_ID] &&
783 reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG0){
784
785 CfgRdCpl = 0;
786 }else{
787 CfgRdCpl = 1;
788 }
789 }
790
791/*
792 if( CfgRdCpl ){
793 if( reqHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG1 ||
794 (( cplHdr[PEC_PCI__CPL_TAG] !== badCplHdr[PEC_PCI__CPL_TAG] ) && //
795 ( cplHdr[PEC_PCI__CPL_REQ_ID] !== badCplHdr[PEC_PCI__CPL_REQ_ID])) ){
796 CfgRdCpl = 1;
797 }else{
798 CfgRdCpl = 0;
799 }
800 }
801*/
802
803 _INFO_MSG_ERR_CPL( psprintf( "Send valid Cpl (tag=%h) !quick CfgRdCpl=%0h (badTag=%h)",
804 cplHdr[PEC_PCI__CPL_TAG], CfgRdCpl, badCplHdr[PEC_PCI__CPL_TAG] ) );
805
806 f_env.drivePCIE( cplHdr, cplData,*,*,*,*,CfgRdCpl );
807 _INFO_MSG_ERR_CPL( psprintf( "Expect valid Cpl (tag=%h)",
808 cplHdr[PEC_PCI__CPL_TAG] ) );
809 f_env.expectILU( cplHdr, cplData );
810 }
811
812 } // End !disableErrCheck
813
814 // Finally, free the PIO tag.
815 _INFO_MSG_ERR_CPL( psprintf( "Free PIO tag=%h", reqTag ) );
816 f_env.freePioTag( reqTag );
817 } /* end Execute */
818
819} /* end ErrCplPEUStr */
820