// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: FNXPCIEXactorManager.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 ============================================
#include <vera_defines.vrh>
#include "XactorList.vrh"
#include "XactorListWildCard.vrh"
#include "XactorManager.vrh"
class FNXPCIEXactorManager extends XactorManager {
// integer DriverSemaphore
// XactorCtrl _XactorCtrl
// XactorBasePacket SampledPkt
// inherited virtual methods
// function bit ExpectPending(XactorBasePacket ExpectedPacket)
// function bit Remove(XactorBasePacket ExpectedPacket)
// function integer NumExpects();
// task RemoveExpect(XactorBasePacket Packet, var bit Success)
// task RemoveXExpect(XactorBasePacket Packet, var bit Success)
// task RemoveRefExpect(XactorBasePacket Packet, var bit Success)
// task RemoveRefXExpect(XactorBasePacket Packet, var bit Success)
// task ExpectPkt(XactorBasePacket ExpectedPkt, integer Window, var bit [1:0] Status)
// task SamplePkt(XactorBasePacket Pkt, integer Window)
integer Bluntend_TX_fifo;
integer DllpExpectDataStructSemaphore;
integer DllpXExpectDataStructSemaphore;
protected XactorList DllpExpectDataStruct;
protected XactorListWildCard DllpXExpectDataStruct;
// Base Class and Method Names For QR Macros
local string ClassName = "FNXPCIEXactorManager";
local string MethodName = null;
bit disablteTlpExpectTimeout = 0;
local event eNewTLPXaction;
local event eNewDLLPXaction;
task new( XactorBaseBuilder Builder,
virtual task DrivePkt( XactorBasePacket DrivenPkt,
virtual task ExpectPkt( XactorBasePacket ExpectedPkt,
virtual task SampleTlpPkt( XactorBasePacket Pkt, integer Window );
virtual task SampleDllpPkt( XactorBasePacket Pkt, integer Window );
virtual function bit Remove(XactorBasePacket ExpectedPacket);
virtual task DumpExpects();
virtual function integer NumExpects();
virtual function integer NumTlpExpects();
virtual function integer NumDllpExpects();
virtual function bit ExpectPending(XactorBasePacket ExpectedPacket);
protected task ExpectConsumer();
protected task DllpExpectConsumer();
protected task RetryExpectIssuer();
protected task RemoveDllpExpect( XactorBasePacket Packet,
protected task RemoveDllpXExpect( XactorBasePacket Packet,
protected task RemoveDllpRefExpect( XactorBasePacket Packet,
protected task RemoveDllpRefXExpect( XactorBasePacket Packet,
task FNXPCIEXactorManager::new( XactorBaseBuilder Builder,
string MethodName = "new";
RetryPktFifo = alloc(MAILBOX, 0, 1);
PCIEX_QR_ERR( "%s-> Failed to Allocate RetryPktFifo Mailbox.",
DllpExpectFifo = alloc(MAILBOX, 0, 1);
PCIEX_QR_ERR( "%s-> Failed to Allocate DllpExpectFifo Mailbox.",
Bluntend_TX_fifo = alloc(MAILBOX, 0, 1);
if (Bluntend_TX_fifo == 0)
PCIEX_QR_ERR( "%s-> Failed to Allocate Bluntend_TX_fifo Mailbox.",
DllpExpectDataStruct = new;
DllpXExpectDataStruct = new;
DllpExpectDataStructSemaphore = alloc(SEMAPHORE, 0, 1, 1);
if (DllpExpectDataStructSemaphore == 0)
PCIEX_QR_ERR( "%s %s-> Allocation of DllpExpectDataStructSemaphore Failed.",
DllpXExpectDataStructSemaphore = alloc(SEMAPHORE, 0, 1, 1);
if (DllpXExpectDataStructSemaphore == 0)
PCIEX_QR_ERR( "%s %s-> Allocation of DllpXExpectDataStructSemaphore Failed.",
task FNXPCIEXactorManager::DllpExpectConsumer()
bit Success, SuccessWildcard;
string MethodName = "DllpExpectConsumer";
// Main DLLP Expect Consumer loop
// Wait for another transaction coming from the Signal Interface
void = mailbox_get(WAIT, DllpExpectFifo, SampledPkt);
// Check if sampled packet has undefined values
if (SampledPkt.PktUndef())
SampledPkt.PktDisplay( RTYP_XACTOR_FMWORK_SAMPLED_X_ERR,
psprintf("at time %d, %s %s -> X Values Detected in Xaction Driven by DUT", get_time(LO), PCIEX_QR_PREFIX, XactorName ));
// Stop the DLLP Expect Consumer if the Transactor is Disabled
if (_XactorCtrl.GetDisableFlag())
sync(ANY, _XactorCtrl.GetEnableEvent());
// Trigger the event for a new transaction
trigger(ONE_BLAST, NewTransaction);
trigger(ONE_BLAST, eNewDLLPXaction );
RemoveDllpExpect(SampledPkt, Success);
RemoveDllpXExpect(SampledPkt, SuccessWildcard);
if (SuccessWildcard || Success)
SampledPkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_1, psprintf("%s %s -> Match Found, Pending Expect Removed", PCIEX_QR_PREFIX, XactorName ));
// Unexpected DLLPs Are Allowed Hence Not Unexpected Transaction Error Is Thrown Here
task FNXPCIEXactorManager::ExpectConsumer()
bit Success, SuccessWildcard;
string MethodName = "ExpectConsumer";
// Main TLP Expect Consumer loop
// Wait for another transaction coming from the Signal Interface
void = mailbox_get(WAIT, ExpectFifo, SampledPkt);
// Check if sampled packet has undefined values
if (SampledPkt.PktUndef())
SampledPkt.PktDisplay( RTYP_XACTOR_FMWORK_SAMPLED_X_ERR,
psprintf("%s %s -> X Values Detected in Xaction Driven by DUT", PCIEX_QR_PREFIX, XactorName ));
// Stop the Expect Consumer if the transactor was disabled
if (_XactorCtrl.GetDisableFlag())
sync(ANY, _XactorCtrl.GetEnableEvent());
// Trigger the event for a new transaction
trigger(ONE_BLAST, NewTransaction);
trigger(ONE_BLAST, eNewTLPXaction );
RemoveExpect(SampledPkt, Success);
RemoveXExpect(SampledPkt, SuccessWildcard);
if (SuccessWildcard || Success) {
SampledPkt.PktDisplay( RTYP_DEBUG_1, psprintf("%s %s -> Match Found, Pending Expect Removed", PCIEX_QR_PREFIX, XactorName ));
if (UnexpectedTLPIsErr) {
PCIEX_QR_I( "%s -> Unexpected Xaction Sampled, Dumping Expect Structure:", XactorName );
rptType = RTYP_XACTOR_FMWORK_UNEXPECTED_XACTION_ERR;
rptType = RTYP_FNX_PCIE_XTR_INFO;
SampledPkt.PktDisplay( rptType, psprintf("%s %s -> Sampled Unexpected Xaction", PCIEX_QR_PREFIX, XactorName ));
// This task will receive DrivenPkt and will wait D clock cycles before DrivenPkt is
task FNXPCIEXactorManager::DrivePkt( XactorBasePacket DrivenPkt,
string MethodName = "DrivePkt";
FNXPCIEXactorPacket drivePkt;
cast_assign( drivePkt, DrivenPkt );
// Wait D cycles before drivePkt is scheduled for driving
repeat (D) @(posedge ClkPort.$XClk);
// Wait if transactor was disabled
if (_XactorCtrl.GetDisableFlag() === 1'b1)
sync(ANY, _XactorCtrl.GetEnableEvent());
// Send drivePkt to the Signal Interface
mailbox_put(DriveFifo, drivePkt);
drivePkt.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_3, psprintf("%s %s-> Drive Enqueued", PCIEX_QR_PREFIX, XactorName ) );
// Wait until the packet is complete driven on serial links
drivePkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf("at time %d, %s %s-> Xaction Driven", get_time(LO), PCIEX_QR_PREFIX, XactorName ) );
// Removes Packet from DllpExpectDataStruct if Present. Success is 1 if
// Packet is removed without problems and 0 otherwise
task FNXPCIEXactorManager::RemoveDllpExpect( XactorBasePacket Packet,
string MethodName = "RemoveDllpExpect";
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
if ((!(DllpExpectDataStruct.Empty())) && (!(Packet.PktUndef())))
DllpExpectDataStruct.Delete( Packet, Success );
semaphore_put(DllpExpectDataStructSemaphore, 1);
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf( "%s %s-> Sampled Xaction Match Found in DllpExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2, psprintf( "%s %s-> Sampled Xaction Has No Match in DllpExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
// Same as RemoveDllpExpect, but it will remove Packet from the DllpXExpectDataStruct
task FNXPCIEXactorManager::RemoveDllpXExpect( XactorBasePacket Packet,
string MethodName = "RemoveDllpXExpect";
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
if (!(DllpXExpectDataStruct.Empty()))
DllpXExpectDataStruct.WildCardDelete1( Packet, Success );
semaphore_put(DllpXExpectDataStructSemaphore, 1);
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2,
psprintf( "%s %s-> Sampled Xaction Match Found in DllpXExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2,
psprintf( "%s %s-> Sampled Xaction Has No Match in DllpXExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
// Removes Packet from DllpExpectDataStruct if Present. Success is 1 if
// Packet is removed without problems and 0 otherwise
task FNXPCIEXactorManager::RemoveDllpRefExpect( XactorBasePacket Packet,
string MethodName = "RemoveDllpRefExpect";
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
if ((!(DllpExpectDataStruct.Empty())) && (!(Packet.PktUndef())))
DllpExpectDataStruct.RefDelete( Packet, Success );
semaphore_put(DllpExpectDataStructSemaphore, 1);
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2,
psprintf( "%s %s-> Removing Expect From DllpExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
// Same as RemoveDllpExpect, but it will remove Packet from the DllpXExpectDataStruct
task FNXPCIEXactorManager::RemoveDllpRefXExpect( XactorBasePacket Packet,
string MethodName = "RemoveDllpRefXExpect";
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
if (!(DllpXExpectDataStruct.Empty()))
DllpXExpectDataStruct.WildCardDelete1( Packet, Success );
semaphore_put(DllpXExpectDataStructSemaphore, 1);
Packet.PktDisplay( RTYP_FNX_PCIE_XTR_DEBUG_2,
psprintf( "%s %s-> Removing Expect From DllpXExpectDataStructure",
PCIEX_QR_PREFIX, XactorName ) );
task FNXPCIEXactorManager::ExpectPkt( XactorBasePacket ExpectedPkt,
FNXPCIEXactorPacket fnxExpectedPkt;
bit SuccessWildcard = 1'b0;
event RemoveEvents[XACT_EXPECT_DATA_STRUCT_REMOVE_EVENTS];
cast_assign( fnxExpectedPkt, ExpectedPkt );
///////////////////////////////////////////////////////////
// Begin -> Handle TLP Expects
if (fnxExpectedPkt.isTlp()) {
if (fnxExpectedPkt.PktUndef()) {
semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
XExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents);
semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
ExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents);
semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
@(negedge ClkPort.$XClk);
// Wait until the expect is satisfied or it times out.
while (!Status[1] && Window) {
if (_XactorCtrl.GetDisableFlag() === 1'b1)
sync(ANY, _XactorCtrl.GetEnableEvent());
if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_EVENT])) {
if( !disablteTlpExpectTimeout ){
@(negedge ClkPort.$XClk);
if (Status[1] !== 1'b1) {
RemoveRefExpect(fnxExpectedPkt, Success);
RemoveRefXExpect(fnxExpectedPkt, SuccessWildcard);
Status[0] = 1'b0; // Expect timedout and is removed by transactor
if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_XACTOR_EVENT]))
else if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_USER_EVENT]))
// End -> Handle TLP Expects
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Begin -> Handle DLLP Expects
if (fnxExpectedPkt.isDllp()) {
if (fnxExpectedPkt.PktUndef()) {
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
DllpXExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents);
semaphore_put(DllpXExpectDataStructSemaphore, 1);
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
ExpectDataStruct.Insert(fnxExpectedPkt, RemoveEvents);
semaphore_put(DllpExpectDataStructSemaphore, 1);
@(negedge ClkPort.$XClk);
// Wait until the expect is satisfied or it times out.
while (!Status[1] && Window) {
if (_XactorCtrl.GetDisableFlag() === 1'b1)
sync(ANY, _XactorCtrl.GetEnableEvent());
if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_EVENT])) {
@(negedge ClkPort.$XClk);
if (Status[1] !== 1'b1) {
RemoveDllpRefExpect(fnxExpectedPkt, Success);
RemoveDllpRefXExpect(fnxExpectedPkt, SuccessWildcard);
Status[0] = 1'b0; // Expect timedout and is removed by transactor
if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_XACTOR_EVENT]))
else if (sync(CHECK, RemoveEvents[XACT_COMP_EXPECT_REMOVED_BY_USER_EVENT]))
// End -> Handle DLLP Expects
///////////////////////////////////////////////////////////
task FNXPCIEXactorManager::RetryExpectIssuer()
FNXPCIEXactorPacket retryPkt;
// Wait For Retry Packet To Come From Signal Interface (Denali retry_buffer_exit Callback)
void = mailbox_get(WAIT, RetryPktFifo, retryPkt);
retryPkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf( "%s %s-> Launching Expect (Replay)", PCIEX_QR_PREFIX, XactorName ) );
// Stop the Retry Expect Issuer if the Transactor is Disabled
if (_XactorCtrl.GetDisableFlag())
sync(ANY, _XactorCtrl.GetEnableEvent());
// [review jbanta 10/13/03] What should window for replay packet expects be?
// [review jbanta 10/13/03] Setting it to 1000 for now
// Block Until Retry Expect is Satisfied (No Need to Fork as Retries Should Happen in Order)
ExpectPkt( retryPkt, 1000, status );
if ( status === 2'b10 ) { // Expect removed by transactor
retryPkt.PktDisplay( RTYP_FNX_PCIE_XTR_INFO, psprintf("%s %s -> Expect Satisfied (Replay)", PCIEX_QR_PREFIX, XactorName ) );
else { // Expect removed by user
retryPkt.PktDisplay( RTYP_XACTOR_FMWORK_EXPECT_REMOVED_BY_USER,
psprintf("%s %s -> Expect Removed by User (Replay)", PCIEX_QR_PREFIX, XactorName ) );
retryPkt.PktDisplay( RTYP_XACTOR_FMWORK_EXPECT_TIMEOUT_ERR,
psprintf("%s %s -> Expect Expired (Replay)", PCIEX_QR_PREFIX, XactorName ) );
task FNXPCIEXactorManager::SampleTlpPkt( XactorBasePacket Pkt,
string MethodName = "SampleTlpPkt";
sync(ANY, eNewTLPXaction);
while (Window && !Success) {
@(negedge ClkPort.$XClk);
PCIEX_QR_ERR( "%s-> Timeout. No TLP received from the DUT.", XactorName );
Pkt.PktDisplay( RTYP_INFO, psprintf("%s %s -> Transaction Sampled", PCIEX_QR_PREFIX, XactorName ) );
task FNXPCIEXactorManager::SampleDllpPkt( XactorBasePacket Pkt,
string MethodName = "SampleDllpPkt";
sync(ANY, eNewDLLPXaction);
while (Window && !Success) {
@(negedge ClkPort.$XClk);
PCIEX_QR_ERR( "%s-> Timeout. No DLLP received from the DUT.", XactorName );
Pkt.PktDisplay( RTYP_INFO, psprintf("%s %s -> Transaction Sampled", PCIEX_QR_PREFIX, XactorName ) );
// Returns 1 if the expect with the value in ExpectedPacket is removed successfully and 0 otherwise
function bit FNXPCIEXactorManager::Remove(XactorBasePacket ExpectedPacket)
FNXPCIEXactorPacket fnxExpectedPkt;
bit SuccessWildcard = 1'b0;
cast_assign( fnxExpectedPkt, ExpectedPacket );
if (fnxExpectedPkt.isTlp()) {
RemoveRefExpect(ExpectedPacket, Success);
RemoveRefXExpect(ExpectedPacket, SuccessWildcard);
if (fnxExpectedPkt.isDllp()) {
RemoveDllpRefExpect(ExpectedPacket, Success);
RemoveDllpRefXExpect(ExpectedPacket, SuccessWildcard);
Remove = Success | SuccessWildcard;
task FNXPCIEXactorManager::DumpExpects() {
string MethodName = "DumpExpects";
semaphore_get(WAIT, _XactorCtrl.ExpectDataStructSemaphore, 1);
PCIEX_QR_I( "%s -> Dumping TLP Expect Structure:", XactorName );
ExpectDataStruct.PrintNodes();
semaphore_put(_XactorCtrl.ExpectDataStructSemaphore, 1);
semaphore_get(WAIT, _XactorCtrl.XExpectDataStructSemaphore, 1);
PCIEX_QR_I( "%s -> Dumping TLP Wilcard Expect Structure:", XactorName );
XExpectDataStruct.PrintNodes();
semaphore_put(_XactorCtrl.XExpectDataStructSemaphore, 1);
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
PCIEX_QR_I( "%s -> Dumping DLLP Expect Structure:", XactorName );
DllpExpectDataStruct.PrintNodes();
semaphore_put(DllpExpectDataStructSemaphore, 1);
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
PCIEX_QR_I( "%s -> Dumping DLLP Wilcard Expect Structure:", XactorName );
DllpXExpectDataStruct.PrintNodes();
semaphore_put(DllpXExpectDataStructSemaphore, 1);
function integer FNXPCIEXactorManager::NumExpects()
NumExpects = NumTlpExpects() + NumDllpExpects();
function integer FNXPCIEXactorManager::NumTlpExpects()
// NOTE: TLP Expects Are Stored in ExpectDataStruct and XExpectDataStruct
// Structures Present in Base XactorManger class, hence super.NumExpects
// Returns Numberof TLP Expects Outstanding
NumTlpExpects = super.NumExpects();
function integer FNXPCIEXactorManager::NumDllpExpects()
// First count the expects pending in the DLLP expect data structure
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
NumDllpExpects = DllpExpectDataStruct.CountNodes();
semaphore_put(DllpExpectDataStructSemaphore, 1);
// Then add the expects pending in the DLLP wildcard expect data structure
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
NumDllpExpects += DllpXExpectDataStruct.CountNodes();
semaphore_put(DllpXExpectDataStructSemaphore, 1);
function bit FNXPCIEXactorManager::ExpectPending(XactorBasePacket ExpectedPacket)
bit dllpExpectPendingBit = 1'b0;
bit dllpXExpectPendingBit = 1'b0;
// First check if the expect is pending in the main expect data structure
semaphore_get(WAIT, DllpExpectDataStructSemaphore, 1);
if ((!(DllpExpectDataStruct.Empty())) && (!ExpectedPacket.PktUndef()))
dllpExpectPendingBit = DllpExpectDataStruct.InStructure(ExpectedPacket);
semaphore_put(DllpExpectDataStructSemaphore, 1);
// Then check if the expect is in the expect data structure with "wildcards"
semaphore_get(WAIT, DllpXExpectDataStructSemaphore, 1);
if ((!(DllpXExpectDataStruct.Empty())) && (ExpectedPacket.PktUndef()))
dllpXExpectPendingBit = DllpXExpectDataStruct.InStructure(ExpectedPacket);
semaphore_put(DllpXExpectDataStructSemaphore, 1);
// NOTE: TLP Expects Are Stored in ExpectDataStruct and XExpectDataStruct
// Structures Present in Base XactorManger class, hence super.ExpectPending()
// Checks For Packet Presence in TLP Data Structures
ExpectPending = super.ExpectPending(ExpectedPacket) | dllpExpectPendingBit | dllpXExpectPendingBit;