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 = PhysicalMemory()) -system = System(cpu = cpus, funcmem = PhysicalMemory(), - physmem = ruby_memory) +class L1Cache(RubyCache): + assoc = 2 + latency = 3 + size = 32768 -for cpu in cpus: - cpu.test = system.physmem.port - cpu.functional = system.funcmem.port +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,54 +87,21 @@ 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() { } @@ -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_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_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_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) + +void RubySystem::init() { - 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) -{ - // 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;