summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/learning_gem5/part3/MSI-dir.sm2
-rw-r--r--src/mem/cache/replacement_policies/replaceable_entry.hh2
-rw-r--r--src/mem/ruby/SConscript1
-rw-r--r--src/mem/ruby/protocol/Garnet_standalone-dir.sm2
-rw-r--r--src/mem/ruby/protocol/MESI_Two_Level-dir.sm2
-rw-r--r--src/mem/ruby/protocol/MI_example-dir.sm20
-rw-r--r--src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm2
-rw-r--r--src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm2
-rw-r--r--src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm2
-rw-r--r--src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm2
-rw-r--r--src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm2
-rw-r--r--src/mem/ruby/protocol/MOESI_CMP_token-L2cache.sm10
-rw-r--r--src/mem/ruby/protocol/MOESI_CMP_token-dir.sm8
-rw-r--r--src/mem/ruby/protocol/MOESI_hammer-dir.sm2
-rw-r--r--src/mem/ruby/protocol/RubySlicc_Types.sm10
-rw-r--r--src/mem/ruby/slicc_interface/AbstractCacheEntry.cc12
-rw-r--r--src/mem/ruby/slicc_interface/AbstractCacheEntry.hh29
-rw-r--r--src/mem/ruby/slicc_interface/AbstractEntry.cc50
-rw-r--r--src/mem/ruby/slicc_interface/AbstractEntry.hh60
-rw-r--r--src/mem/ruby/slicc_interface/SConscript1
-rw-r--r--src/mem/ruby/structures/AbstractReplacementPolicy.cc74
-rw-r--r--src/mem/ruby/structures/AbstractReplacementPolicy.hh66
-rw-r--r--src/mem/ruby/structures/CacheMemory.cc75
-rw-r--r--src/mem/ruby/structures/CacheMemory.hh35
-rw-r--r--src/mem/ruby/structures/DirectoryMemory.cc8
-rw-r--r--src/mem/ruby/structures/DirectoryMemory.hh8
-rw-r--r--src/mem/ruby/structures/LRUPolicy.cc76
-rw-r--r--src/mem/ruby/structures/LRUPolicy.hh48
-rw-r--r--src/mem/ruby/structures/LRUReplacementPolicy.py41
-rw-r--r--src/mem/ruby/structures/PseudoLRUPolicy.cc111
-rw-r--r--src/mem/ruby/structures/PseudoLRUPolicy.hh66
-rw-r--r--src/mem/ruby/structures/PseudoLRUReplacementPolicy.py35
-rw-r--r--src/mem/ruby/structures/ReplacementPolicy.py43
-rw-r--r--src/mem/ruby/structures/RubyCache.py5
-rw-r--r--src/mem/ruby/structures/SConscript6
-rw-r--r--src/mem/ruby/system/WeightedLRUPolicy.cc115
-rw-r--r--src/mem/ruby/system/WeightedLRUPolicy.hh69
-rw-r--r--src/mem/ruby/system/WeightedLRUReplacementPolicy.py5
-rw-r--r--src/mem/slicc/ast/FormalParamAST.py5
-rw-r--r--src/mem/slicc/ast/LocalVariableAST.py5
-rw-r--r--src/mem/slicc/ast/MemberExprAST.py7
-rw-r--r--src/mem/slicc/ast/MethodCallExprAST.py8
42 files changed, 287 insertions, 845 deletions
diff --git a/src/learning_gem5/part3/MSI-dir.sm b/src/learning_gem5/part3/MSI-dir.sm
index 7bd7aae83..f00df37ef 100644
--- a/src/learning_gem5/part3/MSI-dir.sm
+++ b/src/learning_gem5/part3/MSI-dir.sm
@@ -125,7 +125,7 @@ machine(MachineType:Directory, "Directory protocol")
// NOTE: We use a netdest for the sharers and the owner so we can simply
// copy the structure into the message we send as a response.
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirState, desc="Directory state";
NetDest Sharers, desc="Sharers for this block";
NetDest Owner, desc="Owner of this block";
diff --git a/src/mem/cache/replacement_policies/replaceable_entry.hh b/src/mem/cache/replacement_policies/replaceable_entry.hh
index c558beea1..2b08749e4 100644
--- a/src/mem/cache/replacement_policies/replaceable_entry.hh
+++ b/src/mem/cache/replacement_policies/replaceable_entry.hh
@@ -52,7 +52,7 @@ struct ReplacementData {};
*/
class ReplaceableEntry
{
- private:
+ protected:
/**
* Set to which this entry belongs.
*/
diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript
index 450a4bfca..abba91b89 100644
--- a/src/mem/ruby/SConscript
+++ b/src/mem/ruby/SConscript
@@ -111,7 +111,6 @@ def MakeInclude(source):
include_action = MakeAction(MakeIncludeAction, Transform("MAKE INC", 1))
env.Command(target, source, include_action)
-MakeInclude('slicc_interface/AbstractEntry.hh')
MakeInclude('slicc_interface/AbstractCacheEntry.hh')
MakeInclude('slicc_interface/Message.hh')
MakeInclude('slicc_interface/RubyRequest.hh')
diff --git a/src/mem/ruby/protocol/Garnet_standalone-dir.sm b/src/mem/ruby/protocol/Garnet_standalone-dir.sm
index 3a4327972..663ba1703 100644
--- a/src/mem/ruby/protocol/Garnet_standalone-dir.sm
+++ b/src/mem/ruby/protocol/Garnet_standalone-dir.sm
@@ -55,7 +55,7 @@ machine(MachineType:Directory, "Garnet_standalone Directory")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
}
diff --git a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm
index 991de5a2c..2e935de66 100644
--- a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm
+++ b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm
@@ -72,7 +72,7 @@ machine(MachineType:Directory, "MESI Two Level directory protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
MachineID Owner;
}
diff --git a/src/mem/ruby/protocol/MI_example-dir.sm b/src/mem/ruby/protocol/MI_example-dir.sm
index e9f652152..471608de0 100644
--- a/src/mem/ruby/protocol/MI_example-dir.sm
+++ b/src/mem/ruby/protocol/MI_example-dir.sm
@@ -27,7 +27,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-machine(MachineType:Directory, "Directory protocol")
+machine(MachineType:Directory, "Directory protocol")
: DirectoryMemory * directory;
Cycles directory_latency := 12;
Cycles to_memory_controller_latency := 1;
@@ -54,7 +54,7 @@ machine(MachineType:Directory, "Directory protocol")
M_DRD, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA read";
M_DWR, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA write";
- M_DWRI, AccessPermission:Busy, desc="Intermediate state M_DWR-->I";
+ M_DWRI, AccessPermission:Busy, desc="Intermediate state M_DWR-->I";
M_DRDI, AccessPermission:Busy, desc="Intermediate state M_DRD-->I";
IM, AccessPermission:Busy, desc="Intermediate state I-->M";
@@ -83,7 +83,7 @@ machine(MachineType:Directory, "Directory protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
NetDest Sharers, desc="Sharers for this block";
NetDest Owner, desc="Owner of this block";
@@ -125,7 +125,7 @@ machine(MachineType:Directory, "Directory protocol")
directory.allocate(addr, new Entry));
return dir_entry;
}
-
+
State getState(TBE tbe, Addr addr) {
if (is_valid(tbe)) {
return tbe.TBEState;
@@ -150,7 +150,7 @@ machine(MachineType:Directory, "Directory protocol")
}
getDirectoryEntry(addr).DirectoryState := state;
-
+
if (state == State:I) {
assert(getDirectoryEntry(addr).Owner.count() == 0);
assert(getDirectoryEntry(addr).Sharers.count() == 0);
@@ -354,7 +354,7 @@ machine(MachineType:Directory, "Directory protocol")
out_msg.PhysicalAddress := address;
out_msg.LineAddress := address;
out_msg.Type := DMAResponseType:ACK;
- out_msg.Destination.add(tbe.DmaRequestor);
+ out_msg.Destination.add(tbe.DmaRequestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
@@ -401,7 +401,7 @@ machine(MachineType:Directory, "Directory protocol")
action(p_popIncomingDMARequestQueue, "p", desc="Pop incoming DMA queue") {
dmaRequestQueue_in.dequeue(clockEdge());
}
-
+
action(v_allocateTBE, "v", desc="Allocate TBE") {
peek(dmaRequestQueue_in, DMARequestMsg) {
TBEs.allocate(address);
@@ -490,7 +490,7 @@ machine(MachineType:Directory, "Directory protocol")
transition({IM, MI, ID, ID_W}, {GETX, GETS, PUTX, PUTX_NotOwner} ) {
z_recycleRequestQueue;
}
-
+
transition({IM, MI, ID, ID_W}, {DMA_READ, DMA_WRITE} ) {
y_recycleDMARequestQueue;
}
@@ -546,7 +546,7 @@ machine(MachineType:Directory, "Directory protocol")
p_popIncomingDMARequestQueue;
}
- transition(M_DRD, PUTX, M_DRDI) {
+ transition(M_DRD, PUTX, M_DRDI) {
drp_sendDMAData;
c_clearOwner;
l_queueMemoryWBRequest;
@@ -555,7 +555,7 @@ machine(MachineType:Directory, "Directory protocol")
transition(M_DRDI, Memory_Ack, I) {
l_sendWriteBackAck;
- w_deallocateTBE;
+ w_deallocateTBE;
l_popMemQueue;
}
diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm
index cc5ceb0b5..152d8b50a 100644
--- a/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm
+++ b/src/mem/ruby/protocol/MOESI_AMD_Base-Region-dir.sm
@@ -159,7 +159,7 @@ machine(MachineType:Directory, "AMD_Base-like protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
NetDest VicDirtyIgnore, desc="VicDirty coming from whom to ignore";
diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm
index 4cde5ad03..971b84634 100644
--- a/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm
+++ b/src/mem/ruby/protocol/MOESI_AMD_Base-dir.sm
@@ -119,7 +119,7 @@ machine(MachineType:Directory, "AMD Baseline protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
NetDest VicDirtyIgnore, desc="VicDirty coming from whom to ignore";
diff --git a/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm b/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm
index d23094a2e..51efb1015 100644
--- a/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm
+++ b/src/mem/ruby/protocol/MOESI_AMD_Base-probeFilter.sm
@@ -148,7 +148,7 @@ machine(MachineType:Directory, "AMD Baseline protocol")
}
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
NetDest VicDirtyIgnore, desc="VicDirty coming from whom to ignore";
diff --git a/src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm
index f20085fd5..18e3b891e 100644
--- a/src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm
+++ b/src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm
@@ -193,7 +193,7 @@ machine(MachineType:L2Cache, "Token protocol")
}
- structure(DirEntry, desc="...", interface="AbstractEntry") {
+ structure(DirEntry, desc="...", interface="AbstractCacheEntry", main="false") {
NetDest Sharers, desc="Set of the internal processors that want the block in shared state";
MachineID Owner, desc="ID of the L1 cache to forward the block to once we get a response";
bool OwnerValid, default="false", desc="true if Owner means something";
diff --git a/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm b/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm
index f12d16658..29f862e2e 100644
--- a/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm
+++ b/src/mem/ruby/protocol/MOESI_CMP_directory-dir.sm
@@ -106,7 +106,7 @@ machine(MachineType:Directory, "Directory protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface='AbstractEntry') {
+ structure(Entry, desc="...", interface='AbstractCacheEntry', main="false") {
State DirectoryState, desc="Directory state";
NetDest Sharers, desc="Sharers for this block";
NetDest Owner, desc="Owner of this block";
diff --git a/src/mem/ruby/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/ruby/protocol/MOESI_CMP_token-L2cache.sm
index 948a2d95f..119508aa8 100644
--- a/src/mem/ruby/protocol/MOESI_CMP_token-L2cache.sm
+++ b/src/mem/ruby/protocol/MOESI_CMP_token-L2cache.sm
@@ -35,7 +35,7 @@ machine(MachineType:L2Cache, "Token protocol")
// L2 BANK QUEUES
// From local bank of L2 cache TO the network
-
+
// this L2 bank -> a local L1 || mod-directory
MessageBuffer * responseFromL2Cache, network="To", virtual_network="4",
vnet_type="response";
@@ -45,10 +45,10 @@ machine(MachineType:L2Cache, "Token protocol")
// this L2 bank -> a local L1
MessageBuffer * L1RequestFromL2Cache, network="To", virtual_network="1",
vnet_type="request";
-
-
+
+
// FROM the network to this local bank of L2 cache
-
+
// a local L1 || mod-directory -> this L2 bank
MessageBuffer * responseToL2Cache, network="From", virtual_network="4",
vnet_type="response";
@@ -123,7 +123,7 @@ machine(MachineType:L2Cache, "Token protocol")
DataBlock DataBlk, desc="data for the block";
}
- structure(DirEntry, desc="...", interface="AbstractEntry") {
+ structure(DirEntry, desc="...", interface="AbstractCacheEntry", main="false") {
Set Sharers, desc="Set of the internal processors that want the block in shared state";
bool exclusive, default="false", desc="if local exclusive is likely";
}
diff --git a/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm b/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm
index b9b65b585..2e3f12024 100644
--- a/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/ruby/protocol/MOESI_CMP_token-dir.sm
@@ -47,17 +47,17 @@ machine(MachineType:Directory, "Token protocol")
MessageBuffer * requestFromDir, network="To", virtual_network="1",
vnet_type="request";
-
+
// Message Queues to dir from other controllers / network
MessageBuffer * responseToDir, network="From", virtual_network="4",
vnet_type="response";
MessageBuffer * persistentToDir, network="From", virtual_network="3",
vnet_type="persistent";
-
+
MessageBuffer * requestToDir, network="From", virtual_network="2",
vnet_type="request";
-
+
MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
vnet_type="request";
@@ -120,7 +120,7 @@ machine(MachineType:Directory, "Token protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
int Tokens, default="max_tokens()", desc="Number of tokens for the line we're holding";
diff --git a/src/mem/ruby/protocol/MOESI_hammer-dir.sm b/src/mem/ruby/protocol/MOESI_hammer-dir.sm
index 3b0016868..3c457b171 100644
--- a/src/mem/ruby/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/ruby/protocol/MOESI_hammer-dir.sm
@@ -148,7 +148,7 @@ machine(MachineType:Directory, "AMD Hammer-like protocol")
// TYPES
// DirectoryEntry
- structure(Entry, desc="...", interface="AbstractEntry") {
+ structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
}
diff --git a/src/mem/ruby/protocol/RubySlicc_Types.sm b/src/mem/ruby/protocol/RubySlicc_Types.sm
index 2d4c250da..fd7628965 100644
--- a/src/mem/ruby/protocol/RubySlicc_Types.sm
+++ b/src/mem/ruby/protocol/RubySlicc_Types.sm
@@ -174,22 +174,18 @@ structure(RubyRequest, desc="...", interface="Message", external="yes") {
PacketPtr pkt, desc="Packet associated with this request";
}
-structure(AbstractEntry, primitive="yes", external = "yes") {
+structure(AbstractCacheEntry, primitive="yes", external = "yes") {
void changePermission(AccessPermission);
}
structure (DirectoryMemory, external = "yes") {
- AbstractEntry allocate(Addr, AbstractEntry);
- AbstractEntry lookup(Addr);
+ AbstractCacheEntry allocate(Addr, AbstractCacheEntry);
+ AbstractCacheEntry lookup(Addr);
bool isPresent(Addr);
void invalidateBlock(Addr);
void recordRequestType(DirectoryRequestType);
}
-structure(AbstractCacheEntry, primitive="yes", external = "yes") {
- void changePermission(AccessPermission);
-}
-
structure (CacheMemory, external = "yes") {
bool cacheAvail(Addr);
Addr cacheProbe(Addr);
diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
index 00dfc6c64..b98425d7e 100644
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc
@@ -31,21 +31,29 @@
#include "base/trace.hh"
#include "debug/RubyCache.hh"
-AbstractCacheEntry::AbstractCacheEntry()
+AbstractCacheEntry::AbstractCacheEntry() : ReplaceableEntry()
{
m_Permission = AccessPermission_NotPresent;
m_Address = 0;
m_locked = -1;
+ m_last_touch_tick = 0;
}
AbstractCacheEntry::~AbstractCacheEntry()
{
}
+// Get cache permission
+AccessPermission
+AbstractCacheEntry::getPermission() const
+{
+ return m_Permission;
+}
+
void
AbstractCacheEntry::changePermission(AccessPermission new_perm)
{
- AbstractEntry::changePermission(new_perm);
+ m_Permission = new_perm;
if ((new_perm == AccessPermission_Invalid) ||
(new_perm == AccessPermission_NotPresent)) {
m_locked = -1;
diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
index c943c75d0..0519b3f7d 100644
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
@@ -36,21 +36,28 @@
#include <iostream>
#include "base/logging.hh"
+#include "mem/cache/replacement_policies/replaceable_entry.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/protocol/AccessPermission.hh"
-#include "mem/ruby/slicc_interface/AbstractEntry.hh"
class DataBlock;
-class AbstractCacheEntry : public AbstractEntry
+class AbstractCacheEntry : public ReplaceableEntry
{
+ private:
+ // The last access tick for the cache entry.
+ Tick m_last_touch_tick;
+
public:
AbstractCacheEntry();
virtual ~AbstractCacheEntry() = 0;
// Get/Set permission of the entry
+ AccessPermission getPermission() const;
void changePermission(AccessPermission new_perm);
+ virtual void print(std::ostream& out) const = 0;
+
// The methods below are those called by ruby runtime, add when it
// is absolutely necessary and should all be virtual function.
virtual DataBlock& getDataBlk()
@@ -68,22 +75,20 @@ class AbstractCacheEntry : public AbstractEntry
void clearLocked();
bool isLocked(int context) const;
- void setSetIndex(uint32_t s) { m_set_index = s; }
- uint32_t getSetIndex() const { return m_set_index; }
-
- void setWayIndex(uint32_t s) { m_way_index = s; }
- uint32_t getWayIndex() const { return m_way_index; }
-
// Address of this block, required by CacheMemory
Addr m_Address;
// Holds info whether the address is locked.
// Required for implementing LL/SC operations.
int m_locked;
- private:
- // Set and way coordinates of the entry within the cache memory object.
- uint32_t m_set_index;
- uint32_t m_way_index;
+ AccessPermission m_Permission; // Access permission for this
+ // block, required by CacheMemory
+
+ // Get the last access Tick.
+ Tick getLastAccess() { return m_last_touch_tick; }
+
+ // Set the last access Tick.
+ void setLastAccess(Tick tick) { m_last_touch_tick = tick; }
};
inline std::ostream&
diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.cc b/src/mem/ruby/slicc_interface/AbstractEntry.cc
deleted file mode 100644
index 51f16df6a..000000000
--- a/src/mem/ruby/slicc_interface/AbstractEntry.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * 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.
- */
-
-#include "mem/ruby/slicc_interface/AbstractEntry.hh"
-
-AbstractEntry::AbstractEntry()
-{
- m_Permission = AccessPermission_NotPresent;
-}
-
-AbstractEntry::~AbstractEntry()
-{
-}
-
-AccessPermission
-AbstractEntry::getPermission() const
-{
- return m_Permission;
-}
-
-void
-AbstractEntry::changePermission(AccessPermission new_perm)
-{
- m_Permission = new_perm;
-}
diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.hh b/src/mem/ruby/slicc_interface/AbstractEntry.hh
deleted file mode 100644
index a75055f5e..000000000
--- a/src/mem/ruby/slicc_interface/AbstractEntry.hh
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * 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.
- */
-
-#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
-#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
-
-#include <iostream>
-
-#include "mem/ruby/protocol/AccessPermission.hh"
-
-class AbstractEntry
-{
- public:
- AbstractEntry();
- virtual ~AbstractEntry() = 0;
-
- // Get/Set permission of the entry
- AccessPermission getPermission() const;
- void changePermission(AccessPermission new_perm);
-
- virtual void print(std::ostream& out) const = 0;
-
- AccessPermission m_Permission; // Access permission for this
- // block, required by CacheMemory
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, const AbstractEntry& obj)
-{
- obj.print(out);
- out << std::flush;
- return out;
-}
-
-#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript
index 2d00fb7fe..d8d931c63 100644
--- a/src/mem/ruby/slicc_interface/SConscript
+++ b/src/mem/ruby/slicc_interface/SConscript
@@ -36,6 +36,5 @@ if env['PROTOCOL'] == 'None':
SimObject('Controller.py')
Source('AbstractController.cc')
-Source('AbstractEntry.cc')
Source('AbstractCacheEntry.cc')
Source('RubyRequest.cc')
diff --git a/src/mem/ruby/structures/AbstractReplacementPolicy.cc b/src/mem/ruby/structures/AbstractReplacementPolicy.cc
deleted file mode 100644
index 01eb6e517..000000000
--- a/src/mem/ruby/structures/AbstractReplacementPolicy.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- *
- * Author: Derek Hower
- */
-
-#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
-
-#include "base/logging.hh"
-
-AbstractReplacementPolicy::AbstractReplacementPolicy(const Params * p)
- : SimObject(p)
-{
- m_num_sets = p->size/p->block_size/p->assoc;
- m_assoc = p->assoc;
- m_last_ref_ptr = new Tick*[m_num_sets];
- for (unsigned i = 0; i < m_num_sets; i++){
- m_last_ref_ptr[i] = new Tick[m_assoc];
- for (unsigned j = 0; j < m_assoc; j++){
- m_last_ref_ptr[i][j] = 0;
- }
- }
-}
-
-AbstractReplacementPolicy *
-ReplacementPolicyParams::create()
-{
- fatal("Cannot create an AbstractReplacementPolicy");
- return NULL;
-}
-
-
-
-AbstractReplacementPolicy::~AbstractReplacementPolicy()
-{
- if (m_last_ref_ptr != NULL){
- for (unsigned i = 0; i < m_num_sets; i++){
- if (m_last_ref_ptr[i] != NULL){
- delete[] m_last_ref_ptr[i];
- }
- }
- delete[] m_last_ref_ptr;
- }
-}
-
-Tick
-AbstractReplacementPolicy::getLastAccess(int64_t set, int64_t way)
-{
- return m_last_ref_ptr[set][way];
-}
diff --git a/src/mem/ruby/structures/AbstractReplacementPolicy.hh b/src/mem/ruby/structures/AbstractReplacementPolicy.hh
deleted file mode 100644
index c118f3c11..000000000
--- a/src/mem/ruby/structures/AbstractReplacementPolicy.hh
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007 Mark D. Hill and David A. Wood
- * 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.
- */
-
-#ifndef __MEM_RUBY_STRUCTURES_ABSTRACTREPLACEMENTPOLICY_HH__
-#define __MEM_RUBY_STRUCTURES_ABSTRACTREPLACEMENTPOLICY_HH__
-
-#include "base/types.hh"
-#include "mem/ruby/common/TypeDefines.hh"
-#include "params/ReplacementPolicy.hh"
-#include "sim/sim_object.hh"
-
-class CacheMemory;
-
-class AbstractReplacementPolicy : public SimObject
-{
- public:
- typedef ReplacementPolicyParams Params;
- AbstractReplacementPolicy(const Params * p);
- virtual ~AbstractReplacementPolicy();
-
- /* touch a block. a.k.a. update timestamp */
- virtual void touch(int64_t set, int64_t way, Tick time) = 0;
-
- /* returns the way to replace */
- virtual int64_t getVictim(int64_t set) const = 0;
-
- /* get the time of the last access */
- Tick getLastAccess(int64_t set, int64_t way);
-
- virtual bool useOccupancy() const { return false; }
-
- void setCache(CacheMemory * pCache) {m_cache = pCache;}
- CacheMemory * m_cache;
-
- protected:
- unsigned m_num_sets; /** total number of sets */
- unsigned m_assoc; /** set associativity */
- Tick **m_last_ref_ptr; /** timestamp of last reference */
-};
-
-#endif // __MEM_RUBY_STRUCTURES_ABSTRACTREPLACEMENTPOLICY_HH__
diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc
index 5dc346388..a7aa6370b 100644
--- a/src/mem/ruby/structures/CacheMemory.cc
+++ b/src/mem/ruby/structures/CacheMemory.cc
@@ -65,11 +65,12 @@ CacheMemory::CacheMemory(const Params *p)
m_cache_size = p->size;
m_cache_assoc = p->assoc;
m_replacementPolicy_ptr = p->replacement_policy;
- m_replacementPolicy_ptr->setCache(this);
m_start_index_bit = p->start_index_bit;
m_is_instruction_only_cache = p->is_icache;
m_resource_stalls = p->resourceStalls;
m_block_size = p->block_size; // may be 0 at this point. Updated in init()
+ m_use_occupancy = dynamic_cast<WeightedLRUPolicy*>(
+ m_replacementPolicy_ptr) ? true : false;
}
void
@@ -85,6 +86,15 @@ CacheMemory::init()
m_cache.resize(m_cache_num_sets,
std::vector<AbstractCacheEntry*>(m_cache_assoc, nullptr));
+ replacement_data.resize(m_cache_num_sets,
+ std::vector<ReplData>(m_cache_assoc, nullptr));
+ // instantiate all the replacement_data here
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for ( int j = 0; j < m_cache_assoc; j++) {
+ replacement_data[i][j] =
+ m_replacementPolicy_ptr->instantiateEntry();
+ }
+ }
}
CacheMemory::~CacheMemory()
@@ -170,7 +180,8 @@ CacheMemory::tryCacheAccess(Addr address, RubyRequestType type,
if (loc != -1) {
// Do we even have a tag match?
AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
+ m_replacementPolicy_ptr->touch(replacement_data[cacheSet][loc]);
+ m_cache[cacheSet][loc]->setLastAccess(curTick());
data_ptr = &(entry->getDataBlk());
if (entry->m_Permission == AccessPermission_Read_Write) {
@@ -198,7 +209,8 @@ CacheMemory::testCacheAccess(Addr address, RubyRequestType type,
if (loc != -1) {
// Do we even have a tag match?
AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
+ m_replacementPolicy_ptr->touch(replacement_data[cacheSet][loc]);
+ m_cache[cacheSet][loc]->setLastAccess(curTick());
data_ptr = &(entry->getDataBlk());
return m_cache[cacheSet][loc]->m_Permission !=
@@ -252,7 +264,7 @@ CacheMemory::cacheAvail(Addr address) const
}
AbstractCacheEntry*
-CacheMemory::allocate(Addr address, AbstractCacheEntry *entry, bool touch)
+CacheMemory::allocate(Addr address, AbstractCacheEntry *entry)
{
assert(address == makeLineAddress(address));
assert(!isTagPresent(address));
@@ -278,13 +290,11 @@ CacheMemory::allocate(Addr address, AbstractCacheEntry *entry, bool touch)
address);
set[i]->m_locked = -1;
m_tag_index[address] = i;
- entry->setSetIndex(cacheSet);
- entry->setWayIndex(i);
-
- if (touch) {
- m_replacementPolicy_ptr->touch(cacheSet, i, curTick());
- }
-
+ set[i]->setPosition(cacheSet, i);
+ // Call reset function here to set initial value for different
+ // replacement policies.
+ m_replacementPolicy_ptr->reset(replacement_data[cacheSet][i]);
+ set[i]->setLastAccess(curTick());
return entry;
}
}
@@ -300,6 +310,7 @@ CacheMemory::deallocate(Addr address)
int64_t cacheSet = addressToCacheSet(address);
int loc = findTagInSet(cacheSet, address);
if (loc != -1) {
+ m_replacementPolicy_ptr->invalidate(replacement_data[cacheSet][loc]);
delete m_cache[cacheSet][loc];
m_cache[cacheSet][loc] = NULL;
m_tag_index.erase(address);
@@ -314,8 +325,16 @@ CacheMemory::cacheProbe(Addr address) const
assert(!cacheAvail(address));
int64_t cacheSet = addressToCacheSet(address);
- return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->
- m_Address;
+ std::vector<ReplaceableEntry*> candidates;
+ for (int i = 0; i < m_cache_assoc; i++) {
+ // Pass the value of replacement_data to the cache entry so that we
+ // can use it in the getVictim() function.
+ m_cache[cacheSet][i]->replacementData = replacement_data[cacheSet][i];
+ candidates.push_back(static_cast<ReplaceableEntry*>(
+ m_cache[cacheSet][i]));
+ }
+ return m_cache[cacheSet][m_replacementPolicy_ptr->
+ getVictim(candidates)->getWay()]->m_Address;
}
// looks an address up in the cache
@@ -347,16 +366,19 @@ CacheMemory::setMRU(Addr address)
int64_t cacheSet = addressToCacheSet(address);
int loc = findTagInSet(cacheSet, address);
- if (loc != -1)
- m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
+ if (loc != -1) {
+ m_replacementPolicy_ptr->touch(replacement_data[cacheSet][loc]);
+ m_cache[cacheSet][loc]->setLastAccess(curTick());
+ }
}
void
CacheMemory::setMRU(const AbstractCacheEntry *e)
{
- uint32_t cacheSet = e->getSetIndex();
- uint32_t loc = e->getWayIndex();
- m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
+ uint32_t cacheSet = e->getSet();
+ uint32_t loc = e->getWay();
+ m_replacementPolicy_ptr->touch(replacement_data[cacheSet][loc]);
+ m_cache[cacheSet][loc]->setLastAccess(curTick());
}
void
@@ -366,13 +388,17 @@ CacheMemory::setMRU(Addr address, int occupancy)
int loc = findTagInSet(cacheSet, address);
if (loc != -1) {
- if (m_replacementPolicy_ptr->useOccupancy()) {
- (static_cast<WeightedLRUPolicy*>(m_replacementPolicy_ptr))->
- touch(cacheSet, loc, curTick(), occupancy);
+ // m_use_occupancy can decide whether we are using WeightedLRU
+ // replacement policy. Depending on different replacement policies,
+ // use different touch() function.
+ if (m_use_occupancy) {
+ static_cast<WeightedLRUPolicy*>(m_replacementPolicy_ptr)->touch(
+ replacement_data[cacheSet][loc], occupancy);
} else {
m_replacementPolicy_ptr->
- touch(cacheSet, loc, curTick());
+ touch(replacement_data[cacheSet][loc]);
}
+ m_cache[cacheSet][loc]->setLastAccess(curTick());
}
}
@@ -413,9 +439,10 @@ CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const
}
if (request_type != RubyRequestType_NULL) {
+ Tick lastAccessTick;
+ lastAccessTick = m_cache[i][j]->getLastAccess();
tr->addRecord(cntrl, m_cache[i][j]->m_Address,
- 0, request_type,
- m_replacementPolicy_ptr->getLastAccess(i, j),
+ 0, request_type, lastAccessTick,
m_cache[i][j]->getDataBlk());
warmedUpBlocks++;
}
diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh
index 16339ee55..ce5d81d04 100644
--- a/src/mem/ruby/structures/CacheMemory.hh
+++ b/src/mem/ruby/structures/CacheMemory.hh
@@ -35,13 +35,14 @@
#include <vector>
#include "base/statistics.hh"
+#include "mem/cache/replacement_policies/base.hh"
+#include "mem/cache/replacement_policies/replaceable_entry.hh"
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/protocol/CacheRequestType.hh"
#include "mem/ruby/protocol/CacheResourceType.hh"
#include "mem/ruby/protocol/RubyRequest.hh"
#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
-#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
#include "mem/ruby/structures/BankedArray.hh"
#include "mem/ruby/system/CacheRecorder.hh"
#include "params/RubyCache.hh"
@@ -51,6 +52,7 @@ class CacheMemory : public SimObject
{
public:
typedef RubyCacheParams Params;
+ typedef std::shared_ptr<ReplacementData> ReplData;
CacheMemory(const Params *p);
~CacheMemory();
@@ -74,15 +76,10 @@ class CacheMemory : public SimObject
bool cacheAvail(Addr address) const;
// find an unused entry and sets the tag appropriate for the address
- AbstractCacheEntry* allocate(Addr address,
- AbstractCacheEntry* new_entry, bool touch);
- AbstractCacheEntry* allocate(Addr address, AbstractCacheEntry* new_entry)
- {
- return allocate(address, new_entry, true);
- }
+ AbstractCacheEntry* allocate(Addr address, AbstractCacheEntry* new_entry);
void allocateVoid(Addr address, AbstractCacheEntry* new_entry)
{
- allocate(address, new_entry, true);
+ allocate(address, new_entry);
}
// Explicitly free up this address
@@ -173,7 +170,11 @@ class CacheMemory : public SimObject
std::unordered_map<Addr, int> m_tag_index;
std::vector<std::vector<AbstractCacheEntry*> > m_cache;
- AbstractReplacementPolicy *m_replacementPolicy_ptr;
+ /**
+ * We use BaseReplacementPolicy from Classic system here, hence we can use
+ * different replacement policies from Classic system in Ruby system.
+ */
+ BaseReplacementPolicy *m_replacementPolicy_ptr;
BankedArray dataArray;
BankedArray tagArray;
@@ -185,6 +186,22 @@ class CacheMemory : public SimObject
int m_start_index_bit;
bool m_resource_stalls;
int m_block_size;
+
+ /**
+ * We store all the ReplacementData in a 2-dimensional array. By doing
+ * this, we can use all replacement policies from Classic system. Ruby
+ * cache will deallocate cache entry every time we evict the cache block
+ * so we cannot store the ReplacementData inside the cache entry.
+ * Instantiate ReplacementData for multiple times will break replacement
+ * policy like TreePLRU.
+ */
+ std::vector<std::vector<ReplData> > replacement_data;
+
+ /**
+ * Set to true when using WeightedLRU replacement policy, otherwise, set to
+ * false.
+ */
+ bool m_use_occupancy;
};
std::ostream& operator<<(std::ostream& out, const CacheMemory& obj);
diff --git a/src/mem/ruby/structures/DirectoryMemory.cc b/src/mem/ruby/structures/DirectoryMemory.cc
index 551e3f57f..d9da05861 100644
--- a/src/mem/ruby/structures/DirectoryMemory.cc
+++ b/src/mem/ruby/structures/DirectoryMemory.cc
@@ -68,7 +68,7 @@ void
DirectoryMemory::init()
{
m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
- m_entries = new AbstractEntry*[m_num_entries];
+ m_entries = new AbstractCacheEntry*[m_num_entries];
for (int i = 0; i < m_num_entries; i++)
m_entries[i] = NULL;
}
@@ -109,7 +109,7 @@ DirectoryMemory::mapAddressToLocalIdx(Addr address)
return ret >> RubySystem::getBlockSizeBits();
}
-AbstractEntry*
+AbstractCacheEntry*
DirectoryMemory::lookup(Addr address)
{
assert(isPresent(address));
@@ -120,8 +120,8 @@ DirectoryMemory::lookup(Addr address)
return m_entries[idx];
}
-AbstractEntry*
-DirectoryMemory::allocate(Addr address, AbstractEntry *entry)
+AbstractCacheEntry*
+DirectoryMemory::allocate(Addr address, AbstractCacheEntry *entry)
{
assert(isPresent(address));
uint64_t idx;
diff --git a/src/mem/ruby/structures/DirectoryMemory.hh b/src/mem/ruby/structures/DirectoryMemory.hh
index bbed4f975..f879b294f 100644
--- a/src/mem/ruby/structures/DirectoryMemory.hh
+++ b/src/mem/ruby/structures/DirectoryMemory.hh
@@ -47,7 +47,7 @@
#include "base/addr_range.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/protocol/DirectoryRequestType.hh"
-#include "mem/ruby/slicc_interface/AbstractEntry.hh"
+#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
#include "params/RubyDirectoryMemory.hh"
#include "sim/sim_object.hh"
@@ -76,8 +76,8 @@ class DirectoryMemory : public SimObject
uint64_t getSize() { return m_size_bytes; }
bool isPresent(Addr address);
- AbstractEntry *lookup(Addr address);
- AbstractEntry *allocate(Addr address, AbstractEntry* new_entry);
+ AbstractCacheEntry *lookup(Addr address);
+ AbstractCacheEntry *allocate(Addr address, AbstractCacheEntry* new_entry);
void print(std::ostream& out) const;
void recordRequestType(DirectoryRequestType requestType);
@@ -89,7 +89,7 @@ class DirectoryMemory : public SimObject
private:
const std::string m_name;
- AbstractEntry **m_entries;
+ AbstractCacheEntry **m_entries;
// int m_size; // # of memory module blocks this directory is
// responsible for
uint64_t m_size_bytes;
diff --git a/src/mem/ruby/structures/LRUPolicy.cc b/src/mem/ruby/structures/LRUPolicy.cc
deleted file mode 100644
index 3b6d91754..000000000
--- a/src/mem/ruby/structures/LRUPolicy.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- *
- * Author: Derek Hower
- */
-
-#include "mem/ruby/structures/LRUPolicy.hh"
-
-LRUPolicy::LRUPolicy(const Params * p)
- : AbstractReplacementPolicy(p)
-{
-}
-
-
-LRUPolicy::~LRUPolicy()
-{
-}
-
-LRUPolicy *
-LRUReplacementPolicyParams::create()
-{
- return new LRUPolicy(this);
-}
-
-
-void
-LRUPolicy::touch(int64_t set, int64_t index, Tick time)
-{
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
-
- m_last_ref_ptr[set][index] = time;
-}
-
-int64_t
-LRUPolicy::getVictim(int64_t set) const
-{
- Tick time, smallest_time;
- int64_t smallest_index = 0;
- smallest_time = m_last_ref_ptr[set][0];
-
- for (unsigned i = 0; i < m_assoc; i++) {
- time = m_last_ref_ptr[set][i];
-
- if (time < smallest_time) {
- smallest_index = i;
- smallest_time = time;
- }
- }
-
- return smallest_index;
-}
diff --git a/src/mem/ruby/structures/LRUPolicy.hh b/src/mem/ruby/structures/LRUPolicy.hh
deleted file mode 100644
index 388718319..000000000
--- a/src/mem/ruby/structures/LRUPolicy.hh
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2007 Mark D. Hill and David A. Wood
- * 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.
- */
-
-#ifndef __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__
-#define __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__
-
-#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
-#include "params/LRUReplacementPolicy.hh"
-
-/* Simple true LRU replacement policy */
-
-class LRUPolicy : public AbstractReplacementPolicy
-{
- public:
- typedef LRUReplacementPolicyParams Params;
- LRUPolicy(const Params * p);
- ~LRUPolicy();
-
- void touch(int64_t set, int64_t way, Tick time);
- int64_t getVictim(int64_t set) const;
-};
-
-#endif // __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__
diff --git a/src/mem/ruby/structures/LRUReplacementPolicy.py b/src/mem/ruby/structures/LRUReplacementPolicy.py
deleted file mode 100644
index 9c36b5f51..000000000
--- a/src/mem/ruby/structures/LRUReplacementPolicy.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright (c) 2013 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.
-#
-# Author: Derek Hower
-
-
-
-from m5.params import *
-from m5.SimObject import SimObject
-from m5.objects.ReplacementPolicy import ReplacementPolicy
-
-class LRUReplacementPolicy(ReplacementPolicy):
- type = 'LRUReplacementPolicy'
- cxx_class = 'LRUPolicy'
- cxx_header = 'mem/ruby/structures/LRUPolicy.hh'
-
-
diff --git a/src/mem/ruby/structures/PseudoLRUPolicy.cc b/src/mem/ruby/structures/PseudoLRUPolicy.cc
deleted file mode 100644
index e423bb58d..000000000
--- a/src/mem/ruby/structures/PseudoLRUPolicy.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- *
- * Author: Derek Hower
- */
-
-#include "mem/ruby/structures/PseudoLRUPolicy.hh"
-
-PseudoLRUPolicy::PseudoLRUPolicy(const Params * p)
- : AbstractReplacementPolicy(p)
-{
- // associativity cannot exceed capacity of tree representation
- assert(m_num_sets > 0 &&
- m_assoc > 1 &&
- m_assoc <= (int64_t) sizeof(uint64_t)*4);
-
- m_trees = NULL;
- m_num_levels = 0;
-
- m_effective_assoc = 1;
- while (m_effective_assoc < m_assoc) {
- // effective associativity is ceiling power of 2
- m_effective_assoc <<= 1;
- }
- int tmp_assoc = m_effective_assoc;
- while (true) {
- tmp_assoc /= 2;
- if (!tmp_assoc) break;
- m_num_levels++;
- }
- assert(m_num_levels < sizeof(unsigned int)*4);
- m_trees = new uint64_t[m_num_sets];
- for (unsigned i = 0; i < m_num_sets; i++) {
- m_trees[i] = 0;
- }
-}
-
-PseudoLRUPolicy *
-PseudoLRUReplacementPolicyParams::create()
-{
- return new PseudoLRUPolicy(this);
-}
-
-
-PseudoLRUPolicy::~PseudoLRUPolicy()
-{
- if (m_trees != NULL)
- delete[] m_trees;
-}
-
-void
-PseudoLRUPolicy::touch(int64_t set, int64_t index, Tick time)
-{
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
-
- int tree_index = 0;
- int node_val;
- for (int i = m_num_levels - 1; i >= 0; i--) {
- node_val = (index >> i)&1;
- if (node_val)
- m_trees[set] |= node_val << tree_index;
- else
- m_trees[set] &= ~(1 << tree_index);
- tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1;
- }
- m_last_ref_ptr[set][index] = time;
-}
-
-int64_t
-PseudoLRUPolicy::getVictim(int64_t set) const
-{
- int64_t index = 0;
-
- int tree_index = 0;
- int node_val;
- for (unsigned i = 0; i < m_num_levels; i++){
- node_val = (m_trees[set] >> tree_index) & 1;
- index += node_val ? 0 : (m_effective_assoc >> (i + 1));
- tree_index = node_val ? (tree_index * 2) + 1 : (tree_index * 2) + 2;
- }
- assert(index >= 0 && index < m_effective_assoc);
-
- /* return either the found index or the max possible index */
- /* NOTE: this is not a fair replacement when assoc is not a power of 2 */
- return (index > (m_assoc - 1)) ? m_assoc - 1 : index;
-}
diff --git a/src/mem/ruby/structures/PseudoLRUPolicy.hh b/src/mem/ruby/structures/PseudoLRUPolicy.hh
deleted file mode 100644
index a96c802b2..000000000
--- a/src/mem/ruby/structures/PseudoLRUPolicy.hh
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007 Mark D. Hill and David A. Wood
- * Copyright (c) 2013 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.
- */
-
-#ifndef __MEM_RUBY_STRUCTURES_PSEUDOLRUPOLICY_HH__
-#define __MEM_RUBY_STRUCTURES_PSEUDOLRUPOLICY_HH__
-
-#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
-#include "params/PseudoLRUReplacementPolicy.hh"
-
-/**
- * Implementation of tree-based pseudo-LRU replacement
- *
- * Works for any associativity between 1 and 128.
- *
- * Also implements associativities that are not a power of 2 by
- * ignoring paths that lead to a larger index (i.e. truncating the
- * tree). Note that when this occurs, the algorithm becomes less
- * fair, as it will favor indicies in the larger (by index) half of
- * the associative set. This is most unfair when the nearest power of
- * 2 is one below the associativy, and most fair when it is one above.
- */
-
-class PseudoLRUPolicy : public AbstractReplacementPolicy
-{
- public:
- typedef PseudoLRUReplacementPolicyParams Params;
- PseudoLRUPolicy(const Params * p);
- ~PseudoLRUPolicy();
-
- void touch(int64_t set, int64_t way, Tick time);
- int64_t getVictim(int64_t set) const;
-
- private:
- unsigned int m_effective_assoc; /** nearest (to ceiling) power of 2 */
- unsigned int m_num_levels; /** number of levels in the tree */
- uint64_t* m_trees; /** bit representation of the
- * trees, one for each set */
-};
-
-#endif // __MEM_RUBY_STRUCTURES_PSEUDOLRUPOLICY_HH__
diff --git a/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py b/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py
deleted file mode 100644
index 2b892d47a..000000000
--- a/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) 2013 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.
-#
-# Author: Derek Hower
-
-from m5.objects.ReplacementPolicy import ReplacementPolicy
-
-class PseudoLRUReplacementPolicy(ReplacementPolicy):
- type = 'PseudoLRUReplacementPolicy'
- cxx_class = 'PseudoLRUPolicy'
- cxx_header = 'mem/ruby/structures/PseudoLRUPolicy.hh'
diff --git a/src/mem/ruby/structures/ReplacementPolicy.py b/src/mem/ruby/structures/ReplacementPolicy.py
deleted file mode 100644
index 4570cc9df..000000000
--- a/src/mem/ruby/structures/ReplacementPolicy.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Copyright (c) 2013 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.
-#
-# Author: Derek Hower
-
-from m5.params import *
-from m5.proxy import *
-from m5.SimObject import SimObject
-
-class ReplacementPolicy(SimObject):
- type = 'ReplacementPolicy'
- cxx_class = 'AbstractReplacementPolicy'
- cxx_header = 'mem/ruby/structures/AbstractReplacementPolicy.hh'
-
- block_size = Param.Int(Parent.cache_line_size, "block size in bytes")
-
- size = Param.MemorySize(Parent.size, "capacity in bytes")
-
- assoc = Param.Int(Parent.assoc, "associativity")
diff --git a/src/mem/ruby/structures/RubyCache.py b/src/mem/ruby/structures/RubyCache.py
index cf8410c6d..49c20ff4c 100644
--- a/src/mem/ruby/structures/RubyCache.py
+++ b/src/mem/ruby/structures/RubyCache.py
@@ -29,7 +29,7 @@
from m5.params import *
from m5.proxy import *
-from m5.objects.PseudoLRUReplacementPolicy import PseudoLRUReplacementPolicy
+from m5.objects.ReplacementPolicies import *
from m5.SimObject import SimObject
class RubyCache(SimObject):
@@ -38,8 +38,7 @@ class RubyCache(SimObject):
cxx_header = "mem/ruby/structures/CacheMemory.hh"
size = Param.MemorySize("capacity in bytes");
assoc = Param.Int("");
- replacement_policy = Param.ReplacementPolicy(PseudoLRUReplacementPolicy(),
- "")
+ replacement_policy = Param.BaseReplacementPolicy(TreePLRURP(), "")
start_index_bit = Param.Int(6, "index start, default 6 for 64-byte line");
is_icache = Param.Bool(False, "is instruction only cache");
block_size = Param.MemorySize("0B", "block size in bytes. 0 means default RubyBlockSize")
diff --git a/src/mem/ruby/structures/SConscript b/src/mem/ruby/structures/SConscript
index c39cd0e51..fdd9289f3 100644
--- a/src/mem/ruby/structures/SConscript
+++ b/src/mem/ruby/structures/SConscript
@@ -35,17 +35,11 @@ if env['PROTOCOL'] == 'None':
SimObject('RubyCache.py')
SimObject('DirectoryMemory.py')
-SimObject('LRUReplacementPolicy.py')
-SimObject('PseudoLRUReplacementPolicy.py')
-SimObject('ReplacementPolicy.py')
SimObject('RubyPrefetcher.py')
SimObject('WireBuffer.py')
-Source('AbstractReplacementPolicy.cc')
Source('DirectoryMemory.cc')
Source('CacheMemory.cc')
-Source('LRUPolicy.cc')
-Source('PseudoLRUPolicy.cc')
Source('WireBuffer.cc')
Source('PersistentTable.cc')
Source('Prefetcher.cc')
diff --git a/src/mem/ruby/system/WeightedLRUPolicy.cc b/src/mem/ruby/system/WeightedLRUPolicy.cc
index 2899f73a7..8f330d917 100644
--- a/src/mem/ruby/system/WeightedLRUPolicy.cc
+++ b/src/mem/ruby/system/WeightedLRUPolicy.cc
@@ -35,16 +35,12 @@
#include "mem/ruby/system/WeightedLRUPolicy.hh"
+#include <cassert>
+#include <memory>
+
WeightedLRUPolicy::WeightedLRUPolicy(const Params* p)
- : AbstractReplacementPolicy(p), m_cache(p->cache)
+ : BaseReplacementPolicy(p)
{
- m_last_occ_ptr = new int*[m_num_sets];
- for (unsigned i = 0; i < m_num_sets; i++){
- m_last_occ_ptr[i] = new int[m_assoc];
- for (unsigned j = 0; j < m_assoc; j++){
- m_last_occ_ptr[i][j] = 0;
- }
- }
}
WeightedLRUPolicy *
@@ -53,61 +49,78 @@ WeightedLRUReplacementPolicyParams::create()
return new WeightedLRUPolicy(this);
}
-WeightedLRUPolicy::~WeightedLRUPolicy()
-{
- if (m_last_occ_ptr != NULL){
- for (unsigned i = 0; i < m_num_sets; i++){
- if (m_last_occ_ptr[i] != NULL){
- delete[] m_last_occ_ptr[i];
- }
- }
- delete[] m_last_occ_ptr;
- }
-}
-
void
-WeightedLRUPolicy::touch(int64_t set, int64_t index, Tick time)
+WeightedLRUPolicy::touch(const std::shared_ptr<ReplacementData>&
+ replacement_data) const
{
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
-
- m_last_ref_ptr[set][index] = time;
+ std::static_pointer_cast<WeightedLRUReplData>(replacement_data)->
+ last_touch_tick = curTick();
}
void
-WeightedLRUPolicy::touch(int64_t set, int64_t index, Tick time, int occupancy)
+WeightedLRUPolicy::touch(const std::shared_ptr<ReplacementData>&
+ replacement_data, int occupancy) const
{
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
-
- m_last_ref_ptr[set][index] = time;
- m_last_occ_ptr[set][index] = occupancy;
+ std::static_pointer_cast<WeightedLRUReplData>(replacement_data)->
+ last_touch_tick = curTick();
+ std::static_pointer_cast<WeightedLRUReplData>(replacement_data)->
+ last_occ_ptr = occupancy;
}
-int64_t
-WeightedLRUPolicy::getVictim(int64_t set) const
+ReplaceableEntry*
+WeightedLRUPolicy::getVictim(const ReplacementCandidates& candidates) const
{
- Tick time, smallest_time;
- int64_t smallest_index;
-
- smallest_index = 0;
- smallest_time = m_last_ref_ptr[set][0];
- int smallest_weight = m_last_occ_ptr[set][0];
+ assert(candidates.size() > 0);
- for (unsigned i = 1; i < m_assoc; i++) {
+ ReplaceableEntry* victim = candidates[0];
+ // Use weight (last_occ_ptr) to find victim.
+ // Evict the block that has the smallest weight.
+ // If two blocks have the same weight, evict the oldest one.
+ for (const auto& candidate : candidates) {
+ // candidate's replacement_data
+ std::shared_ptr<WeightedLRUReplData> candidate_replacement_data =
+ std::static_pointer_cast<WeightedLRUReplData>(
+ candidate->replacementData);
+ // victim's replacement_data
+ std::shared_ptr<WeightedLRUReplData> victim_replacement_data =
+ std::static_pointer_cast<WeightedLRUReplData>(
+ victim->replacementData);
- int weight = m_last_occ_ptr[set][i];
- if (weight < smallest_weight) {
- smallest_weight = weight;
- smallest_index = i;
- smallest_time = m_last_ref_ptr[set][i];
- } else if (weight == smallest_weight) {
- time = m_last_ref_ptr[set][i];
- if (time < smallest_time) {
- smallest_index = i;
- smallest_time = time;
+ if (candidate_replacement_data->last_occ_ptr <
+ victim_replacement_data->last_occ_ptr) {
+ victim = candidate;
+ } else if (candidate_replacement_data->last_occ_ptr ==
+ victim_replacement_data->last_occ_ptr) {
+ // Evict the block with a smaller tick.
+ Tick time = candidate_replacement_data->last_touch_tick;
+ if (time < victim_replacement_data->last_touch_tick) {
+ victim = candidate;
}
}
}
- return smallest_index;
+ return victim;
+}
+
+std::shared_ptr<ReplacementData>
+WeightedLRUPolicy::instantiateEntry()
+{
+ return std::shared_ptr<ReplacementData>(new WeightedLRUReplData);
+}
+
+void
+WeightedLRUPolicy::reset(const std::shared_ptr<ReplacementData>&
+ replacement_data) const
+{
+ // Set last touch timestamp
+ std::static_pointer_cast<WeightedLRUReplData>(
+ replacement_data)->last_touch_tick = curTick();
+}
+
+void
+WeightedLRUPolicy::invalidate(const std::shared_ptr<ReplacementData>&
+ replacement_data) const
+{
+ // Reset last touch timestamp
+ std::static_pointer_cast<WeightedLRUReplData>(
+ replacement_data)->last_touch_tick = Tick(0);
}
diff --git a/src/mem/ruby/system/WeightedLRUPolicy.hh b/src/mem/ruby/system/WeightedLRUPolicy.hh
index 47fcec4a6..a11784584 100644
--- a/src/mem/ruby/system/WeightedLRUPolicy.hh
+++ b/src/mem/ruby/system/WeightedLRUPolicy.hh
@@ -36,27 +36,78 @@
#ifndef __MEM_RUBY_SYSTEM_WEIGHTEDLRUPOLICY_HH__
#define __MEM_RUBY_SYSTEM_WEIGHTEDLRUPOLICY_HH__
-#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
+#include "mem/cache/replacement_policies/base.hh"
#include "mem/ruby/structures/CacheMemory.hh"
#include "params/WeightedLRUReplacementPolicy.hh"
/* Simple true LRU replacement policy */
-class WeightedLRUPolicy : public AbstractReplacementPolicy
+class WeightedLRUPolicy : public BaseReplacementPolicy
{
+ protected:
+ /** Weighted LRU implementation of replacement data. */
+ struct WeightedLRUReplData : ReplacementData
+ {
+ /** pointer for last occupancy */
+ int last_occ_ptr;
+
+ /** Tick on which the entry was last touched. */
+ Tick last_touch_tick;
+
+ /**
+ * Default constructor. Invalidate data.
+ */
+ WeightedLRUReplData() : ReplacementData(),
+ last_occ_ptr(0), last_touch_tick(0) {}
+ };
public:
typedef WeightedLRUReplacementPolicyParams Params;
WeightedLRUPolicy(const Params* p);
- ~WeightedLRUPolicy();
+ ~WeightedLRUPolicy() {}
+
+ /**
+ * Invalidate replacement data to set it as the next probable victim.
+ * Sets its last touch tick as the starting tick.
+ *
+ * @param replacement_data Replacement data to be invalidated.
+ */
+ void invalidate(const std::shared_ptr<ReplacementData>& replacement_data)
+ const override;
+ /**
+ * Touch an entry to update its replacement data.
+ * Sets its last touch tick as the current tick.
+ *
+ * @param replacement_data Replacement data to be touched.
+ */
+ void touch(const std::shared_ptr<ReplacementData>&
+ replacement_data) const override;
+ void touch(const std::shared_ptr<ReplacementData>& replacement_data,
+ int occupancy) const;
- void touch(int64_t set, int64_t way, Tick time) override;
- void touch(int64_t set, int64_t way, Tick time, int occupancy);
- int64_t getVictim(int64_t set) const override;
+ /**
+ * Reset replacement data. Used when an entry is inserted.
+ * Sets its last touch tick as the current tick.
+ *
+ * @param replacement_data Replacement data to be reset.
+ */
+ void reset(const std::shared_ptr<ReplacementData>& replacement_data) const
+ override;
- bool useOccupancy() const override { return true; }
+ /**
+ * Instantiate a replacement data entry.
+ *
+ * @return A shared pointer to the new replacement data.
+ */
+ std::shared_ptr<ReplacementData> instantiateEntry() override;
- CacheMemory * m_cache;
- int **m_last_occ_ptr;
+ /**
+ * Find replacement victim using weight.
+ *
+ * @param candidates Replacement candidates, selected by indexing policy.
+ * @return Replacement entry to be replaced.
+ */
+ ReplaceableEntry* getVictim(const ReplacementCandidates&
+ candidates) const override;
};
#endif // __MEM_RUBY_SYSTEM_WeightedLRUPolicy_HH__
diff --git a/src/mem/ruby/system/WeightedLRUReplacementPolicy.py b/src/mem/ruby/system/WeightedLRUReplacementPolicy.py
index fa50c95dc..48143e5d9 100644
--- a/src/mem/ruby/system/WeightedLRUReplacementPolicy.py
+++ b/src/mem/ruby/system/WeightedLRUReplacementPolicy.py
@@ -33,10 +33,9 @@
from m5.params import *
from m5.proxy import *
-from m5.objects.ReplacementPolicy import ReplacementPolicy
+from m5.objects.ReplacementPolicies import BaseReplacementPolicy
-class WeightedLRUReplacementPolicy(ReplacementPolicy):
+class WeightedLRUReplacementPolicy(BaseReplacementPolicy):
type = "WeightedLRUReplacementPolicy"
cxx_class = "WeightedLRUPolicy"
cxx_header = "mem/ruby/system/WeightedLRUPolicy.hh"
- cache = Param.RubyCache("")
diff --git a/src/mem/slicc/ast/FormalParamAST.py b/src/mem/slicc/ast/FormalParamAST.py
index ce73304f1..778b5c1aa 100644
--- a/src/mem/slicc/ast/FormalParamAST.py
+++ b/src/mem/slicc/ast/FormalParamAST.py
@@ -53,9 +53,10 @@ class FormalParamAST(AST):
self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or (
+ # Check whether type is entry by checking the interface since
+ # in protocol files, entries use AbstractCacheEntry as interfaces.
"interface" in type and (
- type["interface"] == "AbstractCacheEntry" or
- type["interface"] == "AbstractEntry")):
+ type["interface"] == "AbstractCacheEntry")):
return type, "%s* %s" % (type.c_ident, param)
else:
return type, "const %s& %s" % (type.c_ident, param)
diff --git a/src/mem/slicc/ast/LocalVariableAST.py b/src/mem/slicc/ast/LocalVariableAST.py
index 5c6bfe80a..c1a5fdbd9 100644
--- a/src/mem/slicc/ast/LocalVariableAST.py
+++ b/src/mem/slicc/ast/LocalVariableAST.py
@@ -61,9 +61,10 @@ class LocalVariableAST(StatementAST):
self.pairs)
self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or (
+ # Check whether type is Entry by checking interface since
+ # entries in protocol files use AbstractCacheEntry as interfaces.
"interface" in type and (
- type["interface"] == "AbstractCacheEntry" or
- type["interface"] == "AbstractEntry")):
+ type["interface"] == "AbstractCacheEntry")):
code += "%s* %s" % (type.c_ident, ident)
else:
code += "%s %s" % (type.c_ident, ident)
diff --git a/src/mem/slicc/ast/MemberExprAST.py b/src/mem/slicc/ast/MemberExprAST.py
index 320146065..50151bd0a 100644
--- a/src/mem/slicc/ast/MemberExprAST.py
+++ b/src/mem/slicc/ast/MemberExprAST.py
@@ -41,10 +41,13 @@ class MemberExprAST(ExprAST):
return_type, gcode = self.expr_ast.inline(True)
fix = code.nofix()
+
+ # Check whether return_type is Entry by checking
+ # interfaces since entries in protocol files use
+ # AbstractCacheEntry as interfaces.
if str(return_type) == "TBE" \
or ("interface" in return_type and
- (return_type["interface"] == "AbstractCacheEntry" or
- return_type["interface"] == "AbstractEntry")):
+ (return_type["interface"] == "AbstractCacheEntry")):
code("(*$gcode).m_${{self.field}}")
else:
code("($gcode).m_${{self.field}}")
diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py
index 104d6f8df..102ab6e4c 100644
--- a/src/mem/slicc/ast/MethodCallExprAST.py
+++ b/src/mem/slicc/ast/MethodCallExprAST.py
@@ -143,18 +143,18 @@ class MemberMethodCallExprAST(MethodCallExprAST):
methodId = implementedMethodId
return_type = obj_type.methods[methodId].return_type
+ # Check object type or interface of entries by checking
+ # AbstractCacheEntry since AbstractCacheEntry is used in
+ # protocol files.
if str(obj_type) == "AbstractCacheEntry" or \
- str(obj_type) == "AbstractEntry" or \
("interface" in obj_type and (
- obj_type["interface"] == "AbstractCacheEntry" or
- obj_type["interface"] == "AbstractEntry")):
+ obj_type["interface"] == "AbstractCacheEntry")):
prefix = "%s((*(%s))." % (prefix, code)
else:
prefix = "%s((%s)." % (prefix, code)
return obj_type, methodId, prefix
-
class ClassMethodCallExprAST(MethodCallExprAST):
def __init__(self, slicc, type_ast, proc_name, expr_ast_vec):
s = super(ClassMethodCallExprAST, self)