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
import os, optparse, sys
addToPath('../common')
addToPath('../../tests/configs/')
import ruby_config
parser = optparse.OptionParser()
@ -85,19 +83,43 @@ cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \
progress_interval=options.progress) \
for i in xrange(options.testers) ]
# create the desired simulated system
# ruby memory must be at least 16 MB to work with the mem tester
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb",
cores = options.testers,
memory_size = 16,
ports_per_cpu = 1)
system = System(cpu = cpus,
funcmem = PhysicalMemory(),
physmem = PhysicalMemory())
system = System(cpu = cpus, funcmem = PhysicalMemory(),
physmem = ruby_memory)
class L1Cache(RubyCache):
assoc = 2
latency = 3
size = 32768
for cpu in cpus:
cpu.test = system.physmem.port
cpu.functional = system.funcmem.port
class L2Cache(RubyCache):
assoc = 16
latency = 15
size = 1048576
class CrossbarTopology(Topology):
connections="hi"
for cpu in cpus:
l1_cntrl = L1Cache_Controller()
cpu_seq = RubySequencer(controller=l1_cntrl,
icache=L1Cache(controller=l1_cntrl),
dcache=L1Cache(controller=l1_cntrl))
cpu.controller = l1_cntrl
cpu.sequencer = cpu_seq
cpu.test = cpu_seq.port
cpu_seq.funcmem_port = system.physmem.port
cpu.functional = system.funcmem.port
dir_cntrl = Directory_Controller(directory=RubyDirectoryMemory(),
memory_control=RubyMemoryControl())
network = SimpleNetwork(topology=CrossbarTopology())
system.ruby = RubySystem(network = network,
profiler = RubyProfiler(),
tracer = RubyTracer(),
debug = RubyDebug())
# -----------------------

View file

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

View file

@ -72,14 +72,6 @@ def do_embed_text(target, source, env):
fin.close()
fout.close()
def EmbedText(target, source, param):
env.Command(target, [source, Value(param)], do_embed_text)
EmbedText('default_param.hh', 'config/rubyconfig.defaults',
'global_default_param')
EmbedText('tester_param.hh', 'config/tester.defaults',
'global_default_tester_param')
#
# Link includes
#

View file

@ -87,54 +87,21 @@ void changeDebugFilter(int filter)
g_debug_ptr->setFilter(filter);
}
Debug::Debug()
Debug::Debug(const Params *p)
: SimObject(p)
{
m_verbosityLevel = No_Verb;
m_starting_cycle = ~0;
clearFilter();
debug_cout_ptr = &cout;
}
Debug::Debug( const string & name, const vector<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();
debug_cout_ptr = &cout;
m_starting_cycle = filterStartTime;
if (setFilterString(filterString))
fatal("could not set filter string to %s\n", filterString);
setVerbosityString( verboseString );
setDebugOutputFile( filename );
setFilterString(p->filter_string.c_str());
setVerbosityString(p->verbosity_string.c_str());
setDebugOutputFile(p->output_filename.c_str());
m_starting_cycle = p->start_time;
m_protocol_trace = p->protocol_trace;
g_debug_ptr = this;
}
Debug::~Debug()
{
}
@ -417,3 +384,9 @@ void ERROR_OUT( const char* fmt, ... ) {
}
*/
Debug *
RubyDebugParams::create()
{
return new Debug(this);
}

View file

@ -41,6 +41,9 @@
#include "config/ruby_debug.hh"
#include "mem/ruby/common/Global.hh"
#include "sim/sim_object.hh"
#include "params/RubyDebug.hh"
extern std::ostream * debug_cout_ptr;
@ -70,13 +73,11 @@ enum DebugComponents
enum PriorityLevel {HighPrio, MedPrio, LowPrio};
enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
class Debug {
class Debug : public SimObject {
public:
// Constructors
Debug();
Debug(const std::string & name, const std::vector<std::string> & argv);
Debug( const char *filterString, const char *verboseString,
Time filterStartTime, const char *filename );
typedef RubyDebugParams Params;
Debug(const Params *p);
// Destructor
~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']:
Return()
SimObject('Debug.py')
Source('Address.cc')
Source('DataBlock.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
RubyEventQueue theEventQueue;
RubyEventQueue::RubyEventQueue()
{
m_prio_heap_ptr = NULL;
init();
assert(g_eventQueue_ptr == NULL);
g_eventQueue_ptr = this;
}
RubyEventQueue::~RubyEventQueue()

View file

@ -89,6 +89,15 @@ vector<string> tokenizeString(string str, string delims)
return tokens;
}
/*
* The current state of M5/Ruby integration breaks the libruby
* interface. This code is ifdef'd out for now so that we can move
* forward with the integration process for non-libruby uses. We'll
* have to go back and resolve the libruby compatibility issue at a
* later date.
*/
#if 0
void libruby_init(const char* cfg_filename)
{
ifstream cfg_output(cfg_filename);
@ -115,6 +124,7 @@ void libruby_init(const char* cfg_filename)
RubySystem::create(*sys_conf);
delete sys_conf;
}
#endif
RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
{

View file

@ -29,38 +29,26 @@
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/network/Network.hh"
Network::Network(const string & name)
: m_name(name)
Network::Network(const Params *p)
: SimObject(p)
{
m_virtual_networks = 0;
m_topology_ptr = NULL;
m_virtual_networks = p->number_of_virtual_networks;
m_topology_ptr = p->topology;
m_buffer_size = p->buffer_size;
m_endpoint_bandwidth = p->endpoint_bandwidth;
m_adaptive_routing = p->adaptive_routing;
m_link_latency = p->link_latency;
m_control_msg_size = p->control_msg_size;
assert(m_virtual_networks != 0);
assert(m_topology_ptr != NULL);
}
void Network::init(const vector<string> & argv)
void Network::init()
{
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;
assert(m_virtual_networks != 0);
assert(m_topology_ptr != NULL);
}
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
* All rights reserved.
@ -50,17 +49,20 @@
#include "mem/ruby/system/NodeID.hh"
#include "mem/protocol/MessageSizeType.hh"
#include "mem/ruby/system/System.hh"
#include "sim/sim_object.hh"
#include "params/RubyNetwork.hh"
class NetDest;
class MessageBuffer;
class Throttle;
class Topology;
class Network {
class Network : public SimObject {
public:
// Constructors
Network(const string & name);
virtual void init(const vector<string> & argv);
typedef RubyNetworkParams Params;
Network(const Params *p);
virtual void init();
// Destructor
virtual ~Network() {}

View file

@ -1,6 +1,4 @@
# -*- mode:python -*-
# Copyright (c) 2009 The Hewlett-Packard Development Company
# Copyright (c) 2009 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -26,10 +24,28 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
# Authors: Steve Reinhardt
# Brad Beckmann
Import('*')
from m5.params import *
from m5.SimObject import SimObject
if not env['RUBY']:
Return()
class Topology(SimObject):
type = 'Topology'
connections = Param.String("")
print_config = Param.Bool(False,
"display topology config in the stats file")
class RubyNetwork(SimObject):
type = 'RubyNetwork'
cxx_class = 'Network'
abstract = True
number_of_virtual_networks = Param.Int(10, "");
topology = Param.Topology("");
buffer_size = Param.Int(0,
"default buffer size; 0 indicates infinite buffering");
endpoint_bandwidth = Param.Int(10000, "");
adaptive_routing = Param.Bool(True, "");
link_latency = Param.Int(1,
"local memory latency ?? NetworkLinkLatency");
control_msg_size = Param.Int(8, "");

View file

@ -33,4 +33,6 @@ Import('*')
if not env['RUBY']:
Return()
SimObject('Network.py')
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);

View file

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

View file

@ -30,6 +30,9 @@
Import('*')
# temporarily disable
Return()
if not env['RUBY']:
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");
Network::init(argv);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -73,6 +73,8 @@
#include "mem/gems_common/Vector.hh"
#include "mem/ruby/network/Network.hh"
#include "mem/ruby/system/NodeID.hh"
#include "sim/sim_object.hh"
#include "params/SimpleNetwork.hh"
class NetDest;
class MessageBuffer;
@ -83,13 +85,13 @@ class Topology;
class SimpleNetwork : public Network {
public:
// Constructors
// SimpleNetwork(int nodes);
SimpleNetwork(const string & name);
typedef SimpleNetworkParams Params;
SimpleNetwork(const Params *p);
// Destructor
~SimpleNetwork();
void init(const vector<string> & argv);
void init();
// Public Methods
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 NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights, const Matrix& dist);
Topology::Topology(const string & name)
: m_name(name)
Topology::Topology(const Params *p)
: SimObject(p)
{
m_network_ptr = NULL;
// m_network_ptr = p->network;
m_connections = p->connections;
m_print_config = p->print_config;
m_nodes = MachineType_base_number(MachineType_NUM);
m_number_of_switches = 0;
}
void Topology::init(const vector<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()
@ -457,3 +449,8 @@ static NetDest shortest_path_to_node(SwitchID src, SwitchID next,
return result;
}
Topology *
TopologyParams::create()
{
return new Topology(this);
}

View file

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

View file

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

View file

@ -63,6 +63,8 @@
#include "mem/ruby/common/Debug.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/system/System.hh"
// Allows use of times() library call, which determines virtual runtime
#include <sys/times.h>
@ -71,9 +73,9 @@ extern std::ostream * debug_cout_ptr;
static double process_memory_total();
static double process_memory_resident();
Profiler::Profiler(const string & name)
Profiler::Profiler(const Params *p)
: SimObject(p)
{
m_name = name;
m_requestProfileMap_ptr = new Map<string, int>;
m_inst_profiler_ptr = NULL;
@ -83,6 +85,10 @@ Profiler::Profiler(const string & name)
m_stats_period = 1000000; // Default
m_periodic_output_file_ptr = &cerr;
m_hot_lines = p->hot_lines;
m_all_instructions = p->all_instructions;
RubySystem::m_profiler_ptr = this;
}
Profiler::~Profiler()
@ -136,17 +142,6 @@ void Profiler::init(const vector<string> & argv, vector<string> memory_control_n
m_hot_lines = 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 -> setHotLines(m_hot_lines);
m_address_profiler_ptr -> setAllInstructions(m_all_instructions);
@ -849,3 +844,9 @@ void Profiler::profileMemArbWait(string name, int cycles) { assert(m_memory_co
void Profiler::profileMemRandBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRandBusy++; }
void Profiler::profileMemNotOld(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memNotOld++; }
Profiler *
RubyProfilerParams::create()
{
return new Profiler(this);
}

View file

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

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']:
Return()
SimObject('Profiler.py')
Source('AccessTraceForAddress.cc')
Source('AddressProfiler.cc')
Source('CacheProfiler.cc')

View file

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

View file

@ -39,10 +39,13 @@
#include "mem/ruby/system/System.hh"
//added by SS
Tracer::Tracer(const string & name)
Tracer::Tracer(const Params *p)
: SimObject(p)
{
m_name = name;
m_enabled = false;
m_warmup_length = p->warmup_length;
assert(m_warmup_length > 0);
RubySystem::m_tracer_ptr = this;
}
//commented by SS
@ -55,20 +58,8 @@ Tracer::~Tracer()
{
}
void Tracer::init(const vector<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)
@ -155,3 +146,10 @@ int Tracer::playbackTrace(string filename)
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/system/NodeID.hh"
#include "mem/protocol/CacheRequestType.hh"
#include "sim/sim_object.hh"
#include "params/RubyTracer.hh"
#include "gzstream.hh"
template <class TYPE> class PrioHeap;
class Address;
class TraceRecord;
class Tracer {
class Tracer : public SimObject {
public:
// Constructors
// Tracer();
Tracer(const string & name);
typedef RubyTracerParams Params;
Tracer(const Params *p);
// Destructor
~Tracer();
@ -68,7 +73,7 @@ public:
// Public Class Methods
int playbackTrace(string filename);
void init(const vector<string> & argv);
void init();
private:
// Private Methods
@ -82,7 +87,6 @@ private:
//added by SS
int m_warmup_length;
string m_name;
};
// 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
#define ABSTRACTCONTROLLER_H
#include "sim/sim_object.hh"
#include "params/RubyController.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/common/Address.hh"
@ -9,9 +12,10 @@
class MessageBuffer;
class Network;
class AbstractController : public Consumer {
class AbstractController : public SimObject, public Consumer {
public:
AbstractController() {}
typedef RubyControllerParams Params;
AbstractController(const Params *p) : SimObject(p) {}
virtual void init(Network* net_ptr, const vector<string> & argv) = 0;
// 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']:
Return()
SimObject('Controller.py')
Source('AbstractCacheEntry.cc')
Source('RubySlicc_Profiler_interface.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)
: m_cache_name(name)
CacheMemory *
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;
string policy;
m_num_last_level_caches =
MachineType_base_count(MachineType_FIRST);
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 cache_size = p->size;
m_latency = p->latency;
m_cache_assoc = p->assoc;
string policy = p->replacement_policy;
m_controller = p->controller;
int num_lines = cache_size/RubySystem::getBlockSizeBytes();
m_cache_num_sets = num_lines / m_cache_assoc;
@ -95,6 +74,24 @@ void CacheMemory::init(const vector<string> & argv)
else
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_locked.setSize(m_cache_num_sets);
for (int i = 0; i < m_cache_num_sets; i++) {

View file

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

View file

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

View file

@ -46,29 +46,17 @@ int DirectoryMemory::m_num_directories = 0;
int DirectoryMemory::m_num_directories_bits = 0;
uint64_t DirectoryMemory::m_total_size_bytes = 0;
DirectoryMemory::DirectoryMemory(const string & name)
: m_name(name)
DirectoryMemory::DirectoryMemory(const Params *p)
: SimObject(p)
{
m_version = p->version;
m_size_bytes = p->size_mb * static_cast<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_entries = new Directory_Entry*[m_num_entries];
for (int i=0; i < m_num_entries; i++)
@ -205,3 +193,8 @@ void DirectoryMemory::print(ostream& out) const
}
DirectoryMemory *
RubyDirectoryMemoryParams::create()
{
return new DirectoryMemory(this);
}

View file

@ -43,14 +43,17 @@
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/protocol/Directory_Entry.hh"
#include "sim/sim_object.hh"
#include "params/RubyDirectoryMemory.hh"
class AbstractController;
class DirectoryMemory {
class DirectoryMemory : public SimObject {
public:
// Constructors
DirectoryMemory(const string & name);
void init(const vector<string> & argv);
typedef RubyDirectoryMemoryParams Params;
DirectoryMemory(const Params *p);
void init();
// DirectoryMemory(int version);
// 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
MemoryControl::MemoryControl(const string & name)
: m_name(name)
MemoryControl::MemoryControl(const Params *p)
: SimObject(p)
{
m_name = name;
// printf ("MemoryControl name is %s \n", m_name.c_str());
m_mem_bus_cycle_multiplier = p->mem_bus_cycle_multiplier;
m_banks_per_rank = p->banks_per_rank;
m_ranks_per_dimm = p->ranks_per_dimm;
m_dimms_per_channel = p->dimms_per_channel;
m_bank_bit_0 = p->bank_bit_0;
m_rank_bit_0 = p->rank_bit_0;
m_dimm_bit_0 = p->dimm_bit_0;
m_bank_queue_size = p->bank_queue_size;
m_bank_busy_time = p->bank_busy_time;
m_rank_rank_delay = p->rank_rank_delay;
m_read_write_delay = p->read_write_delay;
m_basic_bus_busy_time = p->basic_bus_busy_time;
m_mem_ctl_latency = p->mem_ctl_latency;
m_refresh_period = p->refresh_period;
m_tFaw = p->tFaw;
m_mem_random_arbitrate = p->mem_random_arbitrate;
m_mem_fixed_delay = p->mem_fixed_delay;
}
void MemoryControl::init(const vector<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_debug = 0;
@ -351,7 +320,6 @@ void MemoryControl::print (ostream& out) const {
void MemoryControl::printConfig (ostream& out) {
out << "Memory Control " << m_version << ":" << endl;
out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl;
out << " Basic read latency: " << m_mem_ctl_latency << endl;
if (m_mem_fixed_delay) {
@ -662,4 +630,9 @@ void MemoryControl::wakeup () {
}
}
MemoryControl *
RubyMemoryControlParams::create()
{
return new MemoryControl(this);
}

View file

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

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/slicc_interface/AbstractController.hh"
//void (*RubyPort::m_hit_callback)(int64_t) = NULL;
uint16_t RubyPort::m_num_ports = 0;
RubyPort::RubyPort(const Params *p)
: MemObject(p)
{
m_version = p->version;
assert(m_version != -1);
m_controller = p->controller;
assert(m_controller != NULL);
m_mandatory_q_ptr = m_controller->getMandatoryQueue();
m_port_id = m_num_ports++;
m_request_cnt = 0;
m_hit_callback = NULL;
assert(m_num_ports <= 2048); // see below for reason
}
Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
return NULL;
}

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

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']:
Return()
SimObject('Cache.py')
SimObject('Sequencer.py')
SimObject('DirectoryMemory.py')
SimObject('MemoryControl.py')
SimObject('RubySystem.py')
Source('DMASequencer.cc')
Source('DirectoryMemory.cc')
Source('CacheMemory.cc')

View file

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

View file

@ -51,7 +51,8 @@ class DataBlock;
class CacheMsg;
class MachineID;
class CacheMemory;
class AbstractController;
class RubySequencerParams;
struct SequencerRequest {
RubyRequest ruby_request;
@ -65,11 +66,11 @@ struct SequencerRequest {
std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj);
class Sequencer : public Consumer, public RubyPort {
class Sequencer : public RubyPort, public Consumer {
public:
typedef RubySequencerParams Params;
// Constructors
Sequencer(const string & name);
void init(const vector<string> & argv);
Sequencer(const Params *);
// Destructor
~Sequencer();
@ -114,13 +115,10 @@ private:
int m_max_outstanding_requests;
int m_deadlock_threshold;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
CacheMemory* m_dataCache_ptr;
CacheMemory* m_instCache_ptr;
// indicates what processor on the chip this sequencer is associated with
int m_version;
int m_controller_type;
Map<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/DMASequencer.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/protocol/ControllerFactory.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/CacheMemory.hh"
#include "mem/ruby/system/DirectoryMemory.hh"
#include "mem/ruby/network/simple/Topology.hh"
#include "mem/ruby/network/simple/SimpleNetwork.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
//#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
//#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
#include "mem/ruby/system/MemoryControl.hh"
int RubySystem::m_random_seed;
@ -84,180 +83,32 @@ Tracer* RubySystem::m_tracer_ptr;
MemoryVector* RubySystem::m_mem_vec_ptr;
RubySystem* RubySystem::create(const vector <RubyObjConf> & sys_conf)
RubySystem::RubySystem(const Params *p)
: SimObject(p)
{
if (g_system_ptr == NULL)
return new RubySystem(sys_conf);
return g_system_ptr;
if (g_system_ptr != NULL)
fatal("Only one RubySystem object currently allowed.\n");
m_random_seed = p->random_seed;
srandom(m_random_seed);
m_randomization = p->randomization;
m_tech_nm = p->tech_nm;
m_freq_mhz = p->freq_mhz;
m_block_size_bytes = p->block_size_bytes;
assert(is_power_of_2(m_block_size_bytes));
m_block_size_bits = log_int(m_block_size_bytes);
m_network_ptr = p->network;
g_debug_ptr = p->debug;
m_profiler_ptr = p->profiler;
m_tracer_ptr = p->tracer;
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;
}
void RubySystem::init(const vector<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
m_memory_size_bytes = 0;
DirectoryMemory* prev = NULL;
@ -270,12 +121,9 @@ RubySystem::RubySystem(const vector <RubyObjConf> & sys_conf)
}
m_mem_vec_ptr->setSize(m_memory_size_bytes);
m_memory_size_bits = log_int(m_memory_size_bytes);
// m_tracer_ptr = new Tracer;
DEBUG_MSG(SYSTEM_COMP, MedPrio,"finished initializing");
DEBUG_NEWLINE(SYSTEM_COMP, MedPrio);
}
RubySystem::~RubySystem()
{
@ -423,5 +271,8 @@ void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) {
#endif
RubySystem *
RubySystemParams::create()
{
return new RubySystem(this);
}

View file

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