diff --git a/src/mem/ruby/system/RubySystem.cc b/src/mem/ruby/system/RubySystem.cc new file mode 100644 --- /dev/null +++ b/src/mem/ruby/system/RubySystem.cc @@ -0,0 +1,508 @@ +/* + * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include + +#include "base/intmath.hh" +#include "base/statistics.hh" +#include "debug/RubyCacheTrace.hh" +#include "debug/RubySystem.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/network/Network.hh" +#include "mem/ruby/system/RubySystem.hh" +#include "mem/simple_mem.hh" +#include "sim/eventq.hh" +#include "sim/simulate.hh" + +using namespace std; + +int RubySystem::m_random_seed; +bool RubySystem::m_randomization; +uint32_t RubySystem::m_block_size_bytes; +uint32_t RubySystem::m_block_size_bits; +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_access_backing_store(p->access_backing_store) +{ + m_random_seed = p->random_seed; + srandom(m_random_seed); + m_randomization = p->randomization; + + m_block_size_bytes = p->block_size_bytes; + assert(isPowerOf2(m_block_size_bytes)); + m_block_size_bits = floorLog2(m_block_size_bytes); + m_memory_size_bits = p->memory_size_bits; + + // Resize to the size of different machine types + m_abstract_controls.resize(MachineType_NUM); + + // Collate the statistics before they are printed. + Stats::registerDumpCallback(new RubyStatsCallback(this)); + // Create the profiler + m_profiler = new Profiler(p, this); + m_phys_mem = p->phys_mem; +} + +void +RubySystem::registerNetwork(Network* network_ptr) +{ + m_network = network_ptr; +} + +void +RubySystem::registerAbstractController(AbstractController* cntrl) +{ + m_abs_cntrl_vec.push_back(cntrl); + + MachineID id = cntrl->getMachineID(); + m_abstract_controls[id.getType()][id.getNum()] = cntrl; +} + +RubySystem::~RubySystem() +{ + delete m_network; + delete m_profiler; +} + +void +RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename, + uint64 uncompressed_trace_size) +{ + // Create the checkpoint file for the memory + string thefile = CheckpointIn::dir() + "/" + filename.c_str(); + + int fd = creat(thefile.c_str(), 0664); + if (fd < 0) { + perror("creat"); + fatal("Can't open memory trace file '%s'\n", filename); + } + + gzFile compressedMemory = gzdopen(fd, "wb"); + if (compressedMemory == NULL) + fatal("Insufficient memory to allocate compression state for %s\n", + filename); + + if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) != + uncompressed_trace_size) { + fatal("Write failed on memory trace file '%s'\n", filename); + } + + if (gzclose(compressedMemory)) { + fatal("Close failed on memory trace file '%s'\n", filename); + } + delete[] raw_data; +} + +void +RubySystem::serializeOld(CheckpointOut &cp) +{ + m_cooldown_enabled = true; + vector sequencer_map; + Sequencer* sequencer_ptr = NULL; + + for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { + sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); + if (sequencer_ptr == NULL) { + sequencer_ptr = sequencer_map[cntrl]; + } + } + + assert(sequencer_ptr != NULL); + + for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { + if (sequencer_map[cntrl] == NULL) { + sequencer_map[cntrl] = sequencer_ptr; + } + } + + // Store the cache-block size, so we are able to restore on systems with a + // different cache-block size. CacheRecorder depends on the correct + // cache-block size upon unserializing. + uint64 block_size_bytes = getBlockSizeBytes(); + SERIALIZE_SCALAR(block_size_bytes); + + DPRINTF(RubyCacheTrace, "Recording Cache Trace\n"); + // Create the CacheRecorder and record the cache trace + m_cache_recorder = new CacheRecorder(NULL, 0, sequencer_map, + block_size_bytes); + + for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { + m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder); + } + + DPRINTF(RubyCacheTrace, "Cache Trace Complete\n"); + // save the current tick value + Tick curtick_original = curTick(); + // save the event queue head + Event* eventq_head = eventq->replaceHead(NULL); + DPRINTF(RubyCacheTrace, "Recording current tick %ld and event queue\n", + curtick_original); + + // Schedule an event to start cache cooldown + DPRINTF(RubyCacheTrace, "Starting cache flush\n"); + enqueueRubyEvent(curTick()); + simulate(); + DPRINTF(RubyCacheTrace, "Cache flush complete\n"); + + // Restore eventq head + eventq_head = eventq->replaceHead(eventq_head); + // Restore curTick + setCurTick(curtick_original); + + // Aggregate the trace entries together into a single array + uint8_t *raw_data = new uint8_t[4096]; + uint64 cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, + 4096); + string cache_trace_file = name() + ".cache.gz"; + writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size); + + SERIALIZE_SCALAR(cache_trace_file); + SERIALIZE_SCALAR(cache_trace_size); + + m_cooldown_enabled = false; +} + +void +RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data, + uint64& uncompressed_trace_size) +{ + // Read the trace file + gzFile compressedTrace; + + // trace file + int fd = open(filename.c_str(), O_RDONLY); + if (fd < 0) { + perror("open"); + fatal("Unable to open trace file %s", filename); + } + + compressedTrace = gzdopen(fd, "rb"); + if (compressedTrace == NULL) { + fatal("Insufficient memory to allocate compression state for %s\n", + filename); + } + + raw_data = new uint8_t[uncompressed_trace_size]; + if (gzread(compressedTrace, raw_data, uncompressed_trace_size) < + uncompressed_trace_size) { + fatal("Unable to read complete trace from file %s\n", filename); + } + + if (gzclose(compressedTrace)) { + fatal("Failed to close cache trace file '%s'\n", filename); + } +} + +void +RubySystem::unserialize(CheckpointIn &cp) +{ + uint8_t *uncompressed_trace = NULL; + + // This value should be set to the checkpoint-system's block-size. + // Optional, as checkpoints without it can be run if the + // checkpoint-system's block-size == current block-size. + uint64 block_size_bytes = getBlockSizeBytes(); + UNSERIALIZE_OPT_SCALAR(block_size_bytes); + + string cache_trace_file; + uint64 cache_trace_size = 0; + + UNSERIALIZE_SCALAR(cache_trace_file); + UNSERIALIZE_SCALAR(cache_trace_size); + cache_trace_file = cp.cptDir + "/" + cache_trace_file; + + readCompressedTrace(cache_trace_file, uncompressed_trace, + cache_trace_size); + m_warmup_enabled = true; + m_systems_to_warmup++; + + vector sequencer_map; + Sequencer* t = NULL; + for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { + sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); + if (t == NULL) t = sequencer_map[cntrl]; + } + + assert(t != NULL); + + for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { + if (sequencer_map[cntrl] == NULL) { + sequencer_map[cntrl] = t; + } + } + + m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size, + sequencer_map, block_size_bytes); +} + +void +RubySystem::startup() +{ + + // Ruby restores state from a checkpoint by resetting the clock to 0 and + // playing the requests that can possibly re-generate the cache state. + // The clock value is set to the actual checkpointed value once all the + // requests have been executed. + // + // This way of restoring state is pretty finicky. For example, if a + // Ruby component reads time before the state has been restored, it would + // cache this value and hence its clock would not be reset to 0, when + // Ruby resets the global clock. This can potentially result in a + // deadlock. + // + // The solution is that no Ruby component should read time before the + // simulation starts. And then one also needs to hope that the time + // Ruby finishes restoring the state is less than the time when the + // state was checkpointed. + + if (m_warmup_enabled) { + // save the current tick value + Tick curtick_original = curTick(); + // save the event queue head + Event* eventq_head = eventq->replaceHead(NULL); + // set curTick to 0 and reset Ruby System's clock + setCurTick(0); + resetClock(); + + // Schedule an event to start cache warmup + enqueueRubyEvent(curTick()); + simulate(); + + delete m_cache_recorder; + m_cache_recorder = NULL; + m_systems_to_warmup--; + if (m_systems_to_warmup == 0) { + m_warmup_enabled = false; + } + + // Restore eventq head + eventq_head = eventq->replaceHead(eventq_head); + // Restore curTick and Ruby System's clock + setCurTick(curtick_original); + resetClock(); + } + + resetStats(); +} + +void +RubySystem::RubyEvent::process() +{ + if (RubySystem::getWarmupEnabled()) { + m_ruby_system->m_cache_recorder->enqueueNextFetchRequest(); + } else if (RubySystem::getCooldownEnabled()) { + m_ruby_system->m_cache_recorder->enqueueNextFlushRequest(); + } +} + +void +RubySystem::resetStats() +{ + m_start_cycle = curCycle(); +} + +bool +RubySystem::functionalRead(PacketPtr pkt) +{ + Address address(pkt->getAddr()); + Address line_address(address); + line_address.makeLineAddress(); + + AccessPermission access_perm = AccessPermission_NotPresent; + int num_controllers = m_abs_cntrl_vec.size(); + + DPRINTF(RubySystem, "Functional Read request for %s\n",address); + + unsigned int num_ro = 0; + unsigned int num_rw = 0; + unsigned int num_busy = 0; + unsigned int num_backing_store = 0; + unsigned int num_invalid = 0; + + // In this loop we count the number of controllers that have the given + // address in read only, read write and busy states. + for (unsigned int i = 0; i < num_controllers; ++i) { + access_perm = m_abs_cntrl_vec[i]-> getAccessPermission(line_address); + if (access_perm == AccessPermission_Read_Only) + num_ro++; + else if (access_perm == AccessPermission_Read_Write) + num_rw++; + else if (access_perm == AccessPermission_Busy) + num_busy++; + else if (access_perm == AccessPermission_Backing_Store) + // See RubySlicc_Exports.sm for details, but Backing_Store is meant + // to represent blocks in memory *for Broadcast/Snooping protocols*, + // where memory has no idea whether it has an exclusive copy of data + // or not. + num_backing_store++; + else if (access_perm == AccessPermission_Invalid || + access_perm == AccessPermission_NotPresent) + num_invalid++; + } + assert(num_rw <= 1); + + // This if case is meant to capture what happens in a Broadcast/Snoop + // protocol where the block does not exist in the cache hierarchy. You + // only want to read from the Backing_Store memory if there is no copy in + // the cache hierarchy, otherwise you want to try to read the RO or RW + // copies existing in the cache hierarchy (covered by the else statement). + // The reason is because the Backing_Store memory could easily be stale, if + // there are copies floating around the cache hierarchy, so you want to read + // it only if it's not in the cache hierarchy at all. + if (num_invalid == (num_controllers - 1) && num_backing_store == 1) { + DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n"); + for (unsigned int i = 0; i < num_controllers; ++i) { + access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address); + if (access_perm == AccessPermission_Backing_Store) { + m_abs_cntrl_vec[i]->functionalRead(line_address, pkt); + return true; + } + } + } else if (num_ro > 0 || num_rw == 1) { + // In Broadcast/Snoop protocols, this covers if you know the block + // exists somewhere in the caching hierarchy, then you want to read any + // valid RO or RW block. In directory protocols, same thing, you want + // to read any valid readable copy of the block. + DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n", + num_busy, num_ro, num_rw); + // 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. + for (unsigned int i = 0;i < num_controllers;++i) { + access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address); + if (access_perm == AccessPermission_Read_Only || + access_perm == AccessPermission_Read_Write) { + m_abs_cntrl_vec[i]->functionalRead(line_address, pkt); + return true; + } + } + } + + return false; +} + +// The function searches through all the buffers that exist in different +// cache, directory and memory controllers, and in the network components +// and writes the data portion of those that hold the address specified +// in the packet. +bool +RubySystem::functionalWrite(PacketPtr pkt) +{ + Address addr(pkt->getAddr()); + Address line_addr = line_address(addr); + AccessPermission access_perm = AccessPermission_NotPresent; + int num_controllers = m_abs_cntrl_vec.size(); + + DPRINTF(RubySystem, "Functional Write request for %s\n",addr); + + uint32_t M5_VAR_USED num_functional_writes = 0; + + for (unsigned int i = 0; i < num_controllers;++i) { + num_functional_writes += + m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt); + + access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr); + if (access_perm != AccessPermission_Invalid && + access_perm != AccessPermission_NotPresent) { + num_functional_writes += + m_abs_cntrl_vec[i]->functionalWrite(line_addr, pkt); + } + } + + num_functional_writes += m_network->functionalWrite(pkt); + DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes); + + return true; +} + +#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 +// +// To use, the SLICC specification must call sequencer.checkCoherence(address) +// when the controller changes to a state with new permissions. Do this +// in setState. The SLICC spec must also define methods "isBlockShared" +// and "isBlockExclusive" that are specific to that protocol +// +void +RubySystem::checkGlobalCoherenceInvariant(const Address& addr) +{ +#if 0 + NodeID exclusive = -1; + bool sharedDetected = false; + NodeID lastShared = -1; + + for (int i = 0; i < m_chip_vector.size(); i++) { + if (m_chip_vector[i]->isBlockExclusive(addr)) { + if (exclusive != -1) { + // coherence violation + WARN_EXPR(exclusive); + WARN_EXPR(m_chip_vector[i]->getID()); + WARN_EXPR(addr); + WARN_EXPR(getTime()); + ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); + } else if (sharedDetected) { + WARN_EXPR(lastShared); + WARN_EXPR(m_chip_vector[i]->getID()); + WARN_EXPR(addr); + WARN_EXPR(getTime()); + ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); + } else { + exclusive = m_chip_vector[i]->getID(); + } + } else if (m_chip_vector[i]->isBlockShared(addr)) { + sharedDetected = true; + lastShared = m_chip_vector[i]->getID(); + + if (exclusive != -1) { + WARN_EXPR(lastShared); + WARN_EXPR(exclusive); + WARN_EXPR(addr); + WARN_EXPR(getTime()); + ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); + } + } + } +#endif +} +#endif + +RubySystem * +RubySystemParams::create() +{ + return new RubySystem(this); +} 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 @@ -432,17 +432,17 @@ void unset_tbe(${{self.TBEType.c_ident}} #include "base/compiler.hh" #include "base/cprintf.hh" #include "debug/RubyGenerated.hh" #include "debug/RubySlicc.hh" #include "mem/protocol/${ident}_Controller.hh" #include "mem/protocol/${ident}_Event.hh" #include "mem/protocol/${ident}_State.hh" #include "mem/protocol/Types.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" ''') for include_path in includes: code('#include "${{include_path}}"') code(''' using namespace std; ''') @@ -1039,17 +1039,17 @@ int #include "mem/protocol/${ident}_State.hh" ''') if outputRequest_types: code('''#include "mem/protocol/${ident}_RequestType.hh"''') code(''' #include "mem/protocol/Types.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" ''') for include_path in includes: code('#include "${{include_path}}"') code(''' @@ -1114,17 +1114,17 @@ void #include "base/misc.hh" #include "base/trace.hh" #include "debug/ProtocolTrace.hh" #include "debug/RubyGenerated.hh" #include "mem/protocol/${ident}_Controller.hh" #include "mem/protocol/${ident}_Event.hh" #include "mem/protocol/${ident}_State.hh" #include "mem/protocol/Types.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) #define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) #define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc deleted file mode 100644 --- a/src/mem/ruby/system/System.cc +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include - -#include "base/intmath.hh" -#include "base/statistics.hh" -#include "debug/RubyCacheTrace.hh" -#include "debug/RubySystem.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/network/Network.hh" -#include "mem/ruby/system/System.hh" -#include "mem/simple_mem.hh" -#include "sim/eventq.hh" -#include "sim/simulate.hh" - -using namespace std; - -int RubySystem::m_random_seed; -bool RubySystem::m_randomization; -uint32_t RubySystem::m_block_size_bytes; -uint32_t RubySystem::m_block_size_bits; -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_access_backing_store(p->access_backing_store) -{ - m_random_seed = p->random_seed; - srandom(m_random_seed); - m_randomization = p->randomization; - - m_block_size_bytes = p->block_size_bytes; - assert(isPowerOf2(m_block_size_bytes)); - m_block_size_bits = floorLog2(m_block_size_bytes); - m_memory_size_bits = p->memory_size_bits; - - // Resize to the size of different machine types - m_abstract_controls.resize(MachineType_NUM); - - // Collate the statistics before they are printed. - Stats::registerDumpCallback(new RubyStatsCallback(this)); - // Create the profiler - m_profiler = new Profiler(p, this); - m_phys_mem = p->phys_mem; -} - -void -RubySystem::registerNetwork(Network* network_ptr) -{ - m_network = network_ptr; -} - -void -RubySystem::registerAbstractController(AbstractController* cntrl) -{ - m_abs_cntrl_vec.push_back(cntrl); - - MachineID id = cntrl->getMachineID(); - m_abstract_controls[id.getType()][id.getNum()] = cntrl; -} - -RubySystem::~RubySystem() -{ - delete m_network; - delete m_profiler; -} - -void -RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename, - uint64 uncompressed_trace_size) -{ - // Create the checkpoint file for the memory - string thefile = CheckpointIn::dir() + "/" + filename.c_str(); - - int fd = creat(thefile.c_str(), 0664); - if (fd < 0) { - perror("creat"); - fatal("Can't open memory trace file '%s'\n", filename); - } - - gzFile compressedMemory = gzdopen(fd, "wb"); - if (compressedMemory == NULL) - fatal("Insufficient memory to allocate compression state for %s\n", - filename); - - if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) != - uncompressed_trace_size) { - fatal("Write failed on memory trace file '%s'\n", filename); - } - - if (gzclose(compressedMemory)) { - fatal("Close failed on memory trace file '%s'\n", filename); - } - delete[] raw_data; -} - -void -RubySystem::serializeOld(CheckpointOut &cp) -{ - m_cooldown_enabled = true; - vector sequencer_map; - Sequencer* sequencer_ptr = NULL; - - for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { - sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); - if (sequencer_ptr == NULL) { - sequencer_ptr = sequencer_map[cntrl]; - } - } - - assert(sequencer_ptr != NULL); - - for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { - if (sequencer_map[cntrl] == NULL) { - sequencer_map[cntrl] = sequencer_ptr; - } - } - - // Store the cache-block size, so we are able to restore on systems with a - // different cache-block size. CacheRecorder depends on the correct - // cache-block size upon unserializing. - uint64 block_size_bytes = getBlockSizeBytes(); - SERIALIZE_SCALAR(block_size_bytes); - - DPRINTF(RubyCacheTrace, "Recording Cache Trace\n"); - // Create the CacheRecorder and record the cache trace - m_cache_recorder = new CacheRecorder(NULL, 0, sequencer_map, - block_size_bytes); - - for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { - m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder); - } - - DPRINTF(RubyCacheTrace, "Cache Trace Complete\n"); - // save the current tick value - Tick curtick_original = curTick(); - // save the event queue head - Event* eventq_head = eventq->replaceHead(NULL); - DPRINTF(RubyCacheTrace, "Recording current tick %ld and event queue\n", - curtick_original); - - // Schedule an event to start cache cooldown - DPRINTF(RubyCacheTrace, "Starting cache flush\n"); - enqueueRubyEvent(curTick()); - simulate(); - DPRINTF(RubyCacheTrace, "Cache flush complete\n"); - - // Restore eventq head - eventq_head = eventq->replaceHead(eventq_head); - // Restore curTick - setCurTick(curtick_original); - - // Aggregate the trace entries together into a single array - uint8_t *raw_data = new uint8_t[4096]; - uint64 cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, - 4096); - string cache_trace_file = name() + ".cache.gz"; - writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size); - - SERIALIZE_SCALAR(cache_trace_file); - SERIALIZE_SCALAR(cache_trace_size); - - m_cooldown_enabled = false; -} - -void -RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data, - uint64& uncompressed_trace_size) -{ - // Read the trace file - gzFile compressedTrace; - - // trace file - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - perror("open"); - fatal("Unable to open trace file %s", filename); - } - - compressedTrace = gzdopen(fd, "rb"); - if (compressedTrace == NULL) { - fatal("Insufficient memory to allocate compression state for %s\n", - filename); - } - - raw_data = new uint8_t[uncompressed_trace_size]; - if (gzread(compressedTrace, raw_data, uncompressed_trace_size) < - uncompressed_trace_size) { - fatal("Unable to read complete trace from file %s\n", filename); - } - - if (gzclose(compressedTrace)) { - fatal("Failed to close cache trace file '%s'\n", filename); - } -} - -void -RubySystem::unserialize(CheckpointIn &cp) -{ - uint8_t *uncompressed_trace = NULL; - - // This value should be set to the checkpoint-system's block-size. - // Optional, as checkpoints without it can be run if the - // checkpoint-system's block-size == current block-size. - uint64 block_size_bytes = getBlockSizeBytes(); - UNSERIALIZE_OPT_SCALAR(block_size_bytes); - - string cache_trace_file; - uint64 cache_trace_size = 0; - - UNSERIALIZE_SCALAR(cache_trace_file); - UNSERIALIZE_SCALAR(cache_trace_size); - cache_trace_file = cp.cptDir + "/" + cache_trace_file; - - readCompressedTrace(cache_trace_file, uncompressed_trace, - cache_trace_size); - m_warmup_enabled = true; - m_systems_to_warmup++; - - vector sequencer_map; - Sequencer* t = NULL; - for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { - sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer()); - if (t == NULL) t = sequencer_map[cntrl]; - } - - assert(t != NULL); - - for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) { - if (sequencer_map[cntrl] == NULL) { - sequencer_map[cntrl] = t; - } - } - - m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size, - sequencer_map, block_size_bytes); -} - -void -RubySystem::startup() -{ - - // Ruby restores state from a checkpoint by resetting the clock to 0 and - // playing the requests that can possibly re-generate the cache state. - // The clock value is set to the actual checkpointed value once all the - // requests have been executed. - // - // This way of restoring state is pretty finicky. For example, if a - // Ruby component reads time before the state has been restored, it would - // cache this value and hence its clock would not be reset to 0, when - // Ruby resets the global clock. This can potentially result in a - // deadlock. - // - // The solution is that no Ruby component should read time before the - // simulation starts. And then one also needs to hope that the time - // Ruby finishes restoring the state is less than the time when the - // state was checkpointed. - - if (m_warmup_enabled) { - // save the current tick value - Tick curtick_original = curTick(); - // save the event queue head - Event* eventq_head = eventq->replaceHead(NULL); - // set curTick to 0 and reset Ruby System's clock - setCurTick(0); - resetClock(); - - // Schedule an event to start cache warmup - enqueueRubyEvent(curTick()); - simulate(); - - delete m_cache_recorder; - m_cache_recorder = NULL; - m_systems_to_warmup--; - if (m_systems_to_warmup == 0) { - m_warmup_enabled = false; - } - - // Restore eventq head - eventq_head = eventq->replaceHead(eventq_head); - // Restore curTick and Ruby System's clock - setCurTick(curtick_original); - resetClock(); - } - - resetStats(); -} - -void -RubySystem::RubyEvent::process() -{ - if (RubySystem::getWarmupEnabled()) { - m_ruby_system->m_cache_recorder->enqueueNextFetchRequest(); - } else if (RubySystem::getCooldownEnabled()) { - m_ruby_system->m_cache_recorder->enqueueNextFlushRequest(); - } -} - -void -RubySystem::resetStats() -{ - m_start_cycle = curCycle(); -} - -bool -RubySystem::functionalRead(PacketPtr pkt) -{ - Address address(pkt->getAddr()); - Address line_address(address); - line_address.makeLineAddress(); - - AccessPermission access_perm = AccessPermission_NotPresent; - int num_controllers = m_abs_cntrl_vec.size(); - - DPRINTF(RubySystem, "Functional Read request for %s\n",address); - - unsigned int num_ro = 0; - unsigned int num_rw = 0; - unsigned int num_busy = 0; - unsigned int num_backing_store = 0; - unsigned int num_invalid = 0; - - // In this loop we count the number of controllers that have the given - // address in read only, read write and busy states. - for (unsigned int i = 0; i < num_controllers; ++i) { - access_perm = m_abs_cntrl_vec[i]-> getAccessPermission(line_address); - if (access_perm == AccessPermission_Read_Only) - num_ro++; - else if (access_perm == AccessPermission_Read_Write) - num_rw++; - else if (access_perm == AccessPermission_Busy) - num_busy++; - else if (access_perm == AccessPermission_Backing_Store) - // See RubySlicc_Exports.sm for details, but Backing_Store is meant - // to represent blocks in memory *for Broadcast/Snooping protocols*, - // where memory has no idea whether it has an exclusive copy of data - // or not. - num_backing_store++; - else if (access_perm == AccessPermission_Invalid || - access_perm == AccessPermission_NotPresent) - num_invalid++; - } - assert(num_rw <= 1); - - // This if case is meant to capture what happens in a Broadcast/Snoop - // protocol where the block does not exist in the cache hierarchy. You - // only want to read from the Backing_Store memory if there is no copy in - // the cache hierarchy, otherwise you want to try to read the RO or RW - // copies existing in the cache hierarchy (covered by the else statement). - // The reason is because the Backing_Store memory could easily be stale, if - // there are copies floating around the cache hierarchy, so you want to read - // it only if it's not in the cache hierarchy at all. - if (num_invalid == (num_controllers - 1) && num_backing_store == 1) { - DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n"); - for (unsigned int i = 0; i < num_controllers; ++i) { - access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address); - if (access_perm == AccessPermission_Backing_Store) { - m_abs_cntrl_vec[i]->functionalRead(line_address, pkt); - return true; - } - } - } else if (num_ro > 0 || num_rw == 1) { - // In Broadcast/Snoop protocols, this covers if you know the block - // exists somewhere in the caching hierarchy, then you want to read any - // valid RO or RW block. In directory protocols, same thing, you want - // to read any valid readable copy of the block. - DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n", - num_busy, num_ro, num_rw); - // 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. - for (unsigned int i = 0;i < num_controllers;++i) { - access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address); - if (access_perm == AccessPermission_Read_Only || - access_perm == AccessPermission_Read_Write) { - m_abs_cntrl_vec[i]->functionalRead(line_address, pkt); - return true; - } - } - } - - return false; -} - -// The function searches through all the buffers that exist in different -// cache, directory and memory controllers, and in the network components -// and writes the data portion of those that hold the address specified -// in the packet. -bool -RubySystem::functionalWrite(PacketPtr pkt) -{ - Address addr(pkt->getAddr()); - Address line_addr = line_address(addr); - AccessPermission access_perm = AccessPermission_NotPresent; - int num_controllers = m_abs_cntrl_vec.size(); - - DPRINTF(RubySystem, "Functional Write request for %s\n",addr); - - uint32_t M5_VAR_USED num_functional_writes = 0; - - for (unsigned int i = 0; i < num_controllers;++i) { - num_functional_writes += - m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt); - - access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr); - if (access_perm != AccessPermission_Invalid && - access_perm != AccessPermission_NotPresent) { - num_functional_writes += - m_abs_cntrl_vec[i]->functionalWrite(line_addr, pkt); - } - } - - num_functional_writes += m_network->functionalWrite(pkt); - DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes); - - return true; -} - -#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 -// -// To use, the SLICC specification must call sequencer.checkCoherence(address) -// when the controller changes to a state with new permissions. Do this -// in setState. The SLICC spec must also define methods "isBlockShared" -// and "isBlockExclusive" that are specific to that protocol -// -void -RubySystem::checkGlobalCoherenceInvariant(const Address& addr) -{ -#if 0 - NodeID exclusive = -1; - bool sharedDetected = false; - NodeID lastShared = -1; - - for (int i = 0; i < m_chip_vector.size(); i++) { - if (m_chip_vector[i]->isBlockExclusive(addr)) { - if (exclusive != -1) { - // coherence violation - WARN_EXPR(exclusive); - WARN_EXPR(m_chip_vector[i]->getID()); - WARN_EXPR(addr); - WARN_EXPR(getTime()); - ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); - } else if (sharedDetected) { - WARN_EXPR(lastShared); - WARN_EXPR(m_chip_vector[i]->getID()); - WARN_EXPR(addr); - WARN_EXPR(getTime()); - ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); - } else { - exclusive = m_chip_vector[i]->getID(); - } - } else if (m_chip_vector[i]->isBlockShared(addr)) { - sharedDetected = true; - lastShared = m_chip_vector[i]->getID(); - - if (exclusive != -1) { - WARN_EXPR(lastShared); - WARN_EXPR(exclusive); - WARN_EXPR(addr); - WARN_EXPR(getTime()); - ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); - } - } - } -#endif -} -#endif - -RubySystem * -RubySystemParams::create() -{ - return new RubySystem(this); -} diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh deleted file mode 100644 --- a/src/mem/ruby/system/System.hh +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Contains all of the various parts of the system we are simulating. - * Performs allocation, deallocation, and setup of all the major - * components of the system - */ - -#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__ -#define __MEM_RUBY_SYSTEM_SYSTEM_HH__ - -#include "base/callback.hh" -#include "base/output.hh" -#include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/slicc_interface/AbstractController.hh" -#include "mem/ruby/system/CacheRecorder.hh" -#include "mem/packet.hh" -#include "params/RubySystem.hh" -#include "sim/clocked_object.hh" - -class Network; -class AbstractController; - -class RubySystem : public ClockedObject -{ - public: - class RubyEvent : public Event - { - public: - RubyEvent(RubySystem* _ruby_system) - { - m_ruby_system = _ruby_system; - } - private: - void process(); - - RubySystem* m_ruby_system; - }; - - friend class RubyEvent; - - typedef RubySystemParams Params; - RubySystem(const Params *p); - ~RubySystem(); - - // config accessors - static int getRandomSeed() { return m_random_seed; } - static int getRandomization() { return m_randomization; } - static uint32_t getBlockSizeBytes() { return m_block_size_bytes; } - static uint32_t getBlockSizeBits() { return m_block_size_bits; } - static uint32_t getMemorySizeBits() { return m_memory_size_bits; } - static bool getWarmupEnabled() { return m_warmup_enabled; } - static bool getCooldownEnabled() { return m_cooldown_enabled; } - - SimpleMemory *getPhysMem() { return m_phys_mem; } - Cycles getStartCycle() { return m_start_cycle; } - const bool getAccessBackingStore() { return m_access_backing_store; } - - // Public Methods - Profiler* - getProfiler() - { - assert(m_profiler != NULL); - return m_profiler; - } - - void regStats() { m_profiler->regStats(name()); } - void collateStats() { m_profiler->collateStats(); } - void resetStats(); - - void serializeOld(CheckpointOut &cp) M5_ATTR_OVERRIDE; - void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; - void process(); - void startup(); - bool functionalRead(Packet *ptr); - bool functionalWrite(Packet *ptr); - - void registerNetwork(Network*); - void registerAbstractController(AbstractController*); - - bool eventQueueEmpty() { return eventq->empty(); } - void enqueueRubyEvent(Tick tick) - { - RubyEvent* e = new RubyEvent(this); - schedule(e, tick); - } - - private: - // Private copy constructor and assignment operator - RubySystem(const RubySystem& obj); - RubySystem& operator=(const RubySystem& obj); - - void readCompressedTrace(std::string filename, - uint8_t *&raw_data, - uint64& uncompressed_trace_size); - void writeCompressedTrace(uint8_t *raw_data, std::string file, - uint64 uncompressed_trace_size); - - private: - // configuration parameters - static int m_random_seed; - static bool m_randomization; - static uint32_t m_block_size_bytes; - static uint32_t m_block_size_bits; - static uint32_t m_memory_size_bits; - - static bool m_warmup_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; - Cycles m_start_cycle; - - public: - Profiler* m_profiler; - CacheRecorder* m_cache_recorder; - std::vector > m_abstract_controls; -}; - -class RubyStatsCallback : public Callback -{ - private: - RubySystem *m_ruby_system; - - public: - virtual ~RubyStatsCallback() {} - RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {} - void process() { m_ruby_system->collateStats(); } -}; - -#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ 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 @@ -33,18 +33,18 @@ #include "debug/MemoryAccess.hh" #include "debug/ProtocolTrace.hh" #include "debug/RubySequencer.hh" #include "debug/RubyStats.hh" #include "mem/protocol/PrefetchBit.hh" #include "mem/protocol/RubyAccessMode.hh" #include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/slicc_interface/RubyRequest.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" #include "mem/packet.hh" #include "sim/system.hh" using namespace std; Sequencer * RubySequencerParams::create() { diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -28,17 +28,17 @@ # # Authors: Nathan Binkert Import('*') if env['PROTOCOL'] == 'None': Return() +SimObject('RubySystem.py') SimObject('Sequencer.py') -SimObject('RubySystem.py') Source('CacheRecorder.cc') Source('DMASequencer.cc') Source('RubyPort.cc') Source('RubyPortProxy.cc') +Source('RubySystem.cc') Source('Sequencer.cc') -Source('System.cc') diff --git a/src/mem/ruby/system/RubySystem.py b/src/mem/ruby/system/RubySystem.py --- a/src/mem/ruby/system/RubySystem.py +++ b/src/mem/ruby/system/RubySystem.py @@ -28,17 +28,17 @@ # Brad Beckmann from m5.params import * from ClockedObject import ClockedObject from SimpleMemory import * class RubySystem(ClockedObject): type = 'RubySystem' - cxx_header = "mem/ruby/system/System.hh" + cxx_header = "mem/ruby/system/RubySystem.hh" random_seed = Param.Int(1234, "random seed used by the simulation"); randomization = Param.Bool(False, "insert random delays on message enqueue times"); block_size_bytes = Param.UInt32(64, "default cache block size; must be a power of two"); memory_size_bits = Param.UInt32(64, "number of bits that a memory address requires"); 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 @@ -28,17 +28,17 @@ #include "base/intmath.hh" #include "debug/RubyCache.hh" #include "debug/RubyCacheTrace.hh" #include "debug/RubyResourceStalls.hh" #include "debug/RubyStats.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/structures/CacheMemory.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; ostream& operator<<(ostream& out, const CacheMemory& obj) { obj.print(out); out << flush; 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 @@ -26,17 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Author: Brad Beckmann * */ #include "base/intmath.hh" #include "mem/ruby/structures/BankedArray.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" BankedArray::BankedArray(unsigned int banks, Cycles accessLatency, unsigned int startIndexBit, RubySystem *rs) : m_ruby_system(rs) { this->banks = banks; this->accessLatency = accessLatency; this->startIndexBit = startIndexBit; 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 @@ -30,17 +30,17 @@ */ #ifndef __MEM_RUBY_STRUCTURES_BANKEDARRAY_HH__ #define __MEM_RUBY_STRUCTURES_BANKEDARRAY_HH__ #include #include "mem/ruby/common/TypeDefines.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "sim/core.hh" class BankedArray { private: unsigned int banks; Cycles accessLatency; unsigned int bankBits; 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 @@ -26,17 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/intmath.hh" #include "debug/RubyCache.hh" #include "debug/RubyStats.hh" #include "mem/ruby/slicc_interface/RubySlicc_Util.hh" #include "mem/ruby/structures/DirectoryMemory.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; int DirectoryMemory::m_num_directories = 0; int DirectoryMemory::m_num_directories_bits = 0; uint64_t DirectoryMemory::m_total_size_bytes = 0; int DirectoryMemory::m_numa_high_bit = 0; 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 @@ -33,17 +33,17 @@ #include #include "base/statistics.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/network/MessageBuffer.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/RubyRequest.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "params/Prefetcher.hh" #include "sim/sim_object.hh" #include "sim/system.hh" #define MAX_PF_INFLIGHT 8 class PrefetchEntry { diff --git a/src/mem/ruby/system/RubySystem.hh b/src/mem/ruby/system/RubySystem.hh new file mode 100644 --- /dev/null +++ b/src/mem/ruby/system/RubySystem.hh @@ -0,0 +1,160 @@ +/* + * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Contains all of the various parts of the system we are simulating. + * Performs allocation, deallocation, and setup of all the major + * components of the system + */ + +#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__ +#define __MEM_RUBY_SYSTEM_SYSTEM_HH__ + +#include "base/callback.hh" +#include "base/output.hh" +#include "mem/ruby/profiler/Profiler.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/system/CacheRecorder.hh" +#include "mem/packet.hh" +#include "params/RubySystem.hh" +#include "sim/clocked_object.hh" + +class Network; +class AbstractController; + +class RubySystem : public ClockedObject +{ + public: + class RubyEvent : public Event + { + public: + RubyEvent(RubySystem* _ruby_system) + { + m_ruby_system = _ruby_system; + } + private: + void process(); + + RubySystem* m_ruby_system; + }; + + friend class RubyEvent; + + typedef RubySystemParams Params; + RubySystem(const Params *p); + ~RubySystem(); + + // config accessors + static int getRandomSeed() { return m_random_seed; } + static int getRandomization() { return m_randomization; } + static uint32_t getBlockSizeBytes() { return m_block_size_bytes; } + static uint32_t getBlockSizeBits() { return m_block_size_bits; } + static uint32_t getMemorySizeBits() { return m_memory_size_bits; } + static bool getWarmupEnabled() { return m_warmup_enabled; } + static bool getCooldownEnabled() { return m_cooldown_enabled; } + + SimpleMemory *getPhysMem() { return m_phys_mem; } + Cycles getStartCycle() { return m_start_cycle; } + const bool getAccessBackingStore() { return m_access_backing_store; } + + // Public Methods + Profiler* + getProfiler() + { + assert(m_profiler != NULL); + return m_profiler; + } + + void regStats() { m_profiler->regStats(name()); } + void collateStats() { m_profiler->collateStats(); } + void resetStats(); + + void serializeOld(CheckpointOut &cp) M5_ATTR_OVERRIDE; + void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; + void process(); + void startup(); + bool functionalRead(Packet *ptr); + bool functionalWrite(Packet *ptr); + + void registerNetwork(Network*); + void registerAbstractController(AbstractController*); + + bool eventQueueEmpty() { return eventq->empty(); } + void enqueueRubyEvent(Tick tick) + { + RubyEvent* e = new RubyEvent(this); + schedule(e, tick); + } + + private: + // Private copy constructor and assignment operator + RubySystem(const RubySystem& obj); + RubySystem& operator=(const RubySystem& obj); + + void readCompressedTrace(std::string filename, + uint8_t *&raw_data, + uint64& uncompressed_trace_size); + void writeCompressedTrace(uint8_t *raw_data, std::string file, + uint64 uncompressed_trace_size); + + private: + // configuration parameters + static int m_random_seed; + static bool m_randomization; + static uint32_t m_block_size_bytes; + static uint32_t m_block_size_bits; + static uint32_t m_memory_size_bits; + + static bool m_warmup_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; + Cycles m_start_cycle; + + public: + Profiler* m_profiler; + CacheRecorder* m_cache_recorder; + std::vector > m_abstract_controls; +}; + +class RubyStatsCallback : public Callback +{ + private: + RubySystem *m_ruby_system; + + public: + virtual ~RubyStatsCallback() {} + RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {} + void process() { m_ruby_system->collateStats(); } +}; + +#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ 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 @@ -42,17 +42,17 @@ #ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ #define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ #include #include #include "mem/protocol/RequestStatus.hh" #include "mem/ruby/network/MessageBuffer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/mem_object.hh" #include "mem/tport.hh" #include "params/RubyPort.hh" class AbstractController; class RubyPort : public MemObject { 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 @@ -29,17 +29,17 @@ #include #include "debug/Config.hh" #include "debug/Drain.hh" #include "debug/RubyDma.hh" #include "debug/RubyStats.hh" #include "mem/protocol/SequencerMsg.hh" #include "mem/ruby/system/DMASequencer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "sim/system.hh" DMASequencer::DMASequencer(const Params *p) : MemObject(p), m_ruby_system(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, p->ruby_system->getAccessBackingStore()), 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 @@ -32,17 +32,17 @@ #include #include #include "mem/mem_object.hh" #include "mem/protocol/DMASequencerRequestType.hh" #include "mem/protocol/RequestStatus.hh" #include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/network/MessageBuffer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/simple_mem.hh" #include "mem/tport.hh" #include "params/DMASequencer.hh" class AbstractController; struct DMARequest { 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 @@ -24,18 +24,18 @@ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "debug/RubyCacheTrace.hh" #include "mem/ruby/system/CacheRecorder.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" using namespace std; void TraceRecord::print(ostream& out) const { out << "[TraceRecord: Node, " << m_cntrl_id << ", " << m_data_address << ", " << m_pc_address << ", " diff --git a/src/mem/ruby/structures/WireBuffer.cc b/src/mem/ruby/structures/WireBuffer.cc --- a/src/mem/ruby/structures/WireBuffer.cc +++ b/src/mem/ruby/structures/WireBuffer.cc @@ -30,17 +30,17 @@ */ #include #include #include "base/cprintf.hh" #include "base/stl_helpers.hh" #include "mem/ruby/structures/WireBuffer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; // Output operator definition ostream& operator<<(ostream& out, const WireBuffer& obj) { 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 @@ -22,17 +22,17 @@ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mem/ruby/structures/TimerTable.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" TimerTable::TimerTable() : m_next_time(0) { m_consumer_ptr = NULL; m_clockobj_ptr = NULL; m_next_valid = false; 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 @@ -109,17 +109,17 @@ #include "base/cprintf.hh" #include "base/random.hh" #include "debug/RubyMemory.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/slicc_interface/Message.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/structures/RubyMemoryControl.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; // Value to reset watchdog timer to. // If we're idle for this many memory control cycles, // shut down our clock (our rescheduling of ourselves). // Refresh shuts down as well. // When we restart, we'll be in a different phase 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 @@ -34,17 +34,17 @@ #include #include #include "mem/abstract_mem.hh" #include "mem/protocol/MemoryMsg.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/profiler/MemCntrlProfiler.hh" #include "mem/ruby/structures/MemoryNode.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "params/RubyMemoryControl.hh" // This constant is part of the definition of tFAW; see // the comments in header to RubyMemoryControl.cc #define ACTIVATE_PER_TFAW 4 ////////////////////////////////////////////////////////////////////////////// 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 @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "debug/RubyPrefetcher.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/structures/Prefetcher.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" Prefetcher* PrefetcherParams::create() { return new Prefetcher(this); } Prefetcher::Prefetcher(const Params *p) 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 @@ -394,17 +394,17 @@ operator<<(std::ostream& out, const ${{s * * Auto generated C++ code started by $__file__:$__line__ */ #include #include #include "mem/protocol/${{self.c_ident}}.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; ''') code(''' /** \\brief Print the state of this object */ void ${{self.c_ident}}::print(ostream& out) const 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 @@ -23,18 +23,18 @@ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mem/protocol/MemoryMsg.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" #include "sim/system.hh" AbstractController::AbstractController(const Params *p) : MemObject(p), Consumer(this), m_version(p->version), m_clusterID(p->cluster_id), m_masterId(p->system->getMasterId(name())), m_is_blocking(false), m_number_of_TBEs(p->number_of_TBEs), m_transitions_per_cycle(p->transitions_per_cycle), 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 @@ -30,17 +30,17 @@ #include "base/cast.hh" #include "base/cprintf.hh" #include "debug/RubyNetwork.hh" #include "mem/ruby/network/simple/Throttle.hh" #include "mem/ruby/network/MessageBuffer.hh" #include "mem/ruby/network/Network.hh" #include "mem/ruby/slicc_interface/Message.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; const int MESSAGE_SIZE_MULTIPLIER = 1000; //const int BROADCAST_SCALING = 4; // Have a 16p system act like a 64p systems const int BROADCAST_SCALING = 1; const int PRIORITY_SWITCH_LIMIT = 128; 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 @@ -39,17 +39,17 @@ #define __MEM_RUBY_NETWORK_SIMPLE_THROTTLE_HH__ #include #include #include #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/network/Network.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" class MessageBuffer; class Throttle : public Consumer { public: Throttle(int sID, RubySystem *rs, NodeID node, Cycles link_latency, int link_bandwidth_multiplier, int endpoint_bandwidth, diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -33,17 +33,17 @@ #include "base/stl_helpers.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/network/MessageBuffer.hh" #include "mem/ruby/network/simple/SimpleLink.hh" #include "mem/ruby/network/simple/SimpleNetwork.hh" #include "mem/ruby/network/simple/Switch.hh" #include "mem/ruby/network/simple/Throttle.hh" #include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; using m5::stl_helpers::deletePointers; SimpleNetwork::SimpleNetwork(const Params *p) : Network(p) { m_buffer_size = p->buffer_size; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc @@ -34,17 +34,17 @@ #include "base/stl_helpers.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/network/BasicLink.hh" #include "mem/ruby/network/garnet/flexible-pipeline/GarnetLink.hh" #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh" #include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh" #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh" #include "mem/ruby/network/garnet/flexible-pipeline/Router.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; using m5::stl_helpers::deletePointers; GarnetNetwork::GarnetNetwork(const Params *p) : BaseGarnetNetwork(p) { m_buffer_size = p->buffer_size; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc @@ -24,17 +24,17 @@ * 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: Niket Agarwal */ #include "mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" OutVcState_d::OutVcState_d(int id, GarnetNetwork_d *network_ptr) : m_time(0) { m_id = id; m_vc_state = IDLE_; if (network_ptr->get_vnet_type(id) == DATA_VNET_) diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc @@ -34,17 +34,17 @@ #include "base/stl_helpers.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; using m5::stl_helpers::deletePointers; GarnetNetwork_d::GarnetNetwork_d(const Params *p) : BaseGarnetNetwork(p) { m_buffers_per_data_vc = p->buffers_per_data_vc; 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 @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/misc.hh" #include "mem/ruby/network/BasicLink.hh" #include "mem/ruby/network/Network.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" uint32_t Network::m_virtual_networks; uint32_t Network::m_control_msg_size; uint32_t Network::m_data_msg_size; Network::Network(const Params *p) : ClockedObject(p) { 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 @@ -29,17 +29,17 @@ #include #include "base/cprintf.hh" #include "base/misc.hh" #include "base/random.hh" #include "base/stl_helpers.hh" #include "debug/RubyQueue.hh" #include "mem/ruby/network/MessageBuffer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; using m5::stl_helpers::operator<<; MessageBuffer::MessageBuffer(const string &name) : m_time_last_time_size_checked(0), m_time_last_time_enqueue(0), m_time_last_time_pop(0), m_last_arrival_time(0) { diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.cc b/src/mem/ruby/filters/NonCountingBloomFilter.cc --- a/src/mem/ruby/filters/NonCountingBloomFilter.cc +++ b/src/mem/ruby/filters/NonCountingBloomFilter.cc @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/NonCountingBloomFilter.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; NonCountingBloomFilter::NonCountingBloomFilter(string str) { string head, tail; #ifndef NDEBUG bool success = diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.cc b/src/mem/ruby/filters/MultiGrainBloomFilter.cc --- a/src/mem/ruby/filters/MultiGrainBloomFilter.cc +++ b/src/mem/ruby/filters/MultiGrainBloomFilter.cc @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/MultiGrainBloomFilter.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; MultiGrainBloomFilter::MultiGrainBloomFilter(string str) { string head, tail; #ifndef NDEBUG bool success = diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc --- a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc +++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/LSB_CountingBloomFilter.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; LSB_CountingBloomFilter::LSB_CountingBloomFilter(string str) { string head, tail; #ifndef NDEBUG bool success = 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 @@ -26,17 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/BulkBloomFilter.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; BulkBloomFilter::BulkBloomFilter(string str) { string head, tail; #ifndef NDEBUG diff --git a/src/mem/ruby/filters/BlockBloomFilter.cc b/src/mem/ruby/filters/BlockBloomFilter.cc --- a/src/mem/ruby/filters/BlockBloomFilter.cc +++ b/src/mem/ruby/filters/BlockBloomFilter.cc @@ -24,17 +24,17 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/intmath.hh" #include "base/str.hh" #include "mem/ruby/filters/BlockBloomFilter.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; BlockBloomFilter::BlockBloomFilter(string str) { string head, tail; #ifndef NDEBUG 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 @@ -22,17 +22,17 @@ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mem/ruby/common/DataBlock.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" DataBlock::DataBlock(const DataBlock &cp) { m_data = new uint8_t[RubySystem::getBlockSizeBytes()]; memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes()); m_alloc = true; } diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc --- a/src/mem/ruby/common/Address.cc +++ b/src/mem/ruby/common/Address.cc @@ -22,17 +22,17 @@ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mem/ruby/common/Address.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" physical_address_t Address::getLineAddress() const { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } physical_address_t 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 @@ -39,17 +39,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/misc.hh" #include "cpu/testers/rubytest/Check.hh" #include "cpu/testers/rubytest/RubyTester.hh" #include "debug/RubyTest.hh" #include "mem/ruby/common/SubBlock.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" #include "sim/sim_exit.hh" #include "sim/system.hh" RubyTester::RubyTester(const Params *p) : MemObject(p), checkStartEvent(this), _masterId(p->system->getMasterId(name())), m_checkTable_ptr(nullptr), m_num_cpus(p->num_cpus), # Node ID 8bdfe8dd9c2bfedc976349e9805172d71911e72a # Parent 5ee72f4b293152dd0c75ab402a49696d6903e604 diff --git a/src/cpu/testers/rubytest/Check.cc b/src/cpu/testers/rubytest/Check.cc --- a/src/cpu/testers/rubytest/Check.cc +++ b/src/cpu/testers/rubytest/Check.cc @@ -26,18 +26,18 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "base/random.hh" #include "cpu/testers/rubytest/Check.hh" #include "debug/RubyTest.hh" #include "mem/ruby/common/SubBlock.hh" +#include "mem/ruby/system/RubySystem.hh" #include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" typedef RubyTester::SenderState SenderState; Check::Check(const Address& address, const Address& pc, int _num_writers, int _num_readers, RubyTester* _tester) : m_num_writers(_num_writers), m_num_readers(_num_readers), m_tester_ptr(_tester) {