Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2env / PEUTestEnv.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: PEUTestEnv.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 "report_info.vrh"
36#include "plusArgMacros.vri"
37
38#ifdef N2_FC
39
40#include "std_display_class.vrh"
41#include "fc_l2_sio_stub.vrh"
42extern fc_l2_sio_stub l2sio_stub;
43
44// this is for our own memory model for PIO address
45#include "memArray.vrh"
46extern MemArray gMem;
47
48// This is for accessing MEMORY
49#include "niu_mem.vrh"
50extern CSparseMem SparseMem;
51
52#endif
53
54#define NCU_BASE_ADDR_IOCFG_FLD 0
55#define NCU_BASE_ADDR_MEM32_FLD 1
56#define NCU_BASE_ADDR_MEM64_FLD 2
57
58#define _INFO_MSG(msg) printf("PEUTestEnv (cycle %0d) %s\n", get_cycle(),msg)
59#define _REPORT_ERROR(msg) Report.report(RTYP_TEST_ERROR,"PEUTestEnv (cycle %0d) %s\n", get_cycle(),msg)
60#define _ERROR_INFO(msg) printf( " %s\n", msg )
61#define _DEBUG_MSG printf
62
63//#define _REPORT_ERROR(msg) QuickReport( Report, RTYP_TEST_ERROR,"PEUTestEnv (cycle %0d) %s\n", get_cycle(),msg)
64
65//N2-review #define _CLOCK_TLU TLU_EgressTLP.dack = void
66
67class PEUTestEnv
68{
69
70#ifndef N2_FC
71 DMUXtr f_DMUXtr;
72 N2fcPiuShadowRegs PiuCsrs;
73#else
74 N2fcIommuMgr MMU;
75#endif
76
77 ilupeuCSR f_CSR;
78 ReportClass Report;
79 ilupeuPodClass Pod;
80 ilupeuScenario Scenario;
81//N2-Not used public LPUXtr f_LPUXtr;
82
83 bit FCP_inject = 0;
84 bit FCP_P_inject = 0;
85 bit FCP_NP_inject = 0;
86 bit FCP_CPL_inject = 0;
87
88 protected CTTransactionID f_ID;
89
90 protected integer sm_mutex;
91
92 protected integer activityCounter; // For hang detect
93 integer activityStalled; // >0 if no activity expected
94 protected integer activityTimeout; // How long must we wait?!?
95
96 protected integer mb_ILUrelRecds; // ILU release recds
97 protected integer mb_egressReqOrder; // Expected req-order from TLU
98 protected integer mb_egressReqSeq; // Seq# of that req
99 protected integer mb_egressCplOrder; // Expected Cpl-order from TLU
100 protected integer mb_egressCplSeq; // Seq# of that completion
101 protected bit egressReqOK; // Do we expect a req from TLU?
102 protected bit egressCplOK; // Do we expect a cpl from TLU?
103 protected integer egressBadCount; // # of non-OK TLPs from TLU
104 protected integer egressLastSeq; // Last seq# in a "order" mb_...
105
106 protected integer ingressExpectCount; // # of pending DMUXtr expects
107
108 protected integer sm_PioTags; // There are 16 available tags
109 protected bit [15:0] pioTagsUsed;
110 protected integer sm_DmaTags; // There are 256 available tags
111 protected bit [255:0] dmaTagsUsed;
112 protected event ev_douBlkFreed; // There are 32 64-B DOU blocks
113 protected integer sm_DouMutex;
114 protected bit [31:0] douBlksUsed;
115 protected integer douBlksRequest;
116
117 protected integer sm_consumePost;
118 protected integer sm_consumeNonpost;
119 protected integer sm_consumeCompletion;
120 protected event ev_creditUpdateReceived;
121
122 protected integer mb_egressRetry;
123 protected integer mb_egressSeqNum;
124 integer egressNextTransmitSeqNum;
125 protected integer mb_unexpectedCpls;
126
127 protected integer egressIdleWeight;
128
129 protected integer egressInitPostWeight;
130 protected integer egressInitNonpostWeight;
131 protected integer egressInitCompletionWeight;
132
133 protected integer egressUpdtPostWeight;
134 protected integer egressUpdtNonpostWeight;
135 protected integer egressUpdtCompletionWeight;
136
137 protected integer egressInitPostVCNZWeight;
138 protected integer egressInitNonpostVCNZWeight;
139 protected integer egressInitCompletionVCNZWeight;
140
141 protected integer egressUpdtPostVCNZWeight;
142 protected integer egressUpdtNonpostVCNZWeight;
143 protected integer egressUpdtCompletionVCNZWeight;
144
145 protected integer egressUpdtPostNZAftInfWeight;
146 protected integer egressUpdtNonpostNZAftInfWeight;
147 protected integer egressUpdtCompletionNZAftInfWeight;
148
149 protected integer egressUpdtPostOverflowWeight;
150 protected integer egressUpdtNonpostOverflowWeight;
151 protected integer egressUpdtCompletionOverflowWeight;
152
153 protected integer egressRetryWeight;
154
155 protected integer egressPostHdrAllowed;
156 protected integer egressPostDataAllowed;
157 protected integer egressNonpostHdrAllowed;
158 protected integer egressNonpostDataAllowed;
159 protected integer egressCompletionHdrAllowed;
160 protected integer egressCompletionDataAllowed;
161
162 protected integer egressPostHdrInit;
163 protected integer egressPostDataInit;
164 protected integer egressNonpostHdrInit;
165 protected integer egressNonpostDataInit;
166 protected integer egressCompletionHdrInit;
167 protected integer egressCompletionDataInit;
168
169 protected integer egressPostHdrAvail;
170 protected integer egressPostDataAvail;
171 protected integer egressNonpostHdrAvail;
172 protected integer egressNonpostDataAvail;
173 protected integer egressCompletionHdrAvail;
174 protected integer egressCompletionDataAvail;
175
176 protected integer mb_egressPostHdrAvail;
177 protected integer mb_egressPostDataAvail;
178 protected integer mb_egressNonpostHdrAvail;
179 protected integer mb_egressNonpostDataAvail;
180 protected integer mb_egressCompletionHdrAvail;
181 protected integer mb_egressCompletionDataAvail;
182
183 protected integer egressPostHdrToReturn;
184 protected integer egressPostDataToReturn;
185 protected integer egressNonpostHdrToReturn;
186 protected integer egressNonpostDataToReturn;
187 protected integer egressCompletionHdrToReturn;
188 protected integer egressCompletionDataToReturn;
189
190// protected bit returnAllEgressCredits;
191 protected bit egressUpdateError;
192
193 protected integer egressPostHdrConsumed;
194 protected integer egressPostDataConsumed;
195 protected integer egressNonpostHdrConsumed;
196 protected integer egressNonpostDataConsumed;
197 protected integer egressCompletionHdrConsumed;
198 protected integer egressCompletionDataConsumed;
199
200 protected event egressPostHdrStopFlag;
201 protected event egressPostDataStopFlag;
202 protected event egressNonpostHdrStopFlag;
203 protected event egressNonpostDataStopFlag;
204 protected event egressCompletionHdrStopFlag;
205 protected event egressCompletionDataStopFlag;
206
207 protected integer egressPostHdrStopValue;
208 protected integer egressPostDataStopValue;
209 protected integer egressNonpostHdrStopValue;
210 protected integer egressNonpostDataStopValue;
211 protected integer egressCompletionHdrStopValue;
212 protected integer egressCompletionDataStopValue;
213
214 protected bit[31:0] egressPostStarved;
215 protected bit[31:0] egressNonpostStarved;
216 protected bit[31:0] egressCompletionStarved;
217
218 protected integer infiniteCredits;
219
220 protected integer egressDataWidth;
221 protected integer ingressDataWidth;
222
223 protected integer egressRetryInit;
224 protected integer egressRetryAvail;
225 protected integer egressRetryConsumed;
226 protected integer egressRetryAllowed;
227
228 protected integer ingressPostHdrInit;
229 protected integer ingressPostDataInit;
230 protected integer ingressNonpostHdrInit;
231 protected integer ingressNonpostDataInit;
232 protected integer ingressCompletionHdrInit;
233 protected integer ingressCompletionDataInit;
234
235 protected integer ingressPostHdrAvail;
236 protected integer ingressPostDataAvail;
237 protected integer ingressNonpostHdrAvail;
238 protected integer ingressNonpostDataAvail;
239 protected integer ingressCompletionHdrAvail;
240 protected integer ingressCompletionDataAvail;
241
242 protected integer ingressPostHdrRsvd;
243 protected integer ingressPostDataRsvd;
244 protected integer ingressNonpostHdrRsvd;
245 protected integer ingressNonpostDataRsvd;
246 protected integer ingressCompletionHdrRsvd;
247 protected integer ingressCompletionDataRsvd;
248
249 protected integer ingressPostHdrConsumed;
250 protected integer ingressPostDataConsumed;
251 protected integer ingressNonpostHdrConsumed;
252 protected integer ingressNonpostDataConsumed;
253 protected integer ingressCompletionHdrConsumed;
254 protected integer ingressCompletionDataConsumed;
255
256 protected bit onlyHiIngressUpdates;
257
258 protected integer gen4DWratio; // Percentage of TLPs w 4DW hdrs
259 protected integer gen1Weight; // Relative # of TLPs w LEN=1
260 protected integer gen16Weight; // Relative # of TLPs w LEN=16
261 protected integer genPartialWeight; // Relative # of TLPs w LEN=2:15
262 protected integer genBulkWeight; // Relative # of TLPs in >1 blk
263 protected integer genMemWeight; // Relative # of Mem Rd/Wr TLPs
264 protected integer genConfigWeight; // Relative # of Cfg Rd/Wr TLPs
265 protected integer genIoWeight; // Relative # of I/O Rd/Wr TLPs
266
267 protected integer minIngressGap; // Min # DWs from EOP to SOP
268 protected integer maxIngressGap; // Max # DWs from EOP to SOP
269
270 protected integer maxRequestSize; // In bytes, from CSR
271 protected integer maxPayloadSize; // In bytes, from CSR
272
273 event ev_linkUp; // "link up" has been asserted
274
275 protected integer ingressThrottle; // % of time "itp_cmd" is IDLE
276 protected bit ingressThrottleRandom; // Should we diddle with it?
277 protected integer ingressAbortRate; // % of time TLP is sent twice
278 protected integer egressThrottle; // % of time "dack" deasserted
279 protected bit egressThrottleRandom; // Should we diddle with it?
280 protected integer egressPipelinePlugged; // Should we hold "dack" down?
281 protected integer interruptExpected; // Do we expect an interrupt?
282 protected integer interruptUnchecked; // Has a test not seen the int?
283 protected bit intMonitorActive; // Has the monitor been started?
284
285 protected bit[31:0] lpuCsr[PEC_LPU_CSR_MAX_COUNT];// The LPU's CSR register space
286
287 protected bit[31:0] localRandomSeed;
288
289 protected integer ingressLatency;
290 protected integer egressLatency;
291
292 protected event ev_ingressUnblocked; // See "resumeIngressPipeline"
293 protected event ev_egressUnblocked; // See "resumeEgressPipeline"
294 protected integer ingressSuspenders;
295 protected integer egressSuspenders;
296
297 protected bit[63:0] ingressCreditAvailCSR;
298 protected bit[63:0] ingressCreditUsedCSR;
299 protected bit[63:0] egressCreditAvailCSR;
300 protected bit[63:0] egressCreditUsedCSR;
301 protected bit[63:0] egressRetryCSR;
302 protected event ev_CSRupdateReq;
303 protected event ev_CSRupdateComplete;
304
305 protected integer iluExpectReq; // Number of ILU Xtr expects.
306 protected integer iluExpectComplete; // Number TLPs ILU Xtr has rcvd.
307
308 protected integer peuExpectTlp; // Number of PCIE Xtr expects.
309 protected integer peuExpectComplete; // Number TLPs PCIE Xtr has rcvd.
310 protected integer peuExpectReq; // # of pending PIO requests
311 protected integer peuExpectCpl; // # of pending DMA completions
312 protected integer peuExpectMsg; // # of pending messages
313
314 protected bit ehbErrorReq; // A mirror of EHB.errReq
315 protected bit ihbErrorReq; // A mirror of IHB.errReq
316
317 protected bit[31:0] nonpostReqPending; // The ILU has seen a PIO req...
318 protected bit[31:0] nonpostReqTimeout; // Expecting a timeout...
319 protected bit[31:0] nonpostReqInLimbo; // Maybe TLU sends it, maybe not
320 protected integer nonpostReqDispatch[32]; // Cycle when req sent by TLU
321 protected event nonpostReqComplete[32]; // The PIO req has been CPL'd!
322 protected bit rsbEmpty; // Is the TLU scoreboard empty?
323
324 bit drainState; // "enterDrainState" was called
325 bit drainStateActive; // We got a drained CPL from ILU
326 bit drainStateSignaled; // We got p2d_drain active
327 event ev_drainStateEnd; // We're at the end of the test
328 event ev_removePcie; // Remove all Denali Drives/Expects
329
330 protected bit softResetPending;
331 protected event ev_softReset;
332 protected event ev_softResetEnd;
333 protected bit softResetOccurred;
334
335 protected bit [63:0] intCSR[];
336
337 protected bit [1:0] iluDebugCtlA[8];
338 protected bit [1:0] iluDebugCtlB[8];
339 protected bit [7:0] iluDebugA0; // Was a port-A debug bit zero?
340 protected bit [7:0] iluDebugA1; // Was a port-A debug bit one?
341 protected bit [7:0] iluDebugB0; // Was a port-B debug bit zero?
342 protected bit [7:0] iluDebugB1; // Was a port-B debug bit one?
343 protected bit monitorILUend; // Stop looking a TLU debugs!
344
345 protected bit [1:0] tluDebugCtlA[8];
346 protected bit [1:0] tluDebugCtlB[8];
347 protected bit [7:0] tluDebugA0; // Was a port-A debug bit zero?
348 protected bit [7:0] tluDebugA1; // Was a port-A debug bit one?
349 protected bit [7:0] tluDebugB0; // Was a port-B debug bit zero?
350 protected bit [7:0] tluDebugB1; // Was a port-B debug bit one?
351 protected bit monitorTLUend; // Stop looking a TLU debugs!
352
353 protected bit [2:0] monitorPMreq; // An expected ASPM request
354 protected bit [2:0] monitorPMstate; // Our current PM state
355 protected event ev_monitorPMreq; // Got it!
356
357 protected bit stallNpstWr; // Is it enabled?
358 protected bit stallNpstWrPending; // Is there an outstanding req?
359 protected bit[7:0] stallNpstWrTag; // If so, what's its tag?
360
361 protected integer perfCtr_dmaRead;
362 protected integer perfCtr_dmaWrite;
363 protected integer perfCtr_recvDWs;
364 protected integer perfCtr_xmitDWs;
365 protected integer perfCtr_pioCpl;
366 protected bit[63:0] coverageVector;
367
368 protected integer reserveIngressCreditsCntr = 0;
369 integer IngressCredits = 1; //Make available to set from test
370//N2 protected bit estarEnabled; // Can we enter Estar mode?
371 protected integer sm_egrCredit;
372
373 bit [7:0] ReceivedReqTag;
374 integer nmbrTlpsReplayBuffer; //Number of unACKd TLPs in replay buffer
375 integer AckdSeqNum = 4095; //Current highest ACKed sequence number
376
377 //Parms for Receiver Errors
378 bit enableRcvrErrInjection = 0;
379 integer nmbrRcvrErrsToInject = 0;
380 integer nmbrRcvrErrsInjected = 0;
381 integer nmbrRcvrErrsDriven = 0;
382 integer rcvrErrPct = 0;
383 integer rcvrErr8b10bWeight = 10;
384 integer rcvrErrFramingWeight = 10;
385 integer rcvrErrDisparityWeight = 10;
386 integer rcvrErrFlipBitWeight = 10;
387 integer rcvrErrLcrcWeight = 10;
388 integer rcvrErrDupSeqNmbrWeight = 0;
389 integer rcvrErrOutOfSeqNmbrWeight = 0;
390 integer rcvrErrBadSeqNmbrWeight = 0;
391 integer InvertLCRCErrWeight = 0;
392 integer EDBErrWeight = 0;
393 integer InvertLCRCAndEDBErrWeight = 0;
394
395 integer rcvrErr8b10bInjected = 0;
396 integer rcvrErrFramingInjected = 0;
397 integer rcvrErrDisparityInjected = 0;
398 integer rcvrErrFlipBitInjected = 0;
399 integer rcvrErrLcrcInjected = 0;
400 integer rcvrErrDupSeqNmbrInjected = 0;
401 integer rcvrErrOutOfSeqNmbrInjected = 0;
402 integer rcvrErrBadSeqNmbrInjected = 0;
403 integer nakExpected = 0;
404 event ev_rcvrErrsDriven;
405
406 //These two bits are needed to indicate that an dup seq error is to be injected on a package. After the package is
407 //driven out, rcvrErrSeqNmbrErr_justinject bit remembers this so the next consecutive package know not to inject
408 //error. Since consecutive injection of duplicate seq causes ILU expects to not match on the second injected package
409 bit rcvrErrSeqNmbrErr_toinject = 0; // indicates that this package will inject rcvrErrSeqNmbrErr
410 bit rcvrErrSeqNmbrErr_justinjected = 0; // indicates that just inject rcvrErrSeqNmbrErr
411
412
413 integer invertLCRC32ErrInjected = 0 ;
414 integer EDBErrInjected = 0;
415 integer InvertLCRCAndEDBErrInjected = 0;
416 integer invertLCRC32 = 0;
417 integer set_endsymbol_EDB = 0;
418 integer InvertLCRCAndEDBErr = 0 ;
419
420 event ev_StallPioCpl; // Stall PIO read completions
421
422
423 // N2Fc
424 protected bit [63:0] fcAddrMsk = 64'h0000_00c0_0000_0000;
425 public bit [63:0] fcAddrArray [256];
426
427 // move from expectPCIE to here for global control from diags
428 integer expectCompleteTO = 8000;
429
430 // for random injection of ECRC
431 integer inject_ECRC_weight = 0; // use for random inject of ECRC during drive PCIE
432
433 bit driftRxClockEnabled = 0;
434
435 function bit[31:0] localRandom( (integer Limit=0) );
436 function integer localRandomRange( integer Hi, integer Lo );
437
438 task new( ilupeuPodClass Pod,
439 ilupeuScenario Scenario,
440 integer RetryCredits = 4096,
441 (integer RetryWidth = 16) );
442
443 task enableEnv( (bit enableInt=1) );
444
445 task wait( integer Cycles, bit start = 0 );
446
447 task softReset((bit noReset = 0));
448
449 task genIngressWrReq( bit[7:0] TlpTag,
450 var bit[127:0] TlpHdr,
451 var integer TlpPayload,
452 (integer TlpLen=0) );
453 task genIngressRdReq( bit[7:0] TlpTag,
454 var bit[127:0] TlpHdr,
455 var integer TlpPayload,
456 (integer TlpLen=0) );
457 task genIngressCpl( bit[127:0] ReadReq,
458 var bit[127:0] TlpHdr,
459 var integer TlpPayload );
460 task genIngressMsg( bit [7:0] TlpTag,
461 var bit[127:0] TlpHdr,
462 var integer TlpPayload,
463 (integer TlpLen=0) );
464 task genEgressWrReq( bit[7:0] TlpTag,
465 var bit[127:0] TlpHdr,
466 var integer TlpPayload,
467 (integer TlpLen=0),
468 (bit[4:0] TlpType=5'bx) );
469 task genEgressRdReq( bit[7:0] TlpTag,
470 var bit[127:0] TlpHdr,
471 var integer TlpPayload,
472 (integer TlpLen=0),
473 (bit[4:0] TlpType=5'bx) );
474 task genEgressCpl( bit[127:0] ReadReq,
475 var bit[127:0] TlpHdr,
476 var integer TlpPayload );
477 task genEgressPartialCpl( bit[127:0] ReadReq,
478 var bit[127:0] TlpHdr,
479 var integer TlpPayload,
480 integer DWremaining );
481 task expectEgressMsg( bit[7:0] MsgCode,
482 (bit[31:0] MsgData = 0),
483 (event StimulusDone = null),
484 (bit Lazy = 0) );
485 task expectTimeoutCpl( bit[127:0] ReqHdr );
486
487 function bit isBulkReq( bit[127:0] TlpHdr );
488
489 task setAddrBndy( var bit[127:0] TlpHdr, integer AddrBndy, integer BlkSize );
490
491 task payloadFill( var integer TlpPayload );
492 function bit isPayloadFill( integer TlpPayload );
493 task poisonPayload( var integer TlpPayload );
494 function bit isPayloadPoisoned( integer TlpPayload );
495 task errorPayload( var integer TlpPayload,
496 (bit[7:0] ErrorMask = 8'b0) );
497 function bit isPayloadErroneous( integer TlpPayload );
498 function bit[7:0] getPayloadErrorMask( integer TlpPayload );
499
500 task setLenWeights( integer SingleWeight, integer ParialWeight,
501 integer LineWeight, integer BulkWeight );
502 task setReqWeights( integer MemoryWeight, integer ConfigWeight,
503 integer IoWeight );
504
505 task linkUp( integer Delay, (integer txBadInit = 0), (bit expectSetSlot=0) );
506 task linkDown();
507
508 task setEgressThrottle( integer Ratio ); // Set % of time "dack" <= 0
509 task setIngressThrottle( integer Ratio ); // Set % of time itp_cmd is IDLE
510 task setIngressAbortRate( integer Ratio ); // Set % of TLPs with bad CRC
511 task setIngressGap( integer MinGap, integer MaxGap );
512 task setIngressDequeueDelay( integer MinDelay, integer MaxDelay );
513
514 task plugIngressPipeline(); // Stop asserting "k2y_rcd_deq"
515 task unplugIngressPipeline(); // Resume giving credits to ILU
516
517 task plugEgressPipeline(); // Stop asserting "l2t_etp_dack"
518 task unplugEgressPipeline(); // Allow TLPs from TLU to LPU
519 task disconnectEgressPipeline(); // Ignore 't2l_etp' until reset
520
521 task suspendIngressPipeline(); // Stop presenting TLPs to TLU
522
523 task resumeIngressPipeline(); // Allow TLPs from LPU to TLU
524 task quiesceIngressPipeline(); // Wait for pipe to empty
525
526 task suspendEgressPipeline(); // Stop presenting TLPs to ILU
527 task resumeEgressPipeline((event Done=null)); // Allow TLPs from DMU to ILU
528 task quiesceEgressPipeline(); // Wait for egress pipe to empty
529
530 task suspendCreditUpdates( integer CreditType, bit Hdr );
531 task resumeCreditUpdates( integer CreditType, bit Hdr );
532 task ignoreNormalUpdates( bit Ignore );
533
534 task setEgressCreditWeight(integer CreditType, integer Weight);
535
536 function integer getEgressCreditAvail(integer CreditType, bit Hdr);
537 function integer areEgressCreditsExhausted(integer CreditType, bit Hdr);
538
539 task waitEgressCreditsExhausted(integer CreditType, bit Hdr);
540 task waitEgressCreditRollAround(integer CreditType, bit Hdr);
541 task waitEgressCredit(integer CreditType, bit Hdr, integer Value);
542
543 function integer verifyEgressCreditStatus();
544
545 function integer areIngressCreditsExhausted(integer CreditType, bit Hdr);
546
547 task waitIngressCreditsExhausted(integer CreditType, bit Hdr);
548 task waitIngressCreditRollAround(integer CreditType, bit Hdr);
549
550 task suspendRetryUpdates();
551 task resumeRetryUpdates();
552
553 function integer areRetryCreditsExhausted();
554 task waitRetryCreditsExhausted();
555
556
557 task driveILU( // Use DMUXtr to drive a packet
558 bit[PEC_PCI__HDR] PktHdr,
559 bit[7:0] DataAddr,
560 integer DataSpec,
561 (bit Priority=0) );
562 task expectILU( // Use DMUXtr to expect a packet
563 bit[PEC_PCI__HDR] PktHdr,
564 integer DataSpec,
565 (bit Optional=0) );
566 task drivePCIE( // Use FNXPcieXtr to drive a packet
567 bit[PEC_PCI__HDR] PktHdr,
568 bit [63:0] DataSpec,
569 (integer LenAdjust=0),
570 (integer BadParity=0),
571 (bit Priority=0),
572 (bit Abort=0),
573 (bit CfgRdCpl=0),
574 (bit isDmaReq=0),
575 (bit null_tlp=0) );
576 task expectPCIE( // Use FNXPcieXtr to expect a packet
577 bit[PEC_PCI__HDR] PktHdr,
578 bit [63:0] DataSpec,
579 bit IgnoreTlpReqTag = 0,
580 (bit isDmaReq=0) ,
581 (integer dma_ptr=0));
582
583 task allocWrTag( // Obtain a PIOWr tag & DOU addr
584 var bit[7:0] TlpTag,
585 var bit[7:0] DataAddr );
586 task allocRdTag( // Obtain a PIO-Read tag
587 var bit[7:0] TlpTag );
588 task freePioTag( // Free a PIO (Read) tag
589 bit[7:0] TlpTag );
590 task allocDmaTag( // Allocate a DMA Read/Write tag
591 var bit[7:0] TlpTag );
592 task freeDmaTag( // Free a DMA tag
593 bit[7:0] TlpTag );
594 task allocCplData( // Allocate some DOU blocks
595 integer Len,
596 bit[6:0] LowAddr,
597 var bit[7:0] DataAddr );
598 task freeCplData( // Free a DOU block
599 bit[7:0] DataAddr );
600
601 task set4DWratio( // Set %-age of TLPs w 4DW hdrs
602 integer ratio );
603
604 task reserveIngressCredits(
605 bit[PEC_PCI__HDR] PktHdr,
606 bit bypass_FC_credit_checking=1
607 );
608 task consumeIngressCredits(
609 bit[PEC_PCI__HDR] PktHdr );
610
611 task expectIdleState();
612
613 function integer getMaxPayloadSize();
614 task setMaxPayloadSize( integer MaxSize );
615 function integer getMaxRequestSize();
616 task setMaxRequestSize( integer MaxSize );
617
618 task expectILUrel();
619
620 function bit[31:0] nextPayloadDW( var integer DataSpec );
621
622 task consumeEgressCredits( bit[PEC_PCI__HDR] PktHdr );
623 task updateIngressCredits();
624 task updateEgressCredits();
625
626 task genReqHdr( var bit[127:0] TlpHdr, bit IsPioReq, integer TlpLen );
627 task genCplHdr( bit[127:0] NpstReq, bit IsPioReq,
628 var bit[127:0] TlpHdr, integer DWremaining );
629
630 task hangDetect(); // Ensure "activityCounter" goes up
631
632 task diddleDack(); // Raise & lower "l2t_etp_dack"
633
634 task enableInterrupt();
635 task disableInterrupt();
636 function bit expectInterrupt( bit Expected );
637 task waitInterrupt();
638 task enableAllErrors(); // Enable all ILU/TLU interrupts
639
640 task monitorInt( bit enab ); // Error if an unexpected interrupt
641 task getIntStatus(); // Collect all ILU/TLU interrupt CSRs
642 task dumpIntStatus(); // Dump out all ILU/TLU interrupt CSRs
643 task showUnexpectedInt(); // Show any unexpected interrupts
644
645 task monitorStatusCSRs( bit IngressCredits );
646 task dumpCreditStatus(); // Dump out ILU/TLU & our credit ideas
647
648 task monitorAHB(); // Handle AHB requests from the TLU
649 function integer getLPUindex( integer addr );
650 function CSRAccessor getCSR( integer addr );
651
652 task monitorCplMailbox();
653
654 function integer getCSRaddr( PEC_CSRtype csr );
655 function bit[63:0] getCSRinit( PEC_CSRtype csr );
656 function bit isCSRreset( PEC_CSRtype csr );
657 function bit[63:0] getCSRreadMask( PEC_CSRtype csr );
658 function bit[63:0] getCSRwriteMask( PEC_CSRtype csr );
659 function bit[63:0] getCSRsetMask( PEC_CSRtype csr );
660 function bit[63:0] getCSRclearMask( PEC_CSRtype csr );
661 function integer getLPUaddr( integer csrIndex );
662 function bit[63:0] readCSR( integer addr );
663 function bit[63:0] readCSRdirect( integer addr );
664 task writeCSR( integer addr, bit [63:0] data );
665 task writeCSRdirect( integer addr, bit [63:0] data );
666 task expectCSR( integer addr, bit [63:0] data );
667 task expectCSRdirect( integer addr, bit [63:0] data );
668
669 task setTLUdebug( bit[8:0] SelA, bit[8:0] SelB );
670 task setILUdebug( bit[5:0] SelA, bit[5:0] SelB );
671 task expectTLUdebug( integer A[8], integer B[8] );
672 task expectILUdebug( integer A[8], integer B[8] );
673 task endTLUdebug();
674 task endILUdebug();
675 task monitorTLUdebug();
676 task monitorILUdebug();
677
678 task setIngressLatency( integer Latency );
679 task setEgressLatency( integer Latency );
680 function integer getIngressLatency( bit[127:0] PktHdr,
681 (integer ExtraPayload=0) );
682 function integer getEgressLatency( bit [127:0] PktHdr );
683 task waitIngressLatency( bit[127:0] PktHdr, (integer ExtraPayload=0) );
684 task waitEgressLatency( bit[127:0] PktHdr );
685
686 task waitEgressPipeFull();
687 task expectEgressParityError( bit[15:0] ErrMask );
688
689 task injectEHBerror( bit[7:0] TlpTag, bit[3:0] ErrMask );
690 task injectIHBerror( bit[7:0] TlpTag, bit[3:0] ErrMask );
691 task enterDrainState( (bit[127:0] TlpHdr = 128'bx) );
692 task waitDrainState();
693
694 task setLPUerror( PEC_ERRtype LpuErr );
695 task setErrorLogEnable( PEC_ERRtype Err, bit LogEnab );
696 task setErrorIntEnable( PEC_ERRtype Err, bit Primary, bit Secondary );
697 task expectError(PEC_ERRtype Err, bit Primary, bit Secondary);
698
699 task enableOptionalCheck( (string OptCheck = "all") );
700 task disableOptionalCheck( (string OptCheck = "all") );
701
702 task monitorPM();
703 task pmDllp( PEC_PMtype PmReq );
704 task pmStatus( string Status ); // "IDLE", "BUSY", "DLLP", or "TLP"
705 task expectASPM( string StateReq, // "L0", "L0s", or "L1"
706 integer ReqTimeout, // How many cycs before req is too late?
707 integer AckDelay, // How many cycs before req ack'd?
708 (event ReqAbort=null), // Oops! Don't expect it!
709 (integer IdleTimeout=10) ); // Window for TLU to end req
710 task expectPM( string StateReq, // As above, but software PME control
711 integer ReqTimeout,
712 integer AckDelay,
713 (event ReqAbort=null) );
714 task L1toL0(); // As if remote device leaves L1
715
716 // For "drainState" processing, we have to maintain a scoreboard
717 // of outstanding non-posted PIO requests...
718 function bit isNonpostReq( bit[127:0] PktHdr );
719 task recordNonpostReq( bit[127:0] PktHdr );
720 task dispatchNonpostReq( bit[127:0] PktHdr );
721 task completeNonpostReq( bit[127:0] PktHdr );
722
723 // Change the initial credit totals advertised by the TLU.
724 task setIngressCredits( integer NpstHdr, integer PostHdr, integer PostData );
725
726 // Set the time-out value for PIO completions
727 task setPioTimeOut( integer TimeOut );
728
729 // Should we expect a Config/IO write to block all PIO reqs until completed?
730 task stallNonpostedWrite( bit Enabled );
731 function bit nonpostedWriteStalled();
732
733 function integer getPerfCtr( string ctrType );
734
735 task setActivityTimeout(integer timeout);
736
737//N2 task enableEstar( bit Enabled );
738//N2 function bit isEstarEnabled();
739//N2 task enterEstar();
740//N2 task exitEstar();
741
742
743 // Initialize the CSR in the LPU
744 task initLpuCSRs(integer numActiveLanes = 8,
745 integer mps = 128,
746 bit fastTrain = 1,
747 (bit enableL0s = 0),
748 (bit [63:0] retryBufSize = 64'h0));
749
750 task sendAck(integer seqNum);
751 task sendNak(integer seqNum);
752 task disableDenaliAcks();
753 task enableDenaliAcks();
754
755#ifdef LPUXTR_INCLUDE_PCIE
756 task enterTxL0s(integer a_cycles);
757 task enterRecovery();
758 function bit [11:0] corruptNextXmtSeqNum(bit [11:0] a_increment);
759 function bit [11:0] corruptNextXmtLCRC(bit [31:0] a_mask);
760 function bit [11:0] corruptNextXmtSTP(bit [8:0] a_symbol);
761 function bit [11:0] corruptNextXmtENDTLP(bit [8:0] a_symbol);
762 function bit [11:0] corruptNextXmt10bTLP(bit [9:0] a_frameMask,
763 integer a_frameCorruptOffset,
764 integer a_frameCorruptFreq,
765 integer a_frameCorruptMax);
766 task corruptNextXmtCRC(bit [15:0] a_mask);
767 task corruptNextXmtSDP(bit [8:0] a_symbol);
768 task corruptNextXmtENDDLLP(bit [8:0] a_symbol);
769 task corruptNextXmt10bDLLP(bit [9:0] a_frameMask,
770 integer a_frameCorruptOffset,
771 integer a_frameCorruptFreq,
772 integer a_frameCorruptMax);
773#endif
774
775//N2 tasks
776task ConvertHdr2PcieTlp( bit[PEC_PCI__HDR] tlpHdr,
777 bit[63:0] _DataSpec,
778 var FNXPCIEXactorTransaction PCIETlpTrans,
779 (integer LenAdjust=0),
780 (bit isDmaReq=0),
781 (integer dma_ptr=0 ) );
782
783task setDWBE( var bit[PEC_PCI__HDR] TlpHdr );
784task returnAllEgressCredits( (integer timerVal = 15) );
785function bit[4:0] getLtssmState();
786function integer getNmbrTlpsReplayBuffer();
787task stayDetectQuiet();
788task exitDetectQuiet();
789task PeuHotReset();
790task toLtssmState( bit [4:0] ltssmState,
791 (integer timer=2000),
792 (integer accessMethod=FIRE_PIO_SLOW) );
793function string ltssmStateToString( bit [4:0] ltssmState );
794task removePcie();
795
796// task and function to detect Denali Endpoint LTSSM states for PM
797task to_endpoint_LtssmState( bit [15:0] ep_ltssmState,
798 (integer timer=2000) );
799function string ep_ltssmStateToString( bit [15:0] ep_ltssmState );
800
801// added for N2_FC
802// used by all SATs, but enabled only for N2_FC.
803//
804task N2fcWrMem (bit [63:0] addr, bit [31:0] din, bit [7:0] be);
805function bit [31:0] N2fcRdMem (bit [63:0] addr);
806
807
808// added by AC
809task SetPEU_ASPM_enable( bit[1:0] value);
810task EndpointExpectDLLP(bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType);
811task disableDenaliFC();
812task enableDenaliFC();
813task Change_soma_parameters_ac(string _str1);
814task driveUnsupportDLLP();
815task driveBadCRCDLLP();
816task driveduplicateSeqNmbrReq( // Use FNXPcieXtr to drive a packet
817 bit[PEC_PCI__HDR] PktHdr,
818 bit [63:0] DataSpec,
819 (integer LenAdjust=0),
820 (integer BadParity=0),
821 (bit Priority=0),
822 (bit Abort=0),
823 (bit CfgRdCpl=0),
824 (bit isDmaReq=0) );
825
826task Endpoint_send_FC_update(bit [8-1:0] DLLPtype, bit [8-1:0] HdrFC, bit [12-1:0] DataFC);
827task Monitor_Endpoint_Sent_DLLP(bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType);
828function string dllptypeToString( bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType );
829task dmu_expect_msg( bit [7:0] f_msg, bit [2:0] f_rc );
830
831task setDenaliLaneSkew( integer lane,
832 integer total_skew,
833 integer bit_skew,
834 integer bit_delay,
835 integer symbol_delay );
836
837task Trigger_link_Up();
838task skewRxClockMax(bit enabled);
839task skewRxClockMin(bit enabled);
840task driftRxClock(bit enabled);
841
842task start_Denali_DTM();
843
844
845} /* end "PEUTestEnv" */
846
847/*
848* new - Construct an environment for execution of PEC testcases
849*
850* Parameters:
851* DMUxactor - An initialized transactor for the DMU-ILU interface
852* CSRcollection - An initialized transactor for the (ILU) CSR ring
853* LPUxactor - An initialized transactor for the LPU-TLU/serdes interface
854* RetryCredits - The number of initial retry credits given to the TLU
855*/
856task PEUTestEnv::new( ilupeuPodClass _Pod,
857 ilupeuScenario _Scenario,
858 integer RetryCredits = 4096,
859 (integer RetryWidth = 16) )
860{
861
862 reg [31:0] seedingtmpseed = 1;
863
864 // seed the RNG for this object to tg_seed, so that it is the same
865 // for rtl and gatesim, or different versions of vera.
866 mGetPlusargDec(tg_seed=, seedingtmpseed);
867 srandom( seedingtmpseed );
868 printf ("%0d- PEUTestEnv::new first random # = %0h\n", get_time(LO), random() );
869
870 Pod = _Pod;
871#ifndef N2_FC
872 f_DMUXtr = _Pod.DMUXtr;
873 PiuCsrs = new();
874#else
875 MMU = new();
876#endif
877 f_CSR = _Pod.CSRXtr;
878 Scenario = _Scenario;
879 egressRetryInit = RetryCredits;
880 egressDataWidth = RetryWidth;
881 ingressDataWidth = RetryWidth;
882 f_ID = new(1,1,1);
883 Report = _Pod.Report;
884
885 //The egress sequence number should always start at 0
886 egressNextTransmitSeqNum = 0;
887 AckdSeqNum = 4095;
888
889 // Set the initial weights for the updating of egress credits.
890 // When we return credits, it's for as many as four TLPs at a time.
891 egressIdleWeight = 50;
892
893 egressInitPostWeight = 0;
894 egressInitNonpostWeight = 0;
895 egressInitCompletionWeight = 0;
896
897 egressUpdtPostWeight = 10;
898 egressUpdtNonpostWeight = 10;
899 egressUpdtCompletionWeight = 10;
900
901 egressInitPostVCNZWeight = 0;
902 egressInitNonpostVCNZWeight = 0;
903 egressInitCompletionVCNZWeight = 0;
904
905 egressUpdtPostVCNZWeight = 0;
906 egressUpdtNonpostVCNZWeight = 0;
907 egressUpdtCompletionVCNZWeight = 0;
908
909 egressUpdtPostNZAftInfWeight = 0;
910 egressUpdtNonpostNZAftInfWeight = 0;
911 egressUpdtCompletionNZAftInfWeight = 0;
912
913 egressUpdtPostOverflowWeight = 0;
914 egressUpdtNonpostOverflowWeight = 0;
915 egressUpdtCompletionOverflowWeight = 0;
916
917 egressRetryWeight = 30;
918
919 mb_egressPostHdrAvail = alloc(MAILBOX, 0, 1);
920 mb_egressPostDataAvail = alloc(MAILBOX, 0, 1);
921 mb_egressNonpostHdrAvail = alloc(MAILBOX, 0, 1);
922 mb_egressNonpostDataAvail = alloc(MAILBOX, 0, 1);
923 mb_egressCompletionHdrAvail = alloc(MAILBOX, 0, 1);
924 mb_egressCompletionDataAvail = alloc(MAILBOX, 0, 1);
925
926 egressPostHdrAllowed = 1;
927 egressPostDataAllowed = 1;
928 egressNonpostHdrAllowed = 1;
929 egressNonpostDataAllowed = 1;
930 egressCompletionHdrAllowed = 1;
931 egressCompletionDataAllowed = 1;
932 egressRetryAllowed = 1;
933
934 trigger(ON, egressPostHdrStopFlag);
935 trigger(ON, egressPostDataStopFlag);
936 trigger(ON, egressNonpostHdrStopFlag);
937 trigger(ON, egressNonpostDataStopFlag);
938 trigger(ON, egressCompletionHdrStopFlag);
939 trigger(ON, egressCompletionDataStopFlag);
940
941 egressPostHdrStopValue = 0;
942 egressPostDataStopValue = 0;
943 egressNonpostHdrStopValue = 0;
944 egressNonpostDataStopValue = 0;
945 egressCompletionHdrStopValue = 0;
946 egressCompletionDataStopValue = 0;
947
948 egressPostStarved = 0;
949 egressNonpostStarved = 0;
950 egressCompletionStarved = 0;
951
952 onlyHiIngressUpdates = 0; // Do not ignore low-priority updates
953
954
955 // Initially, the typical TLP is
956 // half 3DW hdrs and half 4DW hdrs.
957 gen4DWratio = 50;
958
959 gen1Weight = 2;
960 genPartialWeight = 6;
961 gen16Weight = 2;
962 genBulkWeight = 0;
963
964 genMemWeight = 20;
965 genConfigWeight = 0;
966 genIoWeight = 0;
967
968 minIngressGap = 2; // At least 2DW from EOP to next SOP
969 maxIngressGap = 2; // No need for more than 2DW after EOP
970
971 maxRequestSize = 4096; // Any size DMA read-request is OK
972 maxPayloadSize = 128;
973
974 ingressThrottleRandom = 0;
975 ingressThrottle = 0;
976 ingressAbortRate = 0;
977
978 egressThrottleRandom = 0; // Let "diddleDack" control everything
979 egressThrottle = 0; // For now, leave "dack" asserted...
980 egressPipelinePlugged = 0;
981
982 interruptExpected = 0; // We don't expect interrupts usually
983 interruptUnchecked = 0;
984 intMonitorActive = 0;
985
986 nakExpected = 0; // To keep track if A NAK was already sent
987
988 localRandomSeed = urandom() + 1; // We generate our own random numbers
989
990 ingressLatency = 40;
991 egressLatency = 20;
992
993 peuExpectTlp = 0;
994 peuExpectComplete = 0;
995 peuExpectReq = 0;
996 peuExpectCpl = 0;
997 peuExpectMsg = 0;
998 iluExpectReq = 0;
999 iluExpectComplete = 0;
1000
1001 // We're not asking the top-level
1002 // VERILOG to inject an EHB/IBH error.
1003 // Flip the "errReq" to do so.
1004#ifndef N2_FC
1005 EHB.errReq <= 0;
1006 IHB.errReq <= 0;
1007#endif
1008 ehbErrorReq = 0;
1009 ihbErrorReq = 0;
1010
1011 // There aren't any nonposted PIO
1012 // requests waiting for completion,
1013 // and nobody has called "expectTimeout"
1014 // to say that the ILU might generate
1015 // a time-out completion. Note that
1016 // it's an error if timeout[i] and not
1017 // pending[i].
1018 // A non-posted request is "in limbo" if
1019 // it's somewhere within the egress
1020 // pipeline during transition into the
1021 // "drain state".
1022 nonpostReqPending = 32'b0;
1023 nonpostReqTimeout = 32'b0;
1024 nonpostReqInLimbo = 32'b0;
1025 rsbEmpty = 1'b1;
1026
1027 // We aren't in the "drainState".
1028 drainState = 0;
1029 drainStateActive = 0;
1030 drainStateSignaled = 0;
1031 trigger( OFF, ev_drainStateEnd );
1032 trigger( OFF, ev_removePcie );
1033
1034 // We aren't in the middle of a "soft reset"
1035 softResetPending = 0;
1036 trigger( OFF, ev_softReset );
1037 trigger( OFF, ev_softResetEnd );
1038 softResetOccurred = 0;
1039
1040 // Our pipes are open!
1041 trigger( ON, ev_ingressUnblocked );
1042 trigger( ON, ev_egressUnblocked );
1043 ingressSuspenders = 0;
1044 egressSuspenders = 0;
1045
1046 // No ASPM requests are expected from the TLU
1047 monitorPMreq = 3'b000;
1048 monitorPMstate = 3'b001;
1049 trigger( OFF, ev_monitorPMreq );
1050
1051 // The "stall for non-posted PIO writes" feature is disabled
1052 stallNpstWr = 0;
1053 stallNpstWrPending = 0;
1054
1055 // We don't allow entry into Estar mode (ILU clock slowed by 32 times)
1056 // unless someone calls "estarEnabled" to set the ILU's CSR bit
1057//N2 estarEnabled = 0;
1058
1059 // Reset all of our counters
1060 perfCtr_dmaRead = 0;
1061 perfCtr_dmaWrite = 0;
1062 perfCtr_recvDWs = 0;
1063 perfCtr_xmitDWs = 0;
1064 perfCtr_pioCpl = 0;
1065 coverageVector = 64'b0;
1066
1067 //Parms for Receiver Errors
1068 enableRcvrErrInjection = 0;
1069 nmbrRcvrErrsToInject = 0;
1070 nmbrRcvrErrsInjected = 0;
1071 nmbrRcvrErrsDriven = 0;
1072 rcvrErrPct = 0;
1073 rcvrErr8b10bWeight = 10;
1074 rcvrErrFramingWeight = 10;
1075 rcvrErrDisparityWeight = 10;
1076 rcvrErrFlipBitWeight = 10;
1077 rcvrErrLcrcWeight = 10;
1078 rcvrErrDupSeqNmbrWeight = 0;
1079 rcvrErrOutOfSeqNmbrWeight = 0;
1080 rcvrErrBadSeqNmbrWeight = 0;
1081 InvertLCRCErrWeight = 0;
1082 EDBErrWeight = 0;
1083 InvertLCRCAndEDBErrWeight = 0;
1084
1085 rcvrErr8b10bInjected = 0;
1086 rcvrErrFramingInjected = 0;
1087 rcvrErrDisparityInjected = 0;
1088 rcvrErrFlipBitInjected = 0;
1089 rcvrErrLcrcInjected = 0;
1090 rcvrErrDupSeqNmbrInjected = 0;
1091 rcvrErrOutOfSeqNmbrInjected = 0;
1092 rcvrErrBadSeqNmbrInjected = 0;
1093 invertLCRC32ErrInjected = 0 ;
1094 EDBErrInjected = 0;
1095 InvertLCRCAndEDBErrInjected = 0;
1096 InvertLCRCAndEDBErr = 0;
1097
1098 nakExpected = 0;
1099
1100 trigger( ON, ev_StallPioCpl); // default: no one will wait
1101
1102 } /* end "new" */
1103
1104/*
1105 * localRandom - Generate a random number within some bounds
1106 *
1107 * Parameters:
1108 * Limit - One greater than the max returned value, or zero if a 32-bit
1109 * random number is desired.
1110 */
1111function bit[31:0] PEUTestEnv::localRandom( (integer Limit=0) )
1112{
1113 localRandomSeed = urandom(localRandomSeed);
1114 if ( Limit <= 0 )
1115 localRandom = localRandomSeed;
1116 else
1117 localRandom = localRandomSeed % Limit;
1118} /* end localRandom */
1119
1120
1121
1122/*
1123 * localRandomRange - Generate a random number within some bounds
1124 *
1125 * Parameters:
1126 * Hi - A possible value at one end of the range
1127 * Lo - A possible value at the other end of the range
1128 */
1129function integer PEUTestEnv::localRandomRange( integer Hi, integer Lo )
1130{
1131 if ( Hi == Lo )
1132 localRandomRange = Hi;
1133 else if ( Hi < Lo )
1134 localRandomRange = localRandom(Lo-Hi) + Hi;
1135 else
1136 localRandomRange = localRandom(Hi-Lo) + Lo;
1137} /* end localRandomRange */
1138
1139
1140
1141/*
1142* enableEnv - Get things moving within the PEC test environment
1143*
1144* Parameters:
1145* enableInt - Should interrupts be enabled an monitored? (default = true)
1146*/
1147task PEUTestEnv::enableEnv( (bit enableInt = 1) )
1148{
1149 // Some things need to wait for the
1150 // PEU to say it's ready to go...
1151 trigger( OFF, ev_linkUp );
1152
1153 // A simple mutex used by all...
1154 sm_mutex = alloc( SEMAPHORE, 0, 1, 1 );
1155
1156 // The resources required to build a
1157 // packet are tags for PIO requests,
1158 // tags for DMA requests, and DOU
1159 // addresses for completions.
1160 // DMA tags do not include 0-31, which
1161 // are used by PIO requests. It doesn't
1162 // have to be this way, but it makes
1163 // some things a bit easier.
1164 sm_PioTags = alloc( SEMAPHORE, 0, 1, 16 );
1165 pioTagsUsed = 16'b0;
1166 sm_DmaTags = alloc( SEMAPHORE, 0, 1, 224 ); // 256-32 = 224
1167 dmaTagsUsed = 256'h0ffffffff;
1168 trigger( OFF, ev_douBlkFreed );
1169 sm_DouMutex = alloc( SEMAPHORE, 0, 1, 1 );
1170 douBlksUsed = 31'b0;
1171 douBlksRequest = 0;
1172 infiniteCredits = 2000000000;
1173 ingressExpectCount = 0;
1174
1175//N2-review ENV_Control.reset = 0;
1176//N2-review TLU_EgressTLP.disconreq = 0;
1177
1178 // The reservation of credits for
1179 // ingress packets is a critical section
1180 // for the different TLP classes.
1181 sm_consumePost = alloc( SEMAPHORE, 0, 1, 1 );
1182 sm_consumeNonpost = alloc( SEMAPHORE, 0, 1, 1 );
1183 sm_consumeCompletion = alloc( SEMAPHORE, 0, 1, 1 );
1184
1185 // A mailbox is used by the DMUXtr to
1186 // tell us about unsuccessful completion
1187 // TLPs which weren't expected.
1188 mb_unexpectedCpls = alloc( MAILBOX, 0, 1 );
1189#ifndef N2_FC
1190 f_DMUXtr.setCplMailbox( mb_unexpectedCpls );
1191#endif
1192
1193 // Simple FIFOs keep track of the order
1194 // in which TLPs are expected from the
1195 // TLU (egress). The DMU transactor
1196 // makes sure that order is preserved
1197 // for ingress TLPs.
1198 mb_egressReqOrder = alloc( MAILBOX, 0, 1 );
1199 mb_egressReqSeq = alloc( MAILBOX, 0, 1 );
1200 mb_egressCplOrder = alloc( MAILBOX, 0, 1 );
1201 mb_egressCplSeq = alloc( MAILBOX, 0, 1 );
1202 egressLastSeq = 0;
1203 egressReqOK = 1;
1204 egressCplOK = 1;
1205 egressBadCount = 0;
1206
1207 // Fire up ILU queues used by...
1208 mb_ILUrelRecds = alloc( MAILBOX, 0, 1 );
1209 mb_egressRetry = alloc( MAILBOX, 0, 1 );
1210 mb_egressSeqNum = alloc( MAILBOX, 0, 1 );
1211
1212 intMonitorActive = enableInt;
1213
1214 // UD : enableEnv is called by ilupeuBootstr
1215 // instead of removing the call from ilupeuBootstr, dont turn on
1216 // the monitors in this routine. this way all the maiboxes and vairables
1217 // are initialized which should prevent hung threads.
1218 //
1219#ifndef N2_FC
1220 fork
1221 // ...a thread which catches ILU release
1222 // records...
1223 { expectILUrel(); }
1224
1225 // ...and another thread to provide
1226 // updates to egress credits...
1227 { updateEgressCredits(); }
1228
1229 // ...and another that just monitors
1230 // ingress credit updates from the TLU.
1231 { updateIngressCredits(); }
1232
1233 // ...and another that watches the
1234 // "activityCounter" reports an error
1235 // if it doesn't move.
1236 { hangDetect(); }
1237
1238 // ...and another that plays around
1239 // with the egress data-ACK signal.
1240//N2 Since this is not needed don't even call it { diddleDack(); }
1241
1242 // ...and another to enable interrupts
1243 // and make sure that an interrupt only
1244 // occurs when one is expected.
1245 { if ( enableInt ) { repeat(10) @(posedge CLOCK); monitorInt(1); } }
1246
1247 // ...and another which reads CSRs to
1248 // keep track of the device's status.
1249 { monitorStatusCSRs( 1 ); }
1250
1251 // ...and another which watches the
1252 // "unexpected CPL" mailbox.
1253 { monitorCplMailbox(); }
1254
1255 // ...and another for LPU CSR requests.
1256//N2 Since this is not needed don't even call it { if ( !f_LPUXtr.usePCIE ) monitorAHB(); }
1257
1258 // ...and another for the ASPM goo.
1259//N2 Since this is not needed don't even call it { if ( !f_LPUXtr.usePCIE ) monitorPM(); }
1260
1261 join none
1262#endif
1263
1264} /* end enableEnv */
1265
1266
1267
1268/*
1269* wait - Wait a given number of cycles without the hang detect
1270* timing out.
1271*
1272* Parameters:
1273* Cycles - the number of cycles to wait.
1274*/
1275task PEUTestEnv::wait( integer Cycles , bit start = 0) {
1276
1277#ifdef N2_IOS
1278 if (start) {
1279 this.activityStalled += 1;
1280 } else {
1281 this.activityStalled -= 1;
1282 }
1283#else
1284 this.activityStalled += 1;
1285 repeat(Cycles) @(posedge CLOCK);
1286 this.activityStalled -= 1;
1287#endif
1288}
1289
1290
1291/*
1292* softReset - Perform a "soft reset" of the device
1293*
1294* Parameters: None
1295*/
1296task PEUTestEnv::softReset((bit noReset = 0))
1297{
1298 bit[127:0] pktHdr;
1299 bit [8:0] clearRelRecd;
1300 integer clearMB;
1301
1302
1303 activityStalled += 1;
1304 softResetPending = 1;
1305
1306 _INFO_MSG( "Prepare for soft reset" );
1307#ifndef N2_FC
1308#ifndef N2_IOS
1309 trigger( ON, ev_CSRupdateReq );
1310 sync( ANY, ev_CSRupdateComplete );
1311 trigger( OFF, ev_CSRupdateReq );
1312#endif
1313#endif
1314
1315 trigger( ON, ev_softReset );
1316
1317//N2-review f_LPUXtr.linkDown();
1318//N2-review f_LPUXtr.reset();
1319 //Remove any outstanding PCIE expects
1320 removePcie();
1321
1322 //N2 - Reset Denali - which will bring the link down
1323if(!noReset){
1324 Pod.FNXPCIEEnableTrans.SetDenaliReset( 1'b1 );
1325 trigger( OFF, ev_linkUp );
1326}
1327
1328 egressPipelinePlugged = 0;
1329 stallNpstWr = 0;
1330 stallNpstWrPending = 0;
1331
1332#ifndef N2_FC
1333#ifndef N2_IOS
1334
1335if(!noReset){
1336 f_DMUXtr.reset();
1337//N2 @(posedge CLOCK);
1338//N2-review ENV_Control.reset = 1;
1339 //N2 warm reset driven active
1340 Pod.DMUXtr.miscPort.$resetN = 1'b0;
1341 _INFO_MSG( "Request soft reset" );
1342}else{
1343 //Just clear the DMUXtr expects
1344 Pod.DMUXtr.clear( 1 );
1345}
1346#endif
1347#endif
1348
1349 while( mailbox_get( NO_WAIT, mb_egressCplOrder ) > 0 )
1350 void = mailbox_get( NO_WAIT, mb_egressCplOrder, pktHdr );
1351 while( mailbox_get( NO_WAIT, mb_egressCplSeq ) > 0 )
1352 void = mailbox_get( NO_WAIT, mb_egressCplSeq, pktHdr );
1353 while( mailbox_get( NO_WAIT, mb_egressReqOrder ) > 0 )
1354 void = mailbox_get( NO_WAIT, mb_egressReqOrder, pktHdr );
1355 while( mailbox_get( NO_WAIT, mb_egressReqSeq ) > 0 )
1356 void = mailbox_get( NO_WAIT, mb_egressReqSeq, pktHdr );
1357
1358 while( mailbox_get( NO_WAIT, mb_ILUrelRecds ) > 0 )
1359 void = mailbox_get( NO_WAIT, mb_ILUrelRecds, clearRelRecd );
1360 while( mailbox_get( NO_WAIT, mb_egressRetry ) > 0 )
1361 void = mailbox_get( NO_WAIT, mb_egressRetry, clearMB );
1362 while( mailbox_get( NO_WAIT, mb_egressSeqNum ) > 0 )
1363 void = mailbox_get( NO_WAIT, mb_egressSeqNum, clearMB );
1364
1365
1366 repeat(12) @(posedge CLOCK);
1367//N2-review TLU_EgressTLP.disconreq <= 0;
1368//N2-review ENV_Control.reset = 0;
1369 //N2 warm reset driven active
1370#ifndef N2_FC
1371#ifndef N2_IOS
1372if(!noReset){
1373 Pod.DMUXtr.miscPort.$resetN = 1'b0;
1374}
1375#endif
1376#endif
1377 //Take Denali out of reset or else the linkup returns positive because
1378 // its in an unknown state
1379if(!noReset){
1380 Pod.FNXPCIEEnableTrans.SetDenaliReset( 1'b0 );
1381}
1382 repeat(2) @(posedge CLOCK);
1383 //Reset the Replay Monitor in the PCIEXtr
1384 Pod.FNXPCIEEnableTrans.ResetReplayMonitor();
1385
1386if(!noReset){
1387 _INFO_MSG( "Soft reset complete" );
1388}else{
1389 _INFO_MSG( "Soft reset complete with NO reset" );
1390}
1391
1392 //pioTagsUsed = 16'b0;
1393 //dmaTagsUsed = 256'h0ffffffff;
1394 //trigger( OFF, ev_douBlkFreed );
1395 //douBlksUsed = 31'b0;
1396 //douBlksRequest = 0;
1397 ingressExpectCount = 0;
1398 interruptExpected = 0;
1399 interruptUnchecked = 0;
1400 nonpostReqPending = 32'b0;
1401 nonpostReqTimeout = 32'b0;
1402 nonpostReqInLimbo = 32'b0;
1403 rsbEmpty = 1'b1;
1404 nakExpected = 0;
1405 drainState = 0;
1406 drainStateActive = 0;
1407 drainStateSignaled = 0;
1408 trigger( OFF, ev_drainStateEnd );
1409 trigger( OFF, ev_removePcie );
1410
1411 trigger( OFF, ev_softReset );
1412 softResetPending = 0;
1413//N2-review f_LPUXtr.linkInit();
1414 trigger( ONE_SHOT, ev_softResetEnd );
1415 softResetOccurred = 1;
1416
1417#ifndef N2_FC
1418#ifndef N2_IOS
1419if(!noReset){
1420 f_DMUXtr.enableXtr();
1421}
1422#endif
1423#endif
1424
1425 egressReqOK = 1;
1426 egressCplOK = 1;
1427 egressBadCount = 0;
1428
1429 egressPostStarved[31] = 1;
1430 egressNonpostStarved[31] = 1;
1431 egressCompletionStarved[31] = 1;
1432
1433 //Sequence number should always reset to 0
1434 egressNextTransmitSeqNum = 0;
1435 AckdSeqNum = 4095;
1436
1437 //Parms for Receiver Errors
1438 enableRcvrErrInjection = 0;
1439 nmbrRcvrErrsToInject = 0;
1440 nmbrRcvrErrsInjected = 0;
1441 nmbrRcvrErrsDriven = 0;
1442 rcvrErrPct = 0;
1443 rcvrErr8b10bWeight = 10;
1444 rcvrErrFramingWeight = 10;
1445 rcvrErrDisparityWeight = 10;
1446 rcvrErrFlipBitWeight = 10;
1447 rcvrErrLcrcWeight = 10;
1448 rcvrErrDupSeqNmbrWeight = 0;
1449 rcvrErrOutOfSeqNmbrWeight = 0;
1450 rcvrErrBadSeqNmbrWeight = 0;
1451 InvertLCRCErrWeight = 0;
1452 EDBErrWeight = 0;
1453 InvertLCRCAndEDBErrWeight = 0;
1454
1455 rcvrErr8b10bInjected = 0;
1456 rcvrErrFramingInjected = 0;
1457 rcvrErrDisparityInjected = 0;
1458 rcvrErrFlipBitInjected = 0;
1459 rcvrErrLcrcInjected = 0;
1460 rcvrErrDupSeqNmbrInjected = 0;
1461 rcvrErrOutOfSeqNmbrInjected = 0;
1462 rcvrErrBadSeqNmbrInjected = 0;
1463 invertLCRC32ErrInjected = 0 ;
1464 EDBErrInjected = 0;
1465 InvertLCRCAndEDBErrInjected = 0;
1466 InvertLCRCAndEDBErr = 0;
1467
1468 nakExpected = 0;
1469
1470
1471 // Restore threads killed by "softResetPending"
1472#ifndef N2_FC
1473 fork
1474 updateEgressCredits();
1475 updateIngressCredits();
1476 monitorStatusCSRs( 0 );
1477 join none
1478#endif
1479
1480 activityStalled -= 1;
1481} /* end softReset */
1482
1483
1484/*
1485* linkUp - Go through the process of presenting "link up" to the TLU after
1486* a specified delay
1487*
1488* Parameters:
1489* Delay - The number of cycles to wait before asserting "link up"
1490* txBadInit -
1491*
1492* NOTE: The caller is suspended until the "link up" process (and delay) has
1493* completed.
1494*/
1495task PEUTestEnv::linkUp( integer Delay,
1496 (integer txBadInit = 0),
1497 (bit expectSetSlot = 0) )
1498{
1499 ilupeuLinkTrainingStrategy LinkTrainingStrategy;
1500 FNXPCIEXactorTransaction PCIETrans;
1501 bit [63:0] csr;
1502
1503 // First wait for a while so that the enableAllErrors
1504 // CSR write can take effect
1505 if (txBadInit) this.wait(29);
1506
1507 // Disable the flow control protocol interrupt
1508 if (txBadInit) this.setErrorIntEnable( e_ERR_ue_fcp, 0, 0 );
1509
1510 // Bring the link up.
1511 //N2 f_LPUXtr.linkUp( Delay , txBadInit );
1512 //Create the Link Training Strategy
1513 LinkTrainingStrategy = new ( Report,
1514 f_CSR.CSR,
1515 Pod,
1516 Scenario );
1517
1518 PCIETrans = new( Pod.FNXPCIEBldr );
1519
1520 fork
1521 {
1522 // Link Train the ILUPEU - Fork this off so we don't miss the Set Slot Power Msg
1523 LinkTrainingStrategy.Execute();
1524 // Get the initial credit allocations
1525 // If LinkTrainingStrategy.Check_Flow_Control_Init passes then Scenario will hold
1526 // all the correct Initial Flow Control values
1527 //Denali stores infinite credits as all 1's instead of 0
1528 ingressNonpostHdrInit = (Scenario.ilupeuInitialNonPostedHeaderCredit == 8'hff)? 0 : Scenario.ilupeuInitialNonPostedHeaderCredit;
1529 ingressPostHdrInit = (Scenario.ilupeuInitialPostedHeaderCredit == 8'hff)? 0 : Scenario.ilupeuInitialPostedHeaderCredit;
1530 ingressPostDataInit = (Scenario.ilupeuInitialPostedDataCredit == 12'hfff)? 0 : Scenario.ilupeuInitialPostedDataCredit;
1531 //These should be hardwired to infinite
1532 ingressNonpostDataInit = 0;
1533 ingressCompletionHdrInit = 0;
1534 ingressCompletionDataInit = 0;
1535
1536 // A number of threads are waiting
1537 // for us to say "Giddyap!"
1538 trigger( ON, ev_linkUp );
1539 Report.report(RTYP_INFO,"Env:linkUp ilupeu linkup \n");
1540
1541 }
1542
1543 {
1544 //Wait for the FNCPCIEXtr to assert link up and then move on
1545 // so the Set Slot power message isn't missed
1546 PCIETrans.WaitLinkUp();
1547 // Get the initial credit allocations
1548
1549 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_NPH_infinite = %d \n", Scenario.denali_FC_NPH_infinite);
1550 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_NPD_infinite = %d \n", Scenario.denali_FC_NPD_infinite);
1551 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_PH_infinite = %d \n", Scenario.denali_FC_PH_infinite);
1552 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_PD_infinite = %d \n", Scenario.denali_FC_PD_infinite);
1553 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_CPLH_infinite = %d \n", Scenario.denali_FC_CPLH_infinite);
1554 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denali_FC_CPLD_infinite = %d \n", Scenario.denali_FC_CPLD_infinite);
1555
1556 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialNonPostedHeaderCredit = %x \n", Scenario.denaliInitialNonPostedHeaderCredit);
1557 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialNonPostedDataCredit = %x \n",Scenario.denaliInitialNonPostedDataCredit );
1558 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialPostedHeaderCredit = %x \n", Scenario.denaliInitialPostedHeaderCredit);
1559 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialPostedDataCredit = %x \n", Scenario.denaliInitialPostedDataCredit);
1560 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialCompletionHeaderCredit = %x \n", Scenario.denaliInitialCompletionHeaderCredit);
1561 Report.report(RTYP_DEBUG_3,"PEUTestEnv::linkUp: Scenario.denaliInitialCompletionDataCredit = %x \n", Scenario.denaliInitialCompletionDataCredit);
1562
1563 egressNonpostHdrInit = (Scenario.denali_FC_NPH_infinite == 1)? 0 : Scenario.denaliInitialNonPostedHeaderCredit;
1564 egressNonpostDataInit = (Scenario.denali_FC_NPD_infinite == 1)? 0 : Scenario.denaliInitialNonPostedDataCredit;
1565
1566 egressPostHdrInit = (Scenario.denali_FC_PH_infinite == 1)? 0 : Scenario.denaliInitialPostedHeaderCredit;
1567 egressPostDataInit = (Scenario.denali_FC_PD_infinite == 1)? 0 : Scenario.denaliInitialPostedDataCredit;
1568
1569 egressCompletionHdrInit = (Scenario.denali_FC_CPLH_infinite == 1)? 0: Scenario.denaliInitialCompletionHeaderCredit;
1570 egressCompletionDataInit = (Scenario.denali_FC_CPLD_infinite == 1)? 0 : Scenario.denaliInitialCompletionDataCredit;
1571
1572 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressNonpostHdrInit = %d \n", egressNonpostHdrInit);
1573 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressNonpostDataInit = %d \n", egressNonpostDataInit);
1574 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressPostHdrInit = %d \n",egressPostHdrInit );
1575 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressPostDataInit = %d \n", egressPostDataInit);
1576 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressCompletionHdrInit = %d \n",egressCompletionHdrInit );
1577 Report.report(RTYP_DEBUG_3," PEUTestEnv::linkUp: egressCompletionDataInit = %d \n", egressCompletionDataInit);
1578
1579
1580
1581 Report.report(RTYP_INFO,"Env:linkUp Denali linkup \n");
1582
1583 }
1584 join any
1585
1586 fork
1587 {
1588 // Need to fork off the flow control protocol interrupt checking
1589 // so that it doesn't get in the way of the expect egress message
1590 // Check for the flow control protocol error.
1591 if (txBadInit) this.expectError( e_ERR_ue_fcp, 1, 1 );
1592
1593 // Re-enable the flow control protocol interrupt.
1594 if (txBadInit) this.setErrorIntEnable( e_ERR_ue_fcp, 1, 1 );
1595 }
1596 join none
1597
1598
1599 // We used to expect a "set slot power limit" message right away...
1600 //RFE 1987
1601 if( Scenario.ilupeuSetPowerLimitValue || Scenario.ilupeuSetPowerLimitScale ){
1602 expectSetSlot = 1;
1603 }
1604 fork
1605 {
1606 if( expectSetSlot )
1607 expectEgressMsg( PEC_PCI__MSG_CODE_SET_SLOT_POWER_LIMIT );
1608 }
1609 {
1610 //Guarantee LinkTrainingStrategy completed
1611 sync( ANY, ev_linkUp );
1612 }
1613 join
1614
1615} /* end linkUp */
1616
1617
1618
1619/*
1620* linkDown - Forces the RX lanes to electrical idle
1621*/
1622task PEUTestEnv::linkDown()
1623{
1624//N2 f_LPUXtr.linkDown();
1625 //N2 - Reset Denali - which will bring the link down
1626 //Pod.FNXPCIEEnableTrans.SetDenaliReset( 1'b1 );
1627 Pod.FNXPCIEEnableTrans.SetElecIdleLanes( 8'hff );
1628
1629} /* end linkDown */
1630
1631
1632
1633
1634/*
1635* plugIngressPipeline - Prevent TLPs from exiting the ingress pipeline by
1636* denying header credits to the ILU
1637*/
1638task PEUTestEnv::plugIngressPipeline() {
1639
1640#ifndef N2_FC
1641 f_DMUXtr.disableIngressDequeue();
1642#endif
1643}
1644
1645
1646
1647/*
1648* unplugIngressPipeline - Resume returning credits to the ILU, allowing TLPs
1649* to be presented to the DMU
1650*/
1651task PEUTestEnv::unplugIngressPipeline() {
1652
1653#ifndef N2_FC
1654 f_DMUXtr.enableIngressDequeue();
1655#endif
1656}
1657
1658
1659
1660/*
1661* plugEgressPipeline - Prevent TLPs from exiting the egress pipeline by
1662* deasserting "l2t_etp_dack"
1663*/
1664task PEUTestEnv::plugEgressPipeline()
1665{
1666/*N2-Not needed since testing ilu-peu
1667 if ( egressPipelinePlugged == 0 )
1668 _INFO_MSG( "Egress pipeline is plugged... DACK is deasserted" );
1669 egressPipelinePlugged = egressPipelinePlugged + 1;
1670 f_LPUXtr.assertDataAck(0);
1671*/
1672} /* end plugEgressPipeline */
1673
1674/*
1675* unplugEgressPipeline - Resume asserting "data ack" to the TLU, allowing TLPs
1676* to be presented to the LPU
1677*/
1678task PEUTestEnv::unplugEgressPipeline()
1679{
1680 if ( egressPipelinePlugged > 0 )
1681 egressPipelinePlugged = egressPipelinePlugged - 1;
1682 if ( egressPipelinePlugged == 0 )
1683 _INFO_MSG( "Egress pipeline is unplugged... DACK can be asserted" );
1684} /* end unplugEgressPipeline */
1685
1686/*
1687* disconnectEgressPipeline - Force the output of the egress pipeline to "idle"
1688*
1689* NOTE: The caller is suspended until no further egress TLPs will be presented
1690* to the transactor
1691*/
1692task PEUTestEnv::disconnectEgressPipeline()
1693{
1694 _INFO_MSG( "Disconnecting the egress pipeline..." );
1695//N2-review TLU_EgressTLP.disconreq = 1;
1696//N2-review @( TLU_EgressTLP.disconack );
1697 _INFO_MSG( "The egress pipeline is disconnected from the xactor" );
1698}
1699
1700/*
1701* suspendIngressPipeline - Stop presenting TLPs to the ILU (see "driveILU")
1702*/
1703task PEUTestEnv::suspendIngressPipeline()
1704{
1705 trigger( OFF, ev_ingressUnblocked );
1706 ingressSuspenders = ingressSuspenders + 1;
1707} /* end suspendIngressPipeline */
1708
1709/*
1710* resumeIngressPipeline - Allow TLPs to enter the ILU (see "driveILU")
1711*/
1712task PEUTestEnv::resumeIngressPipeline()
1713{
1714 if ( ingressSuspenders > 0 )
1715 {
1716 ingressSuspenders = ingressSuspenders - 1;
1717 if ( ingressSuspenders == 0 )
1718 trigger( ON, ev_ingressUnblocked );
1719 }
1720} /* end resumeIngressPipeline */
1721
1722/*
1723* quiesceIngressPipeline - Wait for the ingress pipeline to become empty
1724*
1725* NOTE: The pipeline must be "suspended" before it can be quiesced!
1726*/
1727task PEUTestEnv::quiesceIngressPipeline()
1728{
1729 while( this.iluExpectReq > this.iluExpectComplete ) @(posedge CLOCK);
1730} /* end quiesceIngressPipeline */
1731
1732/*
1733* suspendEgressPipeline - Stop presenting TLPs to the TLU (see "driveTLU")
1734*/
1735task PEUTestEnv::suspendEgressPipeline()
1736{
1737 trigger( OFF, ev_egressUnblocked );
1738 egressSuspenders = egressSuspenders + 1;
1739} /* end suspendEgressPipeline */
1740
1741/*
1742* resumeEgressPipeline - Allow TLPs to enter the TLU (see "driveTLU")
1743*
1744* Parameters:
1745* Done - An optional event to be triggered when the pipeline delivers a TLP
1746*/
1747task PEUTestEnv::resumeEgressPipeline( (event Done=null) )
1748{
1749 if ( egressSuspenders > 0 )
1750 egressSuspenders = egressSuspenders - 1;
1751 if ( egressSuspenders == 0 )
1752 trigger( ON, ev_egressUnblocked );
1753 if ( Done != null )
1754 {
1755//N2-review @( TLU_EgressTLP.cmd );
1756 trigger( ON, Done );
1757 }
1758} /* end resumeEgressPipeline */
1759
1760/*
1761* quiesceEgressPipeline - Wait for the egress pipeline to become empty
1762*
1763* NOTE: The pipeline must be "suspended" before it can be quiesced!
1764*/
1765task PEUTestEnv::quiesceEgressPipeline()
1766{
1767 while( this.peuExpectTlp > this.peuExpectComplete ) @(posedge CLOCK);
1768} /* end quiesceEgressPipeline */
1769
1770
1771/*
1772* suspendCreditUpdates - Stop returning credits of a given type to the TLU
1773*
1774* Parameters:
1775* CreditType - The sort of credit to be denied, as in "l2t_efc_type"
1776* Hdr - Should header credits be denied?
1777*/
1778task PEUTestEnv::suspendCreditUpdates( integer CreditType, bit Hdr ) {
1779
1780
1781 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1))
1782 this.egressPostHdrAllowed = 0;
1783
1784 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0))
1785 this.egressPostDataAllowed = 0;
1786
1787 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1))
1788 this.egressNonpostHdrAllowed = 0;
1789
1790 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0))
1791 this.egressNonpostDataAllowed = 0;
1792
1793 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1))
1794 this.egressCompletionHdrAllowed = 0;
1795
1796 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0))
1797 this.egressCompletionDataAllowed = 0;
1798
1799 else
1800 _REPORT_ERROR( psprintf("PEUTestEnv::suspendCreditUpdates Bad CreditType %0d / Hdr %1b", CreditType, Hdr) );
1801
1802}
1803
1804
1805
1806/*
1807* resumeCreditUpdates - Resume returning credits of a given type to the TLU
1808*
1809* Parameters:
1810* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
1811* Hdr - Should header credits be returned?
1812*/
1813task PEUTestEnv::resumeCreditUpdates( integer CreditType, bit Hdr ) {
1814
1815 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1))
1816 this.egressPostHdrAllowed = 1;
1817
1818 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0))
1819 this.egressPostDataAllowed = 1;
1820
1821 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1))
1822 this.egressNonpostHdrAllowed = 1;
1823
1824 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0))
1825 this.egressNonpostDataAllowed = 1;
1826
1827 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1))
1828 this.egressCompletionHdrAllowed = 1;
1829
1830 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0))
1831 this.egressCompletionDataAllowed = 1;
1832
1833 else
1834 _REPORT_ERROR(
1835 psprintf("PEUTestEnv::resumeCreditUpdates Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
1836
1837}
1838
1839
1840/*
1841* ignoreNormalUpdates - Should only high-priority ingress credit updates
1842* be considered?
1843*
1844* Parameters:
1845* Ignore - If non-zero, any non-high-priority credit update is ignored
1846*/
1847task PEUTestEnv::ignoreNormalUpdates( bit Ignore )
1848 {
1849 onlyHiIngressUpdates = Ignore;
1850 } /* end ignoreNormalUpdates */
1851
1852/*
1853* setEgressCreditWeight - Set the relative frequency of Egress Posted Flow
1854* Control Updates.
1855*
1856* Parameters:
1857* CreditType - The sort of credit to be returned, as in "l2t_efc_type" +
1858* some other verification defined types.
1859* Weight - The relative frequency of Egress Posted Flow Control Updates.
1860*/
1861task PEUTestEnv::setEgressCreditWeight(integer CreditType, integer Weight) {
1862
1863
1864 if (CreditType === PEC_CREDIT_TYPE__IDLE)
1865 egressIdleWeight = Weight;
1866
1867 else if (CreditType === PEC_CREDIT_TYPE__INIT_COMP)
1868 egressInitCompletionWeight = Weight;
1869
1870 else if (CreditType === PEC_CREDIT_TYPE__INIT_NONPOST)
1871 egressInitNonpostWeight = Weight;
1872
1873 else if (CreditType === PEC_CREDIT_TYPE__INIT_POST)
1874 egressInitPostWeight = Weight;
1875
1876 else if (CreditType === PEC_CREDIT_TYPE__UPDT_COMP)
1877 egressUpdtCompletionWeight = Weight;
1878
1879 else if (CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST)
1880 egressUpdtNonpostWeight = Weight;
1881
1882 else if (CreditType === PEC_CREDIT_TYPE__UPDT_POST)
1883 egressUpdtPostWeight = Weight;
1884
1885 else if (CreditType === PEC_CREDIT_TYPE__INIT_COMP_VCNZ)
1886 egressInitCompletionVCNZWeight = Weight;
1887
1888 else if (CreditType === PEC_CREDIT_TYPE__INIT_NONPOST_VCNZ)
1889 egressInitNonpostVCNZWeight = Weight;
1890
1891 else if (CreditType === PEC_CREDIT_TYPE__INIT_POST_VCNZ)
1892 egressInitPostVCNZWeight = Weight;
1893
1894 else if (CreditType === PEC_CREDIT_TYPE__UPDT_COMP_VCNZ)
1895 egressUpdtCompletionVCNZWeight = Weight;
1896
1897 else if (CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST_VCNZ)
1898 egressUpdtNonpostVCNZWeight = Weight;
1899
1900 else if (CreditType === PEC_CREDIT_TYPE__UPDT_POST_VCNZ)
1901 egressUpdtPostVCNZWeight = Weight;
1902
1903 else if (CreditType === PEC_CREDIT_TYPE__UPDT_COMP_NZ_AFT_INF)
1904 egressUpdtCompletionNZAftInfWeight = Weight;
1905
1906 else if (CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST_NZ_AFT_INF)
1907 egressUpdtNonpostNZAftInfWeight = Weight;
1908
1909 else if (CreditType === PEC_CREDIT_TYPE__UPDT_POST_NZ_AFT_INF)
1910 egressUpdtPostNZAftInfWeight = Weight;
1911
1912 else if (CreditType === PEC_CREDIT_TYPE__UPDT_COMP_OVERFLOW)
1913 egressUpdtCompletionOverflowWeight = Weight;
1914
1915 else if (CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST_OVERFLOW)
1916 egressUpdtNonpostOverflowWeight = Weight;
1917
1918 else if (CreditType === PEC_CREDIT_TYPE__UPDT_POST_OVERFLOW)
1919 egressUpdtPostOverflowWeight = Weight;
1920
1921 else if (CreditType === PEC_CREDIT_TYPE__RETRY)
1922 egressRetryWeight = Weight;
1923
1924 else
1925 _REPORT_ERROR(
1926 psprintf("PEUTestEnv::setEgressCreditWeight Bad CreditType %0d", CreditType));
1927
1928}
1929
1930
1931
1932/*
1933* getEgressCreditAvail - Return number of egress flow control credits available
1934*
1935* Parameters:
1936* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
1937* Hdr - Should header credits be returned?
1938*/
1939function integer PEUTestEnv::getEgressCreditAvail(integer CreditType, bit Hdr) {
1940
1941 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1))
1942 getEgressCreditAvail = egressPostHdrAvail;
1943
1944 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0))
1945 getEgressCreditAvail = egressPostDataAvail;
1946
1947 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1))
1948 getEgressCreditAvail = egressNonpostHdrAvail;
1949
1950 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0))
1951 getEgressCreditAvail = egressNonpostDataAvail;
1952
1953 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1))
1954 getEgressCreditAvail = egressCompletionHdrAvail;
1955
1956 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0))
1957 getEgressCreditAvail = egressCompletionDataAvail;
1958
1959 else
1960 _REPORT_ERROR(
1961 psprintf("PEUTestEnv::getEgressCreditAvail Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
1962}
1963
1964
1965
1966/*
1967* areEgressCreditsExhausted - determine wether the egress credits have
1968* been exhausted for a particular type.
1969*
1970* Parameters:
1971* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
1972* Hdr - Should header credits be returned?
1973*/
1974function integer PEUTestEnv::areEgressCreditsExhausted(integer CreditType,
1975 bit Hdr) {
1976
1977
1978 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1))
1979 areEgressCreditsExhausted =
1980 !(egressPostHdrAvail - egressPostHdrConsumed);
1981
1982 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0))
1983 areEgressCreditsExhausted =
1984 ((egressPostDataAvail - egressPostDataConsumed) < 4);
1985
1986 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1))
1987 areEgressCreditsExhausted =
1988 !(egressNonpostHdrAvail - egressNonpostHdrConsumed);
1989
1990 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0))
1991 areEgressCreditsExhausted =
1992 !(egressNonpostDataAvail - egressNonpostDataConsumed);
1993
1994 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1))
1995 areEgressCreditsExhausted =
1996 !(egressCompletionHdrAvail - egressCompletionHdrConsumed);
1997
1998 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0))
1999 areEgressCreditsExhausted =
2000 ((egressCompletionDataAvail - egressCompletionDataConsumed) < (this.getMaxPayloadSize() / 16));
2001
2002 else
2003 _REPORT_ERROR(
2004 psprintf("PEUTestEnv::areEgressCreditsExhausted Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
2005}
2006
2007
2008
2009/*
2010* waitEgressCreditsExhausted - wait until the egress credits have
2011* been exhausted for a particular type.
2012*
2013* Parameters:
2014* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2015* Hdr - Should header credits be returned?
2016*/
2017task PEUTestEnv::waitEgressCreditsExhausted(integer CreditType, bit Hdr) {
2018
2019
2020 while (!this.areEgressCreditsExhausted(CreditType, Hdr))
2021 @(posedge CLOCK);
2022}
2023
2024
2025
2026/*
2027* waitEgressCreditRollover - Wait for the egress credit counter to roll over
2028*
2029* Parameters:
2030* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2031* Hdr - Should header credits be returned?
2032*/
2033task PEUTestEnv::waitEgressCreditRollAround(integer CreditType, bit Hdr) {
2034
2035 integer initial;
2036
2037 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1)) {
2038
2039 initial = this.egressPostHdrAvail;
2040
2041 while (((this.egressPostHdrAvail - initial) <= 257) &&
2042 (initial !== infiniteCredits))
2043 @(posedge CLOCK);
2044
2045 printf("** Egress Posted Header Credits Rolled Over **\n");
2046 }
2047
2048
2049 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0)) {
2050
2051 initial = this.egressPostDataAvail;
2052
2053 while (((this.egressPostDataAvail - initial) <= 4097) &&
2054 (initial !== infiniteCredits))
2055 @(posedge CLOCK);
2056
2057 printf("** Egress Posted Data Credits Rolled Over **\n");
2058 }
2059
2060
2061 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1)) {
2062
2063 initial = this.egressNonpostHdrAvail;
2064
2065 while (((this.egressNonpostHdrAvail - initial) <= 257) &&
2066 (initial !== infiniteCredits))
2067 @(posedge CLOCK);
2068
2069 printf("** Egress Non-Posted Header Credits Rolled Over **\n");
2070 }
2071
2072
2073 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0)) {
2074
2075 initial = this.egressNonpostDataAvail;
2076
2077 while (((this.egressNonpostDataAvail - initial) <= 4097) &&
2078 (initial !== infiniteCredits))
2079 @(posedge CLOCK);
2080
2081 printf("** Egress Non-Posted Data Credits Rolled Over **\n");
2082 }
2083
2084
2085 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1)) {
2086
2087 initial = this.egressCompletionHdrAvail;
2088
2089 while (((this.egressCompletionHdrAvail - initial) <= 257) &&
2090 (initial !== infiniteCredits))
2091 @(posedge CLOCK);
2092
2093 printf("** Egress Completion Header Credits Rolled Over **\n");
2094 }
2095
2096
2097 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0)) {
2098
2099 initial = this.egressCompletionDataAvail;
2100
2101 while (((this.egressCompletionDataAvail - initial) <= 4097) &&
2102 (initial !== infiniteCredits))
2103 @(posedge CLOCK);
2104
2105 printf("** Egress Completion Data Credits Rolled Over **\n");
2106 }
2107
2108
2109 else
2110 _REPORT_ERROR(
2111 psprintf("PEUTestEnv::waitEgressCreditRollAround Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
2112}
2113
2114
2115
2116/*
2117* waitEgressCredit - Wait for the given egress credit type to reach
2118* the given value.
2119*
2120* Parameters:
2121* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2122* Hdr - Should header credits be returned?
2123* Value - The credit value that we are waiting to reach.
2124*/
2125task PEUTestEnv::waitEgressCredit(integer CreditType, bit Hdr, integer Value) {
2126
2127
2128 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1)) {
2129
2130 egressPostHdrStopValue = Value;
2131 trigger(OFF, egressPostHdrStopFlag);
2132 sync(ALL, egressPostHdrStopFlag);
2133 }
2134
2135
2136 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0)) {
2137
2138 egressPostDataStopValue = Value;
2139 trigger(OFF, egressPostDataStopFlag);
2140 sync(ALL, egressPostDataStopFlag);
2141 }
2142
2143
2144 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1)) {
2145
2146 egressNonpostHdrStopValue = Value;
2147 trigger(OFF, egressNonpostHdrStopFlag);
2148 sync(ALL, egressNonpostHdrStopFlag);
2149 }
2150
2151
2152 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0)) {
2153
2154 egressNonpostDataStopValue = Value;
2155 trigger(OFF, egressNonpostDataStopFlag);
2156 sync(ALL, egressNonpostDataStopFlag);
2157 }
2158
2159
2160 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1)) {
2161
2162 egressCompletionHdrStopValue = Value;
2163 trigger(OFF, egressCompletionHdrStopFlag);
2164 sync(ALL, egressCompletionHdrStopFlag);
2165 }
2166
2167
2168 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0)) {
2169
2170 egressCompletionDataStopValue = Value;
2171 trigger(OFF, egressCompletionDataStopFlag);
2172 sync(ALL, egressCompletionDataStopFlag);
2173 }
2174
2175 else
2176 _REPORT_ERROR(
2177 psprintf("PEUTestEnv::waitEgressCredit Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
2178}
2179
2180
2181
2182/*
2183* verifyEgressCreditStatus - Monitor the egress credit allocation in
2184* the device, and make sure it matches.
2185*/
2186function integer PEUTestEnv::verifyEgressCreditStatus() {
2187
2188
2189 integer tluEgrPostHdr;
2190 integer tluEgrPostData;
2191 integer tluEgrNpstHdr;
2192 integer tluEgrNpstData;
2193 integer tluEgrCmplHdr;
2194 integer tluEgrCmplData;
2195
2196 integer tluEgrRetry;
2197
2198 integer envEgrPostHdr;
2199 integer envEgrPostData;
2200 integer envEgrNpstHdr;
2201 integer envEgrNpstData;
2202 integer envEgrCmplHdr;
2203 integer envEgrCmplData;
2204
2205 integer envEgrRetry;
2206
2207
2208 this.activityStalled += 1;
2209
2210 egressCreditAvailCSR = readCSR( getCSRaddr( e_CSR_ecrdt_avail ) );
2211 egressCreditUsedCSR = readCSR( getCSRaddr( e_CSR_ecrdt_used ) );
2212 egressRetryCSR = readCSR( getCSRaddr( e_CSR_retry_crdt ) );
2213
2214 tluEgrPostHdr = (egressCreditUsedCSR[60] == 1'b1) ?
2215 infiniteCredits : egressCreditAvailCSR[19:12];
2216
2217 tluEgrPostData = (egressCreditAvailCSR[60] == 1'b1) ?
2218 infiniteCredits : egressCreditAvailCSR[11:0];
2219
2220 tluEgrNpstHdr = (egressCreditUsedCSR[61] == 1'b1) ?
2221 infiniteCredits : egressCreditAvailCSR[39:32];
2222
2223 tluEgrNpstData = (egressCreditAvailCSR[61] == 1'b1) ?
2224 infiniteCredits : egressCreditAvailCSR[31:20];
2225
2226 tluEgrCmplHdr = (egressCreditUsedCSR[62] == 1'b1) ?
2227 infiniteCredits : egressCreditAvailCSR[59:52];
2228
2229 tluEgrCmplData = (egressCreditAvailCSR[62] == 1'b1) ?
2230 infiniteCredits : egressCreditAvailCSR[51:40];
2231
2232 tluEgrRetry = egressRetryCSR[15:0];
2233
2234 envEgrPostHdr = (egressPostHdrAvail == infiniteCredits) ?
2235 infiniteCredits : egressPostHdrAvail % 256;
2236
2237 envEgrPostData = (egressPostDataAvail == infiniteCredits) ?
2238 infiniteCredits : egressPostDataAvail % 4096;
2239
2240 envEgrNpstHdr = (egressNonpostHdrAvail == infiniteCredits) ?
2241 infiniteCredits : egressNonpostHdrAvail % 256;
2242
2243 envEgrNpstData = (egressNonpostDataAvail == infiniteCredits) ?
2244 infiniteCredits : egressNonpostDataAvail % 4096;
2245
2246 envEgrCmplHdr = (egressCompletionHdrAvail == infiniteCredits) ?
2247 infiniteCredits : egressCompletionHdrAvail % 256;
2248
2249 envEgrCmplData = (egressCompletionDataAvail == infiniteCredits) ?
2250 infiniteCredits : egressCompletionDataAvail % 4096;
2251
2252 envEgrRetry = egressRetryAvail % 65536;
2253
2254 verifyEgressCreditStatus = ((tluEgrPostHdr == envEgrPostHdr) &&
2255 (tluEgrPostData == envEgrPostData) &&
2256 (tluEgrNpstHdr == envEgrNpstHdr) &&
2257 (tluEgrNpstData == envEgrNpstData) &&
2258 (tluEgrCmplHdr == envEgrCmplHdr) &&
2259 (tluEgrCmplData == envEgrCmplData) &&
2260 (tluEgrRetry == envEgrRetry));
2261
2262 if (!verifyEgressCreditStatus)
2263 dumpCreditStatus();
2264
2265 this.activityStalled -= 1;
2266}
2267
2268
2269
2270/*
2271* areIngressCreditsExhausted - determine wether the ingress credits have
2272* been exhausted for a particular type.
2273*
2274* Parameters:
2275* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2276* Hdr - Should header credits be returned?
2277*/
2278function integer PEUTestEnv::areIngressCreditsExhausted(integer CreditType, bit Hdr) {
2279
2280
2281 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1))
2282 areIngressCreditsExhausted =
2283 !(ingressPostHdrAvail - ingressPostHdrConsumed);
2284
2285 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0))
2286 areIngressCreditsExhausted =
2287 ((ingressPostDataAvail - ingressPostDataConsumed) < (this.getMaxPayloadSize() / 16));
2288
2289 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1))
2290 areIngressCreditsExhausted =
2291 !(ingressNonpostHdrAvail - ingressNonpostHdrConsumed);
2292
2293 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0))
2294 areIngressCreditsExhausted =
2295 ((ingressNonpostDataAvail - ingressNonpostDataConsumed) < (this.getMaxPayloadSize() / 16));
2296
2297 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1))
2298 areIngressCreditsExhausted =
2299 !(ingressCompletionHdrAvail - ingressCompletionHdrConsumed);
2300
2301 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0))
2302 areIngressCreditsExhausted =
2303 ((ingressCompletionDataAvail - ingressCompletionDataConsumed) < (this.getMaxPayloadSize() / 16));
2304
2305 else
2306 _REPORT_ERROR(
2307 psprintf("PEUTestEnv::areIngressCreditsExhausted Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
2308}
2309
2310
2311
2312/*
2313 * waitIngressCreditsExhausted - wait until the egress credits have
2314 * been exhausted for a particular type.
2315 *
2316 * Parameters:
2317 * CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2318 * Hdr - Should header credits be returned?
2319 */
2320task PEUTestEnv::waitIngressCreditsExhausted(integer CreditType, bit Hdr) {
2321
2322
2323 while (!this.areIngressCreditsExhausted(CreditType, Hdr))
2324 @(posedge CLOCK);
2325}
2326
2327
2328
2329/*
2330* waitIngressCreditRollAround - Wait for the ingress credit counter to roll over
2331*
2332* Parameters:
2333* CreditType - The sort of credit to be returned, as in "l2t_efc_type"
2334* Hdr - Should header credits be returned?
2335*/
2336task PEUTestEnv::waitIngressCreditRollAround(integer CreditType, bit Hdr) {
2337
2338
2339 integer initial;
2340
2341
2342 if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_1)) {
2343
2344 initial = this.ingressPostHdrAvail;
2345
2346 while (((this.ingressPostHdrAvail - initial) <= 257) &&
2347 (initial !== infiniteCredits))
2348 @(posedge CLOCK);
2349
2350 printf("** Ingress Posted Header Credits Rolled Over **\n");
2351 }
2352
2353
2354 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_POST) && (Hdr === 1'b_0)) {
2355
2356 initial = this.ingressPostDataAvail;
2357
2358 while (((this.ingressPostDataAvail - initial) <= 4097) &&
2359 (initial !== infiniteCredits))
2360 @(posedge CLOCK);
2361
2362 printf("** Ingress Posted Data Credits Rolled Over **\n");
2363 }
2364
2365
2366 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_1)) {
2367
2368 initial = this.ingressNonpostHdrAvail;
2369
2370 while (((this.ingressNonpostHdrAvail - initial) <= 257) &&
2371 (initial !== infiniteCredits))
2372 @(posedge CLOCK);
2373
2374 printf("** Ingress Non-Posted Header Credits Rolled Over **\n");
2375 }
2376
2377
2378 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_NONPOST) && (Hdr === 1'b_0)) {
2379
2380 initial = this.ingressNonpostDataAvail;
2381
2382 while (((this.ingressNonpostDataAvail - initial) <= 4097) &&
2383 (initial !== infiniteCredits))
2384 @(posedge CLOCK);
2385
2386 printf("** Ingress Non-Posted Data Credits Rolled Over **\n");
2387 }
2388
2389
2390 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_1)) {
2391
2392 initial = this.ingressCompletionHdrAvail;
2393
2394 while (((this.ingressCompletionHdrAvail - initial) <= 257) &&
2395 (initial !== infiniteCredits))
2396 @(posedge CLOCK);
2397
2398 printf("** Ingress Completion Header Credits Rolled Over **\n");
2399 }
2400
2401
2402 else if ((CreditType === PEC_CREDIT_TYPE__UPDT_COMP) && (Hdr === 1'b_0)) {
2403
2404 initial = this.ingressCompletionDataAvail;
2405
2406 while (((this.ingressCompletionDataAvail - initial) <= 4097) &&
2407 (initial !== infiniteCredits))
2408 @(posedge CLOCK);
2409
2410 printf("** Ingress Completion Data Credits Rolled Over **\n");
2411 }
2412
2413
2414 else
2415 _REPORT_ERROR(
2416 psprintf("PEUTestEnv::waitIngressCreditRollAround Bad CreditType %0d / Hdr %1b", CreditType, Hdr));
2417}
2418
2419
2420
2421/*
2422* suspendRetryUpdates - Stop returning retry credits to the TLU
2423*/
2424task PEUTestEnv::suspendRetryUpdates() {
2425
2426 this.egressRetryAllowed = 0;
2427}
2428
2429
2430
2431/*
2432* resumeRetryUpdates - Resume returning retry credits to the TLU
2433*/
2434task PEUTestEnv::resumeRetryUpdates() {
2435
2436 this.egressRetryAllowed = 1;
2437}
2438
2439
2440
2441/*
2442* areRetryCreditsExhausted - determine wether the retry credits
2443* have been exhausted.
2444*/
2445function integer PEUTestEnv::areRetryCreditsExhausted() {
2446
2447 integer maxRetryCredits;
2448
2449
2450// maxRetryCredits = egressDataWidth + this.getMaxPayloadSize();
2451 //N2 review - Cascade calculates the maxRetryCredits based on the
2452 // max supported packet size of 512. This is max_packet_entries
2453 // in xdlh_tlp_gen and can also not transit the last packet that
2454 // credits got allocated for so we'll compensate for that
2455 maxRetryCredits = egressDataWidth + 512 + 32;
2456
2457 areRetryCreditsExhausted =
2458 (egressRetryAvail - egressRetryConsumed) <= maxRetryCredits;
2459}
2460
2461
2462
2463/*
2464* waitRetryCreditsExhausted - wait until the retry credits have
2465* been exhausted.
2466*/
2467task PEUTestEnv::waitRetryCreditsExhausted() {
2468
2469
2470 while (!this.areRetryCreditsExhausted())
2471 @(posedge CLOCK);
2472}
2473
2474
2475
2476/*
2477* setEgressThrottle - Set the % of time that the TLU is preventing from
2478* delivering egress traffic
2479*
2480* Parameters:
2481* Ratio - The % of time that "l2t_etp_dack" is deasserted
2482*/
2483task PEUTestEnv::setEgressThrottle( integer Ratio )
2484{
2485 string msg;
2486
2487 if ( Ratio < 0 || Ratio > 100 )
2488 egressThrottleRandom = 1;
2489 else
2490 {
2491 sprintf( msg, "Egress throttle (dack deassertion ratio) = %0d", Ratio );
2492 _INFO_MSG( msg );
2493 egressThrottle = Ratio;
2494 egressThrottleRandom = 0;
2495 }
2496} /* end setEgressThrottle */
2497
2498/*
2499* setIngressThrottle - Set the % of time that the LPU sends nothing to the TLU.
2500*
2501* Parameters:
2502* Ratio - The % of time that "l2t_itp_cmd" is IDLE
2503*/
2504task PEUTestEnv::setIngressThrottle( integer Ratio )
2505{
2506 string msg;
2507
2508 if ( Ratio < 0 || Ratio > 100 )
2509 ingressThrottleRandom = 1;
2510 else
2511 {
2512 ingressThrottle = Ratio;
2513 ingressThrottleRandom = 0;
2514 sprintf( msg, "Ingress throttle (idle TLP ratio) = %0d", Ratio );
2515 _INFO_MSG( msg );
2516 }
2517} /* end setIngressThrottle */
2518
2519/*
2520* setIngressAbortRate - Set the % of time that the LPU aborts an ingress TLP
2521*
2522* Parameters:
2523* Ratio - The % of time that a TLP is sent to the TLU with bad CRC (i.e.
2524* aborted by the LPU) before being sent (again) correctly.
2525*/
2526task PEUTestEnv::setIngressAbortRate( integer Ratio )
2527{
2528 if ( Ratio < 0 || Ratio > 100 )
2529 ingressAbortRate = 0;
2530 else
2531 ingressAbortRate = Ratio;
2532} /* end setIngressAbortRate */
2533
2534/*
2535* setIngressGap - Set the min/max # of DWs from end of one TLP to start of next
2536*
2537* Parameters:
2538* MinGap - The minimum number of DWs from EOP to SOP
2539* MaxGap - The maximum number of DWs from EOP to SOP
2540*/
2541task PEUTestEnv::setIngressGap( integer MinGap, integer MaxGap )
2542{
2543 _DEBUG_MSG( "PEUTestEnv: Setting min/max ingress gap to %0d/%0d DWs...\n",
2544 MinGap, MaxGap );
2545 minIngressGap = MinGap;
2546 maxIngressGap = MaxGap;
2547} /* end setIngressGap */
2548
2549/*
2550* setIngressDequeueDelay - Set bounds for the number of cycles between
2551* assertion of "OK to push another ingress Hdr"
2552*
2553* Parameters:
2554* MinDelay - The minimum number of cycles from one assertion of 'k2y_rcd_deq'
2555* MaxDelay - The maximum number of cycles...
2556*/
2557task PEUTestEnv::setIngressDequeueDelay( integer MinDelay, integer MaxDelay )
2558{
2559#ifndef N2_FC
2560 _INFO_MSG( psprintf( "Setting k2y_rcd_deq delay to [%0d:%0d]",
2561 MinDelay, MaxDelay ) );
2562 f_DMUXtr.setIngressDequeueDelay( MinDelay, MaxDelay );
2563#endif
2564} /* end setIngressDequeueDelay */
2565
2566
2567/*
2568* expectIdleState - Make sure that the device is in the "idle state"
2569*
2570* Parameters: None
2571*
2572* An error is reported if the device is not in the "idle state"
2573*/
2574task PEUTestEnv::expectIdleState()
2575{
2576 bit[7:0] hdrCredit;
2577 bit[11:0] dataCredit;
2578 bit isIdle;
2579 string msg;
2580
2581 _DEBUG_MSG( "Enter 'expectIdleState' at cycle #%0d\n", get_cycle() );
2582 repeat(10) @(posedge CLOCK); //N2 review
2583 _DEBUG_MSG( "Enter 'expectIdleState' at cycle #%0d after 10 cycle delay\n", get_cycle() );
2584
2585 // If we're in the drain state, then
2586 // our only expectation is that there
2587 // are no pending non-posted requests.
2588 // We have to make sure that anyone
2589 // waiting for a TLP is freed up.
2590 if ( drainState )
2591 {
2592 if ( !sync( CHECK, ev_drainStateEnd ) )
2593 {
2594 _DEBUG_MSG( " ...and releasing any pending traffic strategy\n" );
2595 trigger( ON, ev_drainStateEnd );
2596 }
2597 else if ( nonpostReqPending != 0 )
2598 {
2599 _REPORT_ERROR( "Nonposted PIO requests not completed?!!?" );
2600 sprintf( msg, "Pending nonposted request tags: %b", nonpostReqPending );
2601 _ERROR_INFO( msg );
2602 }
2603 return;
2604 }
2605
2606 // There should be nothing expected
2607 // from the ingress or egress pipes.
2608 if ( peuExpectTlp != peuExpectComplete )
2609 {
2610 _INFO_MSG( psprintf( "#req=%0d #cpl=%0d #msg=%0d",
2611 peuExpectReq, peuExpectCpl, peuExpectMsg ) );
2612 _REPORT_ERROR( "'expectIdleState' called with TLPs expected from PEU!?!" );
2613 }
2614 if ( iluExpectReq != iluExpectComplete )
2615 {
2616 _REPORT_ERROR( "'expectIdleState' called with TLPs expected from ILU!?!" );
2617 sprintf( msg, "iluExpectReq=%0d iluExpectComplete=%0d", iluExpectReq,iluExpectComplete );
2618 _ERROR_INFO( msg );
2619 }
2620
2621 // Make sure that all credits have been
2622 // returned to the TLU.
2623 returnAllEgressCredits();
2624// waitEgressLatency( 128'bx );
2625 repeat(50) @(posedge CLOCK); //N2 review - FC Update timer + Ingress latency
2626 _DEBUG_MSG( "expectIdleState: Egress credits returned at cycle #%0d\n",
2627 get_cycle() );
2628 activityCounter += 1;
2629
2630 // Tell the monitor to read the CSRs
2631 // which record the ILU/TLU's status.
2632 trigger( ON, ev_CSRupdateReq );
2633 sync( ANY, ev_CSRupdateComplete );
2634 _DEBUG_MSG( "expectIdleState: Request status CSR values at cycle #%0d\n",
2635 get_cycle() );
2636 activityCounter += 1;
2637 @( posedge CLOCK );
2638 sync( ANY, ev_CSRupdateComplete );
2639 trigger( OFF, ev_CSRupdateReq );
2640
2641 // If a soft reset had happened,
2642 // then the reserved credits are
2643 // totally out of whack.
2644 if ( softResetOccurred )
2645 {
2646 ingressNonpostHdrRsvd = 0;
2647 ingressPostHdrRsvd = 0;
2648 ingressPostDataRsvd = 0;
2649 }
2650
2651 isIdle = 1;
2652 if ( !rsbEmpty )
2653 {
2654 isIdle = 0;
2655 _DEBUG_MSG( "device status indicates TLU scoreboard is not empty\n" );
2656 }
2657 hdrCredit = ingressCreditAvailCSR[39:32] - ingressCreditUsedCSR[39:32];
2658 if ( hdrCredit != ingressNonpostHdrInit - ingressNonpostHdrRsvd )
2659 {
2660 isIdle = 0;
2661 _DEBUG_MSG( "ingress non-posted hdr mismatch\n" );
2662 }
2663 hdrCredit = ingressCreditAvailCSR[19:12] - ingressCreditUsedCSR[19:12];
2664 if ( hdrCredit != ingressPostHdrInit - ingressPostHdrRsvd )
2665 {
2666 isIdle = 0;
2667 _DEBUG_MSG( "ingress posted hdr mismatch\n" );
2668 }
2669 dataCredit = ingressCreditAvailCSR[11:0] - ingressCreditUsedCSR[11:0];
2670 if ( dataCredit != ingressPostDataInit - ingressPostDataRsvd )
2671 {
2672 isIdle = 0;
2673 _DEBUG_MSG( "ingress posted data mismatch\n" );
2674 }
2675 if ( ingressCreditUsedCSR[39:32] !=
2676 ((ingressNonpostHdrConsumed+ingressNonpostHdrRsvd) % 256)
2677 || ingressCreditUsedCSR[19:12] !=
2678 ((ingressPostHdrConsumed+ingressPostHdrRsvd) % 256)
2679 || ingressCreditUsedCSR[11:00] !=
2680 ((ingressPostDataConsumed+ingressPostDataRsvd) % 4096) )
2681 {
2682//N2 if ( !drainState && !f_LPUXtr.usePCIE ) isIdle = 0;
2683 _DEBUG_MSG( "ingress credits used do not match total consumed by test\n" );
2684 }
2685 if ( egressPostHdrInit != 0 )
2686 {
2687 hdrCredit = egressCreditAvailCSR[19:12] - egressCreditUsedCSR[19:12];
2688 if ( hdrCredit != egressPostHdrInit )
2689 {
2690 isIdle = 0;
2691 _DEBUG_MSG( "egress posted hdr mismatch hdrCredit=%d AvailCSR=%0d UsedCSR=%0d egressPostHdrInit=%0d egressPostHdrConsumed=%0d egressPostHdrAvail=%0d\n",hdrCredit,egressCreditAvailCSR[19:12],egressCreditUsedCSR[19:12],egressPostHdrInit,egressPostHdrConsumed,egressPostHdrAvail );
2692 }
2693 }
2694 if ( egressPostDataInit != 0 )
2695 {
2696 dataCredit = egressCreditAvailCSR[11:0] - egressCreditUsedCSR[11:0];
2697 if ( dataCredit != egressPostDataInit )
2698 {
2699 isIdle = 0;
2700 _DEBUG_MSG( "egress posted data mismatch dataCredit=%d AvailCSR=%0d UsedCSR=%0d egressPostDataInit=%0d egressPostDataConsumed=%0d egressPostDataAvail=%0d\n",dataCredit,egressCreditAvailCSR[11:0],egressCreditUsedCSR[11:0],egressPostDataInit,egressPostDataConsumed,egressPostDataAvail );
2701 }
2702 }
2703 if ( egressNonpostHdrInit != 0 )
2704 {
2705 hdrCredit = egressCreditAvailCSR[39:32] - egressCreditUsedCSR[39:32];
2706 if ( hdrCredit != egressNonpostHdrInit )
2707 {
2708 isIdle = 0;
2709 _DEBUG_MSG( "egress nonposted hdr mismatch hdrCredit=%d AvailCSR=%0d UsedCSR=%0d egressNonpostHdrInit=%0d egressNonpostHdrConsumed=%0d egressNonpostHdrAvail=%0d\n",hdrCredit,egressCreditAvailCSR[39:32],egressCreditUsedCSR[39:32],egressNonpostHdrInit,egressNonpostHdrConsumed,egressNonpostHdrAvail );
2710 }
2711 }
2712 if ( egressNonpostDataInit != 0 )
2713 {
2714 dataCredit = egressCreditAvailCSR[31:20] - egressCreditUsedCSR[31:20];
2715 if ( dataCredit != egressNonpostDataInit )
2716 {
2717 isIdle = 0;
2718 _DEBUG_MSG( "egress nonposted data mismatch dataCredit=%d AvailCSR=%0d UsedCSR=%0d egressNonpostDataInit=%0d egressNonpostDataConsumed=%0d egressNonpostDataAvail=%0d\n",dataCredit,egressCreditAvailCSR[31:20],egressCreditUsedCSR[31:20],egressNonpostDataInit,egressNonpostDataConsumed,egressNonpostDataAvail );
2719 }
2720 }
2721 if ( egressCompletionHdrInit != 0 )
2722 {
2723 hdrCredit = egressCreditAvailCSR[59:52] - egressCreditUsedCSR[59:52];
2724 if ( hdrCredit != egressCompletionHdrInit )
2725 {
2726 isIdle = 0;
2727 _DEBUG_MSG( "egress completion hdr mismatch hdrCredit=%0d AvailCSR=%0d UsedCSR=%0d egressCompletionHdrInit=%0d \n",hdrCredit,egressCreditAvailCSR[59:52],egressCreditUsedCSR[59:52],egressCompletionHdrInit );
2728 }
2729 }
2730 if ( egressCompletionDataInit != 0 )
2731 {
2732 dataCredit = egressCreditAvailCSR[51:40] - egressCreditUsedCSR[51:40];
2733 if ( dataCredit != egressCompletionDataInit )
2734 {
2735 isIdle = 0;
2736 _DEBUG_MSG( "egress completion data mismatch dataCredit=%0d AvailCSR=%0d UsedCSR=%0d egressCompletionDataInit=%0d \n",dataCredit,egressCreditAvailCSR[51:40],egressCreditUsedCSR[51:40],egressCompletionDataInit );
2737 }
2738 }
2739 if ( ( egressCreditUsedCSR[59:52] != (egressCompletionHdrConsumed % 256)
2740 && (egressCompletionHdrAvail != infiniteCredits) )
2741 || ( egressCreditUsedCSR[51:40] != (egressCompletionDataConsumed % 4096)
2742 && (egressCompletionDataAvail != infiniteCredits) )
2743 || ( egressCreditUsedCSR[39:32] != (egressNonpostHdrConsumed % 256)
2744 && egressNonpostHdrAvail != infiniteCredits )
2745 || ( egressCreditUsedCSR[31:20] != (egressNonpostDataConsumed % 4096)
2746 && egressNonpostDataAvail != infiniteCredits )
2747 || ( egressCreditUsedCSR[19:12] != (egressPostHdrConsumed % 256)
2748 && egressPostHdrAvail != infiniteCredits )
2749 || ( egressCreditUsedCSR[11:00] != (egressPostDataConsumed % 4096)
2750 && egressPostDataAvail != infiniteCredits ) )
2751 {
2752 if ( !drainState && !egressUpdateError ) isIdle = 0;
2753 _DEBUG_MSG( "egress credits used do not match total consumed by test\n" );
2754 }
2755 if ( egressRetryCSR[15:0] != (egressRetryAvail % 65536)
2756 || egressRetryCSR[47:32] != (egressRetryConsumed % 65536) )
2757 {
2758 if ( !drainState ) isIdle = 0;
2759 _DEBUG_MSG( "egress retry credits used do not match environment totals egressRetryCSR[15:0]=%0d egressRetryAvail=%0d %0d ||| egressRetryCSR[47:32]=%0d egressRetryConsumed=%0d %0d\n",egressRetryCSR[15:0],egressRetryAvail,egressRetryAvail % 65536,egressRetryCSR[47:32],egressRetryConsumed,egressRetryConsumed % 65536 );
2760 }
2761
2762 // If we're not in the idle state, then
2763 // complain vigorously.
2764 if ( !isIdle )
2765 {
2766 _REPORT_ERROR( "Device not in 'idle' state!" );
2767 getIntStatus();
2768 dumpIntStatus();
2769 dumpCreditStatus();
2770 repeat(20) @(posedge CLOCK);
2771 }
2772 else
2773 _INFO_MSG( "expectIdleState: Device is IDLE\n" );
2774
2775 _INFO_MSG( psprintf( "Coverage = %h_%h_%h_%h\n",
2776 coverageVector[63:48], coverageVector[47:32],
2777 coverageVector[31:16], coverageVector[15:0] ) );
2778
2779} /* end expectIdleState */
2780
2781/*
2782* getMaxPayloadSize - Obtain the maximum payload size (not including ECRC) as
2783* recorded in the PCI-E Device Control register.
2784*
2785* NOTE: The returned value is in bytes
2786*/
2787function integer PEUTestEnv::getMaxPayloadSize()
2788{
2789#ifdef N2_FC
2790 getMaxPayloadSize = PiuCsrs.piuMaxPayloadSize;
2791#else
2792 getMaxPayloadSize = maxPayloadSize;
2793#endif
2794} /* end getMaxPayloadSize */
2795
2796/*
2797* setMaxPayloadSize - Set the maximum payload size by writing (directly) to
2798* the device-status register.
2799*
2800* Parameters:
2801* MaxSize - The (new?) maximum payload size in bytes
2802*/
2803task PEUTestEnv::setMaxPayloadSize( integer MaxSize )
2804{
2805 integer oldMax;
2806 bit [63:0] csr;
2807 string msg;
2808
2809 oldMax = this.maxPayloadSize;
2810
2811 sprintf( msg, "Max payload size = %0d", MaxSize );
2812 _INFO_MSG( msg );
2813
2814 // Start obeying the new limit
2815 // immediately if we're reducing it.
2816 if ( MaxSize < oldMax )
2817 this.maxPayloadSize = MaxSize;
2818
2819#ifndef N2_FC
2820 // Modify the TLU's "device control".
2821 csr = readCSRdirect( getCSRaddr( e_CSR_dev_ctl ) );
2822 case( MaxSize )
2823 {
2824 256: csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_MPS_SLC] = 3'b001;
2825 512: csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_MPS_SLC] = 3'b010;
2826 default: csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_MPS_SLC] = 3'b000;
2827 }
2828
2829#ifdef N2_IOS
2830 writeCSRdirect( getCSRaddr( e_CSR_dev_ctl ), csr );
2831#else
2832 writeCSR( getCSRaddr( e_CSR_dev_ctl ), csr );
2833#endif
2834
2835#endif
2836 // We can now generate bigger requests
2837 // if we increased the limit.
2838 if ( MaxSize > oldMax )
2839 this.maxPayloadSize = MaxSize;
2840
2841} /* end setMaxPayloadSize */
2842
2843/*
2844* getMaxRequestSize - Obtain the maximum DMA (memory) read-request size
2845*
2846* NOTE: The returned value is in bytes
2847*/
2848function integer PEUTestEnv::getMaxRequestSize()
2849{
2850 getMaxRequestSize = maxRequestSize;
2851} /* end getMaxRequestSize */
2852
2853/*
2854* setMaxRequestSize - Record the maximum DMA (memory) read-request size
2855* for TLPs generated by "genIngressRdReq"
2856*
2857* Parameters:
2858* MaxSize - The (new) maximum read-request size in bytes
2859*/
2860task PEUTestEnv::setMaxRequestSize( integer MaxSize )
2861{
2862 maxRequestSize = MaxSize;
2863} /* end setMaxRequestSize */
2864
2865/*
2866* genIngressWrReq - Generate a correct write request for submission to the
2867* ingress pipeline.
2868*
2869* Parameters:
2870* TlpTag - The tag to be used in the request
2871* TlpHdr - The resulting TLP header
2872* TlpPayload - The resulting TLP payload descriptor
2873* TlpLen - The TLP request/payload length in DWs (optional)
2874*
2875* NOTE: Only memory-write requests are valid
2876*/
2877task PEUTestEnv::genIngressWrReq( bit[7:0] TlpTag,
2878 var bit[127:0] TlpHdr,
2879 var integer TlpPayload,
2880 (integer TlpLen=0) )
2881{
2882 /* A valid ingress write-request must
2883 be a memory-write, with a 32-bit or
2884 64-bit address. */
2885 TlpHdr = 128'b0;
2886 TlpHdr[PEC_PCI__FMT_4DW] = localRandom(100) < gen4DWratio;
2887 TlpHdr[PEC_PCI__FMT_DATA] = 1'b1;
2888 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MEM;
2889
2890 /* We must use the caller's tag. */
2891 TlpHdr[PEC_PCI__TLP_TAG] = TlpTag;
2892
2893 /* ...but the rest is done generically*/
2894 genReqHdr( TlpHdr, 0, TlpLen );
2895 Report.report(RTYP_DEBUG_3,"genIngressWrReq TlpHdr[PEC_PCI__TYPE]=%0h TlpHdr=%0h \n",TlpHdr[PEC_PCI__TYPE],TlpHdr );
2896
2897 /* The payload is a byte-sequence with
2898 a random starting byte. */
2899 TlpPayload = localRandom(256);
2900} /* end genIngressWrReq */
2901
2902/*
2903* genIngressRdReq - Generate an ingress (DMA memory) read request
2904*
2905* Parameters:
2906* TlpTag - The tag to be used in the request
2907* TlpHdr - The resulting TLP header
2908* TlpPayload - The resulting TLP payload descriptor
2909* TlpLen - The TLP request/payload length in DWs (optional)
2910*/
2911task PEUTestEnv::genIngressRdReq(
2912 bit[7:0] TlpTag,
2913 var bit[127:0] TlpHdr,
2914 var integer TlpPayload,
2915 (integer TlpLen=0) )
2916{
2917 /* A valid ingress read-request must
2918 be a memory-read, with a 32-bit or
2919 64-bit address. */
2920 TlpHdr = 128'b0;
2921 TlpHdr[PEC_PCI__FMT_4DW] = localRandom(100) < gen4DWratio;
2922 TlpHdr[PEC_PCI__FMT_DATA] = 1'b0;
2923 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MEM;
2924
2925 /* We must use the caller's tag. */
2926 TlpHdr[PEC_PCI__TLP_TAG] = TlpTag;
2927
2928 /* ...but the rest is done generically*/
2929 genReqHdr( TlpHdr, 0, TlpLen );
2930
2931 /* The payload is a byte-sequence with
2932 a random starting byte. */
2933 TlpPayload = localRandom(256);
2934} /* end genIngressRdReq */
2935
2936/*
2937* genIngressCpl - Generate a completion to a valid egress (PIO) request
2938*
2939* Parameters:
2940* NpstReq - The original non-posted request requiring a completion
2941* TlpHdr - The header for a successful completion to that request
2942* TlpPayload - A payload descriptor
2943*/
2944task PEUTestEnv::genIngressCpl(
2945 bit[127:0] NpstReq,
2946 var bit[127:0] TlpHdr,
2947 var integer TlpPayload )
2948{
2949 genCplHdr( NpstReq, 1, TlpHdr, 0 );
2950 TlpPayload = localRandom(256);
2951} /* end genIngressCpl */
2952
2953/*
2954* genIngressMsg - Generate a valid (expected) DMA message
2955*
2956* Parameters:
2957* TlpTag - The tag to be used
2958* TlpHdr - The resulting message header
2959* TlpPayload - A payload descriptor
2960* TlpLen - The length of the message's payload in DWs (zero => no payload)
2961*/
2962task PEUTestEnv::genIngressMsg(
2963 bit[7:0] TlpTag,
2964 var bit[127:0] TlpHdr,
2965 var integer TlpPayload,
2966 (integer TlpLen=0) )
2967{
2968 /* A message with/without payload is
2969 very much like a memory write/read
2970 request with a 4DW header and a
2971 random tag. The "address" is a
2972 random value which is then used as
2973 embedded payload. */
2974 TlpHdr = 128'b0;
2975 TlpHdr[PEC_PCI__FMT_4DW] = 1'b1;
2976 TlpHdr[PEC_PCI__FMT_DATA] = 1'b0;
2977 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MEM;
2978 TlpHdr[PEC_PCI__TLP_TAG] = TlpTag;
2979 genReqHdr( TlpHdr, 0, TlpLen );
2980 if ( TlpLen == 0 ) TlpHdr[PEC_PCI__LEN] = 0;
2981
2982 /* Set the TLP type to a message with
2983 a random routing code. */
2984//N2 Each message has only 1 valid routing code so use the right one
2985//N2 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG
2986//N2 + (localRandom() & PEC_PCI__TYPE_MSG_RC_MASK);
2987
2988
2989 //The attribute is always 0 except for vendor defined messages
2990 TlpHdr[PEC_PCI__ATTR] = 0;
2991
2992 /* Pick a message code from among those
2993 which are passed on by the TLU. */
2994 randcase
2995 {
2996 1: {
2997 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ASSERT_INTA;
2998 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
2999 TlpHdr[PEC_PCI__TC] = 0;
3000 }
3001 1: {
3002 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ASSERT_INTB;
3003 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3004 TlpHdr[PEC_PCI__TC] = 0;
3005 }
3006 1: {
3007 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ASSERT_INTC;
3008 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3009 TlpHdr[PEC_PCI__TC] = 0;
3010 }
3011 1: {
3012 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ASSERT_INTD;
3013 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3014 TlpHdr[PEC_PCI__TC] = 0;
3015 }
3016 1: {
3017 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_DEASSERT_INTA;
3018 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3019 TlpHdr[PEC_PCI__TC] = 0;
3020 }
3021 1: {
3022 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_DEASSERT_INTB;
3023 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3024 TlpHdr[PEC_PCI__TC] = 0;
3025 }
3026 1: {
3027 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_DEASSERT_INTC;
3028 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3029 TlpHdr[PEC_PCI__TC] = 0;
3030 }
3031 1: {
3032 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_DEASSERT_INTD;
3033 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_100;
3034 TlpHdr[PEC_PCI__TC] = 0;
3035 }
3036 1: {
3037 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_PM_PME;
3038 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_000;
3039 TlpHdr[PEC_PCI__TC] = 0;
3040 }
3041 1: {
3042 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_PM_TO_ACK;
3043 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_101;
3044 TlpHdr[PEC_PCI__TC] = 0;
3045 }
3046 1: {
3047 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ERR_COR;
3048 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_000;
3049 TlpHdr[PEC_PCI__TC] = 0;
3050 }
3051 1: {
3052 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ERR_NONFATAL;
3053 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_000;
3054 TlpHdr[PEC_PCI__TC] = 0;
3055 }
3056 1: {
3057 TlpHdr[PEC_PCI__MSG_CODE] = PEC_PCI__MSG_CODE_ERR_FATAL;
3058 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG + 3'b_000;
3059 TlpHdr[PEC_PCI__TC] = 0;
3060 }
3061 }
3062
3063 /* The payload is a byte-sequence with
3064 a random starting byte. */
3065 TlpPayload = localRandom(256);
3066} /* end genIngressMsg */ /* No message with data or VD-1 messages */ /*???*/
3067
3068/*
3069* genEgressWrReq - Generate a correct write request for submission to the
3070* egress pipeline.
3071*
3072* Parameters:
3073* TlpTag - The tag to be used in the request
3074* TlpHdr - The resulting TLP header
3075* TlpPayload - The resulting TLP payload descriptor
3076* TlpLen - The TLP request/payload length in DWs (optional)
3077* TlpType - The TLP's type (optional)
3078*/
3079task PEUTestEnv::genEgressWrReq( bit[7:0] TlpTag,
3080 var bit[127:0] TlpHdr,
3081 var integer TlpPayload,
3082 (integer TlpLen=0),
3083 (bit[4:0] TlpType=5'bx) )
3084{
3085 integer pickit;
3086 /* A valid egress write-request can
3087 be a memory-write, with a 32-bit or
3088 64-bit address, or a non-posted
3089 (config or I/O) request. */
3090 TlpHdr = 128'b0;
3091 pickit = localRandom(genMemWeight + genConfigWeight + genIoWeight);
3092
3093 if ( TlpType !== 5'bx )
3094 {
3095 TlpHdr[PEC_PCI__TYPE] = TlpType;
3096 }
3097 else if ( pickit < genMemWeight || TlpLen > 1 )
3098 {
3099 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MEM;
3100 }
3101 else if ( pickit < genMemWeight + genConfigWeight )
3102 {
3103 if ( localRandom(2) )
3104 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CFG1;
3105 else
3106 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CFG0;
3107 }
3108 else
3109 {
3110 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_IO;
3111 }
3112
3113 if ( TlpHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
3114 TlpHdr[PEC_PCI__FMT_4DW] = localRandom(100) < gen4DWratio;
3115
3116 TlpHdr[PEC_PCI__FMT_DATA] = 1'b1;
3117
3118
3119 /* We must use the caller's tag. */
3120 TlpHdr[PEC_PCI__TLP_TAG] = TlpTag;
3121
3122 //If a length wasn't passed in for a PIO Memory write then set it here
3123 if ( (TlpHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM) && TlpLen === 0 )
3124 TlpLen = urandom_range( 2, 1 );
3125
3126
3127 /* ...but the rest is done generically*/
3128 if ( TlpHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
3129 genReqHdr( TlpHdr, 1, TlpLen );
3130 else
3131 genReqHdr( TlpHdr, 1, 1 );
3132
3133 /* The payload is a byte-sequence with
3134 a random starting byte. */
3135 TlpPayload = localRandom(256);
3136} /* end genEgressWrReq */
3137
3138/*
3139* genEgressRdReq - Generate a valid PIO read request
3140*
3141* Parameters:
3142* TlpTag - The tag to be used for this request
3143* TlpHdr - The resulting TLP header
3144* TlpPayload - The resulting TLP payload descriptor
3145* TlpLen - The length of the request in DWs (optional)
3146*/
3147task PEUTestEnv::genEgressRdReq(
3148 bit[7:0] TlpTag,
3149 var bit[127:0] TlpHdr,
3150 var integer TlpPayload,
3151 (integer TlpLen=0),
3152 (bit[4:0] TlpType=5'bx) )
3153{
3154 integer pickit;
3155 /* A valid egress read-request can
3156 be a memory-read, with a 32-bit or
3157 64-bit address, or a config/IO
3158 request with a 32-bit address. */
3159 TlpHdr = 128'b0;
3160 pickit = localRandom(genMemWeight + genConfigWeight + genIoWeight);
3161
3162 if ( TlpType !== 5'bx )
3163 {
3164 TlpHdr[PEC_PCI__TYPE] = TlpType;
3165 }
3166 else if ( pickit < genMemWeight || TlpLen > 1 )
3167 {
3168 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MEM;
3169 }
3170 else if ( pickit < genMemWeight + genConfigWeight )
3171 {
3172 if ( localRandom(2) )
3173 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CFG1;
3174 else
3175 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CFG0;
3176 }
3177 else
3178 {
3179 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_IO;
3180 }
3181
3182 if ( TlpHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
3183 TlpHdr[PEC_PCI__FMT_4DW] = localRandom(100) < gen4DWratio;
3184
3185 TlpHdr[PEC_PCI__FMT_DATA] = 1'b0;
3186
3187 /* We must use the caller's tag. */
3188 TlpHdr[PEC_PCI__TLP_TAG] = TlpTag;
3189
3190 /* ...but the rest is done generically*/
3191 if ( TlpHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
3192 genReqHdr( TlpHdr, 1, TlpLen );
3193 else
3194 genReqHdr( TlpHdr, 1, 1 );
3195
3196 TlpPayload = 0;
3197} /* end genEgressRdReq */
3198
3199/*
3200* genEgressCpl - Generate an egress completion corresponding to an ingress
3201* (DMA) memory-read request
3202*
3203* Parameters:
3204* ReadReq - The header for the memory-read request
3205* TlpHdr - A valid header for a completion to the request
3206* TlpPayload - A payload spec'n for the request
3207*/
3208task PEUTestEnv::genEgressCpl(
3209 bit[127:0] ReadReq,
3210 var bit[127:0] TlpHdr,
3211 var integer TlpPayload )
3212{
3213 genCplHdr( ReadReq, 0, TlpHdr, 0 );
3214 TlpPayload = localRandom(256);
3215} /* end genEgressCpl */
3216
3217
3218/*
3219* genEgressPartialCpl - Generate one of the multiple egress completions required
3220* to service a bulk (DMA) memory-read request
3221*
3222* Parameters:
3223* ReadReq - The header for the memory-read request
3224* TlpHdr - A valid header for a completion to the request
3225* TlpPayload - A payload spec'n for the request
3226* Cpl - The number of DWs of data already completed
3227*/
3228task PEUTestEnv::genEgressPartialCpl(
3229 bit[127:0] ReadReq,
3230 var bit[127:0] TlpHdr,
3231 var integer TlpPayload,
3232 integer DWremaining )
3233{
3234 integer dwsRemaining;
3235
3236 dwsRemaining = ReadReq[PEC_PCI__LEN];
3237 if ( dwsRemaining == 0 ) dwsRemaining = 1024;
3238 dwsRemaining = dwsRemaining - DWremaining;
3239
3240 if ( dwsRemaining <= 0 )
3241 _REPORT_ERROR("TEST BUG! 'genEgressPartialCpl' called with bogus DW count");
3242
3243 genCplHdr( ReadReq, 0, TlpHdr, dwsRemaining );
3244 TlpPayload = localRandom(256);
3245} /* end genEgressCpl */
3246
3247/*
3248* expectEgressMsg - Expect a power-management/set-slot message from the TLU
3249*
3250* Parameters:
3251* MsgCode - The sort of message expected (e.g. PEC_PCI__MSG_CODE_PM_TURN_OFF)
3252* MsgData - Expected data (for messages with data)
3253* StimulusDone - An event posted when the stimulus has completed
3254* Lazy - Should we wait forever for the messsage?
3255*/
3256task PEUTestEnv::expectEgressMsg( bit[7:0] MsgCode,
3257 (bit[31:0] MsgData = 0),
3258 (event StimulusDone = null),
3259 (bit Lazy = 0) )
3260{
3261 bit [127:0] tlpHdr;
3262 FNXPCIEXactorTransaction PCIEMsgTrans;
3263 bit setSlot;
3264 bit [2:0] routingCode;
3265//N2 PECXtrDataTLP tlpPkt;
3266 integer postHdrLimit;
3267 string msg;
3268 integer expectTO;
3269 bit [7:0] pyldByteAry[*];
3270 integer msgDLen = 0;
3271 integer j;
3272
3273 tlpHdr = 128'b0;
3274 setSlot = ( MsgCode == PEC_PCI__MSG_CODE_SET_SLOT_POWER_LIMIT );
3275
3276 case ( MsgCode )
3277 {
3278 PEC_PCI__MSG_CODE_PM_TURN_OFF:
3279 routingCode = 3'b011;
3280 PEC_PCI__MSG_CODE_PM_ACTIVE_STATE_NAK:
3281 routingCode = 3'b100;
3282 default:
3283 routingCode = 3'b100;
3284 }
3285
3286 tlpHdr[PEC_PCI__FMT_DATA] = setSlot;
3287 tlpHdr[PEC_PCI__FMT_4DW] = 1'b1;
3288 tlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG | routingCode;
3289 tlpHdr[PEC_PCI__LEN] = setSlot;
3290 tlpHdr[PEC_PCI__MSG_CODE] = MsgCode;
3291
3292 //
3293
3294// have Z's.
3295#ifndef N2_FC
3296 // assign `CPU.dmu.d2p_req_id = 16'h0100 ; Hardwired in ilu_peu_top.v
3297 tlpHdr[ILUPEU_TLP_HDR_REQ_BUS_NUM_BITS] = 8'h01;
3298 tlpHdr[ILUPEU_TLP_HDR_REQ_DEV_NUM_BITS] = 5'h00;
3299 tlpHdr[ILUPEU_TLP_HDR_REQ_FUNC_NUM_BITS] = 3'h0;
3300#else
3301 // value taken from pio write probe (N2fcXactionProbe.vr)
3302 tlpHdr[ILUPEU_TLP_HDR_REQ_BUS_NUM_BITS] = PiuCsrs.piuREQ_ID[15:8];
3303 tlpHdr[ILUPEU_TLP_HDR_REQ_DEV_NUM_BITS] = PiuCsrs.piuREQ_ID[7:3];
3304 tlpHdr[ILUPEU_TLP_HDR_REQ_FUNC_NUM_BITS] = PiuCsrs.piuREQ_ID[2:0];
3305#endif
3306
3307 // Get a PCIE Transaction to give to the xactor.
3308 PCIEMsgTrans = new( Pod.FNXPCIEBldr );
3309 PCIEMsgTrans.SetID( f_ID.NextTransID() );
3310
3311 // ...and shove in the header data,
3312 // ...and whatever payload is expected.
3313 ConvertHdr2PcieTlp( tlpHdr,
3314 0,
3315 PCIEMsgTrans );
3316
3317 // ...and whatever payload is expected.
3318 if ( setSlot )
3319 {
3320 //Delete the data generated in ConvertHdr2PcieTlp
3321 PCIEMsgTrans.MyPacket.Pyld.delete();
3322 //and put in the right payload
3323 msgDLen = 1;
3324 pyldByteAry = new[msgDLen*4];
3325 for(j=0; j < (msgDLen*4); j++){
3326 pyldByteAry[j] = MsgData[j*8+7:j*8];
3327 }
3328 PCIEMsgTrans.MyPacket.SetPyld( pyldByteAry );
3329 }
3330
3331 // The xactor returns when it has seen
3332 // the TLP.
3333
3334 if ( !Lazy ) this.peuExpectTlp = this.peuExpectTlp + 1;
3335 if ( !Lazy ) this.peuExpectMsg = this.peuExpectMsg + 1;
3336
3337 PCIEMsgTrans.MyPacket.PktDisplay( RTYP_DEBUG_3, "Env::expectEgressMsg " );
3338
3339
3340#ifdef N2_FC
3341 expectTO = 5000;
3342#else
3343 expectTO = 1500;
3344#endif
3345 fork
3346 {
3347 //#ifndef N2_FC
3348//review - UDAY Needs to troubleshoot for FC
3349 void = PCIEMsgTrans.Expect( expectTO );
3350 //return the credits consumed by the message!
3351 //#endif
3352 consumeEgressCredits( tlpHdr );
3353 }
3354 {
3355 sync( ANY, ev_drainStateEnd );
3356 printf("Env::expectEgressMsg ev_drainStateEnd hit \n");
3357 }
3358 {
3359 postHdrLimit = 1;
3360 while( postHdrLimit > 0
3361 && !sync( CHECK, StimulusDone ) ) @(posedge CLOCK);
3362 if ( postHdrLimit > 0 ) postHdrLimit = egressPostHdrConsumed + 4;
3363 while( postHdrLimit > 0
3364 && egressPostHdrConsumed < postHdrLimit ) @(posedge CLOCK);
3365
3366 while( Lazy && postHdrLimit > 0 ) @(posedge CLOCK);
3367 if ( postHdrLimit > 0 )
3368 {
3369 _REPORT_ERROR("Egress message not received after 4 posted TLPs\n");
3370 _ERROR_INFO( msg );
3371 }
3372 printf("Env::expectEgressMsg postHdrLimit=%0d hit \n",postHdrLimit);
3373 }
3374 join any
3375
3376 if ( !Lazy ) this.peuExpectComplete = this.peuExpectComplete + 1;
3377 if ( !Lazy ) this.peuExpectMsg = this.peuExpectMsg - 1;
3378 activityCounter = activityCounter + 1;
3379
3380 // For round-robin's sake, expect anything after the message
3381 egressCplOK = 1;
3382 egressReqOK = 1;
3383 egressBadCount = 0;
3384
3385 // Break the "...message not received..." loop
3386 postHdrLimit = 0;
3387
3388} /* end expectEgressMsg */
3389
3390/*
3391* expectTimeoutCpl - Expect a timed-out completion to a given non-posted request
3392*
3393* Parameters:
3394* ReqHdr - The TLP header for the request which we expect to time-out
3395*/
3396task PEUTestEnv::expectTimeoutCpl( bit[127:0] ReqHdr )
3397{
3398 bit[7:0] tag;
3399 // First, make sure that there's a
3400 // pending non-posted request with the
3401 // given tag.
3402 tag = ReqHdr[PEC_PCI__TLP_TAG];
3403 if ( tag > 31 || nonpostReqPending[tag] == 1'b0 )
3404 {
3405 _REPORT_ERROR("Internal error: Invalid tag supplied for nonposted PIO req");
3406 }
3407 else
3408 {
3409 if ( stallNpstWrPending && tag == stallNpstWrTag )
3410 {
3411 _INFO_MSG( "Time-out for prior non-posted write request expected" );
3412 stallNpstWrPending = 0;
3413 }
3414 _DEBUG_MSG( "PEUTestEnv %s: PIO request tag=%h at cycle %0d\n",
3415 "expectTimeoutCpl", tag, get_cycle() );
3416 nonpostReqTimeout[tag] = 1'b1;
3417 sync( ANY, nonpostReqComplete[tag] );
3418 _DEBUG_MSG( "PEUTestEnv %s: Time-out for tag=%h at cycle %0d\n",
3419 "expectTimeoutCpl", tag, get_cycle() );
3420 }
3421} /* end expectTimeoutCpl */
3422
3423/*
3424* isNonpostReq - Is a request non-posted?
3425*
3426* Parameters:
3427* PktHdr - The header of interest
3428*
3429* Returned value: Non-zero if the request is non-posted (i.e. requires a reply)
3430*/
3431function bit PEUTestEnv::isNonpostReq( bit[127:0] PktHdr )
3432 {
3433 if ( PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_CFG0
3434 || PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_CFG1
3435 || PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_IO
3436 || (PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_MEM && !PktHdr[PEC_PCI__FMT_DATA]))
3437 isNonpostReq = 1;
3438 else
3439 isNonpostReq = 0;
3440 }
3441
3442/*
3443 * recordNonpostReq - Look at the header of a TLP just submitted to the
3444 * ILU and record it as a non-posted PIO request, if it is.
3445 *
3446 * Parameters:
3447 * PktHdr - The header of a TLP just presented to the ILU
3448 */
3449task PEUTestEnv::recordNonpostReq( bit[127:0] PktHdr )
3450{
3451 integer tag;
3452
3453 // If the TLP was a non-posted request,
3454 // then record the tag.
3455 if ( isNonpostReq(PktHdr) )
3456 {
3457 tag = PktHdr[PEC_PCI__TLP_TAG];
3458 nonpostReqPending[tag] = 1'b1;
3459 nonpostReqDispatch[tag] = 0;
3460 trigger( OFF, nonpostReqComplete[tag] );
3461
3462 // If we're entering the "drain state",
3463 // then we don't know whether or not to
3464 // expect the request from the TLU.
3465 if ( drainState && !drainStateActive ) nonpostReqInLimbo[tag] = 1'b1;
3466 }
3467} /* end recordNonpostReq */
3468
3469/*
3470 * dispatchNonpostReq - Take note of the fact that a nonposted PIO request
3471 * has just be sent by the TLU
3472 *
3473 * Parameters:
3474 * PktHdr - The header of a TLP just presented by the TLU
3475 */
3476task PEUTestEnv::dispatchNonpostReq( bit[127:0] PktHdr )
3477{
3478 integer tag;
3479
3480 // If the TLP was a non-posted request,
3481 // then get the tag...
3482 if ( PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_CFG0
3483 || PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_CFG1
3484 || PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_IO
3485 || (PktHdr[PEC_PCI__TYPE]==PEC_PCI__TYPE_MEM && !PktHdr[PEC_PCI__FMT_DATA]))
3486 {
3487 tag = PktHdr[PEC_PCI__TLP_TAG];
3488
3489 // ...and make sure that it's still
3490 // a "pending" request...
3491 if ( !nonpostReqPending[tag]
3492 && !sync( CHECK, ev_drainStateEnd ) )
3493 {
3494 if ( nonpostReqInLimbo[tag] )
3495 nonpostReqInLimbo[tag] = 1'b0;
3496 else
3497 _REPORT_ERROR( "PIO request from TLU is not pending?!?" );
3498 }
3499
3500 // ...before recording the cycle when
3501 // the request left the TLU.
3502 else
3503 {
3504 nonpostReqDispatch[tag] = get_cycle();
3505 nonpostReqInLimbo[tag] = 1'b0;
3506 }
3507 }
3508
3509} /* end dispatchNonpostReq */
3510
3511/*
3512 * completeNonpostReq - Look at the header of a TLP submitted by the ILU, and
3513 * take note of a completion to a non-posted PIO request
3514 *
3515 * Parameters:
3516 * PktHdr - The header of a TLP just submitted by the ILU
3517 */
3518task PEUTestEnv::completeNonpostReq( bit [127:0] PktHdr )
3519{
3520 integer tag;
3521
3522 // If the TLP was a completion, then
3523 // get the tag.
3524 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
3525 {
3526 tag = PktHdr[PEC_PCI__CPL_TAG];
3527// completeNonpostReq nonpostReqPending=%0h tag=%0h\n",nonpostReqPending,tag );
3528 // ...and clear our records that the
3529 // corresponding requst is pending.
3530 nonpostReqPending[tag] = 1'b0;
3531 nonpostReqTimeout[tag] = 1'b0;
3532 trigger( ON, nonpostReqComplete[tag] );
3533 }
3534
3535} /* end completeNonpostReq */
3536
3537/*
3538 * genReqHdr - Generate a valid request TLP header
3539 *
3540 * Parameters:
3541 * TlpHdr - The header to be filled in (format, type and tag already exist)
3542 * IsPioReq - Is this a PIO (egress) request?
3543 * TlpLen - The length of the request in DWs (zero=>random)
3544 */
3545task PEUTestEnv::genReqHdr(
3546 var bit[127:0] TlpHdr,
3547 bit IsPioReq,
3548 integer TlpLen )
3549{
3550 integer pickit;
3551 bit [63:0] tlpAddr;
3552 integer maxLen;
3553 integer bulkReq;
3554 integer len;
3555
3556 /* We'll always leave the EP (poisoned)
3557 bit off, but we can set the TD (ECRC)
3558 bit if this is a DMA request. */
3559 TlpHdr[PEC_PCI__EP] = 1'b0;
3560 if ( IsPioReq )
3561 TlpHdr[PEC_PCI__TD] = 1'b0;
3562 else if ( TlpHdr[PEC_PCI__FMT_DATA] )
3563 TlpHdr[PEC_PCI__TD] = localRandom(2); /*???*/
3564 else
3565 TlpHdr[PEC_PCI__TD] = 1'b0;
3566
3567 /* For egress/PIO requests, the traffic
3568 class and attributes are zero.
3569 They're random in ingress requests.*/
3570 if ( IsPioReq )
3571 {
3572 TlpHdr[PEC_PCI__REQ_ID] = localRandom();
3573 TlpHdr[PEC_PCI__TC] = 0;
3574 TlpHdr[PEC_PCI__ATTR] = 0;
3575 }
3576 else
3577 {
3578 TlpHdr[PEC_PCI__REQ_ID] = localRandom();
3579 TlpHdr[PEC_PCI__TC] = localRandom();
3580 TlpHdr[PEC_PCI__ATTR] = localRandom();
3581 }
3582 //Denali can hold a TLP from being transmitted if a previous TLP
3583 // with the same tag and Request ID has not completed yet. This only
3584 // should happen with error TLPs. To help with this make all good REQs
3585 // PEC_PCI__REQ_ID[0] = 0
3586 TlpHdr[80] = 1'b0;
3587
3588
3589 /* If the caller gave us a length,
3590 then use it. Otherwise, use the
3591 controlling parameters. */
3592
3593 if ( IsPioReq )
3594 pickit = localRandom( gen1Weight + genPartialWeight + gen16Weight );
3595 else
3596 pickit = localRandom( gen1Weight + genPartialWeight + gen16Weight
3597 + genBulkWeight );
3598 bulkReq = pickit >= (gen1Weight + genPartialWeight + gen16Weight);
3599
3600 if ( TlpLen < 0 || TlpLen > 1024 )
3601 TlpHdr[PEC_PCI__LEN] = 16;
3602 else if ( TlpLen == 1024 )
3603 TlpHdr[PEC_PCI__LEN] = 0;
3604 else if ( TlpLen > 0 )
3605 TlpHdr[PEC_PCI__LEN] = TlpLen;
3606 else
3607 {
3608 if ( pickit < gen1Weight )
3609 TlpHdr[PEC_PCI__LEN] = 1;
3610 else if ( pickit < gen1Weight + genPartialWeight )
3611 TlpHdr[PEC_PCI__LEN] = 2 + localRandom(14);
3612 else if ( pickit < gen1Weight + genPartialWeight + gen16Weight )
3613 TlpHdr[PEC_PCI__LEN] = 16;
3614 else
3615 {
3616 if ( TlpHdr[PEC_PCI__FMT_DATA] )
3617 maxLen = getMaxPayloadSize() / 4;
3618 else
3619 maxLen = maxRequestSize / 4;
3620 TlpHdr[PEC_PCI__LEN] = 2 + localRandom(maxLen-1);
3621 }
3622 }
3623
3624 /* The address is random*/
3625 tlpAddr = {localRandom(),localRandom()};
3626 tlpAddr[1:0] = 2'b0;
3627 //Allign 8 byte PIO writes
3628 if( IsPioReq && TlpHdr[PEC_PCI__FMT_DATA] && (TlpHdr[PEC_PCI__LEN] == 2) )
3629 tlpAddr[2] = 1'b0;
3630
3631 /* A "bulk" request must cross a
3632 block boundary, or RCB (16DWs). */
3633 /* A "non-bulk" request must not. */
3634 if ( bulkReq )
3635 {
3636 if ( TlpHdr[PEC_PCI__LEN] + tlpAddr[5:2] <= 16 )
3637 tlpAddr[5:2] = 17 - TlpHdr[PEC_PCI__LEN];
3638 }
3639 else
3640 {
3641 if ( TlpHdr[PEC_PCI__LEN] + tlpAddr[5:2] > 16 )
3642 tlpAddr[5:2] = 16 - TlpHdr[PEC_PCI__LEN];
3643 }
3644
3645 /* The request cannot cross a 4KB bndy*/
3646 len = TlpHdr[PEC_PCI__LEN];
3647 if ( len == 0 ) len = 1024;
3648 if ( len + tlpAddr[11:2] > 1024 )
3649 {
3650 if ( len > 16 )
3651 tlpAddr[11:2] = 1024 - TlpHdr[PEC_PCI__LEN];
3652 else
3653 tlpAddr[6] = 1'b0;
3654 }
3655
3656 /* Finally, we can set the address. */
3657 if ( TlpHdr[PEC_PCI__FMT_4DW] )
3658 TlpHdr[PEC_PCI__ADDR] = tlpAddr;
3659 else
3660 TlpHdr[PEC_PCI__ADDR32] = tlpAddr[31:0];
3661
3662 //If this is a cfg type then set the reserved bits to 0
3663 //this is called from TimeOutPEUStr
3664 if( TlpHdr[ PEC_PCI__TYPE ] === PEC_PCI__TYPE_CFG0 ||
3665 TlpHdr[ PEC_PCI__TYPE ] === PEC_PCI__TYPE_CFG1 ){
3666 TlpHdr[ 47:44 ] = 4'h0;
3667 TlpHdr[ 33:32 ] = 2'h0;
3668 }
3669
3670 /* DWBEs are random, but their validity
3671 depends on the length and boundary.*/
3672 setDWBE( TlpHdr );
3673
3674 if ( TlpHdr[PEC_PCI__LEN] == 1 )
3675 {
3676 TlpHdr[PEC_PCI__FIRST_DWBE] = localRandom(16);
3677 TlpHdr[PEC_PCI__LAST_DWBE] = 0;
3678 }
3679/* N2 review
3680 //If QW aligned First and Last can be non-contiguous
3681 else if ( TlpHdr[PEC_PCI__LEN] == 2 && tlpAddr[3] == 1'b0 )
3682 {
3683 TlpHdr[PEC_PCI__FIRST_DWBE] = 1 + localRandom(15);
3684 TlpHdr[PEC_PCI__LAST_DWBE] = 1 + localRandom(15);
3685 }
3686*/
3687 else
3688 {
3689 TlpHdr[PEC_PCI__FIRST_DWBE] = 8'h78 >> localRandom(4);
3690 TlpHdr[PEC_PCI__LAST_DWBE] = 8'h0f >> localRandom(4);
3691 }
3692
3693 Report.report(RTYP_DEBUG_3,"PEUTestEnv::genReqHdr() QW aligned Len=%0d tlpAddr=%0h FIRST_DWBE=%0h LAST_DWBE=%0h \n",TlpHdr[PEC_PCI__LEN],tlpAddr,TlpHdr[PEC_PCI__FIRST_DWBE],TlpHdr[PEC_PCI__LAST_DWBE] );
3694
3695} /* end genReqHdr */
3696
3697/*
3698 * genCplHdr - Generate a completion TLP header corresponding to a request
3699 *
3700 * Parameters:
3701 * NpstReq - The header for the original non-posted request
3702 * IsPioReq - Is this to be a completion to a PIO request?
3703 * TlpHdr - A valid header for a completion to the request
3704 * DWremaining - The number of DWs which remain to be completed, or zero
3705 * if the entire request is to be completed
3706 */
3707task PEUTestEnv::genCplHdr(
3708 bit[127:0] NpstReq,
3709 bit IsPioReq,
3710 var bit[127:0] TlpHdr,
3711 integer DWremaining )
3712{
3713 bit [63:0] addr;
3714 integer reqDWs;
3715
3716 /* Reserved fields in an egress header
3717 must be zero. Ditto for TD and BCM*/
3718 if ( IsPioReq )
3719 TlpHdr = 128'b0;
3720// TlpHdr = { localRandom(), localRandom(), localRandom(), localRandom() };
3721//N2 review - Need to update Denali to handle reserved fields != 0
3722 else
3723 TlpHdr = 128'b0;
3724
3725 /* A completion always uses a 3DW hdr.*/
3726 if ( NpstReq[PEC_PCI__FMT_DATA] )
3727 TlpHdr[PEC_PCI__FMT_DATA] = 1'b0;
3728 else
3729 TlpHdr[PEC_PCI__FMT_DATA] = 1'b1;
3730 TlpHdr[PEC_PCI__FMT_4DW] = 1'b0;
3731 TlpHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_CPL;
3732
3733 /* The completion is not poisoned. */
3734 TlpHdr[PEC_PCI__EP] = 1'b0;
3735
3736 /* The completion is successful. */
3737 TlpHdr[PEC_PCI__CPL_STATUS] = 3'b000;
3738
3739 /* Many values are taken from the req.*/
3740 TlpHdr[PEC_PCI__TC] = NpstReq[PEC_PCI__TC];
3741 TlpHdr[PEC_PCI__ATTR] = NpstReq[PEC_PCI__ATTR];
3742 TlpHdr[PEC_PCI__CPL_REQ_ID] = NpstReq[PEC_PCI__REQ_ID];
3743 TlpHdr[PEC_PCI__CPL_TAG] = NpstReq[PEC_PCI__TLP_TAG];
3744
3745 /* The length is easy if we're handling
3746 request with a single completion. */
3747 if ( DWremaining <= 0 ){
3748 TlpHdr[PEC_PCI__LEN] = NpstReq[PEC_PCI__LEN];
3749
3750 //If this is a Cpl not a CplD then set the LEN = 0
3751 if( TlpHdr[PEC_PCI__FMT_DATA] === 1'b0 ){
3752
3753 TlpHdr[PEC_PCI__LEN] = 0;
3754 }
3755
3756 }
3757 /* Otherwise, determine the number of
3758 RCB blocks required by the request,
3759 and return as many blocks as are in
3760 the "maximum payload size". */
3761 else
3762 {
3763 if ( NpstReq[PEC_PCI__FMT_4DW] )
3764 addr = NpstReq[PEC_PCI__ADDR];
3765 else
3766 addr = NpstReq[PEC_PCI__ADDR32];
3767 reqDWs = NpstReq[PEC_PCI__LEN];
3768 if ( reqDWs == 0 ) reqDWs = 1024;
3769
3770 /* If this is the first completion... */
3771 if ( DWremaining == reqDWs )
3772 {
3773 /* ...then the number of DWs in the
3774 payload depends on how far we start
3775 into a block. */
3776 if ( (reqDWs + addr[5:2]) < getMaxPayloadSize() / 4 ) // Assuming a 64B RCB...
3777 TlpHdr[PEC_PCI__LEN] = DWremaining;
3778 else
3779 TlpHdr[PEC_PCI__LEN] = (getMaxPayloadSize() / 4) - addr[5:2];
3780 }
3781
3782 /* Otherwise, handle whatever's left in
3783 one completion, if we can... */
3784 else if ( DWremaining < getMaxPayloadSize() / 4 )
3785 {
3786 TlpHdr[PEC_PCI__LEN] = DWremaining;
3787 }
3788
3789 /* ...or hand off a "maxPayload" if
3790 we're in the middle of the request.*/
3791 else
3792 {
3793 TlpHdr[PEC_PCI__LEN] = getMaxPayloadSize() / 4;
3794 }
3795 }
3796
3797 /* The completer-ID is a don't-care. */
3798 TlpHdr[PEC_PCI__CPL_ID] = localRandom();
3799
3800 if ( NpstReq[PEC_PCI__FMT_4DW] )
3801 TlpHdr[PEC_PCI__LOWADDR] = NpstReq[PEC_PCI__ADDR] & ~(64'h03);
3802 else
3803 TlpHdr[PEC_PCI__LOWADDR] = NpstReq[PEC_PCI__ADDR32] & ~(32'h03);
3804 //BYTECOUNT should hold the number of remaining bytes including this Cpl
3805 if( DWremaining === 0 ){
3806 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__LEN] * 4;
3807 }else{
3808 TlpHdr[PEC_PCI__BYTECOUNT] = DWremaining * 4;
3809 }
3810//N2 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__LEN] * 4;
3811
3812 /* Modify the byte-count and low-addr
3813 as required by the DWBEs. */
3814 if ( NpstReq[PEC_PCI__TYPE] != PEC_PCI__TYPE_MEM )
3815 {
3816 TlpHdr[PEC_PCI__BYTECOUNT] = 4;
3817 TlpHdr[PEC_PCI__LOWADDR] = 0;
3818 }
3819 else if( DWremaining > 0 && DWremaining < reqDWs ) // For other than the 1st of many Cpls.
3820 {
3821 //N2 - Set bit 6 of the LowerAddress according to the alignment of 64-Byte data
3822 // according to PCIE spec 1.0a pg.87 sec. 2.3.1.1
3823 TlpHdr[PEC_PCI__LOWADDR] = {addr[6],6'h0};
3824
3825 //The byte count needs to be adjusted for last Cpls byte enables
3826 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b1000) )
3827 {
3828 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3829 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b0100) )
3830 {
3831 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3832 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b0010) )
3833 {
3834 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3835 }
3836 }
3837 }
3838 }
3839 else if ( NpstReq[PEC_PCI__FIRST_DWBE] == 0 )
3840 {
3841 TlpHdr[PEC_PCI__BYTECOUNT] = 1;
3842 }
3843 else if ( NpstReq[PEC_PCI__LEN] == 1 )
3844 {
3845 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0001) )
3846 {
3847 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3848 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3849 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0010) )
3850 {
3851 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3852 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3853 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0100) )
3854 {
3855 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3856 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3857 }
3858 }
3859 }
3860
3861 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b1000) )
3862 {
3863 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3864 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0100) )
3865 {
3866 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3867 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0010) )
3868 {
3869 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3870 }
3871 }
3872 }
3873 }
3874 else
3875 {
3876 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0001) )
3877 {
3878 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3879 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3880 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0010) )
3881 {
3882 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3883 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3884 if ( !(NpstReq[PEC_PCI__FIRST_DWBE] & 4'b0100) )
3885 {
3886 TlpHdr[PEC_PCI__LOWADDR] = TlpHdr[PEC_PCI__LOWADDR] + 1;
3887 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3888 }
3889 }
3890 }
3891
3892 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b1000) )
3893 {
3894 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3895 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b0100) )
3896 {
3897 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3898 if ( !(NpstReq[PEC_PCI__LAST_DWBE] & 4'b0010) )
3899 {
3900 TlpHdr[PEC_PCI__BYTECOUNT] = TlpHdr[PEC_PCI__BYTECOUNT] - 1;
3901 }
3902 }
3903 }
3904 }
3905} /* end genCplHdr */ /* LOWADDR & BYTECOUNT crap for bulk */ /*???*/
3906
3907/*
3908* setAddrBndy - Set the boundary for a TLP address.
3909*
3910* Parameters:
3911* TlpHdr - The packet-header to be modified
3912* AddrBndy - The requested address boundary (in bytes)
3913* BlkSize - The block size for that boundary (in bytes, a power of two)
3914*
3915* For example, setting "AddrBndy" to 4 and "BlkSize" to 16 means that the
3916* resulting address is four bytes into a block of 16... the low-order hex
3917* digit for the address is "4".
3918*/
3919task PEUTestEnv::setAddrBndy( var bit[127:0] TlpHdr,
3920 integer AddrBndy,
3921 integer BlkSize )
3922{
3923 bit[63:0] addrMask;
3924
3925 addrMask = 64'hffffffff00000000 | ~(BlkSize-1);
3926
3927 if ( TlpHdr[PEC_PCI__FMT_4DW] )
3928 TlpHdr[PEC_PCI__ADDR] = (TlpHdr[PEC_PCI__ADDR] & addrMask) + AddrBndy;
3929 else
3930 TlpHdr[PEC_PCI__ADDR32] = (TlpHdr[PEC_PCI__ADDR32] & addrMask) + AddrBndy;
3931
3932 //Adjust the DWBE since address changed - especially needed for len=2
3933 setDWBE( TlpHdr );
3934
3935} /* end setAddrBndy */
3936
3937/*
3938* setLenWeights - Set the relative frequency of lengths used for (memory)
3939* read/write requests
3940*
3941* Parameters:
3942* SingleWeight - The relative number of single DW requests
3943* PartialWeight - The relative number of requests from 2 to 15 DWs
3944* LineWeight - The relative number of full cache-line (16 DW) requests
3945* BulkWeight - The relative number of requests spanning the cache-line
3946* boundary (or RCB) up to the "maxPayload/RequestSize"
3947*
3948* NOTE: If a given "...Weight" is negative, then the corresponding value is
3949* not set.
3950*/
3951task PEUTestEnv::setLenWeights( integer SingleWeight, integer PartialWeight,
3952 integer LineWeight, integer BulkWeight )
3953{
3954 string msg;
3955
3956 if ( SingleWeight >= 0 ) gen1Weight = SingleWeight;
3957 if ( PartialWeight >= 0 ) genPartialWeight = PartialWeight;
3958 if ( LineWeight >= 0 ) gen16Weight = LineWeight;
3959 if ( BulkWeight >= 0 ) genBulkWeight = BulkWeight;
3960
3961 sprintf( msg, "Payload weights: 1DW=%0d 2-15DW=%0d 16DW=%0d >16DW=%0d",
3962 SingleWeight, PartialWeight, LineWeight, BulkWeight );
3963 _INFO_MSG( msg );
3964} /* end setLenWeights */
3965
3966/*
3967* setReqWeights - Set the relative frequency of memory, config, and I/O
3968* PIO (egress) requests
3969*
3970* Parameters:
3971* MemoryWeight - The relative number of memory requests
3972* ConfigWeight - The relative number of configuration requests
3973* IoWeight - The relative number of I/O requests
3974*
3975* NOTE: If a given "...Weight" is negative, then the corresponding value is
3976* not set.
3977*/
3978task PEUTestEnv::setReqWeights( integer MemoryWeight,
3979 integer ConfigWeight,
3980 integer IoWeight )
3981{
3982 string msg;
3983
3984 if ( MemoryWeight >= 0 ) genMemWeight = MemoryWeight;
3985 if ( ConfigWeight >= 0 ) genConfigWeight = ConfigWeight;
3986 if ( IoWeight >= 0 ) genIoWeight = IoWeight;
3987
3988 sprintf( msg, "PIO request weights: Memory=%0d Config=%0d IO=%0d",
3989 genMemWeight, genConfigWeight, genIoWeight );
3990 _INFO_MSG( msg );
3991} /* end setReqWeights */
3992
3993
3994
3995
3996/*
3997* isBulkReq - Is a given TLP (header) a "bulk" memory request crossing the RCB?
3998*
3999* Parameters:
4000* TlpHdr - The header of the TLP in question
4001*
4002* Returned value: Non-zero if the header represents a memory read/write request
4003* which crosses the RCB/cache-line boundary (64B in our case)
4004*/
4005function bit PEUTestEnv::isBulkReq( bit[127:0] TlpHdr )
4006{
4007 bit [63:0] addr;
4008
4009 if ( TlpHdr[PEC_PCI__TYPE] != PEC_PCI__TYPE_MEM )
4010 isBulkReq = 0;
4011 else if ( TlpHdr[PEC_PCI__LEN] == 0 )
4012 isBulkReq = 1;
4013 else if ( TlpHdr[PEC_PCI__LEN] > 16 )
4014 isBulkReq = 1;
4015 else
4016 {
4017 if ( TlpHdr[PEC_PCI__FMT_4DW] )
4018 addr = TlpHdr[PEC_PCI__ADDR];
4019 else
4020 addr = TlpHdr[PEC_PCI__ADDR32];
4021 isBulkReq = (TlpHdr[PEC_PCI__LEN] + addr[5:2]) > 16;
4022 }
4023} /* end isBulkReq */
4024
4025/*
4026* payloadFill - Mark a TLP's payload as being filled with a given byte
4027*
4028* Parameters:
4029* TlpPayload - The payload descriptor of interest
4030*/
4031task PEUTestEnv::payloadFill( var integer TlpPayload )
4032{
4033 TlpPayload = TlpPayload | 32'h00002000;
4034}
4035
4036/*
4037 * isPayloadFill - Is a payload just the same byte over and over?
4038 *
4039 * Parameters:
4040 * TlpPayload - The payload descriptor of interest
4041 */
4042function bit PEUTestEnv::isPayloadFill( integer TlpPayload )
4043{
4044 isPayloadFill = ( TlpPayload & 32'h00002000 ) != 0;
4045}
4046
4047/*
4048* poisonPayload - Mark a TLP's payload as being "poisoned"
4049*
4050* Parameters:
4051* TlpPayload - The payload descriptor of interest
4052*/
4053task PEUTestEnv::poisonPayload( var integer TlpPayload )
4054{
4055 TlpPayload = TlpPayload | 32'h00001000;
4056}
4057
4058/*
4059* isPayloadPoisoned - Is a TLP's payload poisoned?
4060*
4061* Parameters:
4062* TlpPayload - The payload descriptor of interest
4063*/
4064function bit PEUTestEnv::isPayloadPoisoned( integer TlpPayload )
4065{
4066 isPayloadPoisoned = ( TlpPayload & 32'h00001000 ) != 0;
4067}
4068
4069/*
4070* errorPayload - Mark a TLP's payload as having a parity error
4071*
4072* Parameters:
4073* TlpPayload - The payload descriptor of interest
4074* ErrorMask - Which (of up to eight) parity bits are in error?
4075*/
4076task PEUTestEnv::errorPayload( var integer TlpPayload,
4077 (bit[7:0] ErrorMask = 8'b0) )
4078{
4079 TlpPayload = TlpPayload | { ErrorMask, 24'h004000 };
4080}
4081
4082/*
4083* isPayloadErroneous - Is a TLP's payload hampered by parity errors?
4084*
4085* Parameters:
4086* TlpPayload - The payload descriptor of interest
4087*/
4088function bit PEUTestEnv::isPayloadErroneous( integer TlpPayload )
4089{
4090 isPayloadErroneous = ( TlpPayload & 32'h00004000 ) != 0;
4091}
4092
4093function bit[7:0] PEUTestEnv::getPayloadErrorMask( integer TlpPayload )
4094{
4095 bit[31:0] payloadDesc;
4096
4097 payloadDesc = TlpPayload;
4098 getPayloadErrorMask = payloadDesc[31:24];
4099}
4100
4101/*
4102* driveILU - Drive a packet into the egress port of the ILU
4103*
4104* Parameters:
4105* PktHdr - The packet's header in PCI-Express format
4106* DataAddr - The starting DOU address of the packet's payload
4107* DataSpec - A description of the payload
4108*/
4109task PEUTestEnv::driveILU(
4110 bit[PEC_PCI__HDR] PktHdr,
4111 bit[7:0] DataAddr,
4112 integer DataSpec,
4113 (bit Priority=0) )
4114{
4115#ifndef N2_FC
4116 bit [7:0] poison;
4117 bit [7:0] payloadByte;
4118 bit payloadFill;
4119 bit payloadErr;
4120 bit [7:0] errMask;
4121 integer blkCount;
4122 integer badBlk;
4123 string msg;
4124
4125
4126 // Hold off any new request if we're in the
4127 // middle of a soft-reset sequence.
4128 if ( softResetPending && PktHdr[PEC_PCI__TYPE] != PEC_PCI__TYPE_CPL )
4129 {
4130 sync( ANY, ev_softResetEnd );
4131 sync( ANY, ev_linkUp );
4132 }
4133
4134 // Wait for the egress pipeline to
4135 // resume if it's currently blocked.
4136 if ( !Priority && !sync( CHECK, ev_egressUnblocked ) )
4137 {
4138 sync( ANY, ev_egressUnblocked );
4139 }
4140
4141 /* The payload is based on the low-order
4142 byte of the "DataSpec". */
4143 payloadByte = DataSpec;
4144
4145 /* If the data is supposed to be
4146 poisoned, then figure out which
4147 blocks should have errors. */
4148 poison = 0;
4149 if ( isPayloadPoisoned(DataSpec) )
4150 {
4151 /* How many blocks are there? */
4152 blkCount = (PktHdr[PEC_PCI__LEN] + 15) / 16;
4153
4154 /* Use the (random) "payloadByte" to
4155 help us figure which block is
4156 poisoned. */
4157 badBlk = payloadByte % blkCount;
4158 poison = 1 << badBlk;
4159
4160 /* ...and maybe a second block is also
4161 very bad... */
4162 badBlk = (payloadByte*3) % blkCount;
4163 poison = poison | ( 1 << badBlk );
4164 /* Is that enough? */ /*???*/
4165 }
4166
4167 payloadByte = DataSpec; // The low-order byte
4168 payloadFill = isPayloadFill( DataSpec );
4169 payloadErr = isPayloadErroneous( DataSpec );
4170 errMask = getPayloadErrorMask( DataSpec );
4171
4172 if ( payloadErr )
4173 {
4174 sprintf( msg, "Send TLP to ILU with incorrect data parity (tag=%h errMask=%0h payloadByte=%0h DataAddr=%0h)",
4175 PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL ?
4176 PktHdr[PEC_PCI__CPL_TAG] : PktHdr[PEC_PCI__TLP_TAG],
4177 errMask, payloadByte, DataAddr );
4178 _INFO_MSG(msg);
4179 }
4180
4181 fork
4182 f_DMUXtr.send( PktHdr,
4183 {errMask,payloadErr,payloadFill,poison,payloadByte},
4184 DataAddr );
4185 sync( ANY, ev_softReset );
4186 join any
4187 recordNonpostReq( PktHdr );
4188
4189 activityCounter = activityCounter + 1;
4190#endif
4191} /* end "driveILU" */
4192
4193/*
4194 * expectILUrel - Catch release records from the ILU
4195 *
4196 * Parameters: None
4197 *
4198 * Note: "mb_ILUrelRecds" has ILU release records from the transactor
4199 */
4200task PEUTestEnv::expectILUrel()
4201{
4202#ifndef N2_FC
4203 bit [8:0] relRecd;
4204 // Tell the DMU xactor about the
4205 // mailbox to be used for release recds!
4206 f_DMUXtr.setRelMailbox( mb_ILUrelRecds );
4207
4208 // ...and then wait for a release
4209 // record in the mailbox.
4210 while( mb_ILUrelRecds != 0 )
4211 {
4212 void = mailbox_get( WAIT, mb_ILUrelRecds, relRecd );
4213 activityCounter = activityCounter + 1;
4214
4215 //If we release the Tag too soon then there is a race condition
4216 // when injecting parity errors
4217 repeat(2) @(posedge CLOCK);
4218
4219 // Either a DOU block was released...
4220 if ( relRecd[8] )
4221 {
4222 if ( !relRecd[7] ) freeCplData( relRecd[7:0] );
4223 }
4224
4225 // ...or a PIO tag.
4226 else
4227 {
4228 freePioTag( relRecd[7:0] );
4229 }
4230 }
4231
4232#endif
4233} /* end "expectILUrel" */
4234
4235/*
4236* expectILU - A TLP is expected from the ILU
4237*
4238* Parameters:
4239* PktHdr - The packet header (in PCI-Express format)
4240* DataSpec - An integer describing the payload (for now, the origin for an
4241* incrementing byte string)
4242*/
4243task PEUTestEnv::expectILU(
4244 bit[PEC_PCI__HDR] PktHdr,
4245 integer DataSpec,
4246 (bit Optional=0) )
4247{
4248#ifndef N2_FC
4249 integer tag;
4250
4251 // If this is a completion and if
4252 // we're in the "drain state", then
4253 // wait for the ILU to drain it.
4254//N2 - Only need 1 ReportClass static ReportClass report = new;
4255
4256 if (Report.get_global_print_threshold() < RPRT_DEBUG_1) {
4257 printf("PEUTestEnv::expectILU(PktHdr=128'h%0h, DataSpec=%0d)\n", PktHdr, DataSpec);
4258 }
4259
4260 tag = PktHdr[PEC_PCI__CPL_TAG];
4261 if ( drainStateActive && PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
4262 {
4263 // Wait for the "we're done" event so that the strategy doesn't return early
4264 if ( tag >= 0 && tag <= 31 )
4265 sync( ANY, nonpostReqComplete[tag] );
4266 }
4267 else if ( !sync( CHECK, ev_drainStateEnd ) )
4268 {
4269 iluExpectReq = iluExpectReq + 1;
4270 fork
4271 f_DMUXtr.recv( PktHdr, DataSpec, Optional );
4272 sync( ANY, ev_drainStateEnd, ev_softReset );
4273 join any
4274/*
4275 //For corner case in testbench where the UR hasn't come out and expectIdle was
4276 // called
4277 //If this is a completion and its still not been cleared in drain state then wait
4278 // until the UR completion comes out and clears the nonpostReqComplete[tag]
4279 if ( sync( CHECK, ev_drainStateEnd ) && (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL) && (tag >= 0 && tag <= 31) ){
4280 sync( ANY, nonpostReqComplete[tag] );
4281 }else{
4282 completeNonpostReq( PktHdr );
4283 }
4284*/
4285 completeNonpostReq( PktHdr );
4286 iluExpectComplete = iluExpectComplete + 1;
4287 activityCounter = activityCounter + 1;
4288 }
4289#endif
4290} /* end "expectILU" */
4291
4292
4293
4294
4295
4296/* N2
4297* drivePCIE - Tell the FNXPcieXtr to send a TLP to the PEU
4298*
4299* Parameters:
4300* PktHdr - The TLP's header, in PCI-Express format
4301* DataSpec - A specification of the packet payload
4302* LenAdjust - An adjustment to the number of DWs presented to the transactor
4303* BadParity - Where should bad parity be inserted (zero=>no bad parity)
4304* Priority - Should the TLP be presented even if the ingress pipe is plugged?
4305* Abort - Should the TLP be aborted (only) before returning?
4306*
4307* NOTE: The caller is suspended until the TLP is on its way to the PEU.
4308*/
4309task PEUTestEnv::drivePCIE(
4310 bit[PEC_PCI__HDR] PktHdr,
4311 bit [63:0] DataSpec,
4312 (integer LenAdjust=0),
4313 (integer BadParity=0),
4314 (bit Priority=0),
4315 (bit Abort=0),
4316 (bit CfgRdCpl=0),
4317 (bit isDmaReq=0),
4318 (bit null_tlp=0) )
4319{
4320//N2 PECXtrDataTLP tlpPkt;
4321//N2 PECXtrDataTLP badPkt;
4322 FNXPCIEXactorTransaction PCIETlpTrans;
4323 FNXPCIEXactorTransaction PCIEDllpTrans;
4324 FNXPCIEXactorTransaction PCIEDllpTrans2;
4325 integer status1, status2;
4326 integer hdrLen;
4327 integer dataLen;
4328 integer xtrLen;
4329 integer tlpGap;
4330 integer pickit;
4331 integer idleChance;
4332 integer badPtyDW;
4333 integer i;
4334 bit [7:0] pyldByteAry[*];
4335 bit [11:0] NakSeqNmbr1 = 0;
4336 bit [11:0] NakSeqNmbr2 = 0;
4337 bit [11:0] nakSent = 0;
4338 integer RcvrErrInjected = 0;
4339 bit donot_increment_nmbrRcvrErrsInjected = 0; // indicator to not increment total rcv error number if
4340 // not injecting rcvrduplicateseqnumber when it's selected in randcase
4341
4342 // for random injection of ECRC
4343 bit inject_ECRC = 0;
4344
4345 // ECRC related
4346 randcase {
4347 inject_ECRC_weight : inject_ECRC = 1;
4348 10 : inject_ECRC = 0;
4349 }
4350
4351 // end ECRC related
4352
4353 Report.report(RTYP_DEBUG_3,"PEUTestEnv::drivePCIE(PktHdr=128'h%0h, DataSpec=%0d, LenAdjust=%0d, BadParity=%0d)\n", PktHdr, DataSpec, LenAdjust, BadParity);
4354 // If this is a completion to a
4355 // non-posted PIO request and if we're
4356 // in the "drain state", then don't
4357 // present it to the PEU... it might be
4358 // flagged as an unsolicited completion
4359 // since the PEU never saw the request.
4360//N2-review Check This
4361
4362 if ( (drainStateActive && PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL) ||
4363 sync( CHECK, ev_removePcie) )
4364 {
4365 return;
4366 }
4367
4368 // If the ingress pipeline is suspended,
4369 // then wait for someone to unblock it.
4370 // Don't block a "priority" TLP
4371 if ( !Priority && !sync( CHECK, ev_ingressUnblocked ) )
4372 {
4373 sync( ANY, ev_drainStateEnd, ev_softReset, ev_ingressUnblocked );
4374 }
4375if ( Priority ){
4376 printf( "Sending priority TLP (tag=%h)\n", PktHdr[PEC_PCI__CPL_TAG] );
4377}
4378
4379 // Bail out if we've been in the "drain state" or if a soft reset is underway.
4380 // Any strategy trying to send a request is held
4381 // in "reserveIngressCredits".
4382 if ( sync( CHECK, ev_drainStateEnd ) || softResetPending ||
4383 sync( CHECK, ev_removePcie) )
4384 {
4385 return;
4386 }
4387
4388 // How big is the header and payload?
4389 hdrLen = 3 + PktHdr[PEC_PCI__FMT_4DW];
4390 if ( PktHdr[PEC_PCI__FMT_DATA] )
4391 {
4392 dataLen = PktHdr[PEC_PCI__LEN];
4393 if ( dataLen == 0 ) dataLen = 1024;
4394 }
4395 else
4396 dataLen = 0;
4397 if ( PktHdr[PEC_PCI__TD] ) dataLen = dataLen + 1;
4398
4399 // And how big is the TLP that we'll
4400 // give to the transactor?
4401 xtrLen = hdrLen + dataLen + LenAdjust;
4402 if ( xtrLen < 1 ) xtrLen = 2;
4403
4404 // Get a PCIE Transaction to give to the xactor.
4405 PCIETlpTrans = new( Pod.FNXPCIEBldr );
4406 PCIETlpTrans.SetID( f_ID.NextTransID() );
4407
4408 // ...and shove in the header data,
4409 // ...and whatever payload is expected.
4410 ConvertHdr2PcieTlp( PktHdr,
4411 DataSpec,
4412 PCIETlpTrans,
4413 LenAdjust,
4414 isDmaReq);
4415
4416 //Don't adjust the payload if this is a length error being sent
4417 if ( CfgRdCpl && (PktHdr[PEC_PCI__LEN] == 1) ) //DANGER IOS FC - Do NOT execute this
4418 {
4419#ifndef N2_FC
4420 //If this is a completion for a config read
4421 //Delete the data generated in ConvertHdr2PcieTlp
4422 PCIETlpTrans.MyPacket.Pyld.delete();
4423 pyldByteAry = new[4];
4424 //and put in the right byte swapped payload
4425 for(i=0; i < 4 ; i++){
4426 pyldByteAry[3-i] = DataSpec + i;
4427 }
4428 PCIETlpTrans.MyPacket.SetPyld( pyldByteAry );
4429#else
4430 bit [7:0] tmpByteAry[*];
4431 tmpByteAry = new[4];
4432 //Get the data generated in ConvertHdr2PcieTlp
4433 PCIETlpTrans.MyPacket.GetPyld( pyldByteAry );
4434 //and put it in the right byte swapped order
4435 for(i=0; i < 4 ; i++){
4436 tmpByteAry[3-i] = pyldByteAry[i];
4437 }
4438 PCIETlpTrans.MyPacket.Pyld.delete();
4439 PCIETlpTrans.MyPacket.SetPyld( tmpByteAry );
4440#endif
4441 }
4442
4443/* N2 review Test this
4444 // increase the payload length of the packet by LenAdjust if needed
4445 for ( i=hdrLen+dataLen; i<xtrLen; i++ )
4446 {
4447 tlpPkt._TLP[i] = nextPayloadDW( DataSpec );
4448 }
4449*/
4450
4451/* N2 - review- Need to test this
4452 // Specify a LPU parity error, if requested
4453 // A negative "BadParity" means "from the end of the packet"
4454 for ( i=0; i<xtrLen; i++ ) tlpPkt._badParity[i] = 4'b0000;
4455 if ( BadParity > 0 && BadParity <= xtrLen*4 )
4456 {
4457 badPtyDW = (BadParity-1)/4;
4458 tlpPkt._badParity[badPtyDW] = 4'b1000 >> ((BadParity-1)%4);
4459 }
4460 else if ( BadParity < 0 && BadParity >= -(xtrLen*4) )
4461 {
4462 badPtyDW = xtrLen + (BadParity+1)/4 - 1;
4463 tlpPkt._badParity[badPtyDW] = 4'b0001 << (((-BadParity)-1)%4);
4464 }
4465 else if ( BadParity != 0 )
4466 {
4467 badPtyDW = localRandom( xtrLen );
4468 tlpPkt._badParity[badPtyDW] = localRandomRange(1,15);
4469 }
4470*/
4471
4472
4473//N2 ingressThrottle - no control over idles between PEU and PTL(TLU)
4474//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4475
4476 // Add some gas to the end of the TLP.
4477 // N2 - Delay is before PCIETlpTrans gets driven
4478 tlpGap = localRandomRange(minIngressGap,maxIngressGap);
4479
4480 // If we're really lucky, send a aborted
4481 // copy of this packet to the TLU.
4482 // But don't play games if this is a completion and we're expecting a time-out
4483//N2 Abort & ingressAbortRate should always be 0
4484//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4485
4486 //If this is a completion then put it in the front of the Denali User Queue
4487 // so an unexpected completion timeout doesn't happen
4488 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL ){
4489 PCIETlpTrans.MyPacket.DriveImmediately = 1;
4490 }
4491
4492
4493
4494 // The PCIETlpTrans returns when the packet is
4495 // completely driven on serial links
4496 // Don't submit the TLP if we're about to reset.
4497 // And if there is a reset pending, hang out until it happens.
4498if ( Priority )
4499printf( "Calling xtr for TLP (tag=%h)\n", PktHdr[PEC_PCI__CPL_TAG] );
4500 fork
4501 {
4502
4503 // if null tlp, then set denaliErr
4504 if (null_tlp) {
4505 PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_TLP_NULL;
4506 InvertLCRCAndEDBErr = 1;
4507 Report.report(RTYP_DEBUG_3,"PEUTestEnv.drivePCIE is called with null_tlp = %d", null_tlp);
4508 }
4509
4510 // do not inject error in cpl package. bench/denali drops package then
4511 if ( PktHdr[PEC_PCI__TYPE] !== PEC_PCI__TYPE_CPL ) {
4512 // if inject ECRC and TD = 1, then set denali to generate ECRC
4513 if (inject_ECRC && (PktHdr[PEC_PCI__TD] == 1)) {
4514 PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_TLP_ENABLE_ECRC;
4515 Report.report(RTYP_DEBUG_3,"PEUTestEnv.drivePCIE is called with TD =1 and ECRC inject at time %d \n", get_time(LO));
4516 }
4517 }
4518
4519 //If enabled then drive packet with a physical error
4520 // after a NAK is sent the packet will be retried by Denali without the error
4521 if( enableRcvrErrInjection && (nmbrRcvrErrsToInject > nmbrRcvrErrsInjected) ){
4522 //Not every packet gets an error
4523 if( urandom()%100 < rcvrErrPct ){
4524
4525 randcase{
4526 rcvrErr8b10bWeight: { PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_8B10B;
4527 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_8B10B );
4528 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4529 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4530 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
4531 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4532 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
4533 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
4534 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
4535 rcvrErr8b10bInjected += 1;
4536 }
4537
4538 rcvrErrFramingWeight: { PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_FRAME;
4539 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4540 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4541 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
4542 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4543 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
4544 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
4545 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
4546 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_MOS_FTS_NC );
4547 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_EDB );
4548 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_MOS_SKP_NC );
4549 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_LIDLE );
4550 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_MOS_IDL_NC );
4551 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_STP1 );
4552 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
4553 rcvrErrFramingInjected += 1;
4554 }
4555 rcvrErrDisparityWeight: { PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DISPARITY;
4556 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4557 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_DISP );
4558 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4559 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4560 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
4561 rcvrErrDisparityInjected += 1;
4562 }
4563 rcvrErrFlipBitWeight: { PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_FLIP_1BIT;
4564 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_8B10B );
4565 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4566 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4567 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
4568 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4569 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
4570 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
4571 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
4572 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_DISP );
4573 rcvrErrFlipBitInjected += 1;
4574 }
4575 rcvrErrLcrcWeight: { PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_LCRC;
4576 rcvrErrLcrcInjected += 1;
4577 }
4578 // do not want to inject DupSeqNmbr error in two consecutive packages so
4579 // use this scheme
4580 // Since completions get added to the front of the Denali user queue then that
4581 // was allowing 2 packets in a row to get the error injected so just
4582 // don't let the error be injected in completions
4583 rcvrErrDupSeqNmbrWeight: {
4584 if ( PktHdr[PEC_PCI__TYPE] !== PEC_PCI__TYPE_CPL ){
4585 donot_increment_nmbrRcvrErrsInjected = 0;
4586 if (rcvrErrSeqNmbrErr_toinject == 0 &&
4587 rcvrErrSeqNmbrErr_justinjected == 0) {
4588 rcvrErrSeqNmbrErr_toinject = 1;
4589 PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DL_SEQ_DUP;
4590 rcvrErrDupSeqNmbrInjected += 1;
4591 }
4592 // else inidcates no error inject so don't increment nmbrRcvrErrsInjected
4593 else {
4594 donot_increment_nmbrRcvrErrsInjected = 1;
4595 if (rcvrErrSeqNmbrErr_justinjected == 1) {
4596 rcvrErrSeqNmbrErr_justinjected = 0;
4597 }
4598 }
4599 }else{
4600 //If its a compleiton then don't inject the error
4601 donot_increment_nmbrRcvrErrsInjected = 1;
4602 }
4603 }
4604
4605 rcvrErrOutOfSeqNmbrWeight: {
4606 if ( PktHdr[PEC_PCI__TYPE] !== PEC_PCI__TYPE_CPL ){
4607 donot_increment_nmbrRcvrErrsInjected = 0;
4608 if( rcvrErrSeqNmbrErr_toinject == 0 &&
4609 rcvrErrSeqNmbrErr_justinjected == 0) {
4610 rcvrErrSeqNmbrErr_toinject = 1;
4611 PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DL_SEQ_INCR;
4612 rcvrErrOutOfSeqNmbrInjected += 1;
4613 }
4614 // else indicates no error inject so don't increment nmbrRcvrErrsInjected
4615 else {
4616 donot_increment_nmbrRcvrErrsInjected = 1;
4617 if (rcvrErrSeqNmbrErr_justinjected == 1) {
4618 rcvrErrSeqNmbrErr_justinjected = 0;
4619 }
4620 }
4621 }else{
4622 //If its a compleiton then don't inject the error
4623 donot_increment_nmbrRcvrErrsInjected = 1;
4624 }
4625 }
4626 rcvrErrBadSeqNmbrWeight: {
4627 if ( PktHdr[PEC_PCI__TYPE] !== PEC_PCI__TYPE_CPL ){
4628 donot_increment_nmbrRcvrErrsInjected = 0;
4629 if( rcvrErrSeqNmbrErr_toinject == 0 &&
4630 rcvrErrSeqNmbrErr_justinjected == 0) {
4631 rcvrErrSeqNmbrErr_toinject = 1;
4632 PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DL_SEQ_RNDM;
4633 rcvrErrBadSeqNmbrInjected += 1;
4634 }
4635 // else indicates no error inject so don't increment nmbrRcvrErrsInjected
4636 else {
4637 donot_increment_nmbrRcvrErrsInjected = 1;
4638 if (rcvrErrSeqNmbrErr_justinjected == 1) {
4639 rcvrErrSeqNmbrErr_justinjected = 0;
4640 }
4641 }
4642 }else{
4643 //If its a compleiton then don't inject the error
4644 donot_increment_nmbrRcvrErrsInjected = 1;
4645 }
4646 }
4647
4648 InvertLCRCErrWeight : {invertLCRC32 = 1;
4649 PCIETlpTrans.MyPacket.invertLCRC32 = 1;
4650 invertLCRC32ErrInjected +=1;
4651 }
4652 EDBErrWeight : {set_endsymbol_EDB = 1 ;
4653 PCIETlpTrans.MyPacket.set_endsymbol_EDB = 1;
4654 EDBErrInjected +=1;
4655 PCIETlpTrans.tempSuppressDenaliErr(PCIE_PL_NONFATAL_FRAME_NULL_TLP );
4656 }
4657
4658 // note: this mode is not used in receiver error strategy, been move to null strategy
4659 InvertLCRCAndEDBErrWeight: { // invertLCRC32 = 1; set_endsymbol_EDB = 1;
4660 // PCIETlpTrans.MyPacket.invertLCRC32 = 1;
4661 // PCIETlpTrans.MyPacket.set_endsymbol_EDB = 1;
4662
4663// PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_TLP_NULL;
4664// InvertLCRCAndEDBErr = 1;
4665 // PCIETlpTrans.tempSuppressDenaliErr(PCIE_PL_NONFATAL_FRAME_NULL_TLP );
4666 }
4667
4668
4669
4670 }
4671 if (donot_increment_nmbrRcvrErrsInjected == 0 ) {
4672 nmbrRcvrErrsInjected += 1;
4673 RcvrErrInjected = 1;
4674 }
4675 }
4676 }
4677 if( !softResetPending ){
4678 PCIETlpTrans.Drive( tlpGap );
4679
4680 // Check for a NAK
4681 fork
4682 if( (RcvrErrInjected == 1) ){
4683 nmbrRcvrErrsDriven +=1;
4684 Report.report(RTYP_DEBUG_3,"PEUTestEnv::drivePCIE Env Receiver Error injected nmbrRcvrErrsToInject=%0d nmbrRcvrErrsInjected=%0d nmbrRcvrErrsDriven=%0d\n",nmbrRcvrErrsToInject,nmbrRcvrErrsInjected,nmbrRcvrErrsDriven );
4685
4686 //Signal that the last error was injected
4687 if( nmbrRcvrErrsToInject == nmbrRcvrErrsDriven ){
4688 trigger( ONE_SHOT, ev_rcvrErrsDriven );
4689 }
4690
4691 case( PCIETlpTrans.MyPacket.DenaliErr ){
4692/* Moved unSuppressDenaliErr to ilupeuIngressRcvrErr
4693 PCIE_EI_8B10B: PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_8B10B );
4694 PCIE_EI_FRAME: {PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4695 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4696 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
4697 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4698 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
4699 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
4700 }
4701 PCIE_EI_DISPARITY:{ PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_DISP );
4702 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4703 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4704 PCIETlpTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4705 }
4706 PCIE_EI_FLIP_1BIT:{PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
4707 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
4708 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
4709 PCIETlpTrans.tempSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
4710 }
4711*/
4712
4713 PCIE_EI_DL_SEQ_DUP:{
4714 if (rcvrErrSeqNmbrErr_toinject == 1) {
4715 rcvrErrSeqNmbrErr_toinject = 0;
4716 rcvrErrSeqNmbrErr_justinjected = 1;
4717 }
4718 }
4719
4720 PCIE_EI_DL_SEQ_INCR:{
4721 if (rcvrErrSeqNmbrErr_toinject == 1) {
4722 rcvrErrSeqNmbrErr_toinject = 0;
4723 rcvrErrSeqNmbrErr_justinjected = 1;
4724 }
4725 }
4726 PCIE_EI_DL_SEQ_RNDM:{
4727 if (rcvrErrSeqNmbrErr_toinject == 1) {
4728 rcvrErrSeqNmbrErr_toinject = 0;
4729 rcvrErrSeqNmbrErr_justinjected = 1;
4730 }
4731 }
4732
4733
4734
4735 }
4736
4737
4738
4739 // no NAK for invertLCRC & EDB case, all others, expect NAK
4740 if (!(InvertLCRCAndEDBErr)) {
4741 if( nakExpected == 0 ){
4742 nakExpected += 1;
4743 //and check for a NAK being sent
4744 //Get the sequence number from transmitted packet
4745 NakSeqNmbr1 = PCIETlpTrans.MyPacket.DLLFrmSeqNum - 1;
4746 NakSeqNmbr2 = PCIETlpTrans.MyPacket.DLLFrmSeqNum;
4747
4748 //Since disparity errors can occur on the next transmitted packet
4749 // then set another NAK expect for the next sequence number
4750 fork
4751 {
4752 PCIEDllpTrans = new( Pod.FNXPCIEBldr );
4753 PCIEDllpTrans.SetID( f_ID.NextTransID() );
4754 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
4755 PCIEDllpTrans.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_NAK;
4756 PCIEDllpTrans.MyPacket.AckNakSeqNum = NakSeqNmbr1;
4757 // time = %0d, fork off wait for Nak of seqNum = %0d", get_time(LO), NakSeqNmbr1);
4758 status1 = PCIEDllpTrans.ExpectExpire( 200 );
4759 if( status1 ){ //If transactin was not removed or didn't fail
4760 nakSent = NakSeqNmbr1;
4761 }
4762
4763 }
4764
4765 {
4766 PCIEDllpTrans2 = new( Pod.FNXPCIEBldr );
4767 PCIEDllpTrans2.SetID( f_ID.NextTransID() );
4768 PCIEDllpTrans2.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
4769 PCIEDllpTrans2.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_NAK;
4770 PCIEDllpTrans2.MyPacket.AckNakSeqNum = NakSeqNmbr2;
4771 // time = %0d, fork off wait for 2nd Nak of seqNum = %0d", get_time(LO), NakSeqNmbr2);
4772 status2 = PCIEDllpTrans2.ExpectExpire( 200 );
4773 if( status2 ){ //If transactin was not removed or didn't fail
4774 nakSent = NakSeqNmbr2;
4775 }
4776
4777 }
4778 join any
4779
4780 if( nakSent == NakSeqNmbr1 ){
4781 void = PCIEDllpTrans2.Remove();
4782 //Wait until replayed packet has been transmitted
4783 PCIETlpTrans.MyPacket.SyncReplayEnd();
4784 }
4785 if( nakSent == NakSeqNmbr2 ){
4786 void = PCIEDllpTrans.Remove();
4787 //Wait until the current transmitted seq number retry packet
4788 while( Pod.FNXPCIEBldr.SignalInterface.currentSeqNum !== NakSeqNmbr2 ){
4789 @( posedge CLOCK );
4790 }
4791 }
4792
4793
4794 nakExpected -= 1;
4795 }
4796 }
4797 }
4798
4799
4800 join none
4801
4802
4803 }else{
4804 sync( ANY, ev_softReset );
4805 }
4806 }
4807 {
4808 sync( ANY, ev_softReset, ev_removePcie );
4809 }
4810 {
4811 sync( ANY, ev_removePcie );
4812 //Mark packets still stuck in the Denali User Queue to be Discarded
4813 //PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DISCARD;
4814 }
4815 join any
4816 activityCounter = activityCounter + 1;
4817if ( Priority )
4818printf( "Xtr has sent priority TLP (tag=%h)\n", PktHdr[PEC_PCI__CPL_TAG] );
4819
4820/* N2 - review- Need to test this
4821 // If we just inserted bad parity into a TLP header, then the bad DW
4822 // might also appear as padding for the prior TLP.
4823 if ( BadParity != 0 && !softResetPending )
4824 {
4825 _DEBUG_MSG( "PEUTestEnv (cycle %0d) %s (offset=%0d)\n", get_cycle(),
4826 "Inject bad ingress TLP parity",
4827 BadParity > 0 ? (BadParity-1) : (xtrLen*4 + BadParity + 1) );
4828 if ( badPtyDW < 3 )
4829 this.f_DMUXtr.ignoreUnusedParity();
4830 }
4831*/
4832
4833//Good from here down
4834 if ( LenAdjust != 0 )
4835 _INFO_MSG( psprintf("TLP length adjusted by %0d DWs", LenAdjust) );
4836
4837 // Bump ingress performance counters...
4838 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
4839 {
4840 if ( PktHdr[PEC_PCI__FMT_DATA] )
4841 perfCtr_dmaWrite = perfCtr_dmaWrite + 1;
4842 else
4843 perfCtr_dmaRead = perfCtr_dmaRead + 1;
4844 }
4845
4846 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
4847 perfCtr_pioCpl = perfCtr_pioCpl + 1;
4848
4849//2.0 PRM spec needs to be updated since PEU counter is only counting incoming DMAs data
4850// and not PIO completions
4851 if ( PktHdr[PEC_PCI__FMT_DATA] && PktHdr[PEC_PCI__TYPE] !== PEC_PCI__TYPE_CPL )
4852 perfCtr_recvDWs = perfCtr_recvDWs + PktHdr[PEC_PCI__LEN];
4853
4854 if ( (PktHdr[PEC_PCI__TYPE]& ~PEC_PCI__TYPE_MSG_RC_MASK) == PEC_PCI__TYPE_MSG)
4855 {
4856 if ( PktHdr[PEC_PCI__MSG_CODE] == PEC_PCI__MSG_CODE_VENDOR_TYPE_0 )
4857 {
4858 if ( !PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[0] = 1;
4859 if ( PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[1] = 1;
4860 }
4861 if ( PktHdr[PEC_PCI__MSG_CODE] == PEC_PCI__MSG_CODE_VENDOR_TYPE_1 )
4862 {
4863 if ( !PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[2] = 1;
4864 if ( PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[3] = 1;
4865 }
4866 if ( PktHdr[PEC_PCI__EP] ) coverageVector[4] = 1;
4867 if ( !PktHdr[PEC_PCI__FMT_4DW] ) coverageVector[12] = 1;
4868 }
4869
4870 else if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM )
4871 {
4872 if ( PktHdr[PEC_PCI__EP] )
4873 {
4874 if ( !PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[5] = 1;
4875 if ( PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[6] = 1;
4876 }
4877 }
4878
4879 else if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
4880 {
4881 if ( PktHdr[PEC_PCI__EP] )
4882 {
4883 if ( !PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[7] = 1;
4884 if ( PktHdr[PEC_PCI__FMT_DATA] ) coverageVector[8] = 1;
4885 }
4886 }
4887
4888 else
4889 {
4890 if ( PktHdr[PEC_PCI__EP] ) coverageVector[9] = 1;
4891 }
4892
4893 if ( xtrLen == 1 ) coverageVector[10] = 1;
4894 if ( xtrLen == 2 ) coverageVector[11] = 1;
4895
4896
4897 // If we just completed our "stalling"
4898 // Config/IO write, then we're free!!
4899 if ( stallNpstWrPending
4900 && PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL
4901 && PktHdr[PEC_PCI__CPL_TAG] == stallNpstWrTag )
4902 {
4903 stallNpstWrPending = 0;
4904 _INFO_MSG( "Completion for non-posted PIO write request submitted" );
4905 }
4906
4907} /* end "drivePCIE" */
4908
4909
4910/* N2
4911* expectPCIE - Tell the FNXPcieXtr to expect a TLP
4912*
4913* Parameters:
4914* PktHdr - The TLP's header, in PCI-Express format
4915* DataSpec - A specification of the packet payload
4916*/
4917task PEUTestEnv::expectPCIE(
4918 bit[PEC_PCI__HDR] PktHdr,
4919 bit [63:0] DataSpec,
4920 bit IgnoreTlpReqTag = 0,
4921 (bit isDmaReq=0),
4922 (integer dma_ptr=0) )
4923{
4924//N2 PECXtrDataTLP tlpPkt;
4925 FNXPCIEXactorTransaction PCIETlpTrans;
4926 bit[127:0] nextPktHdr;
4927 integer nextCplSeq;
4928 integer nextReqSeq;
4929 integer hdrLen;
4930 integer dataLen;
4931 integer i;
4932// integer expectCompleteTO;
4933 string msg;
4934 bit[4:0] tag;
4935 event never;
4936 event reqComplete = null;
4937 bit [7:0] ExpectedReqTag;
4938
4939 // If we're in the drain state, then
4940 // this baby will never come out (or
4941 // at least it shouldn't).
4942 if ( drainStateActive || softResetPending ) return;
4943
4944 // The transmitter's ID used to be always zero when simulating gates...
4945 // if ( get_plus_arg(CHECK, "sim_type=gates") )
4946 // PktHdr[ PEC_PCI__REQ_ID ] = 0;
4947
4948 // Add this TLP to the queue of
4949 // requests/completions expected from
4950 // the PEU.
4951 void = semaphore_get( WAIT, sm_mutex, 1 );
4952 egressLastSeq = egressLastSeq + 1;
4953 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL
4954 || PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL_LK )
4955 {
4956 //printf( "PEUTestEnv::expectPCIE - putting %h into mb_egressCplOrder mailbox\n", PktHdr );
4957 mailbox_put( mb_egressCplOrder, PktHdr );
4958 mailbox_put( mb_egressCplSeq, egressLastSeq );
4959 }
4960 else
4961 {
4962 mailbox_put( mb_egressReqOrder, PktHdr );
4963 mailbox_put( mb_egressReqSeq, egressLastSeq );
4964 }
4965 semaphore_put( sm_mutex, 1 );
4966
4967 // How big is the header and payload?
4968 hdrLen = 3 + PktHdr[PEC_PCI__FMT_4DW];
4969 if ( PktHdr[PEC_PCI__FMT_DATA] )
4970 dataLen = PktHdr[PEC_PCI__LEN];
4971 else
4972 dataLen = 0;
4973
4974
4975 // Get a PCIE Transaction to give to the xactor.
4976 PCIETlpTrans = new( Pod.FNXPCIEBldr );
4977 PCIETlpTrans.SetID( f_ID.NextTransID() );
4978
4979 // ...and shove in the header data,
4980 // ...and whatever payload is expected.
4981 ConvertHdr2PcieTlp( PktHdr,
4982 DataSpec,
4983 PCIETlpTrans,
4984 *,
4985 isDmaReq,
4986 dma_ptr );
4987 PCIETlpTrans.MyPacket.IgnoreTlpReqTag = IgnoreTlpReqTag;
4988
4989/* N2 review Test this later
4990 // Expect a parity error if one was inserted.
4991 tlpPkt._abort = 1'b0;
4992 if ( isPayloadErroneous(DataSpec) )
4993 tlpPkt._status = PC_TLP_STATUS_DATA_PARITY_ERROR;
4994 else
4995 tlpPkt._status = PC_TLP_STATUS_NO_ERROR;
4996*/
4997
4998 // The xactor returns when it has seen
4999 // the TLP. And force an exit if we receive
5000 // a "reqComplete" for a nonposted request.
5001 tag = PktHdr[PEC_PCI__TLP_TAG];
5002 trigger( OFF, never );
5003 if ( isNonpostReq(PktHdr) ) {
5004 reqComplete = nonpostReqComplete[ tag ];
5005 }
5006 else
5007 reqComplete = never;
5008
5009 this.peuExpectTlp = this.peuExpectTlp + 1;
5010 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
5011 this.peuExpectCpl = this.peuExpectCpl + 1;
5012 else
5013 this.peuExpectReq = this.peuExpectReq + 1;
5014
5015
5016
5017
5018 //N2 Big fork-join here since I can't stop the egress pipeline
5019 // allow the expects to finish even if in drain state
5020 fork
5021 {
5022 void = PCIETlpTrans.Expect( expectCompleteTO );
5023
5024 if( !sync( CHECK, ev_removePcie ) ){ //Order doesnt matter if expect packets are removed
5025 // Make sure that this TLP is the one
5026 // we expected next from the PEU!
5027 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL
5028 || PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL_LK )
5029 {
5030 nextPktHdr = 128'b0;
5031 void = mailbox_get( NO_WAIT, mb_egressCplOrder, nextPktHdr );
5032 //printf( "PEUTestEnv::expectPCIE - got %h out of mb_egressCplOrder mailbox\n", nextPktHdr );
5033 void = mailbox_get( NO_WAIT, mb_egressCplSeq, nextCplSeq );
5034 if ( mailbox_get( NO_WAIT, mb_egressReqSeq ) )
5035 void = mailbox_get( COPY_NO_WAIT, mb_egressReqSeq, nextReqSeq );
5036 else
5037 nextReqSeq = nextCplSeq;
5038
5039 if ( nextPktHdr != PktHdr )
5040 {
5041#ifndef N2_FC
5042#ifndef N2_IOS
5043 _REPORT_ERROR( "CRAMP! Out-of-order completion received from PEU!" );
5044 sprintf( msg,"Expect: %h\n", nextPktHdr );
5045 _ERROR_INFO( msg );
5046 sprintf( msg,"Actual: %h\n", PktHdr );
5047 _ERROR_INFO( msg );
5048#endif
5049#endif
5050 }
5051 else if ( !egressCplOK && nextReqSeq < nextCplSeq
5052 && !stallNpstWr
5053 && !egressPostStarved && !egressNonpostStarved )
5054 {
5055 egressReqOK = 1;
5056 egressBadCount = egressBadCount + 1;
5057 printf( "egressBadCount = %0d\n", egressBadCount );
5058 if ( egressBadCount > 4 )
5059 _REPORT_ERROR( "CRAMP! Completion violates round-robin arbitration!" );
5060 }
5061 else
5062 {
5063 egressReqOK = 1;
5064 egressCplOK = 1;
5065 //N2 || stallNpstWr
5066 //N2 || egressPostStarved
5067 //N2 || egressNonpostStarved;
5068 egressBadCount = 0;
5069 }
5070 }
5071 else
5072 {
5073 void = mailbox_get( NO_WAIT, mb_egressReqOrder, nextPktHdr );
5074 void = mailbox_get( NO_WAIT, mb_egressReqSeq, nextReqSeq );
5075 if ( mailbox_get( NO_WAIT, mb_egressCplSeq ) )
5076 void = mailbox_get( COPY_NO_WAIT, mb_egressCplSeq, nextCplSeq );
5077 else
5078 nextCplSeq = nextReqSeq;
5079 if ( nextPktHdr != PktHdr )
5080 {
5081#ifndef N2_FC
5082 _REPORT_ERROR( "CRAMP! Out-of-order request received from PEU!" );
5083 sprintf( msg,"Expect: %h\n", nextPktHdr );
5084 _ERROR_INFO( msg );
5085 sprintf( msg,"Actual: %h\n", PktHdr );
5086 _ERROR_INFO( msg );
5087#endif
5088 }
5089 else if ( !egressReqOK && nextCplSeq < nextReqSeq
5090 && !egressCompletionStarved )
5091 {
5092 egressCplOK = 1;
5093 egressBadCount = egressBadCount + 1;
5094 printf( "egressBadCount = %0d\n", egressBadCount );
5095 if ( egressBadCount > 4 )
5096 _REPORT_ERROR( "CRAMP! PIO request violates round-robin arbitration!" );
5097 }
5098 else
5099 {
5100 egressCplOK = 1;
5101 egressReqOK = 1;
5102 //N2 || egressCompletionStarved;
5103 egressBadCount = 0;
5104 }
5105 }
5106
5107
5108 // Make sure that the PEU didn't violate
5109 // credit restrictions, and make
5110 // arrangements for those credits to be
5111 // returned (eventually).
5112 // No credits are consumed if the TLP
5113 // was aborted due to a parity error.
5114 //N2 if ( !PktHdr[PEC_PCI__FMT_DATA] || !isPayloadErroneous(DataSpec) )
5115 //N2 if ( !f_LPUXtr.usePCIE )
5116 if ( !sync( CHECK, ev_removePcie ) ){
5117
5118 consumeEgressCredits( PktHdr );
5119 }
5120
5121 // If we're waiting for a non-posted write
5122 // to complete, then there shouldn't be any
5123 // other request! Cplns are OK...
5124 if ( stallNpstWrPending
5125 && PktHdr[PEC_PCI__TYPE] != PEC_PCI__TYPE_CPL
5126 && PktHdr[PEC_PCI__TYPE] != PEC_PCI__TYPE_CPL_LK )
5127 {
5128 _REPORT_ERROR( "PIO request dispatched when nonposted write is pending" );
5129 }
5130
5131 if ( stallNpstWr
5132 && PktHdr[PEC_PCI__FMT_DATA]
5133 && ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG0
5134 || PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CFG1
5135 || PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_IO ) )
5136 {
5137 stallNpstWrPending = 1;
5138 stallNpstWrTag = PktHdr[PEC_PCI__TLP_TAG];
5139 _INFO_MSG( psprintf( "Non-posted PIO write request dispatched... tag=%h",
5140 stallNpstWrTag ) );
5141 }
5142 }//End if ( !sync( CHECK, ev_removePcie )
5143 }
5144 {
5145 sync( ANY, ev_softReset, ev_removePcie );
5146 //Since soft reset means no more transactions will be sent
5147 // remove any outstanding expects that would timeout later
5148 void = PCIETlpTrans.Remove();
5149 }
5150 {
5151 sync( ANY, reqComplete, ev_drainStateEnd );
5152 }
5153
5154 join any
5155
5156 //End N2 Big fork-join
5157
5158#ifdef N2_FC
5159//Added in v 1.155 but it causes some tests to fail
5160// in PEU. The ilupeuLnkTrnFstx8x8LinkDownRetrainLink fails after the
5161// 1st warm reset because CSR daemon access quit working. ifdef around
5162// for right now.
5163 // kill the other threads
5164 terminate;
5165#endif
5166
5167 // Grab ReqTag so we can send completion with it
5168 ReceivedReqTag = PCIETlpTrans.MyPacket.ReceivedReqTag;
5169
5170#ifdef N2_FC
5171 if ( (PCIETlpTrans.MyPacket.CmnType == FNX_PCIE_XTR_TYPE_IOWR ||
5172 PCIETlpTrans.MyPacket.CmnType == FNX_PCIE_XTR_TYPE_CFGWR0 ||
5173 PCIETlpTrans.MyPacket.CmnType == FNX_PCIE_XTR_TYPE_CFGWR1 ||
5174 PCIETlpTrans.MyPacket.CmnType == FNX_PCIE_XTR_TYPE_MWR) &&
5175 PCIETlpTrans.MyPacket.CmnFmt[FNX_PCIE_XTR_FMT_DATA_SLC])
5176 {
5177 bit [4:0] CmdType = PCIETlpTrans.MyPacket.CmnType;
5178 bit [63:0] fcaddr = 0;
5179 bit [63:0] piodata = 0;
5180 if( PCIETlpTrans.MyPacket.CmnFmt[FNX_PCIE_XTR_FMT_64BIT_SLC] ){
5181 fcaddr = {PCIETlpTrans.MyPacket.AddrUpper, PCIETlpTrans.MyPacket.AddrLower, 2'b0};
5182 }
5183 else {
5184 fcaddr = {32'b0, PCIETlpTrans.MyPacket.AddrLower, 2'b0};
5185 }
5186 if (CmdType == FNX_PCIE_XTR_TYPE_IORD) {
5187 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD] | 32'h10000000;
5188 }
5189 else if (CmdType == FNX_PCIE_XTR_TYPE_CFGRD0 ||
5190 CmdType == FNX_PCIE_XTR_TYPE_CFGRD1) {
5191 fcaddr = {PCIETlpTrans.MyPacket.CfgBusNum,
5192 PCIETlpTrans.MyPacket.CfgDeviceNum,
5193 PCIETlpTrans.MyPacket.CfgFuncNum,
5194 PCIETlpTrans.MyPacket.CfgExtRegNum,
5195 PCIETlpTrans.MyPacket.CfgRegNum, 2'b0};
5196 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD];
5197 }
5198 else if( PCIETlpTrans.MyPacket.CmnFmt[FNX_PCIE_XTR_FMT_64BIT_SLC] ) {
5199 //fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM64_FLD];
5200 }
5201 else {
5202 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM32_FLD];
5203 }
5204 for(i=0; i < PCIETlpTrans.MyPacket.Pyld.size() ; i++){
5205 piodata[63-(i*8):64-((i+1)*8)] = PCIETlpTrans.MyPacket.Pyld[i];
5206 }
5207
5208 // in order to not violate ordering rules, store data to sparce mem
5209 // now rather then when the pio is detected at the ncu
5210 QuickReport( Report, RTYP_DEBUG_1,
5211 "UDEBUG PEUTestEnv::expectPCIE PIO Write : addr %0h, pyldsize %d data %0h\n",
5212 fcaddr, PCIETlpTrans.MyPacket.Pyld.size(),
5213 (PCIETlpTrans.MyPacket.Pyld.size() < 8) ? piodata[63:32] : piodata
5214 );
5215 N2fcWrMem (fcAddrMsk | fcaddr, piodata[63:32], PCIETlpTrans.MyPacket.BEFirstDW);
5216 if (PCIETlpTrans.MyPacket.Pyld.size() == 8)
5217 N2fcWrMem (fcAddrMsk | fcaddr + 4, piodata[31:0], PCIETlpTrans.MyPacket.BELastDW );
5218 }
5219 else {
5220 if ( !(PCIETlpTrans.MyPacket.CmnType >= FNX_PCIE_XTR_TYPE_CPL &&
5221 PCIETlpTrans.MyPacket.CmnType <= FNX_PCIE_XTR_TYPE_CPLDLK) ) {
5222
5223 bit [4:0] CmdType = PCIETlpTrans.MyPacket.CmnType;
5224 bit [63:0] fcaddr = 0;
5225 if( PCIETlpTrans.MyPacket.CmnFmt[FNX_PCIE_XTR_FMT_64BIT_SLC] ){
5226 fcaddr = {PCIETlpTrans.MyPacket.AddrUpper, PCIETlpTrans.MyPacket.AddrLower, 2'b0};
5227 }
5228 else {
5229 fcaddr = {32'b0, PCIETlpTrans.MyPacket.AddrLower, 2'b0};
5230 }
5231 if (CmdType == FNX_PCIE_XTR_TYPE_IORD) {
5232 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD] | 32'h10000000;
5233 }
5234 else if (CmdType == FNX_PCIE_XTR_TYPE_CFGRD0 ||
5235 CmdType == FNX_PCIE_XTR_TYPE_CFGRD1) {
5236 fcaddr = {PCIETlpTrans.MyPacket.CfgBusNum,
5237 PCIETlpTrans.MyPacket.CfgDeviceNum,
5238 PCIETlpTrans.MyPacket.CfgFuncNum,
5239 PCIETlpTrans.MyPacket.CfgExtRegNum,
5240 PCIETlpTrans.MyPacket.CfgRegNum, 2'b0};
5241 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD];
5242 }
5243 else if( PCIETlpTrans.MyPacket.CmnFmt[FNX_PCIE_XTR_FMT_64BIT_SLC] ) {
5244 //fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM64_FLD];
5245 }
5246 else {
5247 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM32_FLD];
5248 }
5249 fcAddrArray[ReceivedReqTag] = fcaddr;
5250 QuickReport( Report, RTYP_INFO,"UDEBUG PEUTestEnv::expectPCIE save completion Addr = %0h Tag = %0h\n",
5251 fcAddrArray[ReceivedReqTag], ReceivedReqTag);
5252 }
5253 }
5254#endif
5255
5256
5257// if ( PktHdr[PEC_PCI__FMT_DATA] )
5258 if ( PktHdr[PEC_PCI__FMT_DATA] && PktHdr[PEC_PCI__TYPE] === PEC_PCI__TYPE_CPL )
5259 perfCtr_xmitDWs = perfCtr_xmitDWs + PktHdr[PEC_PCI__LEN];
5260
5261 this.peuExpectComplete = this.peuExpectComplete + 1;
5262 if ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL )
5263 this.peuExpectCpl = this.peuExpectCpl - 1;
5264 else
5265 this.peuExpectReq = this.peuExpectReq - 1;
5266 activityCounter = activityCounter + 1;
5267
5268 // If this was a nonposted PIO request,
5269 // then remember that we've sent it.
5270#ifndef N2_FC
5271 dispatchNonpostReq( PktHdr );
5272#endif
5273 // Don't worry about violating
5274 // credit restrictions if we're in the
5275 // "drain state"... we're just faking
5276 // out the strategy anyway.
5277 if ( sync( CHECK, ev_drainStateEnd ) ) return;
5278 if ( sync( CHECK, reqComplete ) ) return;
5279
5280 // If we're in the middle of a soft reset,
5281 // then free the DOU blocks associated with
5282 // a DMA completion. Since we don't know
5283 // which ones are involved, free them all.
5284 if ( sync( CHECK, ev_softReset ) )
5285 {
5286 for ( i=0; i<32; i++ )
5287 if ( douBlksUsed[i] ) freeCplData( i*4 );
5288 trigger( ON, ev_douBlkFreed );
5289 return;
5290 }
5291
5292
5293} /* end "expectPCIE" */
5294
5295
5296/*
5297 * nextPayloadDW - Obtain the next DW of payload, given a "spec"
5298 *
5299 * Parameters:
5300 * DataSpec - A specification of the packet payload
5301 */
5302function bit[31:0] PEUTestEnv::nextPayloadDW(
5303 var integer DataSpec )
5304{
5305 bit [7:0] dataByte;
5306 bit [31:0] dataDW;
5307 integer j;
5308
5309 if ( isPayloadPoisoned(DataSpec) || isPayloadErroneous(DataSpec) )
5310 dataDW = 32'hXXXXXXXX;
5311 else
5312 {
5313 dataByte = DataSpec;
5314 dataDW = 32'b0;
5315 for ( j=0; j<4; j++ )
5316 {
5317 dataDW = { dataDW[23:0], dataByte };
5318 if ( !isPayloadFill( DataSpec ) ) dataByte = dataByte + 1;
5319 }
5320
5321 if ( !isPayloadFill( DataSpec ) ) DataSpec = dataByte;
5322 }
5323
5324 nextPayloadDW = dataDW;
5325} /* end "nextPayloadDW" */
5326
5327/*
5328* allocWrTag - Allocate a tag (and starting DOU address) for a PIO write request
5329*
5330* Parameters:
5331* TlpTag - The allocated tag
5332* DataAddr - The allocated DOU address (for up to 16DW of payload)
5333*/
5334task PEUTestEnv::allocWrTag( // Obtain a PIOWr tag & DOU addr
5335 var bit[7:0] TlpTag,
5336 var bit[7:0] DataAddr )
5337{
5338 bit [3:0] tag;
5339
5340#ifndef N2_FC
5341 // Wait 'til a tag is available
5342 void = semaphore_get( WAIT, sm_PioTags, 1 );
5343#endif
5344
5345 // Then pick one at random
5346 tag = localRandom();
5347 while ( pioTagsUsed[tag] ) tag = tag + 5;
5348 pioTagsUsed[tag] = 1'b1;
5349
5350 TlpTag = { 4'b0001, tag };
5351
5352 // There's a DOU block tied
5353 // to every tag.
5354// DataAddr = { 2'b10, tag, 2'b00 };
5355 DataAddr = { 4'b1000, tag };
5356 Report.report(RTYP_DEBUG_3,"PEUTestEnv::allocWrTag TlpTag=%0h pioTagsUsed=%0h \n",TlpTag,pioTagsUsed);
5357} /* end "allocWrTag" */
5358
5359
5360
5361/*
5362* allocRdTag - Allocate a tag for a PIO read request
5363*
5364* Parameters:
5365* TlpTag - The allocated tag
5366*/
5367task PEUTestEnv::allocRdTag(
5368 var bit[7:0] TlpTag )
5369{
5370 bit [3:0] tag = 4'b0;
5371
5372#ifndef N2_FC
5373 // Wait 'til a tag is available
5374 void = semaphore_get( WAIT, sm_PioTags, 1 );
5375#endif
5376
5377 // Then pick one at random
5378 tag = localRandom();
5379 while ( pioTagsUsed[tag] ) tag = tag + 7;
5380 pioTagsUsed[tag] = 1'b1;
5381
5382 TlpTag = { 4'b0000, tag };
5383 Report.report(RTYP_DEBUG_3,"PEUTestEnv::allocRdTag TlpTag=%0h pioTagsUsed=%0h \n",TlpTag,pioTagsUsed);
5384} /* end "allocRdTag" */
5385
5386
5387
5388/*
5389* freePioTag - Deallocate a tag for a non-posted PIO request
5390*
5391* Parameters:
5392* TlpTag - The tag to be freed
5393*/
5394task PEUTestEnv::freePioTag( // Release a PIO tag
5395 bit[7:0] TlpTag )
5396{
5397 integer tag;
5398 string errMsg;
5399
5400 tag = TlpTag[3:0];
5401 if ( TlpTag[4] )
5402 {
5403 if ( pioTagsUsed[tag] )
5404 {
5405 pioTagsUsed[tag] = 1'b0;
5406#ifndef N2_FC
5407 semaphore_put( sm_PioTags, 1 );
5408 }
5409 // When a strategy frees a tag while in drain-state, it might
5410 // have already been freed when the ILU presents the completion.
5411 else if ( !sync( CHECK, ev_drainStateEnd ) )
5412 {
5413 sprintf( errMsg, "PIO-Write tag '%x' erroneously released", tag );
5414 _REPORT_ERROR( errMsg );
5415#endif
5416 }
5417 }
5418 else
5419 {
5420 if ( pioTagsUsed[tag] )
5421 {
5422 pioTagsUsed[tag] = 1'b0;
5423#ifndef N2_FC
5424 semaphore_put( sm_PioTags, 1 );
5425 }
5426 else if ( !sync( CHECK, ev_drainStateEnd ) )
5427 {
5428 sprintf( errMsg, "PIO-Read tag '%x' erroneously released", tag );
5429 _REPORT_ERROR( errMsg );
5430#endif
5431 }
5432 }
5433 Report.report(RTYP_DEBUG_3,"PEUTestEnv::freePioTag called with TlpTag=%0h pioTagsUsed=%0h \n",TlpTag,pioTagsUsed);
5434} /* end "freePioTag" */
5435
5436
5437/*
5438* allocDmaTag - Allocate a tag for a DMA (ingress) request
5439*
5440* Parameters:
5441* TlpTag - The reserved DMA-request tag
5442*
5443* NOTE: The caller is suspended if there are no available DMA tags
5444*/
5445task PEUTestEnv::allocDmaTag( // Obtain a DMA tag
5446 var bit[7:0] TlpTag )
5447{
5448 bit [7:0] tag;
5449
5450 // Wait 'til a tag is available
5451 void = semaphore_get( WAIT, sm_DmaTags, 1 );
5452
5453 // Then pick one at random
5454 tag = localRandom();
5455 while ( dmaTagsUsed[tag] ) tag = tag + 13;
5456 dmaTagsUsed[tag] = 1'b1;
5457
5458 TlpTag = tag;
5459} /* end "allocDmaTag" */
5460
5461
5462/*
5463* freeDmaTag - De-allocate a tag for a DMA (ingress) request
5464*
5465* Parameters:
5466* TlpTag - The DMA-request tag to be freed
5467*/
5468task PEUTestEnv::freeDmaTag( // Release a DMA tag
5469 bit[7:0] TlpTag )
5470{
5471 dmaTagsUsed[TlpTag] = 1'b0;
5472 semaphore_put( sm_DmaTags, 1 );
5473} /* end "freeDmaTag" */
5474
5475/*
5476* allocCplData - Allocate a number of (contiguous DMA read) DOU blocks
5477*
5478* Parameters:
5479* Len - The number of DWs to be stored
5480* LowAddr - The low-address bits from the completion header
5481* DouAddr - The full address of the first DOU block
5482*
5483* NOTE: This caller is suspended if insufficient DOU blocks are available
5484*/
5485task PEUTestEnv::allocCplData( // Allocate some DOU blocks
5486 integer Len,
5487 bit[6:0] LowAddr,
5488 var bit[7:0] DouAddr )
5489{
5490 bit [4:0] firstBlk;
5491 bit [4:0] thisBlk;
5492 integer blkCount;
5493 integer unusedBlks;
5494 integer i;
5495
5496 // How many blocks are req'd?
5497 blkCount = ( Len + LowAddr[5:2] + 15 ) / 16;
5498 if ( blkCount > 32 || Len == 0 )
5499 _REPORT_ERROR( "TEST BUG! Excessive length given to allocCplData" );
5500
5501 // Only one customer at a time
5502 void = semaphore_get( WAIT, sm_DouMutex, 1 );
5503 douBlksRequest = blkCount;
5504
5505 // Look for "blkCount" consecutive
5506 // blocks, and wait for them to show
5507 // up if they aren't there.
5508 while( blkCount > 0 )
5509 {
5510 trigger( OFF, ev_douBlkFreed );
5511
5512 thisBlk = localRandom();
5513 unusedBlks = 0;
5514 for ( i=0; i<64 && unusedBlks<blkCount; i++ )
5515 {
5516 if ( douBlksUsed[thisBlk] )
5517 unusedBlks = 0;
5518 else
5519 {
5520 if ( unusedBlks == 0 ) firstBlk = thisBlk;
5521 unusedBlks = unusedBlks + 1;
5522 }
5523 thisBlk = thisBlk + 1;
5524 }
5525
5526 // If we've found "blkCount" consecutive
5527 // blocks, then we're done.
5528 if ( unusedBlks == blkCount ) break;
5529
5530 // If we didn't find free blocks, we
5531 // have to wait for a block to free up.
5532 sync( ANY, ev_douBlkFreed );
5533 }
5534
5535 // Mark the reserved blocks as "used"
5536 thisBlk = firstBlk;
5537 for ( i=0; i<blkCount; i++ )
5538 {
5539 douBlksUsed[thisBlk] = 1'b1;
5540 thisBlk = thisBlk + 1;
5541 }
5542
5543 // Let someone else get a block
5544 douBlksRequest = 0;
5545 semaphore_put( sm_DouMutex, 1 );
5546
5547 DouAddr = { 1'b0, firstBlk, 2'b00 };
5548} /* end "allocCplData" */
5549
5550/*
5551* freeCplData - Free a DOU block allocated by "allocCplData"
5552*
5553* Parameters:
5554* DouAddr - The full address of the DOU block to be deallocated
5555*/
5556task PEUTestEnv::freeCplData(
5557 bit[7:0] DouAddr )
5558{
5559 integer blk;
5560 string errMsg;
5561
5562 blk = DouAddr[6:2];
5563 if ( DouAddr[7] || (!douBlksUsed[blk] && !softResetPending) )
5564 {
5565 sprintf( errMsg, "DOU block '%x' erroneously released", DouAddr );
5566 _REPORT_ERROR( errMsg );
5567 }
5568 else
5569 {
5570 douBlksUsed[blk] = 1'b0;
5571 trigger( ON, ev_douBlkFreed );
5572 }
5573} /* end "freeCplData" */
5574
5575/*
5576* set4DWratio - Set the ratio of generated TLPs with 4DW headers
5577*
5578* Parameters:
5579* ratio - The desired percentage of TLPs with 4DW headers (from zero to 100)
5580*/
5581task PEUTestEnv::set4DWratio( integer ratio )
5582{
5583 if ( ratio >= 0 && ratio <= 100 )
5584 gen4DWratio = ratio;
5585}
5586
5587/*
5588* reserveIngressCredits - Reserve ingress credits required to send a given TLP.
5589* If the credits are not available, then the caller is
5590* suspended until they are.
5591*
5592* Parameters:
5593* PktHdr - The header of the TLP in question
5594*/
5595//Default switched to bypass_FC_credit since Denali will control credits and pacing of
5596// tlps
5597task PEUTestEnv::reserveIngressCredits( bit[PEC_PCI__HDR] PktHdr, bit bypass_FC_credit_checking=1 )
5598{
5599 integer isCpl; // Is the "PktHdr" a completion?
5600 integer isPost; // Is the "PktHdr" a posted request?
5601 integer dataCredits; // # of data credits required
5602 integer hdrAvail; // Total header credits available
5603 integer dataAvail; // Total data credits available
5604
5605 Report.report(RTYP_DEBUG_3,"reserveIngressCredits called reserveIngressCreditsCntr=%0d \n",reserveIngressCreditsCntr);
5606 // A completion?
5607 isCpl = (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL)
5608 || (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL_LK);
5609
5610 if ( !isCpl && softResetPending )
5611 {
5612 sync( ANY, ev_softResetEnd );
5613 }
5614
5615 // If this is a DMA request, then wait
5616 // until the link is up.
5617 if ( !isCpl && !sync( CHECK, ev_linkUp ) )
5618 {
5619 sync( ANY, ev_linkUp );
5620 }
5621
5622 // A posted request? (Msg or MemWrite)
5623 isPost = ( (PktHdr[PEC_PCI__TYPE] & ~PEC_PCI__TYPE_MSG_RC_MASK)
5624 == PEC_PCI__TYPE_MSG )
5625 || ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM
5626 && PktHdr[PEC_PCI__FMT_DATA] );
5627
5628 // How many data credits are required?
5629 dataCredits = 0;
5630 if ( PktHdr[PEC_PCI__FMT_DATA] )
5631 dataCredits = (PktHdr[PEC_PCI__LEN] + 3) / 4;
5632
5633 // Get in line for credits!
5634 if ( isCpl )
5635 void = semaphore_get( WAIT, sm_consumeCompletion, 1 );
5636 else if ( isPost )
5637 void = semaphore_get( WAIT, sm_consumePost, 1 );
5638 else
5639 void = semaphore_get( WAIT, sm_consumeNonpost, 1 );
5640
5641
5642 // for FC overflow testing, then bypass the credit checking or else nothing proceeds
5643 if ( (bypass_FC_credit_checking) == 0) {
5644
5645 QuickReport( Report, RTYP_INFO, "Env:: reserveIngressCredits: checking credits ");
5646
5647 // Wait for credits if necessary
5648 if ( isCpl )
5649 {
5650 hdrAvail = ingressCompletionHdrAvail - ingressCompletionHdrRsvd;
5651 dataAvail = ingressCompletionDataAvail - ingressCompletionDataRsvd;
5652 while( !sync( CHECK, ev_drainStateEnd ) && !softResetPending
5653 && ( hdrAvail - ingressCompletionHdrConsumed < 1
5654 || dataAvail - ingressCompletionDataConsumed < dataCredits ) )
5655 {
5656 sync( ANY, ev_creditUpdateReceived, ev_drainStateEnd, ev_softReset );
5657 hdrAvail = ingressCompletionHdrAvail - ingressCompletionHdrRsvd;
5658 dataAvail = ingressCompletionDataAvail - ingressCompletionDataRsvd;
5659 }
5660 }
5661 else if ( isPost )
5662 {
5663 hdrAvail = ingressPostHdrAvail - ingressPostHdrRsvd;
5664 dataAvail = ingressPostDataAvail - ingressPostDataRsvd;
5665
5666Report.report(RTYP_DEBUG_3,"reserveIngressCreditsCnt ingressPostHdrAvail=%0d ingressPostHdrRsvd=%0d ingressPostDataAvail=%0d ingressPostDataRsvd=%0d hdrAvail=%0d dataAvail=%0d ingressPostHdrConsumed=%0d ingressPostDataConsumed=%0d dataCredits=%0d \n",
5667ingressPostHdrAvail,ingressPostHdrRsvd,ingressPostDataAvail,ingressPostDataRsvd,hdrAvail,dataAvail,ingressPostHdrConsumed,ingressPostDataConsumed,dataCredits );
5668
5669 while( !sync( CHECK, ev_drainStateEnd ) && !softResetPending
5670 && ( hdrAvail - ingressPostHdrConsumed < 1
5671 || dataAvail - ingressPostDataConsumed < dataCredits ) )
5672 {
5673 sync( ANY, ev_creditUpdateReceived, ev_drainStateEnd, ev_softReset );
5674 hdrAvail = ingressPostHdrAvail - ingressPostHdrRsvd;
5675 dataAvail = ingressPostDataAvail - ingressPostDataRsvd;
5676 }
5677 }
5678 else
5679 {
5680 hdrAvail = ingressNonpostHdrAvail - ingressNonpostHdrRsvd;
5681 dataAvail = ingressNonpostDataAvail - ingressNonpostDataRsvd;
5682 while( !sync( CHECK, ev_drainStateEnd ) && !softResetPending
5683 && ( hdrAvail - ingressNonpostHdrConsumed < 1
5684 || dataAvail - ingressNonpostDataConsumed < dataCredits ) )
5685 {
5686 sync( ANY, ev_creditUpdateReceived, ev_drainStateEnd, ev_softReset );
5687 hdrAvail = ingressNonpostHdrAvail - ingressNonpostHdrRsvd;
5688 dataAvail = ingressNonpostDataAvail - ingressNonpostDataRsvd;
5689 }
5690 }
5691 } // end bypass
5692
5693 // Add the credits required for this
5694 // TLP to the total reserved so far.
5695 if ( sync( CHECK, ev_drainStateEnd ) || softResetPending )
5696 {
5697 // Do nothing
5698 }
5699 else if ( isCpl )
5700 {
5701 ingressCompletionHdrRsvd = ingressCompletionHdrRsvd + 1;
5702 ingressCompletionDataRsvd = ingressCompletionDataRsvd + dataCredits;
5703 }
5704 else if ( isPost )
5705 {
5706 ingressPostHdrRsvd = ingressPostHdrRsvd + 1;
5707 ingressPostDataRsvd = ingressPostDataRsvd + dataCredits;
5708 }
5709 else
5710 {
5711 ingressNonpostHdrRsvd = ingressNonpostHdrRsvd + 1;
5712 ingressNonpostDataRsvd = ingressNonpostDataRsvd + dataCredits;
5713 }
5714
5715 // Give someone else a chance to
5716 // reserve necesary credits.
5717 if ( isCpl )
5718 semaphore_put( sm_consumeCompletion, 1 );
5719 else if ( isPost )
5720 semaphore_put( sm_consumePost, 1 );
5721 else
5722 semaphore_put( sm_consumeNonpost, 1 );
5723
5724reserveIngressCreditsCntr += 1;
5725
5726} /* end "reserveIngressCredits" */
5727
5728/*
5729* consumeIngressCredits - Return the credits for an ingress TLP to the pool
5730* of credits to (eventually) be returned by the TLU.
5731*
5732* Parameters:
5733* PktHdr - The header of the TLP whose credits might be returned by the TLU.
5734*/
5735task PEUTestEnv::consumeIngressCredits( bit[PEC_PCI__HDR] PktHdr )
5736{
5737 integer isCpl; // Is the "PktHdr" a completion?
5738 integer isPost; // Is the "PktHdr" a posted request?
5739 integer dataCredits; // # of data credits required
5740 integer hdrAvail; // Total header credits available
5741 integer dataAvail; // Total data credits available
5742
5743 // If the link isn't up, then this is bogus
5744 if ( !sync( CHECK, ev_linkUp ) ) return;
5745
5746 // A completion?
5747 isCpl = (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL)
5748 || (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL_LK);
5749
5750 // A posted request? (Msg or MemWrite)
5751 isPost = ( (PktHdr[PEC_PCI__TYPE] & ~PEC_PCI__TYPE_MSG_RC_MASK)
5752 == PEC_PCI__TYPE_MSG )
5753 || ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM
5754 && PktHdr[PEC_PCI__FMT_DATA] );
5755
5756 // How many data credits are required?
5757 dataCredits = 0;
5758 if ( PktHdr[PEC_PCI__FMT_DATA] )
5759 dataCredits = (PktHdr[PEC_PCI__LEN] + 3) / 4;
5760
5761 // Credits are no longer reserved,
5762 // they are now officially consumed.
5763 if ( isCpl )
5764 {
5765 ingressCompletionHdrRsvd = ingressCompletionHdrRsvd - 1;
5766 ingressCompletionDataRsvd = ingressCompletionDataRsvd - dataCredits;
5767 ingressCompletionHdrConsumed = ingressCompletionHdrConsumed + 1;
5768 ingressCompletionDataConsumed = ingressCompletionDataConsumed + dataCredits;
5769 }
5770 else if ( isPost )
5771 {
5772 ingressPostHdrRsvd = ingressPostHdrRsvd - 1;
5773 ingressPostDataRsvd = ingressPostDataRsvd - dataCredits;
5774 ingressPostHdrConsumed = ingressPostHdrConsumed + 1;
5775 ingressPostDataConsumed = ingressPostDataConsumed + dataCredits;
5776 }
5777 else
5778 {
5779 ingressNonpostHdrRsvd = ingressNonpostHdrRsvd - 1;
5780 ingressNonpostDataRsvd = ingressNonpostDataRsvd - dataCredits;
5781 ingressNonpostHdrConsumed = ingressNonpostHdrConsumed + 1;
5782 ingressNonpostDataConsumed = ingressNonpostDataConsumed + dataCredits;
5783 }
5784
5785} /* end "consumeIngressCredits" */
5786
5787/*
5788* consumeEgressCredits - Add the credits required for a TLP sent by the
5789* TLU to the total consumed so far, and put a token
5790* in the appropriate mailbox so that the credits are
5791* restored by "updateEgressCredits" at a later time.
5792*
5793* Parameters:
5794* PktHdr - The header of the TLP presented by the TLU
5795*/
5796task PEUTestEnv::consumeEgressCredits( bit[PEC_PCI__HDR] PktHdr )
5797{
5798 integer isCpl; // Is the "PktHdr" a completion?
5799 integer isPost; // Is the "PktHdr" a posted request?
5800 integer dataCredits; // # of associated data credits
5801 integer retryCredits; // # of retry credits consumed
5802 string msg;
5803
5804 bit[63:0] RetryCSR;
5805
5806 //Since ev_drainStateEnd means we will reset the PEU don't worry about the
5807 // credits anymore
5808 if( sync( CHECK, ev_drainStateEnd )){
5809 return;
5810 }
5811
5812 // A completion?
5813 isCpl = (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL)
5814 || (PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_CPL_LK);
5815
5816 // A posted request? (Msg or MemWrite)
5817 isPost = ( (PktHdr[PEC_PCI__TYPE] & ~PEC_PCI__TYPE_MSG_RC_MASK)
5818 == PEC_PCI__TYPE_MSG )
5819 || ( PktHdr[PEC_PCI__TYPE] == PEC_PCI__TYPE_MEM
5820 && PktHdr[PEC_PCI__FMT_DATA] );
5821 Report.report(RTYP_DEBUG_3,"PEUTestEnv::consumeEgressCredits isPost=%0d PktHdr[PEC_PCI__TYPE=%0h PEC_PCI__TYPE_MSG_RC_MASK=%0h PEC_PCI__TYPE_MSG=%0h result=%0h" , isPost,PktHdr[PEC_PCI__TYPE],PEC_PCI__TYPE_MSG_RC_MASK, (PktHdr[PEC_PCI__TYPE] & ~PEC_PCI__TYPE_MSG_RC_MASK) );
5822 // How many data credits are involved?
5823 dataCredits = 0;
5824 if ( PktHdr[PEC_PCI__FMT_DATA] )
5825 dataCredits = (PktHdr[PEC_PCI__LEN] + 3) / 4;
5826
5827
5828 // Add the credits required by the
5829 // given "PktHdr" to the total consumed
5830 // by the TLU. Complain vigorously if
5831 // the TLU has exceeded its budget.
5832 if ( isPost )
5833 {
5834 egressPostHdrConsumed = egressPostHdrConsumed + 1;
5835 egressPostDataConsumed = egressPostDataConsumed + dataCredits;
5836 if ( egressPostHdrConsumed > egressPostHdrAvail
5837 || egressPostDataConsumed > egressPostDataAvail )
5838 {
5839 _REPORT_ERROR( "BLAST! Egress posted credit allowance exceeded!" );
5840 sprintf( msg ,"egressPostHdrConsumed=%0d > egressPostHdrAvail%0d || egressPostDataConsumed=%0d > egressPostDataAvail=%0d",egressPostHdrConsumed,egressPostHdrAvail,egressPostDataConsumed,egressPostDataAvail);
5841 _ERROR_INFO(msg);
5842 }
5843
5844 // Add the credits associated with this
5845 // TLP to the appropriate bin...
5846
5847 this.egressPostHdrToReturn += 1;
5848 this.egressPostDataToReturn += dataCredits;
5849 }
5850 else if ( isCpl )
5851 {
5852 egressCompletionHdrConsumed = egressCompletionHdrConsumed + 1;
5853 egressCompletionDataConsumed = egressCompletionDataConsumed + dataCredits;
5854 if ( egressCompletionHdrConsumed > egressCompletionHdrAvail
5855 || egressCompletionDataConsumed > egressCompletionDataAvail )
5856 {
5857 _REPORT_ERROR( "BLAST! Egress compl'n credit allowance exceeded!" );
5858 }
5859
5860 // Add the credits associated with this
5861 // TLP to the appropriate bin...
5862
5863 this.egressCompletionHdrToReturn += 1;
5864 this.egressCompletionDataToReturn += dataCredits;
5865 }
5866 else
5867 {
5868 egressNonpostHdrConsumed = egressNonpostHdrConsumed + 1;
5869 egressNonpostDataConsumed = egressNonpostDataConsumed + dataCredits;
5870 if ( egressNonpostHdrConsumed > egressNonpostHdrAvail
5871 || egressNonpostDataConsumed > egressNonpostDataAvail )
5872 {
5873 _REPORT_ERROR( "BLAST! Egress non-posted credit allowance exceeded!" );
5874 }
5875
5876 // Add the credits associated with this
5877 // TLP to the appropriate bin...
5878
5879 this.egressNonpostHdrToReturn += 1;
5880 this.egressNonpostDataToReturn += dataCredits;
5881 }
5882
5883 // We have to do the same for retry
5884 // credits...
5885 retryCredits = 12;
5886 if ( PktHdr[PEC_PCI__FMT_4DW] ) retryCredits = retryCredits + 4;
5887 if ( PktHdr[PEC_PCI__TD] ) retryCredits = retryCredits + 4;
5888 if ( PktHdr[PEC_PCI__FMT_DATA] ) retryCredits = retryCredits +
5889 4*PktHdr[PEC_PCI__LEN];
5890
5891 // Retry credits are consumed in
5892 // N-byte blocks, where N is the
5893 // number of lanes in the link.
5894//N2-review - Is this the same for Cascade
5895 if ( (retryCredits % egressDataWidth) > 0 ){
5896 retryCredits = retryCredits + egressDataWidth
5897 - (retryCredits % egressDataWidth);
5898 }
5899
5900 egressRetryConsumed = egressRetryConsumed + retryCredits;
5901 if ( egressRetryConsumed > egressRetryAvail )
5902 {
5903 _REPORT_ERROR( "ZUT! The TLU has exceeded its retry credit allowance!" );
5904 }
5905
5906#ifdef N2_FC
5907#else
5908 fork
5909 {
5910 RetryCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_erb.read(CSRT_DAEMON);
5911// mb_egressRetry retryCredits=%0d egressRetryConsumed=%0d RetryCSR[15:0]=%0h RetryCSR[47:32]=%0h \n",retryCredits,egressRetryConsumed,RetryCSR[15:0],RetryCSR[47:32] );
5912 }
5913 join none
5914#endif
5915
5916 mailbox_put( mb_egressRetry, retryCredits );
5917 //Put a sequence number that corresponds to the credits so they can be restored when
5918 // a ACK or NAK is received
5919// mb_egressSeqNum egressNextTransmitSeqNum=%0d \n",egressNextTransmitSeqNum );
5920 mailbox_put( mb_egressSeqNum, egressNextTransmitSeqNum );
5921 //Increment the Egress sequence number each time a TLP is sent
5922
5923 egressNextTransmitSeqNum = egressNextTransmitSeqNum + 1;
5924// consumeEgressCredits isCpl=%0d isPost=%0d egressPostHdrToReturn=%0d egressNonpostHdrToReturn=%0d egressCompletionHdrToReturn=%0d \n",isCpl,isPost,egressPostHdrToReturn,egressNonpostHdrToReturn,egressCompletionHdrToReturn);
5925
5926} /* end "consumeEgressCredits" */
5927
5928/*
5929 * updateIngressCredits - A perpetual thread which records updated ingress
5930 * credit totals from the TLU
5931 */
5932task PEUTestEnv::updateIngressCredits()
5933{
5934 FNXPCIEXactorTransaction PCIEDllpTrans;
5935 PEC_FCtype fcType;
5936 integer fcHdr;
5937 integer fcData;
5938 bit fcHP;
5939 integer changed;
5940
5941 integer rxLastPostHdr;
5942 integer rxLastPostData;
5943 integer rxLastNonpostHdr;
5944 integer rxLastNonpostData;
5945 integer rxLastCompletionHdr;
5946 integer rxLastCompletionData;
5947
5948 integer rxTimeOut;
5949 integer oldPostDataConsumed;
5950
5951 // Wait for "link up"
5952 sync( ANY, ev_linkUp, ev_softReset );
5953 if ( sync( CHECK, ev_softReset ) ) return;
5954
5955 // We start with the initial credit totals
5956 ingressPostHdrAvail = ingressPostHdrInit;
5957 ingressPostDataAvail = ingressPostDataInit;
5958 ingressNonpostHdrAvail = ingressNonpostHdrInit;
5959 ingressNonpostDataAvail = ingressNonpostDataInit;
5960 ingressCompletionHdrAvail = ingressCompletionHdrInit;
5961 ingressCompletionDataAvail = ingressCompletionDataInit;
5962
5963 if ( ingressPostHdrAvail == 0 )
5964 ingressPostHdrAvail = infiniteCredits;
5965 if ( ingressPostDataAvail == 0 )
5966 ingressPostDataAvail = infiniteCredits;
5967 if ( ingressNonpostHdrAvail == 0 )
5968 ingressNonpostHdrAvail = infiniteCredits;
5969 if ( ingressNonpostDataAvail == 0 )
5970 ingressNonpostDataAvail = infiniteCredits;
5971 if ( ingressCompletionHdrAvail == 0 )
5972 ingressCompletionHdrAvail = infiniteCredits;
5973 if ( ingressCompletionDataAvail == 0 )
5974 ingressCompletionDataAvail = infiniteCredits;
5975
5976 // We haven't reserved or consumed any
5977 // credits yet.
5978 ingressPostHdrRsvd = 0;
5979 ingressPostDataRsvd = 0;
5980 ingressNonpostHdrRsvd = 0;
5981 ingressNonpostDataRsvd = 0;
5982 ingressCompletionHdrRsvd = 0;
5983 ingressCompletionDataRsvd = 0;
5984
5985 ingressPostHdrConsumed = 0;
5986 ingressPostDataConsumed = 0;
5987 ingressNonpostHdrConsumed = 0;
5988 ingressNonpostDataConsumed = 0;
5989 ingressCompletionHdrConsumed = 0;
5990 ingressCompletionDataConsumed = 0;
5991
5992 // Set the rxLast* to the current cycle time.
5993 rxLastPostHdr = get_cycle();
5994 rxLastPostData = get_cycle();
5995 rxLastNonpostHdr = get_cycle();
5996 rxLastNonpostData = get_cycle();
5997 rxLastCompletionHdr = get_cycle();
5998 rxLastCompletionData = get_cycle();
5999
6000 rxTimeOut = 25;
6001
6002 oldPostDataConsumed = 0;
6003
6004 PCIEDllpTrans = new( Pod.FNXPCIEBldr );
6005 //Set up the CTTransactionID
6006 PCIEDllpTrans.SetID( f_ID.NextTransID() );
6007
6008 // Respond to every credit update from
6009 // the device by reflecting the new
6010 // credit totals locally.
6011 while( 1 )
6012 {
6013 //Start with a clean packet each time
6014 PCIEDllpTrans.MyPacket.PktReset();
6015 //The SampleDllp will return a copy of each DLLP packets that the FNXPCIEXtr recieves so
6016 // determine if this is a Flow Control Update and then update the environment variables
6017 fork
6018 PCIEDllpTrans.SampleDllp( PCIEDllpTrans.MyPacket , 50000 );
6019 sync( ANY, ev_softReset );
6020 join any
6021
6022 if ( softResetPending ) return;
6023
6024 //Check to make sure DLLP is a Flow Control update before proceeding since ACKs, NAKs,
6025 // and power management dllps can be returned from SampleDllp
6026 if( PCIEDllpTrans.MyPacket.isDllpFCUpdate() ){
6027
6028 case( PCIEDllpTrans.MyPacket.DllpType[FNX_PCIE_XTR_DLLP_FC_TYPE_TYPE_INT_SLC] ){
6029 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_P: fcType = e_FC_posted;
6030 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_NP: fcType = e_FC_nonposted;
6031 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_CPL: fcType = e_FC_completion;
6032 default: PCIEDllpTrans.MyPacket.PktDisplay( RTYP_TEST_ERROR, "Env.updateIngressCredits PCIEDllpTrans.MyPacket.isDllpFCUpdate() is not a flow control update packet" );
6033
6034 }
6035 fcHdr = PCIEDllpTrans.MyPacket.DllpFCHdrFC;
6036 fcData = PCIEDllpTrans.MyPacket.DllpFCDataFC;
6037
6038 changed =
6039 ( ingressPostHdrAvail != infiniteCredits
6040 && fcType == e_FC_posted
6041 && ingressPostHdrAvail%256 != fcHdr )
6042 || ( ingressPostDataAvail != infiniteCredits
6043 && fcType == e_FC_posted
6044 && ingressPostDataAvail%4096 != fcData )
6045 || ( ingressNonpostHdrAvail != infiniteCredits
6046 && fcType == e_FC_nonposted
6047 && ingressNonpostHdrAvail%256 != fcHdr )
6048 || ( ingressNonpostDataAvail != infiniteCredits
6049 && fcType == e_FC_nonposted
6050 && ingressNonpostDataAvail%4096 != fcData )
6051 || ( ingressCompletionHdrAvail != infiniteCredits
6052 && fcType == e_FC_completion
6053 && ingressCompletionHdrAvail%256 != fcHdr )
6054 || ( ingressCompletionDataAvail != infiniteCredits
6055 && fcType == e_FC_completion
6056 && ingressCompletionDataAvail%4096 != fcData );
6057
6058
6059 if ( changed ) activityCounter = activityCounter + 1;
6060
6061
6062 // Now check the high priority status
6063 // N2 - Cascade deosn't use high priority so ignore it coming out of PTL
6064
6065 if ( fcType == e_FC_posted ) {
6066 // We need to delay checking the posted data since there's
6067 // latency between the times that "consumeIngressCredits" is called
6068 // (i.e. when the header enters the TLU) and when the data credits are
6069 // recognized by the TLU (i.e. a cycle or two after the end of the TLP).
6070 oldPostDataConsumed = ingressPostDataConsumed;
6071 }
6072
6073
6074 // Now update the necessary timers
6075 if ((ingressPostHdrAvail != infiniteCredits) &&
6076 (fcType == e_FC_posted) &&
6077 (ingressPostHdrAvail%256 != fcHdr))
6078 rxLastPostHdr= get_cycle();
6079
6080 if ((ingressPostDataAvail != infiniteCredits) &&
6081 (fcType == e_FC_posted) &&
6082 (ingressPostDataAvail%4096 != fcData))
6083 rxLastPostData = get_cycle();
6084
6085 if ((ingressNonpostHdrAvail != infiniteCredits) &&
6086 (fcType == e_FC_nonposted) &&
6087 (ingressNonpostHdrAvail%256 != fcHdr))
6088 rxLastNonpostHdr = get_cycle();
6089
6090 if ((ingressNonpostDataAvail != infiniteCredits) &&
6091 (fcType == e_FC_nonposted) &&
6092 (ingressNonpostDataAvail%4096 != fcData))
6093 rxLastNonpostData = get_cycle();
6094
6095 if ((ingressCompletionHdrAvail != infiniteCredits) &&
6096 (fcType == e_FC_completion) &&
6097 (ingressCompletionHdrAvail%256 != fcHdr))
6098 rxLastCompletionHdr = get_cycle();
6099
6100 if ((ingressCompletionDataAvail != infiniteCredits) &&
6101 (fcType == e_FC_completion) &&
6102 (ingressCompletionDataAvail%4096 != fcData))
6103 rxLastCompletionData = get_cycle();
6104
6105
6106
6107
6108 // Update credit totals.
6109 //N2 - Cascade doesn't have a High Priority Flow Control update
6110 //N2 so get rid of fcHP & onlyHiIngressUpdates
6111 if ( fcType == e_FC_posted )
6112 {
6113 Report.report(RTYP_DEBUG_3,"updateIngressCredits1 ingressPostHdrAvail=%0d ingressPostDataAvail=%0d fcHdr=%0d fcData=%0d \n",ingressPostHdrAvail,ingressPostDataAvail,fcHdr,fcData );
6114 if ( ingressPostHdrAvail != infiniteCredits )
6115 ingressPostHdrAvail = ((fcHdr - (ingressPostHdrAvail%256)) >= 0) ?
6116 ingressPostHdrAvail + ( fcHdr - (ingressPostHdrAvail%256)) :
6117 ingressPostHdrAvail + ( (256+fcHdr) - (ingressPostHdrAvail%256));
6118 if ( ingressPostDataAvail != infiniteCredits )
6119 ingressPostDataAvail =((fcData - (ingressPostDataAvail%4096)) >= 0) ?
6120 ingressPostDataAvail + ( fcData - (ingressPostDataAvail%4096)) :
6121 ingressPostDataAvail + ( (4096+fcData) - (ingressPostDataAvail%4096));
6122 Report.report(RTYP_DEBUG_3,"updateIngressCredits2 ingressPostHdrAvail=%0d ingressPostDataAvail=%0d fcHdr=%0d fcData=%0d \n",ingressPostHdrAvail,ingressPostDataAvail,fcHdr,fcData);
6123 }
6124 if ( fcType == e_FC_nonposted )
6125 {
6126 if ( ingressNonpostHdrAvail != infiniteCredits )
6127 ingressNonpostHdrAvail = ((fcHdr - (ingressNonpostHdrAvail%256)) >= 0) ?
6128 ingressNonpostHdrAvail + ( fcHdr - (ingressNonpostHdrAvail%256)) :
6129 ingressNonpostHdrAvail + ( (256+fcHdr) - (ingressNonpostHdrAvail%256));
6130 if ( ingressNonpostDataAvail != infiniteCredits )
6131 ingressNonpostDataAvail = ((fcData - (ingressNonpostDataAvail%4096)) >= 0) ?
6132 ingressNonpostDataAvail + ( fcData - (ingressNonpostDataAvail%4096)) :
6133 ingressNonpostDataAvail + ( (4096+fcData) - (ingressNonpostDataAvail%4096));
6134 }
6135 if ( fcType == e_FC_completion )
6136 {
6137 if ( ingressCompletionHdrAvail != infiniteCredits )
6138 ingressCompletionHdrAvail = ((fcHdr - (ingressCompletionHdrAvail%256)) >= 0) ?
6139 ingressCompletionHdrAvail + ( fcHdr - (ingressCompletionHdrAvail%256)) :
6140 ingressCompletionHdrAvail + ( (256+fcHdr) - (ingressCompletionHdrAvail%256));
6141 if ( ingressCompletionDataAvail != infiniteCredits )
6142 ingressCompletionDataAvail = ((fcData - (ingressCompletionDataAvail%4096)) >= 0) ?
6143 ingressCompletionDataAvail + ( fcData - (ingressCompletionDataAvail%4096)) :
6144 ingressCompletionDataAvail + ( (4096+fcData) - (ingressCompletionDataAvail%4096));
6145 }
6146
6147
6148
6149 // If someone is waiting for credits,
6150 // then tell them to try again.
6151 trigger( ONE_SHOT, ev_creditUpdateReceived );
6152 trigger( ONE_SHOT, ev_CSRupdateReq );
6153 } //End if( PCIEDllpTrans.MyPacket.isDllpFC() )
6154
6155 //Delay a cycle to allow time to progress
6156 @( posedge if_ILU_PEU_PCIE_RX.refclk );
6157
6158 } //End while( 1 )
6159} /* end "updateIngressCredits" */
6160
6161
6162
6163/*
6164 * updateEgressCredits - Monitors Ingress DLLPs from PCIEXtr to update Egress
6165 * Flow Control values based on update flow control packets
6166 * and retry credits based on ACK/NAKs
6167 */
6168task PEUTestEnv::updateEgressCredits() {
6169
6170 FNXPCIEXactorTransaction PCIEIngressDllpTrans;
6171 PEC_FCtype fcType;
6172 integer egressSeqNum; // Sequence # put in mailbox for egress TLPs
6173 integer retryPending; // Credits not yet returned to the TLU
6174 integer hdrCredits;
6175 integer dataCredits;
6176 integer i;
6177 integer seqDif; // Used to temporarily hold difference between 2 sequence numbers
6178 integer egressTransmitSeqNum; // The current highest transmitted sequence number
6179 integer AckNakSeqNum; // Sequence number of the Ingress DLLPs ACK/NAK
6180 // A reset chip starts at 4095 since the first
6181 // real ack sequence will be 0
6182 bit discardDllp;
6183 integer fcHdr;
6184 integer fcData;
6185 integer creditDifHdr;
6186 integer creditDifData;
6187
6188
6189// FNXPCIEXactorTransaction PCIETrans;
6190// PCIETrans = new( Pod.FNXPCIEBldr );
6191 PCIEIngressDllpTrans = new( Pod.FNXPCIEBldr );
6192
6193 //Wait for the Denali link to come up
6194 PCIEIngressDllpTrans.WaitLinkUp();
6195
6196 // We start with the initial credit allocation
6197 egressPostHdrAvail = egressPostHdrInit;
6198 egressPostDataAvail = egressPostDataInit;
6199 egressNonpostHdrAvail = egressNonpostHdrInit;
6200 egressNonpostDataAvail = egressNonpostDataInit;
6201 egressCompletionHdrAvail = egressCompletionHdrInit;
6202 egressCompletionDataAvail = egressCompletionDataInit;
6203
6204 if ( egressPostHdrAvail == 0 )
6205 egressPostHdrAvail = infiniteCredits;
6206 if ( egressPostDataAvail == 0 )
6207 egressPostDataAvail = infiniteCredits;
6208 if ( egressNonpostHdrAvail == 0 )
6209 egressNonpostHdrAvail = infiniteCredits;
6210 if ( egressNonpostDataAvail == 0 )
6211 egressNonpostDataAvail = infiniteCredits;
6212 if ( egressCompletionHdrAvail == 0 )
6213 egressCompletionHdrAvail = infiniteCredits;
6214 if ( egressCompletionDataAvail == 0 )
6215 egressCompletionDataAvail = infiniteCredits;
6216
6217 mailbox_put(mb_egressPostHdrAvail, egressPostHdrAvail);
6218 mailbox_put(mb_egressPostDataAvail, egressPostDataAvail);
6219 mailbox_put(mb_egressNonpostHdrAvail, egressNonpostHdrAvail);
6220 mailbox_put(mb_egressNonpostDataAvail, egressNonpostDataAvail);
6221 mailbox_put(mb_egressCompletionHdrAvail, egressCompletionHdrAvail);
6222 mailbox_put(mb_egressCompletionDataAvail, egressCompletionDataAvail);
6223
6224 // The TLU hasn't eaten any credits yet.
6225 egressPostHdrConsumed = 0;
6226 egressPostDataConsumed = 0;
6227 egressNonpostHdrConsumed = 0;
6228 egressNonpostDataConsumed = 0;
6229 egressCompletionHdrConsumed = 0;
6230 egressCompletionDataConsumed = 0;
6231
6232 egressPostHdrToReturn = 0;
6233 egressPostDataToReturn = 0;
6234 egressNonpostHdrToReturn = 0;
6235 egressNonpostDataToReturn = 0;
6236 egressCompletionHdrToReturn = 0;
6237 egressCompletionDataToReturn = 0;
6238
6239// returnAllEgressCredits = 0;
6240
6241 egressUpdateError = 0; // We need to know if a FC error occurred
6242
6243 // Let's begin by setting the total
6244 // number of "retry" credits available
6245 // to the TLU.
6246 retryPending = 0;
6247 egressRetryAvail = egressRetryInit;
6248 egressRetryConsumed = 0;
6249//N2-Not needed since testing ilu-peu f_LPUXtr.advertiseRetryCredit( egressRetryAvail );
6250
6251 // Now, wait for "link up" to be
6252 // asserted...
6253//N2-review Might miss Set Slot Power sync( ANY, ev_linkUp );
6254
6255 // Update credit values as they are returned...
6256 // Enable the Sampling of Ingress DLLPs
6257// PCIEIngressDllpTrans = new( Pod.FNXPCIEBldr );
6258 PCIEIngressDllpTrans.EnableSampleIngressDllp();
6259//N2 DMT Bypass Link Train PCIEIngressDllpTrans.EnableSampleIngressDllp();
6260
6261 while( 1 ) {
6262
6263 //Start with a clean packet each time
6264 PCIEIngressDllpTrans.MyPacket.PktReset();
6265 //The SampleIngressDllp will return a copy of each DLLP packet that the FNXPCIEXtr transmits
6266 // so determine if this is a Flow Control Update or an ACK/NAK and then update
6267 // the correct environment variables
6268
6269 fork
6270 PCIEIngressDllpTrans.SampleIngressDllp( PCIEIngressDllpTrans.MyPacket , 50000 );
6271 sync( ANY, ev_softReset );
6272 join any
6273
6274 if( softResetPending || (sync( CHECK, ev_drainStateEnd )) ){
6275 PCIEIngressDllpTrans.DisableSampleIngressDllp();
6276 terminate; //kill the SampleIngressDllp process
6277 break;
6278 }
6279
6280 //Delay here since Denali is returning ACK/NAK the same cycle as matching TLPs
6281 @( posedge if_ILU_PEU_PCIE_RX.refclk );
6282
6283 //Check to make sure DLLP is a Flow Control update before proceeding since ACKs, NAKs,
6284 // and power management dllps can be returned from SampleDllp
6285 if( PCIEIngressDllpTrans.MyPacket.isDllpFCUpdate() ){
6286
6287 case( PCIEIngressDllpTrans.MyPacket.DllpType[FNX_PCIE_XTR_DLLP_FC_TYPE_TYPE_INT_SLC] ){
6288 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_P: fcType = e_FC_posted;
6289 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_NP: fcType = e_FC_nonposted;
6290 FNX_PCIE_XTR_FC_DLLP_TYPE_UPDATE_FC_CPL: fcType = e_FC_completion;
6291 default: PCIEIngressDllpTrans.MyPacket.PktDisplay( RTYP_TEST_ERROR, "Env.updateEgressCredits PCIEIngressDllpTrans.MyPacket.isDllpFCUpdate() is not a flow control update packet" );
6292
6293 }
6294 fcHdr = PCIEIngressDllpTrans.MyPacket.DllpFCHdrFC;
6295 fcData = PCIEIngressDllpTrans.MyPacket.DllpFCDataFC;
6296
6297 //
6298 case( fcType ){
6299
6300 e_FC_posted: { //Flag an error for bad update from testbench unless expected
6301 if (FCP_inject == 0 && FCP_P_inject == 0 ) {
6302 if( egressPostHdrAvail == infiniteCredits && fcHdr != 0 ){ //N2 review Error Case Allowed to test dut
6303 QuickReport( Report, RTYP_TEST_ERROR,
6304 "Env::updateEgressCredits() egressPostHdrAvail == infiniteCredits but received update Flow Control Hdr Credit=$0d",
6305 fcHdr);
6306 }
6307 //Flag an error for bad update from testbench unless expected
6308 if( egressPostDataAvail == infiniteCredits && fcData != 0 ){ //N2 review Error Case Allowed to test dut
6309 QuickReport( Report, RTYP_TEST_ERROR,
6310 "Env::updateEgressCredits() egressPostDataAvail == infiniteCredits but received update Flow Control data Credit=$0d",
6311 fcData);
6312 }
6313
6314 //Determine difference between the last updates
6315 if( (fcHdr - (egressPostHdrAvail%256)) >= 0 ){
6316 creditDifHdr = fcHdr - (egressPostHdrAvail%256);
6317 }else{
6318 creditDifHdr = (fcHdr+256) - (egressPostHdrAvail%256);
6319 }
6320 if( (fcData - (egressPostDataAvail%4096)) >= 0 ){
6321 creditDifData = fcData - (egressPostDataAvail%4096);
6322 }else{
6323 creditDifData = (fcData+4096) - (egressPostDataAvail%4096);
6324 }
6325
6326 //Flag an error if Update is greater than # of outstanding credits
6327 if( creditDifHdr > egressPostHdrToReturn ){ //N2 review Error Case
6328 QuickReport( Report, RTYP_TEST_ERROR,
6329 "Env::updateEgressCredits() More Posted Header Credits returned than were outstanding fcHdr=%0d egressPostHdrToReturn=%0d creditDifHdr=%0d egressPostHdrAvail=%0d",
6330 fcHdr,egressPostHdrToReturn,creditDifHdr,egressPostHdrAvail );
6331 }
6332 //Flag an error if Update is greater than # of outstanding credits
6333 if( creditDifData > egressPostDataToReturn ){ //N2 review Error Case
6334 QuickReport( Report, RTYP_TEST_ERROR,
6335 "Env::updateEgressCredits() More Posted Data Credits returned than were outstanding fcData=%0d egressPostDataToReturn=%0d creditDifData=%0d egressPostDataAvail=%0d",
6336 fcHdr,egressPostDataToReturn,creditDifData,egressPostDataAvail );
6337 }
6338 //N2 - May not need these
6339 if( egressPostHdrAvail == infiniteCredits && fcHdr == 0 ){
6340 egressPostHdrToReturn = 0;
6341 egressPostDataToReturn = 0;
6342 }
6343
6344 //Keep the running total of Egress avail credits
6345 egressPostHdrAvail = egressPostHdrAvail + creditDifHdr;
6346 egressPostDataAvail = egressPostDataAvail + creditDifData;
6347
6348 //Keep track of outstanding credits that need to be returned
6349 egressPostHdrToReturn = egressPostHdrToReturn - creditDifHdr;
6350 egressPostDataToReturn = egressPostDataToReturn - creditDifData;
6351
6352 } // if FCP_inject
6353 } //End e_FC_posted
6354
6355 e_FC_nonposted: { //Flag an error for bad update from testbench unless expected
6356 if (FCP_inject == 0 && FCP_NP_inject == 0 ) {
6357 if( egressNonpostHdrAvail == infiniteCredits && fcHdr != 0 ){ //N2 review Error Case Allowed to test dut
6358 QuickReport( Report, RTYP_TEST_ERROR,
6359 "Env::updateEgressCredits() egressNonpostHdrAvail == infiniteCredits but received update Flow Control Hdr Credit=$0d",
6360 fcHdr);
6361 }
6362 //Flag an error for bad update from testbench unless expected
6363 if( egressNonpostDataAvail == infiniteCredits && fcHdr != 0 ){ //N2 review Error Case Allowed to test dut
6364 QuickReport( Report, RTYP_TEST_ERROR,
6365 "Env::updateEgressCredits() egressNonpostDataAvail == infiniteCredits but received update Flow Control data Credit=$0d",
6366 fcData);
6367 }
6368
6369 //Determine difference between the last updates
6370 if( (fcHdr - (egressNonpostHdrAvail%256)) >= 0 ){
6371 creditDifHdr = fcHdr - (egressNonpostHdrAvail%256);
6372 }else{
6373 creditDifHdr = (fcHdr+256) - (egressNonpostHdrAvail%256);
6374 }
6375 if( (fcData - (egressNonpostDataAvail%4096)) >= 0 ){
6376 creditDifData = fcData - (egressNonpostDataAvail%4096);
6377 }else{
6378 creditDifData = (fcData+4096) - (egressNonpostDataAvail%4096);
6379 }
6380
6381 //Flag an error if Update is greater than # of outstanding credits
6382 if( creditDifHdr > egressNonpostHdrToReturn ){ //N2 review Error Case
6383 QuickReport( Report, RTYP_TEST_ERROR,
6384 "Env::updateEgressCredits() More Non Posted Header Credits returned than were outstanding fcHdr=%0d egressNonpostHdrToReturn=%0d creditDifHdr=%0d",
6385 fcHdr,egressNonpostHdrToReturn,creditDifHdr );
6386 }
6387 //Flag an error if Update is greater than # of outstanding credits
6388 if( creditDifData > egressNonpostDataToReturn ){ //N2 review Error Case
6389 QuickReport( Report, RTYP_TEST_ERROR,
6390 "Env::updateEgressCredits() More Non Posted Data Credits returned than were outstanding fcData=%0d egressNonPostDataToReturn=%0d creditDifData=%0d",
6391 fcHdr,egressNonpostDataToReturn,creditDifData );
6392 }
6393 //N2 - May not need these
6394 if( egressNonpostHdrAvail == infiniteCredits && fcHdr == 0 ){
6395 egressNonpostHdrToReturn = 0;
6396 egressNonpostDataToReturn = 0;
6397 }
6398
6399 //Keep the running total of Egress avail credits
6400 egressNonpostHdrAvail = egressNonpostHdrAvail + creditDifHdr;
6401 egressNonpostDataAvail = egressNonpostDataAvail + creditDifData;
6402
6403 //Keep track of outstanding credits that need to be returned
6404 egressNonpostHdrToReturn = egressNonpostHdrToReturn - creditDifHdr;
6405 egressNonpostDataToReturn = egressNonpostDataToReturn - creditDifData;
6406
6407 } // FCP_inject
6408 } //End e_FC_nonposted
6409
6410
6411 e_FC_completion: { //Flag an error for bad update from testbench unless expected
6412 if (FCP_inject == 0 && FCP_CPL_inject == 0 ) {
6413 if( egressCompletionHdrAvail == infiniteCredits && fcHdr != 0 ){ //N2 review Error Case Allowed to test dut
6414 QuickReport( Report, RTYP_TEST_ERROR,
6415 "Env::updateEgressCredits() egressCompletionHdrAvail == infiniteCredits but received update Flow Control Hdr Credit=$0d",
6416 fcHdr);
6417 }
6418 //Flag an error for bad update from testbench unless expected
6419 if( egressCompletionDataAvail == infiniteCredits && fcData != 0 ){ //N2 review Error Case Allowed to test dut
6420 QuickReport( Report, RTYP_TEST_ERROR,
6421 "Env::updateEgressCredits() egressCompletionDataAvaie == infiniteCredits but received update Flow Control data Credit=$0d",
6422 fcHdr);
6423 }
6424
6425 //Determine difference between the last updates
6426 if( (fcHdr - (egressCompletionHdrAvail%256)) >= 0 ){
6427 creditDifHdr = fcHdr - (egressCompletionHdrAvail%256);
6428 }else{
6429 creditDifHdr = (fcHdr+256) - (egressCompletionHdrAvail%256);
6430 }
6431 if( (fcData - (egressCompletionDataAvail%4096)) >= 0 ){
6432 creditDifData = fcData - (egressCompletionDataAvail%4096);
6433 }else{
6434 creditDifData = (fcData+4096) - (egressCompletionDataAvail%4096);
6435 }
6436
6437 //Flag an error if Update is greater than # of outstanding credits
6438 if( (creditDifHdr > egressCompletionHdrToReturn) &&
6439 (egressCompletionHdrAvail != infiniteCredits) ){ //N2 review Error Case
6440 QuickReport( Report, RTYP_TEST_ERROR,
6441 "Env::updateEgressCredits() More Completion Header Credits returned than were outstanding fcHdr=%0d egressCompletionHdrToReturn=%0d creditDifHdr=%0d",
6442 fcHdr,egressCompletionHdrToReturn,creditDifHdr );
6443 }
6444 //Flag an error if Update is greater than # of outstanding credits
6445 if( (creditDifData > egressCompletionDataToReturn) &&
6446 (egressCompletionDataAvail != infiniteCredits) ){ //N2 review Error Case
6447 QuickReport( Report, RTYP_TEST_ERROR,
6448 "Env::updateEgressCredits() More Completion Data Credits returned than were outstanding fcData=%0d egressNonPostDataToReturn=%0d creditDifData=%0d",
6449 fcHdr,egressNonpostDataToReturn,creditDifData );
6450 }
6451
6452 //Keep the running total of Egress Header
6453 if( (egressCompletionHdrAvail == infiniteCredits) && (fcHdr == 0) ){
6454 egressCompletionHdrToReturn = 0;
6455 egressCompletionHdrAvail = infiniteCredits;
6456 }else{
6457 egressCompletionHdrToReturn = egressCompletionHdrToReturn - creditDifHdr;
6458 egressCompletionHdrAvail = egressCompletionHdrAvail + creditDifHdr;
6459 }
6460
6461 //Keep the running total of Egress Data
6462 if( (egressCompletionDataAvail == infiniteCredits) && (fcData == 0) ){
6463 egressCompletionDataToReturn = 0;
6464 egressCompletionDataAvail = infiniteCredits;
6465 }else{
6466 egressCompletionDataToReturn = egressCompletionDataToReturn - creditDifData;
6467 egressCompletionDataAvail = egressCompletionDataAvail + creditDifData;
6468 }
6469
6470
6471 } // FCP_inject
6472 } //End e_FC_completion
6473
6474 } //End case( fcType )
6475 } //End if FCUpdate
6476
6477 //RETRY CREDITS
6478 //If an ACK/NAK has been received and there are credits to restore in the
6479 // egrressRetry mailbox then the retry credits can be restored
6480 if( PCIEIngressDllpTrans.MyPacket.isDllpAckNak() ){
6481
6482 discardDllp = 0;
6483 AckNakSeqNum = PCIEIngressDllpTrans.MyPacket.AckNakSeqNum;
6484 //Make sure difference between NextTransmitSeqNum and AckNakSeqNum <= 2048
6485 // since the dllp should be dropped and no credits returned
6486 //review - This should also cause a DL layer error
6487 egressTransmitSeqNum = ( (egressNextTransmitSeqNum%4096) == 0 ? 4095 : egressNextTransmitSeqNum - 1 );
6488 if( (egressTransmitSeqNum%4096 - AckNakSeqNum) >= 0 ){
6489 seqDif = (egressTransmitSeqNum%4096) - AckNakSeqNum;
6490 }else{
6491 seqDif = (egressTransmitSeqNum%4096)+4096 - AckNakSeqNum;
6492 }
6493 if( seqDif >= 2048 ){
6494 discardDllp = 1;
6495 //review - Error
6496 }
6497 //Keep track of the number of Tlps in the replay buffer
6498 nmbrTlpsReplayBuffer = seqDif;
6499//1 review AckNakSeqNum=%0d egressTransmitSeqNum=%0d seqDif=%0d AckdSeqNum=%0d discardDllp=%0d\n",AckNakSeqNum,egressTransmitSeqNum,seqDif,AckdSeqNum,discardDllp );
6500
6501 if( (AckNakSeqNum - AckdSeqNum) >= 0 ){
6502 seqDif = AckNakSeqNum - AckdSeqNum;
6503 }else{
6504 seqDif = (AckNakSeqNum+4096) - AckdSeqNum;
6505 }
6506 if( seqDif >= 2048 ){
6507 discardDllp = 1;
6508 //review - Error
6509 }
6510//2 review AckNakSeqNum=%0d egressTransmitSeqNum=%0d seqDif=%0d AckdSeqNum=%0d discardDllp=%0d\n",AckNakSeqNum,egressTransmitSeqNum,seqDif,AckdSeqNum,discardDllp );
6511
6512 if( AckNakSeqNum == AckdSeqNum ){
6513 //Not an error - Its legal to send an already sent seq # in a ack/nak
6514 discardDllp = 1;
6515 }
6516//3 review AckNakSeqNum=%0d egressTransmitSeqNum=%0d seqDif=%0d AckdSeqNum=%0d discardDllp=%0d\n",AckNakSeqNum,egressTransmitSeqNum,seqDif,AckdSeqNum,discardDllp );
6517
6518 //review - add check for AckNakSeqNum being less then AckdSeqNum - old AckNakSeqNum
6519
6520 //If we made it this far there should be something in mb_egressSeqNum
6521 if( !(mailbox_get( NO_WAIT, mb_egressSeqNum )) && !discardDllp ){
6522 QuickReport( Report, RTYP_TEST_ERROR,
6523 "Env::updateEgressCredits() nothing in mb_egressSeqNum #Entries=%0d when expected AckNakSeqNum=%0d AckdSeqNum=%0d egressTransmitSeqNum=%0d %4096=%0d ",(mailbox_get( NO_WAIT, mb_egressSeqNum )),AckNakSeqNum,AckdSeqNum,egressTransmitSeqNum,egressTransmitSeqNum%4096 );
6524 }
6525
6526 //Check to see if the ACK/NAK sequence number is >= the oldest transmitted tlp
6527 // sequence number
6528 mailbox_get( COPY_NO_WAIT, mb_egressSeqNum, egressSeqNum );
6529 //Get the difference between the lastAckd seq and the current Acks seq
6530 if( (AckNakSeqNum - egressSeqNum%4096) >= 0 ){
6531 seqDif = AckNakSeqNum - (egressSeqNum%4096);
6532 }else{
6533 seqDif = (AckNakSeqNum+4096) - (egressSeqNum%4096);
6534 }
6535//4 review AckNakSeqNum=%0d egressTransmitSeqNum=%0d seqDif=%0d AckdSeqNum=%0d discardDllp=%0d\n",AckNakSeqNum,egressTransmitSeqNum,seqDif,AckdSeqNum,discardDllp );
6536
6537 for( i = 0; (i <= seqDif) && !discardDllp; i++ ){
6538 //Pop the oldest unacknowledged tlp sequence number
6539 mailbox_get( NO_WAIT, mb_egressSeqNum, egressSeqNum );
6540
6541 //Its an error if there aren't any credits to go with the sequence number
6542 if( !mailbox_get( NO_WAIT, mb_egressRetry )){
6543 QuickReport( Report, RTYP_TEST_ERROR,
6544 "Env::updateEgressCredits() mb_egressSeqNum had entry but mb_egressRetry didn't");
6545 }
6546 //... pull the credits returned for the TLP that goes with the egressSeqNum
6547 mailbox_get( NO_WAIT, mb_egressRetry, dataCredits );
6548
6549 //Keep the running total of available retry credits
6550 // the dut wil be several cycles behind in updating its credits
6551 egressRetryAvail = egressRetryAvail + dataCredits;
6552
6553 //Make AckdSeqNum modulo to track with the incoming AckNakSeqNum
6554 AckdSeqNum = egressSeqNum%4096;
6555 }
6556
6557 //At this point its an error if the AckNakSeqNum != the last popped egressSeqNum
6558 if( (AckNakSeqNum != egressSeqNum%4096) && !discardDllp ){
6559 QuickReport( Report, RTYP_TEST_ERROR,
6560 "Env::updateEgressCredits() AckNakSeqNum=%0d is not equal to egressSeqNum=%0d %4096=%0d after processing ACK/NAK ",AckNakSeqNum,egressSeqNum,egressSeqNum%4096 );
6561 }
6562 } //End //If an ACK or NAK has been received and there are credits
6563
6564
6565/*N2 review Comment out until fixed
6566 randcase {
6567
6568 egressIdleWeight : {
6569 // Do nothing this cycle
6570 // Nothing to see here ...
6571 }
6572
6573 egressInitPostWeight : {
6574
6575 f_LPUXtr.sendCreditInit(e_FC_posted, 0,
6576 egressPostHdrInit,
6577 egressPostDataInit);
6578 }
6579
6580 egressInitNonpostWeight : {
6581
6582 f_LPUXtr.sendCreditInit(e_FC_nonposted, 0,
6583 egressNonpostHdrInit,
6584 egressNonpostDataInit);
6585 }
6586
6587 egressInitCompletionWeight : {
6588
6589 f_LPUXtr.sendCreditInit(e_FC_completion, 0,
6590 egressCompletionHdrInit,
6591 egressCompletionDataInit);
6592 }
6593
6594
6595 egressUpdtPostWeight : {
6596
6597//N2 review If Infinite credits send infinite update
6598 if ( egressPostHdrAvail == infiniteCredits
6599 && egressPostDataAvail == infiniteCredits ) {
6600 egressPostHdrToReturn = 0;
6601 egressPostDataToReturn = 0;
6602 f_LPUXtr.sendCreditUpdate( e_FC_posted, 0, 0, 0 );
6603 }else {
6604 if (( egressPostHdrAvail != infiniteCredits ) &&
6605 ( egressPostHdrAllowed == 1)) {
6606 if (!sync(CHECK, egressPostHdrStopFlag)) {
6607 integer distance =
6608 ((egressPostHdrStopValue % 256) - (egressPostHdrAvail % 256) + 256) % 256;
6609 if (distance == 0) {
6610 egressPostHdrAvail = egressPostHdrAvail;
6611 trigger(ON, egressPostHdrStopFlag);
6612 }else if (distance >= 4) {
6613 egressPostHdrAvail +=
6614 (egressPostHdrToReturn < 4) ? egressPostHdrToReturn : 4;
6615
6616 egressPostHdrToReturn =
6617 (egressPostHdrToReturn < 4) ? 0 : egressPostHdrToReturn - 4;
6618 }else {
6619 egressPostHdrAvail +=
6620 (egressPostHdrToReturn < distance) ? egressPostHdrToReturn : distance;
6621
6622 egressPostHdrToReturn =
6623 (egressPostHdrToReturn < distance) ? 0 : egressPostHdrToReturn - distance;
6624 }
6625 }else {
6626 egressPostHdrAvail +=
6627 (egressPostHdrToReturn < 4) ? egressPostHdrToReturn : 4;
6628 egressPostHdrToReturn =
6629 (egressPostHdrToReturn < 4) ? 0 : egressPostHdrToReturn - 4;
6630 }
6631 }
6632
6633 if (( egressPostDataAvail != infiniteCredits ) &&
6634 ( egressPostDataAllowed == 1)) {
6635 if (!sync(CHECK, egressPostDataStopFlag)) {
6636 integer distance =
6637 ((egressPostDataStopValue % 4096) - (egressPostDataAvail % 4096) + 4096) % 4096;
6638 if (distance == 0) {
6639 egressPostDataAvail = egressPostDataAvail;
6640 trigger(ON, egressPostDataStopFlag);
6641 }else if (distance >= 16) {
6642
6643 egressPostDataAvail +=
6644 (egressPostDataToReturn < 16) ? egressPostDataToReturn : 16;
6645
6646 egressPostDataToReturn =
6647 (egressPostDataToReturn < 16) ? 0 : egressPostDataToReturn - 16;
6648 }else {
6649
6650 egressPostDataAvail +=
6651 (egressPostDataToReturn < distance) ? egressPostDataToReturn : distance;
6652
6653 egressPostDataToReturn =
6654 (egressPostDataToReturn < distance) ? 0 : egressPostDataToReturn - distance;
6655 }
6656 }else {
6657
6658 egressPostDataAvail +=
6659 (egressPostDataToReturn < 16) ? egressPostDataToReturn : 16;
6660 egressPostDataToReturn =
6661 (egressPostDataToReturn < 16) ? 0 : egressPostDataToReturn - 16;
6662 }
6663 }
6664
6665 f_LPUXtr.sendCreditUpdate( e_FC_posted, 0,
6666 egressPostHdrAvail==infiniteCredits ? 0
6667 : egressPostHdrAvail,
6668 egressPostDataAvail==infiniteCredits ? 0
6669 : egressPostDataAvail );
6670 }//End else ! hdr & data infinite credits
6671 }
6672
6673
6674
6675 egressUpdtNonpostWeight : {
6676
6677 if ( egressNonpostHdrAvail == infiniteCredits
6678 && egressNonpostDataAvail == infiniteCredits ) {
6679
6680 egressNonpostHdrToReturn = 0;
6681 egressNonpostDataToReturn = 0;
6682 f_LPUXtr.sendCreditUpdate( e_FC_nonposted, 0, 0, 0 );
6683 }
6684
6685 else {
6686
6687 if (( egressNonpostHdrAvail != infiniteCredits ) &&
6688 ( egressNonpostHdrAllowed == 1)) {
6689
6690 if (!sync(CHECK, egressNonpostHdrStopFlag)) {
6691
6692 integer distance =
6693 ((egressNonpostHdrStopValue % 256) - (egressNonpostHdrAvail % 256) + 256) % 256;
6694
6695 if (distance == 0) {
6696
6697 egressNonpostHdrAvail = egressNonpostHdrAvail;
6698 trigger(ON, egressNonpostHdrStopFlag);
6699 }
6700
6701 else if (distance >= 4) {
6702
6703 egressNonpostHdrAvail +=
6704 (egressNonpostHdrToReturn < 4) ? egressNonpostHdrToReturn : 4;
6705
6706 egressNonpostHdrToReturn =
6707 (egressNonpostHdrToReturn < 4) ? 0 : egressNonpostHdrToReturn - 4;
6708 }
6709
6710 else {
6711
6712 egressNonpostHdrAvail +=
6713 (egressNonpostHdrToReturn < distance) ? egressNonpostHdrToReturn : distance;
6714
6715 egressNonpostHdrToReturn =
6716 (egressNonpostHdrToReturn < distance) ? 0 : egressNonpostHdrToReturn - distance;
6717 }
6718 }
6719
6720 else {
6721
6722 egressNonpostHdrAvail +=
6723 (egressNonpostHdrToReturn < 4) ? egressNonpostHdrToReturn : 4;
6724 egressNonpostHdrToReturn =
6725 (egressNonpostHdrToReturn < 4) ? 0 : egressNonpostHdrToReturn - 4;
6726 }
6727 }
6728
6729
6730 if (( egressNonpostDataAvail != infiniteCredits ) &&
6731 ( egressNonpostDataAllowed == 1)) {
6732
6733 if (!sync(CHECK, egressNonpostDataStopFlag)) {
6734
6735 integer distance =
6736 ((egressNonpostDataStopValue % 4096) - (egressNonpostDataAvail % 4096) + 4096) % 4096;
6737
6738
6739 if (distance == 0) {
6740
6741 egressNonpostDataAvail = egressNonpostDataAvail;
6742 trigger(ON, egressNonpostDataStopFlag);
6743 }
6744
6745 else if (distance >= 16) {
6746
6747 egressNonpostDataAvail +=
6748 (egressNonpostDataToReturn < 16) ? egressNonpostDataToReturn : 16;
6749
6750 egressNonpostDataToReturn =
6751 (egressNonpostDataToReturn < 16) ? 0 : egressNonpostDataToReturn - 16;
6752 }
6753
6754 else {
6755
6756 egressNonpostDataAvail +=
6757 (egressNonpostDataToReturn < distance) ? egressNonpostDataToReturn : distance;
6758
6759 egressNonpostDataToReturn =
6760 (egressNonpostDataToReturn < distance) ? 0 : egressNonpostDataToReturn - distance;
6761 }
6762 }
6763
6764 else {
6765
6766 egressNonpostDataAvail +=
6767 (egressNonpostDataToReturn < 16) ? egressNonpostDataToReturn : 16;
6768 egressNonpostDataToReturn =
6769 (egressNonpostDataToReturn < 16) ? 0 : egressNonpostDataToReturn - 16;
6770 }
6771 }
6772
6773
6774 f_LPUXtr.sendCreditUpdate( e_FC_nonposted, 0,
6775 egressNonpostHdrAvail==infiniteCredits ? 0
6776 : egressNonpostHdrAvail,
6777 egressNonpostDataAvail==infiniteCredits ? 0
6778 : egressNonpostDataAvail );
6779 }
6780 }
6781
6782 egressUpdtCompletionWeight : {
6783
6784 if ( egressCompletionHdrAvail == infiniteCredits
6785 && egressCompletionDataAvail == infiniteCredits ) {
6786
6787 egressCompletionHdrToReturn = 0;
6788 egressCompletionDataToReturn = 0;
6789 f_LPUXtr.sendCreditUpdate( e_FC_completion, 0, 0, 0 );
6790 }
6791
6792 else {
6793
6794 if (( egressCompletionHdrAvail != infiniteCredits ) &&
6795 ( egressCompletionHdrAllowed == 1)) {
6796
6797 if (!sync(CHECK, egressCompletionHdrStopFlag)) {
6798
6799 integer distance =
6800 ((egressCompletionHdrStopValue % 256) - (egressCompletionHdrAvail % 256) + 256) % 256;
6801
6802 if (distance == 0) {
6803
6804 egressCompletionHdrAvail = egressCompletionHdrAvail;
6805 trigger(ON, egressCompletionHdrStopFlag);
6806 }
6807
6808 else if (distance >= 4) {
6809
6810 egressCompletionHdrAvail +=
6811 (egressCompletionHdrToReturn < 4) ? egressCompletionHdrToReturn : 4;
6812
6813 egressCompletionHdrToReturn =
6814 (egressCompletionHdrToReturn < 4) ? 0 : egressCompletionHdrToReturn - 4;
6815 }
6816
6817 else {
6818
6819 egressCompletionHdrAvail +=
6820 (egressCompletionHdrToReturn < distance) ? egressCompletionHdrToReturn : distance;
6821
6822 egressCompletionHdrToReturn =
6823 (egressCompletionHdrToReturn < distance) ? 0 : egressCompletionHdrToReturn - distance;
6824 }
6825 }
6826
6827 else {
6828
6829 egressCompletionHdrAvail +=
6830 (egressCompletionHdrToReturn < 4) ? egressCompletionHdrToReturn : 4;
6831 egressCompletionHdrToReturn =
6832 (egressCompletionHdrToReturn < 4) ? 0 : egressCompletionHdrToReturn - 4;
6833 }
6834 }
6835
6836
6837 if (( egressCompletionDataAvail != infiniteCredits ) &&
6838 ( egressCompletionDataAllowed == 1)) {
6839
6840 if (!sync(CHECK, egressCompletionDataStopFlag)) {
6841
6842 integer distance =
6843 ((egressCompletionDataStopValue % 4096) - (egressCompletionDataAvail % 4096) + 4096) % 4096;
6844
6845
6846 if (distance == 0) {
6847
6848 egressCompletionDataAvail = egressCompletionDataAvail;
6849 trigger(ON, egressCompletionDataStopFlag);
6850 }
6851
6852 else if (distance >= 16) {
6853
6854 egressCompletionDataAvail +=
6855 (egressCompletionDataToReturn < 16) ? egressCompletionDataToReturn : 16;
6856
6857 egressCompletionDataToReturn =
6858 (egressCompletionDataToReturn < 16) ? 0 : egressCompletionDataToReturn - 16;
6859 }
6860
6861 else {
6862
6863 egressCompletionDataAvail +=
6864 (egressCompletionDataToReturn < distance) ? egressCompletionDataToReturn : distance;
6865
6866 egressCompletionDataToReturn =
6867 (egressCompletionDataToReturn < distance) ? 0 : egressCompletionDataToReturn - distance;
6868 }
6869 }
6870
6871 else {
6872
6873 egressCompletionDataAvail +=
6874 (egressCompletionDataToReturn < 16) ? egressCompletionDataToReturn : 16;
6875 egressCompletionDataToReturn =
6876 (egressCompletionDataToReturn < 16) ? 0 : egressCompletionDataToReturn - 16;
6877 }
6878 }
6879
6880
6881 f_LPUXtr.sendCreditUpdate( e_FC_completion, 0,
6882 egressCompletionHdrAvail==infiniteCredits ? 0
6883 : egressCompletionHdrAvail,
6884 egressCompletionDataAvail==infiniteCredits ? 0
6885 : egressCompletionDataAvail );
6886 }
6887 }
6888
6889
6890 egressInitPostVCNZWeight : {
6891
6892 f_LPUXtr.sendCreditInit( e_FC_posted, localRandomRange(7, 1),
6893 localRandom(), localRandom());
6894 }
6895
6896
6897 egressInitNonpostVCNZWeight : {
6898
6899 f_LPUXtr.sendCreditInit( e_FC_nonposted, localRandomRange(7, 1),
6900 localRandom(), localRandom());
6901 }
6902
6903
6904 egressInitCompletionVCNZWeight : {
6905
6906 f_LPUXtr.sendCreditInit( e_FC_completion, localRandomRange(7, 1),
6907 localRandom(), localRandom());
6908 }
6909
6910
6911 egressUpdtPostVCNZWeight : {
6912
6913 f_LPUXtr.sendCreditUpdate( e_FC_posted, localRandomRange(7, 1),
6914 localRandom(), localRandom());
6915 }
6916
6917
6918 egressUpdtNonpostVCNZWeight : {
6919
6920 f_LPUXtr.sendCreditUpdate( e_FC_nonposted, localRandomRange(7, 1),
6921 localRandom(), localRandom());
6922 }
6923
6924
6925 egressUpdtCompletionVCNZWeight : {
6926
6927 f_LPUXtr.sendCreditUpdate( e_FC_completion, localRandomRange(7, 1),
6928 localRandom(), localRandom());
6929 }
6930
6931
6932 egressUpdtPostNZAftInfWeight : {
6933
6934 _INFO_MSG( "Sending finite posted credit update" );
6935 f_LPUXtr.sendCreditUpdate(e_FC_posted, 0,
6936 (egressPostHdrAvail == infiniteCredits) ?
6937 localRandom() : egressPostHdrAvail,
6938 (egressPostDataAvail == infiniteCredits) ?
6939 localRandom() : egressPostDataAvail
6940 );
6941 egressUpdateError = 1;
6942 }
6943
6944
6945 egressUpdtNonpostNZAftInfWeight : {
6946
6947 _INFO_MSG( "Sending finite non-posted credit update" );
6948 f_LPUXtr.sendCreditUpdate(e_FC_nonposted, 0,
6949 (egressNonpostHdrAvail == infiniteCredits) ?
6950 localRandom() : egressNonpostHdrAvail,
6951 (egressNonpostDataAvail == infiniteCredits) ?
6952 localRandom() : egressNonpostDataAvail
6953 );
6954 egressUpdateError = 1;
6955 }
6956
6957
6958 egressUpdtCompletionNZAftInfWeight : {
6959
6960 _INFO_MSG( "Sending finite completion credit update" );
6961 f_LPUXtr.sendCreditUpdate(e_FC_completion, 0,
6962 (egressCompletionHdrAvail == infiniteCredits) ?
6963 localRandom() : egressCompletionHdrAvail,
6964 (egressCompletionDataAvail == infiniteCredits) ?
6965 localRandom() : egressCompletionDataAvail
6966 );
6967 egressUpdateError = 1;
6968 }
6969
6970
6971 egressUpdtPostOverflowWeight : {
6972
6973 _INFO_MSG( "Sending overflow posted credit update" );
6974 f_LPUXtr.sendCreditUpdate(e_FC_posted, 0,
6975 (egressPostHdrAvail == infiniteCredits) ?
6976 0 : egressPostHdrConsumed + localRandomRange(255, 138),
6977 (egressPostDataAvail == infiniteCredits) ?
6978 0 : egressPostDataConsumed + localRandomRange(4095, 2058)
6979 );
6980 egressUpdateError = 1;
6981 }
6982
6983
6984 egressUpdtNonpostOverflowWeight : {
6985
6986 _INFO_MSG( "Sending overflow non-posted credit update" );
6987 f_LPUXtr.sendCreditUpdate(e_FC_nonposted, 0,
6988 (egressNonpostHdrAvail == infiniteCredits) ?
6989 0 : egressNonpostHdrConsumed + localRandomRange(255, 138),
6990 (egressNonpostDataAvail == infiniteCredits) ?
6991 0 : egressNonpostDataConsumed + localRandomRange(4095, 2058)
6992 );
6993 egressUpdateError = 1;
6994 }
6995
6996
6997 egressUpdtCompletionOverflowWeight : {
6998
6999 _INFO_MSG( "Sending overflow completion credit update" );
7000 f_LPUXtr.sendCreditUpdate(e_FC_completion, 0,
7001 (egressCompletionHdrAvail == infiniteCredits) ?
7002 0 : egressCompletionHdrConsumed + localRandomRange(255, 138),
7003 (egressCompletionDataAvail == infiniteCredits) ?
7004 egressUpdateError = 1;
7005 }
7006
7007
7008 egressRetryWeight : {
7009
7010 if (( egressRetryAllowed == 1 ) &&
7011 ( mailbox_get( NO_WAIT, mb_egressRetry ) > 0 )) {
7012
7013 mailbox_get( NO_WAIT, mb_egressRetry, dataCredits );
7014 egressRetryAvail = egressRetryAvail + dataCredits;
7015 }
7016
7017 f_LPUXtr.advertiseRetryCredit( egressRetryAvail );
7018 }
7019 }
7020End N2 */
7021
7022// @( posedge CLOCK );
7023 if ( softResetPending ) return;
7024
7025/* N2 moved below to returnEgressCredits()
7026 // If we've been told to restore all
7027 // credits, then let's do so.
7028 if( returnAllEgressCredits ){
7029 QuickReport( Report, RTYP_INFO,
7030 "Env::updateEgressCredits() returnAllEgressCredits called N2- ");
7031 }
7032*/
7033
7034
7035/*N2 review
7036 if ( returnAllEgressCredits )
7037 {
7038 while ( mailbox_get( NO_WAIT, mb_egressRetry ) > 0 )
7039 {
7040 mailbox_get( NO_WAIT, mb_egressRetry, dataCredits );
7041 egressRetryAvail = egressRetryAvail + dataCredits;
7042 }
7043 f_LPUXtr.advertiseRetryCredit( egressRetryAvail );
7044
7045 if ( ( egressPostHdrAvail != infiniteCredits
7046 && egressPostHdrToReturn > 0 )
7047 || ( egressPostDataAvail != infiniteCredits
7048 && egressPostDataToReturn > 0 ) )
7049 {
7050 if ( egressPostHdrAvail != infiniteCredits )
7051 egressPostHdrAvail += egressPostHdrToReturn;
7052 egressPostHdrToReturn = 0;
7053 if ( egressPostDataAvail != infiniteCredits )
7054 egressPostDataAvail += egressPostDataToReturn;
7055 egressPostDataToReturn = 0;
7056 f_LPUXtr.sendCreditUpdate(e_FC_posted, 0,
7057 egressPostHdrAvail==infiniteCredits ? 0
7058 : egressPostHdrAvail,
7059 egressPostDataAvail==infiniteCredits ? 0
7060 : egressPostDataAvail );
7061 @( posedge CLOCK );
7062 if ( softResetPending ) return;
7063 }
7064 if ( ( egressNonpostHdrAvail != infiniteCredits
7065 && egressNonpostHdrToReturn > 0 )
7066 || ( egressNonpostDataAvail != infiniteCredits
7067 && egressNonpostDataToReturn > 0 ) )
7068 {
7069 if ( egressNonpostHdrAvail != infiniteCredits )
7070 egressNonpostHdrAvail += egressNonpostHdrToReturn;
7071 egressNonpostHdrToReturn = 0;
7072 if ( egressNonpostDataAvail != infiniteCredits )
7073 egressNonpostDataAvail += egressNonpostDataToReturn;
7074 egressNonpostDataToReturn = 0;
7075 f_LPUXtr.sendCreditUpdate(e_FC_nonposted, 0,
7076 egressNonpostHdrAvail==infiniteCredits ? 0
7077 : egressNonpostHdrAvail,
7078 egressNonpostDataAvail==infiniteCredits ? 0
7079 : egressNonpostDataAvail );
7080 @( posedge CLOCK );
7081 if ( softResetPending ) return;
7082 }
7083 if ( ( egressCompletionHdrAvail != infiniteCredits
7084 && egressCompletionHdrToReturn > 0 )
7085 || ( egressCompletionDataAvail != infiniteCredits
7086 && egressCompletionDataToReturn > 0 ) )
7087 {
7088 if ( egressCompletionHdrAvail != infiniteCredits )
7089 egressCompletionHdrAvail += egressCompletionHdrToReturn;
7090 egressCompletionHdrToReturn = 0;
7091 if ( egressCompletionDataAvail != infiniteCredits )
7092 egressCompletionDataAvail += egressCompletionDataToReturn;
7093 egressCompletionDataToReturn = 0;
7094 f_LPUXtr.sendCreditUpdate(e_FC_completion, 0,
7095 egressCompletionHdrAvail==infiniteCredits ? 0
7096 : egressCompletionHdrAvail,
7097 egressCompletionDataAvail==infiniteCredits ? 0
7098 : egressCompletionDataAvail );
7099 @( posedge CLOCK );
7100 if ( softResetPending ) return;
7101 }
7102 returnAllEgressCredits = 0;
7103 } // end "if (returnAllEgressCredits)..."
7104END N2 */
7105
7106 // Record whether we think the TLU is out of credits for each TLP type.
7107 // The "round robin" checker in "expectTLU" uses this... it let's a violation
7108 // get through if credits have been lean recently.
7109 egressPostStarved[30:0] = egressPostStarved[31:1];
7110 egressNonpostStarved[30:0] = egressNonpostStarved[31:1];
7111 egressCompletionStarved[30:0] = egressCompletionStarved[31:1];
7112
7113 egressPostStarved[20] =
7114 areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_POST, 0 )
7115 || areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_POST, 1 );
7116 egressNonpostStarved[20] =
7117 areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_NONPOST, 0 )
7118 || areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_NONPOST, 1 );
7119 egressCompletionStarved[20] =
7120 areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_COMP, 0 )
7121 || areEgressCreditsExhausted( PEC_CREDIT_TYPE__UPDT_COMP, 1 );
7122 }
7123} /* end updateEgressCredits */
7124
7125
7126
7127/*
7128 * hangDetect - Watch the "activityCounter" and report an error if it doesn't
7129 * move for a significant period of time
7130 */
7131task PEUTestEnv::hangDetect()
7132{
7133#ifndef N2_FC
7134 integer lastCount;
7135 integer quietTime;
7136 string errMsg;
7137
7138 activityCounter = 0;
7139 activityStalled = 0;
7140 activityTimeout = 750;
7141
7142 lastCount = 0;
7143 quietTime = 0;
7144 while( lastCount >= 0 )
7145 {
7146 @( posedge CLOCK );
7147
7148 if( softResetPending ) break; // If something just happened, then
7149 // reset our local counter and timer.
7150 if ( lastCount != activityCounter || softResetPending )
7151 {
7152 lastCount = activityCounter;
7153 quietTime = 0;
7154 }
7155
7156 // If we aren't expecting any activity
7157 // then (again) reset the timer so that
7158 // it doesn't go off.
7159 else if ( activityStalled )
7160 {
7161 quietTime = 0;
7162 }
7163
7164 // Otherwise, bump the timer...
7165 else if ( quietTime < activityTimeout )
7166 {
7167 quietTime = quietTime + 1;
7168 }
7169
7170 // ...or blow up if we've been inactive
7171 // for too long.
7172 else if ( lastCount > 0 )
7173 {
7174 _REPORT_ERROR( "HANG DETECT\n" );
7175 sprintf( errMsg, " activityStalled=%0d quietTime=%0d activityTimeout=%0d lastCount=%0d",
7176 activityStalled,quietTime,activityTimeout,lastCount );
7177 _ERROR_INFO( errMsg );
7178
7179 // Try to describe everything that might
7180 // be in the way of making progress.
7181 _ERROR_INFO( "Egress credits (hdr/data)..." );
7182 sprintf( errMsg, " Post: %0d/%0d Npst: %0d/%0d Cpln: %0d/%0d",
7183 egressPostHdrAvail == infiniteCredits ? 999
7184 : egressPostHdrAvail - egressPostHdrConsumed,
7185 egressPostDataAvail == infiniteCredits ? 999
7186 : egressPostDataAvail - egressPostDataConsumed,
7187 egressNonpostHdrAvail == infiniteCredits ? 999
7188 : egressNonpostHdrAvail - egressNonpostHdrConsumed,
7189 egressNonpostDataAvail == infiniteCredits ? 999
7190 : egressNonpostDataAvail - egressNonpostDataConsumed,
7191 egressCompletionHdrAvail == infiniteCredits ? 999
7192 : egressCompletionHdrAvail - egressCompletionHdrConsumed,
7193 egressCompletionDataAvail == infiniteCredits ? 999
7194 : egressCompletionDataAvail - egressCompletionDataConsumed );
7195 _ERROR_INFO( errMsg );
7196 _ERROR_INFO( "Ingress credits (hdr/data)..." );
7197 sprintf( errMsg, " Post: %0d/%0d Npst: %0d/%0d Cpln: %0d/%0d",
7198 ingressPostHdrAvail == infiniteCredits ? 999
7199 : ingressPostHdrAvail - ingressPostHdrConsumed,
7200 ingressPostDataAvail == infiniteCredits ? 999
7201 : ingressPostDataAvail - ingressPostDataConsumed,
7202 ingressNonpostHdrAvail == infiniteCredits ? 999
7203 : ingressNonpostHdrAvail - ingressNonpostHdrConsumed,
7204 ingressNonpostDataAvail == infiniteCredits ? 999
7205 : ingressNonpostDataAvail - ingressNonpostDataConsumed,
7206 ingressCompletionHdrAvail == infiniteCredits ? 999
7207 : ingressCompletionHdrAvail - ingressCompletionHdrConsumed,
7208 ingressCompletionDataAvail == infiniteCredits ? 999
7209 : ingressCompletionDataAvail-ingressCompletionDataConsumed );
7210 _ERROR_INFO( errMsg );
7211 sprintf( errMsg, "Retry credits = %0d (%0d avail, %0d consumed)",
7212 egressRetryAvail - egressRetryConsumed,
7213 egressRetryAvail, egressRetryConsumed );
7214 _ERROR_INFO( errMsg );
7215 sprintf( errMsg, "DMA DOU blocks reserved: %h", douBlksUsed );
7216 _ERROR_INFO( errMsg );
7217 if ( douBlksRequest > 0 )
7218 {
7219 sprintf( errMsg, "Outstanding request for %0d DOU blocks",
7220 douBlksRequest );
7221 _ERROR_INFO( errMsg );
7222 }
7223 sprintf( errMsg, "PIO tags reserved: %h", pioTagsUsed );
7224 _ERROR_INFO( errMsg );
7225 sprintf( errMsg, "Pending non-posted PIO tags: %h", nonpostReqPending );
7226 _ERROR_INFO( errMsg );
7227 sprintf( errMsg, "..and those held in the TLU: %h", nonpostReqInLimbo );
7228 _ERROR_INFO( errMsg );
7229 sprintf( errMsg, "%0d/%0d egress req/cpl TLPs expected from the PEU",
7230 mailbox_get( NO_WAIT, mb_egressReqOrder ),
7231 mailbox_get( NO_WAIT, mb_egressCplOrder ) );
7232 _ERROR_INFO( errMsg );
7233 sprintf( errMsg, "%0d ingress TLPs expected from the ILU",
7234 iluExpectReq - iluExpectComplete );
7235 _ERROR_INFO( errMsg );
7236 sprintf( errMsg, "%0d egress TLPs expected from the PEU",
7237 peuExpectTlp - peuExpectComplete );
7238 _ERROR_INFO( errMsg );
7239
7240 sprintf( errMsg, "DMU credits: ingress=%0d egress=%0d",
7241 f_DMUXtr.ingressCreditsAvailable(),
7242 f_DMUXtr.egressCreditsAvailable() );
7243 _ERROR_INFO( errMsg );
7244
7245 dumpCreditStatus();
7246 getIntStatus();
7247 dumpIntStatus();
7248 }
7249 }
7250#endif
7251} /* end hangDetect */
7252
7253/* N2 - Not needed since we're testing ilu-peu
7254 * diddleDack - Play around with the egress "data ack" signal.
7255 *
7256 * This is a permanent thread which asserts/deasserts "l2t_etp_dack"
7257 * as directed by "egressThrottle" (set by the public method "setEgressThrottle")
7258 * If "egressThrottleRandom" is specified, then we'll use a value from {0,20,50}
7259 * with the value changing every thousand cycles (or so).
7260 */
7261task PEUTestEnv::diddleDack()
7262{
7263// N2 - Not needed
7264} /* end diddleDack */
7265
7266/*
7267 * monitorInt - Enable interrupts and make sure that we get only only when
7268 * we expect one.
7269 *
7270 * Parameters:
7271 * EnableErrs - Should we call "enableAllErrors"?
7272 */
7273task PEUTestEnv::monitorInt( bit EnableErrs )
7274{
7275#ifndef N2_FC
7276 if ( EnableErrs ) enableAllErrors();
7277 while( 1 )
7278 {
7279 @( posedge CLOCK );
7280 //miscPort.$int is active low
7281 if ( !Pod.DMUXtr.miscPort.$int && !interruptExpected && !softResetPending )
7282 {
7283 getIntStatus();
7284 showUnexpectedInt();
7285 dumpIntStatus();
7286 dumpCreditStatus();
7287 }
7288 else if ( !Pod.DMUXtr.miscPort.$int && interruptExpected && !softResetPending )
7289 {
7290 if ( interruptUnchecked==0 ) interruptUnchecked = 1;
7291 }
7292 else if ( Pod.DMUXtr.miscPort.$int && interruptUnchecked==1 && !softResetPending )
7293 {
7294 _REPORT_ERROR( "Interrupt not caught by test" );
7295 }
7296 }
7297#endif
7298} /* end monitorInt */
7299
7300/*
7301* disableInterrupt - A test/strategy/whatever is expecting an interrupt
7302*
7303* Parameters: None
7304*/
7305task PEUTestEnv::disableInterrupt()
7306{
7307 interruptExpected = interruptExpected + 1;
7308} /* end disableInterrupt */
7309
7310/*
7311* enableInterrupt - A test no longer expects an interrupt
7312*
7313* Parameters: None
7314*/
7315task PEUTestEnv::enableInterrupt()
7316{
7317 if ( interruptExpected )
7318 interruptExpected = interruptExpected - 1;
7319 if ( interruptExpected == 0 ) interruptUnchecked = 0;
7320} /* end enableInterrupt */
7321
7322/*
7323* expectInterrupt - A test either expects (or does not expect) an interrupt
7324*
7325* Parameters:
7326* Expected - Is an interrupt expected?
7327*/
7328function bit PEUTestEnv::expectInterrupt( bit Expected )
7329{
7330#ifndef N2_FC
7331 //miscPort.$int is active low
7332 if ( !Pod.DMUXtr.miscPort.$int && !Expected )
7333 {
7334 _REPORT_ERROR( "Interrupt from ILU when none expected by test" );
7335 getIntStatus();
7336 dumpIntStatus();
7337 expectInterrupt = 1;
7338 }
7339 else if ( Pod.DMUXtr.miscPort.$int && Expected )
7340 {
7341 _REPORT_ERROR( "No interrupt from ILU when one is expected by test" );
7342 getIntStatus();
7343 dumpIntStatus();
7344 expectInterrupt = 1;
7345 }
7346 else
7347 {
7348 expectInterrupt = 0;
7349 Report.report(RTYP_DEBUG_3,"PEUTestEnv.expectInterrupt good Expected=%0b \n",Expected);
7350 }
7351
7352 if ( interruptUnchecked==1 ) interruptUnchecked = 2;
7353#endif
7354} /* end expectInterrupt */
7355
7356//Wait until an Interrupt is signaled
7357task PEUTestEnv::waitInterrupt()
7358{
7359 //miscPort.$int is active low
7360 while ( Pod.DMUXtr.miscPort.$int ){
7361 @( posedge CLOCK );
7362 }
7363} /* end waitInterrupt */
7364
7365
7366/*
7367* enableAllErrors - Set all interrupt-enable bits so that any error results
7368* in an interrupt, halting simulation if "disableInterrupt"
7369* has not been called.
7370*
7371* Parameters: None
7372*/
7373task PEUTestEnv::enableAllErrors()
7374{
7375#ifndef N2_FC
7376 bit [63:0] ones;
7377 integer lupIndex;
7378
7379 ones = ~ 64'b0;
7380
7381 _INFO_MSG( "Enable all errors (but not the 'link up' event)" );
7382
7383 // Enable all ILU + TLU(PEC) interrupts
7384#ifdef N2_IOS
7385 f_CSR.CSR.fire_dlc_ilu_cib_csr_a_pec_int_en.write(ones,CSRT_OMNI);
7386#else
7387 f_CSR.CSR.fire_dlc_ilu_cib_csr_a_pec_int_en.write(ones,FIRE_PIO_MED);
7388#endif
7389
7390 // Enable all ILU interrupts
7391 f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_log_en.write(ones,CSRT_OMNI);
7392 f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_int_en.write(ones,CSRT_OMNI);
7393
7394 // Enable all uncorrectable TLU(+LPU) interrupts
7395 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_log.write(ones,CSRT_OMNI);
7396 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_int_en.write(ones,CSRT_OMNI);
7397
7398 // Enable all correctable TLU(+LPU) interrupts
7399 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_log.write(ones,CSRT_OMNI);
7400 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_int_en.write(ones,CSRT_OMNI);
7401
7402 // Enable all other TLU(+LPU) interrupts
7403 // EXCEPT "link up", which isn't an error at all!
7404 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_log.write(ones,CSRT_OMNI);
7405 lupIndex = PEC_ERR_bitIndex( e_ERR_oe_lup );
7406 ones[lupIndex] = 1'b0;
7407 ones[lupIndex+32] = 1'b0;
7408 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_int_en.write(ones,CSRT_OMNI);
7409
7410 // Enable all DLPL error interrupts
7411 //Don't enable the allignment error as there are deskew errors during link training
7412 //LOS can occur in detect so disable it here and reenable in LinkTraining Strategy
7413 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_int_en.write(63'h3bfff,CSRT_OMNI);
7414 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_log_en.write(FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_INT_EN_EN_ERROR_FMASK&63'h3fffe,CSRT_OMNI);
7415
7416 // If the interrupt monitor isn't running, then start it up!
7417 if ( !intMonitorActive )
7418 {
7419 intMonitorActive = 1;
7420 fork
7421 monitorInt(0);
7422 join none
7423 }
7424#endif
7425} /* end enableAllErrors */
7426
7427/*
7428 * getIntStatus - collect interrupt status
7429 *
7430 * Parameters: None
7431 */
7432task PEUTestEnv::getIntStatus()
7433{
7434 intCSR[0] = readCSRdirect( getCSRaddr(e_CSR_pec_int_en) );
7435 intCSR[1] = readCSR( getCSRaddr(e_CSR_pec_err) );
7436 //intCSR[1] = 64'bx;
7437 intCSR[2] = readCSRdirect( getCSRaddr(e_CSR_ilu_int_en) );
7438 intCSR[3] = readCSRdirect( getCSRaddr(e_CSR_ilu_log_en) );
7439 intCSR[4] = readCSRdirect( getCSRaddr(e_CSR_ilu_err) );
7440 intCSR[5] = readCSRdirect( getCSRaddr(e_CSR_ue_int_en) );
7441 intCSR[6] = readCSRdirect( getCSRaddr(e_CSR_ue_log_en) );
7442 intCSR[7] = readCSRdirect( getCSRaddr(e_CSR_ue_err) );
7443 intCSR[8] = readCSRdirect( getCSRaddr(e_CSR_ue_recv_hdr1) );
7444 intCSR[9] = readCSRdirect( getCSRaddr(e_CSR_ue_recv_hdr2) );
7445 intCSR[10] = readCSRdirect( getCSRaddr(e_CSR_ue_xmit_hdr1) );
7446 intCSR[11] = readCSRdirect( getCSRaddr(e_CSR_ue_xmit_hdr2) );
7447 intCSR[12] = readCSRdirect( getCSRaddr(e_CSR_ce_int_en) );
7448 intCSR[13] = readCSRdirect( getCSRaddr(e_CSR_ce_log_en) );
7449 intCSR[14] = readCSRdirect( getCSRaddr(e_CSR_ce_err) );
7450 intCSR[15] = readCSRdirect( getCSRaddr(e_CSR_oe_int_en) );
7451 intCSR[16] = readCSRdirect( getCSRaddr(e_CSR_oe_log_en) );
7452 intCSR[17] = readCSRdirect( getCSRaddr(e_CSR_oe_err) );
7453 intCSR[18] = readCSRdirect( getCSRaddr(e_CSR_oe_recv_hdr1) );
7454 intCSR[19] = readCSRdirect( getCSRaddr(e_CSR_oe_recv_hdr2) );
7455 intCSR[20] = readCSRdirect( getCSRaddr(e_CSR_oe_xmit_hdr1) );
7456 intCSR[21] = readCSRdirect( getCSRaddr(e_CSR_oe_xmit_hdr2) );
7457 intCSR[22] = readCSRdirect( getCSRaddr(e_CSR_dlpl_ee_int_en) );
7458 intCSR[23] = readCSRdirect( getCSRaddr(e_CSR_dlpl_ee_log_en) );
7459 intCSR[24] = readCSRdirect( getCSRaddr(e_CSR_dlpl_ee_err) );
7460} /* end getIntStatus */
7461
7462/*
7463 * dumpIntStatus - Write messages describing the state of the ILU/TLU error
7464 * reporting (interrupt) mechanism
7465 *
7466 * Parameters: None
7467 */
7468task PEUTestEnv::dumpIntStatus()
7469{
7470 string msg;
7471 sprintf( msg, "PEC interrupt enable....... %h", intCSR[0] );
7472 _ERROR_INFO(msg);
7473 sprintf( msg, "PEC errors................. %h", intCSR[1] );
7474 _ERROR_INFO(msg);
7475 sprintf( msg, "ILU error log enable....... %h", intCSR[3] );
7476 _ERROR_INFO(msg);
7477 sprintf( msg, "ILU interrupt enable....... %h", intCSR[2] );
7478 _ERROR_INFO(msg);
7479 sprintf( msg, "ILU errors................. %h", intCSR[4] );
7480 _ERROR_INFO(msg);
7481 sprintf( msg, "TLU UE error log enable.... %h", intCSR[6] );
7482 _ERROR_INFO(msg);
7483 sprintf( msg, "TLU UE interrupt enable.... %h", intCSR[5] );
7484 _ERROR_INFO(msg);
7485 sprintf( msg, "TLU uncorrectable errors... %h", intCSR[7] );
7486 _ERROR_INFO(msg);
7487 sprintf( msg, "TLU UE logged 'R' header... %h %h", intCSR[8], intCSR[9] );
7488 _ERROR_INFO(msg);
7489 sprintf( msg, "TLU UE logged 'T' header... %h %h", intCSR[10], intCSR[11] );
7490 _ERROR_INFO(msg);
7491 sprintf( msg, "TLU CE error log enable.... %h", intCSR[13] );
7492 _ERROR_INFO(msg);
7493 sprintf( msg, "TLU CE interrupt enable.... %h", intCSR[12] );
7494 _ERROR_INFO(msg);
7495 sprintf( msg, "TLU correctable errors..... %h", intCSR[14] );
7496 _ERROR_INFO(msg);
7497 sprintf( msg, "TLU OE error log enable.... %h", intCSR[16] );
7498 _ERROR_INFO(msg);
7499 sprintf( msg, "TLU OE interrupt enable.... %h", intCSR[15] );
7500 _ERROR_INFO(msg);
7501 sprintf( msg, "TLU 'other' errors......... %h", intCSR[17] );
7502 _ERROR_INFO(msg);
7503 sprintf( msg, "TLU OE logged 'R' header... %h %h", intCSR[18], intCSR[19] );
7504 _ERROR_INFO(msg);
7505 sprintf( msg, "TLU OE logged 'T' header... %h %h", intCSR[20], intCSR[21] );
7506 _ERROR_INFO(msg);
7507 sprintf( msg, "DLPL error log enable....... %h", intCSR[23] );
7508 _ERROR_INFO(msg);
7509 sprintf( msg, "DLPL interrupt enable....... %h", intCSR[22] );
7510 _ERROR_INFO(msg);
7511 sprintf( msg, "DLPL errors................. %h", intCSR[24] );
7512 _ERROR_INFO(msg);
7513} /* end dumpIntStatus */
7514
7515/*
7516 * showUnexpectedInt - shows BY NAME which unexpected interrupt(s) occurred
7517 *
7518 * Parameters: None
7519 */
7520task PEUTestEnv::showUnexpectedInt()
7521{
7522 PEC_ERRtype err;
7523 string msg;
7524 integer lupIndex;
7525 integer bitIndex;
7526
7527 /* Uncorrectable Errors */
7528 bitIndex = 0;
7529 while ( ( bitIndex < 64 ) && ( (intCSR[5][bitIndex] & intCSR[7][bitIndex]) != 1 ) )
7530 bitIndex++;
7531
7532 if ( bitIndex < 64 ) {
7533 err = e_ERR_ue_mfp;
7534 while ( ( err <= e_ERR_ue_dlp ) && ( PEC_ERR_bitIndex( err ) != ( bitIndex % 32 ) ) )
7535 err++;
7536
7537 if ( err <= e_ERR_ue_dlp ) {
7538 case (err)
7539 {
7540 e_ERR_ue_mfp: _REPORT_ERROR( "Unexpected malformed packet error interrupt!" );
7541 e_ERR_ue_rof: _REPORT_ERROR( "Unexpected Receiver overflow interrupt!" );
7542 e_ERR_ue_ur: _REPORT_ERROR( "Unexpected Unsupported request interrupt!" );
7543 e_ERR_ue_uc: _REPORT_ERROR( "Unexpected Unexpected completion interrupt!" );
7544 e_ERR_ue_cto: _REPORT_ERROR( "Unexpected Completion time-out interrupt!" );
7545 e_ERR_ue_fcp: _REPORT_ERROR( "Unexpected Flow-control protocol error interrupt!" );
7546 e_ERR_ue_pp: _REPORT_ERROR( "Unexpected Poisoned TLP received interrupt!" );
7547 e_ERR_ue_dlp: _REPORT_ERROR( "Unexpected Data-link protocol error (LPU) interrupt!" );
7548//N2 - removed .81 PRM e_ERR_ue_te: _REPORT_ERROR( "Unexpected Training error (LPU) interrupt!" );
7549 default: { sprintf(msg, "case default Unexpected unknown (bit %0d) uncorrectable error interrupt!", bitIndex );
7550 _REPORT_ERROR( msg );
7551 }
7552 }
7553 } else {
7554 sprintf(msg, "Unexpected unknown (bit %0d) uncorrectable error interrupt!", bitIndex );
7555 _REPORT_ERROR( msg );
7556 }
7557 }
7558
7559 /* Correctable Errors */
7560
7561 bitIndex = 0;
7562 while ( ( bitIndex < 64 ) && ( (intCSR[12][bitIndex] & intCSR[14][bitIndex]) != 1 ) )
7563 bitIndex++;
7564
7565 if ( bitIndex < 64 ) {
7566 err = e_ERR_ce_rto;
7567 while ( ( err <= e_ERR_ce_re ) && ( PEC_ERR_bitIndex( err ) != ( bitIndex % 32 ) ) )
7568 err++;
7569
7570 if ( err <= e_ERR_ce_re ) {
7571 case (err)
7572 {
7573 e_ERR_ce_rto: _REPORT_ERROR( "Unexpected Replay time-out (PEU) interrupt!" );
7574 e_ERR_ce_rnr: _REPORT_ERROR( "Unexpected Replay roll-over (PEU) interrupt!" );
7575 e_ERR_ce_bdp: _REPORT_ERROR( "Unexpected Bad DLLP (PEU) interrupt!" );
7576 e_ERR_ce_btp: _REPORT_ERROR( "Unexpected Bad TLP (PEU) interrupt!" );
7577 e_ERR_ce_re: _REPORT_ERROR( "Unexpected Receiver error (PEU) interrupt!" );
7578 default: { sprintf(msg, "case default Unexpected unknown (bit %0d) correctable error interrupt!", bitIndex );
7579 _REPORT_ERROR( msg );
7580 }
7581 }
7582 } else {
7583 sprintf(msg, "Unexpected unknown (bit %0d) correctable error interrupt!", bitIndex );
7584 _REPORT_ERROR( msg );
7585 }
7586 }
7587
7588 /* Other Errors */
7589
7590 bitIndex = 0;
7591 while ( ( bitIndex < 64 ) && ( (intCSR[15][bitIndex] & intCSR[17][bitIndex]) != 1 ) )
7592 bitIndex++;
7593
7594 if ( bitIndex < 64 ) {
7595 err = e_ERR_oe_mrc;
7596 while ( ( err <= e_ERR_oe_eip ) && ( PEC_ERR_bitIndex( err ) != ( bitIndex % 32 ) ) )
7597 err++;
7598
7599 if ( err <= e_ERR_oe_eip ) {
7600 case (err)
7601 {
7602 e_ERR_oe_mrc: _REPORT_ERROR( "Unexpected Memory read capture interrupt!" );
7603 e_ERR_oe_cto: _REPORT_ERROR( "Unexpected Completion time-out (dup) interrupt!" );
7604 e_ERR_oe_mfc: _REPORT_ERROR( "Unexpected Malformed completion interrupt!" );
7605 e_ERR_oe_nfp: _REPORT_ERROR( "Unexpected No forward progress interrupt!" );
7606 e_ERR_oe_lwc: _REPORT_ERROR( "Unexpected Link-width change interrupt!" );
7607 e_ERR_oe_wuc: _REPORT_ERROR( "Unexpected Unsuccessful cpl to write interrupt!" );
7608 e_ERR_oe_ruc: _REPORT_ERROR( "Unexpected Unsuccessful cpl to read interrupt!" );
7609 e_ERR_oe_crs: _REPORT_ERROR( "Unexpected Cfg cpl'n with retry status interrupt!" );
7610 e_ERR_oe_iip: _REPORT_ERROR( "Unexpected Ingress interface parity err interrupt!" );
7611 e_ERR_oe_edp: _REPORT_ERROR( "Unexpected Egress data (EDB) parity err interrupt!" );
7612 e_ERR_oe_ehp: _REPORT_ERROR( "Unexpected Egress hdr (EHB) parity err interrupt!" );
7613 e_ERR_oe_lin: _REPORT_ERROR( "Unexpected Link interrupt interrupt!" );
7614 e_ERR_oe_lrs: _REPORT_ERROR( "Unexpected Link reset interrupt!" );
7615 e_ERR_oe_ldn: _REPORT_ERROR( "Unexpected Link down interrupt!" );
7616 e_ERR_oe_lup: _REPORT_ERROR( "Unexpected Link up interrupt!" );
7617 e_ERR_oe_eru: _REPORT_ERROR( "Unexpected Retry buffer underflow interrupt!" );
7618 e_ERR_oe_ero: _REPORT_ERROR( "Unexpected Retry buffer overflow interrupt!" );
7619 e_ERR_oe_emp: _REPORT_ERROR( "Unexpected Egress minimum pkt error interrupt!" );
7620 e_ERR_oe_epe: _REPORT_ERROR( "Unexpected Egress protocol error interrupt!" );
7621 e_ERR_oe_erp: _REPORT_ERROR( "Unexpected Egress retry parity error interrupt!" );
7622 e_ERR_oe_eip: _REPORT_ERROR( "Unexpected Egress interface parity error interrupt!" );
7623 default: { sprintf(msg, "case default Unexpected unknown (bit %0d) other error interrupt!", bitIndex );
7624 _REPORT_ERROR( msg );
7625 }
7626 }
7627 } else {
7628 sprintf(msg, "Unexpected unknown (bit %0d) other error interrupt!", bitIndex );
7629 _REPORT_ERROR( msg );
7630 }
7631 }
7632
7633 /* DLPL Errors */
7634
7635 bitIndex = 0;
7636 while ( ( bitIndex < 64 ) && ( (intCSR[22][bitIndex] & intCSR[24][bitIndex]) != 1 ) )
7637 bitIndex++;
7638
7639 if ( bitIndex < 64 ) {
7640 err = e_ERR_dlpl_sds_los;
7641 while ( ( err <= e_ERR_dlpl_out_skip ) && ( PEC_ERR_bitIndex( err ) != ( bitIndex % 32 ) ) )
7642 err++;
7643
7644 if ( err <= e_ERR_dlpl_out_skip ) {
7645 case (err)
7646 {
7647 e_ERR_dlpl_sds_los: _REPORT_ERROR( "Unexpected Serdes Loss Signal interrupt!" );
7648 e_ERR_dlpl_src_tlp: _REPORT_ERROR( "Unexpected Ingress TLP w/ inverted CRC and EDB interrupt!" );
7649 e_ERR_dlpl_unsup_dllp: _REPORT_ERROR( "Unexpected Ingress Unsupported DLLP interrupt!" );
7650 e_ERR_dlpl_ill_stp_pos: _REPORT_ERROR( "Unexpected Ingress illegal STP position interrupt!" );
7651 e_ERR_dlpl_ill_sdp_pos: _REPORT_ERROR( "Unexpected Ingress illegal SDP position interrupt!" );
7652 e_ERR_dlpl_multi_stp: _REPORT_ERROR( "Ingress multiple stp without END/EDB interrupt!" );
7653 e_ERR_dlpl_multi_sdp: _REPORT_ERROR( "Ingress multiple sdp without END/EDB interrupt!" );
7654 e_ERR_dlpl_ill_pad_pos: _REPORT_ERROR( "Unexpected Ingress illegal pad position interrupt!" );
7655 e_ERR_dlpl_stp_no_end_edb: _REPORT_ERROR( "Unexpected Ingress STP without END/EDB interrupt!" );
7656 e_ERR_dlpl_sdp_no_end: _REPORT_ERROR( "Unexpected Ingress SDP without END interrupt!" );
7657 e_ERR_dlpl_end_no_stp_sdp: _REPORT_ERROR( "Unexpected Ingress END without STP/SDP interrupt!" );
7658 e_ERR_dlpl_sync: _REPORT_ERROR( "Unexpected Lost bit/byte sync interrupt!" );
7659 e_ERR_dlpl_ill_end_pos: _REPORT_ERROR( "Unexpected Ingress illegal END position interrupt!" );
7660 e_ERR_dlpl_kchar_dllp: _REPORT_ERROR( "Unexpected Ingress kchar in dllp interrupt!" );
7661
7662 e_ERR_dlpl_align: _REPORT_ERROR( "Unexpected Alignment error interrupt!" );
7663 e_ERR_dlpl_elas_fifo_ovfl: _REPORT_ERROR( "Unexpected Elastic fifo overflow interrupt!" );
7664 e_ERR_dlpl_elas_fifo_unfl: _REPORT_ERROR( "Unexpected Elastic fifo underflow interrupt!" );
7665 e_ERR_dlpl_out_skip: _REPORT_ERROR( "Unexpected Number of outstanding SKIPs > 6 interrupt!" );
7666 default: { sprintf(msg, "case default Unexpected unknown (bit %0d) DLPL error interrupt!", bitIndex );
7667 _REPORT_ERROR( msg );
7668 }
7669 }
7670 } else {
7671 sprintf(msg, "Unexpected unknown (bit %0d) DLPL error interrupt!", bitIndex );
7672 _REPORT_ERROR( msg );
7673 }
7674 }
7675} /* end showUnexpectedInt */
7676
7677//N2-Not Needed
7678/*
7679 * monitorAHB - A "transactor" for the TLU/LPU AHB port
7680 *
7681 * Parameters: None
7682 */
7683task PEUTestEnv::monitorAHB()
7684{
7685/* N2
7686 bit [31:0] csrAddr;
7687 bit [31:0] dataOut;
7688 integer delay;
7689 integer i;
7690 bit retry;
7691
7692 // Initialize all LPU registers
7693 for (i=0; i<PEC_LPU_CSR_MAX_COUNT; i++ ) lpuCsr[i] = 0;
7694
7695 // There is no pending AHB request
7696 delay = 0;
7697
7698 // We haven't asked for a "retry"
7699 retry = 0;
7700
7701 // Monitor the AHB interface
7702 while( 1 )
7703 {
7704 if ( delay && TLU_AHB.Msel && TLU_AHB.Mready && TLU_AHB.Mtrans == 2'b10 )
7705 {
7706 _REPORT_ERROR( "TLU submits AHB request while another is in progress" );
7707 }
7708
7709 // If the bus-master is asking us to
7710 // perform a (nonsequential) transfer...
7711 if ( !delay && TLU_AHB.Msel && TLU_AHB.Mready && TLU_AHB.Mtrans == 2'b10 )
7712 {
7713 // Make sure that a single-word
7714 // read/write is requested.
7715 if ( TLU_AHB.Msize != 3'b010 )
7716 {
7717 _REPORT_ERROR( "Invalid non-word AHB request from TLU!" );
7718 }
7719 if ( TLU_AHB.Mburst != 3'b000 )
7720 {
7721 _REPORT_ERROR( "Invalid 'burst' AHB request from TLU!" );
7722 }
7723
7724 // Get the CSR's index from the address
7725 csrAddr = TLU_AHB.Maddr[PEC_LPU_CSR_AHB_ADDR];
7726
7727 // Then either write it...
7728 if ( TLU_AHB.Mwrite )
7729 {
7730 lpuCsr[ csrAddr ] = TLU_AHB.Mwdata;
7731 dataOut = 32'bx;
7732 retry = 0;
7733 }
7734
7735 // ...or read it.
7736 else
7737 {
7738 dataOut = lpuCsr[ csrAddr ];
7739 if ( retry )
7740 retry = 0;
7741 else
7742 retry = 0; // If we wanted to retry, we'd set it to one...
7743 }
7744
7745 // We'll take the delay from the addr.
7746 delay = csrAddr[2:0] + 1;
7747 }
7748
7749 // All done!
7750 @1 TLU_AHB.Sready = void;
7751 if ( softResetPending )
7752 {
7753 if ( delay > 0 )
7754 {
7755 TLU_AHB.Srdata <= 32'b0;
7756 TLU_AHB.Sready <= 1;
7757 @1 TLU_AHB.Sready = void;
7758 }
7759 delay = 0;
7760 TLU_AHB.Sready <= 0;
7761 }
7762 else if ( delay == 1 )
7763 {
7764 TLU_AHB.Srdata <= dataOut;
7765 TLU_AHB.Sready <= 1;
7766 if ( retry )
7767 TLU_AHB.Sresp <= 2'b10;
7768 else
7769 TLU_AHB.Sresp <= 2'b00;
7770 }
7771 else
7772 {
7773 TLU_AHB.Srdata <= 32'bx;
7774 TLU_AHB.Sready <= 0;
7775 }
7776 if ( delay > 0 ) delay = delay - 1;
7777 }
7778END N2 */
7779} /* end monitorAHB */
7780
7781/*
7782* getCSRaddr - Obtain the address of an ILU/TLU CSR
7783*
7784* Parameters:
7785* csr - An indication of the CSR of interest
7786*
7787* Returned value: The "csr's" address
7788*/
7789function integer PEUTestEnv::getCSRaddr( PEC_CSRtype csr )
7790{
7791 integer addr;
7792
7793 case ( csr )
7794 {
7795 e_CSR_pec_int_en :
7796 addr = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_ADDR;
7797 e_CSR_pec_err :
7798 addr = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_ADDR;
7799 e_CSR_ilu_int_en :
7800 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_ADDR;
7801 e_CSR_ilu_log_en :
7802 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_ADDR;
7803 e_CSR_ilu_en_err :
7804 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_ADDR;
7805 e_CSR_ilu_err :
7806 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_ADDR;
7807 e_CSR_ilu_err_diag :
7808 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_ADDR;
7809 e_CSR_ilu_diagnos :
7810 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_ADDR;
7811 e_CSR_dev_cap :
7812 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_ADDR;
7813 e_CSR_dev_ctl :
7814 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_ADDR;
7815 e_CSR_dev_status :
7816 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_ADDR;
7817 e_CSR_lnk_cap :
7818 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_ADDR;
7819 e_CSR_lnk_ctl :
7820 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_ADDR;
7821 e_CSR_lnk_status :
7822 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_ADDR;
7823 e_CSR_slot_cap :
7824 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_ADDR;
7825 e_CSR_pme_ctl :
7826 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_ADDR;
7827 e_CSR_ue_int_en :
7828 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_ADDR;
7829 e_CSR_ue_log_en :
7830 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_ADDR;
7831 e_CSR_ue_en_err :
7832 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_ADDR;
7833 e_CSR_ue_err :
7834 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_ADDR;
7835 e_CSR_ue_err_diag :
7836 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_ADDR;
7837 e_CSR_ue_recv_hdr1 :
7838 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_ADDR;
7839 e_CSR_ue_recv_hdr2 :
7840 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_ADDR;
7841 e_CSR_ue_xmit_hdr1 :
7842 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_ADDR;
7843 e_CSR_ue_xmit_hdr2 :
7844 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_ADDR;
7845 e_CSR_ce_int_en :
7846 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_ADDR;
7847 e_CSR_ce_log_en :
7848 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_ADDR;
7849 e_CSR_ce_en_err :
7850 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_ADDR;
7851 e_CSR_ce_err :
7852 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_ADDR;
7853 e_CSR_ce_err_diag :
7854 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_ADDR;
7855 e_CSR_oe_int_en :
7856 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_ADDR;
7857 e_CSR_oe_log_en :
7858 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_ADDR;
7859 e_CSR_oe_en_err :
7860 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_ADDR;
7861 e_CSR_oe_err :
7862 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR;
7863 e_CSR_oe_err_diag :
7864 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_ADDR;
7865 e_CSR_oe_recv_hdr1 :
7866 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_ADDR;
7867 e_CSR_oe_recv_hdr2 :
7868 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_ADDR;
7869 e_CSR_oe_xmit_hdr1 :
7870 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_ADDR;
7871 e_CSR_oe_xmit_hdr2 :
7872 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_ADDR;
7873 e_CSR_tlu_ctl :
7874 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR;
7875 e_CSR_tlu_stat :
7876 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_ADDR;
7877 e_CSR_tlu_diag :
7878 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_ADDR;
7879 e_CSR_tlu_debug_a :
7880 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_ADDR;
7881 e_CSR_tlu_debug_b :
7882 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_ADDR;
7883 e_CSR_ecrdt_avail :
7884 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_ADDR;
7885 e_CSR_ecrdt_used :
7886 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_ADDR;
7887 e_CSR_retry_crdt :
7888 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_ADDR;
7889 e_CSR_icrdt_init :
7890 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_ADDR;
7891 e_CSR_icrdt_avail :
7892 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_ADDR;
7893 e_CSR_icrdt_used :
7894 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_ADDR;
7895 e_CSR_tlu_prfc :
7896 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_ADDR;
7897 e_CSR_tlu_prf0 :
7898 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_ADDR;
7899 e_CSR_tlu_prf1 :
7900 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_ADDR;
7901 e_CSR_tlu_prf2 :
7902 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_ADDR;
7903 e_CSR_core_status :
7904 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR;
7905 e_CSR_replay_tim_thresh :
7906 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIM_THRESH_ADDR;
7907 e_CSR_replay_timer :
7908 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_ADDR;
7909 e_CSR_dlpl_ee_int_en :
7910 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_INT_EN_ADDR;
7911 e_CSR_dlpl_ee_log_en :
7912 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_LOG_EN_ADDR;
7913 e_CSR_dlpl_ee_int_sts :
7914 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_INT_STS_ADDR;
7915 e_CSR_dlpl_ee_err :
7916 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_ADDR;
7917 e_CSR_dlpl_ee_err_diag :
7918 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1S_ALIAS_ADDR;
7919 e_CSR_dlpl_link_ctl :
7920 addr = FIRE_PLC_TLU_CTB_TLR_CSR_A_LINK_CTL_ADDR;
7921
7922/*
7923//N2 ILU Error injection
7924 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_RW1S_ALIAS_ADDR;
7925 addr = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_RW1C_ALIAS_ADDR;
7926
7927*/
7928 }
7929
7930 getCSRaddr = addr;
7931} /* end getCSRaddr */
7932
7933/*
7934* isCSRreset - Is a CSR reset during a "soft reset"?
7935*
7936* Parameters:
7937* csr - An indication of the CSR of interest
7938*
7939* Returned value: Non-zero if the CSR is reset during a soft reset
7940*/
7941function bit PEUTestEnv::isCSRreset( PEC_CSRtype csr )
7942{
7943 case ( csr )
7944 {
7945 e_CSR_pec_int_en : isCSRreset = 1;
7946 e_CSR_pec_err : isCSRreset = 1;
7947 e_CSR_ilu_int_en : isCSRreset = 1;
7948 e_CSR_ilu_log_en : isCSRreset = 0;
7949 e_CSR_ilu_en_err : isCSRreset = 1;
7950 e_CSR_dev_cap : isCSRreset = 1;
7951 e_CSR_dev_ctl : isCSRreset = 1;
7952 e_CSR_dev_status : isCSRreset = 1;
7953 e_CSR_lnk_cap : isCSRreset = 1;
7954 e_CSR_lnk_ctl : isCSRreset = 1;
7955 e_CSR_lnk_status : isCSRreset = 1;
7956 e_CSR_slot_cap : isCSRreset = 1;
7957 e_CSR_pme_ctl : isCSRreset = 1;
7958 e_CSR_ue_int_en : isCSRreset = 1;
7959 e_CSR_ue_log_en : isCSRreset = 0;
7960 e_CSR_ue_en_err : isCSRreset = 1;
7961 e_CSR_ce_int_en : isCSRreset = 1;
7962 e_CSR_ce_log_en : isCSRreset = 0;
7963 e_CSR_ce_en_err : isCSRreset = 1;
7964 e_CSR_oe_int_en : isCSRreset = 1;
7965 e_CSR_oe_log_en : isCSRreset = 0;
7966 e_CSR_oe_en_err : isCSRreset = 1;
7967 e_CSR_tlu_ctl : isCSRreset = 0;
7968 e_CSR_tlu_stat : isCSRreset = 1;
7969 e_CSR_tlu_diag : isCSRreset = 1;
7970 e_CSR_tlu_debug_a : isCSRreset = 1;
7971 e_CSR_tlu_debug_b : isCSRreset = 1;
7972 e_CSR_ecrdt_avail : isCSRreset = 1;
7973 e_CSR_ecrdt_used : isCSRreset = 1;
7974 e_CSR_retry_crdt : isCSRreset = 1;
7975 e_CSR_icrdt_avail : isCSRreset = 1;
7976 e_CSR_icrdt_used : isCSRreset = 1;
7977 e_CSR_tlu_prfc : isCSRreset = 1;
7978 e_CSR_tlu_prf0 : isCSRreset = 1;
7979 e_CSR_tlu_prf1 : isCSRreset = 1;
7980 e_CSR_tlu_prf2 : isCSRreset = 1;
7981 e_CSR_core_status : isCSRreset = 1;
7982 default: isCSRreset = 0;
7983 }
7984} /* end isCSRreset */
7985
7986/*
7987* getCSRreadMask - Which bits of a CSR are defined/readable?
7988*
7989* Parameters:
7990* csr - An indication of the CSR of interest
7991*
7992* Returned value: A bit-mask of defined CSR bits
7993*
7994* NOTE: The mask does NOT include "read as zero" bits
7995*/
7996function bit[63:0] PEUTestEnv::getCSRreadMask( PEC_CSRtype csr )
7997{
7998 case ( csr )
7999 {
8000 e_CSR_pec_int_en :
8001 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_READ_MASK;
8002 e_CSR_pec_err :
8003 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_READ_MASK;
8004 e_CSR_ilu_int_en :
8005 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_READ_MASK;
8006 e_CSR_ilu_log_en :
8007 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_READ_MASK;
8008 e_CSR_ilu_en_err :
8009 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_READ_MASK;
8010 e_CSR_ilu_err :
8011 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_READ_MASK;
8012 e_CSR_ilu_err_diag :
8013 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_READ_MASK;
8014 e_CSR_ilu_diagnos :
8015 getCSRreadMask = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_READ_MASK;
8016 e_CSR_dev_cap :
8017 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_READ_MASK;
8018 e_CSR_dev_ctl :
8019 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_READ_MASK;
8020 e_CSR_dev_status :
8021 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_READ_MASK;
8022 e_CSR_lnk_cap :
8023 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_READ_MASK;
8024 e_CSR_lnk_ctl :
8025 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_READ_MASK
8026 ^ FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_HW_LD_MASK;
8027 e_CSR_lnk_status :
8028 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_READ_MASK;
8029 e_CSR_slot_cap :
8030 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_READ_MASK;
8031 e_CSR_pme_ctl :
8032 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_READ_MASK;
8033 e_CSR_ue_int_en :
8034 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_READ_MASK;
8035 e_CSR_ue_log_en :
8036 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_READ_MASK;
8037 e_CSR_ue_en_err :
8038 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_READ_MASK;
8039 e_CSR_ue_err :
8040 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_READ_MASK;
8041 e_CSR_ue_err_diag :
8042 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_READ_MASK;
8043 e_CSR_ue_recv_hdr1 :
8044 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_READ_MASK;
8045 e_CSR_ue_recv_hdr2 :
8046 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_READ_MASK;
8047 e_CSR_ue_xmit_hdr1 :
8048 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_READ_MASK;
8049 e_CSR_ue_xmit_hdr2 :
8050 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_READ_MASK;
8051 e_CSR_ce_int_en :
8052 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_READ_MASK;
8053 e_CSR_ce_log_en :
8054 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_READ_MASK;
8055 e_CSR_ce_en_err :
8056 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_READ_MASK;
8057 e_CSR_ce_err :
8058 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_READ_MASK;
8059 e_CSR_ce_err_diag :
8060 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_READ_MASK;
8061 e_CSR_oe_int_en :
8062 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_READ_MASK;
8063 e_CSR_oe_log_en :
8064 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_READ_MASK;
8065 e_CSR_oe_en_err :
8066 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_READ_MASK;
8067 e_CSR_oe_err :
8068 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_READ_MASK;
8069 e_CSR_oe_err_diag :
8070 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_READ_MASK;
8071 e_CSR_oe_recv_hdr1 :
8072 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_READ_MASK;
8073 e_CSR_oe_recv_hdr2 :
8074 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_READ_MASK;
8075 e_CSR_oe_xmit_hdr1 :
8076 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_READ_MASK;
8077 e_CSR_oe_xmit_hdr2 :
8078 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_READ_MASK;
8079 e_CSR_tlu_ctl :
8080 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_READ_MASK;
8081 e_CSR_tlu_stat :
8082 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_READ_MASK;
8083 e_CSR_tlu_diag :
8084 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_READ_MASK;
8085 e_CSR_tlu_debug_a :
8086 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_READ_MASK;
8087 e_CSR_tlu_debug_b :
8088 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_READ_MASK;
8089 e_CSR_ecrdt_avail :
8090 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_READ_MASK;
8091 e_CSR_ecrdt_used :
8092 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_READ_MASK;
8093 e_CSR_retry_crdt :
8094 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_READ_MASK;
8095 e_CSR_icrdt_init :
8096 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_READ_MASK;
8097 e_CSR_icrdt_avail :
8098 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_READ_MASK;
8099 e_CSR_icrdt_used :
8100 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_READ_MASK;
8101 e_CSR_tlu_prfc :
8102 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_READ_MASK;
8103 e_CSR_tlu_prf0 :
8104 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_READ_MASK;
8105 e_CSR_tlu_prf1 :
8106 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_READ_MASK;
8107 e_CSR_tlu_prf2 :
8108 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_READ_MASK;
8109 e_CSR_core_status :
8110 getCSRreadMask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_READ_MASK;
8111 default:
8112 getCSRreadMask = 64'b0;
8113 }
8114} /* end getCSRreadMask */
8115
8116/*
8117* getCSRwriteMask - Which bits of a CSR are writable?
8118*
8119* Parameters:
8120* csr - An indication of the CSR of interest
8121*
8122* Returned value: A bit-mask of software-modifiable CSR bits
8123*/
8124function bit[63:0] PEUTestEnv::getCSRwriteMask( PEC_CSRtype csr )
8125{
8126 bit[63:0] mask;
8127
8128 case ( csr )
8129 {
8130 e_CSR_pec_int_en :
8131 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_WRITE_MASK;
8132 e_CSR_pec_err :
8133 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_WRITE_MASK;
8134 e_CSR_ilu_int_en :
8135 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_WRITE_MASK;
8136 e_CSR_ilu_log_en :
8137 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_WRITE_MASK;
8138 e_CSR_ilu_en_err :
8139 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_WRITE_MASK;
8140 e_CSR_ilu_err :
8141 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_WRITE_MASK;
8142 e_CSR_ilu_err_diag :
8143 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_WRITE_MASK;
8144 e_CSR_ilu_diagnos :
8145 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_WRITE_MASK;
8146 e_CSR_dev_cap :
8147 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_WRITE_MASK;
8148 e_CSR_dev_ctl :
8149 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_WRITE_MASK;
8150 e_CSR_dev_status :
8151 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_WRITE_MASK;
8152 e_CSR_lnk_cap :
8153 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_WRITE_MASK;
8154 e_CSR_lnk_ctl :
8155 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_WRITE_MASK;
8156 e_CSR_lnk_status :
8157 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_WRITE_MASK;
8158 e_CSR_slot_cap :
8159 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_WRITE_MASK;
8160 e_CSR_pme_ctl :
8161 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_WRITE_MASK;
8162 e_CSR_ue_int_en :
8163 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_WRITE_MASK;
8164 e_CSR_ue_log_en :
8165 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_WRITE_MASK;
8166 e_CSR_ue_en_err :
8167 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_WRITE_MASK;
8168 e_CSR_ue_err :
8169 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_WRITE_MASK;
8170 e_CSR_ue_err_diag :
8171 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_WRITE_MASK;
8172 e_CSR_ue_recv_hdr1 :
8173 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_WRITE_MASK;
8174 e_CSR_ue_recv_hdr2 :
8175 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_WRITE_MASK;
8176 e_CSR_ue_xmit_hdr1 :
8177 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_WRITE_MASK;
8178 e_CSR_ue_xmit_hdr2 :
8179 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_WRITE_MASK;
8180 e_CSR_ce_int_en :
8181 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_WRITE_MASK;
8182 e_CSR_ce_log_en :
8183 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_WRITE_MASK;
8184 e_CSR_ce_en_err :
8185 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_WRITE_MASK;
8186 e_CSR_ce_err :
8187 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_WRITE_MASK;
8188 e_CSR_ce_err_diag :
8189 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_WRITE_MASK;
8190 e_CSR_oe_int_en :
8191 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_WRITE_MASK;
8192 e_CSR_oe_log_en :
8193 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_WRITE_MASK;
8194 e_CSR_oe_en_err :
8195 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_WRITE_MASK;
8196 e_CSR_oe_err :
8197 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_WRITE_MASK;
8198 e_CSR_oe_err_diag :
8199 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_WRITE_MASK;
8200 e_CSR_oe_recv_hdr1 :
8201 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_WRITE_MASK;
8202 e_CSR_oe_recv_hdr2 :
8203 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_WRITE_MASK;
8204 e_CSR_oe_xmit_hdr1 :
8205 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_WRITE_MASK;
8206 e_CSR_oe_xmit_hdr2 :
8207 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_WRITE_MASK;
8208 e_CSR_tlu_ctl :
8209 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_WRITE_MASK;
8210 e_CSR_tlu_stat :
8211 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_WRITE_MASK;
8212 e_CSR_tlu_diag :
8213 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_WRITE_MASK;
8214 e_CSR_tlu_debug_a :
8215 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_WRITE_MASK;
8216 e_CSR_tlu_debug_b :
8217 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_WRITE_MASK;
8218 e_CSR_ecrdt_avail :
8219 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_WRITE_MASK;
8220 e_CSR_ecrdt_used :
8221 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_WRITE_MASK;
8222 e_CSR_retry_crdt :
8223 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_WRITE_MASK;
8224 e_CSR_icrdt_init :
8225 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_WRITE_MASK;
8226 e_CSR_icrdt_avail :
8227 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_WRITE_MASK;
8228 e_CSR_icrdt_used :
8229 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_WRITE_MASK;
8230 e_CSR_tlu_prfc :
8231 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_WRITE_MASK;
8232 e_CSR_tlu_prf0 :
8233 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_WRITE_MASK;
8234 e_CSR_tlu_prf1 :
8235 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_WRITE_MASK;
8236 e_CSR_tlu_prf2 :
8237 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_WRITE_MASK;
8238 e_CSR_core_status :
8239 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_WRITE_MASK;
8240 default:
8241 mask = 64'b0;
8242 }
8243 getCSRwriteMask = mask | getCSRsetMask(csr) | getCSRclearMask(csr);
8244} /* end getCSRwriteMask */
8245
8246/*
8247* getCSRsetMask - Which bits of a CSR are write-1-to-set?
8248*
8249* Parameters:
8250* csr - An indication of the CSR of interest
8251*
8252* Returned value: A bit-mask of software-modifiable set-only CSR bits
8253*/
8254function bit[63:0] PEUTestEnv::getCSRsetMask( PEC_CSRtype csr )
8255{
8256 bit[63:0] mask;
8257
8258 case ( csr )
8259 {
8260 e_CSR_pec_int_en :
8261 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_SET_MASK;
8262 e_CSR_pec_err :
8263 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_SET_MASK;
8264 e_CSR_ilu_int_en :
8265 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_SET_MASK;
8266 e_CSR_ilu_log_en :
8267 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_SET_MASK;
8268 e_CSR_ilu_en_err :
8269 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_SET_MASK;
8270 e_CSR_ilu_err :
8271 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_SET_MASK;
8272 e_CSR_ilu_err_diag :
8273 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_SET_MASK;
8274 e_CSR_ilu_diagnos :
8275 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_SET_MASK;
8276 e_CSR_dev_cap :
8277 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_SET_MASK;
8278 e_CSR_dev_ctl :
8279 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_SET_MASK;
8280 e_CSR_dev_status :
8281 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_SET_MASK;
8282 e_CSR_lnk_cap :
8283 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_SET_MASK;
8284 e_CSR_lnk_ctl :
8285 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_SET_MASK;
8286 e_CSR_lnk_status :
8287 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_SET_MASK;
8288 e_CSR_slot_cap :
8289 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_SET_MASK;
8290 e_CSR_pme_ctl :
8291 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_SET_MASK;
8292 e_CSR_ue_int_en :
8293 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_SET_MASK;
8294 e_CSR_ue_log_en :
8295 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_SET_MASK;
8296 e_CSR_ue_en_err :
8297 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_SET_MASK;
8298 e_CSR_ue_err :
8299 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_SET_MASK;
8300 e_CSR_ue_err_diag :
8301 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_SET_MASK;
8302 e_CSR_ue_recv_hdr1 :
8303 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_SET_MASK;
8304 e_CSR_ue_recv_hdr2 :
8305 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_SET_MASK;
8306 e_CSR_ue_xmit_hdr1 :
8307 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_SET_MASK;
8308 e_CSR_ue_xmit_hdr2 :
8309 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_SET_MASK;
8310 e_CSR_ce_int_en :
8311 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_SET_MASK;
8312 e_CSR_ce_log_en :
8313 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_SET_MASK;
8314 e_CSR_ce_en_err :
8315 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_SET_MASK;
8316 e_CSR_ce_err :
8317 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_SET_MASK;
8318 e_CSR_ce_err_diag :
8319 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_SET_MASK;
8320 e_CSR_oe_int_en :
8321 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_SET_MASK;
8322 e_CSR_oe_log_en :
8323 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_SET_MASK;
8324 e_CSR_oe_en_err :
8325 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_SET_MASK;
8326 e_CSR_oe_err :
8327 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_SET_MASK;
8328 e_CSR_oe_err_diag :
8329 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_SET_MASK;
8330 e_CSR_oe_recv_hdr1 :
8331 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_SET_MASK;
8332 e_CSR_oe_recv_hdr2 :
8333 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_SET_MASK;
8334 e_CSR_oe_xmit_hdr1 :
8335 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_SET_MASK;
8336 e_CSR_oe_xmit_hdr2 :
8337 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_SET_MASK;
8338 e_CSR_tlu_ctl :
8339 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_SET_MASK;
8340 e_CSR_tlu_stat :
8341 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_SET_MASK;
8342 e_CSR_tlu_diag :
8343 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_SET_MASK;
8344 e_CSR_tlu_debug_a :
8345 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_SET_MASK;
8346 e_CSR_tlu_debug_b :
8347 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_SET_MASK;
8348 e_CSR_ecrdt_avail :
8349 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_SET_MASK;
8350 e_CSR_ecrdt_used :
8351 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_SET_MASK;
8352 e_CSR_retry_crdt :
8353 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_SET_MASK;
8354 e_CSR_icrdt_init :
8355 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_SET_MASK;
8356 e_CSR_icrdt_avail :
8357 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_SET_MASK;
8358 e_CSR_icrdt_used :
8359 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_SET_MASK;
8360 e_CSR_tlu_prfc :
8361 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_SET_MASK;
8362 e_CSR_tlu_prf0 :
8363 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_SET_MASK;
8364 e_CSR_tlu_prf1 :
8365 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_SET_MASK;
8366 e_CSR_tlu_prf2 :
8367 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_SET_MASK;
8368 e_CSR_core_status :
8369 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_SET_MASK;
8370 default:
8371 mask = 64'b0;
8372 }
8373 getCSRsetMask = mask;
8374} /* end getCSRsetMask */
8375
8376/*
8377* getCSRclearMask - Which bits of a CSR are "write-1-to-clear"?
8378*
8379* Parameters:
8380* csr - An indication of the CSR of interest
8381*
8382* Returned value: A bit-mask of software-modifiable clear-only CSR bits
8383*/
8384function bit[63:0] PEUTestEnv::getCSRclearMask( PEC_CSRtype csr )
8385{
8386 bit[63:0] mask;
8387
8388 case ( csr )
8389 {
8390 e_CSR_pec_int_en :
8391 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_CLEAR_MASK;
8392 e_CSR_pec_err :
8393 mask = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_CLEAR_MASK;
8394 e_CSR_ilu_int_en :
8395 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_CLEAR_MASK;
8396 e_CSR_ilu_log_en :
8397 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_CLEAR_MASK;
8398 e_CSR_ilu_en_err :
8399 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_CLEAR_MASK;
8400 e_CSR_ilu_err :
8401 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_CLEAR_MASK;
8402 e_CSR_ilu_err_diag :
8403 mask =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_CLEAR_MASK;
8404 e_CSR_ilu_diagnos :
8405 mask = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_CLEAR_MASK;
8406 e_CSR_dev_cap :
8407 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_CLEAR_MASK;
8408 e_CSR_dev_ctl :
8409 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_CLEAR_MASK;
8410 e_CSR_dev_status :
8411 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_CLEAR_MASK;
8412 e_CSR_lnk_cap :
8413 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_CLEAR_MASK;
8414 e_CSR_lnk_ctl :
8415 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_CLEAR_MASK;
8416 e_CSR_lnk_status :
8417 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_CLEAR_MASK;
8418 e_CSR_slot_cap :
8419 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_CLEAR_MASK;
8420 e_CSR_pme_ctl :
8421 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_CLEAR_MASK;
8422 e_CSR_ue_int_en :
8423 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_CLEAR_MASK;
8424 e_CSR_ue_log_en :
8425 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_CLEAR_MASK;
8426 e_CSR_ue_en_err :
8427 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_CLEAR_MASK;
8428 e_CSR_ue_err :
8429 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_CLEAR_MASK;
8430 e_CSR_ue_err_diag :
8431 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_CLEAR_MASK;
8432 e_CSR_ue_recv_hdr1 :
8433 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_CLEAR_MASK;
8434 e_CSR_ue_recv_hdr2 :
8435 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_CLEAR_MASK;
8436 e_CSR_ue_xmit_hdr1 :
8437 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_CLEAR_MASK;
8438 e_CSR_ue_xmit_hdr2 :
8439 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_CLEAR_MASK;
8440 e_CSR_ce_int_en :
8441 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_CLEAR_MASK;
8442 e_CSR_ce_log_en :
8443 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_CLEAR_MASK;
8444 e_CSR_ce_en_err :
8445 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_CLEAR_MASK;
8446 e_CSR_ce_err :
8447 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_CLEAR_MASK;
8448 e_CSR_ce_err_diag :
8449 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_CLEAR_MASK;
8450 e_CSR_oe_int_en :
8451 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_CLEAR_MASK;
8452 e_CSR_oe_log_en :
8453 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_CLEAR_MASK;
8454 e_CSR_oe_en_err :
8455 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_CLEAR_MASK;
8456 e_CSR_oe_err :
8457 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_CLEAR_MASK;
8458 e_CSR_oe_err_diag :
8459 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_CLEAR_MASK;
8460 e_CSR_oe_recv_hdr1 :
8461 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_CLEAR_MASK;
8462 e_CSR_oe_recv_hdr2 :
8463 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_CLEAR_MASK;
8464 e_CSR_oe_xmit_hdr1 :
8465 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_CLEAR_MASK;
8466 e_CSR_oe_xmit_hdr2 :
8467 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_CLEAR_MASK;
8468 e_CSR_tlu_ctl :
8469 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_CLEAR_MASK;
8470 e_CSR_tlu_stat :
8471 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_CLEAR_MASK;
8472 e_CSR_tlu_diag :
8473 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_CLEAR_MASK;
8474 e_CSR_tlu_debug_a :
8475 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_CLEAR_MASK;
8476 e_CSR_tlu_debug_b :
8477 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_CLEAR_MASK;
8478 e_CSR_ecrdt_avail :
8479 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_CLEAR_MASK;
8480 e_CSR_ecrdt_used :
8481 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_CLEAR_MASK;
8482 e_CSR_retry_crdt :
8483 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_CLEAR_MASK;
8484 e_CSR_icrdt_init :
8485 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_CLEAR_MASK;
8486 e_CSR_icrdt_avail :
8487 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_CLEAR_MASK;
8488 e_CSR_icrdt_used :
8489 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_CLEAR_MASK;
8490 e_CSR_tlu_prfc :
8491 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_CLEAR_MASK;
8492 e_CSR_tlu_prf0 :
8493 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_CLEAR_MASK;
8494 e_CSR_tlu_prf1 :
8495 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_CLEAR_MASK;
8496 e_CSR_tlu_prf2 :
8497 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_CLEAR_MASK;
8498 e_CSR_core_status :
8499 mask = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_CLEAR_MASK;
8500 default:
8501 mask = 64'b0;
8502 }
8503 getCSRclearMask = mask;
8504} /* end getCSRclearMask */
8505
8506/*
8507* getCSRinit - What is the reset value for a CSR?
8508*
8509* Parameters:
8510* csr - An indication of the CSR of interest
8511*
8512* Returned value: The (hard/soft) reset value of the CSR
8513*/
8514function bit[63:0] PEUTestEnv::getCSRinit( PEC_CSRtype csr )
8515{
8516 case ( csr )
8517 {
8518 e_CSR_pec_int_en :
8519 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_POR_VALUE;
8520 e_CSR_pec_err :
8521 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_POR_VALUE;
8522 e_CSR_ilu_int_en :
8523 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_POR_VALUE;
8524 e_CSR_ilu_log_en :
8525 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_POR_VALUE;
8526 e_CSR_ilu_en_err :
8527 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_POR_VALUE;
8528 e_CSR_ilu_err :
8529 getCSRinit =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_POR_VALUE;
8530 e_CSR_ilu_err_diag :
8531 getCSRinit =FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_POR_VALUE;
8532 e_CSR_ilu_diagnos :
8533 getCSRinit = FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_POR_VALUE;
8534 e_CSR_dev_cap :
8535 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_POR_VALUE;
8536 e_CSR_dev_ctl :
8537 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_POR_VALUE;
8538 e_CSR_dev_status :
8539 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_POR_VALUE;
8540 e_CSR_lnk_cap :
8541 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_POR_VALUE;
8542 e_CSR_lnk_ctl :
8543 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_POR_VALUE;
8544 e_CSR_lnk_status :
8545 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_POR_VALUE;
8546 e_CSR_slot_cap :
8547 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_POR_VALUE;
8548 e_CSR_pme_ctl :
8549 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_POR_VALUE;
8550 e_CSR_ue_int_en :
8551 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_POR_VALUE;
8552 e_CSR_ue_log_en :
8553 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_POR_VALUE;
8554 e_CSR_ue_en_err :
8555 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_POR_VALUE;
8556 e_CSR_ue_err :
8557 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_POR_VALUE;
8558 e_CSR_ue_err_diag :
8559 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_POR_VALUE;
8560 e_CSR_ue_recv_hdr1 :
8561 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_POR_VALUE;
8562 e_CSR_ue_recv_hdr2 :
8563 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_POR_VALUE;
8564 e_CSR_ue_xmit_hdr1 :
8565 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_POR_VALUE;
8566 e_CSR_ue_xmit_hdr2 :
8567 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_POR_VALUE;
8568 e_CSR_ce_int_en :
8569 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_POR_VALUE;
8570 e_CSR_ce_log_en :
8571 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_POR_VALUE;
8572 e_CSR_ce_en_err :
8573 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_POR_VALUE;
8574 e_CSR_ce_err :
8575 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_POR_VALUE;
8576 e_CSR_ce_err_diag :
8577 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_POR_VALUE;
8578 e_CSR_oe_int_en :
8579 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_POR_VALUE;
8580 e_CSR_oe_log_en :
8581 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_POR_VALUE;
8582 e_CSR_oe_en_err :
8583 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_POR_VALUE;
8584 e_CSR_oe_err :
8585 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_POR_VALUE;
8586 e_CSR_oe_err_diag :
8587 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_POR_VALUE;
8588 e_CSR_oe_recv_hdr1 :
8589 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_POR_VALUE;
8590 e_CSR_oe_recv_hdr2 :
8591 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_POR_VALUE;
8592 e_CSR_oe_xmit_hdr1 :
8593 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_POR_VALUE;
8594 e_CSR_oe_xmit_hdr2 :
8595 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_POR_VALUE;
8596 e_CSR_tlu_ctl :
8597 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_POR_VALUE;
8598 e_CSR_tlu_stat :
8599 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_POR_VALUE;
8600 e_CSR_tlu_diag :
8601 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_POR_VALUE;
8602 e_CSR_tlu_debug_a :
8603 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_POR_VALUE;
8604 e_CSR_tlu_debug_b :
8605 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_POR_VALUE;
8606 e_CSR_ecrdt_avail :
8607 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_POR_VALUE;
8608 e_CSR_ecrdt_used :
8609 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_POR_VALUE;
8610 e_CSR_retry_crdt :
8611 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_POR_VALUE;
8612 e_CSR_icrdt_init :
8613 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_POR_VALUE;
8614 e_CSR_icrdt_avail :
8615 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_POR_VALUE;
8616 e_CSR_icrdt_used :
8617 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_POR_VALUE;
8618 e_CSR_tlu_prfc :
8619 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_POR_VALUE;
8620 e_CSR_tlu_prf0 :
8621 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_POR_VALUE;
8622 e_CSR_tlu_prf1 :
8623 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_POR_VALUE;
8624 e_CSR_tlu_prf2 :
8625 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_POR_VALUE;
8626 e_CSR_core_status :
8627 getCSRinit = FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_POR_VALUE;
8628 default:
8629 getCSRinit = 64'b0;
8630 }
8631} /* end getCSRinit */
8632
8633/*
8634* getLPUaddr - Obtain the address of an LPU CSR given its index
8635*
8636* Parameters:
8637* csrIndex - The zero-origin index of the CSR of interest
8638*
8639* Returned value: The address of the corresponding LPU register
8640*/
8641function integer PEUTestEnv::getLPUaddr( integer csrIndex )
8642{
8643/*N2 - Since there are no LPU registers always return a -1 if this gets called
8644 getLPUaddr = FIRE_PLC_TLU_CTB_LPR_CSR_A_AHB_ADDR + 8*csrIndex;
8645*/
8646 getLPUaddr = -1;
8647} /* end getLPUaddr */
8648
8649/*
8650 * getLPUindex - Obtain the index of an LPU CSR given its address
8651 *
8652 * Parameters:
8653 * addr - The address of interest
8654 *
8655 * Returned value: The index of the corresponding LPU register, or -1
8656 */
8657function integer PEUTestEnv::getLPUindex( integer addr )
8658{
8659
8660/*N2 - Since there are no LPU registers always return a -1 if this gets called
8661 if ( addr >= FIRE_PLC_TLU_CTB_LPR_CSR_A_AHB_ADDR
8662 && ( addr < FIRE_PLC_TLU_CTB_LPR_CSR_A_AHB_ADDR
8663 + FIRE_PLC_TLU_CTB_LPR_CSR_A_AHB_DEPTH * 8 ) )
8664 {
8665 getLPUindex = (addr - FIRE_PLC_TLU_CTB_LPR_CSR_A_AHB_ADDR) / 8;
8666 }
8667 else
8668*/
8669
8670 {
8671 getLPUindex = -1;
8672 }
8673} /* end getLPUindex */
8674
8675/*
8676 * getCSR - Given a CSR address, return the corresponding CSR object
8677 *
8678 * Parameters:
8679 * addr - The address of the CSR of interest
8680 *
8681 * Returned value: The corresponding CSR, or "null"
8682 */
8683function CSRAccessor PEUTestEnv::getCSR( integer addr )
8684{
8685 CSRAccessor thisCSR;
8686 integer csrIndex;
8687 string msg;
8688
8689 case( addr & 32'hfffffff8 )
8690 {
8691 FIRE_DLC_ILU_CIB_CSR_A_PEC_INT_EN_ADDR :
8692 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_pec_int_en;
8693 FIRE_DLC_ILU_CIB_CSR_A_PEC_EN_ERR_ADDR :
8694 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_pec_en_err;
8695 FIRE_DLC_ILU_CIB_CSR_A_ILU_INT_EN_ADDR :
8696 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_int_en;
8697 FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_EN_ADDR :
8698 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_log_en;
8699 FIRE_DLC_ILU_CIB_CSR_A_ILU_EN_ERR_ADDR :
8700 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_en_err;
8701 FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1C_ALIAS_ADDR :
8702 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_log_err_rw1c_alias;
8703 FIRE_DLC_ILU_CIB_CSR_A_ILU_LOG_ERR_RW1S_ALIAS_ADDR :
8704 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_log_err_rw1s_alias;
8705 FIRE_DLC_ILU_CIB_CSR_A_ILU_DIAGNOS_ADDR :
8706 thisCSR = f_CSR.CSR.fire_dlc_ilu_cib_csr_a_ilu_diagnos;
8707 FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CAP_ADDR :
8708 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_dev_cap;
8709 FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_CTL_ADDR :
8710 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_dev_ctl;
8711 FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_ADDR :
8712 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_dev_sts;
8713 FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CAP_ADDR :
8714 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_cap;
8715 FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_ADDR :
8716 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_ctl;
8717 FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_ADDR :
8718 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_sts;
8719 FIRE_PLC_TLU_CTB_TLR_CSR_A_SLT_CAP_ADDR :
8720 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_slt_cap;
8721 FIRE_PLC_TLU_CTB_TLR_CSR_A_TRN_OFF_ADDR :
8722 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_trn_off;
8723 FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_INT_EN_ADDR :
8724 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_int_en;
8725 FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_LOG_ADDR :
8726 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_log;
8727 FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_EN_ERR_ADDR :
8728 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_en_err;
8729 FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1C_ALIAS_ADDR :
8730 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_err_rw1c_alias;
8731 FIRE_PLC_TLU_CTB_TLR_CSR_A_UE_ERR_RW1S_ALIAS_ADDR :
8732 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ue_err_rw1s_alias;
8733 FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR1_ADDR :
8734 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_rue_hdr1;
8735 FIRE_PLC_TLU_CTB_TLR_CSR_A_RUE_HDR2_ADDR :
8736 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_rue_hdr2;
8737 FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR1_ADDR :
8738 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tue_hdr1;
8739 FIRE_PLC_TLU_CTB_TLR_CSR_A_TUE_HDR2_ADDR :
8740 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tue_hdr2;
8741 FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_INT_EN_ADDR :
8742 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_int_en;
8743 FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_LOG_ADDR :
8744 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_log;
8745 FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_EN_ERR_ADDR :
8746 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_en_err;
8747 FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1C_ALIAS_ADDR :
8748 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_err_rw1c_alias;
8749 FIRE_PLC_TLU_CTB_TLR_CSR_A_CE_ERR_RW1S_ALIAS_ADDR :
8750 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_ce_err_rw1s_alias;
8751 FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_INT_EN_ADDR :
8752 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_int_en;
8753 FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_LOG_ADDR :
8754 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_log;
8755 FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_EN_ERR_ADDR :
8756 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_en_err;
8757 FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1C_ALIAS_ADDR :
8758 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_err_rw1c_alias;
8759 FIRE_PLC_TLU_CTB_TLR_CSR_A_OE_ERR_RW1S_ALIAS_ADDR :
8760 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_oe_err_rw1s_alias;
8761 FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR1_ADDR :
8762 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_roe_hdr1;
8763 FIRE_PLC_TLU_CTB_TLR_CSR_A_ROE_HDR2_ADDR :
8764 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_roe_hdr2;
8765 FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR1_ADDR :
8766 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_toe_hdr1;
8767 FIRE_PLC_TLU_CTB_TLR_CSR_A_TOE_HDR2_ADDR :
8768 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_toe_hdr2;
8769 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR :
8770 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ctl;
8771 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_ADDR :
8772 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_sts;
8773 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DIAG_ADDR :
8774 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_diag;
8775 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_A_ADDR :
8776 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_dbg_sel_a;
8777 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_DBG_SEL_B_ADDR :
8778 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_dbg_sel_b;
8779 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECL_ADDR :
8780 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ecl;
8781 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ECC_ADDR :
8782 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ecc;
8783 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ERB_ADDR :
8784 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_erb;
8785 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_ADDR :
8786 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ici;
8787 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICA_ADDR :
8788 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ica;
8789 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICR_ADDR :
8790 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_icr;
8791 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRFC_ADDR :
8792 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_prfc;
8793 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF0_ADDR :
8794 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_prf0;
8795 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF1_ADDR :
8796 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_prf1;
8797 FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_PRF2_ADDR :
8798 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_prf2;
8799 FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR :
8800 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_core_status;
8801 FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_ADDR :
8802 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_replay_timer;
8803 FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIM_THRESH_ADDR :
8804 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_replay_tim_thresh;
8805 FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_LOG_EN_ADDR :
8806 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_log_en;
8807 FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_INT_EN_ADDR :
8808 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_int_en;
8809 FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_INT_STS_ADDR :
8810 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_int_sts;
8811 FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1C_ALIAS_ADDR :
8812 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_sts_clr_rw1c_alias;
8813 FIRE_PLC_TLU_CTB_TLR_CSR_A_EVENT_ERR_STS_CLR_RW1S_ALIAS_ADDR :
8814 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_event_err_sts_clr_rw1s_alias;
8815
8816 default:
8817 {
8818 sprintf( msg, "PEUTestEnv::getCSR( integer addr=%0h ) ", addr );
8819 _REPORT_ERROR( msg );
8820 /* ahb removed from N2
8821 csrIndex = getLPUindex( addr );
8822 if ( csrIndex >= 0 )
8823 thisCSR = f_CSR.CSR.fire_plc_tlu_ctb_lpr_csr_a_ahb[csrIndex];
8824 else
8825 thisCSR = null;
8826 */
8827 }
8828 }
8829
8830 getCSR = thisCSR;
8831} /* end getCSR */
8832
8833/*
8834* readCSR - Read a ILU/TLU/LPU CSR in the normal way
8835*
8836* Parameters:
8837* addr - The address of the register of interest
8838*
8839* Returned value: The value of the specified register
8840*/
8841function bit[63:0] PEUTestEnv::readCSR( integer addr )
8842{
8843#ifndef N2_FC
8844 CSRAccessor csr;
8845
8846 csr = getCSR( addr );
8847 if ( csr == null )
8848 readCSR = 64'b0;
8849 else if ( PEC_CSR__IS_PEC_ADDR(addr) )
8850 readCSR = csr.read( FIRE_PIO_SLOW );
8851 else
8852 readCSR = csr.read( FIRE_PIO_MED );
8853#else
8854 readCSR = readCSRdirect(addr);
8855#endif
8856
8857} /* end readCSR */
8858
8859/*
8860* readCSRdirect - Read a ILU/TLU/LPU CSR directly
8861*
8862* Parameters:
8863* addr - The address of the register of interest
8864*
8865* Returned value: The value of the specified register
8866*/
8867function bit[63:0] PEUTestEnv::readCSRdirect( integer addr )
8868{
8869 CSRAccessor csr;
8870
8871 csr = getCSR( addr );
8872 if ( csr == null )
8873 readCSRdirect = 64'b0;
8874//N2 else if ( getLPUindex(addr) >= 0 )
8875//N2 readCSRdirect = lpuCsr[ getLPUindex(addr) ];
8876 else
8877 readCSRdirect = csr.read( CSRT_OMNI );
8878
8879} /* end readCSRdirect */
8880
8881/*
8882* writeCSR - Write a ILU/TLU/LPU CSR in the normal way
8883*
8884* Parameters:
8885* addr - The address of the register of interest
8886* data - The value to be written to the corresponding CSR
8887*/
8888task PEUTestEnv::writeCSR( integer addr, bit [63:0] data )
8889{
8890#ifndef N2_FC
8891 CSRAccessor csr;
8892
8893 csr = getCSR( addr );
8894 if ( csr == null )
8895 csr = null;
8896 else if ( PEC_CSR__IS_PEC_ADDR(addr) )
8897 csr.write( data, FIRE_PIO_SLOW );
8898 else
8899 csr.write( data, FIRE_PIO_MED );
8900#else
8901 writeCSRdirect (addr, data);
8902#endif
8903
8904} /* end writeCSR */
8905
8906/*
8907* writeCSRdirect - Write a ILU/TLU/LPU CSR directly (in zero simulation time)
8908*
8909* Parameters:
8910* addr - The address of the register of interest
8911* data - The value to be written to the corresponding CSR
8912*/
8913task PEUTestEnv::writeCSRdirect( integer addr, bit [63:0] data )
8914{
8915 CSRAccessor csr;
8916
8917 csr = getCSR( addr );
8918 if ( csr == null )
8919 csr = null;
8920 else if ( getLPUindex(addr) >= 0 )
8921 lpuCsr[ getLPUindex(addr) ] = data;
8922 else
8923 csr.write( data, CSRT_OMNI );
8924
8925} /* end writeCSRdirect */
8926
8927/*
8928* expectCSR - Expect a ILU/TLU/LPU CSR value by reading it
8929*
8930* Parameters:
8931* addr - The address of the register of interest
8932* data - The expected value of the corresponding CSR
8933*/
8934task PEUTestEnv::expectCSR( integer addr, bit [63:0] data )
8935{
8936 bit [63:0] actual;
8937 string msg;
8938
8939 actual = readCSR( addr );
8940 if ( actual != data )
8941 {
8942 sprintf( msg, "Incorrect CSR value (addr=%h)", addr );
8943 _REPORT_ERROR( msg );
8944 sprintf( msg, "Actual: %h", actual );
8945 _ERROR_INFO( msg );
8946 sprintf( msg, "Expect: %h", data );
8947 _ERROR_INFO( msg );
8948 }
8949} /* end expectCSR */
8950
8951/*
8952* expectCSRdirect - Expect a ILU/TLU/LPU CSR value by directly looking at it
8953*
8954* Parameters:
8955* addr - The address of the register of interest
8956* data - The expected value of the corresponding CSR
8957*/
8958task PEUTestEnv::expectCSRdirect( integer addr, bit [63:0] data )
8959{
8960 bit [63:0] actual;
8961 string msg;
8962
8963 actual = readCSRdirect( addr );
8964 if ( actual != data )
8965 {
8966 sprintf( msg, "Incorrect CSR value (addr=%h)", addr );
8967 _REPORT_ERROR( msg );
8968 sprintf( msg, "Actual: %h", actual );
8969 _ERROR_INFO( msg );
8970 sprintf( msg, "Expect: %h", data );
8971 _ERROR_INFO( msg );
8972 }
8973} /* end expectCSRdirect */
8974
8975/*
8976* setTLUdebug - Set the debug port selects for the TLU
8977*
8978* Parameters:
8979* SelA - Select for debug port "A"
8980* SelB - Select for debug port "B"
8981*/
8982task PEUTestEnv::setTLUdebug( bit[8:0] SelA, bit[8:0] SelB )
8983{
8984/* N2 review
8985 // Debug values from the LPU mimic the debug select...
8986 TLU_Control.dbga = SelA;
8987 TLU_Control.dbgb = SelB;
8988
8989 writeCSRdirect( getCSRaddr( e_CSR_tlu_debug_a ), { 55'b0, SelA } );
8990 writeCSRdirect( getCSRaddr( e_CSR_tlu_debug_b ), { 55'b0, SelB } );
8991*/
8992} /* end setTLUdebug */
8993
8994/*
8995* setILUdebug - Set the debug port selects for the ILU
8996*
8997* Parameters:
8998* SelA - Select for debug port "A"
8999* SelB - Select for debug port "B"
9000*/
9001task PEUTestEnv::setILUdebug( bit[5:0] SelA, bit[5:0] SelB )
9002{
9003//N2 review ILU_CSR.dbgSelA = SelA;
9004//N2 review ILU_CSR.dbgSelB = SelB;
9005} /* end setILUdebug */
9006
9007/*
9008* expectTLUdebug - Start looking at the TLU debug ports
9009*
9010* Parameters:
9011* A - Expected behavior of debug port "A"
9012* B - Expected behavior of debug port "B"
9013*/
9014task PEUTestEnv::expectTLUdebug( integer A[8], integer B[8] )
9015{
9016/* N2 review
9017 integer i;
9018
9019 for (i=0; i<8; i++)
9020 {
9021 tluDebugCtlA[i] = A[i];
9022 tluDebugCtlB[i] = B[i];
9023 }
9024 tluDebugA0 = ~TLU_Control.dbgA;
9025 tluDebugA1 = TLU_Control.dbgA;
9026 tluDebugB0 = ~TLU_Control.dbgB;
9027 tluDebugB1 = TLU_Control.dbgB;
9028 monitorTLUend = 0;
9029 fork
9030 monitorTLUdebug();
9031 join none
9032*/
9033} /* end expectTLUdebug */
9034
9035/*
9036 * expectILUdebug - Start looking at the ILU debug ports
9037 *
9038 * Parameters:
9039 * A - Expected behavior of debug port "A"
9040 * B - Expected behavior of debug port "B"
9041 */
9042task PEUTestEnv::expectILUdebug( integer A[8], integer B[8] )
9043{
9044} /* end expectILUdebug */
9045
9046/*
9047* endTLUdebug - Stop looking at the TLU debug ports
9048*
9049* Parameters: None
9050*
9051* NOTE: The caller is suspended into debug-port monitoring completes.
9052* (Only a cycle.)
9053*/
9054task PEUTestEnv::endTLUdebug()
9055{
9056 integer i;
9057 string errMsg;
9058
9059 monitorTLUend = 1;
9060 @( posedge CLOCK );
9061 for ( i=0; i<8; i++ )
9062 {
9063 casez( { tluDebugA1[i], tluDebugA0[i], tluDebugCtlA[i] } )
9064 {
9065 4'b1z0z: errMsg = "One occurred, but not expected";
9066 4'bz1z0: errMsg = "Zero occurred, but not expected";
9067 4'b0z1z: errMsg = "Constant zero, but not expected";
9068 4'bz0z1: errMsg = "Constant one, but not expected";
9069 default: errMsg = "";
9070 }
9071 if ( errMsg != "" )
9072 {
9073 _REPORT_ERROR( psprintf("TLU debug port-A bit-%0d: %s", i, errMsg) );
9074 }
9075 }
9076 for ( i=0; i<8; i++ )
9077 {
9078 casez( { tluDebugB1[i], tluDebugB0[i], tluDebugCtlB[i] } )
9079 {
9080 4'b1z0z: errMsg = "One occurred, but not expected";
9081 4'bz1z0: errMsg = "Zero occurred, but not expected";
9082 4'b0z1z: errMsg = "Constant zero, but not expected";
9083 4'bz0z1: errMsg = "Constant one, but not expected";
9084 default: errMsg = "";
9085 }
9086 if ( errMsg != "" )
9087 {
9088 _REPORT_ERROR( psprintf("TLU debug port-B bit-%0d: %s", i, errMsg) );
9089 }
9090 }
9091} /* end endTLUdebug */
9092
9093/*
9094 * endILUdebug - Stop looking at the ILU debug ports
9095 *
9096 * Parameters: None
9097 */
9098task PEUTestEnv::endILUdebug()
9099{
9100} /* end endILUdebug */
9101
9102/*
9103 * monitorTLUdebug - A thread which monitors the TLU's debug results
9104 *
9105 * NOTE: The thread ends when "monitorTLUend" is true
9106 */
9107task PEUTestEnv::monitorTLUdebug()
9108{
9109/* N2
9110 fork
9111 while( !monitorTLUend ) @(posedge CLOCK);
9112 while( !monitorTLUend )
9113 {
9114 @( TLU_Control.dbgA );
9115 tluDebugA0 = tluDebugA0 | ~TLU_Control.dbgA;
9116 tluDebugA1 = tluDebugA1 | TLU_Control.dbgA;
9117 }
9118 while( !monitorTLUend )
9119 {
9120 @( TLU_Control.dbgB );
9121 tluDebugB0 = tluDebugB0 | ~TLU_Control.dbgB;
9122 tluDebugB1 = tluDebugB1 | TLU_Control.dbgB;
9123 }
9124 join any
9125 terminate;
9126*/
9127}
9128
9129/*
9130 * monitorILUdebug - A thread which monitors the ILU's debug results
9131 *
9132 * NOTE: The thread ends when "monitorILUend" is true
9133 */
9134task PEUTestEnv::monitorILUdebug()
9135{
9136/* N2 review
9137 fork
9138 while( !monitorILUend ) @(posedge CLOCK);
9139 while( !monitorILUend )
9140 {
9141 @( ILU_CSR.dbgA );
9142 iluDebugA0 = iluDebugA0 | ~ILU_CSR.dbgA;
9143 iluDebugA1 = iluDebugA1 | ILU_CSR.dbgA;
9144 }
9145 while( !monitorILUend )
9146 {
9147 @( ILU_CSR.dbgB );
9148 iluDebugB0 = iluDebugB0 | ~ILU_CSR.dbgB;
9149 iluDebugB1 = iluDebugB1 | ILU_CSR.dbgB;
9150 }
9151 join any
9152 terminate;
9153*/
9154}
9155
9156/*
9157* setIngressLatency - Set the number of cycles for a TLP to pass from TLU to ILU
9158*
9159* Parameters:
9160* Latency - The number of clocks for... you guessed it
9161*/
9162task PEUTestEnv::setIngressLatency( integer Latency ) {
9163
9164 ingressLatency = Latency;
9165}
9166
9167
9168
9169/*
9170 * setEgressLatency - Set the number of cycles for a TLP to pass from ILU to TLU
9171 *
9172 * Parameters:
9173 * Latency - The number of clocks for... you guessed it
9174 */
9175task PEUTestEnv::setEgressLatency( integer Latency ) {
9176
9177 egressLatency = Latency;
9178}
9179
9180
9181
9182/*
9183* getIngressLatency - Get the amount of time it should take for a TLP
9184* to pass from the TLU to ILU.
9185*
9186* Parameters:
9187* PktHdr - The TLP's header
9188*/
9189function integer PEUTestEnv::getIngressLatency( bit[127:0] PktHdr,
9190 (integer ExtraPayload=0) ) {
9191
9192 getIngressLatency = ingressLatency; // User supplied latency.
9193
9194 if ( (^PktHdr[PEC_PCI__LEN]) !== 1'b_x || ExtraPayload != 0 ) {
9195
9196 if ( PktHdr[PEC_PCI__LEN] ) // Need to deliver payload
9197 getIngressLatency += PktHdr[PEC_PCI__LEN]/(ingressDataWidth/4)
9198 + ExtraPayload;
9199 else if ( PktHdr[PEC_PCI__LEN] == 0 )
9200 getIngressLatency += 4096/ingressDataWidth + ExtraPayload;
9201 else
9202 getIngressLatency += ExtraPayload;
9203 getIngressLatency += 2; // Add a fudge factor
9204
9205 getIngressLatency *= 10000; // Compensate for cycles in
9206 getIngressLatency /= (10000 - 100*ingressThrottle + 1); // which idle is driven to TLU.
9207 }
9208}
9209
9210/*
9211 * getEgressLatency - Get the amount of time it should take for a TLP
9212 * to pass from the ILU to TLU.
9213 *
9214 * Parameters:
9215 * PktHdr - The TLP's header
9216 */
9217function integer PEUTestEnv::getEgressLatency( bit [127:0] PktHdr ) {
9218
9219 getEgressLatency = egressLatency; // User supplied latency.
9220
9221 if ( (^PktHdr[PEC_PCI__LEN]) !== 1'b_x) {
9222
9223 getEgressLatency += PktHdr[PEC_PCI__LEN]/(egressDataWidth/4);
9224 getEgressLatency += 2; // Add a fudge factor
9225
9226 getEgressLatency *= 10000; // Compensate for cycles in
9227 getEgressLatency /= (10000 - 100*egressThrottle + 1); // which dack is asserted.
9228 }
9229}
9230
9231
9232
9233/*
9234* waitIngressLatency - Wait for a TLP to pass from TLU to ILU
9235*
9236* Parameters:
9237* PktHdr - The TLP's header
9238*
9239* NOTE: We aren't guaranteeing that the TLP has actually come out of the
9240* ILU... just that the header should have been presented by the ILU if
9241* the ingress pipeline was otherwise empty
9242*/
9243task PEUTestEnv::waitIngressLatency( bit[127:0] PktHdr,
9244 (integer ExtraPayload=0) ) {
9245
9246 // We should wait for the TLP to be fed into the TLU, but we're lazy...
9247 repeat( this.getIngressLatency(PktHdr,ExtraPayload) ) @(posedge CLOCK);
9248}
9249
9250
9251
9252/*
9253* waitEgressLatency - Wait for a TLP to pass from ILU to TLU
9254*
9255* Parameters:
9256* PktHdr - The TLP's header
9257*
9258* NOTE: We aren't guaranteeing that the TLP has actually come out of the
9259* TLU... just that the header should have been presented by the TLU if
9260* the ingress pipeline was otherwise empty
9261*/
9262task PEUTestEnv::waitEgressLatency( bit[127:0] PktHdr ) {
9263
9264 // We should wait for the TLP to be fed into the ILU, but we're lazy...
9265 repeat( this.getEgressLatency(PktHdr) ) @(posedge CLOCK);
9266}
9267
9268
9269
9270/*
9271* waitEgressPipeFull - Wait for the Egress Pipeline to be full
9272*
9273* Parameters: None
9274*/
9275task PEUTestEnv::waitEgressPipeFull() {
9276
9277
9278#ifndef N2_FC
9279 bit [127:0] PktHdr;
9280 integer latency;
9281 integer peuPktRcvd;
9282 integer cycle;
9283
9284
9285 // Generate a packet header with max length. Use the header to get the
9286 // max egress latency.
9287 PktHdr[PEC_PCI__LEN] = this.getMaxPayloadSize() / 4;
9288 latency = this.getEgressLatency(PktHdr);
9289
9290
9291 // Grab the current number of packets received by the TLU.
9292 peuPktRcvd = this.peuExpectComplete;
9293
9294
9295 // Need to have a number of cycles of fullness to advance.
9296 for (cycle = 0; cycle < latency; cycle++) {
9297
9298
9299 // If there are egress credits available, restart the counter.
9300 if (f_DMUXtr.egressCreditsAvailable() != 0)
9301 cycle = 0;
9302
9303 // If more packets have been received by the TLU, restart the counter.
9304 if (peuPktRcvd != this.peuExpectComplete)
9305 cycle = 0;
9306
9307 // Grab the current number of packets received by the TLU.
9308 peuPktRcvd = this.peuExpectComplete;
9309
9310 // Advance the clock a cycle.
9311 @(posedge CLOCK);
9312 }
9313
9314 // Egress Pipe Is Full!!
9315#endif
9316}
9317
9318/*
9319* expectEgressParityError - Expect a one-time parity error on the TLU->LPU
9320* interface, returning after the error has occurred
9321*
9322* Parameters:
9323* ErrMask - Which "t2l_etp_dpar" bits do we expect to be in error?
9324*/
9325task PEUTestEnv::expectEgressParityError( bit[15:0] ErrMask )
9326 {
9327/* N2 review
9328 TLU_Control.etperr = ErrMask;
9329 @( TLU_Control.etperrack );
9330 TLU_Control.etperr = 16'b0;
9331*/
9332 } /* end expectEgressParityError */
9333
9334/*
9335 * monitorStatusCSRs - Continually read the TLU's credit status registers.
9336 * If things don't look right, then scream and yell.
9337 *
9338 * Parameters:
9339 * IngressCredits - Should we worry about ingress credits as we go?
9340 */
9341task PEUTestEnv::monitorStatusCSRs( bit ingressCredits )
9342{
9343 bit [7:0] hdrCredit;
9344 bit [11:0] dataCredit;
9345 integer envNpstHdr;
9346 integer envPostHdr;
9347 integer envPostData;
9348 string msg;
9349
9350 IngressCredits = ingressCredits;
9351
9352 repeat(10) @(posedge CLOCK);
9353 while( !softResetPending )
9354 {
9355 sync( ANY, ev_CSRupdateReq );
9356 if ( softResetPending ) break;
9357 if( drainStateSignaled ){ IngressCredits = 0;
9358 }
9359
9360 // The order is important...
9361 // Read the TLU's idea of how many
9362 // credits have been used...
9363 ingressCreditUsedCSR = readCSR( getCSRaddr( e_CSR_icrdt_used ) );
9364 if ( softResetPending ) break;
9365 if( drainStateSignaled ){ IngressCredits = 0;
9366 }
9367
9368 // ...then determine how many credits
9369 // we think are available...
9370 envNpstHdr = ingressNonpostHdrAvail - ingressNonpostHdrConsumed;
9371// Since Denali is allowed to control Ingress packets it could have
9372// many Q'd transactions with Reserved credits
9373// - ingressNonpostHdrRsvd;
9374 envPostHdr = ingressPostHdrAvail - ingressPostHdrConsumed;
9375// - ingressPostHdrRsvd;
9376 envPostData = ingressPostDataAvail - ingressPostDataConsumed;
9377// - ingressPostDataRsvd;
9378
9379 // ...and finally the number of credits
9380 // that the TLU has given us (total).
9381 ingressCreditAvailCSR = readCSR( getCSRaddr( e_CSR_icrdt_avail ) );
9382 if ( softResetPending ) break;
9383 if( drainStateSignaled ){ IngressCredits = 0;
9384 }
9385
9386 // Check non-posted header credits...
9387 hdrCredit = ingressCreditAvailCSR[39:32] - ingressCreditUsedCSR[39:32];
9388 if ( IngressCredits && hdrCredit < envNpstHdr )
9389 {
9390 _REPORT_ERROR( "Ingress non-posted header credits are out of sync!?!" );
9391 sprintf( msg, "TLU avail = %h env = %3h TLU used = %h",
9392 ingressCreditAvailCSR[39:32], envNpstHdr,
9393 ingressCreditUsedCSR[39:32] );
9394 _ERROR_INFO( msg );
9395 dumpCreditStatus();
9396 }
9397
9398 // Check posted header credits...
9399 hdrCredit = ingressCreditAvailCSR[19:12] - ingressCreditUsedCSR[19:12];
9400 if ( IngressCredits && hdrCredit < envPostHdr )
9401 {
9402 _REPORT_ERROR( "Ingress posted header credits are out of sync!?!" );
9403 sprintf( msg, "TLU avail = %h env = %3h TLU used = %h",
9404 ingressCreditAvailCSR[19:12], envPostHdr,
9405 ingressCreditUsedCSR[19:12] );
9406 _ERROR_INFO( msg );
9407 dumpCreditStatus();
9408 }
9409
9410 // Check posted data credits...
9411 dataCredit = ingressCreditAvailCSR[11:0] - ingressCreditUsedCSR[11:0];
9412 if ( IngressCredits && dataCredit < envPostData )
9413 {
9414 _REPORT_ERROR( "Ingress posted data credits are out of sync!?!" );
9415 sprintf( msg, "TLU avail = %h env = %3h TLU used = %h",
9416 ingressCreditAvailCSR[11:0], envPostData,
9417 ingressCreditUsedCSR[11:0] );
9418 _ERROR_INFO( msg );
9419 dumpCreditStatus();
9420 }
9421
9422 // We aren't doing anything with the
9423 // egress credits yet...
9424 egressCreditAvailCSR = readCSR( getCSRaddr( e_CSR_ecrdt_avail ) );
9425 if ( softResetPending ) break;
9426
9427 egressCreditUsedCSR = readCSR( getCSRaddr( e_CSR_ecrdt_used ) );
9428 if ( softResetPending ) break;
9429
9430 egressRetryCSR = readCSR( getCSRaddr( e_CSR_retry_crdt ) );
9431 if ( softResetPending ) break;
9432
9433 // Get the "transactions pending" bit from the TLU device status register
9434 rsbEmpty = !( readCSR( getCSRaddr( e_CSR_dev_status ) )
9435 & FIRE_PLC_TLU_CTB_TLR_CSR_A_DEV_STS_TP_FMASK );
9436
9437 // If anyone was waiting, then tell them
9438 // that we've updated our vision of the
9439 // device's status
9440 trigger( ONE_SHOT, ev_CSRupdateComplete );
9441 }
9442 trigger( ONE_SHOT, ev_CSRupdateComplete );
9443} /* end monitorStatusCSRs */
9444
9445/*
9446 * dumpCreditStatus - Dump the environment's idea of what's going on and
9447 * the TLU's idea of how many credits it has.
9448 */
9449task PEUTestEnv::dumpCreditStatus()
9450{
9451 printf( "Environment ingress credit status...\n" );
9452 printf( " npstHdr avail/rsvd/consumed = %6d (%2h) %3d %6d (%2h)\n",
9453 ingressNonpostHdrAvail, ingressNonpostHdrAvail % 256,
9454 ingressNonpostHdrRsvd,
9455 ingressNonpostHdrConsumed, ingressNonpostHdrConsumed % 256 );
9456 printf( " postHdr avail/rsvd/consumed = %6d (%2h) %3d %6d (%2h)\n",
9457 ingressPostHdrAvail, ingressPostHdrAvail % 256,
9458 ingressPostHdrRsvd,
9459 ingressPostHdrConsumed, ingressPostHdrConsumed % 256 );
9460 printf( " postData avail/rsvd/consumed = %6d (%3h) %3d %6d (%3h)\n",
9461 ingressPostDataAvail, ingressPostDataAvail % 4096,
9462 ingressPostDataRsvd,
9463 ingressPostDataConsumed, ingressPostDataConsumed % 4096 );
9464
9465 printf( "TLU ingress credit status...\n" );
9466 printf( " npstHdr avail / consumed = %2h %2h\n",
9467 ingressCreditAvailCSR[39:32], ingressCreditUsedCSR[39:32] );
9468 printf( " postHdr avail / consumed = %2h %2h\n",
9469 ingressCreditAvailCSR[19:12], ingressCreditUsedCSR[19:12] );
9470 printf( " postData avail / consumed = %3h %3h\n",
9471 ingressCreditAvailCSR[11:0], ingressCreditUsedCSR[11:0] );
9472
9473 printf( "Environment egress credit status...\n" );
9474 printf( " cplnHdr avail / consumed = %6d (%2h) %6d (%2h)\n",
9475 egressCompletionHdrAvail, egressCompletionHdrAvail % 256,
9476 egressCompletionHdrConsumed, egressCompletionHdrConsumed % 256 );
9477 printf( " cplnData avail / consumed = %6d (%3h) %6d (%3h)\n",
9478 egressCompletionDataAvail, egressCompletionDataAvail % 4096,
9479 egressCompletionDataConsumed, egressCompletionDataConsumed % 4096 );
9480 printf( " npstHdr avail / consumed = %6d (%2h) %6d (%2h)\n",
9481 egressNonpostHdrAvail, egressNonpostHdrAvail % 256,
9482 egressNonpostHdrConsumed, egressNonpostHdrConsumed % 256 );
9483 printf( " npstData avail / consumed = %6d (%3h) %6d (%3h)\n",
9484 egressNonpostDataAvail, egressNonpostDataAvail % 4096,
9485 egressNonpostDataConsumed, egressNonpostDataConsumed % 4096 );
9486 printf( " postHdr avail / consumed = %6d (%2h) %6d (%2h)\n",
9487 egressPostHdrAvail, egressPostHdrAvail % 256,
9488 egressPostHdrConsumed, egressPostHdrConsumed % 256 );
9489 printf( " postData avail / consumed = %6d (%3h) %6d (%3h)\n",
9490 egressPostDataAvail, egressPostDataAvail % 4096,
9491 egressPostDataConsumed, egressPostDataConsumed % 4096 );
9492 printf( " retry avail / consumed = %6d (%4h) %6d (%4h)\n",
9493 egressRetryAvail, egressRetryAvail % 65536,
9494 egressRetryConsumed, egressRetryConsumed % 65536 );
9495
9496 printf( "TLU egress credit status...\n" );
9497 printf( " cplnHdr avail / consumed = %2h %2h\n",
9498 egressCreditAvailCSR[59:52], egressCreditUsedCSR[59:52] );
9499 printf( " cplnData avail / consumed = %3h %3h\n",
9500 egressCreditAvailCSR[51:40], egressCreditUsedCSR[51:40] );
9501 printf( " npstHdr avail / consumed = %2h %2h\n",
9502 egressCreditAvailCSR[39:32], egressCreditUsedCSR[39:32] );
9503 printf( " npstData avail / consumed = %3h %3h\n",
9504 egressCreditAvailCSR[31:20], egressCreditUsedCSR[31:20] );
9505 printf( " postHdr avail / consumed = %2h %2h\n",
9506 egressCreditAvailCSR[19:12], egressCreditUsedCSR[19:12] );
9507 printf( " postData avail / consumed = %3h %3h\n",
9508 egressCreditAvailCSR[11:0], egressCreditUsedCSR[11:0] );
9509 printf( " retry avail / consumed = %4h %4h\n",
9510 egressRetryCSR[15:0], egressRetryCSR[47:32] );
9511
9512} /* end dumpCreditStatus */
9513
9514/*
9515 * monitorCplMailbox - Watch the mailbox connected to the DMU-transactor and
9516 * make sure that any CPL not expected by the transactor is
9517 * expected by us
9518 *
9519 * Parameters: None
9520 */
9521task PEUTestEnv::monitorCplMailbox()
9522{
9523#ifndef N2_FC
9524 bit[127:0] cplHdr;
9525 bit[7:0] tag;
9526 string msg;
9527 integer i;
9528
9529 while( 1 )
9530 {
9531 mailbox_get( WAIT, mb_unexpectedCpls, cplHdr );
9532 activityCounter = activityCounter + 1;
9533
9534 // Get the tag for the original
9535 // nonposted PIO request.
9536 tag = cplHdr[PEC_PCI__CPL_TAG];
9537
9538 // If the tag does not correspond to
9539 // a pending request, then OOPS!
9540 if ( !nonpostReqPending[tag] )
9541 {
9542 _REPORT_ERROR( "Completion forwarded from DMUXtr is truly unexpected" );
9543 sprintf( msg, "ReqID=%h CplID=%h Tag=%h Status=%h",
9544 cplHdr[PEC_PCI__CPL_ID], cplHdr[PEC_PCI__CPL_REQ_ID],
9545 cplHdr[PEC_PCI__CPL_TAG], cplHdr[PEC_PCI__CPL_STATUS] );
9546 _ERROR_INFO( msg );
9547 }
9548
9549 // Otherwise, if we got a time-out
9550 // completion, make sure that it was
9551 // expected.
9552 else if ( cplHdr[PEC_PCI__CPL_STATUS] == PEC_PCI__CPL_STATUS_TIMEOUT )
9553 {
9554 if ( !nonpostReqTimeout[tag] )
9555 {
9556 _REPORT_ERROR( "Time-out completion from DMUXtr is unexpected" );
9557 sprintf( msg, "ReqID=%h CplID=%h Tag=%h Status=%h",
9558 cplHdr[PEC_PCI__CPL_ID], cplHdr[PEC_PCI__CPL_REQ_ID],
9559 cplHdr[PEC_PCI__CPL_TAG], cplHdr[PEC_PCI__CPL_STATUS] );
9560 _ERROR_INFO( msg );
9561 }
9562 nonpostReqTimeout[tag] = 1'b0;
9563 nonpostReqPending[tag] = 1'b0;
9564 trigger( ON, nonpostReqComplete[tag] );
9565 }
9566
9567 // Otherwise, if we got a UR completion,
9568 // we had better be in the drain state.
9569 else if ( cplHdr[PEC_PCI__CPL_STATUS] == PEC_PCI__CPL_STATUS_UR )
9570 {
9571 if ( !drainState )
9572 {
9573 _REPORT_ERROR( "UR completion from DMUXtr is unexpected" );
9574 sprintf( msg, "ReqID=%h CplID=%h Tag=%h Status=%h",
9575 cplHdr[PEC_PCI__CPL_ID], cplHdr[PEC_PCI__CPL_REQ_ID],
9576 cplHdr[PEC_PCI__CPL_TAG], cplHdr[PEC_PCI__CPL_STATUS] );
9577 }
9578
9579 // In response to the completion, we
9580 // have to somehow free the tag.
9581 // We'll do this by aborting the
9582 // "expectTLU" (if the request hasn't
9583 // been dispatched) and then forcing
9584 // every non-error "expectILU" CPL'n
9585 // to return immediately.
9586 else
9587 {
9588 if ( !drainStateActive )
9589 {
9590 _INFO_MSG( "ILU is now in the 'drain state'... " );
9591 plugEgressPipeline();
9592fork
9593{
9594//Delay for 4 PCI clocks and then check ilu.iil.xfrsfm.ihb_empty before clearing DMUXtr
9595repeat( 100 ) @(posedge CLOCK ); //N2 review
9596 f_DMUXtr.clear(0);
9597}
9598join none
9599 }
9600 // if ( nonpostReqInLimbo[tag] ) freePioTag(tag);
9601 // nonpostReqInLimbo[tag] = 1'b0;
9602 drainStateActive = 1;
9603 }
9604 printf("PEUTestEnv UR completion from DMUXtr drainState=%0d drainStateActive=%0d tag=%h \n",drainState,drainStateActive,tag);
9605 nonpostReqTimeout[tag] = 1'b0;
9606 nonpostReqPending[tag] = 1'b0;
9607 trigger( ON, nonpostReqComplete[tag] );
9608 }
9609
9610 // Otherwise, the ILU has sent us a
9611 // bizarre completion status
9612 else
9613 {
9614 _REPORT_ERROR( "Completion from DMUXtr has unexpected status" );
9615 sprintf( msg, "ReqID=%h CplID=%h Tag=%h Status=%h",
9616 cplHdr[PEC_PCI__CPL_ID], cplHdr[PEC_PCI__CPL_REQ_ID],
9617 cplHdr[PEC_PCI__CPL_TAG], cplHdr[PEC_PCI__CPL_STATUS] );
9618 nonpostReqTimeout[tag] = 1'b0;
9619 nonpostReqPending[tag] = 1'b0;
9620 }
9621 }
9622#endif
9623} /* end monitorCplMailbox */
9624
9625/*
9626* injectEHBerror - Inject a parity error into the egress header buffer
9627*
9628* Parameters:
9629* TlpTag - The tag of the target TLP header to receive the parity error
9630* ErrMask - Which "dpar" bits are to be polluted?
9631*
9632* NOTE: Injecting an EHB parity error will cause the DUT to enter the "drain
9633* state". Call "enterDrainState" after supplying the target TLP to the
9634* ILU.
9635* NOTE: This procedure returns immediately.
9636*/
9637task PEUTestEnv::injectEHBerror( bit[7:0] TlpTag, bit[3:0] ErrMask )
9638{
9639 string msg;
9640
9641 // Can't be injectin two errurs at once!
9642 if ( EHB.errAck != ehbErrorReq )
9643 _REPORT_ERROR( "'injectEHBerror' called while another error is pending!" );
9644
9645 // Tell the top-level VERILOG to flip
9646 // some parity bits when the target TLP
9647 // is written to the EHB.
9648 else
9649 {
9650 sprintf( msg, "Inject EHB error: mask='b%b tag='h%h", ErrMask, TlpTag );
9651 _INFO_MSG(msg);
9652 ehbErrorReq = !ehbErrorReq;
9653 EHB.errReq <= ehbErrorReq;
9654 EHB.errTag <= TlpTag;
9655 EHB.errSel <= ErrMask;
9656 }
9657} /* end injectEHBerror */
9658
9659/*
9660* injectIHBerror - Inject a parity error into the ingress header buffer
9661*
9662* Parameters:
9663* TlpTag - The tag of the target TLP header to receive the parity error
9664* ErrMask - Which "dpar" bits are to be polluted?
9665*
9666* NOTE: Injecting an IHB parity error will cause the DUT to enter the "drain
9667* state". Call "enterDrainState" after supplying the target TLP to the
9668* TLU.
9669* NOTE: This procedure returns immediately.
9670*/
9671task PEUTestEnv::injectIHBerror( bit[7:0] TlpTag, bit[3:0] ErrMask )
9672{
9673 string msg;
9674
9675 // Can't be injectin two errurs at once!
9676 if ( IHB.errAck != ihbErrorReq )
9677 _REPORT_ERROR( "'injectIHBerror' called while another error is pending!" );
9678
9679 // Tell the top-level VERILOG to flip
9680 // some parity bits when the target TLP
9681 // is written to the EHB.
9682 else
9683 {
9684 sprintf( msg, "Inject IHB error: mask='b%b tag='h%h", ErrMask, TlpTag );
9685 _INFO_MSG(msg);
9686 ihbErrorReq = !ihbErrorReq;
9687 IHB.errReq <= ihbErrorReq;
9688 IHB.errTag <= TlpTag;
9689 IHB.errSel <= ErrMask;
9690 }
9691} /* end injectIHBerror */
9692
9693/*
9694* enterDrainState - We're goin' down! Man the life-craft!
9695* Pending non-posted PIO requests can be completed by a
9696* "UR" request from the ILU.
9697*
9698* Parameters:
9699* TlpHdr - The optional header from the TLP which caused the problem.
9700*/
9701task PEUTestEnv::enterDrainState( (bit[127:0] TlpHdr = 128'bx) )
9702{
9703 integer tag;
9704 // Setting "drainState" means that it's
9705 // OK to get a UR completion from the
9706 // ILU. We'll set "drainStateActive"
9707 // when we get that first completion.
9708 drainState = 1;
9709 drainStateActive = 0;
9710 _INFO_MSG( "Entering 'drain state'" );
9711
9712 // A pending non-posted request is in
9713 // limbo if it's in between the ILU and
9714 // TLU as we enter the drain state.
9715 for ( tag=0; tag<32; tag++ )
9716 nonpostReqInLimbo[tag] = nonpostReqPending[tag] && !nonpostReqDispatch[tag];
9717} /* end enterDrainState */
9718
9719/*
9720* waitDrainState - Wait for the TLU to report a drain-state error to the ILU
9721*
9722* Parameters: None
9723*/
9724task PEUTestEnv::waitDrainState()
9725{
9726 //N2 review - Do we need a timeout here?
9727 if ( !Pod.DMUXtr.miscPort.$drain ) @(Pod.DMUXtr.miscPort.$drain);
9728 drainStateSignaled = 1; //Used to turn off Ingress credit checking
9729 _INFO_MSG( "Env::waitDrainState() 'drain state entered'" );
9730} /* end waitDrainState */
9731
9732/*
9733* setLPUerror - Set an LPU error indicator for one cycle
9734*
9735* Parameters:
9736* LpuErr - The error to be presented to the TLU
9737*/
9738task PEUTestEnv::setLPUerror( PEC_ERRtype LpuErr )
9739{
9740/*N2 review
9741 integer bitIndex;
9742
9743 if ( !PEC_ERR_isLPU(LpuErr) ) return;
9744
9745 bitIndex = PEC_ERR_LPUpos(LpuErr);
9746 if ( bitIndex < 0 )
9747 {
9748 if ( LpuErr == e_ERR_oe_lin )
9749 TLU_Control.int <= 1;
9750 if ( LpuErr == e_ERR_oe_lrs )
9751 TLU_Control.reset <= 1;
9752 }
9753 else if ( PEC_ERR_isUE(LpuErr) )
9754 TLU_Control.ue[bitIndex] <= 1;
9755 else if ( PEC_ERR_isCE(LpuErr) )
9756 TLU_Control.ce[bitIndex] <= 1;
9757 else if ( PEC_ERR_isOE(LpuErr) )
9758 TLU_Control.oe[bitIndex] <= 1;
9759*/
9760} // end setLPUerror
9761
9762/*
9763* setErrorLogEnable - Set the error log enable bit for a particular error
9764*
9765* Parameters:
9766* Err - The error of interest
9767* LogEnab - The log-enable bit for that error
9768*/
9769task PEUTestEnv::setErrorLogEnable( PEC_ERRtype Err, bit LogEnab )
9770{
9771 integer indx;
9772 integer addr;
9773 bit [63:0] csr;
9774
9775 case ( 1 ) {
9776 PEC_ERR_isUE(Err) : addr = getCSRaddr( e_CSR_ue_log_en );
9777 PEC_ERR_isCE(Err) : addr = getCSRaddr( e_CSR_ce_log_en );
9778 PEC_ERR_isOE(Err) : addr = getCSRaddr( e_CSR_oe_log_en );
9779 PEC_ERR_isILU(Err) : addr = getCSRaddr( e_CSR_ilu_log_en );
9780 PEC_ERR_isDLPL(Err): addr = getCSRaddr( e_CSR_dlpl_ee_log_en );
9781 default : addr = 0;
9782 }
9783
9784 if ( addr != 0 )
9785 {
9786 csr = readCSRdirect( addr );
9787 indx = PEC_ERR_bitIndex( Err );
9788 csr[indx] = LogEnab;
9789 writeCSR( addr, csr );
9790 }
9791} /* end setErrorLogEnable */
9792
9793/*
9794* setErrorIntEnable - Set the primary and secondary interrupt-enables for
9795* a particular error
9796*
9797* Parameters:
9798* Err - The error of interest
9799* Primary - The primary interrupt enable
9800* Secondary - The secondary interrupt enable
9801*
9802* NOTE: If the "Secondary" enable is "1", then the "Primary" must be "1" also.
9803*/
9804task PEUTestEnv::setErrorIntEnable(PEC_ERRtype Err, bit Primary, bit Secondary)
9805{
9806 integer indx;
9807 integer addr;
9808 bit [63:0] csr;
9809
9810 case ( 1 ) {
9811 PEC_ERR_isUE(Err) : addr = getCSRaddr( e_CSR_ue_int_en );
9812 PEC_ERR_isCE(Err) : addr = getCSRaddr( e_CSR_ce_int_en );
9813 PEC_ERR_isOE(Err) : addr = getCSRaddr( e_CSR_oe_int_en );
9814 PEC_ERR_isILU(Err) : addr = getCSRaddr( e_CSR_ilu_int_en );
9815 PEC_ERR_isDLPL(Err): addr = getCSRaddr( e_CSR_dlpl_ee_int_en );
9816 default : addr = 0;
9817 }
9818
9819 if ( addr != 0 )
9820 {
9821 csr = readCSRdirect( addr );
9822 indx = PEC_ERR_bitIndex( Err );
9823 csr[indx] = Primary;
9824 csr[indx + 32] = Secondary;
9825 writeCSRdirect( addr, csr );
9826 }
9827} /* end setErrorIntEnable */
9828
9829/*
9830* expectError - Expect primary and/or secondary error-log bits to be set/clear
9831* for a particular error
9832*
9833* Parameters:
9834* Err - The error of interest
9835* Primary - The expected primary log bit
9836* Secondary - The expected secondary log bit
9837*
9838* NOTE: The error logs are cleared by this task
9839*/
9840task PEUTestEnv::expectError(PEC_ERRtype Err, bit Primary, bit Secondary)
9841{
9842#ifndef N2_FC
9843 // UD : this part is temp...
9844 // just need to get Linkn training to work... also check if this reg has OMNI access
9845 //
9846 integer indx;
9847 integer addr;
9848 bit [63:0] csr;
9849 string msg;
9850
9851 case ( 1 ) {
9852 PEC_ERR_isUE(Err) : addr = getCSRaddr( e_CSR_ue_err );
9853 PEC_ERR_isCE(Err) : addr = getCSRaddr( e_CSR_ce_err );
9854 PEC_ERR_isOE(Err) : addr = getCSRaddr( e_CSR_oe_err );
9855 PEC_ERR_isILU(Err) : addr = getCSRaddr( e_CSR_ilu_err );
9856 PEC_ERR_isDLPL(Err): addr = getCSRaddr( e_CSR_dlpl_ee_err );
9857 default : addr = 0;
9858 }
9859
9860 if ( addr != 0 )
9861 {
9862 csr = readCSRdirect( addr );
9863 indx = PEC_ERR_bitIndex( Err );
9864 if ( (csr[indx] != Primary && Primary !== 1'bx)
9865 || (csr[indx + 32] != Secondary && Secondary !== 1'bx) )
9866 {
9867 dumpIntStatus();
9868 _REPORT_ERROR( "Incorrect error-log bit-values" );
9869 sprintf( msg, " Actual: %b", csr );
9870 _ERROR_INFO( msg );
9871 csr[indx] = Primary;
9872 csr[indx+32] = Secondary;
9873 sprintf( msg, " Expect: %b", csr );
9874 _ERROR_INFO( msg );
9875 csr = 64'bx;
9876 csr[indx] = 1'b1;
9877 csr[indx+32] = 1'b1;
9878 sprintf( msg, " Mask: %b", csr );
9879 _ERROR_INFO( msg );
9880 }
9881 csr = 64'b0;
9882 csr[indx] = 1'b1;
9883 csr[indx+32] = 1'b1;
9884#ifdef N2_IOS
9885 writeCSRdirect (addr, csr);
9886#else
9887 writeCSR( addr, csr );
9888#endif
9889 }
9890#endif
9891} /* end expectError */
9892
9893/*
9894* enableOptionalCheck - (Re)enable optional error checking
9895*
9896* Parameter:
9897* OptCheck - A string describing the optional check, default is "all"
9898*/
9899task PEUTestEnv::enableOptionalCheck( (string OptCheck = "all") )
9900 {
9901 bit [31:0] diagAddr;
9902 bit [63:0] diagCsr;
9903
9904 diagAddr = getCSRaddr( e_CSR_tlu_diag );
9905 diagCsr = readCSR( diagAddr );
9906
9907 if ( OptCheck == "all" )
9908 diagCsr[47:32] = diagCsr[47:32] & ~(16'h1f73);
9909 if ( OptCheck == "DWBE" )
9910 diagCsr[36] = 1'b0;
9911 if ( OptCheck == "cross 4KB" )
9912 diagCsr[37] = 1'b0;
9913 if ( OptCheck == "receiver overflow" )
9914 diagCsr[38] = 1'b0;
9915 if ( OptCheck == "NonConfigCRS" )
9916 diagCsr[40] = 1'b0;
9917 if ( OptCheck == "completion TC" )
9918 diagCsr[41] = 1'b0;
9919 if ( OptCheck == "completion attr" )
9920 diagCsr[42] = 1'b0;
9921 if ( OptCheck == "completion count" )
9922 diagCsr[43] = 1'b0;
9923 if ( OptCheck == "completion address" )
9924 diagCsr[44] = 1'b0;
9925
9926 writeCSR( diagAddr, diagCsr );
9927 } /* end enableOptionalCheck */
9928
9929/*
9930* disableOptionalCheck - Disable optional error checking
9931*
9932* Parameter:
9933* OptCheck - A string describing the optional check, default is "all"
9934*/
9935task PEUTestEnv::disableOptionalCheck( (string OptCheck = "all") )
9936 {
9937 bit [31:0] diagAddr;
9938 bit [63:0] diagCsr;
9939
9940 diagAddr = getCSRaddr( e_CSR_tlu_diag );
9941 diagCsr = readCSR( diagAddr );
9942
9943 if ( OptCheck == "all" )
9944 diagCsr[47:32] = diagCsr[47:32] | 16'h1f73;
9945 if ( OptCheck == "DWBE" )
9946 diagCsr[36] = 1'b1;
9947 if ( OptCheck == "cross 4KB" )
9948 diagCsr[37] = 1'b1;
9949 if ( OptCheck == "receiver overflow" )
9950 diagCsr[38] = 1'b1;
9951 if ( OptCheck == "NonConfigCRS" )
9952 diagCsr[40] = 1'b1;
9953 if ( OptCheck == "completion TC" )
9954 diagCsr[41] = 1'b1;
9955 if ( OptCheck == "completion attr" )
9956 diagCsr[42] = 1'b1;
9957 if ( OptCheck == "completion count" )
9958 diagCsr[43] = 1'b1;
9959 if ( OptCheck == "completion address" )
9960 diagCsr[44] = 1'b1;
9961
9962 writeCSR( diagAddr, diagCsr );
9963 } /* end disableOptionalCheck */
9964
9965
9966//N2-Not needed
9967/*
9968* monitorPM - Monitor the power-management port to the TLU
9969*
9970* Parameters: None
9971*/
9972task PEUTestEnv::monitorPM()
9973{
9974/* N2 review
9975 bit [2:0] oldReq;
9976 bit [2:0] newReq;
9977 oldReq = 3'b000;
9978 newReq = 3'b000;
9979 while( 1 )
9980 {
9981 @( posedge TLU_PM.clk );
9982 if ( TLU_PM.req == 3 || TLU_PM.req == 4 )
9983 {
9984 if ( TLU_PM.dllpreq != 3'b100 )
9985 _REPORT_ERROR( "TLU requests entry to L1 but does not send ACK DLLPs" );
9986 }
9987 else if ( TLU_PM.req == 5 )
9988 {
9989 if ( TLU_PM.dllpreq != 3'b100 )
9990 _REPORT_ERROR( "TLU requests entry to L2/3 without sending ACK DLLPs" );
9991 }
9992 else if ( oldReq >= 3 && oldReq <= 5 && TLU_PM.dllpreq == 3'b100 )
9993 {
9994 // TLU is a bit slow taking out the ACK-DLLP request
9995 }
9996 else if ( TLU_PM.dllpreq != 3'b000 )
9997 _REPORT_ERROR( "Unexpected power-management DLLP request from TLU" );
9998
9999
10000 if ( TLU_PM.req != oldReq && TLU_PM.req != 3'b000 )
10001 {
10002 _INFO_MSG( psprintf( "TLU requests transition to '%s'",
10003 TLU_PM.req==1 ? "L0" : TLU_PM.req==2 ? "L0s" :
10004 TLU_PM.req==3 ? "L1" : TLU_PM.req==4 ? "L1(PME)" :
10005 TLU_PM.req==5 ? "L23" : "????" ) );
10006 if ( newReq != 3'b000 )
10007 _REPORT_ERROR( "Unexpected PM state request from TLU" );
10008 newReq = 3'b000;
10009 if ( oldReq != 3'b000 )
10010 newReq = TLU_PM.req;
10011 else if ( TLU_PM.req == monitorPMreq )
10012 trigger( ON, ev_monitorPMreq );
10013 else
10014 _REPORT_ERROR( "Unexpected PM state request from TLU" );
10015 }
10016 else if ( newReq != 3'b000 )
10017 {
10018 if ( TLU_PM.req != newReq )
10019 _REPORT_ERROR( "TLU withdraws PM state request after one cycle?" );
10020 else if ( TLU_PM.req == monitorPMreq )
10021 trigger( ON, ev_monitorPMreq );
10022 else
10023 _REPORT_ERROR( "Unexpected ASPM state request from TLU" );
10024 newReq = 3'b000;
10025 }
10026
10027 if ( TLU_PM.req[2:1] != 2'b00 && TLU_EgressTLP.cmd != 3'b000 )
10028 _REPORT_ERROR( "TLU submits a TLP while requesting a low-power state" );
10029 else if ( monitorPMstate != 3'b001 && TLU_EgressTLP.cmd != 3'b000 )
10030 _REPORT_ERROR( "TLU submits a TLP while not in L0" );
10031 oldReq = TLU_PM.req;
10032 }
10033*/
10034} /* end monitorPM */
10035
10036/*
10037* pmDllp - Pretend that the LPU has gotten a/some power-management DLLPs...
10038*
10039* Parameters:
10040* PmReq - The PM request received by the LPU
10041*/
10042task PEUTestEnv::pmDllp( PEC_PMtype PmReq )
10043{
10044//N2 review f_LPUXtr.pmDllp( PmReq );
10045} /* end pmDllp */
10046
10047/*
10048* pmStatus - Tell the TLU what the LPU's doing
10049*
10050* Parameters:
10051* Status - Either "DLLP" if the LPU has a DLLP to send, or
10052* "TLP" if it has a (retry) TLP to send, or
10053* "BUSY" if both are true, or
10054* "IDLE" if there's nothing to send
10055*/
10056task PEUTestEnv::pmStatus( string Status )
10057{
10058//N2 review f_LPUXtr.pmStatus( Status );
10059} /* end pmStatus */
10060
10061/*
10062* expectASPM - Expect an ASPM transition request from the TLU
10063*
10064* Parameters:
10065* StateReq - Either "L0", or "L0s", or "L1" as the requested ASPM state
10066* ReqTimeout - Within how many cycles do we expect this request?
10067* AckDelay - After how many cycles to we transition to that state?
10068* ReqAbort - If triggered, don't expect the request after all.
10069*/
10070task PEUTestEnv::expectASPM( string StateReq,
10071 integer ReqTimeout,
10072 integer AckDelay,
10073 (event ReqAbort=null),
10074 (integer IdleTimeout=10) )
10075{
10076/* N2 review
10077 integer i;
10078 event abortEvent=null;
10079
10080 _INFO_MSG( psprintf( "Expecting an ASPM transition to '%s'...", StateReq ) );
10081 case ( StateReq ) {
10082 "L0" : monitorPMreq = 3'b001;
10083 "L0s" : monitorPMreq = 3'b010;
10084 "L1" : monitorPMreq = 3'b011;
10085 }
10086
10087 if ( ReqAbort == null )
10088 abortEvent = ev_monitorPMreq;
10089 else
10090 abortEvent = ReqAbort;
10091 fork
10092 sync( ALL, ev_monitorPMreq );
10093 repeat(ReqTimeout) @(posedge CLOCK);
10094 sync( ALL, abortEvent );
10095 join any
10096 terminate;
10097
10098 if ( ReqAbort != null && sync( CHECK, ReqAbort ) )
10099 {
10100 if ( sync( CHECK, ev_monitorPMreq ) )
10101 _REPORT_ERROR( "PM transition aborted, but occurred anyway" );
10102 monitorPMreq = 3'b000;
10103 return;
10104 }
10105
10106 if ( !sync( CHECK, ev_monitorPMreq ) )
10107 {
10108 _REPORT_ERROR( psprintf( "No transition to '%s' within %0d cycles",
10109 StateReq, ReqTimeout ) );
10110 dumpCreditStatus();
10111 return;
10112 }
10113 trigger( OFF, ev_monitorPMreq );
10114
10115 // Acknowledge the TLU's request
10116 // to move to a new PM state after
10117 // the specified delay.
10118 if ( AckDelay > 0 )
10119 {
10120 repeat( AckDelay ) @(posedge CLOCK);
10121
10122 // If we're moving out of L0, shut off
10123 // the egress pipeline. And turn it
10124 // back on if we're re-entering L0.
10125 if ( monitorPMreq == 3'b001 )
10126 {
10127 fork
10128 unplugEgressPipeline();
10129 join none
10130 }
10131 else if ( monitorPMstate == 3'b001 )
10132 {
10133 fork
10134 plugEgressPipeline();
10135 join none
10136 }
10137
10138 // Move to the new PM state and wait
10139 // for the TLU to remove its request.
10140 fork
10141 f_LPUXtr.pmState( StateReq );
10142 join none
10143 monitorPMstate = monitorPMreq;
10144 if ( IdleTimeout <= 0 ) return;
10145 for ( i=0; i<IdleTimeout; i++ )
10146 {
10147 @( posedge TLU_PM.clk );
10148 if ( TLU_PM.req == 3'b000 ) return;
10149 }
10150 _REPORT_ERROR( "TLU does not deassert ASPM request after 10 cycles" );
10151 }
10152
10153 monitorPMreq = 3'b000;
10154END N2 */
10155} /* end expectASPM */
10156
10157/*
10158* expectPM - Expect a software-driven (PME) transition request from the TLU
10159*
10160* Parameters:
10161* StateReq - Either "L0", or "L0s", or "L1" as the requested ASPM state
10162* ReqTimeout - Within how many cycles do we expect this request?
10163* AckDelay - After how many cycles to we transition to that state?
10164* ReqAbort - If triggered, don't expect the request after all.
10165*/
10166task PEUTestEnv::expectPM(
10167 string StateReq,
10168 integer ReqTimeout,
10169 integer AckDelay,
10170 (event ReqAbort=null) ) {
10171
10172/* N2 review
10173 integer i;
10174 event abortEvent=null;
10175
10176 _INFO_MSG( psprintf( "Expecting an PM transition to '%s'...", StateReq ) );
10177 case ( StateReq ) {
10178 "L0" : monitorPMreq = 3'b001;
10179 "L1" : monitorPMreq = 3'b100;
10180 "L2" : monitorPMreq = 3'b101;
10181 }
10182
10183 if ( ReqAbort == null )
10184 abortEvent = ev_monitorPMreq;
10185 else
10186 abortEvent = ReqAbort;
10187 fork
10188 sync( ALL, ev_monitorPMreq );
10189 repeat(ReqTimeout) @(posedge CLOCK);
10190 sync( ALL, abortEvent );
10191 join any
10192 terminate;
10193
10194 if ( ReqAbort != null && sync( CHECK, ReqAbort ) )
10195 {
10196 if ( sync( CHECK, ev_monitorPMreq ) )
10197 _REPORT_ERROR( "PM transition aborted, but occurred anyway" );
10198 monitorPMreq = 3'b000;
10199 return;
10200 }
10201
10202 if ( !sync( CHECK, ev_monitorPMreq ) )
10203 {
10204 _REPORT_ERROR( psprintf( "No transition to '%s' within %0d cycles",
10205 StateReq, ReqTimeout ) );
10206 return;
10207 }
10208 trigger( OFF, ev_monitorPMreq );
10209
10210 // Acknowledge the TLU's request
10211 // to move to a new PM state after
10212 // the specified delay.
10213 if ( AckDelay > 0 )
10214 {
10215 repeat( AckDelay ) @(posedge CLOCK);
10216
10217 // If we're moving out of L0, shut off
10218 // the egress pipeline. And turn it
10219 // back on if we're re-entering L0.
10220 if ( monitorPMreq == 3'b001 )
10221 {
10222 fork
10223 unplugEgressPipeline();
10224 join none
10225 }
10226 else if ( monitorPMstate == 3'b001 )
10227 {
10228 fork
10229 plugEgressPipeline();
10230 join none
10231 }
10232
10233 // Move to the new PM state and wait
10234 // for the TLU to remove its request.
10235 fork
10236 f_LPUXtr.pmState( StateReq );
10237 join none
10238 monitorPMstate = monitorPMreq;
10239 for ( i=0; i<10; i++ )
10240 {
10241 @( posedge TLU_PM.clk );
10242 if ( TLU_PM.req != monitorPMreq ) return;
10243 }
10244 _REPORT_ERROR( "TLU does not deassert PM request after 10 cycles" );
10245 }
10246
10247 monitorPMreq = 3'b000;
10248END N2 */
10249} /* end expectPM */
10250
10251/*
10252* L1toL0 - Transition from L1 to L0 as would happen if the remote device has
10253* something to send.
10254*
10255* Parameters: None
10256*/
10257task PEUTestEnv::L1toL0()
10258 {
10259/* N2 review
10260 if ( monitorPMstate != 3'b011 && monitorPMstate != 3'b100 )
10261 _REPORT_ERROR( "L1toL0 called, but we're not in L1!" );
10262 else
10263 {
10264 fork
10265 unplugEgressPipeline();
10266 f_LPUXtr.pmState( "L0" );
10267 join none
10268 monitorPMstate = 3'b001;
10269 monitorPMreq = 3'b000;
10270 }
10271END N2*/
10272 } /* end L1toL0 */
10273
10274/*
10275* setIngressCredits - Set the number of credits advertised by the TLU and
10276* expected (after soft reset) by the PCIE transactor
10277*
10278* Parameters:
10279* NpstHdr - The number of nonposted-header credits
10280* PostHdr - The number of posted-header credits
10281* PostData - The number of posted-data credits
10282*/
10283task PEUTestEnv::setIngressCredits( integer NpstHdr,
10284 integer PostHdr,
10285 integer PostData )
10286{
10287 bit [63:0] csrData;
10288
10289 csrData = 64'b0;
10290 csrData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_NHC_SLC ] = NpstHdr;
10291 csrData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_PHC_SLC ] = PostHdr;
10292 csrData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_ICI_PDC_SLC ] = PostData;
10293 writeCSR( getCSRaddr( e_CSR_icrdt_init ), csrData );
10294
10295//N2 f_LPUXtr.setInitIngressCredits( e_FC_nonposted, NpstHdr, 0 );
10296//N2 f_LPUXtr.setInitIngressCredits( e_FC_posted, PostHdr, PostData );
10297 //N2 - Change the Initial credits in Scenario so Init and LinkTraining can use them
10298 Scenario.ilupeuInitialNonPostedHeaderCredit = NpstHdr;
10299 Scenario.ilupeuInitialPostedHeaderCredit = PostHdr;
10300 Scenario.ilupeuInitialPostedDataCredit = PostData;
10301
10302 _INFO_MSG( psprintf( "%s: npstHdr=%0d postHdr=%0d postData=%0d",
10303 "Set ingress credits", NpstHdr, PostHdr, PostData ) );
10304} /* end setIngressCredits */
10305
10306/*
10307* setPioTimeOut - Set the time-out value for PIO completions
10308*
10309* Parameters:
10310* TimeOut - An encoded time-out value: 0="no time-out", 1="sim", 2="normal"
10311*
10312* NOTE: If the "TimeOut" is negative, then it's set only if the current
10313* value is zero (i.e. no time-out).
10314*/
10315task PEUTestEnv::setPioTimeOut( integer TimeOut )
10316 {
10317 bit [63:0] tluCtl;
10318
10319#ifdef N2_IOS
10320 tluCtl = readCSRdirect( getCSRaddr(e_CSR_tlu_ctl) );
10321#else
10322 tluCtl = readCSR( getCSRaddr(e_CSR_tlu_ctl) );
10323#endif
10324 if ( tluCtl[18:16] == 3'b000 || TimeOut >= 0 )
10325 {
10326 if ( TimeOut == 0 )
10327 tluCtl[18:16] = 3'b000;
10328 if ( TimeOut == 1 || TimeOut == -1 )
10329 tluCtl[18:16] = 3'b111;
10330 if ( TimeOut == 2 || TimeOut == -2 )
10331 tluCtl[18:16] = 3'b110;
10332#ifdef N2_IOS
10333 writeCSRdirect( getCSRaddr(e_CSR_tlu_ctl), tluCtl );
10334#else
10335 writeCSR( getCSRaddr(e_CSR_tlu_ctl), tluCtl );
10336#endif
10337
10338 }
10339 } /* end setPioTimeOut */
10340
10341/*
10342* stallNonpostedWrite - Should we expect an outstanding Config/IO-write
10343* request to prevent dispatch of other PIO requests
10344* until completed (or time-out)?
10345*
10346* Parameters:
10347* Enabled - "1" if the "stall" is on
10348*/
10349task PEUTestEnv::stallNonpostedWrite( bit Enabled )
10350{
10351 bit[63:0] csr;
10352
10353 csr = readCSRdirect( getCSRaddr( e_CSR_tlu_ctl ) );
10354 csr[ FIRE_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_NPWR_EN_POSITION ] = Enabled;
10355 writeCSRdirect( getCSRaddr( e_CSR_tlu_ctl ), csr );
10356 stallNpstWr = Enabled;
10357
10358} /* end stallNonpostedWrite */
10359
10360/*
10361* nonpostedWriteStalled - Did someone call "stallNonpostedWrite"?
10362*/
10363function bit PEUTestEnv::nonpostedWriteStalled()
10364 {
10365 nonpostedWriteStalled = stallNpstWr;
10366 }
10367
10368
10369function integer PEUTestEnv::getPerfCtr( string ctrType )
10370 {
10371 case ( ctrType )
10372 {
10373 "dma read" : getPerfCtr = perfCtr_dmaRead;
10374 "dma write" : getPerfCtr = perfCtr_dmaWrite;
10375 "recv DWs" : getPerfCtr = perfCtr_recvDWs;
10376 "xmit DWs" : getPerfCtr = perfCtr_xmitDWs;
10377 "pio cpl" : getPerfCtr = perfCtr_pioCpl;
10378 default : getPerfCtr = 0;
10379 }
10380}
10381
10382task PEUTestEnv::setActivityTimeout(integer timeout) {
10383 activityTimeout = timeout;
10384}
10385
10386/*
10387* enableEstar - Set the CSR bit which enables entry/exit into E-star mode
10388*
10389* Parameters:
10390* Enabled - Should Estar clocking be enabled?
10391*/
10392//N2 task PEUTestEnv::enableEstar( bit Enabled )
10393//N2 {
10394//N2 estarEnabled = Enabled;
10395//N2 } /* end enableEstar */
10396
10397/*
10398* isEstarEnabled - Is Estar clocking enabled?
10399*
10400* Parameters: None
10401*
10402* Returned value: The value of the Estar-enable CSR bit
10403*/
10404//N2 function bit PEUTestEnv::isEstarEnabled()
10405//N2 {
10406//N2 isEstarEnabled = estarEnabled;
10407//N2 } /* end isEstarEnabled */
10408
10409/*
10410* enterEstar - Enter Estar mode... the ILU clock is slowed by 32 times
10411*
10412* Parameters: None
10413*/
10414//N2 task PEUTestEnv::enterEstar()
10415//N2 {
10416//N2 if ( !estarEnabled )
10417//N2 _REPORT_ERROR( "'enterEstar' called, but Estar is not enabled!?!" );
10418//N2 else
10419//N2 ENV_Control.estar = 1;
10420//N2 } /* end enterEstar */
10421
10422
10423/*
10424* exitEstar - Leave Estar mode
10425*
10426* Parameters: None
10427*/
10428//N2 task PEUTestEnv::exitEstar()
10429//N2 {
10430//N2 ENV_Control.estar = 0;
10431//N2 } /* end exitEstar */
10432
10433/*
10434 * Initialize the timers in the LPU
10435 *
10436 * Parameters:
10437 *
10438 * numActiveLanes - number of active lanes, default = 8 lanes
10439 * mps - max. payload size, default = 128 bytes
10440 *
10441 */
10442task PEUTestEnv::initLpuCSRs(integer numActiveLanes = 8,
10443 integer mps = 128,
10444 bit fastTrain = 1,
10445 (bit enableL0s = 0),
10446 (bit [63:0] retryBufSize = 64'h0))
10447{
10448/*N2 review Need to write new TLU CSRs for PEU
10449#ifdef LPUXTR_INCLUDE_PCIE
10450 integer replay;
10451 integer acknak;
10452 bit [63:0] csrdata;
10453
10454 // Simulation mode fast training setup that has to be
10455 // done as early as possible in the sim.
10456
10457 if ( fastTrain )
10458 {
10459 // Set fast simulation mode
10460 csrdata = readCSR ( 32'h006e_2600 );
10461 csrdata[30] = 1'b1;
10462 writeCSR( 32'h006e_2600, csrdata );
10463
10464 // Initialize LTSSM 12ms timer (WARNING: have to make sure we set it to a value
10465 // greater than what it has already counted at this point in the sim)
10466 csrdata = 63'h200;
10467 writeCSR( 32'h006e_2788, csrdata );
10468
10469 // Reset the RX Phy to reinitialize timers to fast sim values
10470 csrdata = 63'hff;
10471 writeCSR( 32'h006e_2680, csrdata );
10472 csrdata = 63'h00;
10473 writeCSR( 32'h006e_2680, csrdata );
10474 }
10475
10476 case( numActiveLanes )
10477 {
10478 1:
10479 case( mps )
10480 {
10481 512: { replay = 1677; acknak = 559; }
10482 256: { replay = 1248; acknak = 416; }
10483 default: { replay = 711; acknak = 237; }
10484 }
10485
10486 4:
10487 case( mps )
10488 {
10489 512: { replay = 462; acknak = 154; }
10490 256: { replay = 354; acknak = 118; }
10491 default: { replay = 354; acknak = 118; } // LPU Spec replay = 264; PCIE Spec replay = 3(acknak);
10492 }
10493
10494 8:
10495 case( mps )
10496 {
10497 512: { replay = 318; acknak = 106; } // LPU Spec replay = 258; PCIE Spec replay = 3(acknak);
10498 256: { replay = 321; acknak = 107; }
10499 default: { replay = 336; acknak = 112; } // LPU Spec replay = 246; PCIE Spec replay = 3(acknak);
10500 }
10501 }
10502
10503 if (enableL0s) {
10504
10505 replay += 564;
10506 acknak += 564;
10507 }
10508
10509 printf("AckNak Latency Timer : %0d\n", acknak);
10510 printf("Replay Timer : %0d\n", replay);
10511
10512 writeCSR( 32'h006e_2400, acknak );
10513 writeCSR( 32'h006e_2410, replay );
10514
10515 if (retryBufSize) {
10516
10517 printf("Replay Buffer Size : %0x\n", retryBufSize);
10518 writeCSR( 32'h006e_2428, retryBufSize );
10519 }
10520
10521 // write the new values to the PCIEX transactor
10522 f_LPUXtr.setLatencyTimer( acknak );
10523 f_LPUXtr.setRetryTimer( replay );
10524#endif
10525END N2 */
10526} /* end initLpuCSRs */
10527
10528
10529
10530task PEUTestEnv::sendAck(integer seqNum) {
10531 FNXPCIEXactorTransaction PCIEDllpTrans;
10532
10533 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
10534 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
10535 PCIEDllpTrans.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_ACK;
10536 PCIEDllpTrans.MyPacket.AckNakSeqNum = seqNum;
10537 PCIEDllpTrans.MyPacket.DriveImmediately = 1;
10538 PCIEDllpTrans.Drive(0);
10539}
10540
10541
10542task PEUTestEnv::sendNak(integer seqNum) {
10543 FNXPCIEXactorTransaction PCIEDllpTrans;
10544
10545 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
10546 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
10547 PCIEDllpTrans.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_NAK;
10548 PCIEDllpTrans.MyPacket.AckNakSeqNum = seqNum;
10549 PCIEDllpTrans.MyPacket.DriveImmediately = 1;
10550 PCIEDllpTrans.Drive(0);
10551}
10552
10553
10554task PEUTestEnv::disableDenaliAcks() {
10555 FNXPCIEXactorTransaction PCIEDllpTrans;
10556
10557 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
10558 PCIEDllpTrans.EnableAckDiscard();
10559}
10560
10561task PEUTestEnv::enableDenaliAcks() {
10562 FNXPCIEXactorTransaction PCIEDllpTrans;
10563
10564 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
10565 PCIEDllpTrans.DisableAckDiscard();
10566}
10567
10568#ifdef LPUXTR_INCLUDE_PCIE
10569task PEUTestEnv::enterTxL0s(integer a_cycles) {
10570
10571 f_LPUXtr.enterTxL0s(a_cycles);
10572}
10573
10574
10575task PEUTestEnv::enterRecovery() {
10576
10577 f_LPUXtr.enterRecovery();
10578}
10579
10580
10581function bit [11:0] PEUTestEnv::corruptNextXmtSeqNum(bit [11:0] a_increment) {
10582
10583 corruptNextXmtSeqNum = this.f_LPUXtr.corruptNextXmtSeqNum(a_increment);
10584}
10585
10586
10587function bit [11:0] PEUTestEnv::corruptNextXmtLCRC(bit [31:0] a_mask) {
10588
10589 corruptNextXmtLCRC = this.f_LPUXtr.corruptNextXmtLCRC(a_mask);
10590}
10591
10592
10593function bit [11:0] PEUTestEnv::corruptNextXmtSTP(bit [8:0] a_symbol) {
10594
10595 corruptNextXmtSTP = this.f_LPUXtr.corruptNextXmtSTP(a_symbol);
10596}
10597
10598
10599function bit [11:0] PEUTestEnv::corruptNextXmtENDTLP(bit [8:0] a_symbol) {
10600
10601 corruptNextXmtENDTLP = this.f_LPUXtr.corruptNextXmtENDTLP(a_symbol);
10602}
10603
10604
10605function bit [11:0] PEUTestEnv::corruptNextXmt10bTLP(bit [9:0] a_frameMask,
10606 integer a_frameCorruptOffset,
10607 integer a_frameCorruptFreq,
10608 integer a_frameCorruptMax) {
10609
10610 corruptNextXmt10bTLP = this.f_LPUXtr.corruptNextXmt10bTLP(a_frameMask,
10611 a_frameCorruptOffset,
10612 a_frameCorruptFreq,
10613 a_frameCorruptMax);
10614}
10615
10616
10617task PEUTestEnv::corruptNextXmtCRC(bit [15:0] a_mask) {
10618
10619 this.f_LPUXtr.corruptNextXmtCRC(a_mask);
10620}
10621
10622
10623task PEUTestEnv::corruptNextXmtSDP(bit [8:0] a_symbol) {
10624
10625 this.f_LPUXtr.corruptNextXmtSDP(a_symbol);
10626}
10627
10628
10629task PEUTestEnv::corruptNextXmtENDDLLP(bit [8:0] a_symbol) {
10630
10631 this.f_LPUXtr.corruptNextXmtENDDLLP(a_symbol);
10632}
10633
10634
10635task PEUTestEnv::corruptNextXmt10bDLLP(bit [9:0] a_frameMask,
10636 integer a_frameCorruptOffset,
10637 integer a_frameCorruptFreq,
10638 integer a_frameCorruptMax) {
10639
10640 this.f_LPUXtr.corruptNextXmt10bDLLP(a_frameMask,
10641 a_frameCorruptOffset,
10642 a_frameCorruptFreq,
10643 a_frameCorruptMax);
10644}
10645#endif
10646
10647
10648task PEUTestEnv::ConvertHdr2PcieTlp( bit[PEC_PCI__HDR] tlpHdr,
10649 bit [63:0] _DataSpec,
10650 var FNXPCIEXactorTransaction PCIETlpTrans,
10651 (integer LenAdjust=0),
10652 (bit isDmaReq=0),
10653 (integer dma_ptr=0)) {
10654 bit [31:0] dataDW;
10655 bit [63:0] dataQW;
10656 integer j;
10657 integer i, length, pyldByteValue;
10658 //Payload arrays
10659 bit [7:0] pyldByteAry[*];
10660 bit [63:0] fcaddr = 64'b0;
10661 bit [39:0] pa = 40'b0;
10662 bit [7:0] busid;
10663 bit fcRdCmd = 1'b1;
10664 bit fcEgressCmd = !isDmaReq;
10665 bit zero_len_read = (tlpHdr[PEC_PCI__LEN] == 1) &&
10666 (tlpHdr[PEC_PCI__FIRST_DWBE] == 0) &&
10667 (tlpHdr[PEC_PCI__LAST_DWBE] == 0) ;
10668
10669 //PcieXtr Transaction Packet
10670 FNXPCIEXactorPacket TlpPkt;
10671
10672 //Set the initial payload byte value
10673 pyldByteValue = _DataSpec;
10674
10675 //Get the handle to the transaction packet
10676 TlpPkt = PCIETlpTrans.MyPacket;
10677
10678 //Use the TlpPkt to build up a 3 or 4 DW header plus a payload if needed
10679 //Handle all the common fields first
10680 TlpPkt.CmnFmt = tlpHdr[ILUPEU_TLP_HDR_FMT_BITS];
10681 TlpPkt.CmnType = tlpHdr[ILUPEU_TLP_HDR_TYPE_BITS];
10682 TlpPkt.CmnTC = tlpHdr[ILUPEU_TLP_HDR_TC_BITS];
10683 TlpPkt.CmnTD = tlpHdr[ILUPEU_TLP_HDR_TD_BITS];
10684 TlpPkt.CmnEP = tlpHdr[ILUPEU_TLP_HDR_EP_BITS];
10685 TlpPkt.CmnRO = tlpHdr[ILUPEU_TLP_HDR_RO_BITS];
10686 TlpPkt.CmnSnoop = tlpHdr[ILUPEU_TLP_HDR_SNOOP_BITS];
10687 TlpPkt.CmnLength = tlpHdr[ILUPEU_TLP_HDR_LEN_BITS];
10688
10689
10690 //Set all header fields that are common to Memory, IO, and Cfg and Msg TLP's
10691 if( TlpPkt.CmnType <= FNX_PCIE_XTR_TYPE_CFGWR1 ||
10692 TlpPkt.CmnType[FNX_PCIE_XTR_TYPE_MSG_FIXED_SLC] === FNX_PCIE_XTR_TYPE_MSG_FIXED ){
10693
10694 TlpPkt.ReqBusNum = tlpHdr[ILUPEU_TLP_HDR_REQ_BUS_NUM_BITS];
10695 TlpPkt.ReqDeviceNum = tlpHdr[ILUPEU_TLP_HDR_REQ_DEV_NUM_BITS];
10696 TlpPkt.ReqFuncNum = tlpHdr[ILUPEU_TLP_HDR_REQ_FUNC_NUM_BITS];
10697 TlpPkt.ReqTag = tlpHdr[ILUPEU_TLP_HDR_TAG_BITS];
10698 if( TlpPkt.CmnType[FNX_PCIE_XTR_TYPE_MSG_FIXED_SLC] === FNX_PCIE_XTR_TYPE_MSG_FIXED ){
10699
10700 TlpPkt.MsgCode = tlpHdr[ILUPEU_TLP_HDR_MSG_CODE_BITS];
10701 TlpPkt.MsgRouting = tlpHdr[ILUPEU_TLP_HDR_TYPE_BITS]; //Lower 3 bits of type
10702 }
10703 else{
10704 TlpPkt.BELastDW = tlpHdr[ILUPEU_TLP_HDR_LAST_DWBE_BITS];
10705 TlpPkt.BEFirstDW = tlpHdr[ILUPEU_TLP_HDR_FIRST_DWBE_BITS];
10706 }
10707 }
10708
10709
10710 //Set address header fields for Memory, IO
10711 //If this is a 64 bit address than assign both halves of the address
10712 if( TlpPkt.CmnType <= FNX_PCIE_XTR_TYPE_IOWR ){
10713 if( tlpHdr[ILUPEU_TLP_HDR_FMT_4DW_BITS] ){
10714 TlpPkt.AddrUpper = tlpHdr[ILUPEU_TLP_HDR_ADDR64_UPPER_BITS];
10715 TlpPkt.AddrLower = tlpHdr[ILUPEU_TLP_HDR_ADDR64_LOWER_BITS];
10716
10717 if (tlpHdr[ILUPEU_TLP_HDR_TYPE_BITS] === FNX_PCIE_XTR_TYPE_IOWR) {
10718 fcaddr = ({TlpPkt.AddrUpper, TlpPkt.AddrLower, 2'b0} |
10719 PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD]);
10720 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv IO 3DW fcaddr = %0h\n", fcaddr);
10721 }
10722 else {
10723 fcaddr = {TlpPkt.AddrUpper, TlpPkt.AddrLower, 2'b0};
10724
10725 if (fcEgressCmd) {
10726 //fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM64_FLD];
10727 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv Mrd64 fcaddr = %0h %0h %0h\n",
10728 fcaddr, TlpPkt.AddrUpper, TlpPkt.AddrLower);
10729 }
10730 else {
10731 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv Dma fcaddr = %0h %0h %0h\n",
10732 fcaddr, TlpPkt.AddrUpper, TlpPkt.AddrLower);
10733 }
10734 }
10735 }
10736 else{
10737 TlpPkt.AddrLower = tlpHdr[ILUPEU_TLP_HDR_ADDR32_BITS];
10738
10739 if (tlpHdr[ILUPEU_TLP_HDR_TYPE_BITS] === FNX_PCIE_XTR_TYPE_IOWR) {
10740 fcaddr = {32'b0, TlpPkt.AddrLower, 2'b0} | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD] | 32'h10000000;
10741 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv IO 3DW Cmd fcaddr = %0h\n", fcaddr);
10742 }
10743 else {
10744 fcaddr = {32'b0, TlpPkt.AddrLower, 2'b0};
10745
10746 if (fcEgressCmd) {
10747 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM32_FLD];
10748 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv Mrd32 fcaddr = %0h %0h, Tag = %0h\n",
10749 fcaddr, TlpPkt.ReceivedReqTag, TlpPkt.AddrLower);
10750 }
10751 else {
10752 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv Dma fcaddr = %0h %0h, Tag = %0h\n",
10753 fcaddr, TlpPkt.ReceivedReqTag, TlpPkt.AddrLower);
10754 }
10755 }
10756 }
10757 }
10758
10759 //Set up DW3 header fields for Configuration Requests
10760 if( TlpPkt.CmnType >= FNX_PCIE_XTR_TYPE_CFGRD0 && TlpPkt.CmnType <= FNX_PCIE_XTR_TYPE_CFGWR1 ){
10761
10762 TlpPkt.CfgBusNum = tlpHdr[ILUPEU_TLP_HDR_CFG_BUS_NUM_BITS];
10763 TlpPkt.CfgDeviceNum = tlpHdr[ILUPEU_TLP_HDR_CFG_DEV_NUM_BITS];
10764 TlpPkt.CfgFuncNum = tlpHdr[ILUPEU_TLP_HDR_CFG_FUNC_NUM_BITS];
10765 TlpPkt.CfgExtRegNum = tlpHdr[ILUPEU_TLP_HDR_CFG_EXT_REG_NUM_BITS];
10766 TlpPkt.CfgRegNum = tlpHdr[ILUPEU_TLP_HDR_CFG_REG_NUM_BITS];
10767
10768 // 2'b0 inserted in address below to properly align the address.
10769 //
10770 fcaddr = {TlpPkt.CfgBusNum, TlpPkt.CfgDeviceNum, TlpPkt.CfgFuncNum,
10771 TlpPkt.CfgExtRegNum, TlpPkt.CfgRegNum, 2'b0};
10772
10773 fcaddr = fcaddr | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD];
10774
10775 QuickReport( Report, RTYP_INFO,"-%0d-UDEBUG:PEUTestEnv::ConvertHdr2PcieTlp : A = %0h - %0h %0h %0h %0h %0h - %0h \n",
10776 get_time(LO), fcaddr, TlpPkt.CfgBusNum, TlpPkt.CfgDeviceNum, TlpPkt.CfgFuncNum,
10777 TlpPkt.CfgExtRegNum, TlpPkt.CfgRegNum, tlpHdr);
10778
10779 }
10780
10781
10782
10783 //Set up DW3 & DW4 fields for Messages
10784 if( TlpPkt.CmnType[FNX_PCIE_XTR_TYPE_MSG_FIXED_SLC] === FNX_PCIE_XTR_TYPE_MSG_FIXED ){
10785
10786 TlpPkt.MsgDW3 = tlpHdr[ILUPEU_TLP_HDR_MSG_DW3_BITS];
10787 TlpPkt.MsgDW4 = tlpHdr[ILUPEU_TLP_HDR_MSG_DW4_BITS];
10788 }
10789
10790
10791 //Set up fields for Completions
10792 if( TlpPkt.CmnType >= FNX_PCIE_XTR_TYPE_CPL && TlpPkt.CmnType <= FNX_PCIE_XTR_TYPE_CPLDLK ){
10793
10794 TlpPkt.CmplBusNum = tlpHdr[ILUPEU_TLP_HDR_CPL_CPL_BUS_NUM_BITS];
10795 TlpPkt.CmplDeviceNum = tlpHdr[ILUPEU_TLP_HDR_CPL_CPL_DEV_NUM_BITS];
10796 TlpPkt.CmplFuncNum = tlpHdr[ILUPEU_TLP_HDR_CPL_CPL_FUNC_NUM_BITS];
10797 TlpPkt.CmplStatus = tlpHdr[ILUPEU_TLP_HDR_CPL_STATUS_BITS];
10798 TlpPkt.CmplBCM = tlpHdr[ILUPEU_TLP_HDR_CPL_BCM_BITS];
10799 TlpPkt.CmplByteCount = tlpHdr[ILUPEU_TLP_HDR_CPL_BYTECOUNT_BITS];
10800 TlpPkt.ReqBusNum = tlpHdr[ILUPEU_TLP_HDR_CPL_REQ_BUS_NUM_BITS];
10801 TlpPkt.ReqDeviceNum = tlpHdr[ILUPEU_TLP_HDR_CPL_REQ_DEV_NUM_BITS];
10802 TlpPkt.ReqFuncNum = tlpHdr[ILUPEU_TLP_HDR_CPL_REQ_FUNC_NUM_BITS];
10803 TlpPkt.ReqTag = tlpHdr[ILUPEU_TLP_HDR_CPL_TAG_BITS];
10804 TlpPkt.CmplLowerAddr = tlpHdr[ILUPEU_TLP_HDR_CPL_LOWADDR_BITS];
10805 //Set reserved fields for ingress completions
10806
10807 TlpPkt.CmnResv1 = tlpHdr[127];
10808 TlpPkt.CmnResv2 = tlpHdr[119];
10809 TlpPkt.CmnResv3 = tlpHdr[115:112];
10810 TlpPkt.CmnResv4 = tlpHdr[107:106];
10811 TlpPkt.CmplResv5 = tlpHdr[39];
10812
10813 fcaddr = fcAddrArray[TlpPkt.ReqTag];
10814 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv Cpl fcaddr = %0h, Tag = %0h tlp@ %0h %0h \n",
10815 fcaddr, TlpPkt.ReqTag,
10816 tlpHdr[ILUPEU_TLP_HDR_ADDR64_UPPER_BITS],
10817 tlpHdr[ILUPEU_TLP_HDR_ADDR64_LOWER_BITS]
10818 );
10819 if (isDmaReq) {
10820 // review: temp hack for DMA RD completion ...
10821 // fcaddr[63:39] = 0; // if so, clear those bits
10822
10823 //}
10824
10825
10826 fcAddrArray[TlpPkt.ReqTag] = fcAddrArray[TlpPkt.ReqTag] + (4*TlpPkt.CmnLength);
10827 QuickReport( Report, RTYP_INFO,"UDEBUG:PEUTestEnv fixed fcaddr for next DMA RD cmpl, fcaddr = %0h cnt = %d\n",
10828 fcAddrArray[TlpPkt.ReqTag], TlpPkt.CmplByteCount );
10829 }
10830 }
10831
10832
10833 if ( (TlpPkt.CmnType == FNX_PCIE_XTR_TYPE_IOWR ||
10834 TlpPkt.CmnType == FNX_PCIE_XTR_TYPE_CFGWR0 ||
10835 TlpPkt.CmnType == FNX_PCIE_XTR_TYPE_CFGWR1 ||
10836 TlpPkt.CmnType == FNX_PCIE_XTR_TYPE_MWR) &&
10837 TlpPkt.CmnFmt[FNX_PCIE_XTR_FMT_DATA_SLC]) {
10838
10839 fcRdCmd = 1'b0;
10840 }
10841 else {
10842 fcRdCmd = 1'b1;
10843
10844 // save received req tag only if this is a read command
10845 // and not for completions
10846 //
10847 if ( !(TlpPkt.CmnType >= FNX_PCIE_XTR_TYPE_CPL &&
10848 TlpPkt.CmnType <= FNX_PCIE_XTR_TYPE_CPLDLK) ) {
10849 if (isDmaReq) {
10850 QuickReport( Report, RTYP_INFO,"UDEBUG .. DMA RD completion Addr = %0h Tag = %0h\n", fcaddr, tlpHdr[PEC_PCI__TLP_TAG] );
10851 fcAddrArray[tlpHdr[PEC_PCI__TLP_TAG]] = fcaddr;
10852 }
10853 }
10854 }
10855
10856/*
10857DMUXtr payload specification
10858 payloadByte = payload[7:0];
10859 poisonedPayload = payload[15:8];
10860 fillPayload = payload[16];
10861 errPayload = payload[17];
10862 errMask = payload[25:18];
10863*/
10864
10865 //Set up the random payload if needed
10866 if( TlpPkt.CmnFmt[FNX_PCIE_XTR_FMT_DATA_SLC] ){
10867 if( TlpPkt.CmnLength === 0 ){
10868 length = 1024;
10869 }
10870 else{
10871 length = TlpPkt.CmnLength;
10872 }
10873
10874 //Adjust the length if test requests it
10875 length += LenAdjust;
10876
10877 pyldByteAry = new[length*4];
10878 if( length == 0 ){
10879 pyldByteAry = new[1];
10880 pyldByteAry.delete();
10881 }
10882 //In order to use the DMUXtr env code -get a DW and then
10883 // put it into a byte array byte 0 = DW[31:24]
10884#ifdef N2_FC
10885 if (~fcEgressCmd && fcRdCmd) {
10886 if (TlpPkt.CmnType == FNX_PCIE_XTR_TYPE_CPL) {
10887 busid = tlpHdr[ILUPEU_TLP_HDR_CPL_REQ_BUS_NUM_BITS];
10888 } else {
10889 busid = tlpHdr[ILUPEU_TLP_HDR_REQ_BUS_NUM_BITS];
10890 }
10891 if (!MMU.get_physical_address(fcaddr, pa, busid, 0)) {
10892 printf("PEUTestEnv::ConvertHdr2PcieTlp translation error detected by MMU.get_physical_address for VA %0h busid %h\n", fcaddr, busid);
10893 return;
10894 }
10895 fcaddr = pa; // from here on, use the physical address
10896 fork
10897 l2sio_stub.reassemble_dma_pkt("PEUTestEnv::ConvertHdr2PcieTlp", length, fcaddr, dma_ptr);
10898 sync( ANY, ev_removePcie );
10899 join any
10900 terminate; // kill the other thread
10901 if( sync( CHECK, ev_removePcie ) ){
10902 l2sio_stub.free_data_semaphore("PEUTestEnv::ConvertHdr2PcieTlp", dma_ptr);
10903 return;
10904 }
10905 }
10906#endif
10907 for( i=0; i< length; i++){
10908#ifdef N2_FC
10909 if (fcEgressCmd) {
10910 if (fcRdCmd) {
10911 // PIO read responce - read from gmem
10912 dataDW = N2fcRdMem (fcAddrMsk | fcaddr);
10913 for( j=0; j<4; j++)
10914 pyldByteAry[(i*4)+j] = dataDW[31-(j*8):24-(j*8)];
10915 printf("UDEBUG : PEUTestEnv::ConvertHdr2PcieTlp : Adr %0h, dataDW %0h, i %0d\n",
10916 fcaddr, dataDW, i );
10917 }
10918 else {
10919 bit [3:0] DWBE = i ? TlpPkt.BELastDW : TlpPkt.BEFirstDW;
10920 dataDW = _DataSpec[63-(i*32):32-(i*32)];
10921 // PIO write - leave Xs in the expected pkt for bytes w/ BM == 0
10922 //N2fcWrMem (fcAddrMsk | fcaddr, dataDW, DWBE);
10923 printf("UDEBUG : PEUTestEnv::ConvertHdr2PcieTlp : Adr %0h, data %0h, LBE %0h FBE %0h i %0d\n",
10924 fcaddr, dataDW, TlpPkt.BELastDW, TlpPkt.BEFirstDW, i );
10925 for( j=0; j<4; j++) {
10926 if (DWBE & (1<<j))
10927 pyldByteAry[(i*4)+j] = dataDW[31-(j*8):24-(j*8)];
10928 }
10929 }
10930 }
10931 // ingress command from endpoint
10932 //
10933 else {
10934 if (fcRdCmd) {
10935 // for DMA read, read from data captured at the L2-SIU interface
10936 // to create expected TLP payload, 4 bytes at a time
10937 if (!zero_len_read) {
10938 l2sio_stub.read_mem ("PEUTestEnv::ConvertHdr2PcieTlp", fcaddr, dataDW, dma_ptr);
10939 //printf("UDEBUG : PEUTestEnv::ConvertHdr2PcieTlp DMA read l2sio : Adr %0h, data %0h, i %0d dma_ptr %0d\n", fcaddr, dataDW, i, dma_ptr);
10940 } else {
10941 dataDW = 32'hxxxxxxxx; // make data unknown for 0 length reads
10942 }
10943
10944 for( j=0; j<4; j++)
10945 pyldByteAry[(i*4)+j] = dataDW[31-(j*8):24-(j*8)];
10946 }
10947 else {
10948 // for DMA write, create the payload data, and
10949 // let dma sync take care of writing data to gMem when it gets to the L2
10950 dataDW = this.nextPayloadDW( pyldByteValue );
10951 //printf("UDEBUG : PEUTestEnv::ConvertHdr2PcieTlp DMA wr : Adr %0h, data %0h, i %0d\n", fcaddr, dataDW, i );
10952 for( j=0; j<4; j++)
10953 pyldByteAry[(i*4)+j] = dataDW[31-(j*8):24-(j*8)];
10954 }
10955 }
10956 fcaddr += 4;
10957#else
10958 dataDW = this.nextPayloadDW( pyldByteValue );
10959
10960 for( j=0; j<4; j++){
10961 pyldByteAry[(i*4)+j] = dataDW[31-(j*8):24-(j*8)];
10962 }
10963 fcaddr += 4;
10964#endif
10965 }
10966 TlpPkt.SetPyld( pyldByteAry );
10967 }
10968
10969 //Add TLP Digest
10970 if( TlpPkt.CmnTD ){
10971 TlpPkt.ECRC = urandom();
10972 }
10973
10974 //Turn off Denali automatic tag generation
10975 TlpPkt.GenTag = 0;
10976
10977
10978 TlpPkt.PktDisplay( RTYP_DEBUG_3, "::ConvertHdr2PcieTlp()" );
10979
10980 QuickReport( Report,
10981 RTYP_DEBUG_3,
10982 "ConvertHdr2PcieTlp() tlpHdr=%h ",tlpHdr );
10983
10984} //End ConvertHdr2PcieTlp
10985
10986
10987task PEUTestEnv::setDWBE( var bit[PEC_PCI__HDR] TlpHdr ){
10988
10989 bit [63:0] tlpAddr;
10990
10991 if ( TlpHdr[PEC_PCI__FMT_4DW] )
10992 tlpAddr = TlpHdr[PEC_PCI__ADDR];
10993 else
10994 tlpAddr[31:0] = TlpHdr[PEC_PCI__ADDR32];
10995
10996 /* DWBEs are random, but their validity
10997 depends on the length and boundary.*/
10998 if ( TlpHdr[PEC_PCI__LEN] == 1 )
10999 {
11000 TlpHdr[PEC_PCI__FIRST_DWBE] = localRandom(16);
11001 TlpHdr[PEC_PCI__LAST_DWBE] = 0;
11002 }
11003 //If QW aligned First and Last can be non-contiguous
11004 else if ( TlpHdr[PEC_PCI__LEN] == 2 && tlpAddr[3:0] == 4'b0000 )
11005 {
11006 TlpHdr[PEC_PCI__FIRST_DWBE] = 1 + localRandom(15);
11007 TlpHdr[PEC_PCI__LAST_DWBE] = 1 + localRandom(15);
11008 }
11009 else
11010 {
11011 TlpHdr[PEC_PCI__FIRST_DWBE] = 8'h78 >> localRandom(4);
11012 TlpHdr[PEC_PCI__LAST_DWBE] = 8'h0f >> localRandom(4);
11013 }
11014}
11015
11016task PEUTestEnv::returnAllEgressCredits( (integer timerVal = 15) ){
11017 bit[ FNX_PCIE_XTR_REG_DEN_WIDTH-1:0 ] denRegTmpData;
11018 FNXPCIEXactorTransaction PCIETrans;
11019 PCIETrans = new( Pod.FNXPCIEBldr );
11020
11021 QuickReport( Report, RTYP_INFO,
11022 "Env::returnAllEgressCredits() called ");
11023
11024 //Just set the Denali Flow Control timer values to 15 to force Denali
11025 // to send any updates
11026 denRegTmpData = 0;
11027 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_OP_SLC] = PCIE_FCCTRL_set_timer;
11028 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_VC_SLC] = 0; //VC 0
11029 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_PH;
11030 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11031 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11032
11033 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_PD;
11034 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11035 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11036
11037 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_NPH;
11038 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11039 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11040
11041 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_NPD;
11042 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11043 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11044
11045 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_CPLH;
11046 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11047 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11048
11049 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_FC_TYPE_SLC] = PCIE_FCTYPE_CPLD;
11050 denRegTmpData[FNX_PCIE_XTR_REG_DEN_FC_CTRL_TIMER_VAL_SLC] = timerVal;
11051 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_FC_CTRL, denRegTmpData );
11052
11053}
11054
11055//Read the DLPL Core status register and return the LTSSM state
11056function bit[4:0] PEUTestEnv::getLtssmState(){
11057
11058 bit [63:0] csr;
11059 bit [4:0] ltssmState;
11060 string msg;
11061
11062
11063 csr = readCSRdirect( getCSRaddr( e_CSR_core_status ) );
11064
11065 ltssmState = csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_LTSSM_STATE_SLC];
11066
11067 sprintf( msg, "PEUTestEnv::getLtssmState ltssmState = %0h %s", ltssmState,ltssmStateToString(ltssmState) );
11068 _INFO_MSG( msg );
11069
11070 getLtssmState = ltssmState;
11071}
11072
11073//Get the number of unACKd TLPs in the replay buffer
11074function integer PEUTestEnv::getNmbrTlpsReplayBuffer(){
11075 integer nmbrTlpsReplayBuffer;
11076 integer oldestTransmitSeqNum;
11077
11078 oldestTransmitSeqNum = ( (egressNextTransmitSeqNum%4096) == 0 ? 4095 : egressNextTransmitSeqNum - 1 );
11079 if( (oldestTransmitSeqNum%4096 - AckdSeqNum) >= 0 ){
11080 nmbrTlpsReplayBuffer = (oldestTransmitSeqNum%4096) - AckdSeqNum;
11081 }else{
11082 nmbrTlpsReplayBuffer = (oldestTransmitSeqNum%4096)+4096 - AckdSeqNum;
11083 }
11084
11085 //Return the number of Tlps in the replay buffer
11086 getNmbrTlpsReplayBuffer = nmbrTlpsReplayBuffer;
11087}
11088
11089
11090
11091//------------------------------------------------------------------------------
11092// N2 FC. Write received data in gMem
11093//------------------------------------------------------------------------------
11094
11095task PEUTestEnv::N2fcWrMem (bit [63:0] addr, bit [31:0] din, bit [7:0] be) {
11096#ifdef N2_FC
11097 bit [63:0] rdat, wdat;
11098 bit [63:0] memAddr = addr;
11099
11100 rdat = gMem.read_mem(memAddr);
11101
11102 // writeBM() will mask off addr bits 2:0. We need to pass the data in the
11103 // right position within a 64 bit word
11104 wdat = rdat;
11105 if(memAddr[2]) {
11106 wdat[31: 0] = din;
11107 be[7:4] = 0;
11108 be[3:0] = {be[0],be[1],be[2],be[3]};
11109 }
11110 else {
11111 wdat[63:32] = din;
11112 //be[7:4] = be[3:0];
11113 be[7:4] = {be[0],be[1],be[2],be[3]};
11114 be[3:0] = 0;
11115 }
11116 gMem.writeBM(memAddr, wdat, be);
11117
11118 wdat = gMem.read_mem(memAddr);
11119
11120 printf ("-%0d-UDEBUG:PEUTestEnv::N2fcWrMem: A= %0h, wdat= %0h, BE= %0h, gMem Dat Old = %0h New = %0h\n",
11121 get_time(LO), addr, din, be, rdat, wdat);
11122
11123#endif
11124
11125
11126}
11127
11128
11129//------------------------------------------------------------------------------
11130// N2 FC. Read data in gMem
11131//------------------------------------------------------------------------------
11132
11133function bit [31:0] PEUTestEnv::N2fcRdMem (bit [63:0] addr) {
11134
11135#ifdef N2_FC
11136 bit [63:0] rdat;
11137 bit [63:0] memAddr = addr;
11138
11139 rdat = gMem.read_mem(memAddr);
11140
11141 printf ("-%0d-UDEBUG:PEUTestEnv::N2fcRdMem : New Addr = %0h, Data = %0h - %0h %0h\n",
11142 get_time(LO), memAddr, rdat, rdat[63:32], rdat[31:0]);
11143
11144 N2fcRdMem = (memAddr[2]==1'b0) ? rdat[63:32] : rdat[31:0];
11145#endif
11146}
11147
11148//-------------------------------
11149//Set bit to stay in Detect.Quiet
11150//-------------------------------
11151task PEUTestEnv::stayDetectQuiet() {
11152 bit [63:0] csrRegTmpData;
11153
11154 csrRegTmpData = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ctl.read(FIRE_PIO_SLOW);
11155 csrRegTmpData[8] = 1; //Turn on remain in detect.quiet
11156 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ctl.write(csrRegTmpData,FIRE_PIO_SLOW);
11157}
11158
11159//-------------------------------
11160//Set bit to exit in Detect.Quiet
11161//-------------------------------
11162task PEUTestEnv::exitDetectQuiet() {
11163 bit [63:0] csrRegTmpData;
11164
11165 csrRegTmpData = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ctl.read(FIRE_PIO_SLOW);
11166 csrRegTmpData[8] = 0; //Turn off remain in detect.quiet
11167 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_tlu_ctl.write(csrRegTmpData,FIRE_PIO_SLOW);
11168}
11169
11170
11171//---------------------------------------------------------------------
11172//set Assert Reset bit set which should cause transition to HOT RESET State
11173//---------------------------------------------------------------------
11174task PEUTestEnv::PeuHotReset() {
11175 bit [63:0] csrRegTmpData;
11176
11177 csrRegTmpData = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_link_ctl.read(FIRE_PIO_SLOW);
11178 csrRegTmpData[FIRE_PLC_TLU_CTB_TLR_CSR_A_LINK_CTL_RESET_ASSERT_SLC] = 1'b1;
11179 f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_link_ctl.write(csrRegTmpData,FIRE_PIO_SLOW);
11180 printf("\n ............Asserting Hot Reset csr bit............. \n");
11181}
11182
11183//--------------------------------------------------------
11184//This task expects to enter specified LTSSM state or times out waiting
11185//--------------------------------------------------------
11186task PEUTestEnv::toLtssmState( bit [4:0] ltssmState,
11187 (integer timer=2000),
11188 (integer accessMethod=FIRE_PIO_SLOW) ){
11189 bit [63:0] csrRegTmpData;
11190 string msg;
11191
11192 csrRegTmpData = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_core_status.read(accessMethod);
11193 fork
11194 {
11195 while( (csrRegTmpData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_LTSSM_STATE_SLC ] !== ltssmState) && timer ){
11196 csrRegTmpData = f_CSR.CSR.fire_plc_tlu_ctb_tlr_csr_a_core_status.read(accessMethod);
11197 if( accessMethod === OMNI ) @(posedge CLOCK);
11198 }
11199 }
11200 {
11201 while( timer ){
11202 @(posedge CLOCK);
11203 timer--;
11204 }
11205 }
11206 join any
11207
11208 if( !timer ){
11209 sprintf(msg,"::toLtssmState timed out waiting to enter LTSSM_STATE -%s- ---Still in state -%s- (%0h) at time %d",ltssmStateToString(ltssmState), ltssmStateToString(csrRegTmpData[FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_LTSSM_STATE_SLC ]), csrRegTmpData[FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_LTSSM_STATE_SLC ], get_time(LO) );
11210 _REPORT_ERROR("::toLtssmState timed out");
11211 _ERROR_INFO(msg);
11212 }else{
11213 printf("\n=========== PEU Entered LTSSM_STATE -%s- (%h) ===========\n",ltssmStateToString(ltssmState), csrRegTmpData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_LTSSM_STATE_SLC ]);
11214 }
11215}
11216
11217
11218function string PEUTestEnv::ltssmStateToString( bit [4:0] ltssmState ){
11219 string msg;
11220
11221 //Get the values from ilupeu_defines.vri
11222 case (ltssmState){
11223 ILUPEU_LTSSM_PRE_DETECT_QUIET: sprintf(msg, "PreDetect.Quiet");
11224 ILUPEU_LTSSM_DETECT_QUIET: sprintf(msg, "Detect.Quiet");
11225 ILUPEU_LTSSM_DETECT_ACT: sprintf(msg, "Detect.Active");
11226 ILUPEU_LTSSM_DETECT_WAIT: sprintf(msg, "Detect.Wait");
11227 ILUPEU_LTSSM_POLL_ACTIVE: sprintf(msg, "Polling.Active");
11228 ILUPEU_LTSSM_POLL_COMPLIANCE: sprintf(msg, "Polling.Compliance");
11229 ILUPEU_LTSSM_POLL_CONFIG: sprintf(msg, "Polling.Configuration");
11230 ILUPEU_LTSSM_CFG_LINKWD_START: sprintf(msg, "Configuration.Linkwidth.Start");
11231 ILUPEU_LTSSM_CFG_LINKWD_ACEPT: sprintf(msg, "Configuration.Linkwidth.Accept");
11232 ILUPEU_LTSSM_CFG_LANENUM_WAIT: sprintf(msg, "Configuration.Lanenum.Wait");
11233 ILUPEU_LTSSM_CFG_LANENUM_ACEPT: sprintf(msg, "Configuration.Lanenum.Accept");
11234 ILUPEU_LTSSM_CFG_COMPLETE: sprintf(msg, "Configuration.Complete");
11235 ILUPEU_LTSSM_CFG_IDLE: sprintf(msg, "Configuration.Idle");
11236 ILUPEU_LTSSM_RCVRY_RCVRLOCK: sprintf(msg, "Recovery.RcvrLock");
11237 ILUPEU_LTSSM_RCVRY_RCVRCFG: sprintf(msg, "Recovery.RcvrCfg");
11238 ILUPEU_LTSSM_RCVRY_IDLE: sprintf(msg, "Recovery.Idle");
11239 ILUPEU_LTSSM_HOT_RESET_ENTRY: sprintf(msg, "HotReset.Entry");
11240 ILUPEU_LTSSM_HOT_RESET: sprintf(msg, "HotReset");
11241 ILUPEU_LTSSM_L0: sprintf(msg, "L0");
11242 ILUPEU_LTSSM_L0S: sprintf(msg, "L0S");
11243 ILUPEU_LTSSM_L123_SEND_EIDLE: sprintf(msg, "L123.SEND.EIDLE (ENTRY)");
11244 ILUPEU_LTSSM_L1_IDLE: sprintf(msg, "L1.Idle");
11245 ILUPEU_LTSSM_L2_IDLE: sprintf(msg, "L2.Idle");
11246 ILUPEU_LTSSM_L2_WAKE: sprintf(msg, "L2.Wake");
11247 ILUPEU_LTSSM_DISABLED_ENTRY: sprintf(msg, "Disabled.Entry");
11248 ILUPEU_LTSSM_DISABLED_IDLE: sprintf(msg, "Disabled.Idle");
11249 ILUPEU_LTSSM_DISABLED: sprintf(msg, "Disabled");
11250 ILUPEU_LTSSM_LPBK_ENTRY: sprintf(msg, "Loopback.Entry");
11251 ILUPEU_LTSSM_LPBK_ACTIVE: sprintf(msg, "Loopback.Active");
11252 ILUPEU_LTSSM_LPBK_EXIT: sprintf(msg, "Loopback.Exit");
11253 ILUPEU_LTSSM_LPBK_EXIT_TIMEOUT: sprintf(msg, "Loopback.Exit.Timeout");
11254 default: sprintf(msg, "OUCH! ERROR! You Missed Try Again");
11255 }
11256
11257 ltssmStateToString = msg;
11258}
11259
11260task PEUTestEnv::removePcie(){
11261
11262 trigger( ON, ev_removePcie );
11263}
11264
11265
11266//--------------------------------------------------------
11267//This task expects Denali Endpoint to enter specified LTSSM state or times out waiting
11268//--------------------------------------------------------
11269task PEUTestEnv::to_endpoint_LtssmState( bit [15:0] ep_ltssmState,
11270 (integer timer=2000) ){
11271 bit [31:0] denali_ltssm_tempdata;
11272 bit [15:0] denali_ltssm_new_state;
11273 bit [15:0] denali_ltssm_old_state;
11274 string msg;
11275
11276 denali_ltssm_tempdata = Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_LTSSM_STATE );
11277
11278 denali_ltssm_new_state = denali_ltssm_tempdata[15:0];
11279 denali_ltssm_old_state = denali_ltssm_tempdata[31:16];
11280
11281
11282 fork
11283 {
11284 while( (denali_ltssm_new_state !== ep_ltssmState) && timer ){
11285 denali_ltssm_tempdata = Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_LTSSM_STATE );
11286 denali_ltssm_new_state = denali_ltssm_tempdata[15:0];
11287 denali_ltssm_old_state = denali_ltssm_tempdata[31:16];
11288 @(posedge CLOCK);
11289 }
11290 }
11291 {
11292 while( timer ){
11293 @(posedge CLOCK);
11294 timer--;
11295 }
11296 }
11297 join any
11298
11299 if( !timer ){
11300 sprintf(msg,"PEUTestEnv::to_endpoint_LtssmState timed out waiting to enter LTSSM_STATE -%s- (new_state = %0h, old_state = %0h) \n",ep_ltssmStateToString(ep_ltssmState), denali_ltssm_new_state, denali_ltssm_old_state );
11301 _REPORT_ERROR("::to_endpoint_LtssmState timed out");
11302 _ERROR_INFO(msg);
11303 }else{
11304 printf("\n=========== Denali Endpoint Entered LTSSM_STATE -%s- (new_state = %h, old_state = %0h) ===========\n",ep_ltssmStateToString(ep_ltssmState), denali_ltssm_new_state, denali_ltssm_old_state);
11305 }
11306}
11307
11308
11309
11310
11311
11312task PEUTestEnv::SetPEU_ASPM_enable( bit[1:0] value=3) {
11313
11314 CSRCollection CSR;
11315 bit[ ILUPEU_CSR_WIDTH-1:0 ] csrRegTmpData;
11316 bit[ FNX_PCIE_XTR_REG_DEN_WIDTH-1:0 ] denRegTmpData;
11317
11318 CSR = Pod.CSRXtr.CSR;
11319 // CSR = new(Pod.CSRXtr.CSR);
11320
11321 // Setting PEU Link control ASPM to value
11322 csrRegTmpData = 0;
11323 csrRegTmpData = CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_ctl.read();
11324 csrRegTmpData[ FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_ASPM_SLC ] = value;
11325 CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_ctl.write(csrRegTmpData,FIRE_PIO_SLOW);
11326
11327 // Set the same value to Denali root monitor link control register ASPM
11328 denRegTmpData = Pod.denali_root_monitor_PCIEEnableTrans.ReadDenaliReg( PCIE_REG_EXP_LINK_CTRL );
11329 denRegTmpData[FNX_PCIE_XTR_REG_DEN_EXP_LINK_CTRL_ASPM_CTRL_SLC] = value;
11330 Pod.denali_root_monitor_PCIEEnableTrans.WriteDenaliReg(PCIE_REG_EXP_LINK_CTRL, denRegTmpData);
11331
11332 // report the value set
11333 csrRegTmpData = CSR.fire_plc_tlu_ctb_tlr_csr_a_lnk_ctl.read();
11334 denRegTmpData = Pod.FNXPCIEEnableTrans.ReadDenaliReg( PCIE_REG_EXP_LINK_CTRL );
11335 // ilupeuLinkCtrlASPM = %h \n", csrRegTmpData[FIRE_PLC_TLU_CTB_TLR_CSR_A_LNK_CTL_ASPM_SLC]);
11336 // denali root monitor LinkCtrlASPM = %h \n", denRegTmpData);
11337
11338
11339
11340}
11341
11342
11343 task PEUTestEnv::EndpointExpectDLLP(bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType) {
11344 FNXPCIEXactorTransaction PCIEDllpTrans;
11345
11346 PCIEDllpTrans = new( Pod.FNXPCIEBldr );
11347
11348
11349 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
11350 PCIEDllpTrans.MyPacket.DllpType = DllpType;
11351
11352 void = PCIEDllpTrans.Expect( 7000 );
11353 }
11354
11355
11356
11357//These tasks will discard FC update from Denali
11358task PEUTestEnv::disableDenaliFC() {
11359 FNXPCIEXactorTransaction PCIEDllpTrans;
11360
11361 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
11362 PCIEDllpTrans.EnableFCDiscard();
11363}
11364
11365task PEUTestEnv::enableDenaliFC() {
11366 FNXPCIEXactorTransaction PCIEDllpTrans;
11367
11368 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
11369 PCIEDllpTrans.DisableFCDiscard();
11370}
11371
11372
11373// task to change denali soma timing parameter
11374task PEUTestEnv::Change_soma_parameters_ac(string _str1) {
11375 integer Err;
11376 string str1;
11377 // str1 = "mmsomaset tb_top.pcie_root_monitor ttoTLCpl 1 us ";
11378 str1 = _str1;
11379 Err = DenaliDDVTclEval(str1);
11380 // bad status when = 1
11381 if (Err == 1) {
11382 printf("AC: Error: changing soma parameter: %s at time %d \n", str1, get_time(LO));
11383 }
11384 else {
11385 printf("AC: changing soma parameter: %s at time %d \n", str1, get_time(LO));
11386 }
11387}
11388
11389
11390
11391
11392
11393function string PEUTestEnv::ep_ltssmStateToString( bit [15:0] ep_ltssmState ){
11394 string msg;
11395
11396 //Get the values from ilupeu_defines.vri
11397 case (ep_ltssmState){
11398
11399 PCIE_LTSSM_STATE_L0: sprintf(msg, "PCIE_LTSSM_STATE_L0");
11400 PCIE_LTSSM_STATE_L1Idle: sprintf(msg, " PCIE_LTSSM_L1Idle");
11401 PCIE_LTSSM_STATE_L2Idle: sprintf(msg, " PCIE_LTSSM_L2Idle");
11402
11403 PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0 : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0 "); // x000000a0,
11404 PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sIdle : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sIdle "); // x00000022,
11405 PCIE_LTSSM_STATE_Rx_L0_Tx_L0sIdle : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0_Tx_L0sIdle "); // x00000082,
11406 PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0 : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0 "); // x000000c0,
11407 PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0 : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0 "); // x00000090,
11408 PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sEntry : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sEntry "); // x00000044,
11409 PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sEntry : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sEntry "); // x00000024,
11410 PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sEntry : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sEntry "); // x00000014,
11411 PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sIdle : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sIdle "); // x00000042,
11412 PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sIdle : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sIdle "); // x00000012,
11413 PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sFTS : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sEntry_Tx_L0sFTS "); // x00000041,
11414 PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sFTS : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sIdle_Tx_L0sFTS "); // x00000021,
11415 PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sFTS : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0sFTS_Tx_L0sFTS "); // x00000011,
11416 PCIE_LTSSM_STATE_Rx_L0_Tx_L0sEntry : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0_Tx_L0sEntry "); // x00000084,
11417 PCIE_LTSSM_STATE_Rx_L0_Tx_L0sFTS : sprintf(msg, " PCIE_LTSSM_STATE_Rx_L0_Tx_L0sFTS "); // x00000081
11418 PCIE_LTSSM_STATE_ConfigurationIdle : sprintf(msg, " PCIE_LTSSM_STATE_ConfigurationIdle "); // x00003500
11419 PCIE_LTSSM_STATE_ConfigurationLinkwidthStart : sprintf(msg, " PCIE_LTSSM_STATE_ConfigurationLinkwidthStart "); // x00000081
11420 PCIE_LTSSM_STATE_ConfigurationLanenumAccept : sprintf(msg, "PCIE_LTSSM_STATE_ConfigurationLanenumAccept "); // 0x00003200,
11421 PCIE_LTSSM_STATE_ConfigurationLanenumWait : sprintf(msg, "PCIE_LTSSM_STATE_ConfigurationLanenumWait "); // 0x00003300,
11422 PCIE_LTSSM_STATE_ConfigurationComplete : sprintf(msg, "PCIE_LTSSM_STATE_ConfigurationComplete "); // 0x00003400,
11423 PCIE_LTSSM_STATE_ConfigurationIdle : sprintf(msg, "PCIE_LTSSM_STATE_ConfigurationIdle "); // 0x00003500,
11424 PCIE_LTSSM_STATE_LoopbackEntry_Master : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackEntry_Master "); // 0x00007000,
11425 PCIE_LTSSM_STATE_LoopbackActive_Master : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackActive_Master "); // 0x00007100,
11426 PCIE_LTSSM_STATE_LoopbackExit_Master : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackExit_Master "); // 0x00007200,
11427 PCIE_LTSSM_STATE_LoopbackEntry_Slave : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackEntry_Slave "); // 0x00007400,
11428 PCIE_LTSSM_STATE_LoopbackActive_Slave : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackActive_Slave "); // 0x00007500,
11429 PCIE_LTSSM_STATE_LoopbackExit_Slave : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackExit_Slave "); // 0x00007600,
11430 PCIE_LTSSM_STATE_LoopbackExit_Idle : sprintf(msg, "PCIE_LTSSM_STATE_LoopbackExit_Idle "); // 0x00007700,
11431 PCIE_LTSSM_STATE_DetectEntry : sprintf(msg, "PCIE_LTSSM_STATE_DetectEntry "); // 0x00001000,
11432 PCIE_LTSSM_STATE_DetectQuiet : sprintf(msg, "PCIE_LTSSM_STATE_DetectQuiet "); // 0x00001100,
11433
11434
11435 PCIE_LTSSM_STATE_DisabledEntry : sprintf(msg, " PCIE_LTSSM_STATE_DisabledEntry "); // x00008000
11436 PCIE_LTSSM_STATE_Disabled : sprintf(msg, " PCIE_LTSSM_STATE_Disabled "); // x00008100
11437 PCIE_LTSSM_STATE_HotReset : sprintf(msg, " PCIE_LTSSM_STATE_HotReset "); // x0000f000
11438
11439 PCIE_LTSSM_STATE_RecoveryRcvrLock : sprintf(msg, " PCIE_LTSSM_STATE_RecoveryRcvrLock "); // x00004000
11440 PCIE_LTSSM_STATE_RecoveryRcvrCfg : sprintf(msg, " PCIE_LTSSM_STATE_RecoveryRcvrCfg "); // x00004100
11441 PCIE_LTSSM_STATE_RecoveryIdle : sprintf(msg, " PCIE_LTSSM_STATE_RecoveryIdle "); // x00004200
11442
11443 default: _REPORT_ERROR( psprintf("ep_ltssmStateToString ERROR! You Missed Try Again") );
11444 }
11445
11446 ep_ltssmStateToString = msg;
11447}
11448
11449
11450task PEUTestEnv::driveUnsupportDLLP() {
11451
11452 FNXPCIEXactorTransaction PCIEDllpTrans;
11453 bit [11:0] DLLPSeqNmbr = 0;
11454
11455 // create Nak with invalid large sequence number
11456 PCIEDllpTrans = new(Pod.FNXPCIEBldr);
11457 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
11458 PCIEDllpTrans.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_NAK;
11459 DLLPSeqNmbr = PCIEDllpTrans.MyPacket.DLLFrmSeqNum - 1;
11460 if (DLLPSeqNmbr < 12'hFEF) {
11461 PCIEDllpTrans.MyPacket.AckNakSeqNum = DLLPSeqNmbr + 12'h10;
11462 }
11463 else {
11464 PCIEDllpTrans.MyPacket.AckNakSeqNum = 12'hFFF;
11465 }
11466
11467 // inject error into this packet
11468
11469 PCIEDllpTrans.MyPacket.DenaliErr = PCIE_EI_RSRVD_TYPE;
11470 PCIEDllpTrans.MyPacket.inject_unsupport_dllp_type = 1;
11471 // env.driveUnsupportDLLP: inject_unsupport_dllp_type = %d at time %d\n", PCIEDllpTrans.MyPacket.inject_unsupport_dllp_type, get_time(LO));
11472 // drive it out
11473 PCIEDllpTrans.MyPacket.DriveImmediately = 1;
11474 PCIEDllpTrans.Drive(0);
11475
11476 activityCounter = activityCounter + 1;
11477 printf("AC: Unsupported DLLP was injected \n");
11478
11479
11480
11481}
11482
11483task PEUTestEnv::driveBadCRCDLLP() {
11484
11485 FNXPCIEXactorTransaction PCIEDllpTrans;
11486 bit [11:0] DLLPSeqNmbr = 0;
11487
11488 // create Nak with invalid large sequence number
11489 PCIEDllpTrans = new(Pod.FNXPCIEBldr);
11490 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
11491 PCIEDllpTrans.MyPacket.DllpType = FNX_PCIE_XTR_DLLP_TYPE_NAK;
11492 DLLPSeqNmbr = PCIEDllpTrans.MyPacket.DLLFrmSeqNum - 1;
11493 if (DLLPSeqNmbr < 12'hFEF) {
11494 PCIEDllpTrans.MyPacket.AckNakSeqNum = DLLPSeqNmbr + 12'h10;
11495 }
11496 else {
11497 PCIEDllpTrans.MyPacket.AckNakSeqNum = 12'hFFF;
11498 }
11499
11500
11501 // inject error into this packet
11502
11503 PCIEDllpTrans.MyPacket.DenaliErr = PCIE_EI_LCRC;
11504 // drive it out
11505 PCIEDllpTrans.MyPacket.DriveImmediately = 1;
11506 PCIEDllpTrans.Drive(0);
11507
11508 activityCounter = activityCounter + 1;
11509 printf("AC: Bad CRC DLLP was injected at time %d \n", get_time(LO));
11510
11511
11512
11513}
11514
11515
11516
11517/* N2
11518* driveduplicateSeqNmbrReq - Tell the FNXPcieXtr to send a duplicate sequence number TLP to the PEU
11519*
11520* Parameters:
11521* PktHdr - The TLP's header, in PCI-Express format
11522* DataSpec - A specification of the packet payload
11523* LenAdjust - An adjustment to the number of DWs presented to the transactor
11524* BadParity - Where should bad parity be inserted (zero=>no bad parity)
11525* Priority - Should the TLP be presented even if the ingress pipe is plugged?
11526* Abort - Should the TLP be aborted (only) before returning?
11527*
11528* NOTE: The caller is suspended until the TLP is on its way to the PEU.
11529*/
11530task PEUTestEnv::driveduplicateSeqNmbrReq(
11531 bit[PEC_PCI__HDR] PktHdr,
11532 bit [63:0] DataSpec,
11533 (integer LenAdjust=0),
11534 (integer BadParity=0),
11535 (bit Priority=0),
11536 (bit Abort=0),
11537 (bit CfgRdCpl=0),
11538 (bit isDmaReq=0) )
11539{
11540 FNXPCIEXactorTransaction PCIETlpTrans;
11541 FNXPCIEXactorTransaction PCIEDllpTrans;
11542 integer hdrLen;
11543 integer dataLen;
11544 integer xtrLen;
11545 integer tlpGap;
11546 integer pickit;
11547 integer idleChance;
11548 integer badPtyDW;
11549 integer i;
11550 bit [7:0] pyldByteAry[*];
11551 bit [11:0] SeqNmbr = 0;
11552
11553//N2 - Only need 1 report class ReportClass report = new;
11554 if (Report.get_global_print_threshold() < RPRT_DEBUG_1) {
11555 printf("AC: PEUTestEnv::driveduplicateSeqNmbrReq(PktHdr=128'h%0h, DataSpec=%0d, LenAdjust=%0d, BadParity=%0d)\n",
11556 PktHdr, DataSpec, LenAdjust, BadParity);
11557 }
11558
11559
11560 // If the ingress pipeline is suspended,
11561 // then wait for someone to unblock it.
11562 // Don't block a "priority" TLP
11563 if ( !Priority && !sync( CHECK, ev_ingressUnblocked ) )
11564 {
11565 sync( ANY, ev_drainStateEnd, ev_softReset, ev_ingressUnblocked );
11566 }
11567
11568
11569 // How big is the header and payload?
11570 hdrLen = 3 + PktHdr[PEC_PCI__FMT_4DW];
11571 if ( PktHdr[PEC_PCI__FMT_DATA] )
11572 {
11573 dataLen = PktHdr[PEC_PCI__LEN];
11574 if ( dataLen == 0 ) dataLen = 1024;
11575 }
11576 else
11577 dataLen = 0;
11578 if ( PktHdr[PEC_PCI__TD] ) dataLen = dataLen + 1;
11579
11580 // And how big is the TLP that we'll
11581 // give to the transactor?
11582 xtrLen = hdrLen + dataLen + LenAdjust;
11583 if ( xtrLen < 1 ) xtrLen = 2;
11584
11585 // Get a PCIE Transaction to give to the xactor.
11586 PCIETlpTrans = new( Pod.FNXPCIEBldr );
11587 PCIEDllpTrans = new( Pod.FNXPCIEBldr );
11588 PCIETlpTrans.SetID( f_ID.NextTransID() );
11589 PCIEDllpTrans.SetID( f_ID.NextTransID() );
11590
11591 // ...and shove in the header data,
11592 // ...and whatever payload is expected.
11593 ConvertHdr2PcieTlp( PktHdr,
11594 DataSpec,
11595 PCIETlpTrans,
11596 LenAdjust,
11597 isDmaReq);
11598
11599 //Don't adjust the payload if this is a length error being sent
11600 if ( CfgRdCpl && (PktHdr[PEC_PCI__LEN] == 1) ) //DANGER IOS FC - Do NOT execute this
11601 {
11602 //If this is a completion for a config read
11603 //Delete the data generated in ConvertHdr2PcieTlp
11604 PCIETlpTrans.MyPacket.Pyld.delete();
11605 pyldByteAry = new[4];
11606 //and put in the right byte swapped payload
11607 for(i=0; i < 4 ; i++){
11608 pyldByteAry[3-i] = DataSpec + i;
11609 }
11610 PCIETlpTrans.MyPacket.SetPyld( pyldByteAry );
11611 }
11612
11613
11614//N2 ingressThrottle - no control over idles between PEU and PTL(TLU)
11615//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11616
11617 // Add some gas to the end of the TLP.
11618 // N2 - Delay is before PCIETlpTrans gets driven
11619 tlpGap = localRandomRange(minIngressGap,maxIngressGap);
11620
11621
11622
11623
11624
11625 // The PCIETlpTrans returns when the packet is
11626 // completely driven on serial links
11627 // Don't submit the TLP if we're about to reset.
11628 // And if there is a reset pending, hang out until it happens.
11629if ( Priority )
11630printf( "Calling xtr for TLP (tag=%h)\n", PktHdr[PEC_PCI__CPL_TAG] );
11631 fork
11632 {
11633 if( !softResetPending ){
11634
11635 // modify PCIE_REG_DEN_NXT_TX_TLP_SEQ by 1
11636 SeqNmbr = PCIETlpTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ);
11637 SeqNmbr = SeqNmbr - 1;
11638 PCIETlpTrans.WriteDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ, SeqNmbr);
11639
11640
11641
11642 }else{
11643 sync( ANY, ev_softReset );
11644 }
11645 }
11646 {
11647 sync( ANY, ev_softReset, ev_removePcie );
11648 }
11649 {
11650 sync( ANY, ev_removePcie );
11651 //Mark packets still stuck in the Denali User Queue to be Discarded
11652 //PCIETlpTrans.MyPacket.DenaliErr = PCIE_EI_DISCARD;
11653 }
11654 join any
11655 activityCounter = activityCounter + 1;
11656
11657// if ( Priority )
11658// printf( "Xtr has sent priority TLP (tag=%h)\n", PktHdr[PEC_PCI__CPL_TAG] );
11659
11660/* N2 - review- Need to test this
11661 // If we just inserted bad parity into a TLP header, then the bad DW
11662 // might also appear as padding for the prior TLP.
11663 if ( BadParity != 0 && !softResetPending )
11664 {
11665 _DEBUG_MSG( "PEUTestEnv (cycle %0d) %s (offset=%0d)\n", get_cycle(),
11666 "Inject bad ingress TLP parity",
11667 BadParity > 0 ? (BadParity-1) : (xtrLen*4 + BadParity + 1) );
11668 if ( badPtyDW < 3 )
11669 this.f_DMUXtr.ignoreUnusedParity();
11670 }
11671*/
11672
11673
11674} /* end "driveduplicateSeqNmbrReq" */
11675
11676
11677
11678
11679task PEUTestEnv::Endpoint_send_FC_update(bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DLLPtype, bit [FNX_PCIE_XTR_DLLP_FC_HDR_FC_WIDTH-1:0] HdrFC, bit [FNX_PCIE_XTR_DLLP_FC_DATA_FC_WIDTH-1:0] DataFC) {
11680 FNXPCIEXactorTransaction PCIEDllpTrans;
11681 bit [FNX_PCIE_XTR_DLLP_FC_VC_WIDTH-1:0] VC_no;
11682
11683 PCIEDllpTrans = Pod.FNXPCIEEnableTrans;
11684 PCIEDllpTrans.MyPacket.PktType = FNX_PCIE_XTR_PKT_TYPE_DLLP;
11685 VC_no = PCIEDllpTrans.MyPacket.GetDllpFCVC();
11686
11687 // PCIEDllpTrans.MyPacket.SetDllpFCVC(3'b000); // setting VC = 0
11688 PCIEDllpTrans.MyPacket.SetDllpFCVC(0); // setting VC = 0
11689 VC_no = PCIEDllpTrans.MyPacket.GetDllpFCVC();
11690
11691 PCIEDllpTrans.MyPacket.DllpType = DLLPtype;
11692 PCIEDllpTrans.MyPacket.DllpFCHdrFC = HdrFC;
11693 PCIEDllpTrans.MyPacket.DllpFCDataFC = DataFC;
11694
11695 printf("AC: PCIEDllpTrans.MyPacket.DllpType = %b, PCIEDllpTrans.MyPacket.DllpFCHdrFC = %x, PCIEDllpTrans.MyPacket.DllpFCDataFC = %x \n", PCIEDllpTrans.MyPacket.DllpType, PCIEDllpTrans.MyPacket.DllpFCHdrFC, PCIEDllpTrans.MyPacket.DllpFCDataFC);
11696
11697 PCIEDllpTrans.MyPacket.DriveImmediately = 1;
11698 PCIEDllpTrans.Drive(0);
11699}
11700
11701
11702task PEUTestEnv::Monitor_Endpoint_Sent_DLLP(bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType)
11703{
11704 FNXPCIEXactorTransaction PCIEIngressDllpTrans;
11705
11706 PCIEIngressDllpTrans = new( Pod.FNXPCIEBldr );
11707 PCIEIngressDllpTrans.EnableSampleIngressDllp();
11708
11709
11710 //Start with a clean packet each time
11711 PCIEIngressDllpTrans.MyPacket.PktReset();
11712 //The SampleIngressDllp will return a copy of each DLLP packet that the FNXPCIEXtr transmits
11713 // so determine if this is a Flow Control Update or an ACK/NAK and then update
11714 // the correct environment variables
11715
11716 PCIEIngressDllpTrans.SampleIngressDllp( PCIEIngressDllpTrans.MyPacket , 5000 );
11717
11718 if( PCIEIngressDllpTrans.MyPacket.isDllpAckNak() || PCIEIngressDllpTrans.MyPacket.isDllpPM()){
11719
11720 if (DllpType == PCIEIngressDllpTrans.MyPacket.DllpType) {
11721 _DEBUG_MSG( "AC: received expected endpoint sent DllpType of %s", dllptypeToString(PCIEIngressDllpTrans.MyPacket.DllpType) );
11722 }
11723 else {
11724 _REPORT_ERROR( psprintf("PEUTestEnv::expected endpoint to send DllpType = %s, but receive DllpType = %s", dllptypeToString(DllpType), dllptypeToString(PCIEIngressDllpTrans.MyPacket.DllpType)));
11725
11726 }
11727 // PCIEIngressDllpTrans.MyPacket.AckNakSeqNum
11728
11729 }
11730
11731}
11732
11733function string PEUTestEnv::dllptypeToString( bit [FNX_PCIE_XTR_DLLP_TYPE_WIDTH-1:0] DllpType ){
11734
11735 string msg;
11736
11737 case(DllpType) {
11738
11739 FNX_PCIE_XTR_DLLP_TYPE_ACK : sprintf(msg, "ACK ");
11740 FNX_PCIE_XTR_DLLP_TYPE_NAK : sprintf(msg, "NAK ");
11741 FNX_PCIE_XTR_DLLP_TYPE_PM_ENTER_L1 : sprintf(msg, "PM_ENTER_L1 ");
11742 FNX_PCIE_XTR_DLLP_TYPE_PM_ENTER_L23 : sprintf(msg, "PM_ENTER_L23 ");
11743 FNX_PCIE_XTR_DLLP_TYPE_PM_ACTIVE_ST_REQ_L1 : sprintf(msg, "PM_ACTIVE_ST_REQ_L1 ");
11744 FNX_PCIE_XTR_DLLP_TYPE_PM_REQUEST_ACK : sprintf(msg, "PM_REQUEST_ACK ");
11745 FNX_PCIE_XTR_DLLP_TYPE_VENDOR : sprintf(msg, "VENDOR ");
11746 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC1_P : sprintf(msg, "INIT_FC1_P ");
11747 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC1_NP : sprintf(msg, "INIT_FC1_NP ");
11748 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC1_CPL : sprintf(msg, "INIT_FC1_CPL ");
11749 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC2_P : sprintf(msg, "INIT_FC2_P ");
11750 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC2_NP : sprintf(msg, "INIT_FC2_NP ");
11751 FNX_PCIE_XTR_DLLP_TYPE_INIT_FC2_CPL : sprintf(msg, "INIT_FC2_CPL ");
11752 default: _INFO_MSG("DllpType of unknown type" );
11753
11754 }
11755
11756 dllptypeToString = msg;
11757
11758}
11759
11760
11761
11762/*
11763* dmu_expect_msg - dmu is expecting A msg TLP from the ILU
11764*
11765* Parameters:
11766* f_msg = 8 bit message code, ie. PEC_PCI__TYPE_MSG
11767*/
11768task PEUTestEnv::dmu_expect_msg(
11769 bit [7:0] f_msg, // The requested message code
11770 bit [2:0] f_rc)
11771{
11772
11773 bit[PEC_PCI__HDR] ingressHdr; // The ingress TLP's header
11774 integer ingressData; // A payload descriptor
11775 bit[7:0] ingressTag; // The tag for the TLP
11776
11777 // First, get in line for a DMA tag...
11778 // f_env.allocDmaTag( ingressTag );
11779
11780 // Then build a TLP
11781 genIngressMsg( ingressTag, ingressHdr, ingressData );
11782
11783 // ingressData = 0;
11784
11785 ingressHdr[PEC_PCI__MSG_CODE] = f_msg;
11786 ingressHdr[PEC_PCI__FMT] = PEC_PCI__FMT_NO_DATA_4DW; // msg with no data
11787 ingressHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG;
11788 ingressHdr[PEC_PCI__TYPE] =
11789 ( ingressHdr[PEC_PCI__TYPE] & ~PEC_PCI__TYPE_MSG_RC_MASK )
11790 | ( f_rc & PEC_PCI__TYPE_MSG_RC_MASK );
11791 ingressHdr[PEC_PCI__TC] = 0;
11792 ingressHdr[PEC_PCI__TD] = 0;
11793 ingressHdr[PEC_PCI__EP] = 0;
11794 ingressHdr[PEC_PCI__ATTR] = 0;
11795 ingressHdr[PEC_PCI__LEN] = 0;
11796 ingressHdr[PEC_PCI__REQ_ID] = 32;
11797 ingressHdr[PEC_PCI__TLP_TAG] = 0;
11798 ingressHdr[PEC_PCI__ADDR] = 0;
11799// ingressHdr[PEC_PCI__TYPE] = PEC_PCI__TYPE_MSG;
11800
11801 printf("PEUTestEnv::dmu_expect_msg: ingressHdr[PEC_PCI__FMT] = %h, ingressHdr[PEC_PCI__TYPE] = %0h, ingressHdr[PEC_PCI__MSG_CODE] = %h \n", ingressHdr[PEC_PCI__FMT] , ingressHdr[PEC_PCI__TYPE], ingressHdr[PEC_PCI__MSG_CODE]);
11802
11803 reserveIngressCredits( ingressHdr );
11804 expectILU( ingressHdr, ingressData );
11805 consumeIngressCredits( ingressHdr );
11806 // f_env.freeDmaTag( ingressTag );
11807
11808} /* end "dmu_expect_msg" */
11809
11810task PEUTestEnv::setDenaliLaneSkew( integer lane,
11811 integer total_skew,
11812 integer bit_skew,
11813 integer bit_delay,
11814 integer symbol_delay ){
11815
11816
11817 bit[ 31:0 ] Val;
11818 bit[ FNX_PCIE_XTR_REG_DEN_WIDTH-1:0 ] denRegTmpData;
11819 FNXPCIEXactorTransaction PCIETrans;
11820 PCIETrans = new( Pod.FNXPCIEBldr );
11821
11822
11823 denRegTmpData = 0;
11824 denRegTmpData[4:0] = lane; //Lane Number
11825 denRegTmpData[6:5] = PCIE_LN_SKEW_OP_set_tx; //Operation get/set tx/rx
11826 denRegTmpData[8:7] = PCIE_LN_SKEW_total_skew; //Parameter bit_skew/bit_delay/symbol_delay
11827 denRegTmpData[31:9] = total_skew;
11828 if( total_skew ){
11829 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_LN_SKEW, denRegTmpData );
11830 }
11831
11832 denRegTmpData[8:7] = PCIE_LN_SKEW_bit_skew; //Parameter bit_skew/bit_delay/symbol_delay
11833 denRegTmpData[31:9] = bit_skew;
11834 if( bit_skew ){
11835 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_LN_SKEW, denRegTmpData );
11836 }
11837
11838 denRegTmpData[8:7] = PCIE_LN_SKEW_bit_delay; //Parameter bit_skew/bit_delay/symbol_delay
11839 denRegTmpData[31:9] = bit_delay;
11840 if( bit_delay ){
11841 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_LN_SKEW, denRegTmpData );
11842 }
11843
11844 denRegTmpData[8:7] = PCIE_LN_SKEW_symbol_delay; //Parameter bit_skew/bit_delay/symbol_delay
11845 denRegTmpData[31:9] = symbol_delay;
11846 if( symbol_delay ){
11847 PCIETrans.WriteDenaliReg( PCIE_REG_DEN_LN_SKEW, denRegTmpData );
11848 }
11849
11850 QuickReport( Report, RTYP_INFO, "setDenaliLaneSkew lane=%0d total_skew=%0d bit_skew=%0d bit_delay=%0d symbol_delay=%0d\n",lane,total_skew,bit_skew,bit_delay,symbol_delay );
11851
11852}
11853
11854
11855task PEUTestEnv::Trigger_link_Up()
11856{
11857
11858 // Get the initial credit allocations
11859 // If LinkTrainingStrategy.Check_Flow_Control_Init passes then Scenario will hold
11860 // all the correct Initial Flow Control values
11861 //Denali stores infinite credits as all 1's instead of 0
11862 ingressNonpostHdrInit = (Scenario.ilupeuInitialNonPostedHeaderCredit == 8'hff)? 0 : Scenario.ilupeuInitialNonPostedHeaderCredit;
11863 ingressPostHdrInit = (Scenario.ilupeuInitialPostedHeaderCredit == 8'hff)? 0 : Scenario.ilupeuInitialPostedHeaderCredit;
11864 ingressPostDataInit = (Scenario.ilupeuInitialPostedDataCredit == 12'hfff)? 0 : Scenario.ilupeuInitialPostedDataCredit;
11865 //These should be hardwired to infinite
11866 ingressNonpostDataInit = 0;
11867 ingressCompletionHdrInit = 0;
11868 ingressCompletionDataInit = 0;
11869
11870
11871 egressNonpostHdrInit = (Scenario.denali_FC_NPH_infinite == 1)? 0 : Scenario.denaliInitialNonPostedHeaderCredit;
11872 egressNonpostDataInit = (Scenario.denali_FC_NPD_infinite == 1)? 0 : Scenario.denaliInitialNonPostedDataCredit;
11873
11874 egressPostHdrInit = (Scenario.denali_FC_PH_infinite == 1)? 0 : Scenario.denaliInitialPostedHeaderCredit;
11875 egressPostDataInit = (Scenario.denali_FC_PD_infinite == 1)? 0 : Scenario.denaliInitialPostedDataCredit;
11876
11877 egressCompletionHdrInit = (Scenario.denali_FC_CPLH_infinite == 1)? 0: Scenario.denaliInitialCompletionHeaderCredit;
11878 egressCompletionDataInit = (Scenario.denali_FC_CPLD_infinite == 1)? 0 : Scenario.denaliInitialCompletionDataCredit;
11879
11880 Report.report(RTYP_DEBUG_3," AC: egressNonpostHdrInit = %d \n", egressNonpostHdrInit);
11881 Report.report(RTYP_DEBUG_3," AC: egressNonpostDataInit = %d \n", egressNonpostDataInit);
11882 Report.report(RTYP_DEBUG_3," AC: egressPostHdrInit = %d \n",egressPostHdrInit );
11883 Report.report(RTYP_DEBUG_3," AC: egressPostDataInit = %d \n", egressPostDataInit);
11884 Report.report(RTYP_DEBUG_3," AC: egressCompletionHdrInit = %d \n",egressCompletionHdrInit );
11885 Report.report(RTYP_DEBUG_3," AC: egressCompletionDataInit = %d \n", egressCompletionDataInit);
11886
11887 trigger( ON, ev_linkUp );
11888 Report.report(RTYP_INFO,"Env:linkUp ilupeu linkup \n");
11889
11890}
11891
11892task PEUTestEnv::skewRxClockMax( bit enabled )
11893{
11894//Symbol Parameter Min Nom Max Units Comments
11895//UI Unit Interval 399.88 400 400.12 ps Each UI is 400 ps +/-300 ppm.
11896
11897 if( enabled ){
11898 //Set Denali clock to -600ppm
11899 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.74 ps");
11900
11901 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 399.78 ps");
11902 }else{
11903 //Set back to default clock
11904 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.99 ps");
11905
11906 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.01 ps");
11907 }
11908}
11909
11910task PEUTestEnv::skewRxClockMin( bit enabled )
11911{
11912//Symbol Parameter Min Nom Max Units Comments
11913//UI Unit Interval 399.88 400 400.12 ps Each UI is 400 ps +/-300 ppm.
11914
11915 if( enabled ){
11916 //Set Denali clock to -600ppm
11917 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.22 ps");
11918
11919 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.26 ps");
11920 }else{
11921 //Set back to default clock
11922 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.99 ps");
11923
11924 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.01 ps");
11925 }
11926}
11927
11928task PEUTestEnv::driftRxClock( bit enabled )
11929{
11930//Since the PEU clock is stable we can drift the Denali clock +/-600ppm
11931//Symbol Parameter Min Nom Max Units Comments
11932//UI Unit Interval 399.88 400 400.12 ps Each UI is 400 ps +/-300 ppm.
11933 driftRxClockEnabled = enabled;
11934
11935 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.10 ps");
11936 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.14 ps");
11937
11938 fork
11939 {
11940 while( driftRxClockEnabled ){
11941 if( driftRxClockEnabled ){
11942 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.22 ps");
11943 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.26 ps");
11944 }
11945 if( driftRxClockEnabled ){
11946 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11947 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.10 ps");
11948 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.14 ps");
11949 }
11950 if( driftRxClockEnabled ){
11951 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11952 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.01 ps");
11953 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.03 ps");
11954 }
11955 if( driftRxClockEnabled ){
11956 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11957 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.86 ps");
11958 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 399.90 ps");
11959 }
11960 if( driftRxClockEnabled ){
11961 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11962 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.74 ps");
11963 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 399.78 ps");
11964 }
11965 if( driftRxClockEnabled ){
11966 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11967 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.82 ps");
11968 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 399.88 ps");
11969 }
11970 if( driftRxClockEnabled ){
11971 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11972 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.97 ps");
11973 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 399.99 ps");
11974 }
11975 if( driftRxClockEnabled ){
11976 repeat( urandom_range(250, 100) ) @(posedge CLOCK);
11977 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 400.08 ps");
11978 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.12 ps");
11979 }
11980 }
11981
11982 //Set back to default clock
11983 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImin 399.99 ps");
11984
11985 void = DenaliDDVTclEval("mmsomaset tb_top.pcieA ttxUImax 400.01 ps");
11986 }
11987 join none
11988}
11989
11990task PEUTestEnv::start_Denali_DTM()
11991{
11992
11993 integer ui_delay = 0;
11994 integer nmbr_clk_symbls = 250;
11995 integer nmbr_fts_symbls = 50;
11996
11997 // 10/17/06
11998 // Needed to force Denali to stay in L0
11999 FNXPCIEXactorTransaction PCIEXtrTrans;
12000 PCIEXtrTrans = new( Pod.FNXPCIEBldr );
12001
12002 //Take Denali out of reset
12003 Pod.FNXPCIEEnableTrans.SetDenaliReset( 1'b0 );
12004 printf("After SetDenaliReset( 1'b0 )\n");
12005
12006
12007 // 10/17/06
12008 //Added so fullchip did not need to reprogram the PEU skip interval timer
12009
12010 fork
12011 wait( 1800, 1); //Wait for 500 cycles and turn off Hang Detect
12012 {
12013 @(posedge CLOCK);
12014 @(posedge CLOCK);
12015 //Wait until LTSSM = L0
12016 to_endpoint_LtssmState(PCIE_LTSSM_STATE_L0,100);
12017
12018 printf("Starting forcing to L0 until PEU sends 1st COM \n");
12019 repeat(1800){
12020 //Keep forcing to L0 until PEU sends 1st COM
12021 PCIEXtrTrans.WriteDenaliReg( PCIE_REG_DEN_LINK_CTRL, 32'h800 );
12022 @(posedge CLOCK);
12023
12024 }
12025 printf("Finishing forcing Denali to L0 until after PEU sends 1st COM SKIP \n");
12026 }
12027 join none
12028
12029
12030 //Disable all Denali Errors
12031 Pod.FNXPCIEEnableTrans.SuppressDenaliErr( PCIE_NO_ERROR );
12032
12033 //Don't transmit a SKIP ordered set first
12034 Pod.FNXPCIEEnableTrans.WriteDenaliReg( PCIE_REG_DEN_TX_SKIP_SETS, 0 );
12035
12036
12037// AT+ DTM 104MHz, instead of 100MHz, copied from
12038// /import/n2-svl-localdir6/somePerson/work1/verif/diag/vera/ilu_peu/src/directed/ilupeux8x8DTM.vr
12039
12040//Change Denalis Timing to be 9.6ns(104MHz) instead of 4ns(250MHz)
12041 Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttoPollSpeed 960.01 ps ");
12042 Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxUImin 959.99 ps ");
12043 Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxUImax 960.01 ps ");
12044 Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxLaneSKEWmax 3000 ps ");
12045 Change_soma_parameters_ac("mmsomaset tb_top.pcieA trxUImin 959.99 ps ");
12046 Change_soma_parameters_ac("mmsomaset tb_top.pcieA trxUImax 960.01 ps ");
12047
12048// AT- DTM 104: //Change Denalis Timing to be 10ns(100MHz) instead of 4ns(250MHz)
12049// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttoPollSpeed 1000.01 ps ");
12050// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxUImin 999.99 ps ");
12051// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxUImax 1000.01 ps ");
12052// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA ttxLaneSKEWmax 3000 ps ");
12053// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA trxUImin 999.99 ps ");
12054// AT- DTM 104: Change_soma_parameters_ac("mmsomaset tb_top.pcieA trxUImax 1000.01 ps ");
12055 printf("After Change_soma_parameters_ac \n");
12056
12057// repeat( 10 ) @(posedge CLOCK);
12058
12059
12060 if( get_plus_arg( CHECK, "PEU_DTM_PCIE_SKEW_LANE0_UI=" ) ){
12061
12062 ui_delay = get_plus_arg( NUM, "PEU_DTM_PCIE_SKEW_LANE0_UI=" );
12063 printf(" XXXXXXXXXXX PEU_DTM_PCIE_SKEW_LANE0_UI ui_delay=%0d \n",ui_delay);
12064 ui_delay = ui_delay + 1; //Denalis format?
12065 //Set a 10ui delay for lane 0
12066 setDenaliLaneSkew( 0, 960000, 000000, ui_delay, 0 ); // delay lane 0
12067 }
12068
12069 //Set Denali replay timer really high so there are no Replays
12070 Pod.FNXPCIEEnableTrans.WriteDenaliReg( PCIE_REG_DEN_REPLAY_TIMER, 64'hffff );
12071 //Set Denali replay buffer really big to hold all transactions set
12072 Pod.FNXPCIEEnableTrans.WriteDenaliReg( PCIE_REG_DEN_RETRY_SIZE, 64'hfffff );
12073
12074 if( get_plus_arg( CHECK, "PEU_DTM_NMBR_CLK_SYMBLS=" ) ){
12075
12076 nmbr_clk_symbls = get_plus_arg( NUM, "PEU_DTM_NMBR_CLK_SYMBLS=" );
12077 printf(" XXXXXXXXXXX PEU_DTM_NMBR_CLK_SYMBLS nmbr_clk_symbls=%0d \n",nmbr_clk_symbls);
12078 }
12079 //Data D21.5=xb5 is alternating 1's & 0's to allow bit lock to happen first
12080 repeat( nmbr_clk_symbls/250 ){
12081 Pod.FNXPCIEEnableTrans.Transmit_symbol_ToLink(250, 9'h0b5);
12082 printf("After calling send D21.5=xb5 clock pattern \n");
12083
12084 repeat( 250 ) @( posedge CLOCK );
12085 printf("After send D21.5=xb5 clock pattern delay\n");
12086 }
12087
12088 Pod.FNXPCIEEnableTrans.Transmit_symbol_ToLink(nmbr_clk_symbls%250, 9'h0b5);
12089 printf("After calling final send D21.5=xb5 clock pattern \n");
12090
12091 repeat( nmbr_clk_symbls%250 ) @( posedge CLOCK );
12092 printf("After final send D21.5=xb5 clock pattern delay\n");
12093
12094
12095 if( get_plus_arg( CHECK, "PEU_DTM_NMBR_FTS_SYMBLS=" ) ){
12096
12097 nmbr_fts_symbls = get_plus_arg( NUM, "PEU_DTM_NMBR_FTS_SYMBLS=" );
12098 printf(" XXXXXXXXXXX PEU_DTM_NMBR_FTS_SYMBLS nmbr_fts_symbls=%0d \n",nmbr_fts_symbls);
12099 }
12100 //Request Denali to send # of FTS-Fast Training Sequences
12101 repeat( nmbr_fts_symbls/50 ){
12102 Pod.FNXPCIEEnableTrans.TransmitFTSToLink( 50 );
12103 printf("After send # of FTS-Fast \n");
12104 repeat( 50 * 4 ) @( posedge CLOCK );
12105 }
12106 Pod.FNXPCIEEnableTrans.TransmitFTSToLink( nmbr_fts_symbls%50 );
12107 Pod.FNXPCIEEnableTrans.TransmitSKPToLink( 1 );
12108
12109 repeat( (nmbr_fts_symbls%50) * 4 ) @( posedge CLOCK );
12110 printf("After final send fts pattern delay\n");
12111
12112
12113
12114 // 10/17/06
12115 //Wait for the force Denali to L0 loop to complete
12116 wait_child();
12117
12118}
12119