Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / ilu_peu / vera / N2fc / N2fcPioCfgIORdStr.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: N2fcPioCfgIORdStr.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 N2fcPioCfgIORdStr extends PioCfgIORdPEUStr {
local string cmd;
local bit [63:0] addr;
local bit [31:0] length;
local bit [31:0] dat;
local integer pio_error; // 0 = no error, 1 = timeout, 2 = uc
// ******************************************************************
// The Test Environment objects need to execute the strategy.
// ******************************************************************
protected PEUTestEnv _env;
public task new (PEUTestEnv a_env, string cmd, bit [63:0] addr, bit [31:0] length, bit [31:0] dat, integer err);
public task Execute();
local task SetCplHdr ();
local task SetupParms ();
}
task N2fcPioCfgIORdStr::new (PEUTestEnv a_env,
string cmd,
bit [63:0] addr,
bit [31:0] length,
bit [31:0] dat,
integer err
) {
super.new (a_env);
if ( err == 3 ) {
return; // don't set up an expect or a completion
}
this._env = a_env;
this.cmd = cmd;
this.addr = addr;
this.length = length;
this.dat = dat;
this.pio_error = err;
this.SetupParms ();
this.Execute ();
}
//-------------------------------------------------------------------------
// over-ride parent class method
//-------------------------------------------------------------------------
task N2fcPioCfgIORdStr::Execute() {
bit CfgRdCpl=0; //If set the env will flip the completion byte order
// since Denali does it automatically so DMUXtr doesn't
// need to store an array for the payload
//// printf ("\nUDEBUG : N2fcPioCfgIORdStr::Execute called \n");
SetPacketParams();
// Set up the Reqest ID bits from the CSR
reqHdr[PEC_PCI__REQ_ID] = PiuCsrs.piuREQ_ID;
cplHdr[PEC_PCI__CPL_REQ_ID] = PiuCsrs.piuREQ_ID;
this._env.expectPCIE(reqHdr, 0, 1);
non_posted_read_cmpl_outstanding++;
SetCplHdr ();
if ( this.pio_error == 1 ) {
printf ("\nDEBUG : N2fcPioCfgIORdStr::Execute pio timeout requested, so no completion generated\n");
return; // timeout - don't send a completion
}
fork { // don't block other expects
sync( ALL, _env.ev_StallPioCpl); // stall the completion if event is OFF
//Added CfgRdCpl since Denali flips the bytes for Cfg Reads
// this will flip the bytes back so the DMUXtr doesn't need to be changed
//IOS extends this class and has its own execute so it won't affect IOS
//FullChip needs to do the same
CfgRdCpl = (this._type_req !== PEC_PCI__TYPE_IO);
if ((this._cpl_status === PEC_PCI__CPL_STATUS_RSVD1) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD2) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD3) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD4)) {
this._env.Pod.FNXPCIEEnableTrans.SuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlCplSt ); //Malformed Completion TLP - Reserved completion status (%u).
}
printf ("\nDEBUG : N2fcPioCfgIORdStr::Execute _op_cpl %d f_abortErrTlp %d pio_error %d\n\n", this._ep_cpl, super.f_abortErrTlp, pio_error);
//if ( this._ep_cpl && super.f_abortErrTlp ) {
if (this.pio_error == 2) {
this._cpl_status = PEC_PCI__CPL_STATUS_UR;
cplHdr [PEC_PCI__CPL_STATUS] = PEC_PCI__CPL_STATUS_UR;
cplHdr [PEC_PCI__FMT] = PEC_PCI__FMT_NO_DATA_3DW;
cplHdr [PEC_PCI__LEN] = 0;
this._env.drivePCIE(cplHdr, this._data,*,*,*, 1, CfgRdCpl);
}
else {
this._env.drivePCIE(cplHdr, this._data,*,*,*, *, CfgRdCpl );
}
if ((this._cpl_status === PEC_PCI__CPL_STATUS_CA) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_UR) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD1) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD2) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD3) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD4)) {
//this._env.expectILU(urHdr, this._data);
//mailbox_put(this._errQueue, e_ERR_oe_ruc);
//mailbox_put(this._errQueue, cplHdr );
if ( (this._cpl_status === PEC_PCI__CPL_STATUS_RSVD1) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD2) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD3) ||
(this._cpl_status === PEC_PCI__CPL_STATUS_RSVD4)) {
this._env.Pod.FNXPCIEEnableTrans.unSuppressDenaliErr( PCIE_TL_NONFATAL_TLP_MF_vlCplSt ); //Malformed Completion TLP - Reserved completion status (%u).
}
}
else if (this._cpl_status === PEC_PCI__CPL_STATUS_CRS) {
this._env.expectTimeoutCpl(reqHdr);
//mailbox_put(this._errQueue, e_ERR_oe_crs);
//mailbox_put(this._errQueue, cplHdr );
}
else if (this._ep_cpl === 1'b_1) {
@(posedge CLOCK);
cplHdr [PEC_PCI__EP] = 0;
this._env.drivePCIE(cplHdr, this._data,*,*,*,*,CfgRdCpl );
this._env.expectILU(cplHdr, this._data);
if ( this._errQueue != 0 )
{
cplHdr [PEC_PCI__EP] = 1;
//mailbox_put(this._errQueue, e_ERR_ue_pp);
//mailbox_put(this._errQueue, cplHdr);
}
}
else {
//// this._env.expectILU(cplHdr, this._data);
}
this._env.freePioTag(this._tag);
non_posted_read_cmpl_outstanding--;
} join none
}
//-------------------------------------------------------------------------
// New method. capture the header Request Tag and return it on completion
//-------------------------------------------------------------------------
task N2fcPioCfgIORdStr::SetCplHdr () {
printf ("\nUDEBUG : N2fcPioCfgIORdStr::SetCplHdr Got a Req Tag of %0h\n", this._env.ReceivedReqTag);
cplHdr[PEC_PCI__CPL_TAG] = this._env.ReceivedReqTag;
}
//-------------------------------------------------------------------------
// New method. Setup parent properties based on Core request
//-------------------------------------------------------------------------
task N2fcPioCfgIORdStr::SetupParms() {
// setup parameters based on request
//
_type_req_prob_cfg0 = 0;
_type_req_prob_cfg1 = 0;
_type_req_prob_io = 0;
_len_min = 1;
_len_max = 1;
_cpl_id_min = 0;
_cpl_id_max = 0;
_data_min = dat;
_data_max = dat;
_format_req_prob_3dw = 100;
_format_req_prob_4dw = 0;
_ep_cpl_prob_false = 100;
_ep_cpl_prob_true = 0;
_td_cpl_prob_false = 100;
_td_cpl_prob_true = 0;
_cpl_status_prob_sc = 100;
_cpl_status_prob_ur = 0;
_cpl_status_prob_crs = 0;
_cpl_status_prob_ca = 0;
_cpl_status_prob_rsvd1 = 0;
_cpl_status_prob_rsvd2 = 0;
_cpl_status_prob_rsvd3 = 0;
_cpl_status_prob_rsvd4 = 0;
_bcm_prob_false = 100;
_bcm_prob_true = 0;
case (cmd) {
"CFGRD0" : {
this._type_req_prob_cfg0 = 1;
_addr_lsb_min = {addr[27:12], 4'b0, addr[11:2], 2'b0};
}
"CFGRD1" : {
this._type_req_prob_cfg1 = 1;
_addr_lsb_min = {addr[27:12], 4'b0, addr[11:2], 2'b0};
}
"IORD" : {
this._type_req_prob_io = 1;
_addr_lsb_min = {addr[27:2], 2'b0};
}
default : { printf ("\n N2fcPioCfgIORdStr unknown command \n"); }
}
_addr_lsb_max = _addr_lsb_min;
// Select DWBE based on address, length combination
//
_last_dwbe_min = 4'b0000;
_last_dwbe_max = _last_dwbe_min;
case (length) {
32'd1 :
case (addr[1:0]) {
2'b00 : _first_dwbe_min = 4'b0001;
2'b01 : _first_dwbe_min = 4'b0010;
2'b10 : _first_dwbe_min = 4'b0100;
2'b11 : _first_dwbe_min = 4'b1000;
default :
printf ("\n N2fcPioCfgIORdStr::SetupParms size warning A = %0h L = %0d\n", addr[1:0], length);
}
32'd2 :
case (addr[1:0]) {
2'b00 :_first_dwbe_min = 4'b0011;
2'b10 :_first_dwbe_min = 4'b1100;
default :
printf ("\n N2fcPioCfgIORdStr::SetupParms size warning A = %0h L = %0d\n", addr[1:0], length);
}
32'd4 :
case (addr[1:0]) {
2'b00 :_first_dwbe_min = 4'b1111;
default :
printf ("\n N2fcPioCfgIORdStr::SetupParms size warning A = %0h L = %0d\n", addr[1:0], length);
}
32'd8 : {
_first_dwbe_min = 4'b1111;
_last_dwbe_min = 4'b1111;
_len_min = 2;
printf ("\n N2fcPioCfgIORdStr::SetupParms size warning A = %0h L = %0d\n", addr[1:0], length);
}
default :
printf ("\n N2fcPioCfgIORdStr::SetupParms warning: Illegal Size = %0d\n", length);
}
_first_dwbe_max = _first_dwbe_min;
}