/* * 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. * * Authors: 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"; VicClean, desc="L2 clean eviction"; VicDirty, desc="L2 dirty eviction"; 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 } 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, default="0", desc="time the initial requests was sent from the L1Cache"; Cycles ForwardRequestTime, default="0", desc="time the dir forwarded the request"; Cycles ProbeRequestStartTime, default="0", 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"; 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="probe 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"; 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"; 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; } } // 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 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, default="0", desc="time the initial requests was sent from the L1Cache"; Cycles ForwardRequestTime, default="0", desc="time the dir forwarded the request"; Cycles ProbeRequestStartTime, default="0", 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"; 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"; 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"; } 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"; } 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"; 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; } }