From 92de70b69aaf3f399a855057b556ed198139e5d8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 6 Jul 2009 15:49:47 -0700 Subject: [PATCH] ruby: Import the latest ruby changes from gems. This was done with an automated process, so there could be things that were done in this tree in the past that didn't make it. One known regression is that atomic memory operations do not seem to work properly anymore. --- src/mem/gems_common/std-includes.hh | 4 + src/mem/gems_common/util.cc | 18 +- src/mem/gems_common/util.hh | 1 + .../protocol/MESI_CMP_directory-L1cache.sm | 51 +- .../protocol/MESI_CMP_directory-L2cache.sm | 7 +- src/mem/protocol/MESI_CMP_directory-mem.sm | 242 +++- src/mem/protocol/MESI_CMP_directory-msg.sm | 32 + src/mem/protocol/MESI_CMP_directory.slicc | 2 + src/mem/protocol/MI_example-cache.sm | 51 +- src/mem/protocol/MI_example-dir.sm | 458 +++++- src/mem/protocol/MI_example-dma.sm | 135 ++ src/mem/protocol/MI_example-msg.sm | 32 +- src/mem/protocol/MI_example.slicc | 3 +- .../protocol/RubySlicc_ComponentMapping.sm | 1 + src/mem/protocol/RubySlicc_Exports.sm | 26 +- src/mem/protocol/RubySlicc_Types.sm | 58 +- .../standard_1level_CMP-protocol.sm} | 24 +- src/mem/ruby/buffers/MessageBuffer.cc | 14 +- src/mem/ruby/buffers/MessageBuffer.hh | 4 + src/mem/ruby/common/Address.hh | 35 +- src/mem/ruby/common/Consumer.hh | 3 +- src/mem/ruby/common/DataBlock.cc | 93 +- src/mem/ruby/common/DataBlock.hh | 98 +- src/mem/ruby/common/Debug.cc | 68 +- src/mem/ruby/common/Debug.hh | 38 +- src/mem/ruby/common/Driver.hh | 19 +- src/mem/ruby/common/Global.hh | 25 +- src/mem/ruby/common/Set.cc | 7 +- src/mem/ruby/common/SubBlock.cc | 10 - src/mem/ruby/common/SubBlock.hh | 15 +- src/mem/ruby/common/TypeDefines.hh | 23 + src/mem/ruby/config/MI_example-homogeneous.rb | 64 + src/mem/ruby/config/RubyConfig.cc | 272 ++-- src/mem/ruby/config/RubyConfig.hh | 208 ++- src/mem/ruby/config/cfg.rb | 751 ++++++++++ src/mem/ruby/config/config.hh | 396 ++---- src/mem/ruby/config/defaults.rb | 181 +++ src/mem/ruby/config/libruby_cfg_test.cc | 14 + src/mem/ruby/config/print_cfg.rb | 14 + src/mem/ruby/config/rubyconfig.defaults | 68 +- src/mem/ruby/config/tester.defaults | 17 +- src/mem/ruby/eventqueue/RubyEventQueue.cc | 6 +- src/mem/ruby/filters/AbstractBloomFilter.hh | 71 + src/mem/ruby/filters/BlockBloomFilter.cc | 147 ++ src/mem/ruby/filters/BlockBloomFilter.hh | 82 ++ src/mem/ruby/filters/BulkBloomFilter.cc | 232 +++ .../Tester.hh => filters/BulkBloomFilter.hh} | 76 +- src/mem/ruby/filters/GenericBloomFilter.cc | 150 ++ .../GenericBloomFilter.hh} | 67 +- src/mem/ruby/filters/H3BloomFilter.cc | 210 +++ src/mem/ruby/filters/H3BloomFilter.hh | 1258 +++++++++++++++++ .../ruby/filters/LSB_CountingBloomFilter.cc | 141 ++ .../ruby/filters/LSB_CountingBloomFilter.hh | 82 ++ .../ruby/filters/MultiBitSelBloomFilter.cc | 191 +++ .../MultiBitSelBloomFilter.hh} | 92 +- src/mem/ruby/filters/MultiGrainBloomFilter.cc | 172 +++ src/mem/ruby/filters/MultiGrainBloomFilter.hh | 88 ++ .../ruby/filters/NonCountingBloomFilter.cc | 144 ++ .../NonCountingBloomFilter.hh} | 79 +- src/mem/ruby/init.cc | 191 --- src/mem/ruby/libruby.cc | 206 +++ src/mem/ruby/libruby.hh | 109 ++ src/mem/ruby/libruby_internal.hh | 13 + src/mem/ruby/network/Network.cc | 34 + src/mem/ruby/network/Network.hh | 26 +- .../garnet-fixed-pipeline/CreditLink_d.hh | 2 +- .../garnet-fixed-pipeline/GarnetNetwork_d.cc | 38 +- .../garnet-fixed-pipeline/GarnetNetwork_d.hh | 15 +- .../NetworkInterface_d.cc | 10 +- .../garnet-fixed-pipeline/NetworkLink_d.cc | 11 +- .../garnet-fixed-pipeline/NetworkLink_d.hh | 2 +- .../garnet-fixed-pipeline/OutVcState_d.cc | 7 +- .../garnet-fixed-pipeline/OutVcState_d.hh | 4 +- .../garnet-fixed-pipeline/OutputUnit_d.cc | 4 +- .../network/garnet-fixed-pipeline/Router_d.cc | 6 +- .../garnet-fixed-pipeline/SWallocator_d.cc | 2 +- .../garnet-fixed-pipeline/VCallocator_d.cc | 2 +- .../garnet-flexible-pipeline/GarnetNetwork.cc | 47 +- .../garnet-flexible-pipeline/GarnetNetwork.hh | 16 +- .../garnet-flexible-pipeline/NetworkConfig.hh | 79 +- .../NetworkInterface.cc | 8 +- .../garnet-flexible-pipeline/NetworkLink.cc | 4 +- .../garnet-flexible-pipeline/Router.cc | 16 +- src/mem/ruby/network/simple/CustomTopology.cc | 140 ++ src/mem/ruby/network/simple/CustomTopology.hh | 17 + .../simple/HierarchicalSwitchTopology.cc | 66 + .../simple/HierarchicalSwitchTopology.hh | 17 + src/mem/ruby/network/simple/PerfectSwitch.cc | 12 +- src/mem/ruby/network/simple/PtToPtTopology.cc | 82 ++ src/mem/ruby/network/simple/PtToPtTopology.hh | 17 + src/mem/ruby/network/simple/SimpleNetwork.cc | 58 +- src/mem/ruby/network/simple/SimpleNetwork.hh | 8 +- src/mem/ruby/network/simple/Switch.cc | 5 +- src/mem/ruby/network/simple/Switch.hh | 2 + src/mem/ruby/network/simple/Throttle.cc | 13 +- src/mem/ruby/network/simple/Throttle.hh | 5 +- src/mem/ruby/network/simple/Topology.cc | 485 ++----- src/mem/ruby/network/simple/Topology.hh | 21 +- .../ruby/network/simple/Torus2DTopology.cc | 84 ++ .../ruby/network/simple/Torus2DTopology.hh | 17 + src/mem/ruby/profiler/AddressProfiler.cc | 21 +- src/mem/ruby/profiler/AddressProfiler.hh | 8 + src/mem/ruby/profiler/Profiler.cc | 382 +++-- src/mem/ruby/profiler/Profiler.hh | 456 +++--- src/mem/ruby/recorder/CacheRecorder.cc | 38 +- src/mem/ruby/recorder/CacheRecorder.hh | 4 +- src/mem/ruby/recorder/TraceRecord.cc | 41 +- src/mem/ruby/recorder/TraceRecord.hh | 11 +- src/mem/ruby/recorder/Tracer.cc | 41 +- src/mem/ruby/recorder/Tracer.hh | 14 +- .../slicc_interface/AbstractCacheEntry.cc | 2 + .../slicc_interface/AbstractCacheEntry.hh | 3 + src/mem/ruby/slicc_interface/AbstractChip.hh | 126 -- .../slicc_interface/AbstractController.hh | 33 + .../RubySlicc_ComponentMapping.hh | 285 +--- .../RubySlicc_Profiler_interface.cc | 25 +- .../ruby/slicc_interface/RubySlicc_Util.hh | 29 +- src/mem/ruby/storebuffer/hfa.hh | 103 ++ src/mem/ruby/storebuffer/hfatypes.hh | 80 ++ src/mem/ruby/storebuffer/interface.cc | 67 + src/mem/ruby/storebuffer/interface.hh | 46 + src/mem/ruby/storebuffer/stb_interface.cc | 73 + src/mem/ruby/storebuffer/stb_interface.hh | 42 + src/mem/ruby/storebuffer/storebuffer.cc | 564 ++++++++ src/mem/ruby/storebuffer/storebuffer.hh | 150 ++ src/mem/ruby/system/AbstractMemOrCache.hh | 1 - src/mem/ruby/system/CacheMemory.hh | 381 +++-- src/mem/ruby/system/DMASequencer.cc | 130 ++ src/mem/ruby/system/DMASequencer.hh | 49 + src/mem/ruby/system/DirectoryMemory.cc | 165 ++- src/mem/ruby/system/DirectoryMemory.hh | 37 +- src/mem/ruby/system/MemoryControl.cc | 156 +- src/mem/ruby/system/MemoryControl.hh | 20 +- src/mem/ruby/system/MemoryVector.hh | 81 ++ src/mem/ruby/system/NodePersistentTable.cc | 193 --- src/mem/ruby/system/NodePersistentTable.hh | 99 -- src/mem/ruby/system/PersistentArbiter.cc | 165 --- src/mem/ruby/system/PersistentTable.cc | 194 --- src/mem/ruby/system/PersistentTable.hh | 99 -- src/mem/ruby/system/ProcessorInterface.hh | 45 + src/mem/ruby/system/RubyPort.cc | 5 + src/mem/ruby/system/RubyPort.hh | 60 + src/mem/ruby/system/Sequencer.cc | 1212 ++++++---------- src/mem/ruby/system/Sequencer.hh | 98 +- src/mem/ruby/system/StoreBuffer.cc | 302 ---- src/mem/ruby/system/StoreBuffer.hh | 121 -- src/mem/ruby/system/StoreCache.cc | 178 --- src/mem/ruby/system/System.cc | 384 +++-- src/mem/ruby/system/System.hh | 136 +- src/mem/ruby/system/TBETable.hh | 21 +- src/mem/ruby/tester/BarrierGenerator.cc | 333 ----- src/mem/ruby/tester/BarrierGenerator.hh | 138 -- src/mem/ruby/tester/Check.cc | 310 ---- src/mem/ruby/tester/Check.hh | 107 -- src/mem/ruby/tester/CheckTable.cc | 128 -- src/mem/ruby/tester/DetermGETXGenerator.cc | 72 +- src/mem/ruby/tester/DetermGETXGenerator.hh | 17 +- src/mem/ruby/tester/DetermInvGenerator.cc | 100 +- src/mem/ruby/tester/DetermInvGenerator.hh | 11 +- .../ruby/tester/DetermSeriesGETSGenerator.cc | 56 +- .../ruby/tester/DetermSeriesGETSGenerator.hh | 11 +- src/mem/ruby/tester/DeterministicDriver.cc | 145 +- src/mem/ruby/tester/DeterministicDriver.hh | 54 +- .../Driver_Tester.cc} | 11 +- .../{RequestGenerator.hh => Driver_Tester.hh} | 76 +- src/mem/ruby/tester/EventQueue_Tester.hh | 118 ++ src/mem/ruby/tester/Global_Tester.hh | 74 + src/mem/ruby/tester/Instruction.cc | 51 - src/mem/ruby/tester/Instruction.hh | 57 - src/mem/ruby/tester/RaceyDriver.cc | 67 +- src/mem/ruby/tester/RaceyDriver.hh | 32 +- src/mem/ruby/tester/RaceyPseudoThread.cc | 353 +++++ src/mem/ruby/tester/RaceyPseudoThread.hh | 151 ++ src/mem/ruby/tester/RequestGenerator.cc | 220 --- src/mem/ruby/tester/SpecifiedGenerator.cc | 4 - src/mem/ruby/tester/SpecifiedGenerator.hh | 8 +- src/mem/ruby/tester/SyntheticDriver.cc | 286 ---- src/mem/ruby/tester/SyntheticDriver.hh | 118 -- src/mem/ruby/tester/Tester.cc | 112 -- src/mem/ruby/tester/main.cc | 9 +- src/mem/ruby/tester/main.hh | 9 +- src/mem/ruby/tester/test_framework.cc | 433 +++--- src/mem/ruby/tester/test_framework.hh | 4 +- src/mem/slicc/ast/ASTs.hh | 1 + src/mem/slicc/ast/EnqueueStatementAST.cc | 2 +- src/mem/slicc/ast/MachineAST.cc | 6 +- src/mem/slicc/ast/MachineAST.hh | 5 + src/mem/slicc/ast/MethodCallExprAST.cc | 26 +- src/mem/slicc/ast/NewExprAST.cc | 9 + src/mem/slicc/ast/NewExprAST.hh | 20 + src/mem/slicc/ast/ObjDeclAST.cc | 29 +- src/mem/slicc/parser/lexer.ll | 9 +- src/mem/slicc/parser/parser.yy | 28 +- src/mem/slicc/symbols/Func.cc | 5 +- src/mem/slicc/symbols/Func.hh | 2 +- src/mem/slicc/symbols/StateMachine.cc | 439 +++++- src/mem/slicc/symbols/StateMachine.hh | 34 +- src/mem/slicc/symbols/Symbol.hh | 4 +- src/mem/slicc/symbols/SymbolTable.cc | 717 +--------- src/mem/slicc/symbols/SymbolTable.hh | 2 +- src/mem/slicc/symbols/Type.cc | 94 +- src/mem/slicc/symbols/Type.hh | 3 +- src/mem/slicc/symbols/Var.hh | 2 +- 203 files changed, 12394 insertions(+), 8465 deletions(-) create mode 100644 src/mem/protocol/MI_example-dma.sm rename src/mem/{ruby/init.hh => protocol/standard_1level_CMP-protocol.sm} (81%) create mode 100644 src/mem/ruby/common/TypeDefines.hh create mode 100644 src/mem/ruby/config/MI_example-homogeneous.rb create mode 100644 src/mem/ruby/config/cfg.rb create mode 100644 src/mem/ruby/config/defaults.rb create mode 100644 src/mem/ruby/config/libruby_cfg_test.cc create mode 100644 src/mem/ruby/config/print_cfg.rb create mode 100644 src/mem/ruby/filters/AbstractBloomFilter.hh create mode 100644 src/mem/ruby/filters/BlockBloomFilter.cc create mode 100644 src/mem/ruby/filters/BlockBloomFilter.hh create mode 100644 src/mem/ruby/filters/BulkBloomFilter.cc rename src/mem/ruby/{tester/Tester.hh => filters/BulkBloomFilter.hh} (60%) create mode 100644 src/mem/ruby/filters/GenericBloomFilter.cc rename src/mem/ruby/{system/StoreCache.hh => filters/GenericBloomFilter.hh} (66%) create mode 100644 src/mem/ruby/filters/H3BloomFilter.cc create mode 100644 src/mem/ruby/filters/H3BloomFilter.hh create mode 100644 src/mem/ruby/filters/LSB_CountingBloomFilter.cc create mode 100644 src/mem/ruby/filters/LSB_CountingBloomFilter.hh create mode 100644 src/mem/ruby/filters/MultiBitSelBloomFilter.cc rename src/mem/ruby/{system/PersistentArbiter.hh => filters/MultiBitSelBloomFilter.hh} (57%) create mode 100644 src/mem/ruby/filters/MultiGrainBloomFilter.cc create mode 100644 src/mem/ruby/filters/MultiGrainBloomFilter.hh create mode 100644 src/mem/ruby/filters/NonCountingBloomFilter.cc rename src/mem/ruby/{tester/CheckTable.hh => filters/NonCountingBloomFilter.hh} (59%) delete mode 100644 src/mem/ruby/init.cc create mode 100644 src/mem/ruby/libruby.cc create mode 100644 src/mem/ruby/libruby.hh create mode 100644 src/mem/ruby/libruby_internal.hh create mode 100644 src/mem/ruby/network/Network.cc create mode 100644 src/mem/ruby/network/simple/CustomTopology.cc create mode 100644 src/mem/ruby/network/simple/CustomTopology.hh create mode 100644 src/mem/ruby/network/simple/HierarchicalSwitchTopology.cc create mode 100644 src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh create mode 100644 src/mem/ruby/network/simple/PtToPtTopology.cc create mode 100644 src/mem/ruby/network/simple/PtToPtTopology.hh create mode 100644 src/mem/ruby/network/simple/Torus2DTopology.cc create mode 100644 src/mem/ruby/network/simple/Torus2DTopology.hh delete mode 100644 src/mem/ruby/slicc_interface/AbstractChip.hh create mode 100644 src/mem/ruby/slicc_interface/AbstractController.hh create mode 100644 src/mem/ruby/storebuffer/hfa.hh create mode 100644 src/mem/ruby/storebuffer/hfatypes.hh create mode 100644 src/mem/ruby/storebuffer/interface.cc create mode 100644 src/mem/ruby/storebuffer/interface.hh create mode 100644 src/mem/ruby/storebuffer/stb_interface.cc create mode 100644 src/mem/ruby/storebuffer/stb_interface.hh create mode 100644 src/mem/ruby/storebuffer/storebuffer.cc create mode 100644 src/mem/ruby/storebuffer/storebuffer.hh create mode 100644 src/mem/ruby/system/DMASequencer.cc create mode 100644 src/mem/ruby/system/DMASequencer.hh create mode 100644 src/mem/ruby/system/MemoryVector.hh delete mode 100644 src/mem/ruby/system/NodePersistentTable.cc delete mode 100644 src/mem/ruby/system/NodePersistentTable.hh delete mode 100644 src/mem/ruby/system/PersistentArbiter.cc delete mode 100644 src/mem/ruby/system/PersistentTable.cc delete mode 100644 src/mem/ruby/system/PersistentTable.hh create mode 100644 src/mem/ruby/system/ProcessorInterface.hh create mode 100644 src/mem/ruby/system/RubyPort.cc create mode 100644 src/mem/ruby/system/RubyPort.hh delete mode 100644 src/mem/ruby/system/StoreBuffer.cc delete mode 100644 src/mem/ruby/system/StoreBuffer.hh delete mode 100644 src/mem/ruby/system/StoreCache.cc delete mode 100644 src/mem/ruby/tester/BarrierGenerator.cc delete mode 100644 src/mem/ruby/tester/BarrierGenerator.hh delete mode 100644 src/mem/ruby/tester/Check.cc delete mode 100644 src/mem/ruby/tester/Check.hh delete mode 100644 src/mem/ruby/tester/CheckTable.cc rename src/mem/ruby/{slicc_interface/AbstractChip.cc => tester/Driver_Tester.cc} (86%) rename src/mem/ruby/tester/{RequestGenerator.hh => Driver_Tester.hh} (56%) create mode 100644 src/mem/ruby/tester/EventQueue_Tester.hh create mode 100644 src/mem/ruby/tester/Global_Tester.hh delete mode 100644 src/mem/ruby/tester/Instruction.cc delete mode 100644 src/mem/ruby/tester/Instruction.hh create mode 100644 src/mem/ruby/tester/RaceyPseudoThread.cc create mode 100644 src/mem/ruby/tester/RaceyPseudoThread.hh delete mode 100644 src/mem/ruby/tester/RequestGenerator.cc delete mode 100644 src/mem/ruby/tester/SyntheticDriver.cc delete mode 100644 src/mem/ruby/tester/SyntheticDriver.hh delete mode 100644 src/mem/ruby/tester/Tester.cc create mode 100644 src/mem/slicc/ast/NewExprAST.cc create mode 100644 src/mem/slicc/ast/NewExprAST.hh diff --git a/src/mem/gems_common/std-includes.hh b/src/mem/gems_common/std-includes.hh index 619214f1d..d6062337f 100644 --- a/src/mem/gems_common/std-includes.hh +++ b/src/mem/gems_common/std-includes.hh @@ -26,6 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * $Id: std-includes.hh,v 3.7 2003/02/24 21:05:24 xu Exp $ + */ + #ifndef INCLUDES_H #define INCLUDES_H diff --git a/src/mem/gems_common/util.cc b/src/mem/gems_common/util.cc index a64da15a6..403be383f 100644 --- a/src/mem/gems_common/util.cc +++ b/src/mem/gems_common/util.cc @@ -30,8 +30,7 @@ * $Id$ */ -#include - +#include "assert.hh" #include "mem/gems_common/util.hh" // Split a string into a head and tail strings on the specified @@ -43,7 +42,7 @@ string string_split(string& str, char split_character) string head = ""; string tail = ""; - unsigned counter = 0; + uint counter = 0; while(counter < str.size()) { if (str[counter] == split_character) { counter++; @@ -91,6 +90,19 @@ float string_to_float(string& str) return ret; } +bool string_to_bool(const string & str) +{ + string lower(str); + for (size_t i=0;i0); Time current_time = g_eventQueue_ptr->getTime(); Time arrival_time = 0; - if (!RANDOMIZATION || (m_randomization == false)) { + if (!RubySystem::getRandomization() || (m_randomization == false)) { // No randomization arrival_time = current_time + delta; @@ -294,7 +296,7 @@ void MessageBuffer::pop() { DEBUG_MSG(QUEUE_COMP,MedPrio,"pop from " + m_name); assert(isReady()); - m_prio_heap.extractMin(); + Time ready_time = m_prio_heap.extractMin().m_time; // record previous size and time so the current buffer size isn't adjusted until next cycle if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { m_size_at_cycle_start = m_size; @@ -321,13 +323,13 @@ void MessageBuffer::clear() void MessageBuffer::recycle() { - // const int RECYCLE_LATENCY = 3; + // const int RubyConfig::getRecycleLatency() = 3; DEBUG_MSG(QUEUE_COMP,MedPrio,"recycling " + m_name); assert(isReady()); MessageBufferNode node = m_prio_heap.extractMin(); - node.m_time = g_eventQueue_ptr->getTime() + RECYCLE_LATENCY; + node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency; m_prio_heap.insert(node); - g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, g_eventQueue_ptr->getTime() + RECYCLE_LATENCY); + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, g_eventQueue_ptr->getTime() + m_recycle_latency); } int MessageBuffer::setAndReturnDelayCycles(MsgPtr& message) diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index b58203a93..3ca6790d0 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -60,6 +60,7 @@ public: // Public Methods static void printConfig(ostream& out) {} + void setRecycleLatency(int recycle_latency) { m_recycle_latency = recycle_latency; } // TRUE if head of queue timestamp <= SystemTime bool isReady() const { @@ -105,6 +106,9 @@ public: void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } private: + //added by SS + int m_recycle_latency; + // Private Methods int setAndReturnDelayCycles(MsgPtr& message); diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index d72fbf38a..b6899d1ac 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -1,3 +1,4 @@ + /* * Copyright (c) 1999 Mark D. Hill and David A. Wood * All rights reserved. @@ -26,12 +27,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * $Id$ + */ + #ifndef ADDRESS_H #define ADDRESS_H #include #include "mem/ruby/common/Global.hh" -#include "mem/ruby/config/RubyConfig.hh" +#include "mem/ruby/system/System.hh" #include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/MachineID.hh" @@ -63,17 +68,16 @@ public: physical_address_t maskHighOrderBits(int number) const; physical_address_t shiftLowOrderBits(int number) const; physical_address_t getLineAddress() const - { return bitSelect(RubyConfig::dataBlockBits(), ADDRESS_WIDTH); } + { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } physical_address_t getOffset() const - { return bitSelect(0, RubyConfig::dataBlockBits()-1); } + { return bitSelect(0, RubySystem::getBlockSizeBits()-1); } - void makeLineAddress() { m_address = maskLowOrderBits(RubyConfig::dataBlockBits()); } + void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); } // returns the next stride address based on line address void makeNextStrideAddress( int stride) { - m_address = maskLowOrderBits(RubyConfig::dataBlockBits()) - + RubyConfig::dataBlockBytes()*stride; + m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) + + RubySystem::getBlockSizeBytes()*stride; } - void makePageAddress() { m_address = maskLowOrderBits(RubyConfig::pageSizeBits()); } int getBankSetNum() const; int getBankSetDist() const; @@ -103,6 +107,7 @@ private: inline Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } +/* inline Address next_stride_address(const Address& addr, int stride) { Address temp = addr; @@ -110,9 +115,7 @@ Address next_stride_address(const Address& addr, int stride) { temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem return temp; } - -inline -Address page_address(const Address& addr) { Address temp(addr); temp.makePageAddress(); return temp; } +*/ // Output operator declaration ostream& operator<<(ostream& out, const Address& obj); @@ -202,17 +205,19 @@ physical_address_t Address::shiftLowOrderBits(int number) const inline integer_t Address::memoryModuleIndex() const { - integer_t index = bitSelect(RubyConfig::dataBlockBits()+RubyConfig::memoryBits(), ADDRESS_WIDTH); + integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); assert (index >= 0); + /* if (index >= RubyConfig::memoryModuleBlocks()) { - cerr << " memoryBits: " << RubyConfig::memoryBits() << " memorySizeBits: " << RubyConfig::memorySizeBits() - << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush + cerr << " memoryBits: " << RubySystem::getMemorySizeBits() << " memorySizeBits: " << RubySystem::getMemorySizeBits() + << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush << "error: limit exceeded. " << - " dataBlockBits: " << RubyConfig::dataBlockBits() << + " getDataBlockBits: " << RubySystem::getBlockSizeBits() << " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() << " index: " << index << endl; } assert (index < RubyConfig::memoryModuleBlocks()); + */ return index; // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); @@ -239,7 +244,7 @@ ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS inline void Address::print(ostream& out) const { - out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush; + out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush; } class Address; diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh index 34cd7864c..4a14ca20f 100644 --- a/src/mem/ruby/common/Consumer.hh +++ b/src/mem/ruby/common/Consumer.hh @@ -53,7 +53,8 @@ public: virtual ~Consumer() { } // Public Methods - pure virtual methods - void triggerWakeup() { Time time = g_eventQueue_ptr->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }} + // void triggerWakeup() { Time time = g_eventQueue_ptr->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }} + void triggerWakeup(RubyEventQueue * eventQueue) { Time time = eventQueue->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }} virtual void wakeup() = 0; virtual void print(ostream& out) const = 0; const Time& getLastScheduledWakeup() const { return m_last_scheduled_wakeup; } diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc index ce72bc7f4..5e6b8338e 100644 --- a/src/mem/ruby/common/DataBlock.cc +++ b/src/mem/ruby/common/DataBlock.cc @@ -1,91 +1,16 @@ -/* - * Copyright (c) 1999-2008 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. - */ - -/* - * $Id$ - */ - #include "mem/ruby/common/DataBlock.hh" -DataBlock::DataBlock() -{ - if (DATA_BLOCK || XACT_MEMORY) { - m_data.setSize(RubyConfig::dataBlockBytes()); - } - clear(); -} - -DataBlock::~DataBlock() -{ - -} - -void DataBlock::clear() -{ - int size = m_data.size(); - for (int i = 0; i < size; i++) { - m_data[i] = 0; - } -} - -bool DataBlock::equal(const DataBlock& obj) const +DataBlock & +DataBlock::operator=(const DataBlock & obj) { - bool value = true; - int size = m_data.size(); - for (int i = 0; i < size; i++) { - value = value && (m_data[i] == obj.m_data[i]); - } - return value; -} - -void DataBlock::print(ostream& out) const -{ - int size = m_data.size(); - for (int i = 0; i < size; i+=4) { - out << hex << *((uint32*)(&(m_data[i]))) << " "; - } - out << dec << "]" << flush; -} - -uint8 DataBlock::getByte(int whichByte) const -{ - if (DATA_BLOCK || XACT_MEMORY) { - return m_data[whichByte]; + if (this == &obj) { + // assert(false); } else { - return 0; - } -} - -void DataBlock::setByte(int whichByte, uint8 data) -{ - if (DATA_BLOCK || XACT_MEMORY) { - m_data[whichByte] = data; + if (!m_alloc) + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); + m_alloc = true; } + return *this; } - diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 8711cb740..2a0811f76 100644 --- a/src/mem/ruby/common/DataBlock.hh +++ b/src/mem/ruby/common/DataBlock.hh @@ -31,29 +31,41 @@ #define DATABLOCK_H #include "mem/ruby/common/Global.hh" -#include "mem/ruby/config/RubyConfig.hh" +#include "mem/ruby/system/System.hh" #include "mem/gems_common/Vector.hh" class DataBlock { -public: + public: // Constructors - DataBlock(); + DataBlock() {alloc();} + DataBlock(const DataBlock & cp) { + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes()); + m_alloc = true; + } // Destructor - ~DataBlock(); + ~DataBlock() { if(m_alloc) delete [] m_data;} + + DataBlock& operator=(const DataBlock& obj); // Public Methods + void assign(uint8* data); + void clear(); uint8 getByte(int whichByte) const; + const uint8* getData(int offset, int len) const; void setByte(int whichByte, uint8 data); + void setData(uint8* data, int offset, int len); + void copyPartial(const DataBlock & dblk, int offset, int len); bool equal(const DataBlock& obj) const; void print(ostream& out) const; private: - // Private Methods - + void alloc(); // Data Members (m_ prefix) - Vector m_data; + uint8* m_data; + bool m_alloc; }; // Output operator declaration @@ -61,6 +73,78 @@ ostream& operator<<(ostream& out, const DataBlock& obj); bool operator==(const DataBlock& obj1, const DataBlock& obj2); +// inline functions for speed + +inline +void DataBlock::assign(uint8* data) +{ + delete [] m_data; + m_data = data; + m_alloc = false; +} + +inline +void DataBlock::alloc() +{ + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + m_alloc = true; + clear(); +} + +inline +void DataBlock::clear() +{ + memset(m_data, 0, RubySystem::getBlockSizeBytes()); +} + +inline +bool DataBlock::equal(const DataBlock& obj) const +{ + return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); +} + +inline +void DataBlock::print(ostream& out) const +{ + int size = RubySystem::getBlockSizeBytes(); + out << "[ "; + for (int i = 0; i < size; i+=4) { + out << hex << *((uint32*)(&(m_data[i]))) << " "; + } + out << dec << "]" << flush; +} + +inline +uint8 DataBlock::getByte(int whichByte) const +{ + return m_data[whichByte]; +} + +inline +const uint8* DataBlock::getData(int offset, int len) const +{ + assert(offset + len <= RubySystem::getBlockSizeBytes()); + return &m_data[offset]; +} + +inline +void DataBlock::setByte(int whichByte, uint8 data) +{ + m_data[whichByte] = data; +} + +inline +void DataBlock::setData(uint8* data, int offset, int len) +{ + assert(offset + len <= RubySystem::getBlockSizeBytes()); + memcpy(&m_data[offset], data, len); +} + +inline +void DataBlock::copyPartial(const DataBlock & dblk, int offset, int len) +{ + setData(&dblk.m_data[offset], offset, len); +} // ******************* Definitions ******************* diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index 02f4069ee..c1a6e16d0 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -38,36 +38,28 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Debug.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" +#include "mem/gems_common/util.hh" class Debug; extern Debug* g_debug_ptr; std::ostream * debug_cout_ptr; -struct DebugComponentData +bool Debug::m_protocol_trace = false; + +// component character list +const char DEFINE_COMP_CHAR[] = { - const char *desc; - const char ch; +#undef DEFINE_COMP +#define DEFINE_COMP(component, character, description) character, +#include "Debug.def" }; -// component character list -DebugComponentData debugComponents[] = +// component description list +const char* DEFINE_COMP_DESCRIPTION[] = { - {"System", 's' }, - {"Node", 'N' }, - {"Queue", 'q' }, - {"Event Queue", 'e' }, - {"Network", 'n' }, - {"Sequencer", 'S' }, - {"Tester", 't' }, - {"Generated", 'g' }, - {"SLICC", 'l' }, - {"Network Queues", 'Q' }, - {"Time", 'T' }, - {"Network Internals", 'i' }, - {"Store Buffer", 'b' }, - {"Cache", 'c' }, - {"Predictor", 'p' }, - {"Allocator", 'a' }, +#undef DEFINE_COMP +#define DEFINE_COMP(component, character, description) description, +#include "Debug.def" }; extern "C" void changeDebugVerbosity(VerbosityLevel vb); @@ -83,6 +75,32 @@ void changeDebugFilter(int filter) g_debug_ptr->setFilter(filter); } +Debug::Debug() +{ + m_verbosityLevel = No_Verb; + m_starting_cycle = ~0; + clearFilter(); + debug_cout_ptr = &cout; +} + +Debug::Debug( const string & name, const vector & argv ) +{ + for (size_t i=0;i #include -#include "config/ruby_debug.hh" -#include "mem/ruby/common/Global.hh" - extern std::ostream * debug_cout_ptr; // component enumeration enum DebugComponents { - SYSTEM_COMP, - NODE_COMP, - QUEUE_COMP, - EVENTQUEUE_COMP, - NETWORK_COMP, - SEQUENCER_COMP, - TESTER_COMP, - GENERATED_COMP, - SLICC_COMP, - NETWORKQUEUE_COMP, - TIME_COMP, - NETWORK_INTERNALS_COMP, - STOREBUFFER_COMP, - CACHE_COMP, - PREDICTOR_COMP, - ALLOCATOR_COMP, - NUMBER_OF_COMPS +#undef DEFINE_COMP +#define DEFINE_COMP(component, character, description) component, +#include "Debug.def" + NUMBER_OF_COMPS }; enum PriorityLevel {HighPrio, MedPrio, LowPrio}; @@ -70,6 +54,8 @@ enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb}; class Debug { public: // Constructors + Debug(); + Debug( const string & name, const vector & argv ); Debug( const char *filterString, const char *verboseString, Time filterStartTime, const char *filename ); @@ -77,6 +63,7 @@ public: ~Debug(); // Public Methods + static bool getProtocolTrace() { return m_protocol_trace; } bool validDebug(int module, PriorityLevel priority); void printVerbosity(ostream& out) const; void setVerbosity(VerbosityLevel vb); @@ -108,6 +95,7 @@ private: Debug& operator=(const Debug& obj); // Data Members (m_ prefix) + static bool m_protocol_trace; VerbosityLevel m_verbosityLevel; int m_filter; Time m_starting_cycle; @@ -155,7 +143,7 @@ const bool ASSERT_FLAG = true; << __PRETTY_FUNCTION__ << " in "\ << __FILE__ << ":"\ << __LINE__ << endl << flush;\ - if(isatty(STDERR_FILENO)) {\ + if(isatty(STDIN_FILENO)) {\ cerr << "At this point you might want to attach a debug to ";\ cerr << "the running and get to the" << endl;\ cerr << "crash site; otherwise press enter to continue" << endl;\ @@ -176,7 +164,7 @@ const bool ASSERT_FLAG = true; << __PRETTY_FUNCTION__ << " in "\ << __FILE__ << ":"\ << __LINE__ << endl << flush;\ - if(isatty(STDERR_FILENO)) {\ + if(isatty(STDIN_FILENO)) {\ cerr << "press enter to continue" << endl;\ cerr << "PID: " << getpid();\ cerr << endl << flush; \ @@ -303,5 +291,5 @@ const bool ASSERT_FLAG = true; }\ } -#endif // __MEM_RUBY_DEBUG_HH__ +#endif //DEBUG_H diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh index 38bdbbf91..db8279fa5 100644 --- a/src/mem/ruby/common/Driver.hh +++ b/src/mem/ruby/common/Driver.hh @@ -27,6 +27,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * $Id$ + * + * Description: + * + */ + #ifndef DRIVER_H #define DRIVER_H @@ -34,7 +41,6 @@ #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/system/NodeID.hh" #include "mem/protocol/CacheRequestType.hh" -#include "mem/packet.hh" class RubySystem; class SubBlock; @@ -52,10 +58,15 @@ public: // Public Methods virtual void get_network_config() {} - virtual void hitCallback(Packet* pkt) = 0; + virtual void dmaHitCallback() = 0; + virtual void hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) = 0; // Called by sequencer + virtual void conflictCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) { assert(0) }; // Called by sequencer virtual integer_t getInstructionCount(int procID) const { return 1; } virtual integer_t getCycleCount(int procID) const { return 1; } - + virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);} + virtual int inTransaction(int procID, int thread ) const{ + cout << "Driver.hh inTransaction " << endl; +return false; } //called by Sequencer virtual void printDebug(){} //called by Sequencer virtual void printStats(ostream& out) const = 0; @@ -63,6 +74,8 @@ public: virtual void printConfig(ostream& out) const = 0; + //virtual void abortCallback(NodeID proc){} + virtual integer_t readPhysicalMemory(int procID, physical_address_t address, int len ){ ASSERT(0); return 0; } diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh index 205b2bcb2..591ffed1e 100644 --- a/src/mem/ruby/common/Global.hh +++ b/src/mem/ruby/common/Global.hh @@ -32,9 +32,10 @@ * * */ -#ifndef __MEM_RUBY_GLOBAL_HH__ -#define __MEM_RUBY_GLOBAL_HH__ +#ifndef GLOBAL_H +#define GLOBAL_H +/* #ifdef SINGLE_LEVEL_CACHE const bool TWO_LEVEL_CACHE = false; #define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // currently all protocols require L1s == nodes @@ -60,24 +61,11 @@ const bool TWO_LEVEL_CACHE = true; #define DIRECTORY_MEMBER_VARIABLE m_Directory_directory_vec[m_version] #define TBE_TABLE_MEMBER_VARIABLE m_L1Cache_TBEs_vec[m_version] -typedef unsigned char uint8; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef int int32; -typedef long long int64; - -typedef long long integer_t; -typedef unsigned long long uinteger_t; +*/ -typedef int64 Time; -typedef uint64 physical_address_t; -typedef uint64 la_t; -typedef uint64 pa_t; -typedef integer_t simtime_t; // external includes for all classes +#include "mem/ruby/common/TypeDefines.hh" #include "mem/gems_common/std-includes.hh" #include "mem/ruby/common/Debug.hh" @@ -85,6 +73,7 @@ typedef integer_t simtime_t; typedef Time LogicalTime; typedef int64 Index; // what the address bit ripper returns typedef int word; // one word of a cache line +typedef unsigned int uint; typedef int SwitchID; typedef int LinkID; @@ -105,5 +94,5 @@ extern inline int max_tokens() } -#endif // __MEM_RUBY_GLOBAL_HH__ +#endif //GLOBAL_H diff --git a/src/mem/ruby/common/Set.cc b/src/mem/ruby/common/Set.cc index 4cb40a246..6f01c4043 100644 --- a/src/mem/ruby/common/Set.cc +++ b/src/mem/ruby/common/Set.cc @@ -40,6 +40,7 @@ // set sizes #include "mem/ruby/common/Set.hh" +#include "mem/ruby/system/System.hh" #include "mem/ruby/config/RubyConfig.hh" #if __amd64__ || __LP64__ @@ -51,7 +52,7 @@ Set::Set() { m_p_nArray = NULL; - setSize(RubyConfig::numberOfProcessors()); + setSize(RubySystem::getNumberOfSequencers()); } // copy constructor @@ -511,7 +512,7 @@ void Set::setSize(int size) #endif // __32BITS__ // decide whether to use dynamic or static alloction - if(m_nArrayLen<=NUMBER_WORDS_PER_SET) { // constant defined in RubyConfig.h + if(m_nArrayLen<=NUMBER_WORDS_PER_SET) { // constant defined in RubyConfig.hh // its OK to use the static allocation, and it will // probably be faster (as m_nArrayLen is already in the // cache and they will probably share the same cache line) @@ -560,7 +561,7 @@ void Set::print(ostream& out) const return; } char buff[24]; - out << "[Set 0x "; + out << "[Set (" << m_nSize << ") 0x "; for (int i=m_nArrayLen-1; i>=0; i--) { #ifdef __32BITS__ sprintf(buff,"%08X ",m_p_nArray[i]); diff --git a/src/mem/ruby/common/SubBlock.cc b/src/mem/ruby/common/SubBlock.cc index 568d3106a..de40e3f7d 100644 --- a/src/mem/ruby/common/SubBlock.cc +++ b/src/mem/ruby/common/SubBlock.cc @@ -42,16 +42,6 @@ SubBlock::SubBlock(const Address& addr, int size) } } -SubBlock::SubBlock(const Address& addr, const Address& logicalAddress, int size) -{ - m_address = addr; - m_logicalAddress = logicalAddress; - setSize(size); - for(int i=0; i= m_address.getAddress()) && (addr.getAddress() < (m_address.getAddress()+getSize()))); } - // uint8 getByte(const Address& addr) { return m_data[addr.getAddress() - m_address.getAddress()]; } void internalMergeTo(DataBlock& data) const; void internalMergeFrom(const DataBlock& data); // Data Members (m_ prefix) Address m_address; - Address m_logicalAddress; - Vector m_data; + Vector m_data; }; // Output operator declaration diff --git a/src/mem/ruby/common/TypeDefines.hh b/src/mem/ruby/common/TypeDefines.hh new file mode 100644 index 000000000..97b3cd8a4 --- /dev/null +++ b/src/mem/ruby/common/TypeDefines.hh @@ -0,0 +1,23 @@ + +#ifndef TYPEDEFINES_H +#define TYPEDEFINES_H + + +typedef unsigned char uint8; +typedef unsigned int uint32; +typedef unsigned long long uint64; + +typedef signed char int8; +typedef int int32; +typedef long long int64; + +typedef long long integer_t; +typedef unsigned long long uinteger_t; + +typedef int64 Time; +typedef uint64 physical_address_t; +typedef uint64 la_t; +typedef uint64 pa_t; +typedef integer_t simtime_t; + +#endif diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb new file mode 100644 index 000000000..8c2eef009 --- /dev/null +++ b/src/mem/ruby/config/MI_example-homogeneous.rb @@ -0,0 +1,64 @@ +#!/usr/bin/ruby +# +# Creates a homogeneous CMP system with a single unified cache per +# core and a crossbar network. Uses the default parameters listed +# below, which can be overridden if a wrapper script sets the hash +# libruby_args. +# + +require "cfg.rb" + +# default values + +num_cores = 16 +L1_CACHE_SIZE_KB = 32 +L1_CACHE_ASSOC = 8 +L1_CACHE_LATENCY = "auto" +num_memories = 2 +memory_size_mb = 1024 +NUM_DMA = 1 + +# check for overrides + +for i in 0..$*.size-1 do + if $*[i] == "-p" + num_cores = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-m" + num_memories = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-s" + memory_size_mb = $*[i+1].to_i + i = i + 1 + end +end + +net_ports = Array.new +iface_ports = Array.new + +num_cores.times { |n| + cache = SetAssociativeCache.new("l1u_"+n.to_s, L1_CACHE_SIZE_KB, L1_CACHE_LATENCY, L1_CACHE_ASSOC, "PSEUDO_LRU") + sequencer = Sequencer.new("Sequencer_"+n.to_s, cache, cache) + iface_ports << sequencer + net_ports << MI_example_CacheController.new("L1CacheController_"+n.to_s, + "L1Cache", + [cache], + sequencer) +} +num_memories.times { |n| + directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) + memory_control = MemoryControl.new("MemoryControl_"+n.to_s) + net_ports << MI_example_DirectoryController.new("DirectoryController_"+n.to_s, + "Directory", + directory, memory_control) +} +NUM_DMA.times { |n| + dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) + iface_ports << dma_sequencer + net_ports << DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer) +} + +topology = CrossbarTopology.new("theTopology", net_ports) +on_chip_net = Network.new("theNetwork", topology) + +RubySystem.init(iface_ports, on_chip_net) diff --git a/src/mem/ruby/config/RubyConfig.cc b/src/mem/ruby/config/RubyConfig.cc index fe58a74d3..987a3d81d 100644 --- a/src/mem/ruby/config/RubyConfig.cc +++ b/src/mem/ruby/config/RubyConfig.cc @@ -36,135 +36,191 @@ * */ -#include "config/ruby_debug.hh" #include "mem/ruby/config/RubyConfig.hh" -#include "mem/protocol/protocol_name.hh" +//#include "mem/protocol/protocol_name.hh" #include "mem/gems_common/util.hh" -#include "mem/protocol/Protocol.hh" + +#define CONFIG_DEF_FILE "mem/ruby/config/config.hh" + +#define ERROR_MSG(MESSAGE)\ +{\ + cerr << "Fatal Error: in fn "\ + << __PRETTY_FUNCTION__ << " in "\ + << __FILE__ << ":"\ + << __LINE__ << ": "\ + << (MESSAGE) << endl << flush;\ + abort();\ +} + +// declare all configuration variables +#define PARAM_BOOL( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + bool RubyConfig::m_##NAME = DEFAULT_VALUE; +#define PARAM_STRING( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + const char* RubyConfig::m_##NAME = DEFAULT_VALUE; +#define PARAM_ULONG( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + uint64 RubyConfig::m_##NAME = DEFAULT_VALUE; +#define PARAM( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + int RubyConfig::m_##NAME = DEFAULT_VALUE; +#define PARAM_ARRAY( NAME, TYPE, DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + TYPE* RubyConfig::m_##NAME = NULL; +#define PARAM_ARRAY2D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + TYPE** RubyConfig::m_##NAME = NULL; +#define PARAM_ARRAY3D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, D3_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + TYPE*** RubyConfig::m_##NAME = NULL; +#include CONFIG_DEF_FILE +#undef PARAM_BOOL +#undef PARAM_STRING +#undef PARAM_ULONG +#undef PARAM +#undef PARAM_ARRAY +#undef PARAM_ARRAY2D +#undef PARAM_ARRAY3D #define CHECK_POWER_OF_2(N) { if (!is_power_of_2(N)) { ERROR_MSG(#N " must be a power of 2."); }} #define CHECK_ZERO(N) { if (N != 0) { ERROR_MSG(#N " must be zero at initialization."); }} #define CHECK_NON_ZERO(N) { if (N == 0) { ERROR_MSG(#N " must be non-zero."); }} +uint32 RubyConfig::m_data_block_mask; + +void RubyConfig::reset() +{ + #define PARAM_BOOL( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + m_##NAME = DEFAULT_VALUE; +#define PARAM_STRING( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + m_##NAME = DEFAULT_VALUE; +#define PARAM_ULONG( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + m_##NAME = DEFAULT_VALUE; +#define PARAM( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + m_##NAME = DEFAULT_VALUE; +#define PARAM_ARRAY( NAME, TYPE, DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + m_##NAME = new TYPE[DEFAULT_ARRAY_SIZE]; \ + for (int i=0; i= g_PROCS_PER_CHIP); // obviously can't have less processors than procs/chip - g_NUM_CHIPS = g_NUM_PROCESSORS/g_PROCS_PER_CHIP; - ASSERT(g_NUM_L2_BANKS >= g_NUM_CHIPS); // cannot have a single L2cache across multiple chips - - g_NUM_L2_BANKS_PER_CHIP = g_NUM_L2_BANKS/g_NUM_CHIPS; - - ASSERT(L2_CACHE_NUM_SETS_BITS > log_int(g_NUM_L2_BANKS_PER_CHIP)); // cannot have less than one set per bank - L2_CACHE_NUM_SETS_BITS = L2_CACHE_NUM_SETS_BITS - log_int(g_NUM_L2_BANKS_PER_CHIP); - - if (g_NUM_CHIPS > g_NUM_MEMORIES) { - g_NUM_MEMORIES_PER_CHIP = 1; // some chips have a memory, others don't + CHECK_ZERO(m_MEMORY_SIZE_BITS); + CHECK_ZERO(m_NUM_PROCESSORS_BITS); + CHECK_ZERO(m_NUM_CHIP_BITS); + CHECK_ZERO(m_NUM_L2_BANKS_BITS); + CHECK_ZERO(m_NUM_MEMORIES_BITS); + CHECK_ZERO(m_PROCS_PER_CHIP_BITS); + CHECK_ZERO(m_NUM_L2_BANKS_PER_CHIP); + CHECK_ZERO(m_NUM_L2_BANKS_PER_CHIP_BITS); + CHECK_ZERO(m_NUM_MEMORIES_BITS); + CHECK_ZERO(m_MEMORY_MODULE_BLOCKS); + CHECK_ZERO(m_MEMORY_MODULE_BITS); + CHECK_ZERO(m_NUM_MEMORIES_PER_CHIP); + + CHECK_POWER_OF_2(m_MemorySizeBytes); + CHECK_POWER_OF_2(m_NUM_PROCESSORS); + CHECK_POWER_OF_2(m_NUM_L2_BANKS); + CHECK_POWER_OF_2(m_NUM_MEMORIES); + CHECK_POWER_OF_2(m_ProcsPerChip); + + assert(m_NUM_PROCESSORS >= m_ProcsPerChip); // obviously can't have less processors than procs/chip + m_NUM_CHIPS = m_NUM_PROCESSORS/m_ProcsPerChip; + assert(m_NUM_L2_BANKS >= m_NUM_CHIPS); // cannot have a single L2cache across multiple chips + + m_NUM_L2_BANKS_PER_CHIP = m_NUM_L2_BANKS/m_NUM_CHIPS; + + if (m_NUM_CHIPS > m_NUM_MEMORIES) { + m_NUM_MEMORIES_PER_CHIP = 1; // some chips have a memory, others don't } else { - g_NUM_MEMORIES_PER_CHIP = g_NUM_MEMORIES/g_NUM_CHIPS; + m_NUM_MEMORIES_PER_CHIP = m_NUM_MEMORIES/m_NUM_CHIPS; } - g_NUM_CHIP_BITS = log_int(g_NUM_CHIPS); - g_MEMORY_SIZE_BITS = log_int(g_MEMORY_SIZE_BYTES); - g_DATA_BLOCK_BITS = log_int(g_DATA_BLOCK_BYTES); - g_PAGE_SIZE_BITS = log_int(g_PAGE_SIZE_BYTES); - g_NUM_PROCESSORS_BITS = log_int(g_NUM_PROCESSORS); - g_NUM_L2_BANKS_BITS = log_int(g_NUM_L2_BANKS); - g_NUM_L2_BANKS_PER_CHIP_BITS = log_int(g_NUM_L2_BANKS_PER_CHIP); - g_NUM_MEMORIES_BITS = log_int(g_NUM_MEMORIES); - g_PROCS_PER_CHIP_BITS = log_int(g_PROCS_PER_CHIP); - - g_MEMORY_MODULE_BITS = g_MEMORY_SIZE_BITS - g_DATA_BLOCK_BITS - g_NUM_MEMORIES_BITS; - g_MEMORY_MODULE_BLOCKS = (int64(1) << g_MEMORY_MODULE_BITS); - - if ((!Protocol::m_CMP) && (g_PROCS_PER_CHIP > 1)) { - ERROR_MSG("Non-CMP protocol should set g_PROCS_PER_CHIP to 1"); - } + m_NUM_CHIP_BITS = log_int(m_NUM_CHIPS); + m_MEMORY_SIZE_BITS = log_int(m_MemorySizeBytes); - // Randomize the execution - srandom(g_RANDOM_SEED); -} + m_data_block_mask = ~ (~0 << m_DATA_BLOCK_BITS); -int RubyConfig::L1CacheNumToL2Base(NodeID L1CacheNum) -{ - return L1CacheNum/g_PROCS_PER_CHIP; + m_NUM_PROCESSORS_BITS = log_int(m_NUM_PROCESSORS); + m_NUM_L2_BANKS_BITS = log_int(m_NUM_L2_BANKS); + m_NUM_L2_BANKS_PER_CHIP_BITS = log_int(m_NUM_L2_BANKS_PER_CHIP); + m_NUM_MEMORIES_BITS = log_int(m_NUM_MEMORIES); + m_PROCS_PER_CHIP_BITS = log_int(m_ProcsPerChip); + + m_MEMORY_MODULE_BITS = m_MEMORY_SIZE_BITS - m_DATA_BLOCK_BITS - m_NUM_MEMORIES_BITS; + m_MEMORY_MODULE_BLOCKS = (int64(1) << m_MEMORY_MODULE_BITS); + + */ + + // Randomize the execution + // srandom(m_RandomSeed); } static void print_parameters(ostream& out) { -#define PARAM(NAME) { out << #NAME << ": " << NAME << endl; } -#define PARAM_UINT(NAME) { out << #NAME << ": " << NAME << endl; } -#define PARAM_ULONG(NAME) { out << #NAME << ": " << NAME << endl; } -#define PARAM_BOOL(NAME) { out << #NAME << ": " << bool_to_string(NAME) << endl; } -#define PARAM_DOUBLE(NAME) { out << #NAME << ": " << NAME << endl; } -#define PARAM_STRING(NAME) { assert(NAME != NULL); out << #NAME << ": " << string(NAME) << endl; } -#define PARAM_ARRAY(PTYPE, NAME, ARRAY_SIZE) \ - { \ - out << #NAME << ": ("; \ - for (int i = 0; i < ARRAY_SIZE; i++) { \ - if (i != 0) { \ - out << ", "; \ - } \ - out << NAME[i]; \ - } \ - out << ")" << endl; \ - } \ - - -#include "mem/ruby/config/config.hh" +#define print_true(NAME) +#define print_false(NAME) \ + out << #NAME << ": " << RubyConfig::get##NAME () << endl + +#define PARAM(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_UINT(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_ULONG(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_BOOL(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_DOUBLE(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_STRING(NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR) { print_##CUSTOM_ACCESSOR(NAME); } +#define PARAM_ARRAY( NAME, TYPE, DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) { out << #NAME << ": ARRAY" << endl; } +#define PARAM_ARRAY2D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) { out << #NAME << ": ARRAY2D" << endl; } +#define PARAM_ARRAY3D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, D3_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) { out << #NAME << ": ARRAY3D" << endl; } +#include CONFIG_VAR_FILENAME #undef PARAM #undef PARAM_UINT #undef PARAM_ULONG @@ -172,15 +228,17 @@ static void print_parameters(ostream& out) #undef PARAM_DOUBLE #undef PARAM_STRING #undef PARAM_ARRAY +#undef PARAM_ARRAY2D +#undef PARAM_ARRAY3D } void RubyConfig::printConfiguration(ostream& out) { out << "Ruby Configuration" << endl; out << "------------------" << endl; - out << "protocol: " << CURRENT_PROTOCOL << endl; + //out << "protocol: " << CURRENT_PROTOCOL << endl; out << "compiled_at: " << __TIME__ << ", " << __DATE__ << endl; - out << "RUBY_DEBUG: " << bool_to_string(RUBY_DEBUG) << endl; + // out << "RUBY_DEBUG: " << bool_to_string(RUBY_DEBUG) << endl; char buffer[100]; gethostname(buffer, 50); diff --git a/src/mem/ruby/config/RubyConfig.hh b/src/mem/ruby/config/RubyConfig.hh index 6de6bd1aa..f2e3a0f13 100644 --- a/src/mem/ruby/config/RubyConfig.hh +++ b/src/mem/ruby/config/RubyConfig.hh @@ -40,12 +40,13 @@ #ifndef RUBYCONFIG_H #define RUBYCONFIG_H -#include "mem/ruby/common/Global.hh" -#include "mem/gems_common/ioutil/vardecl.hh" -#include "mem/ruby/system/NodeID.hh" +#include +#include +#include +#include -#define MEMORY_LATENCY RubyConfig::memoryResponseLatency() -#define ABORT_DELAY m_chip_ptr->getTransactionManager(m_version)->getAbortDelay() +#include "mem/ruby/common/TypeDefines.hh" +#define CONFIG_VAR_FILENAME "mem/ruby/config/config.hh" // Set paramterization /* @@ -61,96 +62,169 @@ */ const int NUMBER_WORDS_PER_SET = 4; +using namespace std; + class RubyConfig { public: // CACHE BLOCK CONFIG VARIBLES - static int dataBlockBits() { return g_DATA_BLOCK_BITS; } - static int dataBlockBytes() { return g_DATA_BLOCK_BYTES; } + static uint32 dataBlockMask() { return m_data_block_mask; } + + static int numberOfDMA() { return 1; } + static int numberOfDMAPerChip() { return 1; } + static int DMATransitionsPerCycle() { return 1; } // SUPPORTED PHYSICAL MEMORY CONFIG VARIABLES - static int pageSizeBits() { return g_PAGE_SIZE_BITS; } - static int pageSizeBytes() { return g_PAGE_SIZE_BYTES; } - static int memorySizeBits() { return g_MEMORY_SIZE_BITS; } - static int64 memorySizeBytes() { return g_MEMORY_SIZE_BYTES; } - static int memoryModuleBits() { return g_MEMORY_MODULE_BITS; } - static int64 memoryModuleBlocks() { return g_MEMORY_MODULE_BLOCKS; } - - // returns number of SMT threads per physical processor - static int numberofSMTThreads() { return g_NUM_SMT_THREADS; } + // static int memoryModuleBits() { return m_MEMORY_MODULE_BITS; } + // static int64 memoryModuleBlocks() { return m_MEMORY_MODULE_BLOCKS; } + // defines the number of simics processors (power of 2) - static int numberOfProcessors() { return g_NUM_PROCESSORS; } - static int procsPerChipBits() { return g_PROCS_PER_CHIP_BITS; } - static int numberOfProcsPerChip() { return g_PROCS_PER_CHIP; } - static int numberOfChips() { return g_NUM_CHIPS; } + // static int numberOfProcessors() { return m_NUM_PROCESSORS; } + // static int procsPerChipBits() { return m_PROCS_PER_CHIP_BITS; } + // static int numberOfProcsPerChip() { return m_ProcsPerChip; } + // static int numberOfChips() { return m_NUM_CHIPS; } // MACHINE INSTANIATION CONFIG VARIABLES // ------------------------------------- // L1 CACHE MACHINES // defines the number of L1banks - idependent of ruby chips (power of 2) // NOTE - no protocols currently supports L1s != processors, just a placeholder - static int L1CacheBits() { return g_NUM_PROCESSORS_BITS; } - static int numberOfL1Cache() { return g_NUM_PROCESSORS; } - static int L1CachePerChipBits() { return procsPerChipBits() ; } // L1s != processors not currently supported - static int numberOfL1CachePerChip() { return numberOfProcsPerChip(); } // L1s != processors not currently supported - static int numberOfL1CachePerChip(NodeID myNodeID) { return numberOfL1CachePerChip(); } - static int L1CacheTransitionsPerCycle() { return L1CACHE_TRANSITIONS_PER_RUBY_CYCLE; } - - // L2 CACHE MACHINES - // defines the number of L2banks/L2Caches - idependent of ruby chips (power of 2) - static int L2CacheBits() { return g_NUM_L2_BANKS_BITS; } - static int numberOfL2Cache() { return g_NUM_L2_BANKS; } - static int L1CacheNumToL2Base(NodeID L1RubyNodeID); - static int L2CachePerChipBits() { return g_NUM_L2_BANKS_PER_CHIP_BITS; } - static int numberOfL2CachePerChip() { return g_NUM_L2_BANKS_PER_CHIP; } - static int numberOfL2CachePerChip(NodeID myNodeID) { return numberOfL2CachePerChip(); } - static int L2CacheTransitionsPerCycle() { return L2CACHE_TRANSITIONS_PER_RUBY_CYCLE; } // DIRECTORY/MEMORY MACHINES // defines the number of ruby memories - idependent of ruby chips (power of 2) - static int memoryBits() { return g_NUM_MEMORIES_BITS; } - static int numberOfDirectory() { return numberOfMemories(); } - static int numberOfMemories() { return g_NUM_MEMORIES; } - static int numberOfDirectoryPerChip() { return g_NUM_MEMORIES_PER_CHIP; } - static int numberOfDirectoryPerChip(NodeID myNodeID) { return g_NUM_MEMORIES_PER_CHIP; } - static int DirectoryTransitionsPerCycle() { return DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE; } - - // PERSISTENT ARBITER MACHINES - static int numberOfPersistentArbiter() { return numberOfMemories(); } - static int numberOfPersistentArbiterPerChip() {return numberOfDirectoryPerChip(); } - static int numberOfPersistentArbiterPerChip(NodeID myNodeID) {return numberOfDirectoryPerChip(myNodeID); } - static int PersistentArbiterTransitionsPerCycle() { return L2CACHE_TRANSITIONS_PER_RUBY_CYCLE; } + // static int memoryBits() { return m_NUM_MEMORIES_BITS; } + // static int numberOfDirectory() { return numberOfMemories(); } + // static int numberOfMemories() { return m_NUM_MEMORIES; } + // static int numberOfDirectoryPerChip() { return m_NUM_MEMORIES_PER_CHIP; } + // static int DirectoryTransitionsPerCycle() { return m_DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE; } // ---- END MACHINE SPECIFIC VARIABLES ---- // VARIABLE MEMORY RESPONSE LATENCY // *** NOTE *** This is where variation is added to the simulation // see Alameldeen et al. HPCA 2003 for further details - static int memoryResponseLatency() { return MEMORY_RESPONSE_LATENCY_MINUS_2+(random() % 5); } +// static int getMemoryLatency() { return m_MEMORY_RESPONSE_LATENCY_MINUS_2+(random() % 5); } + static void reset(); static void init(); - static void printConfiguration(ostream& out); + static void printConfiguration(std::ostream& out); // Memory Controller - static int memBusCycleMultiplier () { return MEM_BUS_CYCLE_MULTIPLIER; } - static int banksPerRank () { return BANKS_PER_RANK; } - static int ranksPerDimm () { return RANKS_PER_DIMM; } - static int dimmsPerChannel () { return DIMMS_PER_CHANNEL; } - static int bankBit0 () { return BANK_BIT_0; } - static int rankBit0 () { return RANK_BIT_0; } - static int dimmBit0 () { return DIMM_BIT_0; } - static int bankQueueSize () { return BANK_QUEUE_SIZE; } - static int bankBusyTime () { return BANK_BUSY_TIME; } - static int rankRankDelay () { return RANK_RANK_DELAY; } - static int readWriteDelay () { return READ_WRITE_DELAY; } - static int basicBusBusyTime () { return BASIC_BUS_BUSY_TIME; } - static int memCtlLatency () { return MEM_CTL_LATENCY; } - static int refreshPeriod () { return REFRESH_PERIOD; } - static int tFaw () { return TFAW; } - static int memRandomArbitrate () { return MEM_RANDOM_ARBITRATE; } - static int memFixedDelay () { return MEM_FIXED_DELAY; } + +// static int memBusCycleMultiplier () { return m_MEM_BUS_CYCLE_MULTIPLIER; } +/* static int banksPerRank () { return m_BANKS_PER_RANK; } + static int ranksPerDimm () { return m_RANKS_PER_DIMM; } + static int dimmsPerChannel () { return m_DIMMS_PER_CHANNEL; } + static int bankBit0 () { return m_BANK_BIT_0; } + static int rankBit0 () { return m_RANK_BIT_0; } + static int dimmBit0 () { return m_DIMM_BIT_0; } + static int bankQueueSize () { return m_BANK_QUEUE_SIZE; } + static int bankBusyTime () { return m_BankBusyTime; } + static int rankRankDelay () { return m_RANK_RANK_DELAY; } + static int readWriteDelay () { return m_READ_WRITE_DELAY; } + static int basicBusBusyTime () { return m_BASIC_BUS_BUSY_TIME; } + static int memCtlLatency () { return m_MEM_CTL_LATENCY; } + static int refreshPeriod () { return m_REFRESH_PERIOD; } + static int tFaw () { return m_TFAW; } + static int memRandomArbitrate () { return m_MEM_RANDOM_ARBITRATE; } + static int memFixedDelay () { return m_MEM_FIXED_DELAY; } +*/ + /* cache accessors */ + static int getCacheIDFromParams(int level, int num, string split_type) { + // TODO: this function + return 0; + } + +#define accessor_true( TYPE, NAME ) +#define accessor_false( TYPE, NAME ) \ + static TYPE get##NAME() { return m_##NAME; } \ + static void set##NAME(TYPE val) { m_##NAME = val; } + +#define array_accessor_true( TYPE, NAME, DEFAULT_ARRAY_SIZE ) +#define array_accessor_false( TYPE, NAME, DEFAULT_ARRAY_SIZE ) \ + static TYPE get##NAME(int idx) { \ + assert(m_##NAME != NULL); \ + return m_##NAME[idx]; \ + } \ + static void set##NAME(int idx, TYPE val) { \ + if(m_##NAME == NULL) { \ + assert(DEFAULT_ARRAY_SIZE > 0); \ + m_##NAME = new TYPE[DEFAULT_ARRAY_SIZE]; \ + } \ + m_##NAME[idx] = val; \ + } + +#define array2d_accessor_true( TYPE, NAME ) +#define array2d_accessor_false( TYPE, NAME ) \ + static TYPE get##NAME(int idx1, int idx2) { return m_##NAME[idx1][idx2]; } \ + static void set##NAME(int idx1, int idx2, TYPE val) { m_##NAME[idx1][idx2] = val; } + +#define array3d_accessor_true( TYPE, NAME ) +#define array3d_accessor_false( TYPE, NAME ) \ + static TYPE get##NAME(int idx1, int idx2, int idx3) { return m_##NAME[idx1][idx2][idx3]; } \ + static void set##NAME(int idx1, int idx2, int idx3, TYPE val) { m_##NAME[idx1][idx2][idx3] = val; } + +#define PARAM( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(int32,NAME) +#define PARAM_UINT( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(uint32,NAME) +#define PARAM_ULONG( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(uint64,NAME) +#define PARAM_BOOL( NAME, DEFAULT_VALUE,CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(bool,NAME) +#define PARAM_DOUBLE( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(double,NAME) +#define PARAM_STRING( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + accessor_##CUSTOM_ACCESSOR(const char*,NAME) +#define PARAM_ARRAY( NAME, TYPE, DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + array_accessor_##CUSTOM_ACCESSOR(TYPE, NAME, DEFAULT_ARRAY_SIZE) +#define PARAM_ARRAY2D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + array2d_accessor_##CUSTOM_ACCESSOR(TYPE, NAME) +#define PARAM_ARRAY3D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, D3_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + array3d_accessor_##CUSTOM_ACCESSOR(TYPE, NAME) +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY +#undef PARAM_ARRAY2D +#undef PARAM_ARRAY3D private: + static uint32 m_data_block_mask; + +#define PARAM( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static int32 m_##NAME; +#define PARAM_UINT( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static uint32 m_##NAME; +#define PARAM_ULONG( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static uint64 m_##NAME; +#define PARAM_BOOL( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static bool m_##NAME; +#define PARAM_DOUBLE( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static double m_##NAME; +#define PARAM_STRING( NAME, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static const char *m_##NAME; +#define PARAM_ARRAY( NAME, TYPE, DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static TYPE* m_##NAME; +#define PARAM_ARRAY2D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static TYPE** m_##NAME; +#define PARAM_ARRAY3D( NAME, TYPE, D1_DEFAULT_ARRAY_SIZE, D2_DEFAULT_ARRAY_SIZE, D3_DEFAULT_ARRAY_SIZE, DEFAULT_VALUE, CUSTOM_ACCESSOR ) \ + static TYPE*** m_##NAME; +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY +#undef PARAM_ARRAY2D +#undef PARAM_ARRAY3D + }; #endif //RUBYCONFIG_H diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb new file mode 100644 index 000000000..de8bcafd2 --- /dev/null +++ b/src/mem/ruby/config/cfg.rb @@ -0,0 +1,751 @@ +#!/usr/bin/ruby + +class AssertionFailure < RuntimeError +end + +class Boolean + def self.is_a?(obj) + return self.name == "Boolean" + end +end + +def assert(condition,message) + unless condition + raise AssertionFailure, "Assertion failed: #{message}" + end +end + +class LibRubyObject + @@all_objs = Array.new + attr_reader :obj_name + @@default_params = Hash.new + + def initialize(obj_name) + assert obj_name.is_a?(String), "Obj_Name must be a string" + @obj_name = obj_name + @@all_objs << self + @params = Hash.new + end + + def cppClassName() + raise NotImplementedException + end + + def self.param(param_name, type) + idx = self.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx][param_name] = nil + send :define_method, param_name do + @params[param_name] = @@default_params[idx][param_name] if ! @params.key?(param_name) + @params[param_name] + end + method_name = (param_name.to_s + "=").to_sym + send :define_method, method_name do |val| + if val.is_a?(FalseClass) || val.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert val.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end +# assert val.is_a?(type), "#{param_name} must be of type #{type}" + @params[param_name] = val + end + end + + def self.default_param(param_name, type, default) + idx = self.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + if default.is_a?(FalseClass) || default.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert default.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end + @@default_params[idx][param_name] = default + send :define_method, param_name do + @params[param_name] = @@default_params[idx][param_name] if ! @params.key?(param_name) + @params[param_name] + end + method_name = (param_name.to_s + "=").to_sym + send :define_method, method_name do |val| + assert val.is_a?(type), "#{param_name} must be of type #{type}" + @params[param_name] = val + end + end + + def applyDefaults() + idx = self.class.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx].each { |key, val| + @params[key] = val if ! @params.key?(key) + } + end + + def argv() + str = "" + + applyDefaults + + @params.each { |key, val| + str += key.id2name + " " + if val.is_a?(LibRubyObject) + str += val.obj_name + " " + else + if val.is_a?(String) and val == "" + str += "null " + else + str += val.to_s + " " + end + end + } + return str + end + + def self.printConstructors() + @@all_objs.each { |obj| + print obj.cppClassName, " ", obj.obj_name, " ",obj.argv,"\n" + } + end + def self.all() + @@all_objs + end +end + +class IfacePort < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def bochsConnType + raise NotImplementedException + end +end + +class NetPort < LibRubyObject + attr :mach_type + attr_reader :version + + @@type_cnt = Hash.new + @type_id + def initialize(obj_name, mach_type) + super(obj_name) + @mach_type = mach_type + @@type_cnt[mach_type] ||= 0 + @type_id = @@type_cnt[mach_type] + @@type_cnt[mach_type] += 1 + + idx = "NetPort".to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx].each { |key, val| + @params[key] = val if ! @params.key?(key) + } + end + + def port_name + mach_type + end + def port_num + @type_id + end + def cppClassName + "NetPort" + end +end + +class MemoryVector < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName + "MemoryController" + end +end + +class Debug < LibRubyObject + def initialize *args + case args.size + when 1 + super(args[0]) + when 6 + init_params *args[1] + else + raise Exception + end + end + + def init_params (protocol_trace, filter_string, verbosity_string, start_time, output_filename) + @params[:protocol_trace] = protocol_trace + @params[:filter_string] = filter_string + @params[:verbosity_string] = verbosity_string + @params[:start_time] = start_time + @params[:output_filename] = output_filename + end + + def cppClassName + "Debug" + end +end + +class RubySystem + + @@params = Hash.new + @@network = nil + + def self.init(iface_ports, network) + @@iface_ports = iface_ports + @@network = network + end + + def self.default_param(param_name, type, default) + if default.is_a?(FalseClass) || default.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert default.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end + @@params[param_name] = default + method_name = (param_name.to_s).to_sym + instance_eval <<-EOS + def #{method_name.to_s} + @@params[:#{param_name.to_s}] + end + EOS + instance_eval <<-EOS + def #{method_name.to_s}=(val) + @@params[:#{param_name.to_s}] = val + end + EOS + end + + def self.generateConfig() + # get current time for random seed if set to "rand" + if @@params[:random_seed] == "rand" + t = Time.now + @@params[:random_seed] = t.usec.to_i + end + if ! @@params[:random_seed].is_a?(Integer) + raise TypeException + end + print "System sys0 ",argv,"\n" + LibRubyObject.all.each { |obj| + if obj.is_a?(SetAssociativeCache) + obj.calculateLatency + end + } + LibRubyObject.printConstructors + end + + def self.printIfacePorts() + @@iface_ports.each { |port| + print port.obj_name, " " + } + puts + end + + def self.getBochsConnections() + ports = Hash.new + @@iface_ports.each { |port| + ports[port.obj_name] = port.bochsConnType + } + return ports + end + + def self.getMemorySizeMB() + DirectoryMemory.memorySizeMB + end + + # override the default accessors (generated by default_param) for random_seed + def self.random_seed=(seed) + assert (val.is_a?(Integer) or val == "rand"), "RubySystem.random_seed takes either an integer value or the string \"rand\"" + @@params[:random_seed] = seed + end + +private + + def self.argv() + str = "" + @@params.each { |key, val| + str += key.id2name + " " + str += val.to_s + " " + } + return str + end + + def self.writeConfig() + @@network.printTopology + end + +end + +#require "defaults.rb" + + + +class CacheController < NetPort + @@total_cache_controllers = 0 + attr :caches + attr :sequencer + def initialize(obj_name, mach_type, caches, sequencer) + super(obj_name, mach_type) + @caches = caches + @caches.each { |cache| + cache.controller = self + } + + @sequencer = sequencer + @sequencer.controller = self + + @version = @@total_cache_controllers + @@total_cache_controllers += 1 + @sequencer.version = @version + buffer_size() + end + + def argv() + vec = "version "+@version.to_s + @caches.each { |cache| + vec += " cache " + cache.obj_name + } + vec += " sequencer "+@sequencer.obj_name + vec += " transitions_per_cycle "+@params[:transitions_per_cycle].to_s + vec += " buffer_size "+@params[:buffer_size].to_s + vec += " number_of_TBEs "+@params[:number_of_TBEs].to_s + + end + + def cppClassName() + "generated:"+@mach_type + end +end + +class DirectoryController < NetPort + @@total_directory_controllers = 0 + attr :directory + attr :memory_control + + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type) + + @directory = directory + directory.controller = self + + @memory_control = memory_control + + @version = @@total_directory_controllers + @@total_directory_controllers += 1 + buffer_size() + end + + def argv() + "version "+@version.to_s+" directory_name "+@directory.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s + " memory_controller_name "+@memory_control.obj_name + " recycle_latency "+@params[:recycle_latency].to_s + end + + def cppClassName() + "generated:"+@mach_type + end + +end + +class DMAController < NetPort + @@total_dma_controllers = 0 + attr :dma_sequencer + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type) + @dma_sequencer = dma_sequencer + @version = @@total_dma_controllers + @@total_dma_controllers += 1 + dma_sequencer.controller = self + buffer_size + end + + def argv() + "version "+@version.to_s+" dma_sequencer "+@dma_sequencer.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s + end + + def cppClassName() + "generated:"+@mach_type + end +end + +class Cache < LibRubyObject + attr :size_kb, :latency + attr_writer :controller + def initialize(obj_name, size_kb, latency) + super(obj_name) + assert size_kb.is_a?(Integer), "Cache size must be an integer" + @size_kb = size_kb + @latency = latency + end + + def args + "controller "+@controller.obj_name+" size_kb "+@size_kb.to_s+" latency "+@latency.to_s + end +end + +class SetAssociativeCache < Cache + attr :assoc, :replacement_policy + + # latency can be either an integer, a float, or the string "auto" + # when an integer, it represents the number of cycles for a hit + # when a float, it represents the cache access time in ns + # when set to "auto", libruby will attempt to find a realistic latency by running CACTI + def initialize(obj_name, size_kb, latency, assoc, replacement_policy) + super(obj_name, size_kb, latency) + @assoc = assoc + @replacement_policy = replacement_policy + end + + def calculateLatency() + if @latency == "auto" + cacti_args = Array.new() + cacti_args << (@size_kb*1024) << RubySystem.block_size_bytes << @assoc + cacti_args << 1 << 0 << 0 << 0 << 1 + cacti_args << RubySystem.tech_nm << RubySystem.block_size_bytes*8 + cacti_args << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 1 + cacti_args << 360 << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 << 0 << 0 + cacti_args << 50 << 10 << 10 << 0 << 1 << 1 + + cacti_cmd = File.dirname(__FILE__) + "/cacti/cacti " + cacti_args.join(" ") + + IO.popen(cacti_cmd) { |pipe| + str1 = pipe.readline + str2 = pipe.readline + results = str2.split(", ") + if results.size != 61 + print "CACTI ERROR: CACTI produced unexpected output.\n" + print "Are you using the version shipped with libruby?\n" + raise Exception + end + latency_ns = results[5].to_f + if (latency_ns == "1e+39") + print "CACTI ERROR: CACTI was unable to realistically model the cache ",@obj_name,"\n" + print "Either change the cache parameters or manually set the latency values\n" + raise Exception + end + clk_period_ns = 1e9 * (1.0 / (RubySystem.freq_mhz * 1e6)) + latency_cycles = (latency_ns / clk_period_ns).ceil + @latency = latency_cycles + } + elsif @latency.is_a?(Float) + clk_period_ns = 1e9 * (1.0 / (RubySystem.freq_mhz * 1e6)) + latency_cycles = (@latency / clk_period_ns).ceil + @latency = latency_cycles + elsif ! @latency.is_a?(Integer) + raise Exception + end + end + + def argv() + args+" assoc "+@assoc.to_s+" replacement_policy "+@replacement_policy + end + + def cppClassName() + "SetAssociativeCache" + end +end + +class DirectoryMemory < LibRubyObject + attr :size_mb + attr_writer :controller + @@total_size_mb = 0 + + def initialize(obj_name, size_mb) + super(obj_name) + @size_mb = size_mb + @@total_size_mb += size_mb + end + + def argv() + "version "+@controller.version.to_s+" size_mb "+@size_mb.to_s+" controller "+@controller.obj_name + end + + def cppClassName() + "DirectoryMemory" + end + + def self.memorySizeMB() + @@total_size_mb + end +end + +#added by SS +class MemoryControl < LibRubyObject + attr :name + def initialize(obj_name) + super(obj_name) + @name = obj_name + end + + def argv() + vec = super() + vec += " mem_bus_cycle_multiplier "+mem_bus_cycle_multiplier.to_s + vec += " banks_per_rank "+banks_per_rank.to_s + vec += " ranks_per_dimm "+ranks_per_dimm.to_s + vec += " dimms_per_channel "+dimms_per_channel.to_s + vec += " bank_bit_0 "+bank_bit_0.to_s + vec += " rank_bit_0 "+rank_bit_0.to_s + vec += " dimm_bit_0 "+dimm_bit_0.to_s + vec += " bank_queue_size "+bank_queue_size.to_s + vec += " bank_busy_time "+bank_busy_time.to_s + vec += " rank_rank_delay "+rank_rank_delay.to_s + vec += " read_write_delay "+read_write_delay.to_s + vec += " basic_bus_busy_time "+basic_bus_busy_time.to_s + vec += " mem_ctl_latency "+mem_ctl_latency.to_s + vec += " refresh_period "+refresh_period.to_s + vec += " tFaw "+tFaw.to_s + vec += " mem_random_arbitrate "+mem_random_arbitrate.to_s + vec += " mem_fixed_delay "+mem_fixed_delay.to_s + vec += " memory_controller_name "+@name + + end + + + def cppClassName() + "MemoryControl" + end +end + + + +class Sequencer < IfacePort + + def cppClassName() + "Sequencer" + end + + param :controller, NetPort # must be set after initialization + param :icache, Cache + param :dcache, Cache + param :version, Integer + + def initialize(obj_name, icache, dcache) + super(obj_name) + self.icache=icache + self.dcache=dcache + end + + def bochsConnType() + return "cpu"+version.to_s + end + +end + + + +class DMASequencer < IfacePort + def initialize(obj_name) + super(obj_name) + @params = { + :controller => nil, + :version => nil + } + end + + def controller=(controller) + @params[:controller] = controller.obj_name + @params[:version] = controller.version + end + + def cppClassName() + "DMASequencer" + end + + def bochsConnType() + return "dma"+@params[:version].to_s + end +end + +class IntNode + @@num = 0 + def initialize() + + end +end + +class Network < LibRubyObject +end + +class Topology < LibRubyObject + attr :net_ports + param :network, Network + def initialize(name, net_ports) + super(name) + @net_ports = net_ports + end + + def cppClassName + "Topology" + end +end + +class Network < LibRubyObject + param :topology, Topology + def initialize(name, topo) + super(name) + @params[:topology] = topo + topo.network= self + end + + def argv() + vec = super() + + vec += " endpoint_bandwidth "+endpoint_bandwidth.to_s + vec += " adaptive_routing "+adaptive_routing.to_s + vec += " number_of_virtual_networks "+number_of_virtual_networks.to_s + vec += " fan_out_degree "+fan_out_degree.to_s + + vec += " buffer_size "+buffer_size.to_s + vec += " link_latency "+adaptive_routing.to_s + vec += " on_chip_latency "+on_chip_latency.to_s + + end + + def printTopology() + topology.printFile + end + def cppClassName() + "SimpleNetwork" + end + +end + +class PtToPtTopology < Topology + + param :connections,String + + def initialize(name, net_ports) + super(name, net_ports) + @params[:connections] = "" + @net_ports.each_index { |idx| + @params[:connections] << ("ext_node:"+@net_ports[idx].port_name+":"+@net_ports[idx].port_num.to_s) + @params[:connections] << ("%int_node:"+ idx.to_s+ "%link_latency:"+ link_latency.to_s) + @params[:connections] << ("%bw_multiplier:"+external_bw.to_s+"#") + } + @net_ports.each_index { |outer_idx| + @net_ports.each_index { |inner_idx| + if (outer_idx != inner_idx) + @params[:connections] << ("int_node:"+ outer_idx.to_s+ "%int_node:"+ inner_idx.to_s) + @params[:connections] << ("%link_latency:"+link_latency.to_s+"%bw_multiplier:"+internal_bw.to_s) + @params[:connections] << ("%link_weight:"+1.to_s+"#") + end + } + } + # call the accessors of the parent class to initialize them + # need to find a better method!! + print_config + end + +end + +class CrossbarTopology < Topology + param :connections,String + + def initialize(name, net_ports) + super(name, net_ports) + @params[:connections] = "" + crossbar_node = @net_ports.size + @net_ports.each_index { |idx| + @params[:connections] << ("ext_node:"+@net_ports[idx].port_name+":"+@net_ports[idx].port_num.to_s) + @params[:connections] << ("%int_node:"+ idx.to_s+ "%link_latency:"+ link_latency.to_s) + @params[:connections] << ("%bw_multiplier:"+external_bw.to_s+"#") + } + @net_ports.each_index { |idx| + @params[:connections] << ("int_node:"+idx.to_s+"%int_node:"+crossbar_node.to_s) + @params[:connections] << ("%link_latency:"+link_latency.to_s+"%bw_multiplier:"+internal_bw.to_s) + @params[:connections] << ("%link_weight:"+1.to_s+"#") + } + print_config + end +end + +#added by SS +class Tracer < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName() + "Tracer" + end + +end + +class Profiler < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName() + "Profiler" + end + +end + +class MI_example_CacheController < CacheController + def initialize(obj_name, mach_type, caches, sequencer) + super(obj_name, mach_type, caches, sequencer) + end + def argv() + vec = super() + vec += " issue_latency "+issue_latency.to_s + vec += " cache_response_latency "+cache_response_latency.to_s + end + +end + +class MI_example_DirectoryController < DirectoryController + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type, directory, memory_control) + end + def argv() + vec = super() + vec += " to_mem_ctrl_latency "+to_mem_ctrl_latency.to_s + vec += " directory_latency "+directory_latency.to_s + vec += " memory_latency "+memory_latency.to_s + end + +end + +#added by SS +class GarnetNetwork < Network + def initialize(name, topo) + super(name, topo) + end + def argv() + vec = super() + vec += " flit_size "+flit_size.to_s + vec += " number_of_pipe_stages "+number_of_pipe_stages.to_s + vec += " vcs_per_class "+vcs_per_class.to_s + vec += " buffer_size "+buffer_size.to_s + vec += " using_network_testing "+using_network_testing.to_s + end + +end + +class GarnetFixedPipeline < GarnetNetwork + def initialize(name, net_ports) + super(name, net_ports) + end + + def argv() + super() + end + + def cppClassName() + "GarnetNetwork_d" + end +end + +class GarnetFlexiblePipeline < GarnetNetwork + def initialize(name, net_ports) + super(name, net_ports) + end + + def argv() + super() + end + + def cppClassName() + "GarnetNetwork" + end +end + +require "defaults.rb" diff --git a/src/mem/ruby/config/config.hh b/src/mem/ruby/config/config.hh index 3cad258a2..ad91cd73d 100644 --- a/src/mem/ruby/config/config.hh +++ b/src/mem/ruby/config/config.hh @@ -1,74 +1,23 @@ -// -// This file has been modified by Kevin Moore and Dan Nussbaum of the -// Scalable Systems Research Group at Sun Microsystems Laboratories -// (http://research.sun.com/scalable/) to support the Adaptive -// Transactional Memory Test Platform (ATMTP). For information about -// ATMTP, see the GEMS website: http://www.cs.wisc.edu/gems/. -// -// Please send email to atmtp-interest@sun.com with feedback, questions, or -// to request future announcements about ATMTP. -// -// ---------------------------------------------------------------------- -// -// File modification date: 2008-02-23 -// -// ---------------------------------------------------------------------- -// -// ATMTP is distributed as part of the GEMS software toolset and is -// available for use and modification under the terms of version 2 of the -// GNU General Public License. The GNU General Public License is contained -// in the file $GEMS/LICENSE. -// -// Multifacet GEMS is free software; you can redistribute it and/or modify -// it under the terms of version 2 of the GNU General Public License as -// published by the Free Software Foundation. -// -// Multifacet GEMS is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with the Multifacet GEMS; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA -// -// ---------------------------------------------------------------------- -// - -// see rubyconfig.defaults for some explanations - -PARAM( g_RANDOM_SEED ); - -// Maximum number of cycles a request is can be outstanding before the -// Sequencer of StoreBuffer declares we're in deadlock/livelock -PARAM( g_DEADLOCK_THRESHOLD ); -PARAM_BOOL( RANDOMIZATION ); -PARAM_BOOL( g_SYNTHETIC_DRIVER ); -PARAM_BOOL( g_DETERMINISTIC_DRIVER ); // FOR MOESI_CMP_token -PARAM_BOOL( g_FILTERING_ENABLED ); -PARAM_BOOL( g_DISTRIBUTED_PERSISTENT_ENABLED ); -PARAM_BOOL( g_DYNAMIC_TIMEOUT_ENABLED ); -PARAM( g_RETRY_THRESHOLD ); -PARAM( g_FIXED_TIMEOUT_LATENCY ); - -PARAM( g_trace_warmup_length ); -PARAM_DOUBLE( g_bash_bandwidth_adaptive_threshold ); +//PARAM_BOOL( FilteringEnabled, false, false ); +//PARAM_BOOL( DistributedPersistentEnabled, true, false ); +//PARAM_BOOL( DynamicTimeoutEnabled, true, false ); +//PARAM( RetryThreshold, 1, false ); +//PARAM( FixedTimeoutLatency, 300, false ); -PARAM( g_tester_length ); -PARAM( g_synthetic_locks ); -PARAM( g_deterministic_addrs ); -// Specified Generator: See SpecifiedGeneratorType in external.sm for valid values -PARAM_STRING( g_SpecifiedGenerator ); -PARAM( g_callback_counter ); -PARAM( g_NUM_COMPLETIONS_BEFORE_PASS ); +//PARAM( TraceWarmupLength, 1000000, false ); -PARAM( g_NUM_SMT_THREADS ); +//PARAM( callback_counter, 0, false ); +//PARAM( NUM_COMPLETIONS_BEFORE_PASS, 0, false ); -PARAM( g_think_time ); -PARAM( g_hold_time ); -PARAM( g_wait_time ); +//PARAM( tester_length, 0, false ); +//PARAM( synthetic_locks, 2048, false ); +//PARAM( think_time, 5, false ); +//PARAM( wait_time, 5, false ); +//PARAM( hold_time, 5, false ); +//PARAM( deterministic_addrs, 1, false ); +//PARAM_STRING( SpecifiedGenerator, "DetermInvGenerator", false ); // For debugging purposes, one can enable a trace of all the protocol // state machine changes. Unfortunately, the code to generate the @@ -80,243 +29,208 @@ PARAM( g_wait_time ); // "g_debug_ptr->setDebugTime(1)" to beging the following to set the // debug begin time // -// this use to be ruby/common/Global.h +// this use to be ruby/common/Global.hh -PARAM_BOOL( PROTOCOL_DEBUG_TRACE ); -// a string for filtering debugging output (for all g_debug vars see Debug.h) -PARAM_STRING( DEBUG_FILTER_STRING ); +//PARAM_BOOL( ProtocolDebugTrace, true, false ); +// a string for filtering debugging output (for all g_debug vars see Debug.hh) +//PARAM_STRING( DEBUG_FILTER_STRING, "", false ); // filters debugging messages based on priority (low, med, high) -PARAM_STRING( DEBUG_VERBOSITY_STRING ); +//PARAM_STRING( DEBUG_VERBOSITY_STRING, "", false ); // filters debugging messages based on a ruby time -PARAM_ULONG( DEBUG_START_TIME ); +//PARAM_ULONG( DEBUG_START_TIME, 0, false ); // sends debugging messages to a output filename -PARAM_STRING( DEBUG_OUTPUT_FILENAME ); - -// defines relative (integer) clock multipliers between ruby, opal, and simics -PARAM( SIMICS_RUBY_MULTIPLIER ); -PARAM( OPAL_RUBY_MULTIPLIER ); +//PARAM_STRING( DEBUG_OUTPUT_FILENAME, "", false ); -PARAM_BOOL( TRANSACTION_TRACE_ENABLED ); -PARAM_BOOL( USER_MODE_DATA_ONLY ); -PARAM_BOOL( PROFILE_HOT_LINES ); +//PARAM_BOOL( ProfileHotLines, false, false ); // PROFILE_ALL_INSTRUCTIONS is used if you want Ruby to profile all instructions executed // The following need to be true for this to work correctly: // 1. Disable istc and dstc for this simulation run // 2. Add the following line to the object "sim" in the checkpoint you run from: -// instruction_profile_line_size: 4 +// instruction_profile_line_size: 4 // This is used to have simics report back all instruction requests // For more details on how to find out how to interpret the output physical instruction // address, please read the document in the simics-howto directory -PARAM_BOOL( PROFILE_ALL_INSTRUCTIONS ); +//PARAM_BOOL( ProfileAllInstructions, false, false ); // Set the following variable to true if you want a complete trace of // PCs (physical address of program counters, with executing processor IDs) // to be printed to stdout. Make sure to direct the simics output to a file. // Otherwise, the run will take a really long time! // A long run may write a file that can exceed the OS limit on file length -PARAM_BOOL( PRINT_INSTRUCTION_TRACE ); -PARAM( g_DEBUG_CYCLE ); - -// Don't allow any datablocks to enter the STC -PARAM_BOOL( BLOCK_STC ); +//PARAM_BOOL( PRINT_INSTRUCTION_TRACE, false, false ); +//PARAM( DEBUG_CYCLE, 0, false ); // Make the entire memory system perfect -PARAM_BOOL( PERFECT_MEMORY_SYSTEM ); -PARAM( PERFECT_MEMORY_SYSTEM_LATENCY ); - -PARAM_BOOL( DATA_BLOCK ); // Define NO_DATA_BLOCK to make the DataBlock take zero space - -PARAM_BOOL( REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH ); +//PARAM_BOOL( PERFECT_MEMORY_SYSTEM, false, false ); +//PARAM( PERFECT_MEMORY_SYSTEM_LATENCY, 0, false ); // ********************************************* -// CACHE & MEMORY PARAMETERS +// SYSTEM PARAMETERS // ********************************************* +//PARAM( NumberOfChips, 1, false ); +//PARAM( NumberOfCores, 2, false ); +//PARAM_ARRAY( NumberOfCoresPerChip, int, m_NumberOfChips, 2, false); -PARAM( L1_CACHE_ASSOC ); -PARAM( L1_CACHE_NUM_SETS_BITS ); -PARAM( L2_CACHE_ASSOC ); -PARAM( L2_CACHE_NUM_SETS_BITS ); - -PARAM_ULONG( g_MEMORY_SIZE_BYTES ); -PARAM( g_DATA_BLOCK_BYTES ); -// The following page size parameter is used by the stride prefetcher -PARAM( g_PAGE_SIZE_BYTES ); -PARAM_STRING( g_REPLACEMENT_POLICY ); +// ********************************************* +// CACHE PARAMETERS +// ********************************************* -PARAM( g_NUM_PROCESSORS ); -PARAM( g_NUM_L2_BANKS ); -PARAM( g_NUM_MEMORIES ); -PARAM( g_PROCS_PER_CHIP ); +//PARAM( NumberOfCaches, m_NumberOfCores, false ); +//PARAM( NumberOfCacheLevels, 1, false ); +/* this returns the number of discrete CacheMemories per level (i.e. a split L1 counts for 2) */ +//PARAM_ARRAY( NumberOfCachesPerLevel, int, m_NumberOfCacheLevels, m_NumberOfCores, false ); // this is the number of discrete caches if the level is private + // or the number of banks if the level is shared +//PARAM( CacheIDFromParams, 1, true ); // returns a unique CacheID from the parameters (level, num, split_type) +//PARAM_ARRAY( CacheLatency, int, m_NumberOfCaches, 1, false ); // returns the latency for cache, indexed by CacheID +//PARAM_ARRAY( CacheSplitType, string, m_NumberOfCaches, "unified", false ); // returns "data", "instruction", or "unified", indexed by CacheID +//PARAM_ARRAY( CacheType, string, m_NumberOfCaches, "SetAssociative", false ); // returns the type of a cache, indexed by CacheID +//PARAM_ARRAY( CacheAssoc, int, m_NumberOfCaches, 4, false ); // returns the cache associativity, indexed by CacheID +//PARAM_ARRAY( NumberOfCacheSets, int, m_NumberOfCaches, 256, false ); // returns the number of cache sets, indexed by CacheID +//PARAM_ARRAY( NumberOfCacheSetBits, int, m_NumberOfCaches, log_int(256), false ); // returns the number of cache set bits, indexed by CacheID +//PARAM_ARRAY( CacheReplacementPolicy, string, m_NumberOfCaches, "PSEUDO_LRU", false ); // other option is "LRU" + +//PARAM( DataBlockBytes, 64, false ); +//PARAM( DataBlockBits, log_int(m_DataBlockBytes), false); + +// ******************************************** +// MEMORY PARAMETERS +// ******************************************** + +//PARAM_ARRAY( NumberOfControllersPerType, int, m_NumberOfCacheLevels+2, m_NumberOfCores, false); +//PARAM_ARRAY2D( NumberOfControllersPerTypePerChip, int, m_NumberOfCacheLevels+2, m_NumberOfChips, m_NumberOfCores, false); + +// ******************************************** +// DMA CONTROLLER PARAMETERS +// ******************************************** + +//PARAM( NumberOfDMA, 1, false ); +//PARAM_ARRAY( NumberOfDMAPerChip, int, m_NumberOfChips, 1, false); +//PARAM_ARRAY( ChipNumFromDMAVersion, int, m_NumberOfDMA, 0, false ); + +//PARAM_ULONG( MemorySizeBytes, 4294967296, false ); +//PARAM_ULONG( MemorySizeBits, 32, false); + +//PARAM( NUM_PROCESSORS, 0, false ); +//PARAM( NUM_L2_BANKS, 0, false ); +//PARAM( NUM_MEMORIES, 0, false ); +//PARAM( ProcsPerChip, 1, false ); // The following group of parameters are calculated. They must // _always_ be left at zero. -PARAM( g_NUM_CHIPS ); -PARAM( g_NUM_CHIP_BITS ); -PARAM( g_MEMORY_SIZE_BITS ); -PARAM( g_DATA_BLOCK_BITS ); -PARAM( g_PAGE_SIZE_BITS ); -PARAM( g_NUM_PROCESSORS_BITS ); -PARAM( g_PROCS_PER_CHIP_BITS ); -PARAM( g_NUM_L2_BANKS_BITS ); -PARAM( g_NUM_L2_BANKS_PER_CHIP_BITS ); -PARAM( g_NUM_L2_BANKS_PER_CHIP ); -PARAM( g_NUM_MEMORIES_BITS ); -PARAM( g_NUM_MEMORIES_PER_CHIP ); -PARAM( g_MEMORY_MODULE_BITS ); -PARAM_ULONG( g_MEMORY_MODULE_BLOCKS ); - -// determines the mapping between L2 banks and sets within L2 banks -PARAM_BOOL( MAP_L2BANKS_TO_LOWEST_BITS ); +//PARAM( NUM_CHIPS, 0, false ); +//PARAM( NUM_CHIP_BITS, 0, false ); +//PARAM( MEMORY_SIZE_BITS, 0, false ); +//PARAM( DATA_BLOCK_BITS, 0, false ); +//PARAM( PAGE_SIZE_BITS, 0, false ); +//PARAM( NUM_PROCESSORS_BITS, 0, false ); +//PARAM( PROCS_PER_CHIP_BITS, 0, false ); +//PARAM( NUM_L2_BANKS_BITS, 0, false ); +//PARAM( NUM_L2_BANKS_PER_CHIP_BITS, 0, false ); +//PARAM( NUM_L2_BANKS_PER_CHIP, 0, false ); +//PARAM( NUM_MEMORIES_BITS, 0, false ); +//PARAM( NUM_MEMORIES_PER_CHIP, 0, false ); +//PARAM( MEMORY_MODULE_BITS, 0, false ); +//PARAM_ULONG( MEMORY_MODULE_BLOCKS, 0, false ); // TIMING PARAMETERS -PARAM( DIRECTORY_CACHE_LATENCY ); - -PARAM( NULL_LATENCY ); -PARAM( ISSUE_LATENCY ); -PARAM( CACHE_RESPONSE_LATENCY ); -PARAM( L2_RESPONSE_LATENCY ); -PARAM( L2_TAG_LATENCY ); -PARAM( L1_RESPONSE_LATENCY ); -PARAM( MEMORY_RESPONSE_LATENCY_MINUS_2 ); -PARAM( DIRECTORY_LATENCY ); -PARAM( NETWORK_LINK_LATENCY ); -PARAM( COPY_HEAD_LATENCY ); -PARAM( ON_CHIP_LINK_LATENCY ); -PARAM( RECYCLE_LATENCY ); -PARAM( L2_RECYCLE_LATENCY ); -PARAM( TIMER_LATENCY ); -PARAM( TBE_RESPONSE_LATENCY ); -PARAM_BOOL( PERIODIC_TIMER_WAKEUPS ); - -// constants used by TM protocols -PARAM_BOOL( PROFILE_EXCEPTIONS ); -PARAM_BOOL( PROFILE_XACT ); -PARAM_BOOL( PROFILE_NONXACT ); -PARAM_BOOL( XACT_DEBUG ); -PARAM ( XACT_DEBUG_LEVEL ); -PARAM_BOOL( XACT_MEMORY ); -PARAM_BOOL( XACT_ENABLE_TOURMALINE ); -PARAM( XACT_NUM_CURRENT ); -PARAM( XACT_LAST_UPDATE ); -PARAM_BOOL( XACT_ISOLATION_CHECK ); -PARAM_BOOL( PERFECT_FILTER ); -PARAM_STRING( READ_WRITE_FILTER ); -PARAM_BOOL( PERFECT_VIRTUAL_FILTER ); -PARAM_STRING( VIRTUAL_READ_WRITE_FILTER ); -PARAM_BOOL( PERFECT_SUMMARY_FILTER ); -PARAM_STRING( SUMMARY_READ_WRITE_FILTER ); -PARAM_BOOL( XACT_EAGER_CD ); -PARAM_BOOL( XACT_LAZY_VM ); -PARAM_STRING( XACT_CONFLICT_RES ); -PARAM_BOOL( XACT_VISUALIZER ); -PARAM( XACT_COMMIT_TOKEN_LATENCY ) ; -PARAM_BOOL( XACT_NO_BACKOFF ); -PARAM ( XACT_LOG_BUFFER_SIZE ); -PARAM ( XACT_STORE_PREDICTOR_HISTORY); -PARAM ( XACT_STORE_PREDICTOR_ENTRIES); -PARAM ( XACT_STORE_PREDICTOR_THRESHOLD); -PARAM ( XACT_FIRST_ACCESS_COST ); -PARAM ( XACT_FIRST_PAGE_ACCESS_COST ); -PARAM_BOOL( ENABLE_MAGIC_WAITING ); -PARAM_BOOL( ENABLE_WATCHPOINT ); -PARAM_BOOL( XACT_ENABLE_VIRTUALIZATION_LOGTM_SE ); - -// ATMTP -PARAM_BOOL( ATMTP_ENABLED ); -PARAM_BOOL( ATMTP_ABORT_ON_NON_XACT_INST ); -PARAM_BOOL( ATMTP_ALLOW_SAVE_RESTORE_IN_XACT ); -PARAM( ATMTP_XACT_MAX_STORES ); -PARAM( ATMTP_DEBUG_LEVEL ); +//PARAM( DIRECTORY_CACHE_LATENCY, 6, false ); + +//PARAM( NULL_LATENCY, 1, false ); +//PARAM( ISSUE_LATENCY, 2, false ); +//PARAM( CACHE_RESPONSE_LATENCY, 12, false ); +//PARAM( L2_RESPONSE_LATENCY, 6, false ); +//PARAM( L2_TAG_LATENCY, 6, false ); +//PARAM( L1_RESPONSE_LATENCY, 3, false ); + +//PARAM( MEMORY_RESPONSE_LATENCY_MINUS_2, 158, false ); +//PARAM( DirectoryLatency, 6, false ); + +//PARAM( NetworkLinkLatency, 1, false ); +//PARAM( COPY_HEAD_LATENCY, 4, false ); +//PARAM( OnChipLinkLatency, 1, false ); +//PARAM( RecycleLatency, 10, false ); +//PARAM( L2_RECYCLE_LATENCY, 5, false ); +//PARAM( TIMER_LATENCY, 10000, false ); +//PARAM( TBE_RESPONSE_LATENCY, 1, false ); +//PARAM_BOOL( PERIODIC_TIMER_WAKEUPS, true, false ); // constants used by CMP protocols -PARAM( L1_REQUEST_LATENCY ); -PARAM( L2_REQUEST_LATENCY ); -PARAM_BOOL( SINGLE_ACCESS_L2_BANKS ); // hack to simulate multi-cycle L2 bank accesses +//PARAM( L1_REQUEST_LATENCY, 2, false ); +//PARAM( L2_REQUEST_LATENCY, 4, false ); +//PARAM_BOOL( SINGLE_ACCESS_L2_BANKS, true, false ); // hack to simulate multi-cycle L2 bank accesses // Ruby cycles between when a sequencer issues a miss it arrives at // the L1 cache controller -PARAM( SEQUENCER_TO_CONTROLLER_LATENCY ); +//PARAM( SequencerToControllerLatency, 4, false ); // Number of transitions each controller state machines can complete per cycle -PARAM( L1CACHE_TRANSITIONS_PER_RUBY_CYCLE ); -PARAM( L2CACHE_TRANSITIONS_PER_RUBY_CYCLE ); -PARAM( DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE ); - -// Maximum number of requests (including prefetches) outstanding from -// the sequencer (Note: this also include items buffered in the store -// buffer) -PARAM( g_SEQUENCER_OUTSTANDING_REQUESTS ); +//PARAM( L1CacheTransitionsPerCycle, 32, false ); +//PARAM( L2CACHE_TRANSITIONS_PER_RUBY_CYCLE, 32, false ); +//PARAM( DirectoryTransitionsPerCycle, 32, false ); +//PARAM( DMATransitionsPerCycle, 1, false ); // Number of TBEs available for demand misses, prefetches, and replacements -PARAM( NUMBER_OF_TBES ); -PARAM( NUMBER_OF_L1_TBES ); -PARAM( NUMBER_OF_L2_TBES ); +//PARAM( NumberOfTBEs, 128, false ); +//PARAM( NumberOfL1TBEs, 32, false ); +//PARAM( NumberOfL2TBEs, 32, false ); // NOTE: Finite buffering allows us to simulate a wormhole routed network // with idealized flow control. All message buffers within the network (i.e. // the switch's input and output buffers) are set to the size specified below // by the PROTOCOL_BUFFER_SIZE -PARAM_BOOL( FINITE_BUFFERING ); -PARAM( FINITE_BUFFER_SIZE ); // Zero is unbounded buffers +//PARAM_BOOL( FiniteBuffering, false, false ); +//PARAM( FiniteBufferSize, 3, false ); // Zero is unbounded buffers // Number of requests buffered between the sequencer and the L1 conroller // This can be more accurately simulated in Opal, therefore it's set to an // infinite number // Only effects the simualtion when FINITE_BUFFERING is enabled -PARAM( PROCESSOR_BUFFER_SIZE ); +//PARAM( ProcessorBufferSize, 10, false ); // The PROTOCOL_BUFFER_SIZE limits the size of all other buffers connecting to // Controllers. Controlls the number of request issued by the L2 HW Prefetcher -PARAM( PROTOCOL_BUFFER_SIZE ); - -// Enable the TSO (Total Store Order) memory model -PARAM_BOOL( TSO ); // Note: This also disables the "write" STCs +//PARAM( ProtocolBufferSize, 32, false ); // NETWORK PARAMETERS // Network Topology: See TopologyType in external.sm for valid values -PARAM_STRING( g_NETWORK_TOPOLOGY ); +//PARAM_STRING( NetworkTopology, "PT_TO_PT", false ); // Cache Design specifies file prefix for topology -PARAM_STRING( g_CACHE_DESIGN ); - -PARAM( g_endpoint_bandwidth ); -PARAM_BOOL( g_adaptive_routing ); -PARAM( NUMBER_OF_VIRTUAL_NETWORKS ); -PARAM( FAN_OUT_DEGREE ); -PARAM_BOOL( g_PRINT_TOPOLOGY ); +//PARAM_STRING( CacheDesign, "NUCA", false ); -// transactional memory -PARAM( XACT_LENGTH ); -PARAM( XACT_SIZE ); -PARAM( ABORT_RETRY_TIME ); +//PARAM( EndpointBandwidth, 10000, false ); +//PARAM_BOOL( AdaptiveRouting, true, false ); +//PARAM( NumberOfVirtualNetworks, 6, false ); +//PARAM( FanOutDegree, 4, false ); +//PARAM_BOOL( PrintTopology, true, false ); // Princeton Network (Garnet) -PARAM_BOOL( g_GARNET_NETWORK ); -PARAM_BOOL( g_DETAIL_NETWORK ); -PARAM_BOOL( g_NETWORK_TESTING ); -PARAM( g_FLIT_SIZE ); -PARAM( g_NUM_PIPE_STAGES ); -PARAM( g_VCS_PER_CLASS ); -PARAM( g_BUFFER_SIZE ); +//PARAM_BOOL( UsingGarnetNetwork, true, false ); +//PARAM_BOOL( UsingDetailNetwork, false, false ); +//PARAM_BOOL( UsingNetworkTesting, false, false ); +//PARAM( FlitSize, 16, false ); +//PARAM( NumberOfPipeStages, 4, false ); +//PARAM( VCSPerClass, 4, false ); +//PARAM( BufferSize, 4, false ); // MemoryControl: -PARAM( MEM_BUS_CYCLE_MULTIPLIER ); -PARAM( BANKS_PER_RANK ); -PARAM( RANKS_PER_DIMM ); -PARAM( DIMMS_PER_CHANNEL ); -PARAM( BANK_BIT_0 ); -PARAM( RANK_BIT_0 ); -PARAM( DIMM_BIT_0 ); -PARAM( BANK_QUEUE_SIZE ); -PARAM( BANK_BUSY_TIME ); -PARAM( RANK_RANK_DELAY ); -PARAM( READ_WRITE_DELAY ); -PARAM( BASIC_BUS_BUSY_TIME ); -PARAM( MEM_CTL_LATENCY ); -PARAM( REFRESH_PERIOD ); -PARAM( TFAW ); -PARAM( MEM_RANDOM_ARBITRATE ); -PARAM( MEM_FIXED_DELAY ); +//PARAM( MEM_BUS_CYCLE_MULTIPLIER, 10, false ); +//PARAM( BANKS_PER_RANK, 8, false ); +//PARAM( RANKS_PER_DIMM, 2, false ); +//PARAM( DIMMS_PER_CHANNEL, 2, false ); +//PARAM( BANK_BIT_0, 8, false ); +//PARAM( RANK_BIT_0, 11, false ); +//PARAM( DIMM_BIT_0, 12, false ); +//PARAM( BANK_QUEUE_SIZE, 12, false ); +//PARAM( BankBusyTime, 11, false ); +//PARAM( RANK_RANK_DELAY, 1, false ); +//PARAM( READ_WRITE_DELAY, 2, false ); +//PARAM( BASIC_BUS_BUSY_TIME, 2, false ); +//PARAM( MEM_CTL_LATENCY, 12, false ); +//PARAM( REFRESH_PERIOD, 1560, false ); +//PARAM( TFAW, 0, false ); +//PARAM( MEM_RANDOM_ARBITRATE, 0, false ); +//PARAM( MEM_FIXED_DELAY, 0, false ); diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb new file mode 100644 index 000000000..110bf4241 --- /dev/null +++ b/src/mem/ruby/config/defaults.rb @@ -0,0 +1,181 @@ +#!/usr/bin/ruby + + + +class NetPort < LibRubyObject + # number of transitions a SLICC state machine can transition per + # cycle + default_param :transitions_per_cycle, Integer, 32 + + # buffer_size limits the size of all other buffers connecting to + # SLICC Controllers. When 0, infinite buffering is used. + default_param :buffer_size, Integer, 32 + + # added by SS for TBE + default_param :number_of_TBEs, Integer, 128 + + default_param :recycle_latency, Integer, 10 +end + +class Sequencer < IfacePort + # Maximum number of requests (including prefetches) outstanding from + # the sequencer + default_param :max_outstanding_requests, Integer, 16 + + # Maximum number of cycles a request is can be outstanding before + # the Sequencer declares we're in deadlock/livelock + default_param :deadlock_threshold, Integer, 500000 + +end + +class Debug < LibRubyObject + # For debugging purposes, one can enable a trace of all the protocol + # state machine changes. Unfortunately, the code to generate the + # trace is protocol specific. To enable the code for some of the + # standard protocols, + # 1. change protocol_trace = true + # 2. enable debug in the Ruby Makefile + # 3. set start_time = 1 + default_param :protocol_trace, Boolean, false + + # a string for filtering debugging output (for all g_debug vars see Debug.h) + default_param :filter_string, String, "q" + + # filters debugging messages based on priority (low, med, high) + default_param :verbosity_string, String, "none" + + # filters debugging messages based on a ruby time + default_param :start_time, Integer, 1 + + # sends debugging messages to a output filename + default_param :output_filename, String, "" +end + +class Topology < LibRubyObject + # The default link latency between all nodes (internal and external) + # in the toplogy + default_param :link_latency, Integer, 1 + + # the bandwidth from an external network port to it's corresponding + # internal switch + default_param :external_bw, Integer, 64 + + # the bandwitch between internal switches in the network + default_param :internal_bw, Integer, 16 + + # indicates whether the topology config will be displayed in the + # stats file + default_param :print_config, Boolean, true +end + +class Network < LibRubyObject + default_param :endpoint_bandwidth, Integer, 10000 + default_param :adaptive_routing, Boolean, true + default_param :number_of_virtual_networks, Integer, 6 + default_param :fan_out_degree, Integer, 4 + + # default buffer size. Setting to 0 indicates infinite buffering + default_param :buffer_size, Integer, 3 + + # local memory latency ?? NetworkLinkLatency + default_param :link_latency, Integer, 1 + + # on chip latency + default_param :on_chip_latency, Integer, 1 +end + +class GarnetNetwork < Network + default_param :flit_size, Integer, 16 + default_param :number_of_pipe_stages, Integer, 4 + default_param :vcs_per_class, Integer, 4 + default_param :buffer_size, Integer, 4 + default_param :using_network_testing, Boolean, false +end + + + +#added by SS +class Tracer < LibRubyObject + default_param :warmup_length, Integer, 1000000 +end + +#added by SS +class Profiler < LibRubyObject + default_param :hot_lines, Boolean, false + default_param :all_instructions, Boolean, false +end + +#added by SS +class MI_example_CacheController < CacheController + default_param :issue_latency, Integer, 2 + default_param :cache_response_latency, Integer, 12 +end + +class MI_example_DirectoryController < DirectoryController + default_param :to_mem_ctrl_latency, Integer, 1 + default_param :directory_latency, Integer, 6 + default_param :memory_latency, Integer, 158 +end + + +#added by SS +class MemoryControl < LibRubyObject + + default_param :mem_bus_cycle_multiplier, Integer, 10 + default_param :banks_per_rank, Integer, 8 + default_param :ranks_per_dimm, Integer, 2 + default_param :dimms_per_channel, Integer, 2 + default_param :bank_bit_0, Integer, 8 + default_param :rank_bit_0, Integer, 11 + default_param :dimm_bit_0, Integer, 12 + default_param :bank_queue_size, Integer, 12 + default_param :bank_busy_time, Integer, 11 + default_param :rank_rank_delay, Integer, 1 + default_param :read_write_delay, Integer, 2 + default_param :basic_bus_busy_time, Integer, 2 + default_param :mem_ctl_latency, Integer, 12 + default_param :refresh_period, Integer, 1560 + default_param :tFaw, Integer, 0 + default_param :mem_random_arbitrate, Integer, 0 + default_param :mem_fixed_delay, Integer, 0 + +end + +class RubySystem + + # Random seed used by the simulation. If set to "rand", the seed + # will be set to the current wall clock at libruby + # initialization. Otherwise, set this to an integer. + default_param :random_seed, Object, "rand" + + # When set to true, the simulation will insert random delays on + # message enqueue times. Note that even if this is set to false, + # you can still have a non-deterministic simulation if random seed + # is set to "rand". This is because the Ruby swtiches use random + # link priority elevation + default_param :randomization, Boolean, false + + # tech_nm is the device size used to calculate latency and area + # information about system components + default_param :tech_nm, Integer, 45 + + # default frequency for the system + default_param :freq_mhz, Integer, 3000 + + # the default cache block size in the system + # libruby does not currently support different block sizes + # among different caches + # Must be a power of two + default_param :block_size_bytes, Integer, 64 + + # The default debug object. There shouldn't be a reason to ever + # change this line. To adjust debug paramters statically, adjust + # them in the Debug class above. To adjust these fields + # dynamically, access this RubySystem object, + # e.g. RubySystem.debug.protocol_trace = true + default_param :debug, Debug, Debug.new("dbg0") + default_param :tracer, Tracer, Tracer.new("tracer0") + + default_param :profiler, Profiler, Profiler.new("profiler0") +end + diff --git a/src/mem/ruby/config/libruby_cfg_test.cc b/src/mem/ruby/config/libruby_cfg_test.cc new file mode 100644 index 000000000..5d5b69d5f --- /dev/null +++ b/src/mem/ruby/config/libruby_cfg_test.cc @@ -0,0 +1,14 @@ + +#include +#include + +#include "../libruby.hh" + +int main(int argc, char* argv[]) +{ + assert(argc == 2); + const char* cfg_file = argv[1]; + + libruby_init(cfg_file); + libruby_print_config(std::cout); +} diff --git a/src/mem/ruby/config/print_cfg.rb b/src/mem/ruby/config/print_cfg.rb new file mode 100644 index 000000000..0a6d180d4 --- /dev/null +++ b/src/mem/ruby/config/print_cfg.rb @@ -0,0 +1,14 @@ + +ruby_cfg_file = nil +$stderr.puts $*.inspect +for i in 0..$*.size-1 do + if $*[i] == "-r" # ruby config file + i += 1 + ruby_cfg_file = $*[i] + break + end +end + +require ruby_cfg_file + +RubySystem.generateConfig diff --git a/src/mem/ruby/config/rubyconfig.defaults b/src/mem/ruby/config/rubyconfig.defaults index 873192c05..936a2f091 100644 --- a/src/mem/ruby/config/rubyconfig.defaults +++ b/src/mem/ruby/config/rubyconfig.defaults @@ -43,10 +43,6 @@ g_DEADLOCK_THRESHOLD: 500000 // (does not apply when running Opal) SIMICS_RUBY_MULTIPLIER: 4 -// corresponding parameter when using Opal+Ruby+Simics -OPAL_RUBY_MULTIPLIER: 1 - - // Ruby cycles between when a sequencer issues a request and it arrives at // the L1 cache controller // @@ -107,7 +103,7 @@ L2_CACHE_ASSOC: 4 L2_CACHE_NUM_SETS_BITS: 16 // 32 bits = 4 GB address space -g_MEMORY_SIZE_BYTES: 4294967296 +g_MEMORY_SIZE_BYTES: 1073741824 //4294967296 g_DATA_BLOCK_BYTES: 64 g_PAGE_SIZE_BYTES: 4096 g_REPLACEMENT_POLICY: PSEDUO_LRU // currently, only other option is LRU @@ -176,8 +172,6 @@ L1_REQUEST_LATENCY: 2 L2_REQUEST_LATENCY: 4 - - // Number of transitions each controller state machines can complete per cycle // i.e. the number of ports to each controller // L1cache is the sum of the L1I and L1D cache ports @@ -186,6 +180,7 @@ L1CACHE_TRANSITIONS_PER_RUBY_CYCLE: 32 // much greater constraint on the concurrency of a L2 cache bank L2CACHE_TRANSITIONS_PER_RUBY_CYCLE: 32 DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE: 32 +DMA_TRANSITIONS_PER_RUBY_CYCLE: 1 // Number of TBEs available for demand misses, ALL prefetches, and replacements @@ -195,10 +190,6 @@ NUMBER_OF_TBES: 128 NUMBER_OF_L1_TBES: 32 NUMBER_OF_L2_TBES: 32 -// TSO is deprecated -TSO: false - - // ** INTERCONECT PARAMETERS ** // g_PRINT_TOPOLOGY: true @@ -207,7 +198,7 @@ g_CACHE_DESIGN: NUCA // specifies file prefix for FILE_SPECIFIED topology FAN_OUT_DEGREE: 4 // for HIERARCHICAL SWITCH topology g_adaptive_routing: true -NUMBER_OF_VIRTUAL_NETWORKS: 4 +NUMBER_OF_VIRTUAL_NETWORKS: 6 // bandwidth unit is 1/1000 byte per cycle. the following parameter is multiplied by // topology specific link weights @@ -240,57 +231,6 @@ PROTOCOL_BUFFER_SIZE: 32 SINGLE_ACCESS_L2_BANKS: true -// constants used by TM protocols -PROFILE_EXCEPTIONS: false -PROFILE_XACT: true -PROFILE_NONXACT: false -XACT_DEBUG: true -XACT_DEBUG_LEVEL: 1 -//XACT_MEMORY: true // set to true for TM protocols. set it HERE for lazy systems to register the proper SIMICS interfaces -XACT_MEMORY: false -XACT_ENABLE_TOURMALINE: false // perfect memory system -XACT_NUM_CURRENT: 0 // must be 0 -XACT_LAST_UPDATE: 0 // must be 0 -XACT_ISOLATION_CHECK: false // Checks whether each memory access preserves transaction isolation -PERFECT_FILTER: true // If true, use perfect physical read/write filters -READ_WRITE_FILTER: Perfect_ -PERFECT_VIRTUAL_FILTER: true // If true, use perfect virtual read/write filters -VIRTUAL_READ_WRITE_FILTER: Perfect_ -PERFECT_SUMMARY_FILTER: true // If true, use perfect summary read/write filters -SUMMARY_READ_WRITE_FILTER: Perfect_ -XACT_EAGER_CD: true -XACT_LAZY_VM: false -XACT_CONFLICT_RES: BASE -XACT_COMMIT_TOKEN_LATENCY: 0 -XACT_VISUALIZER: false -XACT_NO_BACKOFF: false -XACT_LOG_BUFFER_SIZE: 0 -XACT_STORE_PREDICTOR_ENTRIES: 256 -XACT_STORE_PREDICTOR_HISTORY: 256 -XACT_STORE_PREDICTOR_THRESHOLD: 4 -XACT_FIRST_ACCESS_COST: 0 -XACT_FIRST_PAGE_ACCESS_COST: 0 -ENABLE_MAGIC_WAITING: false -ENABLE_WATCHPOINT: false -XACT_ENABLE_VIRTUALIZATION_LOGTM_SE: false -// g_NETWORK_TOPOLOGY: FILE_SPECIFIED -// NUMBER_OF_VIRTUAL_NETWORKS: 5 -// L2_REQUEST_LATENCY: 15 -// SEQUENCER_TO_CONTROLLER_LATENCY: 3 -// L2_RESPONSE_LATENCY: 20 -// L2_TAG_LATENCY: 6 -// MEMORY_RESPONSE_LATENCY_MINUS_2: 448 -// RECYCLE_LATENCY: 1 -// g_MEMORY_SIZE_BYTES: 268435456 -// REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH: true - -// ATMTP -ATMTP_ENABLED: false -ATMTP_ABORT_ON_NON_XACT_INST: false -ATMTP_ALLOW_SAVE_RESTORE_IN_XACT: false -ATMTP_XACT_MAX_STORES: 32 -ATMTP_DEBUG_LEVEL: 0 - // MOESI_CMP_token parameters (some might be deprecated) g_FILTERING_ENABLED: false g_DISTRIBUTED_PERSISTENT_ENABLED: true @@ -321,7 +261,7 @@ g_hold_time: 5 g_wait_time: 5 // Princeton Network (Garnet) -g_GARNET_NETWORK: false +g_GARNET_NETWORK: true g_DETAIL_NETWORK: false g_NETWORK_TESTING: false g_FLIT_SIZE: 16 diff --git a/src/mem/ruby/config/tester.defaults b/src/mem/ruby/config/tester.defaults index 6ba655770..b30d1ba99 100644 --- a/src/mem/ruby/config/tester.defaults +++ b/src/mem/ruby/config/tester.defaults @@ -6,10 +6,11 @@ // Please: - Add new variables only to rubyconfig.defaults file. // - Change them here only when necessary. +g_SIMICS: false DATA_BLOCK: true RANDOMIZATION: true -g_SYNTHETIC_DRIVER: true -g_DETERMINISTIC_DRIVER: false +g_SYNTHETIC_DRIVER: false +g_DETERMINISTIC_DRIVER: true g_DEADLOCK_THRESHOLD: 500000 g_SpecifiedGenerator: DetermGETXGenerator @@ -28,23 +29,13 @@ L2_CACHE_NUM_SETS_BITS: 5 g_MEMORY_SIZE_BYTES: 1048576 -// XACT MEMORY -XACT_LENGTH: 2000 -XACT_SIZE: 1000 -ABORT_RETRY_TIME: 400 -XACT_ISOLATION_CHECK: true -L2CACHE_TRANSITIONS_PER_RUBY_CYCLE: 1000 -DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE: 1000 -PERFECT_FILTER: true // If true, use perfect read/write filters -READ_WRITE_FILTER: Perfect_ - //g_NETWORK_TOPOLOGY: FILE_SPECIFIED RECYCLE_LATENCY: 1 //NUMBER_OF_VIRTUAL_NETWORKS: 5 //g_NUM_MEMORIES: 16 L2CACHE_TRANSITIONS_PER_RUBY_CYCLE: 1000 DIRECTORY_TRANSITIONS_PER_RUBY_CYCLE: 1000 -//g_PROCS_PER_CHIP: 16 +//g_PROCS_PER_CHIP: 2 //g_NUM_L2_BANKS: 16 //g_endpoint_bandwidth: 10000 //g_NUM_PROCESSORS: 16 diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.cc b/src/mem/ruby/eventqueue/RubyEventQueue.cc index 4a979942f..1a4159f1d 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueue.cc +++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc @@ -49,7 +49,7 @@ RubyEventQueue::RubyEventQueue() RubyEventQueue::~RubyEventQueue() { - // delete m_prio_heap_ptr; + delete m_prio_heap_ptr; } void RubyEventQueue::init() @@ -91,7 +91,7 @@ void RubyEventQueue::triggerEvents(Time t) assert(thisNode.m_consumer_ptr != NULL); DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,*(thisNode.m_consumer_ptr)); DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,thisNode.m_time); - thisNode.m_consumer_ptr->triggerWakeup(); + thisNode.m_consumer_ptr->triggerWakeup(this); } m_globalTime = t; } @@ -107,7 +107,7 @@ void RubyEventQueue::triggerAllEvents() assert(thisNode.m_consumer_ptr != NULL); DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,*(thisNode.m_consumer_ptr)); DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,thisNode.m_time); - thisNode.m_consumer_ptr->triggerWakeup(); + thisNode.m_consumer_ptr->triggerWakeup(this); } } diff --git a/src/mem/ruby/filters/AbstractBloomFilter.hh b/src/mem/ruby/filters/AbstractBloomFilter.hh new file mode 100644 index 000000000..7e37a6e06 --- /dev/null +++ b/src/mem/ruby/filters/AbstractBloomFilter.hh @@ -0,0 +1,71 @@ + +/* + * Copyright (c) 1999-2008 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. + */ + +/* + * AbstractBloomFilter.hh + * + * Description: + * + * + */ + +#ifndef ABSTRACT_BLOOM_FILTER_H +#define ABSTRACT_BLOOM_FILTER_H + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/config/RubyConfig.hh" +#include "mem/ruby/common/Address.hh" + +class AbstractBloomFilter { +public: + + virtual ~AbstractBloomFilter() {}; + virtual void clear() = 0; + virtual void increment(const Address& addr) = 0; + virtual void decrement(const Address& addr) = 0; + virtual void merge(AbstractBloomFilter * other_filter) = 0; + virtual void set(const Address& addr) = 0; + virtual void unset(const Address& addr) = 0; + + virtual bool isSet(const Address& addr) = 0; + virtual int getCount(const Address& addr) = 0; + virtual int getTotalCount() = 0; + + virtual void print(ostream& out) const = 0; + + virtual int getIndex(const Address& addr) = 0; + virtual int readBit(const int index) = 0; + virtual void writeBit(const int index, const int value) = 0; + +private: + +}; + + +#endif diff --git a/src/mem/ruby/filters/BlockBloomFilter.cc b/src/mem/ruby/filters/BlockBloomFilter.cc new file mode 100644 index 000000000..9bf5b41c5 --- /dev/null +++ b/src/mem/ruby/filters/BlockBloomFilter.cc @@ -0,0 +1,147 @@ + +/* + * Copyright (c) 1999-2008 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. + */ + +/* + * BlockBloomFilter.cc + * + * Description: + * + * + */ + +#include "mem/ruby/filters/BlockBloomFilter.hh" +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Address.hh" + +BlockBloomFilter::BlockBloomFilter(string str) +{ + string tail(str); + string head = string_split(tail, '_'); + + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); + + m_filter.setSize(m_filter_size); + + clear(); +} + +BlockBloomFilter::~BlockBloomFilter(){ +} + +void BlockBloomFilter::clear() +{ + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } +} + +void BlockBloomFilter::increment(const Address& addr) +{ + // Not used +} + + +void BlockBloomFilter::decrement(const Address& addr) +{ + // Not used +} + +void BlockBloomFilter::merge(AbstractBloomFilter * other_filter) +{ + // TODO +} + +void BlockBloomFilter::set(const Address& addr) +{ + int i = get_index(addr); + m_filter[i] = 1; +} + +void BlockBloomFilter::unset(const Address& addr) +{ + int i = get_index(addr); + m_filter[i] = 0; +} + +bool BlockBloomFilter::isSet(const Address& addr) +{ + int i = get_index(addr); + return (m_filter[i]); +} + + +int BlockBloomFilter::getCount(const Address& addr) +{ + return m_filter[get_index(addr)]; +} + +int BlockBloomFilter::getTotalCount() +{ + int count = 0; + + for (int i = 0; i < m_filter_size; i++) { + if (m_filter[i]) { + count++; + } + } + return count; +} + +int BlockBloomFilter::getIndex(const Address& addr) +{ + return get_index(addr); +} + +void BlockBloomFilter::print(ostream& out) const +{ +} + +int BlockBloomFilter::readBit(const int index) { + return m_filter[index]; +} + +void BlockBloomFilter::writeBit(const int index, const int value) { + m_filter[index] = value; +} + +int BlockBloomFilter::get_index(const Address& addr) +{ + // Pull out some bit field ==> B1 + // Pull out additional bits, not the same as B1 ==> B2 + // XOR B1 and B2 to get hash index + physical_address_t block_bits = addr.bitSelect( RubySystem::getBlockSizeBits(), 2*RubySystem::getBlockSizeBits() - 1); + int offset = 5; + physical_address_t other_bits = addr.bitSelect( 2*RubySystem::getBlockSizeBits() + offset, 2*RubySystem::getBlockSizeBits() + offset + m_filter_size_bits - 1); + int index = block_bits ^ other_bits; + assert(index < m_filter_size); + return index; +} + + diff --git a/src/mem/ruby/filters/BlockBloomFilter.hh b/src/mem/ruby/filters/BlockBloomFilter.hh new file mode 100644 index 000000000..205b4172d --- /dev/null +++ b/src/mem/ruby/filters/BlockBloomFilter.hh @@ -0,0 +1,82 @@ + +/* + * Copyright (c) 1999-2008 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. + */ + +/* + * BlockBloomFilter.hh + * + * Description: + * + * + */ + +#ifndef BLOCK_BLOOM_FILTER_H +#define BLOCK_BLOOM_FILTER_H + +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/config/RubyConfig.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/AbstractBloomFilter.hh" + +class BlockBloomFilter : public AbstractBloomFilter { +public: + + ~BlockBloomFilter(); + BlockBloomFilter(string config); + + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); + + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); + + void print(ostream& out) const; + +private: + + int get_index(const Address& addr); + + Vector m_filter; + int m_filter_size; + int m_filter_size_bits; + + int m_count_bits; + int m_count; +}; + + +#endif diff --git a/src/mem/ruby/filters/BulkBloomFilter.cc b/src/mem/ruby/filters/BulkBloomFilter.cc new file mode 100644 index 000000000..264b4201c --- /dev/null +++ b/src/mem/ruby/filters/BulkBloomFilter.cc @@ -0,0 +1,232 @@ + +/* + * Copyright (c) 1999-2008 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. + */ + +/* + * BulkBloomFilter.cc + * + * Description: + * + * + */ + +#include "mem/ruby/filters/BulkBloomFilter.hh" +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Address.hh" + +BulkBloomFilter::BulkBloomFilter(string str) +{ + string tail(str); + string head = string_split(tail, '_'); + + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); + // split the filter bits in half, c0 and c1 + m_sector_bits = m_filter_size_bits - 1; + + m_temp_filter.setSize(m_filter_size); + m_filter.setSize(m_filter_size); + clear(); + + // clear temp filter + for(int i=0; i < m_filter_size; ++i){ + m_temp_filter[i] = 0; + } +} + +BulkBloomFilter::~BulkBloomFilter(){ + +} + +void BulkBloomFilter::clear() +{ + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } +} + +void BulkBloomFilter::increment(const Address& addr) +{ + // Not used +} + + +void BulkBloomFilter::decrement(const Address& addr) +{ + // Not used +} + +void BulkBloomFilter::merge(AbstractBloomFilter * other_filter) +{ + // TODO +} + +void BulkBloomFilter::set(const Address& addr) +{ + // c0 contains the cache index bits + int set_bits = m_sector_bits; + int block_bits = RubySystem::getBlockSizeBits(); + int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); + // c1 contains the lower m_sector_bits permuted bits + //Address permuted_bits = permute(addr); + //int c1 = permuted_bits.bitSelect(0, set_bits-1); + int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); + //ASSERT(c0 < (m_filter_size/2)); + //ASSERT(c0 + (m_filter_size/2) < m_filter_size); + //ASSERT(c1 < (m_filter_size/2)); + // set v0 bit + m_filter[c0 + (m_filter_size/2)] = 1; + // set v1 bit + m_filter[c1] = 1; +} + +void BulkBloomFilter::unset(const Address& addr) +{ + // not used +} + +bool BulkBloomFilter::isSet(const Address& addr) +{ + // c0 contains the cache index bits + int set_bits = m_sector_bits; + int block_bits = RubySystem::getBlockSizeBits(); + int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); + // c1 contains the lower 10 permuted bits + //Address permuted_bits = permute(addr); + //int c1 = permuted_bits.bitSelect(0, set_bits-1); + int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); + //ASSERT(c0 < (m_filter_size/2)); + //ASSERT(c0 + (m_filter_size/2) < m_filter_size); + //ASSERT(c1 < (m_filter_size/2)); + // set v0 bit + m_temp_filter[c0 + (m_filter_size/2)] = 1; + // set v1 bit + m_temp_filter[c1] = 1; + + // perform filter intersection. If any c part is 0, no possibility of address being in signature. + // get first c intersection part + bool zero = false; + for(int i=0; i < m_filter_size/2; ++i){ + // get intersection of signatures + m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; + zero = zero || m_temp_filter[i]; + } + zero = !zero; + if(zero){ + // one section is zero, no possiblility of address in signature + // reset bits we just set + m_temp_filter[c0 + (m_filter_size/2)] = 0; + m_temp_filter[c1] = 0; + return false; + } + + // check second section + zero = false; + for(int i=m_filter_size/2; i < m_filter_size; ++i){ + // get intersection of signatures + m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; + zero = zero || m_temp_filter[i]; + } + zero = !zero; + if(zero){ + // one section is zero, no possiblility of address in signature + m_temp_filter[c0 + (m_filter_size/2)] = 0; + m_temp_filter[c1] = 0; + return false; + } + // one section has at least one bit set + m_temp_filter[c0 + (m_filter_size/2)] = 0; + m_temp_filter[c1] = 0; + return true; +} + + +int BulkBloomFilter::getCount(const Address& addr) +{ + // not used + return 0; +} + +int BulkBloomFilter::getTotalCount() +{ + int count = 0; + for (int i = 0; i < m_filter_size; i++) { + if (m_filter[i]) { + count++; + } + } + return count; +} + +int BulkBloomFilter::getIndex(const Address& addr) +{ + return get_index(addr); +} + +int BulkBloomFilter::readBit(const int index) { + return 0; + // TODO +} + +void BulkBloomFilter::writeBit(const int index, const int value) { + // TODO +} + +void BulkBloomFilter::print(ostream& out) const +{ +} + +int BulkBloomFilter::get_index(const Address& addr) +{ + return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1); +} + +Address BulkBloomFilter::permute(const Address & addr){ + // permutes the original address bits according to Table 5 + int block_offset = RubySystem::getBlockSizeBits(); + physical_address_t part1 = addr.bitSelect( block_offset, block_offset + 6 ); + physical_address_t part2 = addr.bitSelect( block_offset + 9, block_offset + 9 ); + physical_address_t part3 = addr.bitSelect( block_offset + 11, block_offset + 11 ); + physical_address_t part4 = addr.bitSelect( block_offset + 17, block_offset + 17 ); + physical_address_t part5 = addr.bitSelect( block_offset + 7, block_offset + 8 ); + physical_address_t part6 = addr.bitSelect( block_offset + 10, block_offset + 10 ); + physical_address_t part7 = addr.bitSelect( block_offset + 12, block_offset + 12 ); + physical_address_t part8 = addr.bitSelect( block_offset + 13, block_offset + 13 ); + physical_address_t part9 = addr.bitSelect( block_offset + 15, block_offset + 16 ); + physical_address_t part10 = addr.bitSelect( block_offset + 18, block_offset + 20 ); + physical_address_t part11 = addr.bitSelect( block_offset + 14, block_offset + 14 ); + + physical_address_t result = (part1 << 14 ) | (part2 << 13 ) | (part3 << 12 ) | (part4 << 11 ) | (part5 << 9) | (part6 << 8) + | (part7 << 7) | (part8 << 6) | (part9 << 4) | (part10 << 1) | (part11); + // assume 32 bit addresses (both virtual and physical) + // select the remaining high-order 11 bits + physical_address_t remaining_bits = (addr.bitSelect( block_offset + 21, 31 )) << 21; + result = result | remaining_bits; + + return Address(result); +} diff --git a/src/mem/ruby/tester/Tester.hh b/src/mem/ruby/filters/BulkBloomFilter.hh similarity index 60% rename from src/mem/ruby/tester/Tester.hh rename to src/mem/ruby/filters/BulkBloomFilter.hh index 7b721e038..2dbdb6612 100644 --- a/src/mem/ruby/tester/Tester.hh +++ b/src/mem/ruby/filters/BulkBloomFilter.hh @@ -28,66 +28,60 @@ */ /* - * $Id$ + * BulkBloomFilter.hh * * Description: * + * */ -#ifndef TESTER_H -#define TESTER_H +#ifndef BULK_BLOOM_FILTER_H +#define BULK_BLOOM_FILTER_H +#include "mem/gems_common/Map.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Driver.hh" -#include "mem/ruby/tester/CheckTable.hh" -#include "mem/protocol/CacheRequestType.hh" - -class RubySystem; +#include "mem/ruby/config/RubyConfig.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/AbstractBloomFilter.hh" -class Tester : public Driver, public Consumer { +class BulkBloomFilter : public AbstractBloomFilter { public: - // Constructors - Tester(RubySystem* sys_ptr); - // Destructor - ~Tester(); + ~BulkBloomFilter(); + BulkBloomFilter(string config); - // Public Methods + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - void hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread); - void wakeup(); - void printStats(ostream& out) const {} - void clearStats() {} - void printConfig(ostream& out) const {} + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); void print(ostream& out) const; -private: - // Private Methods - void checkForDeadlock(); +private: - // Private copy constructor and assignment operator - Tester(const Tester& obj); - Tester& operator=(const Tester& obj); + int get_index(const Address& addr); + Address permute(const Address & addr); - // Data Members (m_ prefix) + Vector m_filter; + Vector m_temp_filter; - CheckTable m_checkTable; - Vector