diff --git a/src/mem/ruby/system/RubySystem.hh b/src/mem/ruby/system/RubySystem.hh --- a/src/mem/ruby/system/RubySystem.hh +++ b/src/mem/ruby/system/RubySystem.hh @@ -44,8 +44,8 @@ #include "params/RubySystem.hh" #include "sim/clocked_object.hh" +class AbstractController; class Network; -class AbstractController; class RubySystem : public ClockedObject { @@ -55,12 +55,12 @@ public: RubyEvent(RubySystem* _ruby_system) { - m_ruby_system = _ruby_system; + m_ruby_system_ptr = _ruby_system; } private: void process(); - RubySystem* m_ruby_system; + RubySystem* m_ruby_system_ptr; }; friend class RubyEvent; @@ -70,10 +70,10 @@ ~RubySystem(); // config accessors - static int getRandomization() { return m_randomization; } - static uint32_t getMemorySizeBits() { return m_memory_size_bits; } - static bool getWarmupEnabled() { return m_warmup_enabled; } - static bool getCooldownEnabled() { return m_cooldown_enabled; } + int getRandomization() { return m_randomization; } + uint32_t getMemorySizeBits() { return m_memory_size_bits; } + bool getWarmupEnabled() { return m_warmup_enabled; } + bool getCooldownEnabled() { return m_cooldown_enabled; } uint32_t getBlockSizeBytes() { return m_block_size_bytes; } SimpleMemory *getPhysMem() { return m_phys_mem; } @@ -101,9 +101,14 @@ bool functionalRead(PacketPtr ptr); bool functionalWrite(PacketPtr ptr); + void incNumControllers(MachineType machine_type); + int getNumControllers(MachineType machine_type); + void registerNetwork(Network*); void registerAbstractController(AbstractController*); + uint64_t mapAddressToDirectoryVersion(Addr address); + bool eventQueueEmpty() { return eventq->empty(); } void enqueueRubyEvent(Tick tick) { @@ -128,36 +133,41 @@ private: // configuration parameters - static bool m_randomization; - const uint32_t m_block_size_bytes; - const uint32_t m_block_size_bits; - static uint32_t m_memory_size_bits; + bool m_randomization; + uint32_t m_block_size_bytes; + uint32_t m_block_size_bits; + uint32_t m_memory_size_bits; - static bool m_warmup_enabled; + bool m_warmup_enabled; + bool m_cooldown_enabled; static unsigned m_systems_to_warmup; - static bool m_cooldown_enabled; SimpleMemory *m_phys_mem; const bool m_access_backing_store; Network* m_network; std::vector m_abs_cntrl_vec; + std::vector m_num_controllers; Cycles m_start_cycle; public: Profiler* m_profiler; CacheRecorder *m_cache_recorder; std::vector > m_abstract_controls; + + int m_num_directories; + int m_num_directories_bits; + int m_numa_high_bit; }; class RubyStatsCallback : public Callback { private: - RubySystem *m_ruby_system; + RubySystem *m_ruby_system_ptr; public: virtual ~RubyStatsCallback() {} - RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {} - void process() { m_ruby_system->collateStats(); } + RubyStatsCallback(RubySystem *system) : m_ruby_system_ptr(system) {} + void process() { m_ruby_system_ptr->collateStats(); } }; #endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ diff --git a/src/mem/ruby/system/RubySystem.cc b/src/mem/ruby/system/RubySystem.cc --- a/src/mem/ruby/system/RubySystem.cc +++ b/src/mem/ruby/system/RubySystem.cc @@ -46,13 +46,7 @@ using namespace std; -bool RubySystem::m_randomization; -uint32_t RubySystem::m_memory_size_bits; -bool RubySystem::m_warmup_enabled = false; -// To look forward to allowing multiple RubySystem instances, track the number -// of RubySystems that need to be warmed up on checkpoint restore. unsigned RubySystem::m_systems_to_warmup = 0; -bool RubySystem::m_cooldown_enabled = false; RubySystem::RubySystem(const Params *p) : ClockedObject(p), m_block_size_bytes(p->block_size_bytes), @@ -62,6 +56,9 @@ { m_randomization = p->randomization; + m_warmup_enabled = false; + m_cooldown_enabled = false; + assert(isPowerOf2(m_block_size_bytes)); m_memory_size_bits = p->memory_size_bits; @@ -73,6 +70,11 @@ // Create the profiler m_profiler = new Profiler(p, this); m_phys_mem = p->phys_mem; + + // Initialize directory stats to zero + m_num_directories = 0; + m_num_directories_bits = 0; + m_numa_high_bit = 0; } void @@ -90,6 +92,18 @@ m_abstract_controls[id.getType()][id.getNum()] = cntrl; } +uint64_t +RubySystem::mapAddressToDirectoryVersion(Addr address) +{ + if (m_num_directories_bits == 0) + return 0; + + uint64_t ret = bitSelect(address, + m_numa_high_bit - m_num_directories_bits + 1, + m_numa_high_bit); + return ret; +} + RubySystem::~RubySystem() { delete m_network; @@ -249,7 +263,7 @@ // Aggregate the trace entries together into a single array uint8_t *raw_data = new uint8_t[4096]; uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, - 4096); + 4096); string cache_trace_file = name() + ".cache.gz"; writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size); @@ -388,11 +402,11 @@ void RubySystem::RubyEvent::process() { - if (RubySystem::getWarmupEnabled()) { - m_ruby_system->m_cache_recorder->enqueueNextFetchRequest( - m_ruby_system->m_block_size_bytes); - } else if (RubySystem::getCooldownEnabled()) { - m_ruby_system->m_cache_recorder->enqueueNextFlushRequest(); + if (m_ruby_system_ptr->getWarmupEnabled()) { + m_ruby_system_ptr->m_cache_recorder->enqueueNextFetchRequest( + m_ruby_system_ptr->m_block_size_bytes); + } else if (m_ruby_system_ptr->getCooldownEnabled()) { + m_ruby_system_ptr->m_cache_recorder->enqueueNextFlushRequest(); } } @@ -515,6 +529,26 @@ return true; } +void +RubySystem::incNumControllers(MachineType machine_type) +{ + if (m_num_controllers.size() <= machine_type) { + m_num_controllers.resize(machine_type + 1); + } + + m_num_controllers[machine_type]++; +} + +int +RubySystem::getNumControllers(MachineType machine_type) +{ + if (m_num_controllers.size() <= machine_type) { + m_num_controllers.resize(machine_type + 1); + } + + return m_num_controllers[machine_type]; +} + #ifdef CHECK_COHERENCE // This code will check for cases if the given cache block is exclusive in // one node and shared in another-- a coherence violation diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -147,6 +147,9 @@ Stats::Counter getIncompleteTimes(const MachineType t) const { return m_IncompleteTimes[t]; } + protected: + RubySystem *m_ruby_system_ptr; + private: void issueRequest(PacketPtr pkt, RubyRequestType type); diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -56,6 +56,7 @@ m_block_size_bits(floorLog2(m_block_size_bytes)), m_IncompleteTimes(MachineType_NUM), deadlockCheckEvent(this) { + m_ruby_system_ptr = p->ruby_system; m_outstanding_count = 0; m_instCache_ptr = p->icache; @@ -451,7 +452,7 @@ printAddress(request_address), total_latency); // update the data unless it is a non-data-carrying flush - if (RubySystem::getWarmupEnabled()) { + if (m_ruby_system_ptr->getWarmupEnabled()) { data.setData(pkt->getConstPtr(), offset_address, pkt->getSize()); } else if (!pkt->isFlush()) { @@ -486,15 +487,15 @@ delete srequest; - RubySystem *rs = m_ruby_system; - if (RubySystem::getWarmupEnabled()) { + if (m_ruby_system_ptr->getWarmupEnabled()) { assert(pkt->req); delete pkt->req; delete pkt; - rs->m_cache_recorder->enqueueNextFetchRequest(m_block_size_bytes); - } else if (RubySystem::getCooldownEnabled()) { + m_ruby_system_ptr->m_cache_recorder->\ + enqueueNextFetchRequest(m_block_size_bytes); + } else if (m_ruby_system_ptr->getCooldownEnabled()) { delete pkt; - rs->m_cache_recorder->enqueueNextFlushRequest(); + m_ruby_system_ptr->m_cache_recorder->enqueueNextFlushRequest(); } else { ruby_hit_callback(pkt); } @@ -612,8 +613,8 @@ nullptr : pkt->getPtr(), pkt->getSize(), pc, secondary_type, RubyAccessMode_Supervisor, pkt, - m_block_size_bits, PrefetchBit_No, - proc_id); + m_ruby_system_ptr, m_block_size_bits, + PrefetchBit_No, proc_id); DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %#x %s\n", curTick(), m_version, "Seq", "Begin", "", "", @@ -671,7 +672,7 @@ Sequencer::checkCoherence(Addr addr) { #ifdef CHECK_COHERENCE - m_ruby_system->checkGlobalCoherenceInvariant(addr); + m_ruby_system_ptr->checkGlobalCoherenceInvariant(addr); #endif } diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py --- a/src/mem/slicc/ast/EnqueueStatementAST.py +++ b/src/mem/slicc/ast/EnqueueStatementAST.py @@ -56,7 +56,8 @@ # Declare message code("std::shared_ptr<${{msg_type.c_ident}}> out_msg = "\ - "std::make_shared<${{msg_type.c_ident}}>(clockEdge());") + "std::make_shared<${{msg_type.c_ident}}>(clockEdge(), "\ + "m_ruby_system_ptr);") # The other statements t = self.statements.generate(code, None) diff --git a/src/mem/slicc/ast/NewExprAST.py b/src/mem/slicc/ast/NewExprAST.py --- a/src/mem/slicc/ast/NewExprAST.py +++ b/src/mem/slicc/ast/NewExprAST.py @@ -28,9 +28,10 @@ from slicc.ast.ExprAST import ExprAST class NewExprAST(ExprAST): - def __init__(self, slicc, type_ast): + def __init__(self, slicc, type_ast, args): super(NewExprAST, self).__init__(slicc) self.type_ast = type_ast + self.args = args def __repr__(self): return "[NewExprAST: %r]" % self.type_ast @@ -42,6 +43,9 @@ def generate(self, code): type = self.type_ast.type fix = code.nofix() - code("new ${{type.c_ident}}") + if self.args: + code("new ${{type.c_ident}}(${{self.args}})") + else: + code("new ${{type.c_ident}}") code.fix(fix) return type diff --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py --- a/src/mem/slicc/ast/ObjDeclAST.py +++ b/src/mem/slicc/ast/ObjDeclAST.py @@ -59,6 +59,8 @@ c_code = "m_recycle_latency" elif self.ident == "block_size_bits": c_code = "m_block_size_bits" + elif self.ident == "ruby_system": + c_code = "m_ruby_system_ptr" else: c_code = "(*m_%s_ptr)" % (self.ident) diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -655,9 +655,13 @@ "aexpr : ident '(' exprs ')'" p[0] = ast.FuncCallExprAST(self, p[1], p[3]) - def p_expr__new(self, p): + def p_expr__new0(self, p): "aexpr : NEW type" - p[0] = ast.NewExprAST(self, p[2]) + p[0] = ast.NewExprAST(self, p[2], []) + + def p_expr__new1(self, p): + "aexpr : NEW type '(' STRING ')'" + p[0] = ast.NewExprAST(self, p[2], p[4]) def p_expr__null(self, p): "aexpr : OOD" diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -46,6 +46,7 @@ "MessageBuffer": "MessageBuffer", "DMASequencer": "DMASequencer", "Prefetcher":"Prefetcher", + "RubySystem":"RubySystem", "Cycles":"Cycles", } @@ -291,7 +292,7 @@ public: typedef ${c_ident}Params Params; $c_ident(const Params *p); - static int getNumControllers(); + int getNumControllers(); void init(); MessageBuffer *getMandatoryQueue() const; @@ -487,8 +488,6 @@ return new $c_ident(this); } -int $c_ident::m_num_controllers = 0; - // for adding information to the protocol debug trace stringstream ${ident}_transitionComment; @@ -504,7 +503,8 @@ { m_machineID.type = MachineType_${ident}; m_machineID.num = m_version; - m_num_controllers++; + + m_ruby_system_ptr->incNumControllers(MachineType_$ident); m_in_ports = $num_in_ports; ''') @@ -540,7 +540,8 @@ $c_ident::initNetQueues() { MachineType machine_type = string_to_MachineType("${{self.ident}}"); - int base M5_VAR_USED = MachineType_base_number(machine_type); + int base M5_VAR_USED = MachineType_base_number(machine_type, + m_ruby_system_ptr); ''') code.indent() @@ -714,7 +715,7 @@ int $c_ident::getNumControllers() { - return m_num_controllers; + return m_ruby_system_ptr->getNumControllers(MachineType_$ident); } MessageBuffer* diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -63,6 +63,9 @@ interface = self["interface"] if interface in ("Message"): self["message"] = "yes" + elif interface in ("AbstractCacheEntry") or \ + interface in ("AbstractEntry"): + self["entry"] = "yes" # FIXME - all of the following id comparisons are fragile hacks if self.ident in ("CacheMemory"): @@ -83,6 +86,9 @@ if self.ident == "Prefetcher": self["prefetcher"] = "yes" + if self.ident == "DirEntry": + self["dir_entry"] = "yes" + self.isMachineType = (ident == "MachineType") self.isStateDecl = ("state_decl" in self) @@ -100,6 +106,9 @@ def isMessage(self): return "message" in self @property + def isEntry(self): + return "entry" in self + @property def isBuffer(self): return "buffer" in self @property @@ -203,17 +212,32 @@ code('#include "mem/protocol/$0.hh"', self["interface"]) parent = " : public %s" % self["interface"] + # only when RubySystem is an argument + if self.isMessage or self.isEntry or \ + 'tbe' in self or 'dir_entry' in self: + code(''' +class RubySystem; +''') + code(''' $klass ${{self.c_ident}}$parent { public: - ${{self.c_ident}} ''', klass="class") + code('RubySystem *m_ruby_system_ptr;') + + # ******** Preferred constructor ******** + code(''' + ${{self.c_ident}} +''') if self.isMessage: - code('(Tick curTime) : %s(curTime) {' % self["interface"]) + code('(Tick curTime, RubySystem *m_ruby_system_ptr) : %s(curTime, m_ruby_system_ptr) {' \ + % self["interface"]) + elif self.isEntry or 'tbe' in self or 'dir_entry' in self: + code('(RubySystem *m_ruby_system_ptr) : m_ruby_system_ptr(m_ruby_system_ptr) {') else: - code('()\n\t\t{') + code('()\n\t{') code.indent() if not self.isGlobal: @@ -232,6 +256,10 @@ code.dedent() code('}') + # ******** Empty constructor ******** + if 'tbe' in self or 'dir_entry' in self: + code(' ${{self.c_ident}}() {}') + # ******** Copy constructor ******** if not self.isGlobal: code('${{self.c_ident}}(const ${{self.c_ident}}&other)') @@ -256,14 +284,14 @@ params = ', '.join(params) if self.isMessage: - params = "const Tick curTime, " + params + params = "const Tick curTime, RubySystem *rs," + params code('${{self.c_ident}}($params)') # Call superclass constructor if "interface" in self: if self.isMessage: - code(' : ${{self["interface"]}}(curTime)') + code(' : ${{self["interface"]}}(curTime, rs)') else: code(' : ${{self["interface"]}}()') @@ -396,7 +424,6 @@ #include #include "mem/protocol/${{self.c_ident}}.hh" -#include "mem/ruby/system/RubySystem.hh" using namespace std; ''') @@ -453,6 +480,8 @@ code('#include "base/misc.hh"') code('#include "mem/ruby/common/Address.hh"') code('#include "mem/ruby/common/TypeDefines.hh"') + code() + code('class RubySystem;') code('struct MachineID;') code(''' @@ -494,8 +523,8 @@ code(''' int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); MachineType ${{self.c_ident}}_from_base_level(int); -int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); -int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); +int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj, RubySystem *rs); +int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj, RubySystem *rs); ''') for enum in self.enums.itervalues(): @@ -539,6 +568,7 @@ #include "base/misc.hh" #include "mem/protocol/${{self.c_ident}}.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; @@ -695,7 +725,7 @@ * \\return the base number of components for each machine */ int -${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) +${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj, RubySystem *rs) { int base = 0; switch(obj) { @@ -707,7 +737,8 @@ for enum in reversed(self.enums.values()): # Check if there is a defined machine with this type if enum.get("Primary"): - code(' base += ${{enum.ident}}_Controller::getNumControllers();') + code(' base += rs->getNumControllers('\ + 'MachineType_${{enum.ident}});') else: code(' base += 0;') code(' case ${{self.c_ident}}_${{enum.ident}}:') @@ -726,7 +757,7 @@ * \\return the total number of components for each machine */ int -${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) +${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj, RubySystem *rs) { switch(obj) { ''') @@ -735,7 +766,8 @@ for enum in self.enums.itervalues(): code('case ${{self.c_ident}}_${{enum.ident}}:') if enum.get("Primary"): - code('return ${{enum.ident}}_Controller::getNumControllers();') + code('return rs->getNumControllers('\ + 'MachineType_${{enum.ident}});') else: code('return 0;') diff --git a/src/mem/ruby/structures/TBETable.hh b/src/mem/ruby/structures/TBETable.hh --- a/src/mem/ruby/structures/TBETable.hh +++ b/src/mem/ruby/structures/TBETable.hh @@ -33,13 +33,14 @@ #include #include "mem/ruby/common/Address.hh" +#include "mem/ruby/system/RubySystem.hh" template class TBETable { public: - TBETable(int number_of_TBEs) - : m_number_of_TBEs(number_of_TBEs) + TBETable(int number_of_TBEs, RubySystem *rs) + : m_number_of_TBEs(number_of_TBEs), m_ruby_system_ptr(rs) { } @@ -67,6 +68,7 @@ private: const int m_number_of_TBEs; + RubySystem *m_ruby_system_ptr; }; template @@ -92,7 +94,7 @@ { assert(!isPresent(address)); assert(m_map.size() < m_number_of_TBEs); - m_map[address] = new ENTRY(); + m_map[address] = new ENTRY(m_ruby_system_ptr); } template diff --git a/src/mem/ruby/structures/TimerTable.cc b/src/mem/ruby/structures/TimerTable.cc --- a/src/mem/ruby/structures/TimerTable.cc +++ b/src/mem/ruby/structures/TimerTable.cc @@ -35,7 +35,7 @@ { m_consumer_ptr = NULL; m_next_valid = false; - m_next_address = 0; + m_next_address = Addr(0); } bool diff --git a/src/mem/ruby/structures/WireBuffer.hh b/src/mem/ruby/structures/WireBuffer.hh --- a/src/mem/ruby/structures/WireBuffer.hh +++ b/src/mem/ruby/structures/WireBuffer.hh @@ -94,6 +94,10 @@ // queues where memory requests live std::vector m_message_queue; + + protected: + RubySystem * m_ruby_system_ptr; + }; std::ostream& operator<<(std::ostream& out, const WireBuffer& obj); diff --git a/src/mem/ruby/structures/WireBuffer.py b/src/mem/ruby/structures/WireBuffer.py --- a/src/mem/ruby/structures/WireBuffer.py +++ b/src/mem/ruby/structures/WireBuffer.py @@ -34,4 +34,4 @@ type = 'RubyWireBuffer' cxx_class = 'WireBuffer' cxx_header = "mem/ruby/structures/WireBuffer.hh" - ruby_system = Param.RubySystem(Parent.any, "") + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") diff --git a/src/mem/ruby/system/CacheRecorder.cc b/src/mem/ruby/system/CacheRecorder.cc --- a/src/mem/ruby/system/CacheRecorder.cc +++ b/src/mem/ruby/system/CacheRecorder.cc @@ -147,8 +147,7 @@ rec->m_data_address = data_addr; rec->m_pc_address = pc_addr; rec->m_type = type; - memcpy(rec->m_data, data.getData(0, m_block_size_bytes), - m_block_size_bytes); + memcpy(rec->m_data, data.getData(0, m_block_size_bytes), m_block_size_bytes); m_records.push_back(rec); } diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -61,14 +61,14 @@ typedef DMASequencerParams Params; DMASequencer(const Params *); void init() override; - RubySystem *m_ruby_system; + RubySystem *m_ruby_system_ptr; public: class MemSlavePort : public QueuedSlavePort { private: RespPacketQueue queue; - RubySystem* m_ruby_system; + RubySystem* m_ruby_system_ptr; bool access_backing_store; public: diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -1,3 +1,4 @@ + /* * Copyright (c) 2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -38,7 +39,7 @@ #include "sim/system.hh" DMASequencer::DMASequencer(const Params *p) - : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version), + : MemObject(p), m_ruby_system_ptr(p->ruby_system), m_version(p->version), m_controller(NULL), m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester), slave_port(csprintf("%s.slave", name()), this, 0, p->ruby_system, @@ -78,7 +79,8 @@ DMASequencer *_port, PortID id, RubySystem* _ruby_system, bool _access_backing_store) : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), - m_ruby_system(_ruby_system), access_backing_store(_access_backing_store) + m_ruby_system_ptr(_ruby_system), + access_backing_store(_access_backing_store) { DPRINTF(RubyDma, "Created slave memport on ruby sequencer %s\n", _name); } @@ -191,7 +193,7 @@ // turn packet around to go back to requester if response expected if (access_backing_store) { - m_ruby_system->getPhysMem()->access(pkt); + m_ruby_system_ptr->getPhysMem()->access(pkt); } else if (needsResponse) { pkt->makeResponse(); } @@ -200,7 +202,7 @@ DPRINTF(RubyDma, "Sending packet back over port\n"); // send next cycle DMASequencer *seq = static_cast(&owner); - RubySystem *rs = seq->m_ruby_system; + RubySystem *rs = seq->m_ruby_system_ptr; schedTimingResp(pkt, curTick() + rs->clockPeriod()); } else { delete pkt; @@ -240,7 +242,7 @@ active_request.pkt = pkt; std::shared_ptr msg = - std::make_shared(clockEdge()); + std::make_shared(clockEdge(), m_ruby_system_ptr); msg->getPhysicalAddress() = paddr; msg->getLineAddress() = makeLineAddress(msg->getPhysicalAddress(), m_block_size_bits); @@ -280,7 +282,7 @@ } std::shared_ptr msg = - std::make_shared(clockEdge()); + std::make_shared(clockEdge(), m_ruby_system_ptr); msg->getPhysicalAddress() = active_request.start_paddr + active_request.bytes_completed; diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -178,7 +178,7 @@ */ bool recvTimingResp(PacketPtr pkt, PortID master_port_id); - RubySystem *m_ruby_system; + RubySystem *m_ruby_system_ptr; uint32_t m_version; AbstractController* m_controller; MessageBuffer* m_mandatory_q_ptr; diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -1,3 +1,4 @@ + /* * Copyright (c) 2012-2013 ARM Limited * All rights reserved. @@ -51,7 +52,7 @@ #include "sim/system.hh" RubyPort::RubyPort(const Params *p) - : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version), + : MemObject(p), m_ruby_system_ptr(p->ruby_system), m_version(p->version), m_controller(NULL), m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester), system(p->system), pioMasterPort(csprintf("%s.pio-master-port", name()), this), @@ -171,7 +172,7 @@ // send next cycle rp->pioSlavePort.schedTimingResp( - pkt, curTick() + rp->m_ruby_system->clockPeriod()); + pkt, curTick() + rp->m_ruby_system_ptr->clockPeriod()); return true; } @@ -193,8 +194,8 @@ pkt->getAddr(), port->name()); // attempt to send the response in the next cycle - RubyPort *rp = static_cast(&owner); - port->schedTimingResp(pkt, curTick() + rp->m_ruby_system->clockPeriod()); + RubySystem *rs = static_cast(&owner)->m_ruby_system_ptr; + port->schedTimingResp(pkt, curTick() + rs->clockPeriod()); return true; } @@ -226,6 +227,7 @@ DPRINTF(RubyPort, "Timing request for address %#x on port %d\n", pkt->getAddr(), id); RubyPort *ruby_port = static_cast(&owner); + RubySystem *rs M5_VAR_USED = ruby_port->m_ruby_system_ptr; if (pkt->memInhibitAsserted()) panic("RubyPort should never see an inhibited request\n"); @@ -242,7 +244,7 @@ pkt->pushSenderState(new SenderState(this)); // send next cycle - RubySystem *rs = ruby_port->m_ruby_system; + RubySystem *rs = ruby_port->m_ruby_system_ptr; ruby_port->memMasterPort.schedTimingReq(pkt, curTick() + rs->clockPeriod()); return true; @@ -284,7 +286,7 @@ DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); RubyPort *rp M5_VAR_USED = static_cast(&owner); - RubySystem *rs = rp->m_ruby_system; + RubySystem *rs = rp->m_ruby_system_ptr; // Check for pio requests and directly send them to the dedicated // pio port. @@ -451,7 +453,7 @@ DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); RubyPort *ruby_port = static_cast(&owner); - RubySystem *rs = ruby_port->m_ruby_system; + RubySystem *rs = ruby_port->m_ruby_system_ptr; if (accessPhysMem) { rs->getPhysMem()->access(pkt); } else if (needsResponse) { @@ -502,7 +504,7 @@ // Allocate the invalidate request and packet on the stack, as it is // assumed they will not be modified or deleted by receivers. // TODO: should this really be using funcMasterId? - Request request(address, m_ruby_system->getBlockSizeBytes(), 0, + Request request(address, m_ruby_system_ptr->getBlockSizeBytes(), 0, Request::funcMasterId); // Use a single packet to signal all snooping ports of the invalidation. // This assumes that snooping ports do NOT modify the packet/request diff --git a/src/mem/protocol/MESI_Two_Level-L2cache.sm b/src/mem/protocol/MESI_Two_Level-L2cache.sm --- a/src/mem/protocol/MESI_Two_Level-L2cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L2cache.sm @@ -146,7 +146,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); Tick cyclesToTicks(Cycles c); @@ -400,7 +400,8 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -425,7 +426,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:MEMORY_DATA; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; @@ -437,7 +439,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -448,7 +451,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:MEMORY_DATA; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; @@ -683,7 +687,7 @@ action(qq_allocateL2CacheBlock, "\q", desc="Set L2 cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(L2cache.allocate(address, new Entry)); + set_cache_entry(L2cache.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MESI_Two_Level-dir.sm b/src/mem/protocol/MESI_Two_Level-dir.sm --- a/src/mem/protocol/MESI_Two_Level-dir.sm +++ b/src/mem/protocol/MESI_Two_Level-dir.sm @@ -96,7 +96,8 @@ // ** OBJECTS ** - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", + constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); Tick cyclesToTicks(Cycles c); @@ -112,7 +113,7 @@ } dir_entry := static_cast(Entry, "pointer", - directory.allocate(addr, new Entry)); + directory.allocate(addr, new Entry("m_ruby_system_ptr"))); return dir_entry; } diff --git a/src/mem/protocol/MESI_Two_Level-dma.sm b/src/mem/protocol/MESI_Two_Level-dma.sm --- a/src/mem/protocol/MESI_Two_Level-dma.sm +++ b/src/mem/protocol/MESI_Two_Level-dma.sm @@ -114,7 +114,8 @@ out_msg.Type := CoherenceRequestType:DMA_READ; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -127,7 +128,8 @@ out_msg.Type := CoherenceRequestType:DMA_WRITE; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -100,7 +100,7 @@ // STRUCTURES - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; // PROTOTYPES Tick clockEdge(); @@ -272,7 +272,7 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, ruby_system)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -283,7 +283,7 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUTX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, ruby_system)); out_msg.DataBlk := cache_entry.DataBlk; out_msg.MessageSize := MessageSizeType:Data; } @@ -320,7 +320,7 @@ action(i_allocateL1CacheBlock, "i", desc="Allocate a cache block") { if (is_valid(cache_entry)) { } else { - set_cache_entry(cacheMemory.allocate(address, new Entry)); + set_cache_entry(cacheMemory.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -106,7 +106,7 @@ } // ** OBJECTS ** - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); Cycles ticksToCycles(Tick t); @@ -122,7 +122,7 @@ } dir_entry := static_cast(Entry, "pointer", - directory.allocate(addr, new Entry)); + directory.allocate(addr, new Entry("m_ruby_system_ptr"))); return dir_entry; } diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -117,7 +117,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -132,7 +133,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm @@ -140,7 +140,7 @@ void set_tbe(TBE b); void unset_tbe(); - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; TimerTable useTimerTable; int l2_select_low_bit, default="getBlockSizeBits()"; @@ -881,13 +881,13 @@ action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if ((is_invalid(cache_entry))) { - set_cache_entry(L1Dcache.allocate(address, new Entry)); + set_cache_entry(L1Dcache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") { if ((is_invalid(cache_entry))) { - set_cache_entry(L1Icache.allocate(address, new Entry)); + set_cache_entry(L1Icache.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm @@ -224,9 +224,9 @@ bool isTagPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; PerfectCacheMemory localDirectory, template="", - constructor="m_block_size_bits"; + constructor="m_block_size_bits, m_ruby_system_ptr"; Tick clockEdge(); Tick cyclesToTicks(Cycles c); @@ -731,7 +731,8 @@ out_msg.Type := CoherenceRequestType:GETS; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -744,7 +745,8 @@ out_msg.Type := CoherenceRequestType:GETX; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -756,7 +758,8 @@ out_msg.Type := CoherenceRequestType:PUTX; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -767,7 +770,8 @@ out_msg.Type := CoherenceRequestType:PUTO; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -779,7 +783,8 @@ out_msg.Type := CoherenceRequestType:PUTO_SHARERS; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -1148,7 +1153,8 @@ enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; @@ -1160,7 +1166,8 @@ enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; @@ -1433,7 +1440,8 @@ out_msg.addr := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA; @@ -1504,7 +1512,7 @@ } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - set_cache_entry(L2cache.allocate(address, new Entry)); + set_cache_entry(L2cache.allocate(address, new Entry("m_ruby_system_ptr"))); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { @@ -1562,7 +1570,8 @@ enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:DMA_ACK; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm @@ -117,7 +117,7 @@ } // ** OBJECTS ** - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); Tick cyclesToTicks(Cycles c); @@ -132,7 +132,7 @@ } dir_entry := static_cast(Entry, "pointer", - directory.allocate(addr, new Entry)); + directory.allocate(addr, new Entry("m_ruby_system_ptr"))); return dir_entry; } diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm --- a/src/mem/protocol/MOESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm @@ -71,7 +71,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; State cur_state; Tick clockEdge(); @@ -159,7 +159,8 @@ out_msg.Type := CoherenceRequestType:DMA_READ; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; @@ -174,7 +175,8 @@ out_msg.Type := CoherenceRequestType:DMA_WRITE; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; @@ -207,7 +209,8 @@ enqueue(respToDirectory_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -194,12 +194,12 @@ void wakeUpBuffers(Addr a); Cycles curCycle(); - TBETable L1_TBEs, template="", constructor="m_number_of_TBEs"; + TBETable L1_TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; bool starving, default="false"; int l2_select_low_bit, default="getBlockSizeBits()"; - PersistentTable persistentTable; + PersistentTable persistentTable, constructor="m_ruby_system_ptr"; TimerTable useTimerTable; TimerTable reissueTimerTable; @@ -766,7 +766,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := tbe.Prefetch; out_msg.AccessMode := tbe.AccessMode; @@ -888,7 +889,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := tbe.Prefetch; out_msg.AccessMode := tbe.AccessMode; @@ -992,7 +994,8 @@ out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Tokens := in_msg.Tokens; out_msg.MessageSize := in_msg.MessageSize; out_msg.DataBlk := in_msg.DataBlk; @@ -1458,7 +1461,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } starving := false; @@ -1531,14 +1535,14 @@ action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if (is_valid(cache_entry)) { } else { - set_cache_entry(L1Dcache.allocate(address, new Entry)); + set_cache_entry(L1Dcache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { if (is_valid(cache_entry)) { } else { - set_cache_entry(L1Icache.allocate(address, new Entry)); + set_cache_entry(L1Icache.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -146,9 +146,9 @@ int countReadStarvingForAddress(Addr); } - PersistentTable persistentTable; + PersistentTable persistentTable, constructor="m_ruby_system_ptr"; PerfectCacheMemory localDirectory, template="", - constructor="m_block_size_bits"; + constructor="m_block_size_bits, m_ruby_system_ptr"; Tick clockEdge(); void set_cache_entry(AbstractCacheEntry b); @@ -523,7 +523,8 @@ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; out_msg.Prefetch := in_msg.Prefetch; @@ -542,7 +543,8 @@ out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Tokens := in_msg.Tokens; out_msg.MessageSize := in_msg.MessageSize; out_msg.DataBlk := in_msg.DataBlk; @@ -558,7 +560,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Tokens := cache_entry.Tokens; out_msg.MessageSize := MessageSizeType:Writeback_Control; } @@ -571,7 +574,8 @@ enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) { out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Tokens := cache_entry.Tokens; out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; @@ -974,7 +978,7 @@ } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - set_cache_entry(L2cache.allocate(address, new Entry)); + set_cache_entry(L2cache.allocate(address, new Entry("m_ruby_system_ptr"))); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -164,10 +164,10 @@ // ** OBJECTS ** - PersistentTable persistentTable; + PersistentTable persistentTable, constructor="m_ruby_system_ptr"; TimerTable reissueTimerTable; - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; bool starving, default="false"; int l2_select_low_bit, default="getBlockSizeBits()"; @@ -185,7 +185,7 @@ } dir_entry := static_cast(Entry, "pointer", - directory.allocate(addr, new Entry)); + directory.allocate(addr, new Entry("m_ruby_system_ptr"))); return dir_entry; } @@ -475,7 +475,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := PrefetchBit:No; out_msg.AccessMode := RubyAccessMode:Supervisor; @@ -543,7 +544,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := PrefetchBit:No; out_msg.AccessMode := RubyAccessMode:Supervisor; @@ -724,7 +726,8 @@ MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } starving := false; diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm --- a/src/mem/protocol/MOESI_CMP_token-dma.sm +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -118,7 +118,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -133,7 +134,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -178,7 +178,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); void set_cache_entry(AbstractCacheEntry b); @@ -389,7 +389,7 @@ } else if (in_msg.Type == CoherenceRequestType:MERGED_GETS) { trigger(Event:Merged_GETS, in_msg.addr, cache_entry, tbe); } else if (in_msg.Type == CoherenceRequestType:GETS) { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { if (is_valid(cache_entry)) { if (IsAtomicAccessed(cache_entry) && no_mig_atomic) { trigger(Event:Other_GETS_No_Mig, in_msg.addr, cache_entry, tbe); @@ -554,12 +554,13 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); // One from each other cache (n-1) plus the memory (+1) - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); } } @@ -569,30 +570,32 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); // One from each other cache (n-1) plus the memory (+1) - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); } } action(b_issueGETXIfMoreThanOne, "bo", desc="Issue GETX") { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { enqueue(requestNetwork_out, RequestMsg, issue_latency) { assert(is_valid(tbe)); out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); } } // One from each other cache (n-1) plus the memory (+1) - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); } action(bf_issueGETF, "bf", desc="Issue GETF") { @@ -601,12 +604,13 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETF; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); // One from each other cache (n-1) plus the memory (+1) - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); } } @@ -621,7 +625,7 @@ out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -644,7 +648,7 @@ out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -661,7 +665,8 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUT; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -671,7 +676,8 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUTF; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -687,7 +693,7 @@ out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -711,7 +717,7 @@ out_msg.Dirty := cache_entry.Dirty; DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -735,7 +741,7 @@ out_msg.Dirty := tbe.Dirty; DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -758,7 +764,7 @@ out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; @@ -778,7 +784,7 @@ out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; DPRINTF(RubySlicc, "%s\n", out_msg.DataBlk); - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; @@ -826,7 +832,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -836,7 +843,8 @@ out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCKM; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -848,7 +856,8 @@ out_msg.Type := CoherenceResponseType:UNBLOCKS; out_msg.Sender := machineID; out_msg.CurOwner := tbe.CurOwner; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -1068,7 +1077,7 @@ out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -1093,7 +1102,7 @@ out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (in_msg.DirectedProbe) { - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); } else { out_msg.Acks := 2; } @@ -1116,7 +1125,7 @@ DPRINTF(RubySlicc, "%s\n", out_msg.Destination); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; - out_msg.Acks := machineCount(MachineType:L1Cache); + out_msg.Acks := machineCount(MachineType:L1Cache, ruby_system); out_msg.SilentAcks := in_msg.SilentAcks; out_msg.MessageSize := MessageSizeType:Response_Data; out_msg.InitialRequestTime := in_msg.InitialRequestTime; @@ -1130,7 +1139,8 @@ assert(is_valid(tbe)); out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { out_msg.Type := CoherenceResponseType:WB_DIRTY; @@ -1161,7 +1171,8 @@ assert(is_valid(tbe)); out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { @@ -1227,18 +1238,18 @@ action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(L1Dcache.allocate(address, new Entry)); + set_cache_entry(L1Dcache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(L1Icache.allocate(address, new Entry)); + set_cache_entry(L1Icache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - set_cache_entry(L2cache.allocate(address, new Entry)); + set_cache_entry(L2cache.allocate(address, new Entry("m_ruby_system_ptr"))); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -196,7 +196,7 @@ Set fwd_set; - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Entry getDirectoryEntry(Addr addr), return_by_pointer="yes" { Entry dir_entry := static_cast(Entry, "pointer", directory[addr]); @@ -206,7 +206,7 @@ } dir_entry := static_cast(Entry, "pointer", - directory.allocate(addr, new Entry)); + directory.allocate(addr, new Entry("m_ruby_system_ptr"))); return dir_entry; } @@ -516,7 +516,8 @@ action(oc_sendBlockAck, "oc", desc="Send block ack to the owner") { peek(requestQueue_in, RequestMsg) { - if (((probe_filter_enabled || full_bit_dir_enabled) && (in_msg.Requestor == cache_entry.Owner)) || machineCount(MachineType:L1Cache) == 1) { + if (((probe_filter_enabled || full_bit_dir_enabled) && (in_msg.Requestor == cache_entry.Owner)) || + machineCount(MachineType:L1Cache, ruby_system) == 1) { enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) { out_msg.addr := address; out_msg.Type := CoherenceRequestType:BLOCK_ACK; @@ -543,9 +544,9 @@ action(pfa_probeFilterAllocate, "pfa", desc="Allocate ProbeFilterEntry") { if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { - set_cache_entry(probeFilter.allocate(address, new PfEntry)); + set_cache_entry(probeFilter.allocate(address, new PfEntry("m_ruby_system_ptr"))); cache_entry.Owner := in_msg.Requestor; - cache_entry.Sharers.setSize(machineCount(MachineType:L1Cache)); + cache_entry.Sharers.setSize(machineCount(MachineType:L1Cache, ruby_system)); } } } @@ -587,7 +588,7 @@ // // One ack for each last-level cache // - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); // // Assume initially that the caches store a clean copy and that memory // will provide the data @@ -602,7 +603,7 @@ assert(is_valid(cache_entry)); tbe.NumPendingMsgs := cache_entry.Sharers.count(); } else { - tbe.NumPendingMsgs := machineCount(MachineType:L1Cache); + tbe.NumPendingMsgs := machineCount(MachineType:L1Cache, ruby_system); } } @@ -629,10 +630,10 @@ fwd_set.remove(machineIDToNodeID(in_msg.Requestor)); if (fwd_set.count() > 0) { tbe.Acks := 1; - tbe.SilentAcks := machineCount(MachineType:L1Cache) - fwd_set.count(); + tbe.SilentAcks := machineCount(MachineType:L1Cache, ruby_system) - fwd_set.count(); tbe.SilentAcks := tbe.SilentAcks - 1; } else { - tbe.Acks := machineCount(MachineType:L1Cache); + tbe.Acks := machineCount(MachineType:L1Cache, ruby_system); tbe.SilentAcks := 0; } } else { @@ -644,7 +645,7 @@ action(saa_setAcksToAllIfPF, "saa", desc="Non-forwarded request, set the ack amount to all") { assert(is_valid(tbe)); if (probe_filter_enabled || full_bit_dir_enabled) { - tbe.Acks := machineCount(MachineType:L1Cache); + tbe.Acks := machineCount(MachineType:L1Cache, ruby_system); tbe.SilentAcks := 0; } else { tbe.Acks := 1; @@ -860,7 +861,7 @@ action(fn_forwardRequestIfNecessary, "fn", desc="Forward requests if necessary") { assert(is_valid(tbe)); - if ((machineCount(MachineType:L1Cache) > 1) && (tbe.Acks <= 1)) { + if ((machineCount(MachineType:L1Cache, ruby_system) > 1) && (tbe.Acks <= 1)) { if (full_bit_dir_enabled) { assert(is_valid(cache_entry)); peek(requestQueue_in, RequestMsg) { @@ -898,7 +899,7 @@ } action(ia_invalidateAllRequest, "ia", desc="invalidate all copies") { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { if (full_bit_dir_enabled) { assert(cache_entry.Sharers.count() > 0); peek(requestQueue_in, RequestMsg) { @@ -923,7 +924,7 @@ } action(io_invalidateOwnerRequest, "io", desc="invalidate all copies") { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) { assert(is_valid(cache_entry)); out_msg.addr := address; @@ -937,7 +938,7 @@ } action(fb_forwardRequestBcast, "fb", desc="Forward requests to all nodes") { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { peek(requestQueue_in, RequestMsg) { if (full_bit_dir_enabled) { fwd_set := cache_entry.Sharers; @@ -951,7 +952,7 @@ out_msg.MessageSize := MessageSizeType:Multicast_Control; out_msg.InitialRequestTime := in_msg.InitialRequestTime; out_msg.ForwardRequestTime := curCycle(); - out_msg.SilentAcks := machineCount(MachineType:L1Cache) - fwd_set.count(); + out_msg.SilentAcks := machineCount(MachineType:L1Cache, ruby_system) - fwd_set.count(); out_msg.SilentAcks := out_msg.SilentAcks - 1; } } @@ -986,7 +987,7 @@ } action(fr_forwardMergeReadRequestsToOwner, "frr", desc="Forward coalesced read request to owner") { - assert(machineCount(MachineType:L1Cache) > 1); + assert(machineCount(MachineType:L1Cache, ruby_system) > 1); // // Fixme! The unblock network should not stall on the forward network. Add a trigger queue to // decouple the two. @@ -1010,7 +1011,7 @@ } action(fc_forwardRequestConditionalOwner, "fc", desc="Forward request to one or more nodes") { - assert(machineCount(MachineType:L1Cache) > 1); + assert(machineCount(MachineType:L1Cache, ruby_system) > 1); if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { enqueue(forwardNetwork_out, RequestMsg, from_memory_controller_latency) { @@ -1042,7 +1043,7 @@ } action(nofc_forwardRequestConditionalOwner, "nofc", desc="Forward request to one or more nodes if the requestor is not the owner") { - if (machineCount(MachineType:L1Cache) > 1) { + if (machineCount(MachineType:L1Cache, ruby_system) > 1) { if (probe_filter_enabled || full_bit_dir_enabled) { peek(requestQueue_in, RequestMsg) { diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm --- a/src/mem/protocol/MOESI_hammer-dma.sm +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -115,7 +115,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -130,7 +131,8 @@ out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/Network_test-cache.sm b/src/mem/protocol/Network_test-cache.sm --- a/src/mem/protocol/Network_test-cache.sm +++ b/src/mem/protocol/Network_test-cache.sm @@ -148,8 +148,9 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); - //out_msg.Destination := broadcast(MachineType:Directory); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); + //out_msg.Destination := broadcast(MachineType:Directory, ruby_system); out_msg.MessageSize := MessageSizeType:Control; } } @@ -159,7 +160,8 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -169,7 +171,8 @@ out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(map_Address_to_Directory(address, + ruby_system)); out_msg.MessageSize := MessageSizeType:Data; } } diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -29,15 +29,14 @@ // Mapping functions -int machineCount(MachineType machType); -MachineID mapAddressToRange(Addr addr, MachineType type, - int low, int high); -MachineID mapAddressToRange(Addr addr, MachineType type, - int low, int high, NodeID n); -NetDest broadcast(MachineType type); +int machineCount(MachineType machType, RubySystem *rs); +MachineID mapAddressToRange(Addr addr, MachineType type, int low, int high); +MachineID mapAddressToRange(Addr addr, MachineType type, int low, int high, + NodeID n); +NetDest broadcast(MachineType type, RubySystem *rs); MachineID map_Address_to_DMA(Addr addr); -MachineID map_Address_to_Directory(Addr addr); -NodeID map_Address_to_DirectoryNode(Addr addr); +MachineID map_Address_to_Directory(Addr addr, RubySystem *rs); +NodeID map_Address_to_DirectoryNode(Addr addr, RubySystem *rs); NodeID machineIDToNodeID(MachineID machID); NodeID machineIDToVersion(MachineID machID); MachineType machineIDToMachineType(MachineID machID); diff --git a/src/mem/protocol/RubySlicc_Defines.sm b/src/mem/protocol/RubySlicc_Defines.sm --- a/src/mem/protocol/RubySlicc_Defines.sm +++ b/src/mem/protocol/RubySlicc_Defines.sm @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// Hack, no node object since base class has them +// Hack, below members not in machine definitions since base class has them NodeID version; MachineID machineID; NodeID clusterID; diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm --- a/src/mem/protocol/RubySlicc_Exports.sm +++ b/src/mem/protocol/RubySlicc_Exports.sm @@ -38,6 +38,9 @@ external_type(Addr, primitive="yes"); external_type(Cycles, primitive="yes", default="Cycles(0)"); external_type(Tick, primitive="yes", default="0"); +external_type(RubySystem, primitive="yes"); + +RubySystem * ruby_system; structure(DataBlock, external = "yes", desc="..."){ void clear(); diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -69,7 +69,8 @@ NodeID smallestElement(); } -structure (NetDest, external = "yes", non_obj="yes") { +structure (NetDest, external = "yes", default = "NetDest(m_ruby_system_ptr)", + non_obj="yes") { void setSize(int); void setSize(int, int); void add(NodeID); diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc --- a/src/mem/ruby/common/DataBlock.cc +++ b/src/mem/ruby/common/DataBlock.cc @@ -27,7 +27,8 @@ */ #include "mem/ruby/common/DataBlock.hh" -#include "mem/ruby/system/RubySystem.hh" + +#include DataBlock::DataBlock() : m_data(nullptr), m_alloc(false), m_block_size_bytes(0) diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -35,19 +35,19 @@ #include "mem/ruby/common/Set.hh" #include "mem/ruby/common/MachineID.hh" +class RubySystem; + // NetDest specifies the network destination of a Message class NetDest { public: // Constructors // creates and empty set - NetDest(); - explicit NetDest(int bit_size); - + NetDest() = default; + NetDest(RubySystem *rs); + NetDest(const NetDest&) = default; NetDest& operator=(const Set& obj); - - ~NetDest() - { } + ~NetDest() = default; void add(MachineID newElement); void addNetDest(const NetDest& netDest); @@ -92,6 +92,9 @@ void print(std::ostream& out) const; + protected: + RubySystem *m_ruby_system_ptr; + private: // returns a value >= MachineType_base_level("this machine") // and < MachineType_base_level("next highest machine") diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc --- a/src/mem/ruby/common/NetDest.cc +++ b/src/mem/ruby/common/NetDest.cc @@ -28,11 +28,14 @@ #include +#include "base/compiler.hh" #include "mem/ruby/common/NetDest.hh" +#include "mem/ruby/system/RubySystem.hh" -NetDest::NetDest() +NetDest::NetDest(RubySystem *rs) { - resize(); + m_ruby_system_ptr = rs; + resize(); } void @@ -54,9 +57,12 @@ void NetDest::setNetDest(MachineType machine, const Set& set) { + MachineType next_machine M5_VAR_USED = (MachineType)(machine + 1); + // assure that there is only one set of destinations for this machine - assert(MachineType_base_level((MachineType)(machine + 1)) - + assert(MachineType_base_level(next_machine) - MachineType_base_level(machine) == 1); + m_bits[MachineType_base_level(machine)] = set; } @@ -95,7 +101,8 @@ void NetDest::broadcast(MachineType machineType) { - for (NodeID i = 0; i < MachineType_base_count(machineType); i++) { + int mach_count = MachineType_base_count(machineType, m_ruby_system_ptr); + for (NodeID i = 0; i < mach_count; i++) { MachineID mach = {machineType, i}; add(mach); } @@ -110,7 +117,8 @@ 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)) { - int id = MachineType_base_number((MachineType)i) + j; + int id = MachineType_base_number((MachineType)i, + m_ruby_system_ptr) + j; dest.push_back((NodeID)id); } } @@ -152,9 +160,10 @@ MachineID NetDest::smallestElement(MachineType machine) const { - int size = m_bits[MachineType_base_level(machine)].getSize(); + int mach_level = MachineType_base_level(machine); + int size = m_bits[mach_level].getSize(); for (NodeID j = 0; j < size; j++) { - if (m_bits[MachineType_base_level(machine)].isElement(j)) { + if (m_bits[mach_level].isElement(j)) { MachineID mach = {machine, j}; return mach; } @@ -192,7 +201,7 @@ NetDest::OR(const NetDest& orNetDest) const { assert(m_bits.size() == orNetDest.getSize()); - NetDest result; + NetDest result(m_ruby_system_ptr); for (int i = 0; i < m_bits.size(); i++) { result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]); } @@ -204,7 +213,7 @@ NetDest::AND(const NetDest& andNetDest) const { assert(m_bits.size() == andNetDest.getSize()); - NetDest result; + NetDest result(m_ruby_system_ptr); for (int i = 0; i < m_bits.size(); i++) { result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]); } @@ -250,7 +259,8 @@ assert(m_bits.size() == MachineType_NUM); for (int i = 0; i < m_bits.size(); i++) { - m_bits[i].setSize(MachineType_base_count((MachineType)i)); + m_bits[i].setSize(MachineType_base_count((MachineType)i, + m_ruby_system_ptr)); } } diff --git a/src/mem/ruby/filters/BulkBloomFilter.cc b/src/mem/ruby/filters/BulkBloomFilter.cc --- a/src/mem/ruby/filters/BulkBloomFilter.cc +++ b/src/mem/ruby/filters/BulkBloomFilter.cc @@ -31,7 +31,6 @@ #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/BulkBloomFilter.hh" -#include "mem/ruby/system/RubySystem.hh" using namespace std; diff --git a/src/mem/ruby/network/BasicRouter.hh b/src/mem/ruby/network/BasicRouter.hh --- a/src/mem/ruby/network/BasicRouter.hh +++ b/src/mem/ruby/network/BasicRouter.hh @@ -36,6 +36,8 @@ #include "params/BasicRouter.hh" #include "sim/clocked_object.hh" +class RubySystem; + class BasicRouter : public ClockedObject { public: @@ -51,6 +53,8 @@ // ID in relation to other routers in the system // uint32_t m_id; + + RubySystem *m_ruby_system_ptr; }; inline std::ostream& diff --git a/src/mem/ruby/network/BasicRouter.cc b/src/mem/ruby/network/BasicRouter.cc --- a/src/mem/ruby/network/BasicRouter.cc +++ b/src/mem/ruby/network/BasicRouter.cc @@ -32,6 +32,7 @@ : ClockedObject(p) { m_id = p->router_id; + m_ruby_system_ptr = p->ruby_system; } void diff --git a/src/mem/ruby/network/BasicRouter.py b/src/mem/ruby/network/BasicRouter.py --- a/src/mem/ruby/network/BasicRouter.py +++ b/src/mem/ruby/network/BasicRouter.py @@ -28,9 +28,11 @@ # Brad Beckmann from m5.params import * +from m5.proxy import * from ClockedObject import ClockedObject class BasicRouter(ClockedObject): type = 'BasicRouter' cxx_header = "mem/ruby/network/BasicRouter.hh" + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") router_id = Param.Int("ID in relation to other routers") diff --git a/src/mem/ruby/network/MessageBuffer.hh b/src/mem/ruby/network/MessageBuffer.hh --- a/src/mem/ruby/network/MessageBuffer.hh +++ b/src/mem/ruby/network/MessageBuffer.hh @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -159,6 +158,8 @@ int m_input_link_id; int m_vnet_id; + + RubySystem *m_ruby_system_ptr; }; Tick random_time(); diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc --- a/src/mem/ruby/network/MessageBuffer.cc +++ b/src/mem/ruby/network/MessageBuffer.cc @@ -44,7 +44,7 @@ m_max_size(p->buffer_size), m_time_last_time_size_checked(0), m_time_last_time_enqueue(0), m_time_last_time_pop(0), m_last_arrival_time(0), m_strict_fifo(p->ordered), - m_randomization(p->randomization) + m_randomization(p->randomization), m_ruby_system_ptr(p->ruby_system) { m_msg_counter = 0; m_consumer = NULL; @@ -151,7 +151,7 @@ assert(delta > 0); Tick arrival_time = 0; - if (!RubySystem::getRandomization() || !m_randomization) { + if (!m_ruby_system_ptr->getRandomization() || !m_randomization) { // No randomization arrival_time = current_time + delta; } else { @@ -178,7 +178,7 @@ } // If running a cache trace, don't worry about the last arrival checks - if (!RubySystem::getWarmupEnabled()) { + if (!m_ruby_system_ptr->getWarmupEnabled()) { m_last_arrival_time = arrival_time; } diff --git a/src/mem/ruby/network/MessageBuffer.py b/src/mem/ruby/network/MessageBuffer.py --- a/src/mem/ruby/network/MessageBuffer.py +++ b/src/mem/ruby/network/MessageBuffer.py @@ -38,6 +38,7 @@ buffer_size = Param.Unsigned(0, "Maximum number of entries to buffer \ (0 allows infinite entries)") randomization = Param.Bool(False, "") + ruby_system = Param.RubySystem(Parent.any, "") master = MasterPort("Master port to MessageBuffer receiver") slave = SlavePort("Slave port from MessageBuffer sender") diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh --- a/src/mem/ruby/network/Network.hh +++ b/src/mem/ruby/network/Network.hh @@ -54,6 +54,7 @@ class NetDest; class MessageBuffer; +class RubySystem; class Network : public ClockedObject { @@ -101,6 +102,8 @@ virtual uint32_t functionalWrite(PacketPtr pkt, uint32_t block_size_bits) { fatal("Functional write not implemented.\n"); } + RubySystem *m_ruby_system_ptr; + protected: // Private copy constructor and assignment operator Network(const Network& obj); diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -44,12 +44,12 @@ // Total nodes/controllers in network // Must make sure this is called after the State Machine constructors - m_nodes = MachineType_base_number(MachineType_NUM); + m_nodes = MachineType_base_number(MachineType_NUM, p->ruby_system); assert(m_nodes != 0); assert(m_virtual_networks != 0); - m_topology_ptr = new Topology(p->routers.size(), p->ext_links, - p->int_links); + m_topology_ptr = new Topology(p->ruby_system, p->routers.size(), + p->ext_links, p->int_links); // Allocate to and from queues // Queues that are getting messages from protocol @@ -61,6 +61,8 @@ m_ordered.resize(m_virtual_networks); m_vnet_type_names.resize(m_virtual_networks); + m_ruby_system_ptr = p->ruby_system; + for (int i = 0; i < m_virtual_networks; i++) { m_ordered[i] = false; } diff --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py --- a/src/mem/ruby/network/Network.py +++ b/src/mem/ruby/network/Network.py @@ -28,6 +28,7 @@ # Brad Beckmann from m5.params import * +from m5.proxy import * from ClockedObject import ClockedObject from BasicLink import BasicLink @@ -47,7 +48,7 @@ block_size_bytes = Param.UInt32(64, "block size used for data messages.") control_msg_size = Param.UInt32(8, "") - ruby_system = Param.RubySystem("") + ruby_system = Param.RubySystem(Parent.any, "") routers = VectorParam.BasicRouter("Network routers") netifs = VectorParam.ClockedObject("Network Interfaces") diff --git a/src/mem/ruby/network/Topology.hh b/src/mem/ruby/network/Topology.hh --- a/src/mem/ruby/network/Topology.hh +++ b/src/mem/ruby/network/Topology.hh @@ -50,10 +50,11 @@ class NetDest; class Network; +class RubySystem; typedef std::vector > Matrix; -struct LinkEntry +struct LinkEntry { BasicLink *link; LinkDirection direction; @@ -64,7 +65,8 @@ class Topology { public: - Topology(uint32_t num_routers, const std::vector &ext_links, + Topology(RubySystem *rs, uint32_t num_routers, + const std::vector &ext_links, const std::vector &int_links); uint32_t numSwitches() const { return m_number_of_switches; } @@ -87,9 +89,10 @@ bool link_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final, const Matrix &weights, const Matrix &dist); - NetDest shortest_path_to_node(SwitchID src, SwitchID next, + NetDest shortest_path_to_node(RubySystem *rs, SwitchID src, SwitchID next, const Matrix &weights, const Matrix &dist); + RubySystem *m_ruby_system_ptr; const uint32_t m_nodes; const uint32_t m_number_of_switches; diff --git a/src/mem/ruby/network/Topology.cc b/src/mem/ruby/network/Topology.cc --- a/src/mem/ruby/network/Topology.cc +++ b/src/mem/ruby/network/Topology.cc @@ -34,6 +34,7 @@ #include "mem/ruby/network/BasicLink.hh" #include "mem/ruby/network/Topology.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; @@ -46,18 +47,19 @@ // the second m_nodes set of SwitchIDs represent the the output queues // of the network. -Topology::Topology(uint32_t num_routers, +Topology::Topology(RubySystem *rs, uint32_t num_routers, const vector &ext_links, const vector &int_links) - : m_nodes(ext_links.size()), m_number_of_switches(num_routers), - m_ext_link_vector(ext_links), m_int_link_vector(int_links) + : m_ruby_system_ptr(rs), m_nodes(ext_links.size()), + m_number_of_switches(num_routers), m_ext_link_vector(ext_links), + m_int_link_vector(int_links) { // Total nodes/controllers in network assert(m_nodes > 1); // analyze both the internal and external links, create data structures // Note that the python created links are bi-directional, but that the - // topology and networks utilize uni-directional links. Thus each + // topology and networks utilize uni-directional links. Thus each // BasicLink is converted to two calls to add link, on for each direction for (vector::const_iterator i = ext_links.begin(); i != ext_links.end(); ++i) { @@ -65,7 +67,8 @@ AbstractController *abs_cntrl = ext_link->params()->ext_node; BasicRouter *router = ext_link->params()->int_node; - int machine_base_idx = MachineType_base_number(abs_cntrl->getType()); + int machine_base_idx = MachineType_base_number(abs_cntrl->getType(), + rs); int ext_idx1 = machine_base_idx + abs_cntrl->getVersion(); int ext_idx2 = ext_idx1 + m_nodes; int int_idx = router->params()->router_id + 2*m_nodes; @@ -106,7 +109,7 @@ i != m_link_map.end(); ++i) { std::pair src_dest = (*i).first; max_switch_id = max(max_switch_id, src_dest.first); - max_switch_id = max(max_switch_id, src_dest.second); + max_switch_id = max(max_switch_id, src_dest.second); } // Initialize weight, latency, and inter switched vectors @@ -133,7 +136,7 @@ component_latencies[src][dst] = link->m_latency; topology_weights[src][dst] = link->m_weight; } - + // Walk topology and hookup the links Matrix dist = shortest_path(topology_weights, component_latencies, component_inter_switches); @@ -143,7 +146,8 @@ int weight = topology_weights[i][j]; if (weight > 0 && weight != INFINITE_LATENCY) { NetDest destination_set = - shortest_path_to_node(i, j, topology_weights, dist); + shortest_path_to_node(m_ruby_system_ptr, i, j, + topology_weights, dist); makeLink(net, i, j, destination_set); } } @@ -151,12 +155,12 @@ } void -Topology::addLink(SwitchID src, SwitchID dest, BasicLink* link, +Topology::addLink(SwitchID src, SwitchID dest, BasicLink* link, LinkDirection dir) { assert(src <= m_number_of_switches+m_nodes+m_nodes); assert(dest <= m_number_of_switches+m_nodes+m_nodes); - + std::pair src_dest_pair; LinkEntry link_entry; @@ -176,7 +180,7 @@ assert(src >= 2 * m_nodes || dest >= 2 * m_nodes); std::pair src_dest; - LinkEntry link_entry; + LinkEntry link_entry; if (src < m_nodes) { src_dest.first = src; @@ -261,23 +265,24 @@ } NetDest -Topology::shortest_path_to_node(SwitchID src, SwitchID next, +Topology::shortest_path_to_node(RubySystem *rs, SwitchID src, SwitchID next, const Matrix &weights, const Matrix &dist) { - NetDest result; + NetDest result(rs); int d = 0; int machines; int max_machines; machines = MachineType_NUM; - max_machines = MachineType_base_number(MachineType_NUM); + max_machines = MachineType_base_number(MachineType_NUM, rs); for (int m = 0; m < machines; m++) { - for (NodeID i = 0; i < MachineType_base_count((MachineType)m); i++) { + int mach_count = MachineType_base_count((MachineType)m, rs); + for (NodeID i = 0; i < mach_count; i++) { // we use "d+max_machines" below since the "destination" // switches for the machines are numbered - // [MachineType_base_number(MachineType_NUM)... - // 2*MachineType_base_number(MachineType_NUM)-1] for the + // [MachineType_base_number(MachineType_NUM, rs)... + // 2*MachineType_base_number(MachineType_NUM, rs)-1] for the // component network if (link_is_shortest_path_to_node(src, next, d + max_machines, weights, dist)) { diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc @@ -122,6 +122,8 @@ Message *net_msg_ptr = msg_ptr.get(); NetDest net_msg_dest = net_msg_ptr->getDestination(); + RubySystem *rs = m_net_ptr->m_ruby_system_ptr; + // gets all the destinations associated with this message. vector dest_nodes = net_msg_dest.getAllDest(); @@ -144,14 +146,17 @@ Message *new_net_msg_ptr = new_msg_ptr.get(); if (dest_nodes.size() > 1) { - NetDest personal_dest; + NetDest personal_dest(rs); for (int m = 0; m < (int) MachineType_NUM; m++) { - if ((destID >= MachineType_base_number((MachineType) m)) && - destID < MachineType_base_number((MachineType) (m+1))) { + MachineType machine = (MachineType) m; + MachineType next_machine = (MachineType)(m + 1); + if (destID >= MachineType_base_number(machine, rs) && + destID < MachineType_base_number(next_machine, rs)) + { // calculating the NetDest associated with this destID personal_dest.clear(); personal_dest.add((MachineID) {(MachineType) m, (destID - - MachineType_base_number((MachineType) m))}); + MachineType_base_number((MachineType) m, rs))}); new_net_msg_ptr->getDestination() = personal_dest; break; } diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc @@ -116,6 +116,8 @@ Message *net_msg_ptr = msg_ptr.get(); NetDest net_msg_dest = net_msg_ptr->getDestination(); + RubySystem *rs = m_net_ptr->m_ruby_system_ptr; + // get all the destinations associated with this message. vector dest_nodes = net_msg_dest.getAllDest(); @@ -138,14 +140,17 @@ Message *new_net_msg_ptr = new_msg_ptr.get(); if (dest_nodes.size() > 1) { - NetDest personal_dest; + NetDest personal_dest(rs); for (int m = 0; m < (int) MachineType_NUM; m++) { - if ((destID >= MachineType_base_number((MachineType) m)) && - destID < MachineType_base_number((MachineType) (m+1))) { + MachineType machine = (MachineType) m; + MachineType next_machine = (MachineType)(m + 1); + if (destID >= MachineType_base_number(machine, rs) && + destID < MachineType_base_number(next_machine, rs)) + { // calculating the NetDest associated with this destID personal_dest.clear(); personal_dest.add((MachineID) {(MachineType) m, (destID - - MachineType_base_number((MachineType) m))}); + MachineType_base_number((MachineType) m, rs))}); new_net_msg_ptr->getDestination() = personal_dest; break; } diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh --- a/src/mem/ruby/network/simple/Throttle.hh +++ b/src/mem/ruby/network/simple/Throttle.hh @@ -103,7 +103,7 @@ Cycles m_link_latency; int m_wakeups_wo_switch; int m_endpoint_bandwidth; - RubySystem *m_ruby_system; + RubySystem *m_ruby_system_ptr; // Statistical variables Stats::Scalar m_link_utilization; diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc --- a/src/mem/ruby/network/simple/Throttle.cc +++ b/src/mem/ruby/network/simple/Throttle.cc @@ -51,7 +51,7 @@ int link_bandwidth_multiplier, int endpoint_bandwidth, Switch *em) : Consumer(em), m_switch_id(sID), m_switch(em), m_node(node), - m_ruby_system(rs) + m_ruby_system_ptr(rs) { m_vnets = 0; @@ -113,7 +113,7 @@ DPRINTF(RubyNetwork, "throttle: %d my bw %d bw spent " "enqueueing net msg %d time: %lld.\n", m_node, getLinkBandwidth(), m_units_remaining[vnet], - m_ruby_system->curCycle()); + m_ruby_system_ptr->curCycle()); // Move the message in->dequeue(current_time); @@ -232,8 +232,8 @@ void Throttle::collateStats() { - double time_delta = double(m_ruby_system->curCycle() - - m_ruby_system->getStartCycle()); + double time_delta = double(m_ruby_system_ptr->curCycle() - + m_ruby_system_ptr->getStartCycle()); m_link_utilization = 100.0 * m_link_utilization_proxy / time_delta; } diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -67,8 +67,6 @@ Profiler(const RubySystemParams *params, RubySystem *rs); ~Profiler(); - RubySystem *m_ruby_system; - void wakeup(); void regStats(const std::string &name); void collateStats(); @@ -82,6 +80,8 @@ bool getHotLines() const { return m_hot_lines; } bool getAllInstructions() const { return m_all_instructions; } + RubySystem *m_ruby_system_ptr; + private: // Private copy constructor and assignment operator Profiler(const Profiler& obj); diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -61,7 +61,8 @@ using m5::stl_helpers::operator<<; Profiler::Profiler(const RubySystemParams *p, RubySystem *rs) - : m_ruby_system(rs), m_hot_lines(p->hot_lines), + : m_ruby_system_ptr(rs), + m_hot_lines(p->hot_lines), m_all_instructions(p->all_instructions), m_num_vnets(p->number_of_virtual_networks) { @@ -251,8 +252,8 @@ for (uint32_t i = 0; i < MachineType_NUM; i++) { for (map::iterator it = - m_ruby_system->m_abstract_controls[i].begin(); - it != m_ruby_system->m_abstract_controls[i].end(); ++it) { + m_ruby_system_ptr->m_abstract_controls[i].begin(); + it != m_ruby_system_ptr->m_abstract_controls[i].end(); ++it) { AbstractController *ctr = (*it).second; delayHistogram.add(ctr->getDelayHist()); @@ -265,8 +266,8 @@ for (uint32_t i = 0; i < MachineType_NUM; i++) { for (map::iterator it = - m_ruby_system->m_abstract_controls[i].begin(); - it != m_ruby_system->m_abstract_controls[i].end(); ++it) { + m_ruby_system_ptr->m_abstract_controls[i].begin(); + it != m_ruby_system_ptr->m_abstract_controls[i].end(); ++it) { AbstractController *ctr = (*it).second; Sequencer *seq = ctr->getSequencer(); @@ -278,8 +279,8 @@ for (uint32_t i = 0; i < MachineType_NUM; i++) { for (map::iterator it = - m_ruby_system->m_abstract_controls[i].begin(); - it != m_ruby_system->m_abstract_controls[i].end(); ++it) { + m_ruby_system_ptr->m_abstract_controls[i].begin(); + it != m_ruby_system_ptr->m_abstract_controls[i].end(); ++it) { AbstractController *ctr = (*it).second; Sequencer *seq = ctr->getSequencer(); diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -139,6 +139,7 @@ const NodeID m_version; MachineID m_machineID; const NodeID m_clusterID; + RubySystem *m_ruby_system_ptr; // MasterID used by some components of gem5. const MasterID m_masterId; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -37,6 +37,7 @@ AbstractController::AbstractController(const Params *p) : MemObject(p), Consumer(this), m_version(p->version), m_clusterID(p->cluster_id), + m_ruby_system_ptr(p->ruby_system), m_masterId(p->system->getMasterId(name())), m_is_blocking(false), m_block_size_bytes(p->block_size_bytes), m_block_size_bits(floorLog2(m_block_size_bytes)), @@ -46,13 +47,12 @@ memoryPort(csprintf("%s.memory", name()), this, "") { assert(isPowerOf2(m_block_size_bytes)); - } void AbstractController::init() { - params()->ruby_system->registerAbstractController(this); + m_ruby_system_ptr->registerAbstractController(this); m_delayHistogram.init(10); uint32_t size = Network::getNumberOfVirtualNetworks(); for (uint32_t i = 0; i < size; i++) { @@ -219,7 +219,7 @@ pkt->pushSenderState(s); // Use functional rather than timing accesses during warmup - if (RubySystem::getWarmupEnabled()) { + if (m_ruby_system_ptr->getWarmupEnabled()) { memoryPort.sendFunctional(pkt); recvTimingResp(pkt); return; @@ -242,7 +242,7 @@ pkt->pushSenderState(s); // Use functional rather than timing accesses during warmup - if (RubySystem::getWarmupEnabled()) { + if (m_ruby_system_ptr->getWarmupEnabled()) { memoryPort.sendFunctional(pkt); recvTimingResp(pkt); return; @@ -299,7 +299,8 @@ assert(getMemoryQueue()); assert(pkt->isResponse()); - std::shared_ptr msg = std::make_shared(clockEdge()); + std::shared_ptr msg = std::make_shared(clockEdge(), + m_ruby_system_ptr); (*msg).m_DataBlk.alloc(m_block_size_bytes); (*msg).m_addr = pkt->getAddr(); (*msg).m_Sender = m_machineID; diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py --- a/src/mem/ruby/slicc_interface/Controller.py +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -47,7 +47,7 @@ recycle_latency = Param.Cycles(10, "") number_of_TBEs = Param.Int(256, "") - ruby_system = Param.RubySystem("") + ruby_system = Param.RubySystem(Parent.any, "") memory = MasterPort("Port for attaching a memory controller") system = Param.System(Parent.any, "system object parameter") diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -39,12 +39,14 @@ class Message; typedef std::shared_ptr MsgPtr; +class RubySystem; class Message { public: - Message(Tick curTime) - : m_time(curTime), + Message(Tick curTime, RubySystem *rs) + : m_ruby_system(rs), + m_time(curTime), m_LastEnqueueTime(curTime), m_DelayedTicks(0), m_msg_counter(0) { } @@ -105,6 +107,9 @@ int getVnet() const { return vnet; } void setVnet(int net) { vnet = net; } + protected: + RubySystem *m_ruby_system; + private: const Tick m_time; Tick m_LastEnqueueTime; // my last enqueue time diff --git a/src/mem/ruby/slicc_interface/RubyRequest.hh b/src/mem/ruby/slicc_interface/RubyRequest.hh --- a/src/mem/ruby/slicc_interface/RubyRequest.hh +++ b/src/mem/ruby/slicc_interface/RubyRequest.hh @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 2009 Mark D. Hill and David A. Wood * All rights reserved. * @@ -53,9 +53,9 @@ RubyRequest(Tick curTime, uint64_t _paddr, uint8_t* _data, int _len, uint64_t _pc, RubyRequestType _type, RubyAccessMode _access_mode, - PacketPtr _pkt, uint32_t block_size_bits, + PacketPtr _pkt, RubySystem *rs, uint32_t block_size_bits, PrefetchBit _pb = PrefetchBit_No, ContextID _proc_id = 100) - : Message(curTime), + : Message(curTime, rs), m_PhysicalAddress(_paddr), m_Type(_type), m_ProgramCounter(_pc), @@ -69,7 +69,7 @@ m_LineAddress = makeLineAddress(m_PhysicalAddress, block_size_bits); } - RubyRequest(Tick curTime) : Message(curTime) {} + RubyRequest(Tick curTime, RubySystem *rs) : Message(curTime, rs) {} MsgPtr clone() const { return std::shared_ptr(new RubyRequest(*this)); } diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -34,30 +34,31 @@ #include "mem/ruby/common/MachineID.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/structures/DirectoryMemory.hh" +#include "mem/ruby/system/RubySystem.hh" // used to determine the home directory // returns a value between 0 and total_directories_within_the_system inline NodeID -map_Address_to_DirectoryNode(Addr addr) +map_Address_to_DirectoryNode(Addr addr, RubySystem *rs) { - return DirectoryMemory::mapAddressToDirectoryVersion(addr); + return rs->mapAddressToDirectoryVersion(addr); } // used to determine the home directory // returns a value between 0 and total_directories_within_the_system inline MachineID -map_Address_to_Directory(Addr addr) +map_Address_to_Directory(Addr addr, RubySystem *rs) { MachineID mach = - {MachineType_Directory, map_Address_to_DirectoryNode(addr)}; + {MachineType_Directory, map_Address_to_DirectoryNode(addr, rs)}; return mach; } inline NetDest -broadcast(MachineType type) +broadcast(MachineType type, RubySystem *rs) { - NetDest dest; - for (NodeID i = 0; i < MachineType_base_count(type); i++) { + NetDest dest(rs); + for (NodeID i = 0; i < MachineType_base_count(type, rs); i++) { MachineID mach = {type, i}; dest.add(mach); } @@ -65,8 +66,8 @@ } inline MachineID -mapAddressToRange(Addr addr, MachineType type, int low_bit, - int num_bits, int cluster_id = 0) +mapAddressToRange(Addr addr, MachineType type, int low_bit, int num_bits, + int cluster_id = 0) { MachineID mach = {type, 0}; if (num_bits == 0) @@ -90,9 +91,9 @@ } inline int -machineCount(MachineType machType) +machineCount(MachineType machType, RubySystem *rs) { - return MachineType_base_count(machType); + return MachineType_base_count(machType, rs); } inline MachineID diff --git a/src/mem/ruby/structures/BankedArray.hh b/src/mem/ruby/structures/BankedArray.hh --- a/src/mem/ruby/structures/BankedArray.hh +++ b/src/mem/ruby/structures/BankedArray.hh @@ -45,7 +45,7 @@ Cycles accessLatency; unsigned int bankBits; unsigned int startIndexBit; - RubySystem *m_ruby_system; + RubySystem *m_ruby_system_ptr; class AccessRecord { diff --git a/src/mem/ruby/structures/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc --- a/src/mem/ruby/structures/BankedArray.cc +++ b/src/mem/ruby/structures/BankedArray.cc @@ -35,7 +35,7 @@ BankedArray::BankedArray(unsigned int banks, Cycles accessLatency, unsigned int startIndexBit, RubySystem *rs) - : m_ruby_system(rs) + : m_ruby_system_ptr(rs) { this->banks = banks; this->accessLatency = accessLatency; @@ -87,7 +87,7 @@ busyBanks[bank].idx = idx; busyBanks[bank].startAccess = curTick(); busyBanks[bank].endAccess = curTick() + - (accessLatency-1) * m_ruby_system->clockPeriod(); + (accessLatency-1) * m_ruby_system_ptr->clockPeriod(); } unsigned int diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh --- a/src/mem/ruby/structures/CacheMemory.hh +++ b/src/mem/ruby/structures/CacheMemory.hh @@ -149,6 +149,9 @@ int getNumBlocks() const { return m_cache_num_sets * m_cache_assoc; } Addr getAddressAtIdx(int idx) const; + protected: + RubySystem *m_ruby_system_ptr; + private: // convert a Address to its location in the cache int64_t addressToCacheSet(Addr address) const; diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -61,6 +61,7 @@ m_block_size_bytes(p->block_size_bytes), m_block_size_bits(floorLog2(m_block_size_bytes)) { + m_ruby_system_ptr = p->ruby_system; m_cache_size = p->size; m_cache_assoc = p->assoc; m_replacementPolicy_ptr = p->replacement_policy; diff --git a/src/mem/ruby/structures/DirectoryMemory.hh b/src/mem/ruby/structures/DirectoryMemory.hh --- a/src/mem/ruby/structures/DirectoryMemory.hh +++ b/src/mem/ruby/structures/DirectoryMemory.hh @@ -48,7 +48,6 @@ void init(); uint64_t mapAddressToLocalIdx(Addr address); - static uint64_t mapAddressToDirectoryVersion(Addr address); uint64_t getSize() { return m_size_bytes; } @@ -64,7 +63,6 @@ DirectoryMemory(const DirectoryMemory& obj); DirectoryMemory& operator=(const DirectoryMemory& obj); - private: const int m_version; AbstractEntry **m_entries; @@ -76,9 +74,7 @@ uint64_t m_size_bits; uint64_t m_num_entries; - static int m_num_directories; - static int m_num_directories_bits; - static int m_numa_high_bit; + RubySystem *m_ruby_system_ptr; }; inline std::ostream& diff --git a/src/mem/ruby/structures/DirectoryMemory.cc b/src/mem/ruby/structures/DirectoryMemory.cc --- a/src/mem/ruby/structures/DirectoryMemory.cc +++ b/src/mem/ruby/structures/DirectoryMemory.cc @@ -35,18 +35,15 @@ using namespace std; -int DirectoryMemory::m_num_directories = 0; -int DirectoryMemory::m_num_directories_bits = 0; -int DirectoryMemory::m_numa_high_bit = 0; - DirectoryMemory::DirectoryMemory(const Params *p) : SimObject(p), m_version(p->version), - m_block_size_bytes(p->block_size_bytes), m_size_bytes(p->size) + m_block_size_bytes(p->block_size_bytes), m_size_bytes(p->size), + m_ruby_system_ptr(p->ruby_system) { m_size_bits = floorLog2(m_size_bytes); m_block_size_bits = floorLog2(m_block_size_bytes); m_num_entries = 0; - m_numa_high_bit = p->numa_high_bit; + m_ruby_system_ptr->m_numa_high_bit = p->numa_high_bit; } void @@ -57,13 +54,13 @@ for (int i = 0; i < m_num_entries; i++) m_entries[i] = NULL; - m_num_directories++; - m_num_directories_bits = ceilLog2(m_num_directories); + int nd = (++m_ruby_system_ptr->m_num_directories); + m_ruby_system_ptr->m_num_directories_bits = ceilLog2(nd); - if (m_numa_high_bit == 0) { - m_numa_high_bit = RubySystem::getMemorySizeBits() - 1; + if (m_ruby_system_ptr->m_numa_high_bit == 0) { + m_ruby_system_ptr->m_numa_high_bit = m_size_bits - 1; } - assert(m_numa_high_bit != 0); + assert(m_ruby_system_ptr->m_numa_high_bit != 0); } DirectoryMemory::~DirectoryMemory() @@ -77,22 +74,11 @@ delete [] m_entries; } -uint64_t -DirectoryMemory::mapAddressToDirectoryVersion(Addr address) -{ - if (m_num_directories_bits == 0) - return 0; - - uint64_t ret = bitSelect(address, - m_numa_high_bit - m_num_directories_bits + 1, - m_numa_high_bit); - return ret; -} - bool DirectoryMemory::isPresent(Addr address) { - bool ret = (mapAddressToDirectoryVersion(address) == m_version); + bool ret = (m_ruby_system_ptr->mapAddressToDirectoryVersion(address) == + m_version); return ret; } @@ -100,9 +86,11 @@ DirectoryMemory::mapAddressToLocalIdx(Addr address) { uint64_t ret; - if (m_num_directories_bits > 0) { - ret = bitRemove(address, m_numa_high_bit - m_num_directories_bits + 1, - m_numa_high_bit); + if (m_ruby_system_ptr->m_num_directories_bits > 0) { + ret = bitRemove(address, + m_ruby_system_ptr->m_numa_high_bit - + m_ruby_system_ptr->m_num_directories_bits + 1, + m_ruby_system_ptr->m_numa_high_bit); } else { ret = address; } diff --git a/src/mem/ruby/structures/DirectoryMemory.py b/src/mem/ruby/structures/DirectoryMemory.py --- a/src/mem/ruby/structures/DirectoryMemory.py +++ b/src/mem/ruby/structures/DirectoryMemory.py @@ -35,6 +35,7 @@ type = 'RubyDirectoryMemory' cxx_class = 'DirectoryMemory' cxx_header = "mem/ruby/structures/DirectoryMemory.hh" + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") version = Param.Int(0, "") block_size_bytes = Param.UInt32(64, "block size used for ownership info.") size = Param.MemorySize("1GB", "capacity in bytes") diff --git a/src/mem/ruby/structures/PerfectCacheMemory.hh b/src/mem/ruby/structures/PerfectCacheMemory.hh --- a/src/mem/ruby/structures/PerfectCacheMemory.hh +++ b/src/mem/ruby/structures/PerfectCacheMemory.hh @@ -53,7 +53,7 @@ class PerfectCacheMemory { public: - PerfectCacheMemory(uint32_t block_size_bits); + PerfectCacheMemory(uint32_t block_size_bits, RubySystem *rs); // tests to see if an address is present in the cache bool isTagPresent(Addr address) const; @@ -90,6 +90,7 @@ // Data Members (m_prefix) const uint32_t m_block_size_bits; std::unordered_map > m_map; + RubySystem *m_ruby_system_ptr; }; template @@ -103,8 +104,9 @@ template inline -PerfectCacheMemory::PerfectCacheMemory(uint32_t block_size_bits) - : m_block_size_bits(block_size_bits) +PerfectCacheMemory::PerfectCacheMemory(uint32_t block_size_bits, + RubySystem *rs) + : m_block_size_bits(block_size_bits), m_ruby_system_ptr(rs) { } @@ -131,7 +133,7 @@ { PerfectCacheLineState line_state; line_state.m_permission = AccessPermission_Invalid; - line_state.m_entry = ENTRY(); + line_state.m_entry = ENTRY(m_ruby_system_ptr); m_map[makeLineAddress(address, m_block_size_bits)] = line_state; } diff --git a/src/mem/ruby/structures/PersistentTable.hh b/src/mem/ruby/structures/PersistentTable.hh --- a/src/mem/ruby/structures/PersistentTable.hh +++ b/src/mem/ruby/structures/PersistentTable.hh @@ -37,10 +37,15 @@ #include "mem/ruby/common/MachineID.hh" #include "mem/ruby/common/NetDest.hh" +class RubySystem; + class PersistentTableEntry { public: - PersistentTableEntry() {} + PersistentTableEntry() = default; + PersistentTableEntry(RubySystem *rs) : m_starving(rs), + m_marked(rs), + m_request_to_write(rs) {} void print(std::ostream& out) const {} NetDest m_starving; @@ -52,7 +57,7 @@ { public: // Constructors - PersistentTable(); + PersistentTable(RubySystem *rs); // Destructor ~PersistentTable(); @@ -79,6 +84,9 @@ // Data Members (m_prefix) typedef std::unordered_map AddressMap; AddressMap m_map; + + protected: + RubySystem *m_ruby_system_ptr; }; inline std::ostream& diff --git a/src/mem/ruby/structures/PersistentTable.cc b/src/mem/ruby/structures/PersistentTable.cc --- a/src/mem/ruby/structures/PersistentTable.cc +++ b/src/mem/ruby/structures/PersistentTable.cc @@ -38,7 +38,8 @@ 10, 11, 12, 13, 14, 15}; #endif -PersistentTable::PersistentTable() +PersistentTable::PersistentTable(RubySystem *rs) + : m_ruby_system_ptr(rs) { } @@ -51,7 +52,7 @@ MachineID locker, AccessType type) { - static const PersistentTableEntry dflt; + static const PersistentTableEntry dflt(m_ruby_system_ptr); pair r = m_map.insert(AddressMap::value_type(address, dflt)); bool present = !r.second; diff --git a/src/mem/ruby/structures/Prefetcher.hh b/src/mem/ruby/structures/Prefetcher.hh --- a/src/mem/ruby/structures/Prefetcher.hh +++ b/src/mem/ruby/structures/Prefetcher.hh @@ -106,6 +106,9 @@ void regStats(); + protected: + RubySystem *m_ruby_system_ptr; + private: /** * Returns an unused stream buffer (or if all are used, returns the diff --git a/src/mem/ruby/structures/Prefetcher.cc b/src/mem/ruby/structures/Prefetcher.cc --- a/src/mem/ruby/structures/Prefetcher.cc +++ b/src/mem/ruby/structures/Prefetcher.cc @@ -37,8 +37,10 @@ } Prefetcher::Prefetcher(const Params *p) - : SimObject(p), m_num_streams(p->num_streams), - m_array(p->num_streams), m_train_misses(p->train_misses), + : SimObject(p), m_ruby_system_ptr (p->ruby_system), + m_num_streams(p->num_streams), + m_array(p->num_streams, PrefetchEntry()), + m_train_misses(p->train_misses), m_num_startup_pfs(p->num_startup_pfs), m_num_unit_filters(p->unit_filter), m_num_nonunit_filters(p->nonunit_filter), m_unit_filter(p->unit_filter, 0), diff --git a/src/mem/ruby/structures/RubyMemoryControl.hh b/src/mem/ruby/structures/RubyMemoryControl.hh --- a/src/mem/ruby/structures/RubyMemoryControl.hh +++ b/src/mem/ruby/structures/RubyMemoryControl.hh @@ -90,6 +90,9 @@ bool functionalRead(PacketPtr pkt); uint32_t functionalWrite(PacketPtr pkt); + protected: + RubySystem *m_ruby_system_ptr; + private: void enqueueToDirectory(MemoryNode *req, Cycles latency); const int getRank(int bank) const; diff --git a/src/mem/ruby/structures/RubyMemoryControl.cc b/src/mem/ruby/structures/RubyMemoryControl.cc --- a/src/mem/ruby/structures/RubyMemoryControl.cc +++ b/src/mem/ruby/structures/RubyMemoryControl.cc @@ -147,6 +147,7 @@ : AbstractMemory(p), Consumer(this), port(name() + ".port", *this), m_event(this) { + m_ruby_system_ptr = p->ruby_system; m_banks_per_rank = p->banks_per_rank; m_ranks_per_dimm = p->ranks_per_dimm; m_dimms_per_channel = p->dimms_per_channel; diff --git a/src/mem/ruby/structures/RubyMemoryControl.py b/src/mem/ruby/structures/RubyMemoryControl.py --- a/src/mem/ruby/structures/RubyMemoryControl.py +++ b/src/mem/ruby/structures/RubyMemoryControl.py @@ -28,12 +28,14 @@ # Brad Beckmann from m5.params import * +from m5.proxy import * from AbstractMemory import AbstractMemory class RubyMemoryControl(AbstractMemory): type = 'RubyMemoryControl' cxx_class = 'RubyMemoryControl' cxx_header = "mem/ruby/structures/RubyMemoryControl.hh" + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") banks_per_rank = Param.Int(8, ""); ranks_per_dimm = Param.Int(2, ""); diff --git a/src/mem/ruby/structures/RubyPrefetcher.py b/src/mem/ruby/structures/RubyPrefetcher.py --- a/src/mem/ruby/structures/RubyPrefetcher.py +++ b/src/mem/ruby/structures/RubyPrefetcher.py @@ -35,6 +35,7 @@ type = 'Prefetcher' cxx_class = 'Prefetcher' cxx_header = "mem/ruby/structures/Prefetcher.hh" + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") num_streams = Param.UInt32(4, "Number of prefetch streams to be allocated") # Node ID d0a78af897009d449b38045231a01f30b2fb8626 # Parent 01b85102d5b9265ed61cc04e7e6749ada3ea35e9 diff --git a/configs/example/multi-system-se.py b/configs/example/multi-system-se.py new file mode 100644 --- /dev/null +++ b/configs/example/multi-system-se.py @@ -0,0 +1,203 @@ +# Copyright (c) 2012-2013 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Copyright (c) 2006-2008 The Regents of The University of Michigan +# Copyright (c) 2015 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. +# +# Authors: Brandon Potter +# +# Multi-system test script (adapted from configs/example/se.py). + +import optparse +import sys +import os + +import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, fatal + +addToPath('../common') +addToPath('../ruby') + +import Options +import Simulation +import CacheConfig +import MemConfig +import Ruby + +def get_processes(options): + sys_workloads = options.cmd.split(':') + sys_inputs = options.input.split(':') if options.input else [] + sys_outputs = options.output.split(':') if options.output else [] + sys_errouts = options.errout.split(':') if options.errout else [] + sys_pargs = options.options.split(':') if options.options else [] + + sys_multiprocesses = [] + for i in xrange(len(sys_workloads)): + workloads = sys_workloads[i].split(';') + inputs = sys_inputs[i].split(';') if sys_inputs else [] + outputs = sys_outputs[i].split(';') if sys_outputs else [] + errouts = sys_errouts[i].split(';') if sys_errouts else [] + pargs = sys_pargs[i].split(';') if sys_pargs else [] + + index = 0 + multiprocesses = [] + for workload in workloads: + process = LiveProcess() + + if options.env: + with open(options.env, 'r') as f: + process.env = [line.rstrip() for line in f] + + process.cwd = os.getcwd() + process.executable = workload + process.cmd = [workload] + if len(pargs) > index: + process.cmd += pargs[index].split() + if len(inputs) > index: + process.input = inputs[index] + if len(outputs) > index: + process.output = outputs[index] + if len(errouts) > index: + process.errout = errouts[index] + multiprocesses.append(process) + index += 1 + + sys_multiprocesses.append(multiprocesses) + + return sys_multiprocesses + + +parser = optparse.OptionParser() +Options.addCommonOptions(parser) +Options.addSEOptions(parser) + +parser.add_option("--num-systems", type="int", default=1, + help="Number of copies of the system to create") + +if '--ruby' in sys.argv: + Ruby.define_options(parser) + +(options, args) = parser.parse_args() + +if args: + fatal("configuration script failed to parse all arguments") +elif not options.cmd: + fatal("must specify workload(s)") +# Choosing to ignore the more advanced options for script brevity. +# The point here is to show how to setup a multi-system configuration. +elif options.smt: + fatal("smt disabled") +elif options.fastmem: + fatal("fastmem disabled") +elif options.simpoint_profile: + fatal("simpoint disabled") +elif options.checker: + fatal("checker disabled") + +sys_multiprocesses = get_processes(options) +assert(len(sys_multiprocesses) == options.num_systems) + +(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) + +cpu_class_list = [] +sys_list = [] +for s in xrange(options.num_systems): + cpu_class_list.append(Simulation.setCPUClass(options)[0]) + + system = System(cpu=[cpu_class_list[s](cpu_id=i) \ + for i in xrange(options.num_cpus)], + mem_mode=test_mem_mode, + mem_ranges=[AddrRange(options.mem_size)], + cache_line_size=options.cacheline_size) + + system.voltage_domain = VoltageDomain(voltage=options.sys_voltage) + system.cpu_voltage_domain = VoltageDomain() + system.clk_domain = SrcClockDomain(clock=options.sys_clock, + voltage_domain=system.voltage_domain) + system.cpu_clk_domain = SrcClockDomain(clock=options.cpu_clock, + voltage_domain= + system.cpu_voltage_domain) + for cpu in system.cpu: + cpu.clk_domain = system.cpu_clk_domain + + sys_list.append(system) + + for i in xrange(options.num_cpus): + sys_list[s].cpu[i].createThreads() + # Quick and dirty fix to resolve the issue of being forced to + # assign workloads to every CPU. The CPUs remain inactive until + # thread contexts are manually activated. + sys_list[s].cpu[i].workload = sys_multiprocesses[s][0] + if i < len(sys_multiprocesses[s]): + sys_list[s].cpu[i].workload = sys_multiprocesses[s][i] + + if options.ruby: + if not (options.cpu_type in ("detailed", "timing")): + fatal("Ruby requires CPU with a timing model!") + + Ruby.create_system(options, False, sys_list[s]) + + sys_list[s].ruby.clk_domain = \ + SrcClockDomain(clock=options.ruby_clock, + voltage_domain=sys_list[s].voltage_domain) + + for i in xrange(options.num_cpus): + ruby_port = sys_list[s].ruby._cpu_ports[i] + + # Create the interrupt controller and connect its ports to Ruby + # Note that the interrupt controller is always present but only + # in x86 does it have message ports that need to be connected + sys_list[s].cpu[i].createInterruptController() + + sys_list[s].cpu[i].icache_port = ruby_port.slave + sys_list[s].cpu[i].dcache_port = ruby_port.slave + if buildEnv['TARGET_ISA'] == 'x86': + sys_list[s].cpu[i].interrupts[0].pio = ruby_port.master + sys_list[s].cpu[i].interrupts[0].int_master = ruby_port.slave + sys_list[s].cpu[i].interrupts[0].int_slave = ruby_port.master + sys_list[s].cpu[i].itb.walker.port = ruby_port.slave + sys_list[s].cpu[i].dtb.walker.port = ruby_port.slave + else: + MemClass = Simulation.setMemClass(options) + sys_list[s].membus = SystemXBar() + sys_list[s].system_port = sys_list[s].membus.slave + CacheConfig.config_cache(options, sys_list[s]) + MemConfig.config_mem(options, sys_list[s]) + +root = Root(full_system=False, system=sys_list) +Simulation.run(options, root, sys_list, FutureClass) diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py +++ b/configs/ruby/Ruby.py @@ -175,8 +175,8 @@ InterfaceClass = None # Instantiate the network object so that the controllers can connect to it. - network = NetworkClass(ruby_system = ruby, topology = options.topology, - routers = [], ext_links = [], int_links = [], netifs = []) + network = NetworkClass(topology = options.topology, routers = [], + ext_links = [], int_links = [], netifs = []) ruby.network = network protocol = buildEnv['PROTOCOL'] diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh --- a/src/cpu/testers/rubytest/RubyTester.hh +++ b/src/cpu/testers/rubytest/RubyTester.hh @@ -53,6 +53,8 @@ #include "mem/ruby/common/TypeDefines.hh" #include "params/RubyTester.hh" +class RubySystem; + class RubyTester : public MemObject { public: @@ -111,6 +113,8 @@ bool getCheckFlush() { return m_check_flush; } MasterID masterId() { return _masterId; } + + RubySystem *m_ruby_system_ptr; protected: class CheckStartEvent : public Event { diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc --- a/src/cpu/testers/rubytest/RubyTester.cc +++ b/src/cpu/testers/rubytest/RubyTester.cc @@ -47,7 +47,8 @@ #include "sim/system.hh" RubyTester::RubyTester(const Params *p) - : MemObject(p), checkStartEvent(this), + : MemObject(p), m_ruby_system_ptr(p->ruby_system), + checkStartEvent(this), _masterId(p->system->getMasterId(name())), m_checkTable_ptr(nullptr), m_num_cpus(p->num_cpus), m_block_size_bytes(p->block_size_bytes), diff --git a/src/cpu/testers/rubytest/RubyTester.py b/src/cpu/testers/rubytest/RubyTester.py --- a/src/cpu/testers/rubytest/RubyTester.py +++ b/src/cpu/testers/rubytest/RubyTester.py @@ -33,6 +33,7 @@ class RubyTester(MemObject): type = 'RubyTester' cxx_header = "cpu/testers/rubytest/RubyTester.hh" + ruby_system = Param.RubySystem(Parent.any, "The parent RubySystem object") num_cpus = Param.Int("number of cpus / RubyPorts") block_size_bytes = Param.UInt32(64, "cache block size.") cpuDataPort = VectorMasterPort("the cpu data cache ports") diff --git a/src/mem/protocol/MESI_Three_Level-L0cache.sm b/src/mem/protocol/MESI_Three_Level-L0cache.sm --- a/src/mem/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/protocol/MESI_Three_Level-L0cache.sm @@ -133,7 +133,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; Tick clockEdge(); Cycles ticksToCycles(Tick t); @@ -564,13 +564,13 @@ action(oo_allocateDCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(Dcache.allocate(address, new Entry)); + set_cache_entry(Dcache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(pp_allocateICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(Icache.allocate(address, new Entry)); + set_cache_entry(Icache.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MESI_Three_Level-L1cache.sm b/src/mem/protocol/MESI_Three_Level-L1cache.sm --- a/src/mem/protocol/MESI_Three_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Three_Level-L1cache.sm @@ -147,7 +147,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; int l2_select_low_bit, default="getBlockSizeBits()"; @@ -706,7 +706,7 @@ action(oo_allocateCacheBlock, "\o", desc="Set cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(cache.allocate(address, new Entry)); + set_cache_entry(cache.allocate(address, new Entry("m_ruby_system_ptr"))); } } diff --git a/src/mem/protocol/MESI_Two_Level-L1cache.sm b/src/mem/protocol/MESI_Two_Level-L1cache.sm --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm @@ -62,11 +62,11 @@ MessageBuffer * responseToL1Cache, network="From", virtual_network="1", vnet_type="response"; - // Request Buffer for prefetches - MessageBuffer * optionalQueue; + // Request Buffer for prefetches + MessageBuffer * optionalQueue; - // Buffer for requests generated by the processor core. - MessageBuffer * mandatoryQueue; + // Buffer for requests generated by the processor core. + MessageBuffer * mandatoryQueue; { // STATES state_declaration(State, desc="Cache states", default="L1Cache_State_I") { @@ -152,7 +152,7 @@ bool isPresent(Addr); } - TBETable TBEs, template="", constructor="m_number_of_TBEs"; + TBETable TBEs, template="", constructor="m_number_of_TBEs, m_ruby_system_ptr"; int l2_select_low_bit, default="getBlockSizeBits()"; @@ -920,13 +920,13 @@ action(oo_allocateL1DCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(L1Dcache.allocate(address, new Entry)); + set_cache_entry(L1Dcache.allocate(address, new Entry("m_ruby_system_ptr"))); } } action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { if (is_invalid(cache_entry)) { - set_cache_entry(L1Icache.allocate(address, new Entry)); + set_cache_entry(L1Icache.allocate(address, new Entry("m_ruby_system_ptr"))); } }