From c86f849d5a1da1fc77f2fca43b82cb6760f68bc9 Mon Sep 17 00:00:00 2001 From: "Brad Beckmann ext:(%2C%20Nilay%20Vaish%20%3Cnilay%40cs.wisc.edu%3E)" Date: Thu, 30 Jun 2011 19:49:26 -0500 Subject: Ruby: Add support for functional accesses This patch rpovides functional access support in Ruby. Currently only the M5Port of RubyPort supports functional accesses. The support for functional through the PioPort will be added as a separate patch. --- src/mem/ruby/network/Network.cc | 1 + src/mem/ruby/network/Network.py | 1 + src/mem/ruby/profiler/Profiler.cc | 2 + src/mem/ruby/profiler/Profiler.py | 1 + src/mem/ruby/recorder/Tracer.cc | 2 +- src/mem/ruby/recorder/Tracer.py | 1 + src/mem/ruby/slicc_interface/AbstractController.hh | 9 +- src/mem/ruby/slicc_interface/Controller.py | 1 + src/mem/ruby/slicc_interface/SConscript | 1 + src/mem/ruby/system/Cache.py | 41 ----- src/mem/ruby/system/DirectoryMemory.cc | 4 +- src/mem/ruby/system/DirectoryMemory.py | 43 ----- src/mem/ruby/system/RubyPort.cc | 175 ++++++++++++++++++++- src/mem/ruby/system/RubyPort.hh | 7 +- src/mem/ruby/system/RubySystem.py | 3 - src/mem/ruby/system/SConscript | 3 +- src/mem/ruby/system/Sequencer.py | 1 + src/mem/ruby/system/System.cc | 28 +++- src/mem/ruby/system/System.hh | 13 +- 19 files changed, 229 insertions(+), 108 deletions(-) delete mode 100644 src/mem/ruby/system/Cache.py delete mode 100644 src/mem/ruby/system/DirectoryMemory.py (limited to 'src/mem/ruby') diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index caab89715..adb90eba9 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -48,6 +48,7 @@ Network::Network(const Params *p) // Initialize the controller's network pointers m_topology_ptr->initNetworkPtr(this); + p->ruby_system->registerNetwork(this); } void diff --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py index 909f2f727..9642b046e 100644 --- a/src/mem/ruby/network/Network.py +++ b/src/mem/ruby/network/Network.py @@ -48,3 +48,4 @@ class RubyNetwork(SimObject): number_of_virtual_networks = Param.Int(10, ""); topology = Param.Topology(""); control_msg_size = Param.Int(8, ""); + ruby_system = Param.RubySystem(""); diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index afb77f09f..08a4439db 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -92,6 +92,8 @@ Profiler::Profiler(const Params *p) m_inst_profiler_ptr->setHotLines(m_hot_lines); m_inst_profiler_ptr->setAllInstructions(m_all_instructions); } + + p->ruby_system->registerProfiler(this); } Profiler::~Profiler() diff --git a/src/mem/ruby/profiler/Profiler.py b/src/mem/ruby/profiler/Profiler.py index d15573aa4..3521911c2 100644 --- a/src/mem/ruby/profiler/Profiler.py +++ b/src/mem/ruby/profiler/Profiler.py @@ -36,3 +36,4 @@ class RubyProfiler(SimObject): hot_lines = Param.Bool(False, "") all_instructions = Param.Bool(False, "") num_of_sequencers = Param.Int("") + ruby_system = Param.RubySystem("") diff --git a/src/mem/ruby/recorder/Tracer.cc b/src/mem/ruby/recorder/Tracer.cc index bff59a832..fcfe5338c 100644 --- a/src/mem/ruby/recorder/Tracer.cc +++ b/src/mem/ruby/recorder/Tracer.cc @@ -40,7 +40,7 @@ Tracer::Tracer(const Params *p) m_enabled = false; m_warmup_length = p->warmup_length; assert(m_warmup_length > 0); - RubySystem::m_tracer_ptr = this; + p->ruby_system->registerTracer(this); } void diff --git a/src/mem/ruby/recorder/Tracer.py b/src/mem/ruby/recorder/Tracer.py index 7b6fd8421..7a689f9f7 100644 --- a/src/mem/ruby/recorder/Tracer.py +++ b/src/mem/ruby/recorder/Tracer.py @@ -34,3 +34,4 @@ class RubyTracer(SimObject): type = 'RubyTracer' cxx_class = 'Tracer' warmup_length = Param.Int(100000, "") + ruby_system = Param.RubySystem("") diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index eb8399af2..f1dac39ad 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -36,7 +36,9 @@ #include "mem/protocol/MachineType.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/network/Network.hh" +#include "mem/ruby/system/System.hh" #include "params/RubyController.hh" #include "sim/sim_object.hh" @@ -47,7 +49,7 @@ class AbstractController : public SimObject, public Consumer { public: typedef RubyControllerParams Params; - AbstractController(const Params *p) : SimObject(p) {} + AbstractController(const Params *p); const Params *params() const { return (const Params *)_params; } // returns the number of controllers created of the specific subtype @@ -61,6 +63,8 @@ class AbstractController : public SimObject, public Consumer virtual void blockOnQueue(Address, MessageBuffer*) = 0; virtual void unblock(Address) = 0; virtual void initNetworkPtr(Network* net_ptr) = 0; + virtual AccessPermission getAccessPermission(Address addr) = 0; + virtual DataBlock& getDataBlock(Address addr) = 0; virtual void print(std::ostream & out) const = 0; virtual void printStats(std::ostream & out) const = 0; @@ -68,9 +72,6 @@ class AbstractController : public SimObject, public Consumer virtual void wakeup() = 0; // virtual void dumpStats(std::ostream & out) = 0; virtual void clearStats() = 0; - - private: - virtual AccessPermission getAccessPermission(Address addr) = 0; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py index a5ad45145..44e08ecdc 100644 --- a/src/mem/ruby/slicc_interface/Controller.py +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -41,3 +41,4 @@ class RubyController(SimObject): buffer_size = Param.Int(0, "max buffer size 0 means infinite") recycle_latency = Param.Int(10, "") number_of_TBEs = Param.Int(256, "") + ruby_system = Param.RubySystem(""); diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript index 256f8e64e..9d4e6fe3b 100644 --- a/src/mem/ruby/slicc_interface/SConscript +++ b/src/mem/ruby/slicc_interface/SConscript @@ -35,6 +35,7 @@ if not env['RUBY']: SimObject('Controller.py') +Source('AbstractController.cc') Source('AbstractEntry.cc') Source('AbstractCacheEntry.cc') Source('RubyRequest.cc') diff --git a/src/mem/ruby/system/Cache.py b/src/mem/ruby/system/Cache.py deleted file mode 100644 index ab3ec4b29..000000000 --- a/src/mem/ruby/system/Cache.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2009 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: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.SimObject import SimObject -from Controller import RubyController - -class RubyCache(SimObject): - type = 'RubyCache' - cxx_class = 'CacheMemory' - size = Param.MemorySize("capacity in bytes"); - latency = Param.Int(""); - assoc = Param.Int(""); - replacement_policy = Param.String("PSEUDO_LRU", ""); - start_index_bit = Param.Int(6, "index start, default 6 for 64-byte line"); diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index fe54c8d79..c461ce09b 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -156,7 +156,7 @@ DirectoryMemory::lookup(PhysAddress address) assert(isPresent(address)); Directory_Entry* entry; uint64 idx; - DPRINTF(RubyCache, "address: %s\n", address); + DPRINTF(RubyCache, "Looking up address: %s\n", address); if (m_use_map) { if (m_sparseMemory->exist(address)) { @@ -166,6 +166,7 @@ DirectoryMemory::lookup(PhysAddress address) // Note: SparseMemory internally creates a new Directory Entry m_sparseMemory->add(address); entry = m_sparseMemory->lookup(address); + entry->changePermission(AccessPermission_Read_Write); } } else { idx = mapAddressToLocalIdx(address); @@ -175,6 +176,7 @@ DirectoryMemory::lookup(PhysAddress address) if (entry == NULL) { entry = new Directory_Entry(); entry->getDataBlk().assign(m_ram->getBlockPtr(address)); + entry->changePermission(AccessPermission_Read_Only); m_entries[idx] = entry; } } diff --git a/src/mem/ruby/system/DirectoryMemory.py b/src/mem/ruby/system/DirectoryMemory.py deleted file mode 100644 index d3b6bc591..000000000 --- a/src/mem/ruby/system/DirectoryMemory.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2009 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: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.proxy import * -from m5.SimObject import SimObject - -class RubyDirectoryMemory(SimObject): - type = 'RubyDirectoryMemory' - cxx_class = 'DirectoryMemory' - version = Param.Int(0, "") - size = Param.MemorySize("1GB", "capacity in bytes") - use_map = Param.Bool(False, "enable sparse memory") - map_levels = Param.Int(4, "sparse memory map levels") - # the default value of the numa high bit is specified in the command line - # option and must be passed into the directory memory sim object - numa_high_bit = Param.Int("numa high bit") diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 40f893257..662f971f2 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -31,8 +31,8 @@ #include "arch/x86/insts/microldstop.hh" #endif // X86_ISA #include "cpu/testers/rubytest/RubyTester.hh" -#include "debug/MemoryAccess.hh" #include "debug/Ruby.hh" +#include "mem/protocol/AccessPermission.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/system/RubyPort.hh" #include "mem/physical.hh" @@ -54,6 +54,8 @@ RubyPort::RubyPort(const Params *p) m_usingRubyTester = p->using_ruby_tester; access_phys_mem = p->access_phys_mem; + + ruby_system = p->ruby_system; } void @@ -68,7 +70,7 @@ RubyPort::getPort(const std::string &if_name, int idx) { if (if_name == "port") { return new M5Port(csprintf("%s-port%d", name(), idx), this, - access_phys_mem); + ruby_system, access_phys_mem); } if (if_name == "pio_port") { @@ -85,7 +87,7 @@ RubyPort::getPort(const std::string &if_name, int idx) assert (physMemPort == NULL); physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this, - access_phys_mem); + ruby_system, access_phys_mem); return physMemPort; } @@ -109,12 +111,13 @@ RubyPort::PioPort::PioPort(const std::string &_name, ruby_port = _port; } -RubyPort::M5Port::M5Port(const std::string &_name, - RubyPort *_port, bool _access_phys_mem) +RubyPort::M5Port::M5Port(const std::string &_name, RubyPort *_port, + RubySystem *_system, bool _access_phys_mem) : SimpleTimingPort(_name, _port) { DPRINTF(RubyPort, "creating port from ruby sequcner to cpu %s\n", _name); ruby_port = _port; + ruby_system = _system; _onRetryList = false; access_phys_mem = _access_phys_mem; } @@ -289,6 +292,168 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) return false; } +bool +RubyPort::M5Port::doFunctionalRead(PacketPtr pkt) +{ + Address address(pkt->getAddr()); + Address line_address(address); + line_address.makeLineAddress(); + + AccessPermission accessPerm = AccessPermission_NotPresent; + int num_controllers = ruby_system->m_abs_cntrl_vec.size(); + + // In this loop, we try to figure which controller has a read only or + // a read write copy of the given address. Any valid copy would suffice + // for a functional read. + + DPRINTF(RubyPort, "Functional Read request for %s\n",address); + for(int i = 0;i < num_controllers;++i) + { + accessPerm = ruby_system->m_abs_cntrl_vec[i] + ->getAccessPermission(line_address); + if(accessPerm == AccessPermission_Read_Only || + accessPerm == AccessPermission_Read_Write) + { + unsigned startByte = address.getAddress() - line_address.getAddress(); + + uint8* data = pkt->getPtr(true); + unsigned int size_in_bytes = pkt->getSize(); + DataBlock& block = ruby_system->m_abs_cntrl_vec[i] + ->getDataBlock(line_address); + + DPRINTF(RubyPort, "reading from %s block %s\n", + ruby_system->m_abs_cntrl_vec[i]->name(), block); + for (unsigned i = 0; i < size_in_bytes; ++i) + { + data[i] = block.getByte(i + startByte); + } + return true; + } + } + return false; +} + +bool +RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt) +{ + Address addr(pkt->getAddr()); + Address line_addr = line_address(addr); + AccessPermission accessPerm = AccessPermission_NotPresent; + int num_controllers = ruby_system->m_abs_cntrl_vec.size(); + + DPRINTF(RubyPort, "Functional Write request for %s\n",addr); + + unsigned int num_ro = 0; + unsigned int num_rw = 0; + unsigned int num_busy = 0; + + // In this loop we count the number of controllers that have the given + // address in read only, read write and busy states. + for(int i = 0;i < num_controllers;++i) + { + accessPerm = ruby_system->m_abs_cntrl_vec[i]-> + getAccessPermission(line_addr); + if(accessPerm == AccessPermission_Read_Only) num_ro++; + else if(accessPerm == AccessPermission_Read_Write) num_rw++; + else if(accessPerm == AccessPermission_Busy) num_busy++; + } + + // If the number of read write copies is more than 1, then there is bug in + // coherence protocol. Otherwise, if all copies are in stable states, i.e. + // num_busy == 0, we update all the copies. If there is at least one copy + // in busy state, then we check if there is read write copy. If yes, then + // also we let the access go through. + + DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n", + num_busy, num_ro, num_rw); + assert(num_rw <= 1); + if((num_busy == 0 && num_ro > 0) || num_rw == 1) + { + uint8* data = pkt->getPtr(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = addr.getAddress() - line_addr.getAddress(); + + for(int i = 0; i < num_controllers;++i) + { + accessPerm = ruby_system->m_abs_cntrl_vec[i]-> + getAccessPermission(line_addr); + if(accessPerm == AccessPermission_Read_Only || + accessPerm == AccessPermission_Read_Write|| + accessPerm == AccessPermission_Maybe_Stale) + { + DataBlock& block = ruby_system->m_abs_cntrl_vec[i] + ->getDataBlock(line_addr); + + DPRINTF(RubyPort, "%s\n",block); + for (unsigned i = 0; i < size_in_bytes; ++i) + { + block.setByte(i + startByte, data[i]); + } + DPRINTF(RubyPort, "%s\n",block); + } + } + return true; + } + return false; +} + +void +RubyPort::M5Port::recvFunctional(PacketPtr pkt) +{ + DPRINTF(RubyPort, "Functional access caught for address %#x\n", + pkt->getAddr()); + + // Check for pio requests and directly send them to the dedicated + // pio port. + if (!isPhysMemAddress(pkt->getAddr())) { + assert(ruby_port->pio_port != NULL); + DPRINTF(RubyPort, "Request for address 0x%#x is a pio request\n", + pkt->getAddr()); + panic("RubyPort::PioPort::recvFunctional() not implemented!\n"); + } + + assert(pkt->getAddr() + pkt->getSize() <= + line_address(Address(pkt->getAddr())).getAddress() + + RubySystem::getBlockSizeBytes()); + + bool accessSucceeded = false; + bool needsResponse = pkt->needsResponse(); + + // Do the functional access on ruby memory + if (pkt->isRead()) { + accessSucceeded = doFunctionalRead(pkt); + } else if (pkt->isWrite()) { + accessSucceeded = doFunctionalWrite(pkt); + } else { + panic("RubyPort: unsupported functional command %s\n", + pkt->cmdString()); + } + + // Unless the requester explicitly said otherwise, generate an error if + // the functional request failed + if (!accessSucceeded && !pkt->suppressFuncError()) { + fatal("Ruby functional %s failed for address %#x\n", + pkt->isWrite() ? "write" : "read", pkt->getAddr()); + } + + if (access_phys_mem) { + // The attached physmem contains the official version of data. + // The following command performs the real functional access. + // This line should be removed once Ruby supplies the official version + // of data. + ruby_port->physMemPort->sendFunctional(pkt); + } + + // turn packet around to go back to requester if response expected + if (needsResponse) { + pkt->setFunctionalResponseStatus(accessSucceeded); + DPRINTF(RubyPort, "Sending packet back over port\n"); + sendFunctional(pkt); + } + DPRINTF(RubyPort, "Functional access %s!\n", + accessSucceeded ? "successful":"failed"); +} + void RubyPort::ruby_hit_callback(PacketPtr pkt) { diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index dc7a141c3..e1ba2f7d1 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -50,12 +50,13 @@ class RubyPort : public MemObject { private: RubyPort *ruby_port; + RubySystem* ruby_system; bool _onRetryList; bool access_phys_mem; public: M5Port(const std::string &_name, RubyPort *_port, - bool _access_phys_mem); + RubySystem*_system, bool _access_phys_mem); bool sendTiming(PacketPtr pkt); void hitCallback(PacketPtr pkt); unsigned deviceBlockSize() const; @@ -69,9 +70,12 @@ class RubyPort : public MemObject protected: virtual bool recvTiming(PacketPtr pkt); virtual Tick recvAtomic(PacketPtr pkt); + virtual void recvFunctional(PacketPtr pkt); private: bool isPhysMemAddress(Addr addr); + bool doFunctionalRead(PacketPtr pkt); + bool doFunctionalWrite(PacketPtr pkt); }; friend class M5Port; @@ -145,6 +149,7 @@ class RubyPort : public MemObject M5Port* physMemPort; PhysicalMemory* physmem; + RubySystem* ruby_system; // // Based on similar code in the M5 bus. Stores pointers to those ports diff --git a/src/mem/ruby/system/RubySystem.py b/src/mem/ruby/system/RubySystem.py index 7878cec63..d66ada4b9 100644 --- a/src/mem/ruby/system/RubySystem.py +++ b/src/mem/ruby/system/RubySystem.py @@ -39,9 +39,6 @@ class RubySystem(SimObject): block_size_bytes = Param.Int(64, "default cache block size; must be a power of two"); mem_size = Param.MemorySize("total memory size of the system"); - network = Param.RubyNetwork("") - profiler = Param.RubyProfiler(""); - tracer = Param.RubyTracer(""); stats_filename = Param.String("ruby.stats", "file to which ruby dumps its stats") no_mem_vec = Param.Bool(False, "do not allocate Ruby's mem vector"); diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index f1e7c425c..0820ef2c8 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -33,9 +33,8 @@ Import('*') if not env['RUBY']: Return() -SimObject('Cache.py') +SimObject('AbstractMemory.py') SimObject('Sequencer.py') -SimObject('DirectoryMemory.py') SimObject('MemoryControl.py') SimObject('WireBuffer.py') SimObject('RubySystem.py') diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py index 16fb795f8..5d56dc000 100644 --- a/src/mem/ruby/system/Sequencer.py +++ b/src/mem/ruby/system/Sequencer.py @@ -43,6 +43,7 @@ class RubyPort(MemObject): using_network_tester = Param.Bool(False, "") access_phys_mem = Param.Bool(True, "should the rubyport atomically update phys_mem") + ruby_system = Param.RubySystem("") class RubySequencer(RubyPort): type = 'RubySequencer' diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index d9c4fa821..81824b9b7 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -74,10 +74,6 @@ RubySystem::RubySystem(const Params *p) m_memory_size_bits = floorLog2(m_memory_size_bytes); } - m_network_ptr = p->network; - m_profiler_ptr = p->profiler; - m_tracer_ptr = p->tracer; - g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock); g_system_ptr = this; if (p->no_mem_vec) { @@ -100,6 +96,30 @@ RubySystem::init() m_profiler_ptr->clearStats(); } +void +RubySystem::registerNetwork(Network* network_ptr) +{ + m_network_ptr = network_ptr; +} + +void +RubySystem::registerProfiler(Profiler* profiler_ptr) +{ + m_profiler_ptr = profiler_ptr; +} + +void +RubySystem::registerTracer(Tracer* tracer_ptr) +{ + m_tracer_ptr = tracer_ptr; +} + +void +RubySystem::registerAbstractController(AbstractController* cntrl) +{ + m_abs_cntrl_vec.push_back(cntrl); +} + RubySystem::~RubySystem() { delete m_network_ptr; diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 608aca1d8..88a0186c5 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -39,9 +39,12 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/system/RubyPort.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" #include "params/RubySystem.hh" #include "sim/sim_object.hh" +class AbstractController; +class AbstractMemory; class CacheRecorder; class MemoryVector; class Network; @@ -128,6 +131,12 @@ class RubySystem : public SimObject virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + void registerNetwork(Network*); + void registerProfiler(Profiler*); + void registerTracer(Tracer*); + void registerAbstractMemory(AbstractMemory*); + void registerAbstractController(AbstractController*); + private: // Private copy constructor and assignment operator RubySystem(const RubySystem& obj); @@ -153,6 +162,7 @@ class RubySystem : public SimObject static Profiler* m_profiler_ptr; static Tracer* m_tracer_ptr; static MemoryVector* m_mem_vec_ptr; + std::vector m_abs_cntrl_vec; }; inline std::ostream& @@ -180,6 +190,3 @@ class RubyExitCallback : public Callback }; #endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ - - - -- cgit v1.2.3