Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2str / ilupeuIngressAckNakErr.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: ilupeuIngressAckNakErr.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 ilupeuIngressAckNakErr extends PEUStrBase
{
integer f_errQueue; // A mailbox for bad pkt headers
integer nmbrAckNakErrsToInject = 10; //Total number of packets that get error injected
//Set the percentage weight of each type of receiver error
integer DLLPAckLessthanAckedErrWeight = 10;
integer DLLPNakLessthanAckedErrWeight = 10;
integer DLLPAckmorethanTLPNxtSeqErrWeight = 10;
integer DLLPNakmorethanTLPNxtSeqErrWeight = 10;
denaliPcieEiTypeT DenaliErrortype;
string DLLPtype;
//Only allow 1 of these strategies to be active at a time
static integer AckNakErr_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 DLLPAckNakErrsInject_freq = 100; // freq of clock cycles to inject this error
integer nmbrDLLPAckNakErrsInjected;
integer SeqNum = 0 ;
integer seqnum_adjust = 2;
string value = "";
integer DLP_error_inject = 0;
//Get the semaphore when its your turn
semaphore_get( WAIT, AckNakErr_semaphore, 1);
//Clear all the specific error trackers
nmbrDLLPAckNakErrsInjected = 0;
// create random number to cause Ack/Nak DLLP type
DLLPAckNakErrsInject_freq = (urandom() % 20) + 20;
// PCIEDllpTrans = new( Pod.FNXPCIEBldr );
//inject errors until all the errors are injected
while (nmbrAckNakErrsToInject > nmbrDLLPAckNakErrsInjected) {
// adjust sequence number by 2 to 4097
// seqnum_adjust = (urandom() % 50) + 2;
seqnum_adjust = (urandom() % 4095) + 2;
//determine the type of errors inject based on the weight specified in the testcase
randcase {
// DLLPAckLessthanAckedErrWeight: {SeqNum = f_env.AckdSeqNum - 1; DLLPtype = "ack"; value = "less than"; }
// DLLPNakLessthanAckedErrWeight : {SeqNum = f_env.AckdSeqNum - 1; DLLPtype = "nak"; value = "less than"; }
// DLLPAckLessthanAckedErrWeight: {SeqNum = f_env.AckdSeqNum - seqnum_adjust; DLLPtype = "ack"; value = "less than"; }
// DLLPNakLessthanAckedErrWeight : {SeqNum = f_env.AckdSeqNum - seqnum_adjust; DLLPtype = "nak"; value = "less than"; }
// DLLPAckmorethanTLPNxtSeqErrWeight: {
// // SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + 1;
// SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + seqnum_adjust;
// DLLPtype = "ack"; value = "more than"; }
// DLLPNakmorethanTLPNxtSeqErrWeight: {
// // SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + 1;
// SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + seqnum_adjust;
// DLLPtype = "nak" ; value = "more than";}
DLLPAckLessthanAckedErrWeight: {SeqNum = f_env.AckdSeqNum - seqnum_adjust; DLLPtype = "ack"; value = "less than"; DLP_error_inject = 1; f_env.Pod.denali_root_monitor_PCIEEnableTrans.tempSuppressDenaliErr(PCIE_DL_FATAL_PROTOCOL_ERROR);}
DLLPNakLessthanAckedErrWeight : {SeqNum = f_env.AckdSeqNum - seqnum_adjust; DLLPtype = "nak"; value = "less than"; DLP_error_inject = 1; f_env.Pod.denali_root_monitor_PCIEEnableTrans.tempSuppressDenaliErr(PCIE_DL_FATAL_PROTOCOL_ERROR);}
DLLPAckmorethanTLPNxtSeqErrWeight: {
// SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + 1;
SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + seqnum_adjust;
DLLPtype = "ack"; value = "more than"; DLP_error_inject = 1; f_env.Pod.denali_root_monitor_PCIEEnableTrans.tempSuppressDenaliErr(PCIE_DL_FATAL_PROTOCOL_ERROR);}
DLLPNakmorethanTLPNxtSeqErrWeight: {
// SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + 1;
SeqNum = f_env.Pod.FNXPCIEEnableTrans.ReadDenaliReg(PCIE_REG_DEN_NXT_TX_TLP_SEQ) + seqnum_adjust;
DLLPtype = "nak" ; value = "more than"; DLP_error_inject = 1;
f_env.Pod.denali_root_monitor_PCIEEnableTrans.tempSuppressDenaliErr(PCIE_DL_FATAL_PROTOCOL_ERROR); }
}
f_env.Pod.FNXPCIEEnableTrans.tempSuppressDenaliErr( PCIE_DL_FATAL_PROTOCOL_ERROR );
printf("AC: at time %0d, SeqNum to be sent = %d, DLLPtype = %0s, value = %s \n", get_time(LO), SeqNum, DLLPtype, value);
// sending the ack or nak
if (DLLPtype == "ack") {
f_env.sendAck(SeqNum);
}
if (DLLPtype == "nak") {
f_env.sendNak(SeqNum);
}
nmbrDLLPAckNakErrsInjected += 1;
printf("AC: IngressDLLAckNakErr injects error: nmbrDLLPAckNakErrsInjected=%0d nmbrAckNakErrsToInject=%0d \n",nmbrDLLPAckNakErrsInjected, nmbrAckNakErrsToInject);
repeat (DLLPAckNakErrsInject_freq) @(posedge CLOCK);
}
//Delay to allow the last error to propogate before checking
repeat( 100 ) @(posedge CLOCK);
//Track possible errors based on the type of errors injected
nmbrErrs = 0; // number of error type that got set.
printf("AC: nmbrErrs = %d \n", nmbrErrs);
if (nmbrDLLPAckNakErrsInjected == 1) {
nmbrErrs += 1; // only primary ce error got set.
}
else if (nmbrDLLPAckNakErrsInjected > 1) {
nmbrErrs += 2; // both primary and secondary ce errors got set.
}
if( f_errQueue != 0 ){
// note: bx = no header to check
// bx0 = error above is optional. clear it if it's set
mailbox_put( f_errQueue, e_ERR_none );
mailbox_put( f_errQueue, nmbrErrs );
mailbox_put( f_errQueue, e_ERR_ue_dlp ); // e_ERR_ue_dlp = DLLP protocol error
mailbox_put( f_errQueue, 128'bx );
mailbox_put( f_errQueue, e_ERR_ue_dlp ); // e_ERR_ue_dlp = DLLP protocol error
mailbox_put( f_errQueue, 128'bx );
} // f_errQueue !=0
// after the errors are injected, then do not suppress the error detection
if( DLP_error_inject ){
f_env.Pod.denali_root_monitor_PCIEEnableTrans.unSuppressDenaliErr(PCIE_DL_FATAL_PROTOCOL_ERROR);
DLP_error_inject = 0;
}
repeat( 10 ) @(posedge CLOCK);
semaphore_put( AckNakErr_semaphore, 1 );
} /* end Execute */
} /* end IngressUnsupportDLLPErr */