363 lines
16 KiB
Plaintext
363 lines
16 KiB
Plaintext
/*
|
|
* Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* For use for simulation and test purposes only
|
|
*
|
|
* 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.
|
|
*
|
|
* Author: Lisa Hsu
|
|
*/
|
|
|
|
|
|
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";
|
|
HSAScope scope, default="HSAScope_SYSTEM", desc="Request Scope";
|
|
int wfid, default="0", desc="wavefront id";
|
|
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";
|
|
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";
|
|
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";
|
|
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;
|
|
}
|
|
|
|
}
|