Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2str / ilupeuMalCplPEUStr.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: ilupeuMalCplPEUStr.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 ============================================
#define _INFO_MSG_MAL_CPL(msg) printf( "MalCpl (cyc %0d) %s\n", get_cycle(), msg )
class MalCplPEUStr extends PEUStrBase
{
local bit f_typeSpecified; // Was a bad-boy type supplied?
local bit [1:0] f_fmt; // The bad format
local bit [4:0] f_type; // The bad type
local bit f_lenSpecified; // Was a TLP length supplied?
local integer f_len; // A requested TLP length
local integer f_cross4K; // By what amount do we cross 4K
local integer f_adjustLen; // The delta to the true length
local integer f_errQueue; // A mailbox for bad pkt headers
local bit f_tdSpecified; // Was the TD supplied?
local bit f_tdFieldValue; // The TD value
local integer f_solicitedCpl;
task new( PEUTestEnv a_env )
{
super.new( a_env );
f_typeSpecified = 0;
f_lenSpecified = 0;
f_errQueue = 0;
f_adjustLen = 0;
f_cross4K = 0;
f_tdSpecified = 0;
f_solicitedCpl = 1;
} /* end new */
function bit SetType( bit [1:0] a_fmt, bit [4:0] a_type )
{
bit isInvalid;
f_typeSpecified = 1;
f_type = a_type;
f_fmt = a_fmt;
case ( a_fmt ) {
2'b00 : isInvalid = !( PEC_PCI__TYPE_VALID_00 & ( 1 << a_type ) );
2'b01 : isInvalid = !( PEC_PCI__TYPE_VALID_01 & ( 1 << a_type ) );
2'b10 : isInvalid = !( PEC_PCI__TYPE_VALID_10 & ( 1 << a_type ) );
2'b11 : isInvalid = !( PEC_PCI__TYPE_VALID_11 & ( 1 << a_type ) );
}
SetType = isInvalid;
} /* end SetType */
task SetLength( integer a_length )
{
f_len = a_length;
f_lenSpecified = 1;
} /* end AdjustLen */
task AdjustLen( integer a_lengthDelta )
{
f_adjustLen = a_lengthDelta;
} /* end AdjustLen */
task Cross4K( integer a_dwCount )
{
f_cross4K = a_dwCount;
} /* end AdjustLen */
task SetErrQueue( integer a_queue )
{
f_errQueue = a_queue;
} /* end SetErrQueue */
task SetTD( bit a_TDValue )
{
f_tdFieldValue = a_TDValue;
f_tdSpecified = 1;
} /* end SetTD */
task SetSolicited( integer a_solicited )
{
f_solicitedCpl = a_solicited;
}
task Execute()
{
bit [ PEC_PCI__HDR ] reqHdr; // The request TLP's header
bit [ PEC_PCI__HDR ] cplHdr; // The completion TLP's header
bit [ PEC_PCI__HDR ] badCplHdr; // The corrupted completion TLP's header
bit [ 7:0 ] reqTag; // The tag for the TLP
integer pyld; // Reusable pyld variable
// Get in line for a PIO tag
if ( f_solicitedCpl )
f_env.allocRdTag( reqTag );
else
reqTag = urandom();
// Then build a TLP.
// Only PIO reads need completions
if ( f_typeSpecified ) {
if ( f_lenSpecified )
f_env.genEgressRdReq( reqTag, reqHdr, pyld, f_len, f_type );
else
f_env.genEgressRdReq( reqTag, reqHdr, pyld, *, f_type );
}
else {
if ( f_lenSpecified )
f_env.genEgressRdReq( reqTag, reqHdr, pyld, f_len, * );
else
f_env.genEgressRdReq( reqTag, reqHdr, pyld );
}
// make sure RequesterID is 0, since RSB
// will check that the completion has this
// field set to 0
reqHdr[ PEC_PCI__REQ_ID ] = 16'h0;
// adjust the Fmt field, since it
// might not be what we want
if( f_typeSpecified ) {
reqHdr[ PEC_PCI__FMT_4DW ] = f_fmt[ 0 ];
if ( reqHdr[ PEC_PCI__FMT_4DW ] === 1'b1 ){
reqHdr[ PEC_PCI__ADDR ] = {urandom(),urandom()};
}else{ //Make sure addr[1:0] = 0
reqHdr[33:32] = 0;
}
}
// create completion based on PIO req
f_env.genIngressCpl( reqHdr, cplHdr, pyld );
badCplHdr = cplHdr;
// corrupt the ingress completion
if ( f_cross4K != 0 ) {
// not implemented yet
}
if ( f_tdSpecified ) {
badCplHdr[ PEC_PCI__TD ] = f_tdFieldValue;
}
// Force the digest if we've got a
// cpl without data and a negative
// 'adjustment'.
if ( f_adjustLen < 0 && !badCplHdr[PEC_PCI__FMT_DATA] )
badCplHdr[PEC_PCI__TD] = 1;
// Check if cpl is supposed to be expected
if ( f_solicitedCpl ) {
// drive the ILU with the request
_INFO_MSG_MAL_CPL( psprintf("Sending PIO request (tag=%h)",reqTag) );
f_env.driveILU( reqHdr, 0, 0 );
// expect the request out the TLU
f_env.expectPCIE( reqHdr, 0 );
// drive the TLU with the bad cpl
// and free the PIO tag
f_env.drivePCIE( badCplHdr, pyld, f_adjustLen, *, *, f_abortErrTlp );
_INFO_MSG_MAL_CPL( psprintf("Sending malformed completion (tag=%h)",reqTag) );
f_env.waitIngressLatency( badCplHdr, (f_adjustLen>0) ? f_adjustLen : 0 );
if ( f_errQueue != 0 ) {
mailbox_put( f_errQueue, e_ERR_ue_mfp );
mailbox_put( f_errQueue, (f_adjustLen<0) ? 128'bx : cplHdr );
}
f_env.drivePCIE( cplHdr, pyld );
f_env.expectILU( cplHdr, pyld );
f_env.freePioTag( reqTag );
}
else { /* unsolicited cpl */
f_env.drivePCIE( badCplHdr, pyld, f_adjustLen, *, *, f_abortErrTlp );
_INFO_MSG_MAL_CPL( psprintf("Sending malformed completion (tag=%h)",reqTag) );
f_env.waitIngressLatency( badCplHdr, (f_adjustLen>0) ? f_adjustLen : 0 );
if( f_errQueue != 0 ) {
mailbox_put( f_errQueue, e_ERR_ue_mfp );
mailbox_put( f_errQueue, (f_adjustLen<0) ? 128'bx : cplHdr );
}
}
} /* end Execute */
} /* end MalCplPEUStr */