Discussion:
[PATCH 00 of 30] Unified GEM5 Configuration and Event Queue
(too old to reply)
Brad Beckmann
2009-12-12 22:37:28 UTC
Permalink
Here are the patches that will unify configuration and the event queue between ruby and M5. Please let me know if you have any comments and/or suggestions for improvement.

Brad
Brad Beckmann
2009-12-12 22:37:48 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID d0e96be22141976017c9d11e942be11587b8e4e2
# Parent cae9a08951751d7556ee4cc37a29824e23848b65
ruby: cleaned up Ruby debug defaults

diff -r cae9a0895175 -r d0e96be22141 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
@@ -187,9 +187,9 @@
network = network,
profiler = ruby_profiler,
tracer = RubyTracer(),
- debug = RubyDebug(),#filter_string = 'qQin',
- #verbosity_string = 'high',
- #protocol_trace = True),
+ debug = RubyDebug(filter_string = 'none',
+ verbosity_string = 'none',
+ protocol_trace = False),
mem_size_mb = mem_size_mb)
nathan binkert
2009-12-21 22:02:15 UTC
Permalink
Please just fold this into the patch where it was incorrectly added.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657436 28800
# Node ID d0e96be22141976017c9d11e942be11587b8e4e2
# Parent  cae9a08951751d7556ee4cc37a29824e23848b65
ruby: cleaned up Ruby debug defaults
diff -r cae9a0895175 -r d0e96be22141 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:16 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:16 2009 -0800
@@ -187,9 +187,9 @@
                         network = network,
                         profiler = ruby_profiler,
                         tracer = RubyTracer(),
-                         debug = RubyDebug(),#filter_string = 'qQin',
-                                           #verbosity_string = 'high',
-                                           #protocol_trace = True),
+                         debug = RubyDebug(filter_string = 'none',
+                                           verbosity_string = 'none',
+                                           protocol_trace = False),
                         mem_size_mb = mem_size_mb)
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:55 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID 3c00a365603e5724aea9b87b4b730839ef78139a
# Parent efe0dabd91852d85b6301852dd9737fa5e8ee2f1
ruby: Removed the passing of dma sequencer
The dma sequencer doesn't need to be passed between ruby config files, so
it is removed.

diff -r efe0dabd9185 -r 3c00a365603e configs/ruby/MOESI_hammer.py
--- a/configs/ruby/MOESI_hammer.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/ruby/MOESI_hammer.py Sat Dec 12 14:37:17 2009 -0800
@@ -47,8 +47,7 @@
if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be built.")

- sequencers_map = {"cpu": [],
- "dma": []}
+ cpu_sequencers = []

#
# The ruby network creation expects the list of nodes in the system to be
@@ -93,7 +92,7 @@
#
# Add controllers and sequencers to the appropriate lists
#
- sequencers_map["cpu"].append(cpu_seq)
+ cpu_sequencers.append(cpu_seq)
l1_cntrl_nodes.append(l1_cntrl)

for i in xrange(options.num_dirs):
@@ -122,8 +121,7 @@

dma_cntrl.dma_sequencer.port = dma_device.dma
dma_cntrl_nodes.append(dma_cntrl)
- sequencers_map["dma"].append(dma_seq)

all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes

- return (sequencers_map, dir_cntrl_nodes, all_cntrls)
+ return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
diff -r efe0dabd9185 -r 3c00a365603e configs/ruby/Ruby.py
--- a/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
@@ -34,13 +34,16 @@

import MOESI_hammer

-def create_system(options, physmem):
+def create_system(options, physmem, piobus = None, dma_devices = []):

protocol = buildEnv['PROTOCOL']

if protocol == "MOESI_hammer":
- (sequencers, dir_cntrls, all_cntrls) = MOESI_hammer.create_system( \
- options, physmem)
+ (cpu_sequencers, dir_cntrls, all_cntrls) = \
+ MOESI_hammer.create_system(options, \
+ physmem, \
+ piobus, \
+ dma_devices)
else:
print "Error: unsupported ruby protocol"
sys.exit(1)
@@ -77,6 +80,6 @@
protocol_trace = False),
mem_size_mb = mem_size_mb)

- ruby.cpu_ruby_ports = sequencers
+ ruby.cpu_ruby_ports = cpu_sequencers

return ruby
Brad Beckmann
2009-12-12 22:37:30 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657434 28800
# Node ID 5d3a90f0ef4c0f69f61fd262028a32fa5e632f8e
# Parent 8f73bf7c3c5e9d1cd8573b6db7975fefc9bda613
ruby: Make SLICC-generated objects SimObjects.
Add SLICC support for state-machine parameter defaults
(passed through to Python as SimObject Param defaults).

diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/protocol/MOESI_hammer-cache.sm
--- a/src/mem/protocol/MOESI_hammer-cache.sm Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-cache.sm Sat Dec 12 14:37:14 2009 -0800
@@ -34,8 +34,8 @@
*/

machine(L1Cache, "AMD Hammer-like protocol")
-: int cache_response_latency,
- int issue_latency
+: int cache_response_latency = 12,
+ int issue_latency = 2
{

// NETWORK BUFFERS
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/protocol/MOESI_hammer-dir.sm
--- a/src/mem/protocol/MOESI_hammer-dir.sm Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-dir.sm Sat Dec 12 14:37:14 2009 -0800
@@ -34,7 +34,7 @@
*/

machine(Directory, "AMD Hammer-like protocol")
-: int memory_controller_latency
+: int memory_controller_latency = 12
{

MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false";
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/protocol/MOESI_hammer-dma.sm
--- a/src/mem/protocol/MOESI_hammer-dma.sm Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-dma.sm Sat Dec 12 14:37:14 2009 -0800
@@ -28,7 +28,7 @@


machine(DMA, "DMA Controller")
-: int request_latency
+: int request_latency = 6
{

MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true";
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/protocol/SConscript
--- a/src/mem/protocol/SConscript Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/protocol/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -70,6 +70,29 @@
print " %s" % name

target.extend(sorted(slicc.files()))
+ pdir = str(protocol_dir)
+ hdir = str(html_dir)
+
+ if not isdir(pdir):
+ os.mkdir(pdir)
+ if not isdir(hdir):
+ os.mkdir(hdir)
+
+ slicc = SLICC(debug=True)
+ files = [str(s) for s in source[1:]]
+ slicc.load(files, verbose=False)
+
+ print "SLICC Generator pass 1..."
+ slicc.findMachines()
+
+ print "SLICC Generator pass 2..."
+ slicc.generate()
+
+ print "SLICC writing C++ files..."
+ slicc.writeCodeFiles(pdir)
+
+ print "SLICC writing HTML files..."
+ slicc.writeHTMLFiles(hdir)
return target, source

def slicc_action(target, source, env):
@@ -108,5 +131,10 @@
nodes = env.SLICC([], [ Value(protocol) ] + sources)
env.Depends(nodes, slicc_depends)

-for f in sorted(s for s in nodes if str(s).endswith('.cc')):
- Source(f)
+for f in nodes:
+ s = str(f)
+ if str(s).endswith('.cc'):
+ Source(f)
+ elif str(s).endswith('.py'):
+ SimObject(f)
+
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/ast/FormalParamAST.py
--- a/src/mem/slicc/ast/FormalParamAST.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/ast/FormalParamAST.py Sat Dec 12 14:37:14 2009 -0800
@@ -29,10 +29,11 @@
from slicc.symbols import Var

class FormalParamAST(AST):
- def __init__(self, slicc, type_ast, ident):
+ def __init__(self, slicc, type_ast, ident, default = None):
super(FormalParamAST, self).__init__(slicc)
self.type_ast = type_ast
self.ident = ident
+ self.default = default

def __repr__(self):
return "[FormalParamAST: %s]" % self.ident
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/ast/MachineAST.py
--- a/src/mem/slicc/ast/MachineAST.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/ast/MachineAST.py Sat Dec 12 14:37:14 2009 -0800
@@ -43,6 +43,7 @@
def files(self, parent=None):
s = set(('%s_Controller.cc' % self.ident,
'%s_Controller.hh' % self.ident,
+ '%s_Controller.py' % self.ident,
'%s_Profiler.cc' % self.ident,
'%s_Profiler.hh' % self.ident,
'%s_Transitions.cc' % self.ident,
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/parser.py
--- a/src/mem/slicc/parser.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/parser.py Sat Dec 12 14:37:14 2009 -0800
@@ -115,8 +115,6 @@

def files(self):
f = set([
- 'ControllerFactory.cc',
- 'ControllerFactory.hh',
'MachineType.cc',
'MachineType.hh',
'Types.hh' ])
@@ -418,6 +416,10 @@
"param : type ident"
p[0] = ast.FormalParamAST(self, p[1], p[2])

+ def p_param__default(self, p):
+ "param : type ident '=' NUMBER"
+ p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
+
# Idents and lists
def p_idents__braced(self, p):
"idents : '{' identx '}'"
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:14 2009 -0800
@@ -124,6 +124,7 @@
self.table = table

def writeCodeFiles(self, path):
+ self.printControllerPython(path)
self.printControllerHH(path)
self.printControllerCC(path)
self.printCSwitch(path)
@@ -134,6 +135,29 @@
for func in self.functions:
func.writeCodeFiles(path)

+ def printControllerPython(self, path):
+ code = code_formatter()
+ ident = self.ident
+ py_ident = "%s_Controller" % ident
+ c_ident = "%s_Controller" % self.ident
+ code('''
+from m5.params import *
+from m5.SimObject import SimObject
+from Controller import RubyController
+
+class $py_ident(RubyController):
+ type = '$py_ident'
+''')
+ code.indent()
+ for param in self.config_parameters:
+ dflt_str = ''
+ if param.default is not None:
+ dflt_str = str(param.default) + ', '
+ code('${{param.name}} = Param.Int(${dflt_str}"")')
+ code.dedent()
+ code.write(path, '%s.py' % py_ident)
+
+
def printControllerHH(self, path):
'''Output the method declarations for the class declaration'''
code = code_formatter()
@@ -152,6 +176,8 @@
#ifndef ${ident}_CONTROLLER_H
#define ${ident}_CONTROLLER_H

+#include "params/$c_ident.hh"
+
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
@@ -174,7 +200,8 @@
#ifdef CHECK_COHERENCE
#endif /* CHECK_COHERENCE */
public:
- $c_ident(const string & name);
+ typedef ${c_ident}Params Params;
+ $c_ident(const Params *p);
static int getNumControllers();
void init(Network* net_ptr, const vector<string> & argv);
MessageBuffer* getMandatoryQueue() const;
@@ -288,16 +315,30 @@
seen_types.add(var.type.ident)

code('''
+$c_ident *
+${c_ident}Params::create()
+{
+ return new $c_ident(this);
+}
+
+
int $c_ident::m_num_controllers = 0;

stringstream ${ident}_transitionComment;
#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
/** \\brief constructor */
-$c_ident::$c_ident(const string &name)
- : m_name(name)
+$c_ident::$c_ident(const Params *p)
+ : AbstractController(p)
{
+ m_version = p->version;
+ m_transitions_per_cycle = p->transitions_per_cycle;
+ m_buffer_size = p->buffer_size;
+ m_recycle_latency = p->recycle_latency;
+ m_number_of_TBEs = p->number_of_TBEs;
''')
code.indent()
+ for param in self.config_parameters:
+ code('m_${{param.name}} = p->${{param.name}};')
if self.ident == "L1Cache":
code('''
servicing_atomic = 0;
@@ -320,35 +361,6 @@

void $c_ident::init(Network *net_ptr, const vector<string> &argv)
{
- for (size_t i = 0; i < argv.size(); i += 2) {
- if (argv[i] == "version")
- m_version = atoi(argv[i+1].c_str());
- else if (argv[i] == "transitions_per_cycle")
- m_transitions_per_cycle = atoi(argv[i+1].c_str());
- else if (argv[i] == "buffer_size")
- m_buffer_size = atoi(argv[i+1].c_str());
- else if (argv[i] == "recycle_latency")
- m_recycle_latency = atoi(argv[i+1].c_str());
- else if (argv[i] == "number_of_TBEs")
- m_number_of_TBEs = atoi(argv[i+1].c_str());
-''')
-
- code.indent()
- code.indent()
- for param in self.config_parameters:
- code('else if (argv[i] == "${{param.name}}")')
- if param.type_ast.type.ident == "int":
- code(' m_${{param.name}} = atoi(argv[i+1].c_str());')
- elif param.type_ast.type.ident == "bool":
- code(' m_${{param.name}} = string_to_bool(argv[i+1]);')
- else:
- self.error("only int and bool parameters are "\
- "currently supported")
- code.dedent()
- code.dedent()
- code('''
- }
-
m_net_ptr = net_ptr;
m_machineID.type = MachineType_${ident};
m_machineID.num = m_version;
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/symbols/SymbolTable.py
--- a/src/mem/slicc/symbols/SymbolTable.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/symbols/SymbolTable.py Sat Dec 12 14:37:14 2009 -0800
@@ -133,63 +133,6 @@
for symbol in self.sym_vec:
symbol.writeCodeFiles(path)

- self.writeControllerFactory(path)
-
- def writeControllerFactory(self, path):
- code = code_formatter()
-
- code('''
-/** \\file ControllerFactory.hh
- * Auto generatred C++ code started by $__file__:$__line__
- */
-
-#ifndef CONTROLLERFACTORY_H
-#define CONTROLLERFACTORY_H
-
-#include <string>
-class Network;
-class AbstractController;
-
-class ControllerFactory {
- public:
- static AbstractController *createController(const std::string &controller_type, const std::string &name);
-};
-#endif // CONTROLLERFACTORY_H''')
- code.write(path, "ControllerFactory.hh")
-
- code = code_formatter()
- code('''
-/** \\file ControllerFactory.cc
- * Auto generatred C++ code started by $__file__:$__line__
- */
-
-#include "mem/protocol/ControllerFactory.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "mem/protocol/MachineType.hh"
-''')
-
- controller_types = []
- for symbol in self.getAllType(StateMachine):
- code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"')
- controller_types.append(symbol.ident)
-
- code('''
-AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) {
-''')
-
- for ct in controller_types:
- code('''
- if (controller_type == "$ct")
- return new ${ct}_Controller(name);
-''')
-
- code('''
- assert(0); // invalid controller type
- return NULL;
-}
-''')
- code.write(path, "ControllerFactory.cc")
-
def writeHTMLFiles(self, path):
machines = list(self.getAllType(StateMachine))
if len(machines) > 1:
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/symbols/Type.py
--- a/src/mem/slicc/symbols/Type.py Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/symbols/Type.py Sat Dec 12 14:37:14 2009 -0800
@@ -476,7 +476,6 @@
''')

if self.isMachineType:
- code('#include "mem/protocol/ControllerFactory.hh"')
for enum in self.enums.itervalues():
code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
nathan binkert
2009-12-21 20:35:07 UTC
Permalink
Comments inline
Post by Brad Beckmann
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/protocol/SConscript
--- a/src/mem/protocol/SConscript       Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/protocol/SConscript       Sat Dec 12 14:37:14 2009 -0800
+    s = str(f)
+        Source(f)
+        SimObject(f)
+
You don't need the str(s) since s is already a string.
Post by Brad Beckmann
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/parser.py
--- a/src/mem/slicc/parser.py   Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/parser.py   Sat Dec 12 14:37:14 2009 -0800
@@ -418,6 +416,10 @@
        "param : type ident"
        p[0] = ast.FormalParamAST(self, p[1], p[2])
+        "param : type ident '=' NUMBER"
+        p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
+
    # Idents and lists
        "idents : '{' identx '}'"
This syntax is getting odd. I'm not sure if it's worthing changing at
this point, but organic growth of a language can make it look ugly
over time.
Steve Reinhardt
2010-01-04 22:11:15 UTC
Permalink
Post by Brad Beckmann
diff -r 8f73bf7c3c5e -r 5d3a90f0ef4c src/mem/slicc/parser.py
--- a/src/mem/slicc/parser.py   Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/slicc/parser.py   Sat Dec 12 14:37:14 2009 -0800
@@ -418,6 +416,10 @@
        "param : type ident"
        p[0] = ast.FormalParamAST(self, p[1], p[2])
+        "param : type ident '=' NUMBER"
+        p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
+
    # Idents and lists
        "idents : '{' identx '}'"
This syntax is getting odd.  I'm not sure if it's worthing changing at
this point, but organic growth of a language can make it look ugly
over time.
I don't follow... are you complaining about the syntax we're
introducing, or the way we're parsing it? In this particular case,
the syntax seems straightforward to me, as we're just extending the
state-machine parameter block to allow defaults, e.g., 'int
buffer_size = 10'. There's a minor oddity in that the default value
has to be an integer for now, regardless of the type of the parameter,
but we can check that for consistency elsewhere. (Right now it falls
through into the generated Python, so you won't get the type error
until later than necessary.) We can extend it to allow more general
defaults as needed.

Steve
nathan binkert
2010-01-04 22:26:35 UTC
Permalink
Post by Steve Reinhardt
I don't follow... are you complaining about the syntax we're
introducing, or the way we're parsing it?  In this particular case,
the syntax seems straightforward to me, as we're just extending the
state-machine parameter block to allow defaults, e.g., 'int
buffer_size = 10'.  There's a minor oddity in that the default value
has to be an integer for now, regardless of the type of the parameter,
but we can check that for consistency elsewhere.  (Right now it falls
through into the generated Python, so you won't get the type error
until later than necessary.)  We can extend it to allow more general
defaults as needed.
I guess it seemed that the language seemed to try to be C++ like so as
to be familiar to people. The expression that you've added is C-like,
but the larger expression that it is part of seems to do member
initialization very strangely. Then again, this is both a declaration
and a definition, so perhaps it is unavoidable.

Doesn't matter much to me.

Nate
Steve Reinhardt
2010-01-04 22:32:57 UTC
Permalink
Post by nathan binkert
Post by Steve Reinhardt
I don't follow... are you complaining about the syntax we're
introducing, or the way we're parsing it?  In this particular case,
the syntax seems straightforward to me, as we're just extending the
state-machine parameter block to allow defaults, e.g., 'int
buffer_size = 10'.  There's a minor oddity in that the default value
has to be an integer for now, regardless of the type of the parameter,
but we can check that for consistency elsewhere.  (Right now it falls
through into the generated Python, so you won't get the type error
until later than necessary.)  We can extend it to allow more general
defaults as needed.
I guess it seemed that the language seemed to try to be C++ like so as
to be familiar to people.  The expression that you've added is C-like,
but the larger expression that it is part of seems to do member
initialization very strangely.  Then again, this is both a declaration
and a definition, so perhaps it is unavoidable.
Doesn't matter much to me.
So you were thinking it should be 'int buffer_size(10)'?

I thought I was doing well to use '=' and not ':=' :-)

Steve
nathan binkert
2010-01-04 22:37:56 UTC
Permalink
Post by Steve Reinhardt
So you were thinking it should be 'int buffer_size(10)'?
No. This is what I was getting at about organic growth. I think = is
the natural choice given what is there, but if we were to try to start
with a fresh language that tried to be C++-like, I'm not sure we would
have gotten down this path. That said, I don't use the language and
I'm not clear that being C++-like buys that much.
Post by Steve Reinhardt
I thought I was doing well to use '=' and not ':=' :-)
:= and = have become very confused. Is there a real semantic
difference, or is it simply that some syntax uses = while other syntax
uses :=.

Nate
Steve Reinhardt
2010-01-04 23:10:56 UTC
Permalink
Post by Steve Reinhardt
So you were thinking it should be 'int buffer_size(10)'?
No.  This is what I was getting at about organic growth.  I think = is
the natural choice given what is there, but if we were to try to start
with a fresh language that tried to be C++-like, I'm not sure we would
have gotten down this path.  That said, I don't use the language and
I'm not clear that being C++-like buys that much.
I never thought of SLICC as being C++-like any more than C-like or
Java-like or in some cases Pascal-like (or wherever that ':='
assignment operator came from), so I guess I didn't see any
inconsistency.
Post by Steve Reinhardt
I thought I was doing well to use '=' and not ':=' :-)
:= and = have become very confused.   Is there a real semantic
difference, or is it simply that some syntax uses = while other syntax
uses :=.
I believe there's a real difference, though I won't argue that it's a
very useful one. As far as I can tell, := is the imperative
assignment operator, while = is used just about everywhere else
(including associating values with attributes in declarations).

Anyway, as long as SLICCer is still on the horizon, I'm going to hold
off on worrying about syntactic improvements until then.

Steve
Brad Beckmann
2009-12-12 22:37:40 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 856ecd55b3729ea5f083b76bc4750a29b008b707
# Parent 8b7cf38ad6de8a71ddcc3044abab28c7ec0d2599
ruby: Converted the sequencer deadlock event to m5 eventq

diff -r 8b7cf38ad6de -r 856ecd55b372 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:15 2009 -0800
@@ -60,9 +60,9 @@


Sequencer::Sequencer(const Params *p)
- : RubyPort(p)
+ : RubyPort(p), deadlockCheckEvent(this)
{
- m_deadlock_check_scheduled = false;
+ //m_deadlock_check_scheduled = false;
m_outstanding_count = 0;

m_max_outstanding_requests = 0;
@@ -128,10 +128,11 @@
assert(m_outstanding_count == total_outstanding);

if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
- g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
- } else {
- m_deadlock_check_scheduled = false;
- }
+ schedule(deadlockCheckEvent, m_deadlock_threshold);
+ //g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
+ } // else {
+// m_deadlock_check_scheduled = false;
+// }
}

void Sequencer::printProgress(ostream& out) const{
@@ -190,10 +191,13 @@
assert(m_outstanding_count == total_outstanding);

// See if we should schedule a deadlock check
- if (m_deadlock_check_scheduled == false) {
- g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
- m_deadlock_check_scheduled = true;
+ if (deadlockCheckEvent.scheduled() == false) {
+ schedule(deadlockCheckEvent, m_deadlock_threshold);
}
+// if (m_deadlock_check_scheduled == false) {
+// g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
+// m_deadlock_check_scheduled = true;
+// }

Address line_addr(request->ruby_request.paddr);
line_addr.makeLineAddress();
diff -r 8b7cf38ad6de -r 856ecd55b372 src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
@@ -124,6 +124,18 @@
bool m_deadlock_check_scheduled;
int m_servicing_atomic;
int m_atomics_counter;
+
+ class SequencerWakeupEvent : public Event
+ {
+ Sequencer *m_sequencer_ptr;
+
+ public:
+ SequencerWakeupEvent(Sequencer *_seq) : m_sequencer_ptr(_seq) {}
+ void process() { m_sequencer_ptr->wakeup(); }
+ const char *description() const { return "Sequencer deadlock check"; }
+ };
+
+ SequencerWakeupEvent deadlockCheckEvent;
};

// Output operator declaration
@@ -140,5 +152,6 @@
return out;
}

+
#endif //SEQUENCER_H
nathan binkert
2009-12-21 21:17:13 UTC
Permalink
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID 856ecd55b3729ea5f083b76bc4750a29b008b707
# Parent  8b7cf38ad6de8a71ddcc3044abab28c7ec0d2599
ruby: Converted the sequencer deadlock event to m5 eventq
diff -r 8b7cf38ad6de -r 856ecd55b372 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:15 2009 -0800
-    m_deadlock_check_scheduled = false;
+  //m_deadlock_check_scheduled = false;
delete, not comment.
Post by Brad Beckmann
+    schedule(deadlockCheckEvent, m_deadlock_threshold);
+    //g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
+  } // else {
+//     m_deadlock_check_scheduled = false;
+//   }
 }
delete
Post by Brad Beckmann
+//   if (m_deadlock_check_scheduled == false) {
+//     g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
+//     m_deadlock_check_scheduled = true;
+//   }
delete
Post by Brad Beckmann
@@ -140,5 +152,6 @@
  return out;
 }
+
Don't add random whitespace.
Brad Beckmann
2009-12-12 22:37:34 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 1788fb1fa57c0b95f0ec58b991cbb503a98c276c
# Parent d5c731012d722a9b54373ed45600e9e978001ea9
ruby: Hook up network queues to SLICC-generated state machines.

diff -r d5c731012d72 -r 1788fb1fa57c src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh Sat Dec 12 14:37:15 2009 -0800
@@ -16,7 +16,6 @@
public:
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
// virtual int getNumberOfControllers() const = 0;
diff -r d5c731012d72 -r 1788fb1fa57c src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
@@ -203,7 +203,7 @@
typedef ${c_ident}Params Params;
$c_ident(const Params *p);
static int getNumControllers();
- void init(Network* net_ptr, const vector<string> & argv);
+ void init();
MessageBuffer* getMandatoryQueue() const;
const int & getVersion() const;
const string toString() const;
@@ -359,7 +359,7 @@
code('''
}

-void $c_ident::init(Network *net_ptr, const vector<string> &argv)
+void $c_ident::init()
{
m_net_ptr = net_ptr;
m_machineID.type = MachineType_${ident};
nathan binkert
2009-12-21 20:44:22 UTC
Permalink
The commit message doesn't match the actual change.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID 1788fb1fa57c0b95f0ec58b991cbb503a98c276c
# Parent  d5c731012d722a9b54373ed45600e9e978001ea9
ruby: Hook up network queues to SLICC-generated state machines.
diff -r d5c731012d72 -r 1788fb1fa57c src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh        Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh        Sat Dec 12 14:37:15 2009 -0800
@@ -16,7 +16,6 @@
    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
  //  virtual int getNumberOfControllers() const = 0;
diff -r d5c731012d72 -r 1788fb1fa57c src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py     Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py     Sat Dec 12 14:37:15 2009 -0800
@@ -203,7 +203,7 @@
    typedef ${c_ident}Params Params;
    $c_ident(const Params *p);
    static int getNumControllers();
-    void init(Network* net_ptr, const vector<string> & argv);
+    void init();
    MessageBuffer* getMandatoryQueue() const;
    const int & getVersion() const;
    const string toString() const;
@@ -359,7 +359,7 @@
        code('''
 }
-void $c_ident::init(Network *net_ptr, const vector<string> &argv)
+void $c_ident::init()
 {
    m_net_ptr = net_ptr;
    m_machineID.type = MachineType_${ident};
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:38 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID dcde9bc50b96aa1197e001486522a37cb18fd2f1
# Parent 05140b07714b6f591b3f511b7a3f076aae3d756b
ruby: Fixed the Sequencer init function
Removed the Sequencer init function so that the parent (RubyPort) init
function is used instead and thus the mandatory queue is set to the
correct value.

diff -r 05140b07714b -r dcde9bc50b96 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:15 2009 -0800
@@ -83,10 +83,6 @@
assert(m_dataCache_ptr != NULL);
}

-void Sequencer::init()
-{
-}
-
Sequencer::~Sequencer() {

}
@@ -493,7 +489,7 @@
// Send the message to the cache controller
assert(latency > 0);

-
+ assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg, latency);
}
/*
diff -r 05140b07714b -r dcde9bc50b96 src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
@@ -71,7 +71,6 @@
typedef RubySequencerParams Params;
// Constructors
Sequencer(const Params *);
- void init();

// Destructor
~Sequencer();
Brad Beckmann
2009-12-12 22:37:32 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID e657fd802abe54b28a19e2c851e8b3f700b10293
# Parent f164db9baf4ad51cf790ea3b134fed28f4e3d026
ruby: Add support for generating topologies in Python.

diff -r f164db9baf4a -r e657fd802abe configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -104,24 +104,35 @@
latency = 15
size = 1048576

-class CrossbarTopology(Topology):
- connections="hi"
+# It would be nice to lump all the network nodes into a single list,
+# but for consistency with the old scripts I'm segregating them by
+# type. I'm not sure if this is really necessary or not.
+
+# net_nodes = []
+l1_cntrl_nodes = []
+dir_cntrl_nodes = []

- for cpu in cpus:
+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_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())
+ dir_cntrl = Directory_Controller(version = i,
+ directory = RubyDirectoryMemory(),
+ memory_control = RubyMemoryControl())

-network = SimpleNetwork(topology=CrossbarTopology())
+ # net_nodes += [l1_cntrl, dir_cntrl]
+ l1_cntrl_nodes.append(l1_cntrl)
+ dir_cntrl_nodes.append(dir_cntrl)
+
+network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
+ dir_cntrl_nodes))

system.ruby = RubySystem(network = network,
profiler = RubyProfiler(),
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/Network.py
--- a/src/mem/ruby/network/Network.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/Network.py Sat Dec 12 14:37:15 2009 -0800
@@ -1,13 +1,42 @@
from m5.params import *
from m5.SimObject import SimObject

+class Link(SimObject):
+ type = 'Link'
+ latency = Param.Int(1, "")
+ bw_multiplier = Param.Int("")
+ weight = Param.Int(1, "")
+
+class ExtLink(Link):
+ type = 'ExtLink'
+ ext_node = Param.RubyController("External node")
+ int_node = Param.Int("ID of internal node")
+ bw_multiplier = 64
+
+class IntLink(Link):
+ type = 'IntLink'
+ node_a = Param.Int("ID of internal node on one end")
+ node_b = Param.Int("ID of internal node on other end")
+ bw_multiplier = 16
+
class Topology(SimObject):
type = 'Topology'
- connections = Param.String("")
+ ext_links = VectorParam.ExtLink("Links to external nodes")
+ int_links = VectorParam.IntLink("Links between internal nodes")
+ num_int_nodes = Param.Int("Nunber of internal nodes")
print_config = Param.Bool(False, "")

+def makeCrossbar(nodes):
+ ext_links = [ExtLink(ext_node=n, int_node=i)
+ for (i, n) in enumerate(nodes)]
+ xbar = len(nodes) # node ID for crossbar switch
+ int_links = [IntLink(node_a=i, node_b=xbar) for i in range(len(nodes))]
+ return Topology(ext_links=ext_links, int_links=int_links,
+ num_int_nodes=len(nodes)+1)
+
class RubyNetwork(SimObject):
type = 'RubyNetwork'
+ cxx_class = 'Network'
abstract = True
number_of_virtual_networks = Param.Int(10, "");
topology = Param.Topology("");
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc Sat Dec 12 14:37:15 2009 -0800
@@ -96,7 +96,7 @@
ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
m_ni_ptr_vector.insertAtBottom(ni);
}
- m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+ m_topology_ptr->createLinks(this, false); // false because this isn't a reconfiguration
for(int i = 0; i < m_router_ptr_vector.size(); i++)
{
m_router_ptr_vector[i]->init();
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc Sat Dec 12 14:37:15 2009 -0800
@@ -95,7 +95,7 @@
ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
m_ni_ptr_vector.insertAtBottom(ni);
}
- m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+ m_topology_ptr->createLinks(this, false); // false because this isn't a reconfiguration
}

GarnetNetwork::~GarnetNetwork()
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/CustomTopology.cc
--- a/src/mem/ruby/network/simple/CustomTopology.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/CustomTopology.cc Sat Dec 12 14:37:15 2009 -0800
@@ -23,6 +23,7 @@
endpointConnectionExist[k] = false;
}

+#if 0
stringstream networkFile( m_connections );

string line = "";
@@ -121,6 +122,7 @@
}
}
} // end of file
+#endif

// makes sure all enpoints are connected in the soon to be created network
for (int k = 0; k < endpointConnectionExist.size(); k++) {
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:15 2009 -0800
@@ -62,8 +62,6 @@
SimpleNetwork::SimpleNetwork(const Params *p)
: Network(p)
{
- m_virtual_networks = 0;
- m_topology_ptr = NULL;
}

void SimpleNetwork::init()
@@ -101,7 +99,7 @@
for (int i=0; i<number_of_switches; i++) {
m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
}
- m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+ m_topology_ptr->createLinks(this, false); // false because this isn't a reconfiguration
}

void SimpleNetwork::reset()
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:15 2009 -0800
@@ -39,6 +39,7 @@
#include "mem/ruby/network/simple/Topology.hh"
#include "mem/ruby/common/NetDest.hh"
#include "mem/ruby/network/Network.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/protocol/TopologyType.hh"
#include "mem/gems_common/util.hh"
#include "mem/protocol/MachineType.hh"
@@ -65,19 +66,29 @@
Topology::Topology(const Params *p)
: SimObject(p)
{
-// 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;
+ m_number_of_switches = p->num_int_nodes;
+ // initialize component latencies record
+ m_component_latencies.setSize(0);
+ m_component_inter_switches.setSize(0);
}

void Topology::init()
{
+ // need to defer this until init, to guarantee that constructors
+ // for all the controller objects have been called.
+ m_nodes = MachineType_base_number(MachineType_NUM);
}

void Topology::makeTopology()
{
+ if (m_nodes != params()->ext_links.size()) {
+ fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+ m_nodes != params()->ext_links.size());
+ }
+
+
+
/*
if (m_nodes == 1) {
SwitchID id = newSwitchID();
@@ -95,6 +106,7 @@
Vector< SwitchID > int_network_switches; // internal switches extracted from the file
Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network

+#if 0
endpointConnectionExist.setSize(m_nodes);

// initialize endpoint check vector
@@ -201,6 +213,7 @@
}
} // end of file

+
// makes sure all enpoints are connected in the soon to be created network
for (int k = 0; k < endpointConnectionExist.size(); k++) {
if (endpointConnectionExist[k] == false) {
@@ -210,18 +223,39 @@
}

ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size() && latencies.size() == weights.size())
+
for (int k = 0; k < nodePairs.size(); k++) {
- ASSERT(nodePairs[k].size() == 2);
addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], weights[k]);
}
+#endif

- // initialize component latencies record
- m_component_latencies.setSize(0);
- m_component_inter_switches.setSize(0);
+ for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+ i != params()->ext_links.end(); ++i)
+ {
+ const ExtLinkParams *p = (*i)->params();
+ AbstractController *c = p->ext_node;
+ int ext_idx1 =
+ MachineType_base_number(c->getMachineType()) + c->getVersion();
+ int ext_idx2 = ext_idx1 + m_nodes;
+ int int_idx = p->int_node + 2*m_nodes;
+
+ addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
+ addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
+ }
+
+ for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+ i != params()->int_links.end(); ++i)
+ {
+ const IntLinkParams *p = (*i)->params();
+ int a = p->node_a + 2*m_nodes;
+ int b = p->node_b + 2*m_nodes;
+ addLink(a, b, p->latency, p->bw_multiplier, p->weight);
+ addLink(b, a, p->latency, p->bw_multiplier, p->weight);
+ }
}


-void Topology::createLinks(bool isReconfiguration)
+void Topology::createLinks(Network *net, bool isReconfiguration)
{
// Find maximum switchID

@@ -279,7 +313,7 @@
if (weight > 0 && weight != INFINITE_LATENCY) {
NetDest destination_set = shortest_path_to_node(i, j, topology_weights, dist);
assert(latency != -1);
- makeLink(i, j, destination_set, latency, weight, bw_multiplier, isReconfiguration);
+ makeLink(net, i, j, destination_set, latency, weight, bw_multiplier, isReconfiguration);
}
}
}
@@ -303,6 +337,7 @@

void Topology::addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight)
{
+ cprintf("addLink(%d, %d, %d, %d, %d)\n", src, dest, link_latency, bw_multiplier, link_weight);
ASSERT(src <= m_number_of_switches+m_nodes+m_nodes);
ASSERT(dest <= m_number_of_switches+m_nodes+m_nodes);
m_links_src_vector.insertAtBottom(src);
@@ -312,20 +347,20 @@
m_bw_multiplier_vector.insertAtBottom(bw_multiplier);
}

-void Topology::makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+void Topology::makeLink(Network *net, SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
{
// Make sure we're not trying to connect two end-point nodes directly together
assert((src >= 2*m_nodes) || (dest >= 2*m_nodes));

if (src < m_nodes) {
- m_network_ptr->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, bw_multiplier, isReconfiguration);
+ net->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, bw_multiplier, isReconfiguration);
} else if (dest < 2*m_nodes) {
assert(dest >= m_nodes);
NodeID node = dest-m_nodes;
- m_network_ptr->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+ net->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
} else {
assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
- m_network_ptr->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+ net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
}
}

@@ -454,3 +489,21 @@
{
return new Topology(this);
}
+
+Link *
+LinkParams::create()
+{
+ return new Link(this);
+}
+
+ExtLink *
+ExtLinkParams::create()
+{
+ return new ExtLink(this);
+}
+
+IntLink *
+IntLinkParams::create()
+{
+ return new IntLink(this);
+}
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:15 2009 -0800
@@ -52,17 +52,45 @@
#include "mem/ruby/system/NodeID.hh"
#include "sim/sim_object.hh"
#include "params/Topology.hh"
+#include "params/Link.hh"
+#include "params/ExtLink.hh"
+#include "params/IntLink.hh"

class Network;
class NetDest;

typedef Vector < Vector <int> > Matrix;

+class Link : public SimObject {
+ public:
+ typedef LinkParams Params;
+ Link(const Params *p) : SimObject(p) {}
+ const Params *params() const { return (const Params *)_params; }
+};
+
+
+class ExtLink : public Link {
+ public:
+ typedef ExtLinkParams Params;
+ ExtLink(const Params *p) : Link(p) {}
+ const Params *params() const { return (const Params *)_params; }
+};
+
+
+class IntLink : public Link {
+ public:
+ typedef IntLinkParams Params;
+ IntLink(const Params *p) : Link(p) {}
+ const Params *params() const { return (const Params *)_params; }
+};
+
+
class Topology : public SimObject {
public:
// Constructors
typedef TopologyParams Params;
Topology(const Params *p);
+ const Params *params() const { return (const Params *)_params; }

// Destructor
virtual ~Topology() {}
@@ -72,7 +100,7 @@
// Public Methods
void makeTopology();
int numSwitches() const { return m_number_of_switches; }
- void createLinks(bool isReconfiguration);
+ void createLinks(Network *net, bool isReconfiguration);

const string getName() { return m_name; }
void printStats(ostream& out) const {}
@@ -86,7 +114,7 @@
void addLink(SwitchID src, SwitchID dest, int link_latency);
void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier);
void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight);
- void makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int weight, int bw_multiplier, bool isReconfiguration);
+ void makeLink(Network *net, SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int weight, int bw_multiplier, bool isReconfiguration);

// void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);

@@ -98,8 +126,6 @@
// Data Members (m_ prefix)
string m_name;
bool m_print_config;
- Network* m_network_ptr;
- string m_connections;
NodeID m_nodes;
int m_number_of_switches;
nathan binkert
2009-12-21 20:37:36 UTC
Permalink
Again, #if 0 in several places. This related to garnet?

Nate
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID e657fd802abe54b28a19e2c851e8b3f700b10293
# Parent  f164db9baf4ad51cf790ea3b134fed28f4e3d026
ruby: Add support for generating topologies in Python.
diff -r f164db9baf4a -r e657fd802abe configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
@@ -104,24 +104,35 @@
    latency = 15
    size = 1048576
-    connections="hi"
+# It would be nice to lump all the network nodes into a single list,
+# but for consistency with the old scripts I'm segregating them by
+# type.  I'm not sure if this is really necessary or not.
+
+# net_nodes = []
+l1_cntrl_nodes = []
+dir_cntrl_nodes = []
    l1_cntrl = L1Cache_Controller()
-    cpu_seq = RubySequencer(controller=l1_cntrl,
-                            icache=L1Cache(controller=l1_cntrl),
-                            dcache=L1Cache(controller=l1_cntrl))
+    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())
+    dir_cntrl = Directory_Controller(version = i,
+                                     directory = RubyDirectoryMemory(),
+                                     memory_control = RubyMemoryControl())
-network = SimpleNetwork(topology=CrossbarTopology())
+    # net_nodes += [l1_cntrl, dir_cntrl]
+    l1_cntrl_nodes.append(l1_cntrl)
+    dir_cntrl_nodes.append(dir_cntrl)
+
+network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
+                                                dir_cntrl_nodes))
 system.ruby = RubySystem(network = network,
                         profiler = RubyProfiler(),
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/Network.py
--- a/src/mem/ruby/network/Network.py   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/Network.py   Sat Dec 12 14:37:15 2009 -0800
@@ -1,13 +1,42 @@
 from m5.params import *
 from m5.SimObject import SimObject
+    type = 'Link'
+    latency = Param.Int(1, "")
+    bw_multiplier = Param.Int("")
+    weight = Param.Int(1, "")
+
+    type = 'ExtLink'
+    ext_node = Param.RubyController("External node")
+    int_node = Param.Int("ID of internal node")
+    bw_multiplier = 64
+
+    type = 'IntLink'
+    node_a = Param.Int("ID of internal node on one end")
+    node_b = Param.Int("ID of internal node on other end")
+    bw_multiplier = 16
+
    type = 'Topology'
-    connections = Param.String("")
+    ext_links = VectorParam.ExtLink("Links to external nodes")
+    int_links = VectorParam.IntLink("Links between internal nodes")
+    num_int_nodes = Param.Int("Nunber of internal nodes")
    print_config = Param.Bool(False, "")
+    ext_links = [ExtLink(ext_node=n, int_node=i)
+                 for (i, n) in enumerate(nodes)]
+    xbar = len(nodes) # node ID for crossbar switch
+    int_links = [IntLink(node_a=i, node_b=xbar) for i in range(len(nodes))]
+    return Topology(ext_links=ext_links, int_links=int_links,
+                    num_int_nodes=len(nodes)+1)
+
    type = 'RubyNetwork'
+    cxx_class = 'Network'
    abstract = True
    number_of_virtual_networks = Param.Int(10, "");
    topology = Param.Topology("");
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Sat Dec 12 14:37:15 2009 -0800
@@ -96,7 +96,7 @@
                ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
                m_ni_ptr_vector.insertAtBottom(ni);
        }
-        m_topology_ptr->createLinks(false);  // false because this isn't a reconfiguration
+        m_topology_ptr->createLinks(this, false);  // false because this isn't a reconfiguration
        for(int i = 0; i < m_router_ptr_vector.size(); i++)
        {
                m_router_ptr_vector[i]->init();
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc    Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc    Sat Dec 12 14:37:15 2009 -0800
@@ -95,7 +95,7 @@
                ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
                m_ni_ptr_vector.insertAtBottom(ni);
        }
-        m_topology_ptr->createLinks(false);  // false because this isn't a reconfiguration
+        m_topology_ptr->createLinks(this, false);  // false because this isn't a reconfiguration
 }
 GarnetNetwork::~GarnetNetwork()
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/CustomTopology.cc
--- a/src/mem/ruby/network/simple/CustomTopology.cc     Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/CustomTopology.cc     Sat Dec 12 14:37:15 2009 -0800
@@ -23,6 +23,7 @@
    endpointConnectionExist[k] = false;
  }
+#if 0
  stringstream networkFile( m_connections );
  string line = "";
@@ -121,6 +122,7 @@
      }
    }
  } // end of file
+#endif
  // makes sure all enpoints are connected in the soon to be created network
  for (int k = 0; k < endpointConnectionExist.size(); k++) {
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc      Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc      Sat Dec 12 14:37:15 2009 -0800
@@ -62,8 +62,6 @@
 SimpleNetwork::SimpleNetwork(const Params *p)
    : Network(p)
 {
-  m_virtual_networks = 0;
-  m_topology_ptr = NULL;
 }
 void SimpleNetwork::init()
@@ -101,7 +99,7 @@
  for (int i=0; i<number_of_switches; i++) {
    m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
  }
-  m_topology_ptr->createLinks(false);  // false because this isn't a reconfiguration
+  m_topology_ptr->createLinks(this, false);  // false because this isn't a reconfiguration
 }
 void SimpleNetwork::reset()
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc   Sat Dec 12 14:37:15 2009 -0800
@@ -39,6 +39,7 @@
 #include "mem/ruby/network/simple/Topology.hh"
 #include "mem/ruby/common/NetDest.hh"
 #include "mem/ruby/network/Network.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/protocol/TopologyType.hh"
 #include "mem/gems_common/util.hh"
 #include "mem/protocol/MachineType.hh"
@@ -65,19 +66,29 @@
 Topology::Topology(const Params *p)
    : SimObject(p)
 {
-//    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;
+    m_number_of_switches = p->num_int_nodes;
+  // initialize component latencies record
+  m_component_latencies.setSize(0);
+  m_component_inter_switches.setSize(0);
 }
 void Topology::init()
 {
+    // need to defer this until init, to guarantee that constructors
+    // for all the controller objects have been called.
+    m_nodes = MachineType_base_number(MachineType_NUM);
 }
 void Topology::makeTopology()
 {
+    if (m_nodes != params()->ext_links.size()) {
+        fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+              m_nodes != params()->ext_links.size());
+    }
+
+
+
  /*
  if (m_nodes == 1) {
    SwitchID id = newSwitchID();
@@ -95,6 +106,7 @@
  Vector< SwitchID > int_network_switches;  // internal switches extracted from the file
  Vector<bool> endpointConnectionExist;  // used to ensure all endpoints are connected to the network
+#if 0
  endpointConnectionExist.setSize(m_nodes);
  // initialize endpoint check vector
@@ -201,6 +213,7 @@
    }
  } // end of file
+
  // makes sure all enpoints are connected in the soon to be created network
  for (int k = 0; k < endpointConnectionExist.size(); k++) {
    if (endpointConnectionExist[k] == false) {
@@ -210,18 +223,39 @@
  }
  ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size() && latencies.size() == weights.size())
+
  for (int k = 0; k < nodePairs.size(); k++) {
-    ASSERT(nodePairs[k].size() == 2);
    addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], weights[k]);
  }
+#endif
-  // initialize component latencies record
-  m_component_latencies.setSize(0);
-  m_component_inter_switches.setSize(0);
+  for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+       i != params()->ext_links.end(); ++i)
+  {
+      const ExtLinkParams *p = (*i)->params();
+      AbstractController *c = p->ext_node;
+      int ext_idx1 =
+          MachineType_base_number(c->getMachineType()) + c->getVersion();
+      int ext_idx2 = ext_idx1 + m_nodes;
+      int int_idx = p->int_node + 2*m_nodes;
+
+      addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
+      addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
+  }
+
+  for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+       i != params()->int_links.end(); ++i)
+  {
+      const IntLinkParams *p = (*i)->params();
+      int a = p->node_a + 2*m_nodes;
+      int b = p->node_b + 2*m_nodes;
+      addLink(a, b, p->latency, p->bw_multiplier, p->weight);
+      addLink(b, a, p->latency, p->bw_multiplier, p->weight);
+  }
 }
-void Topology::createLinks(bool isReconfiguration)
+void Topology::createLinks(Network *net, bool isReconfiguration)
 {
  // Find maximum switchID
@@ -279,7 +313,7 @@
      if (weight > 0 && weight != INFINITE_LATENCY) {
        NetDest destination_set = shortest_path_to_node(i, j, topology_weights, dist);
        assert(latency != -1);
-        makeLink(i, j, destination_set, latency, weight, bw_multiplier, isReconfiguration);
+        makeLink(net, i, j, destination_set, latency, weight, bw_multiplier, isReconfiguration);
      }
    }
  }
@@ -303,6 +337,7 @@
 void Topology::addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight)
 {
+    cprintf("addLink(%d, %d, %d, %d, %d)\n", src, dest, link_latency, bw_multiplier, link_weight);
  ASSERT(src <= m_number_of_switches+m_nodes+m_nodes);
  ASSERT(dest <= m_number_of_switches+m_nodes+m_nodes);
  m_links_src_vector.insertAtBottom(src);
@@ -312,20 +347,20 @@
  m_bw_multiplier_vector.insertAtBottom(bw_multiplier);
 }
-void Topology::makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+void Topology::makeLink(Network *net, SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
 {
  // Make sure we're not trying to connect two end-point nodes directly together
  assert((src >= 2*m_nodes) || (dest >= 2*m_nodes));
  if (src < m_nodes) {
-    m_network_ptr->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, bw_multiplier, isReconfiguration);
+    net->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, bw_multiplier, isReconfiguration);
  } else if (dest < 2*m_nodes) {
    assert(dest >= m_nodes);
    NodeID node = dest-m_nodes;
-    m_network_ptr->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+    net->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
  } else {
    assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
-    m_network_ptr->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+    net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
  }
 }
@@ -454,3 +489,21 @@
 {
    return new Topology(this);
 }
+
+Link *
+LinkParams::create()
+{
+    return new Link(this);
+}
+
+ExtLink *
+ExtLinkParams::create()
+{
+    return new ExtLink(this);
+}
+
+IntLink *
+IntLinkParams::create()
+{
+    return new IntLink(this);
+}
diff -r f164db9baf4a -r e657fd802abe src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh   Sat Dec 12 14:37:15 2009 -0800
@@ -52,17 +52,45 @@
 #include "mem/ruby/system/NodeID.hh"
 #include "sim/sim_object.hh"
 #include "params/Topology.hh"
+#include "params/Link.hh"
+#include "params/ExtLink.hh"
+#include "params/IntLink.hh"
 class Network;
 class NetDest;
 typedef Vector < Vector <int> > Matrix;
+class Link : public SimObject {
+    typedef LinkParams Params;
+    Link(const Params *p) : SimObject(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
+class ExtLink : public Link {
+    typedef ExtLinkParams Params;
+    ExtLink(const Params *p) : Link(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
+class IntLink : public Link {
+    typedef IntLinkParams Params;
+    IntLink(const Params *p) : Link(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
 class Topology : public SimObject {
  // Constructors
    typedef TopologyParams Params;
    Topology(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
  // Destructor
  virtual ~Topology() {}
@@ -72,7 +100,7 @@
  // Public Methods
  void makeTopology();
  int numSwitches() const { return m_number_of_switches; }
-  void createLinks(bool isReconfiguration);
+  void createLinks(Network *net, bool isReconfiguration);
  const string getName() { return m_name; }
  void printStats(ostream& out) const {}
@@ -86,7 +114,7 @@
  void addLink(SwitchID src, SwitchID dest, int link_latency);
  void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier);
  void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight);
-  void makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int weight, int bw_multiplier, bool isReconfiguration);
+  void makeLink(Network *net, SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int weight, int bw_multiplier, bool isReconfiguration);
  //  void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);
@@ -98,8 +126,6 @@
  // Data Members (m_ prefix)
  string m_name;
  bool m_print_config;
-  Network* m_network_ptr;
-  string m_connections;
  NodeID m_nodes;
  int m_number_of_switches;
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:39 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 8b7cf38ad6de8a71ddcc3044abab28c7ec0d2599
# Parent dcde9bc50b96aa1197e001486522a37cb18fd2f1
ruby: Small fix to ruby debug defaults

diff -r dcde9bc50b96 -r 8b7cf38ad6de src/mem/ruby/common/Debug.py
--- a/src/mem/ruby/common/Debug.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/common/Debug.py Sat Dec 12 14:37:15 2009 -0800
@@ -8,5 +8,5 @@
filter_string = Param.String('none', "")
verbosity_string = Param.String('none', "")
output_filename = Param.String('none', "")
- start_time = Param.Tick(30300000, "")
+ start_time = Param.Tick(0, "")
protocol_trace = Param.Bool(False, "")
Brad Beckmann
2009-12-12 22:37:44 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID e68f680829daff5e16ea6d520c7302f7ed5055f9
# Parent 3518bdc98c5697d49bc20c3955e2013977f1e6c8
ruby: Converted MOESI_hammer dma cntrl to new config system

diff -r 3518bdc98c56 -r e68f680829da configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
@@ -104,6 +104,7 @@
#
l1_cntrl_nodes = []
dir_cntrl_nodes = []
+dma_cntrl_nodes = []

#
# Must create the individual controllers before the network to ensure the
@@ -138,12 +139,15 @@
directory = RubyDirectoryMemory(),
memBuffer = RubyMemoryControl())

+ dma_cntrl = DMA_Controller(version = i,
+ dma_sequencer = DMASequencer())
#
# As noted above: Two independent list are track to maintain the order of
# nodes/controllers assumed by the ruby network
#
l1_cntrl_nodes.append(l1_cntrl)
dir_cntrl_nodes.append(dir_cntrl)
+ dma_cntrl_nodes.append(dma_cntrl)

#
# Finally tie the memtester ports to the correct system ports
@@ -157,7 +161,8 @@
# constructor.
#
network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
- dir_cntrl_nodes))
+ dir_cntrl_nodes + \
+ dma_cntrl_nodes))

mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
for dir_cntrl in dir_cntrl_nodes])
@@ -166,7 +171,9 @@
network = network,
profiler = RubyProfiler(),
tracer = RubyTracer(),
- debug = RubyDebug(),
+ debug = RubyDebug(filter_string = 'qQin',
+ verbosity_string = 'high',
+ protocol_trace = True),
mem_size_mb = mem_size_mb)


diff -r 3518bdc98c56 -r e68f680829da src/mem/protocol/MOESI_hammer-dma.sm
--- a/src/mem/protocol/MOESI_hammer-dma.sm Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-dma.sm Sat Dec 12 14:37:16 2009 -0800
@@ -28,7 +28,8 @@


machine(DMA, "DMA Controller")
-: int request_latency = 6
+: DMASequencer * dma_sequencer,
+ int request_latency = 6
{

MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true";
@@ -47,20 +48,14 @@
Ack, desc="DMA write to memory completed";
}

- external_type(DMASequencer) {
- void ackCallback();
- void dataCallback(DataBlock);
- }
-
MessageBuffer mandatoryQueue, ordered="false", no_vector="true";
- DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true";
State cur_state, no_vector="true";

State getState(Address addr) {
return cur_state;
}
void setState(Address addr, State state) {
- cur_state := state;
+ cur_state := state;
}

out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
diff -r 3518bdc98c56 -r e68f680829da src/mem/protocol/RubySlicc_Types.sm
--- a/src/mem/protocol/RubySlicc_Types.sm Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/protocol/RubySlicc_Types.sm Sat Dec 12 14:37:16 2009 -0800
@@ -122,6 +122,11 @@

}

+external_type(DMASequencer) {
+ void ackCallback();
+ void dataCallback(DataBlock);
+}
+
external_type(TimerTable, inport="yes") {
bool isReady();
Address readyAddress();
diff -r 3518bdc98c56 -r e68f680829da src/mem/ruby/system/DMASequencer.cc
--- a/src/mem/ruby/system/DMASequencer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/DMASequencer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -8,6 +8,10 @@
#include "mem/protocol/SequencerRequestType.hh"
#include "mem/ruby/system/System.hh"

+//
+// Fix me: This code needs comments!
+//
+
DMASequencer::DMASequencer(const Params *p)
: RubyPort(p)
{
@@ -58,11 +62,16 @@
msg.getLineAddress() = line_address(msg.getPhysicalAddress());
msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
int offset = paddr & m_data_block_mask;
+
msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
len :
RubySystem::getBlockSizeBytes() - offset;
- if (write)
+
+ if (write) {
msg.getDataBlk().setData(data, offset, msg.getLen());
+ }
+
+ assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg);
active_request.bytes_issued += msg.getLen();

@@ -82,14 +91,18 @@
SequencerMsg msg;
msg.getPhysicalAddress() = Address(active_request.start_paddr +
active_request.bytes_completed);
+
assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
msg.getLineAddress() = line_address(msg.getPhysicalAddress());
+
msg.getType() = (active_request.write ? SequencerRequestType_ST :
SequencerRequestType_LD);
+
msg.getLen() = (active_request.len -
active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
active_request.len - active_request.bytes_completed :
RubySystem::getBlockSizeBytes());
+
if (active_request.write) {
msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed],
0, msg.getLen());
@@ -97,6 +110,8 @@
} else {
msg.getType() = SequencerRequestType_LD;
}
+
+ assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg);
active_request.bytes_issued += msg.getLen();
}
diff -r 3518bdc98c56 -r e68f680829da src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:16 2009 -0800
@@ -38,6 +38,7 @@
"Sequencer": "RubySequencer",
"DirectoryMemory": "RubyDirectoryMemory",
"MemoryControl": "RubyMemoryControl",
+ "DMASequencer": "DMASequencer"
}

class StateMachine(Symbol):
Brad Beckmann
2009-12-12 22:37:53 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID 70be840d4d3d6c1e115c32379ff3c80068ef53f5
# Parent fa98d755bc7afb680785e9fb2cb711c42514b815
ruby: reorganized ruby python configuration
Reorganized ruby python configuration so that protocol and ruby memory system
configuration code can be shared by multiple front-end configuration files
(i.e. memory tester, full system, and hopefully the regression tester). This
code works for memory tester, but have not tested fs mode.

diff -r fa98d755bc7a -r 70be840d4d3d configs/common/Options.py
--- a/configs/common/Options.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/common/Options.py Sat Dec 12 14:37:17 2009 -0800
@@ -36,7 +36,9 @@
parser.add_option("--fastmem", action="store_true")

# Run duration options
-parser.add_option("-m", "--maxtick", type="int")
+parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
+ metavar="T",
+ help="Stop after T ticks")
parser.add_option("--maxtime", type="float")
parser.add_option("--maxinsts", type="int")
parser.add_option("--prog_intvl", type="int")
diff -r fa98d755bc7a -r 70be840d4d3d configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:17 2009 -0800
@@ -34,6 +34,17 @@
from m5.util import addToPath
import os, optparse, sys
addToPath('../common')
+addToPath('../ruby')
+
+import Ruby
+
+if buildEnv['FULL_SYSTEM']:
+ panic("This script requires system-emulation mode (*_SE).")
+
+# Get paths we might need. It's expected this file is in m5/configs/example.
+config_path = os.path.dirname(os.path.abspath(__file__))
+config_root = os.path.dirname(config_path)
+m5_root = os.path.dirname(config_root)

parser = optparse.OptionParser()

@@ -43,13 +54,6 @@
help="Use blocking caches")
parser.add_option("-l", "--maxloads", metavar="N", default=0,
help="Stop after N loads")
-parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
- metavar="T",
- help="Stop after T ticks")
-
-parser.add_option("-t", "--testers", type="int", metavar="N", default=1,
- help="number of testers/cores")
-
parser.add_option("-f", "--functional", type="int", default=0,
metavar="PCT",
help="Target percentage of functional accesses "
@@ -64,6 +68,8 @@
help="Progress message interval "
"[default: %default]")

+execfile(os.path.join(config_root, "common", "Options.py"))
+
(options, args) = parser.parse_args()

if args:
@@ -72,126 +78,31 @@

block_size = 64

-if options.testers > block_size:
+if options.num_cpus > block_size:
print "Error: Number of testers %d limited to %d because of false sharing" \
- % (options.testers, block_size)
+ % (options.num_cpus, block_size)
sys.exit(1)

cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \
percent_functional=options.functional, \
percent_uncacheable=options.uncacheable, \
progress_interval=options.progress) \
- for i in xrange(options.testers) ]
+ for i in xrange(options.num_cpus) ]

system = System(cpu = cpus,
funcmem = PhysicalMemory(),
physmem = PhysicalMemory())

-class L1Cache(RubyCache):
- assoc = 2
- latency = 3
- size = 32768
+system.ruby = Ruby.create_system(options, system.physmem)

-class L2Cache(RubyCache):
- assoc = 16
- latency = 15
- size = 1048576
+assert(len(cpus) == len(system.ruby.cpu_ruby_ports))

-#
-# The ruby network creation expects the list of nodes in the system to be
-# consistent with the NetDest list. Therefore the l1 controller nodes must be
-# listed before the directory nodes and directory nodes before dma nodes, etc.
-#
-l1_cntrl_nodes = []
-dir_cntrl_nodes = []
-dma_cntrl_nodes = []
-
-#
-# Must create the individual controllers before the network to ensure the
-# controller constructors are called before the network constructor
-#
for (i, cpu) in enumerate(cpus):
#
- # First create the Ruby objects associated with this cpu
- # Eventually this code should go in a python file specific to the
- # MOESI_hammer protocol
+ # Tie the memtester ports to the correct system ports
#
- l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i))
- l1i_cache = L1Cache(cache_profiler = l1i_profiler)
-
- l1d_profiler = CacheProfiler(description = ("l1d_%s_profiler" % i))
- l1d_cache = L1Cache(cache_profiler = l1d_profiler)
-
- l2_profiler = CacheProfiler(description = ("l2_%s_profiler" % i))
- l2_cache = L2Cache(cache_profiler = l2_profiler)
-
- cpu_seq = RubySequencer(icache = l1i_cache,
- dcache = l1d_cache,
- funcmem_port = system.physmem.port)
-
- l1_cntrl = L1Cache_Controller(version = i,
- sequencer = cpu_seq,
- L1IcacheMemory = l1i_cache,
- L1DcacheMemory = l1d_cache,
- L2cacheMemory = l2_cache)
-
- mem_cntrl = RubyMemoryControl(version = i)
-
- dir_cntrl = Directory_Controller(version = i,
- directory = RubyDirectoryMemory(),
- memBuffer = mem_cntrl)
-
- dma_cntrl = DMA_Controller(version = i,
- dma_sequencer = DMASequencer())
- #
- # As noted above: Two independent list are track to maintain the order of
- # nodes/controllers assumed by the ruby network
- #
- l1_cntrl_nodes.append(l1_cntrl)
- dir_cntrl_nodes.append(dir_cntrl)
- dma_cntrl_nodes.append(dma_cntrl)
-
- #
- # Finally tie the memtester ports to the correct system ports
- #
- cpu.test = cpu_seq.port
+ cpu.test = system.ruby.cpu_ruby_ports[i].port
cpu.functional = system.funcmem.port
-
-
-#
-# Important: the topology constructor must be called before the network
-# constructor.
-#
-network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
- dir_cntrl_nodes + \
- dma_cntrl_nodes))
-
-mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
- for dir_cntrl in dir_cntrl_nodes])
-
-#
-# determine the number of memory controllers and other memory controller
-# parameters for the profiler
-#
-mcCount = len(dir_cntrl_nodes)
-banksPerRank = dir_cntrl_nodes[0].memBuffer.banks_per_rank
-ranksPerDimm = dir_cntrl_nodes[0].memBuffer.ranks_per_dimm
-dimmsPerChannel = dir_cntrl_nodes[0].memBuffer.dimms_per_channel
-
-ruby_profiler = RubyProfiler(mem_cntrl_count = mcCount,
- banks_per_rank = banksPerRank,
- ranks_per_dimm = ranksPerDimm,
- dimms_per_channel = dimmsPerChannel)
-
-system.ruby = RubySystem(clock = '1GHz',
- network = network,
- profiler = ruby_profiler,
- tracer = RubyTracer(),
- debug = RubyDebug(filter_string = 'none',
- verbosity_string = 'none',
- protocol_trace = False),
- mem_size_mb = mem_size_mb)
-

# -----------------------
# run simulation
diff -r fa98d755bc7a -r 70be840d4d3d configs/ruby/MOESI_hammer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configs/ruby/MOESI_hammer.py Sat Dec 12 14:37:17 2009 -0800
@@ -0,0 +1,111 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# 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.
+#
+# Authors: Brad Beckmann
+
+import m5
+from m5.objects import *
+from m5.defines import buildEnv
+from m5.util import addToPath
+
+
+class L1Cache(RubyCache):
+ assoc = 2
+ latency = 3
+ size = 32768
+
+class L2Cache(RubyCache):
+ assoc = 16
+ latency = 15
+ size = 1048576
+
+def create_system(options, physmem):
+
+ if buildEnv['PROTOCOL'] != 'MOESI_hammer':
+ panic("This script requires the MOESI_hammer protocol to be built.")
+
+ sequencers = []
+ #
+ # The ruby network creation expects the list of nodes in the system to be
+ # consistent with the NetDest list. Therefore the l1 controller nodes must be
+ # listed before the directory nodes and directory nodes before dma nodes, etc.
+ #
+ l1_cntrl_nodes = []
+ dir_cntrl_nodes = []
+ dma_cntrl_nodes = []
+
+ #
+ # Must create the individual controllers before the network to ensure the
+ # controller constructors are called before the network constructor
+ #
+ for i in range(options.num_cpus):
+ #
+ # First create the Ruby objects associated with this cpu
+ # Eventually this code should go in a python file specific to the
+ # MOESI_hammer protocol
+ #
+ l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i))
+ l1i_cache = L1Cache(cache_profiler = l1i_profiler)
+
+ l1d_profiler = CacheProfiler(description = ("l1d_%s_profiler" % i))
+ l1d_cache = L1Cache(cache_profiler = l1d_profiler)
+
+ l2_profiler = CacheProfiler(description = ("l2_%s_profiler" % i))
+ l2_cache = L2Cache(cache_profiler = l2_profiler)
+
+ cpu_seq = RubySequencer(icache = l1i_cache,
+ dcache = l1d_cache,
+ funcmem_port = physmem.port)
+
+ l1_cntrl = L1Cache_Controller(version = i,
+ sequencer = cpu_seq,
+ L1IcacheMemory = l1i_cache,
+ L1DcacheMemory = l1d_cache,
+ L2cacheMemory = l2_cache)
+
+ mem_cntrl = RubyMemoryControl(version = i)
+
+ dir_cntrl = Directory_Controller(version = i,
+ directory = RubyDirectoryMemory(),
+ memBuffer = mem_cntrl)
+
+ dma_cntrl = DMA_Controller(version = i,
+ dma_sequencer = DMASequencer())
+
+ #
+ # Add controllers and sequencers to the appropriate lists
+ # As noted above: Independent list are track to maintain the order of
+ # nodes/controllers assumed by the ruby network
+ #
+ sequencers.append(cpu_seq)
+ l1_cntrl_nodes.append(l1_cntrl)
+ dir_cntrl_nodes.append(dir_cntrl)
+ dma_cntrl_nodes.append(dma_cntrl)
+
+ all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
+
+ return (sequencers, dir_cntrl_nodes, all_cntrls)
diff -r fa98d755bc7a -r 70be840d4d3d configs/ruby/Ruby.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
@@ -0,0 +1,82 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# 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.
+#
+# Authors: Brad Beckmann
+
+import m5
+from m5.objects import *
+from m5.defines import buildEnv
+from m5.util import addToPath
+
+import MOESI_hammer
+
+def create_system(options, physmem):
+
+ protocol = buildEnv['PROTOCOL']
+
+ if protocol == "MOESI_hammer":
+ (sequencers, dir_cntrls, all_cntrls) = MOESI_hammer.create_system( \
+ options, physmem)
+ else:
+ print "Error: unsupported ruby protocol"
+ sys.exit(1)
+
+ #
+ # Important: the topology constructor must be called before the network
+ # constructor.
+ #
+ network = SimpleNetwork(topology = makeCrossbar(all_cntrls))
+
+ mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
+ for dir_cntrl in dir_cntrls])
+
+ #
+ # determine the number of memory controllers and other memory controller
+ # parameters for the profiler
+ #
+ mcCount = len(dir_cntrls)
+ banksPerRank = dir_cntrls[0].memBuffer.banks_per_rank
+ ranksPerDimm = dir_cntrls[0].memBuffer.ranks_per_dimm
+ dimmsPerChannel = dir_cntrls[0].memBuffer.dimms_per_channel
+
+ ruby_profiler = RubyProfiler(mem_cntrl_count = mcCount,
+ banks_per_rank = banksPerRank,
+ ranks_per_dimm = ranksPerDimm,
+ dimms_per_channel = dimmsPerChannel)
+
+ ruby = RubySystem(clock = '1GHz',
+ network = network,
+ profiler = ruby_profiler,
+ tracer = RubyTracer(),
+ debug = RubyDebug(filter_string = 'none',
+ verbosity_string = 'none',
+ protocol_trace = False),
+ mem_size_mb = mem_size_mb)
+
+ ruby.cpu_ruby_ports = sequencers
+
+ return ruby
diff -r fa98d755bc7a -r 70be840d4d3d src/mem/protocol/SConsopts
--- a/src/mem/protocol/SConsopts Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/protocol/SConsopts Sat Dec 12 14:37:17 2009 -0800
@@ -54,3 +54,4 @@
all_protocols)

sticky_vars.AddVariables(opt)
+export_vars += ['PROTOCOL']
Brad Beckmann
2009-12-12 22:37:56 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID 2d19b51213922c91d5ca388835c8753750b73cbc
# Parent 3c00a365603e5724aea9b87b4b730839ef78139a
ruby: fixed Set.cc bug to allow zero sized sets
This is necessary for example when no dma sequencers are necessary in the
simulated system.

diff -r 3c00a365603e -r 2d19b5121392 src/mem/ruby/common/Set.cc
--- a/src/mem/ruby/common/Set.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/common/Set.cc Sat Dec 12 14:37:17 2009 -0800
@@ -69,8 +69,11 @@
Set::Set(int size)
{
m_p_nArray = NULL;
- assert(size>0);
- setSize(size);
+ m_nArrayLen = 0;
+ m_nSize = 0;
+ if(size > 0) {
+ setSize(size);
+ }
}

Set::~Set() {
Brad Beckmann
2009-12-12 22:37:42 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 1c05b3999b00f4bb3fc0558bf0304f8a5cf3a78a
# Parent c1b464b8baad8ab20030eb6b36859035c769122d
ruby: Wrapped ruby events into m5 events
Wrapped ruby events using the m5 event object. Removed the prio_heap
from ruby's event queue and instead schedule ruby events on the m5 event
queue.

diff -r c1b464b8baad -r 1c05b3999b00 src/mem/ruby/eventqueue/RubyEventQueue.cc
--- a/src/mem/ruby/eventqueue/RubyEventQueue.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc Sat Dec 12 14:37:15 2009 -0800
@@ -33,83 +33,35 @@

#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/common/Consumer.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
-#include "mem/gems_common/PrioHeap.hh"
#include "mem/ruby/eventqueue/RubyEventQueueNode.hh"

// Class public method definitions

-RubyEventQueue::RubyEventQueue(Tick _clock)
- : m_clock(_clock)
+RubyEventQueue::RubyEventQueue(EventQueue* eventq, Tick _clock)
+ : EventManager(eventq), m_clock(_clock)
{
- m_prio_heap_ptr = NULL;
- init();
- assert(g_eventQueue_ptr == NULL);
- g_eventQueue_ptr = this;
}

RubyEventQueue::~RubyEventQueue()
{
- delete m_prio_heap_ptr;
}

-void RubyEventQueue::init()
-{
- m_globalTime = 1;
- m_timeOfLastRecovery = 1;
- m_prio_heap_ptr = new PrioHeap<RubyEventQueueNode>;
- m_prio_heap_ptr->init();
-}
-
-bool RubyEventQueue::isEmpty() const
-{
- return (m_prio_heap_ptr->size() == 0);
+void RubyEventQueue::scheduleEvent(Consumer* consumer, Time timeDelta)
+{
+ scheduleEventAbsolute(consumer, timeDelta + getTime());
}

void RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs)
{
// Check to see if this is a redundant wakeup
- // Time time = timeDelta + m_globalTime;
ASSERT(consumer != NULL);
if (consumer->getLastScheduledWakeup() != timeAbs) {
// This wakeup is not redundant
- RubyEventQueueNode thisNode;
- thisNode.m_consumer_ptr = consumer;
- assert(timeAbs > m_globalTime);
- thisNode.m_time = timeAbs;
- m_prio_heap_ptr->insert(thisNode);
- consumer->setLastScheduledWakeup(timeAbs);
- }
-}
-
-void RubyEventQueue::triggerEvents(Time t)
-{
- RubyEventQueueNode thisNode;
-
- while(m_prio_heap_ptr->size() > 0 && m_prio_heap_ptr->peekMin().m_time <= t) {
- m_globalTime = m_prio_heap_ptr->peekMin().m_time;
- thisNode = m_prio_heap_ptr->extractMin();
- assert(thisNode.m_consumer_ptr != NULL);
- DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,*(thisNode.m_consumer_ptr));
- DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,thisNode.m_time);
- thisNode.m_consumer_ptr->triggerWakeup(this);
- }
- m_globalTime = t;
-}
-
-void RubyEventQueue::triggerAllEvents()
-{
- // FIXME - avoid repeated code
- RubyEventQueueNode thisNode;
-
- while(m_prio_heap_ptr->size() > 0) {
- m_globalTime = m_prio_heap_ptr->peekMin().m_time;
- thisNode = m_prio_heap_ptr->extractMin();
- assert(thisNode.m_consumer_ptr != NULL);
- DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,*(thisNode.m_consumer_ptr));
- DEBUG_EXPR(EVENTQUEUE_COMP,MedPrio,thisNode.m_time);
- thisNode.m_consumer_ptr->triggerWakeup(this);
+ RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer);
+ assert(timeAbs > getTime());
+ schedule(thisNode, (timeAbs * m_clock));
+ consumer->setLastScheduledWakeup(timeAbs * m_clock);
}
}

@@ -118,5 +70,5 @@
void
RubyEventQueue::print(ostream& out) const
{
- out << "[Event Queue: " << *m_prio_heap_ptr << "]";
+ out << "[Event Queue:]";
}
diff -r c1b464b8baad -r 1c05b3999b00 src/mem/ruby/eventqueue/RubyEventQueue.hh
--- a/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:15 2009 -0800
@@ -62,15 +62,16 @@
#include "config/no_vector_bounds_checks.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Vector.hh"
+#include "sim/eventq.hh"

class Consumer;
template <class TYPE> class PrioHeap;
class RubyEventQueueNode;

-class RubyEventQueue {
+class RubyEventQueue : public EventManager {
public:
// Constructors
- RubyEventQueue(Tick clock);
+ RubyEventQueue(EventQueue* eventq, Tick _clock);

// Destructor
~RubyEventQueue();
@@ -78,28 +79,21 @@
// Public Methods

Time getTime() const { return curTick/m_clock; }
- void scheduleEvent(Consumer* consumer, Time timeDelta) { scheduleEventAbsolute(consumer, timeDelta + m_globalTime); }
+ void scheduleEvent(Consumer* consumer, Time timeDelta);
void scheduleEventAbsolute(Consumer* consumer, Time timeAbs);
- void triggerEvents(Time t); // called to handle all events <= time t
- void triggerAllEvents();
void print(ostream& out) const;
- bool isEmpty() const;

- Time getTimeOfLastRecovery() {return m_timeOfLastRecovery;}
- void setTimeOfLastRecovery(Time t) {m_timeOfLastRecovery = t;}
+ void triggerEvents(Time t) { assert(0); }
+ void triggerAllEvents() { assert(0); }

// Private Methods
private:
// Private copy constructor and assignment operator
- void init();
RubyEventQueue(const RubyEventQueue& obj);
RubyEventQueue& operator=(const RubyEventQueue& obj);

// Data Members (m_ prefix)
Tick m_clock;
- PrioHeap<RubyEventQueueNode>* m_prio_heap_ptr;
- Time m_globalTime;
- Time m_timeOfLastRecovery;
};

// Output operator declaration
diff -r c1b464b8baad -r 1c05b3999b00 src/mem/ruby/eventqueue/RubyEventQueueNode.cc
--- a/src/mem/ruby/eventqueue/RubyEventQueueNode.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueueNode.cc Sat Dec 12 14:37:15 2009 -0800
@@ -37,7 +37,6 @@
void RubyEventQueueNode::print(ostream& out) const
{
out << "[";
- out << "Time=" << m_time;
if (m_consumer_ptr != NULL) {
out << " Consumer=" << m_consumer_ptr;
} else {
diff -r c1b464b8baad -r 1c05b3999b00 src/mem/ruby/eventqueue/RubyEventQueueNode.hh
--- a/src/mem/ruby/eventqueue/RubyEventQueueNode.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueueNode.hh Sat Dec 12 14:37:15 2009 -0800
@@ -36,31 +36,27 @@
#define RUBYEVENTQUEUENODE_H

#include "mem/ruby/common/Global.hh"
-class Consumer;
+#include "sim/eventq.hh"
+#include "mem/ruby/common/Consumer.hh"
+//class Consumer;

-class RubyEventQueueNode {
+class RubyEventQueueNode : public Event {
public:
// Constructors
- RubyEventQueueNode() { m_time = 0; m_consumer_ptr = NULL; }
+ RubyEventQueueNode(Consumer* _consumer)
+ : m_consumer_ptr(_consumer)
+ {
+ setFlags(AutoDelete);
+ }

// Destructor
//~RubyEventQueueNode();

// Public Methods
void print(ostream& out) const;
+ virtual void process() { m_consumer_ptr->wakeup(); }
+ virtual const char *description() const { return "Ruby Event"; }

- // Assignment operator and copy constructor since the default
- // constructors confuse purify when long longs are present.
- RubyEventQueueNode& operator=(const RubyEventQueueNode& obj) {
- m_time = obj.m_time;
- m_consumer_ptr = obj.m_consumer_ptr;
- return *this;
- }
-
- RubyEventQueueNode(const RubyEventQueueNode& obj) {
- m_time = obj.m_time;
- m_consumer_ptr = obj.m_consumer_ptr;
- }
private:
// Private Methods

@@ -68,8 +64,6 @@
// RubyEventQueueNode(const RubyEventQueueNode& obj);

// Data Members (m_ prefix)
-public:
- Time m_time;
Consumer* m_consumer_ptr;
};

@@ -78,14 +72,6 @@

// ******************* Definitions *******************

-inline extern bool node_less_then_eq(const RubyEventQueueNode& n1, const RubyEventQueueNode& n2);
-
-inline extern
-bool node_less_then_eq(const RubyEventQueueNode& n1, const RubyEventQueueNode& n2)
-{
- return (n1.m_time <= n2.m_time);
-}
-
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const RubyEventQueueNode& obj)
diff -r c1b464b8baad -r 1c05b3999b00 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
@@ -108,7 +108,7 @@
m_tracer_ptr = p->tracer;

//assert( g_debug_ptr != NULL);
- g_eventQueue_ptr = new RubyEventQueue(m_clock);
+ g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock);
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;
m_mem_vec_ptr->setSize(m_memory_size_bytes);
Brad Beckmann
2009-12-12 22:37:46 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID 20d225368dfe44492bde8b187f898311fb9b924e
# Parent 23ea85c0fc27eaa31f042bdc37238856ffc7769e
ruby: hit callback fix with the new config system
Made the static hit callback function public so that the sequencer can
call it.

diff -r 23ea85c0fc27 -r 20d225368dfe src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:16 2009 -0800
@@ -63,6 +63,7 @@
protected:
const string m_name;
void (*m_hit_callback)(int64_t);
+ static void ruby_hit_callback(int64_t req_id);

int64_t makeUniqueRequestID() {
// The request ID is generated by combining the port ID with a request count
@@ -104,7 +105,6 @@

typedef std::map<int64_t, RequestCookie*> RequestMap;
static RequestMap pending_requests;
- static void ruby_hit_callback(int64_t req_id);

FunctionalPort funcMemPort;
};
diff -r 23ea85c0fc27 -r 20d225368dfe src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -342,7 +342,7 @@
}
}

- m_hit_callback(srequest->id);
+ ruby_hit_callback(srequest->id);
delete srequest;
}
nathan binkert
2009-12-21 22:01:10 UTC
Permalink
Post by Brad Beckmann
# HG changeset patch
# Date 1260657436 28800
# Node ID 20d225368dfe44492bde8b187f898311fb9b924e
# Parent  23ea85c0fc27eaa31f042bdc37238856ffc7769e
ruby: hit callback fix with the new config system
Made the static hit callback function public so that the sequencer can
call it.
diff -r 23ea85c0fc27 -r 20d225368dfe src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh   Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh   Sat Dec 12 14:37:16 2009 -0800
@@ -63,6 +63,7 @@
  const string m_name;
  void (*m_hit_callback)(int64_t);
+  static void ruby_hit_callback(int64_t req_id);
  int64_t makeUniqueRequestID() {
    // The request ID is generated by combining the port ID with a request count
@@ -104,7 +105,6 @@
    typedef std::map<int64_t, RequestCookie*> RequestMap;
    static RequestMap pending_requests;
-    static void ruby_hit_callback(int64_t req_id);
    FunctionalPort funcMemPort;
 };
diff -r 23ea85c0fc27 -r 20d225368dfe src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:16 2009 -0800
@@ -342,7 +342,7 @@
    }
  }
-  m_hit_callback(srequest->id);
+  ruby_hit_callback(srequest->id);
  delete srequest;
 }
where is the definition of ruby_hit_callback? Is anythign still using
m_hit_callback?
Brad Beckmann
2009-12-12 22:37:50 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID 1e80abe5cdd5f3b768f040ed5b8f91bd65acf95e
# Parent 9bc2d1989135d514762556074847b27e503eda04
ruby: Convered ruby tracing support usage of sequencer
Modified ruby's tracing support to no longer rely on the RubySystem map
to convert a sequencer string name to a sequencer pointer. As a
temporary solution, the code uses the sim_object find function.
Eventually, we should develop a better fix.

diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/CacheRecorder.cc
--- a/src/mem/ruby/recorder/CacheRecorder.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/CacheRecorder.cc Sat Dec 12 14:37:16 2009 -0800
@@ -48,9 +48,13 @@
delete m_records_ptr;
}

-void CacheRecorder::addRecord(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time)
+void CacheRecorder::addRecord(Sequencer* sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time)
{
- m_records_ptr->insert(TraceRecord(sequencer_name, data_addr, pc_addr, type, time));
+ m_records_ptr->insert(TraceRecord(sequencer, data_addr, pc_addr, type, time));
}

int CacheRecorder::dumpRecords(string filename)
diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/CacheRecorder.hh
--- a/src/mem/ruby/recorder/CacheRecorder.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/CacheRecorder.hh Sat Dec 12 14:37:16 2009 -0800
@@ -47,6 +47,7 @@
template <class TYPE> class PrioHeap;
class Address;
class TraceRecord;
+class Sequencer;

class CacheRecorder {
public:
@@ -57,7 +58,11 @@
~CacheRecorder();

// Public Methods
- void addRecord(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time);
+ void addRecord(Sequencer* sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time);
int dumpRecords(string filename);

void print(ostream& out) const;
diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/TraceRecord.cc
--- a/src/mem/ruby/recorder/TraceRecord.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/TraceRecord.cc Sat Dec 12 14:37:16 2009 -0800
@@ -36,10 +36,15 @@
#include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/System.hh"
#include "mem/protocol/CacheMsg.hh"
+#include "sim/sim_object.hh"

-TraceRecord::TraceRecord(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time)
+TraceRecord::TraceRecord(Sequencer* _sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time)
{
- m_sequencer_name = sequencer_name;
+ m_sequencer_ptr = _sequencer;
m_data_address = data_addr;
m_pc_address = pc_addr;
m_time = time;
@@ -63,7 +68,7 @@

TraceRecord& TraceRecord::operator=(const TraceRecord& obj)
{
- m_sequencer_name = obj.m_sequencer_name;
+ m_sequencer_ptr = obj.m_sequencer_ptr;
m_time = obj.m_time;
m_data_address = obj.m_data_address;
m_pc_address = obj.m_pc_address;
@@ -73,34 +78,38 @@

void TraceRecord::issueRequest() const
{
- // Lookup sequencer pointer from system
- // Note that the chip index also needs to take into account SMT configurations
- Sequencer* sequencer_ptr = RubySystem::getSequencer(m_sequencer_name);
- assert(sequencer_ptr != NULL);
+ assert(m_sequencer_ptr != NULL);

- RubyRequest request(m_data_address.getAddress(), NULL, RubySystem::getBlockSizeBytes(), m_pc_address.getAddress(), m_type, RubyAccessMode_User);
+ RubyRequest request(m_data_address.getAddress(),
+ NULL,
+ RubySystem::getBlockSizeBytes(),
+ m_pc_address.getAddress(),
+ m_type,
+ RubyAccessMode_User);

// Clear out the sequencer
- while (!sequencer_ptr->empty()) {
+ while (!m_sequencer_ptr->empty()) {
g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 100);
}

- sequencer_ptr->makeRequest(request);
+ m_sequencer_ptr->makeRequest(request);

// Clear out the sequencer
- while (!sequencer_ptr->empty()) {
+ while (!m_sequencer_ptr->empty()) {
g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 100);
}
}

void TraceRecord::print(ostream& out) const
{
- out << "[TraceRecord: Node, " << m_sequencer_name << ", " << m_data_address << ", " << m_pc_address << ", " << m_type << ", Time: " << m_time << "]";
+ out << "[TraceRecord: Node, " << m_sequencer_ptr->name() << ", "
+ << m_data_address << ", " << m_pc_address << ", "
+ << m_type << ", Time: " << m_time << "]";
}

void TraceRecord::output(ostream& out) const
{
- out << m_sequencer_name << " ";
+ out << m_sequencer_ptr->name() << " ";
m_data_address.output(out);
out << " ";
m_pc_address.output(out);
@@ -111,7 +120,16 @@

bool TraceRecord::input(istream& in)
{
- in >> m_sequencer_name;
+ string sequencer_name;
+ in >> sequencer_name;
+
+ //
+ // The SimObject find function is slow and iterates through the
+ // simObjectList to find the sequencer pointer. Therefore, expect trace
+ // playback to be slow.
+ //
+ m_sequencer_ptr = (Sequencer*)SimObject::find(sequencer_name.c_str());
+
m_data_address.input(in);
m_pc_address.input(in);
string type;
diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/TraceRecord.hh
--- a/src/mem/ruby/recorder/TraceRecord.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/TraceRecord.hh Sat Dec 12 14:37:16 2009 -0800
@@ -49,8 +49,17 @@
class TraceRecord {
public:
// Constructors
- TraceRecord(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time);
- TraceRecord() { m_sequencer_name = ""; m_time = 0; m_type = RubyRequestType_NULL; }
+ TraceRecord(Sequencer* _sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time);
+
+ TraceRecord() {
+ m_sequencer_ptr = NULL;
+ m_time = 0;
+ m_type = RubyRequestType_NULL;
+ }

// Destructor
// ~TraceRecord();
@@ -70,7 +79,7 @@
// Private Methods

// Data Members (m_ prefix)
- string m_sequencer_name;
+ Sequencer* m_sequencer_ptr;
Time m_time;
Address m_data_address;
Address m_pc_address;
diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/Tracer.cc
--- a/src/mem/ruby/recorder/Tracer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/Tracer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -89,10 +89,14 @@
}
}

-void Tracer::traceRequest(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time)
+void Tracer::traceRequest(Sequencer* sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time)
{
assert(m_enabled == true);
- TraceRecord tr(sequencer_name, data_addr, pc_addr, type, time);
+ TraceRecord tr(sequencer, data_addr, pc_addr, type, time);
tr.output(m_trace_file);
}

diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/recorder/Tracer.hh
--- a/src/mem/ruby/recorder/Tracer.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/recorder/Tracer.hh Sat Dec 12 14:37:16 2009 -0800
@@ -52,6 +52,7 @@
template <class TYPE> class PrioHeap;
class Address;
class TraceRecord;
+class Sequencer;

class Tracer : public SimObject {
public:
@@ -67,7 +68,11 @@
void startTrace(string filename);
void stopTrace();
bool traceEnabled() { return m_enabled; }
- void traceRequest(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time);
+ void traceRequest(Sequencer* sequencer,
+ const Address& data_addr,
+ const Address& pc_addr,
+ RubyRequestType type,
+ Time time);

void print(ostream& out) const;

diff -r 9bc2d1989135 -r 1e80abe5cdd5 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -472,7 +472,7 @@
}

if (g_system_ptr->getTracer()->traceEnabled()) {
- g_system_ptr->getTracer()->traceRequest(m_name, line_addr, Address(request.pc),
+ g_system_ptr->getTracer()->traceRequest(this, line_addr, Address(request.pc),
request.type, g_eventQueue_ptr->getTime());
}
Brad Beckmann
2009-12-12 22:37:43 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID 3518bdc98c5697d49bc20c3955e2013977f1e6c8
# Parent 1c05b3999b00f4bb3fc0558bf0304f8a5cf3a78a
ruby: Added the cache profiler to the new config system

diff -r 1c05b3999b00 -r 3518bdc98c56 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
@@ -115,10 +115,14 @@
# Eventually this code should go in a python file specific to the
# MOESI_hammer protocol
#
-
- l1i_cache = L1Cache()
- l1d_cache = L1Cache()
- l2_cache = L2Cache()
+ l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i))
+ l1i_cache = L1Cache(cache_profiler = l1i_profiler)
+
+ l1d_profiler = CacheProfiler(description = ("l1d_%s_profiler" % i))
+ l1d_cache = L1Cache(cache_profiler = l1d_profiler)
+
+ l2_profiler = CacheProfiler(description = ("l2_%s_profiler" % i))
+ l2_cache = L2Cache(cache_profiler = l2_profiler)

cpu_seq = RubySequencer(icache = l1i_cache,
dcache = l1d_cache,
diff -r 1c05b3999b00 -r 3518bdc98c56 src/mem/ruby/profiler/CacheProfiler.cc
--- a/src/mem/ruby/profiler/CacheProfiler.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/profiler/CacheProfiler.cc Sat Dec 12 14:37:16 2009 -0800
@@ -43,10 +43,10 @@
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/gems_common/Vector.hh"

-CacheProfiler::CacheProfiler(string description)
- : m_requestSize(-1)
+CacheProfiler::CacheProfiler(const CacheProfilerParams* params)
+ : SimObject(params), m_requestSize(-1)
{
- m_description = description;
+ m_description = params->description;
m_requestTypeVec_ptr = new Vector<int>;
m_requestTypeVec_ptr->setSize(int(CacheRequestType_NUM));

@@ -141,3 +141,8 @@
}
}

+CacheProfiler *
+CacheProfilerParams::create()
+{
+ return new CacheProfiler(this);
+}
diff -r 1c05b3999b00 -r 3518bdc98c56 src/mem/ruby/profiler/CacheProfiler.hh
--- a/src/mem/ruby/profiler/CacheProfiler.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/profiler/CacheProfiler.hh Sat Dec 12 14:37:16 2009 -0800
@@ -46,12 +46,15 @@
#include "mem/protocol/PrefetchBit.hh"
#include "mem/protocol/CacheRequestType.hh"

+#include "params/CacheProfiler.hh"
+
template <class TYPE> class Vector;

-class CacheProfiler {
+class CacheProfiler : public SimObject {
public:
// Constructors
- CacheProfiler(string description);
+ typedef CacheProfilerParams Params;
+ CacheProfiler(const Params *);

// Destructor
~CacheProfiler();
diff -r 1c05b3999b00 -r 3518bdc98c56 src/mem/ruby/profiler/Profiler.py
--- a/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:16 2009 -0800
@@ -6,3 +6,8 @@
cxx_class = 'Profiler'
hot_lines = Param.Bool(False, "")
all_instructions = Param.Bool(False, "")
+
+class CacheProfiler(SimObject):
+ type = 'CacheProfiler'
+ cxx_class = 'CacheProfiler'
+ description = Param.String("")
diff -r 1c05b3999b00 -r 3518bdc98c56 src/mem/ruby/system/Cache.py
--- a/src/mem/ruby/system/Cache.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Cache.py Sat Dec 12 14:37:16 2009 -0800
@@ -9,3 +9,4 @@
latency = Param.Int("");
assoc = Param.Int("");
replacement_policy = Param.String("PSEUDO_LRU", "");
+ cache_profiler = Param.CacheProfiler("");
diff -r 1c05b3999b00 -r 3518bdc98c56 src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.cc Sat Dec 12 14:37:16 2009 -0800
@@ -58,6 +58,7 @@
m_latency = p->latency;
m_cache_assoc = p->assoc;
m_policy = p->replacement_policy;
+ m_profiler_ptr = p->cache_profiler;
}


@@ -363,7 +364,7 @@
void CacheMemory::profileMiss(const CacheMsg & msg)
{
m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
- msg.getSize(), msg.getPrefetch());
+ msg.getSize(), msg.getPrefetch());
}

void CacheMemory::recordCacheContents(CacheRecorder& tr) const
Brad Beckmann
2009-12-12 22:37:47 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID cae9a08951751d7556ee4cc37a29824e23848b65
# Parent 20d225368dfe44492bde8b187f898311fb9b924e
ruby: sequencer deadlock check fix
Fixed the sequencer deadlock check m5 event

diff -r 20d225368dfe -r cae9a0895175 src/mem/ruby/eventqueue/RubyEventQueue.hh
--- a/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:16 2009 -0800
@@ -79,6 +79,7 @@
// Public Methods

Time getTime() const { return curTick/m_clock; }
+ Tick getClock() const { return m_clock; }
void scheduleEvent(Consumer* consumer, Time timeDelta);
void scheduleEventAbsolute(Consumer* consumer, Time timeAbs);
void print(ostream& out) const;
diff -r 20d225368dfe -r cae9a0895175 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -128,7 +128,8 @@
assert(m_outstanding_count == total_outstanding);

if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
- schedule(deadlockCheckEvent, m_deadlock_threshold);
+ schedule(deadlockCheckEvent,
+ (m_deadlock_threshold * g_eventQueue_ptr->getClock()) + curTick);
//g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
} // else {
// m_deadlock_check_scheduled = false;
Brad Beckmann
2009-12-12 22:37:51 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID d9f2104b2c11b32657c6fd30623a2a881a6e93ed
# Parent 1e80abe5cdd5f3b768f040ed5b8f91bd65acf95e
ruby: Removed out_link_vec from Consumer
Removed the out_line_vec data structure from the Consumer. I'm not sure
what this did before, but currently it has no usefulness.

diff -r 1e80abe5cdd5 -r d9f2104b2c11 src/mem/ruby/common/Consumer.hh
--- a/src/mem/ruby/common/Consumer.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/common/Consumer.hh Sat Dec 12 14:37:16 2009 -0800
@@ -47,7 +47,7 @@
class Consumer {
public:
// Constructors
- Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; m_out_link_vec.setSize(0); }
+ Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; }

// Destructor
virtual ~Consumer() { }
@@ -59,10 +59,6 @@
virtual void print(ostream& out) const = 0;
const Time& getLastScheduledWakeup() const { return m_last_scheduled_wakeup; }
void setLastScheduledWakeup(const Time& time) { m_last_scheduled_wakeup = time; }
- Vector< Vector<MessageBuffer*> > getOutBuffers() { return m_out_link_vec; }
-
-protected:
- Vector< Vector<MessageBuffer*> > m_out_link_vec;

private:
// Private Methods
diff -r 1e80abe5cdd5 -r d9f2104b2c11 src/mem/ruby/network/simple/PerfectSwitch.cc
--- a/src/mem/ruby/network/simple/PerfectSwitch.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/network/simple/PerfectSwitch.cc Sat Dec 12 14:37:16 2009 -0800
@@ -88,7 +88,6 @@
m_out.insertAtBottom(out);
m_routing_table.insertAtBottom(routing_table_entry);

- m_out_link_vec.insertAtBottom(out);
}

void PerfectSwitch::clearRoutingTables()
diff -r 1e80abe5cdd5 -r d9f2104b2c11 src/mem/ruby/network/simple/Throttle.cc
--- a/src/mem/ruby/network/simple/Throttle.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/network/simple/Throttle.cc Sat Dec 12 14:37:16 2009 -0800
@@ -102,8 +102,6 @@
m_message_counters[i][j] = 0;
}
}
-
- m_out_link_vec.insertAtBottom(out_vec);
}

void Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
Brad Beckmann
2009-12-12 22:37:49 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID 9bc2d1989135d514762556074847b27e503eda04
# Parent d0e96be22141976017c9d11e942be11587b8e4e2
ruby: removed some commented out code
Removed some commented out code from the sequencer and system that is
no longer needed with the new configuration system.

diff -r d0e96be22141 -r 9bc2d1989135 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:16 2009 -0800
@@ -62,7 +62,6 @@
Sequencer::Sequencer(const Params *p)
: RubyPort(p), deadlockCheckEvent(this)
{
- //m_deadlock_check_scheduled = false;
m_outstanding_count = 0;

m_max_outstanding_requests = 0;
@@ -130,10 +129,7 @@
if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
schedule(deadlockCheckEvent,
(m_deadlock_threshold * g_eventQueue_ptr->getClock()) + curTick);
- //g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
- } // else {
-// m_deadlock_check_scheduled = false;
-// }
+ }
}

void Sequencer::printProgress(ostream& out) const{
@@ -195,10 +191,6 @@
if (deadlockCheckEvent.scheduled() == false) {
schedule(deadlockCheckEvent, m_deadlock_threshold);
}
-// if (m_deadlock_check_scheduled == false) {
-// g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
-// m_deadlock_check_scheduled = true;
-// }

Address line_addr(request->ruby_request.paddr);
line_addr.makeLineAddress();
diff -r d0e96be22141 -r 9bc2d1989135 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:16 2009 -0800
@@ -107,127 +107,10 @@
m_profiler_ptr = p->profiler;
m_tracer_ptr = p->tracer;

- //assert( g_debug_ptr != NULL);
g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock);
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;
m_mem_vec_ptr->setSize(m_memory_size_bytes);
-
- /* 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
- */
-
-#if 0
- 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);
- }
-#endif
}
nathan binkert
2009-12-21 22:02:42 UTC
Permalink
Again, a fold would be nicer.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657436 28800
# Node ID 9bc2d1989135d514762556074847b27e503eda04
# Parent  d0e96be22141976017c9d11e942be11587b8e4e2
ruby: removed some commented out code
Removed some commented out code from the sequencer and system that is
no longer needed with the new configuration system.
diff -r d0e96be22141 -r 9bc2d1989135 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc  Sat Dec 12 14:37:16 2009 -0800
@@ -62,7 +62,6 @@
 Sequencer::Sequencer(const Params *p)
    : RubyPort(p), deadlockCheckEvent(this)
 {
-  //m_deadlock_check_scheduled = false;
    m_outstanding_count = 0;
    m_max_outstanding_requests = 0;
@@ -130,10 +129,7 @@
  if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
    schedule(deadlockCheckEvent,
             (m_deadlock_threshold * g_eventQueue_ptr->getClock()) + curTick);
-    //g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
-  } // else {
-//     m_deadlock_check_scheduled = false;
-//   }
+  }
 }
 void Sequencer::printProgress(ostream& out) const{
@@ -195,10 +191,6 @@
  if (deadlockCheckEvent.scheduled() == false) {
    schedule(deadlockCheckEvent, m_deadlock_threshold);
  }
-//   if (m_deadlock_check_scheduled == false) {
-//     g_eventQueue_ptr->scheduleEvent(this, m_deadlock_threshold);
-//     m_deadlock_check_scheduled = true;
-//   }
  Address line_addr(request->ruby_request.paddr);
  line_addr.makeLineAddress();
diff -r d0e96be22141 -r 9bc2d1989135 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc     Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/System.cc     Sat Dec 12 14:37:16 2009 -0800
@@ -107,127 +107,10 @@
    m_profiler_ptr = p->profiler;
    m_tracer_ptr = p->tracer;
-    //assert( g_debug_ptr != NULL);
    g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock);
    g_system_ptr = this;
    m_mem_vec_ptr = new MemoryVector;
    m_mem_vec_ptr->setSize(m_memory_size_bytes);
-
-  /* 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
-   */
-
-#if 0
-  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);
-  }
-#endif
 }
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:52 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID fa98d755bc7afb680785e9fb2cb711c42514b815
# Parent d9f2104b2c11b32657c6fd30623a2a881a6e93ed
ruby: Added pio port support to Ruby Port
Added a pio port to RubyPort so that pio requests from the cpus can be
routed to m5 devices. The code compiles, but has not yet been tested.

diff -r d9f2104b2c11 -r fa98d755bc7a src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:17 2009 -0800
@@ -2,10 +2,9 @@
#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::RequestMap RubyPort::pending_requests;
+RubyPort::RequestMap RubyPort::pending_cpu_requests;

RubyPort::RubyPort(const Params *p)
: MemObject(p),
@@ -20,6 +19,7 @@
m_port_id = m_num_ports++;
m_request_cnt = 0;
m_hit_callback = NULL;
+ pio_port = NULL;
assert(m_num_ports <= 2048); // see below for reason
}

@@ -34,21 +34,47 @@
{
if (if_name == "port") {
return new M5Port(csprintf("%s-port%d", name(), idx), this);
+ } else if (if_name == "pio_port") {
+ //
+ // ensure there is only one pio port
+ //
+ assert(pio_port == NULL);
+
+ pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx),
+ this);
+
+ return pio_port;
} else if (if_name == "funcmem_port") {
return &funcMemPort;
}
return NULL;
}

+RubyPort::PioPort::PioPort(const std::string &_name,
+ RubyPort *_port)
+ : SimpleTimingPort(_name, _port)
+{
+ DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name);
+ ruby_port = _port;
+}
+
RubyPort::M5Port::M5Port(const std::string &_name,
RubyPort *_port)
: SimpleTimingPort(_name, _port)
{
- DPRINTF(Ruby, "creating port to ruby memory %s\n", _name);
+ DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name);
ruby_port = _port;
}

Tick
+RubyPort::PioPort::recvAtomic(PacketPtr pkt)
+{
+ panic("RubyPort::PioPort::recvAtomic() not implemented!\n");
+ return 0;
+}
+
+
+Tick
RubyPort::M5Port::recvAtomic(PacketPtr pkt)
{
panic("RubyPort::M5Port::recvAtomic() not implemented!\n");
@@ -57,6 +83,36 @@


bool
+RubyPort::PioPort::recvTiming(PacketPtr pkt)
+{
+ //
+ // In FS mode, ruby memory will receive pio responses from devices and
+ // it must forward these responses back to the particular CPU.
+ //
+ DPRINTF(MemoryAccess,
+ "Pio response for address %#x\n",
+ pkt->getAddr());
+
+ assert(pkt->isResponse());
+
+ //
+ // First we must retrieve the request port from the sender State
+ //
+ RubyPort::SenderState *senderState =
+ safe_cast<RubyPort::SenderState *>(pkt->senderState);
+ M5Port *port = senderState->port;
+ assert(port != NULL);
+
+ // pop the sender state from the packet
+ pkt->senderState = senderState->saved;
+ delete senderState;
+
+ port->sendTiming(pkt);
+
+ return true;
+}
+
+bool
RubyPort::M5Port::recvTiming(PacketPtr pkt)
{
DPRINTF(MemoryAccess,
@@ -66,28 +122,6 @@
//dsm: based on SimpleTimingPort::recvTiming(pkt);

//
- // In FS mode, ruby memory will receive pio responses from devices and
- // it must forward these responses back to the particular CPU.
- //
-#if 0
- if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) {
- DPRINTF(MemoryAccess,
- "Pio Response callback %#x\n",
- pkt->getAddr());
- SenderState *senderState = safe_cast<SenderState *>(pkt->senderState);
- M5Port *port = senderState->port;
-
- // pop the sender state from the packet
- pkt->senderState = senderState->saved;
- delete senderState;
-
- port->sendTiming(pkt);
-
- return true;
- }
-#endif
-
- //
// After checking for pio responses, the remainder of packets
// received by ruby should only be M5 requests, which should never
// get nacked. There used to be code to hanldle nacks here, but
@@ -106,13 +140,19 @@

//
// Check for pio requests and directly send them to the dedicated
- // pio_port.
+ // pio port.
//
-#if 0
- if (isPioAddress(pkt->getAddr()) != false) {
- return ruby_mem->pio_port->sendTiming(pkt);
+ if (!isPhysMemAddress(pkt->getAddr())) {
+ assert(ruby_port->pio_port != NULL);
+
+ //
+ // Save the port in the sender state object to be used later to
+ // route the response
+ //
+ pkt->senderState = new SenderState(this, pkt->senderState);
+
+ return ruby_port->pio_port->sendTiming(pkt);
}
-#endif

//
// For DMA and CPU requests, translate them to ruby requests before
@@ -144,7 +184,7 @@
}

// Save the request for the callback
- RubyPort::pending_requests[req_id] = new RequestCookie(pkt, this);
+ RubyPort::pending_cpu_requests[req_id] = new RequestCookie(pkt, this);

return true;
}
@@ -154,16 +194,14 @@
{
//
// Note: This single fuction can be called by cpu and dma ports,
- // as well as the functional port. The functional port prevents
- // us from replacing this single function with separate port
- // functions.
+ // as well as the functional port.
//
- RequestMap::iterator i = pending_requests.find(req_id);
- if (i == pending_requests.end())
+ RequestMap::iterator i = pending_cpu_requests.find(req_id);
+ if (i == pending_cpu_requests.end())
panic("could not find pending request %d\n", req_id);

RequestCookie *cookie = i->second;
- pending_requests.erase(i);
+ pending_cpu_requests.erase(i);

Packet *pkt = cookie->pkt;
M5Port *port = cookie->m5Port;
@@ -204,24 +242,50 @@
}

bool
+RubyPort::PioPort::sendTiming(PacketPtr pkt)
+{
+ schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
+ return true;
+}
+
+bool
+RubyPort::M5Port::isPhysMemAddress(Addr addr)
+{
+ AddrRangeList physMemAddrList;
+ bool snoop = false;
+ ruby_port->funcMemPort.getPeerAddressRanges(physMemAddrList, snoop);
+ for(AddrRangeIter iter = physMemAddrList.begin();
+ iter != physMemAddrList.end();
+ iter++) {
+ if (addr >= iter->start && addr <= iter->end) {
+ DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n",
+ iter->start, iter->end);
+ return true;
+ }
+ }
+ assert(isPioAddress(addr));
+ return false;
+}
+
+bool
RubyPort::M5Port::isPioAddress(Addr addr)
{
-#if 0
AddrRangeList pioAddrList;
bool snoop = false;
- if (ruby_mem->pio_port == NULL) {
+ if (ruby_port->pio_port == NULL) {
return false;
}

- ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop);
- for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) {
+ ruby_port->pio_port->getPeerAddressRanges(pioAddrList, snoop);
+ for(AddrRangeIter iter = pioAddrList.begin();
+ iter != pioAddrList.end();
+ iter++) {
if (addr >= iter->start && addr <= iter->end) {
DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
iter->start, iter->end);
return true;
}
}
-#endif
return false;
}

diff -r d9f2104b2c11 -r fa98d755bc7a src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:17 2009 -0800
@@ -35,10 +35,39 @@

private:
bool isPioAddress(Addr addr);
+ bool isPhysMemAddress(Addr addr);
};

friend class M5Port;

+ class PioPort : public SimpleTimingPort
+ {
+
+ RubyPort *ruby_port;
+
+ public:
+ PioPort(const std::string &_name,
+ RubyPort *_port);
+ bool sendTiming(PacketPtr pkt);
+
+ protected:
+ virtual bool recvTiming(PacketPtr pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
+ };
+
+ friend class PioPort;
+
+ struct SenderState : public Packet::SenderState
+ {
+ M5Port* port;
+ Packet::SenderState *saved;
+
+ SenderState(M5Port* _port,
+ Packet::SenderState *sender_state = NULL)
+ : port(_port), saved(sender_state)
+ {}
+ };
+
typedef RubyPortParams Params;
RubyPort(const Params *p);
virtual ~RubyPort() {}
@@ -89,6 +118,7 @@
int m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
+ PioPort* pio_port;

private:
static uint16_t m_num_ports;
@@ -104,7 +134,7 @@
};

typedef std::map<int64_t, RequestCookie*> RequestMap;
- static RequestMap pending_requests;
+ static RequestMap pending_cpu_requests;

FunctionalPort funcMemPort;
};
diff -r d9f2104b2c11 -r fa98d755bc7a src/mem/ruby/system/Sequencer.py
--- a/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:17 2009 -0800
@@ -7,6 +7,7 @@
abstract = True
port = VectorPort("M5 port")
version = Param.Int(0, "")
+ pio_port = Port("Ruby_pio_port")

class RubySequencer(RubyPort):
type = 'RubySequencer'
Brad Beckmann
2009-12-12 22:37:54 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID efe0dabd91852d85b6301852dd9737fa5e8ee2f1
# Parent 70be840d4d3d6c1e115c32379ff3c80068ef53f5
ruby: FS support using the new configuration system

diff -r 70be840d4d3d -r efe0dabd9185 configs/common/FSConfig.py
--- a/configs/common/FSConfig.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/common/FSConfig.py Sat Dec 12 14:37:17 2009 -0800
@@ -79,14 +79,14 @@

return self

-def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None):
+def makeLinuxAlphaRubySystem(mem_mode, phys_mem, mdesc = None):
class BaseTsunami(Tsunami):
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
pci_func=0, pci_dev=0, pci_bus=0)


- self = LinuxAlphaSystem(physmem = rubymem)
+ self = LinuxAlphaSystem(physmem = phys_mem)
if not mdesc:
# generic system
mdesc = SysConfig()
@@ -104,13 +104,11 @@
self.tsunami.ide.pio = self.piobus.port
self.tsunami.ethernet.pio = self.piobus.port

- # connect the dma ports directly to ruby dma ports
- self.tsunami.ide.dma = self.physmem.dma_port
- self.tsunami.ethernet.dma = self.physmem.dma_port
+ #
+ # store the dma devices for later connection to dma ruby ports
+ #
+ self.dma_devices = [self.tsunami.ide, self.tsunami.ethernet]

- # connect the pio bus to rubymem
- self.physmem.pio_port = self.piobus.port
-
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
read_only = True))
self.intrctrl = IntrControl()
diff -r 70be840d4d3d -r efe0dabd9185 configs/common/Options.py
--- a/configs/common/Options.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/common/Options.py Sat Dec 12 14:37:17 2009 -0800
@@ -34,7 +34,9 @@
parser.add_option("--caches", action="store_true")
parser.add_option("--l2cache", action="store_true")
parser.add_option("--fastmem", action="store_true")
-
+parser.add_option("--clock", action="store", type="string", default='1GHz')
+parser.add_option("--num-dirs", type="int", default=1)
+
# Run duration options
parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
metavar="T",
diff -r 70be840d4d3d -r efe0dabd9185 configs/example/ruby_fs.py
--- a/configs/example/ruby_fs.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/example/ruby_fs.py Sat Dec 12 14:37:17 2009 -0800
@@ -43,10 +43,10 @@
if not buildEnv['FULL_SYSTEM']:
panic("This script requires full-system mode (*_FS).")

-addToPath('../../tests/configs/')
addToPath('../common')
+addToPath('../ruby')

-import ruby_config
+import Ruby

from FSConfig import *
from SysPaths import *
@@ -114,87 +114,25 @@
test_mem_mode = 'timing'
FutureClass = None

-CPUClass.clock = '1GHz'
+CPUClass.clock = options.clock

-#
-# Since we are running in timing mode, set the number of M5 ticks to ruby ticks
-# to the cpu clock frequency
-#
-M5_to_ruby_tick = '1000t'
+physmem = PhysicalMemory()

-np = options.num_cpus
+system = makeLinuxAlphaRubySystem(test_mem_mode, physmem, bm[0])

-# check for max instruction count
-if options.max_inst:
- max_inst = options.max_inst
-else:
- max_inst = 0
-
-# set cache size
-if options.cache_size:
- cache_size = options.cache_size
-else:
- cache_size = 32768 # 32 kB is default
-
-# set cache assoc
-if options.cache_assoc:
- cache_assoc = options.cache_assoc
-else:
- cache_assoc = 8 # 8 is default
-
-# set map levels
-if options.map_levels:
- map_levels = options.map_levels
-else:
- map_levels = 4 # 4 levels is the default
+system.ruby = Ruby.create_system(options,
+ physmem,
+ system.piobus,
+ system.dma_devices)

-if options.protocol == "MOESI_hammer":
- ruby_config_file = "MOESI_hammer-homogeneous.rb"
-elif options.protocol == "MOESI_CMP_token":
- ruby_config_file = "TwoLevel_SplitL1UnifiedL2.rb"
-elif options.protocol == "MI_example":
- ruby_config_file = "MI_example-homogeneous.rb"
-else:
- print "Error: unsupported ruby protocol"
- sys.exit(1)
+system.cpu = [CPUClass(cpu_id=i) for i in xrange(options.num_cpus)]

-#
-# Currently, since ruby configuraiton is separate from m5, we need to manually
-# tell ruby that two dma ports are created by makeLinuxAlphaRubySystem().
-# Eventually, this will be fix with a unified configuration system.
-#
-rubymem = ruby_config.generate(ruby_config_file,
- np,
- np,
- 128,
- False,
- cache_size,
- cache_assoc,
- map_levels,
- 2,
- M5_to_ruby_tick)
-
-if options.ruby_debug == True:
- rubymem.debug = True
- rubymem.debug_file = options.ruby_debug_file
-
-system = makeLinuxAlphaRubySystem(test_mem_mode, rubymem, bm[0])
-
-system.cpu = [CPUClass(cpu_id=i) for i in xrange(np)]
-
-if options.l2cache:
- print "Error: -l2cache incompatible with ruby, must configure it ruby-style"
- sys.exit(1)
-
-if options.caches:
- print "Error: -caches incompatible with ruby, must configure it ruby-style"
- sys.exit(1)
-
-for i in xrange(np):
- system.cpu[i].connectMemPorts(system.physmem)
-
- if options.fastmem:
- system.cpu[i].physmem_port = system.physmem.port
+for (i, cpu) in enumerate(system.cpu):
+ #
+ # Tie the cpu ports to the correct ruby system ports
+ #
+ cpu.icache_port = system.ruby.cpu_ruby_ports[i].port
+ cpu.dcache_port = system.ruby.cpu_ruby_ports[i].port

root = Root(system = system)

diff -r 70be840d4d3d -r efe0dabd9185 configs/ruby/MOESI_hammer.py
--- a/configs/ruby/MOESI_hammer.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/ruby/MOESI_hammer.py Sat Dec 12 14:37:17 2009 -0800
@@ -32,7 +32,6 @@
from m5.defines import buildEnv
from m5.util import addToPath

-
class L1Cache(RubyCache):
assoc = 2
latency = 3
@@ -43,12 +42,14 @@
latency = 15
size = 1048576

-def create_system(options, physmem):
+def create_system(options, phys_mem, piobus, dma_devices):

if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be built.")

- sequencers = []
+ sequencers_map = {"cpu": [],
+ "dma": []}
+
#
# The ruby network creation expects the list of nodes in the system to be
# consistent with the NetDest list. Therefore the l1 controller nodes must be
@@ -62,11 +63,10 @@
# Must create the individual controllers before the network to ensure the
# controller constructors are called before the network constructor
#
- for i in range(options.num_cpus):
+
+ for i in xrange(options.num_cpus):
#
# First create the Ruby objects associated with this cpu
- # Eventually this code should go in a python file specific to the
- # MOESI_hammer protocol
#
l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i))
l1i_cache = L1Cache(cache_profiler = l1i_profiler)
@@ -79,13 +79,27 @@

cpu_seq = RubySequencer(icache = l1i_cache,
dcache = l1d_cache,
- funcmem_port = physmem.port)
+ physMemPort = phys_mem.port,
+ physmem = phys_mem)
+
+ if piobus != None:
+ cpu_seq.pio_port = piobus.port

l1_cntrl = L1Cache_Controller(version = i,
sequencer = cpu_seq,
L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache,
L2cacheMemory = l2_cache)
+ #
+ # Add controllers and sequencers to the appropriate lists
+ #
+ sequencers_map["cpu"].append(cpu_seq)
+ l1_cntrl_nodes.append(l1_cntrl)
+
+ for i in xrange(options.num_dirs):
+ #
+ # Create the Ruby objects associated with the directory controller
+ #

mem_cntrl = RubyMemoryControl(version = i)

@@ -93,19 +107,23 @@
directory = RubyDirectoryMemory(),
memBuffer = mem_cntrl)

+ dir_cntrl_nodes.append(dir_cntrl)
+
+ for i, dma_device in enumerate(dma_devices):
+ #
+ # Create the Ruby objects associated with the dma controller
+ #
+ dma_seq = DMASequencer(version = i,
+ physMemPort = phys_mem.port,
+ physmem = phys_mem)
+
dma_cntrl = DMA_Controller(version = i,
- dma_sequencer = DMASequencer())
+ dma_sequencer = dma_seq)

- #
- # Add controllers and sequencers to the appropriate lists
- # As noted above: Independent list are track to maintain the order of
- # nodes/controllers assumed by the ruby network
- #
- sequencers.append(cpu_seq)
- l1_cntrl_nodes.append(l1_cntrl)
- dir_cntrl_nodes.append(dir_cntrl)
+ dma_cntrl.dma_sequencer.port = dma_device.dma
dma_cntrl_nodes.append(dma_cntrl)
+ sequencers_map["dma"].append(dma_seq)

all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes

- return (sequencers, dir_cntrl_nodes, all_cntrls)
+ return (sequencers_map, dir_cntrl_nodes, all_cntrls)
diff -r 70be840d4d3d -r efe0dabd9185 configs/ruby/Ruby.py
--- a/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
@@ -68,7 +68,7 @@
ranks_per_dimm = ranksPerDimm,
dimms_per_channel = dimmsPerChannel)

- ruby = RubySystem(clock = '1GHz',
+ ruby = RubySystem(clock = options.clock,
network = network,
profiler = ruby_profiler,
tracer = RubyTracer(),
diff -r 70be840d4d3d -r efe0dabd9185 src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:17 2009 -0800
@@ -7,12 +7,13 @@
RubyPort::RequestMap RubyPort::pending_cpu_requests;

RubyPort::RubyPort(const Params *p)
- : MemObject(p),
- funcMemPort(csprintf("%s-funcmem_port", name()), this)
+ : MemObject(p)
{
m_version = p->version;
assert(m_version != -1);

+ physmem = p->physmem;
+
m_controller = NULL;
m_mandatory_q_ptr = NULL;

@@ -20,6 +21,7 @@
m_request_cnt = 0;
m_hit_callback = NULL;
pio_port = NULL;
+ physMemPort = NULL;
assert(m_num_ports <= 2048); // see below for reason
}

@@ -44,8 +46,23 @@
this);

return pio_port;
- } else if (if_name == "funcmem_port") {
- return &funcMemPort;
+ } else if (if_name == "physMemPort") {
+ //
+ // RubyPort should only have one port to physical memory
+ //
+ assert (physMemPort == NULL);
+
+ physMemPort = new M5Port(csprintf("%s-physMemPort", name()),
+ this);
+
+ return physMemPort;
+ } else if (if_name == "functional") {
+ //
+ // Calls for the functional port only want to access functional memory.
+ // Therefore, directly pass these calls ports to physmem.
+ //
+ assert(physmem != NULL);
+ return physmem->getPort(if_name, idx);
}
return NULL;
}
@@ -219,11 +236,11 @@
DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
needsResponse);

- ruby_port->funcMemPort.sendFunctional(pkt);
+ ruby_port->physMemPort->sendAtomic(pkt);

// turn packet around to go back to requester if response expected
if (needsResponse) {
- // recvAtomic() should already have turned packet into
+ // sendAtomic() should already have turned packet into
// atomic response
assert(pkt->isResponse());
DPRINTF(MemoryAccess, "Sending packet back over port\n");
@@ -253,7 +270,7 @@
{
AddrRangeList physMemAddrList;
bool snoop = false;
- ruby_port->funcMemPort.getPeerAddressRanges(physMemAddrList, snoop);
+ ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
for(AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end();
iter++) {
@@ -263,29 +280,5 @@
return true;
}
}
- assert(isPioAddress(addr));
return false;
}
-
-bool
-RubyPort::M5Port::isPioAddress(Addr addr)
-{
- AddrRangeList pioAddrList;
- bool snoop = false;
- if (ruby_port->pio_port == NULL) {
- return false;
- }
-
- ruby_port->pio_port->getPeerAddressRanges(pioAddrList, snoop);
- for(AddrRangeIter iter = pioAddrList.begin();
- iter != pioAddrList.end();
- iter++) {
- if (addr >= iter->start && addr <= iter->end) {
- DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
- iter->start, iter->end);
- return true;
- }
- }
- return false;
-}
-
diff -r 70be840d4d3d -r efe0dabd9185 src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:17 2009 -0800
@@ -7,6 +7,7 @@

#include "mem/mem_object.hh"
#include "mem/tport.hh"
+#include "mem/physical.hh"

#include "params/RubyPort.hh"

@@ -34,7 +35,6 @@
virtual Tick recvAtomic(PacketPtr pkt);

private:
- bool isPioAddress(Addr addr);
bool isPhysMemAddress(Addr addr);
};

@@ -136,7 +136,9 @@
typedef std::map<int64_t, RequestCookie*> RequestMap;
static RequestMap pending_cpu_requests;

- FunctionalPort funcMemPort;
+ M5Port* physMemPort;
+
+ PhysicalMemory* physmem;
};

#endif
diff -r 70be840d4d3d -r efe0dabd9185 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:17 2009 -0800
@@ -189,7 +189,7 @@

// See if we should schedule a deadlock check
if (deadlockCheckEvent.scheduled() == false) {
- schedule(deadlockCheckEvent, m_deadlock_threshold);
+ schedule(deadlockCheckEvent, m_deadlock_threshold + curTick);
}

Address line_addr(request->ruby_request.paddr);
diff -r 70be840d4d3d -r efe0dabd9185 src/mem/ruby/system/Sequencer.py
--- a/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:17 2009 -0800
@@ -8,6 +8,8 @@
port = VectorPort("M5 port")
version = Param.Int(0, "")
pio_port = Port("Ruby_pio_port")
+ physmem = Param.PhysicalMemory("")
+ physMemPort = Port("port to physical memory")

class RubySequencer(RubyPort):
type = 'RubySequencer'
@@ -16,7 +18,6 @@
dcache = Param.RubyCache("")
max_outstanding_requests = Param.Int(16, "")
deadlock_threshold = Param.Int(500000, "")
- funcmem_port = Port("port to functional memory")

class DMASequencer(RubyPort):
type = 'DMASequencer'
Brad Beckmann
2009-12-12 22:37:58 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID d52040d526f6620587296985f441c824f6b352eb
# Parent a47f0bcef634e82f98f1f35f3aef3d08f8420d22
ruby: Removed RubySystem::getNumberOfSequencers
removed the static function RubySystem::getNumberOfSequencers and replaced
it with a python config variable

diff -r a47f0bcef634 -r d52040d526f6 configs/ruby/Ruby.py
--- a/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
+++ b/configs/ruby/Ruby.py Sat Dec 12 14:37:17 2009 -0800
@@ -66,7 +66,8 @@
ranksPerDimm = dir_cntrls[0].memBuffer.ranks_per_dimm
dimmsPerChannel = dir_cntrls[0].memBuffer.dimms_per_channel

- ruby_profiler = RubyProfiler(mem_cntrl_count = mcCount,
+ ruby_profiler = RubyProfiler(num_of_sequencers = len(cpu_sequencers),
+ mem_cntrl_count = mcCount,
banks_per_rank = banksPerRank,
ranks_per_dimm = ranksPerDimm,
dimms_per_channel = dimmsPerChannel)
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/common/Set.cc
--- a/src/mem/ruby/common/Set.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/common/Set.cc Sat Dec 12 14:37:17 2009 -0800
@@ -51,7 +51,8 @@
Set::Set()
{
m_p_nArray = NULL;
- setSize(RubySystem::getNumberOfSequencers());
+ m_nArrayLen = 0;
+ m_nSize = 0;
}

// copy constructor
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/profiler/AddressProfiler.cc
--- a/src/mem/ruby/profiler/AddressProfiler.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/profiler/AddressProfiler.cc Sat Dec 12 14:37:17 2009 -0800
@@ -45,15 +45,22 @@
#include "mem/ruby/profiler/Profiler.hh"

// Helper functions
-static AccessTraceForAddress& lookupTraceForAddress(const Address& addr, Map<Address, AccessTraceForAddress>* record_map);
-static void printSorted(ostream& out, const Map<Address, AccessTraceForAddress>* record_map, string description);
+static AccessTraceForAddress& lookupTraceForAddress(const Address& addr,
+ Map<Address,
+ AccessTraceForAddress>* record_map);

-AddressProfiler::AddressProfiler()
+static void printSorted(ostream& out,
+ int num_of_sequencers,
+ const Map<Address, AccessTraceForAddress>* record_map,
+ string description);
+
+AddressProfiler::AddressProfiler(int num_of_sequencers)
{
m_dataAccessTrace = new Map<Address, AccessTraceForAddress>;
m_macroBlockAccessTrace = new Map<Address, AccessTraceForAddress>;
m_programCounterAccessTrace = new Map<Address, AccessTraceForAddress>;
m_retryProfileMap = new Map<Address, AccessTraceForAddress>;
+ m_num_of_sequencers = num_of_sequencers;
clearStats();
}

@@ -88,18 +95,18 @@
out << "Hot Data Blocks" << endl;
out << "---------------" << endl;
out << endl;
- printSorted(out, m_dataAccessTrace, "block_address");
+ printSorted(out, m_num_of_sequencers, m_dataAccessTrace, "block_address");

out << endl;
out << "Hot MacroData Blocks" << endl;
out << "--------------------" << endl;
out << endl;
- printSorted(out, m_macroBlockAccessTrace, "macroblock_address");
+ printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace, "macroblock_address");

out << "Hot Instructions" << endl;
out << "----------------" << endl;
out << endl;
- printSorted(out, m_programCounterAccessTrace, "pc_address");
+ printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace, "pc_address");
}

if (m_all_instructions){
@@ -107,7 +114,7 @@
out << "All Instructions Profile:" << endl;
out << "-------------------------" << endl;
out << endl;
- printSorted(out, m_programCounterAccessTrace, "pc_address");
+ printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace, "pc_address");
out << endl;
}

@@ -123,7 +130,7 @@
m_retryProfileHisto.printPercent(out);
out << endl;

- printSorted(out, m_retryProfileMap, "block_address");
+ printSorted(out, m_num_of_sequencers, m_retryProfileMap, "block_address");
out << endl;
}

@@ -212,7 +219,10 @@

// ***** Normal Functions ******

-static void printSorted(ostream& out, const Map<Address, AccessTraceForAddress>* record_map, string description)
+static void printSorted(ostream& out,
+ int num_of_sequencers,
+ const Map<Address, AccessTraceForAddress>* record_map,
+ string description)
{
const int records_printed = 100;

@@ -241,8 +251,8 @@
// Allows us to track how many lines where touched by n processors
Vector<int64> m_touched_vec;
Vector<int64> m_touched_weighted_vec;
- m_touched_vec.setSize(RubySystem::getNumberOfSequencers()+1);
- m_touched_weighted_vec.setSize(RubySystem::getNumberOfSequencers()+1);
+ m_touched_vec.setSize(num_of_sequencers+1);
+ m_touched_weighted_vec.setSize(num_of_sequencers+1);
for (int i=0; i<m_touched_vec.size(); i++) {
m_touched_vec[i] = 0;
m_touched_weighted_vec[i] = 0;
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/profiler/AddressProfiler.hh
--- a/src/mem/ruby/profiler/AddressProfiler.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/profiler/AddressProfiler.hh Sat Dec 12 14:37:17 2009 -0800
@@ -53,7 +53,7 @@
class AddressProfiler {
public:
// Constructors
- AddressProfiler();
+ AddressProfiler(int num_of_sequencers);

// Destructor
~AddressProfiler();
@@ -95,6 +95,7 @@
bool m_hot_lines;
bool m_all_instructions;

+ int m_num_of_sequencers;
};

// Output operator declaration
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/profiler/Profiler.cc
--- a/src/mem/ruby/profiler/Profiler.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.cc Sat Dec 12 14:37:17 2009 -0800
@@ -88,6 +88,8 @@
m_hot_lines = p->hot_lines;
m_all_instructions = p->all_instructions;

+ m_num_of_sequencers = p->num_of_sequencers;
+
//
// Initialize the memory controller profiler structs
//
@@ -125,12 +127,12 @@
m_hot_lines = false;
m_all_instructions = false;

- m_address_profiler_ptr = new AddressProfiler;
+ m_address_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
m_address_profiler_ptr -> setHotLines(m_hot_lines);
m_address_profiler_ptr -> setAllInstructions(m_all_instructions);

if (m_all_instructions) {
- m_inst_profiler_ptr = new AddressProfiler;
+ m_inst_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
m_inst_profiler_ptr -> setHotLines(m_hot_lines);
m_inst_profiler_ptr -> setAllInstructions(m_all_instructions);
}
@@ -156,9 +158,9 @@
// FIXME - avoid the repeated code

Vector<integer_t> perProcCycleCount;
- perProcCycleCount.setSize(RubySystem::getNumberOfSequencers());
+ perProcCycleCount.setSize(m_num_of_sequencers);

- for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) {
+ for(int i=0; i < m_num_of_sequencers; i++) {
perProcCycleCount[i] = g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
// The +1 allows us to avoid division by zero
}
@@ -317,11 +319,11 @@
Vector<double> perProcMissesPerTrans;


- perProcCycleCount.setSize(RubySystem::getNumberOfSequencers());
- perProcCyclesPerTrans.setSize(RubySystem::getNumberOfSequencers());
- perProcMissesPerTrans.setSize(RubySystem::getNumberOfSequencers());
+ perProcCycleCount.setSize(m_num_of_sequencers);
+ perProcCyclesPerTrans.setSize(m_num_of_sequencers);
+ perProcMissesPerTrans.setSize(m_num_of_sequencers);

- for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) {
+ for(int i=0; i < m_num_of_sequencers; i++) {
perProcCycleCount[i] = g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
// The +1 allows us to avoid division by zero

@@ -342,7 +344,7 @@
integer_t transactions_started = m_perProcStartTransaction.sum();
integer_t transactions_ended = m_perProcEndTransaction.sum();

- double cycles_per_transaction = (transactions_ended != 0) ? (RubySystem::getNumberOfSequencers() * double(ruby_cycles)) / double(transactions_ended) : 0;
+ double cycles_per_transaction = (transactions_ended != 0) ? (m_num_of_sequencers * double(ruby_cycles)) / double(transactions_ended) : 0;
double misses_per_transaction = (transactions_ended != 0) ? double(total_misses) / double(transactions_ended) : 0;

out << "Total_misses: " << total_misses << endl;
@@ -566,8 +568,8 @@
{
m_ruby_start = g_eventQueue_ptr->getTime();

- m_cycles_executed_at_start.setSize(RubySystem::getNumberOfSequencers());
- for (int i=0; i < RubySystem::getNumberOfSequencers(); i++) {
+ m_cycles_executed_at_start.setSize(m_num_of_sequencers);
+ for (int i=0; i < m_num_of_sequencers; i++) {
if (g_system_ptr == NULL) {
m_cycles_executed_at_start[i] = 0;
} else {
@@ -575,13 +577,13 @@
}
}

- m_perProcTotalMisses.setSize(RubySystem::getNumberOfSequencers());
- m_perProcUserMisses.setSize(RubySystem::getNumberOfSequencers());
- m_perProcSupervisorMisses.setSize(RubySystem::getNumberOfSequencers());
- m_perProcStartTransaction.setSize(RubySystem::getNumberOfSequencers());
- m_perProcEndTransaction.setSize(RubySystem::getNumberOfSequencers());
+ m_perProcTotalMisses.setSize(m_num_of_sequencers);
+ m_perProcUserMisses.setSize(m_num_of_sequencers);
+ m_perProcSupervisorMisses.setSize(m_num_of_sequencers);
+ m_perProcStartTransaction.setSize(m_num_of_sequencers);
+ m_perProcEndTransaction.setSize(m_num_of_sequencers);

- for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) {
+ for(int i=0; i < m_num_of_sequencers; i++) {
m_perProcTotalMisses[i] = 0;
m_perProcUserMisses[i] = 0;
m_perProcSupervisorMisses[i] = 0;
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/profiler/Profiler.hh
--- a/src/mem/ruby/profiler/Profiler.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.hh Sat Dec 12 14:37:17 2009 -0800
@@ -262,6 +262,8 @@
//added by SS
bool m_hot_lines;
bool m_all_instructions;
+
+ int m_num_of_sequencers;
};

// Output operator declaration
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/profiler/Profiler.py
--- a/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:17 2009 -0800
@@ -6,6 +6,7 @@
cxx_class = 'Profiler'
hot_lines = Param.Bool(False, "")
all_instructions = Param.Bool(False, "")
+ num_of_sequencers = Param.Int("")
mem_cntrl_count = Param.Int(0, "")
banks_per_rank = Param.Int("")
ranks_per_dimm = Param.Int("")
diff -r a47f0bcef634 -r d52040d526f6 src/mem/ruby/system/System.hh
--- a/src/mem/ruby/system/System.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/System.hh Sat Dec 12 14:37:17 2009 -0800
@@ -125,9 +125,6 @@

static RubyEventQueue* getEventQueue() { return g_eventQueue_ptr; }

- static int getNumberOfDirectories() { return m_directories.size(); }
- static int getNumberOfSequencers() { return m_sequencers.size(); }
-
Profiler* getProfiler() {assert(m_profiler_ptr != NULL); return m_profiler_ptr; }
static Tracer* getTracer() { assert(m_tracer_ptr != NULL); return m_tracer_ptr; }
static MemoryVector* getMemoryVector() { assert(m_mem_vec_ptr != NULL); return m_mem_vec_ptr;}
Brad Beckmann
2009-12-12 22:37:35 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 7cecf4257a724ff3ad529e48f2fd3f2c32872cf4
# Parent 1788fb1fa57c0b95f0ec58b991cbb503a98c276c
ruby: fixed dir_cntrl name in memtest-ruby.py

diff -r 1788fb1fa57c -r 7cecf4257a72 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -134,7 +134,8 @@
network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
dir_cntrl_nodes))

-mem_size_mb = sum([int(dc.directory.size_mb) for dc in dc_nodes])
+mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
+ for dir_cntrl in dir_cntrl_nodes])

system.ruby = RubySystem(network = network,
profiler = RubyProfiler(),
nathan binkert
2009-12-21 20:54:07 UTC
Permalink
Seems like this should be folded with the previous.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID 7cecf4257a724ff3ad529e48f2fd3f2c32872cf4
# Parent  1788fb1fa57c0b95f0ec58b991cbb503a98c276c
ruby: fixed dir_cntrl name in memtest-ruby.py
diff -r 1788fb1fa57c -r 7cecf4257a72 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
@@ -134,7 +134,8 @@
 network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
                                                dir_cntrl_nodes))
-mem_size_mb = sum([int(dc.directory.size_mb) for dc in dc_nodes])
+mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
+                   for dir_cntrl in dir_cntrl_nodes])
 system.ruby = RubySystem(network = network,
                         profiler = RubyProfiler(),
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:29 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657434 28800
# Node ID 8f73bf7c3c5e9d1cd8573b6db7975fefc9bda613
# Parent 289ac904233db4bfc30a0fad1af7c21ea922aa5c
ruby: Convert most Ruby objects to M5 SimObjects.

diff -r 289ac904233d -r 8f73bf7c3c5e configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Wed Nov 18 18:00:41 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:14 2009 -0800
@@ -34,8 +34,6 @@
from m5.util import addToPath
import os, optparse, sys
addToPath('../common')
-addToPath('../../tests/configs/')
-import ruby_config

parser = optparse.OptionParser()

@@ -85,19 +83,50 @@
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)
+### create the desired simulated system
+### ruby memory must be at least 16 MB to work with the mem tester
+##ruby_memory = ruby_config.generate("MI_example-homogeneous.rb",
+## cores = options.testers,
+## memory_size = 16,
+## ports_per_cpu = 1)

-system = System(cpu = cpus, funcmem = PhysicalMemory(),
- physmem = ruby_memory)
+system = System(cpu = cpus,
+ funcmem = PhysicalMemory(),
+ physmem = PhysicalMemory())

-for cpu in cpus:
- cpu.test = system.physmem.port
- cpu.functional = system.funcmem.port
+class L1Cache(RubyCache):
+ assoc = 2
+ latency = 3
+ size = 32768
+
+class L2Cache(RubyCache):
+ assoc = 16
+ latency = 15
+ size = 1048576
+
+class CrossbarTopology(Topology):
+ connections="hi"
+
+ for cpu in cpus:
+ l1_cntrl = L1Cache_Controller()
+ cpu_seq = RubySequencer(controller=l1_cntrl,
+ icache=L1Cache(controller=l1_cntrl),
+ dcache=L1Cache(controller=l1_cntrl))
+ cpu.controller = l1_cntrl
+ cpu.sequencer = cpu_seq
+ cpu.test = cpu_seq.port
+ cpu_seq.funcmem_port = system.physmem.port
+ cpu.functional = system.funcmem.port
+
+ dir_cntrl = Directory_Controller(directory=RubyDirectoryMemory(),
+ memory_control=RubyMemoryControl())
+
+network = SimpleNetwork(topology=CrossbarTopology())
+
+system.ruby = RubySystem(network = network,
+ profiler = RubyProfiler(),
+ tracer = RubyTracer(),
+ debug = RubyDebug())


# -----------------------
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/SConscript
--- a/src/mem/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -35,9 +35,6 @@
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('tport.cc')
Source('mport.cc')

-if env['RUBY']:
- Source('rubymem.cc')
-
if env['FULL_SYSTEM']:
Source('vport.cc')
else:
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/common/Debug.cc
--- a/src/mem/ruby/common/Debug.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/common/Debug.cc Sat Dec 12 14:37:14 2009 -0800
@@ -87,54 +87,21 @@
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 @@
}
*/

+
+Debug *
+RubyDebugParams::create()
+{
+ return new Debug(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/common/Debug.hh
--- a/src/mem/ruby/common/Debug.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/common/Debug.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 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();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/common/Debug.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/common/Debug.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,12 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyDebug(SimObject):
+ type = 'RubyDebug'
+ cxx_class = 'Debug'
+
+ filter_string = Param.String('none', "")
+ verbosity_string = Param.String('none', "")
+ output_filename = Param.String('none', "")
+ start_time = Param.Tick(30300000, "")
+ protocol_trace = Param.Bool(False, "")
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/common/SConscript
--- a/src/mem/ruby/common/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/common/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,8 @@
if not env['RUBY']:
Return()

+SimObject('Debug.py')
+
Source('Address.cc')
Source('DataBlock.cc')
Source('Debug.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/eventqueue/RubyEventQueue.cc
--- a/src/mem/ruby/eventqueue/RubyEventQueue.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc Sat Dec 12 14:37:14 2009 -0800
@@ -40,10 +40,14 @@

// Class public method definitions

+RubyEventQueue theEventQueue;
+
RubyEventQueue::RubyEventQueue()
{
m_prio_heap_ptr = NULL;
init();
+ assert(g_eventQueue_ptr == NULL);
+ g_eventQueue_ptr = this;
}

RubyEventQueue::~RubyEventQueue()
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/libruby.cc
--- a/src/mem/ruby/libruby.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/libruby.cc Sat Dec 12 14:37:14 2009 -0800
@@ -92,6 +92,7 @@
return tokens;
}

+#if 0
void libruby_init(const char* cfg_filename)
{
ifstream cfg_output(cfg_filename);
@@ -118,6 +119,7 @@
RubySystem::create(*sys_conf);
delete sys_conf;
}
+#endif

RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
{
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/Network.cc
--- a/src/mem/ruby/network/Network.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/Network.cc Sat Dec 12 14:37:14 2009 -0800
@@ -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)
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/Network.hh
--- a/src/mem/ruby/network/Network.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/Network.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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() {}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/Network.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/network/Network.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,18 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class Topology(SimObject):
+ type = 'Topology'
+ connections = Param.String("")
+ print_config = Param.Bool(False, "")
+
+class RubyNetwork(SimObject):
+ type = 'RubyNetwork'
+ abstract = True
+ number_of_virtual_networks = Param.Int(10, "");
+ topology = Param.Topology("");
+ buffer_size = Param.Int(0, "");
+ endpoint_bandwidth = Param.Int(10000, "");
+ adaptive_routing = Param.Bool(True, "");
+ link_latency = Param.Int(1, "");
+ control_msg_size = Param.Int(8, "");
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/SConscript
--- a/src/mem/ruby/network/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,4 +33,6 @@
if not env['RUBY']:
Return()

+SimObject('Network.py')
+
Source('Network.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc Sat Dec 12 14:37:14 2009 -0800
@@ -43,7 +43,7 @@
{
}

-void GarnetNetwork_d::init(const vector<string> & argv)
+void GarnetNetwork_d::init()
{
Network::init(argv);

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh Sat Dec 12 14:37:14 2009 -0800
@@ -50,7 +50,7 @@

~GarnetNetwork_d();

- void init(const vector<string> & argv);
+ void init();

//added by SS
NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-fixed-pipeline/SConscript
--- a/src/mem/ruby/network/garnet-fixed-pipeline/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -30,6 +30,9 @@

Import('*')

+# temporarily disable
+Return()
+
if not env['RUBY']:
Return()

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc Sat Dec 12 14:37:14 2009 -0800
@@ -44,7 +44,7 @@
{
}

-void GarnetNetwork::init(const vector<string> & argv)
+void GarnetNetwork::init()
{
// printf("hello\n");
Network::init(argv);
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh Sat Dec 12 14:37:14 2009 -0800
@@ -49,7 +49,7 @@

~GarnetNetwork();

- void init(const vector<string> & argv);
+ void init();

//added by SS
NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh Sat Dec 12 14:37:14 2009 -0800
@@ -48,7 +48,7 @@
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());
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-flexible-pipeline/SConscript
--- a/src/mem/ruby/network/garnet-flexible-pipeline/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -30,6 +30,9 @@

Import('*')

+# temporarily disable
+Return()
+
if not env['RUBY']:
Return()

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/orion/SConscript
--- a/src/mem/ruby/network/orion/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/orion/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -30,6 +30,9 @@

Import('*')

+# temporarily disable
+Return()
+
if not env['RUBY']:
Return()

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/CustomTopology.hh
--- a/src/mem/ruby/network/simple/CustomTopology.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/CustomTopology.hh Sat Dec 12 14:37:14 2009 -0800
@@ -8,7 +8,7 @@
{
public:
CustomTopology(const string & name);
- void init(const vector<string> & argv);
+ void init();

protected:
void construct();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh
--- a/src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh Sat Dec 12 14:37:14 2009 -0800
@@ -8,7 +8,7 @@
{
public:
HierarchicalSwitchTopology(const string & name);
- void init(const vector<string> & argv);
+ void init();

protected:
void construct();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/PtToPtTopology.hh
--- a/src/mem/ruby/network/simple/PtToPtTopology.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/PtToPtTopology.hh Sat Dec 12 14:37:14 2009 -0800
@@ -8,7 +8,7 @@
{
public:
PtToPtTopology(const string & name);
- void init(const vector<string> & argv);
+ void init();

protected:
void construct();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/SConscript
--- a/src/mem/ruby/network/simple/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,8 @@
if not env['RUBY']:
Return()

+SimObject('SimpleNetwork.py')
+
Source('CustomTopology.cc')
Source('PerfectSwitch.cc')
Source('SimpleNetwork.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:14 2009 -0800
@@ -59,17 +59,17 @@
}
*/

-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 @@
{
out << "[SimpleNetwork]";
}
+
+
+SimpleNetwork *
+SimpleNetworkParams::create()
+{
+ return new SimpleNetwork(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/SimpleNetwork.hh
--- a/src/mem/ruby/network/simple/SimpleNetwork.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 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;
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/SimpleNetwork.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/network/simple/SimpleNetwork.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,5 @@
+from m5.params import *
+from Network import RubyNetwork
+
+class SimpleNetwork(RubyNetwork):
+ type = 'SimpleNetwork'
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:14 2009 -0800
@@ -62,27 +62,18 @@
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]);
- cerr << "print config: " << m_print_config << endl;
- }
- }
- assert(m_network_ptr != NULL);
}

void Topology::makeTopology()
@@ -458,3 +449,8 @@
return result;
}

+Topology *
+TopologyParams::create()
+{
+ return new Topology(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@

protected:
// Private Methods
- void init();
SwitchID newSwitchID();
void addLink(SwitchID src, SwitchID dest, int link_latency);
void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier);
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/simple/Torus2DTopology.hh
--- a/src/mem/ruby/network/simple/Torus2DTopology.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/simple/Torus2DTopology.hh Sat Dec 12 14:37:14 2009 -0800
@@ -8,7 +8,7 @@
{
public:
Torus2DTopology(const string & name);
- void init(const vector<string> & argv);
+ void init();

protected:
void construct();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/profiler/Profiler.cc
--- a/src/mem/ruby/profiler/Profiler.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.cc Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
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 @@
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 @@
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::profileMemRandBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRandBusy++; }
void Profiler::profileMemNotOld(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memNotOld++; }

+
+Profiler *
+RubyProfilerParams::create()
+{
+ return new Profiler(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/profiler/Profiler.hh
--- a/src/mem/ruby/profiler/Profiler.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
};


-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 @@
//added by SS
bool m_hot_lines;
bool m_all_instructions;
- string m_name;
-
};

// Output operator declaration
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/profiler/Profiler.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,8 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyProfiler(SimObject):
+ type = 'RubyProfiler'
+ cxx_class = 'Profiler'
+ hot_lines = Param.Bool(False, "")
+ all_instructions = Param.Bool(False, "")
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/profiler/SConscript
--- a/src/mem/ruby/profiler/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/profiler/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,8 @@
if not env['RUBY']:
Return()

+SimObject('Profiler.py')
+
Source('AccessTraceForAddress.cc')
Source('AddressProfiler.cc')
Source('CacheProfiler.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/recorder/SConscript
--- a/src/mem/ruby/recorder/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/recorder/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,8 @@
if not env['RUBY']:
Return()

+SimObject('Tracer.py')
+
Source('CacheRecorder.cc')
Source('Tracer.cc')
Source('TraceRecord.cc', Werror=False)
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/recorder/Tracer.cc
--- a/src/mem/ruby/recorder/Tracer.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/recorder/Tracer.cc Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
{
}

-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 @@
void Tracer::print(ostream& out) const
{
}
+
+
+Tracer *
+RubyTracerParams::create()
+{
+ return new Tracer(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/recorder/Tracer.hh
--- a/src/mem/ruby/recorder/Tracer.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/recorder/Tracer.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 Class Methods
int playbackTrace(string filename);
- void init(const vector<string> & argv);
+ void init();
private:
// Private Methods

@@ -82,7 +87,6 @@

//added by SS
int m_warmup_length;
- string m_name;
};

// Output operator declaration
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/recorder/Tracer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/recorder/Tracer.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,7 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyTracer(SimObject):
+ type = 'RubyTracer'
+ cxx_class = 'Tracer'
+ warmup_length = Param.Int(100000, "")
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/slicc_interface/Controller.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/slicc_interface/Controller.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,13 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyController(SimObject):
+ type = 'RubyController'
+ cxx_class = 'AbstractController'
+ abstract = True
+ version = Param.Int("")
+ transitions_per_cycle = \
+ Param.Int(32, "no. of SLICC state machine transitions per cycle")
+ buffer_size = Param.Int(0, "max buffer size 0 means infinite")
+ recycle_latency = Param.Int(10, "")
+ number_of_TBEs = Param.Int(256, "")
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/slicc_interface/SConscript
--- a/src/mem/ruby/slicc_interface/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/slicc_interface/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,8 @@
if not env['RUBY']:
Return()

+SimObject('Controller.py')
+
Source('AbstractCacheEntry.cc')
Source('RubySlicc_Profiler_interface.cc')
Source('RubySlicc_ComponentMapping.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/Cache.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/system/Cache.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,12 @@
+from m5.params import *
+from m5.SimObject import SimObject
+from Controller import RubyController
+
+class RubyCache(SimObject):
+ type = 'RubyCache'
+ cxx_class = 'CacheMemory'
+ size = Param.Int("");
+ latency = Param.Int("");
+ assoc = Param.Int("");
+ replacement_policy = Param.String("PSEUDO_LRU", "");
+ controller = Param.RubyController("");
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.cc Sat Dec 12 14:37:14 2009 -0800
@@ -47,43 +47,24 @@

// ****************************************************************

-CacheMemory::CacheMemory(const string & name)
- : m_cache_name(name)
+CacheMemory *
+RubyCacheParams::create()
{
- m_profiler_ptr = new CacheProfiler(name);
+ return new CacheMemory(this);
}
+

+CacheMemory::CacheMemory(const Params *p)
+ : SimObject(p)
+{
void CacheMemory::init(const vector<string> & argv)
{
- 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;
- }
- }
-
- assert(cache_size != -1);
+ // m_profiler_ptr = new CacheProfiler(name);
+ int cache_size = p->size;
+ m_latency = p->latency;
+ m_cache_assoc = p->assoc;
+ string policy = p->replacement_policy;
+ m_controller = p->controller;

m_cache_num_sets = (cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes();
assert(m_cache_num_sets > 1);
@@ -97,6 +78,24 @@
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++) {
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/CacheMemory.hh
--- a/src/mem/ruby/system/CacheMemory.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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"
@@ -56,12 +59,14 @@
#include "mem/protocol/CacheMsg.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();
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/DMASequencer.cc
--- a/src/mem/ruby/system/DMASequencer.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/DMASequencer.cc Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
{

}
+
+
+DMASequencer *
+DMASequencerParams::create()
+{
+ return new DMASequencer(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/DMASequencer.hh
--- a/src/mem/ruby/system/DMASequencer.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/DMASequencer.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
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);
// void issueRequest(uint64_t paddr, uint8* data, int len, bool rw);
@@ -38,13 +38,10 @@
void issueNext();

private:
- int m_version;
- AbstractController* m_controller;
bool m_is_busy;
uint64_t m_data_block_mask;
DMARequest active_request;
int num_active_requests;
- MessageBuffer* m_mandatory_q_ptr;
};

#endif // DMACONTROLLER_H
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/DirectoryMemory.cc
--- a/src/mem/ruby/system/DirectoryMemory.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/DirectoryMemory.cc Sat Dec 12 14:37:14 2009 -0800
@@ -46,29 +46,17 @@
int DirectoryMemory::m_num_directories_bits = 0;
int 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 @@

}

+DirectoryMemory *
+RubyDirectoryMemoryParams::create()
+{
+ return new DirectoryMemory(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/DirectoryMemory.hh
--- a/src/mem/ruby/system/DirectoryMemory.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/DirectoryMemory.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/DirectoryMemory.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/system/DirectoryMemory.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,10 @@
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+class RubyDirectoryMemory(SimObject):
+ type = 'RubyDirectoryMemory'
+ cxx_class = 'DirectoryMemory'
+ version = Param.Int(0, "")
+ size_mb = Param.Int(1024, "")
+ controller = Param.RubyController(Parent.any, "")
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/MemoryControl.cc
--- a/src/mem/ruby/system/MemoryControl.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/MemoryControl.cc Sat Dec 12 14:37:14 2009 -0800
@@ -151,61 +151,30 @@
// ****************************************************************

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


void MemoryControl::printConfig (ostream& out) {
- out << "Memory Control " << m_version << ":" << endl;
+ // 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 +631,9 @@
}
}

+MemoryControl *
+RubyMemoryControlParams::create()
+{
+ return new MemoryControl(this);
+}

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/MemoryControl.hh
--- a/src/mem/ruby/system/MemoryControl.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/MemoryControl.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
string m_name;
string m_description;
- int m_version;
int m_msg_counter;
int m_awakened;

diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/MemoryControl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/system/MemoryControl.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,23 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyMemoryControl(SimObject):
+ type = 'RubyMemoryControl'
+ cxx_class = 'MemoryControl'
+ mem_bus_cycle_multiplier = Param.Int(10, "");
+ banks_per_rank = Param.Int(8, "");
+ ranks_per_dimm = Param.Int(2, "");
+ dimms_per_channel = Param.Int(2, "");
+ bank_bit_0 = Param.Int(8, "");
+ rank_bit_0 = Param.Int(11, "");
+ dimm_bit_0 = Param.Int(12, "");
+ bank_queue_size = Param.Int(12, "");
+ bank_busy_time = Param.Int(11, "");
+ rank_rank_delay = Param.Int(1, "");
+ read_write_delay = Param.Int(2, "");
+ basic_bus_busy_time = Param.Int(2, "");
+ mem_ctl_latency = Param.Int(12, "");
+ refresh_period = Param.Int(1560, "");
+ tFaw = Param.Int(0, "");
+ mem_random_arbitrate = Param.Int(0, "");
+ mem_fixed_delay = Param.Int(0, "");
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:14 2009 -0800
@@ -1,5 +1,28 @@
-
+#include "mem/physical.hh"
#include "mem/ruby/system/RubyPort.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"

//void (*RubyPort::m_hit_callback)(int64_t) = NULL;
uint16_t RubyPort::m_num_ports = 0;
+
+RubyPort::RubyPort(const Params *p)
+ : MemObject(p)
+{
+ m_version = p->version;
+ assert(m_version != -1);
+ m_controller = p->controller;
+ assert(m_controller != NULL);
+
+ m_mandatory_q_ptr = m_controller->getMandatoryQueue();
+
+ m_port_id = m_num_ports++;
+ m_request_cnt = 0;
+ m_hit_callback = NULL;
+ assert(m_num_ports <= 2048); // see below for reason
+}
+
+Port *
+RubyPort::getPort(const std::string &if_name, int idx)
+{
+ return NULL;
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:14 2009 -0800
@@ -5,20 +5,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 +55,10 @@
return id;
}

+ int m_version;
+ AbstractController* m_controller;
+ MessageBuffer* m_mandatory_q_ptr;
+
private:
static uint16_t m_num_ports;
uint16_t m_port_id;
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/RubySystem.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,15 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubySystem(SimObject):
+ type = 'RubySystem'
+ random_seed = Param.Int(1234, "");
+ randomization = Param.Bool(False, "");
+ tech_nm = Param.Int(45, "");
+ freq_mhz = Param.Int(3000, "");
+ block_size_bytes = Param.Int(64, "");
+ network = Param.RubyNetwork("")
+ debug = Param.RubyDebug("")
+ profiler = Param.RubyProfiler("");
+ tracer = Param.RubyTracer("");
+
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/SConscript
--- a/src/mem/ruby/system/SConscript Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/SConscript Sat Dec 12 14:37:14 2009 -0800
@@ -33,6 +33,12 @@
if not env['RUBY']:
Return()

+SimObject('Cache.py')
+SimObject('Sequencer.py')
+SimObject('DirectoryMemory.py')
+SimObject('MemoryControl.py')
+SimObject('RubySystem.py')
+
Source('DMASequencer.cc')
Source('DirectoryMemory.cc')
Source('CacheMemory.cc')
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.cc Sat Dec 12 14:37:14 2009 -0800
@@ -41,6 +41,8 @@
#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
@@ -49,49 +51,40 @@
return out;
}

-Sequencer::Sequencer(const string & name)
- :RubyPort(name)
+
+Sequencer *
+RubySequencerParams::create()
{
+ 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_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;
- m_servicing_atomic = -1;
- m_atomics_counter = 0;
- 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_servicing_atomic = -1;
+ m_atomics_counter = 0;
+
+ 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);
+}
+
+void Sequencer::init()
+{
}

Sequencer::~Sequencer() {
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:14 2009 -0800
@@ -51,7 +51,8 @@
class CacheMsg;
class MachineID;
class CacheMemory;
-class AbstractController;
+
+class RubySequencerParams;

struct SequencerRequest {
RubyRequest ruby_request;
@@ -65,11 +66,12 @@

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 *);
+ void init();

// Destructor
~Sequencer();
@@ -113,13 +115,10 @@
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;
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/Sequencer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:14 2009 -0800
@@ -0,0 +1,21 @@
+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, "")
+ deadlock_threshold = Param.Int(500000, "")
+ funcmem_port = Port("port to functional memory")
+
+class DMASequencer(RubyPort):
+ type = 'DMASequencer'
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:14 2009 -0800
@@ -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,61 +83,26 @@
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");

-void RubySystem::init(const vector<string> & argv)
-{
- for (size_t i=0; i < argv.size(); i+=2) {
- if (argv[i] == "random_seed") {
- m_random_seed = atoi(argv[i+1].c_str());
- srandom(m_random_seed);
- } else if (argv[i] == "randomization") {
- m_randomization = string_to_bool(argv[i+1]);
- } else if (argv[i] == "tech_nm") {
- m_tech_nm = atoi(argv[i+1].c_str());
- } else if (argv[i] == "freq_mhz") {
- m_freq_mhz = atoi(argv[i+1].c_str());
- } else if (argv[i] == "block_size_bytes") {
- m_block_size_bytes = atoi(argv[i+1].c_str());
- assert(is_power_of_2(m_block_size_bytes));
- m_block_size_bits = log_int(m_block_size_bytes);
- } else if (argv[i] == "debug") {
+ 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;

- } 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;
+ //assert( g_debug_ptr != NULL);
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;

@@ -146,6 +110,7 @@
* e.g. a sequencer needs a pointer to a controller and a controller needs a pointer to a sequencer
*/

+#if 0
vector<string> memory_control_names;

for (size_t i=0;i<sys_conf.size(); i++) {
@@ -153,32 +118,32 @@
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 == "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);
+// } 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") {
+// } 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);
+// 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);
@@ -255,9 +220,12 @@
else
assert(0);
}
+#endif
+}

-// m_profiler_ptr = new Profiler;

+void RubySystem::init()
+{
// calculate system-wide parameters
m_memory_size_bytes = 0;
DirectoryMemory* prev = NULL;
@@ -270,11 +238,8 @@
}
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()
{
@@ -419,5 +384,8 @@
#endif


-
-
+RubySystem *
+RubySystemParams::create()
+{
+ return new RubySystem(this);
+}
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/System.hh
--- a/src/mem/ruby/system/System.hh Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/System.hh Sat Dec 12 14:37:14 2009 -0800
@@ -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 @@
{}
};

-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 @@
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 @@
//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;
nathan binkert
2009-12-21 17:03:37 UTC
Permalink
Overall, things look pretty good. There are more or less four things
that you've done that need work.

1) You created SimObjects for all of the ruby objects and in the
process, you didn't give any help strings to any of the parameters.
While I understand that this can be tedious, this is one minimal form
of documentation that does help users.
2) You removed Garnet from the compile. Do we want to keep garnet?
If so, this is guaranteed to lead to bit rot.
3) You commented out code instead of removing it. This should only
*very* rarely be done. The old code is in the history, so just delete
it.
4) You've added #includes in places, but have not maintained sorted
order. It's a lot easier to visually scan #includes if they're all
sorted. This lets you easily find duplicates and quickly figure out
if you need to add something. (There's something in the coding style
document about this.)

I also have several comments inline.

Nate
Post by Brad Beckmann
+### 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)
Please don't comment out code and then commit it. It's in the
history, so please just delete it.
Post by Brad Beckmann
-system = System(cpu = cpus, funcmem = PhysicalMemory(),
-                physmem = ruby_memory)
+system = System(cpu = cpus,
+                funcmem = PhysicalMemory(),
+                physmem = PhysicalMemory())
Do you really want two different PhysicalMemory objects here?
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/common/Debug.hh
--- a/src/mem/ruby/common/Debug.hh      Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/common/Debug.hh      Sat Dec 12 14:37:14 2009 -0800
#include "config/ruby_debug.hh"
#include "mem/ruby/common/Global.hh"
+#include "sim/sim_object.hh"
+
+#include "params/RubyDebug.hh"
Please keep all includes in a single block and sort them. This makes
it much easier to find an include and to avoid duplicate includes.
There is a section in the style guide about this.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/libruby.cc
--- a/src/mem/ruby/libruby.cc   Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/libruby.cc   Sat Dec 12 14:37:14 2009 -0800
+#if 0
void libruby_init(const char* cfg_filename)
{
 ifstream cfg_output(cfg_filename);
@@ -118,6 +119,7 @@
 RubySystem::create(*sys_conf);
 delete sys_conf;
}
+#endif
This seems wrong. Either the code should just be removed, or things
should be initialized in some new way. I'm guessing the latter.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Sat Dec 12 14:37:14 2009 -0800
-void GarnetNetwork_d::init(const vector<string> & argv)
+void GarnetNetwork_d::init()
{
       Network::init(argv);
This must not compile. You've removed argv, yet you still use it.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-fixed-pipeline/SConscript
--- a/src/mem/ruby/network/garnet-fixed-pipeline/SConscript     Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SConscript     Sat Dec 12 14:37:14 2009 -0800
+# temporarily disable
+Return()
+
You shouldn't commit this. Seems like you need to fix garnet.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/garnet-flexible-pipeline/SConscript
--- a/src/mem/ruby/network/garnet-flexible-pipeline/SConscript  Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/SConscript  Sat Dec 12 14:37:14 2009 -0800
+# temporarily disable
+Return()
+
Again
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/network/orion/SConscript
--- a/src/mem/ruby/network/orion/SConscript     Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/network/orion/SConscript     Sat Dec 12 14:37:14 2009 -0800
+# temporarily disable
+Return()
+
Again
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc        Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.cc        Sat Dec 12 14:37:14 2009 -0800
+#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
I assume that this should be deleted?
Post by Brad Beckmann
+void Sequencer::init()
+{
}
I just noticed this, and I'm not sure if you do it elsewhere, but it
seems that you should just remove the init() function in cases where
it is empty.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh  Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.hh  Sat Dec 12 14:37:14 2009 -0800
-class Sequencer : public Consumer, public RubyPort {
+class Sequencer : public RubyPort, public Consumer {
Is MI really necessary? In general, we avoid it if we can because it
can be confusing. (I know that you didn't add it, so you don't need
to fix it here) I'm also curious, is there a reason that order
mattered? For my own education, I'd like to understand what was going
on if it did.
Post by Brad Beckmann
diff -r 289ac904233d -r 8f73bf7c3c5e src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc     Wed Nov 18 18:00:41 2009 -0800
+++ b/src/mem/ruby/system/System.cc     Sat Dec 12 14:37:14 2009 -0800
-#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"
Should get fixed
Post by Brad Beckmann
@@ -146,6 +110,7 @@
  *  e.g. a sequencer needs a pointer to a controller and a controller needs a pointer to a sequencer
  */
+#if 0
 vector<string> memory_control_names;
 for (size_t i=0;i<sys_conf.size(); i++) {
Delete the code, don't comment it.
Post by Brad Beckmann
@@ -153,32 +118,32 @@
   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 == "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);
+//    } 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") {
+//    } 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);
+//      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);
@@ -255,9 +220,12 @@
   else
     assert(0);
 }
+#endif
+}
Seems that all of this should just be deleted
Steve Reinhardt
2009-12-21 18:19:14 UTC
Permalink
Overall, things look pretty good.  There are more or less four things
that you've done that need work.
1) You created SimObjects for all of the ruby objects and in the
process, you didn't give any help strings to any of the parameters.
While I understand that this can be tedious, this is one minimal form
of documentation that does help users.
2) You removed Garnet from the compile.  Do we want to keep garnet?
If so, this is guaranteed to lead to bit rot.
3) You commented out code instead of removing it.  This should only
*very* rarely be done.  The old code is in the history, so just delete
it.
4) You've added #includes in places, but have not maintained sorted
order.  It's a lot easier to visually scan #includes if they're all
sorted.  This lets you easily find duplicates and quickly figure out
if you need to add something.  (There's something in the coding style
document about this.)
I'm responsible for 1 & 2 and probably partially responsible for 4.
(Yes, we still need to clean up the individual patch attributions.) I
did the initial SimObject conversion and was just trying to get
something that compiled, which is why I bailed on the parameter
description strings and on compiling Garnet. (To be honest I don't
remember to what extent there were existing parameter description
strings that didn't get copied over vs. not being any in the first
place.) Then once I got to a certain point where things compiled but
didn't quite work (basically all the Ruby objects were getting
constructed but they weren't hooked up right) I handed it over to Brad
since he understood that part better. I guess we both forgot about
going back and taking care of those temporary shortcuts.

Steve
Steve Reinhardt
2010-01-05 02:46:13 UTC
Permalink
I spent the day working over the patches, so even though it might be
another few days until we send out updated versions, I wanted to
Overall, things look pretty good.  There are more or less four things
that you've done that need work.
1) You created SimObjects for all of the ruby objects and in the
process, you didn't give any help strings to any of the parameters.
While I understand that this can be tedious, this is one minimal form
of documentation that does help users.
I found the original Ruby documentation strings (turned out they were
in comments in defaults.rb and not in cfg.rb where I thought they'd
be) and copied them over, so at least we're not losing any ground
there. I'm not the person to document the previously undocumented
params though.
2) You removed Garnet from the compile.  Do we want to keep garnet?
If so, this is guaranteed to lead to bit rot.
We definitely want to keep it and will be porting it over. It's a
fairly substantial but separable piece though so we'll do it in a
separate patch.
4) You've added #includes in places, but have not maintained sorted
order.  It's a lot easier to visually scan #includes if they're all
sorted.  This lets you easily find duplicates and quickly figure out
if you need to add something.  (There's something in the coding style
document about this.)
I started to do this, but the original includes were not sorted, so it
causes cascading problems through the whole patch set when you sort
everything the first time you add an include. I can see where that
could complicate integrating Derek's changes. I think this is better
done in a style-only pass at the end... we'll need at least one of
those to fix indentation etc. anyway.

Steve
nathan binkert
2010-01-05 14:33:13 UTC
Permalink
Post by Steve Reinhardt
I started to do this, but the original includes were not sorted, so it
causes cascading problems through the whole patch set when you sort
everything the first time you add an include.  I can see where that
could complicate integrating Derek's changes.  I think this is better
done in a style-only pass at the end... we'll need at least one of
those to fix indentation etc. anyway.
Oh, I thought I had them sorted. A style pass at the end is fine.

Nate
Steve Reinhardt
2010-01-05 19:58:25 UTC
Permalink
Post by Steve Reinhardt
I started to do this, but the original includes were not sorted, so it
causes cascading problems through the whole patch set when you sort
everything the first time you add an include.  I can see where that
could complicate integrating Derek's changes.  I think this is better
done in a style-only pass at the end... we'll need at least one of
those to fix indentation etc. anyway.
Oh, I thought I had them sorted.  A style pass at the end is fine.
Some of them may be sorted, but not all.

Steve

Brad Beckmann
2009-12-12 22:37:36 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 2811007a9adc2edc51fdd303909662a852186d52
# Parent 7cecf4257a724ff3ad529e48f2fd3f2c32872cf4
ruby: connects sm queues to the network

diff -r 7cecf4257a72 -r 2811007a9adc configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -104,15 +104,21 @@
latency = 15
size = 1048576

-# It would be nice to lump all the network nodes into a single list,
-# but for consistency with the old scripts I'm segregating them by
-# type. I'm not sure if this is really necessary or not.
+#
+# The ruby network creation expects the list of nodes in the system to be
+# consistent with the NetDest list. Therefore the l1 controller nodes must be
+# listed before the directory nodes and directory nodes before dma nodes, etc.
+#

# net_nodes = []
l1_cntrl_nodes = []
dir_cntrl_nodes = []

-for cpu in cpus:
+#
+# Must create the individual controllers before the network to ensure the
+# controller constructors are called before the network constructor
+#
+for (i, cpu) in enumerate(cpus):
l1_cntrl = L1Cache_Controller()
cpu_seq = RubySequencer(controller = l1_cntrl,
icache = L1Cache(controller = l1_cntrl),
@@ -131,6 +137,10 @@
l1_cntrl_nodes.append(l1_cntrl)
dir_cntrl_nodes.append(dir_cntrl)

+#
+# Important: the topology constructor must be called before the network
+# constructor.
+#
network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
dir_cntrl_nodes))

diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/Network.cc
--- a/src/mem/ruby/network/Network.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/Network.cc Sat Dec 12 14:37:15 2009 -0800
@@ -28,6 +28,7 @@

#include "mem/protocol/MachineType.hh"
#include "mem/ruby/network/Network.hh"
+#include "mem/ruby/network/simple/Topology.hh"

Network::Network(const Params *p)
: SimObject(p)
@@ -40,13 +41,25 @@
m_link_latency = p->link_latency;
m_control_msg_size = p->control_msg_size;

+ //
+ // Total nodes/controllers in network
+ // Must make sure this is called after the State Machine constructors
+ //
+ m_nodes = MachineType_base_number(MachineType_NUM);
+ assert(m_nodes != 0);
+
assert(m_virtual_networks != 0);
assert(m_topology_ptr != NULL);
+
+ //
+ // Initialize the controller's network pointers
+ //
+ m_topology_ptr->initNetworkPtr(this);
}

void Network::init()
{
- m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
+// m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network

m_data_msg_size = RubySystem::getBlockSizeBytes() + m_control_msg_size;
}
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:15 2009 -0800
@@ -62,13 +62,12 @@
SimpleNetwork::SimpleNetwork(const Params *p)
: Network(p)
{
-}
-
-void SimpleNetwork::init()
-{
-
- Network::init();
-
+ //
+ // Note: the parent Network Object constructor is called before the
+ // SimpleNetwork child constructor. Therefore, the member variables
+ // used below should already be initialized.
+ //
+
m_endpoint_switches.setSize(m_nodes);

m_in_use.setSize(m_virtual_networks);
@@ -91,10 +90,45 @@
"fromNet node "+int_to_string(node)+" j "+int_to_string(j));
}
}
+}
+
+void SimpleNetwork::init()
+{
+
+ Network::init();
+
+// m_endpoint_switches.setSize(m_nodes);
+
+// m_in_use.setSize(m_virtual_networks);
+// m_ordered.setSize(m_virtual_networks);
+// for (int i = 0; i < m_virtual_networks; i++) {
+// m_in_use[i] = false;
+// m_ordered[i] = false;
+// }
+
+// // Allocate to and from queues
+// m_toNetQueues.setSize(m_nodes);
+// m_fromNetQueues.setSize(m_nodes);
+// for (int node = 0; node < m_nodes; node++) {
+// m_toNetQueues[node].setSize(m_virtual_networks);
+// m_fromNetQueues[node].setSize(m_virtual_networks);
+// for (int j = 0; j < m_virtual_networks; j++) {
+// m_toNetQueues[node][j] = new MessageBuffer(
+// "toNet node "+int_to_string(node)+" j "+int_to_string(j));
+// m_fromNetQueues[node][j] = new MessageBuffer(
+// "fromNet node "+int_to_string(node)+" j "+int_to_string(j));
+// }
+// }

// Setup the network switches
// m_topology_ptr = new Topology(this, m_nodes);
- m_topology_ptr->makeTopology();
+ // m_topology_ptr->makeTopology();
+
+ //
+ // The topology pointer should have already been initialized in the parent
+ // class network constructor.
+ //
+ assert(m_topology_ptr != NULL);
int number_of_switches = m_topology_ptr->numSwitches();
for (int i=0; i<number_of_switches; i++) {
m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:15 2009 -0800
@@ -68,24 +68,110 @@
{
m_print_config = p->print_config;
m_number_of_switches = p->num_int_nodes;
- // initialize component latencies record
- m_component_latencies.setSize(0);
- m_component_inter_switches.setSize(0);
+ // initialize component latencies record
+ m_component_latencies.setSize(0);
+ m_component_inter_switches.setSize(0);
+
+ //
+ // Total nodes/controllers in network
+ // Must make sure this is called after the State Machine constructors
+ //
+ m_nodes = MachineType_base_number(MachineType_NUM);
+ assert(m_nodes > 1);
+
+ if (m_nodes != params()->ext_links.size()) {
+ fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+ m_nodes != params()->ext_links.size());
+ }
+
+ //Vector<Abstract> endpointConnectionExist; // used to ensure all endpoints are connected to the network
+
+ //
+ // First create the links between the endpoints (i.e. controllers) and the
+ // network.
+ //
+ for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+ i != params()->ext_links.end(); ++i)
+ {
+ const ExtLinkParams *extParams = (*i)->params();
+ AbstractController *cntrl = extParams->ext_node;
+
+ //
+ // Store the controller pointers so that we can later pass them
+ // the network pointer
+ //
+ m_controller_vector.insertAtBottom(cntrl);
+
+ //
+ // Now calculate the correct ids for the external to internal links
+ //
+ int ext_idx1 =
+ MachineType_base_number(cntrl->getMachineType()) + cntrl->getVersion();
+ int ext_idx2 = ext_idx1 + m_nodes;
+ int int_idx = extParams->int_node + 2*m_nodes;
+
+ //
+ // create the links in both directions
+ //
+ addLink(ext_idx1,
+ int_idx,
+ extParams->latency,
+ extParams->bw_multiplier,
+ extParams->weight);
+
+ addLink(int_idx,
+ ext_idx2,
+ extParams->latency,
+ extParams->bw_multiplier,
+ extParams->weight);
+ }
+
+ //
+ // Now create the internal network links
+ //
+ for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+ i != params()->int_links.end(); ++i)
+ {
+ const IntLinkParams *intParams = (*i)->params();
+ int node_a_id = intParams->node_a + 2*m_nodes;
+ int node_b_id = intParams->node_b + 2*m_nodes;
+
+ addLink(node_a_id,
+ node_b_id,
+ intParams->latency,
+ intParams->bw_multiplier,
+ intParams->weight);
+
+ addLink(node_b_id,
+ node_a_id,
+ intParams->latency,
+ intParams->bw_multiplier,
+ intParams->weight);
+ }
+
}

void Topology::init()
{
- // need to defer this until init, to guarantee that constructors
- // for all the controller objects have been called.
- m_nodes = MachineType_base_number(MachineType_NUM);
+// // need to defer this until init, to guarantee that constructors
+// // for all the controller objects have been called.
+// m_nodes = MachineType_base_number(MachineType_NUM);
+}
+
+void Topology::initNetworkPtr(Network* net_ptr)
+{
+ for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++)
+ {
+ m_controller_vector[cntrl]->initNetworkPtr(net_ptr);
+ }
}

void Topology::makeTopology()
{
- if (m_nodes != params()->ext_links.size()) {
- fatal("m_nodes (%d) != ext_links vector length (%d)\n",
- m_nodes != params()->ext_links.size());
- }
+// if (m_nodes != params()->ext_links.size()) {
+// fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+// m_nodes != params()->ext_links.size());
+// }



@@ -97,14 +183,14 @@
return;
}
*/
- assert(m_nodes > 1);
+// assert(m_nodes > 1);

- Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
- Vector<int> latencies; // link latencies for each link extracted
- Vector<int> bw_multis; // bw multipliers for each link extracted
- Vector<int> weights; // link weights used to enfore e-cube deadlock free routing
- Vector< SwitchID > int_network_switches; // internal switches extracted from the file
- Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network
+// Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+// Vector<int> latencies; // link latencies for each link extracted
+// Vector<int> bw_multis; // bw multipliers for each link extracted
+// Vector<int> weights; // link weights used to enfore e-cube deadlock free routing
+// Vector< SwitchID > int_network_switches; // internal switches extracted from the file
+// Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network

#if 0
endpointConnectionExist.setSize(m_nodes);
@@ -229,29 +315,29 @@
}
#endif

- for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
- i != params()->ext_links.end(); ++i)
- {
- const ExtLinkParams *p = (*i)->params();
- AbstractController *c = p->ext_node;
- int ext_idx1 =
- MachineType_base_number(c->getMachineType()) + c->getVersion();
- int ext_idx2 = ext_idx1 + m_nodes;
- int int_idx = p->int_node + 2*m_nodes;
+// for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+// i != params()->ext_links.end(); ++i)
+// {
+// const ExtLinkParams *p = (*i)->params();
+// AbstractController *c = p->ext_node;
+// int ext_idx1 =
+// MachineType_base_number(c->getMachineType()) + c->getVersion();
+// int ext_idx2 = ext_idx1 + m_nodes;
+// int int_idx = p->int_node + 2*m_nodes;

- addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
- addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
- }
+// addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
+// addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
+// }

- for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
- i != params()->int_links.end(); ++i)
- {
- const IntLinkParams *p = (*i)->params();
- int a = p->node_a + 2*m_nodes;
- int b = p->node_b + 2*m_nodes;
- addLink(a, b, p->latency, p->bw_multiplier, p->weight);
- addLink(b, a, p->latency, p->bw_multiplier, p->weight);
- }
+// for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+// i != params()->int_links.end(); ++i)
+// {
+// const IntLinkParams *p = (*i)->params();
+// int a = p->node_a + 2*m_nodes;
+// int b = p->node_b + 2*m_nodes;
+// addLink(a, b, p->latency, p->bw_multiplier, p->weight);
+// addLink(b, a, p->latency, p->bw_multiplier, p->weight);
+// }
}


diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:15 2009 -0800
@@ -102,6 +102,8 @@
int numSwitches() const { return m_number_of_switches; }
void createLinks(Network *net, bool isReconfiguration);

+ void initNetworkPtr(Network* net_ptr);
+
const string getName() { return m_name; }
void printStats(ostream& out) const {}
void clearStats() {}
@@ -129,6 +131,8 @@
NodeID m_nodes;
int m_number_of_switches;

+ Vector<AbstractController*> m_controller_vector;
+
Vector<SwitchID> m_links_src_vector;
Vector<SwitchID> m_links_dest_vector;
Vector<int> m_links_latency_vector;
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh Sat Dec 12 14:37:15 2009 -0800
@@ -8,6 +8,7 @@
#include "mem/ruby/common/Consumer.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/network/Network.hh"

class MessageBuffer;
class Network;
@@ -27,6 +28,7 @@
virtual void set_atomic(Address addr) = 0;
virtual void started_writes() = 0;
virtual void clear_atomic() = 0;
+ virtual void initNetworkPtr(Network* net_ptr) = 0;

virtual void print(ostream & out) const = 0;
virtual void printStats(ostream & out) const = 0;
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
@@ -209,6 +209,7 @@
const string toString() const;
const string getName() const;
const MachineType getMachineType() const;
+ void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
void print(ostream& out) const;
void printConfig(ostream& out) const;
void wakeup();
@@ -361,13 +362,8 @@

void $c_ident::init()
{
- m_net_ptr = net_ptr;
m_machineID.type = MachineType_${ident};
m_machineID.num = m_version;
- for (size_t i = 0; i < argv.size(); i += 2) {
- if (argv[i] != "version")
- m_cfg[argv[i]] = argv[i+1];
- }

// Objects
s_profiler.setVersion(m_version);
nathan binkert
2009-12-21 21:01:22 UTC
Permalink
This changeset comments out a lot of code instead of just deleting it.
Please fix.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID 2811007a9adc2edc51fdd303909662a852186d52
# Parent  7cecf4257a724ff3ad529e48f2fd3f2c32872cf4
ruby: connects sm queues to the network
diff -r 7cecf4257a72 -r 2811007a9adc configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
@@ -104,15 +104,21 @@
    latency = 15
    size = 1048576
-# It would be nice to lump all the network nodes into a single list,
-# but for consistency with the old scripts I'm segregating them by
-# type.  I'm not sure if this is really necessary or not.
+#
+# The ruby network creation expects the list of nodes in the system to be
+# consistent with the NetDest list.  Therefore the l1 controller nodes must be
+# listed before the directory nodes and directory nodes before dma nodes, etc.
+#
 # net_nodes = []
 l1_cntrl_nodes = []
 dir_cntrl_nodes = []
+#
+# Must create the individual controllers before the network to ensure the
+# controller constructors are called before the network constructor
+#
    l1_cntrl = L1Cache_Controller()
    cpu_seq = RubySequencer(controller = l1_cntrl,
                            icache = L1Cache(controller = l1_cntrl),
@@ -131,6 +137,10 @@
    l1_cntrl_nodes.append(l1_cntrl)
    dir_cntrl_nodes.append(dir_cntrl)
+#
+# Important: the topology constructor must be called before the network
+# constructor.
+#
 network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
                                                dir_cntrl_nodes))
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/Network.cc
--- a/src/mem/ruby/network/Network.cc   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/Network.cc   Sat Dec 12 14:37:15 2009 -0800
@@ -28,6 +28,7 @@
 #include "mem/protocol/MachineType.hh"
 #include "mem/ruby/network/Network.hh"
+#include "mem/ruby/network/simple/Topology.hh"
 Network::Network(const Params *p)
    : SimObject(p)
@@ -40,13 +41,25 @@
    m_link_latency = p->link_latency;
    m_control_msg_size = p->control_msg_size;
+    //
+    // Total nodes/controllers in network
+    // Must make sure this is called after the State Machine constructors
+    //
+    m_nodes = MachineType_base_number(MachineType_NUM);
+    assert(m_nodes != 0);
+
    assert(m_virtual_networks != 0);
    assert(m_topology_ptr != NULL);
+
+    //
+    // Initialize the controller's network pointers
+    //
+    m_topology_ptr->initNetworkPtr(this);
 }
 void Network::init()
 {
-  m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
+//   m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
  m_data_msg_size = RubySystem::getBlockSizeBytes() + m_control_msg_size;
 }
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc      Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc      Sat Dec 12 14:37:15 2009 -0800
@@ -62,13 +62,12 @@
 SimpleNetwork::SimpleNetwork(const Params *p)
    : Network(p)
 {
-}
-
-void SimpleNetwork::init()
-{
-
-  Network::init();
-
+  //
+  // Note: the parent Network Object constructor is called before the
+  // SimpleNetwork child constructor.  Therefore, the member variables
+  // used below should already be initialized.
+  //
+
  m_endpoint_switches.setSize(m_nodes);
  m_in_use.setSize(m_virtual_networks);
@@ -91,10 +90,45 @@
                   "fromNet node "+int_to_string(node)+" j "+int_to_string(j));
    }
  }
+}
+
+void SimpleNetwork::init()
+{
+
+  Network::init();
+
+//   m_endpoint_switches.setSize(m_nodes);
+
+//   m_in_use.setSize(m_virtual_networks);
+//   m_ordered.setSize(m_virtual_networks);
+//   for (int i = 0; i < m_virtual_networks; i++) {
+//     m_in_use[i] = false;
+//     m_ordered[i] = false;
+//   }
+
+//   // Allocate to and from queues
+//   m_toNetQueues.setSize(m_nodes);
+//   m_fromNetQueues.setSize(m_nodes);
+//   for (int node = 0; node < m_nodes; node++) {
+//     m_toNetQueues[node].setSize(m_virtual_networks);
+//     m_fromNetQueues[node].setSize(m_virtual_networks);
+//     for (int j = 0; j < m_virtual_networks; j++) {
+//       m_toNetQueues[node][j] = new MessageBuffer(
+//                    "toNet node "+int_to_string(node)+" j "+int_to_string(j));
+//       m_fromNetQueues[node][j] = new MessageBuffer(
+//                    "fromNet node "+int_to_string(node)+" j "+int_to_string(j));
+//     }
+//   }
  // Setup the network switches
  //  m_topology_ptr = new Topology(this, m_nodes);
-  m_topology_ptr->makeTopology();
+  // m_topology_ptr->makeTopology();
+
+  //
+  // The topology pointer should have already been initialized in the parent
+  // class network constructor.
+  //
+  assert(m_topology_ptr != NULL);
  int number_of_switches = m_topology_ptr->numSwitches();
  for (int i=0; i<number_of_switches; i++) {
    m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc   Sat Dec 12 14:37:15 2009 -0800
@@ -68,24 +68,110 @@
 {
    m_print_config = p->print_config;
    m_number_of_switches = p->num_int_nodes;
-  // initialize component latencies record
-  m_component_latencies.setSize(0);
-  m_component_inter_switches.setSize(0);
+    // initialize component latencies record
+    m_component_latencies.setSize(0);
+    m_component_inter_switches.setSize(0);
+
+    //
+    // Total nodes/controllers in network
+    // Must make sure this is called after the State Machine constructors
+    //
+    m_nodes = MachineType_base_number(MachineType_NUM);
+    assert(m_nodes > 1);
+
+    if (m_nodes != params()->ext_links.size()) {
+        fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+              m_nodes != params()->ext_links.size());
+    }
+
+    //Vector<Abstract> endpointConnectionExist;  // used to ensure all endpoints are connected to the network
+
+    //
+    // First create the links between the endpoints (i.e. controllers) and the
+    // network.
+    //
+    for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+         i != params()->ext_links.end(); ++i)
+      {
+        const ExtLinkParams *extParams = (*i)->params();
+        AbstractController *cntrl = extParams->ext_node;
+
+        //
+        // Store the controller pointers so that we can later pass them
+        // the network pointer
+        //
+        m_controller_vector.insertAtBottom(cntrl);
+
+        //
+        // Now calculate the correct ids for the external to internal links
+        //
+        int ext_idx1 =
+          MachineType_base_number(cntrl->getMachineType()) + cntrl->getVersion();
+        int ext_idx2 = ext_idx1 + m_nodes;
+        int int_idx = extParams->int_node + 2*m_nodes;
+
+        //
+        // create the links in both directions
+        //
+        addLink(ext_idx1,
+                int_idx,
+                extParams->latency,
+                extParams->bw_multiplier,
+                extParams->weight);
+
+        addLink(int_idx,
+                ext_idx2,
+                extParams->latency,
+                extParams->bw_multiplier,
+                extParams->weight);
+      }
+
+    //
+    // Now create the internal network links
+    //
+    for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+         i != params()->int_links.end(); ++i)
+      {
+        const IntLinkParams *intParams = (*i)->params();
+        int node_a_id = intParams->node_a + 2*m_nodes;
+        int node_b_id = intParams->node_b + 2*m_nodes;
+
+        addLink(node_a_id,
+                node_b_id,
+                intParams->latency,
+                intParams->bw_multiplier,
+                intParams->weight);
+
+        addLink(node_b_id,
+                node_a_id,
+                intParams->latency,
+                intParams->bw_multiplier,
+                intParams->weight);
+      }
+
 }
 void Topology::init()
 {
-    // need to defer this until init, to guarantee that constructors
-    // for all the controller objects have been called.
-    m_nodes = MachineType_base_number(MachineType_NUM);
+//     // need to defer this until init, to guarantee that constructors
+//     // for all the controller objects have been called.
+//     m_nodes = MachineType_base_number(MachineType_NUM);
+}
+
+void Topology::initNetworkPtr(Network* net_ptr)
+{
+    for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++)
+      {
+        m_controller_vector[cntrl]->initNetworkPtr(net_ptr);
+      }
 }
 void Topology::makeTopology()
 {
-    if (m_nodes != params()->ext_links.size()) {
-        fatal("m_nodes (%d) != ext_links vector length (%d)\n",
-              m_nodes != params()->ext_links.size());
-    }
+//     if (m_nodes != params()->ext_links.size()) {
+//         fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+//               m_nodes != params()->ext_links.size());
+//     }
@@ -97,14 +183,14 @@
    return;
  }
  */
-  assert(m_nodes > 1);
+//   assert(m_nodes > 1);
-  Vector< Vector < SwitchID > > nodePairs;  // node pairs extracted from the file
-  Vector<int> latencies;  // link latencies for each link extracted
-  Vector<int> bw_multis;  // bw multipliers for each link extracted
-  Vector<int> weights;  // link weights used to enfore e-cube deadlock free routing
-  Vector< SwitchID > int_network_switches;  // internal switches extracted from the file
-  Vector<bool> endpointConnectionExist;  // used to ensure all endpoints are connected to the network
+//   Vector< Vector < SwitchID > > nodePairs;  // node pairs extracted from the file
+//   Vector<int> latencies;  // link latencies for each link extracted
+//   Vector<int> bw_multis;  // bw multipliers for each link extracted
+//   Vector<int> weights;  // link weights used to enfore e-cube deadlock free routing
+//   Vector< SwitchID > int_network_switches;  // internal switches extracted from the file
+//   Vector<bool> endpointConnectionExist;  // used to ensure all endpoints are connected to the network
 #if 0
  endpointConnectionExist.setSize(m_nodes);
@@ -229,29 +315,29 @@
  }
 #endif
-  for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
-       i != params()->ext_links.end(); ++i)
-  {
-      const ExtLinkParams *p = (*i)->params();
-      AbstractController *c = p->ext_node;
-      int ext_idx1 =
-          MachineType_base_number(c->getMachineType()) + c->getVersion();
-      int ext_idx2 = ext_idx1 + m_nodes;
-      int int_idx = p->int_node + 2*m_nodes;
+//   for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+//        i != params()->ext_links.end(); ++i)
+//   {
+//       const ExtLinkParams *p = (*i)->params();
+//       AbstractController *c = p->ext_node;
+//       int ext_idx1 =
+//           MachineType_base_number(c->getMachineType()) + c->getVersion();
+//       int ext_idx2 = ext_idx1 + m_nodes;
+//       int int_idx = p->int_node + 2*m_nodes;
-      addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
-      addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
-  }
+//       addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
+//       addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
+//   }
-  for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
-       i != params()->int_links.end(); ++i)
-  {
-      const IntLinkParams *p = (*i)->params();
-      int a = p->node_a + 2*m_nodes;
-      int b = p->node_b + 2*m_nodes;
-      addLink(a, b, p->latency, p->bw_multiplier, p->weight);
-      addLink(b, a, p->latency, p->bw_multiplier, p->weight);
-  }
+//   for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+//        i != params()->int_links.end(); ++i)
+//   {
+//       const IntLinkParams *p = (*i)->params();
+//       int a = p->node_a + 2*m_nodes;
+//       int b = p->node_b + 2*m_nodes;
+//       addLink(a, b, p->latency, p->bw_multiplier, p->weight);
+//       addLink(b, a, p->latency, p->bw_multiplier, p->weight);
+//   }
 }
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh   Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh   Sat Dec 12 14:37:15 2009 -0800
@@ -102,6 +102,8 @@
  int numSwitches() const { return m_number_of_switches; }
  void createLinks(Network *net, bool isReconfiguration);
+  void initNetworkPtr(Network* net_ptr);
+
  const string getName() { return m_name; }
  void printStats(ostream& out) const {}
  void clearStats() {}
@@ -129,6 +131,8 @@
  NodeID m_nodes;
  int m_number_of_switches;
+  Vector<AbstractController*> m_controller_vector;
+
  Vector<SwitchID> m_links_src_vector;
  Vector<SwitchID> m_links_dest_vector;
  Vector<int> m_links_latency_vector;
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh        Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh        Sat Dec 12 14:37:15 2009 -0800
@@ -8,6 +8,7 @@
 #include "mem/ruby/common/Consumer.hh"
 #include "mem/protocol/MachineType.hh"
 #include "mem/ruby/common/Address.hh"
+#include "mem/ruby/network/Network.hh"
 class MessageBuffer;
 class Network;
@@ -27,6 +28,7 @@
  virtual void set_atomic(Address addr) = 0;
  virtual void started_writes() = 0;
  virtual void clear_atomic() = 0;
+  virtual void initNetworkPtr(Network* net_ptr) = 0;
  virtual void print(ostream & out) const = 0;
  virtual void printStats(ostream & out) const = 0;
diff -r 7cecf4257a72 -r 2811007a9adc src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py     Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py     Sat Dec 12 14:37:15 2009 -0800
@@ -209,6 +209,7 @@
    const string toString() const;
    const string getName() const;
    const MachineType getMachineType() const;
+    void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
    void print(ostream& out) const;
    void printConfig(ostream& out) const;
    void wakeup();
@@ -361,13 +362,8 @@
 void $c_ident::init()
 {
-    m_net_ptr = net_ptr;
    m_machineID.type = MachineType_${ident};
    m_machineID.num = m_version;
-    for (size_t i = 0; i < argv.size(); i += 2) {
-        if (argv[i] != "version")
-            m_cfg[argv[i]] = argv[i+1];
-    }
    // Objects
    s_profiler.setVersion(m_version);
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:57 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657437 28800
# Node ID a47f0bcef634e82f98f1f35f3aef3d08f8420d22
# Parent 2d19b51213922c91d5ca388835c8753750b73cbc
ruby: added ruby stats print
Moved the previous rubymem stats print feature to ruby System so that ruby
stats are printed on simulation exit.

diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Dec 12 14:37:17 2009 -0800
@@ -252,6 +252,7 @@
for(int i=0; i<m_switch_ptr_vector.size(); i++) {
m_switch_ptr_vector[i]->printStats(out);
}
+ m_topology_ptr->printStats(out);
}

void SimpleNetwork::clearStats()
@@ -259,6 +260,7 @@
for(int i=0; i<m_switch_ptr_vector.size(); i++) {
m_switch_ptr_vector[i]->clearStats();
}
+ m_topology_ptr->clearStats();
}

void SimpleNetwork::printConfig(ostream& out) const
diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc Sat Dec 12 14:37:17 2009 -0800
@@ -450,6 +450,20 @@
}
}

+void Topology::printStats(ostream& out) const
+{
+ for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
+ m_controller_vector[cntrl]->printStats(out);
+ }
+}
+
+void Topology::clearStats()
+{
+ for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
+ m_controller_vector[cntrl]->clearStats();
+ }
+}
+
void Topology::printConfig(ostream& out) const
{
if (m_print_config == false) return;
diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh Sat Dec 12 14:37:17 2009 -0800
@@ -105,8 +105,8 @@
void initNetworkPtr(Network* net_ptr);

const string getName() { return m_name; }
- void printStats(ostream& out) const {}
- void clearStats() {}
+ void printStats(ostream& out) const;
+ void clearStats();
void printConfig(ostream& out) const;
void print(ostream& out) const { out << "[Topology]"; }

diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:17 2009 -0800
@@ -13,4 +13,5 @@
debug = Param.RubyDebug("")
profiler = Param.RubyProfiler("");
tracer = Param.RubyTracer("");
-
+ stats_filename = Param.String("ruby.stats",
+ "file to which ruby dumps its stats")
diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:17 2009 -0800
@@ -56,6 +56,7 @@
//#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"
+#include "base/output.hh"

int RubySystem::m_random_seed;
bool RubySystem::m_randomization;
@@ -111,6 +112,12 @@
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;
m_mem_vec_ptr->setSize(m_memory_size_bytes);
+
+ //
+ // Print ruby configuration and stats at exit
+ //
+ RubyExitCallback* rubyExitCB = new RubyExitCallback(p->stats_filename);
+ registerExitCallback(rubyExitCB);
}


@@ -262,9 +269,20 @@
}
#endif

-
RubySystem *
RubySystemParams::create()
{
return new RubySystem(this);
}
+
+/**
+ * virtual process function that is invoked when the callback
+ * queue is executed.
+ */
+void RubyExitCallback::process()
+{
+ std::ostream *os = simout.create(stats_filename);
+ RubySystem::printConfig(*os);
+ *os << endl;
+ RubySystem::printStats(*os);
+}
diff -r 2d19b5121392 -r a47f0bcef634 src/mem/ruby/system/System.hh
--- a/src/mem/ruby/system/System.hh Sat Dec 12 14:37:17 2009 -0800
+++ b/src/mem/ruby/system/System.hh Sat Dec 12 14:37:17 2009 -0800
@@ -48,6 +48,7 @@
#include <map>
#include "sim/sim_object.hh"
#include "params/RubySystem.hh"
+#include "base/callback.hh"

class Profiler;
class Network;
@@ -203,6 +204,27 @@
return out;
}

+class RubyExitCallback : public Callback
+{
+ private:
+ string stats_filename;
+
+ public:
+ /**
+ * virtualize the destructor to make sure that the correct one
+ * gets called.
+ */
+
+ virtual ~RubyExitCallback() {}
+
+ RubyExitCallback(const string& _stats_filename)
+ {
+ stats_filename = _stats_filename;
+ }
+
+ virtual void process();
+};
+
#endif //SYSTEM_H
Brad Beckmann
2009-12-12 22:37:37 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID 05140b07714b6f591b3f511b7a3f076aae3d756b
# Parent 2811007a9adc2edc51fdd303909662a852186d52
ruby: Ruby changes required to use the python config system
This patch includes the necessary changes to connect ruby objects using
the python configuration system. Mainly it consists of removing
unnecessary ruby object pointers and connecting the necessary object
pointers using the generated param objects. This patch includes the
slicc changes necessary to connect generated ruby objects together using
the python configuraiton system.

diff -r 2811007a9adc -r 05140b07714b configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -83,13 +83,6 @@
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())
@@ -109,8 +102,6 @@
# consistent with the NetDest list. Therefore the l1 controller nodes must be
# listed before the directory nodes and directory nodes before dma nodes, etc.
#
-
-# net_nodes = []
l1_cntrl_nodes = []
dir_cntrl_nodes = []

@@ -119,23 +110,43 @@
# controller constructors are called before the network constructor
#
for (i, cpu) in enumerate(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
+ #
+ # First create the Ruby objects associated with this cpu
+ # Eventually this code should go in a python file specific to the
+ # MOESI_hammer protocol
+ #
+
+ l1i_cache = L1Cache()
+ l1d_cache = L1Cache()
+ l2_cache = L2Cache()
+
+ cpu_seq = RubySequencer(icache = l1i_cache,
+ dcache = l1d_cache,
+ funcmem_port = system.physmem.port)
+
+ l1_cntrl = L1Cache_Controller(version = i,
+ sequencer = cpu_seq,
+ L1IcacheMemory = l1i_cache,
+ L1DcacheMemory = l1d_cache,
+ L2cacheMemory = l2_cache)
+
+ dir_cntrl = Directory_Controller(version = i,
+ directory = RubyDirectoryMemory(),
+ memBuffer = RubyMemoryControl())
+
+ #
+ # As noted above: Two independent list are track to maintain the order of
+ # nodes/controllers assumed by the ruby network
+ #
+ l1_cntrl_nodes.append(l1_cntrl)
+ dir_cntrl_nodes.append(dir_cntrl)
+
+ #
+ # Finally tie the memtester ports to the correct system ports
+ #
cpu.test = cpu_seq.port
- cpu_seq.funcmem_port = system.physmem.port
cpu.functional = system.funcmem.port

- dir_cntrl = Directory_Controller(version = i,
- directory = RubyDirectoryMemory(),
- memory_control = RubyMemoryControl())
-
- # net_nodes += [l1_cntrl, dir_cntrl]
- l1_cntrl_nodes.append(l1_cntrl)
- dir_cntrl_nodes.append(dir_cntrl)

#
# Important: the topology constructor must be called before the network
diff -r 2811007a9adc -r 05140b07714b src/mem/protocol/MOESI_hammer-cache.sm
--- a/src/mem/protocol/MOESI_hammer-cache.sm Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-cache.sm Sat Dec 12 14:37:15 2009 -0800
@@ -34,7 +34,11 @@
*/

machine(L1Cache, "AMD Hammer-like protocol")
-: int cache_response_latency = 12,
+: Sequencer * sequencer,
+ CacheMemory * L1IcacheMemory,
+ CacheMemory * L1DcacheMemory,
+ CacheMemory * L2cacheMemory,
+ int cache_response_latency = 12,
int issue_latency = 2
{

@@ -104,7 +108,7 @@
// STRUCTURE DEFINITIONS

MessageBuffer mandatoryQueue, ordered="false";
- Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
+ //Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';

// CacheEntry
structure(Entry, desc="...", interface="AbstractCacheEntry") {
@@ -122,17 +126,6 @@
bool Sharers, desc="On a GetS, did we find any other sharers in the system";
}

- external_type(CacheMemory) {
- bool cacheAvail(Address);
- Address cacheProbe(Address);
- void allocate(Address, Entry);
- void deallocate(Address);
- Entry lookup(Address);
- void changePermission(Address, AccessPermission);
- bool isTagPresent(Address);
- void profileMiss(CacheMsg);
- }
-
external_type(TBETable) {
TBE lookup(Address);
void allocate(Address);
@@ -141,17 +134,14 @@
}

TBETable TBEs, template_hack="<L1Cache_TBE>";
- CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])';
- CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])';
- CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["l2cache"])';

Entry getCacheEntry(Address addr), return_by_ref="yes" {
if (L2cacheMemory.isTagPresent(addr)) {
- return L2cacheMemory[addr];
+ return static_cast(Entry, L2cacheMemory[addr]);
} else if (L1DcacheMemory.isTagPresent(addr)) {
- return L1DcacheMemory[addr];
+ return static_cast(Entry, L1DcacheMemory[addr]);
} else {
- return L1IcacheMemory[addr];
+ return static_cast(Entry, L1IcacheMemory[addr]);
}
}

diff -r 2811007a9adc -r 05140b07714b src/mem/protocol/MOESI_hammer-dir.sm
--- a/src/mem/protocol/MOESI_hammer-dir.sm Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-dir.sm Sat Dec 12 14:37:15 2009 -0800
@@ -34,7 +34,9 @@
*/

machine(Directory, "AMD Hammer-like protocol")
-: int memory_controller_latency = 12
+: DirectoryMemory * directory,
+ MemoryControl * memBuffer,
+ int memory_controller_latency = 12
{

MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false";
@@ -108,20 +110,11 @@
// TYPES

// DirectoryEntry
- structure(Entry, desc="...") {
+ structure(Entry, desc="...", interface="AbstractEntry") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
}

- external_type(DirectoryMemory) {
- Entry lookup(Address);
- bool isPresent(Address);
- }
-
- external_type(MemoryControl, inport="yes", outport="yes") {
-
- }
-
// TBE entries for DMA requests
structure(TBE, desc="TBE entries for outstanding DMA requests") {
Address PhysicalAddress, desc="physical address";
@@ -145,17 +138,17 @@

// ** OBJECTS **

- DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])';
+ TBETable TBEs, template_hack="<Directory_TBE>";

- MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])';
-
- TBETable TBEs, template_hack="<Directory_TBE>";
+ Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
+ return static_cast(Entry, directory[addr]);
+ }

State getState(Address addr) {
if (TBEs.isPresent(addr)) {
return TBEs[addr].TBEState;
} else {
- return directory[addr].DirectoryState;
+ return getDirectoryEntry(addr).DirectoryState;
}
}

@@ -163,7 +156,7 @@
if (TBEs.isPresent(addr)) {
TBEs[addr].TBEState := state;
}
- directory[addr].DirectoryState := state;
+ getDirectoryEntry(addr).DirectoryState := state;
}

MessageBuffer triggerQueue, ordered="true";
@@ -454,7 +447,7 @@
out_msg.Sender := machineID;
out_msg.OriginalRequestorMachId := in_msg.Requestor;
out_msg.MessageSize := in_msg.MessageSize;
- out_msg.DataBlk := directory[address].DataBlk;
+ out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
DEBUG_EXPR(out_msg);
}
}
@@ -468,7 +461,7 @@
out_msg.Sender := machineID;
out_msg.OriginalRequestorMachId := in_msg.Requestor;
out_msg.MessageSize := in_msg.MessageSize;
- out_msg.DataBlk := directory[address].DataBlk;
+ out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
DEBUG_EXPR(out_msg);
}
}
@@ -564,15 +557,15 @@
peek(unblockNetwork_in, ResponseMsg) {
assert(in_msg.Dirty);
assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
- directory[address].DataBlk := in_msg.DataBlk;
+ getDirectoryEntry(address).DataBlk := in_msg.DataBlk;
DEBUG_EXPR(in_msg.Address);
DEBUG_EXPR(in_msg.DataBlk);
}
}

action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
- directory[address].DataBlk := TBEs[address].DataBlk;
- directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
+ getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk;
+ getDirectoryEntry(address).DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
}

action(a_assertCacheData, "ac", desc="Assert that a cache provided the data") {
@@ -610,7 +603,7 @@
// implementation. We include the data in the "dataless"
// message so we can assert the clean data matches the datablock
// in memory
- assert(directory[address].DataBlk == in_msg.DataBlk);
+ assert(getDirectoryEntry(address).DataBlk == in_msg.DataBlk);
}
}

diff -r 2811007a9adc -r 05140b07714b src/mem/protocol/RubySlicc_Types.sm
--- a/src/mem/protocol/RubySlicc_Types.sm Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/protocol/RubySlicc_Types.sm Sat Dec 12 14:37:15 2009 -0800
@@ -98,6 +98,30 @@
void profileNack(Address, int, int, uint64);
}

+external_type(AbstractEntry, primitive="yes");
+
+external_type(DirectoryMemory) {
+ AbstractEntry lookup(Address);
+ bool isPresent(Address);
+}
+
+external_type(AbstractCacheEntry, primitive="yes");
+
+external_type(CacheMemory) {
+ bool cacheAvail(Address);
+ Address cacheProbe(Address);
+ void allocate(Address, AbstractCacheEntry);
+ void deallocate(Address);
+ AbstractCacheEntry lookup(Address);
+ void changePermission(Address, AccessPermission);
+ bool isTagPresent(Address);
+ void profileMiss(CacheMsg);
+}
+
+external_type(MemoryControl, inport="yes", outport="yes") {
+
+}
+
external_type(TimerTable, inport="yes") {
bool isReady();
Address readyAddress();
@@ -119,3 +143,5 @@
}


+
+
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/SConscript
--- a/src/mem/ruby/SConscript Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/SConscript Sat Dec 12 14:37:15 2009 -0800
@@ -95,6 +95,7 @@
target = generated_dir.File(basename(source))
env.Command(target, source, MakeIncludeAction)

+MakeInclude('slicc_interface/AbstractEntry.hh')
MakeInclude('slicc_interface/AbstractCacheEntry.hh')
MakeInclude('slicc_interface/AbstractProtocol.hh')
MakeInclude('slicc_interface/Message.hh')
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
--- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh Sat Dec 12 14:37:15 2009 -0800
@@ -40,10 +40,11 @@
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/protocol/AccessPermission.hh"
+#include "mem/ruby/slicc_interface/AbstractEntry.hh"

class DataBlock;

-class AbstractCacheEntry {
+class AbstractCacheEntry : public AbstractEntry {
public:
// Constructors
AbstractCacheEntry();
@@ -51,15 +52,6 @@
// Destructor, prevent it from instantiation
virtual ~AbstractCacheEntry() = 0;

- // Public Methods
-
- // The methods below are those called by ruby runtime, add when it is
- // absolutely necessary and should all be virtual function.
- virtual DataBlock& getDataBlk() = 0;
-
-
- virtual void print(ostream& out) const = 0;
-
// Data Members (m_ prefix)
Address m_Address; // Address of this block, required by CacheMemory
Time m_LastRef; // Last time this block was referenced, required by CacheMemory
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/AbstractEntry.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.cc Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: See AbstractCacheEntry.hh
+ *
+ */
+
+#include "mem/ruby/slicc_interface/AbstractEntry.hh"
+
+// Must define constructor and destructor in subclasses
+AbstractEntry::AbstractEntry() {
+}
+
+AbstractEntry::~AbstractEntry() {
+}
+
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/AbstractEntry.hh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.hh Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: Common base class for a machine node.
+ *
+ */
+
+#ifndef AbstractEntry_H
+#define AbstractEntry_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/protocol/AccessPermission.hh"
+
+class DataBlock;
+
+class AbstractEntry {
+public:
+ // Constructors
+ AbstractEntry();
+
+ // Destructor, prevent it from instantiation
+ virtual ~AbstractEntry() = 0;
+
+ // Public Methods
+
+ // The methods below are those called by ruby runtime, add when it is
+ // absolutely necessary and should all be virtual function.
+ virtual DataBlock& getDataBlk() = 0;
+
+
+ virtual void print(ostream& out) const = 0;
+
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const AbstractEntry& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const AbstractEntry& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //AbstractEntry_H
+
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/SConscript
--- a/src/mem/ruby/slicc_interface/SConscript Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/slicc_interface/SConscript Sat Dec 12 14:37:15 2009 -0800
@@ -35,6 +35,7 @@

SimObject('Controller.py')

+Source('AbstractEntry.cc')
Source('AbstractCacheEntry.cc')
Source('RubySlicc_Profiler_interface.cc')
Source('RubySlicc_ComponentMapping.cc')
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/Cache.py
--- a/src/mem/ruby/system/Cache.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Cache.py Sat Dec 12 14:37:15 2009 -0800
@@ -9,4 +9,3 @@
latency = Param.Int("");
assoc = Param.Int("");
replacement_policy = Param.String("PSEUDO_LRU", "");
- controller = Param.RubyController("");
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.cc Sat Dec 12 14:37:15 2009 -0800
@@ -31,9 +31,6 @@
int CacheMemory::m_num_last_level_caches = 0;
MachineType CacheMemory::m_last_level_machine_type = MachineType_FIRST;

-// Output operator declaration
-//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj);
-
// ******************* Definitions *******************

// Output operator definition
@@ -57,32 +54,27 @@
CacheMemory::CacheMemory(const Params *p)
: SimObject(p)
{
-void CacheMemory::init(const vector<string> & argv)
-{
- // m_profiler_ptr = new CacheProfiler(name);
- int cache_size = p->size;
+ m_cache_size = p->size;
m_latency = p->latency;
m_cache_assoc = p->assoc;
- string policy = p->replacement_policy;
- m_controller = p->controller;
-
- m_cache_num_sets = (cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes();
- assert(m_cache_num_sets > 1);
- m_cache_num_set_bits = log_int(m_cache_num_sets);
- assert(m_cache_num_set_bits > 0);
-
- if(policy == "PSEUDO_LRU")
- m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
- else if (policy == "LRU")
- m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc);
- else
- assert(false);
-
+ m_policy = p->replacement_policy;
}


void CacheMemory::init()
{
+ m_cache_num_sets = (m_cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes();
+ assert(m_cache_num_sets > 1);
+ m_cache_num_set_bits = log_int(m_cache_num_sets);
+ assert(m_cache_num_set_bits > 0);
+
+ if(m_policy == "PSEUDO_LRU")
+ m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
+ else if (m_policy == "LRU")
+ m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc);
+ else
+ assert(false);
+
m_num_last_level_caches =
MachineType_base_count(MachineType_FIRST);
#if 0
@@ -130,8 +122,6 @@
void CacheMemory::printConfig(ostream& out)
{
out << "Cache config: " << m_cache_name << endl;
- if (m_controller != NULL)
- out << " controller: " << m_controller->getName() << endl;
out << " cache_associativity: " << m_cache_assoc << endl;
out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl;
const int cache_num_sets = 1 << m_cache_num_set_bits;
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/CacheMemory.hh
--- a/src/mem/ruby/system/CacheMemory.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/CacheMemory.hh Sat Dec 12 14:37:15 2009 -0800
@@ -71,10 +71,6 @@
// Destructor
~CacheMemory();

- // factory
- // static CacheMemory* createCache(int level, int num, char split_type, AbstractCacheEntry* (*entry_factory)());
- // static CacheMemory* getCache(int cache_id);
-
static int numberOfLastLevelCaches();

// Public Methods
@@ -154,7 +150,6 @@

private:
const string m_cache_name;
- AbstractController* m_controller;
int m_latency;

// Data Members (m_prefix)
@@ -170,6 +165,8 @@

CacheProfiler* m_profiler_ptr;

+ int m_cache_size;
+ string m_policy;
int m_cache_num_sets;
int m_cache_num_set_bits;
int m_cache_assoc;
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/DirectoryMemory.cc
--- a/src/mem/ruby/system/DirectoryMemory.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/DirectoryMemory.cc Sat Dec 12 14:37:15 2009 -0800
@@ -39,7 +39,6 @@
#include "mem/ruby/system/System.hh"
#include "mem/ruby/system/DirectoryMemory.hh"
#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/gems_common/util.hh"

int DirectoryMemory::m_num_directories = 0;
@@ -52,7 +51,6 @@
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()
@@ -85,7 +83,6 @@
void DirectoryMemory::printConfig(ostream& out) const
{
out << "DirectoryMemory module config: " << m_name << endl;
- out << " controller: " << m_controller->getName() << endl;
out << " version: " << m_version << endl;
out << " memory_bits: " << m_size_bits << endl;
out << " memory_size_bytes: " << m_size_bytes << endl;
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/DirectoryMemory.hh
--- a/src/mem/ruby/system/DirectoryMemory.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/DirectoryMemory.hh Sat Dec 12 14:37:15 2009 -0800
@@ -46,8 +46,6 @@
#include "sim/sim_object.hh"
#include "params/RubyDirectoryMemory.hh"

-class AbstractController;
-
class DirectoryMemory : public SimObject {
public:
// Constructors
@@ -83,7 +81,6 @@

private:
const string m_name;
- AbstractController* m_controller;
// Data Members (m_ prefix)
Directory_Entry **m_entries;
// int m_size; // # of memory module blocks this directory is responsible for
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/DirectoryMemory.py
--- a/src/mem/ruby/system/DirectoryMemory.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/DirectoryMemory.py Sat Dec 12 14:37:15 2009 -0800
@@ -7,4 +7,3 @@
cxx_class = 'DirectoryMemory'
version = Param.Int(0, "")
size_mb = Param.Int(1024, "")
- controller = Param.RubyController(Parent.any, "")
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:15 2009 -0800
@@ -13,10 +13,9 @@
{
m_version = p->version;
assert(m_version != -1);
- m_controller = p->controller;
- assert(m_controller != NULL);

- m_mandatory_q_ptr = m_controller->getMandatoryQueue();
+ m_controller = NULL;
+ m_mandatory_q_ptr = NULL;

m_port_id = m_num_ports++;
m_request_cnt = 0;
@@ -24,6 +23,12 @@
assert(m_num_ports <= 2048); // see below for reason
}

+void RubyPort::init()
+{
+ assert(m_controller != NULL);
+ m_mandatory_q_ptr = m_controller->getMandatoryQueue();
+}
+
Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:15 2009 -0800
@@ -41,16 +41,24 @@

typedef RubyPortParams Params;
RubyPort(const Params *p);
- virtual ~RubyPort() {}
+ virtual ~RubyPort() {}
+
+ void init();

Port *getPort(const std::string &if_name, int idx);

- virtual int64_t makeRequest(const RubyRequest & request) = 0;
+ virtual int64_t makeRequest(const RubyRequest & request) = 0;

- void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
- assert(m_hit_callback == NULL); // can't assign hit_callback twice
- m_hit_callback = hit_callback;
- }
+ void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
+ assert(m_hit_callback == NULL); // can't assign hit_callback twice
+ m_hit_callback = hit_callback;
+ }
+
+ //
+ // Called by the controller to give the sequencer a pointer.
+ // A pointer to the controller is needed for atomic support.
+ //
+ void setController(AbstractController* _cntrl) { m_controller = _cntrl; }

protected:
const string m_name;
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.hh Sat Dec 12 14:37:15 2009 -0800
@@ -118,9 +118,6 @@
CacheMemory* m_dataCache_ptr;
CacheMemory* m_instCache_ptr;

- // indicates what processor on the chip this sequencer is associated with
- int m_controller_type;
-
Map<Address, SequencerRequest*> m_writeRequestTable;
Map<Address, SequencerRequest*> m_readRequestTable;
// Global outstanding request count, across all request tables
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/system/Sequencer.py
--- a/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/Sequencer.py Sat Dec 12 14:37:15 2009 -0800
@@ -1,11 +1,11 @@
from m5.params import *
+from m5.proxy 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):
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/ast/FormalParamAST.py
--- a/src/mem/slicc/ast/FormalParamAST.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/ast/FormalParamAST.py Sat Dec 12 14:37:15 2009 -0800
@@ -29,11 +29,12 @@
from slicc.symbols import Var

class FormalParamAST(AST):
- def __init__(self, slicc, type_ast, ident, default = None):
+ def __init__(self, slicc, type_ast, ident, default = None, pointer = False):
super(FormalParamAST, self).__init__(slicc)
self.type_ast = type_ast
self.ident = ident
self.default = default
+ self.pointer = pointer

def __repr__(self):
return "[FormalParamAST: %s]" % self.ident
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/ast/MethodCallExprAST.py
--- a/src/mem/slicc/ast/MethodCallExprAST.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/ast/MethodCallExprAST.py Sat Dec 12 14:37:15 2009 -0800
@@ -68,7 +68,8 @@

for actual_type, expected_type in \
zip(paramTypes, obj_type.methods[methodId].param_types):
- if actual_type != expected_type:
+ if actual_type != expected_type and \
+ str(actual_type["interface"]) != str(expected_type):
self.error("Type mismatch: expected: %s actual: %s",
expected_type, actual_type)

@@ -97,9 +98,48 @@
methodId = obj_type.methodId(self.proc_name, paramTypes)

prefix = ""
+ implements_interface = False
if methodId not in obj_type.methods:
- self.error("Invalid method call: Type '%s' does not have a method '%s'",
- obj_type, methodId)
+ #
+ # The initial method check has failed, but before generating an
+ # error we must check whether any of the paramTypes implement
+ # an interface. If so, we must check if the method ids using
+ # the inherited types exist.
+ #
+ # This code is a temporary fix and only checks for the methodId
+ # where all paramTypes are converted to their inherited type. The
+ # right way to do this is to replace slicc's simple string
+ # comparison for determining the correct overloaded method, with a
+ # more robust param by param check.
+ #
+ implemented_paramTypes = []
+ for paramType in paramTypes:
+ implemented_paramType = paramType
+ if paramType.isInterface:
+ implements_interface = True
+ implemented_paramType.abstract_ident = paramType["interface"]
+ else:
+ implemented_paramType.abstract_ident = paramType.c_ident
+
+ implemented_paramTypes.append(implemented_paramType)
+
+ if implements_interface:
+ implementedMethodId = obj_type.methodIdAbstract(self.proc_name,
+ implemented_paramTypes)
+ else:
+ implementedMethodId = ""
+
+ if implementedMethodId not in obj_type.methods:
+ self.error("Invalid method call: " \
+ "Type '%s' does not have a method '%s' nor '%s'",
+ obj_type, methodId, implementedMethodId)
+ else:
+ #
+ # Replace the methodId with the implementedMethodId found in
+ # the method list.
+ #
+ methodId = implementedMethodId
+
return_type = obj_type.methods[methodId].return_type
if return_type.isInterface:
prefix = "static_cast<%s &>" % return_type.c_ident
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/ast/StaticCastAST.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/slicc/ast/StaticCastAST.py Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,51 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# 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.
+
+from slicc.ast.ExprAST import ExprAST
+
+class StaticCastAST(ExprAST):
+ def __init__(self, slicc, type_ast, expr_ast):
+ super(StaticCastAST, self).__init__(slicc)
+
+ self.type_ast = type_ast
+ self.expr_ast = expr_ast
+
+ def __repr__(self):
+ return "[StaticCastAST: %r]" % self.expr_ast
+
+ def generate(self, code):
+ actual_type, ecode = self.expr_ast.inline(True)
+ code('static_cast<${{self.type_ast.type.c_ident}} &>($ecode)')
+
+ # The interface type should match
+ if str(actual_type) != str(self.type_ast.type["interface"]):
+ self.expr_ast.error("static cast miss-match, type is '%s'," \
+ "but inherited type is '%s'",
+ actual_type, self.type_ast.type["interface"])
+
+ return self.type_ast.type
+
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/ast/__init__.py
--- a/src/mem/slicc/ast/__init__.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/ast/__init__.py Sat Dec 12 14:37:15 2009 -0800
@@ -59,6 +59,7 @@
from slicc.ast.ReturnStatementAST import *
from slicc.ast.StatementAST import *
from slicc.ast.StatementListAST import *
+from slicc.ast.StaticCastAST import *
from slicc.ast.TransitionDeclAST import *
from slicc.ast.TypeAST import *
from slicc.ast.TypeDeclAST import *
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/parser.py
--- a/src/mem/slicc/parser.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/parser.py Sat Dec 12 14:37:15 2009 -0800
@@ -154,6 +154,7 @@
'copy_head' : 'COPY_HEAD',
'check_allocate' : 'CHECK_ALLOCATE',
'check_stop_slots' : 'CHECK_STOP_SLOTS',
+ 'static_cast' : 'STATIC_CAST',
'if' : 'IF',
'else' : 'ELSE',
'return' : 'RETURN',
@@ -416,6 +417,10 @@
"param : type ident"
p[0] = ast.FormalParamAST(self, p[1], p[2])

+ def p_param__pointer(self, p):
+ "param : type STAR ident"
+ p[0] = ast.FormalParamAST(self, p[1], p[3], None, True)
+
def p_param__default(self, p):
"param : type ident '=' NUMBER"
p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
@@ -531,6 +536,10 @@
"statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])

+ def p_statement__static_cast(self, p):
+ "aexpr : STATIC_CAST '(' type ',' expr ')'"
+ p[0] = ast.StaticCastAST(self, p[3], p[5])
+
def p_statement__return(self, p):
"statement : RETURN expr SEMI"
p[0] = ast.ReturnStatementAST(self, p[2])
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/StateMachine.py Sat Dec 12 14:37:15 2009 -0800
@@ -31,14 +31,27 @@
from slicc.symbols.Var import Var
import slicc.generate.html as html

+python_class_map = {"int": "Int",
+ "string": "String",
+ "bool": "Bool",
+ "CacheMemory": "RubyCache",
+ "Sequencer": "RubySequencer",
+ "DirectoryMemory": "RubyDirectoryMemory",
+ "MemoryControl": "RubyMemoryControl",
+ }
+
class StateMachine(Symbol):
def __init__(self, symtab, ident, location, pairs, config_parameters):
super(StateMachine, self).__init__(symtab, ident, location, pairs)
self.table = None
self.config_parameters = config_parameters
for param in config_parameters:
- var = Var(symtab, param.name, location, param.type_ast.type,
- "m_%s" % param.name, {}, self)
+ if param.pointer:
+ var = Var(symtab, param.name, location, param.type_ast.type,
+ "(*m_%s_ptr)" % param.name, {}, self)
+ else:
+ var = Var(symtab, param.name, location, param.type_ast.type,
+ "m_%s" % param.name, {}, self)
self.symtab.registerSym(param.name, var)

self.states = orderdict()
@@ -153,7 +166,13 @@
dflt_str = ''
if param.default is not None:
dflt_str = str(param.default) + ', '
- code('${{param.name}} = Param.Int(${dflt_str}"")')
+ if python_class_map.has_key(param.type_ast.type.c_ident):
+ python_type = python_class_map[param.type_ast.type.c_ident]
+ code('${{param.name}} = Param.${{python_type}}(${dflt_str}"")')
+ else:
+ self.error("Unknown c++ to python class conversion for c++ " \
+ "type: '%s'. Please update the python_class_map " \
+ "in StateMachine.py", param.type_ast.type.c_ident)
code.dedent()
code.write(path, '%s.py' % py_ident)

@@ -224,7 +243,10 @@
code.indent()
# added by SS
for param in self.config_parameters:
- code('int m_${{param.ident}};')
+ if param.pointer:
+ code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;')
+ else:
+ code('${{param.type_ast.type}} m_${{param.ident}};')

if self.ident == "L1Cache":
code('''
@@ -338,10 +360,33 @@
m_number_of_TBEs = p->number_of_TBEs;
''')
code.indent()
+
+ #
+ # After initializing the universal machine parameters, initialize the
+ # this machines config parameters. Also detemine if these configuration
+ # params include a sequencer. This information will be used later for
+ # contecting the sequencer back to the L1 cache controller.
+ #
+ contains_sequencer = False
for param in self.config_parameters:
- code('m_${{param.name}} = p->${{param.name}};')
+ if param.name == "sequencer":
+ contains_sequencer = True
+ if param.pointer:
+ code('m_${{param.name}}_ptr = p->${{param.name}};')
+ else:
+ code('m_${{param.name}} = p->${{param.name}};')
+
+ #
+ # For the l1 cache controller, add the special atomic support which
+ # includes passing the sequencer a pointer to the controller.
+ #
if self.ident == "L1Cache":
+ if not contains_sequencer:
+ self.error("The L1Cache controller must include the sequencer " \
+ "configuration parameter")
+
code('''
+m_sequencer_ptr->setController(this);
servicing_atomic = 0;
started_receiving_writes = false;
locked_read_request1 = Address(-1);
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/symbols/Type.py
--- a/src/mem/slicc/symbols/Type.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/slicc/symbols/Type.py Sat Dec 12 14:37:15 2009 -0800
@@ -51,6 +51,7 @@
def __init__(self, table, ident, location, pairs, machine=None):
super(Type, self).__init__(table, ident, location, pairs)
self.c_ident = ident
+ self.abstract_ident = ""
if machine:
if self.isExternal or self.isPrimitive:
if "external_name" in self:
@@ -154,6 +155,9 @@
def methodId(self, name, param_type_vec):
return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])

+ def methodIdAbstract(self, name, param_type_vec):
+ return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ])
+
def methodAdd(self, name, return_type, param_type_vec):
ident = self.methodId(name, param_type_vec)
if ident in self.methods:
nathan binkert
2009-12-21 21:15:21 UTC
Permalink
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID 05140b07714b6f591b3f511b7a3f076aae3d756b
# Parent  2811007a9adc2edc51fdd303909662a852186d52
diff -r 2811007a9adc -r 05140b07714b src/mem/protocol/MOESI_hammer-cache.sm
--- a/src/mem/protocol/MOESI_hammer-cache.sm    Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-cache.sm    Sat Dec 12 14:37:15 2009 -0800
-  Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
+  //Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
Don't comment out code.
Post by Brad Beckmann
diff -r 2811007a9adc -r 05140b07714b src/mem/protocol/RubySlicc_Types.sm
--- a/src/mem/protocol/RubySlicc_Types.sm       Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/protocol/RubySlicc_Types.sm       Sat Dec 12 14:37:15 2009 -0800
@@ -119,3 +143,5 @@
}
+
+
Please remove this random whitespace change.
Post by Brad Beckmann
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/AbstractEntry.cc
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.cc     Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
Shouldn't this just be AMD? or was this moved?
Post by Brad Beckmann
+/*
+ * $Id$
+ *
+ * Description: See AbstractCacheEntry.hh
+ *
+ */
Please don't add this comment. It is more or less just useless
Post by Brad Beckmann
diff -r 2811007a9adc -r 05140b07714b src/mem/ruby/slicc_interface/AbstractEntry.hh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/ruby/slicc_interface/AbstractEntry.hh     Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
Again. AMD?
Post by Brad Beckmann
+/*
+ * $Id$
+ *
+ * Description: Common base class for a machine node.
+ *
+ */
Please remove the $Id$. It doesn't mean anything in hg.
Post by Brad Beckmann
diff -r 2811007a9adc -r 05140b07714b src/mem/slicc/ast/StaticCastAST.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/slicc/ast/StaticCastAST.py        Sat Dec 12 14:37:15 2009 -0800
@@ -0,0 +1,51 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
Is this copied from somewhere? If so, please use "hg cp" instead of
just cp. If it is not copied, please fix the copyright.
Brad Beckmann
2009-12-12 22:37:45 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657436 28800
# Node ID 23ea85c0fc27eaa31f042bdc37238856ffc7769e
# Parent e68f680829daff5e16ea6d520c7302f7ed5055f9
ruby: Memory Controller Profiler with new config system
This patch includes a rather substantial change to the memory controller
profiler in order to work with the new configuration system. Most
noteably, the mem_cntrl_profiler no longer uses a string map, but instead
a vector. Eventually this support should be removed from the main
profiler and go into a separate object. Each memory controller should have
a pointer to that new mem_cntrl profile object.

diff -r e68f680829da -r 23ea85c0fc27 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:16 2009 -0800
@@ -135,9 +135,11 @@
L1DcacheMemory = l1d_cache,
L2cacheMemory = l2_cache)

+ mem_cntrl = RubyMemoryControl(version = i)
+
dir_cntrl = Directory_Controller(version = i,
directory = RubyDirectoryMemory(),
- memBuffer = RubyMemoryControl())
+ memBuffer = mem_cntrl)

dma_cntrl = DMA_Controller(version = i,
dma_sequencer = DMASequencer())
@@ -167,13 +169,27 @@
mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
for dir_cntrl in dir_cntrl_nodes])

+#
+# determine the number of memory controllers and other memory controller
+# parameters for the profiler
+#
+mcCount = len(dir_cntrl_nodes)
+banksPerRank = dir_cntrl_nodes[0].memBuffer.banks_per_rank
+ranksPerDimm = dir_cntrl_nodes[0].memBuffer.ranks_per_dimm
+dimmsPerChannel = dir_cntrl_nodes[0].memBuffer.dimms_per_channel
+
+ruby_profiler = RubyProfiler(mem_cntrl_count = mcCount,
+ banks_per_rank = banksPerRank,
+ ranks_per_dimm = ranksPerDimm,
+ dimms_per_channel = dimmsPerChannel)
+
system.ruby = RubySystem(clock = '1GHz',
network = network,
- profiler = RubyProfiler(),
+ profiler = ruby_profiler,
tracer = RubyTracer(),
- debug = RubyDebug(filter_string = 'qQin',
- verbosity_string = 'high',
- protocol_trace = True),
+ debug = RubyDebug(),#filter_string = 'qQin',
+ #verbosity_string = 'high',
+ #protocol_trace = True),
mem_size_mb = mem_size_mb)


diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/profiler/Profiler.cc
--- a/src/mem/ruby/profiler/Profiler.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.cc Sat Dec 12 14:37:16 2009 -0800
@@ -88,57 +88,40 @@
m_hot_lines = p->hot_lines;
m_all_instructions = p->all_instructions;

- RubySystem::m_profiler_ptr = this;
-}
+ //
+ // Initialize the memory controller profiler structs
+ //
+ m_mc_profilers.setSize(p->mem_cntrl_count);
+ for (int mem_cntrl = 0; mem_cntrl < p->mem_cntrl_count; mem_cntrl++) {
+ m_mc_profilers[mem_cntrl] = new memory_control_profiler;
+ m_mc_profilers[mem_cntrl]->m_memReq = 0;
+ m_mc_profilers[mem_cntrl]->m_memBankBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memBusBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memRefresh = 0;
+ m_mc_profilers[mem_cntrl]->m_memRead = 0;
+ m_mc_profilers[mem_cntrl]->m_memWrite = 0;
+ m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0;
+ m_mc_profilers[mem_cntrl]->m_memInputQ = 0;
+ m_mc_profilers[mem_cntrl]->m_memBankQ = 0;
+ m_mc_profilers[mem_cntrl]->m_memArbWait = 0;
+ m_mc_profilers[mem_cntrl]->m_memRandBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memNotOld = 0;

-Profiler::~Profiler()
-{
- if (m_periodic_output_file_ptr != &cerr) {
- delete m_periodic_output_file_ptr;
- }
- delete m_requestProfileMap_ptr;
-}
+ m_mc_profilers[mem_cntrl]->m_banks_per_rank = p->banks_per_rank;
+ m_mc_profilers[mem_cntrl]->m_ranks_per_dimm = p->ranks_per_dimm;
+ m_mc_profilers[mem_cntrl]->m_dimms_per_channel =
+ p->dimms_per_channel;

-void Profiler::init(const vector<string> & argv, vector<string> memory_control_names)
-{
- // added by SS
- vector<string>::iterator it;
- memory_control_profiler* mcp;
- m_memory_control_names = memory_control_names;
-// printf ( "Here in Profiler::init \n");
- for ( it=memory_control_names.begin() ; it < memory_control_names.end(); it++ ){
-// printf ( "Here in Profiler::init memory control name %s \n", (*it).c_str());
- mcp = new memory_control_profiler;
- mcp->m_memReq = 0;
- mcp->m_memBankBusy = 0;
- mcp->m_memBusBusy = 0;
- mcp->m_memReadWriteBusy = 0;
- mcp->m_memDataBusBusy = 0;
- mcp->m_memTfawBusy = 0;
- mcp->m_memRefresh = 0;
- mcp->m_memRead = 0;
- mcp->m_memWrite = 0;
- mcp->m_memWaitCycles = 0;
- mcp->m_memInputQ = 0;
- mcp->m_memBankQ = 0;
- mcp->m_memArbWait = 0;
- mcp->m_memRandBusy = 0;
- mcp->m_memNotOld = 0;
+ int totalBanks = p->banks_per_rank *
+ p->ranks_per_dimm *
+ p->dimms_per_channel;

- mcp->m_banks_per_rank = RubySystem::getMemoryControl((*it).c_str())->getBanksPerRank();
- mcp->m_ranks_per_dimm = RubySystem::getMemoryControl((*it).c_str())->getRanksPerDimm();
- mcp->m_dimms_per_channel = RubySystem::getMemoryControl((*it).c_str())->getDimmsPerChannel();
+ m_mc_profilers[mem_cntrl]->m_memBankCount.setSize(totalBanks);
+ }

- int totalBanks = mcp->m_banks_per_rank
- * mcp->m_ranks_per_dimm
- * mcp->m_dimms_per_channel;
-
- mcp->m_memBankCount.setSize(totalBanks);
-
- m_memory_control_profilers [(*it).c_str()] = mcp;
- }
-
- clearStats();
m_hot_lines = false;
m_all_instructions = false;

@@ -153,6 +136,21 @@
}
}

+Profiler::~Profiler()
+{
+ if (m_periodic_output_file_ptr != &cerr) {
+ delete m_periodic_output_file_ptr;
+ }
+
+ for (int mem_cntrl = 0;
+ mem_cntrl < m_mc_profilers.size();
+ mem_cntrl++) {
+ delete m_mc_profilers[mem_cntrl];
+ }
+
+ delete m_requestProfileMap_ptr;
+}
+
void Profiler::wakeup()
{
// FIXME - avoid the repeated code
@@ -170,17 +168,51 @@
integer_t transactions_started = m_perProcStartTransaction.sum();
integer_t transactions_ended = m_perProcEndTransaction.sum();

- (*m_periodic_output_file_ptr) << "ruby_cycles: " << g_eventQueue_ptr->getTime()-m_ruby_start << endl;
- (*m_periodic_output_file_ptr) << "total_misses: " << total_misses << " " << m_perProcTotalMisses << endl;
- (*m_periodic_output_file_ptr) << "simics_cycles_executed: " << simics_cycles_executed << " " << perProcCycleCount << endl;
- (*m_periodic_output_file_ptr) << "transactions_started: " << transactions_started << " " << m_perProcStartTransaction << endl;
- (*m_periodic_output_file_ptr) << "transactions_ended: " << transactions_ended << " " << m_perProcEndTransaction << endl;
- (*m_periodic_output_file_ptr) << "mbytes_resident: " << process_memory_resident() << endl;
- (*m_periodic_output_file_ptr) << "mbytes_total: " << process_memory_total() << endl;
+ (*m_periodic_output_file_ptr) << "ruby_cycles: "
+ << g_eventQueue_ptr->getTime()-m_ruby_start
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "total_misses: "
+ << total_misses
+ << " "
+ << m_perProcTotalMisses
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "simics_cycles_executed: "
+ << simics_cycles_executed
+ << " "
+ << perProcCycleCount
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "transactions_started: "
+ << transactions_started
+ << " "
+ << m_perProcStartTransaction
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "transactions_ended: "
+ << transactions_ended
+ << " "
+ << m_perProcEndTransaction
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "mbytes_resident: "
+ << process_memory_resident()
+ << endl;
+
+ (*m_periodic_output_file_ptr) << "mbytes_total: "
+ << process_memory_total()
+ << endl;
+
if (process_memory_total() > 0) {
- (*m_periodic_output_file_ptr) << "resident_ratio: " << process_memory_resident()/process_memory_total() << endl;
+ (*m_periodic_output_file_ptr) << "resident_ratio: "
+ << process_memory_resident()/process_memory_total()
+ << endl;
}
- (*m_periodic_output_file_ptr) << "miss_latency: " << m_allMissLatencyHistogram << endl;
+
+ (*m_periodic_output_file_ptr) << "miss_latency: "
+ << m_allMissLatencyHistogram
+ << endl;

*m_periodic_output_file_ptr << endl;

@@ -207,7 +239,9 @@

void Profiler::setPeriodicStatsInterval(integer_t period)
{
- cout << "Recording periodic statistics every " << m_stats_period << " Ruby cycles" << endl;
+ cout << "Recording periodic statistics every " << m_stats_period
+ << " Ruby cycles" << endl;
+
m_stats_period = period;
g_eventQueue_ptr->scheduleEvent(this, 1);
}
@@ -271,7 +305,8 @@
out << "mbytes_resident: " << process_memory_resident() << endl;
out << "mbytes_total: " << process_memory_total() << endl;
if (process_memory_total() > 0) {
- out << "resident_ratio: " << process_memory_resident()/process_memory_total() << endl;
+ out << "resident_ratio: "
+ << process_memory_resident()/process_memory_total() << endl;
}
out << endl;

@@ -326,30 +361,30 @@

out << endl;

- vector<string>::iterator it;
-
- for ( it=m_memory_control_names.begin() ; it < m_memory_control_names.end(); it++ ){
- long long int m_memReq = m_memory_control_profilers[(*it).c_str()] -> m_memReq;
- long long int m_memRefresh = m_memory_control_profilers[(*it).c_str()] -> m_memRefresh;
- long long int m_memInputQ = m_memory_control_profilers[(*it).c_str()] -> m_memInputQ;
- long long int m_memBankQ = m_memory_control_profilers[(*it).c_str()] -> m_memBankQ;
- long long int m_memWaitCycles = m_memory_control_profilers[(*it).c_str()] -> m_memWaitCycles;
- long long int m_memRead = m_memory_control_profilers[(*it).c_str()] -> m_memRead;
- long long int m_memWrite = m_memory_control_profilers[(*it).c_str()] -> m_memWrite;
- long long int m_memBankBusy = m_memory_control_profilers[(*it).c_str()] -> m_memBankBusy;
- long long int m_memRandBusy = m_memory_control_profilers[(*it).c_str()] -> m_memRandBusy;
- long long int m_memNotOld = m_memory_control_profilers[(*it).c_str()] -> m_memNotOld;
- long long int m_memArbWait = m_memory_control_profilers[(*it).c_str()] -> m_memArbWait;
- long long int m_memBusBusy = m_memory_control_profilers[(*it).c_str()] -> m_memBusBusy;
- long long int m_memTfawBusy = m_memory_control_profilers[(*it).c_str()] -> m_memTfawBusy;
- long long int m_memReadWriteBusy = m_memory_control_profilers[(*it).c_str()] -> m_memReadWriteBusy;
- long long int m_memDataBusBusy = m_memory_control_profilers[(*it).c_str()] -> m_memDataBusBusy;
- Vector<long long int> m_memBankCount = m_memory_control_profilers[(*it).c_str()] -> m_memBankCount;
+ for (int mem_cntrl = 0;
+ mem_cntrl < m_mc_profilers.size();
+ mem_cntrl++) {
+ uint64 m_memReq = m_mc_profilers[mem_cntrl]->m_memReq;
+ uint64 m_memRefresh = m_mc_profilers[mem_cntrl]->m_memRefresh;
+ uint64 m_memInputQ = m_mc_profilers[mem_cntrl]->m_memInputQ;
+ uint64 m_memBankQ = m_mc_profilers[mem_cntrl]->m_memBankQ;
+ uint64 m_memWaitCycles = m_mc_profilers[mem_cntrl]->m_memWaitCycles;
+ uint64 m_memRead = m_mc_profilers[mem_cntrl]->m_memRead;
+ uint64 m_memWrite = m_mc_profilers[mem_cntrl]->m_memWrite;
+ uint64 m_memBankBusy = m_mc_profilers[mem_cntrl]->m_memBankBusy;
+ uint64 m_memRandBusy = m_mc_profilers[mem_cntrl]->m_memRandBusy;
+ uint64 m_memNotOld = m_mc_profilers[mem_cntrl]->m_memNotOld;
+ uint64 m_memArbWait = m_mc_profilers[mem_cntrl]->m_memArbWait;
+ uint64 m_memBusBusy = m_mc_profilers[mem_cntrl]->m_memBusBusy;
+ uint64 m_memTfawBusy = m_mc_profilers[mem_cntrl]->m_memTfawBusy;
+ uint64 m_memReadWriteBusy = m_mc_profilers[mem_cntrl]->m_memReadWriteBusy;
+ uint64 m_memDataBusBusy = m_mc_profilers[mem_cntrl]->m_memDataBusBusy;
+ Vector<uint64> m_memBankCount = m_mc_profilers[mem_cntrl]->m_memBankCount;

if (m_memReq || m_memRefresh) { // if there's a memory controller at all
- long long int total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles;
+ uint64 total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles;
double stallsPerReq = total_stalls * 1.0 / m_memReq;
- out << "Memory control " << (*it) << ":" << endl;
+ out << "Memory control " << mem_cntrl << ":" << endl;
out << " memory_total_requests: " << m_memReq << endl; // does not include refreshes
out << " memory_reads: " << m_memRead << endl;
out << " memory_writes: " << m_memWrite << endl;
@@ -609,25 +644,29 @@
//added by SS
vector<string>::iterator it;

- for ( it=m_memory_control_names.begin() ; it < m_memory_control_names.end(); it++ ){
- m_memory_control_profilers[(*it).c_str()] -> m_memReq = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memBankBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memBusBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memTfawBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memReadWriteBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memDataBusBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memRefresh = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memRead = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memWrite = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memWaitCycles = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memInputQ = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memBankQ = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memArbWait = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memRandBusy = 0;
- m_memory_control_profilers[(*it).c_str()] -> m_memNotOld = 0;
+ for (int mem_cntrl = 0;
+ mem_cntrl < m_mc_profilers.size();
+ mem_cntrl++) {
+ m_mc_profilers[mem_cntrl]->m_memReq = 0;
+ m_mc_profilers[mem_cntrl]->m_memBankBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memBusBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memRefresh = 0;
+ m_mc_profilers[mem_cntrl]->m_memRead = 0;
+ m_mc_profilers[mem_cntrl]->m_memWrite = 0;
+ m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0;
+ m_mc_profilers[mem_cntrl]->m_memInputQ = 0;
+ m_mc_profilers[mem_cntrl]->m_memBankQ = 0;
+ m_mc_profilers[mem_cntrl]->m_memArbWait = 0;
+ m_mc_profilers[mem_cntrl]->m_memRandBusy = 0;
+ m_mc_profilers[mem_cntrl]->m_memNotOld = 0;

- for (int bank=0; bank < m_memory_control_profilers[(*it).c_str()] -> m_memBankCount.size(); bank++) {
- m_memory_control_profilers[(*it).c_str()] -> m_memBankCount[bank] = 0;
+ for (int bank=0;
+ bank < m_mc_profilers[mem_cntrl]->m_memBankCount.size();
+ bank++) {
+ m_mc_profilers[mem_cntrl]->m_memBankCount[bank] = 0;
}
}
// Flush the prefetches through the system - used so that there are no outstanding requests after stats are cleared
@@ -823,26 +862,66 @@
}

// For MemoryControl:
-void Profiler::profileMemReq(string name, int bank) {
-// printf("name is %s", name.c_str());
- assert(m_memory_control_profilers.count(name) == 1);
- m_memory_control_profilers[name] -> m_memReq++;
- m_memory_control_profilers[name] -> m_memBankCount[bank]++;
+void Profiler::profileMemReq(int mem_cntrl, int bank) {
+ m_mc_profilers[mem_cntrl]->m_memReq++;
+ m_mc_profilers[mem_cntrl]->m_memBankCount[bank]++;
}
-void Profiler::profileMemBankBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBankBusy++; }
-void Profiler::profileMemBusBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBusBusy++; }
-void Profiler::profileMemReadWriteBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memReadWriteBusy++; }
-void Profiler::profileMemDataBusBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memDataBusBusy++; }
-void Profiler::profileMemTfawBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memTfawBusy++; }
-void Profiler::profileMemRefresh(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRefresh++; }
-void Profiler::profileMemRead(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRead++; }
-void Profiler::profileMemWrite(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memWrite++; }
-void Profiler::profileMemWaitCycles(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memWaitCycles += cycles; }
-void Profiler::profileMemInputQ(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memInputQ += cycles; }
-void Profiler::profileMemBankQ(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memBankQ += cycles; }
-void Profiler::profileMemArbWait(string name, int cycles) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memArbWait += cycles; }
-void Profiler::profileMemRandBusy(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memRandBusy++; }
-void Profiler::profileMemNotOld(string name) { assert(m_memory_control_profilers.count(name) == 1); m_memory_control_profilers[name] -> m_memNotOld++; }
+
+void Profiler::profileMemBankBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memBankBusy++;
+}
+
+void Profiler::profileMemBusBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memBusBusy++;
+}
+
+void Profiler::profileMemReadWriteBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memReadWriteBusy++;
+}
+
+void Profiler::profileMemDataBusBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memDataBusBusy++;
+}
+
+void Profiler::profileMemTfawBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memTfawBusy++;
+}
+
+void Profiler::profileMemRefresh(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memRefresh++;
+}
+
+void Profiler::profileMemRead(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memRead++;
+}
+
+void Profiler::profileMemWrite(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memWrite++;
+}
+
+void Profiler::profileMemWaitCycles(int mem_cntrl, int cycles) {
+ m_mc_profilers[mem_cntrl]->m_memWaitCycles += cycles;
+}
+
+void Profiler::profileMemInputQ(int mem_cntrl, int cycles) {
+ m_mc_profilers[mem_cntrl]->m_memInputQ += cycles;
+}
+
+void Profiler::profileMemBankQ(int mem_cntrl, int cycles) {
+ m_mc_profilers[mem_cntrl]->m_memBankQ += cycles;
+}
+
+void Profiler::profileMemArbWait(int mem_cntrl, int cycles) {
+ m_mc_profilers[mem_cntrl]->m_memArbWait += cycles;
+}
+
+void Profiler::profileMemRandBusy(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memRandBusy++;
+}
+
+void Profiler::profileMemNotOld(int mem_cntrl) {
+ m_mc_profilers[mem_cntrl]->m_memNotOld++;
+}


Profiler *
diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/profiler/Profiler.hh
--- a/src/mem/ruby/profiler/Profiler.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.hh Sat Dec 12 14:37:16 2009 -0800
@@ -80,22 +80,22 @@
template <class KEY_TYPE, class VALUE_TYPE> class Map;

struct memory_control_profiler {
- long long int m_memReq;
- long long int m_memBankBusy;
- long long int m_memBusBusy;
- long long int m_memTfawBusy;
- long long int m_memReadWriteBusy;
- long long int m_memDataBusBusy;
- long long int m_memRefresh;
- long long int m_memRead;
- long long int m_memWrite;
- long long int m_memWaitCycles;
- long long int m_memInputQ;
- long long int m_memBankQ;
- long long int m_memArbWait;
- long long int m_memRandBusy;
- long long int m_memNotOld;
- Vector<long long int> m_memBankCount;
+ uint64 m_memReq;
+ uint64 m_memBankBusy;
+ uint64 m_memBusBusy;
+ uint64 m_memTfawBusy;
+ uint64 m_memReadWriteBusy;
+ uint64 m_memDataBusBusy;
+ uint64 m_memRefresh;
+ uint64 m_memRead;
+ uint64 m_memWrite;
+ uint64 m_memWaitCycles;
+ uint64 m_memInputQ;
+ uint64 m_memBankQ;
+ uint64 m_memArbWait;
+ uint64 m_memRandBusy;
+ uint64 m_memNotOld;
+ Vector<uint64> m_memBankCount;
int m_banks_per_rank;
int m_ranks_per_dimm;
int m_dimms_per_channel;
@@ -108,8 +108,6 @@
typedef RubyProfilerParams Params;
Profiler(const Params *);

- void init(const vector<string> & argv, vector<string> memory_control_names);
-
// Destructor
~Profiler();

@@ -173,21 +171,21 @@
}

// added for MemoryControl:
- void profileMemReq(string name, int bank);
- void profileMemBankBusy(string name);
- void profileMemBusBusy(string name);
- void profileMemTfawBusy(string name);
- void profileMemReadWriteBusy(string name);
- void profileMemDataBusBusy(string name);
- void profileMemRefresh(string name);
- void profileMemRead(string name);
- void profileMemWrite(string name);
- void profileMemWaitCycles(string name, int cycles);
- void profileMemInputQ(string name, int cycles);
- void profileMemBankQ(string name, int cycles);
- void profileMemArbWait(string name, int cycles);
- void profileMemRandBusy(string name);
- void profileMemNotOld(string name);
+ void profileMemReq(int mem_cntrl, int bank);
+ void profileMemBankBusy(int mem_cntrl);
+ void profileMemBusBusy(int mem_cntrl);
+ void profileMemTfawBusy(int mem_cntrl);
+ void profileMemReadWriteBusy(int mem_cntrl);
+ void profileMemDataBusBusy(int mem_cntrl);
+ void profileMemRefresh(int mem_cntrl);
+ void profileMemRead(int mem_cntrl);
+ void profileMemWrite(int mem_cntrl);
+ void profileMemWaitCycles(int mem_cntrl, int cycles);
+ void profileMemInputQ(int mem_cntrl, int cycles);
+ void profileMemBankQ(int mem_cntrl, int cycles);
+ void profileMemArbWait(int mem_cntrl, int cycles);
+ void profileMemRandBusy(int mem_cntrl);
+ void profileMemNotOld(int mem_cntrl);
//added by SS
bool getHotLines() { return m_hot_lines; }
bool getAllInstructions() { return m_all_instructions; }
@@ -259,7 +257,7 @@

// added for MemoryControl:
//added by SS
- map< string, memory_control_profiler* > m_memory_control_profilers;
+ Vector < memory_control_profiler* > m_mc_profilers;

//added by SS
bool m_hot_lines;
diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/profiler/Profiler.py
--- a/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/profiler/Profiler.py Sat Dec 12 14:37:16 2009 -0800
@@ -6,6 +6,10 @@
cxx_class = 'Profiler'
hot_lines = Param.Bool(False, "")
all_instructions = Param.Bool(False, "")
+ mem_cntrl_count = Param.Int(0, "")
+ banks_per_rank = Param.Int("")
+ ranks_per_dimm = Param.Int("")
+ dimms_per_channel = Param.Int("")

class CacheProfiler(SimObject):
type = 'CacheProfiler'
diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/system/MemoryControl.cc
--- a/src/mem/ruby/system/MemoryControl.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/MemoryControl.cc Sat Dec 12 14:37:16 2009 -0800
@@ -154,6 +154,7 @@
MemoryControl::MemoryControl(const Params *p)
: SimObject(p)
{
+ m_version = p->version;
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;
@@ -266,8 +267,8 @@
printf("New memory request%7d: 0x%08llx %c arrived at %10lld ", m_msg_counter, addr, is_mem_read? 'R':'W', at);
printf("bank =%3x\n", bank);
}
-// printf ("m_name is %s \n", m_name.c_str());
- g_system_ptr->getProfiler()->profileMemReq(m_name, bank);
+
+ g_system_ptr->getProfiler()->profileMemReq(m_version, bank);
m_input_queue.push_back(memRef);
if (!m_awakened) {
g_eventQueue_ptr->scheduleEvent(this, 1);
@@ -394,19 +395,19 @@

bool MemoryControl::queueReady (int bank) {
if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) {
- g_system_ptr->getProfiler()->profileMemBankBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemBankBusy(m_version);
//if (m_debug) printf(" bank %x busy %d\n", bank, m_bankBusyCounter[bank]);
return false;
}
if (m_mem_random_arbitrate >= 2) {
if ((random() % 100) < m_mem_random_arbitrate) {
- g_system_ptr->getProfiler()->profileMemRandBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemRandBusy(m_version);
return false;
}
}
if (m_mem_fixed_delay) return true;
if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) {
- g_system_ptr->getProfiler()->profileMemNotOld(m_name);
+ g_system_ptr->getProfiler()->profileMemNotOld(m_version);
return false;
}
if (m_busBusyCounter_Basic == m_basic_bus_busy_time) {
@@ -415,26 +416,26 @@
// a bus wait. This is a little inaccurate since it MIGHT
// have also been blocked waiting for a read-write or a
// read-read instead, but it's pretty close.
- g_system_ptr->getProfiler()->profileMemArbWait(m_name, 1);
+ g_system_ptr->getProfiler()->profileMemArbWait(m_version, 1);
return false;
}
if (m_busBusyCounter_Basic > 0) {
- g_system_ptr->getProfiler()->profileMemBusBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemBusBusy(m_version);
return false;
}
int rank = getRank(bank);
if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) {
- g_system_ptr->getProfiler()->profileMemTfawBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemTfawBusy(m_version);
return false;
}
bool write = !m_bankQueues[bank].front().m_is_mem_read;
if (write && (m_busBusyCounter_Write > 0)) {
- g_system_ptr->getProfiler()->profileMemReadWriteBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemReadWriteBusy(m_version);
return false;
}
if (!write && (rank != m_busBusy_WhichRank)
&& (m_busBusyCounter_ReadNewRank > 0)) {
- g_system_ptr->getProfiler()->profileMemDataBusBusy(m_name);
+ g_system_ptr->getProfiler()->profileMemDataBusBusy(m_version);
return false;
}
return true;
@@ -459,7 +460,7 @@
//uint64 current_time = g_eventQueue_ptr->getTime();
//printf(" Refresh bank %3x at %lld\n", bank, current_time);
//}
- g_system_ptr->getProfiler()->profileMemRefresh(m_name);
+ g_system_ptr->getProfiler()->profileMemRefresh(m_version);
m_need_refresh--;
m_refresh_bank++;
if (m_refresh_bank >= m_total_banks) m_refresh_bank = 0;
@@ -503,12 +504,12 @@
m_bankBusyCounter[bank] = m_bank_busy_time;
m_busBusy_WhichRank = rank;
if (req.m_is_mem_read) {
- g_system_ptr->getProfiler()->profileMemRead(m_name);
+ g_system_ptr->getProfiler()->profileMemRead(m_version);
m_busBusyCounter_Basic = m_basic_bus_busy_time;
m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay;
m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time + m_rank_rank_delay;
} else {
- g_system_ptr->getProfiler()->profileMemWrite(m_name);
+ g_system_ptr->getProfiler()->profileMemWrite(m_version);
m_busBusyCounter_Basic = m_basic_bus_busy_time;
m_busBusyCounter_Write = m_basic_bus_busy_time;
m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time;
@@ -577,7 +578,7 @@
issueRefresh(m_roundRobin);
int qs = m_bankQueues[m_roundRobin].size();
if (qs > 1) {
- g_system_ptr->getProfiler()->profileMemBankQ(m_name, qs-1);
+ g_system_ptr->getProfiler()->profileMemBankQ(m_version, qs-1);
}
if (qs > 0) {
m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is queued
@@ -586,14 +587,14 @@
issueRequest(m_roundRobin);
banksIssued++;
if (m_mem_fixed_delay) {
- g_system_ptr->getProfiler()->profileMemWaitCycles(m_name, m_mem_fixed_delay);
+ g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, m_mem_fixed_delay);
}
}
}
}

// memWaitCycles is a redundant catch-all for the specific counters in queueReady
- g_system_ptr->getProfiler()->profileMemWaitCycles(m_name, queueHeads - banksIssued);
+ g_system_ptr->getProfiler()->profileMemWaitCycles(m_version, queueHeads - banksIssued);

// Check input queue and move anything to bank queues if not full.
// Since this is done here at the end of the cycle, there will always
@@ -610,7 +611,7 @@
m_input_queue.pop_front();
m_bankQueues[bank].push_back(req);
}
- g_system_ptr->getProfiler()->profileMemInputQ(m_name, m_input_queue.size());
+ g_system_ptr->getProfiler()->profileMemInputQ(m_version, m_input_queue.size());
}
}

diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/system/MemoryControl.hh
--- a/src/mem/ruby/system/MemoryControl.hh Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/MemoryControl.hh Sat Dec 12 14:37:16 2009 -0800
@@ -123,7 +123,7 @@

// data members
Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
- string m_name;
+ int m_version;
string m_description;
int m_msg_counter;
int m_awakened;
diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/system/MemoryControl.py
--- a/src/mem/ruby/system/MemoryControl.py Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/MemoryControl.py Sat Dec 12 14:37:16 2009 -0800
@@ -4,6 +4,7 @@
class RubyMemoryControl(SimObject):
type = 'RubyMemoryControl'
cxx_class = 'MemoryControl'
+ version = Param.Int("");
mem_bus_cycle_multiplier = Param.Int(10, "");
banks_per_rank = Param.Int(8, "");
ranks_per_dimm = Param.Int(2, "");
diff -r e68f680829da -r 23ea85c0fc27 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:16 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:16 2009 -0800
@@ -233,6 +233,7 @@

void RubySystem::init()
{
+ m_profiler_ptr->clearStats();
}
nathan binkert
2009-12-21 21:59:44 UTC
Permalink
Post by Brad Beckmann
# HG changeset patch
# Date 1260657436 28800
# Node ID 23ea85c0fc27eaa31f042bdc37238856ffc7769e
# Parent  e68f680829daff5e16ea6d520c7302f7ed5055f9
diff -r e68f680829da -r 23ea85c0fc27 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:16 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:16 2009 -0800
+                         debug = RubyDebug(),#filter_string = 'qQin',
+                                           #verbosity_string = 'high',
+                                           #protocol_trace = True),
More commented code.
Post by Brad Beckmann
@@ -170,17 +168,51 @@
+  (*m_periodic_output_file_ptr) << "ruby_cycles: "
+                                << g_eventQueue_ptr->getTime()-m_ruby_start
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "total_misses: "
+                                << total_misses
+                                << " "
+                                << m_perProcTotalMisses
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "simics_cycles_executed: "
+                                << simics_cycles_executed
+                                << " "
+                                << perProcCycleCount
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "transactions_started: "
+                                << transactions_started
+                                << " "
+                                << m_perProcStartTransaction
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "transactions_ended: "
+                                << transactions_ended
+                                << " "
+                                << m_perProcEndTransaction
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "mbytes_resident: "
+                                << process_memory_resident()
+                                << endl;
+
+  (*m_periodic_output_file_ptr) << "mbytes_total: "
+                                << process_memory_total()
+                                << endl;
+
Seems like a temporary variable that has a much shorter name would
help clean this code up. Also, you can use cprintf if you want to
clean it up even more.
Post by Brad Beckmann
+    uint64 m_memReq = m_mc_profilers[mem_cntrl]->m_memReq;
+    uint64 m_memRefresh = m_mc_profilers[mem_cntrl]->m_memRefresh;
+    uint64 m_memInputQ = m_mc_profilers[mem_cntrl]->m_memInputQ;
+    uint64 m_memBankQ = m_mc_profilers[mem_cntrl]->m_memBankQ;
+    uint64 m_memWaitCycles = m_mc_profilers[mem_cntrl]->m_memWaitCycles;
+    uint64 m_memRead = m_mc_profilers[mem_cntrl]->m_memRead;
+    uint64 m_memWrite = m_mc_profilers[mem_cntrl]->m_memWrite;
+    uint64 m_memBankBusy = m_mc_profilers[mem_cntrl]->m_memBankBusy;
+    uint64 m_memRandBusy = m_mc_profilers[mem_cntrl]->m_memRandBusy;
+    uint64 m_memNotOld = m_mc_profilers[mem_cntrl]->m_memNotOld;
+    uint64 m_memArbWait = m_mc_profilers[mem_cntrl]->m_memArbWait;
+    uint64 m_memBusBusy = m_mc_profilers[mem_cntrl]->m_memBusBusy;
+    uint64 m_memTfawBusy = m_mc_profilers[mem_cntrl]->m_memTfawBusy;
+    uint64 m_memReadWriteBusy = m_mc_profilers[mem_cntrl]->m_memReadWriteBusy;
+    uint64 m_memDataBusBusy = m_mc_profilers[mem_cntrl]->m_memDataBusBusy;
+    Vector<uint64> m_memBankCount = m_mc_profilers[mem_cntrl]->m_memBankCount;
I dont' have enough context to understand what is going on here, but
what is the point of all of these variables? It seems that just using
a short temporary for "m_mc_profilers[mem_cntrl]" would make it easy
to avoid these temporaries
Post by Brad Beckmann
+
+void Profiler::profileMemBankBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memBankBusy++;
+}
+
+void Profiler::profileMemBusBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memBusBusy++;
+}
+
+void Profiler::profileMemReadWriteBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memReadWriteBusy++;
+}
+
+void Profiler::profileMemDataBusBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memDataBusBusy++;
+}
+
+void Profiler::profileMemTfawBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memTfawBusy++;
+}
+
+void Profiler::profileMemRefresh(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memRefresh++;
+}
+
+void Profiler::profileMemRead(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memRead++;
+}
+
+void Profiler::profileMemWrite(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memWrite++;
+}
+
+void Profiler::profileMemWaitCycles(int mem_cntrl, int cycles) {
+  m_mc_profilers[mem_cntrl]->m_memWaitCycles += cycles;
+}
+
+void Profiler::profileMemInputQ(int mem_cntrl, int cycles) {
+  m_mc_profilers[mem_cntrl]->m_memInputQ += cycles;
+}
+
+void Profiler::profileMemBankQ(int mem_cntrl, int cycles) {
+  m_mc_profilers[mem_cntrl]->m_memBankQ += cycles;
+}
+
+void Profiler::profileMemArbWait(int mem_cntrl, int cycles) {
+  m_mc_profilers[mem_cntrl]->m_memArbWait += cycles;
+}
+
+void Profiler::profileMemRandBusy(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memRandBusy++;
+}
+
+void Profiler::profileMemNotOld(int mem_cntrl) {
+  m_mc_profilers[mem_cntrl]->m_memNotOld++;
+}
M5 style would have a newline after the return type, and a newline
before the opening brace of the function. If you're going to change
this, it'd be nice to make it follow the style.
Brad Beckmann
2009-12-12 22:37:31 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID f164db9baf4ad51cf790ea3b134fed28f4e3d026
# Parent 5d3a90f0ef4c0f69f61fd262028a32fa5e632f8e
ruby: Copy M5 Port code from RubyMemory to RubyPort.

diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc Sat Dec 12 14:37:15 2009 -0800
@@ -5,8 +5,11 @@
//void (*RubyPort::m_hit_callback)(int64_t) = NULL;
uint16_t RubyPort::m_num_ports = 0;

+RubyPort::RequestMap RubyPort::pending_requests;
+
RubyPort::RubyPort(const Params *p)
- : MemObject(p)
+ : MemObject(p),
+ funcMemPort(csprintf("%s-funcmem_port", name()), this)
{
m_version = p->version;
assert(m_version != -1);
@@ -24,5 +27,196 @@
Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
+ if (if_name == "port") {
+ return new M5Port(csprintf("%s-port%d", name(), idx), this);
+ } else if (if_name == "funcmem_port") {
+ return &funcMemPort;
+ }
return NULL;
}
+
+RubyPort::M5Port::M5Port(const std::string &_name,
+ RubyPort *_port)
+ : SimpleTimingPort(_name, _port)
+{
+ DPRINTF(Ruby, "creating port to ruby memory %s\n", _name);
+ ruby_port = _port;
+}
+
+Tick
+RubyPort::M5Port::recvAtomic(PacketPtr pkt)
+{
+ panic("RubyPort::M5Port::recvAtomic() not implemented!\n");
+ return 0;
+}
+
+
+bool
+RubyPort::M5Port::recvTiming(PacketPtr pkt)
+{
+ DPRINTF(MemoryAccess,
+ "Timing access caught for address %#x\n",
+ pkt->getAddr());
+
+ //dsm: based on SimpleTimingPort::recvTiming(pkt);
+
+ //
+ // In FS mode, ruby memory will receive pio responses from devices and
+ // it must forward these responses back to the particular CPU.
+ //
+#if 0
+ if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) {
+ DPRINTF(MemoryAccess,
+ "Pio Response callback %#x\n",
+ pkt->getAddr());
+ SenderState *senderState = safe_cast<SenderState *>(pkt->senderState);
+ M5Port *port = senderState->port;
+
+ // pop the sender state from the packet
+ pkt->senderState = senderState->saved;
+ delete senderState;
+
+ port->sendTiming(pkt);
+
+ return true;
+ }
+#endif
+
+ //
+ // After checking for pio responses, the remainder of packets
+ // received by ruby should only be M5 requests, which should never
+ // get nacked. There used to be code to hanldle nacks here, but
+ // I'm pretty sure it didn't work correctly with the drain code,
+ // so that would need to be fixed if we ever added it back.
+ //
+ assert(pkt->isRequest());
+
+ if (pkt->memInhibitAsserted()) {
+ warn("memInhibitAsserted???");
+ // snooper will supply based on copy of packet
+ // still target's responsibility to delete packet
+ delete pkt;
+ return true;
+ }
+
+ //
+ // Check for pio requests and directly send them to the dedicated
+ // pio_port.
+ //
+#if 0
+ if (isPioAddress(pkt->getAddr()) != false) {
+ return ruby_mem->pio_port->sendTiming(pkt);
+ }
+#endif
+
+ //
+ // For DMA and CPU requests, translate them to ruby requests before
+ // sending them to our assigned ruby port.
+ //
+ RubyRequestType type = RubyRequestType_NULL;
+ Addr pc = 0;
+ if (pkt->isRead()) {
+ if (pkt->req->isInstFetch()) {
+ type = RubyRequestType_IFETCH;
+ pc = pkt->req->getPC();
+ } else {
+ type = RubyRequestType_LD;
+ }
+ } else if (pkt->isWrite()) {
+ type = RubyRequestType_ST;
+ } else if (pkt->isReadWrite()) {
+ // type = RubyRequestType_RMW;
+ }
+
+ RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
+ pkt->getSize(), pc, type,
+ RubyAccessMode_Supervisor);
+
+ // Submit the ruby request
+ int64_t req_id = ruby_port->makeRequest(ruby_request);
+ if (req_id == -1) {
+ return false;
+ }
+
+ // Save the request for the callback
+ RubyPort::pending_requests[req_id] = new RequestCookie(pkt, this);
+
+ return true;
+}
+
+void
+RubyPort::ruby_hit_callback(int64_t req_id)
+{
+ //
+ // Note: This single fuction can be called by cpu and dma ports,
+ // as well as the functional port. The functional port prevents
+ // us from replacing this single function with separate port
+ // functions.
+ //
+ RequestMap::iterator i = pending_requests.find(req_id);
+ if (i == pending_requests.end())
+ panic("could not find pending request %d\n", req_id);
+
+ RequestCookie *cookie = i->second;
+ pending_requests.erase(i);
+
+ Packet *pkt = cookie->pkt;
+ M5Port *port = cookie->m5Port;
+ delete cookie;
+
+ port->hitCallback(pkt);
+}
+
+void
+RubyPort::M5Port::hitCallback(PacketPtr pkt)
+{
+
+ bool needsResponse = pkt->needsResponse();
+
+ DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
+ needsResponse);
+
+ ruby_port->funcMemPort.sendFunctional(pkt);
+
+ // turn packet around to go back to requester if response expected
+ if (needsResponse) {
+ // recvAtomic() should already have turned packet into
+ // atomic response
+ assert(pkt->isResponse());
+ DPRINTF(MemoryAccess, "Sending packet back over port\n");
+ sendTiming(pkt);
+ } else {
+ delete pkt;
+ }
+ DPRINTF(MemoryAccess, "Hit callback done!\n");
+}
+
+bool
+RubyPort::M5Port::sendTiming(PacketPtr pkt)
+{
+ schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
+ return true;
+}
+
+bool
+RubyPort::M5Port::isPioAddress(Addr addr)
+{
+#if 0
+ AddrRangeList pioAddrList;
+ bool snoop = false;
+ if (ruby_mem->pio_port == NULL) {
+ return false;
+ }
+
+ ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop);
+ for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) {
+ if (addr >= iter->start && addr <= iter->end) {
+ DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
+ iter->start, iter->end);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh Sat Dec 12 14:37:15 2009 -0800
@@ -17,6 +17,28 @@

class RubyPort : public MemObject {
public:
+
+ class M5Port : public SimpleTimingPort
+ {
+
+ RubyPort *ruby_port;
+
+ public:
+ M5Port(const std::string &_name,
+ RubyPort *_port);
+ bool sendTiming(PacketPtr pkt);
+ void hitCallback(PacketPtr pkt);
+
+ protected:
+ virtual bool recvTiming(PacketPtr pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
+
+ private:
+ bool isPioAddress(Addr addr);
+ };
+
+ friend class M5Port;
+
typedef RubyPortParams Params;
RubyPort(const Params *p);
virtual ~RubyPort() {}
@@ -63,6 +85,20 @@
static uint16_t m_num_ports;
uint16_t m_port_id;
uint64_t m_request_cnt;
+
+ struct RequestCookie {
+ Packet *pkt;
+ M5Port *m5Port;
+ RequestCookie(Packet *p, M5Port *m5p)
+ : pkt(p), m5Port(m5p)
+ {}
+ };
+
+ typedef std::map<int64_t, RequestCookie*> RequestMap;
+ static RequestMap pending_requests;
+ static void ruby_hit_callback(int64_t req_id);
+
+ FunctionalPort funcMemPort;
};

#endif
nathan binkert
2009-12-21 20:36:31 UTC
Permalink
You've moved a lot of #if 0 code here. Is this code useful? What is
needed to make it work?

Nate
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID f164db9baf4ad51cf790ea3b134fed28f4e3d026
# Parent  5d3a90f0ef4c0f69f61fd262028a32fa5e632f8e
ruby: Copy M5 Port code from RubyMemory to RubyPort.
diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc   Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.cc   Sat Dec 12 14:37:15 2009 -0800
@@ -5,8 +5,11 @@
 //void (*RubyPort::m_hit_callback)(int64_t) = NULL;
 uint16_t RubyPort::m_num_ports = 0;
+RubyPort::RequestMap RubyPort::pending_requests;
+
 RubyPort::RubyPort(const Params *p)
-    : MemObject(p)
+    : MemObject(p),
+      funcMemPort(csprintf("%s-funcmem_port", name()), this)
 {
    m_version = p->version;
    assert(m_version != -1);
@@ -24,5 +27,196 @@
 Port *
 RubyPort::getPort(const std::string &if_name, int idx)
 {
+    if (if_name == "port") {
+        return new M5Port(csprintf("%s-port%d", name(), idx), this);
+    } else if (if_name == "funcmem_port") {
+        return &funcMemPort;
+    }
    return NULL;
 }
+
+RubyPort::M5Port::M5Port(const std::string &_name,
+                         RubyPort *_port)
+    : SimpleTimingPort(_name, _port)
+{
+    DPRINTF(Ruby, "creating port to ruby memory %s\n", _name);
+    ruby_port = _port;
+}
+
+Tick
+RubyPort::M5Port::recvAtomic(PacketPtr pkt)
+{
+    panic("RubyPort::M5Port::recvAtomic() not implemented!\n");
+    return 0;
+}
+
+
+bool
+RubyPort::M5Port::recvTiming(PacketPtr pkt)
+{
+    DPRINTF(MemoryAccess,
+            "Timing access caught for address %#x\n",
+            pkt->getAddr());
+
+    //dsm: based on SimpleTimingPort::recvTiming(pkt);
+
+    //
+    // In FS mode, ruby memory will receive pio responses from devices and
+    // it must forward these responses back to the particular CPU.
+    //
+#if 0
+   if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) {
+        DPRINTF(MemoryAccess,
+                "Pio Response callback %#x\n",
+                pkt->getAddr());
+        SenderState *senderState = safe_cast<SenderState *>(pkt->senderState);
+        M5Port *port = senderState->port;
+
+        // pop the sender state from the packet
+        pkt->senderState = senderState->saved;
+        delete senderState;
+
+        port->sendTiming(pkt);
+
+        return true;
+    }
+#endif
+
+    //
+    // After checking for pio responses, the remainder of packets
+    // received by ruby should only be M5 requests, which should never
+    // get nacked.  There used to be code to hanldle nacks here, but
+    // I'm pretty sure it didn't work correctly with the drain code,
+    // so that would need to be fixed if we ever added it back.
+    //
+    assert(pkt->isRequest());
+
+    if (pkt->memInhibitAsserted()) {
+        warn("memInhibitAsserted???");
+        // snooper will supply based on copy of packet
+        // still target's responsibility to delete packet
+        delete pkt;
+        return true;
+    }
+
+    //
+    // Check for pio requests and directly send them to the dedicated
+    // pio_port.
+    //
+#if 0
+    if (isPioAddress(pkt->getAddr()) != false) {
+        return ruby_mem->pio_port->sendTiming(pkt);
+    }
+#endif
+
+    //
+    // For DMA and CPU requests, translate them to ruby requests before
+    // sending them to our assigned ruby port.
+    //
+    RubyRequestType type = RubyRequestType_NULL;
+    Addr pc = 0;
+    if (pkt->isRead()) {
+        if (pkt->req->isInstFetch()) {
+            type = RubyRequestType_IFETCH;
+            pc = pkt->req->getPC();
+        } else {
+            type = RubyRequestType_LD;
+        }
+    } else if (pkt->isWrite()) {
+        type = RubyRequestType_ST;
+    } else if (pkt->isReadWrite()) {
+      //        type = RubyRequestType_RMW;
+    }
+
+    RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
+                             pkt->getSize(), pc, type,
+                             RubyAccessMode_Supervisor);
+
+    // Submit the ruby request
+    int64_t req_id = ruby_port->makeRequest(ruby_request);
+    if (req_id == -1) {
+        return false;
+    }
+
+    // Save the request for the callback
+    RubyPort::pending_requests[req_id] = new RequestCookie(pkt, this);
+
+    return true;
+}
+
+void
+RubyPort::ruby_hit_callback(int64_t req_id)
+{
+    //
+    // Note: This single fuction can be called by cpu and dma ports,
+    // as well as the functional port.  The functional port prevents
+    // us from replacing this single function with separate port
+    // functions.
+    //
+    RequestMap::iterator i = pending_requests.find(req_id);
+    if (i == pending_requests.end())
+        panic("could not find pending request %d\n", req_id);
+
+    RequestCookie *cookie = i->second;
+    pending_requests.erase(i);
+
+    Packet *pkt = cookie->pkt;
+    M5Port *port = cookie->m5Port;
+    delete cookie;
+
+    port->hitCallback(pkt);
+}
+
+void
+RubyPort::M5Port::hitCallback(PacketPtr pkt)
+{
+
+    bool needsResponse = pkt->needsResponse();
+
+    DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
+            needsResponse);
+
+    ruby_port->funcMemPort.sendFunctional(pkt);
+
+    // turn packet around to go back to requester if response expected
+    if (needsResponse) {
+        // recvAtomic() should already have turned packet into
+        // atomic response
+        assert(pkt->isResponse());
+        DPRINTF(MemoryAccess, "Sending packet back over port\n");
+        sendTiming(pkt);
+    } else {
+        delete pkt;
+    }
+    DPRINTF(MemoryAccess, "Hit callback done!\n");
+}
+
+bool
+RubyPort::M5Port::sendTiming(PacketPtr pkt)
+{
+    schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
+    return true;
+}
+
+bool
+RubyPort::M5Port::isPioAddress(Addr addr)
+{
+#if 0
+    AddrRangeList pioAddrList;
+    bool snoop = false;
+    if (ruby_mem->pio_port == NULL) {
+        return false;
+    }
+
+    ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop);
+    for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) {
+        if (addr >= iter->start && addr <= iter->end) {
+            DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
+                    iter->start, iter->end);
+            return true;
+        }
+    }
+#endif
+    return false;
+}
+
diff -r 5d3a90f0ef4c -r f164db9baf4a src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh   Sat Dec 12 14:37:14 2009 -0800
+++ b/src/mem/ruby/system/RubyPort.hh   Sat Dec 12 14:37:15 2009 -0800
@@ -17,6 +17,28 @@
 class RubyPort : public MemObject {
+
+    class M5Port : public SimpleTimingPort
+    {
+
+        RubyPort *ruby_port;
+
+        M5Port(const std::string &_name,
+               RubyPort *_port);
+        bool sendTiming(PacketPtr pkt);
+        void hitCallback(PacketPtr pkt);
+
+        virtual bool recvTiming(PacketPtr pkt);
+        virtual Tick recvAtomic(PacketPtr pkt);
+
+        bool isPioAddress(Addr addr);
+    };
+
+    friend class M5Port;
+
    typedef RubyPortParams Params;
    RubyPort(const Params *p);
  virtual ~RubyPort() {}
@@ -63,6 +85,20 @@
  static uint16_t m_num_ports;
  uint16_t m_port_id;
  uint64_t m_request_cnt;
+
+    struct RequestCookie {
+        Packet *pkt;
+        M5Port *m5Port;
+        RequestCookie(Packet *p, M5Port *m5p)
+            : pkt(p), m5Port(m5p)
+        {}
+    };
+
+    typedef std::map<int64_t, RequestCookie*> RequestMap;
+    static RequestMap pending_requests;
+    static void ruby_hit_callback(int64_t req_id);
+
+    FunctionalPort funcMemPort;
 };
 #endif
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:33 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID d5c731012d722a9b54373ed45600e9e978001ea9
# Parent e657fd802abe54b28a19e2c851e8b3f700b10293
ruby: Calculate system total memory capacity in Python
rather than in RubySystem object.

diff -r e657fd802abe -r d5c731012d72 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -134,10 +134,13 @@
network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
dir_cntrl_nodes))

+mem_size_mb = sum([int(dc.directory.size_mb) for dc in dc_nodes])
+
system.ruby = RubySystem(network = network,
profiler = RubyProfiler(),
tracer = RubyTracer(),
- debug = RubyDebug())
+ debug = RubyDebug(),
+ mem_size_mb = mem_size_mb)


# -----------------------
diff -r e657fd802abe -r d5c731012d72 src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
@@ -8,6 +8,7 @@
tech_nm = Param.Int(45, "");
freq_mhz = Param.Int(3000, "");
block_size_bytes = Param.Int(64, "");
+ mem_size_mb = Param.Int("");
network = Param.RubyNetwork("")
debug = Param.RubyDebug("")
profiler = Param.RubyProfiler("");
diff -r e657fd802abe -r d5c731012d72 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
@@ -94,9 +94,14 @@
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_memory_size_bytes = (uint64_t)p->mem_size_mb * 1024 * 1024;
+ m_memory_size_bits = log_int(m_memory_size_bytes);
+
m_network_ptr = p->network;
g_debug_ptr = p->debug;
m_profiler_ptr = p->profiler;
@@ -105,6 +110,7 @@
//assert( g_debug_ptr != NULL);
g_system_ptr = this;
m_mem_vec_ptr = new MemoryVector;
+ m_mem_vec_ptr->setSize(m_memory_size_bytes);

/* 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
@@ -226,18 +232,6 @@

void RubySystem::init()
{
- // calculate system-wide parameters
- m_memory_size_bytes = 0;
- DirectoryMemory* prev = NULL;
- for (map< string, DirectoryMemory*>::const_iterator it = m_directories.begin();
- it != m_directories.end(); it++) {
- if (prev != NULL)
- assert((*it).second->getSize() == prev->getSize()); // must be equal for proper address mapping
- m_memory_size_bytes += (*it).second->getSize();
- prev = (*it).second;
- }
- m_mem_vec_ptr->setSize(m_memory_size_bytes);
- m_memory_size_bits = log_int(m_memory_size_bytes);
}
nathan binkert
2009-12-21 20:43:41 UTC
Permalink
It would be nice if you made this parameter a MemorySize type instead of Int.
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID d5c731012d722a9b54373ed45600e9e978001ea9
# Parent  e657fd802abe54b28a19e2c851e8b3f700b10293
ruby: Calculate system total memory capacity in Python
rather than in RubySystem object.
diff -r e657fd802abe -r d5c731012d72 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py   Sat Dec 12 14:37:15 2009 -0800
@@ -134,10 +134,13 @@
 network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
                                                dir_cntrl_nodes))
+mem_size_mb = sum([int(dc.directory.size_mb) for dc in dc_nodes])
+
 system.ruby = RubySystem(network = network,
                         profiler = RubyProfiler(),
                         tracer = RubyTracer(),
-                         debug = RubyDebug())
+                         debug = RubyDebug(),
+                         mem_size_mb = mem_size_mb)
 # -----------------------
diff -r e657fd802abe -r d5c731012d72 src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
@@ -8,6 +8,7 @@
    tech_nm = Param.Int(45, "");
    freq_mhz = Param.Int(3000, "");
    block_size_bytes = Param.Int(64, "");
+    mem_size_mb = Param.Int("");
    network = Param.RubyNetwork("")
    debug = Param.RubyDebug("")
    profiler = Param.RubyProfiler("");
diff -r e657fd802abe -r d5c731012d72 src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc     Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/System.cc     Sat Dec 12 14:37:15 2009 -0800
@@ -94,9 +94,14 @@
    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_memory_size_bytes = (uint64_t)p->mem_size_mb * 1024 * 1024;
+    m_memory_size_bits = log_int(m_memory_size_bytes);
+
    m_network_ptr = p->network;
    g_debug_ptr = p->debug;
    m_profiler_ptr = p->profiler;
@@ -105,6 +110,7 @@
    //assert( g_debug_ptr != NULL);
  g_system_ptr = this;
  m_mem_vec_ptr = new MemoryVector;
+    m_mem_vec_ptr->setSize(m_memory_size_bytes);
  /* 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
@@ -226,18 +232,6 @@
 void RubySystem::init()
 {
-  // calculate system-wide parameters
-  m_memory_size_bytes = 0;
-  DirectoryMemory* prev = NULL;
-  for (map< string, DirectoryMemory*>::const_iterator it = m_directories.begin();
-       it != m_directories.end(); it++) {
-    if (prev != NULL)
-      assert((*it).second->getSize() == prev->getSize()); // must be equal for proper address mapping
-    m_memory_size_bytes += (*it).second->getSize();
-    prev = (*it).second;
-  }
-  m_mem_vec_ptr->setSize(m_memory_size_bytes);
-  m_memory_size_bits = log_int(m_memory_size_bytes);
 }
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Brad Beckmann
2009-12-12 22:37:41 UTC
Permalink
# HG changeset patch
# User Brad Beckmann <Brad.Beckmann-***@public.gmane.org>
# Date 1260657435 28800
# Node ID c1b464b8baad8ab20030eb6b36859035c769122d
# Parent 856ecd55b3729ea5f083b76bc4750a29b008b707
ruby: Added clock to ruby system
As a first step to migrate ruby to the M5 eventqueue, added a clock
variable to the ruby system.

diff -r 856ecd55b372 -r c1b464b8baad configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
+++ b/configs/example/memtest-ruby.py Sat Dec 12 14:37:15 2009 -0800
@@ -158,7 +158,8 @@
mem_size_mb = sum([int(dir_cntrl.directory.size_mb) \
for dir_cntrl in dir_cntrl_nodes])

-system.ruby = RubySystem(network = network,
+system.ruby = RubySystem(clock = '1GHz',
+ network = network,
profiler = RubyProfiler(),
tracer = RubyTracer(),
debug = RubyDebug(),
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/eventqueue/RubyEventQueue.cc
--- a/src/mem/ruby/eventqueue/RubyEventQueue.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc Sat Dec 12 14:37:15 2009 -0800
@@ -40,9 +40,8 @@

// Class public method definitions

-RubyEventQueue theEventQueue;
-
-RubyEventQueue::RubyEventQueue()
+RubyEventQueue::RubyEventQueue(Tick _clock)
+ : m_clock(_clock)
{
m_prio_heap_ptr = NULL;
init();
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/eventqueue/RubyEventQueue.hh
--- a/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.hh Sat Dec 12 14:37:15 2009 -0800
@@ -70,14 +70,14 @@
class RubyEventQueue {
public:
// Constructors
- RubyEventQueue();
+ RubyEventQueue(Tick clock);

// Destructor
~RubyEventQueue();

// Public Methods

- Time getTime() const { return m_globalTime; }
+ Time getTime() const { return curTick/m_clock; }
void scheduleEvent(Consumer* consumer, Time timeDelta) { scheduleEventAbsolute(consumer, timeDelta + m_globalTime); }
void scheduleEventAbsolute(Consumer* consumer, Time timeAbs);
void triggerEvents(Time t); // called to handle all events <= time t
@@ -96,6 +96,7 @@
RubyEventQueue& operator=(const RubyEventQueue& obj);

// Data Members (m_ prefix)
+ Tick m_clock;
PrioHeap<RubyEventQueueNode>* m_prio_heap_ptr;
Time m_globalTime;
Time m_timeOfLastRecovery;
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
@@ -6,7 +6,7 @@
random_seed = Param.Int(1234, "");
randomization = Param.Bool(False, "");
tech_nm = Param.Int(45, "");
- freq_mhz = Param.Int(3000, "");
+ clock = Param.Clock('1000t', "");
block_size_bytes = Param.Int(64, "");
mem_size_mb = Param.Int("");
network = Param.RubyNetwork("")
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/System.cc Sat Dec 12 14:37:15 2009 -0800
@@ -60,7 +60,7 @@
int RubySystem::m_random_seed;
bool RubySystem::m_randomization;
int RubySystem::m_tech_nm;
-int RubySystem::m_freq_mhz;
+Tick RubySystem::m_clock;
int RubySystem::m_block_size_bytes;
int RubySystem::m_block_size_bits;
uint64 RubySystem::m_memory_size_bytes;
@@ -93,7 +93,7 @@
srandom(m_random_seed);
m_randomization = p->randomization;
m_tech_nm = p->tech_nm;
- m_freq_mhz = p->freq_mhz;
+ m_clock = p->clock;

m_block_size_bytes = p->block_size_bytes;
assert(is_power_of_2(m_block_size_bytes));
@@ -108,8 +108,9 @@
m_tracer_ptr = p->tracer;

//assert( g_debug_ptr != NULL);
- g_system_ptr = this;
- m_mem_vec_ptr = new MemoryVector;
+ g_eventQueue_ptr = new RubyEventQueue(m_clock);
+ g_system_ptr = this;
+ m_mem_vec_ptr = new MemoryVector;
m_mem_vec_ptr->setSize(m_memory_size_bytes);

/* object contruction is broken into two steps (Constructor and init) to avoid cyclic dependencies
@@ -246,7 +247,7 @@
out << " random_seed: " << m_random_seed << endl;
out << " randomization: " << m_randomization << endl;
out << " tech_nm: " << m_tech_nm << endl;
- out << " freq_mhz: " << m_freq_mhz << endl;
+ out << " cycle_period: " << m_clock << endl;
out << " block_size_bytes: " << m_block_size_bytes << endl;
out << " block_size_bits: " << m_block_size_bits << endl;
out << " memory_size_bytes: " << m_memory_size_bytes << endl;
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/system/System.hh
--- a/src/mem/ruby/system/System.hh Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/System.hh Sat Dec 12 14:37:15 2009 -0800
@@ -97,7 +97,6 @@
static int getRandomSeed() { return m_random_seed; }
static int getRandomization() { return m_randomization; }
static int getTechNm() { return m_tech_nm; }
- static int getFreqMhz() { return m_freq_mhz; }
static int getBlockSizeBytes() { return m_block_size_bytes; }
static int getBlockSizeBits() { return m_block_size_bits; }
static uint64 getMemorySizeBytes() { return m_memory_size_bytes; }
@@ -164,7 +163,7 @@
static int m_random_seed;
static bool m_randomization;
static int m_tech_nm;
- static int m_freq_mhz;
+ static Tick m_clock;
static int m_block_size_bytes;
static int m_block_size_bits;
static uint64 m_memory_size_bytes;
nathan binkert
2009-12-21 21:19:04 UTC
Permalink
Post by Brad Beckmann
# HG changeset patch
# Date 1260657435 28800
# Node ID c1b464b8baad8ab20030eb6b36859035c769122d
# Parent  856ecd55b3729ea5f083b76bc4750a29b008b707
diff -r 856ecd55b372 -r c1b464b8baad src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
+++ b/src/mem/ruby/system/RubySystem.py Sat Dec 12 14:37:15 2009 -0800
@@ -6,7 +6,7 @@
    random_seed = Param.Int(1234, "");
    randomization = Param.Bool(False, "");
    tech_nm = Param.Int(45, "");
-    freq_mhz = Param.Int(3000, "");
+    clock = Param.Clock('1000t', "");
Should this really just be '1GHz' ? '1000t' is not as obvious.
nathan binkert
2009-12-12 22:49:22 UTC
Permalink
I'm already at MICRO, so I can't easily review these all right now,
but I will definitely read these papers.

Nate
Here are the patches that will unify configuration and the event queue between ruby and M5.  Please let me know if you have any comments and/or suggestions for improvement.
Brad
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Steve Reinhardt
2009-12-12 23:28:22 UTC
Permalink
Some of these are really mine rather than Brad's, so don't be in too
much of a hurry to blame him if you see something you don't like.
We'll fix up the attributions before we push. I've got to get used to
using "qnew -U" now that we're using a shared patch queue.

Glad to see you got these out, Brad.

Steve
Post by nathan binkert
I'm already at MICRO, so I can't easily review these all right now,
but I will definitely read these papers.
 Nate
Here are the patches that will unify configuration and the event queue between ruby and M5.  Please let me know if you have any comments and/or suggestions for improvement.
Brad
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
nathan binkert
2009-12-13 03:49:07 UTC
Permalink
Post by Steve Reinhardt
Some of these are really mine rather than Brad's, so don't be in too
much of a hurry to blame him if you see something you don't like.
We'll fix up the attributions before we push.  I've got to get used to
using "qnew -U" now that we're using a shared patch queue.
Glad to see you got these out, Brad.
you can fix it with qref (or just manually hack the file.

Nate
Steve Reinhardt
2009-12-13 04:24:57 UTC
Permalink
Post by nathan binkert
Post by Steve Reinhardt
Some of these are really mine rather than Brad's, so don't be in too
much of a hurry to blame him if you see something you don't like.
We'll fix up the attributions before we push.  I've got to get used to
using "qnew -U" now that we're using a shared patch queue.
Glad to see you got these out, Brad.
you can fix it with qref (or just manually hack the file.
Yea, I know -U works with qref too. Better to get in the habit of
using it with qnew, I think.

Steve
nathan binkert
2009-12-13 06:16:54 UTC
Permalink
You can add that to your ~/.hgrc file. Probably not a bad idea for
everyone to do actually.

Nate
Post by nathan binkert
Post by Steve Reinhardt
Some of these are really mine rather than Brad's, so don't be in too
much of a hurry to blame him if you see something you don't like.
We'll fix up the attributions before we push.  I've got to get used to
using "qnew -U" now that we're using a shared patch queue.
Glad to see you got these out, Brad.
you can fix it with qref (or just manually hack the file.
Yea, I know -U works with qref too.  Better to get in the habit of
using it with qnew, I think.
Steve
_______________________________________________
m5-dev mailing list
http://m5sim.org/mailman/listinfo/m5-dev
Loading...