diff options
Diffstat (limited to 'src/mem/ruby/config/cfg.rb')
-rw-r--r-- | src/mem/ruby/config/cfg.rb | 751 |
1 files changed, 751 insertions, 0 deletions
diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb new file mode 100644 index 000000000..de8bcafd2 --- /dev/null +++ b/src/mem/ruby/config/cfg.rb @@ -0,0 +1,751 @@ +#!/usr/bin/ruby + +class AssertionFailure < RuntimeError +end + +class Boolean + def self.is_a?(obj) + return self.name == "Boolean" + end +end + +def assert(condition,message) + unless condition + raise AssertionFailure, "Assertion failed: #{message}" + end +end + +class LibRubyObject + @@all_objs = Array.new + attr_reader :obj_name + @@default_params = Hash.new + + def initialize(obj_name) + assert obj_name.is_a?(String), "Obj_Name must be a string" + @obj_name = obj_name + @@all_objs << self + @params = Hash.new + end + + def cppClassName() + raise NotImplementedException + end + + def self.param(param_name, type) + idx = self.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx][param_name] = nil + send :define_method, param_name do + @params[param_name] = @@default_params[idx][param_name] if ! @params.key?(param_name) + @params[param_name] + end + method_name = (param_name.to_s + "=").to_sym + send :define_method, method_name do |val| + if val.is_a?(FalseClass) || val.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert val.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end +# assert val.is_a?(type), "#{param_name} must be of type #{type}" + @params[param_name] = val + end + end + + def self.default_param(param_name, type, default) + idx = self.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + if default.is_a?(FalseClass) || default.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert default.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end + @@default_params[idx][param_name] = default + send :define_method, param_name do + @params[param_name] = @@default_params[idx][param_name] if ! @params.key?(param_name) + @params[param_name] + end + method_name = (param_name.to_s + "=").to_sym + send :define_method, method_name do |val| + assert val.is_a?(type), "#{param_name} must be of type #{type}" + @params[param_name] = val + end + end + + def applyDefaults() + idx = self.class.name.to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx].each { |key, val| + @params[key] = val if ! @params.key?(key) + } + end + + def argv() + str = "" + + applyDefaults + + @params.each { |key, val| + str += key.id2name + " " + if val.is_a?(LibRubyObject) + str += val.obj_name + " " + else + if val.is_a?(String) and val == "" + str += "null " + else + str += val.to_s + " " + end + end + } + return str + end + + def self.printConstructors() + @@all_objs.each { |obj| + print obj.cppClassName, " ", obj.obj_name, " ",obj.argv,"\n" + } + end + def self.all() + @@all_objs + end +end + +class IfacePort < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def bochsConnType + raise NotImplementedException + end +end + +class NetPort < LibRubyObject + attr :mach_type + attr_reader :version + + @@type_cnt = Hash.new + @type_id + def initialize(obj_name, mach_type) + super(obj_name) + @mach_type = mach_type + @@type_cnt[mach_type] ||= 0 + @type_id = @@type_cnt[mach_type] + @@type_cnt[mach_type] += 1 + + idx = "NetPort".to_sym + @@default_params[idx] = Hash.new if ! @@default_params.key?(idx) + @@default_params[idx].each { |key, val| + @params[key] = val if ! @params.key?(key) + } + end + + def port_name + mach_type + end + def port_num + @type_id + end + def cppClassName + "NetPort" + end +end + +class MemoryVector < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName + "MemoryController" + end +end + +class Debug < LibRubyObject + def initialize *args + case args.size + when 1 + super(args[0]) + when 6 + init_params *args[1] + else + raise Exception + end + end + + def init_params (protocol_trace, filter_string, verbosity_string, start_time, output_filename) + @params[:protocol_trace] = protocol_trace + @params[:filter_string] = filter_string + @params[:verbosity_string] = verbosity_string + @params[:start_time] = start_time + @params[:output_filename] = output_filename + end + + def cppClassName + "Debug" + end +end + +class RubySystem + + @@params = Hash.new + @@network = nil + + def self.init(iface_ports, network) + @@iface_ports = iface_ports + @@network = network + end + + def self.default_param(param_name, type, default) + if default.is_a?(FalseClass) || default.is_a?(TrueClass) + assert type.is_a?(Boolean), "default value of param \"#{param_name}\" must be either true or false" + else + assert default.is_a?(type), "default value of param \"#{param_name}\" does not match type #{type}" + end + @@params[param_name] = default + method_name = (param_name.to_s).to_sym + instance_eval <<-EOS + def #{method_name.to_s} + @@params[:#{param_name.to_s}] + end + EOS + instance_eval <<-EOS + def #{method_name.to_s}=(val) + @@params[:#{param_name.to_s}] = val + end + EOS + end + + def self.generateConfig() + # get current time for random seed if set to "rand" + if @@params[:random_seed] == "rand" + t = Time.now + @@params[:random_seed] = t.usec.to_i + end + if ! @@params[:random_seed].is_a?(Integer) + raise TypeException + end + print "System sys0 ",argv,"\n" + LibRubyObject.all.each { |obj| + if obj.is_a?(SetAssociativeCache) + obj.calculateLatency + end + } + LibRubyObject.printConstructors + end + + def self.printIfacePorts() + @@iface_ports.each { |port| + print port.obj_name, " " + } + puts + end + + def self.getBochsConnections() + ports = Hash.new + @@iface_ports.each { |port| + ports[port.obj_name] = port.bochsConnType + } + return ports + end + + def self.getMemorySizeMB() + DirectoryMemory.memorySizeMB + end + + # override the default accessors (generated by default_param) for random_seed + def self.random_seed=(seed) + assert (val.is_a?(Integer) or val == "rand"), "RubySystem.random_seed takes either an integer value or the string \"rand\"" + @@params[:random_seed] = seed + end + +private + + def self.argv() + str = "" + @@params.each { |key, val| + str += key.id2name + " " + str += val.to_s + " " + } + return str + end + + def self.writeConfig() + @@network.printTopology + end + +end + +#require "defaults.rb" + + + +class CacheController < NetPort + @@total_cache_controllers = 0 + attr :caches + attr :sequencer + def initialize(obj_name, mach_type, caches, sequencer) + super(obj_name, mach_type) + @caches = caches + @caches.each { |cache| + cache.controller = self + } + + @sequencer = sequencer + @sequencer.controller = self + + @version = @@total_cache_controllers + @@total_cache_controllers += 1 + @sequencer.version = @version + buffer_size() + end + + def argv() + vec = "version "+@version.to_s + @caches.each { |cache| + vec += " cache " + cache.obj_name + } + vec += " sequencer "+@sequencer.obj_name + vec += " transitions_per_cycle "+@params[:transitions_per_cycle].to_s + vec += " buffer_size "+@params[:buffer_size].to_s + vec += " number_of_TBEs "+@params[:number_of_TBEs].to_s + + end + + def cppClassName() + "generated:"+@mach_type + end +end + +class DirectoryController < NetPort + @@total_directory_controllers = 0 + attr :directory + attr :memory_control + + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type) + + @directory = directory + directory.controller = self + + @memory_control = memory_control + + @version = @@total_directory_controllers + @@total_directory_controllers += 1 + buffer_size() + end + + def argv() + "version "+@version.to_s+" directory_name "+@directory.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s + " memory_controller_name "+@memory_control.obj_name + " recycle_latency "+@params[:recycle_latency].to_s + end + + def cppClassName() + "generated:"+@mach_type + end + +end + +class DMAController < NetPort + @@total_dma_controllers = 0 + attr :dma_sequencer + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type) + @dma_sequencer = dma_sequencer + @version = @@total_dma_controllers + @@total_dma_controllers += 1 + dma_sequencer.controller = self + buffer_size + end + + def argv() + "version "+@version.to_s+" dma_sequencer "+@dma_sequencer.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s + end + + def cppClassName() + "generated:"+@mach_type + end +end + +class Cache < LibRubyObject + attr :size_kb, :latency + attr_writer :controller + def initialize(obj_name, size_kb, latency) + super(obj_name) + assert size_kb.is_a?(Integer), "Cache size must be an integer" + @size_kb = size_kb + @latency = latency + end + + def args + "controller "+@controller.obj_name+" size_kb "+@size_kb.to_s+" latency "+@latency.to_s + end +end + +class SetAssociativeCache < Cache + attr :assoc, :replacement_policy + + # latency can be either an integer, a float, or the string "auto" + # when an integer, it represents the number of cycles for a hit + # when a float, it represents the cache access time in ns + # when set to "auto", libruby will attempt to find a realistic latency by running CACTI + def initialize(obj_name, size_kb, latency, assoc, replacement_policy) + super(obj_name, size_kb, latency) + @assoc = assoc + @replacement_policy = replacement_policy + end + + def calculateLatency() + if @latency == "auto" + cacti_args = Array.new() + cacti_args << (@size_kb*1024) << RubySystem.block_size_bytes << @assoc + cacti_args << 1 << 0 << 0 << 0 << 1 + cacti_args << RubySystem.tech_nm << RubySystem.block_size_bytes*8 + cacti_args << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 1 + cacti_args << 360 << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 << 0 << 0 + cacti_args << 50 << 10 << 10 << 0 << 1 << 1 + + cacti_cmd = File.dirname(__FILE__) + "/cacti/cacti " + cacti_args.join(" ") + + IO.popen(cacti_cmd) { |pipe| + str1 = pipe.readline + str2 = pipe.readline + results = str2.split(", ") + if results.size != 61 + print "CACTI ERROR: CACTI produced unexpected output.\n" + print "Are you using the version shipped with libruby?\n" + raise Exception + end + latency_ns = results[5].to_f + if (latency_ns == "1e+39") + print "CACTI ERROR: CACTI was unable to realistically model the cache ",@obj_name,"\n" + print "Either change the cache parameters or manually set the latency values\n" + raise Exception + end + clk_period_ns = 1e9 * (1.0 / (RubySystem.freq_mhz * 1e6)) + latency_cycles = (latency_ns / clk_period_ns).ceil + @latency = latency_cycles + } + elsif @latency.is_a?(Float) + clk_period_ns = 1e9 * (1.0 / (RubySystem.freq_mhz * 1e6)) + latency_cycles = (@latency / clk_period_ns).ceil + @latency = latency_cycles + elsif ! @latency.is_a?(Integer) + raise Exception + end + end + + def argv() + args+" assoc "+@assoc.to_s+" replacement_policy "+@replacement_policy + end + + def cppClassName() + "SetAssociativeCache" + end +end + +class DirectoryMemory < LibRubyObject + attr :size_mb + attr_writer :controller + @@total_size_mb = 0 + + def initialize(obj_name, size_mb) + super(obj_name) + @size_mb = size_mb + @@total_size_mb += size_mb + end + + def argv() + "version "+@controller.version.to_s+" size_mb "+@size_mb.to_s+" controller "+@controller.obj_name + end + + def cppClassName() + "DirectoryMemory" + end + + def self.memorySizeMB() + @@total_size_mb + end +end + +#added by SS +class MemoryControl < LibRubyObject + attr :name + def initialize(obj_name) + super(obj_name) + @name = obj_name + end + + def argv() + vec = super() + vec += " mem_bus_cycle_multiplier "+mem_bus_cycle_multiplier.to_s + vec += " banks_per_rank "+banks_per_rank.to_s + vec += " ranks_per_dimm "+ranks_per_dimm.to_s + vec += " dimms_per_channel "+dimms_per_channel.to_s + vec += " bank_bit_0 "+bank_bit_0.to_s + vec += " rank_bit_0 "+rank_bit_0.to_s + vec += " dimm_bit_0 "+dimm_bit_0.to_s + vec += " bank_queue_size "+bank_queue_size.to_s + vec += " bank_busy_time "+bank_busy_time.to_s + vec += " rank_rank_delay "+rank_rank_delay.to_s + vec += " read_write_delay "+read_write_delay.to_s + vec += " basic_bus_busy_time "+basic_bus_busy_time.to_s + vec += " mem_ctl_latency "+mem_ctl_latency.to_s + vec += " refresh_period "+refresh_period.to_s + vec += " tFaw "+tFaw.to_s + vec += " mem_random_arbitrate "+mem_random_arbitrate.to_s + vec += " mem_fixed_delay "+mem_fixed_delay.to_s + vec += " memory_controller_name "+@name + + end + + + def cppClassName() + "MemoryControl" + end +end + + + +class Sequencer < IfacePort + + def cppClassName() + "Sequencer" + end + + param :controller, NetPort # must be set after initialization + param :icache, Cache + param :dcache, Cache + param :version, Integer + + def initialize(obj_name, icache, dcache) + super(obj_name) + self.icache=icache + self.dcache=dcache + end + + def bochsConnType() + return "cpu"+version.to_s + end + +end + + + +class DMASequencer < IfacePort + def initialize(obj_name) + super(obj_name) + @params = { + :controller => nil, + :version => nil + } + end + + def controller=(controller) + @params[:controller] = controller.obj_name + @params[:version] = controller.version + end + + def cppClassName() + "DMASequencer" + end + + def bochsConnType() + return "dma"+@params[:version].to_s + end +end + +class IntNode + @@num = 0 + def initialize() + + end +end + +class Network < LibRubyObject +end + +class Topology < LibRubyObject + attr :net_ports + param :network, Network + def initialize(name, net_ports) + super(name) + @net_ports = net_ports + end + + def cppClassName + "Topology" + end +end + +class Network < LibRubyObject + param :topology, Topology + def initialize(name, topo) + super(name) + @params[:topology] = topo + topo.network= self + end + + def argv() + vec = super() + + vec += " endpoint_bandwidth "+endpoint_bandwidth.to_s + vec += " adaptive_routing "+adaptive_routing.to_s + vec += " number_of_virtual_networks "+number_of_virtual_networks.to_s + vec += " fan_out_degree "+fan_out_degree.to_s + + vec += " buffer_size "+buffer_size.to_s + vec += " link_latency "+adaptive_routing.to_s + vec += " on_chip_latency "+on_chip_latency.to_s + + end + + def printTopology() + topology.printFile + end + def cppClassName() + "SimpleNetwork" + end + +end + +class PtToPtTopology < Topology + + param :connections,String + + def initialize(name, net_ports) + super(name, net_ports) + @params[:connections] = "" + @net_ports.each_index { |idx| + @params[:connections] << ("ext_node:"+@net_ports[idx].port_name+":"+@net_ports[idx].port_num.to_s) + @params[:connections] << ("%int_node:"+ idx.to_s+ "%link_latency:"+ link_latency.to_s) + @params[:connections] << ("%bw_multiplier:"+external_bw.to_s+"#") + } + @net_ports.each_index { |outer_idx| + @net_ports.each_index { |inner_idx| + if (outer_idx != inner_idx) + @params[:connections] << ("int_node:"+ outer_idx.to_s+ "%int_node:"+ inner_idx.to_s) + @params[:connections] << ("%link_latency:"+link_latency.to_s+"%bw_multiplier:"+internal_bw.to_s) + @params[:connections] << ("%link_weight:"+1.to_s+"#") + end + } + } + # call the accessors of the parent class to initialize them + # need to find a better method!! + print_config + end + +end + +class CrossbarTopology < Topology + param :connections,String + + def initialize(name, net_ports) + super(name, net_ports) + @params[:connections] = "" + crossbar_node = @net_ports.size + @net_ports.each_index { |idx| + @params[:connections] << ("ext_node:"+@net_ports[idx].port_name+":"+@net_ports[idx].port_num.to_s) + @params[:connections] << ("%int_node:"+ idx.to_s+ "%link_latency:"+ link_latency.to_s) + @params[:connections] << ("%bw_multiplier:"+external_bw.to_s+"#") + } + @net_ports.each_index { |idx| + @params[:connections] << ("int_node:"+idx.to_s+"%int_node:"+crossbar_node.to_s) + @params[:connections] << ("%link_latency:"+link_latency.to_s+"%bw_multiplier:"+internal_bw.to_s) + @params[:connections] << ("%link_weight:"+1.to_s+"#") + } + print_config + end +end + +#added by SS +class Tracer < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName() + "Tracer" + end + +end + +class Profiler < LibRubyObject + def initialize(obj_name) + super(obj_name) + end + + def cppClassName() + "Profiler" + end + +end + +class MI_example_CacheController < CacheController + def initialize(obj_name, mach_type, caches, sequencer) + super(obj_name, mach_type, caches, sequencer) + end + def argv() + vec = super() + vec += " issue_latency "+issue_latency.to_s + vec += " cache_response_latency "+cache_response_latency.to_s + end + +end + +class MI_example_DirectoryController < DirectoryController + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type, directory, memory_control) + end + def argv() + vec = super() + vec += " to_mem_ctrl_latency "+to_mem_ctrl_latency.to_s + vec += " directory_latency "+directory_latency.to_s + vec += " memory_latency "+memory_latency.to_s + end + +end + +#added by SS +class GarnetNetwork < Network + def initialize(name, topo) + super(name, topo) + end + def argv() + vec = super() + vec += " flit_size "+flit_size.to_s + vec += " number_of_pipe_stages "+number_of_pipe_stages.to_s + vec += " vcs_per_class "+vcs_per_class.to_s + vec += " buffer_size "+buffer_size.to_s + vec += " using_network_testing "+using_network_testing.to_s + end + +end + +class GarnetFixedPipeline < GarnetNetwork + def initialize(name, net_ports) + super(name, net_ports) + end + + def argv() + super() + end + + def cppClassName() + "GarnetNetwork_d" + end +end + +class GarnetFlexiblePipeline < GarnetNetwork + def initialize(name, net_ports) + super(name, net_ports) + end + + def argv() + super() + end + + def cppClassName() + "GarnetNetwork" + end +end + +require "defaults.rb" |