From 98c94cfe3ce83634f3bad79ca18263f42e36ca6a Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 29 Jan 2010 20:29:17 -0800 Subject: [PATCH] ruby: Convert most Ruby objects to M5 SimObjects. The necessary companion conversion of Ruby objects generated by SLICC are converted to M5 SimObjects in the following patch, so this patch alone does not compile. Conversion of Garnet network models is also handled in a separate patch; that code is temporarily disabled from compiling to allow testing of interim code. --- configs/example/memtest-ruby.py | 52 +- src/mem/SConscript | 6 - src/mem/ruby/SConscript | 8 - src/mem/ruby/common/Debug.cc | 55 +- src/mem/ruby/common/Debug.hh | 11 +- src/mem/ruby/common/Debug.py | 23 + src/mem/ruby/common/SConscript | 2 + src/mem/ruby/config/MESI_CMP_directory.rb | 75 -- src/mem/ruby/config/MI_example-homogeneous.rb | 91 --- src/mem/ruby/config/MI_example.rb | 37 - src/mem/ruby/config/MOESI_CMP_directory.rb | 69 -- src/mem/ruby/config/MOESI_CMP_token.rb | 92 --- .../ruby/config/MOESI_hammer-homogeneous.rb | 109 --- src/mem/ruby/config/MOESI_hammer.rb | 41 -- .../ruby/config/TwoLevel_SplitL1UnifiedL2.rb | 139 ---- src/mem/ruby/config/assert.rb | 18 - src/mem/ruby/config/cfg.rb | 672 ------------------ src/mem/ruby/config/defaults.rb | 248 ------- src/mem/ruby/config/libruby_cfg_test.cc | 14 - src/mem/ruby/config/print_cfg.rb | 14 - src/mem/ruby/config/util.rb | 10 - src/mem/ruby/eventqueue/RubyEventQueue.cc | 4 + src/mem/ruby/libruby.cc | 10 + src/mem/ruby/network/Network.cc | 38 +- src/mem/ruby/network/Network.hh | 10 +- .../{config/SConscript => network/Network.py} | 30 +- src/mem/ruby/network/SConscript | 2 + .../garnet-fixed-pipeline/GarnetNetwork_d.cc | 2 +- .../garnet-fixed-pipeline/GarnetNetwork_d.hh | 2 +- .../network/garnet-fixed-pipeline/SConscript | 3 + .../garnet-flexible-pipeline/GarnetNetwork.cc | 2 +- .../garnet-flexible-pipeline/GarnetNetwork.hh | 2 +- .../garnet-flexible-pipeline/NetworkConfig.hh | 2 +- .../garnet-flexible-pipeline/SConscript | 3 + src/mem/ruby/network/orion/SConscript | 3 + .../simple/HierarchicalSwitchTopology.hh | 2 +- src/mem/ruby/network/simple/PtToPtTopology.hh | 2 +- src/mem/ruby/network/simple/SConscript | 2 + src/mem/ruby/network/simple/SimpleNetwork.cc | 15 +- src/mem/ruby/network/simple/SimpleNetwork.hh | 8 +- src/mem/ruby/network/simple/SimpleNetwork.py | 5 + src/mem/ruby/network/simple/Topology.cc | 25 +- src/mem/ruby/network/simple/Topology.hh | 11 +- .../ruby/network/simple/Torus2DTopology.hh | 2 +- src/mem/ruby/profiler/Profiler.cc | 27 +- src/mem/ruby/profiler/Profiler.hh | 10 +- src/mem/ruby/profiler/Profiler.py | 8 + src/mem/ruby/profiler/SConscript | 2 + src/mem/ruby/recorder/SConscript | 2 + src/mem/ruby/recorder/Tracer.cc | 28 +- src/mem/ruby/recorder/Tracer.hh | 12 +- src/mem/ruby/recorder/Tracer.py | 7 + .../slicc_interface/AbstractController.hh | 8 +- src/mem/ruby/slicc_interface/Controller.py | 13 + src/mem/ruby/slicc_interface/SConscript | 2 + src/mem/ruby/system/Cache.py | 12 + src/mem/ruby/system/CacheMemory.cc | 59 +- src/mem/ruby/system/CacheMemory.hh | 11 +- src/mem/ruby/system/DMASequencer.cc | 25 +- src/mem/ruby/system/DMASequencer.hh | 13 +- src/mem/ruby/system/DirectoryMemory.cc | 31 +- src/mem/ruby/system/DirectoryMemory.hh | 9 +- src/mem/ruby/system/DirectoryMemory.py | 10 + src/mem/ruby/system/MemoryControl.cc | 77 +- src/mem/ruby/system/MemoryControl.hh | 10 +- src/mem/ruby/system/MemoryControl.py | 23 + src/mem/ruby/system/RubyPort.cc | 52 ++ src/mem/ruby/system/RubyPort.hh | 55 +- src/mem/ruby/system/RubySystem.py | 18 + src/mem/ruby/system/SConscript | 6 + src/mem/ruby/system/Sequencer.cc | 75 +- src/mem/ruby/system/Sequencer.hh | 12 +- src/mem/ruby/system/Sequencer.py | 23 + src/mem/ruby/system/System.cc | 207 +----- src/mem/ruby/system/System.hh | 10 +- 75 files changed, 641 insertions(+), 2187 deletions(-) create mode 100644 src/mem/ruby/common/Debug.py delete mode 100644 src/mem/ruby/config/MESI_CMP_directory.rb delete mode 100644 src/mem/ruby/config/MI_example-homogeneous.rb delete mode 100644 src/mem/ruby/config/MI_example.rb delete mode 100644 src/mem/ruby/config/MOESI_CMP_directory.rb delete mode 100644 src/mem/ruby/config/MOESI_CMP_token.rb delete mode 100644 src/mem/ruby/config/MOESI_hammer-homogeneous.rb delete mode 100644 src/mem/ruby/config/MOESI_hammer.rb delete mode 100644 src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb delete mode 100644 src/mem/ruby/config/assert.rb delete mode 100644 src/mem/ruby/config/cfg.rb delete mode 100644 src/mem/ruby/config/defaults.rb delete mode 100644 src/mem/ruby/config/libruby_cfg_test.cc delete mode 100644 src/mem/ruby/config/print_cfg.rb delete mode 100644 src/mem/ruby/config/util.rb rename src/mem/ruby/{config/SConscript => network/Network.py} (63%) create mode 100644 src/mem/ruby/network/simple/SimpleNetwork.py create mode 100644 src/mem/ruby/profiler/Profiler.py create mode 100644 src/mem/ruby/recorder/Tracer.py create mode 100644 src/mem/ruby/slicc_interface/Controller.py create mode 100644 src/mem/ruby/system/Cache.py create mode 100644 src/mem/ruby/system/DirectoryMemory.py create mode 100644 src/mem/ruby/system/MemoryControl.py create mode 100644 src/mem/ruby/system/RubySystem.py create mode 100644 src/mem/ruby/system/Sequencer.py diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py index e47b8e0a3..e6684fb5a 100644 --- a/configs/example/memtest-ruby.py +++ b/configs/example/memtest-ruby.py @@ -34,8 +34,6 @@ from m5.defines import buildEnv from m5.util import addToPath import os, optparse, sys addToPath('../common') -addToPath('../../tests/configs/') -import ruby_config parser = optparse.OptionParser() @@ -85,19 +83,43 @@ cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \ progress_interval=options.progress) \ for i in xrange(options.testers) ] -# create the desired simulated system -# ruby memory must be at least 16 MB to work with the mem tester -ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", - cores = options.testers, - memory_size = 16, - ports_per_cpu = 1) - -system = System(cpu = cpus, funcmem = PhysicalMemory(), - physmem = ruby_memory) - -for cpu in cpus: - cpu.test = system.physmem.port - cpu.functional = system.funcmem.port +system = System(cpu = cpus, + funcmem = PhysicalMemory(), + physmem = PhysicalMemory()) + +class L1Cache(RubyCache): + assoc = 2 + latency = 3 + size = 32768 + +class L2Cache(RubyCache): + assoc = 16 + latency = 15 + size = 1048576 + +class CrossbarTopology(Topology): + connections="hi" + + for cpu in cpus: + l1_cntrl = L1Cache_Controller() + cpu_seq = RubySequencer(controller=l1_cntrl, + icache=L1Cache(controller=l1_cntrl), + dcache=L1Cache(controller=l1_cntrl)) + cpu.controller = l1_cntrl + cpu.sequencer = cpu_seq + cpu.test = cpu_seq.port + cpu_seq.funcmem_port = system.physmem.port + cpu.functional = system.funcmem.port + + dir_cntrl = Directory_Controller(directory=RubyDirectoryMemory(), + memory_control=RubyMemoryControl()) + +network = SimpleNetwork(topology=CrossbarTopology()) + +system.ruby = RubySystem(network = network, + profiler = RubyProfiler(), + tracer = RubyTracer(), + debug = RubyDebug()) # ----------------------- diff --git a/src/mem/SConscript b/src/mem/SConscript index 2188850e0..46de3eb57 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -35,9 +35,6 @@ SimObject('Bus.py') SimObject('MemObject.py') SimObject('PhysicalMemory.py') -if env['RUBY']: - SimObject('RubyMemory.py') - Source('bridge.cc') Source('bus.cc') Source('dram.cc') @@ -48,9 +45,6 @@ Source('port.cc') Source('tport.cc') Source('mport.cc') -if env['RUBY']: - Source('rubymem.cc') - if env['FULL_SYSTEM']: Source('vport.cc') else: diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript index 3559f042f..66b091e22 100644 --- a/src/mem/ruby/SConscript +++ b/src/mem/ruby/SConscript @@ -72,14 +72,6 @@ def do_embed_text(target, source, env): fin.close() fout.close() -def EmbedText(target, source, param): - env.Command(target, [source, Value(param)], do_embed_text) - -EmbedText('default_param.hh', 'config/rubyconfig.defaults', - 'global_default_param') -EmbedText('tester_param.hh', 'config/tester.defaults', - 'global_default_tester_param') - # # Link includes # diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index cb9fdf082..68ab2448b 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -87,53 +87,20 @@ void changeDebugFilter(int filter) g_debug_ptr->setFilter(filter); } -Debug::Debug() +Debug::Debug(const Params *p) + : SimObject(p) { - m_verbosityLevel = No_Verb; - m_starting_cycle = ~0; clearFilter(); debug_cout_ptr = &cout; -} - -Debug::Debug( const string & name, const vector & argv ) -{ - // - // must clear the filter before adding filter strings - // - clearFilter(); - for (size_t i=0;ifilter_string.c_str()); + setVerbosityString(p->verbosity_string.c_str()); + setDebugOutputFile(p->output_filename.c_str()); + m_starting_cycle = p->start_time; + m_protocol_trace = p->protocol_trace; + g_debug_ptr = this; } -Debug::Debug( const char *filterString, const char *verboseString, - Time filterStartTime, const char *filename ) -{ - m_verbosityLevel = No_Verb; - clearFilter(); - debug_cout_ptr = &cout; - - m_starting_cycle = filterStartTime; - if (setFilterString(filterString)) - fatal("could not set filter string to %s\n", filterString); - setVerbosityString( verboseString ); - setDebugOutputFile( filename ); -} Debug::~Debug() { @@ -417,3 +384,9 @@ void ERROR_OUT( const char* fmt, ... ) { } */ + +Debug * +RubyDebugParams::create() +{ + return new Debug(this); +} diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh index 03e123866..5fb4d412f 100644 --- a/src/mem/ruby/common/Debug.hh +++ b/src/mem/ruby/common/Debug.hh @@ -41,6 +41,9 @@ #include "config/ruby_debug.hh" #include "mem/ruby/common/Global.hh" +#include "sim/sim_object.hh" + +#include "params/RubyDebug.hh" extern std::ostream * debug_cout_ptr; @@ -70,13 +73,11 @@ enum DebugComponents enum PriorityLevel {HighPrio, MedPrio, LowPrio}; enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb}; -class Debug { +class Debug : public SimObject { public: // Constructors - Debug(); - Debug(const std::string & name, const std::vector & argv); - Debug( const char *filterString, const char *verboseString, - Time filterStartTime, const char *filename ); + typedef RubyDebugParams Params; + Debug(const Params *p); // Destructor ~Debug(); diff --git a/src/mem/ruby/common/Debug.py b/src/mem/ruby/common/Debug.py new file mode 100644 index 000000000..09886d0c6 --- /dev/null +++ b/src/mem/ruby/common/Debug.py @@ -0,0 +1,23 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubyDebug(SimObject): + type = 'RubyDebug' + cxx_class = 'Debug' + + filter_string = Param.String('none', + "a string for filtering debugging output (see Debug.h)") + verbosity_string = Param.String('none', + "filters debugging messages based on priority (low, med, high)") + output_filename = Param.String('none', + "sends debugging messages to a file") + start_time = Param.Tick(1, + "filters debugging messages based on a ruby time") + # 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 + protocol_trace = Param.Bool(False, + "enable protocol state machine trace") diff --git a/src/mem/ruby/common/SConscript b/src/mem/ruby/common/SConscript index 15df8312e..56f5d7556 100644 --- a/src/mem/ruby/common/SConscript +++ b/src/mem/ruby/common/SConscript @@ -33,6 +33,8 @@ Import('*') if not env['RUBY']: Return() +SimObject('Debug.py') + Source('Address.cc') Source('DataBlock.cc') Source('Debug.cc') diff --git a/src/mem/ruby/config/MESI_CMP_directory.rb b/src/mem/ruby/config/MESI_CMP_directory.rb deleted file mode 100644 index 7a9d47f24..000000000 --- a/src/mem/ruby/config/MESI_CMP_directory.rb +++ /dev/null @@ -1,75 +0,0 @@ -require "cfg.rb" -require "util.rb" - - -class MESI_CMP_directory_L2CacheController < CacheController - attr :cache - - def initialize(obj_name, mach_type, cache) - super(obj_name, mach_type, [cache]) - @cache = cache - end - def argv() - vec = super() - vec += " cache " + cache.obj_name - vec += " l2_request_latency "+request_latency.to_s - vec += " l2_response_latency "+response_latency.to_s - vec += " to_l1_latency "+to_L1_latency.to_s - return vec - end - -end - -class MESI_CMP_directory_L1CacheController < L1CacheController - attr :icache, :dcache - attr :num_l2_controllers - - def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers) - super(obj_name, mach_type, [icache, dcache], sequencer) - @icache = icache - @dcache = dcache - @num_l2_controllers = num_l2_controllers - end - - def argv() - num_select_bits = log_int(num_l2_controllers) - num_block_bits = log_int(RubySystem.block_size_bytes) - l2_select_low_bit = num_block_bits - - vec = super() - vec += " icache " + @icache.obj_name - vec += " dcache " + @dcache.obj_name - vec += " l1_request_latency "+l1_request_latency.to_s - vec += " l1_response_latency "+l1_response_latency.to_s - vec += " to_l2_latency "+to_L2_latency.to_s - vec += " l2_select_low_bit " + l2_select_low_bit.to_s - vec += " l2_select_num_bits " + num_select_bits.to_s - return vec - end - -end - -class MESI_CMP_directory_DMAController < DMAController - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type, dma_sequencer) - end - def argv() - vec = super - vec += " request_latency "+request_latency.to_s - return vec - end -end - - -class MESI_CMP_directory_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 - end - -end -require "defaults.rb" diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb deleted file mode 100644 index d409e6782..000000000 --- a/src/mem/ruby/config/MI_example-homogeneous.rb +++ /dev/null @@ -1,91 +0,0 @@ -#!/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" - -RubySystem.reset - -# default values - -num_cores = 2 -l1_cache_size_bytes = 32768 -l1_cache_assoc = 8 -l1_cache_latency = 1 -num_memories = 2 -memory_size_mb = 1024 -num_dma = 1 -protocol = "MI_example" - -# check for overrides - - -for i in 0..$*.size-1 do - if $*[i] == "-c" - protocol = $*[i+1] - i = i+1 - elsif $*[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] == "-R" - if $*[i+1] == "rand" - RubySystem.random_seed = "rand" - else - RubySystem.random_seed = $*[i+1].to_i - end - i = i+ 1 - elsif $*[i] == "-s" - memory_size_mb = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-C" - l1_cache_size_bytes = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-A" - l1_cache_assoc = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-D" - num_dma = $*[i+1].to_i - i = i + 1 - end -end - -net_ports = Array.new -iface_ports = Array.new - -assert(protocol == "MI_example", __FILE__ + " cannot be used with protocol " + protocol) - -require protocol+".rb" - -num_cores.times { |n| - cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_bytes, 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 << MI_example_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/MI_example.rb b/src/mem/ruby/config/MI_example.rb deleted file mode 100644 index 8113087aa..000000000 --- a/src/mem/ruby/config/MI_example.rb +++ /dev/null @@ -1,37 +0,0 @@ - -require "util.rb" - -class MI_example_CacheController < L1CacheController - attr :cache - def initialize(obj_name, mach_type, cache, sequencer) - super(obj_name, mach_type, [cache], sequencer) - @cache = cache - end - def argv() - vec = super() - vec += " cache " + @cache.obj_name - 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 += " directory_latency "+directory_latency.to_s - end -end - -class MI_example_DMAController < DMAController - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type, dma_sequencer) - end - def argv() - vec = super - vec += " request_latency "+request_latency.to_s - end -end diff --git a/src/mem/ruby/config/MOESI_CMP_directory.rb b/src/mem/ruby/config/MOESI_CMP_directory.rb deleted file mode 100644 index 1e8a82fab..000000000 --- a/src/mem/ruby/config/MOESI_CMP_directory.rb +++ /dev/null @@ -1,69 +0,0 @@ - -require "cfg.rb" -require "util.rb" - - -class MOESI_CMP_directory_L1CacheController < L1CacheController - attr :icache, :dcache - attr :num_l2_controllers - def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers) - super(obj_name, mach_type, [icache, dcache], sequencer) - @icache = icache - @dcache = dcache - @num_l2_controllers = num_l2_controllers - end - def argv() - num_select_bits = log_int(num_l2_controllers) - num_block_bits = log_int(RubySystem.block_size_bytes) - - l2_select_low_bit = num_block_bits - - vec = super() - vec += " icache " + @icache.obj_name - vec += " dcache " + @dcache.obj_name - vec += " request_latency "+request_latency().to_s - vec += " l2_select_low_bit " + l2_select_low_bit.to_s - vec += " l2_select_num_bits " + num_select_bits.to_s - return vec - end -end - -class MOESI_CMP_directory_L2CacheController < CacheController - attr :cache - def initialize(obj_name, mach_type, cache) - super(obj_name, mach_type, [cache]) - @cache = cache - end - def argv() - vec = super() - vec += " cache " + @cache.obj_name - vec += " request_latency "+request_latency().to_s - vec += " response_latency "+response_latency().to_s - return vec - end -end - - -class MOESI_CMP_directory_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 += " directory_latency "+directory_latency.to_s - return vec - end - -end - -class MOESI_CMP_directory_DMAController < DMAController - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type, dma_sequencer) - end - def argv() - vec = super - vec += " request_latency "+request_latency.to_s - vec += " response_latency "+response_latency.to_s - return vec - end -end diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb deleted file mode 100644 index ba963dc06..000000000 --- a/src/mem/ruby/config/MOESI_CMP_token.rb +++ /dev/null @@ -1,92 +0,0 @@ - -require "cfg.rb" -require "util.rb" - - -class MOESI_CMP_token_L1CacheController < L1CacheController - attr :icache, :dcache - attr :num_l2_controllers - attr :n_tokens - def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens) - super(obj_name, mach_type, [icache, dcache], sequencer) - @icache = icache - @dcache = dcache - @num_l2_controllers = num_l2_controllers - @n_tokens = n_tokens - end - def argv() - num_select_bits = log_int(num_l2_controllers) - num_block_bits = log_int(RubySystem.block_size_bytes) - - l2_select_low_bit = num_block_bits - - vec = super() - vec += " icache " + @icache.obj_name - vec += " dcache " + @dcache.obj_name - vec += " l1_request_latency " + l1_request_latency.to_s - vec += " l1_response_latency " + l1_response_latency.to_s - vec += " l2_select_low_bit " + l2_select_low_bit.to_s - vec += " l2_select_num_bits " + num_select_bits.to_s - vec += " N_tokens " + n_tokens.to_s - vec += " retry_threshold " + retry_threshold.to_s - vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s - vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s - - return vec - end -end - -class MOESI_CMP_token_L2CacheController < CacheController - attr :cache - attr :n_tokens - def initialize(obj_name, mach_type, cache, n_tokens) - super(obj_name, mach_type, [cache]) - @cache = cache - @n_tokens = n_tokens - end - def argv() - vec = super() - vec += " cache " + @cache.obj_name - vec += " l2_request_latency " + l2_request_latency.to_s - vec += " l2_response_latency " + l2_response_latency.to_s - vec += " N_tokens " + n_tokens.to_s - vec += " filtering_enabled " + filtering_enabled.to_s - return vec - end -end - - -class MOESI_CMP_token_DirectoryController < DirectoryController - attr :num_l2_controllers - def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers) - super(obj_name, mach_type, directory, memory_control) - @num_l2_controllers = num_l2_controllers - end - def argv() - num_select_bits = log_int(num_l2_controllers) - num_block_bits = log_int(RubySystem.block_size_bytes) - - l2_select_low_bit = num_block_bits - - vec = super() - vec += " directory_latency "+directory_latency.to_s - vec += " l2_select_low_bit " + l2_select_low_bit.to_s - vec += " l2_select_num_bits " + num_select_bits.to_s - vec += " distributed_persistent "+distributed_persistent.to_s - vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s - return vec - end - -end - -class MOESI_CMP_token_DMAController < DMAController - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type, dma_sequencer) - end - def argv() - vec = super - vec += " request_latency "+request_latency.to_s - vec += " response_latency "+response_latency.to_s - return vec - end -end diff --git a/src/mem/ruby/config/MOESI_hammer-homogeneous.rb b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb deleted file mode 100644 index 02af0ec27..000000000 --- a/src/mem/ruby/config/MOESI_hammer-homogeneous.rb +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/ruby -# -# Creates multiple on-chip nodes with three level of cache. -# - -require "cfg.rb" - -RubySystem.reset - -# default values - -num_cores = 2 -l1_cache_size_bytes = 32768 -l1_cache_assoc = 2 -l1_cache_latency = 3 -l2_cache_size_bytes = 1048576 -l2_cache_assoc = 16 -l2_cache_latency = 15 -num_memories = 2 -memory_size_mb = 1024 -num_dma = 0 -use_map = false -map_levels = 4 -protocol = "MOESI_hammer" - -# check for overrides - - -for i in 0..$*.size-1 do - if $*[i] == "-c" - protocol = $*[i+1] - i = i+1 - elsif $*[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 - elsif $*[i] == "-U" - use_map = $*[i+1] - i = i + 1 - elsif $*[i] == "-C" - l1_cache_size_bytes = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-A" - l1_cache_assoc = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-M" - map_levels = $*[i+1].to_i - i = i + 1 - elsif $*[i] == "-D" - num_dma = $*[i+1].to_i - i = i + 1 - end -end - -net_ports = Array.new -iface_ports = Array.new - -assert(protocol == "MOESI_hammer", __FILE__ + " cannot be used with protocol " + protocol) - -require protocol+".rb" - -num_cores.times { |n| - icache = SetAssociativeCache.new("l1i_"+n.to_s, - l1_cache_size_bytes, - l1_cache_latency, - l1_cache_assoc, - "PSEUDO_LRU") - dcache = SetAssociativeCache.new("l1d_"+n.to_s, - l1_cache_size_bytes, - l1_cache_latency, - l1_cache_assoc, - "PSEUDO_LRU") - l2cache = SetAssociativeCache.new("l2u_"+n.to_s, - l2_cache_size_bytes, - l2_cache_latency, - l2_cache_assoc, - "PSEUDO_LRU") - sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) - iface_ports << sequencer - net_ports << MOESI_hammer_CacheController.new("L1CacheController_"+n.to_s, - "L1Cache", - icache, - dcache, - l2cache, - 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 << MOESI_hammer_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 << MOESI_hammer_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/MOESI_hammer.rb b/src/mem/ruby/config/MOESI_hammer.rb deleted file mode 100644 index d3735028b..000000000 --- a/src/mem/ruby/config/MOESI_hammer.rb +++ /dev/null @@ -1,41 +0,0 @@ - -require "util.rb" - -class MOESI_hammer_CacheController < L1CacheController - attr :cache - def initialize(obj_name, mach_type, icache, dcache, l2cache, sequencer) - super(obj_name, mach_type, [icache, dcache, l2cache], sequencer) - @icache = icache - @dcache = dcache - @l2cache = l2cache - end - def argv() - vec = super() - vec += " icache " + @icache.obj_name - vec += " dcache " + @dcache.obj_name - vec += " l2cache " + @l2cache.obj_name - vec += " issue_latency "+issue_latency.to_s - vec += " cache_response_latency "+cache_response_latency.to_s - end - -end - -class MOESI_hammer_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 += " memory_controller_latency "+memory_controller_latency.to_s - end -end - -class MOESI_hammer_DMAController < DMAController - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type, dma_sequencer) - end - def argv() - vec = super - vec += " request_latency "+request_latency.to_s - end -end diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb deleted file mode 100644 index ee22df656..000000000 --- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb +++ /dev/null @@ -1,139 +0,0 @@ -#!/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 using command line args. -# - -require "cfg.rb" - -RubySystem.reset - -# default values - -num_cores = 2 -l1_icache_size_kb = 64 -l1_icache_assoc = 8 -l1_icache_latency = 1 -l1_dcache_size_kb = 32 -l1_dcache_assoc = 8 -l1_dcache_latency = 1 -l2_cache_size_kb = 8192 # total size (sum of all banks) -l2_cache_assoc = 16 -l2_cache_latency = 12 -num_l2_banks = num_cores -num_memories = 1 -memory_size_mb = 1024 -num_dma = 1 - -#default protocol -protocol = "MOESI_CMP_directory" - -# check for overrides - -for i in 0..$*.size-1 do - if $*[i] == "-c" or $*[i] == "--protocol" - i += 1 - protocol = $*[i] - elsif $*[i] == "-A" - l1_dcache_size_kb = $*[i+1].to_i - i = i+1 - elsif $*[i] == "-B" - num_l2_banks = $*[i+1].to_i - i = i+1 - elsif $*[i] == "-m" - num_memories = $*[i+1].to_i - i = i+1 - elsif $*[i] == "-p" - num_cores = $*[i+1].to_i - i = i+1 - elsif $*[i] == "-R" - if $*[i+1] == "rand" - RubySystem.random_seed = "rand" - else - RubySystem.random_seed = $*[i+1].to_i - end - 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 - -assert((protocol == "MESI_CMP_directory" or protocol == "MOESI_CMP_directory"), __FILE__+" cannot be used with protocol '#{protocol}'"); - -require protocol+".rb" - -num_cores.times { |n| - icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb*1024, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU") - dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb*1024, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU") - sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) - iface_ports << sequencer - if protocol == "MOESI_CMP_directory" - net_ports << MOESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s, - "L1Cache", - icache, dcache, - sequencer, - num_l2_banks) - elsif protocol == "MESI_CMP_directory" - net_ports << MESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s, - "L1Cache", - icache, dcache, - sequencer, - num_l2_banks) - end -} -num_l2_banks.times { |n| - cache = SetAssociativeCache.new("l2u_"+n.to_s, (l2_cache_size_kb*1024)/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU") - if protocol == "MOESI_CMP_directory" - net_ports << MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s, - "L2Cache", - cache) - elsif protocol == "MESI_CMP_directory" - net_ports << MESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s, - "L2Cache", - cache) - end - - net_ports.last.request_latency = l2_cache_latency + 2 - net_ports.last.response_latency = l2_cache_latency + 2 -} -num_memories.times { |n| - directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) - memory_control = MemoryControl.new("MemoryControl_"+n.to_s) - if protocol == "MOESI_CMP_directory" - net_ports << MOESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s, - "Directory", - directory, - memory_control) - elsif protocol == "MESI_CMP_directory" - net_ports << MESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s, - "Directory", - directory, - memory_control) - end - -} -num_dma.times { |n| - dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) - iface_ports << dma_sequencer - if protocol == "MOESI_CMP_directory" - net_ports << MOESI_CMP_directory_DMAController.new("DMAController_"+n.to_s, - "DMA", - dma_sequencer) - elsif protocol == "MESI_CMP_directory" - net_ports << MESI_CMP_directory_DMAController.new("DMAController_"+n.to_s, - "DMA", - dma_sequencer) - end - - -} - -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/assert.rb b/src/mem/ruby/config/assert.rb deleted file mode 100644 index cc3e43214..000000000 --- a/src/mem/ruby/config/assert.rb +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -class AssertionFailure < RuntimeError - attr_reader :msg, :output - def initialize(message, out=nil) - @msg = message - @output = out - end -end - -class NotImplementedException < Exception -end - -def assert(condition,message) - unless condition - raise AssertionFailure.new(message), "\n\nAssertion failed: \n\n #{message}\n\n" - end -end diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb deleted file mode 100644 index a20562243..000000000 --- a/src/mem/ruby/config/cfg.rb +++ /dev/null @@ -1,672 +0,0 @@ -#!/usr/bin/ruby - -root = File.dirname(File.expand_path(__FILE__)) -require root+'/assert.rb' - -class Boolean - def self.is_a?(obj) - return self.name == "Boolean" - end -end - -class LibRubyObject - @@all_objs = Array.new - @@default_params = Hash.new - @@param_types = Hash.new - - attr_reader :obj_name - - 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 - - # add all parent parameter accessors if they don't exist - self.class.ancestors.each { |ancestor| - if @@default_params.key?(ancestor.name.to_sym) - @@default_params[ancestor.name.to_sym].each { |p, default| - p = p.to_sym - @params[p] = default - if ! respond_to?(p) - self.class.send(:define_method, p) { - @params[p] = @@default_params[ancestor.name.to_sym][p] if ! @params.key?(p) - return @params[p] - } - end - setter_method_name = (p.to_s + "=").to_sym - if ! respond_to?(setter_method_name) - self.class.send(:define_method, setter_method_name) { |val| - type = @@param_types[ancestor.name.to_sym][p] - if val.is_a?(FalseClass) || val.is_a?(TrueClass) - assert type.is_a?(Boolean), "default value of param \"#{p}\" must be either true or false" - else - assert val.is_a?(type), "default value of param \"#{p}\", which is of type #{val.class.name} does not match expected type #{type}" - end - @params[p] = val - } - end - } - end - } - 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 - @@param_types[idx] = Hash.new if ! @@param_types.key?(idx) - @@param_types[idx][param_name] = type - 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 - - idx = self.name.to_sym - @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) - @@default_params[idx][param_name] = default - @@param_types[idx] = Hash.new if ! @@param_types.key?(idx) - @@param_types[idx][param_name] = type - - 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 + " " - assert(val != nil, "parameter #{key} is nil") - 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() - str = "" - @@all_objs.each { |obj| - str += obj.cppClassName + " " + obj.obj_name + " " + obj.argv + "\n" - } - return str - 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 - param :version, Integer - - @@type_cnt = Hash.new - def initialize(obj_name, mach_type) - super(obj_name) - @mach_type = mach_type - @@type_cnt[mach_type] ||= 0 - self.version= @@type_cnt[mach_type] # sets the version parameter - - @@type_cnt[mach_type] += 1 - - end - - def port_name - mach_type - end - def port_num - version - end - def self.totalOfType(mach_type) - return @@type_cnt[mach_type] - end - def cppClassName() - "generated:"+@mach_type - end - -end - -class MemoryVector < LibRubyObject - def initialize(obj_name) - super(obj_name) - end - - def cppClassName - "MemoryVector" - 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 - @@defaults = Hash.new - @@network = nil - - def self.init(iface_ports, network) - @@iface_ports = iface_ports - @@network = network - end - - def self.reset() - @@iface_ports = nil - @@network = nil - @@params.each { |param_name, param| - param = @@defaults[param_name] - } - 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 - @@defaults[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.getConfig() - # 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 - str = "System sys0 "+argv+"\n" - LibRubyObject.all.each { |obj| - if obj.is_a?(SetAssociativeCache) - obj.calculateLatency - end - } - str += LibRubyObject.printConstructors - #puts str.gsub('%',' ').gsub('#','\n') - return str - end - - def self.generateConfig() - puts getConfig - 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 - -class CacheController < NetPort - - def initialize(obj_name, mach_type, caches) - super(obj_name, mach_type) - caches.each { |cache| - cache.controller = self - } - end - - def cppClassName() - "generated:"+@mach_type - end -end - -class Sequencer < IfacePort -end - -class L1CacheController < CacheController - param :sequencer, Sequencer - - def initialize(obj_name, mach_type, caches, sequencer) - super(obj_name, mach_type, caches) - - sequencer.controller = self - sequencer.version = version - self.sequencer= sequencer - end - -# def argv() -# vec = super() -# vec += " sequencer "+@sequencer.obj_name -# end -end - -class DirectoryMemory < LibRubyObject -end -class MemoryControl < LibRubyObject -end - -class DirectoryController < NetPort - @@total_directory_controllers = 0 - param :directory, DirectoryMemory - param :memory_control, MemoryControl - - def initialize(obj_name, mach_type, directory, memory_control) - super(obj_name, mach_type) - - directory.controller = self - directory.version = @@total_directory_controllers - self.directory = directory - self.memory_control = memory_control - - @version = @@total_directory_controllers - @@total_directory_controllers += 1 - buffer_size() - end - - def cppClassName() - "generated:"+@mach_type - end - -end - -class DMASequencer < IfacePort -end - -class DMAController < NetPort - @@total_dma_controllers = 0 - param :dma_sequencer, DMASequencer - param :version, Integer - - def initialize(obj_name, mach_type, dma_sequencer) - super(obj_name, mach_type) - dma_sequencer.controller = self - dma_sequencer.version = @@total_dma_controllers - self.dma_sequencer = dma_sequencer - - self.version = @@total_dma_controllers - @@total_dma_controllers += 1 - end - -end - -class Cache < LibRubyObject - param :size, Integer - param :latency, Integer - param :controller, NetPort - def initialize(obj_name, size, latency) - super(obj_name) - self.size = size - self.latency = latency - # controller must be set manually by the configuration script - # because there is a cyclic dependence - end - -end - -class SetAssociativeCache < Cache - param :assoc, Integer - param :replacement_policy, String - - # 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, latency, assoc, replacement_policy) - super(obj_name, size, latency) - self.assoc = assoc - self.replacement_policy = replacement_policy - end - - def calculateLatency() - if self.latency == "auto" - cacti_args = Array.new() - cacti_args << (self.size*1024) << RubySystem.block_size_bytes << self.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 - self.latency = latency_cycles - } - elsif self.latency.is_a?(Float) - clk_period_ns = 1e9 * (1.0 / (RubySystem.freq_mhz * 1e6)) - latency_cycles = (self.latency / clk_period_ns).ceil - self.latency = latency_cycles - elsif ! self.latency.is_a?(Integer) - raise Exception - end - end - - def cppClassName() - "SetAssociativeCache" - end -end - -class DirectoryMemory < LibRubyObject - param :size_mb, Integer - param :controller, NetPort - param :version, Integer - - @@total_size_mb = 0 - - def initialize(obj_name, size_mb) - super(obj_name) - self.size_mb = size_mb - @@total_size_mb += size_mb - end - - def cppClassName() - "DirectoryMemory" - end - - def self.memorySizeMB() - @@total_size_mb - end -end - -class MemoryControl < LibRubyObject - def initialize(obj_name) - super(obj_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 - param :controller, NetPort - param :version, Integer - - def initialize(obj_name) - super(obj_name) - end - - def cppClassName() - "DMASequencer" - end - - def bochsConnType() - return "dma"+self.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) - topo.network= self - self.topology = topo - 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 - -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 GarnetNetwork < Network - def initialize(name, topo) - super(name, topo) - end -end - -class GarnetFixedPipeline < GarnetNetwork - def initialize(name, net_ports) - super(name, net_ports) - end - - def cppClassName() - "GarnetNetwork_d" - end -end - -class GarnetFlexiblePipeline < GarnetNetwork - def initialize(name, net_ports) - super(name, net_ports) - end - - def cppClassName() - "GarnetNetwork" - end -end - -require "defaults.rb" diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb deleted file mode 100644 index 224bf1eeb..000000000 --- a/src/mem/ruby/config/defaults.rb +++ /dev/null @@ -1,248 +0,0 @@ -#!/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 - - default_param :number_of_TBEs, Integer, 256 - - 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. Valid options (also see Debug.cc): - # {"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' } - # - # e.g., "sq" will print system and queue debugging messages - # Set to "none" for no debugging output - default_param :filter_string, String, "none" - - # filters debugging messages based on priority (none, 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 - # set to "none" to print to stdout - default_param :output_filename, String, "none" -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, false -end - -class Network < LibRubyObject - default_param :endpoint_bandwidth, Integer, 10000 - default_param :adaptive_routing, Boolean, true - default_param :number_of_virtual_networks, Integer, 5 - # default_param :fan_out_degree, Integer, 4 - - # default buffer size. Setting to 0 indicates infinite buffering - # default_param :buffer_size, Integer, 0 - - # local memory latency ?? NetworkLinkLatency - default_param :link_latency, Integer, 1 - - # on chip latency - # default_param :on_chip_latency, Integer, 1 - - default_param :control_msg_size, Integer, 8 -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 - -class Tracer < LibRubyObject - default_param :warmup_length, Integer, 1000000 -end - -class Profiler < LibRubyObject - default_param :hot_lines, Boolean, false - default_param :all_instructions, Boolean, false -end - -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, 11 - default_param :mem_fixed_delay, Integer, 0 - -end - -###### Protocols ####### - -## MI_example protocol - -class MI_example_CacheController < L1CacheController - default_param :issue_latency, Integer, 2 - default_param :cache_response_latency, Integer, 12 -end - -class MI_example_DirectoryController < DirectoryController - default_param :directory_latency, Integer, 6 -end - -class MI_example_DMAController < DMAController - default_param :request_latency, Integer, 6 -end - -## MOESI_CMP_directory protocol - -class MOESI_CMP_directory_L1CacheController < L1CacheController - default_param :request_latency, Integer, 2 -end - -class MOESI_CMP_directory_L2CacheController < CacheController - default_param :request_latency, Integer, 2 - default_param :response_latency, Integer, 2 -end - -class MOESI_CMP_directory_DirectoryController < DirectoryController - default_param :directory_latency, Integer, 6 -end - -class MOESI_CMP_directory_DMAController < DMAController - default_param :request_latency, Integer, 14 - default_param :response_latency, Integer, 14 -end - -class MESI_CMP_directory_L2CacheController < CacheController - default_param :request_latency, Integer, 2 - default_param :response_latency, Integer, 2 - default_param :to_L1_latency, Integer, 1 - -#if 0 then automatically calculated - default_param :lowest_bit, Integer, 0 - default_param :highest_bit, Integer, 0 -end - -class MESI_CMP_directory_L1CacheController < L1CacheController - default_param :l1_request_latency, Integer, 2 - default_param :l1_response_latency, Integer, 2 - default_param :to_L2_latency, Integer, 1 -end - - -class MESI_CMP_directory_DirectoryController < DirectoryController - default_param :to_mem_ctrl_latency, Integer, 1 - default_param :directory_latency, Integer, 6 -end - -class MESI_CMP_directory_DMAController < DMAController - default_param :request_latency, Integer, 6 -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, 1234 #"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 used mainly to debug protocols by forcing - # really strange interleavings and should not be used for - # performance runs. - 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 deleted file mode 100644 index 5d5b69d5f..000000000 --- a/src/mem/ruby/config/libruby_cfg_test.cc +++ /dev/null @@ -1,14 +0,0 @@ - -#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 deleted file mode 100644 index 0a6d180d4..000000000 --- a/src/mem/ruby/config/print_cfg.rb +++ /dev/null @@ -1,14 +0,0 @@ - -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/util.rb b/src/mem/ruby/config/util.rb deleted file mode 100644 index a6aa8f6ab..000000000 --- a/src/mem/ruby/config/util.rb +++ /dev/null @@ -1,10 +0,0 @@ - -def log_int(n) - assert(n.is_a?(Fixnum), "log_int takes a number for an argument") - counter = 0 - while n >= 2 do - counter += 1 - n = n >> 1 - end - return counter -end diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.cc b/src/mem/ruby/eventqueue/RubyEventQueue.cc index 3adc0d22e..271f8f137 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueue.cc +++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc @@ -40,10 +40,14 @@ // Class public method definitions +RubyEventQueue theEventQueue; + RubyEventQueue::RubyEventQueue() { m_prio_heap_ptr = NULL; init(); + assert(g_eventQueue_ptr == NULL); + g_eventQueue_ptr = this; } RubyEventQueue::~RubyEventQueue() diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index 57dd13c87..c4f1ece95 100644 --- a/src/mem/ruby/libruby.cc +++ b/src/mem/ruby/libruby.cc @@ -89,6 +89,15 @@ vector tokenizeString(string str, string delims) return tokens; } + +/* + * The current state of M5/Ruby integration breaks the libruby + * interface. This code is ifdef'd out for now so that we can move + * forward with the integration process for non-libruby uses. We'll + * have to go back and resolve the libruby compatibility issue at a + * later date. + */ +#if 0 void libruby_init(const char* cfg_filename) { ifstream cfg_output(cfg_filename); @@ -115,6 +124,7 @@ void libruby_init(const char* cfg_filename) RubySystem::create(*sys_conf); delete sys_conf; } +#endif RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id)) { diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index ac785f632..7c5883ee6 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -29,38 +29,26 @@ #include "mem/protocol/MachineType.hh" #include "mem/ruby/network/Network.hh" -Network::Network(const string & name) - : m_name(name) +Network::Network(const Params *p) + : SimObject(p) { - m_virtual_networks = 0; - m_topology_ptr = NULL; + m_virtual_networks = p->number_of_virtual_networks; + m_topology_ptr = p->topology; + m_buffer_size = p->buffer_size; + m_endpoint_bandwidth = p->endpoint_bandwidth; + m_adaptive_routing = p->adaptive_routing; + m_link_latency = p->link_latency; + m_control_msg_size = p->control_msg_size; + + assert(m_virtual_networks != 0); + assert(m_topology_ptr != NULL); } -void Network::init(const vector & argv) +void Network::init() { m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network - for (size_t i=0; i & argv); + typedef RubyNetworkParams Params; + Network(const Params *p); + virtual void init(); // Destructor virtual ~Network() {} diff --git a/src/mem/ruby/config/SConscript b/src/mem/ruby/network/Network.py similarity index 63% rename from src/mem/ruby/config/SConscript rename to src/mem/ruby/network/Network.py index bf8352576..94115ebe8 100644 --- a/src/mem/ruby/config/SConscript +++ b/src/mem/ruby/network/Network.py @@ -1,6 +1,4 @@ -# -*- mode:python -*- - -# Copyright (c) 2009 The Hewlett-Packard Development Company +# Copyright (c) 2009 Advanced Micro Devices, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -26,10 +24,28 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Authors: Nathan Binkert +# Authors: Steve Reinhardt +# Brad Beckmann -Import('*') +from m5.params import * +from m5.SimObject import SimObject -if not env['RUBY']: - Return() +class Topology(SimObject): + type = 'Topology' + connections = Param.String("") + print_config = Param.Bool(False, + "display topology config in the stats file") +class RubyNetwork(SimObject): + type = 'RubyNetwork' + cxx_class = 'Network' + abstract = True + number_of_virtual_networks = Param.Int(10, ""); + topology = Param.Topology(""); + buffer_size = Param.Int(0, + "default buffer size; 0 indicates infinite buffering"); + endpoint_bandwidth = Param.Int(10000, ""); + adaptive_routing = Param.Bool(True, ""); + link_latency = Param.Int(1, + "local memory latency ?? NetworkLinkLatency"); + control_msg_size = Param.Int(8, ""); diff --git a/src/mem/ruby/network/SConscript b/src/mem/ruby/network/SConscript index 3c4cdfbc2..28151e5cb 100644 --- a/src/mem/ruby/network/SConscript +++ b/src/mem/ruby/network/SConscript @@ -33,4 +33,6 @@ Import('*') if not env['RUBY']: Return() +SimObject('Network.py') + Source('Network.cc') diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc index df643e800..716cfb9ad 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc @@ -43,7 +43,7 @@ GarnetNetwork_d::GarnetNetwork_d(const string & name) { } -void GarnetNetwork_d::init(const vector & argv) +void GarnetNetwork_d::init() { Network::init(argv); diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh index 997f5e374..33f13b836 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh @@ -50,7 +50,7 @@ public: ~GarnetNetwork_d(); - void init(const vector & argv); + void init(); //added by SS NetworkConfig* getNetworkConfig() { return m_network_config_ptr; } diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SConscript b/src/mem/ruby/network/garnet-fixed-pipeline/SConscript index 0814df2f5..84f4ba378 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/SConscript +++ b/src/mem/ruby/network/garnet-fixed-pipeline/SConscript @@ -30,6 +30,9 @@ Import('*') +# temporarily disable +Return() + if not env['RUBY']: Return() diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc index 5a6b610f9..b2a385843 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc @@ -44,7 +44,7 @@ GarnetNetwork::GarnetNetwork(const string & name) { } -void GarnetNetwork::init(const vector & argv) +void GarnetNetwork::init() { // printf("hello\n"); Network::init(argv); diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh index c0e4ac6e4..fbebcc7bd 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh @@ -49,7 +49,7 @@ public: ~GarnetNetwork(); - void init(const vector & argv); + void init(); //added by SS NetworkConfig* getNetworkConfig() { return m_network_config_ptr; } diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh index 2080ef022..b23e9a88a 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh @@ -48,7 +48,7 @@ class NetworkConfig { bool m_using_network_testing; public: NetworkConfig(){} - void init(const vector & argv) { + void init() { for (size_t i=0; i & argv); + void init(); protected: void construct(); diff --git a/src/mem/ruby/network/simple/PtToPtTopology.hh b/src/mem/ruby/network/simple/PtToPtTopology.hh index f15fa5956..f3c57d0a0 100644 --- a/src/mem/ruby/network/simple/PtToPtTopology.hh +++ b/src/mem/ruby/network/simple/PtToPtTopology.hh @@ -8,7 +8,7 @@ class PtToPtTopology : public Topology { public: PtToPtTopology(const string & name); - void init(const vector & argv); + void init(); protected: void construct(); diff --git a/src/mem/ruby/network/simple/SConscript b/src/mem/ruby/network/simple/SConscript index 3df736c00..1c952abf4 100644 --- a/src/mem/ruby/network/simple/SConscript +++ b/src/mem/ruby/network/simple/SConscript @@ -33,6 +33,8 @@ Import('*') if not env['RUBY']: Return() +SimObject('SimpleNetwork.py') + Source('PerfectSwitch.cc') Source('SimpleNetwork.cc') Source('Switch.cc') diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index adf7ee21e..bbc9cefdb 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -59,17 +59,17 @@ Network* Network::createNetwork(int nodes) } */ -SimpleNetwork::SimpleNetwork(const string & name) - : Network(name) +SimpleNetwork::SimpleNetwork(const Params *p) + : Network(p) { m_virtual_networks = 0; m_topology_ptr = NULL; } -void SimpleNetwork::init(const vector & argv) +void SimpleNetwork::init() { - Network::init(argv); + Network::init(); m_endpoint_switches.setSize(m_nodes); @@ -263,3 +263,10 @@ void SimpleNetwork::print(ostream& out) const { out << "[SimpleNetwork]"; } + + +SimpleNetwork * +SimpleNetworkParams::create() +{ + return new SimpleNetwork(this); +} diff --git a/src/mem/ruby/network/simple/SimpleNetwork.hh b/src/mem/ruby/network/simple/SimpleNetwork.hh index 9ffd862d3..76070538f 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.hh +++ b/src/mem/ruby/network/simple/SimpleNetwork.hh @@ -73,6 +73,8 @@ #include "mem/gems_common/Vector.hh" #include "mem/ruby/network/Network.hh" #include "mem/ruby/system/NodeID.hh" +#include "sim/sim_object.hh" +#include "params/SimpleNetwork.hh" class NetDest; class MessageBuffer; @@ -83,13 +85,13 @@ class Topology; class SimpleNetwork : public Network { public: // Constructors - // SimpleNetwork(int nodes); - SimpleNetwork(const string & name); + typedef SimpleNetworkParams Params; + SimpleNetwork(const Params *p); // Destructor ~SimpleNetwork(); - void init(const vector & argv); + void init(); // Public Methods void printStats(ostream& out) const; diff --git a/src/mem/ruby/network/simple/SimpleNetwork.py b/src/mem/ruby/network/simple/SimpleNetwork.py new file mode 100644 index 000000000..9fd25c38c --- /dev/null +++ b/src/mem/ruby/network/simple/SimpleNetwork.py @@ -0,0 +1,5 @@ +from m5.params import * +from Network import RubyNetwork + +class SimpleNetwork(RubyNetwork): + type = 'SimpleNetwork' diff --git a/src/mem/ruby/network/simple/Topology.cc b/src/mem/ruby/network/simple/Topology.cc index 563a1b01c..9d636df49 100644 --- a/src/mem/ruby/network/simple/Topology.cc +++ b/src/mem/ruby/network/simple/Topology.cc @@ -62,26 +62,18 @@ static Matrix shortest_path(const Matrix& weights, Matrix& latencies, Matrix& in static bool link_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final, const Matrix& weights, const Matrix& dist); static NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights, const Matrix& dist); -Topology::Topology(const string & name) - : m_name(name) +Topology::Topology(const Params *p) + : SimObject(p) { - m_network_ptr = NULL; +// m_network_ptr = p->network; + m_connections = p->connections; + m_print_config = p->print_config; m_nodes = MachineType_base_number(MachineType_NUM); m_number_of_switches = 0; } -void Topology::init(const vector & argv) +void Topology::init() { - for (size_t i=0; i > Matrix; -class Topology { +class Topology : public SimObject { public: // Constructors - // Topology(Network* network_ptr, int number_of_nodes); - Topology(const string & name); + typedef TopologyParams Params; + Topology(const Params *p); // Destructor virtual ~Topology() {} - virtual void init(const vector & argv); + virtual void init(); // Public Methods void makeTopology(); @@ -80,7 +82,6 @@ public: protected: // Private Methods - void init(); SwitchID newSwitchID(); void addLink(SwitchID src, SwitchID dest, int link_latency); void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier); diff --git a/src/mem/ruby/network/simple/Torus2DTopology.hh b/src/mem/ruby/network/simple/Torus2DTopology.hh index 83a314e94..bc50f161a 100644 --- a/src/mem/ruby/network/simple/Torus2DTopology.hh +++ b/src/mem/ruby/network/simple/Torus2DTopology.hh @@ -8,7 +8,7 @@ class Torus2DTopology : public Topology { public: Torus2DTopology(const string & name); - void init(const vector & argv); + void init(); protected: void construct(); diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index d5c47825f..c6fbd1aa4 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -63,6 +63,8 @@ #include "mem/ruby/common/Debug.hh" #include "mem/protocol/MachineType.hh" +#include "mem/ruby/system/System.hh" + // Allows use of times() library call, which determines virtual runtime #include @@ -71,9 +73,9 @@ extern std::ostream * debug_cout_ptr; static double process_memory_total(); static double process_memory_resident(); -Profiler::Profiler(const string & name) +Profiler::Profiler(const Params *p) + : SimObject(p) { - m_name = name; m_requestProfileMap_ptr = new Map; m_inst_profiler_ptr = NULL; @@ -83,6 +85,10 @@ Profiler::Profiler(const string & name) m_stats_period = 1000000; // Default m_periodic_output_file_ptr = &cerr; + m_hot_lines = p->hot_lines; + m_all_instructions = p->all_instructions; + + RubySystem::m_profiler_ptr = this; } Profiler::~Profiler() @@ -136,17 +142,6 @@ void Profiler::init(const vector & argv, vector memory_control_n m_hot_lines = false; m_all_instructions = false; - for (size_t i=0; i setHotLines(m_hot_lines); m_address_profiler_ptr -> setAllInstructions(m_all_instructions); @@ -849,3 +844,9 @@ void Profiler::profileMemArbWait(string name, int cycles) { assert(m_memory_co void Profiler::profileMemRandBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRandBusy++; } void Profiler::profileMemNotOld(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memNotOld++; } + +Profiler * +RubyProfilerParams::create() +{ + return new Profiler(this); +} diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index 673051db3..8bc8de591 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -71,6 +71,9 @@ #include "mem/protocol/GenericRequestType.hh" #include "mem/ruby/system/MemoryControl.hh" +#include "params/RubyProfiler.hh" +#include "sim/sim_object.hh" + class CacheMsg; class AddressProfiler; @@ -99,10 +102,11 @@ struct memory_control_profiler { }; -class Profiler : public Consumer { +class Profiler : public SimObject, public Consumer { public: // Constructors - Profiler(const string & name); + typedef RubyProfilerParams Params; + Profiler(const Params *); void init(const vector & argv, vector memory_control_names); @@ -260,8 +264,6 @@ private: //added by SS bool m_hot_lines; bool m_all_instructions; - string m_name; - }; // Output operator declaration diff --git a/src/mem/ruby/profiler/Profiler.py b/src/mem/ruby/profiler/Profiler.py new file mode 100644 index 000000000..7923f28f1 --- /dev/null +++ b/src/mem/ruby/profiler/Profiler.py @@ -0,0 +1,8 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubyProfiler(SimObject): + type = 'RubyProfiler' + cxx_class = 'Profiler' + hot_lines = Param.Bool(False, "") + all_instructions = Param.Bool(False, "") diff --git a/src/mem/ruby/profiler/SConscript b/src/mem/ruby/profiler/SConscript index 008a36a29..41481e3ca 100644 --- a/src/mem/ruby/profiler/SConscript +++ b/src/mem/ruby/profiler/SConscript @@ -33,6 +33,8 @@ Import('*') if not env['RUBY']: Return() +SimObject('Profiler.py') + Source('AccessTraceForAddress.cc') Source('AddressProfiler.cc') Source('CacheProfiler.cc') diff --git a/src/mem/ruby/recorder/SConscript b/src/mem/ruby/recorder/SConscript index ef78faed4..ef4f4ef05 100644 --- a/src/mem/ruby/recorder/SConscript +++ b/src/mem/ruby/recorder/SConscript @@ -33,6 +33,8 @@ Import('*') if not env['RUBY']: Return() +SimObject('Tracer.py') + Source('CacheRecorder.cc') Source('Tracer.cc') Source('TraceRecord.cc', Werror=False) diff --git a/src/mem/ruby/recorder/Tracer.cc b/src/mem/ruby/recorder/Tracer.cc index a0a3b22b7..55b5efe39 100644 --- a/src/mem/ruby/recorder/Tracer.cc +++ b/src/mem/ruby/recorder/Tracer.cc @@ -39,10 +39,13 @@ #include "mem/ruby/system/System.hh" //added by SS -Tracer::Tracer(const string & name) +Tracer::Tracer(const Params *p) + : SimObject(p) { - m_name = name; m_enabled = false; + m_warmup_length = p->warmup_length; + assert(m_warmup_length > 0); + RubySystem::m_tracer_ptr = this; } //commented by SS @@ -55,20 +58,8 @@ Tracer::~Tracer() { } -void Tracer::init(const vector & argv) +void Tracer::init() { - m_warmup_length = 0; - - for (size_t i=0; i 0); } void Tracer::startTrace(string filename) @@ -155,3 +146,10 @@ int Tracer::playbackTrace(string filename) void Tracer::print(ostream& out) const { } + + +Tracer * +RubyTracerParams::create() +{ + return new Tracer(this); +} diff --git a/src/mem/ruby/recorder/Tracer.hh b/src/mem/ruby/recorder/Tracer.hh index 27a1c95e1..b806b7081 100644 --- a/src/mem/ruby/recorder/Tracer.hh +++ b/src/mem/ruby/recorder/Tracer.hh @@ -43,17 +43,22 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/system/NodeID.hh" #include "mem/protocol/CacheRequestType.hh" +#include "sim/sim_object.hh" + +#include "params/RubyTracer.hh" + #include "gzstream.hh" template class PrioHeap; class Address; class TraceRecord; -class Tracer { +class Tracer : public SimObject { public: // Constructors // Tracer(); - Tracer(const string & name); + typedef RubyTracerParams Params; + Tracer(const Params *p); // Destructor ~Tracer(); @@ -68,7 +73,7 @@ public: // Public Class Methods int playbackTrace(string filename); - void init(const vector & argv); + void init(); private: // Private Methods @@ -82,7 +87,6 @@ private: //added by SS int m_warmup_length; - string m_name; }; // Output operator declaration diff --git a/src/mem/ruby/recorder/Tracer.py b/src/mem/ruby/recorder/Tracer.py new file mode 100644 index 000000000..b47cc16ee --- /dev/null +++ b/src/mem/ruby/recorder/Tracer.py @@ -0,0 +1,7 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubyTracer(SimObject): + type = 'RubyTracer' + cxx_class = 'Tracer' + warmup_length = Param.Int(100000, "") diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index c7062262a..28c8a103a 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -2,6 +2,9 @@ #ifndef ABSTRACTCONTROLLER_H #define ABSTRACTCONTROLLER_H +#include "sim/sim_object.hh" +#include "params/RubyController.hh" + #include "mem/ruby/common/Consumer.hh" #include "mem/protocol/MachineType.hh" #include "mem/ruby/common/Address.hh" @@ -9,9 +12,10 @@ class MessageBuffer; class Network; -class AbstractController : public Consumer { +class AbstractController : public SimObject, public Consumer { public: - AbstractController() {} + typedef RubyControllerParams Params; + AbstractController(const Params *p) : SimObject(p) {} virtual void init(Network* net_ptr, const vector & argv) = 0; // returns the number of controllers created of the specific subtype diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py new file mode 100644 index 000000000..c23dc7849 --- /dev/null +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -0,0 +1,13 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubyController(SimObject): + type = 'RubyController' + cxx_class = 'AbstractController' + abstract = True + version = Param.Int("") + transitions_per_cycle = \ + Param.Int(32, "no. of SLICC state machine transitions per cycle") + buffer_size = Param.Int(0, "max buffer size 0 means infinite") + recycle_latency = Param.Int(10, "") + number_of_TBEs = Param.Int(256, "") diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript index 6ba614fa9..98f4b4fa2 100644 --- a/src/mem/ruby/slicc_interface/SConscript +++ b/src/mem/ruby/slicc_interface/SConscript @@ -33,6 +33,8 @@ Import('*') if not env['RUBY']: Return() +SimObject('Controller.py') + Source('AbstractCacheEntry.cc') Source('RubySlicc_Profiler_interface.cc') Source('RubySlicc_ComponentMapping.cc') diff --git a/src/mem/ruby/system/Cache.py b/src/mem/ruby/system/Cache.py new file mode 100644 index 000000000..250d8e888 --- /dev/null +++ b/src/mem/ruby/system/Cache.py @@ -0,0 +1,12 @@ +from m5.params import * +from m5.SimObject import SimObject +from Controller import RubyController + +class RubyCache(SimObject): + type = 'RubyCache' + cxx_class = 'CacheMemory' + size = Param.Int(""); + latency = Param.Int(""); + assoc = Param.Int(""); + replacement_policy = Param.String("PSEUDO_LRU", ""); + controller = Param.RubyController(""); diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index cf3e094ad..43a0e13e9 100644 --- a/src/mem/ruby/system/CacheMemory.cc +++ b/src/mem/ruby/system/CacheMemory.cc @@ -47,41 +47,20 @@ ostream& operator<<(ostream& out, const CacheMemory& obj) // **************************************************************** -CacheMemory::CacheMemory(const string & name) - : m_cache_name(name) +CacheMemory * +RubyCacheParams::create() { - m_profiler_ptr = new CacheProfiler(name); + return new CacheMemory(this); } -void CacheMemory::init(const vector & argv) +CacheMemory::CacheMemory(const Params *p) + : SimObject(p) { - int cache_size = -1; - string policy; - - m_num_last_level_caches = - MachineType_base_count(MachineType_FIRST); - m_controller = NULL; - for (uint32 i=0; igetMachineType()) { - m_num_last_level_caches = - MachineType_base_count(m_controller->getMachineType()); - m_last_level_machine_type = - m_controller->getMachineType(); - } - } else { - cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; - } - } + int cache_size = p->size; + m_latency = p->latency; + m_cache_assoc = p->assoc; + string policy = p->replacement_policy; + m_controller = p->controller; int num_lines = cache_size/RubySystem::getBlockSizeBytes(); m_cache_num_sets = num_lines / m_cache_assoc; @@ -95,6 +74,24 @@ void CacheMemory::init(const vector & argv) else assert(false); +} + + +void CacheMemory::init() +{ + m_num_last_level_caches = + MachineType_base_count(MachineType_FIRST); +#if 0 + for (uint32 i=0; igetMachineType()) { + m_num_last_level_caches = + MachineType_base_count(m_controller->getMachineType()); + m_last_level_machine_type = + m_controller->getMachineType(); + } + } +#endif + m_cache.setSize(m_cache_num_sets); m_locked.setSize(m_cache_num_sets); for (int i = 0; i < m_cache_num_sets; i++) { diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 8b84f33ec..fac076da9 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -38,6 +38,9 @@ #ifndef CACHEMEMORY_H #define CACHEMEMORY_H +#include "sim/sim_object.hh" +#include "params/RubyCache.hh" + #include "mem/ruby/common/Global.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/common/Address.hh" @@ -57,12 +60,14 @@ #include "base/hashmap.hh" #include -class CacheMemory { +class CacheMemory : public SimObject { public: + typedef RubyCacheParams Params; // Constructors - CacheMemory(const string & name); - void init(const vector & argv); + CacheMemory(const Params *p); + // CacheMemory(const string & name); + void init(); // Destructor ~CacheMemory(); diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 8af892007..330e9f6af 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -8,25 +8,13 @@ #include "mem/protocol/SequencerRequestType.hh" #include "mem/ruby/system/System.hh" -DMASequencer::DMASequencer(const string & name) - : RubyPort(name) +DMASequencer::DMASequencer(const Params *p) + : RubyPort(p) { } -void DMASequencer::init(const vector & argv) +void DMASequencer::init() { - m_version = -1; - m_controller = NULL; - for (size_t i=0;igetMandatoryQueue(); m_is_busy = false; m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); } @@ -135,3 +123,10 @@ void DMASequencer::printConfig(ostream & out) { } + + +DMASequencer * +DMASequencerParams::create() +{ + return new DMASequencer(this); +} diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh index 77c0a2258..12a5c790f 100644 --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -6,6 +6,8 @@ #include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/system/RubyPort.hh" +#include "params/DMASequencer.hh" + struct DMARequest { uint64_t start_paddr; int len; @@ -16,13 +18,11 @@ struct DMARequest { int64_t id; }; -class MessageBuffer; -class AbstractController; - class DMASequencer :public RubyPort { public: - DMASequencer(const string & name); - void init(const vector & argv); + typedef DMASequencerParams Params; + DMASequencer(const Params *); + void init(); /* external interface */ int64_t makeRequest(const RubyRequest & request); bool isReady(const RubyRequest & request, bool dont_set = false) { assert(0); return false;}; @@ -39,13 +39,10 @@ private: void issueNext(); private: - int m_version; - AbstractController* m_controller; bool m_is_busy; uint64_t m_data_block_mask; DMARequest active_request; int num_active_requests; - MessageBuffer* m_mandatory_q_ptr; }; #endif // DMACONTROLLER_H diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index 9b2a3873c..b0b33b048 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -46,29 +46,17 @@ int DirectoryMemory::m_num_directories = 0; int DirectoryMemory::m_num_directories_bits = 0; uint64_t DirectoryMemory::m_total_size_bytes = 0; -DirectoryMemory::DirectoryMemory(const string & name) - : m_name(name) +DirectoryMemory::DirectoryMemory(const Params *p) + : SimObject(p) { + m_version = p->version; + m_size_bytes = p->size_mb * static_cast(1<<20); + m_size_bits = log_int(m_size_bytes); + m_controller = p->controller; } -void DirectoryMemory::init(const vector & argv) +void DirectoryMemory::init() { - m_controller = NULL; - for (vector::const_iterator it = argv.begin(); it != argv.end(); it++) { - if ( (*it) == "version" ) - m_version = atoi( (*(++it)).c_str() ); - else if ( (*it) == "size_mb" ) { - m_size_bytes = atoi((*(++it)).c_str()) * static_cast(1<<20); - m_size_bits = log_int(m_size_bytes); - } else if ( (*it) == "controller" ) { - m_controller = RubySystem::getController((*(++it))); - } else { - cerr << "DirectoryMemory: Unkown config parameter: " << (*it) << endl; - assert(0); - } - } - assert(m_controller != NULL); - m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); m_entries = new Directory_Entry*[m_num_entries]; for (int i=0; i < m_num_entries; i++) @@ -205,3 +193,8 @@ void DirectoryMemory::print(ostream& out) const } +DirectoryMemory * +RubyDirectoryMemoryParams::create() +{ + return new DirectoryMemory(this); +} diff --git a/src/mem/ruby/system/DirectoryMemory.hh b/src/mem/ruby/system/DirectoryMemory.hh index 09211fd83..1575187b0 100644 --- a/src/mem/ruby/system/DirectoryMemory.hh +++ b/src/mem/ruby/system/DirectoryMemory.hh @@ -43,14 +43,17 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/system/MemoryVector.hh" #include "mem/protocol/Directory_Entry.hh" +#include "sim/sim_object.hh" +#include "params/RubyDirectoryMemory.hh" class AbstractController; -class DirectoryMemory { +class DirectoryMemory : public SimObject { public: // Constructors - DirectoryMemory(const string & name); - void init(const vector & argv); + typedef RubyDirectoryMemoryParams Params; + DirectoryMemory(const Params *p); + void init(); // DirectoryMemory(int version); // Destructor diff --git a/src/mem/ruby/system/DirectoryMemory.py b/src/mem/ruby/system/DirectoryMemory.py new file mode 100644 index 000000000..55c2d82bd --- /dev/null +++ b/src/mem/ruby/system/DirectoryMemory.py @@ -0,0 +1,10 @@ +from m5.params import * +from m5.proxy import * +from m5.SimObject import SimObject + +class RubyDirectoryMemory(SimObject): + type = 'RubyDirectoryMemory' + cxx_class = 'DirectoryMemory' + version = Param.Int(0, "") + size_mb = Param.Int(1024, "") + controller = Param.RubyController(Parent.any, "") diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc index 2ef7d8ffc..5a6c9e34c 100644 --- a/src/mem/ruby/system/MemoryControl.cc +++ b/src/mem/ruby/system/MemoryControl.cc @@ -151,61 +151,30 @@ ostream& operator<<(ostream& out, const MemoryControl& obj) // **************************************************************** // CONSTRUCTOR -MemoryControl::MemoryControl(const string & name) - : m_name(name) +MemoryControl::MemoryControl(const Params *p) + : SimObject(p) { - m_name = name; -// printf ("MemoryControl name is %s \n", m_name.c_str()); + m_mem_bus_cycle_multiplier = p->mem_bus_cycle_multiplier; + m_banks_per_rank = p->banks_per_rank; + m_ranks_per_dimm = p->ranks_per_dimm; + m_dimms_per_channel = p->dimms_per_channel; + m_bank_bit_0 = p->bank_bit_0; + m_rank_bit_0 = p->rank_bit_0; + m_dimm_bit_0 = p->dimm_bit_0; + m_bank_queue_size = p->bank_queue_size; + m_bank_busy_time = p->bank_busy_time; + m_rank_rank_delay = p->rank_rank_delay; + m_read_write_delay = p->read_write_delay; + m_basic_bus_busy_time = p->basic_bus_busy_time; + m_mem_ctl_latency = p->mem_ctl_latency; + m_refresh_period = p->refresh_period; + m_tFaw = p->tFaw; + m_mem_random_arbitrate = p->mem_random_arbitrate; + m_mem_fixed_delay = p->mem_fixed_delay; } -void MemoryControl::init(const vector & argv) +void MemoryControl::init() { - - for (vector::const_iterator it = argv.begin(); it != argv.end(); it++) { - if ( (*it) == "version" ) - m_version = atoi( (*(++it)).c_str() ); - else if ( (*it) == "mem_bus_cycle_multiplier" ) { - m_mem_bus_cycle_multiplier = atoi((*(++it)).c_str()); - } else if ( (*it) == "banks_per_rank" ) { - m_banks_per_rank = atoi((*(++it)).c_str()); - } else if ( (*it) == "ranks_per_dimm" ) { - m_ranks_per_dimm = atoi((*(++it)).c_str()); - } else if ( (*it) == "dimms_per_channel" ) { - m_dimms_per_channel = atoi((*(++it)).c_str()); - } else if ( (*it) == "bank_bit_0" ) { - m_bank_bit_0 = atoi((*(++it)).c_str()); - } else if ( (*it) == "rank_bit_0" ) { - m_rank_bit_0 = atoi((*(++it)).c_str()); - } else if ( (*it) == "dimm_bit_0" ) { - m_dimm_bit_0 = atoi((*(++it)).c_str()); - } else if ( (*it) == "bank_queue_size" ) { - m_bank_queue_size = atoi((*(++it)).c_str()); - } else if ( (*it) == "bank_busy_time" ) { - m_bank_busy_time = atoi((*(++it)).c_str()); - } else if ( (*it) == "rank_rank_delay" ) { - m_rank_rank_delay = atoi((*(++it)).c_str()); - } else if ( (*it) == "read_write_delay" ) { - m_read_write_delay = atoi((*(++it)).c_str()); - } else if ( (*it) == "basic_bus_busy_time" ) { - m_basic_bus_busy_time = atoi((*(++it)).c_str()); - } else if ( (*it) == "mem_ctl_latency" ) { - m_mem_ctl_latency = atoi((*(++it)).c_str()); - } else if ( (*it) == "refresh_period" ) { - m_refresh_period = atoi((*(++it)).c_str()); - } else if ( (*it) == "tFaw" ) { - m_tFaw = atoi((*(++it)).c_str()); - } else if ( (*it) == "mem_random_arbitrate" ) { - m_mem_random_arbitrate = atoi((*(++it)).c_str()); - } else if ( (*it) == "mem_fixed_delay" ) { - m_mem_fixed_delay = atoi((*(++it)).c_str()); - } -// } else -// assert(0); - } - - -/////// - //m_version = version; m_msg_counter = 0; m_debug = 0; @@ -351,7 +320,6 @@ void MemoryControl::print (ostream& out) const { void MemoryControl::printConfig (ostream& out) { - out << "Memory Control " << m_version << ":" << endl; out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl; out << " Basic read latency: " << m_mem_ctl_latency << endl; if (m_mem_fixed_delay) { @@ -662,4 +630,9 @@ void MemoryControl::wakeup () { } } +MemoryControl * +RubyMemoryControlParams::create() +{ + return new MemoryControl(this); +} diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh index 3419f8c40..1570e81cd 100644 --- a/src/mem/ruby/system/MemoryControl.hh +++ b/src/mem/ruby/system/MemoryControl.hh @@ -51,6 +51,8 @@ #include "mem/protocol/MemoryMsg.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/system/AbstractMemOrCache.hh" +#include "sim/sim_object.hh" +#include "params/RubyMemoryControl.hh" #include @@ -62,12 +64,13 @@ class Consumer; -class MemoryControl : public Consumer, public AbstractMemOrCache { +class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache { public: // Constructors - MemoryControl(const string & name); - void init(const vector & argv); + typedef RubyMemoryControlParams Params; + MemoryControl(const Params *p); + void init(); // Destructor ~MemoryControl (); @@ -122,7 +125,6 @@ private: Consumer* m_consumer_ptr; // Consumer to signal a wakeup() string m_name; string m_description; - int m_version; int m_msg_counter; int m_awakened; diff --git a/src/mem/ruby/system/MemoryControl.py b/src/mem/ruby/system/MemoryControl.py new file mode 100644 index 000000000..6c8109728 --- /dev/null +++ b/src/mem/ruby/system/MemoryControl.py @@ -0,0 +1,23 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubyMemoryControl(SimObject): + type = 'RubyMemoryControl' + cxx_class = 'MemoryControl' + mem_bus_cycle_multiplier = Param.Int(10, ""); + banks_per_rank = Param.Int(8, ""); + ranks_per_dimm = Param.Int(2, ""); + dimms_per_channel = Param.Int(2, ""); + bank_bit_0 = Param.Int(8, ""); + rank_bit_0 = Param.Int(11, ""); + dimm_bit_0 = Param.Int(12, ""); + bank_queue_size = Param.Int(12, ""); + bank_busy_time = Param.Int(11, ""); + rank_rank_delay = Param.Int(1, ""); + read_write_delay = Param.Int(2, ""); + basic_bus_busy_time = Param.Int(2, ""); + mem_ctl_latency = Param.Int(12, ""); + refresh_period = Param.Int(1560, ""); + tFaw = Param.Int(0, ""); + mem_random_arbitrate = Param.Int(0, ""); + mem_fixed_delay = Param.Int(0, ""); diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 2a5c5f479..b83ba43e3 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -1,5 +1,57 @@ +/* + * Copyright (c) 2009 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mem/physical.hh" #include "mem/ruby/system/RubyPort.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" //void (*RubyPort::m_hit_callback)(int64_t) = NULL; uint16_t RubyPort::m_num_ports = 0; + +RubyPort::RubyPort(const Params *p) + : MemObject(p) +{ + m_version = p->version; + assert(m_version != -1); + m_controller = p->controller; + assert(m_controller != NULL); + + m_mandatory_q_ptr = m_controller->getMandatoryQueue(); + + m_port_id = m_num_ports++; + m_request_cnt = 0; + m_hit_callback = NULL; + assert(m_num_ports <= 2048); // see below for reason +} + +Port * +RubyPort::getPort(const std::string &if_name, int idx) +{ + return NULL; +} diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 2f391070f..20557669a 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -1,3 +1,32 @@ + +/* + * Copyright (c) 2009 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #ifndef RUBYPORT_H #define RUBYPORT_H @@ -5,20 +34,24 @@ #include #include +#include "mem/mem_object.hh" +#include "mem/tport.hh" + +#include "params/RubyPort.hh" + using namespace std; -class RubyPort { +class MessageBuffer; +class AbstractController; + +class RubyPort : public MemObject { public: - RubyPort(const string & name) - : m_name(name) - { - m_port_id = m_num_ports++; - m_request_cnt = 0; - m_hit_callback = NULL; - assert(m_num_ports <= 2048); // see below for reason - } + typedef RubyPortParams Params; + RubyPort(const Params *p); virtual ~RubyPort() {} + Port *getPort(const std::string &if_name, int idx); + virtual int64_t makeRequest(const RubyRequest & request) = 0; void registerHitCallback(void (*hit_callback)(int64_t request_id)) { @@ -51,6 +84,10 @@ protected: return id; } + int m_version; + AbstractController* m_controller; + MessageBuffer* m_mandatory_q_ptr; + private: static uint16_t m_num_ports; uint16_t m_port_id; diff --git a/src/mem/ruby/system/RubySystem.py b/src/mem/ruby/system/RubySystem.py new file mode 100644 index 000000000..2c1d3d789 --- /dev/null +++ b/src/mem/ruby/system/RubySystem.py @@ -0,0 +1,18 @@ +from m5.params import * +from m5.SimObject import SimObject + +class RubySystem(SimObject): + type = 'RubySystem' + random_seed = Param.Int(1234, "random seed used by the simulation"); + randomization = Param.Bool(False, + "insert random delays on message enqueue times"); + tech_nm = Param.Int(45, + "device size used to calculate latency and area information"); + freq_mhz = Param.Int(3000, "default frequency for the system"); + block_size_bytes = Param.Int(64, + "default cache block size; must be a power of two"); + network = Param.RubyNetwork("") + debug = Param.RubyDebug("the default debug object") + profiler = Param.RubyProfiler(""); + tracer = Param.RubyTracer(""); + diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index 4ca1af114..bd721e83d 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -33,6 +33,12 @@ Import('*') if not env['RUBY']: Return() +SimObject('Cache.py') +SimObject('Sequencer.py') +SimObject('DirectoryMemory.py') +SimObject('MemoryControl.py') +SimObject('RubySystem.py') + Source('DMASequencer.cc') Source('DirectoryMemory.cc') Source('CacheMemory.cc') diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index b4716c346..ad219eab3 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -42,55 +42,44 @@ #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" +#include "params/RubySequencer.hh" + //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) #define LLSC_FAIL -2 long int already = 0; -Sequencer::Sequencer(const string & name) - :RubyPort(name) + +Sequencer * +RubySequencerParams::create() { - m_store_waiting_on_load_cycles = 0; - m_store_waiting_on_store_cycles = 0; - m_load_waiting_on_store_cycles = 0; - m_load_waiting_on_load_cycles = 0; + return new Sequencer(this); } - -void Sequencer::init(const vector & argv) + +Sequencer::Sequencer(const Params *p) + : RubyPort(p) { - m_deadlock_check_scheduled = false; - m_outstanding_count = 0; - - m_max_outstanding_requests = 0; - m_deadlock_threshold = 0; - m_version = -1; - m_instCache_ptr = NULL; - m_dataCache_ptr = NULL; - m_controller = NULL; - for (size_t i=0; igetMandatoryQueue(); - } else if ( argv[i] == "icache") - m_instCache_ptr = RubySystem::getCache(argv[i+1]); - else if ( argv[i] == "dcache") - m_dataCache_ptr = RubySystem::getCache(argv[i+1]); - else if ( argv[i] == "version") - m_version = atoi(argv[i+1].c_str()); - else if ( argv[i] == "max_outstanding_requests") - m_max_outstanding_requests = atoi(argv[i+1].c_str()); - else if ( argv[i] == "deadlock_threshold") - m_deadlock_threshold = atoi(argv[i+1].c_str()); - else { - cerr << "WARNING: Sequencer: Unkown configuration parameter: " << argv[i] << endl; - assert(false); - } - } - assert(m_max_outstanding_requests > 0); - assert(m_deadlock_threshold > 0); - assert(m_version > -1); - assert(m_instCache_ptr != NULL); - assert(m_dataCache_ptr != NULL); - assert(m_controller != NULL); + m_store_waiting_on_load_cycles = 0; + m_store_waiting_on_store_cycles = 0; + m_load_waiting_on_store_cycles = 0; + m_load_waiting_on_load_cycles = 0; + + m_deadlock_check_scheduled = false; + m_outstanding_count = 0; + + m_max_outstanding_requests = 0; + m_deadlock_threshold = 0; + m_instCache_ptr = NULL; + m_dataCache_ptr = NULL; + + m_instCache_ptr = p->icache; + m_dataCache_ptr = p->dcache; + m_max_outstanding_requests = p->max_outstanding_requests; + m_deadlock_threshold = p->deadlock_threshold; + + assert(m_max_outstanding_requests > 0); + assert(m_deadlock_threshold > 0); + assert(m_instCache_ptr != NULL); + assert(m_dataCache_ptr != NULL); } Sequencer::~Sequencer() { @@ -495,7 +484,7 @@ void Sequencer::issueRequest(const RubyRequest& request) { // Send the message to the cache controller assert(latency > 0); - + assert(m_mandatory_q_ptr != NULL); m_mandatory_q_ptr->enqueue(msg, latency); } /* diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 1621bbbdc..d2dc5bbb3 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -51,7 +51,8 @@ class DataBlock; class CacheMsg; class MachineID; class CacheMemory; -class AbstractController; + +class RubySequencerParams; struct SequencerRequest { RubyRequest ruby_request; @@ -65,11 +66,11 @@ struct SequencerRequest { std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj); -class Sequencer : public Consumer, public RubyPort { +class Sequencer : public RubyPort, public Consumer { public: + typedef RubySequencerParams Params; // Constructors - Sequencer(const string & name); - void init(const vector & argv); + Sequencer(const Params *); // Destructor ~Sequencer(); @@ -114,13 +115,10 @@ private: int m_max_outstanding_requests; int m_deadlock_threshold; - AbstractController* m_controller; - MessageBuffer* m_mandatory_q_ptr; CacheMemory* m_dataCache_ptr; CacheMemory* m_instCache_ptr; // indicates what processor on the chip this sequencer is associated with - int m_version; int m_controller_type; Map m_writeRequestTable; diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py new file mode 100644 index 000000000..add5a06a1 --- /dev/null +++ b/src/mem/ruby/system/Sequencer.py @@ -0,0 +1,23 @@ +from m5.params import * +from MemObject import MemObject + +class RubyPort(MemObject): + type = 'RubyPort' + abstract = True + port = VectorPort("M5 port") + controller = Param.RubyController("") + version = Param.Int(0, "") + +class RubySequencer(RubyPort): + type = 'RubySequencer' + cxx_class = 'Sequencer' + icache = Param.RubyCache("") + dcache = Param.RubyCache("") + max_outstanding_requests = Param.Int(16, + "max requests (incl. prefetches) outstanding") + deadlock_threshold = Param.Int(500000, + "max outstanding cycles for a request before deadlock/livelock declared") + funcmem_port = Port("port to functional memory") + +class DMASequencer(RubyPort): + type = 'DMASequencer' diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index 4ce919618..0f5cae026 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -47,15 +47,14 @@ #include "mem/ruby/system/Sequencer.hh" #include "mem/ruby/system/DMASequencer.hh" #include "mem/ruby/system/MemoryVector.hh" -#include "mem/protocol/ControllerFactory.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/system/CacheMemory.hh" #include "mem/ruby/system/DirectoryMemory.hh" #include "mem/ruby/network/simple/Topology.hh" #include "mem/ruby/network/simple/SimpleNetwork.hh" #include "mem/ruby/system/RubyPort.hh" -#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" -#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" +//#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" +//#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" #include "mem/ruby/system/MemoryControl.hh" int RubySystem::m_random_seed; @@ -84,180 +83,32 @@ Tracer* RubySystem::m_tracer_ptr; MemoryVector* RubySystem::m_mem_vec_ptr; -RubySystem* RubySystem::create(const vector & sys_conf) +RubySystem::RubySystem(const Params *p) + : SimObject(p) { - if (g_system_ptr == NULL) - return new RubySystem(sys_conf); - return g_system_ptr; + if (g_system_ptr != NULL) + fatal("Only one RubySystem object currently allowed.\n"); + + m_random_seed = p->random_seed; + srandom(m_random_seed); + m_randomization = p->randomization; + m_tech_nm = p->tech_nm; + m_freq_mhz = p->freq_mhz; + m_block_size_bytes = p->block_size_bytes; + assert(is_power_of_2(m_block_size_bytes)); + m_block_size_bits = log_int(m_block_size_bytes); + m_network_ptr = p->network; + g_debug_ptr = p->debug; + m_profiler_ptr = p->profiler; + m_tracer_ptr = p->tracer; + + g_system_ptr = this; + m_mem_vec_ptr = new MemoryVector; } -void RubySystem::init(const vector & argv) -{ - for (size_t i=0; i < argv.size(); i+=2) { - if (argv[i] == "random_seed") { - m_random_seed = atoi(argv[i+1].c_str()); - srandom(m_random_seed); - } else if (argv[i] == "randomization") { - m_randomization = string_to_bool(argv[i+1]); - } else if (argv[i] == "tech_nm") { - m_tech_nm = atoi(argv[i+1].c_str()); - } else if (argv[i] == "freq_mhz") { - m_freq_mhz = atoi(argv[i+1].c_str()); - } else if (argv[i] == "block_size_bytes") { - m_block_size_bytes = atoi(argv[i+1].c_str()); - assert(is_power_of_2(m_block_size_bytes)); - m_block_size_bits = log_int(m_block_size_bytes); - } else if (argv[i] == "debug") { - - } else if (argv[i] == "tracer") { - - } else if (argv[i] == "profiler") { - - // } else if (argv[i] == "MI_example") { - - } else { - cerr << "Error: Unknown RubySystem config parameter -- " << argv[i] << endl; - assert(0); - } - } -} -RubySystem::RubySystem(const vector & sys_conf) +void RubySystem::init() { - // DEBUG_MSG(SYSTEM_COMP, MedPrio,"initializing"); - - for (size_t i=0;i & argv = sys_conf[i].argv; - if (type == "System") { - init(argv); // initialize system-wide variables before doing anything else! - } else if (type == "Debug") { - g_debug_ptr = new Debug(name, argv); - } - } - - assert( g_debug_ptr != NULL); - g_eventQueue_ptr = new RubyEventQueue; - g_system_ptr = this; - m_mem_vec_ptr = new MemoryVector; - - /* object contruction is broken into two steps (Constructor and init) to avoid cyclic dependencies - * e.g. a sequencer needs a pointer to a controller and a controller needs a pointer to a sequencer - */ - - vector memory_control_names; - - for (size_t i=0;i & argv = sys_conf[i].argv; - if (type == "Topology") - m_topologies[name]->init(argv); - } - - for (size_t i=0;i & argv = sys_conf[i].argv; - if (type == "SimpleNetwork" || type == "GarnetNetwork" || type == "GarnetNetwork_d"){ - m_network_ptr->init(argv); - } - } - - for (size_t i=0;i & argv = sys_conf[i].argv; - if (type == "MemoryControl" ){ - m_memorycontrols[name]->init(argv); - } - } - - for (size_t i=0;i & argv = sys_conf[i].argv; - if (type == "System" || type == "Debug") - continue; - else if (type == "SetAssociativeCache") - m_caches[name]->init(argv); - else if (type == "DirectoryMemory") - m_directories[name]->init(argv); - else if (type == "MemoryControl") - continue; - else if (type == "Sequencer") - m_sequencers[name]->init(argv); - else if (type == "DMASequencer") - m_dma_sequencers[name]->init(argv); - else if (type == "Topology") - continue; - else if (type == "SimpleNetwork" || type == "GarnetNetwork" || type == "GarnetNetwork_d") - continue; - else if (type.find("generated") == 0) { - string controller_type = type.substr(11); - m_controllers[name]->init(m_network_ptr, argv); - } -//added by SS - else if (type == "Tracer") - //m_tracers[name]->init(argv); - m_tracer_ptr->init(argv); - else if (type == "Profiler") - m_profiler_ptr->init(argv, memory_control_names); -// else if (type == "MI_example"){ -// } - else - assert(0); - } - -// m_profiler_ptr = new Profiler; - // calculate system-wide parameters m_memory_size_bytes = 0; DirectoryMemory* prev = NULL; @@ -270,12 +121,9 @@ RubySystem::RubySystem(const vector & sys_conf) } m_mem_vec_ptr->setSize(m_memory_size_bytes); m_memory_size_bits = log_int(m_memory_size_bytes); - -// m_tracer_ptr = new Tracer; - DEBUG_MSG(SYSTEM_COMP, MedPrio,"finished initializing"); - DEBUG_NEWLINE(SYSTEM_COMP, MedPrio); } + RubySystem::~RubySystem() { @@ -423,5 +271,8 @@ void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { #endif - - +RubySystem * +RubySystemParams::create() +{ + return new RubySystem(this); +} diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 1d36de878..6f0261888 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -46,6 +46,8 @@ #include "mem/gems_common/Vector.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include +#include "sim/sim_object.hh" +#include "params/RubySystem.hh" class Profiler; class Network; @@ -84,9 +86,10 @@ struct RubyObjConf { {} }; -class RubySystem { +class RubySystem : public SimObject { public: - static RubySystem* create(const vector & sys_conf); + typedef RubySystemParams Params; + RubySystem(const Params *p); // Destructor ~RubySystem(); @@ -152,7 +155,7 @@ private: RubySystem(const RubySystem& obj); RubySystem& operator=(const RubySystem& obj); - void init(const vector & argv); + void init(); static void printSystemConfig(ostream& out); @@ -181,6 +184,7 @@ private: //added by SS //static map< string, Tracer* > m_tracers; +public: static Profiler* m_profiler_ptr; static Tracer* m_tracer_ptr; static MemoryVector* m_mem_vec_ptr; -- 2.30.2