diff options
Diffstat (limited to 'src/mem/ruby/protocol/RubySlicc_Exports.sm')
-rw-r--r-- | src/mem/ruby/protocol/RubySlicc_Exports.sm | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/mem/ruby/protocol/RubySlicc_Exports.sm b/src/mem/ruby/protocol/RubySlicc_Exports.sm new file mode 100644 index 000000000..8e17f9849 --- /dev/null +++ b/src/mem/ruby/protocol/RubySlicc_Exports.sm @@ -0,0 +1,355 @@ +/* + * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood + * Copyright (c) 2011 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: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * 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; + * neither the name of the copyright holders 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 + * OWNER 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. + */ + +// Declarations of external types that are common to all protocols +external_type(int, primitive="yes", default="0"); +external_type(bool, primitive="yes", default="false"); +external_type(std::string, primitive="yes"); +external_type(uint32_t, primitive="yes"); +external_type(uint64_t, primitive="yes"); +external_type(PacketPtr, primitive="yes"); +external_type(Packet, primitive="yes"); +external_type(Addr, primitive="yes"); +external_type(Cycles, primitive="yes", default="Cycles(0)"); +external_type(Tick, primitive="yes", default="0"); + +structure(WriteMask, external="yes", desc="...") { + void clear(); + bool cmpMask(WriteMask); + bool isEmpty(); + bool isFull(); + bool isOverlap(WriteMask); + void orMask(WriteMask); + void fillMask(); +} + +structure(DataBlock, external = "yes", desc="..."){ + void clear(); + void copyPartial(DataBlock, int, int); + void copyPartial(DataBlock, WriteMask); + void atomicPartial(DataBlock, WriteMask); +} + +bool testAndRead(Addr addr, DataBlock datablk, Packet *pkt); +bool testAndReadMask(Addr addr, DataBlock datablk, WriteMask mask, Packet *pkt); +bool testAndWrite(Addr addr, DataBlock datablk, Packet *pkt); + +// AccessPermission +// The following five states define the access permission of all memory blocks. +// These permissions have multiple uses. They coordinate locking and +// synchronization primitives, as well as enable functional accesses. +// One should not need to add any additional permission values and it is very +// risky to do so. +enumeration(AccessPermission, desc="...", default="AccessPermission_NotPresent") { + // Valid data + Read_Only, desc="block is Read Only (modulo functional writes)"; + Read_Write, desc="block is Read/Write"; + + // Possibly Invalid data + // The maybe stale permission indicates that accordingly to the protocol, + // there is no guarantee the block contains valid data. However, functional + // writes should update the block because a dataless PUT request may + // revalidate the block's data. + Maybe_Stale, desc="block can be stale or revalidated by a dataless PUT"; + // In Broadcast/Snoop protocols, memory has no idea if it is exclusive owner + // or not of a block, making it hard to make the logic of having only one + // read_write block in the system impossible. This is to allow the memory to + // say, "I have the block" and for the RubyPort logic to know that this is a + // last-resort block if there are no writable copies in the caching hierarchy. + // This is not supposed to be used in directory or token protocols where + // memory/NB has an idea of what is going on in the whole system. + Backing_Store, desc="for memory in Broadcast/Snoop protocols"; + + // Invalid data + Invalid, desc="block is in an Invalid base state"; + NotPresent, desc="block is NotPresent"; + Busy, desc="block is in a transient state, currently invalid"; +} +//HSA scopes +enumeration(HSAScope, desc="...", default="HSAScope_UNSPECIFIED") { + UNSPECIFIED, desc="Unspecified scope"; + NOSCOPE, desc="Explictly unscoped"; + WAVEFRONT, desc="Wavefront scope"; + WORKGROUP, desc="Workgroup scope"; + DEVICE, desc="Device scope"; + SYSTEM, desc="System scope"; +} + +// HSA segment types +enumeration(HSASegment, desc="...", default="HSASegment_GLOBAL") { + GLOBAL, desc="Global segment"; + GROUP, desc="Group segment"; + PRIVATE, desc="Private segment"; + KERNARG, desc="Kernarg segment"; + READONLY, desc="Readonly segment"; + SPILL, desc="Spill segment"; + ARG, desc="Arg segment"; +} + +// TesterStatus +enumeration(TesterStatus, desc="...") { + Idle, desc="Idle"; + Action_Pending, desc="Action Pending"; + Ready, desc="Ready"; + Check_Pending, desc="Check Pending"; +} + +// InvalidateGeneratorStatus +enumeration(InvalidateGeneratorStatus, desc="...") { + Load_Waiting, desc="Load waiting to be issued"; + Load_Pending, desc="Load issued"; + Inv_Waiting, desc="Store (invalidate) waiting to be issued"; + Inv_Pending, desc="Store (invalidate) issued"; +} + +// SeriesRequestGeneratorStatus +enumeration(SeriesRequestGeneratorStatus, desc="...") { + Thinking, desc="Doing work before next action"; + Request_Pending, desc="Request pending"; +} + +// LockStatus +enumeration(LockStatus, desc="...") { + Unlocked, desc="Lock is not held"; + Locked, desc="Lock is held"; +} + +// SequencerStatus +enumeration(SequencerStatus, desc="...") { + Idle, desc="Idle"; + Pending, desc="Pending"; +} + +enumeration(TransitionResult, desc="...") { + Valid, desc="Valid transition"; + ResourceStall, desc="Stalled due to insufficient resources"; + ProtocolStall, desc="Protocol specified stall"; + Reject, desc="Rejected because of a type mismatch"; +} + +// RubyRequestType +enumeration(RubyRequestType, desc="...", default="RubyRequestType_NULL") { + LD, desc="Load"; + ST, desc="Store"; + ATOMIC, desc="Atomic Load/Store -- depricated. use ATOMIC_RETURN or ATOMIC_NO_RETURN"; + ATOMIC_RETURN, desc="Atomic Load/Store, return data"; + ATOMIC_NO_RETURN, desc="Atomic Load/Store, do not return data"; + IFETCH, desc="Instruction fetch"; + IO, desc="I/O"; + REPLACEMENT, desc="Replacement"; + Load_Linked, desc=""; + Store_Conditional, desc=""; + RMW_Read, desc=""; + RMW_Write, desc=""; + Locked_RMW_Read, desc=""; + Locked_RMW_Write, desc=""; + COMMIT, desc="Commit version"; + NULL, desc="Invalid request type"; + FLUSH, desc="Flush request type"; + Release, desc="Release operation"; + Acquire, desc="Acquire opertion"; + AcquireRelease, desc="Acquire and Release opertion"; +} + +enumeration(SequencerRequestType, desc="...", default="SequencerRequestType_NULL") { + Default, desc="Replace this with access_types passed to the DMA Ruby object"; + LD, desc="Load"; + ST, desc="Store"; + ATOMIC, desc="Atomic Load/Store"; + REPLACEMENT, desc="Replacement"; + FLUSH, desc="Flush request type"; + NULL, desc="Invalid request type"; +} + +enumeration(CacheRequestType, desc="...", default="CacheRequestType_NULL") { + DataArrayRead, desc="Read access to the cache's data array"; + DataArrayWrite, desc="Write access to the cache's data array"; + TagArrayRead, desc="Read access to the cache's tag array"; + TagArrayWrite, desc="Write access to the cache's tag array"; +} + +enumeration(CacheResourceType, desc="...", default="CacheResourceType_NULL") { + DataArray, desc="Access to the cache's data array"; + TagArray, desc="Access to the cache's tag array"; +} + +enumeration(DirectoryRequestType, desc="...", default="DirectoryRequestType_NULL") { + Default, desc="Replace this with access_types passed to the Directory Ruby object"; +} + +enumeration(DMASequencerRequestType, desc="...", default="DMASequencerRequestType_NULL") { + Default, desc="Replace this with access_types passed to the DMA Ruby object"; +} + +enumeration(MemoryControlRequestType, desc="...", default="MemoryControlRequestType_NULL") { + Default, desc="Replace this with access_types passed to the DMA Ruby object"; +} + + +// These are statically defined types of states machines that we can have. +// If you want to add a new machine type, edit this enum. It is not necessary +// for a protocol to have state machines defined for the all types here. But +// you cannot use anything other than the ones defined here. Also, a protocol +// can have only one state machine for a given type. +enumeration(MachineType, desc="...", default="MachineType_NULL") { + L0Cache, desc="L0 Cache Mach"; + L1Cache, desc="L1 Cache Mach"; + L2Cache, desc="L2 Cache Mach"; + L3Cache, desc="L3 Cache Mach"; + Directory, desc="Directory Mach"; + DMA, desc="DMA Mach"; + Collector, desc="Collector Mach"; + L1Cache_wCC, desc="L1 Cache Mach to track cache-to-cache transfer (used for miss latency profile)"; + L2Cache_wCC, desc="L2 Cache Mach to track cache-to-cache transfer (used for miss latency profile)"; + CorePair, desc="Cache Mach (2 cores, Private L1Ds, Shared L1I & L2)"; + TCP, desc="GPU L1 Data Cache (Texture Cache per Pipe)"; + TCC, desc="GPU L2 Shared Cache (Texture Cache per Channel)"; + TCCdir, desc="Directory at the GPU L2 Cache (TCC)"; + SQC, desc="GPU L1 Instr Cache (Sequencer Cache)"; + RegionDir, desc="Region-granular directory"; + RegionBuffer,desc="Region buffer for CPU and GPU"; + NULL, desc="null mach type"; +} + +// MessageSizeType +enumeration(MessageSizeType, desc="...") { + Control, desc="Control Message"; + Data, desc="Data Message"; + Request_Control, desc="Request"; + Reissue_Control, desc="Reissued request"; + Response_Data, desc="data response"; + ResponseL2hit_Data, desc="data response"; + ResponseLocal_Data, desc="data response"; + Response_Control, desc="non-data response"; + Writeback_Data, desc="Writeback data"; + Writeback_Control, desc="Writeback control"; + Broadcast_Control, desc="Broadcast control"; + Multicast_Control, desc="Multicast control"; + Forwarded_Control, desc="Forwarded control"; + Invalidate_Control, desc="Invalidate control"; + Unblock_Control, desc="Unblock control"; + Persistent_Control, desc="Persistent request activation messages"; + Completion_Control, desc="Completion messages"; +} + +// AccessType +enumeration(AccessType, desc="...") { + Read, desc="Reading from cache"; + Write, desc="Writing to cache"; +} + +// RubyAccessMode +enumeration(RubyAccessMode, default="RubyAccessMode_User", desc="...") { + Supervisor, desc="Supervisor mode"; + User, desc="User mode"; + Device, desc="Device mode"; +} + +enumeration(PrefetchBit, default="PrefetchBit_No", desc="...") { + No, desc="No, not a prefetch"; + Yes, desc="Yes, a prefetch"; + L1_HW, desc="This is a L1 hardware prefetch"; + L2_HW, desc="This is a L2 hardware prefetch"; +} + +// CacheMsg +structure(SequencerMsg, desc="...", interface="Message") { + Addr LineAddress, desc="Line address for this request"; + Addr PhysicalAddress, desc="Physical address for this request"; + SequencerRequestType Type, desc="Type of request (LD, ST, etc)"; + Addr ProgramCounter, desc="Program counter of the instruction that caused the miss"; + RubyAccessMode AccessMode, desc="user/supervisor access type"; + DataBlock DataBlk, desc="Data"; + int Len, desc="size in bytes of access"; + PrefetchBit Prefetch, desc="Is this a prefetch request"; + MessageSizeType MessageSize, default="MessageSizeType_Request_Control"; + + bool functionalRead(Packet *pkt) { + return testAndRead(PhysicalAddress, DataBlk, pkt); + } + + bool functionalWrite(Packet *pkt) { + return testAndWrite(PhysicalAddress, DataBlk, pkt); + } +} + +// MaskPredictorType +enumeration(MaskPredictorType, "MaskPredictorType_Undefined", desc="...") { + Undefined, desc="Undefined"; + AlwaysUnicast, desc="AlwaysUnicast"; + TokenD, desc="TokenD"; + AlwaysBroadcast, desc="AlwaysBroadcast"; + TokenB, desc="TokenB"; + TokenNull, desc="TokenNull"; + Random, desc="Random"; + Pairwise, desc="Pairwise"; + Owner, desc="Owner"; + BroadcastIfShared, desc="Broadcast-If-Shared"; + BroadcastCounter, desc="Broadcast Counter"; + Group, desc="Group"; + Counter, desc="Counter"; + StickySpatial, desc="StickySpatial"; + OwnerBroadcast, desc="Owner/Broadcast Hybrid"; + OwnerGroup, desc="Owner/Group Hybrid"; + OwnerBroadcastMod, desc="Owner/Broadcast Hybrid-Mod"; + OwnerGroupMod, desc="Owner/Group Hybrid-Mod"; + LastNMasks, desc="Last N Masks"; + BandwidthAdaptive, desc="Bandwidth Adaptive"; +} + +// MaskPredictorIndex +enumeration(MaskPredictorIndex, "MaskPredictorIndex_Undefined", desc="...") { + Undefined, desc="Undefined"; + DataBlock, desc="Data Block"; + PC, desc="Program Counter"; +} + +// MaskPredictorTraining +enumeration(MaskPredictorTraining, "MaskPredictorTraining_Undefined", desc="...") { + Undefined, desc="Undefined"; + None, desc="None"; + Implicit, desc="Implicit"; + Explicit, desc="Explicit"; + Both, desc="Both"; +} + +// Request Status +enumeration(RequestStatus, desc="...", default="RequestStatus_NULL") { + Ready, desc="The sequencer is ready and the request does not alias"; + Issued, desc="The sequencer successfully issued the request"; + BufferFull, desc="Can not issue because the sequencer is full"; + Aliased, desc="This request aliased with a currently outstanding request"; + NULL, desc=""; +} + +// LinkDirection +enumeration(LinkDirection, desc="...") { + In, desc="Inward link direction"; + Out, desc="Outward link direction"; +} |