Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / vlib / FNXPCIEXactor / src / FNXPCIEXactorSignalInterface.vr
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: FNXPCIEXactorSignalInterface.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 ============================================
#include <vera_defines.vrh>
// XactorFmwork and XactorComponents libraries
#include "XactorBasePacket.vrh"
#include "XactorBaseSignalInterface.vrh"
#include "XactorCtrl.vrh"
#include "XactorUtilities.vrh"
#include "XactorDefines.vri"
#include "XactorClk.port.vri"
// DenaliPCIE libary
#include "DenaliPCIE.vri"
// FNXPCIEXactor library
#include "FNXPCIEXactorDefines.vri"
#include "FNXPCIEXactorPorts.vri"
// report library
#include "cReport.vrh"
#include "FNXPCIEXactorReportMacros.vri"
class FNXPCIEXactorSignalInterface extends XactorBaseSignalInterface {
// Inherited Members
// MyReport declared in XactorBaseSignalInterface
// Base Class and Method Names For QR Macros
local string ClassName = "FNXPCIEXtrSgnlIntf";
local string MethodName = null;
local string XactorName; // Name of transactor
local integer PortNum; // PCIE Port Number
local FNXPCIEXactorUtilities Util; // Xactor Utilities
local FNXPCIEXactorAssertCovDatabase AssertCovDatabase; // Assertion Coverage Database
local FNXPCIEXactorStatsDatabase StatsDatabase; // Statistics Database
local FNXPCIEXactorReplayMonitor ReplayMonitor; // Replay Buffer Monitor
local XactorCtrl xtrCtrl;
local XactorClk ClkPort; // Clock port
local FNXPCIEXactorDenaliClkPort DenaliClkPort; // Denali PCIE Clock Port
local FNXPCIEXactorDenaliDevice PCIEDevice; // Denali PCIE Device Reference For This Transactor
local FNXPCIEXactorMiscPort MiscPort; // 3/4/04
local integer mToLinks; // To Links Mailbox
local integer mTLPsFromLinks; // TLPs From Links Mailbox
local integer mDLLPsFromLinks; // DLLPs From Links Mailbox
local integer mRetryExpectPipe; // Mailbox: Pipeline to Pass Retry Expects From Denali Callbacks to Xactor Builder
local integer mbluntendTXdata; // EP blunt end data transmit fifo
local bit sampleDllpToLink = 0;
local integer mDLLPsToLinks; // DLLPs To Links Mailbox
local event eLinkUp;
local event eDLLActive;
local event eDLLPToLink;
local FNXPCIEXactorPacket sampledDllpPktToLink;
// public members
bit ExpectOn; // Boolean: Enable/Disable Passing Sampled Packets to Expect Manager
bit TlpDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated TLP Discarding
bit ReplayMonitorOn; // Boolean: Enable/Disable Passing Packets to Replay Monitor
bit AckDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated ACK Discarding
bit FCDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated All Flow Control Discarding
bit FCPostDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated Posted Flow Control Discarding
bit FCNonPostDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated Non Posted Flow Control Discarding
bit FCCplDiscardOn; // Boolean: Enable/Disable Auto-Denali Generated Completion Flow Control Discarding
bit [8:0] linkNmbrTS1; //Used to pass in a new link number driven in TS1s bit[8]=kchar
bit [8:0] linkNmbrTS2; //Used to pass in a new link number driven in TS2s bit[8]=kchar
bit [8:0] laneNmbrTS1; //Used to pass in a new lane number driven in TS1s bit[8]=kchar
bit [8:0] laneNmbrTS2; //Used to pass in a new lane number driven in TS2s bit[8]=kchar
integer expectNullPkt = 0; //Keeps track of how many NULL packets are expected
bit [11:0] currentSeqNum = 0;
bit [11:0] transmittedSeqNum = 0;
// extended sync
integer fts_os_set_count; // use to count the fts os during RC TX_L0s.FTS extended sync scenario
bit count_4096FTS_1SKP = 0;
bit blunt_end = 0;
task new( integer ExpectFifo, // incoming TLP transactions Fifo
integer DllpExpectFifo, // incoming DLLP transactions Fifo
integer DriveFifo, // outgoing TLP/DLLP transactions Fifo
integer RetryPktFifo, // retried TLP transactions Fifo
ReportClass _MyReport, // Reference to report object
string _XactorName, // Name of transactor
XactorCtrl _XactorCtrl, // Used to support disable/enable/reset Xactor
XactorClk _ClkPort, // Clock port
FNXPCIEXactorDenaliClkPort _DenaliClkPort, // Denali PCIE Clock Port
FNXPCIEXactorDenaliDevice _PCIEDevice, // Denali PCIE Device reference
FNXPCIEXactorMiscPort _MiscPort, // Port for Denali reset and Receive Detect signals
FNXPCIEXactorUtilities _Util, // Xactor Utilities
FNXPCIEXactorAssertCovDatabase _AssertCovDatabase, // Assertion Coverage Database
integer _PortNum, // PCIE Port Number
integer Bluntend_TX_fifo // EP blunt end data transmit fifo
);
// public methods
task WriteDenaliReg( integer iDenReg, bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data );
function bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] ReadDenaliReg( integer iDenReg );
task SetupBAR32( integer denReg,
integer addrWidth,
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH-1:0] baseAddr );
task SetupBAR64( integer denRegLower,
integer denRegUpper,
integer addrWidth,
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH*2-1:0] baseAddr );
task SetReqID( bit [FNX_PCIE_XTR_REQ_BUS_NUM_WIDTH-1:0] busNum,
bit [FNX_PCIE_XTR_REQ_DEVICE_NUM_WIDTH-1:0] devNum,
bit [FNX_PCIE_XTR_REQ_FUNC_NUM_WIDTH-1:0] funcNum,
integer regOffset = 0 );
task SuppressDenaliErr( denaliPcieErrorTypeT denErr );
task tempSuppressDenaliErr( denaliPcieErrorTypeT denErr );
task unSuppressDenaliErr( denaliPcieErrorTypeT denErr );
task WaitLinkUp();
task WaitDLLActive();
function string GetEpilogueStr();
task SetRcvDetMode( bit _rcvDetMode );
task SetRcvDetLanes( bit[FNX_PCIE_XTR_RCV_DET_LANES_WIDTH-1:0] _rcvDetLanes );
task SetDenaliReset( bit _denaliReset );
task ResetReplayMonitor();
task EnableSampleDllpToLink();
task DisableSampleDllpToLink();
task SampleDllpPktToLink( XactorBasePacket Pkt, integer Window );
task SetElecIdleLanes( bit[FNX_PCIE_XTR_RCV_DET_LANES_WIDTH-1:0] _elecIdleLanes );
task TransmitFTSToLink( integer nmbrFts );
task TransmitSKPToLink( integer nmbrSkp );
// task Transmit_symbol_ToLink( integer nmbrSymbol );
// task TransmitOrdersetToLink( integer nmbrFts, bit [31:0] orderset );
// task TransmitOrdersetToLink( integer nmbrFts, denaliPcieOrderedSet orderset );
task Transmit_symbol_ToLink( integer nmbrSymbol , bit [8:0] symbol);
task TransmitTS1ToLink( integer nmbrTS1 );
//////////////////////////////////////////////////////////////
// Begin -> private methods
//
local task DrivePackets();
local task ProcessRegCbs();
local task ProcessPktCbs();
// assertion coverage processiong methods
local task ProcessPktCb_assert_pass( FNXPCIEXactorPktCbRecord pktCbRecord );
// xmit callback processing methods
local task ProcessPktCb_TL_user_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_user_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_transmit_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_transmit_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_to_DL( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_TX_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_TX_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_to_PL( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_PL_TX_start_packet( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_PL_TX_end_packet( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TX_trans_done( FNXPCIEXactorPktCbRecord pktCbRecord );
// xmit replay buffer callback processing methods
local task ProcessPktCb_DL_TX_retry_buffer_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_TX_retry_buffer_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_TX_retry_buffer_purge( FNXPCIEXactorPktCbRecord pktCbRecord );
// receive callback processing methods
local task ProcessPktCb_PL_RX_start_packet( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_PL_RX_end_packet( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_RX_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_RX_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_PL_to_DL( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_DL_to_TL( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_RX_packet( FNXPCIEXactorPktCbRecord pktCbRecord );
// completion callback processing methods
local task ProcessPktCb_TL_TX_completion_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_TX_completion_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_RX_completion_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_TL_RX_completion_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord );
// error callback processing methods
local task ProcessPktCb_TX_error( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_RX_error( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_error( FNXPCIEXactorPktCbRecord pktCbRecord );
local task ProcessPktCb_unknown( FNXPCIEXactorPktCbRecord pktCbRecord );
// register callback processing methods
local task ProcessRegCbLTSSMState( FNXPCIEXactorRegCbRecord regCbRecord );
local task ProcessRegCbDLCMSMState( FNXPCIEXactorRegCbRecord regCbRecord );
local task ProcessRegCbTLPortState( FNXPCIEXactorRegCbRecord regCbRecord );
local task ProcessRegCbDevCtrl( FNXPCIEXactorRegCbRecord regCbRecord );
local task ProcessRegCbLinkState( FNXPCIEXactorRegCbRecord regCbRecord );
//
// End -> private methods
//////////////////////////////////////////////////////////////
} // end of signal interface sub-class
// constructor
task FNXPCIEXactorSignalInterface::new( integer ExpectFifo, // incoming TLP transactions Fifo
integer DllpExpectFifo, // incoming DLLP transactions Fifo
integer DriveFifo, // outgoing TLP/DLLP transactions Fifo
integer RetryPktFifo, // retried TLP transactions Fifo
ReportClass _MyReport, // Reference to report object
string _XactorName, // Name of transactor
XactorCtrl _XactorCtrl, // Used to support disable/enable/reset Xactor
XactorClk _ClkPort, // Clock port
FNXPCIEXactorDenaliClkPort _DenaliClkPort, // Denali PCIE Clock Port
FNXPCIEXactorDenaliDevice _PCIEDevice, // Denali PCIE Device reference
FNXPCIEXactorMiscPort _MiscPort, // Port for Denali reset and Receive Detect signals
FNXPCIEXactorUtilities _Util, // Xactor Utilities
FNXPCIEXactorAssertCovDatabase _AssertCovDatabase, // Assertion Coverage Database
integer _PortNum, // PCIE Port Number
integer Bluntend_TX_fifo // EP blunt end data transmit fifo
)
{
MyReport = _MyReport;
XactorName = _XactorName;
xtrCtrl = _XactorCtrl;
ClkPort = _ClkPort;
DenaliClkPort = _DenaliClkPort;
PCIEDevice = _PCIEDevice;
Util = _Util;
AssertCovDatabase = _AssertCovDatabase;
PortNum = _PortNum;
MiscPort = _MiscPort;
mToLinks = DriveFifo;
mTLPsFromLinks = ExpectFifo;
mDLLPsFromLinks = DllpExpectFifo;
mRetryExpectPipe = RetryPktFifo;
mbluntendTXdata = Bluntend_TX_fifo;
//N2 DMT Bypass Link Train ExpectOn = 0;
ExpectOn = 1;
TlpDiscardOn = 1;
ReplayMonitorOn = 1;
sampleDllpToLink = 0;
AckDiscardOn = 0;
FCDiscardOn = 0;
FCPostDiscardOn = 0;
FCNonPostDiscardOn = 0;
FCCplDiscardOn = 0;
linkNmbrTS1 = 9'h100;
linkNmbrTS2 = 9'h100;
laneNmbrTS1 = 9'h100;
laneNmbrTS2 = 9'h100;
StatsDatabase = new( MyReport, XactorName );
ReplayMonitor = new( MyReport, XactorName, Util, PortNum );
// 9/16/04 Not sure why ReplayMonitor instantiated twice here - could have been a clearcase merge problem
// ReplayMonitor = new( MyReport, XactorName, Util, PortNum );
//Drive the rcvDetMode to fast simulation and rcvDetLanes to all 8 lanes as default
MiscPort.$rcvDetMode = 1'b0; //0 = 20nSec , 1 = 100 uSec
MiscPort.$rcvDetLanes = 8'hzz; //1 bit for each of the 8 lanes, 1 means a receiver is detected on that lane
MiscPort.$denaliReset = 1'b1; //Default to driven
MiscPort.$elecIdleLanes = 8'h00; //bit for each of the 8 lanes,
//1 means lane forced to electrical idle
// extended sync
fts_os_set_count = 0; // use to count the fts os during RC TX_L0s.FTS extended sync scenario
// count_4096FTS_1SKP = 0;
fork
{ DrivePackets(); }
{ ProcessPktCbs(); }
{ ProcessRegCbs(); }
join none
}
task FNXPCIEXactorSignalInterface::DrivePackets()
{
denaliPciePacket denPkt;
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
bit cast_ok;
integer status;
string MethodName = "DrivePackets";
while (1) { // continously process packets to be driven
if (xtrCtrl.GetDisableFlag() === 1'b0 ) { // ensure xactor is enabled
@(posedge ClkPort.$XClk);
// retreive next packet to be driven
mailbox_get( WAIT, mToLinks, fnxPkt );
// Create Denali Packet To Be Driven From FNX PCIE Packet
denPkt = fnxPkt.CreateDenaliPkt();
// Place FNX PCIE Packet Into User Data of Denali Packet
userData = new();
userData.SetPkt( fnxPkt );
denPkt.setUserData( userData );
// inject Null TLP if this error injection is activated
if (fnxPkt.DenaliErr == PCIE_EI_TLP_NULL) {
denPkt.setErrInject( PCIE_EI_TLP_NULL );
PCIEX_QR_D3("AC: just call setErrInject(PCIE_EI_TlP_NULL) \n");
}
// inject ECRC if this error injection is activated
if (fnxPkt.DenaliErr == PCIE_EI_TLP_ENABLE_ECRC) {
denPkt.setErrInject( PCIE_EI_TLP_ENABLE_ECRC);
denPkt.setErrInject( PCIE_EI_RELAX_CHK );
PCIEX_QR_D3("AC: just call setErrInject(PCIE_EI_TLP_ENABLE_ECRC) \n");
}
// Add Denali Packet to Denali's User Queue
// status = PCIEDevice.transAdd( denPkt, 0 );
if( !fnxPkt.DriveImmediately ){
status = PCIEDevice.transAdd( denPkt, 0, DENALI_ARG_trans_append );
}
else{
status = PCIEDevice.transAdd( denPkt, 0, DENALI_ARG_trans_prepend );
}
// UNCOMMENT FOR DENALI DEBUG
// printf("<><>DENALI<><> Added to User Queue:\n");
// denPkt.printInfo();
if(status != 0){
PCIEX_QR_ERR( "%s-> Failed to Add Packet to Denali User Queue:\n%s",
XactorName, Util.DenaliPktToStr(denPkt,PortNum) );
}
else if( fnxPkt.DriveImmediately ){
PCIEX_QR_D3( "%s-> Added Packet to Beginning of Denali User Queue:\n%s",
XactorName, Util.DenaliPktToStr(denPkt,PortNum) );
}
else{
PCIEX_QR_D3( "%s-> Added Packet to End of Denali User Queue:\n%s",
XactorName, Util.DenaliPktToStr(denPkt,PortNum) );
}
}
else // advance edge, then re-check enable
@(posedge ClkPort.$XClk);
}
}
// process register callbacks received from Denali Xactor
task FNXPCIEXactorSignalInterface::ProcessRegCbs()
{
FNXPCIEXactorRegCbRecord regCbRecord;
string MethodName = "ProcessRegCbs";
while (1) {
if (xtrCtrl.GetDisableFlag() === 1'b0 ) { // ensure xactor is enabled
// blocks until next callback record is popped from malibox
regCbRecord = PCIEDevice.PopRegCbRecord();
PCIEX_QR_D2( "%s-> Callback Dequeued:\n %s",
XactorName, regCbRecord.GetStr() );
case (regCbRecord.Reg) {
PCIE_REG_DEN_LTSSM_STATE : ProcessRegCbLTSSMState( regCbRecord );
PCIE_REG_DEN_DLCMSM_STATE : ProcessRegCbDLCMSMState( regCbRecord );
PCIE_REG_DEN_LINK_ST : ProcessRegCbLinkState( regCbRecord );
PCIE_REG_DEN_TLPORT_STATE : ProcessRegCbTLPortState( regCbRecord );
PCIE_REG_DEN_DEV_CTRL : ProcessRegCbDevCtrl( regCbRecord );
default : PCIEX_QR_D3( "%s-> Register Callback Has No Handler:\n %s",
XactorName, regCbRecord.GetStr() );
}
// Signal Callback Has Been Processed
regCbRecord.MarkProcessed();
}
else // advance edge, then re-check enable
@(posedge ClkPort.$XClk);
}
}
// process packet callbacks received from Denali Xactor
task FNXPCIEXactorSignalInterface::ProcessPktCbs()
{
FNXPCIEXactorPktCbRecord pktCbRecord;
string MethodName = "ProcessPktCbs";
while (1) {
if (xtrCtrl.GetDisableFlag() === 1'b0 ) { // ensure xactor is enabled
// blocks until next callback record is popped from malibox
pktCbRecord = PCIEDevice.PopPktCbRecord();
PCIEX_QR_D2( "%s-> Callback Dequeued:\n %s | Denali Packet Contents:\n%s",
XactorName, pktCbRecord.GetStr(), Util.DenaliPktToStr(pktCbRecord.Pkt,PortNum) );
// UNCOMMENT FOR DENALI DEBUG
// printf("<><>DENALI<><> Callback Packet:\n");
// pktCbRecord.Pkt.printInfo();
case (pktCbRecord.Rsn) {
// assertion coverage callbacks
PCIE_CB_assert_pass : ProcessPktCb_assert_pass( pktCbRecord );
// xmit callbacks
PCIE_CB_TL_user_queue_enter : ProcessPktCb_TL_user_queue_enter( pktCbRecord );
PCIE_CB_TL_user_queue_exit : ProcessPktCb_TL_user_queue_exit( pktCbRecord );
PCIE_CB_TL_transmit_queue_enter : ProcessPktCb_TL_transmit_queue_enter( pktCbRecord );
PCIE_CB_TL_transmit_queue_exit : ProcessPktCb_TL_transmit_queue_exit( pktCbRecord );
PCIE_CB_TL_to_DL : ProcessPktCb_TL_to_DL( pktCbRecord );
PCIE_CB_DL_TX_queue_enter : ProcessPktCb_DL_TX_queue_enter( pktCbRecord );
PCIE_CB_DL_TX_queue_exit : ProcessPktCb_DL_TX_queue_exit( pktCbRecord );
PCIE_CB_DL_to_PL : ProcessPktCb_DL_to_PL( pktCbRecord );
PCIE_CB_PL_TX_start_packet : ProcessPktCb_PL_TX_start_packet( pktCbRecord );
PCIE_CB_PL_TX_end_packet : ProcessPktCb_PL_TX_end_packet( pktCbRecord );
PCIE_CB_TX_trans_done : ProcessPktCb_TX_trans_done( pktCbRecord );
// replay callbacks
PCIE_CB_DL_TX_retry_buffer_enter : ProcessPktCb_DL_TX_retry_buffer_enter( pktCbRecord );
PCIE_CB_DL_TX_retry_buffer_exit : ProcessPktCb_DL_TX_retry_buffer_exit( pktCbRecord );
PCIE_CB_DL_TX_retry_buffer_purge : ProcessPktCb_DL_TX_retry_buffer_purge( pktCbRecord );
// receive callbacks
PCIE_CB_PL_RX_start_packet : ProcessPktCb_PL_RX_start_packet( pktCbRecord );
PCIE_CB_PL_RX_end_packet : ProcessPktCb_PL_RX_end_packet( pktCbRecord );
PCIE_CB_DL_RX_queue_enter : ProcessPktCb_DL_RX_queue_enter( pktCbRecord );
PCIE_CB_DL_RX_queue_exit : ProcessPktCb_DL_RX_queue_exit( pktCbRecord );
PCIE_CB_PL_to_DL : ProcessPktCb_PL_to_DL( pktCbRecord );
PCIE_CB_DL_to_TL : ProcessPktCb_DL_to_TL( pktCbRecord );
PCIE_CB_TL_RX_packet : ProcessPktCb_TL_RX_packet( pktCbRecord );
// completion callbacks
PCIE_CB_TL_TX_completion_queue_enter : ProcessPktCb_TL_TX_completion_queue_enter( pktCbRecord );
PCIE_CB_TL_TX_completion_queue_exit : ProcessPktCb_TL_TX_completion_queue_exit( pktCbRecord );
PCIE_CB_TL_RX_completion_queue_enter : ProcessPktCb_TL_RX_completion_queue_enter( pktCbRecord );
PCIE_CB_TL_RX_completion_queue_exit : ProcessPktCb_TL_RX_completion_queue_exit( pktCbRecord );
// error callbacks
PCIE_CB_TX_error : ProcessPktCb_TX_error( pktCbRecord );
PCIE_CB_RX_error : ProcessPktCb_RX_error( pktCbRecord );
PCIE_CB_error : ProcessPktCb_error( pktCbRecord );
PCIE_CB_unknown : ProcessPktCb_unknown( pktCbRecord );
// default -> no handler
default : PCIEX_QR_D3( "%s-> Callback Has No Handler:\n %s",
XactorName, pktCbRecord.GetStr() );
}
// Signal Callback Has Been Processed
pktCbRecord.MarkProcessed();
}
else // advance edge, then re-check enable
@(posedge ClkPort.$XClk);
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_assert_pass( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_assert_pass";
AssertCovDatabase.Add( pktCbRecord.covPt );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_user_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
FNXPCIEXactorUserData userData;
denaliPcieTlpPacket tlpPkt;
denaliPcieTlpMsgPacket tlpMsgPkt;
denaliPcieTlpMsgTypeT msg_type;
integer status;
string MethodName = "PPktCb_TL_user_queue_enter";
// status = 1 if cast_assign is successful
status = (cast_assign( tlpMsgPkt, pktCbRecord.Pkt, CHECK) );
// printf("tlpMsgPkt cast_assign status = %d \n", status);
// get the message type if this is a message package
if (status == 1) {
msg_type = tlpMsgPkt.getMessageType();
}
// Discard Any TLPs Internally Generated By Denali Transactor (Excluding Replays)
if (cast_assign( tlpPkt, pktCbRecord.Pkt, CHECK) ) { // is a Denali TLP
if (TlpDiscardOn) {
// only discard if not msg || if msg is not = PME_TO_ack or PM_PME
// if ((status == 0 ) || (status == 1 && msg_type !== DENALI_PCIE_TL_MSG_PME_TO_Ack)) {
if (status == 1 && (msg_type == DENALI_PCIE_TL_MSG_PME_TO_Ack
|| msg_type == DENALI_PCIE_TL_MSG_PM_PME )) {
PCIEX_QR_D1( "%s-> AC: PME_To_ACk message, so did not discard:\n%s",
XactorName, pktCbRecord.GetStr() );
}
else {
// not PME_TO_ACK nor PM_PME msg \n");
// Mark TLP Packet to Be Discarded
userData = new();
userData.SetDiscard();
tlpPkt.setUserData( userData );
tlpPkt.setErrInject( PCIE_EI_DISCARD ); // Set TLP to Be Discarded
status = tlpPkt.transSet(); // Pass Changes to Denali C Model
if (status != 0)
PCIEX_QR_ERR( "%s-> transSet() Failed(%0d) For Callback:\n %s\n Denali Packet Contents:\n%s",
XactorName, status, pktCbRecord.GetStr(), Util.DenaliPktToStr(pktCbRecord.Pkt,PortNum) );
else
PCIEX_QR_D1( "%s-> Flagged Denali Generated TLP to be Discarded:\n%s",
XactorName, pktCbRecord.GetStr() );
}
// else {
// PME_To_ACk message, so did not discard:\n%s",
// XactorName, pktCbRecord.GetStr() );
// }
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_user_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
denaliPciePacket denPkt;
denaliPcieDllpPacket dllpPkt;
integer status;
string MethodName = "PPktCb_TL_user_queue_exit";
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
if (fnxPkt != null) {
// Set Denali Error Injection Type If Not NONE (After RELAX_CHK Is Cleared)
if (fnxPkt.DenaliErr !== PCIE_EI_NONE) {
if (cast_assign( denPkt, pktCbRecord.Pkt, CHECK ) )
denPkt.setErrInject( fnxPkt.DenaliErr );
PCIEX_QR_D3("AC: just call denPkt.setErrInject(%s) TL_user_queue_exit \n", fnxPkt.DenaliErr);
status = denPkt.transSet(); // Pass Changes to Denali C Model
}
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_transmit_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_transmit_queue_enter";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_transmit_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_transmit_queue_exit";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_to_DL( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPcieTlpPacket tlpPkt;
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
string MethodName = "PPktCb_TL_to_DL";
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
if (fnxPkt != null) {
// Retrieve Tag and ECRC for TLPs if Set to be Generated
if (cast_assign( tlpPkt, pktCbRecord.Pkt, CHECK)) {
if ( fnxPkt.GenTag ) // Retrieve Tag
fnxPkt.ReqTag = tlpPkt.getTransactionIdTag();
if ( fnxPkt.GenECRC ) // Retrieve ECRC
fnxPkt.ECRC = tlpPkt.getEcrc();
fnxPkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf("%s %s-> Packet Updated:", PCIEX_QR_PREFIX, XactorName ));
}
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_TX_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_DL_TX_queue_enter";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_TX_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_DL_TX_queue_exit";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_to_PL( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPcieDlpPacket dlpPkt;
denaliPcieDllpPacket dllpPkt;
denaliPciePlPacket plPkt;
denaliPcieDllpTypeT dllpType;
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
integer status;
bit [FNX_PCIE_XTR_DLL_FRM_LCRC_32_WIDTH-1:0] DLLLCRC32;
bit [FNX_PCIE_XTR_DLL_FRM_LCRC_32_WIDTH-1:0] temp_DLLLCRC32;
string MethodName = "PPktCb_DL_to_PL";
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
if (fnxPkt != null) {
///////////////////////////////////////////////////////
// Begin -> Update TLP
//
// Retrieve DLL Framing Fields From Denali and Place in FNXPCIEXactorPacket
if (fnxPkt.isTlp()) {
if (cast_assign(dlpPkt, pktCbRecord.Pkt, CHECK)) {
if ( fnxPkt.GenLCRC32 ) // Retrieve 32-bit LCRC
{
fnxPkt.DLLFrmLCRC32 = dlpPkt.getLcrc();
DLLLCRC32 = fnxPkt.DLLFrmLCRC32;
}
if ( fnxPkt.GenSeqNum ) // Retrieve Seq Number
fnxPkt.DLLFrmSeqNum = dlpPkt.getTlpSeqNum();
fnxPkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf("%s %s-> Packet initial Updated:", PCIEX_QR_PREFIX, XactorName ));
//: //=================================================================
// added for invert 32-bit LCRC, and injection of END/EDB symbols
//: //=================================================================
//: if( fnxPkt.invertLCRC32) // invert the 32-bit LCRC
//: {
//: fnxPkt.DLLFrmLCRC32 = ~(DLLLCRC32);
//: dlpPkt.setLcrc(fnxPkt.DLLFrmLCRC32);
//: status = dlpPkt.transSet(); // Pass Changes to Denali C Model
//: temp_DLLLCRC32 = dlpPkt.getLcrc();
// fnxPkt.invertLCRC32 = 0; // once set, then remove the force setting
//: // let the non force version from retry buffer go through on replay
// at time %d, invertLCRC32 is set = %d, fnx.LCRC32 = %0d'h%h dlpPkt.LCRC32 = %h\n", get_time(LO), fnxPkt.invertLCRC32,
//: FNX_PCIE_XTR_DLL_FRM_LCRC_32_WIDTH, fnxPkt.DLLFrmLCRC32, temp_DLLLCRC32 );
//: }
}
//FNXPCIEXactorSignalInterface.vr: fnxPkt.set_endsymbol_EDB = %d \n", fnxPkt.set_endsymbol_EDB) ;
// // processing end symbol
// if (cast_assign( plPkt, pktCbRecord.Pkt, CHECK )) {
// fnxPkt.EndFrame = plPkt.getEndFrame();
// inside cast_assign of pktCbRecord.Pkt \n");
// if (fnxPkt.set_endsymbol_EDB) // end symbol = EDB
// {
// fnxPkt.EndFrame = PCIE_EDB_SYMBOL;
// fnxPkt.EndFrame = 9'h1FE;
// plPkt.setEndFrame(fnxPkt.EndFrame);
// status = plPkt.transSet(); // Pass Changes to Denali C Model
// fnxPkt.set_endsymbol_EDB = 0; // once set, then remove the force setting
// // let the non force version from retry buffer go through on replay
// set_endsymbol_EDB is set = %d, EndFrame = %s \n", fnxPkt.set_endsymbol_EDB,
// fnxPkt.EndFrame );
// }
//
// } // end process end symbol
}
// End -> Update TLP
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// Begin -> Update DLLP
//
// Retrieve DLL Generated Fields From Denali and Place in FNXPCIEXactorPacket
if (fnxPkt.isDllp()) {
if (cast_assign(dllpPkt, pktCbRecord.Pkt, CHECK)) {
if (fnxPkt.GenLCRC16)
fnxPkt.DllpLCRC16 = dllpPkt.getLcrc();
}
}
// End -> Update DLLP
///////////////////////////////////////////////////////
}
}else{ //// packet was generated by Denali
if (cast_assign(dllpPkt, pktCbRecord.Pkt, CHECK)) {
// Discard Any Dllp ACKs Internally Generated By Denali Transactor
dllpType = dllpPkt.getDllpType();
if( AckDiscardOn && ( dllpType == DENALI_PCIE_DL_ACK) ){
dllpPkt.setErrInject( PCIE_EI_DISCARD ); // Set DLLP to Be Discarded
status = dllpPkt.transSet(); // Pass Changes to Denali C Model
if (status != 0)
PCIEX_QR_ERR( "%s:ProcessPktCb_DL_to_PL-> transSet() Failed(%0d) For Callback:\n %s\n Denali Packet Contents:\n%s", XactorName, status, pktCbRecord.GetStr(), Util.DenaliPktToStr(pktCbRecord.Pkt,PortNum) );
else
PCIEX_QR_D1( "%s-> Flagged Denali Generated Dllp ACK to be Discarded:\n%s", XactorName, pktCbRecord.GetStr() );
}
if( (FCDiscardOn && (( dllpType == DENALI_PCIE_DL_UPDATE_FC_P) ||
( dllpType == DENALI_PCIE_DL_UPDATE_FC_NP) ||
( dllpType == DENALI_PCIE_DL_UPDATE_FC_CPL) ))
||(FCPostDiscardOn && (( dllpType == DENALI_PCIE_DL_UPDATE_FC_P)))
||(FCNonPostDiscardOn && (( dllpType == DENALI_PCIE_DL_UPDATE_FC_NP)))
||(FCCplDiscardOn && (( dllpType == DENALI_PCIE_DL_UPDATE_FC_CPL))) ){
dllpPkt.setErrInject( PCIE_EI_DISCARD ); // Set DLLP to Be Discarded
status = dllpPkt.transSet(); // Pass Changes to Denali C Model
if (status != 0)
PCIEX_QR_ERR( "%s:ProcessPktCb_DL_to_PL-> transSet() Failed(%0d) For Callback:\n %s\n Denali Packet Contents:\n%s", XactorName, status, pktCbRecord.GetStr(), Util.DenaliPktToStr(pktCbRecord.Pkt,PortNum) );
else
PCIEX_QR_D1( "%s-> Flagged Denali Generated Dllp FC to be Discarded:\n%s", XactorName, pktCbRecord.GetStr() );
}
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_PL_TX_start_packet( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_PL_TX_start_packet";
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
denaliPcieTrainingSet tsPkt;
denaliPciePlPacket plPkt;
denaliPcieDlpPacket dlpPkt;
bit[8:0] linkNumber[*];
bit[8:0] linkNmbr;
bit[8:0] laneNumber[*];
bit[8:0] laneNmbr;
integer size;
integer i;
integer status;
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
//Keep track of sequence numbers
if (cast_assign(dlpPkt, pktCbRecord.Pkt, CHECK)) {
currentSeqNum = dlpPkt.getTlpSeqNum();
if( currentSeqNum == (transmittedSeqNum + 1)%4096 ){ //This
transmittedSeqNum += 1;
}
}
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
// processing end symbol
//FNXPCIEXactorSignalInterface.vr: fnxPkt.set_endsymbol_EDB = %d \n", fnxPkt.set_endsymbol_EDB) ;
if (cast_assign( plPkt, pktCbRecord.Pkt, CHECK )) {
fnxPkt.EndFrame = plPkt.getEndFrame();
if (fnxPkt.set_endsymbol_EDB) // end symbol = EDB
{
// fnxPkt.EndFrame = PCIE_EDB_SYMBOL;
fnxPkt.EndFrame = 9'h1FE;
plPkt.setEndFrame(fnxPkt.EndFrame);
status = plPkt.transSet(); // Pass Changes to Denali C Model
fnxPkt.set_endsymbol_EDB = 0; // once set, then remove the force setting so during retry, it will not force EDB on again
// let the non force version from retry buffer go through on replay
printf("AC: at time = %d, set_endsymbol_EDB is set = %d, EndFrame = %h \n", get_time(LO), fnxPkt.set_endsymbol_EDB,
fnxPkt.EndFrame );
}
} // end process end symbol
// Mark Packet As Starting To Be Driven
fnxPkt.TriggerDriveStart();
}
else{
//If enabled change the Link number transmitted for TSx's
if( cast_assign( tsPkt, pktCbRecord.Pkt, CHECK) ){
if( (tsPkt.getOsType() == DENALI_PCIE_PL__ts1_set) && linkNmbrTS1 !== 9'h100 ){
tsPkt.getLinkNumber( linkNumber );
size = linkNumber.size();
for( i=0; i<size; i++ ){
linkNumber[i] = linkNmbrTS1;
}
//Pass the array to the TS packet
tsPkt.setLinkNumber( linkNumber );
//Make sure the TS packet is updated
status = pktCbRecord.Pkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:ProcessPktCb_PL_TX_start_packet-> transSet() Failed(%0d) For Callback:\n", XactorName, status );
}
else{
PCIEX_QR_D1( "%s->Changed link Number to %0h in TS1 !\n% s", MethodName, linkNmbrTS1 );
}
} //End TS1
if( (tsPkt.getOsType() == DENALI_PCIE_PL__ts2_set) && linkNmbrTS2 !== 9'h100 ){
tsPkt.getLinkNumber( linkNumber );
size = linkNumber.size();
for( i=0; i<size; i++ ){
linkNumber[i] = linkNmbrTS2;
}
//Pass the array to the TS packet
tsPkt.setLinkNumber( linkNumber );
//Make sure the TS packet is updated
status = pktCbRecord.Pkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:ProcessPktCb_PL_TX_start_packet-> transSet() Failed(%0d) For Callback:\n", XactorName, status );
}
else{
PCIEX_QR_D1( "%s->Changed link Number to %0h in TS2 !\n% s", MethodName, linkNmbrTS2 );
}
} //End TS2
if( (tsPkt.getOsType() == DENALI_PCIE_PL__ts1_set) && laneNmbrTS1 !== 9'h100 ){
tsPkt.getLaneNumber( laneNumber );
size = laneNumber.size();
for( i=0; i<size; i++ ){
if( laneNmbrTS1[8] ){
laneNumber[i] = laneNmbrTS1; //for Kchars
}
else{
laneNumber[i] = laneNmbrTS1 + i;
}
}
//Pass the array to the TS packet
tsPkt.setLaneNumber( laneNumber );
//Make sure the TS packet is updated
status = pktCbRecord.Pkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:ProcessPktCb_PL_TX_start_packet-> transSet() Failed(%0d) For Callback setLaneNumber:\n", XactorName, status );
}
else{
PCIEX_QR_D1( "%s->Changed lane Number to %0h in TS1 !\n% s", MethodName, laneNmbrTS1 );
}
} //End TS1
if( (tsPkt.getOsType() == DENALI_PCIE_PL__ts2_set) && laneNmbrTS2 !== 9'h100 ){
tsPkt.getLaneNumber( laneNumber );
size = laneNumber.size();
for( i=0; i<size; i++ ){
if( laneNmbrTS2[8] ){
laneNumber[i] = laneNmbrTS2; //for Kchars
}
else{
laneNumber[i] = laneNmbrTS2 + i;
}
}
//Pass the array to the TS packet
tsPkt.setLaneNumber( laneNumber );
//Make sure the TS packet is updated
status = pktCbRecord.Pkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:ProcessPktCb_PL_TX_start_packet-> transSet() Failed(%0d) For Callback setLaneNumber:\n", XactorName, status );
}
else{
PCIEX_QR_D1( "%s->Changed lane Number to %0h in TS2 !\n% s", MethodName, laneNmbrTS2 );
}
} //End TS2
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_PL_TX_end_packet( FNXPCIEXactorPktCbRecord pktCbRecord )
{
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
denaliPcieDllpPacket dllpPkt;
denaliPciePllpPacket pllpPkt;
denaliPcieDllpTypeT dllpType;
bit [8:0] pktData[*], dllpData[*];
denaliPciePlPacket plPkt;
string tmpStr;
integer i;
integer status;
string MethodName = "PPktCb_PL_TX_end_packet";
// for blunt end
denaliPcieRawPacket rawPkt;
bit [8:0] TX_rawpktdata[*];
if (blunt_end) {
if (cast_assign(rawPkt, pktCbRecord.Pkt, CHECK)) { // packet is a Raw packet
printf("AC: blunt_end, packet is rawdata \n");
// place transmit data info mailbox for comparison with RX data
if (rawPkt.getPktType() == DENALI_PCIE__RawData) { // packet is a Raw data
// do not put into mailbox the first 3 COMs
rawPkt.getPktData( TX_rawpktdata );
if (TX_rawpktdata[0] == PCIE_SYMBOL_K28__5 ) {
printf("AC: time = %d, blunt end rawdata == COM, remember to not put into mailbox \n", get_time(LO));
}
// place data into mailbox
// mailbox_put(mbluntendTXdata, TX_rawdata);
mailbox_put(mbluntendTXdata, rawPkt);
rawPkt.printInfo();
printf("AC: blunt end transmit data is put into mbluntendTXdata mailbox");
}
}
} // blunt end
else {
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
// Mark Packet As Done Being Driven and Update Statistics Database
if (fnxPkt != null) {
// // nullify if EDB and invertLCRC
// if (fnxPkt.set_endsymbol_EDB && fnxPkt.invertLCRC32) // end symbol = EDB
// {
// if (cast_assign( plPkt, pktCbRecord.Pkt, CHECK)) {
// tlpPkt.setErrInject( PCIE_EI_DISCARD ); // Set TLP to Be Discarded
// status = tlpPkt.transSet(); // Pass Changes to Denali C Model
// plPkt.setErrInject( PCIE_EI_DISCARD ); // Set TLP to Be Discarded
// status = plPkt.transSet(); // Pass Changes to Denali C Model
// %s, null package \n");
// }
// }
fnxPkt.TriggerDriveEnd();
PCIEX_QR_D3("AC: FNXSgnIntf.PL_TX_end_packet: packet driven \n");
if( fnxPkt.ReplayInProgress ){
fnxPkt.TriggerReplayEnd();
fnxPkt.ReplayCnt += 1;
fnxPkt.ReplayInProgress = 0;
}
StatsDatabase.UpdatePkt( fnxPkt, FNX_PCIE_XTR_STAT_DIR_XMIT );
}
//Need to know when testbench has driven specific packets
// especially NAKs
if( sampleDllpToLink ){
if (cast_assign( pllpPkt, pktCbRecord.Pkt, CHECK)) {
// Retrieve Raw DLLP Packet Byte Stream
fnxPkt = new( MyReport, XactorName, Util, PortNum );
pllpPkt.getPktData( pktData );
// Create DLLP Data Stream From PL Data Stream
dllpData = new[FNX_PCIE_XTR_NUM_DLLP_BYTES];
for (i=1; i <= FNX_PCIE_XTR_NUM_DLLP_BYTES; i++)
dllpData[i-1] = pktData[i];
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseDLLPByteStream( dllpData );
//Add packet to fifo that upper level testbench can get access to
if( sampleDllpToLink ){
//Make sure packet starts off clean
sampledDllpPktToLink.PktReset();
//Copy the packet so it can be passed
sampledDllpPktToLink.PktCopy( fnxPkt );
//Trigger event to notify a dllp packet has been sent to the DUT
trigger( ONE_BLAST, eDLLPToLink );
}
}
}
}
else { // packet was driven by Denali
// If Denali Packet is DLLP Print Contents at Debug Level 1
if (cast_assign( pllpPkt, pktCbRecord.Pkt, CHECK)) {
// Retrieve Raw DLLP Packet Byte Stream
fnxPkt = new( MyReport, XactorName, Util, PortNum );
pllpPkt.getPktData( pktData );
// Create DLLP Data Stream From PL Data Stream
dllpData = new[FNX_PCIE_XTR_NUM_DLLP_BYTES];
for (i=1; i <= FNX_PCIE_XTR_NUM_DLLP_BYTES; i++)
dllpData[i-1] = pktData[i];
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseDLLPByteStream( dllpData );
//Add packet to fifo that upper level testbench can get access to
if( sampleDllpToLink ){
//Make sure packet starts off clean
sampledDllpPktToLink.PktReset();
//Copy the packet so it can be passed
sampledDllpPktToLink.PktCopy( fnxPkt );
//Trigger event to notify a dllp packet has been sent to the DUT
trigger( ONE_BLAST, eDLLPToLink );
}
StatsDatabase.UpdatePkt( fnxPkt, FNX_PCIE_XTR_STAT_DIR_XMIT );
PCIEX_QR_D2( "%s-> Denali DLLP Driven.\n%s", XactorName, fnxPkt.PktToStr() );
}
}
} // else blunt end
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TX_trans_done( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TX_trans_done";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_TX_retry_buffer_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_DL_TX_retry_buffer_enter";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_TX_retry_buffer_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
FNXPCIEXactorPacket fnxPkt;
FNXPCIEXactorUserData userData;
string MethodName = "PPktCb_DL_TX_retry_buffer_exit";
denaliPcieTlpPacket tlpPkt;
integer status;
//XXXXXXXXXXXXXXXXXXXXx review
//Remove any errors that were injected in the original packet
// if (cast_assign( tlpPkt, pktCbRecord.Pkt, CHECK) ) { // is a Denali TLP
pktCbRecord.Pkt.setErrInject( PCIE_EI_NONE ); // Clear any injected Errors
status = pktCbRecord.Pkt.transSet(); // Pass Changes to Denali C Model
if (status != 0)
PCIEX_QR_ERR( "%s:ProcessPktCb_DL_TX_retry_buffer_exit-> transSet() Failed(%0d) For Callback:\n %s\n Denali Packet Contents:\n%s", XactorName, status, pktCbRecord.GetStr(), Util.DenaliPktToStr(pktCbRecord.Pkt,PortNum) );
else
PCIEX_QR_D1( "%s-> setErrInject( PCIE_EI_NONE ) for TX_retry_buffer_exit successful!\n%s", XactorName, pktCbRecord.GetStr() );
// }
//XXXXXXXXXXXXXXXXXXx review
if ( pktCbRecord.Pkt.getUserData() != null ) { // packet was driven by FNX Xactor
// Retrieve FNX PCIE Packet From Denali Packet's User Data
cast_assign( userData, pktCbRecord.Pkt.getUserData() );
fnxPkt = userData.GetPkt();
if (fnxPkt != null)
fnxPkt.ReplayInProgress = 1; //Used to help signal replayed packet is reTransmitted
fnxPkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf("%s %s-> Retrying Packet:", PCIEX_QR_PREFIX, XactorName ));
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_TX_retry_buffer_purge( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_DL_TX_retry_buffer_purge";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_PL_RX_start_packet( FNXPCIEXactorPktCbRecord pktCbRecord )
{
// for blunt end
denaliPcieRawPacket rawPkt;
bit [8:0] RX_rawpktdata[*];
// bit [8:0] expected_bluntendPktdata[*];
denaliPcieRawPacket expected_bluntendPkt;
// for extended sync
// denaliPcieTrainingSet osPkt;
denaliPcieOrderedSet osPkt;
bit bluntend_compare_start = 0;
string MethodName = "PPktCb_PL_RX_start_packet";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
if (blunt_end) {
if (cast_assign(rawPkt, pktCbRecord.Pkt, CHECK)) { // packet is a Raw
printf("AC: blunt_end, RX packet is rawdata \n");
if (rawPkt.getPktType() == DENALI_PCIE__RawData) { // packet is a Raw data
// compare RX data with transmitted data in mailbox
rawPkt.getPktData( RX_rawpktdata );
rawPkt.printInfo();
mailbox_get(NO_WAIT, mbluntendTXdata, expected_bluntendPkt);
if (rawPkt == expected_bluntendPkt) {
printf("AC: RX bluntend data match transmitted data \n");
}
else {
printf("AC: RX bluntend data did not match transmitted data \n");
}
// check symbol for trigger data
if (RX_rawpktdata[0] == PCIE_SYMBOL_K28__5 ) {
bluntend_compare_start = 1;
printf("AC: time = %d, blunt end rawdata == COM, remember to compare only after this trigger \n", get_time(LO)
);
}
}
}
} // blunt end
// extended sync
if (count_4096FTS_1SKP) {
// determine if OS is received and there are 4096 FTS then 1 SKP
if( cast_assign( osPkt, pktCbRecord.Pkt, CHECK) ){
osPkt.printInfo();
// note: skip does arrive in between 4096 FTS
if ((osPkt.getOsType() == DENALI_PCIE_PL__skip_set) && fts_os_set_count == 4095){
PCIEX_QR_D3("%s: Received %d FTS os set and 1 skip os set", MethodName, fts_os_set_count );
}
if( (osPkt.getOsType() == DENALI_PCIE_PL__fts_set)){
fts_os_set_count++;
PCIEX_QR_D3("%s: AC: time = %d, Receive FTS os set count = %d", MethodName, get_time(LO), fts_os_set_count );
} //End TS1
}
} // end count_4096FTS_1SKP = 1
// reset fts_os_set_count when not counting 4096FTS, to allow diag to run loop
if (count_4096FTS_1SKP == 0) {
fts_os_set_count = 0 ;
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_PL_RX_end_packet( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_PL_RX_end_packet";
// for extended sync
denaliPcieTrainingSet osPkt;
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_RX_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPcieRawPacket rawPkt;
FNXPCIEXactorPacket fnxPkt;
bit [8:0] pktData[*];
string MethodName = "PPktCb_DL_RX_queue_enter";
// ProcessPktCb_DL_RX_queue_enter at time %d \n", get_time(LO));
if (cast_assign(rawPkt, pktCbRecord.Pkt, CHECK)) { // packet is a Raw
if (rawPkt.getPktType() == DENALI_PCIE__RawDllp) { // packet is a RawDllp
// Retrieve Raw DLLP Packet Byte Stream
fnxPkt = new( MyReport, XactorName, Util, PortNum );
rawPkt.getPktData( pktData );
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseDLLPByteStream( pktData );
PCIEX_QR_D2( "%s-> Received RAW DLLP:\n%s",
XactorName, Util.ByteStreamToStr( pktData, fnxPkt.GetPktPrefixStr(), "Byte Stream" ) );
// Place Received & Parsed DLLP Packet Into mDLLPsFromLinks Mailbox
if (ExpectOn) mailbox_put( mDLLPsFromLinks, fnxPkt );
// Update Statistics Database
StatsDatabase.UpdatePkt( fnxPkt, FNX_PCIE_XTR_STAT_DIR_RCV );
}
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_RX_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
// NOTE: In Denali Release pcie,v3.1_11122003 RAW TLPs Do NOT Propagate to
// The DL_to_TL Callback Point, So Pick TLPs Off at RX_queue_exit Cbk Point
denaliPcieRawDlpPacket rawDlpPkt;
FNXPCIEXactorPacket fnxPkt;
denaliPciePacket denPkt;
integer status;
bit [8:0] pktData[*];
string MethodName = "PPktCb_DL_RX_queue_exit";
//N2 DMT Bypass Link Train
// return;
if (cast_assign(rawDlpPkt, pktCbRecord.Pkt, CHECK)) { // packet is a RawDLP
if( cast_assign( denPkt, pktCbRecord.Pkt, CHECK ) ){
//If this is a NULL packet then just drop it
//review N2 - Tried to get Denali to drop incoming NULL Packets but I
// couldn't get ot to work!!!
if( denPkt.getErr() == PCIE_PL_NONFATAL_FRAME_NULL_TLP ){
//Drop the packet from further processing
denPkt.setErrInject( PCIE_EI_DISCARD );
status = denPkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:%s-> transSet() Failed(%0d) :\n", XactorName,MethodName , status );
}
}
else{
// Retrieve Raw TLP Packet Byte Stream (includes DLL Framing Fields)
fnxPkt = new( MyReport, XactorName, Util, PortNum );
rawDlpPkt.getPktData( pktData );
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseTLPByteStream( pktData );
// Place Received & Parsed TLP Packet Into mTLPsFromLinks Mailbox
if (ExpectOn) mailbox_put( mTLPsFromLinks, fnxPkt );
// Pass Received TLP to Replay Monitor
if (ReplayMonitorOn)
ReplayMonitor.UpdateTlp( fnxPkt );
// Update Statistics Database
StatsDatabase.UpdatePkt( fnxPkt, FNX_PCIE_XTR_STAT_DIR_RCV );
}
}
}
/*
if (cast_assign(rawDlpPkt, pktCbRecord.Pkt, CHECK)) { // packet is a RawDLP
// Retrieve Raw TLP Packet Byte Stream (includes DLL Framing Fields)
fnxPkt = new( MyReport, XactorName, Util, PortNum );
rawDlpPkt.getPktData( pktData );
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseTLPByteStream( pktData );
PCIEX_QR_D2( "%s-> Received RAW TLP:\n%s",
XactorName, Util.ByteStreamToStr(pktData, fnxPkt.GetPktPrefixStr(), "Byte Stream" ) );
// Place Received & Parsed TLP Packet Into mTLPsFromLinks Mailbox
if (ExpectOn) mailbox_put( mTLPsFromLinks, fnxPkt );
// Update Statistics Database
StatsDatabase.UpdatePkt( fnxPkt, FNX_PCIE_XTR_STAT_DIR_RCV );
}
*/
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_PL_to_DL( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPcieRawDlpPacket rawDlpPkt;
denaliPciePacket denPkt;
FNXPCIEXactorPacket fnxPkt;
bit [8:0] pktData[*];
integer status;
string MethodName = "PPktCb_PL_to_DL";
//N2 DMT Bypass Link Train
// return;
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
/* //Moved to DL_RX_queue_exit
if (cast_assign(rawDlpPkt, pktCbRecord.Pkt, CHECK)) { // packet is a RawDLP
if( cast_assign( denPkt, pktCbRecord.Pkt, CHECK ) ){
//If this is a NULL packet then just drop it
if( denPkt.getErr() == PCIE_PL_NONFATAL_FRAME_NULL_TLP ){
//Drop the packet from further processing
denPkt.setErrInject( PCIE_EI_DISCARD );
status = denPkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:%s-> transSet() Failed(%0d) :\n", XactorName,MethodName , status );
}
}
else{
// Retrieve Raw TLP Packet Byte Stream (includes DLL Framing Fields)
fnxPkt = new( MyReport, XactorName, Util, PortNum );
rawDlpPkt.getPktData( pktData );
// Pass Raw Byte Stream to FNX PCIE Packet for Parsing in Packet Fields
fnxPkt.ParseTLPByteStream( pktData );
// Pass Received TLP to Replay Monitor
if (ReplayMonitorOn)
ReplayMonitor.UpdateTlp( fnxPkt );
}
}
}
*/
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_DL_to_TL( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_DL_to_TL";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_RX_packet( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_RX_packet";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TX_error( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPcieRawPacket rawPkt;
integer status;
string MethodName = "PPktCb_TX_error";
// this method: works
if (cast_assign(rawPkt, pktCbRecord.Pkt, CHECK)) { // packet is a Raw
if (rawPkt.getPktType() == DENALI_PCIE__RawData) { // packet is a Raw data
if (rawPkt.getErr() == PCIE_PL_NONFATAL_FRAME_NULL_TLP) {
PCIEX_QR_I( "AC: Null Error %s intentionally set, sim continues",
pktCbRecord.GetStr() );
}
else {
PCIEX_QR_ERR( "%s-> Error Callback %s Received",
XactorName, pktCbRecord.GetStr() );
}
}
}
// PCIEX_QR_ERR( "%s-> Error Callback %s Received",
// XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_RX_error( FNXPCIEXactorPktCbRecord pktCbRecord )
{
denaliPciePacket denPkt;
integer status;
string MethodName = "PPktCb_RX_error";
//Check if this is a null packet error and if one is expected
if( expectNullPkt ){
if( cast_assign( denPkt, pktCbRecord.Pkt, CHECK ) ){
if( denPkt.getErr() == PCIE_PL_NONFATAL_FRAME_NULL_TLP ){
//Drop the packet from further processing
denPkt.setErrInject( PCIE_EI_DISCARD );
status = denPkt.transSet(); // Pass Changes to Denali C Model
if( status != 0 ){
PCIEX_QR_ERR( "%s:%s-> transSet() Failed(%0d) :\n", XactorName,MethodName, status );
}
PCIEX_QR_D3( "%s-> %s Expected NULL packet Received",
XactorName, pktCbRecord.GetStr() );
expectNullPkt -= 1;
}
}
}
else{
PCIEX_QR_ERR( "%s-> Error Callback %s Received",
XactorName, pktCbRecord.GetStr() );
}
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_error( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_error";
PCIEX_QR_ERR( "%s-> Error Callback %s Received",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_unknown( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_unknown";
PCIEX_QR_ERR( "%s-> Error Callback %s Received",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessRegCbLTSSMState( FNXPCIEXactorRegCbRecord regCbRecord )
{
string MethodName = "ProcessRegCbLTSSMState";
denaliPcieLtssmStateT oldSt, newSt;
integer iOldSt, iNewSt;
iOldSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LTSSM_STATE_OLD_SLC];
iNewSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LTSSM_STATE_NEW_SLC];
cast_assign( oldSt, iOldSt );
cast_assign( newSt, iNewSt );
PCIEX_QR_I( "%s-> Denali LTSSM State Updated:\n New=%s Old=%s, time = %d",
XactorName, newSt, oldSt, get_time(LO) );
}
task FNXPCIEXactorSignalInterface::ProcessRegCbDLCMSMState( FNXPCIEXactorRegCbRecord regCbRecord )
{
string MethodName = "ProcessRegCbDLCMSMState";
denaliPcieDlcmsmStateT oldSt, newSt;
integer iOldSt, iNewSt;
iOldSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_DLCMSM_STATE_OLD_SLC];
iNewSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_DLCMSM_STATE_NEW_SLC];
cast_assign( oldSt, iOldSt );
cast_assign( newSt, iNewSt );
// Trigger eDLLActive Event if DLCMSM State is Active
if (newSt === PCIE_DLCMSM_STATE_DL_Active)
trigger( ONE_BLAST, eDLLActive );
PCIEX_QR_I( "%s-> Denali DLCMSM State Updated:\n New=%s Old=%s",
XactorName, newSt, oldSt );
}
task FNXPCIEXactorSignalInterface::ProcessRegCbTLPortState( FNXPCIEXactorRegCbRecord regCbRecord )
{
string MethodName = "ProcessRegCbTLPortState";
denaliPciePortStateT oldSt, newSt;
integer iOldSt, iNewSt;
iOldSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_TLPORT_STATE_OLD_SLC];
iNewSt = regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_TLPORT_STATE_NEW_SLC];
cast_assign( oldSt, iOldSt );
cast_assign( newSt, iNewSt );
PCIEX_QR_I( "%s-> Denali TLPORT State Updated:\n New=%s Old=%s",
XactorName, newSt, oldSt );
}
task FNXPCIEXactorSignalInterface::ProcessRegCbDevCtrl( FNXPCIEXactorRegCbRecord regCbRecord )
{
string MethodName = "ProcessRegCbDevCtrl";
PCIEX_QR_I( "%s-> Denali Device Control Updated:\n BusNum=%0d'h%h DeviceNum=%0d'h%h FuncNum=%0d'h%h",
XactorName, FNX_PCIE_XTR_REQ_BUS_NUM_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_DEV_CTRL_BUS_NUM_SLC],
FNX_PCIE_XTR_REQ_DEVICE_NUM_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_DEV_CTRL_DEVICE_NUM_SLC],
FNX_PCIE_XTR_REQ_FUNC_NUM_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_DEV_CTRL_FUNC_NUM_SLC] );
}
task FNXPCIEXactorSignalInterface::ProcessRegCbLinkState( FNXPCIEXactorRegCbRecord regCbRecord )
{
string MethodName = "ProcessRegCbLinkState";
string tmp1, tmp2;
// Trigger eLinkUp Event if Bit is Set
if (regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_UP_SLC] === 1'b1)
trigger( ONE_BLAST, eLinkUp );
sprintf( tmp1, "LinkUp=%b LinkWidth=%0d'h%h LinkNum=%0d'h%h LaneNum=%0d'h%h",
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_UP_SLC],
FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_WIDTH_SLC],
FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_NUM_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_NUM_SLC],
FNX_PCIE_XTR_REG_DEN_LINK_ST_LANE_NUM_WIDTH, regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LANE_NUM_SLC] );
sprintf( tmp2, "LanesReversed=%b Scrambling=%b LinkToSucc: LO=%b LOs=%b L1=%b L2=%b",
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LANES_REVERSED_SLC],
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_SCRAMBLING_SLC],
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_TO_LO_SUCC_SLC],
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_TO_LOS_SUCC_SLC],
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_TO_L1_SUCC_SLC],
regCbRecord.Data[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_TO_L2_SUCC_SLC] );
PCIEX_QR_I( "%s-> Denali Link State Updated:\n %s\n %s",
XactorName, tmp1, tmp2 );
}
task FNXPCIEXactorSignalInterface::WaitLinkUp()
{
string MethodName = "WaitLinkUp";
bit[FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] lnkStData;
PCIEX_QR_I( "%s-> Start.", XactorName );
// Read Denali Reg And Check If Link Is Already Up, If Not Wait For eLinkUp
// Trigger by Link State Callback Handler
lnkStData = ReadDenaliReg( PCIE_REG_DEN_LINK_ST );
if (lnkStData[FNX_PCIE_XTR_REG_DEN_LINK_ST_LINK_UP_SLC] !== 1)
sync( ANY, eLinkUp );
PCIEX_QR_I( "%s-> Done. Link is Up. REG_DEN_LINK_ST=%0h", XactorName,lnkStData );
}
task FNXPCIEXactorSignalInterface::WaitDLLActive()
{
string MethodName = "WaitDLLActive";
bit[FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] dlcmsmStData;
PCIEX_QR_I( "%s-> Start.", XactorName );
// Read Denali Reg And Check If Link Is Already Up, If Not Wait For eDLLActive
// Trigger by DLCMSMS State Callback Handler
dlcmsmStData = ReadDenaliReg( PCIE_REG_DEN_DLCMSM_STATE );
if (dlcmsmStData[FNX_PCIE_XTR_REG_DEN_DLCMSM_STATE_NEW_SLC] !== PCIE_DLCMSM_STATE_DL_Active)
sync( ANY, eDLLActive );
PCIEX_QR_I( "%s-> Done. DLL is Active.", XactorName );
}
task FNXPCIEXactorSignalInterface::WriteDenaliReg( integer iDenReg, bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data )
{
string MethodName = "WriteDenaliReg";
integer id;
// Get Denali Device Id Used in Register DDV Operations to Configuration Space
void = DenaliDDVgetIdByName( {PCIEDevice.getInstName(),"(cfg_0_0)"}, id );
if (DenaliDDVwrite( id, iDenReg, data ) == 0)
PCIEX_QR_D2( "%s-> Updated Reg=%s Data=32'h%h id=%0d",
XactorName, Util.denaliRegNumToStr(iDenReg), data, id );
else
PCIEX_QR_ERR( "%s-> Update for Reg=%s Data=32'h%h id=%0d Failed.",
XactorName, Util.denaliRegNumToStr(iDenReg), data, id );
}
function bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] FNXPCIEXactorSignalInterface::ReadDenaliReg( integer iDenReg )
{
string MethodName = "ReadDenaliReg";
integer id;
// Get Denali Device Id Used in Register DDV Operations to Configuration Space
void = DenaliDDVgetIdByName( {PCIEDevice.getInstName(),"(cfg_0_0)"}, id );
if (DenaliDDVread( id, iDenReg, ReadDenaliReg) == 0)
PCIEX_QR_D3( "%s-> Reg=%s Read Data=32'h%h",
XactorName, Util.denaliRegNumToStr(iDenReg), ReadDenaliReg );
else
PCIEX_QR_ERR( "%s-> Read of Reg=%s Failed.",
XactorName, Util.denaliRegNumToStr(iDenReg) );
}
task FNXPCIEXactorSignalInterface::SetupBAR32( integer denReg,
integer addrWidth,
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH-1:0] baseAddr )
{
string MethodName = "SetupBAR32";
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH-1:0] barLowerData;
bit [FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_WIDTH-1:0] lowerAddr;
integer i;
// 32-bit BAR is For a 32-bit Non-Prefecthable Memory Decoder
// NOTE: 32-bit BAR's by PCI Definition Must NOT be Prefecthable
barLowerData[ FNX_PCIE_XTR_PCI_BAR_DECODER_TYPE_SLC ] = FNX_PCIE_XTR_PCI_BAR_DECODER_TYPE_MEM;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_TYPE_SLC ] = FNX_PCIE_XTR_PCI_BAR_TYPE_32_BIT;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_PREFETCHABLE_SLC ] = FNX_PCIE_XTR_PCI_BAR_NOT_PREFETCHABLE;
// Ensure Address Width is In Valid Range
if ((addrWidth < 8) || (addrWidth > FNX_PCIE_XTR_PCI_BAR_WIDTH)) {
PCIEX_QR_ERR( "%s-> Invalid 32-bit addrWidth=%0d Specified.",
XactorName, addrWidth );
return;
}
// Ensure Base Address Doesn't Have Lowest 4 Bits Set
if (baseAddr[3:0] !== 4'h0) {
PCIEX_QR_ERR( "%s-> Invalid 32-bit BaseAddr=%h Specified.",
XactorName, baseAddr );
return;
}
// Pass Size of 32-bit BAR to Denali Device
lowerAddr = { FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_WIDTH {1'b0} };
for (i=0; i < (FNX_PCIE_XTR_PCI_BAR_WIDTH - addrWidth); i++)
lowerAddr[FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_WIDTH-i-1] = 1'b1;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ] = lowerAddr;
WriteDenaliReg( denReg, barLowerData );
// Pass Base Address of 32-bit BAR to Denali Device
barLowerData[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ] = baseAddr[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ];
WriteDenaliReg( denReg, barLowerData );
PCIEX_QR_I( "%s-> Setup 32-bit BAR=%s: Width=%0d Base=%h",
XactorName, Util.denaliRegNumToStr(denReg), addrWidth, baseAddr );
}
task FNXPCIEXactorSignalInterface::SetupBAR64( integer denRegLower,
integer denRegUpper,
integer addrWidth,
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH*2-1:0] baseAddr )
{
string MethodName = "SetupBAR64";
bit [FNX_PCIE_XTR_PCI_BAR_WIDTH-1:0] barLowerData, barUpperData;
bit [FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_WIDTH-1:0] lowerAddr;
bit [FNX_PCIE_XTR_PCI_BAR_UPPER_ADDR_WIDTH-1:0] upperAddr;
integer i;
// 64-bit BAR is For a 64-bit Prefecthable Memory Decoder
barLowerData[ FNX_PCIE_XTR_PCI_BAR_DECODER_TYPE_SLC ] = FNX_PCIE_XTR_PCI_BAR_DECODER_TYPE_MEM;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_TYPE_SLC ] = FNX_PCIE_XTR_PCI_BAR_TYPE_64_BIT;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_PREFETCHABLE_SLC ] = FNX_PCIE_XTR_PCI_BAR_PREFETCHABLE;
// Ensure Address Width is In Valid Range
// NOTE: PCIE Requires 64-bit Addresses Are Beyond 4GB Memory Space
if ((addrWidth <= FNX_PCIE_XTR_PCI_BAR_WIDTH) || (addrWidth > FNX_PCIE_XTR_PCI_BAR_WIDTH*2)) {
PCIEX_QR_ERR( "%s-> Invalid 64-bit AddrWidth=%0d Specified.",
XactorName, addrWidth );
return;
}
// Ensure Base Address Doesn't Have Lowest 32 Bits Set
// NOTE: PCIE Requires 64-bit Addresses Are Beyond 4GB Memory Space
if (baseAddr[FNX_PCIE_XTR_PCI_BAR_WIDTH-1:0] !== {FNX_PCIE_XTR_PCI_BAR_WIDTH {1'b0}} ) {
PCIEX_QR_ERR( "%s-> Invalid 64-bit BaseAddr=%h Specified.",
XactorName, baseAddr );
return;
}
// Pass Size of 64-bit BAR to Denali Device
lowerAddr = {FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_WIDTH {1'b0}};
upperAddr = { FNX_PCIE_XTR_PCI_BAR_UPPER_ADDR_WIDTH {1'b0} };
for (i=0; i < (FNX_PCIE_XTR_PCI_BAR_WIDTH*2 - addrWidth); i++)
upperAddr[FNX_PCIE_XTR_PCI_BAR_UPPER_ADDR_WIDTH-i-1] = 1'b1;
barLowerData[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ] = lowerAddr;
barUpperData[ FNX_PCIE_XTR_PCI_BAR_UPPER_ADDR_SLC ] = upperAddr;
WriteDenaliReg( denRegLower, barLowerData );
WriteDenaliReg( denRegUpper, barUpperData );
// Pass Base Address of 64-bit BAR to Denali Device
barLowerData[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ] = baseAddr[ FNX_PCIE_XTR_PCI_BAR_LOWER_ADDR_SLC ];
barUpperData[ FNX_PCIE_XTR_PCI_BAR_UPPER_ADDR_SLC ] = baseAddr[ FNX_PCIE_XTR_PCI_BAR_WIDTH*2-1:FNX_PCIE_XTR_PCI_BAR_WIDTH ];
WriteDenaliReg( denRegLower, barLowerData );
WriteDenaliReg( denRegUpper, barUpperData );
PCIEX_QR_I( "%s-> Setup 64-bit BAR={%s,%s} : Width=%0d Base=%h",
XactorName, Util.denaliRegNumToStr(denRegLower), Util.denaliRegNumToStr(denRegUpper), addrWidth, baseAddr );
}
task FNXPCIEXactorSignalInterface::SetReqID( bit [FNX_PCIE_XTR_REQ_BUS_NUM_WIDTH-1:0] busNum,
bit [FNX_PCIE_XTR_REQ_DEVICE_NUM_WIDTH-1:0] devNum,
bit [FNX_PCIE_XTR_REQ_FUNC_NUM_WIDTH-1:0] funcNum,
integer regOffset = 0 )
{
string MethodName = "SetReqID";
bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data;
data = 0;
data[ FNX_PCIE_XTR_REG_DEN_DEV_CTRL_BUS_NUM_SLC ] = busNum;
data[ FNX_PCIE_XTR_REG_DEN_DEV_CTRL_DEVICE_NUM_SLC ] = devNum;
data[ FNX_PCIE_XTR_REG_DEN_DEV_CTRL_FUNC_NUM_SLC ] = funcNum;
// Ensure Register Offset is Multiple of PCIE_REG_NUM_MAXIMUM
if ((regOffset%PCIE_REG_NUM_MAXIMUM) != 0) {
PCIEX_QR_ERR( "%s-> Invalid regOffset=%0d Specified.",
XactorName, regOffset );
return;
}
WriteDenaliReg( PCIE_REG_DEN_DEV_CTRL+regOffset, data );
PCIEX_QR_I( "%s-> Set ReqID: BusNum=%0d'h%h DeviceNum=%0d'h%h FuncNum=%0d'h%h",
XactorName, FNX_PCIE_XTR_REQ_BUS_NUM_WIDTH, busNum,
FNX_PCIE_XTR_REQ_DEVICE_NUM_WIDTH, devNum,
FNX_PCIE_XTR_REQ_FUNC_NUM_WIDTH, funcNum );
}
task FNXPCIEXactorSignalInterface::SuppressDenaliErr( denaliPcieErrorTypeT denErr )
{
string MethodName = "SuppressDenaliErr";
bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data;
bit [FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_WIDTH-1:0] errId;
// Suppress Specified Error and Disable Callbacks and Assertion Coverage on Both Xmit and Recv Side
errId = denErr;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_SLC] = errId;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_CBK_CTRL_SLC] = PCIE_ERR_CONFIG_disable_callback;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ASSERT_CTRL_SLC] = PCIE_ERR_CONFIG_disable_coverage;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_DIRECTION_SLC] = PCIE_ERR_CONFIG_DIRECTION_TRX;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_SEV_SLC] = PCIE_ERR_CONFIG_FORMAT_SILENT;
// Write Data to Denali ERROR_CTRL Register
WriteDenaliReg( PCIE_REG_DEN_ERROR_CTRL, data);
PCIEX_QR_I( "%s -> Suppressed Err=%s", XactorName, denErr );
}
task FNXPCIEXactorSignalInterface::tempSuppressDenaliErr( denaliPcieErrorTypeT denErr )
{
string MethodName = "tempSuppressDenaliErr";
bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data;
bit [FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_WIDTH-1:0] errId;
// Suppress Specified Error and Disable Callbacks
// BUT leave Assertion Coverage enabled
errId = denErr;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_SLC] = errId;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_CBK_CTRL_SLC] = PCIE_ERR_CONFIG_disable_callback;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ASSERT_CTRL_SLC] = PCIE_ERR_CONFIG_enable_coverage;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_DIRECTION_SLC] = PCIE_ERR_CONFIG_DIRECTION_TRX;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_SEV_SLC] = PCIE_ERR_CONFIG_FORMAT_INFO;
// Write Data to Denali ERROR_CTRL Register
WriteDenaliReg( PCIE_REG_DEN_ERROR_CTRL, data);
PCIEX_QR_I( "%s -> tempSuppressed Err=%s", XactorName, denErr );
}
task FNXPCIEXactorSignalInterface::unSuppressDenaliErr( denaliPcieErrorTypeT denErr )
{
string MethodName = "unSuppressDenaliErr";
bit [FNX_PCIE_XTR_REG_DEN_WIDTH-1:0] data;
bit [FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_WIDTH-1:0] errId;
// Suppress Specified Error and Disable Callbacks
// BUT leave Assertion Coverage enabled
errId = denErr;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ERR_ID_SLC] = errId;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_CBK_CTRL_SLC] = PCIE_ERR_CONFIG_enable_callback;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_ASSERT_CTRL_SLC] = PCIE_ERR_CONFIG_enable_coverage;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_DIRECTION_SLC] = PCIE_ERR_CONFIG_DIRECTION_TRX;
data[FNX_PCIE_XTR_REG_DEN_ERROR_CTRL_SEV_SLC] = PCIE_ERR_CONFIG_FORMAT_ERROR;
// Write Data to Denali ERROR_CTRL Register
WriteDenaliReg( PCIE_REG_DEN_ERROR_CTRL, data);
PCIEX_QR_I( "%s -> unSuppressed Err=%s", XactorName, denErr );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_TX_completion_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_TX_completion_queue_enter";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_TX_completion_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_TX_completion_queue_exit";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_RX_completion_queue_enter( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_RX_completion_queue_enter";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
task FNXPCIEXactorSignalInterface::ProcessPktCb_TL_RX_completion_queue_exit( FNXPCIEXactorPktCbRecord pktCbRecord )
{
string MethodName = "PPktCb_TL_RX_completion_queue_exit";
PCIEX_QR_D3( "%s-> Callback Handler Is Empty:\n %s",
XactorName, pktCbRecord.GetStr() );
}
function string FNXPCIEXactorSignalInterface::GetEpilogueStr()
{
ReplayMonitor.UpdateStats();
GetEpilogueStr = { StatsDatabase.GetStr(), "\n", ReplayMonitor.GetStr() };
}
task FNXPCIEXactorSignalInterface::SetRcvDetMode( bit _rcvDetMode )
{
MiscPort.$rcvDetMode = _rcvDetMode;
}
task FNXPCIEXactorSignalInterface::SetRcvDetLanes( bit[FNX_PCIE_XTR_RCV_DET_LANES_WIDTH-1:0] _rcvDetLanes )
{
MiscPort.$rcvDetLanes = _rcvDetLanes;
}
task FNXPCIEXactorSignalInterface::SetElecIdleLanes( bit[FNX_PCIE_XTR_RCV_DET_LANES_WIDTH-1:0] _elecIdleLanes )
{
MiscPort.$elecIdleLanes = _elecIdleLanes;
}
task FNXPCIEXactorSignalInterface::SetDenaliReset( bit _denaliReset )
{
MiscPort.$denaliReset = _denaliReset;
}
task FNXPCIEXactorSignalInterface::ResetReplayMonitor( )
{
ReplayMonitor.Reset();
}
task FNXPCIEXactorSignalInterface::EnableSampleDllpToLink( )
{
//Enable sampling and create the packet object if it doesn't exist already
sampleDllpToLink = 1;
if( sampledDllpPktToLink == null ){
sampledDllpPktToLink = new( MyReport, XactorName, Util, PortNum );
}
}
task FNXPCIEXactorSignalInterface::DisableSampleDllpToLink( )
{
sampleDllpToLink = 0;
}
task FNXPCIEXactorSignalInterface::SampleDllpPktToLink( XactorBasePacket Pkt,
integer Window )
{
string MethodName = "SampleDllpPktToLink";
bit Success = 0;
fork {
sync(ANY, eDLLPToLink);
Pkt.PktCopy(sampledDllpPktToLink);
Success = 1'b1;
}
{
while (Window && !Success) {
Window--;
@(negedge ClkPort.$XClk);
}
if (!Success)
PCIEX_QR_ERR( "%s-> Timeout. No DLLP Transmitted to the DUT.", XactorName );
else
Pkt.PktDisplay( RTYP_INFO, psprintf("%s %s -> Transaction Sampled", PCIEX_QR_PREFIX, XactorName ) );
}
join any
}
task FNXPCIEXactorSignalInterface::TransmitFTSToLink( integer nmbrFts ){
denaliPcieOrderedSet ftsPkt;
integer i;
integer status;
for( i=0; i<nmbrFts; i++ ){
// Create Denali Packet To Be Driven
ftsPkt = new( DENALI_PCIE_PL__fts_set );
// Add Denali Packet to Denali's User Queue
status = PCIEDevice.transAdd( ftsPkt, 0, DENALI_ARG_trans_append );
if( status != 0 ){
PCIEX_QR_ERR( "%s:TransmitFTSToLink-> transAdd() Failed(%0d) :\n", XactorName, status );
}
}
}
task FNXPCIEXactorSignalInterface::TransmitSKPToLink( integer nmbrSkp ){
denaliPcieOrderedSet skpPkt;
integer i;
integer status;
for( i=0; i<nmbrSkp; i++ ){
// Create Denali Packet To Be Driven
skpPkt = new( DENALI_PCIE_PL__skip_set );
// Add Denali Packet to Denali's User Queue
status = PCIEDevice.transAdd( skpPkt, 0, DENALI_ARG_trans_append );
if( status != 0 ){
PCIEX_QR_ERR( "%s:TransmitSKPToLink-> transAdd() Failed(%0d) :\n", XactorName, status );
}
}
}
task FNXPCIEXactorSignalInterface::TransmitTS1ToLink( integer nmbrTS1 ){
denaliPcieOrderedSet ftsPkt;
integer i;
integer status;
for( i=0; i<nmbrTS1; i++ ){
// Create Denali Packet To Be Driven
ftsPkt = new( DENALI_PCIE_PL__ts1_set );
// Add Denali Packet to Denali's User Queue
status = PCIEDevice.transAdd( ftsPkt, 0, DENALI_ARG_trans_append );
if( status != 0 ){
PCIEX_QR_ERR( "%s:TransmitTS1ToLink-> transAdd() Failed(%0d) :\n", XactorName, status );
}
}
}
// task FNXPCIEXactorSignalInterface::TransmitOrdersetToLink( integer nmbrFts, bit [31:0] orderset ){
// task FNXPCIEXactorSignalInterface::TransmitOrdersetToLink( integer nmbrFts, denaliPcieOrderedSet orderset ){
// denaliPcieOrderedSet ftsPkt;
// integer i;
// integer status;
//
// for( i=0; i<nmbrFts; i++ ){
// // Create Denali Packet To Be Driven
// ftsPkt = new( orderset );
// ftsPkt = new( DENALI_PCIE_PL__ts1_set );
//
// // Add Denali Packet to Denali's User Queue
// status = PCIEDevice.transAdd( ftsPkt, 0, DENALI_ARG_trans_append );
// if( status != 0 ){
// PCIEX_QR_ERR( "%s:TransmitFTSToLink-> transAdd() Failed(%0d) :\n", XactorName, status );
// }
// }
// }
task FNXPCIEXactorSignalInterface::Transmit_symbol_ToLink( integer nmbrSymbol, bit[8:0] symbol ){
// denaliPcieOrderedSet ftsPkt;
denaliPcieRawPacket rawPkt;
denaliPciePacket pkt;
integer i, j;
integer status;
bit[8:0] PkttData[*];
bit[8:0] data[*];
for( i=0; i<nmbrSymbol; i++ ){
printf("AC: i = %d \n", i);
// Create Denali Packet To Be Driven
rawPkt = new( DENALI_PCIE__RawData );
// rawPkt.pktDataLen.setPktDataLen = 1;
rawPkt.setPktDataLen(1);
// for (j=1; j<=8; j++) {
// PktData[j] = 9'b110111100;
// }
// rawPkt.setPktData(PCIE_SYMBOL_K28__5); // PCIE_SYMBOL_K28__5
// rawPkt.setPktData(PktData); // PCIE_SYMBOL_K28__5 ERROR: runtime: illegal array index
// rawPkt.setPktData(PktData[0]); // PCIE_SYMBOL_K28__5 "FNXPCIEXactor.vr", line 7196 : Data type error for array arg on argument #1
// rawPkt.pktData[0] = PCIE_SYMBOL_K28__5; // Member "pktData" not found
// rawPkt.getPktData(PktData); // PCIE_SYMBOL_K28__5 "FNXPCIEXactor.vr", line 7196 : Data type error for array arg on argument #1
// pkt.PktData = PCIE_SYMBOL_K28__5; //Member "PktData" not found
// data=new[1];
// data[0] = PCIE_SYMBOL_K28__5;
data=new[8];
for (j=0; j<8; j++) {
printf("AC: j = %d \n", j);
// data[j] = PCIE_SYMBOL_K28__5;
data[j] = symbol;
}
rawPkt.setPktData(data);
// Add Denali Packet to Denali's User Queue
status = PCIEDevice.transAdd( rawPkt, 0, DENALI_ARG_trans_append );
if( status != 0 ){
PCIEX_QR_ERR( "AC: %s:Transmit_symbol_ToLink-> transAdd() Failed(%0d) at time %d :\n", XactorName, status, get_time(LO) );
}
else {
printf("AC: rawPkt transAdd complete \n");
}
}
}