ruby: Convert most Ruby objects to M5 SimObjects.

The necessary companion conversion of Ruby objects generated by SLICC
are converted to M5 SimObjects in the following patch, so this patch
alone does not compile.
Conversion of Garnet network models is also handled in a separate
patch; that code is temporarily disabled from compiling to allow
testing of interim code.
This commit is contained in:
Steve Reinhardt 2010-01-29 20:29:17 -08:00
parent b43994ba45
commit 98c94cfe3c
75 changed files with 640 additions and 2186 deletions

View file

@ -34,8 +34,6 @@ from m5.defines import buildEnv
from m5.util import addToPath from m5.util import addToPath
import os, optparse, sys import os, optparse, sys
addToPath('../common') addToPath('../common')
addToPath('../../tests/configs/')
import ruby_config
parser = optparse.OptionParser() parser = optparse.OptionParser()
@ -85,19 +83,43 @@ cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \
progress_interval=options.progress) \ progress_interval=options.progress) \
for i in xrange(options.testers) ] for i in xrange(options.testers) ]
# create the desired simulated system system = System(cpu = cpus,
# ruby memory must be at least 16 MB to work with the mem tester funcmem = PhysicalMemory(),
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", physmem = PhysicalMemory())
cores = options.testers,
memory_size = 16,
ports_per_cpu = 1)
system = System(cpu = cpus, funcmem = PhysicalMemory(), class L1Cache(RubyCache):
physmem = ruby_memory) assoc = 2
latency = 3
size = 32768
for cpu in cpus: class L2Cache(RubyCache):
cpu.test = system.physmem.port assoc = 16
cpu.functional = system.funcmem.port 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())
# ----------------------- # -----------------------

View file

@ -35,9 +35,6 @@ SimObject('Bus.py')
SimObject('MemObject.py') SimObject('MemObject.py')
SimObject('PhysicalMemory.py') SimObject('PhysicalMemory.py')
if env['RUBY']:
SimObject('RubyMemory.py')
Source('bridge.cc') Source('bridge.cc')
Source('bus.cc') Source('bus.cc')
Source('dram.cc') Source('dram.cc')
@ -48,9 +45,6 @@ Source('port.cc')
Source('tport.cc') Source('tport.cc')
Source('mport.cc') Source('mport.cc')
if env['RUBY']:
Source('rubymem.cc')
if env['FULL_SYSTEM']: if env['FULL_SYSTEM']:
Source('vport.cc') Source('vport.cc')
else: else:

View file

@ -72,14 +72,6 @@ def do_embed_text(target, source, env):
fin.close() fin.close()
fout.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 # Link includes
# #

View file

@ -87,54 +87,21 @@ void changeDebugFilter(int filter)
g_debug_ptr->setFilter(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<string> & argv )
{
//
// must clear the filter before adding filter strings
//
clearFilter();
for (size_t i=0;i<argv.size();i+=2) {
if (argv[i] == "filter_string") {
if (setFilterString(argv[i+1].c_str())) {
fatal("could not set filter string to %s\n", argv[i+1].c_str());
}
} else if (argv[i] == "verbosity_string") {
setVerbosityString( argv[i+1].c_str() );
} else if (argv[i] == "start_time") {
m_starting_cycle = atoi( argv[i+1].c_str() );
} else if (argv[i] == "output_filename") {
setDebugOutputFile( argv[i+1].c_str() );
} else if (argv[i] == "protocol_trace") {
m_protocol_trace = string_to_bool(argv[i+1]);
} else {
fatal("invalid argument %s\n");
}
}
}
Debug::Debug( const char *filterString, const char *verboseString,
Time filterStartTime, const char *filename )
{
m_verbosityLevel = No_Verb;
clearFilter(); clearFilter();
debug_cout_ptr = &cout; debug_cout_ptr = &cout;
m_starting_cycle = filterStartTime; setFilterString(p->filter_string.c_str());
if (setFilterString(filterString)) setVerbosityString(p->verbosity_string.c_str());
fatal("could not set filter string to %s\n", filterString); setDebugOutputFile(p->output_filename.c_str());
setVerbosityString( verboseString ); m_starting_cycle = p->start_time;
setDebugOutputFile( filename ); m_protocol_trace = p->protocol_trace;
g_debug_ptr = this;
} }
Debug::~Debug() Debug::~Debug()
{ {
} }
@ -417,3 +384,9 @@ void ERROR_OUT( const char* fmt, ... ) {
} }
*/ */
Debug *
RubyDebugParams::create()
{
return new Debug(this);
}

View file

@ -41,6 +41,9 @@
#include "config/ruby_debug.hh" #include "config/ruby_debug.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "sim/sim_object.hh"
#include "params/RubyDebug.hh"
extern std::ostream * debug_cout_ptr; extern std::ostream * debug_cout_ptr;
@ -70,13 +73,11 @@ enum DebugComponents
enum PriorityLevel {HighPrio, MedPrio, LowPrio}; enum PriorityLevel {HighPrio, MedPrio, LowPrio};
enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb}; enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
class Debug { class Debug : public SimObject {
public: public:
// Constructors // Constructors
Debug(); typedef RubyDebugParams Params;
Debug(const std::string & name, const std::vector<std::string> & argv); Debug(const Params *p);
Debug( const char *filterString, const char *verboseString,
Time filterStartTime, const char *filename );
// Destructor // Destructor
~Debug(); ~Debug();

View file

@ -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")

View file

@ -33,6 +33,8 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Debug.py')
Source('Address.cc') Source('Address.cc')
Source('DataBlock.cc') Source('DataBlock.cc')
Source('Debug.cc') Source('Debug.cc')

View file

@ -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"

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -1,14 +0,0 @@
#include <iostream>
#include <assert.h>
#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);
}

View file

@ -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

View file

@ -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

View file

@ -40,10 +40,14 @@
// Class public method definitions // Class public method definitions
RubyEventQueue theEventQueue;
RubyEventQueue::RubyEventQueue() RubyEventQueue::RubyEventQueue()
{ {
m_prio_heap_ptr = NULL; m_prio_heap_ptr = NULL;
init(); init();
assert(g_eventQueue_ptr == NULL);
g_eventQueue_ptr = this;
} }
RubyEventQueue::~RubyEventQueue() RubyEventQueue::~RubyEventQueue()

View file

@ -89,6 +89,15 @@ vector<string> tokenizeString(string str, string delims)
return tokens; 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) void libruby_init(const char* cfg_filename)
{ {
ifstream cfg_output(cfg_filename); ifstream cfg_output(cfg_filename);
@ -115,6 +124,7 @@ void libruby_init(const char* cfg_filename)
RubySystem::create(*sys_conf); RubySystem::create(*sys_conf);
delete sys_conf; delete sys_conf;
} }
#endif
RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id)) RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
{ {

View file

@ -29,38 +29,26 @@
#include "mem/protocol/MachineType.hh" #include "mem/protocol/MachineType.hh"
#include "mem/ruby/network/Network.hh" #include "mem/ruby/network/Network.hh"
Network::Network(const string & name) Network::Network(const Params *p)
: m_name(name) : SimObject(p)
{ {
m_virtual_networks = 0; m_virtual_networks = p->number_of_virtual_networks;
m_topology_ptr = NULL; 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<string> & argv) void Network::init()
{ {
m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
for (size_t i=0; i<argv.size(); i+=2) {
if (argv[i] == "number_of_virtual_networks")
m_virtual_networks = atoi(argv[i+1].c_str());
else if (argv[i] == "topology")
m_topology_ptr = RubySystem::getTopology(argv[i+1]);
else if (argv[i] == "buffer_size")
m_buffer_size = atoi(argv[i+1].c_str());
else if (argv[i] == "endpoint_bandwidth")
m_endpoint_bandwidth = atoi(argv[i+1].c_str());
else if (argv[i] == "adaptive_routing")
m_adaptive_routing = (argv[i+1]=="true");
else if (argv[i] == "link_latency")
m_link_latency = atoi(argv[i+1].c_str());
else if (argv[i] == "control_msg_size")
m_control_msg_size = atoi(argv[i+1].c_str());
}
m_data_msg_size = RubySystem::getBlockSizeBytes() + m_control_msg_size; m_data_msg_size = RubySystem::getBlockSizeBytes() + m_control_msg_size;
assert(m_virtual_networks != 0);
assert(m_topology_ptr != NULL);
} }
int Network::MessageSizeType_to_int(MessageSizeType size_type) int Network::MessageSizeType_to_int(MessageSizeType size_type)

View file

@ -1,4 +1,3 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved. * All rights reserved.
@ -50,17 +49,20 @@
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "mem/protocol/MessageSizeType.hh" #include "mem/protocol/MessageSizeType.hh"
#include "mem/ruby/system/System.hh" #include "mem/ruby/system/System.hh"
#include "sim/sim_object.hh"
#include "params/RubyNetwork.hh"
class NetDest; class NetDest;
class MessageBuffer; class MessageBuffer;
class Throttle; class Throttle;
class Topology; class Topology;
class Network { class Network : public SimObject {
public: public:
// Constructors // Constructors
Network(const string & name); typedef RubyNetworkParams Params;
virtual void init(const vector<string> & argv); Network(const Params *p);
virtual void init();
// Destructor // Destructor
virtual ~Network() {} virtual ~Network() {}

View file

@ -1,6 +1,4 @@
# -*- mode:python -*- # Copyright (c) 2009 Advanced Micro Devices, Inc.
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # 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 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 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']: class Topology(SimObject):
Return() 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, "");

View file

@ -33,4 +33,6 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Network.py')
Source('Network.cc') Source('Network.cc')

View file

@ -43,7 +43,7 @@ GarnetNetwork_d::GarnetNetwork_d(const string & name)
{ {
} }
void GarnetNetwork_d::init(const vector<string> & argv) void GarnetNetwork_d::init()
{ {
Network::init(argv); Network::init(argv);

View file

@ -50,7 +50,7 @@ public:
~GarnetNetwork_d(); ~GarnetNetwork_d();
void init(const vector<string> & argv); void init();
//added by SS //added by SS
NetworkConfig* getNetworkConfig() { return m_network_config_ptr; } NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }

View file

@ -30,6 +30,9 @@
Import('*') Import('*')
# temporarily disable
Return()
if not env['RUBY']: if not env['RUBY']:
Return() Return()

View file

@ -44,7 +44,7 @@ GarnetNetwork::GarnetNetwork(const string & name)
{ {
} }
void GarnetNetwork::init(const vector<string> & argv) void GarnetNetwork::init()
{ {
// printf("hello\n"); // printf("hello\n");
Network::init(argv); Network::init(argv);

View file

@ -49,7 +49,7 @@ public:
~GarnetNetwork(); ~GarnetNetwork();
void init(const vector<string> & argv); void init();
//added by SS //added by SS
NetworkConfig* getNetworkConfig() { return m_network_config_ptr; } NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }

View file

@ -48,7 +48,7 @@ class NetworkConfig {
bool m_using_network_testing; bool m_using_network_testing;
public: public:
NetworkConfig(){} NetworkConfig(){}
void init(const vector<string> & argv) { void init() {
for (size_t i=0; i<argv.size(); i+=2) { for (size_t i=0; i<argv.size(); i+=2) {
if (argv[i] == "flit_size") if (argv[i] == "flit_size")
m_flit_size = atoi(argv[i+1].c_str()); m_flit_size = atoi(argv[i+1].c_str());

View file

@ -30,6 +30,9 @@
Import('*') Import('*')
# temporarily disable
Return()
if not env['RUBY']: if not env['RUBY']:
Return() Return()

View file

@ -30,6 +30,9 @@
Import('*') Import('*')
# temporarily disable
Return()
if not env['RUBY']: if not env['RUBY']:
Return() Return()

View file

@ -8,7 +8,7 @@ class HierarchicalSwitchTopology : public Topology
{ {
public: public:
HierarchicalSwitchTopology(const string & name); HierarchicalSwitchTopology(const string & name);
void init(const vector<string> & argv); void init();
protected: protected:
void construct(); void construct();

View file

@ -8,7 +8,7 @@ class PtToPtTopology : public Topology
{ {
public: public:
PtToPtTopology(const string & name); PtToPtTopology(const string & name);
void init(const vector<string> & argv); void init();
protected: protected:
void construct(); void construct();

View file

@ -33,6 +33,8 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('SimpleNetwork.py')
Source('PerfectSwitch.cc') Source('PerfectSwitch.cc')
Source('SimpleNetwork.cc') Source('SimpleNetwork.cc')
Source('Switch.cc') Source('Switch.cc')

View file

@ -59,17 +59,17 @@ Network* Network::createNetwork(int nodes)
} }
*/ */
SimpleNetwork::SimpleNetwork(const string & name) SimpleNetwork::SimpleNetwork(const Params *p)
: Network(name) : Network(p)
{ {
m_virtual_networks = 0; m_virtual_networks = 0;
m_topology_ptr = NULL; m_topology_ptr = NULL;
} }
void SimpleNetwork::init(const vector<string> & argv) void SimpleNetwork::init()
{ {
Network::init(argv); Network::init();
m_endpoint_switches.setSize(m_nodes); m_endpoint_switches.setSize(m_nodes);
@ -263,3 +263,10 @@ void SimpleNetwork::print(ostream& out) const
{ {
out << "[SimpleNetwork]"; out << "[SimpleNetwork]";
} }
SimpleNetwork *
SimpleNetworkParams::create()
{
return new SimpleNetwork(this);
}

View file

@ -73,6 +73,8 @@
#include "mem/gems_common/Vector.hh" #include "mem/gems_common/Vector.hh"
#include "mem/ruby/network/Network.hh" #include "mem/ruby/network/Network.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "sim/sim_object.hh"
#include "params/SimpleNetwork.hh"
class NetDest; class NetDest;
class MessageBuffer; class MessageBuffer;
@ -83,13 +85,13 @@ class Topology;
class SimpleNetwork : public Network { class SimpleNetwork : public Network {
public: public:
// Constructors // Constructors
// SimpleNetwork(int nodes); typedef SimpleNetworkParams Params;
SimpleNetwork(const string & name); SimpleNetwork(const Params *p);
// Destructor // Destructor
~SimpleNetwork(); ~SimpleNetwork();
void init(const vector<string> & argv); void init();
// Public Methods // Public Methods
void printStats(ostream& out) const; void printStats(ostream& out) const;

View file

@ -0,0 +1,5 @@
from m5.params import *
from Network import RubyNetwork
class SimpleNetwork(RubyNetwork):
type = 'SimpleNetwork'

View file

@ -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 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); static NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights, const Matrix& dist);
Topology::Topology(const string & name) Topology::Topology(const Params *p)
: m_name(name) : 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_nodes = MachineType_base_number(MachineType_NUM);
m_number_of_switches = 0; m_number_of_switches = 0;
} }
void Topology::init(const vector<string> & argv) void Topology::init()
{ {
for (size_t i=0; i<argv.size(); i+=2) {
if (argv[i] == "network")
m_network_ptr = RubySystem::getNetwork();
else if (argv[i] == "connections")
m_connections = argv[i+1];
else if (argv[i] == "print_config") {
m_print_config = string_to_bool(argv[i+1]);
}
}
assert(m_network_ptr != NULL);
} }
void Topology::makeTopology() void Topology::makeTopology()
@ -457,3 +449,8 @@ static NetDest shortest_path_to_node(SwitchID src, SwitchID next,
return result; return result;
} }
Topology *
TopologyParams::create()
{
return new Topology(this);
}

View file

@ -50,22 +50,24 @@
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Vector.hh" #include "mem/gems_common/Vector.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "sim/sim_object.hh"
#include "params/Topology.hh"
class Network; class Network;
class NetDest; class NetDest;
typedef Vector < Vector <int> > Matrix; typedef Vector < Vector <int> > Matrix;
class Topology { class Topology : public SimObject {
public: public:
// Constructors // Constructors
// Topology(Network* network_ptr, int number_of_nodes); typedef TopologyParams Params;
Topology(const string & name); Topology(const Params *p);
// Destructor // Destructor
virtual ~Topology() {} virtual ~Topology() {}
virtual void init(const vector<string> & argv); virtual void init();
// Public Methods // Public Methods
void makeTopology(); void makeTopology();
@ -80,7 +82,6 @@ public:
protected: protected:
// Private Methods // Private Methods
void init();
SwitchID newSwitchID(); SwitchID newSwitchID();
void addLink(SwitchID src, SwitchID dest, int link_latency); void addLink(SwitchID src, SwitchID dest, int link_latency);
void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier); void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier);

View file

@ -8,7 +8,7 @@ class Torus2DTopology : public Topology
{ {
public: public:
Torus2DTopology(const string & name); Torus2DTopology(const string & name);
void init(const vector<string> & argv); void init();
protected: protected:
void construct(); void construct();

View file

@ -63,6 +63,8 @@
#include "mem/ruby/common/Debug.hh" #include "mem/ruby/common/Debug.hh"
#include "mem/protocol/MachineType.hh" #include "mem/protocol/MachineType.hh"
#include "mem/ruby/system/System.hh"
// Allows use of times() library call, which determines virtual runtime // Allows use of times() library call, which determines virtual runtime
#include <sys/times.h> #include <sys/times.h>
@ -71,9 +73,9 @@ extern std::ostream * debug_cout_ptr;
static double process_memory_total(); static double process_memory_total();
static double process_memory_resident(); 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<string, int>; m_requestProfileMap_ptr = new Map<string, int>;
m_inst_profiler_ptr = NULL; m_inst_profiler_ptr = NULL;
@ -83,6 +85,10 @@ Profiler::Profiler(const string & name)
m_stats_period = 1000000; // Default m_stats_period = 1000000; // Default
m_periodic_output_file_ptr = &cerr; 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() Profiler::~Profiler()
@ -136,17 +142,6 @@ void Profiler::init(const vector<string> & argv, vector<string> memory_control_n
m_hot_lines = false; m_hot_lines = false;
m_all_instructions = false; m_all_instructions = false;
for (size_t i=0; i<argv.size(); i+=2) {
if ( argv[i] == "hot_lines") {
m_hot_lines = (argv[i+1]=="true");
} else if ( argv[i] == "all_instructions") {
m_all_instructions = (argv[i+1]=="true");
}else {
cerr << "WARNING: Profiler: Unkown configuration parameter: " << argv[i] << endl;
assert(false);
}
}
m_address_profiler_ptr = new AddressProfiler; m_address_profiler_ptr = new AddressProfiler;
m_address_profiler_ptr -> setHotLines(m_hot_lines); m_address_profiler_ptr -> setHotLines(m_hot_lines);
m_address_profiler_ptr -> setAllInstructions(m_all_instructions); 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::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++; } 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);
}

View file

@ -71,6 +71,9 @@
#include "mem/protocol/GenericRequestType.hh" #include "mem/protocol/GenericRequestType.hh"
#include "mem/ruby/system/MemoryControl.hh" #include "mem/ruby/system/MemoryControl.hh"
#include "params/RubyProfiler.hh"
#include "sim/sim_object.hh"
class CacheMsg; class CacheMsg;
class AddressProfiler; class AddressProfiler;
@ -99,10 +102,11 @@ struct memory_control_profiler {
}; };
class Profiler : public Consumer { class Profiler : public SimObject, public Consumer {
public: public:
// Constructors // Constructors
Profiler(const string & name); typedef RubyProfilerParams Params;
Profiler(const Params *);
void init(const vector<string> & argv, vector<string> memory_control_names); void init(const vector<string> & argv, vector<string> memory_control_names);
@ -260,8 +264,6 @@ private:
//added by SS //added by SS
bool m_hot_lines; bool m_hot_lines;
bool m_all_instructions; bool m_all_instructions;
string m_name;
}; };
// Output operator declaration // Output operator declaration

View file

@ -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, "")

View file

@ -33,6 +33,8 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Profiler.py')
Source('AccessTraceForAddress.cc') Source('AccessTraceForAddress.cc')
Source('AddressProfiler.cc') Source('AddressProfiler.cc')
Source('CacheProfiler.cc') Source('CacheProfiler.cc')

View file

@ -33,6 +33,8 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Tracer.py')
Source('CacheRecorder.cc') Source('CacheRecorder.cc')
Source('Tracer.cc') Source('Tracer.cc')
Source('TraceRecord.cc', Werror=False) Source('TraceRecord.cc', Werror=False)

View file

@ -39,10 +39,13 @@
#include "mem/ruby/system/System.hh" #include "mem/ruby/system/System.hh"
//added by SS //added by SS
Tracer::Tracer(const string & name) Tracer::Tracer(const Params *p)
: SimObject(p)
{ {
m_name = name;
m_enabled = false; m_enabled = false;
m_warmup_length = p->warmup_length;
assert(m_warmup_length > 0);
RubySystem::m_tracer_ptr = this;
} }
//commented by SS //commented by SS
@ -55,20 +58,8 @@ Tracer::~Tracer()
{ {
} }
void Tracer::init(const vector<string> & argv) void Tracer::init()
{ {
m_warmup_length = 0;
for (size_t i=0; i<argv.size(); i+=2) {
if ( argv[i] == "warmup_length") {
m_warmup_length = atoi(argv[i+1].c_str());
}
else {
cerr << "WARNING: Tracer: Unkown configuration parameter: " << argv[i] << endl;
assert(false);
}
}
assert(m_warmup_length > 0);
} }
void Tracer::startTrace(string filename) void Tracer::startTrace(string filename)
@ -155,3 +146,10 @@ int Tracer::playbackTrace(string filename)
void Tracer::print(ostream& out) const void Tracer::print(ostream& out) const
{ {
} }
Tracer *
RubyTracerParams::create()
{
return new Tracer(this);
}

View file

@ -43,17 +43,22 @@
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "mem/protocol/CacheRequestType.hh" #include "mem/protocol/CacheRequestType.hh"
#include "sim/sim_object.hh"
#include "params/RubyTracer.hh"
#include "gzstream.hh" #include "gzstream.hh"
template <class TYPE> class PrioHeap; template <class TYPE> class PrioHeap;
class Address; class Address;
class TraceRecord; class TraceRecord;
class Tracer { class Tracer : public SimObject {
public: public:
// Constructors // Constructors
// Tracer(); // Tracer();
Tracer(const string & name); typedef RubyTracerParams Params;
Tracer(const Params *p);
// Destructor // Destructor
~Tracer(); ~Tracer();
@ -68,7 +73,7 @@ public:
// Public Class Methods // Public Class Methods
int playbackTrace(string filename); int playbackTrace(string filename);
void init(const vector<string> & argv); void init();
private: private:
// Private Methods // Private Methods
@ -82,7 +87,6 @@ private:
//added by SS //added by SS
int m_warmup_length; int m_warmup_length;
string m_name;
}; };
// Output operator declaration // Output operator declaration

View file

@ -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, "")

View file

@ -2,6 +2,9 @@
#ifndef ABSTRACTCONTROLLER_H #ifndef ABSTRACTCONTROLLER_H
#define ABSTRACTCONTROLLER_H #define ABSTRACTCONTROLLER_H
#include "sim/sim_object.hh"
#include "params/RubyController.hh"
#include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Consumer.hh"
#include "mem/protocol/MachineType.hh" #include "mem/protocol/MachineType.hh"
#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Address.hh"
@ -9,9 +12,10 @@
class MessageBuffer; class MessageBuffer;
class Network; class Network;
class AbstractController : public Consumer { class AbstractController : public SimObject, public Consumer {
public: public:
AbstractController() {} typedef RubyControllerParams Params;
AbstractController(const Params *p) : SimObject(p) {}
virtual void init(Network* net_ptr, const vector<string> & argv) = 0; virtual void init(Network* net_ptr, const vector<string> & argv) = 0;
// returns the number of controllers created of the specific subtype // returns the number of controllers created of the specific subtype

View file

@ -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, "")

View file

@ -33,6 +33,8 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Controller.py')
Source('AbstractCacheEntry.cc') Source('AbstractCacheEntry.cc')
Source('RubySlicc_Profiler_interface.cc') Source('RubySlicc_Profiler_interface.cc')
Source('RubySlicc_ComponentMapping.cc') Source('RubySlicc_ComponentMapping.cc')

View file

@ -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("");

View file

@ -47,41 +47,20 @@ ostream& operator<<(ostream& out, const CacheMemory& obj)
// **************************************************************** // ****************************************************************
CacheMemory::CacheMemory(const string & name) CacheMemory *
: m_cache_name(name) RubyCacheParams::create()
{ {
m_profiler_ptr = new CacheProfiler(name); return new CacheMemory(this);
} }
void CacheMemory::init(const vector<string> & argv) CacheMemory::CacheMemory(const Params *p)
: SimObject(p)
{ {
int cache_size = -1; int cache_size = p->size;
string policy; m_latency = p->latency;
m_cache_assoc = p->assoc;
m_num_last_level_caches = string policy = p->replacement_policy;
MachineType_base_count(MachineType_FIRST); m_controller = p->controller;
m_controller = NULL;
for (uint32 i=0; i<argv.size(); i+=2) {
if (argv[i] == "size") {
cache_size = atoi(argv[i+1].c_str());
} else if (argv[i] == "latency") {
m_latency = atoi(argv[i+1].c_str());
} else if (argv[i] == "assoc") {
m_cache_assoc = atoi(argv[i+1].c_str());
} else if (argv[i] == "replacement_policy") {
policy = argv[i+1];
} else if (argv[i] == "controller") {
m_controller = RubySystem::getController(argv[i+1]);
if (m_last_level_machine_type < m_controller->getMachineType()) {
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 num_lines = cache_size/RubySystem::getBlockSizeBytes(); int num_lines = cache_size/RubySystem::getBlockSizeBytes();
m_cache_num_sets = num_lines / m_cache_assoc; m_cache_num_sets = num_lines / m_cache_assoc;
@ -95,6 +74,24 @@ void CacheMemory::init(const vector<string> & argv)
else else
assert(false); assert(false);
}
void CacheMemory::init()
{
m_num_last_level_caches =
MachineType_base_count(MachineType_FIRST);
#if 0
for (uint32 i=0; i<argv.size(); i+=2) {
if (m_last_level_machine_type < m_controller->getMachineType()) {
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_cache.setSize(m_cache_num_sets);
m_locked.setSize(m_cache_num_sets); m_locked.setSize(m_cache_num_sets);
for (int i = 0; i < m_cache_num_sets; i++) { for (int i = 0; i < m_cache_num_sets; i++) {

View file

@ -38,6 +38,9 @@
#ifndef CACHEMEMORY_H #ifndef CACHEMEMORY_H
#define CACHEMEMORY_H #define CACHEMEMORY_H
#include "sim/sim_object.hh"
#include "params/RubyCache.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/protocol/AccessPermission.hh" #include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Address.hh"
@ -57,12 +60,14 @@
#include "base/hashmap.hh" #include "base/hashmap.hh"
#include <vector> #include <vector>
class CacheMemory { class CacheMemory : public SimObject {
public: public:
typedef RubyCacheParams Params;
// Constructors // Constructors
CacheMemory(const string & name); CacheMemory(const Params *p);
void init(const vector<string> & argv); // CacheMemory(const string & name);
void init();
// Destructor // Destructor
~CacheMemory(); ~CacheMemory();

View file

@ -8,25 +8,13 @@
#include "mem/protocol/SequencerRequestType.hh" #include "mem/protocol/SequencerRequestType.hh"
#include "mem/ruby/system/System.hh" #include "mem/ruby/system/System.hh"
DMASequencer::DMASequencer(const string & name) DMASequencer::DMASequencer(const Params *p)
: RubyPort(name) : RubyPort(p)
{ {
} }
void DMASequencer::init(const vector<string> & argv) void DMASequencer::init()
{ {
m_version = -1;
m_controller = NULL;
for (size_t i=0;i<argv.size();i+=2) {
if (argv[i] == "controller")
m_controller = RubySystem::getController(argv[i+1]);
else if (argv[i] == "version")
m_version = atoi(argv[i+1].c_str());
}
assert(m_controller != NULL);
assert(m_version != -1);
m_mandatory_q_ptr = m_controller->getMandatoryQueue();
m_is_busy = false; m_is_busy = false;
m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
} }
@ -135,3 +123,10 @@ void DMASequencer::printConfig(ostream & out)
{ {
} }
DMASequencer *
DMASequencerParams::create()
{
return new DMASequencer(this);
}

View file

@ -6,6 +6,8 @@
#include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/system/RubyPort.hh" #include "mem/ruby/system/RubyPort.hh"
#include "params/DMASequencer.hh"
struct DMARequest { struct DMARequest {
uint64_t start_paddr; uint64_t start_paddr;
int len; int len;
@ -16,13 +18,11 @@ struct DMARequest {
int64_t id; int64_t id;
}; };
class MessageBuffer;
class AbstractController;
class DMASequencer :public RubyPort { class DMASequencer :public RubyPort {
public: public:
DMASequencer(const string & name); typedef DMASequencerParams Params;
void init(const vector<string> & argv); DMASequencer(const Params *);
void init();
/* external interface */ /* external interface */
int64_t makeRequest(const RubyRequest & request); int64_t makeRequest(const RubyRequest & request);
bool isReady(const RubyRequest & request, bool dont_set = false) { assert(0); return false;}; bool isReady(const RubyRequest & request, bool dont_set = false) { assert(0); return false;};
@ -39,13 +39,10 @@ private:
void issueNext(); void issueNext();
private: private:
int m_version;
AbstractController* m_controller;
bool m_is_busy; bool m_is_busy;
uint64_t m_data_block_mask; uint64_t m_data_block_mask;
DMARequest active_request; DMARequest active_request;
int num_active_requests; int num_active_requests;
MessageBuffer* m_mandatory_q_ptr;
}; };
#endif // DMACONTROLLER_H #endif // DMACONTROLLER_H

View file

@ -46,29 +46,17 @@ int DirectoryMemory::m_num_directories = 0;
int DirectoryMemory::m_num_directories_bits = 0; int DirectoryMemory::m_num_directories_bits = 0;
uint64_t DirectoryMemory::m_total_size_bytes = 0; uint64_t DirectoryMemory::m_total_size_bytes = 0;
DirectoryMemory::DirectoryMemory(const string & name) DirectoryMemory::DirectoryMemory(const Params *p)
: m_name(name) : SimObject(p)
{ {
m_version = p->version;
m_size_bytes = p->size_mb * static_cast<uint64>(1<<20);
m_size_bits = log_int(m_size_bytes);
m_controller = p->controller;
} }
void DirectoryMemory::init(const vector<string> & argv) void DirectoryMemory::init()
{ {
m_controller = NULL;
for (vector<string>::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<uint64>(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_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
m_entries = new Directory_Entry*[m_num_entries]; m_entries = new Directory_Entry*[m_num_entries];
for (int i=0; i < m_num_entries; i++) 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);
}

View file

@ -43,14 +43,17 @@
#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Address.hh"
#include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/system/MemoryVector.hh"
#include "mem/protocol/Directory_Entry.hh" #include "mem/protocol/Directory_Entry.hh"
#include "sim/sim_object.hh"
#include "params/RubyDirectoryMemory.hh"
class AbstractController; class AbstractController;
class DirectoryMemory { class DirectoryMemory : public SimObject {
public: public:
// Constructors // Constructors
DirectoryMemory(const string & name); typedef RubyDirectoryMemoryParams Params;
void init(const vector<string> & argv); DirectoryMemory(const Params *p);
void init();
// DirectoryMemory(int version); // DirectoryMemory(int version);
// Destructor // Destructor

View file

@ -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, "")

View file

@ -151,61 +151,30 @@ ostream& operator<<(ostream& out, const MemoryControl& obj)
// **************************************************************** // ****************************************************************
// CONSTRUCTOR // CONSTRUCTOR
MemoryControl::MemoryControl(const string & name) MemoryControl::MemoryControl(const Params *p)
: m_name(name) : SimObject(p)
{ {
m_name = name; m_mem_bus_cycle_multiplier = p->mem_bus_cycle_multiplier;
// printf ("MemoryControl name is %s \n", m_name.c_str()); 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<string> & argv) void MemoryControl::init()
{ {
for (vector<string>::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_msg_counter = 0;
m_debug = 0; m_debug = 0;
@ -351,7 +320,6 @@ void MemoryControl::print (ostream& out) const {
void MemoryControl::printConfig (ostream& out) { void MemoryControl::printConfig (ostream& out) {
out << "Memory Control " << m_version << ":" << endl;
out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl; out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl;
out << " Basic read latency: " << m_mem_ctl_latency << endl; out << " Basic read latency: " << m_mem_ctl_latency << endl;
if (m_mem_fixed_delay) { if (m_mem_fixed_delay) {
@ -662,4 +630,9 @@ void MemoryControl::wakeup () {
} }
} }
MemoryControl *
RubyMemoryControlParams::create()
{
return new MemoryControl(this);
}

View file

@ -51,6 +51,8 @@
#include "mem/protocol/MemoryMsg.hh" #include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/AbstractMemOrCache.hh" #include "mem/ruby/system/AbstractMemOrCache.hh"
#include "sim/sim_object.hh"
#include "params/RubyMemoryControl.hh"
#include <list> #include <list>
@ -62,12 +64,13 @@
class Consumer; class Consumer;
class MemoryControl : public Consumer, public AbstractMemOrCache { class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache {
public: public:
// Constructors // Constructors
MemoryControl(const string & name); typedef RubyMemoryControlParams Params;
void init(const vector<string> & argv); MemoryControl(const Params *p);
void init();
// Destructor // Destructor
~MemoryControl (); ~MemoryControl ();
@ -122,7 +125,6 @@ private:
Consumer* m_consumer_ptr; // Consumer to signal a wakeup() Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
string m_name; string m_name;
string m_description; string m_description;
int m_version;
int m_msg_counter; int m_msg_counter;
int m_awakened; int m_awakened;

View file

@ -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, "");

View file

@ -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/system/RubyPort.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
//void (*RubyPort::m_hit_callback)(int64_t) = NULL; //void (*RubyPort::m_hit_callback)(int64_t) = NULL;
uint16_t RubyPort::m_num_ports = 0; 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;
}

View file

@ -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 #ifndef RUBYPORT_H
#define RUBYPORT_H #define RUBYPORT_H
@ -5,20 +34,24 @@
#include <string> #include <string>
#include <assert.h> #include <assert.h>
#include "mem/mem_object.hh"
#include "mem/tport.hh"
#include "params/RubyPort.hh"
using namespace std; using namespace std;
class RubyPort { class MessageBuffer;
class AbstractController;
class RubyPort : public MemObject {
public: public:
RubyPort(const string & name) typedef RubyPortParams Params;
: m_name(name) RubyPort(const Params *p);
{
m_port_id = m_num_ports++;
m_request_cnt = 0;
m_hit_callback = NULL;
assert(m_num_ports <= 2048); // see below for reason
}
virtual ~RubyPort() {} virtual ~RubyPort() {}
Port *getPort(const std::string &if_name, int idx);
virtual int64_t makeRequest(const RubyRequest & request) = 0; virtual int64_t makeRequest(const RubyRequest & request) = 0;
void registerHitCallback(void (*hit_callback)(int64_t request_id)) { void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
@ -51,6 +84,10 @@ protected:
return id; return id;
} }
int m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
private: private:
static uint16_t m_num_ports; static uint16_t m_num_ports;
uint16_t m_port_id; uint16_t m_port_id;

View file

@ -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("");

View file

@ -33,6 +33,12 @@ Import('*')
if not env['RUBY']: if not env['RUBY']:
Return() Return()
SimObject('Cache.py')
SimObject('Sequencer.py')
SimObject('DirectoryMemory.py')
SimObject('MemoryControl.py')
SimObject('RubySystem.py')
Source('DMASequencer.cc') Source('DMASequencer.cc')
Source('DirectoryMemory.cc') Source('DirectoryMemory.cc')
Source('CacheMemory.cc') Source('CacheMemory.cc')

View file

@ -42,55 +42,44 @@
#include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/AbstractController.hh"
#include "params/RubySequencer.hh"
//Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q)
#define LLSC_FAIL -2 #define LLSC_FAIL -2
long int already = 0; long int already = 0;
Sequencer::Sequencer(const string & name)
:RubyPort(name) Sequencer *
RubySequencerParams::create()
{ {
m_store_waiting_on_load_cycles = 0; return new Sequencer(this);
m_store_waiting_on_store_cycles = 0;
m_load_waiting_on_store_cycles = 0;
m_load_waiting_on_load_cycles = 0;
} }
void Sequencer::init(const vector<string> & argv) Sequencer::Sequencer(const Params *p)
: RubyPort(p)
{ {
m_deadlock_check_scheduled = false; m_store_waiting_on_load_cycles = 0;
m_outstanding_count = 0; m_store_waiting_on_store_cycles = 0;
m_load_waiting_on_store_cycles = 0;
m_load_waiting_on_load_cycles = 0;
m_max_outstanding_requests = 0; m_deadlock_check_scheduled = false;
m_deadlock_threshold = 0; m_outstanding_count = 0;
m_version = -1;
m_instCache_ptr = NULL; m_max_outstanding_requests = 0;
m_dataCache_ptr = NULL; m_deadlock_threshold = 0;
m_controller = NULL; m_instCache_ptr = NULL;
for (size_t i=0; i<argv.size(); i+=2) { m_dataCache_ptr = NULL;
if ( argv[i] == "controller") {
m_controller = RubySystem::getController(argv[i+1]); // args[i] = "L1Cache" m_instCache_ptr = p->icache;
m_mandatory_q_ptr = m_controller->getMandatoryQueue(); m_dataCache_ptr = p->dcache;
} else if ( argv[i] == "icache") m_max_outstanding_requests = p->max_outstanding_requests;
m_instCache_ptr = RubySystem::getCache(argv[i+1]); m_deadlock_threshold = p->deadlock_threshold;
else if ( argv[i] == "dcache")
m_dataCache_ptr = RubySystem::getCache(argv[i+1]); assert(m_max_outstanding_requests > 0);
else if ( argv[i] == "version") assert(m_deadlock_threshold > 0);
m_version = atoi(argv[i+1].c_str()); assert(m_instCache_ptr != NULL);
else if ( argv[i] == "max_outstanding_requests") assert(m_dataCache_ptr != NULL);
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);
} }
Sequencer::~Sequencer() { Sequencer::~Sequencer() {
@ -495,7 +484,7 @@ void Sequencer::issueRequest(const RubyRequest& request) {
// Send the message to the cache controller // Send the message to the cache controller
assert(latency > 0); assert(latency > 0);
assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg, latency); m_mandatory_q_ptr->enqueue(msg, latency);
} }
/* /*

View file

@ -51,7 +51,8 @@ class DataBlock;
class CacheMsg; class CacheMsg;
class MachineID; class MachineID;
class CacheMemory; class CacheMemory;
class AbstractController;
class RubySequencerParams;
struct SequencerRequest { struct SequencerRequest {
RubyRequest ruby_request; RubyRequest ruby_request;
@ -65,11 +66,11 @@ struct SequencerRequest {
std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj); std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj);
class Sequencer : public Consumer, public RubyPort { class Sequencer : public RubyPort, public Consumer {
public: public:
typedef RubySequencerParams Params;
// Constructors // Constructors
Sequencer(const string & name); Sequencer(const Params *);
void init(const vector<string> & argv);
// Destructor // Destructor
~Sequencer(); ~Sequencer();
@ -114,13 +115,10 @@ private:
int m_max_outstanding_requests; int m_max_outstanding_requests;
int m_deadlock_threshold; int m_deadlock_threshold;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
CacheMemory* m_dataCache_ptr; CacheMemory* m_dataCache_ptr;
CacheMemory* m_instCache_ptr; CacheMemory* m_instCache_ptr;
// indicates what processor on the chip this sequencer is associated with // indicates what processor on the chip this sequencer is associated with
int m_version;
int m_controller_type; int m_controller_type;
Map<Address, SequencerRequest*> m_writeRequestTable; Map<Address, SequencerRequest*> m_writeRequestTable;

View file

@ -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'

View file

@ -47,15 +47,14 @@
#include "mem/ruby/system/Sequencer.hh" #include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/DMASequencer.hh" #include "mem/ruby/system/DMASequencer.hh"
#include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/system/MemoryVector.hh"
#include "mem/protocol/ControllerFactory.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/CacheMemory.hh" #include "mem/ruby/system/CacheMemory.hh"
#include "mem/ruby/system/DirectoryMemory.hh" #include "mem/ruby/system/DirectoryMemory.hh"
#include "mem/ruby/network/simple/Topology.hh" #include "mem/ruby/network/simple/Topology.hh"
#include "mem/ruby/network/simple/SimpleNetwork.hh" #include "mem/ruby/network/simple/SimpleNetwork.hh"
#include "mem/ruby/system/RubyPort.hh" #include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.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-fixed-pipeline/GarnetNetwork_d.hh"
#include "mem/ruby/system/MemoryControl.hh" #include "mem/ruby/system/MemoryControl.hh"
int RubySystem::m_random_seed; int RubySystem::m_random_seed;
@ -84,180 +83,32 @@ Tracer* RubySystem::m_tracer_ptr;
MemoryVector* RubySystem::m_mem_vec_ptr; MemoryVector* RubySystem::m_mem_vec_ptr;
RubySystem* RubySystem::create(const vector <RubyObjConf> & sys_conf) RubySystem::RubySystem(const Params *p)
: SimObject(p)
{ {
if (g_system_ptr == NULL) if (g_system_ptr != NULL)
return new RubySystem(sys_conf); fatal("Only one RubySystem object currently allowed.\n");
return g_system_ptr;
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<string> & 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 <RubyObjConf> & sys_conf)
{
// DEBUG_MSG(SYSTEM_COMP, MedPrio,"initializing");
for (size_t i=0;i<sys_conf.size(); i++) {
const string & type = sys_conf[i].type;
const string & name = sys_conf[i].name;
const vector<string> & 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<string> memory_control_names;
for (size_t i=0;i<sys_conf.size(); i++) {
const string & type = sys_conf[i].type;
const string & name = sys_conf[i].name;
if (type == "System" || type == "Debug")
continue;
else if (type == "SetAssociativeCache")
m_caches[name] = new CacheMemory(name);
else if (type == "DirectoryMemory")
m_directories[name] = new DirectoryMemory(name);
else if (type == "Sequencer") {
m_sequencers[name] = new Sequencer(name);
m_ports[name] = m_sequencers[name];
} else if (type == "DMASequencer") {
m_dma_sequencers[name] = new DMASequencer(name);
m_ports[name] = m_dma_sequencers[name];
} else if (type == "Topology") {
assert(m_topologies.size() == 0); // only one toplogy at a time is supported right now
m_topologies[name] = new Topology(name);
} else if (type == "SimpleNetwork") {
assert(m_network_ptr == NULL); // only one network at a time is supported right now
m_network_ptr = new SimpleNetwork(name);
} else if (type.find("generated") == 0) {
string controller_type = type.substr(10);
m_controllers[name] = ControllerFactory::createController(controller_type, name);
// printf ("ss: generated %s \n", controller_type);
//added by SS
} else if (type == "Tracer") {
//m_tracers[name] = new Tracer(name);
m_tracer_ptr = new Tracer(name);
} else if (type == "Profiler") {
m_profiler_ptr = new Profiler(name);
} else if (type == "GarnetNetwork") {
assert(m_network_ptr == NULL); // only one network at a time is supported right now
m_network_ptr = new GarnetNetwork(name);
} else if (type == "GarnetNetwork_d") {
assert(m_network_ptr == NULL); // only one network at a time is supported right now
m_network_ptr = new GarnetNetwork_d(name);
} else if (type == "MemoryControl") {
m_memorycontrols[name] = new MemoryControl(name);
memory_control_names.push_back (name);
} else {
cerr << "Error: Unknown object type -- " << type << endl;
assert(0);
}
}
for (size_t i=0;i<sys_conf.size(); i++) {
string type = sys_conf[i].type;
string name = sys_conf[i].name;
const vector<string> & argv = sys_conf[i].argv;
if (type == "Topology")
m_topologies[name]->init(argv);
}
for (size_t i=0;i<sys_conf.size(); i++) {
string type = sys_conf[i].type;
string name = sys_conf[i].name;
const vector<string> & argv = sys_conf[i].argv;
if (type == "SimpleNetwork" || type == "GarnetNetwork" || type == "GarnetNetwork_d"){
m_network_ptr->init(argv);
}
}
for (size_t i=0;i<sys_conf.size(); i++) {
string type = sys_conf[i].type;
string name = sys_conf[i].name;
const vector<string> & argv = sys_conf[i].argv;
if (type == "MemoryControl" ){
m_memorycontrols[name]->init(argv);
}
}
for (size_t i=0;i<sys_conf.size(); i++) {
string type = sys_conf[i].type;
string name = sys_conf[i].name;
const vector<string> & 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 // calculate system-wide parameters
m_memory_size_bytes = 0; m_memory_size_bytes = 0;
DirectoryMemory* prev = NULL; DirectoryMemory* prev = NULL;
@ -270,12 +121,9 @@ RubySystem::RubySystem(const vector <RubyObjConf> & sys_conf)
} }
m_mem_vec_ptr->setSize(m_memory_size_bytes); m_mem_vec_ptr->setSize(m_memory_size_bytes);
m_memory_size_bits = log_int(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() RubySystem::~RubySystem()
{ {
@ -423,5 +271,8 @@ void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) {
#endif #endif
RubySystem *
RubySystemParams::create()
{
return new RubySystem(this);
}

View file

@ -46,6 +46,8 @@
#include "mem/gems_common/Vector.hh" #include "mem/gems_common/Vector.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include <map> #include <map>
#include "sim/sim_object.hh"
#include "params/RubySystem.hh"
class Profiler; class Profiler;
class Network; class Network;
@ -84,9 +86,10 @@ struct RubyObjConf {
{} {}
}; };
class RubySystem { class RubySystem : public SimObject {
public: public:
static RubySystem* create(const vector <RubyObjConf> & sys_conf); typedef RubySystemParams Params;
RubySystem(const Params *p);
// Destructor // Destructor
~RubySystem(); ~RubySystem();
@ -152,7 +155,7 @@ private:
RubySystem(const RubySystem& obj); RubySystem(const RubySystem& obj);
RubySystem& operator=(const RubySystem& obj); RubySystem& operator=(const RubySystem& obj);
void init(const vector<string> & argv); void init();
static void printSystemConfig(ostream& out); static void printSystemConfig(ostream& out);
@ -181,6 +184,7 @@ private:
//added by SS //added by SS
//static map< string, Tracer* > m_tracers; //static map< string, Tracer* > m_tracers;
public:
static Profiler* m_profiler_ptr; static Profiler* m_profiler_ptr;
static Tracer* m_tracer_ptr; static Tracer* m_tracer_ptr;
static MemoryVector* m_mem_vec_ptr; static MemoryVector* m_mem_vec_ptr;