diff options
Diffstat (limited to 'sim/pyconfig/m5config.py')
-rw-r--r-- | sim/pyconfig/m5config.py | 106 |
1 files changed, 79 insertions, 27 deletions
diff --git a/sim/pyconfig/m5config.py b/sim/pyconfig/m5config.py index a17732052..4e3a4103c 100644 --- a/sim/pyconfig/m5config.py +++ b/sim/pyconfig/m5config.py @@ -26,14 +26,14 @@ from __future__ import generators import os, re, sys, types +noDot = False +try: + import pydot +except: + noDot = True env = {} env.update(os.environ) -def defined(key): - return env.has_key(key) - -def define(key, value = True): - env[key] = value def panic(*args, **kwargs): sys.exit(*args, **kwargs) @@ -59,9 +59,6 @@ class Singleton(type): cls._instance = super(Singleton, cls).__call__(*args, **kwargs) return cls._instance -if os.environ.has_key('FULL_SYSTEM'): - FULL_SYSTEM = True - ##################################################################### # # M5 Python Configuration Utility @@ -216,6 +213,10 @@ def isParamContext(value): return False +class_decorator = '_M5M5_SIMOBJECT_' +expr_decorator = '_M5M5_EXPRESSION_' +dot_decorator = '_M5M5_DOT_' + # The metaclass for ConfigNode (and thus for everything that derives # from ConfigNode, including SimObject). This class controls how new # classes that derive from ConfigNode are instantiated, and provides @@ -225,7 +226,6 @@ def isParamContext(value): class MetaConfigNode(type): keywords = { 'abstract' : types.BooleanType, 'check' : types.FunctionType, - '_init' : types.FunctionType, 'type' : (types.NoneType, types.StringType) } # __new__ is called before __init__, and is where the statements @@ -241,6 +241,11 @@ class MetaConfigNode(type): '_disable' : {} } for key,val in dict.items(): + del dict[key] + + if key.startswith(expr_decorator): + key = key[len(expr_decorator):] + if mcls.keywords.has_key(key): if not isinstance(val, mcls.keywords[key]): raise TypeError, \ @@ -250,11 +255,9 @@ class MetaConfigNode(type): if isinstance(val, types.FunctionType): val = classmethod(val) priv[key] = val - del dict[key] elif key.startswith('_'): priv[key] = val - del dict[key] elif not isNullPointer(val) and isConfigNode(val): dict[key] = val() @@ -262,19 +265,22 @@ class MetaConfigNode(type): elif isSimObjSequence(val): dict[key] = [ v() for v in val ] + else: + dict[key] = val + # If your parent has a value in it that's a config node, clone it. for base in bases: if not isConfigNode(base): continue - for name,value in base._values.iteritems(): - if dict.has_key(name): + for key,value in base._values.iteritems(): + if dict.has_key(key): continue if isConfigNode(value): - priv['_values'][name] = value() + priv['_values'][key] = value() elif isSimObjSequence(value): - priv['_values'][name] = [ val() for val in value ] + priv['_values'][key] = [ val() for val in value ] # entries left in dict will get passed to __init__, where we'll # deal with them as params. @@ -288,12 +294,12 @@ class MetaConfigNode(type): cls._bases = [c for c in cls.__mro__ if isConfigNode(c)] # initialize attributes with values from class definition - for pname,value in dict.iteritems(): - setattr(cls, pname, value) - - if hasattr(cls, '_init'): - cls._init() - del cls._init + for key,value in dict.iteritems(): + key = key.split(dot_decorator) + c = cls + for item in key[:-1]: + c = getattr(c, item) + setattr(c, key[-1], value) def _isvalue(cls, name): for c in cls._bases: @@ -385,7 +391,6 @@ class MetaConfigNode(type): raise AttributeError, \ "object '%s' has no attribute '%s'" % (cls.__name__, cls) - # Set attribute (called on foo.attr = value when foo is an # instance of class cls). def __setattr__(cls, attr, value): @@ -657,7 +662,7 @@ class Node(object): % (self.name, ptype, value._path) found, done = obj.find(ptype, value._path) if isinstance(found, Proxy): - done = false + done = False obj = obj.parent return found @@ -715,6 +720,48 @@ class Node(object): for c in self.children: c.display() + # print type and parameter values to .ini file + def outputDot(self, dot): + + + label = "{%s|" % self.path + if isSimObject(self.realtype): + label += '%s|' % self.type + + if self.children: + # instantiate children in same order they were added for + # backward compatibility (else we can end up with cpu1 + # before cpu0). + for c in self.children: + dot.add_edge(pydot.Edge(self.path,c.path, style="bold")) + + simobjs = [] + for param in self.params: + try: + if param.value is None: + raise AttributeError, 'Parameter with no value' + + value = param.convert(param.value) + string = param.string(value) + except: + print 'exception in %s:%s' % (self.name, param.name) + raise + ptype = eval(param.ptype) + if isConfigNode(ptype) and string != "Null": + simobjs.append(string) + else: + label += '%s = %s\\n' % (param.name, string) + + for so in simobjs: + label += "|<%s> %s" % (so, so) + dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, tailport="w")) + label += '}' + dot.add_node(pydot.Node(self.path,shape="Mrecord",label=label)) + + # recursively dump out children + for c in self.children: + c.outputDot(dot) + def _string(cls, value): if not isinstance(value, Node): raise AttributeError, 'expecting %s got %s' % (Node, value) @@ -1212,10 +1259,6 @@ class Enum(type): # "Constants"... handy aliases for various values. # -# For compatibility with C++ bool constants. -false = False -true = True - # Some memory range specifications use this as a default upper bound. MAX_ADDR = Addr._max MaxTick = Tick._max @@ -1251,6 +1294,15 @@ def instantiate(root): instance = root.instantiate('root') instance.fixup() instance.display() + if not noDot: + dot = pydot.Dot() + instance.outputDot(dot) + dot.orientation = "portrait" + dot.size = "8.5,11" + dot.ranksep="equally" + dot.rank="samerank" + dot.write("config.dot") + dot.write_ps("config.ps") from objects import * |