summaryrefslogtreecommitdiff
path: root/src/mem/ruby
diff options
context:
space:
mode:
authorBrad Beckmann <Brad.Beckmann@amd.com>2009-11-18 16:34:33 -0800
committerBrad Beckmann <Brad.Beckmann@amd.com>2009-11-18 16:34:33 -0800
commit5d8a669539a142ece820cf0c82722ea1c755d7cd (patch)
treeb17fb03643674b83785859378296ed4690e3d715 /src/mem/ruby
parentc6182199c54a874315a97338879d5bfaf3895a6f (diff)
downloadgem5-5d8a669539a142ece820cf0c82722ea1c755d7cd.tar.xz
Resurrection of the CMP token protocol to GEM5
Diffstat (limited to 'src/mem/ruby')
-rw-r--r--src/mem/ruby/SConscript1
-rw-r--r--src/mem/ruby/common/NetDest.cc5
-rw-r--r--src/mem/ruby/common/NetDest.hh2
-rw-r--r--src/mem/ruby/config/MOESI_CMP_token.rb92
-rw-r--r--src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb55
-rw-r--r--src/mem/ruby/config/cfg.rb1
-rw-r--r--src/mem/ruby/config/defaults.rb27
-rw-r--r--src/mem/ruby/system/PersistentTable.cc82
-rw-r--r--src/mem/ruby/system/PersistentTable.hh40
-rw-r--r--src/mem/ruby/system/SConscript1
10 files changed, 246 insertions, 60 deletions
diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript
index 0c8423c85..3559f042f 100644
--- a/src/mem/ruby/SConscript
+++ b/src/mem/ruby/SConscript
@@ -114,6 +114,7 @@ MakeInclude('system/MachineID.hh')
MakeInclude('system/MemoryControl.hh')
MakeInclude('system/NodeID.hh')
MakeInclude('system/PerfectCacheMemory.hh')
+MakeInclude('system/PersistentTable.hh')
MakeInclude('system/Sequencer.hh')
MakeInclude('system/TBETable.hh')
MakeInclude('system/TimerTable.hh')
diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc
index 32771235f..35bb4ec43 100644
--- a/src/mem/ruby/common/NetDest.cc
+++ b/src/mem/ruby/common/NetDest.cc
@@ -133,13 +133,14 @@ NodeID NetDest::elementAt(MachineID index) {
return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
}
-NodeID NetDest::smallestElement() const
+MachineID NetDest::smallestElement() const
{
assert(count() > 0);
for (int i=0; i<m_bits.size(); i++) {
for (int j=0; j<m_bits[i].getSize(); j++) {
if (m_bits[i].isElement(j)) {
- return j;
+ MachineID mach = {MachineType_from_base_level(i), j};
+ return mach;
}
}
}
diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh
index 7301409ce..071106623 100644
--- a/src/mem/ruby/common/NetDest.hh
+++ b/src/mem/ruby/common/NetDest.hh
@@ -96,7 +96,7 @@ public:
//For Princeton Network
Vector<NodeID> getAllDest();
- NodeID smallestElement() const;
+ MachineID smallestElement() const;
MachineID smallestElement(MachineType machine) const;
void setSize();
diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb
new file mode 100644
index 000000000..ba963dc06
--- /dev/null
+++ b/src/mem/ruby/config/MOESI_CMP_token.rb
@@ -0,0 +1,92 @@
+
+require "cfg.rb"
+require "util.rb"
+
+
+class MOESI_CMP_token_L1CacheController < L1CacheController
+ attr :icache, :dcache
+ attr :num_l2_controllers
+ attr :n_tokens
+ def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens)
+ super(obj_name, mach_type, [icache, dcache], sequencer)
+ @icache = icache
+ @dcache = dcache
+ @num_l2_controllers = num_l2_controllers
+ @n_tokens = n_tokens
+ end
+ def argv()
+ num_select_bits = log_int(num_l2_controllers)
+ num_block_bits = log_int(RubySystem.block_size_bytes)
+
+ l2_select_low_bit = num_block_bits
+
+ vec = super()
+ vec += " icache " + @icache.obj_name
+ vec += " dcache " + @dcache.obj_name
+ vec += " l1_request_latency " + l1_request_latency.to_s
+ vec += " l1_response_latency " + l1_response_latency.to_s
+ vec += " l2_select_low_bit " + l2_select_low_bit.to_s
+ vec += " l2_select_num_bits " + num_select_bits.to_s
+ vec += " N_tokens " + n_tokens.to_s
+ vec += " retry_threshold " + retry_threshold.to_s
+ vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s
+ vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s
+
+ return vec
+ end
+end
+
+class MOESI_CMP_token_L2CacheController < CacheController
+ attr :cache
+ attr :n_tokens
+ def initialize(obj_name, mach_type, cache, n_tokens)
+ super(obj_name, mach_type, [cache])
+ @cache = cache
+ @n_tokens = n_tokens
+ end
+ def argv()
+ vec = super()
+ vec += " cache " + @cache.obj_name
+ vec += " l2_request_latency " + l2_request_latency.to_s
+ vec += " l2_response_latency " + l2_response_latency.to_s
+ vec += " N_tokens " + n_tokens.to_s
+ vec += " filtering_enabled " + filtering_enabled.to_s
+ return vec
+ end
+end
+
+
+class MOESI_CMP_token_DirectoryController < DirectoryController
+ attr :num_l2_controllers
+ def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers)
+ super(obj_name, mach_type, directory, memory_control)
+ @num_l2_controllers = num_l2_controllers
+ end
+ def argv()
+ num_select_bits = log_int(num_l2_controllers)
+ num_block_bits = log_int(RubySystem.block_size_bytes)
+
+ l2_select_low_bit = num_block_bits
+
+ vec = super()
+ vec += " directory_latency "+directory_latency.to_s
+ vec += " l2_select_low_bit " + l2_select_low_bit.to_s
+ vec += " l2_select_num_bits " + num_select_bits.to_s
+ vec += " distributed_persistent "+distributed_persistent.to_s
+ vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s
+ return vec
+ end
+
+end
+
+class MOESI_CMP_token_DMAController < DMAController
+ def initialize(obj_name, mach_type, dma_sequencer)
+ super(obj_name, mach_type, dma_sequencer)
+ end
+ def argv()
+ vec = super
+ vec += " request_latency "+request_latency.to_s
+ vec += " response_latency "+response_latency.to_s
+ return vec
+ end
+end
diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
index 83020742e..566055f74 100644
--- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
+++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
@@ -12,13 +12,13 @@ RubySystem.reset
# default values
num_cores = 2
-l1_icache_size_kb = 32
+l1_icache_size_bytes = 32768
l1_icache_assoc = 8
l1_icache_latency = 1
-l1_dcache_size_kb = 32
+l1_dcache_size_bytes = 32768
l1_dcache_assoc = 8
l1_dcache_latency = 1
-l2_cache_size_kb = 2048 # total size (sum of all banks)
+l2_cache_size_bytes = 2048 # total size (sum of all banks)
l2_cache_assoc = 16
l2_cache_latency = 12
num_l2_banks = num_cores
@@ -26,7 +26,7 @@ num_memories = 1
memory_size_mb = 1024
num_dma = 1
-protocol = "MESI_CMP_directory"
+protocol = "MOESI_CMP_token"
# check for overrides
@@ -43,9 +43,20 @@ for i in 0..$*.size-1 do
elsif $*[i] == "-s"
memory_size_mb = $*[i+1].to_i
i = i + 1
+ elsif $*[i] == "-C"
+ l1_dcache_size_bytes = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-A"
+ l1_dcache_assoc = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-D"
+ num_dma = $*[i+1].to_i
+ i = i + 1
end
end
+n_tokens = num_cores + 1
+
net_ports = Array.new
iface_ports = Array.new
@@ -54,10 +65,19 @@ iface_ports = Array.new
require protocol+".rb"
num_cores.times { |n|
- icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU")
- dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU")
+ icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_bytes, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU")
+ dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_bytes, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU")
sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache)
iface_ports << sequencer
+ if protocol == "MOESI_CMP_token"
+ net_ports << MOESI_CMP_token_L1CacheController.new("L1CacheController_"+n.to_s,
+ "L1Cache",
+ icache, dcache,
+ sequencer,
+ num_l2_banks,
+ n_tokens)
+ end
+
if protocol == "MOESI_CMP_directory"
net_ports << MOESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s,
"L1Cache",
@@ -75,7 +95,14 @@ num_cores.times { |n|
end
}
num_l2_banks.times { |n|
- cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_kb/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU")
+ cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_bytes/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU")
+ if protocol == "MOESI_CMP_token"
+ net_ports << MOESI_CMP_token_L2CacheController.new("L2CacheController_"+n.to_s,
+ "L2Cache",
+ cache,
+ n_tokens)
+ end
+
if protocol == "MOESI_CMP_directory"
net_ports << MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s,
"L2Cache",
@@ -93,6 +120,14 @@ num_l2_banks.times { |n|
num_memories.times { |n|
directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories)
memory_control = MemoryControl.new("MemoryControl_"+n.to_s)
+ if protocol == "MOESI_CMP_token"
+ net_ports << MOESI_CMP_token_DirectoryController.new("DirectoryController_"+n.to_s,
+ "Directory",
+ directory,
+ memory_control,
+ num_l2_banks)
+ end
+
if protocol == "MOESI_CMP_directory"
net_ports << MOESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s,
"Directory",
@@ -111,6 +146,12 @@ num_memories.times { |n|
num_dma.times { |n|
dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s)
iface_ports << dma_sequencer
+ if protocol == "MOESI_CMP_token"
+ net_ports << MOESI_CMP_token_DMAController.new("DMAController_"+n.to_s,
+ "DMA",
+ dma_sequencer)
+ end
+
if protocol == "MOESI_CMP_directory"
net_ports << MOESI_CMP_directory_DMAController.new("DMAController_"+n.to_s,
"DMA",
diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb
index f2564e1d3..c470ca92f 100644
--- a/src/mem/ruby/config/cfg.rb
+++ b/src/mem/ruby/config/cfg.rb
@@ -538,7 +538,6 @@ class MemoryControl < LibRubyObject
end
end
-
class Sequencer < IfacePort
def cppClassName()
diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb
index bb054ec4e..f338f4e3f 100644
--- a/src/mem/ruby/config/defaults.rb
+++ b/src/mem/ruby/config/defaults.rb
@@ -167,6 +167,33 @@ class MOESI_CMP_directory_DMAController < DMAController
default_param :response_latency, Integer, 6
end
+## MOESI_CMP_token protocol
+
+class MOESI_CMP_token_L1CacheController < L1CacheController
+ default_param :l1_request_latency, Integer, 2
+ default_param :l1_response_latency, Integer, 2
+ default_param :retry_threshold, Integer, 1
+ default_param :fixed_timeout_latency, Integer, 300
+ default_param :dynamic_timeout_enabled, Boolean, true
+end
+
+class MOESI_CMP_token_L2CacheController < CacheController
+ default_param :l2_request_latency, Integer, 2
+ default_param :l2_response_latency, Integer, 2
+ default_param :filtering_enabled, Boolean, true
+end
+
+class MOESI_CMP_token_DirectoryController < DirectoryController
+ default_param :directory_latency, Integer, 6
+ default_param :distributed_persistent, Boolean, true
+ default_param :fixed_timeout_latency, Integer, 300
+end
+
+class MOESI_CMP_token_DMAController < DMAController
+ default_param :request_latency, Integer, 6
+ default_param :response_latency, Integer, 6
+end
+
## MOESI_hammer protocol
class MOESI_hammer_CacheController < L1CacheController
diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc
index 1e056f6e5..58b67ea60 100644
--- a/src/mem/ruby/system/PersistentTable.cc
+++ b/src/mem/ruby/system/PersistentTable.cc
@@ -27,44 +27,33 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "PersistentTable.hh"
-#include "NetDest.h"
-#include "Map.h"
-#include "Address.h"
-#include "AbstractChip.h"
-#include "util.h"
+#include "mem/ruby/system/PersistentTable.hh"
+#include "mem/gems_common/util.hh"
// randomize so that handoffs are not locality-aware
// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15};
// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-class PersistentTableEntry {
-public:
- NetDest m_starving;
- NetDest m_marked;
- NetDest m_request_to_write;
-};
-
-PersistentTable::PersistentTable(AbstractChip* chip_ptr, int version)
+PersistentTable::PersistentTable()
{
- m_chip_ptr = chip_ptr;
m_map_ptr = new Map<Address, PersistentTableEntry>;
- m_version = version;
}
PersistentTable::~PersistentTable()
{
delete m_map_ptr;
m_map_ptr = NULL;
- m_chip_ptr = NULL;
}
-void PersistentTable::persistentRequestLock(const Address& address, MachineID locker, AccessType type)
+void PersistentTable::persistentRequestLock(const Address& address,
+ MachineID locker,
+ AccessType type)
{
// if (locker == m_chip_ptr->getID() )
- // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker << " requesting lock for " << address << endl;
+ // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
+ // << " requesting lock for " << address << endl;
// MachineID locker = (MachineID) persistent_randomize[llocker];
@@ -79,7 +68,11 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo
m_map_ptr->add(address, entry);
} else {
PersistentTableEntry& entry = m_map_ptr->lookup(address);
- assert(!(entry.m_starving.isElement(locker))); // Make sure we're not already in the locked set
+
+ //
+ // Make sure we're not already in the locked set
+ //
+ assert(!(entry.m_starving.isElement(locker)));
entry.m_starving.add(locker);
if (type == AccessType_Write) {
@@ -89,17 +82,23 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo
}
}
-void PersistentTable::persistentRequestUnlock(const Address& address, MachineID unlocker)
+void PersistentTable::persistentRequestUnlock(const Address& address,
+ MachineID unlocker)
{
// if (unlocker == m_chip_ptr->getID() )
- // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker << " requesting unlock for " << address << endl;
+ // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
+ // << " requesting unlock for " << address << endl;
// MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
assert(address == line_address(address));
assert(m_map_ptr->exist(address));
PersistentTableEntry& entry = m_map_ptr->lookup(address);
- assert(entry.m_starving.isElement(unlocker)); // Make sure we're in the locked set
+
+ //
+ // Make sure we're in the locked set
+ //
+ assert(entry.m_starving.isElement(unlocker));
assert(entry.m_marked.isSubset(entry.m_starving));
entry.m_starving.remove(unlocker);
entry.m_marked.remove(unlocker);
@@ -113,13 +112,20 @@ void PersistentTable::persistentRequestUnlock(const Address& address, MachineID
}
}
-bool PersistentTable::okToIssueStarving(const Address& address) const
+bool PersistentTable::okToIssueStarving(const Address& address,
+ MachineID machId) const
{
assert(address == line_address(address));
if (!m_map_ptr->exist(address)) {
- return true; // No entry present
- } else if (m_map_ptr->lookup(address).m_starving.isElement( (MachineID) {MachineType_L1Cache, m_version})) {
- return false; // We can't issue another lockdown until are previous unlock has occurred
+ //
+ // No entry present
+ //
+ return true;
+ } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) {
+ //
+ // We can't issue another lockdown until are previous unlock has occurred
+ //
+ return false;
} else {
return (m_map_ptr->lookup(address).m_marked.isEmpty());
}
@@ -130,9 +136,7 @@ MachineID PersistentTable::findSmallest(const Address& address) const
assert(address == line_address(address));
assert(m_map_ptr->exist(address));
const PersistentTableEntry& entry = m_map_ptr->lookup(address);
- // cout << "Node " << m_chip_ptr->getID() << " returning " << persistent_randomize[entry.m_starving.smallestElement()] << " for findSmallest(" << address << ")" << endl;
- // return (MachineID) persistent_randomize[entry.m_starving.smallestElement()];
- return (MachineID) { MachineType_L1Cache, entry.m_starving.smallestElement() };
+ return entry.m_starving.smallestElement();
}
AccessType PersistentTable::typeOfSmallest(const Address& address) const
@@ -140,7 +144,7 @@ AccessType PersistentTable::typeOfSmallest(const Address& address) const
assert(address == line_address(address));
assert(m_map_ptr->exist(address));
const PersistentTableEntry& entry = m_map_ptr->lookup(address);
- if (entry.m_request_to_write.isElement((MachineID) {MachineType_L1Cache, entry.m_starving.smallestElement()})) {
+ if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) {
return AccessType_Write;
} else {
return AccessType_Read;
@@ -152,8 +156,16 @@ void PersistentTable::markEntries(const Address& address)
assert(address == line_address(address));
if (m_map_ptr->exist(address)) {
PersistentTableEntry& entry = m_map_ptr->lookup(address);
- assert(entry.m_marked.isEmpty()); // None should be marked
- entry.m_marked = entry.m_starving; // Mark all the nodes currently in the table
+
+ //
+ // None should be marked
+ //
+ assert(entry.m_marked.isEmpty());
+
+ //
+ // Mark all the nodes currently in the table
+ //
+ entry.m_marked = entry.m_starving;
}
}
@@ -177,7 +189,6 @@ int PersistentTable::countStarvingForAddress(const Address& address) const
int PersistentTable::countReadStarvingForAddress(const Address& address) const
{
- int count = 0;
if (m_map_ptr->exist(address)) {
PersistentTableEntry& entry = m_map_ptr->lookup(address);
return (entry.m_starving.count() - entry.m_request_to_write.count());
@@ -187,4 +198,7 @@ int PersistentTable::countReadStarvingForAddress(const Address& address) const
}
}
+void PersistentTable::print(ostream& out) const
+{
+}
diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh
index ab000843d..8cbb48817 100644
--- a/src/mem/ruby/system/PersistentTable.hh
+++ b/src/mem/ruby/system/PersistentTable.hh
@@ -30,20 +30,26 @@
#ifndef PersistentTable_H
#define PersistentTable_H
-#include "Global.h"
-#include "MachineID.h"
-#include "AccessType.h"
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Map.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/system/MachineID.hh"
+#include "mem/protocol/AccessType.hh"
+#include "mem/ruby/common/NetDest.hh"
-class AbstractChip;
+class PersistentTableEntry {
+public:
+ void print(ostream& out) const {}
-template <class KEY_TYPE, class VALUE_TYPE> class Map;
-class Address;
-class PersistentTableEntry;
+ NetDest m_starving;
+ NetDest m_marked;
+ NetDest m_request_to_write;
+};
class PersistentTable {
public:
// Constructors
- PersistentTable(AbstractChip* chip_ptr, int version);
+ PersistentTable();
// Destructor
~PersistentTable();
@@ -51,7 +57,7 @@ public:
// Public Methods
void persistentRequestLock(const Address& address, MachineID locker, AccessType type);
void persistentRequestUnlock(const Address& address, MachineID unlocker);
- bool okToIssueStarving(const Address& address) const;
+ bool okToIssueStarving(const Address& address, MachineID machID) const;
MachineID findSmallest(const Address& address) const;
AccessType typeOfSmallest(const Address& address) const;
void markEntries(const Address& address);
@@ -71,17 +77,12 @@ private:
// Data Members (m_prefix)
Map<Address, PersistentTableEntry>* m_map_ptr;
- AbstractChip* m_chip_ptr;
- int m_version;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const PersistentTable& obj);
-
// ******************* Definitions *******************
// Output operator definition
-extern inline
+extern inline
ostream& operator<<(ostream& out, const PersistentTable& obj)
{
obj.print(out);
@@ -89,4 +90,13 @@ ostream& operator<<(ostream& out, const PersistentTable& obj)
return out;
}
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const PersistentTableEntry& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
#endif //PersistentTable_H
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
index 496fce2fd..4ca1af114 100644
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -38,6 +38,7 @@ Source('DirectoryMemory.cc')
Source('CacheMemory.cc')
Source('MemoryControl.cc')
Source('MemoryNode.cc')
+Source('PersistentTable.cc')
Source('RubyPort.cc')
Source('Sequencer.cc', Werror=False)
Source('System.cc')