summaryrefslogtreecommitdiff
path: root/sim/pyconfig
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2005-02-04 18:25:49 -0500
committerKevin Lim <ktlim@umich.edu>2005-02-04 18:25:49 -0500
commit1e7a744c09d0bde70e0f83179fdf4d6059585e4b (patch)
tree9bbc7713c4bb79abb3f76b07547d8822f0557caa /sim/pyconfig
parentc389c2e327cc3ee1c988855b05505660c6670172 (diff)
parentb78d7c2f16dac11ed468de45a088a362605c6493 (diff)
downloadgem5-1e7a744c09d0bde70e0f83179fdf4d6059585e4b.tar.xz
Hand merge
--HG-- extra : convert_revision : 86c7399b79c17558041a73056745227f70fe8b3b
Diffstat (limited to 'sim/pyconfig')
-rw-r--r--sim/pyconfig/SConscript15
-rw-r--r--sim/pyconfig/m5config.py131
2 files changed, 108 insertions, 38 deletions
diff --git a/sim/pyconfig/SConscript b/sim/pyconfig/SConscript
index 127b0efae..5708ac9a8 100644
--- a/sim/pyconfig/SConscript
+++ b/sim/pyconfig/SConscript
@@ -28,14 +28,15 @@
import os, os.path, re
-def WriteEmbeddedPyFile(target, source, path, name, ext):
+def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
if isinstance(source, str):
source = file(source, 'r')
if isinstance(target, str):
target = file(target, 'w')
- print >>target, "AddModule(%s, %s, %s, '''\\" % (`path`, `name`, `ext`)
+ print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
+ (`path`, `name`, `ext`, `filename`)
for line in source:
line = line
@@ -105,7 +106,7 @@ def MakeEmbeddedPyFile(target, source, env):
name,ext = pyfile.split('.')
if name == '__init__':
node['.hasinit'] = True
- node[pyfile] = (src,name,ext)
+ node[pyfile] = (src,name,ext,src)
done = False
while not done:
@@ -136,12 +137,12 @@ def MakeEmbeddedPyFile(target, source, env):
raise NameError, 'package directory missing __init__.py'
populate(entry, path + [ name ])
else:
- pyfile,name,ext = entry
- files.append((pyfile, path, name, ext))
+ pyfile,name,ext,filename = entry
+ files.append((pyfile, path, name, ext, filename))
populate(tree)
- for pyfile, path, name, ext in files:
- WriteEmbeddedPyFile(target, pyfile, path, name, ext)
+ for pyfile, path, name, ext, filename in files:
+ WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)
CFileCounter = 0
def MakePythonCFile(target, source, env):
diff --git a/sim/pyconfig/m5config.py b/sim/pyconfig/m5config.py
index 4e2a377b0..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
@@ -209,6 +206,17 @@ def isSimObjSequence(value):
return True
+def isParamContext(value):
+ try:
+ return issubclass(value, ParamContext)
+ except:
+ 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
@@ -218,7 +226,6 @@ def isSimObjSequence(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
@@ -234,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, \
@@ -243,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()
@@ -255,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.
@@ -281,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:
@@ -378,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):
@@ -435,7 +447,7 @@ class MetaConfigNode(type):
# Print instance info to .ini file.
def instantiate(cls, name, parent = None):
- instance = Node(name, cls, cls.type, parent)
+ instance = Node(name, cls, cls.type, parent, isParamContext(cls))
if hasattr(cls, 'check'):
cls.check()
@@ -456,7 +468,11 @@ class MetaConfigNode(type):
if cls._getdisable(pname):
continue
- value = cls._getvalue(pname)
+ try:
+ value = cls._getvalue(pname)
+ except:
+ print 'Error getting %s' % pname
+ raise
if isConfigNode(value):
value = instance.child_objects[value]
@@ -533,6 +549,9 @@ class ConfigNode(object):
# v = param.convert(value)
# object.__setattr__(self, attr, v)
+class ParamContext(ConfigNode):
+ pass
+
# SimObject is a minimal extension of ConfigNode, implementing a
# hierarchy node that corresponds to an M5 SimObject. It prints out a
# "type=" line to indicate its SimObject class, prints out the
@@ -569,7 +588,7 @@ class NodeParam(object):
class Node(object):
all = {}
- def __init__(self, name, realtype, type, parent):
+ def __init__(self, name, realtype, type, parent, paramcontext):
self.name = name
self.realtype = realtype
self.type = type
@@ -580,6 +599,7 @@ class Node(object):
self.top_child_names = {}
self.params = []
self.param_names = {}
+ self.paramcontext = paramcontext
path = [ self.name ]
node = self.parent
@@ -642,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
@@ -678,7 +698,8 @@ class Node(object):
# instantiate children in same order they were added for
# backward compatibility (else we can end up with cpu1
# before cpu0).
- print 'children =', ' '.join([ c.name for c in self.children])
+ children = [ c.name for c in self.children if not c.paramcontext]
+ print 'children =', ' '.join(children)
for param in self.params:
try:
@@ -699,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)
@@ -1196,12 +1259,9 @@ 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
# For power-of-two sizing, e.g. 64*K gives an integer value 65536.
K = 1024
@@ -1234,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 *