Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2str / ilupeuReplayPEUStr.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ilupeuReplayPEUStr.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 ============================================
35class ReplayPEUStr extends PEUStrBase
36 {
37 integer f_errQueue; // A mailbox for bad pkt headers
38 string f_typeReplay; // The replay type nak/timeout
39 bit f_typeSpecified; // Was a type specified?
40 integer f_nmbrReplays; // The number of replays to cause
41 // 1-3 are normal
42 // 4 will cause link to retrain
43 bit f_nmbrReplaysSpecified; // Was number of replays specified?
44 integer f_nmbrTlpsRplyBfr; // Number of TLPs in replay buffer before sending NAK
45 bit f_nmbrTlpsRplyBfrSpecified; // Was number of TLPs in replay specified?
46 bit f_restartAck; // restart the ACKs from Denali after replay timeout
47
48 //Only allow 1 of these strategies to be active at a time
49 static integer myturn_semaphore = alloc(SEMAPHORE, 0, 1, 1);
50
51 task new( PEUTestEnv a_env )
52 {
53 super.new( a_env );
54 f_errQueue = 0;
55 f_nmbrReplaysSpecified = 0;
56 f_nmbrTlpsRplyBfrSpecified = 0;
57 f_typeSpecified = 0;
58 f_restartAck = 1;
59 }
60
61 task SetErrQueue( integer a_queue )
62 {
63 f_errQueue = a_queue;
64 }
65
66 task SetType( string a_typeReplay )
67 {
68 f_typeReplay = a_typeReplay;
69 f_typeSpecified = 1;
70 }
71
72 task SetNmbrReplays( integer a_nmbrReplays )
73 {
74 f_nmbrReplays = a_nmbrReplays;
75 f_nmbrReplaysSpecified = 1;
76 }
77
78 task SetNmbrTlpsRplyBfr( integer a_nmbrTlpsRplyBfr )
79 {
80 f_nmbrTlpsRplyBfr = a_nmbrTlpsRplyBfr;
81 f_nmbrTlpsRplyBfrSpecified = 1;
82 }
83
84 task SetRestartAck( integer a_restartAck )
85 {
86 f_restartAck = a_restartAck;
87 }
88
89 task Execute(){
90 integer seqNmbrNak = 0;
91 integer loop = 0;
92 integer cntr;
93 bit[63:0] replay_timer_csr;
94 bit[15:0] replay_timer;
95 bit[1:0] replay_count;
96 bit[15:0] replay_timer_threshold;
97
98 //Get the semaphore when its your turn
99 semaphore_get( WAIT, myturn_semaphore, 1);
100
101 if( !f_typeSpecified ){
102 randcase
103 {
104 10 : { f_typeReplay = "nak"; }
105 1 : { f_typeReplay = "timeout"; }
106 }
107 }
108 //If no length is specified then only allow up to 3 replays so as not to
109 // cause a link retraining
110 if( !f_nmbrReplaysSpecified && f_typeReplay == "nak" ){
111 //Since no error bits are set for NAK replays 1-3 can occur
112 randcase
113 {
114 1 : f_nmbrReplays = 1;
115 1 : f_nmbrReplays = 2;
116 1 : f_nmbrReplays = 3;
117 }
118 }
119 else if( !f_nmbrReplaysSpecified && f_typeReplay == "timeout" ){
120 //Since timeouts set an error bit the ErrorChk Strategy needs to
121 // know how many take place, so if its not specified at the test
122 // level then set to only 1
123 f_nmbrReplays = 1;
124 }
125
126 //Allow only the max of 4 replays since this will cause a retraining
127 if( f_nmbrReplaysSpecified && f_nmbrReplays > 4 ){
128 f_nmbrReplays = 4;
129 }
130
131 //If nmbrTlpsRplyBfr is not set then lets just try between 5 and 20
132 if( !f_nmbrTlpsRplyBfrSpecified ){
133 f_nmbrTlpsRplyBfr = urandom_range( 20, 5 );
134 }
135
136 //If the f_typeSpecified is not valid then just set it to a nak
137 if( f_typeSpecified ){
138 if( f_typeReplay != "nak" && f_typeReplay != "timeout" ){
139
140 f_typeReplay = "nak";
141 }
142 }
143
144 //Turn off the Denali auto generated ACKs
145 f_env.disableDenaliAcks();
146 f_env.activityStalled += 1; //Stall the hangDetect since we could be doing replays
147
148 //Allow disabling of ACKs to propagate through testbench
149 repeat(2) @(posedge if_ILU_PEU_PCIE.refclk);
150
151 replay_timer_threshold = ( (f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_tim_thresh )) ) + (4*f_env.Scenario.ilupeuLtssmNFTS) );
152
153
154 //Loop for the number of replays specified
155 for( loop = 0; loop < f_nmbrReplays ; loop++ ){
156
157 f_env.Report.report(RTYP_INFO,"ReplayPEUStr loop=%0d f_nmbrReplays=%0d \n",loop,f_nmbrReplays);
158
159 //Loop for NAK replays
160 if( f_typeReplay == "nak" ){
161 //If this is a nak then Wait till the number of tlps to be replayed is
162 // met or the replay buffer is full
163 fork
164 {
165 f_env.waitRetryCreditsExhausted();
166 printf("ReplayPEUStr Replay Buffer is FULL!!!!\n");
167 }
168 {
169 while( f_env.getNmbrTlpsReplayBuffer() < f_nmbrTlpsRplyBfr ){
170 f_env.Report.report(RTYP_INFO,"ReplayPEUStr f_env.nmbrTlpsReplayBuffer=%0d < f_nmbrTlpsRplyBfr=%0d while loop\n",f_env.getNmbrTlpsReplayBuffer(),f_nmbrTlpsRplyBfr);
171 repeat(10) @(posedge if_ILU_PEU_PCIE.refclk);
172 }
173 printf("ReplayPEUStr f_env.nmbrTlpsReplayBuffer=%0d < f_nmbrTlpsRplyBfr=%0d done\n",f_env.getNmbrTlpsReplayBuffer(),f_nmbrTlpsRplyBfr);
174 }
175 {
176
177 repeat(2500) @(posedge if_ILU_PEU_PCIE.refclk);
178 f_env.Report.report(RTYP_TEST_ERROR,"ReplayPEUStr takes longer then 2500 cycles to fill replay buffer f_env.getNmbrTlpsReplayBuffer=%0d f_nmbrTlpsRplyBfr=%0d \n",f_env.getNmbrTlpsReplayBuffer(),f_nmbrTlpsRplyBfr );
179 }
180 join any
181 terminate; //Kill the child processes that don't finish 1st
182
183 f_env.Report.report(RTYP_INFO,"ReplayPEUStr finished first fork loop=%0d\n",loop);
184
185 if( f_nmbrReplays >= 4 ){
186 seqNmbrNak = f_env.AckdSeqNum; //Just NAK the same Seq Number
187 }else if( f_nmbrReplays == 1 || loop == f_nmbrReplays-1){
188 //If the number of replays is 1 then we can either clear the replay buffer
189 randcase{
190 2: seqNmbrNak = (f_env.egressNextTransmitSeqNum - 1)%4096; //Clear the replay buffer
191 1: { if( (f_env.AckdSeqNum%4096) == (f_env.egressNextTransmitSeqNum - 1)%4096 ){
192 seqNmbrNak = f_env.AckdSeqNum%4096; //Just replay from the oldest TLP
193 }else{
194 seqNmbrNak = (f_env.AckdSeqNum + 1)%4096;
195 }
196 }
197 1: { if( f_env.egressNextTransmitSeqNum%4096 > f_env.AckdSeqNum%4096 ){
198 seqNmbrNak = urandom_range( (f_env.egressNextTransmitSeqNum - 1)%4096, (f_env.AckdSeqNum + 1)%4096 ); //Replay some of the TLPs
199 }else{ //Special case some rollover ACK seq numbers
200 if( f_env.egressNextTransmitSeqNum%4096 == 0 ){
201 seqNmbrNak = urandom_range( 4095 , (f_env.AckdSeqNum + 1)%4096 );
202 }
203 else if( f_env.egressNextTransmitSeqNum%4096 >= 1 )
204 randcase{
205 2: seqNmbrNak = urandom_range( 4095 , (f_env.AckdSeqNum + 1)%4096 );
206
207 1: seqNmbrNak = urandom_range( (f_env.egressNextTransmitSeqNum - 1)%4096, 0 );
208 }
209 }
210 }
211 }
212 }
213 else{
214 //Don't clear the replay buffer
215 randcase{
216 1: { if( (f_env.AckdSeqNum%4096) == (f_env.egressNextTransmitSeqNum - 1)%4096 ){
217 seqNmbrNak = f_env.AckdSeqNum%4096; //Just replay from the oldest TLP
218 }else{
219 seqNmbrNak = (f_env.AckdSeqNum + 1)%4096;
220 }
221 }
222 1: { if( f_env.egressNextTransmitSeqNum%4096 > f_env.AckdSeqNum%4096 ){
223 seqNmbrNak = urandom_range( (f_env.egressNextTransmitSeqNum - 1)%4096, (f_env.AckdSeqNum + 1)%4096 ); //Replay some of the TLPs
224 }else{ //Special case some rollover ACK seq numbers
225 if( f_env.egressNextTransmitSeqNum%4096 == 0 ){
226 seqNmbrNak = urandom_range( 4094 , (f_env.AckdSeqNum + 1)%4096 );
227 }
228 else if( f_env.egressNextTransmitSeqNum%4096 >= 1 ){
229 randcase{
230 2: { if( ((f_env.AckdSeqNum + 1)%4096 ) == 0 ){
231 randcase{
232 3: seqNmbrNak = 4095;
233 1: seqNmbrNak = 0;
234 }
235 }else{
236 seqNmbrNak = urandom_range( 4095 , (f_env.AckdSeqNum + 1)%4096 );
237 }
238 }
239
240 1: seqNmbrNak = urandom_range( (f_env.egressNextTransmitSeqNum - 1)%4096, 0 );
241 }
242 }
243 }
244 }
245
246 }
247 }
248
249 f_env.Report.report(RTYP_INFO,"ReplayPEUStr checking the replay time\n");
250
251 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
252 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
253
254 //If replay_timer is = 0 then it hasn't started replaying
255 while( replay_timer == 0 ){
256 repeat(10) @( posedge if_ILU_PEU_PCIE.refclk );
257 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
258 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
259 }
260 //replay timer should be less then replay timeout threshold
261 if( replay_timer >= replay_timer_threshold ){
262 f_env.Report.report(RTYP_TEST_ERROR,"ReplayPEUStr replay_timer >= replay_timer_threshold for NAK test \n");
263 }
264// if( replay_timer >= f_env.Scenario.ilupeuReplayTimerThreshold ){
265// f_env.Report.report(RTYP_TEST_ERROR,"ReplayPEUStr replay_timer >= f_env.Scenario.ilupeuReplayTimerThreshold for NAK test \n");
266// }
267 printf("ReplayPEUStr send a NAK seqNmbrNak=%0d f_env.egressNextTransmitSeqNum=%0d f_env.AckdSeqNum=%0d\n",seqNmbrNak,f_env.egressNextTransmitSeqNum,f_env.AckdSeqNum );
268 //Send the NAK
269 f_env.sendNak( seqNmbrNak );
270
271 //Replay Timer will only reset if not on the middle of a replay already
272 //We shouldn't be in a replay so timer should reset to 0
273 //Replay timer should be running so check it and then wait until it
274 // resets to 0 which means the NAK has been received and TLPs have
275 // been acknowledged
276 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
277 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
278 cntr = 50; //review - adjust for lane width
279 while( replay_timer != 0 && cntr ){
280 @( posedge if_ILU_PEU_PCIE.refclk );
281 cntr--;
282 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
283 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
284 }
285
286 if( !cntr && f_nmbrReplays < 4 && loop == 0 ){
287 f_env.Report.report(RTYP_TEST_ERROR,"ReplayPEUStr replay_timer not set to 0 after NAK sent loop = 0\n");
288 }
289 else if( !cntr && (loop > 0) ){
290 //If loop 1, 2 or 3 then we could be in the middle
291 // of the previous replay already so wait until replay
292 // timer goes back to 0 which means previuos replay
293 // is over and the NAK is being processed
294 cntr = 2000; //Longest time a replay should take //review - adjust for lane width
295 while( replay_timer != 0 && cntr ){
296 f_env.Report.report(RTYP_INFO,"waiting for replay timer\n");
297 @( posedge if_ILU_PEU_PCIE.refclk );
298 cntr--;
299 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
300 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
301 }
302 if( !cntr ){
303 f_env.Report.report(RTYP_TEST_ERROR,"ReplayPEUStr replay_timer not set to 0 after NAK sent loop > 0 \n");
304 }
305
306 }
307
308 f_env.Report.report(RTYP_INFO,"ReplayPEUStr going to the error section\n");
309
310 //Check the replay number to make sure a replay starts if needed -N2 - review
311//FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC
312//FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_REPLAY_NUM_SLC
313 //Set the replay rollover errors to expect
314 // There are no errors for a NAK
315 if( f_errQueue != 0 && f_nmbrReplays >= 4 && loop == 3){
316
317 f_env.Report.report(RTYP_INFO,"got in the replay nak loop\n");
318
319 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
320 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
321 mailbox_put( f_errQueue, e_ERR_ce_rnr );
322 mailbox_put( f_errQueue, 128'bx ); //No header to check for this
323// if( replay_timer >= f_env.Scenario.ilupeuReplayTimerThreshold )
324 if( replay_timer >= replay_timer_threshold ){
325 mailbox_put( f_errQueue, e_ERR_ce_rto );
326 mailbox_put( f_errQueue, 128'bx ); //No header to check for this
327 }
328
329 if (!f_restartAck) {
330 f_env.Report.report(RTYP_INFO,"Sending over parity errors\n");
331 mailbox_put( f_errQueue, e_ERR_oe_erp );
332 mailbox_put( f_errQueue, 128'hx);
333 }
334
335
336 //Disable Interrupts here because when Denali transitions to
337 // recovery it can cut of the end of a TLP causing TLP with no END
338 // and Bad TLP error because of dab CRC
339 f_env.disableInterrupt();
340 printf("\n---------- f_env.disableInterrupt() called in ReplayPEUStr---------- \n");
341
342 }
343
344 repeat(urandom_range(50, 30) ) @( posedge if_ILU_PEU_PCIE.refclk );
345
346 } //End f_typeReplay == "nak"
347 f_env.Report.report(RTYP_INFO,"ReplayPEUStr done nak loop\n");
348 //Loop for timeout replays
349 if( f_typeReplay == "timeout" ){
350 f_env.Report.report(RTYP_INFO,"Got in the timeout loop\n");
351 //Since ACKs are disabled just wait for the replay timeout time
352 // and check the replay counter
353 //Delay to let the last ACK sent propogate if needed
354 repeat( 20 ) @( posedge if_ILU_PEU_PCIE.refclk );
355 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
356 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
357 //
358// replay_timer_threshold = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_tim_thresh ) );
359 replay_timer_threshold = ( (f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_tim_thresh )) ) + (4*f_env.Scenario.ilupeuLtssmNFTS) );
360
361 printf("ReplayPEUStr f_typeReplay=timeout replay_timer_threshold=%0d Scenario.ilupeuReplayTimerThreshold=%0d \n",replay_timer_threshold,f_env.Scenario.ilupeuReplayTimerThreshold );
362 repeat( replay_timer_threshold - replay_timer ) @( posedge if_ILU_PEU_PCIE.refclk );
363
364 replay_timer_csr = f_env.readCSRdirect( f_env.getCSRaddr( e_CSR_replay_timer ) );
365 replay_timer = replay_timer_csr[FIRE_PLC_TLU_CTB_TLR_CSR_A_REPLAY_TIMER_RPLAY_TMR_SLC];
366
367 //Let the timeout propogate
368 repeat( 15 ) @( posedge if_ILU_PEU_PCIE.refclk );
369 //Wait until the retry counter increments -N2 - review
370
371 //Set the replay timeout errors to expect
372 // There are no errors for a NAK
373 if( f_errQueue != 0 && f_typeReplay == "timeout"){
374
375 f_env.Report.report(RTYP_INFO,"checking errors in the timeout loop\n");
376 //Let the Error Check know that this stratgy will produce more
377 // then 1 error
378 if( loop === 0 && f_nmbrReplays > 1 ){
379 mailbox_put( f_errQueue, e_ERR_none );
380 mailbox_put( f_errQueue, f_nmbrReplays );
381 }
382
383 mailbox_put( f_errQueue, e_ERR_ce_rto );
384 mailbox_put( f_errQueue, 128'bx ); //No header to check for this
385 if (!f_restartAck) {
386 f_env.Report.report(RTYP_INFO,"sending parity error in timeout loop\n");
387 mailbox_put( f_errQueue, e_ERR_oe_erp );
388 mailbox_put( f_errQueue, 128'hx);
389 }
390 }
391 } //End f_typeReplay == "timeout"
392 f_env.Report.report(RTYP_INFO,"ReplayPEUStr done timeout loop\n");
393 if (!f_restartAck) {
394 f_env.Report.report(RTYP_INFO,"ReplayPEUStr sending parity error in no loop\n");
395 mailbox_put( f_errQueue, e_ERR_oe_erp );
396 mailbox_put( f_errQueue, 128'hx);
397 }
398
399 } //End for loop
400
401 //Turn the Denali auto generated ACKs back on and since the
402 // replay timer has already reset to 0 the replay has started
403 if (f_restartAck) {
404 f_env.Report.report(RTYP_INFO,"ReplayPEUStr enabling acks\n");
405 f_env.enableDenaliAcks();
406 f_env.activityStalled -= 1;
407 }
408
409 if( f_errQueue != 0 && f_nmbrReplays >= 4 && loop == 4){
410 //Exit quickly to catch link retraining
411 }else{
412 //We have to make sure the Replay is done but not timeout so...
413 repeat( f_env.Scenario.ilupeuReplayTimerThreshold - 50 ) @( posedge if_ILU_PEU_PCIE.refclk );
414 }
415
416 semaphore_put( myturn_semaphore, 1 );
417
418 printf("ReplayPEUStr FINISHED!!!\n");
419 } /* end Execute */
420 } /* end TimeOutPEUStr */