- Add capability to auto-generate Param structs from

.mpy SimObject descriptions.  Structs are defined
in simobj/param/ObjectName.hh.
- Move compile-time python params (from CPPDEFINES) to
separate dict from run-time params (from os.environ).
The former are needed to generate proper param structs.
This also helps prevent users from messing things up
by setting the wrong environment vars (which could have
overridden compile-time settings in the old system).
- Other misc cleanup of m5 python package.

SConscript:
    Include simobj/SConscript
build/SConstruct:
    Fix type in comment
python/SConscript:
    Move CPPDEFINES dict-generating code to m5scons.flatten_defines
python/m5/__init__.py:
    - Generate a build_env SmartDict here to hold compile-time
    params (passed in via __main__.m5_build_env).
    - Move panic and env here from config.py.
python/m5/config.py:
    Move panic, env to top level (m5/__init__.py)
python/m5/objects/BaseCPU.mpy:
    Use build_env instead of env for compile-time params
python/m5/smartdict.py:
    Add some comments.
sim/sim_object.hh:
    Include auto-generated Param struct.  Not used yet,
    just here as proof of concept.
test/genini.py:
    Put -E arguments in build_env as well as os.environ

--HG--
extra : convert_revision : cf6f4a2565b230c495b33b18612d6030988adac5
This commit is contained in:
Steve Reinhardt 2005-03-14 07:46:26 -05:00
parent 82964b2705
commit 1b841a871e
9 changed files with 74 additions and 42 deletions

View file

@ -378,7 +378,7 @@ env.Command(Split('''arch/alpha/decoder.cc
# header files into a place where they can be found. # header files into a place where they can be found.
SConscript('libelf/SConscript-local', exports = 'env', duplicate=0) SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
SConscript('python/SConscript', exports = ['env'], duplicate=0) SConscript('python/SConscript', exports = ['env'], duplicate=0)
SConscript('simobj/SConscript', exports = 'env', duplicate=0)
# This function adds the specified sources to the given build # This function adds the specified sources to the given build
# environment, and returns a list of all the corresponding SCons # environment, and returns a list of all the corresponding SCons

View file

@ -289,7 +289,7 @@ for build_dir in build_dirs:
################################################### ###################################################
# #
# Let SCons do its thing. At this point SCons will use the defined # Let SCons do its thing. At this point SCons will use the defined
# build enviornments to build the requested targets. # build environments to build the requested targets.
# #
################################################### ###################################################

View file

@ -26,7 +26,14 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os, os.path, re import os, os.path, re, sys
Import('env')
# tell python where to find m5 python code
sys.path.append(os.path.join(env['SRCDIR'], 'python'))
import m5scons
def WriteEmbeddedPyFile(target, source, path, name, ext, filename): def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
if isinstance(source, str): if isinstance(source, str):
@ -89,7 +96,6 @@ def splitpath(path):
path.insert(0, base) path.insert(0, base)
return path, file return path, file
Import('env')
def MakeEmbeddedPyFile(target, source, env): def MakeEmbeddedPyFile(target, source, env):
target = file(str(target[0]), 'w') target = file(str(target[0]), 'w')
@ -145,27 +151,11 @@ def MakeEmbeddedPyFile(target, source, env):
WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)
def MakeDefinesPyFile(target, source, env): def MakeDefinesPyFile(target, source, env):
target = file(str(target[0]), 'w') f = file(str(target[0]), 'w')
print >>f, "import __main__"
print >>target, "import os" print >>f, "__main__.m5_build_env = ",
defines = env['CPPDEFINES'] print >>f, m5scons.flatten_defines(env['CPPDEFINES'])
if isinstance(defines, list): f.close()
for var in defines:
if isinstance(var, tuple):
key,val = var
else:
key,val = var,'True'
if not isinstance(key, basestring):
panic("invalid type for define: %s" % type(key))
print >>target, "os.environ['%s'] = '%s'" % (key, val)
elif isinstance(defines, dict):
for key,val in defines.iteritems():
print >>target, "os.environ['%s'] = '%s'" % (key, val)
else:
panic("invalid type for defines: %s" % type(defines))
CFileCounter = 0 CFileCounter = 0
def MakePythonCFile(target, source, env): def MakePythonCFile(target, source, env):

View file

@ -1,10 +1,36 @@
import sys, os
# the mpy import code is added to the global import meta_path as a
# side effect of this import
from mpy_importer import AddToPath, LoadMpyFile from mpy_importer import AddToPath, LoadMpyFile
from config import * # define this here so we can use it right away if necessary
config.add_param_types(config.__dict__) def panic(string):
print >>sys.stderr, 'panic:', string
sys.exit(1)
# find the m5 compile options: must be specified as a dict in
# __main__.m5_build_env.
import __main__
if not hasattr(__main__, 'm5_build_env'):
panic("__main__ must define m5_build_env")
# make a SmartDict out of the build options for our local use
import smartdict
build_env = smartdict.SmartDict()
build_env.update(__main__.m5_build_env)
# make a SmartDict out of the OS environment too
env = smartdict.SmartDict()
env.update(os.environ)
# import the main m5 config code
from config import *
config.add_param_types(config)
# import the built-in object definitions
from objects import * from objects import *
config.add_param_types(objects.__dict__) config.add_param_types(objects)
cpp_classes = config.MetaSimObject.cpp_classes cpp_classes = config.MetaSimObject.cpp_classes
cpp_classes.sort() cpp_classes.sort()

View file

@ -27,7 +27,6 @@
from __future__ import generators from __future__ import generators
import os, re, sys, types, inspect import os, re, sys, types, inspect
from smartdict import SmartDict
from convert import * from convert import *
noDot = False noDot = False
@ -36,13 +35,6 @@ try:
except: except:
noDot = True noDot = True
env = SmartDict()
env.update(os.environ)
def panic(string):
print >>sys.stderr, 'panic:', string
sys.exit(1)
def issequence(value): def issequence(value):
return isinstance(value, tuple) or isinstance(value, list) return isinstance(value, tuple) or isinstance(value, list)
@ -1347,7 +1339,7 @@ class SimObject(ConfigNode, ParamType):
# __all__ defines the list of symbols that get exported when # __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked. Try to keep this reasonably # 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces. # short to avoid polluting other namespaces.
__all__ = ['env', 'issequence', 'panic', __all__ = ['issequence',
'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
'Super', 'Enum', 'Super', 'Enum',
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',

View file

@ -4,7 +4,7 @@ simobj BaseCPU(SimObject):
icache = Param.BaseMem(NULL, "L1 instruction cache object") icache = Param.BaseMem(NULL, "L1 instruction cache object")
dcache = Param.BaseMem(NULL, "L1 data cache object") dcache = Param.BaseMem(NULL, "L1 data cache object")
if env.get('FULL_SYSTEM', 'False'): if build_env['FULL_SYSTEM']:
dtb = Param.AlphaDTB("Data TLB") dtb = Param.AlphaDTB("Data TLB")
itb = Param.AlphaITB("Instruction TLB") itb = Param.AlphaITB("Instruction TLB")
mem = Param.FunctionalMemory("memory") mem = Param.FunctionalMemory("memory")

View file

@ -1,6 +1,23 @@
# The SmartDict class fixes a couple of issues with using the content
# of os.environ or similar dicts of strings as Python variables:
#
# 1) Undefined variables should return False rather than raising KeyError.
#
# 2) String values of 'False', '0', etc., should evaluate to False
# (not just the empty string).
#
# #1 is solved by overriding __getitem__, and #2 is solved by using a
# proxy class for values and overriding __nonzero__ on the proxy.
# Everything else is just to (a) make proxies behave like normal
# values otherwise, (b) make sure any dict operation returns a proxy
# rather than a normal value, and (c) coerce values written to the
# dict to be strings.
from convert import * from convert import *
class SmartDict(dict): class SmartDict(dict):
class Proxy(str): class Proxy(str):
def __int__(self): def __int__(self):
return int(to_integer(str(self))) return int(to_integer(str(self)))
@ -58,7 +75,7 @@ class SmartDict(dict):
def __getitem__(self, key): def __getitem__(self, key):
return self.Proxy(dict.__getitem__(self, key)) return self.Proxy(dict.get(self, key, 'False'))
def __setitem__(self, key, item): def __setitem__(self, key, item):
dict.__setitem__(self, key, str(item)) dict.__setitem__(self, key, str(item))
@ -77,9 +94,9 @@ class SmartDict(dict):
for key,value in dict.iteritems(self): for key,value in dict.iteritems(self):
yield key, self.Proxy(value) yield key, self.Proxy(value)
def get(self, key, default=''): def get(self, key, default='False'):
return self.Proxy(dict.get(self, key, str(default))) return self.Proxy(dict.get(self, key, str(default)))
def setdefault(self, key, default=''): def setdefault(self, key, default='False'):
return self.Proxy(dict.setdefault(self, key, str(default))) return self.Proxy(dict.setdefault(self, key, str(default)))

View file

@ -60,6 +60,10 @@ class SimObject : public Serializable, protected StartupCallback
static SimObjectList simObjectList; static SimObjectList simObjectList;
public: public:
// for Params struct
#include "simobj/param/SimObject.hh"
SimObject(const std::string &_name); SimObject(const std::string &_name);
virtual ~SimObject() {} virtual ~SimObject() {}

View file

@ -35,6 +35,8 @@ sys.path.append(joinpath(mypath, '../util/pbs'))
pathlist = [ '.' ] pathlist = [ '.' ]
m5_build_env = {}
try: try:
opts, args = getopt.getopt(sys.argv[1:], '-E:I:') opts, args = getopt.getopt(sys.argv[1:], '-E:I:')
for opt,arg in opts: for opt,arg in opts:
@ -42,11 +44,12 @@ try:
offset = arg.find('=') offset = arg.find('=')
if offset == -1: if offset == -1:
name = arg name = arg
value = True value = '1'
else: else:
name = arg[:offset] name = arg[:offset]
value = arg[offset+1:] value = arg[offset+1:]
os.environ[name] = value os.environ[name] = value
m5_build_env[name] = value
if opt == '-I': if opt == '-I':
pathlist.append(arg) pathlist.append(arg)
except getopt.GetoptError: except getopt.GetoptError: