Merge
--HG-- extra : convert_revision : 22919164108afd74f30207606f59a38992991dae
This commit is contained in:
commit
8f2a84cbe5
|
@ -212,6 +212,9 @@ base_sources = Split('''
|
||||||
mem/trace/mem_trace_writer.cc
|
mem/trace/mem_trace_writer.cc
|
||||||
mem/trace/m5_writer.cc
|
mem/trace/m5_writer.cc
|
||||||
|
|
||||||
|
python/pyconfig.cc
|
||||||
|
python/embedded_py.cc
|
||||||
|
|
||||||
sim/builder.cc
|
sim/builder.cc
|
||||||
sim/configfile.cc
|
sim/configfile.cc
|
||||||
sim/debug.cc
|
sim/debug.cc
|
||||||
|
@ -228,8 +231,6 @@ base_sources = Split('''
|
||||||
sim/stat_control.cc
|
sim/stat_control.cc
|
||||||
sim/trace_context.cc
|
sim/trace_context.cc
|
||||||
sim/universe.cc
|
sim/universe.cc
|
||||||
sim/pyconfig/pyconfig.cc
|
|
||||||
sim/pyconfig/embedded_py.cc
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# MySql sources
|
# MySql sources
|
||||||
|
@ -407,8 +408,8 @@ env.Command(Split('''arch/alpha/decoder.cc
|
||||||
# SConscript-local is the per-config build, which just copies some
|
# SConscript-local is the per-config build, which just copies some
|
||||||
# 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('sim/pyconfig/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
|
||||||
|
|
|
@ -62,6 +62,9 @@ if not os.path.isdir('ext'):
|
||||||
% EXT_SRCDIR
|
% EXT_SRCDIR
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# tell python where to find m5 python code
|
||||||
|
sys.path.append(os.path.join(SRCDIR, 'python'))
|
||||||
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
#
|
#
|
||||||
|
@ -294,7 +297,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.
|
||||||
#
|
#
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
|
|
50
configs/splash2/run.mpy
Normal file
50
configs/splash2/run.mpy
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import Splash2
|
||||||
|
|
||||||
|
if 'SYSTEM' not in env:
|
||||||
|
panic("The SYSTEM environment variable must be set!\ne.g -ESYSTEM=Detailed\n")
|
||||||
|
|
||||||
|
if env['SYSTEM'] == 'Simple':
|
||||||
|
from SimpleConfig import *
|
||||||
|
BaseCPU.workload = Super.workload
|
||||||
|
SimpleStandAlone.cpu = [ CPU() for i in xrange(int(env['NP'])) ]
|
||||||
|
root = SimpleStandAlone
|
||||||
|
elif env['SYSTEM'] == 'Detailed':
|
||||||
|
from DetailedConfig import *
|
||||||
|
BaseCPU.workload = Super.workload
|
||||||
|
DetailedStandAlone.cpu = [ DetailedCPU() for i in xrange(int(env['NP'])) ]
|
||||||
|
root = DetailedStandAlone
|
||||||
|
else:
|
||||||
|
panic("The SYSTEM environment variable was set to something improper.\n Use Simple or Detailed\n")
|
||||||
|
|
||||||
|
if 'BENCHMARK' not in env:
|
||||||
|
panic("The BENCHMARK environment variable must be set!\ne.g. -EBENCHMARK=Cholesky\n")
|
||||||
|
|
||||||
|
if env['BENCHMARK'] == 'Cholesky':
|
||||||
|
root.workload = Splash2.Cholesky()
|
||||||
|
elif env['BENCHMARK'] == 'FFT':
|
||||||
|
root.workload = Splash2.FFT()
|
||||||
|
elif env['BENCHMARK'] == 'LUContig':
|
||||||
|
root.workload = Splash2.LU_contig()
|
||||||
|
elif env['BENCHMARK'] == 'LUNoncontig':
|
||||||
|
root.workload = Splash2.LU_noncontig()
|
||||||
|
elif env['BENCHMARK'] == 'Radix':
|
||||||
|
root.workload = Splash2.Radix()
|
||||||
|
elif env['BENCHMARK'] == 'Barnes':
|
||||||
|
root.workload = Splash2.Barnes()
|
||||||
|
elif env['BENCHMARK'] == 'FMM':
|
||||||
|
root.workload = Splash2.FMM()
|
||||||
|
elif env['BENCHMARK'] == 'OceanContig':
|
||||||
|
root.workload = Splash2.Ocean_contig()
|
||||||
|
elif env['BENCHMARK'] == 'OceanNoncontig':
|
||||||
|
root.workload = Splash2.Ocean_noncontig()
|
||||||
|
elif env['BENCHMARK'] == 'Raytrace':
|
||||||
|
root.workload = Splash2.Raytrace()
|
||||||
|
elif env['BENCHMARK'] == 'WaterNSquared':
|
||||||
|
root.workload = Splash2.Water_nsquared()
|
||||||
|
elif env['BENCHMARK'] == 'WaterSpatial':
|
||||||
|
root.workload = Splash2.Water_spatial()
|
||||||
|
else:
|
||||||
|
panic("The BENCHMARK environment variable was set to something" \
|
||||||
|
+" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \
|
||||||
|
+", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \
|
||||||
|
+" WaterNSquared, or WaterSpatial\n")
|
|
@ -98,11 +98,12 @@ PciConfigAll::startup()
|
||||||
Fault
|
Fault
|
||||||
PciConfigAll::read(MemReqPtr &req, uint8_t *data)
|
PciConfigAll::read(MemReqPtr &req, uint8_t *data)
|
||||||
{
|
{
|
||||||
DPRINTF(PciConfigAll, "read va=%#x size=%d\n",
|
|
||||||
req->vaddr, req->size);
|
|
||||||
|
|
||||||
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
|
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
|
||||||
|
|
||||||
|
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n",
|
||||||
|
req->vaddr, daddr, req->size);
|
||||||
|
|
||||||
int device = (daddr >> 11) & 0x1F;
|
int device = (daddr >> 11) & 0x1F;
|
||||||
int func = (daddr >> 8) & 0x7;
|
int func = (daddr >> 8) & 0x7;
|
||||||
int reg = daddr & 0xFF;
|
int reg = daddr & 0xFF;
|
||||||
|
|
|
@ -285,11 +285,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
SimObjectParam<MemoryController *> mmu;
|
|
||||||
Param<Addr> addr;
|
|
||||||
SimObjectParam<Bus*> io_bus;
|
|
||||||
Param<Tick> pio_latency;
|
|
||||||
|
|
||||||
Param<uint16_t> VendorID;
|
Param<uint16_t> VendorID;
|
||||||
Param<uint16_t> DeviceID;
|
Param<uint16_t> DeviceID;
|
||||||
Param<uint16_t> Command;
|
Param<uint16_t> Command;
|
||||||
|
@ -327,11 +322,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
|
||||||
INIT_PARAM(addr, "Device Address"),
|
|
||||||
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
|
||||||
|
|
||||||
INIT_PARAM(VendorID, "Vendor ID"),
|
INIT_PARAM(VendorID, "Vendor ID"),
|
||||||
INIT_PARAM(DeviceID, "Device ID"),
|
INIT_PARAM(DeviceID, "Device ID"),
|
||||||
INIT_PARAM_DFLT(Command, "Command Register", 0x00),
|
INIT_PARAM_DFLT(Command, "Command Register", 0x00),
|
||||||
|
|
|
@ -26,7 +26,11 @@
|
||||||
# (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')
|
||||||
|
|
||||||
|
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 +93,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 +148,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):
|
||||||
|
@ -193,8 +180,10 @@ EmbedMap %(name)s("%(fname)s",
|
||||||
/* namespace */ }
|
/* namespace */ }
|
||||||
'''
|
'''
|
||||||
|
|
||||||
embedded_py_files = ['m5config.py', 'importer.py', '../../util/pbs/jobfile.py']
|
# base list of .py files to embed
|
||||||
objpath = os.path.join(env['SRCDIR'], 'objects')
|
embedded_py_files = [ '../util/pbs/jobfile.py' ]
|
||||||
|
# add all .py and .mpy files in python/m5
|
||||||
|
objpath = os.path.join(env['SRCDIR'], 'python', 'm5')
|
||||||
for root, dirs, files in os.walk(objpath, topdown=True):
|
for root, dirs, files in os.walk(objpath, topdown=True):
|
||||||
for i,dir in enumerate(dirs):
|
for i,dir in enumerate(dirs):
|
||||||
if dir == 'SCCS':
|
if dir == 'SCCS':
|
37
python/m5/__init__.py
Normal file
37
python/m5/__init__.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
# define this here so we can use it right away if necessary
|
||||||
|
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 *
|
||||||
|
config.add_param_types(objects)
|
||||||
|
|
||||||
|
cpp_classes = config.MetaSimObject.cpp_classes
|
||||||
|
cpp_classes.sort()
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
from __future__ import generators
|
from __future__ import generators
|
||||||
import os, re, sys, types, inspect
|
import os, re, sys, types, inspect
|
||||||
|
|
||||||
from importer import AddToPath, LoadMpyFile
|
from convert import *
|
||||||
|
|
||||||
noDot = False
|
noDot = False
|
||||||
try:
|
try:
|
||||||
|
@ -35,13 +35,6 @@ try:
|
||||||
except:
|
except:
|
||||||
noDot = True
|
noDot = True
|
||||||
|
|
||||||
env = {}
|
|
||||||
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)
|
||||||
|
|
||||||
|
@ -208,6 +201,28 @@ class_decorator = 'M5M5_SIMOBJECT_'
|
||||||
expr_decorator = 'M5M5_EXPRESSION_'
|
expr_decorator = 'M5M5_EXPRESSION_'
|
||||||
dot_decorator = '_M5M5_DOT_'
|
dot_decorator = '_M5M5_DOT_'
|
||||||
|
|
||||||
|
# 'Global' map of legitimate types for SimObject parameters.
|
||||||
|
param_types = {}
|
||||||
|
|
||||||
|
# Dummy base class to identify types that are legitimate for SimObject
|
||||||
|
# parameters.
|
||||||
|
class ParamType(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add types defined in given context (dict or module) that are derived
|
||||||
|
# from ParamType to param_types map.
|
||||||
|
def add_param_types(ctx):
|
||||||
|
if isinstance(ctx, types.DictType):
|
||||||
|
source_dict = ctx
|
||||||
|
elif isinstance(ctx, types.ModuleType):
|
||||||
|
source_dict = ctx.__dict__
|
||||||
|
else:
|
||||||
|
raise TypeError, \
|
||||||
|
"m5.config.add_param_types requires dict or module as arg"
|
||||||
|
for key,val in source_dict.iteritems():
|
||||||
|
if isinstance(val, type) and issubclass(val, ParamType):
|
||||||
|
param_types[key] = val
|
||||||
|
|
||||||
# The metaclass for ConfigNode (and thus for everything that derives
|
# The metaclass for ConfigNode (and thus for everything that derives
|
||||||
# from ConfigNode, including SimObject). This class controls how new
|
# from ConfigNode, including SimObject). This class controls how new
|
||||||
# classes that derive from ConfigNode are instantiated, and provides
|
# classes that derive from ConfigNode are instantiated, and provides
|
||||||
|
@ -245,7 +260,7 @@ class MetaConfigNode(type):
|
||||||
# initialize required attributes
|
# initialize required attributes
|
||||||
cls._params = {}
|
cls._params = {}
|
||||||
cls._values = {}
|
cls._values = {}
|
||||||
cls._enums = {}
|
cls._param_types = {}
|
||||||
cls._bases = [c for c in cls.__mro__ if isConfigNode(c)]
|
cls._bases = [c for c in cls.__mro__ if isConfigNode(c)]
|
||||||
cls._anon_subclass_counter = 0
|
cls._anon_subclass_counter = 0
|
||||||
|
|
||||||
|
@ -268,19 +283,26 @@ class MetaConfigNode(type):
|
||||||
elif isNullPointer(val):
|
elif isNullPointer(val):
|
||||||
cls._values[key] = val
|
cls._values[key] = val
|
||||||
|
|
||||||
# now process _init_dict items
|
# process param types from _init_dict, as these may be needed
|
||||||
|
# by param descriptions also in _init_dict
|
||||||
for key,val in cls._init_dict.items():
|
for key,val in cls._init_dict.items():
|
||||||
|
if isinstance(val, type) and issubclass(val, ParamType):
|
||||||
|
cls._param_types[key] = val
|
||||||
|
if not issubclass(val, ConfigNode):
|
||||||
|
del cls._init_dict[key]
|
||||||
|
|
||||||
|
# now process remaining _init_dict items
|
||||||
|
for key,val in cls._init_dict.items():
|
||||||
|
# param descriptions
|
||||||
if isinstance(val, _Param):
|
if isinstance(val, _Param):
|
||||||
cls._params[key] = val
|
cls._params[key] = val
|
||||||
|
# try to resolve local param types in local param_types scope
|
||||||
|
val.maybe_resolve_type(cls._param_types)
|
||||||
|
|
||||||
# init-time-only keywords
|
# init-time-only keywords
|
||||||
elif cls.init_keywords.has_key(key):
|
elif cls.init_keywords.has_key(key):
|
||||||
cls._set_keyword(key, val, cls.init_keywords[key])
|
cls._set_keyword(key, val, cls.init_keywords[key])
|
||||||
|
|
||||||
# enums
|
|
||||||
elif isinstance(val, type) and issubclass(val, Enum):
|
|
||||||
cls._enums[key] = val
|
|
||||||
|
|
||||||
# See description of decorators in the importer.py file.
|
# See description of decorators in the importer.py file.
|
||||||
# We just strip off the expr_decorator now since we don't
|
# We just strip off the expr_decorator now since we don't
|
||||||
# need from this point on.
|
# need from this point on.
|
||||||
|
@ -417,7 +439,11 @@ class MetaConfigNode(type):
|
||||||
# It's ok: set attribute by delegating to 'object' class.
|
# It's ok: set attribute by delegating to 'object' class.
|
||||||
# Note the use of param.make_value() to verify/canonicalize
|
# Note the use of param.make_value() to verify/canonicalize
|
||||||
# the assigned value
|
# the assigned value
|
||||||
|
try:
|
||||||
param.valid(value)
|
param.valid(value)
|
||||||
|
except:
|
||||||
|
panic("Error setting param %s.%s to %s\n" % \
|
||||||
|
(cls.__name__, attr, value))
|
||||||
cls._setvalue(attr, value)
|
cls._setvalue(attr, value)
|
||||||
elif isConfigNode(value) or isSimObjSequence(value):
|
elif isConfigNode(value) or isSimObjSequence(value):
|
||||||
cls._setvalue(attr, value)
|
cls._setvalue(attr, value)
|
||||||
|
@ -449,7 +475,7 @@ class MetaConfigNode(type):
|
||||||
|
|
||||||
# Print instance info to .ini file.
|
# Print instance info to .ini file.
|
||||||
def instantiate(cls, name, parent = None):
|
def instantiate(cls, name, parent = None):
|
||||||
instance = Node(name, cls, cls.type, parent, isParamContext(cls))
|
instance = Node(name, cls, parent, isParamContext(cls))
|
||||||
|
|
||||||
if hasattr(cls, 'check'):
|
if hasattr(cls, 'check'):
|
||||||
cls.check()
|
cls.check()
|
||||||
|
@ -560,7 +586,7 @@ class MetaSimObject(MetaConfigNode):
|
||||||
def _cpp_decl(cls):
|
def _cpp_decl(cls):
|
||||||
name = cls.__name__
|
name = cls.__name__
|
||||||
code = ""
|
code = ""
|
||||||
code += "\n".join([e.cpp_declare() for e in cls._enums.values()])
|
code += "\n".join([e.cpp_declare() for e in cls._param_types.values()])
|
||||||
code += "\n"
|
code += "\n"
|
||||||
param_names = cls._params.keys()
|
param_names = cls._params.keys()
|
||||||
param_names.sort()
|
param_names.sort()
|
||||||
|
@ -584,10 +610,13 @@ class NodeParam(object):
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
all = {}
|
all = {}
|
||||||
def __init__(self, name, realtype, type, parent, paramcontext):
|
def __init__(self, name, realtype, parent, paramcontext):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.realtype = realtype
|
self.realtype = realtype
|
||||||
self.type = type
|
if isSimObject(realtype):
|
||||||
|
self.type = realtype.type
|
||||||
|
else:
|
||||||
|
self.type = None
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.children = []
|
self.children = []
|
||||||
self.child_names = {}
|
self.child_names = {}
|
||||||
|
@ -849,13 +878,24 @@ class _Param(object):
|
||||||
if not hasattr(self, 'desc'):
|
if not hasattr(self, 'desc'):
|
||||||
raise TypeError, 'desc attribute missing'
|
raise TypeError, 'desc attribute missing'
|
||||||
|
|
||||||
|
def maybe_resolve_type(self, context):
|
||||||
|
# check if already resolved... don't use hasattr(),
|
||||||
|
# as that calls __getattr__()
|
||||||
|
if self.__dict__.has_key('ptype'):
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
self.ptype = context[self.ptype_string]
|
||||||
|
except KeyError:
|
||||||
|
# no harm in trying... we'll try again later using global scope
|
||||||
|
pass
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr == 'ptype':
|
if attr == 'ptype':
|
||||||
try:
|
try:
|
||||||
self.ptype = eval(self.ptype_string)
|
self.ptype = param_types[self.ptype_string]
|
||||||
return self.ptype
|
return self.ptype
|
||||||
except:
|
except:
|
||||||
raise TypeError, 'Param.%s: undefined type' % self.ptype_string
|
panic("undefined Param type %s" % self.ptype_string)
|
||||||
else:
|
else:
|
||||||
raise AttributeError, "'%s' object has no attribute '%s'" % \
|
raise AttributeError, "'%s' object has no attribute '%s'" % \
|
||||||
(type(self).__name__, attr)
|
(type(self).__name__, attr)
|
||||||
|
@ -882,19 +922,10 @@ class _ParamProxy(object):
|
||||||
|
|
||||||
# E.g., Param.Int(5, "number of widgets")
|
# E.g., Param.Int(5, "number of widgets")
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
# Param type could be defined only in context of caller (e.g.,
|
return _Param(self.ptype, *args, **kwargs)
|
||||||
# for locally defined Enum subclass). Need to go look up the
|
|
||||||
# type in that enclosing scope.
|
|
||||||
caller_frame = inspect.stack()[1][0]
|
|
||||||
ptype = caller_frame.f_locals.get(self.ptype, None)
|
|
||||||
if not ptype: ptype = caller_frame.f_globals.get(self.ptype, None)
|
|
||||||
if not ptype: ptype = globals().get(self.ptype, None)
|
|
||||||
# ptype could still be None due to circular references... we'll
|
|
||||||
# try one more time to evaluate lazily when ptype is first needed.
|
|
||||||
# In the meantime we'll save the type name as a string.
|
|
||||||
if not ptype: ptype = self.ptype
|
|
||||||
return _Param(ptype, *args, **kwargs)
|
|
||||||
|
|
||||||
|
# Strange magic to theoretically allow dotted names as Param classes,
|
||||||
|
# e.g., Param.Foo.Bar(...) to have a param of type Foo.Bar
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr == '__bases__':
|
if attr == '__bases__':
|
||||||
raise AttributeError, ''
|
raise AttributeError, ''
|
||||||
|
@ -970,99 +1001,109 @@ VectorParam = _VectorParamProxy(None)
|
||||||
# to correspond to distinct C++ types as well.
|
# to correspond to distinct C++ types as well.
|
||||||
#
|
#
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# Integer parameter type.
|
|
||||||
class _CheckedInt(object):
|
|
||||||
|
# Metaclass for bounds-checked integer parameters. See CheckedInt.
|
||||||
|
class CheckedIntType(type):
|
||||||
|
def __init__(cls, name, bases, dict):
|
||||||
|
super(CheckedIntType, cls).__init__(name, bases, dict)
|
||||||
|
|
||||||
|
# CheckedInt is an abstract base class, so we actually don't
|
||||||
|
# want to do any processing on it... the rest of this code is
|
||||||
|
# just for classes that derive from CheckedInt.
|
||||||
|
if name == 'CheckedInt':
|
||||||
|
return
|
||||||
|
|
||||||
|
if not (hasattr(cls, 'min') and hasattr(cls, 'max')):
|
||||||
|
if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')):
|
||||||
|
panic("CheckedInt subclass %s must define either\n" \
|
||||||
|
" 'min' and 'max' or 'size' and 'unsigned'\n" \
|
||||||
|
% name);
|
||||||
|
if cls.unsigned:
|
||||||
|
cls.min = 0
|
||||||
|
cls.max = 2 ** cls.size - 1
|
||||||
|
else:
|
||||||
|
cls.min = -(2 ** (cls.size - 1))
|
||||||
|
cls.max = (2 ** (cls.size - 1)) - 1
|
||||||
|
|
||||||
|
cls._cpp_param_decl = cls.cppname
|
||||||
|
|
||||||
def _convert(cls, value):
|
def _convert(cls, value):
|
||||||
t = type(value)
|
if isinstance(value, bool):
|
||||||
if t == bool:
|
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
||||||
if t != int and t != long and t != float and t != str:
|
if not isinstance(value, (int, long, float, str)):
|
||||||
raise TypeError, 'Integer parameter of invalid type %s' % t
|
raise TypeError, 'Integer param of invalid type %s' % type(value)
|
||||||
|
|
||||||
if t == str or t == float:
|
if isinstance(value, (str, float)):
|
||||||
value = long(value)
|
value = long(float(value))
|
||||||
|
|
||||||
if not cls._min <= value <= cls._max:
|
if not cls.min <= value <= cls.max:
|
||||||
raise TypeError, 'Integer parameter out of bounds %d < %d < %d' % \
|
raise TypeError, 'Integer param out of bounds %d < %d < %d' % \
|
||||||
(cls._min, value, cls._max)
|
(cls.min, value, cls.max)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
_convert = classmethod(_convert)
|
|
||||||
|
|
||||||
def _string(cls, value):
|
def _string(cls, value):
|
||||||
return str(value)
|
return str(value)
|
||||||
_string = classmethod(_string)
|
|
||||||
|
|
||||||
class CheckedInt(type):
|
# Abstract superclass for bounds-checked integer parameters. This
|
||||||
def __new__(cls, cppname, min, max):
|
# class is subclassed to generate parameter classes with specific
|
||||||
# New class derives from _CheckedInt base with proper bounding
|
# bounds. Initialization of the min and max bounds is done in the
|
||||||
# parameters
|
# metaclass CheckedIntType.__init__.
|
||||||
dict = { '_cpp_param_decl' : cppname, '_min' : min, '_max' : max }
|
class CheckedInt(ParamType):
|
||||||
return type.__new__(cls, cppname, (_CheckedInt, ), dict)
|
__metaclass__ = CheckedIntType
|
||||||
|
|
||||||
class CheckedIntType(CheckedInt):
|
class Int(CheckedInt): cppname = 'int'; size = 32; unsigned = False
|
||||||
def __new__(cls, cppname, size, unsigned):
|
class Unsigned(CheckedInt): cppname = 'unsigned'; size = 32; unsigned = True
|
||||||
dict = {}
|
|
||||||
if unsigned:
|
|
||||||
min = 0
|
|
||||||
max = 2 ** size - 1
|
|
||||||
else:
|
|
||||||
min = -(2 ** (size - 1))
|
|
||||||
max = (2 ** (size - 1)) - 1
|
|
||||||
|
|
||||||
return super(cls, CheckedIntType).__new__(cls, cppname, min, max)
|
class Int8(CheckedInt): cppname = 'int8_t'; size = 8; unsigned = False
|
||||||
|
class UInt8(CheckedInt): cppname = 'uint8_t'; size = 8; unsigned = True
|
||||||
|
class Int16(CheckedInt): cppname = 'int16_t'; size = 16; unsigned = False
|
||||||
|
class UInt16(CheckedInt): cppname = 'uint16_t'; size = 16; unsigned = True
|
||||||
|
class Int32(CheckedInt): cppname = 'int32_t'; size = 32; unsigned = False
|
||||||
|
class UInt32(CheckedInt): cppname = 'uint32_t'; size = 32; unsigned = True
|
||||||
|
class Int64(CheckedInt): cppname = 'int64_t'; size = 64; unsigned = False
|
||||||
|
class UInt64(CheckedInt): cppname = 'uint64_t'; size = 64; unsigned = True
|
||||||
|
|
||||||
Int = CheckedIntType('int', 32, False)
|
class Counter(CheckedInt): cppname = 'Counter'; size = 64; unsigned = True
|
||||||
Unsigned = CheckedIntType('unsigned', 32, True)
|
class Addr(CheckedInt): cppname = 'Addr'; size = 64; unsigned = True
|
||||||
|
class Tick(CheckedInt): cppname = 'Tick'; size = 64; unsigned = True
|
||||||
|
|
||||||
Int8 = CheckedIntType('int8_t', 8, False)
|
class Percent(CheckedInt): cppname = 'int'; min = 0; max = 100
|
||||||
UInt8 = CheckedIntType('uint8_t', 8, True)
|
|
||||||
Int16 = CheckedIntType('int16_t', 16, False)
|
|
||||||
UInt16 = CheckedIntType('uint16_t', 16, True)
|
|
||||||
Int32 = CheckedIntType('int32_t', 32, False)
|
|
||||||
UInt32 = CheckedIntType('uint32_t', 32, True)
|
|
||||||
Int64 = CheckedIntType('int64_t', 64, False)
|
|
||||||
UInt64 = CheckedIntType('uint64_t', 64, True)
|
|
||||||
|
|
||||||
Counter = CheckedIntType('Counter', 64, True)
|
|
||||||
Addr = CheckedIntType('Addr', 64, True)
|
|
||||||
Tick = CheckedIntType('Tick', 64, True)
|
|
||||||
|
|
||||||
Percent = CheckedInt('int', 0, 100)
|
|
||||||
|
|
||||||
class Pair(object):
|
class Pair(object):
|
||||||
def __init__(self, first, second):
|
def __init__(self, first, second):
|
||||||
self.first = first
|
self.first = first
|
||||||
self.second = second
|
self.second = second
|
||||||
|
|
||||||
class _Range(object):
|
class MetaRange(type):
|
||||||
|
def __init__(cls, name, bases, dict):
|
||||||
|
super(MetaRange, cls).__init__(name, bases, dict)
|
||||||
|
if name == 'Range':
|
||||||
|
return
|
||||||
|
cls._cpp_param_decl = 'Range<%s>' % cls.type._cpp_param_decl
|
||||||
|
|
||||||
def _convert(cls, value):
|
def _convert(cls, value):
|
||||||
if not isinstance(value, Pair):
|
if not isinstance(value, Pair):
|
||||||
raise TypeError, 'value %s is not a Pair' % value
|
raise TypeError, 'value %s is not a Pair' % value
|
||||||
return Pair(cls._type._convert(value.first),
|
return Pair(cls.type._convert(value.first),
|
||||||
cls._type._convert(value.second))
|
cls.type._convert(value.second))
|
||||||
_convert = classmethod(_convert)
|
|
||||||
|
|
||||||
def _string(cls, value):
|
def _string(cls, value):
|
||||||
return '%s:%s' % (cls._type._string(value.first),
|
return '%s:%s' % (cls.type._string(value.first),
|
||||||
cls._type._string(value.second))
|
cls.type._string(value.second))
|
||||||
_string = classmethod(_string)
|
|
||||||
|
class Range(ParamType):
|
||||||
|
__metaclass__ = MetaRange
|
||||||
|
|
||||||
def RangeSize(start, size):
|
def RangeSize(start, size):
|
||||||
return Pair(start, start + size - 1)
|
return Pair(start, start + size - 1)
|
||||||
|
|
||||||
class Range(type):
|
class AddrRange(Range): type = Addr
|
||||||
def __new__(cls, type):
|
|
||||||
dict = { '_cpp_param_decl' : 'Range<%s>' % type._cpp_param_decl,
|
|
||||||
'_type' : type }
|
|
||||||
clsname = 'Range_' + type.__name__
|
|
||||||
return super(cls, Range).__new__(cls, clsname, (_Range, ), dict)
|
|
||||||
|
|
||||||
AddrRange = Range(Addr)
|
|
||||||
|
|
||||||
# Boolean parameter type.
|
# Boolean parameter type.
|
||||||
class Bool(object):
|
class Bool(ParamType):
|
||||||
_cpp_param_decl = 'bool'
|
_cpp_param_decl = 'bool'
|
||||||
def _convert(value):
|
def _convert(value):
|
||||||
t = type(value)
|
t = type(value)
|
||||||
|
@ -1090,7 +1131,7 @@ class Bool(object):
|
||||||
_string = staticmethod(_string)
|
_string = staticmethod(_string)
|
||||||
|
|
||||||
# String-valued parameter.
|
# String-valued parameter.
|
||||||
class String(object):
|
class String(ParamType):
|
||||||
_cpp_param_decl = 'string'
|
_cpp_param_decl = 'string'
|
||||||
|
|
||||||
# Constructor. Value must be Python string.
|
# Constructor. Value must be Python string.
|
||||||
|
@ -1130,7 +1171,7 @@ class NextEthernetAddr(object):
|
||||||
self.value = self.addr
|
self.value = self.addr
|
||||||
self.addr = IncEthernetAddr(self.addr, inc)
|
self.addr = IncEthernetAddr(self.addr, inc)
|
||||||
|
|
||||||
class EthernetAddr(object):
|
class EthernetAddr(ParamType):
|
||||||
_cpp_param_decl = 'EthAddr'
|
_cpp_param_decl = 'EthAddr'
|
||||||
|
|
||||||
def _convert(cls, value):
|
def _convert(cls, value):
|
||||||
|
@ -1237,7 +1278,7 @@ class MetaEnum(type):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
# Base class for enum types.
|
# Base class for enum types.
|
||||||
class Enum(object):
|
class Enum(ParamType):
|
||||||
__metaclass__ = MetaEnum
|
__metaclass__ = MetaEnum
|
||||||
vals = []
|
vals = []
|
||||||
|
|
||||||
|
@ -1257,8 +1298,8 @@ class Enum(object):
|
||||||
#
|
#
|
||||||
|
|
||||||
# Some memory range specifications use this as a default upper bound.
|
# Some memory range specifications use this as a default upper bound.
|
||||||
MAX_ADDR = Addr._max
|
MAX_ADDR = Addr.max
|
||||||
MaxTick = Tick._max
|
MaxTick = Tick.max
|
||||||
|
|
||||||
# For power-of-two sizing, e.g. 64*K gives an integer value 65536.
|
# For power-of-two sizing, e.g. 64*K gives an integer value 65536.
|
||||||
K = 1024
|
K = 1024
|
||||||
|
@ -1270,9 +1311,6 @@ G = K*M
|
||||||
# The final hook to generate .ini files. Called from configuration
|
# The final hook to generate .ini files. Called from configuration
|
||||||
# script once config is built.
|
# script once config is built.
|
||||||
def instantiate(root):
|
def instantiate(root):
|
||||||
if not issubclass(root, Root):
|
|
||||||
raise AttributeError, 'Can only instantiate the Root of the tree'
|
|
||||||
|
|
||||||
instance = root.instantiate('root')
|
instance = root.instantiate('root')
|
||||||
instance.fixup()
|
instance.fixup()
|
||||||
instance.display()
|
instance.display()
|
||||||
|
@ -1293,11 +1331,20 @@ def instantiate(root):
|
||||||
# parameters to be set by keyword in the constructor. Note that most
|
# parameters to be set by keyword in the constructor. Note that most
|
||||||
# of the heavy lifting for the SimObject param handling is done in the
|
# of the heavy lifting for the SimObject param handling is done in the
|
||||||
# MetaConfigNode metaclass.
|
# MetaConfigNode metaclass.
|
||||||
class SimObject(ConfigNode):
|
class SimObject(ConfigNode, ParamType):
|
||||||
__metaclass__ = MetaSimObject
|
__metaclass__ = MetaSimObject
|
||||||
type = 'SimObject'
|
type = 'SimObject'
|
||||||
|
|
||||||
from objects import *
|
|
||||||
|
|
||||||
cpp_classes = MetaSimObject.cpp_classes
|
# __all__ defines the list of symbols that get exported when
|
||||||
cpp_classes.sort()
|
# 'from config import *' is invoked. Try to keep this reasonably
|
||||||
|
# short to avoid polluting other namespaces.
|
||||||
|
__all__ = ['issequence',
|
||||||
|
'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
|
||||||
|
'Super', 'Enum',
|
||||||
|
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
|
||||||
|
'Int32', 'UInt32', 'Int64', 'UInt64',
|
||||||
|
'Counter', 'Addr', 'Tick', 'Percent',
|
||||||
|
'Pair', 'RangeSize', 'AddrRange', 'MAX_ADDR', 'NULL', 'K', 'M',
|
||||||
|
'NextEthernetAddr',
|
||||||
|
'instantiate']
|
181
python/m5/convert.py
Normal file
181
python/m5/convert.py
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
# metric prefixes
|
||||||
|
exa = 1.0e18
|
||||||
|
peta = 1.0e15
|
||||||
|
tera = 1.0e12
|
||||||
|
giga = 1.0e9
|
||||||
|
mega = 1.0e6
|
||||||
|
kilo = 1.0e3
|
||||||
|
|
||||||
|
milli = 1.0e-3
|
||||||
|
micro = 1.0e-6
|
||||||
|
nano = 1.0e-9
|
||||||
|
pico = 1.0e-12
|
||||||
|
femto = 1.0e-15
|
||||||
|
atto = 1.0e-18
|
||||||
|
|
||||||
|
# power of 2 prefixes
|
||||||
|
kibi = 1024
|
||||||
|
mebi = kibi * 1024
|
||||||
|
gibi = mebi * 1024
|
||||||
|
tebi = gibi * 1024
|
||||||
|
pebi = tebi * 1024
|
||||||
|
exbi = pebi * 1024
|
||||||
|
|
||||||
|
# memory size configuration stuff
|
||||||
|
def to_integer(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = int(value)
|
||||||
|
elif value.endswith('Ei'):
|
||||||
|
result = int(value[:-2]) * exbi
|
||||||
|
elif value.endswith('Pi'):
|
||||||
|
result = int(value[:-2]) * pebi
|
||||||
|
elif value.endswith('Ti'):
|
||||||
|
result = int(value[:-2]) * tebi
|
||||||
|
elif value.endswith('Gi'):
|
||||||
|
result = int(value[:-2]) * gibi
|
||||||
|
elif value.endswith('Mi'):
|
||||||
|
result = int(value[:-2]) * mebi
|
||||||
|
elif value.endswith('ki'):
|
||||||
|
result = int(value[:-2]) * kibi
|
||||||
|
elif value.endswith('E'):
|
||||||
|
result = int(value[:-1]) * exa
|
||||||
|
elif value.endswith('P'):
|
||||||
|
result = int(value[:-1]) * peta
|
||||||
|
elif value.endswith('T'):
|
||||||
|
result = int(value[:-1]) * tera
|
||||||
|
elif value.endswith('G'):
|
||||||
|
result = int(value[:-1]) * giga
|
||||||
|
elif value.endswith('M'):
|
||||||
|
result = int(value[:-1]) * mega
|
||||||
|
elif value.endswith('k'):
|
||||||
|
result = int(value[:-1]) * kilo
|
||||||
|
elif value.endswith('m'):
|
||||||
|
result = int(value[:-1]) * milli
|
||||||
|
elif value.endswith('u'):
|
||||||
|
result = int(value[:-1]) * micro
|
||||||
|
elif value.endswith('n'):
|
||||||
|
result = int(value[:-1]) * nano
|
||||||
|
elif value.endswith('p'):
|
||||||
|
result = int(value[:-1]) * pico
|
||||||
|
elif value.endswith('f'):
|
||||||
|
result = int(value[:-1]) * femto
|
||||||
|
else:
|
||||||
|
result = int(value)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def to_bool(val):
|
||||||
|
t = type(val)
|
||||||
|
if t == bool:
|
||||||
|
return val
|
||||||
|
|
||||||
|
if t == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if t == int or t == long:
|
||||||
|
return bool(val)
|
||||||
|
|
||||||
|
if t == str:
|
||||||
|
val = val.lower()
|
||||||
|
if val == "true" or val == "t" or val == "yes" or val == "y":
|
||||||
|
return True
|
||||||
|
elif val == "false" or val == "f" or val == "no" or val == "n":
|
||||||
|
return False
|
||||||
|
|
||||||
|
return to_integer(val) != 0
|
||||||
|
|
||||||
|
def to_frequency(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = float(value)
|
||||||
|
elif value.endswith('THz'):
|
||||||
|
result = float(value[:-3]) * tera
|
||||||
|
elif value.endswith('GHz'):
|
||||||
|
result = float(value[:-3]) * giga
|
||||||
|
elif value.endswith('MHz'):
|
||||||
|
result = float(value[:-3]) * mega
|
||||||
|
elif value.endswith('kHz'):
|
||||||
|
result = float(value[:-3]) * kilo
|
||||||
|
elif value.endswith('Hz'):
|
||||||
|
result = float(value[:-2])
|
||||||
|
else:
|
||||||
|
result = float(value)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def to_latency(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = float(value)
|
||||||
|
elif value.endswith('c'):
|
||||||
|
result = float(value[:-1])
|
||||||
|
elif value.endswith('ps'):
|
||||||
|
result = float(value[:-2]) * pico
|
||||||
|
elif value.endswith('ns'):
|
||||||
|
result = float(value[:-2]) * nano
|
||||||
|
elif value.endswith('us'):
|
||||||
|
result = float(value[:-2]) * micro
|
||||||
|
elif value.endswith('ms'):
|
||||||
|
result = float(value[:-2]) * milli
|
||||||
|
elif value.endswith('s'):
|
||||||
|
result = float(value[:-1])
|
||||||
|
else:
|
||||||
|
result = float(value)
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
def to_network_bandwidth(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = float(value)
|
||||||
|
elif value.endswith('Tbps'):
|
||||||
|
result = float(value[:-3]) * tera
|
||||||
|
elif value.endswith('Gbps'):
|
||||||
|
result = float(value[:-3]) * giga
|
||||||
|
elif value.endswith('Mbps'):
|
||||||
|
result = float(value[:-3]) * mega
|
||||||
|
elif value.endswith('kbps'):
|
||||||
|
result = float(value[:-3]) * kilo
|
||||||
|
elif value.endswith('bps'):
|
||||||
|
result = float(value[:-2])
|
||||||
|
else:
|
||||||
|
result = float(value)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def to_memory_bandwidth(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = int(value)
|
||||||
|
elif value.endswith('PB/s'):
|
||||||
|
result = int(value[:-4]) * pebi
|
||||||
|
elif value.endswith('TB/s'):
|
||||||
|
result = int(value[:-4]) * tebi
|
||||||
|
elif value.endswith('GB/s'):
|
||||||
|
result = int(value[:-4]) * gibi
|
||||||
|
elif value.endswith('MB/s'):
|
||||||
|
result = int(value[:-4]) * mebi
|
||||||
|
elif value.endswith('kB/s'):
|
||||||
|
result = int(value[:-4]) * kibi
|
||||||
|
elif value.endswith('B/s'):
|
||||||
|
result = int(value[:-3])
|
||||||
|
else:
|
||||||
|
result = int(value)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def to_memory_size(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
result = int(value)
|
||||||
|
elif value.endswith('PB'):
|
||||||
|
result = int(value[:-2]) * pebi
|
||||||
|
elif value.endswith('TB'):
|
||||||
|
result = int(value[:-2]) * tebi
|
||||||
|
elif value.endswith('GB'):
|
||||||
|
result = int(value[:-2]) * gibi
|
||||||
|
elif value.endswith('MB'):
|
||||||
|
result = int(value[:-2]) * mebi
|
||||||
|
elif value.endswith('kB'):
|
||||||
|
result = int(value[:-2]) * kibi
|
||||||
|
elif value.endswith('B'):
|
||||||
|
result = int(value[:-1])
|
||||||
|
else:
|
||||||
|
result = int(value)
|
||||||
|
|
||||||
|
return result
|
|
@ -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 Bool._convert(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")
|
|
@ -1,8 +1,7 @@
|
||||||
from Device import FooPioDevice, DmaDevice
|
from Device import FooPioDevice, DmaDevice
|
||||||
|
|
||||||
simobj PciConfigData(FooPioDevice):
|
simobj PciConfigData(SimObject):
|
||||||
type = 'PciConfigData'
|
type = 'PciConfigData'
|
||||||
addr = 0xffffffffffffffffL
|
|
||||||
VendorID = Param.UInt16("Vendor ID")
|
VendorID = Param.UInt16("Vendor ID")
|
||||||
DeviceID = Param.UInt16("Device ID")
|
DeviceID = Param.UInt16("Device ID")
|
||||||
Command = Param.UInt16(0, "Command")
|
Command = Param.UInt16(0, "Command")
|
||||||
|
@ -44,9 +43,9 @@ simobj PciConfigAll(FooPioDevice):
|
||||||
simobj PciDevice(DmaDevice):
|
simobj PciDevice(DmaDevice):
|
||||||
type = 'PciDevice'
|
type = 'PciDevice'
|
||||||
abstract = True
|
abstract = True
|
||||||
|
addr = 0xffffffff
|
||||||
pci_bus = Param.Int("PCI bus")
|
pci_bus = Param.Int("PCI bus")
|
||||||
pci_dev = Param.Int("PCI device number")
|
pci_dev = Param.Int("PCI device number")
|
||||||
pci_func = Param.Int("PCI function code")
|
pci_func = Param.Int("PCI function code")
|
||||||
configdata = Param.PciConfigData(Super, "PCI Config data")
|
configdata = Param.PciConfigData(Super, "PCI Config data")
|
||||||
configspace = Param.PciConfigAll(Super, "PCI Configspace")
|
configspace = Param.PciConfigAll(Super, "PCI Configspace")
|
||||||
addr = 0xffffffffffffffffL
|
|
102
python/m5/smartdict.py
Normal file
102
python/m5/smartdict.py
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# 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 *
|
||||||
|
|
||||||
|
class SmartDict(dict):
|
||||||
|
|
||||||
|
class Proxy(str):
|
||||||
|
def __int__(self):
|
||||||
|
return int(to_integer(str(self)))
|
||||||
|
def __long__(self):
|
||||||
|
return long(to_integer(str(self)))
|
||||||
|
def __float__(self):
|
||||||
|
return float(to_integer(str(self)))
|
||||||
|
def __nonzero__(self):
|
||||||
|
return to_bool(str(self))
|
||||||
|
def convert(self, other):
|
||||||
|
t = type(other)
|
||||||
|
if t == bool:
|
||||||
|
return bool(self)
|
||||||
|
if t == int:
|
||||||
|
return int(self)
|
||||||
|
if t == long:
|
||||||
|
return long(self)
|
||||||
|
if t == float:
|
||||||
|
return float(self)
|
||||||
|
return str(self)
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.convert(other) < other
|
||||||
|
def __le__(self, other):
|
||||||
|
return self.convert(other) <= other
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.convert(other) == other
|
||||||
|
def __ne__(self, other):
|
||||||
|
return self.convert(other) != other
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.convert(other) > other
|
||||||
|
def __ge__(self, other):
|
||||||
|
return self.convert(other) >= other
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return self.convert(other) + other
|
||||||
|
def __sub__(self, other):
|
||||||
|
return self.convert(other) - other
|
||||||
|
def __mul__(self, other):
|
||||||
|
return self.convert(other) * other
|
||||||
|
def __div__(self, other):
|
||||||
|
return self.convert(other) / other
|
||||||
|
def __truediv__(self, other):
|
||||||
|
return self.convert(other) / other
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return other + self.convert(other)
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return other - self.convert(other)
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return other * self.convert(other)
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return other / self.convert(other)
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
return other / self.convert(other)
|
||||||
|
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.Proxy(dict.get(self, key, 'False'))
|
||||||
|
|
||||||
|
def __setitem__(self, key, item):
|
||||||
|
dict.__setitem__(self, key, str(item))
|
||||||
|
|
||||||
|
def values(self):
|
||||||
|
return [ self.Proxy(v) for v in dict.values(self) ]
|
||||||
|
|
||||||
|
def itervalues(self):
|
||||||
|
for value in dict.itervalues(self):
|
||||||
|
yield self.Proxy(value)
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return [ (k, self.Proxy(v)) for k,v in dict.items(self) ]
|
||||||
|
|
||||||
|
def iteritems(self):
|
||||||
|
for key,value in dict.iteritems(self):
|
||||||
|
yield key, self.Proxy(value)
|
||||||
|
|
||||||
|
def get(self, key, default='False'):
|
||||||
|
return self.Proxy(dict.get(self, key, str(default)))
|
||||||
|
|
||||||
|
def setdefault(self, key, default='False'):
|
||||||
|
return self.Proxy(dict.setdefault(self, key, str(default)))
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "base/time.hh"
|
#include "base/time.hh"
|
||||||
#include "cpu/base_cpu.hh"
|
#include "cpu/base_cpu.hh"
|
||||||
#include "cpu/full_cpu/smt.hh"
|
#include "cpu/full_cpu/smt.hh"
|
||||||
|
#include "python/pyconfig.hh"
|
||||||
#include "sim/async.hh"
|
#include "sim/async.hh"
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/configfile.hh"
|
#include "sim/configfile.hh"
|
||||||
|
@ -61,7 +62,6 @@
|
||||||
#include "sim/stat_control.hh"
|
#include "sim/stat_control.hh"
|
||||||
#include "sim/stats.hh"
|
#include "sim/stats.hh"
|
||||||
#include "sim/universe.hh"
|
#include "sim/universe.hh"
|
||||||
#include "sim/pyconfig/pyconfig.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -30,12 +30,12 @@ from os.path import join as joinpath, realpath
|
||||||
|
|
||||||
mypath = sys.path[0]
|
mypath = sys.path[0]
|
||||||
sys.path.append(joinpath(mypath, '..'))
|
sys.path.append(joinpath(mypath, '..'))
|
||||||
|
sys.path.append(joinpath(mypath, '../python'))
|
||||||
sys.path.append(joinpath(mypath, '../util/pbs'))
|
sys.path.append(joinpath(mypath, '../util/pbs'))
|
||||||
sys.path.append(joinpath(mypath, '../sim/pyconfig'))
|
|
||||||
|
|
||||||
from importer import AddToPath, LoadMpyFile
|
pathlist = [ '.' ]
|
||||||
|
|
||||||
AddToPath('.')
|
m5_build_env = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], '-E:I:')
|
opts, args = getopt.getopt(sys.argv[1:], '-E:I:')
|
||||||
|
@ -44,17 +44,21 @@ 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':
|
||||||
AddToPath(arg)
|
pathlist.append(arg)
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
sys.exit('Improper Usage')
|
sys.exit('Improper Usage')
|
||||||
|
|
||||||
from m5config import *
|
from m5 import *
|
||||||
|
|
||||||
|
for path in pathlist:
|
||||||
|
AddToPath(path)
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
LoadMpyFile(arg)
|
LoadMpyFile(arg)
|
||||||
|
|
Loading…
Reference in a new issue