| 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 */ |