// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: N2PEUTestBase.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
// ========== Copyright Header End ============================================
BootPEUStr boot; // A strategy for starting things up
protected PEUTestEnv env; // The test environment
PIOPEUCtx pio; // The context to perform PIO traffic
DMAPEUCtx dma; // The context to perform DMA traffic
protected integer txBadInit = 0; // Tx bad init fc dllps before link up
protected bit slowClock; // Do we have a slow ILU clock?
protected bit stallNpstWr; // Do PIO reqs stall after Cfg/IO write?
protected bit AHBdone = 0; // used to start/stop AHB traffic
protected bit PMmsgDone = 0; // used to start/stop PMmsg traffic
protected event donePMmsgs; // signals when PMmsgs finishes
protected integer numPhyLanes;
protected integer numActiveLanes;
protected bit [63:0] retryBufSize;
protected PECBool txEnableScramble;
protected PECBool rxEnableScramble;
// Only need to create 1 Report class to pass around the whole testbench
ReportClass Report = new;
// The Scenario classes holds some test parameters
ilupeuScenario Scenario = new( Report );
// urandom Seed Generation
bit [31:0] urand_seed = 32'hdeadbeef;
bit seed_with_tod = 1'b0;
// bit seed_with_tod = 1'b1;
virtual public task execute(); // Run the whole test
virtual public task setBoot(); // Set the params in Boot Str
virtual public task setEnv(); // Set initial params in env.
virtual public task setPIO(); // Set params for PIO Noise Context
virtual public task setDMA(); // Set params for DMA Noise Context
virtual public task runPIO(); // Run the PIO Noise Context
virtual public task runDMA(); // Run the DMA Noise Context
virtual public task runTest(); // Test something interesting
virtual public task startAHB( PEUTestEnv env );
virtual public task stopAHB();
virtual public task startPMmsgs( PEUTestEnv env,
integer maxDelay = 200 );
virtual public task stopPMmsgs();
virtual public task startLTSSM( PEUTestEnv env,
integer minDelay, integer maxDelay,
integer recovery, integer L0s );
virtual public task stopLTSSM();
virtual public task stopPioDma();
task PEUTestBase::new() {
this.retryBufSize = 64'h0;
//Set the print threshold at the command line
//example: sims ... -vcs_run_args=+report_global_print_threshold=RPRT_DEBUG_3
if( get_plus_arg( CHECK, "+report_global_print_threshold=" ) ){
print_str = get_plus_arg( NUM, "+report_global_print_threshold=" );
RPRT_INFO: Report.set_global_print_threshold( RPRT_INFO );
RPRT_DEBUG_3: Report.set_global_print_threshold( RPRT_DEBUG_3 );
default: Report.set_global_print_threshold( RPRT_INFO );
//If there is no print level passed in then only print the minimum
Report.set_global_print_threshold( RPRT_NONMASKABLE );
//Step 0. Initialize Denali Vera Interface
status = denaliVeraPcieInit();
QuickReport(Report,RTYP_TEST_ERROR,"denaliVeraPcieInit() failed. \n" );
status = DenaliDDVinitialize("","",unk,"","API");
QuickReport(Report,RTYP_TEST_ERROR,"DenaliDDVinitialize() failed. \n" );
// Set Denali Register Callback Task For PCIE Xactors
status = DenaliDDVaccessSetCallback("FNXPCIEXactorRegCbTask");
QuickReport(Report,RTYP_TEST_ERROR,"DenaliDDVaccessSetCallback() failed. \n" );
task PEUTestBase::execute() {
printf("**PEUTestBase Begin Execution**\n");
printf("**PEUTestBase Set Up Boot Strategy**\n");
Scenario ); // Let's get ready to rumble ....
printf("**PEUTestBase Boot Strategy Set Up Complete**\n");
printf("**PEUTestBase Execute Boot Strategy**\n");
printf("**PEUTestBase Boot Strategy Complete**\n");
printf("**PEUTestBase Set Up Environment**\n");
printf("**PEUTestBase Environment Set Up Complete**\n");
//Make the 1st transaction a Cfg Write 0 so that the
// Config ID in Denali can be set
CfgWr0._type_req_prob_cfg1 = 0;
CfgWr0._type_req_prob_io = 0;
CfgWr0._ep_cpl_prob_true = 0;
CfgWr0._td_cpl_prob_true = 0;
CfgWr0._bcm_prob_true = 0;
printf("**PEUTestBase Sent ConfigWrite0 to Denali**\n");
printf("**PEUTestBase Set Up PIO Traffic**\n");
printf("**PEUTestBase PIO Traffic Set Up Complete**\n");
printf("**PEUTestBase Set Up DMA Traffic**\n");
dma = new( "DmaTraffic", env, "random" );
printf("**PEUTestBase DMA Traffic Set Up Complete**\n");
printf("**PEUTestBase Run PIO Traffic**\n");
printf("**PEUTestBase PIO Traffic Complete**\n");
printf("**PEUTestBase Run DMA Traffic**\n");
printf("**PEUTestBase DMA Traffic Complete**\n");
printf("**PEUTestBase Run Test**\n");
printf("**PEUTestBase Test Complete**\n");
printf("**PEUTestBase Signal PIO & DMA Traffic Stop**\n");
printf("**PEUTestBase PIO & DMA Traffic Stop Signal Complete**\n");
while( ( !pioDone && (pio.NumStrat - pio.StratDone) > 100 )
|| ( !dmaDone && (dma.NumStrat - dma.StratDone) > 100 ) )
printf( "**PEUTestBase (cyc %0d) PIO/DMA remaining = %0d/%0d\n",
pio.NumStrat - pio.StratDone, dma.NumStrat - dma.StratDone );
printf( "**PEUTestBase (cyc %0d) PIO/DMA remaining = %0d/%0d\n",
pio.NumStrat - pio.StratDone, dma.NumStrat - dma.StratDone );
printf("**PEUTestBase Expect Idle State**\n");
printf("**PEUTestBase Expect Idle State Complete**\n");
printf("**PEUTestBase Execution Complete**\n");
* Beat up on the AHB interface to the LPU's CSRs.
* But only if we don't have an LPU hooked up!
task PEUTestBase::startAHB( PEUTestEnv env )
/* N2 review - Not Needed???
if ( get_plus_arg( CHECK, "LPU" ) ) return;
repeat(10) @(posedge CLOCK); // Let reset finish...
data = { 32'b0, urandom() };
addr = env.getLPUaddr( urandom() % PEC_LPU_CSR_MAX_COUNT );
env.writeCSR( addr, data );
env.expectCSRdirect( addr, data );
data = { 32'b0, urandom() };
addr = env.getLPUaddr( urandom() % PEC_LPU_CSR_MAX_COUNT );
env.writeCSRdirect( addr, data );
env.expectCSR( addr, data );
data = { 32'b0, urandom() };
addr = env.getLPUaddr( urandom() % PEC_LPU_CSR_MAX_COUNT );
data = env.readCSRdirect( addr );
env.expectCSR( addr, data );
task PEUTestBase::stopAHB()
//N2 review this.AHBdone = 1;
* Write CSRs which cause PM messages to be sent by the TLU.
task PEUTestBase::startPMmsgs( PEUTestEnv env,
trigger( OFF, this.donePMmsgs );
delay = minDelay + urandom() % (maxDelay-minDelay+1);
repeat(delay) @(posedge CLOCK);
addr = env.getCSRaddr( e_CSR_pme_ctl );
msgType = PEC_PCI__MSG_CODE_PM_TURN_OFF;
capData = capData + 64'h00100;
expData = { 22'b0, capData[16:7] };
addr = env.getCSRaddr( e_CSR_slot_cap );
msgType = PEC_PCI__MSG_CODE_SET_SLOT_POWER_LIMIT;
trigger( OFF, csrWritten );
env.expectEgressMsg( msgType, expData, csrWritten );
env.writeCSR( addr, data );
trigger( ON, csrWritten );
trigger( ON, this.donePMmsgs );
} /* end exercisePMmsgs */
task PEUTestBase::stopPMmsgs()
sync( ANY, this.donePMmsgs );
task PEUTestBase::startLTSSM( PEUTestEnv env,
integer minDelay, integer maxDelay,
integer recovery, integer L0s )
task PEUTestBase::stopLTSSM()
task PEUTestBase::setBoot() {
boot.getPhyConfig( this.numPhyLanes,
// QuickReport(Report,RTYP_INFO, " PEUTestBase::setBoot() result of get_plus_arg( CHECK, \"vera_random_seed=\" ) is %h\n", get_plus_arg( CHECK, "vera_random_seed=" ) );
//N2 review boot.setClkDrift(8);
//N2 review boot.setDriftPeriod(19);
boot.setPostedCredits( 16, 64 );
boot.setNonpostedCredits( 16, 64 );
boot.setCompletionCredits( 16, 64 );
//N2 review 1: { boot.slowClock(1); this.slowClock = 1; }
//N2 review 5: { boot.slowClock(0); }
//N2 review 1: { boot.setClkDrift(1); boot.setDriftPeriod(2); }
//N2 review 1: { boot.setClkDrift(10); boot.setDriftPeriod( urandom()%20 + 20 ); }
1: boot.setPostedCredits( 0, 0 );
1: boot.setPostedCredits( 1, 32 );
1: boot.setPostedCredits( 2, 32 );
1: boot.setPostedCredits( 4, 32 );
1: boot.setPostedCredits( 16, 64 );
1: boot.setPostedCredits( 128, 2048 );
1: boot.setNonpostedCredits( 0, 0 );
1: boot.setNonpostedCredits( 1, 32 );
1: boot.setNonpostedCredits( 2, 32 );
1: boot.setNonpostedCredits( 4, 32 );
1: boot.setNonpostedCredits( 16, 64 );
1: boot.setNonpostedCredits( 128, 2048 );
1: boot.setCompletionCredits( 0, 0 );
1: boot.setCompletionCredits( 1, 32 );
1: boot.setCompletionCredits( 2, 32 );
1: boot.setCompletionCredits( 4, 32 );
1: boot.setCompletionCredits( 16, 64 );
1: boot.setCompletionCredits( 128, 2048 );
task PEUTestBase::setEnv() {
integer ingressAbortRate;
//N2 useLpu = get_plus_arg( CHECK, "LPU" );
useLpu = 1; //Always set for N2
// Randomly select environment / device parameters
//N2 review 1: ingressThrottle = useLpu ? 0 : 25;
//N2 review 1: ingressThrottle = useLpu ? 0 : 50;
//N2 review 1: ingressAbortRate = useLpu ? 0 : 10;
//N2 review 1: ingressAbortRate = useLpu ? 0 : 25;
1: { minGap = 2; maxGap = 2; }
1: { minGap = 2; maxGap = 6; }
randcase // Payload sizes...
1: { len1=10; len2=10; len16=10; lenBulk=10; } // A little of each
1: { len1=10; len2=1; len16=1; lenBulk=0; } // Lots of 1DW payloads
1: { len1=10; len2=10; len16=10; lenBulk=0; } // No bulk payloads
// If the initial (random) seed is small, then choose environment
// parameters based on that seed. In this way, a couple of random runs
// can be used for coverage purposes.
if ( get_plus_arg( CHECK, "vera_random_seed=" ) )
seed = get_plus_arg( NUM, "vera_random_seed=" );
1: { mps = 128; stallNpstWr = 0; }
2: { mps = 256; stallNpstWr = 0; }
3: { mps = 512; stallNpstWr = 0; }
// If no "vera random seed" was specified, then we have a directed test.
// Use default values for all tests.
ingressThrottle = useLpu ? 0 : -1;
ingressAbortRate = useLpu ? 0 : 10;
// Set the environment parameters determined above.
env.setLenWeights( len1, len2, len16, lenBulk );
env.setIngressAbortRate( ingressAbortRate );
env.setIngressThrottle( ingressThrottle );
env.setIngressGap( minGap, maxGap );
env.setEgressThrottle( egressThrottle );
env.setMaxPayloadSize( mps );
env.setMaxRequestSize( 4096 );
// env.setMaxRequestSize( mps );
if ( stallNpstWr && !useLpu )
env.stallNonpostedWrite( 1 );
// If we're using the LPU, initialize the replay and acknak timers
//N2 review - Disabled in env
env.initLpuCSRs( this.numActiveLanes, mps, this.fastTrain, this.enableL0s, this.retryBufSize );
// Bring up the link and present initial credit advertisements to the TLU
env.linkUp( 20 * (urandom()%5) + 20, this.txBadInit );
// Wait a bit and make sure the 'link up' event was recorded
repeat(20) @(posedge CLOCK);
env.expectError( e_ERR_oe_lup, 1, 0 );
task PEUTestBase::setPIO() {
pio._ep_cpl_mode = e_fixed;
pio._ep_cpl_fixed = e_false;
pio._cpl_status_mode = e_fixed;
pio._cpl_status_fixed = PEC_PCI__CPL_STATUS_SC;
task PEUTestBase::setDMA() {
dma.NumStrat = ( this.slowClock || this.stallNpstWr ) ? 25000 : 15000;
task PEUTestBase::runPIO() {
if (pio.StratStop !== 1'b1)
error("PIO Background Traffic Finished Early\n");
task PEUTestBase::runDMA() {
if (dma.StratStop !== 1'b1)
error("DMA Background Traffic Finished Early\n");
// Grab Seed With Time of Day Bit
if ( get_plus_arg( CHECK, "seed_with_tod=" ))
seed_with_tod = get_plus_arg( NUM, "seed_with_tod=" );
// Seed With Time of Day if Set
urand_seed = time_0 + urandom();
// Grab Urandom Seed From Command Line If Present
if ( get_plus_arg( CHECK, "urand_seed=" ))
urand_seed = get_plus_arg( HNUM, "urand_seed=" );
QuickReport(Report,RTYP_INFO, "ilupeuTestBase: urandom() seeded with time of day, seed=%h \n",
QuickReport(Report,RTYP_INFO,"ilupeuTestBase: urandom() seeded with seed=%h \n", urand_seed );
task PEUTestBase::runTest() { }
task PEUTestBase::stopPioDma(){