Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2str / ilupeuIngressRcvrErr.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: ilupeuIngressRcvrErr.vr
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
//
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
//
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
//
// ========== Copyright Header End ============================================
class IngressRcvrErr extends PEUStrBase
{
integer f_errQueue; // A mailbox for bad pkt headers
integer nmbrRcvrErrsToInject = 10; //Total number of packets that get error injected
integer rcvrErrPct = 10; //% of packets that get an error
//Set the percentage weight of each type of receiver error
integer rcvrErr8b10bWeight = 10;
integer rcvrErrFramingWeight = 10;
integer rcvrErrDisparityWeight = 10;
integer rcvrErrFlipBitWeight = 10; //This is sometimes a CRC error - If the STP gets flipped
// into a data bit then a CRC error isn't hit
integer rcvrErrLcrcWeight = 10; //This is a CRC error
integer rcvrErrDupSeqNmbrWeight = 0;
integer rcvrErrOutOfSeqNmbrWeight = 0;
integer rcvrErrBadSeqNmbrWeight = 0;
integer InvertLCRCErrWeight = 0;
integer EDBErrWeight = 0;
integer InvertLCRCAndEDBErrWeight = 0;
//
integer invertLCRC32ErrInjected = 0;
integer EDBErrInjected = 0;
integer InvertLCRCAndEDBErrInjected = 0;
//Make the Bad TLP Packet error optional-directed cases
//Only rcvrErrFlipBitWeight & rcvrErrLcrcWeight are certain BTP errors
// and all others are due to sequence errors, So make the default optional
// except for rcvrErrFlipBitWeight & rcvrErrLcrcWeight
bit optional_CE_BTP = 1;
//Only allow 1 of these strategies to be active at a time
static integer rcvrErr_semaphore = alloc(SEMAPHORE, 0, 1, 1);
task new( PEUTestEnv a_env )
{
super.new( a_env );
f_errQueue = 0;
}
task SetErrQueue( integer a_queue )
{
f_errQueue = a_queue;
} /* end SetErrQueue */
task Execute()
{
integer nmbrErrs;
integer other_nonInvertLCRCAndEDBErrInjected = 0 ;
integer denaliReplayTimer;
bit recoveryEntered = 0;
//Get the semaphore when its your turn
semaphore_get( WAIT, rcvrErr_semaphore, 1);
//
optional_CE_BTP = 1;
//Change Denalis replay timer to take out rx_L0s_adj=250
denaliReplayTimer = f_env.Scenario.denaliReplayTimerThreshold - 250;
f_env.Pod.FNXPCIEEnableTrans.WriteDenaliReg( PCIE_REG_DEN_REPLAY_TIMER, denaliReplayTimer );
//Make the replay buffer smaller so back-back replays don't last too long
f_env.Pod.FNXPCIEEnableTrans.WriteDenaliReg( PCIE_REG_DEN_RETRY_SIZE, 32'h300 );
printf("IngressRcvrErr nmbrRcvrErrsToInject=%0d rcvrErrPct=%0d rcvrErr8b10bWeight=%0d rcvrErrFramingWeight=%0d rcvrErrDisparityWeight=%0d rcvrErrFlipBitWeight=%0d rcvrErrLcrcWeight=%0d rcvrErrDupSeqNmbrWeight=%0d rcvrErrOutOfSeqNmbrWeight=%0d rcvrErrBadSeqNmbrWeight=%0d InvertLCRCErrWeight=%0d EDBErrWeight=%0d InvertLCRCAndEDBErrWeight=%0d \n",nmbrRcvrErrsToInject,rcvrErrPct,rcvrErr8b10bWeight,rcvrErrFramingWeight,rcvrErrDisparityWeight,rcvrErrFlipBitWeight,rcvrErrLcrcWeight, rcvrErrDupSeqNmbrWeight, rcvrErrOutOfSeqNmbrWeight, rcvrErrBadSeqNmbrWeight, InvertLCRCErrWeight, EDBErrWeight, InvertLCRCAndEDBErrWeight );
//Set the number of packets to cause errors on
f_env.nmbrRcvrErrsToInject = nmbrRcvrErrsToInject;
f_env.nmbrRcvrErrsInjected = 0;
f_env.nmbrRcvrErrsDriven = 0;
f_env.rcvrErrPct = rcvrErrPct;
//Set the percentage of each type of receiver error
f_env.rcvrErr8b10bWeight = rcvrErr8b10bWeight;
f_env.rcvrErrFramingWeight = rcvrErrFramingWeight;
f_env.rcvrErrDisparityWeight = rcvrErrDisparityWeight;
f_env.rcvrErrFlipBitWeight = rcvrErrFlipBitWeight;
f_env.rcvrErrLcrcWeight = rcvrErrLcrcWeight;
f_env.rcvrErrDupSeqNmbrWeight = rcvrErrDupSeqNmbrWeight;
f_env.rcvrErrOutOfSeqNmbrWeight = rcvrErrOutOfSeqNmbrWeight;
f_env.rcvrErrBadSeqNmbrWeight = rcvrErrBadSeqNmbrWeight;
f_env.InvertLCRCErrWeight = InvertLCRCErrWeight;
f_env.EDBErrWeight = EDBErrWeight;
f_env.InvertLCRCAndEDBErrWeight = InvertLCRCAndEDBErrWeight;
//Clear all the specific error trackers
f_env.rcvrErr8b10bInjected = 0;
f_env.rcvrErrFramingInjected = 0;
f_env.rcvrErrDisparityInjected = 0;
f_env.rcvrErrFlipBitInjected = 0;
f_env.rcvrErrLcrcInjected = 0;
f_env.rcvrErrDupSeqNmbrInjected = 0;
f_env.rcvrErrOutOfSeqNmbrInjected = 0;
f_env.rcvrErrBadSeqNmbrInjected = 0;
f_env.invertLCRC32ErrInjected = 0;
f_env.EDBErrInjected = 0;
f_env.InvertLCRCAndEDBErrInjected = 0;
//Wait until env has injected the right number of errors
f_env.enableRcvrErrInjection = 1;
//If the last Tlp before a retry packet has a framing type error then the
// 1st retry packet could get a crc or other error causing the packet to be
// dropped. This will cause a Denali replay timeout
f_env.Pod.FNXPCIEEnableTrans.SuppressDenaliErr( PCIE_DL_COR_REPLAY_TIMEOUT );
//Framing error injection could insert a COM which causes peu to get a deskew error
// and go into recovery - so disable hang detect for framing errors
if( f_env.rcvrErrFramingWeight ){
fork
{
while( f_env.rcvrErrFramingWeight && !f_env.rcvrErrFramingInjected ){
repeat(10) @(posedge CLOCK);
}
//Check to see if recovery is ever entered
while( f_env.getLtssmState() === ILUPEU_LTSSM_L0 &&
f_env.enableRcvrErrInjection ){
repeat(50) @(posedge CLOCK);
if( f_env.getLtssmState() === ILUPEU_LTSSM_RCVRY_RCVRLOCK ){
recoveryEntered = 1;
f_env.activityStalled += 1;
//Stall the Denali expects until link comes back up
f_env.Pod.FNXPCIEEnableTrans.DisableExpectsTimeout();
printf("IngressRcvrErr rcvrErrFramingInjected and ltssm entered Recovery f_env.activityStalled=%0d \n",f_env.activityStalled );
f_env.toLtssmState( ILUPEU_LTSSM_L0 );
printf("IngressRcvrErr rcvrErrFramingInjected and ltssm entered L0 from Recovery\n");
f_env.activityStalled -= 1;
f_env.Pod.FNXPCIEEnableTrans.EnableExpectsTimeout();
}
}
}
join none
}
//Wait until all the errors are driven
sync( ANY, f_env.ev_rcvrErrsDriven );
//terminate the while loop if no framing errors got injected
if( f_env.rcvrErrFramingWeight && !f_env.rcvrErrFramingInjected ){
terminate;
}else if(f_env.rcvrErrFramingWeight && f_env.rcvrErrFramingInjected ){
//Last injected error may cause entry into Recovery so wait a while
repeat( 50 ) @(posedge if_ILU_PEU_PCIE.refclk);
if( f_env.getLtssmState() !== ILUPEU_LTSSM_L0 ){
printf("IngressRcvrErr waiting for LTSSM to reenter L0 from Recovery\n");
f_env.toLtssmState( ILUPEU_LTSSM_L0,*,OMNI );
}
}
printf("at time %d, IngressRcvrErr last error injected check error regs nmbrRcvrErrsToInject=%0d nmbrRcvrErrsInjected=%0d nmbrRcvrErrsDriven=%0d rcvrErr8b10bInjected=%0d rcvrErrFramingInjected=%0d rcvrErrDisparityInjected=%0d rcvrErrFlipBitInjected=%0d rcvrErrLcrcInjected=%0d rcvrErrDupSeqNmbrInjected=%0d rcvrErrOutOfSeqNmbrInjected=%0d rcvrErrBadSeqNmbrInjected=%0d invertLCRC32ErrInjected=%0d, EDBErrInjected=%0d InvertLCRCAndEDBErrInjected = %0d \n",get_time(LO), nmbrRcvrErrsToInject,f_env.nmbrRcvrErrsInjected,f_env.nmbrRcvrErrsDriven,f_env.rcvrErr8b10bInjected,f_env.rcvrErrFramingInjected,f_env.rcvrErrDisparityInjected,f_env.rcvrErrFlipBitInjected,f_env.rcvrErrLcrcInjected, f_env.rcvrErrDupSeqNmbrInjected, f_env.rcvrErrOutOfSeqNmbrInjected, f_env.rcvrErrBadSeqNmbrInjected, f_env.invertLCRC32ErrInjected, f_env.EDBErrInjected, f_env.InvertLCRCAndEDBErrInjected );
f_env.enableRcvrErrInjection = 0;
//Delay long enough for a Denali replay timeout in case the NAKd transaction had
// a framing type error causing the 1st replayd packet to be bad also
repeat( denaliReplayTimer+25 ) @(posedge if_ILU_PEU_PCIE.refclk);
//Re enable the hang detect
// if( f_env.rcvrErrFramingWeight && f_env.rcvrErrFramingInjected ){
// f_env.activityStalled -= 1;
// }
//Track possible errors
if ((f_env.nmbrRcvrErrsDriven - f_env.InvertLCRCAndEDBErrInjected ) > 0)
{ other_nonInvertLCRCAndEDBErrInjected = 1; }
printf("AC: at time %d, other_nonInvertLCRCAndEDBErrInjected = %d", get_time(LO), other_nonInvertLCRCAndEDBErrInjected);
if (other_nonInvertLCRCAndEDBErrInjected) {
nmbrErrs = 2;
}
else {
nmbrErrs = 0;
}
if (f_env.InvertLCRCAndEDBErrInjected == 1) {
nmbrErrs += 1;
}
else if (f_env.InvertLCRCAndEDBErrInjected > 1) {
nmbrErrs += 2;
}
//ErrLcrc & Err8b10b can possibly cause framing errors
//Framing Errors will NOT cause a e_ERR_ce_re - Receiver Error
// 6/20/05
//CRC Errors/framing errors
if( f_env.rcvrErrFlipBitInjected || f_env.rcvrErrFramingInjected ||
f_env.rcvrErrDisparityInjected || f_env.rcvrErr8b10bInjected ){
nmbrErrs += 7;
}
if( f_env.rcvrErrDisparityInjected || f_env.rcvrErr8b10bInjected ){ //Receiver Error
nmbrErrs += 2;
}
if( f_env.rcvrErrFramingInjected ){ // More framing errors
nmbrErrs += 7;
if( recoveryEntered ){
nmbrErrs += 2;
}
}
printf("AC: nmbrErrs = %d\n", nmbrErrs);
// Tell the error-checker about this
// bad-boy.
if( f_errQueue != 0 ){
mailbox_put( f_errQueue, e_ERR_none );
mailbox_put( f_errQueue, nmbrErrs );
//Bad TLPs caused by either CRC errors or sequence errors when a good TLP
// follows a bad TLP - for some of the more directed cases make it optional
// if (f_env.rcvrErrDupSeqNmbrInjected) { // no error for duplicate seq number
//aC: }
// else {
if( f_env.rcvrErrLcrcInjected ||
f_env.rcvrErrDupSeqNmbrInjected || f_env.rcvrErrOutOfSeqNmbrInjected ||
f_env.rcvrErrBadSeqNmbrInjected || f_env.EDBErrInjected ){
optional_CE_BTP = 0;
}
if (other_nonInvertLCRCAndEDBErrInjected) {
if (nmbrErrs > 0 ) {
mailbox_put( f_errQueue, e_ERR_ce_btp );
if( optional_CE_BTP ){
mailbox_put( f_errQueue, 128'bx0 );
}else{
mailbox_put( f_errQueue, 128'bx );
}
mailbox_put( f_errQueue, e_ERR_ce_btp );
mailbox_put( f_errQueue, 128'bx0 );
}
}
if ( f_env.InvertLCRCAndEDBErrInjected == 1) {
mailbox_put( f_errQueue, e_ERR_ce_btp );
mailbox_put( f_errQueue, 128'bx0 );
}
else if (f_env.InvertLCRCAndEDBErrInjected > 1) {
mailbox_put( f_errQueue, e_ERR_ce_btp );
mailbox_put( f_errQueue, 128'bx0 );
}
if( f_env.rcvrErrDisparityInjected || f_env.rcvrErr8b10bInjected ){
mailbox_put( f_errQueue, e_ERR_ce_re );
mailbox_put( f_errQueue, 128'bx );
mailbox_put( f_errQueue, e_ERR_ce_re );
mailbox_put( f_errQueue, 128'bx0 ); //A secondary error may also be logged
}
if( f_env.rcvrErrFramingInjected || f_env.rcvrErrFlipBitInjected ||
f_env.rcvrErrDisparityInjected || f_env.rcvrErr8b10bInjected ){
mailbox_put( f_errQueue, e_ERR_oe_lin );
mailbox_put( f_errQueue, 128'bx0 ); //Might fail
/*
if( f_env.rcvrErrFramingInjected > 2 ){ //If only 2 errors END->Data STP->data there will be no dlpl errors
mailbox_put( f_errQueue, 128'bx );
}else{
mailbox_put( f_errQueue, 128'bx0 ); //Might fail
}
*/
mailbox_put( f_errQueue, e_ERR_dlpl_stp_no_end_edb );
mailbox_put( f_errQueue, 128'bx0 ); //Optional error may not occur
mailbox_put( f_errQueue, e_ERR_dlpl_kchar_dllp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_multi_stp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_end_no_stp_sdp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_ill_end_pos );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_sdp_no_end );
mailbox_put( f_errQueue, 128'bx0 );
}
if( f_env.rcvrErrFramingInjected ){
mailbox_put( f_errQueue, e_ERR_dlpl_ill_stp_pos );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_ill_sdp_pos );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_ill_pad_pos );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_unsup_dllp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_multi_sdp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_ce_bdp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_ce_rto ); //If END changed to data before ACK
mailbox_put( f_errQueue, 128'bx0 );
if( recoveryEntered ){
mailbox_put( f_errQueue, e_ERR_oe_nfp );
mailbox_put( f_errQueue, 128'bx0 );
mailbox_put( f_errQueue, e_ERR_dlpl_align );
mailbox_put( f_errQueue, 128'bx0 );
}
}
}
//Unsuppress the Denali error TX checks that were Suppressed in the PEUTestEnv
// This was moved out of TestEnv because packets following the one with the injected
// could also get framing type errors in Denali
if( f_env.rcvrErr8b10bInjected ){
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_8B10B );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
}
if( f_env.rcvrErrFramingInjected ){
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_MOS_FTS_NC );
}
if( f_env.rcvrErrDisparityInjected ){
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_DISP );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
}
if( f_env.rcvrErrFlipBitInjected ){
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_8B10B );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_DATA0 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_RSV_KC );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_TLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_BAD_SDP1 );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_DLLP_END );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_FRAME_PAD );
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_PL_NONFATAL_SYM_DISP );
}
if( f_env.rcvrErrLcrcInjected ){
}
if( f_env.rcvrErrDupSeqNmbrInjected ){
}
if( f_env.rcvrErrOutOfSeqNmbrInjected ){
}
if( f_env.rcvrErrBadSeqNmbrInjected ){
}
if( f_env.invertLCRC32ErrInjected ){
}
if( f_env.EDBErrInjected ){
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr(PCIE_PL_NONFATAL_FRAME_NULL_TLP );
}
//
f_env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_DL_COR_REPLAY_TIMEOUT );
repeat( 10 ) @(posedge CLOCK);
semaphore_put( rcvrErr_semaphore, 1 );
} /* end Execute */
} /* end IngressRcvrErr */