Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2ctx / N2ExceptionPEUCtx.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: N2ExceptionPEUCtx.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 ExceptionPEUCtx extends PEUCtxBase
{
bit f_expectInterrupt;
local string f_mode;
local integer f_index;
local integer f_errQueue;
local integer f_offset;
static bit[4:0] f_badType = PEC_PCI__TYPE_MEM;
static PEC_ERRtype f_lpuErr = e_ERR_none;
static integer f_count = 0;
static bit [1:0] f_injectType = 0;
task new( string a_name, PEUTestEnv a_env, string a_mode )
{
super.new(a_name,a_env);
f_mode = a_mode;
f_index = 0;
f_offset = 0;
f_errQueue = 0;
f_expectInterrupt = 1;
}
task Execute()
{
super.Execute();
}
task SetOffset( integer a_offs )
{
f_offset = a_offs;
}
protected function CTStrategyBase ProvideStrategy()
{
integer seed;
PEUStrBase nullStr;
ErrChkPEUStr errChk; // The guy who checks error state
EdbErrPEUStr edbErr; // Generate an EDB parity error
EhbErrPEUStr ehbErr; // Generate an EHB parity error
IhbErrPEUStr ihbErr; // Generate an IHB parity error
LinkErrPEUStr linkErr; // Pull down the "link up" signal
LpuErrPEUStr lpuErr; // Present an LPU-detected error
TimeOutPEUStr timeOut; // Let a non-posted PIO request time out
ReplayPEUStr replay; // Cause a replay to take place by a nak or timeout
InErrPEUStr ingressErr; // Provide bad parity for an ingress TLP
EgrParErrStr egrParErr; // Egress Injected Parity Errors
IngParErrStr ingParErr; // Ingress Injected Parity Errors
// If the "StratStop" (within the base
// context class) has been set, then
// just return a base context which
// does nothing.
if ( this.StratStop )
{
nullStr = new( f_env );
ProvideStrategy = nullStr;
}
// The first strategy? Build a
// mailbox and fire up the guy
// who'll check interrupt status
// after it's all over.
// The test uses "NumStrat" to tell us
// how many errors to generate.
// Every error-generating strategy will
// add something to the "f_errQueue".
else if ( f_index == 0 )
{
f_index = 1;
f_errQueue = alloc( MAILBOX, 0, 1 );
errChk = new( f_env, f_errQueue, this.NumStrat-1 );
// The "errChk" strategy will enable
// interrupt checking when it's done.
if ( f_expectInterrupt ) f_env.disableInterrupt();
ProvideStrategy = errChk;
}
// The directed "EDB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "EDB" )
{
edbErr = new( f_env );
edbErr.SetErrQueue( f_errQueue );
edbErr.SetType( f_badType );
ProvideStrategy = edbErr;
}
// The directed "EHB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "EHB" )
{
ehbErr = new( f_env );
ehbErr.SetErrQueue( f_errQueue );
ehbErr.SetType( f_badType );
ProvideStrategy = ehbErr;
}
// The directed "IHB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "IHB" )
{
ihbErr = new( f_env );
ihbErr.SetErrQueue( f_errQueue );
ihbErr.SetType( f_badType );
ProvideStrategy = ihbErr;
}
// injects a parity error
// on a egress PIO packet
else if ( f_mode == "EgrPar" )
{
egrParErr = new( f_env );
egrParErr.SetErrQueue( f_errQueue );
egrParErr.SetInjectType( f_injectType );
ProvideStrategy = egrParErr;
}
// injects a parity error
// on a ingress packet
else if ( f_mode == "IngPar" )
{
ingParErr = new( f_env );
ingParErr.SetErrQueue( f_errQueue );
ingParErr.SetInjectType( f_injectType );
ProvideStrategy = ingParErr;
}
// The directed "link down" test
// just pulls down the "link up" signal.
else if ( f_mode == "Link" )
{
linkErr = new( f_env );
linkErr.SetErrQueue( f_errQueue );
ProvideStrategy = linkErr;
}
// A LPU-detected error? Find the next
// one and use it!
else if ( f_mode == "LPU" )
{
lpuErr = new( f_env );
lpuErr.SetErrQueue( f_errQueue );
f_lpuErr++;
while( lpuErr.SetError(f_lpuErr) ) f_lpuErr++;
ProvideStrategy = lpuErr;
}
// An ingress parity error?
// A "header" error is one which appears
// in the first 4DWs of the TLP.
else if ( f_mode == "ITP data" )
{
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
f_count = f_count + 1;
if ( f_offset > 0 )
ingressErr.SetOffset( f_offset + 16 );
else if ( f_offset < 0 )
ingressErr.SetOffset( f_offset );
else
ingressErr.SetOffset( f_count + 16 );
ProvideStrategy = ingressErr;
}
else if ( f_mode == "ITP hdr" )
{
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
f_count = f_count + 1;
ingressErr.SetOffset( (f_count % 16) + 1);
ProvideStrategy = ingressErr;
}
// A PIO request times out?
else if ( f_mode == "Time-out" )
{
timeOut = new( f_env );
timeOut.SetErrQueue( f_errQueue );
ProvideStrategy = timeOut;
}
// A replay caused by a timeout
else if ( f_mode == "Replay-Timeout" )
{
replay = new( f_env );
replay.SetErrQueue( f_errQueue );
replay.SetType( "timeout" );
ProvideStrategy = replay;
}
// A replay count rollover caused by a timeout
else if ( f_mode == "Replay-Timeout-Rollover" )
{
replay = new( f_env );
replay.SetErrQueue( f_errQueue );
replay.SetType( "timeout" );
replay.SetNmbrReplays( 4 );
ProvideStrategy = replay;
}
// A replay count rollover caused by NAKs
else if ( f_mode == "Replay-Nak-Rollover" )
{
replay = new( f_env );
replay.SetErrQueue( f_errQueue );
replay.SetType( "nak" );
replay.SetNmbrReplays( 4 );
ProvideStrategy = replay;
}
// A random drain-state test?
// Then just supply any nasty exception.
else if ( f_mode == "Drain" )
{
if ( get_plus_arg( CHECK, "vera_random_seed=" ) )
seed = get_plus_arg( NUM, "vera_random_seed=" );
else
seed = 0;
if ( seed >= 1 && seed <= 4 )
{
printf( "Exception: An EHB parity error... DW-%0d\n", seed-1 );
ehbErr = new( f_env );
ehbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
ehbErr.SetType( PEC_PCI__TYPE_CPL );
ehbErr.SetMask( 1 << (seed-1) );
ProvideStrategy = ehbErr;
}
else if ( seed >= 5 && seed <= 8 )
{
printf( "Exception: An IHB parity error... DW-%0d\n", seed-5 );
ihbErr = new( f_env );
ihbErr.SetErrQueue( f_errQueue );
ihbErr.SetMask( 1 << (seed-5) );
ProvideStrategy = ihbErr;
}
else if ( seed >= 9 && seed <= 15 )
{
printf( "Exception: An EDB parity error... DW-%0d\n", seed-9 );
edbErr = new( f_env );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
edbErr.SetMask( 1 << (seed-9) );
edbErr.SetLength( 8 );
if ( seed <= 12 ) edbErr.SetBndy( 0 );
ProvideStrategy = edbErr;
}
else if ( seed == 16 )
{
printf( "Exception: An EDB parity error... only DW\n" );
edbErr = new( f_env );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
edbErr.SetLength( 1 );
edbErr.SetMask( 4'b1111 );
ProvideStrategy = edbErr;
}
else randcase
{
1: { /* ITP header parity */
printf( "Exception: An ITP (header) parity error\n" );
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
ingressErr.SetOffset( urandom() % 16 + 1 );
ProvideStrategy = ingressErr;
}
1: { /* Link down */
printf( "Exception: The link drops\n" );
linkErr = new( f_env );
linkErr.SetErrQueue( f_errQueue );
ProvideStrategy = linkErr;
}
1: { /* IHB parity */
printf( "Exception: An IHB parity error\n" );
ihbErr = new( f_env );
ihbErr.SetErrQueue( f_errQueue );
ProvideStrategy = ihbErr;
}
1: { /* EDB parity */
printf( "Exception: An EDB parity error\n" );
edbErr = new( f_env );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
ProvideStrategy = edbErr;
}
1: { /* EHB parity */
printf( "Exception: An EHB parity error\n" );
ehbErr = new( f_env );
ehbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
ehbErr.SetType( PEC_PCI__TYPE_CPL );
ProvideStrategy = ehbErr;
}
}
}
// None of the above? A null strategy
// does nothing.
else
{
nullStr = new( f_env );
ProvideStrategy = nullStr;
}
} /* end ProvideStrategy */
protected function CTStrategyBase FinalizeParms( CTStrategyBase a_strategy )
{
FinalizeParms = a_strategy;
} /* end FinalizeParms */
} /* end ExceptionPEUCtx */