summaryrefslogtreecommitdiff
path: root/sim/pyconfig/m5config.py
diff options
context:
space:
mode:
Diffstat (limited to 'sim/pyconfig/m5config.py')
-rw-r--r--sim/pyconfig/m5config.py106
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 *