From b6b972da99c22903671fd86c5d02dcc6657a18b8 Mon Sep 17 00:00:00 2001 From: David Hashe Date: Wed, 16 Sep 2015 12:03:03 -0400 Subject: ruby: rename System.{hh,cc} to RubySystem.{hh,cc} The eventual aim of this change is to pass RubySystem pointers through to objects generated from the SLICC protocol code. Because some of these objects need to dereference their RubySystem pointers, they need access to the System.hh header file. In src/mem/ruby/SConscript, the MakeInclude function creates single-line header files in the build directory that do nothing except include the corresponding header file from the source tree. However, SLICC also generates a list of header files from its symbol table, and writes it to mem/protocol/Types.hh in the build directory. This code assumes that the header file name is the same as the class name. The end result of this is the many of the generated slicc files try to include RubySystem.hh, when the file they really need is System.hh. The path of least resistence is just to rename System.hh to RubySystem.hh. --HG-- rename : src/mem/ruby/system/System.cc => src/mem/ruby/system/RubySystem.cc rename : src/mem/ruby/system/System.hh => src/mem/ruby/system/RubySystem.hh --- src/mem/ruby/common/Address.cc | 3 +- src/mem/ruby/common/DataBlock.cc | 2 +- src/mem/ruby/filters/BlockBloomFilter.cc | 2 +- src/mem/ruby/filters/BulkBloomFilter.cc | 2 +- src/mem/ruby/filters/LSB_CountingBloomFilter.cc | 2 +- src/mem/ruby/filters/MultiGrainBloomFilter.cc | 2 +- src/mem/ruby/filters/NonCountingBloomFilter.cc | 2 +- src/mem/ruby/network/MessageBuffer.cc | 2 +- src/mem/ruby/network/Network.cc | 2 +- .../garnet/fixed-pipeline/GarnetNetwork_d.cc | 2 +- .../network/garnet/fixed-pipeline/OutVcState_d.cc | 3 +- .../garnet/flexible-pipeline/GarnetNetwork.cc | 2 +- src/mem/ruby/network/simple/SimpleNetwork.cc | 2 +- src/mem/ruby/network/simple/Throttle.cc | 2 +- src/mem/ruby/network/simple/Throttle.hh | 2 +- src/mem/ruby/slicc_interface/AbstractController.cc | 2 +- src/mem/ruby/structures/BankedArray.cc | 2 +- src/mem/ruby/structures/BankedArray.hh | 2 +- src/mem/ruby/structures/CacheMemory.cc | 2 +- src/mem/ruby/structures/DirectoryMemory.cc | 2 +- src/mem/ruby/structures/Prefetcher.cc | 2 +- src/mem/ruby/structures/Prefetcher.hh | 2 +- src/mem/ruby/structures/RubyMemoryControl.cc | 2 +- src/mem/ruby/structures/RubyMemoryControl.hh | 2 +- src/mem/ruby/structures/TimerTable.cc | 3 +- src/mem/ruby/structures/WireBuffer.cc | 5 +- src/mem/ruby/system/CacheRecorder.cc | 2 +- src/mem/ruby/system/DMASequencer.cc | 2 +- src/mem/ruby/system/DMASequencer.hh | 2 +- src/mem/ruby/system/RubyPort.hh | 2 +- src/mem/ruby/system/RubySystem.cc | 567 +++++++++++++++++++++ src/mem/ruby/system/RubySystem.hh | 164 ++++++ src/mem/ruby/system/RubySystem.py | 2 +- src/mem/ruby/system/SConscript | 4 +- src/mem/ruby/system/Sequencer.cc | 2 +- src/mem/ruby/system/System.cc | 566 -------------------- src/mem/ruby/system/System.hh | 164 ------ src/mem/slicc/symbols/StateMachine.py | 6 +- src/mem/slicc/symbols/Type.py | 2 +- 39 files changed, 774 insertions(+), 769 deletions(-) create mode 100644 src/mem/ruby/system/RubySystem.cc create mode 100644 src/mem/ruby/system/RubySystem.hh delete mode 100644 src/mem/ruby/system/System.cc delete mode 100644 src/mem/ruby/system/System.hh diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc index 8d8800501..d9fadf128 100644 --- a/src/mem/ruby/common/Address.cc +++ b/src/mem/ruby/common/Address.cc @@ -27,7 +27,8 @@ */ #include "mem/ruby/common/Address.hh" -#include "mem/ruby/system/System.hh" + +#include "mem/ruby/system/RubySystem.hh" Addr bitSelect(Addr addr, unsigned int small, unsigned int big) diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc index 2a292444a..fb2e956e0 100644 --- a/src/mem/ruby/common/DataBlock.cc +++ b/src/mem/ruby/common/DataBlock.cc @@ -27,7 +27,7 @@ */ #include "mem/ruby/common/DataBlock.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" DataBlock::DataBlock(const DataBlock &cp) { diff --git a/src/mem/ruby/filters/BlockBloomFilter.cc b/src/mem/ruby/filters/BlockBloomFilter.cc index c902f9f38..94e748d6e 100644 --- a/src/mem/ruby/filters/BlockBloomFilter.cc +++ b/src/mem/ruby/filters/BlockBloomFilter.cc @@ -29,7 +29,7 @@ #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; diff --git a/src/mem/ruby/filters/BulkBloomFilter.cc b/src/mem/ruby/filters/BulkBloomFilter.cc index 953add219..c656776a4 100644 --- a/src/mem/ruby/filters/BulkBloomFilter.cc +++ b/src/mem/ruby/filters/BulkBloomFilter.cc @@ -31,7 +31,7 @@ #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; diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc index 265e58625..1c2d4fea6 100644 --- a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc +++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc @@ -29,7 +29,7 @@ #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; diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.cc b/src/mem/ruby/filters/MultiGrainBloomFilter.cc index 33d80f0c4..52aae0b55 100644 --- a/src/mem/ruby/filters/MultiGrainBloomFilter.cc +++ b/src/mem/ruby/filters/MultiGrainBloomFilter.cc @@ -29,7 +29,7 @@ #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; diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.cc b/src/mem/ruby/filters/NonCountingBloomFilter.cc index 14bb3a245..a8d00c8d7 100644 --- a/src/mem/ruby/filters/NonCountingBloomFilter.cc +++ b/src/mem/ruby/filters/NonCountingBloomFilter.cc @@ -29,7 +29,7 @@ #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; diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc index a72d8509e..b07bdbdca 100644 --- a/src/mem/ruby/network/MessageBuffer.cc +++ b/src/mem/ruby/network/MessageBuffer.cc @@ -34,7 +34,7 @@ #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<<; diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index 5d0ff980c..d35b909d9 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -29,7 +29,7 @@ #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; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc index 196ebb089..4d5846f55 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc @@ -39,7 +39,7 @@ #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; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc index d0a422f1f..39cfc00b5 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc @@ -29,7 +29,8 @@ */ #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) diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc index 87418b6b1..83cbe8d51 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc @@ -39,7 +39,7 @@ #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; diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index eb3bec256..c10d1cce8 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -38,7 +38,7 @@ #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; diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc index c97531e58..01d1f6fbe 100644 --- a/src/mem/ruby/network/simple/Throttle.cc +++ b/src/mem/ruby/network/simple/Throttle.cc @@ -36,7 +36,7 @@ #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; diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh index 405593bb1..bf70c3075 100644 --- a/src/mem/ruby/network/simple/Throttle.hh +++ b/src/mem/ruby/network/simple/Throttle.hh @@ -44,7 +44,7 @@ #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 Switch; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 9ed8b08d0..5bd38195a 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -30,8 +30,8 @@ #include "debug/RubyQueue.hh" #include "mem/protocol/MemoryMsg.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) diff --git a/src/mem/ruby/structures/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc index b25962df6..550693ca2 100644 --- a/src/mem/ruby/structures/BankedArray.cc +++ b/src/mem/ruby/structures/BankedArray.cc @@ -31,7 +31,7 @@ #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) diff --git a/src/mem/ruby/structures/BankedArray.hh b/src/mem/ruby/structures/BankedArray.hh index 179676f19..e2359afc9 100644 --- a/src/mem/ruby/structures/BankedArray.hh +++ b/src/mem/ruby/structures/BankedArray.hh @@ -35,7 +35,7 @@ #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 diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc index 931f58a8e..a269d4f5b 100644 --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -34,7 +34,7 @@ #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; diff --git a/src/mem/ruby/structures/DirectoryMemory.cc b/src/mem/ruby/structures/DirectoryMemory.cc index 82388a895..267c07174 100644 --- a/src/mem/ruby/structures/DirectoryMemory.cc +++ b/src/mem/ruby/structures/DirectoryMemory.cc @@ -31,7 +31,7 @@ #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; diff --git a/src/mem/ruby/structures/Prefetcher.cc b/src/mem/ruby/structures/Prefetcher.cc index fbf027bef..d12665ae9 100644 --- a/src/mem/ruby/structures/Prefetcher.cc +++ b/src/mem/ruby/structures/Prefetcher.cc @@ -29,7 +29,7 @@ #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() diff --git a/src/mem/ruby/structures/Prefetcher.hh b/src/mem/ruby/structures/Prefetcher.hh index d5c3d4b58..9c3c06851 100644 --- a/src/mem/ruby/structures/Prefetcher.hh +++ b/src/mem/ruby/structures/Prefetcher.hh @@ -38,7 +38,7 @@ #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" diff --git a/src/mem/ruby/structures/RubyMemoryControl.cc b/src/mem/ruby/structures/RubyMemoryControl.cc index 413850627..452606451 100644 --- a/src/mem/ruby/structures/RubyMemoryControl.cc +++ b/src/mem/ruby/structures/RubyMemoryControl.cc @@ -114,7 +114,7 @@ #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; diff --git a/src/mem/ruby/structures/RubyMemoryControl.hh b/src/mem/ruby/structures/RubyMemoryControl.hh index 376ce4d75..f5f31458b 100644 --- a/src/mem/ruby/structures/RubyMemoryControl.hh +++ b/src/mem/ruby/structures/RubyMemoryControl.hh @@ -39,7 +39,7 @@ #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 diff --git a/src/mem/ruby/structures/TimerTable.cc b/src/mem/ruby/structures/TimerTable.cc index 7d0dd3c01..17dac6fc0 100644 --- a/src/mem/ruby/structures/TimerTable.cc +++ b/src/mem/ruby/structures/TimerTable.cc @@ -27,7 +27,8 @@ */ #include "mem/ruby/structures/TimerTable.hh" -#include "mem/ruby/system/System.hh" + +#include "mem/ruby/system/RubySystem.hh" TimerTable::TimerTable() : m_next_time(0) diff --git a/src/mem/ruby/structures/WireBuffer.cc b/src/mem/ruby/structures/WireBuffer.cc index 0375d9446..e2f113643 100644 --- a/src/mem/ruby/structures/WireBuffer.cc +++ b/src/mem/ruby/structures/WireBuffer.cc @@ -35,7 +35,7 @@ #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; @@ -121,7 +121,8 @@ WireBuffer::recycle() push_heap(m_message_queue.begin(), m_message_queue.end(), greater()); m_consumer_ptr-> - scheduleEventAbsolute(m_ruby_system->curCycle() + Cycles(1)); + scheduleEventAbsolute(m_ruby_system->clockPeriod() + * (m_ruby_system->curCycle() + Cycles(1))); } bool diff --git a/src/mem/ruby/system/CacheRecorder.cc b/src/mem/ruby/system/CacheRecorder.cc index 339cf1b4f..78d6939fc 100644 --- a/src/mem/ruby/system/CacheRecorder.cc +++ b/src/mem/ruby/system/CacheRecorder.cc @@ -29,8 +29,8 @@ #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; diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index e263fefdb..85b476cfd 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -34,7 +34,7 @@ #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) diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh index 1539c3999..f9d1b630e 100644 --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -37,7 +37,7 @@ #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" diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index f2841e561..cbcc678d3 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -47,7 +47,7 @@ #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" diff --git a/src/mem/ruby/system/RubySystem.cc b/src/mem/ruby/system/RubySystem.cc new file mode 100644 index 000000000..454775178 --- /dev/null +++ b/src/mem/ruby/system/RubySystem.cc @@ -0,0 +1,567 @@ +/* + * 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 "mem/ruby/system/RubySystem.hh" + +#include +#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/simple_mem.hh" +#include "sim/eventq.hh" +#include "sim/simulate.hh" + +using namespace std; + +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_cache_recorder(NULL) +{ + 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::makeCacheRecorder(uint8_t *uncompressed_trace, + uint64_t cache_trace_size, + uint64_t block_size_bytes) +{ + 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; + } + } + + // Remove the old CacheRecorder if it's still hanging about. + if (m_cache_recorder != NULL) { + delete m_cache_recorder; + } + + // Create the CacheRecorder and record the cache trace + m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size, + sequencer_map, block_size_bytes); +} + +void +RubySystem::memWriteback() +{ + m_cooldown_enabled = true; + + // Make the trace so we know what to write back. + DPRINTF(RubyCacheTrace, "Recording Cache Trace\n"); + makeCacheRecorder(NULL, 0, getBlockSizeBytes()); + 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(); + DPRINTF(RubyCacheTrace, "Recording current tick %ld\n", curtick_original); + + // Deschedule all prior events on the event queue, but record the tick they + // were scheduled at so they can be restored correctly later. + list > original_events; + while (!eventq->empty()) { + Event *curr_head = eventq->getHead(); + if (curr_head->isAutoDelete()) { + DPRINTF(RubyCacheTrace, "Event %s auto-deletes when descheduled," + " not recording\n", curr_head->name()); + } else { + original_events.push_back(make_pair(curr_head, curr_head->when())); + } + eventq->deschedule(curr_head); + } + + // Schedule an event to start cache cooldown + DPRINTF(RubyCacheTrace, "Starting cache flush\n"); + enqueueRubyEvent(curTick()); + simulate(); + DPRINTF(RubyCacheTrace, "Cache flush complete\n"); + + // Deschedule any events left on the event queue. + while (!eventq->empty()) { + eventq->deschedule(eventq->getHead()); + } + + // Restore curTick + setCurTick(curtick_original); + + // Restore all events that were originally on the event queue. This is + // done after setting curTick back to its original value so that events do + // not seem to be scheduled in the past. + while (!original_events.empty()) { + pair event = original_events.back(); + eventq->schedule(event.first, event.second); + original_events.pop_back(); + } + + // No longer flushing back to memory. + m_cooldown_enabled = false; + + // There are several issues with continuing simulation after calling + // memWriteback() at the moment, that stem from taking events off the + // queue, simulating again, and then putting them back on, whilst + // pretending that no time has passed. One is that some events will have + // been deleted, so can't be put back. Another is that any object + // recording the tick something happens may end up storing a tick in the + // future. A simple warning here alerts the user that things may not work + // as expected. + warn_once("Ruby memory writeback is experimental. Continuing simulation " + "afterwards may not always work as intended."); + + // Keep the cache recorder around so that we can dump the trace if a + // checkpoint is immediately taken. +} + +void +RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename, + uint64_t 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::serialize(CheckpointOut &cp) const +{ + // 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_t block_size_bytes = getBlockSizeBytes(); + SERIALIZE_SCALAR(block_size_bytes); + + // Check that there's a valid trace to use. If not, then memory won't be + // up-to-date and the simulation will probably fail when restoring from the + // checkpoint. + if (m_cache_recorder == NULL) { + fatal("Call memWriteback() before serialize() to create ruby trace"); + } + + // Aggregate the trace entries together into a single array + uint8_t *raw_data = new uint8_t[4096]; + uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, + 4096); + 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); +} + +void +RubySystem::drainResume() +{ + // Delete the cache recorder if it was created in memWriteback() + // to checkpoint the current cache state. + if (m_cache_recorder) { + delete m_cache_recorder; + m_cache_recorder = NULL; + } +} + +void +RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data, + uint64_t &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_t block_size_bytes = getBlockSizeBytes(); + UNSERIALIZE_OPT_SCALAR(block_size_bytes); + + string cache_trace_file; + uint64_t 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++; + + // Create the cache recorder that will hang around until startup. + makeCacheRecorder(uncompressed_trace, cache_trace_size, 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) { + DPRINTF(RubyCacheTrace, "Starting ruby cache warmup\n"); + // 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) +{ + Addr address(pkt->getAddr()); + Addr line_address = makeLineAddress(address); + + 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) +{ + Addr addr(pkt->getAddr()); + Addr line_addr = makeLineAddress(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/RubySystem.hh b/src/mem/ruby/system/RubySystem.hh new file mode 100644 index 000000000..7026f6756 --- /dev/null +++ b/src/mem/ruby/system/RubySystem.hh @@ -0,0 +1,164 @@ +/* + * 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/packet.hh" +#include "mem/ruby/profiler/Profiler.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/system/CacheRecorder.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 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 memWriteback(); + void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; + void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; + void drainResume() 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 makeCacheRecorder(uint8_t *uncompressed_trace, + uint64_t cache_trace_size, + uint64_t block_size_bytes); + + static void readCompressedTrace(std::string filename, + uint8_t *&raw_data, + uint64_t &uncompressed_trace_size); + static void writeCompressedTrace(uint8_t *raw_data, std::string file, + uint64_t uncompressed_trace_size); + + private: + // configuration parameters + 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/RubySystem.py b/src/mem/ruby/system/RubySystem.py index c10f8117f..5b13f2ea6 100644 --- a/src/mem/ruby/system/RubySystem.py +++ b/src/mem/ruby/system/RubySystem.py @@ -33,7 +33,7 @@ from SimpleMemory import * class RubySystem(ClockedObject): type = 'RubySystem' - cxx_header = "mem/ruby/system/System.hh" + cxx_header = "mem/ruby/system/RubySystem.hh" randomization = Param.Bool(False, "insert random delays on message enqueue times"); block_size_bytes = Param.UInt32(64, diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index 55fe11d39..8c5077362 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -33,12 +33,12 @@ Import('*') if env['PROTOCOL'] == 'None': Return() -SimObject('Sequencer.py') SimObject('RubySystem.py') +SimObject('Sequencer.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/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 740db7d8d..8e41204b7 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -38,8 +38,8 @@ #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" diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc deleted file mode 100644 index 490a1f085..000000000 --- a/src/mem/ruby/system/System.cc +++ /dev/null @@ -1,566 +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 - -#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; - -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_cache_recorder(NULL) -{ - 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::makeCacheRecorder(uint8_t *uncompressed_trace, - uint64_t cache_trace_size, - uint64_t block_size_bytes) -{ - 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; - } - } - - // Remove the old CacheRecorder if it's still hanging about. - if (m_cache_recorder != NULL) { - delete m_cache_recorder; - } - - // Create the CacheRecorder and record the cache trace - m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size, - sequencer_map, block_size_bytes); -} - -void -RubySystem::memWriteback() -{ - m_cooldown_enabled = true; - - // Make the trace so we know what to write back. - DPRINTF(RubyCacheTrace, "Recording Cache Trace\n"); - makeCacheRecorder(NULL, 0, getBlockSizeBytes()); - 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(); - DPRINTF(RubyCacheTrace, "Recording current tick %ld\n", curtick_original); - - // Deschedule all prior events on the event queue, but record the tick they - // were scheduled at so they can be restored correctly later. - list > original_events; - while (!eventq->empty()) { - Event *curr_head = eventq->getHead(); - if (curr_head->isAutoDelete()) { - DPRINTF(RubyCacheTrace, "Event %s auto-deletes when descheduled," - " not recording\n", curr_head->name()); - } else { - original_events.push_back(make_pair(curr_head, curr_head->when())); - } - eventq->deschedule(curr_head); - } - - // Schedule an event to start cache cooldown - DPRINTF(RubyCacheTrace, "Starting cache flush\n"); - enqueueRubyEvent(curTick()); - simulate(); - DPRINTF(RubyCacheTrace, "Cache flush complete\n"); - - // Deschedule any events left on the event queue. - while (!eventq->empty()) { - eventq->deschedule(eventq->getHead()); - } - - // Restore curTick - setCurTick(curtick_original); - - // Restore all events that were originally on the event queue. This is - // done after setting curTick back to its original value so that events do - // not seem to be scheduled in the past. - while (!original_events.empty()) { - pair event = original_events.back(); - eventq->schedule(event.first, event.second); - original_events.pop_back(); - } - - // No longer flushing back to memory. - m_cooldown_enabled = false; - - // There are several issues with continuing simulation after calling - // memWriteback() at the moment, that stem from taking events off the - // queue, simulating again, and then putting them back on, whilst - // pretending that no time has passed. One is that some events will have - // been deleted, so can't be put back. Another is that any object - // recording the tick something happens may end up storing a tick in the - // future. A simple warning here alerts the user that things may not work - // as expected. - warn_once("Ruby memory writeback is experimental. Continuing simulation " - "afterwards may not always work as intended."); - - // Keep the cache recorder around so that we can dump the trace if a - // checkpoint is immediately taken. -} - -void -RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename, - uint64_t 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::serialize(CheckpointOut &cp) const -{ - // 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_t block_size_bytes = getBlockSizeBytes(); - SERIALIZE_SCALAR(block_size_bytes); - - // Check that there's a valid trace to use. If not, then memory won't be - // up-to-date and the simulation will probably fail when restoring from the - // checkpoint. - if (m_cache_recorder == NULL) { - fatal("Call memWriteback() before serialize() to create ruby trace"); - } - - // Aggregate the trace entries together into a single array - uint8_t *raw_data = new uint8_t[4096]; - uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data, - 4096); - 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); -} - -void -RubySystem::drainResume() -{ - // Delete the cache recorder if it was created in memWriteback() - // to checkpoint the current cache state. - if (m_cache_recorder) { - delete m_cache_recorder; - m_cache_recorder = NULL; - } -} - -void -RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data, - uint64_t &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_t block_size_bytes = getBlockSizeBytes(); - UNSERIALIZE_OPT_SCALAR(block_size_bytes); - - string cache_trace_file; - uint64_t 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++; - - // Create the cache recorder that will hang around until startup. - makeCacheRecorder(uncompressed_trace, cache_trace_size, 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) { - DPRINTF(RubyCacheTrace, "Starting ruby cache warmup\n"); - // 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) -{ - Addr address(pkt->getAddr()); - Addr line_address = makeLineAddress(address); - - 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) -{ - Addr addr(pkt->getAddr()); - Addr line_addr = makeLineAddress(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 index c79732651..000000000 --- a/src/mem/ruby/system/System.hh +++ /dev/null @@ -1,164 +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 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 memWriteback(); - void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; - void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; - void drainResume() 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 makeCacheRecorder(uint8_t *uncompressed_trace, - uint64_t cache_trace_size, - uint64_t block_size_bytes); - - static void readCompressedTrace(std::string filename, - uint8_t *&raw_data, - uint64_t &uncompressed_trace_size); - static void writeCompressedTrace(uint8_t *raw_data, std::string file, - uint64_t uncompressed_trace_size); - - private: - // configuration parameters - 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/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index b5d9c2afe..42a81c096 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -464,7 +464,7 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr); #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: @@ -1029,7 +1029,7 @@ $c_ident::functionalWriteBuffers(PacketPtr& pkt) code(''' #include "mem/protocol/Types.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" ''') @@ -1137,7 +1137,7 @@ ${ident}_Controller::wakeup() #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)) diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index 08fe94ef8..2dc35784a 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -397,7 +397,7 @@ operator<<(std::ostream& out, const ${{self.c_ident}}& obj) #include #include "mem/protocol/${{self.c_ident}}.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/system/RubySystem.hh" using namespace std; ''') -- cgit v1.2.3