Commit | Line | Data |
---|---|---|
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 ============================================ | |
35 | class 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 */ |