blob: 46bab43c2239d68c230e8f3c815e4cefb961389c [file] [log] [blame]
/*
* Copyright (c) 2010-2015, 2018 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
enumeration(CoherenceRequestType, desc="Coherence Request Types") {
// CPU Request Types ONLY
RdBlk, desc="Read Blk";
RdBlkM, desc="Read Blk Modified";
RdBlkS, desc="Read Blk Shared";
CtoD, desc="Change To Dirty";
VicClean, desc="L2 clean eviction";
VicDirty, desc="L2 dirty eviction";
Atomic, desc="Upper level atomic";
AtomicWriteBack, desc="Upper level atomic";
WriteThrough, desc="Ordered WriteThrough w/Data";
WriteThroughFifo, desc="WriteThrough with no data";
WriteThroughDummy, desc="WriteThrough with no data for atomic operation";
WriteFlush, desc="Release Flush";
WrCancel, desc="want to cancel WB to Memory"; // should this be here?
WBApproval, desc="WB Approval";
// Messages between Dir and R-Dir
ForceInv, desc="Send invalide to the block";
ForceDowngrade, desc="Send downgrade to the block";
Unblock, desc="Used to let the dir know a message has been sunk";
// Messages between R-Dir and R-Buffer
PrivateNotify, desc="Let region buffer know it has private access";
SharedNotify, desc="Let region buffer know it has shared access";
WbNotify, desc="Let region buffer know it saw its wb request";
Downgrade, desc="Force the region buffer to downgrade to shared";
// Response to R-Dir (probably should be on a different network, but
// I need it to be ordered with respect to requests)
InvAck, desc="Let the R-Dir know when the inv has occured";
PrivateRequest, desc="R-buf wants the region in private";
UpgradeRequest, desc="R-buf wants the region in private";
SharedRequest, desc="R-buf wants the region in shared (could respond with private)";
CleanWbRequest, desc="R-buf wants to deallocate clean region";
NA, desc="So we don't get segfaults";
}
enumeration(ProbeRequestType, desc="Probe Request Types") {
PrbDowngrade, desc="Probe for Status"; // EtoS, MtoO, StoS
PrbInv, desc="Probe to Invalidate";
// For regions
PrbRepl, desc="Force the cache to do a replacement";
PrbRegDowngrade, desc="Probe for Status"; // EtoS, MtoO, StoS
PrbAtomic, desc="Forwarded Atomic Operation";
}
enumeration(CoherenceResponseType, desc="Coherence Response Types") {
NBSysResp, desc="Northbridge response to CPU Rd request";
NBSysWBAck, desc="Northbridge response ok to WB";
TDSysResp, desc="TCCdirectory response to CPU Rd request";
TDSysWBAck, desc="TCCdirectory response ok to WB";
TDSysWBNack, desc="TCCdirectory response ok to drop";
CPUPrbResp, desc="CPU Probe Response";
CPUData, desc="CPU Data";
StaleNotif, desc="Notification of Stale WBAck, No data to writeback";
CPUCancelWB, desc="want to cancel WB to Memory";
MemData, desc="Data from Memory";
// for regions
PrivateAck, desc="Ack that r-buf received private notify";
RegionWbAck, desc="Writeback Ack that r-buf completed deallocation";
DirReadyAck, desc="Directory (mem ctrl)<->region dir handshake";
}
enumeration(CoherenceState, default="CoherenceState_NA", desc="Coherence State") {
Modified, desc="Modified";
Owned, desc="Owned state";
Exclusive, desc="Exclusive";
Shared, desc="Shared";
NA, desc="NA";
}
structure(CPURequestMsg, desc="...", interface="Message") {
Addr addr, desc="Physical address for this request";
Addr DemandAddress, desc="Physical block address for this request";
CoherenceRequestType Type, desc="Type of request";
DataBlock DataBlk, desc="data for the cache line"; // only for WB
bool Dirty, desc="whether WB data is dirty"; // only for WB
MachineID Requestor, desc="Node who initiated the request";
NetDest Destination, desc="Multicast destination mask";
bool Shared, desc="For CPU_WrVicBlk, vic is O not M. For CPU_ClVicBlk, vic is S";
MessageSizeType MessageSize, desc="size category of the message";
Cycles InitialRequestTime, desc="time the initial requests was sent from the L1Cache";
Cycles ForwardRequestTime, desc="time the dir forwarded the request";
Cycles ProbeRequestStartTime, desc="the time the dir started the probe request";
bool DemandRequest, default="false", desc="For profiling purposes";
NetDest Sharers, desc="Caches that may have a valid copy of the data";
bool ForceShared, desc="R-dir knows it is shared, pass on so it sends an S copy, not E";
bool Private, default="false", desc="Requestor already has private permissions, no need for dir check";
bool CtoDSinked, default="false", desc="This is true if the CtoD previously sent must have been sunk";
bool NoAckNeeded, default="false", desc="True if region buffer doesn't need to ack";
int Acks, default="0", desc="Acks that the dir (mem ctrl) should expect to receive";
CoherenceRequestType OriginalType, default="CoherenceRequestType_NA", desc="Type of request from core fwded through region buffer";
WriteMask writeMask, desc="Write Through Data";
MachineID WTRequestor, desc="Node who initiated the write through";
int wfid, default="0", desc="wavefront id";
uint64_t instSeqNum, desc="instruction sequence number";
bool NoWriteConflict, default="true", desc="write collided with CAB entry";
int ProgramCounter, desc="PC that accesses to this block";
bool functionalRead(Packet *pkt) {
// Only PUTX messages contains the data block
if (Type == CoherenceRequestType:VicDirty) {
return testAndRead(addr, DataBlk, pkt);
}
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return testAndWrite(addr, DataBlk, pkt);
}
}
structure(NBProbeRequestMsg, desc="...", interface="Message") {
Addr addr, desc="Physical address for this request";
ProbeRequestType Type, desc="NB_PrbNxtState signal";
bool ReturnData, desc="Indicates CPU should return data";
NetDest Destination, desc="Node to whom the data is sent";
MessageSizeType MessageSize, desc="size category of the message";
bool DemandRequest, default="false", desc="demand request, requesting 3-hop transfer";
Addr DemandAddress, desc="Demand block address for a region request";
MachineID Requestor, desc="Requestor id for 3-hop requests";
bool NoAckNeeded, default="false", desc="For short circuting acks";
int ProgramCounter, desc="PC that accesses to this block";
bool functionalRead(Packet *pkt) {
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return false;
}
}
structure(TDProbeRequestMsg, desc="...", interface="Message") {
Addr addr, desc="Physical address for this request";
ProbeRequestType Type, desc="TD_PrbNxtState signal";
bool ReturnData, desc="Indicates CPU should return data";
bool localCtoD, desc="Indicates CtoD is within the GPU hierarchy (aka TCC subtree)";
NetDest Destination, desc="Node to whom the data is sent";
MessageSizeType MessageSize, desc="size category of the message";
int Phase, desc="Synchronization Phase";
int wfid, desc="wavefront id for Release";
uint64_t instSeqNum, desc="instruction sequence number";
MachineID Requestor, desc="Node who initiated the request";
bool functionalRead(Packet *pkt) {
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return false;
}
}
// Response Messages seemed to be easily munged into one type
structure(ResponseMsg, desc="...", interface="Message") {
Addr addr, desc="Physical address for this request";
CoherenceResponseType Type, desc="NB Sys Resp or CPU Response to Probe";
MachineID Sender, desc="Node who sent the data";
NetDest Destination, desc="Node to whom the data is sent";
// Begin Used Only By CPU Response
DataBlock DataBlk, desc="data for the cache line";
bool Hit, desc="probe hit valid line";
bool Shared, desc="True if S, or if NB Probe ReturnData==1 && O";
bool Dirty, desc="Is the data dirty (different than memory)?";
bool Ntsl, desc="indicates probed lin will be invalid after probe";
bool UntransferredOwner, desc="pending confirmation of ownership change";
// End Used Only By CPU Response
// Begin NB Response Only
CoherenceState State, default=CoherenceState_NA, desc="What returned data from NB should be in";
bool CtoD, desc="was the originator a CtoD?";
// End NB Response Only
// Normally if a block gets hit by a probe while waiting to be written back,
// you flip the NbReqShared signal (part of the CPURequest signal group).
// But since this is in packets and I don't want to send a separate packet,
// let's just send this signal back with the data instead
bool NbReqShared, desc="modification of Shared field from initial request, e.g. hit by shared probe";
MessageSizeType MessageSize, desc="size category of the message";
Cycles InitialRequestTime, desc="time the initial requests was sent from the L1Cache";
Cycles ForwardRequestTime, desc="time the dir forwarded the request";
Cycles ProbeRequestStartTime, desc="the time the dir started the probe request";
bool DemandRequest, default="false", desc="For profiling purposes";
bool L3Hit, default="false", desc="Did memory or L3 supply the data?";
MachineID OriginalResponder, desc="Mach which wrote the data to the L3";
MachineID WTRequestor, desc="Node who started the writethrough";
bool NotCached, default="false", desc="True when the Region buffer has already evicted the line";
bool NoAckNeeded, default="false", desc="For short circuting acks";
bool isValid, default="false", desc="Is acked block valid";
int wfid, default="0", desc="wavefront id";
uint64_t instSeqNum, desc="instruction sequence number";
int Phase, desc="Synchronization Phase";
int ProgramCounter, desc="PC that issues this request";
bool mispred, desc="tell TCP if the block should not be bypassed";
bool functionalRead(Packet *pkt) {
// Only PUTX messages contains the data block
if (Type == CoherenceResponseType:CPUData ||
Type == CoherenceResponseType:MemData) {
return testAndRead(addr, DataBlk, pkt);
}
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return testAndWrite(addr, DataBlk, pkt);
}
}
structure(UnblockMsg, desc="...", interface="Message") {
Addr addr, desc="Physical address for this request";
NetDest Destination, desc="Destination (always directory)";
MessageSizeType MessageSize, desc="size category of the message";
MachineID Sender, desc="Node who sent the data";
bool currentOwner, default="false", desc="Is the sender the current owner";
bool DoneAck, default="false", desc="Is this a done ack?";
bool Dirty, default="false", desc="Was block dirty when evicted";
bool wasValid, default="false", desc="Was block valid when evicted";
bool valid, default="false", desc="Is block valid";
bool validToInvalid, default="false", desc="Was block valid when evicted";
bool functionalRead(Packet *pkt) {
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return false;
}
}
enumeration(TriggerType, desc="Trigger Type") {
L2_to_L1, desc="L2 to L1 fill";
AcksComplete, desc="NB received all needed Acks";
// For regions
InvNext, desc="Invalidate the next block";
PrivateAck, desc="Loopback ack for machines with no Region Buffer";
AllOutstanding, desc="All outstanding requests have finished";
L3Hit, desc="L3 hit in dir";
// For region directory once the directory is blocked
InvRegion, desc="Invalidate region";
DowngradeRegion, desc="downgrade region";
//For writethrough
UnblockWriteThrough, desc="unblock";
WriteData, desc="Write to full cacheblock data";
WriteDone, desc="Sequencer says that write is done";
AtomicDone, desc="Atomic is done";
}
enumeration(CacheId, desc="Which Cache in the Core") {
L1I, desc="L1 I-cache";
L1D0, desc="L1 D-cache cluster 0";
L1D1, desc="L1 D-cache cluster 1";
NA, desc="Default";
}
structure(TriggerMsg, desc="...", interface="Message") {
Addr addr, desc="Address";
TriggerType Type, desc="Type of trigger";
CacheId Dest, default="CacheId_NA", desc="Cache to invalidate";
int ProgramCounter, desc="PC that accesses to this block";
bool functionalRead(Packet *pkt) {
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return false;
}
}
enumeration(FifoType, desc="Fifo Type") {
WriteDummy, desc="Dummy Write for atomic operation";
WriteThrough, desc="simple writethrough request";
WriteFlush, desc="synchronization message";
}
structure(FifoMsg, desc="...", interface="Message") {
Addr addr, desc="Address";
FifoType Type, desc="WriteThrough/WriteFlush";
int wfid, default="0",desc="wavefront id";
uint64_t instSeqNum, desc="instruction sequence number";
MachineID Requestor, desc="Flush Requestor";
MachineID oRequestor, desc="original Flush Requestor";
bool functionalRead(Packet *pkt) {
return false;
}
bool functionalWrite(Packet *pkt) {
// No check on message type required since the protocol should
// read data from those messages that contain the block
return false;
}
}
enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
READ, desc="Memory Read";
WRITE, desc="Memory Write";
NULL, desc="Invalid";
}
enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") {
DATA, desc="DATA read";
ACK, desc="ACK write";
NULL, desc="Invalid";
}
structure(DMARequestMsg, desc="...", interface="Message") {
DMARequestType Type, desc="Request type (read/write)";
Addr PhysicalAddress, desc="Physical address for this request";
Addr LineAddress, desc="Line address for this request";
MachineID Requestor, desc="Node who initiated the request";
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
int Len, desc="The length of the request";
MessageSizeType MessageSize, desc="size category of the message";
bool functionalRead(Packet *pkt) {
return testAndRead(LineAddress, DataBlk, pkt);
}
bool functionalWrite(Packet *pkt) {
return testAndWrite(LineAddress, DataBlk, pkt);
}
}
structure(DMAResponseMsg, desc="...", interface="Message") {
DMAResponseType Type, desc="Response type (DATA/ACK)";
Addr PhysicalAddress, desc="Physical address for this request";
Addr LineAddress, desc="Line address for this request";
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
MessageSizeType MessageSize, desc="size category of the message";
bool functionalRead(Packet *pkt) {
return testAndRead(LineAddress, DataBlk, pkt);
}
bool functionalWrite(Packet *pkt) {
return testAndWrite(LineAddress, DataBlk, pkt);
}
}