summaryrefslogtreecommitdiff
path: root/python/m5
diff options
context:
space:
mode:
Diffstat (limited to 'python/m5')
-rw-r--r--python/m5/config.py339
-rw-r--r--python/m5/convert.py203
-rw-r--r--python/m5/objects/BaseCache.mpy2
-rw-r--r--python/m5/objects/Bus.mpy2
-rw-r--r--python/m5/objects/Ethernet.mpy4
-rw-r--r--python/m5/objects/Root.mpy2
-rw-r--r--python/m5/smartdict.py156
7 files changed, 465 insertions, 243 deletions
diff --git a/python/m5/config.py b/python/m5/config.py
index f696adc79..a791bbebf 100644
--- a/python/m5/config.py
+++ b/python/m5/config.py
@@ -27,7 +27,7 @@
from __future__ import generators
import os, re, sys, types, inspect
-from m5 import panic
+from m5 import panic, env
from convert import *
from multidict import multidict
@@ -65,7 +65,7 @@ class Singleton(type):
# object, either using keyword assignment in the constructor or in
# separate assignment statements. For example:
#
-# cache = BaseCache('my_cache', root, size=64*K)
+# cache = BaseCache('my_cache', root, size='64KB')
# cache.hit_latency = 3
# cache.assoc = 8
#
@@ -373,7 +373,7 @@ classes. You're trying to derive from:
# now process remaining _init_dict items
for key,val in cls._init_dict.items():
# param descriptions
- if isinstance(val, _Param):
+ if isinstance(val, ParamBase):
cls._new_param(key, val)
# init-time-only keywords
@@ -433,8 +433,10 @@ classes. You're trying to derive from:
try:
param.valid(value)
except Exception, e:
- panic("Exception: %s\nError setting param %s.%s to %s\n" % \
- (e, cls.__name__, attr, value))
+ msg = "%s\nError setting param %s.%s to %s\n" % \
+ (e, cls.__name__, attr, value)
+ e.args = (msg, )
+ raise
cls._values[attr] = value
elif isConfigNode(value) or isSimObjSequence(value):
cls._values[attr] = value
@@ -510,8 +512,10 @@ classes. You're trying to derive from:
instance.params.append(p)
instance.param_names[pname] = p
except Exception, e:
- raise e.__class__, 'Exception while evaluating %s.%s\n%s' % \
+ msg = 'Exception while evaluating %s.%s\n%s' % \
(instance.path, pname, e)
+ e.args = (msg, )
+ raise
return instance
@@ -693,8 +697,10 @@ class Node(object):
else:
param.value = self.unproxy(pval, ptype)
except Exception, e:
- raise e.__class__, 'Error while fixing up %s:%s\n%s' % \
+ msg = 'Error while fixing up %s:%s\n%s' % \
(self.path, param.name, e)
+ e.args = (msg, )
+ raise
for child in self.children:
assert(child != self)
@@ -727,8 +733,9 @@ class Node(object):
value = param.convert(param.value)
string = param.string(value)
except Exception, e:
- raise e.__class__, 'exception in %s:%s\n%s' % \
- (self.path, param.name, e)
+ msg = 'exception in %s:%s\n%s' % (self.path, param.name, e)
+ e.args = (msg, )
+ raise
print '%s = %s' % (param.name, string)
@@ -740,8 +747,6 @@ class Node(object):
# print type and parameter values to .ini file
def outputDot(self, dot):
-
-
label = "{%s|" % self.path
if isSimObject(self.realtype):
label += '%s|' % self.type
@@ -762,9 +767,10 @@ class Node(object):
value = param.convert(param.value)
string = param.string(value)
except Exception, e:
- raise e.__class__, 'exception in %s:%s\n%s' % \
- (self.name, param.name, e)
+ msg = 'exception in %s:%s\n%s' % (self.name, param.name, e)
+ e.args = (msg, )
raise
+
if isConfigNode(param.ptype) and string != "Null":
simobjs.append(string)
else:
@@ -837,7 +843,7 @@ class Value(object):
return len(self._getattr())
# Regular parameter.
-class _Param(object):
+class ParamBase(object):
def __init__(self, ptype, *args, **kwargs):
if isinstance(ptype, types.StringType):
self.ptype_string = ptype
@@ -909,13 +915,13 @@ class _Param(object):
def cpp_decl(self, name):
return '%s %s;' % (self.ptype._cpp_param_decl, name)
-class _ParamProxy(object):
+class ParamFactory(object):
def __init__(self, type):
self.ptype = type
# E.g., Param.Int(5, "number of widgets")
def __call__(self, *args, **kwargs):
- return _Param(self.ptype, *args, **kwargs)
+ return ParamBase(self.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
@@ -929,17 +935,16 @@ class _ParamProxy(object):
if attr != 'ptype':
raise AttributeError, \
'Attribute %s not available in %s' % (attr, self.__class__)
- super(_ParamProxy, self).__setattr__(attr, value)
-
+ super(ParamFactory, self).__setattr__(attr, value)
-Param = _ParamProxy(None)
+Param = ParamFactory(None)
# Vector-valued parameter description. Just like Param, except that
# the value is a vector (list) of the specified type instead of a
# single value.
-class _VectorParam(_Param):
+class VectorParamBase(ParamBase):
def __init__(self, type, *args, **kwargs):
- _Param.__init__(self, type, *args, **kwargs)
+ ParamBase.__init__(self, type, *args, **kwargs)
def valid(self, value):
if value == None:
@@ -974,12 +979,12 @@ class _VectorParam(_Param):
def cpp_decl(self, name):
return 'std::vector<%s> %s;' % (self.ptype._cpp_param_decl, name)
-class _VectorParamProxy(_ParamProxy):
+class VectorParamFactory(ParamFactory):
# E.g., VectorParam.Int(5, "number of widgets")
def __call__(self, *args, **kwargs):
- return _VectorParam(self.ptype, *args, **kwargs)
+ return VectorParamBase(self.ptype, *args, **kwargs)
-VectorParam = _VectorParamProxy(None)
+VectorParam = VectorParamFactory(None)
#####################################################################
#
@@ -995,6 +1000,80 @@ VectorParam = _VectorParamProxy(None)
#
#####################################################################
+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):
+ if not isinstance(value, Range):
+ raise TypeError, 'value %s is not a Pair' % value
+ value = cls(value)
+ value.first = cls.type._convert(value.first)
+ value.second = cls.type._convert(value.second)
+ return value
+
+ def _string(cls, value):
+ first = int(value.first)
+ second = int(value.second)
+ if value.extend:
+ second += first
+ if not value.inclusive:
+ second -= 1
+ return '%s:%s' % (cls.type._string(first), cls.type._string(second))
+
+class Range(ParamType):
+ __metaclass__ = MetaRange
+ def __init__(self, *args, **kwargs):
+ if len(args) == 0:
+ self.first = kwargs.pop('start')
+
+ if 'end' in kwargs:
+ self.second = kwargs.pop('end')
+ self.inclusive = True
+ self.extend = False
+ elif 'size' in kwargs:
+ self.second = kwargs.pop('size')
+ self.inclusive = False
+ self.extend = True
+ else:
+ raise TypeError, "Either end or size must be specified"
+
+ elif len(args) == 1:
+ if kwargs:
+ self.first = args[0]
+ if 'end' in kwargs:
+ self.second = kwargs.pop('end')
+ self.inclusive = True
+ self.extend = False
+ elif 'size' in kwargs:
+ self.second = kwargs.pop('size')
+ self.inclusive = False
+ self.extend = True
+ else:
+ raise TypeError, "Either end or size must be specified"
+ elif isinstance(args[0], Range):
+ self.first = args[0].first
+ self.second = args[0].second
+ self.inclusive = args[0].inclusive
+ self.extend = args[0].extend
+ else:
+ self.first = 0
+ self.second = args[0]
+ self.inclusive = False
+ self.extend = True
+
+ elif len(args) == 2:
+ self.first, self.second = args
+ self.inclusive = True
+ self.extend = False
+ else:
+ raise TypeError, "Too many arguments specified"
+
+ if kwargs:
+ raise TypeError, "too many keywords: %s" % kwargs.keys()
# Metaclass for bounds-checked integer parameters. See CheckedInt.
class CheckedIntType(type):
@@ -1028,8 +1107,10 @@ class CheckedIntType(type):
if not isinstance(value, (int, long, float, str)):
raise TypeError, 'Integer param of invalid type %s' % type(value)
- if isinstance(value, (str, float)):
- value = long(float(value))
+ if isinstance(value, float):
+ value = long(value)
+ elif isinstance(value, str):
+ value = toInteger(value)
if not cls.min <= value <= cls.max:
raise TypeError, 'Integer param out of bounds %d < %d < %d' % \
@@ -1044,7 +1125,7 @@ class CheckedIntType(type):
# class is subclassed to generate parameter classes with specific
# bounds. Initialization of the min and max bounds is done in the
# metaclass CheckedIntType.__init__.
-class CheckedInt(ParamType):
+class CheckedInt(long,ParamType):
__metaclass__ = CheckedIntType
class Int(CheckedInt): cppname = 'int'; size = 32; unsigned = False
@@ -1060,68 +1141,66 @@ class Int64(CheckedInt): cppname = 'int64_t'; size = 64; unsigned = False
class UInt64(CheckedInt): cppname = 'uint64_t'; size = 64; unsigned = True
class Counter(CheckedInt): cppname = 'Counter'; size = 64; unsigned = True
-class Addr(CheckedInt): cppname = 'Addr'; size = 64; unsigned = True
class Tick(CheckedInt): cppname = 'Tick'; size = 64; unsigned = True
class Percent(CheckedInt): cppname = 'int'; min = 0; max = 100
-class Pair(object):
- def __init__(self, first, second):
- self.first = first
- self.second = second
-
-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
+class MemorySize(CheckedInt):
+ cppname = 'uint64_t'
+ size = 64
+ unsigned = True
+ def __new__(cls, value):
+ return super(MemorySize, cls).__new__(cls, toMemorySize(value))
def _convert(cls, value):
- if not isinstance(value, Pair):
- raise TypeError, 'value %s is not a Pair' % value
- return Pair(cls.type._convert(value.first),
- cls.type._convert(value.second))
+ return cls(value)
+ _convert = classmethod(_convert)
def _string(cls, value):
- return '%s:%s' % (cls.type._string(value.first),
- cls.type._string(value.second))
+ return '%d' % value
+ _string = classmethod(_string)
-class Range(ParamType):
- __metaclass__ = MetaRange
+class Addr(CheckedInt):
+ cppname = 'Addr'
+ size = 64
+ unsigned = True
+ def __new__(cls, value):
+ try:
+ value = long(toMemorySize(value))
+ except TypeError:
+ value = long(value)
+ return super(Addr, cls).__new__(cls, value)
-def RangeSize(start, size):
- return Pair(start, start + size - 1)
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
-class AddrRange(Range): type = Addr
+ def _string(cls, value):
+ return '%d' % value
+ _string = classmethod(_string)
+
+class AddrRange(Range):
+ type = Addr
# Boolean parameter type.
class Bool(ParamType):
_cpp_param_decl = 'bool'
- def _convert(value):
- t = type(value)
- if t == bool:
- return value
-
- if t == int or t == long:
- return bool(value)
-
- if t == str:
- v = value.lower()
- if v == "true" or v == "t" or v == "yes" or v == "y":
- return True
- elif v == "false" or v == "f" or v == "no" or v == "n":
- return False
+ def __init__(self, value):
+ try:
+ self.value = toBool(value)
+ except TypeError:
+ self.value = bool(value)
- raise TypeError, 'Bool parameter (%s) of invalid type %s' % (v, t)
- _convert = staticmethod(_convert)
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
- def _string(value):
- if value:
+ def _string(cls, value):
+ if value.value:
return "true"
else:
return "false"
- _string = staticmethod(_string)
+ _string = classmethod(_string)
# String-valued parameter.
class String(ParamType):
@@ -1143,7 +1222,6 @@ class String(ParamType):
return value
_string = classmethod(_string)
-
def IncEthernetAddr(addr, val = 1):
bytes = map(lambda x: int(x, 16), addr.split(':'))
bytes[5] += val
@@ -1239,7 +1317,6 @@ Null = NULL = NullSimObject()
# Metaclass for Enum types
class MetaEnum(type):
-
def __init__(cls, name, bases, init_dict):
if init_dict.has_key('map'):
if not isinstance(cls.map, dict):
@@ -1286,25 +1363,126 @@ class Enum(ParamType):
def _string(self, value):
return str(value)
_string = classmethod(_string)
+
+root_frequency = None
+
#
# "Constants"... handy aliases for various values.
#
+class RootFrequency(float,ParamType):
+ _cpp_param_decl = 'Tick'
+
+ def __new__(cls, value):
+ return super(cls, RootFrequency).__new__(cls, toFrequency(value))
+
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
+
+ def _string(cls, value):
+ return '%d' % int(value)
+ _string = classmethod(_string)
+
+class ClockPeriod(float,ParamType):
+ _cpp_param_decl = 'Tick'
+ def __new__(cls, value):
+ relative = False
+ try:
+ val = toClockPeriod(value)
+ except ValueError, e:
+ relative = True
+ if value.endswith('f'):
+ val = float(value[:-1])
+ if val:
+ val = 1 / val
+ elif value.endswith('c'):
+ val = float(value[:-1])
+ else:
+ raise e
+
+ self = super(cls, ClockPeriod).__new__(cls, val)
+ self.relative = relative
+ return self
+
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
+
+ def _string(cls, value):
+ if not value.relative:
+ value *= root_frequency
+
+ return '%d' % int(value)
+ _string = classmethod(_string)
+
+class Frequency(float,ParamType):
+ _cpp_param_decl = 'Tick'
+
+ def __new__(cls, value):
+ relative = False
+ try:
+ val = toFrequency(value)
+ except ValueError, e:
+ if value.endswith('f'):
+ val = float(value[:-1])
+ relative = True
+ else:
+ raise e
+ self = super(cls, Frequency).__new__(cls, val)
+ self.relative = relative
+ return self
+
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
+
+ def _string(cls, value):
+ if not value.relative:
+ value = root_frequency / value
+
+ return '%d' % int(value)
+ _string = classmethod(_string)
+
+class Latency(float,ParamType):
+ _cpp_param_decl = 'Tick'
+ def __new__(cls, value):
+ relative = False
+ try:
+ val = toLatency(value)
+ except ValueError, e:
+ if value.endswith('c'):
+ val = float(value[:-1])
+ relative = True
+ else:
+ raise e
+ self = super(cls, Latency).__new__(cls, val)
+ self.relative = relative
+ return self
+
+ def _convert(cls, value):
+ return cls(value)
+ _convert = classmethod(_convert)
+
+ def _string(cls, value):
+ if not value.relative:
+ value *= root_frequency
+ return '%d' % value
+ _string = classmethod(_string)
+
# Some memory range specifications use this as a default upper bound.
-MAX_ADDR = Addr.max
+MaxAddr = Addr.max
MaxTick = Tick.max
-
-# For power-of-two sizing, e.g. 64*K gives an integer value 65536.
-K = 1024
-M = K*K
-G = K*M
+AllMemory = AddrRange(0, MaxAddr)
#####################################################################
# The final hook to generate .ini files. Called from configuration
# script once config is built.
def instantiate(root):
+ global root_frequency
instance = root.instantiate('root')
+ root_frequency = RootFrequency._convert(root.frequency._getattr())
instance.fixup()
instance.display()
if not noDot:
@@ -1337,6 +1515,7 @@ __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
'Int32', 'UInt32', 'Int64', 'UInt64',
'Counter', 'Addr', 'Tick', 'Percent',
- 'Pair', 'RangeSize', 'AddrRange', 'MAX_ADDR', 'NULL', 'K', 'M',
- 'NextEthernetAddr',
- 'instantiate']
+ 'MemorySize', 'RootFrequency', 'Frequency', 'Latency',
+ 'ClockPeriod',
+ 'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory', 'NULL',
+ 'NextEthernetAddr', 'instantiate']
diff --git a/python/m5/convert.py b/python/m5/convert.py
index 2ebe93889..6ccefd2fc 100644
--- a/python/m5/convert.py
+++ b/python/m5/convert.py
@@ -22,160 +22,185 @@ pebi = tebi * 1024
exbi = pebi * 1024
# memory size configuration stuff
-def toInteger(value):
+def toFloat(value):
if not isinstance(value, str):
- result = int(value)
- elif value.endswith('Ei'):
- result = int(value[:-2]) * exbi
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('Ei'):
+ return float(value[:-2]) * exbi
elif value.endswith('Pi'):
- result = int(value[:-2]) * pebi
+ return float(value[:-2]) * pebi
elif value.endswith('Ti'):
- result = int(value[:-2]) * tebi
+ return float(value[:-2]) * tebi
elif value.endswith('Gi'):
- result = int(value[:-2]) * gibi
+ return float(value[:-2]) * gibi
elif value.endswith('Mi'):
- result = int(value[:-2]) * mebi
+ return float(value[:-2]) * mebi
elif value.endswith('ki'):
- result = int(value[:-2]) * kibi
+ return float(value[:-2]) * kibi
elif value.endswith('E'):
- result = int(value[:-1]) * exa
+ return float(value[:-1]) * exa
elif value.endswith('P'):
- result = int(value[:-1]) * peta
+ return float(value[:-1]) * peta
elif value.endswith('T'):
- result = int(value[:-1]) * tera
+ return float(value[:-1]) * tera
elif value.endswith('G'):
- result = int(value[:-1]) * giga
+ return float(value[:-1]) * giga
elif value.endswith('M'):
- result = int(value[:-1]) * mega
+ return float(value[:-1]) * mega
elif value.endswith('k'):
- result = int(value[:-1]) * kilo
+ return float(value[:-1]) * kilo
elif value.endswith('m'):
- result = int(value[:-1]) * milli
+ return float(value[:-1]) * milli
elif value.endswith('u'):
- result = int(value[:-1]) * micro
+ return float(value[:-1]) * micro
elif value.endswith('n'):
- result = int(value[:-1]) * nano
+ return float(value[:-1]) * nano
elif value.endswith('p'):
- result = int(value[:-1]) * pico
+ return float(value[:-1]) * pico
elif value.endswith('f'):
- result = int(value[:-1]) * femto
+ return float(value[:-1]) * femto
else:
- result = int(value)
+ return float(value)
+
+def toLong(value):
+ value = toFloat(value)
+ result = int(value)
+ if value != result:
+ raise ValueError, "cannot convert '%s' to long" % value
return result
-def toBool(val):
- t = type(val)
- if t == bool:
- return val
+def toInteger(value):
+ value = toFloat(value)
+ result = int(value)
+ if value != result:
+ raise ValueError, "cannot convert '%s' to integer" % value
- if t == None:
- return False
+ return result
- if t == int or t == long:
- return bool(val)
+def toBool(value):
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
- 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
+ value = value.lower()
+ if value == "true" or value == "t" or value == "yes" or value == "y":
+ return True
+ elif value == "false" or value == "f" or value == "no" or value == "n":
+ return False
- return toInteger(val) != 0
+ raise ValueError, "cannot convert '%s' to bool" % value
def toFrequency(value):
if not isinstance(value, str):
- result = float(value)
- elif value.endswith('THz'):
- result = float(value[:-3]) * tera
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('THz'):
+ return float(value[:-3]) * tera
elif value.endswith('GHz'):
- result = float(value[:-3]) * giga
+ return float(value[:-3]) * giga
elif value.endswith('MHz'):
- result = float(value[:-3]) * mega
+ return float(value[:-3]) * mega
elif value.endswith('kHz'):
- result = float(value[:-3]) * kilo
+ return float(value[:-3]) * kilo
elif value.endswith('Hz'):
- result = float(value[:-2])
- else:
- result = float(value)
+ return float(value[:-2])
- return result
+ raise ValueError, "cannot convert '%s' to frequency" % value
def toLatency(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
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('ps'):
+ return float(value[:-2]) * pico
elif value.endswith('ns'):
- result = float(value[:-2]) * nano
+ return float(value[:-2]) * nano
elif value.endswith('us'):
- result = float(value[:-2]) * micro
+ return float(value[:-2]) * micro
elif value.endswith('ms'):
- result = float(value[:-2]) * milli
+ return float(value[:-2]) * milli
elif value.endswith('s'):
- result = float(value[:-1])
- else:
- result = float(value)
+ return float(value[:-1])
+
+ raise ValueError, "cannot convert '%s' to latency" % value
+
+def toClockPeriod(value):
+ """result is a clock period"""
+
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ try:
+ val = toFrequency(value)
+ if val != 0:
+ val = 1 / val
+ return val
+ except ValueError:
+ pass
+
+ try:
+ val = toLatency(value)
+ return val
+ except ValueError:
+ pass
+
+ raise ValueError, "cannot convert '%s' to clock period" % value
- return result;
def toNetworkBandwidth(value):
if not isinstance(value, str):
- result = float(value)
- elif value.endswith('Tbps'):
- result = float(value[:-3]) * tera
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('Tbps'):
+ return float(value[:-3]) * tera
elif value.endswith('Gbps'):
- result = float(value[:-3]) * giga
+ return float(value[:-3]) * giga
elif value.endswith('Mbps'):
- result = float(value[:-3]) * mega
+ return float(value[:-3]) * mega
elif value.endswith('kbps'):
- result = float(value[:-3]) * kilo
+ return float(value[:-3]) * kilo
elif value.endswith('bps'):
- result = float(value[:-2])
+ return float(value[:-2])
else:
- result = float(value)
+ return float(value)
- return result
+ raise ValueError, "cannot convert '%s' to network bandwidth" % value
def toMemoryBandwidth(value):
if not isinstance(value, str):
- result = int(value)
- elif value.endswith('PB/s'):
- result = int(value[:-4]) * pebi
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('PB/s'):
+ return float(value[:-4]) * pebi
elif value.endswith('TB/s'):
- result = int(value[:-4]) * tebi
+ return float(value[:-4]) * tebi
elif value.endswith('GB/s'):
- result = int(value[:-4]) * gibi
+ return float(value[:-4]) * gibi
elif value.endswith('MB/s'):
- result = int(value[:-4]) * mebi
+ return float(value[:-4]) * mebi
elif value.endswith('kB/s'):
- result = int(value[:-4]) * kibi
+ return float(value[:-4]) * kibi
elif value.endswith('B/s'):
- result = int(value[:-3])
- else:
- result = int(value)
+ return float(value[:-3])
- return result
+ raise ValueError, "cannot convert '%s' to memory bandwidth" % value
def toMemorySize(value):
if not isinstance(value, str):
- result = int(value)
- elif value.endswith('PB'):
- result = int(value[:-2]) * pebi
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ if value.endswith('PB'):
+ return float(value[:-2]) * pebi
elif value.endswith('TB'):
- result = int(value[:-2]) * tebi
+ return float(value[:-2]) * tebi
elif value.endswith('GB'):
- result = int(value[:-2]) * gibi
+ return float(value[:-2]) * gibi
elif value.endswith('MB'):
- result = int(value[:-2]) * mebi
+ return float(value[:-2]) * mebi
elif value.endswith('kB'):
- result = int(value[:-2]) * kibi
+ return float(value[:-2]) * kibi
elif value.endswith('B'):
- result = int(value[:-1])
- else:
- result = int(value)
+ return float(value[:-1])
- return result
+ raise ValueError, "cannot convert '%s' to memory size" % value
diff --git a/python/m5/objects/BaseCache.mpy b/python/m5/objects/BaseCache.mpy
index 98a422e30..b9986917f 100644
--- a/python/m5/objects/BaseCache.mpy
+++ b/python/m5/objects/BaseCache.mpy
@@ -23,7 +23,7 @@ simobj BaseCache(BaseMem):
"always service demand misses first")
protocol = Param.CoherenceProtocol(NULL, "coherence protocol to use")
repl = Param.Repl(NULL, "replacement policy")
- size = Param.Int("capacity in bytes")
+ size = Param.MemorySize("capacity in bytes")
split = Param.Bool(False, "whether or not this cache is split")
split_size = Param.Int(0,
"How many ways of the cache belong to CPU/LRU partition")
diff --git a/python/m5/objects/Bus.mpy b/python/m5/objects/Bus.mpy
index 025d69785..aa12f757a 100644
--- a/python/m5/objects/Bus.mpy
+++ b/python/m5/objects/Bus.mpy
@@ -2,5 +2,5 @@ from BaseHier import BaseHier
simobj Bus(BaseHier):
type = 'Bus'
- clock_ratio = Param.Int("ratio of CPU to bus frequency")
+ clock_ratio = Param.ClockPeriod("ratio of CPU to bus frequency")
width = Param.Int("bus width in bytes")
diff --git a/python/m5/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy
index cd251f36d..3acd8d04d 100644
--- a/python/m5/objects/Ethernet.mpy
+++ b/python/m5/objects/Ethernet.mpy
@@ -68,8 +68,8 @@ simobj NSGigE(PciDevice):
rx_delay = Param.Tick(1000, "Receive Delay")
tx_delay = Param.Tick(1000, "Transmit Delay")
- rx_fifo_size = Param.Int(131072, "max size in bytes of rxFifo")
- tx_fifo_size = Param.Int(131072, "max size in bytes of txFifo")
+ rx_fifo_size = Param.MemorySize('128kB', "max size in bytes of rxFifo")
+ tx_fifo_size = Param.MemorySize('128kB', "max size in bytes of txFifo")
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
diff --git a/python/m5/objects/Root.mpy b/python/m5/objects/Root.mpy
index 0e531054b..c535bd2dc 100644
--- a/python/m5/objects/Root.mpy
+++ b/python/m5/objects/Root.mpy
@@ -5,7 +5,7 @@ from Trace import Trace
simobj Root(SimObject):
type = 'Root'
- frequency = Param.Tick(200000000, "tick frequency")
+ frequency = Param.RootFrequency('200MHz', "tick frequency")
output_file = Param.String('cout', "file to dump simulator output to")
full_system = Param.Bool("Full system simulation?")
hier = HierParams(do_data = False, do_events = True)
diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py
index 0dbcc50b0..a2661c279 100644
--- a/python/m5/smartdict.py
+++ b/python/m5/smartdict.py
@@ -16,93 +16,111 @@
from convert import *
+class Variable(str):
+ """Intelligent proxy class for SmartDict. Variable will use the
+ various convert functions to attempt to convert values to useable
+ types"""
+ def __int__(self):
+ return toInteger(str(self))
+ def __long__(self):
+ return toLong(str(self))
+ def __float__(self):
+ return toFloat(str(self))
+ def __nonzero__(self):
+ return toBool(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)
+
+class UndefinedVariable(object):
+ """Placeholder class to represent undefined variables. Will
+ generally cause an exception whenever it is used, but evaluates to
+ zero for boolean truth testing such as in an if statement"""
+ def __nonzero__(self):
+ return False
+
class SmartDict(dict):
+ """Dictionary class that holds strings, but intelligently converts
+ those strings to other types depending on their usage"""
- class Proxy(str):
- def __int__(self):
- return int(toInteger(str(self)))
- def __long__(self):
- return long(toInteger(str(self)))
- def __float__(self):
- return float(toInteger(str(self)))
- def __nonzero__(self):
- return toBool(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)
-
-
- # __getitem__ uses dict.get() to return 'False' if the key is not
- # found (rather than raising KeyError). Note that this does *not*
- # set the key's value to 'False' in the dict, so that even after
- # we call env['foo'] we still get a meaningful answer from "'foo'
- # in env" (which calls dict.__contains__, which we do not
- # override).
def __getitem__(self, key):
- return self.Proxy(dict.get(self, key, 'False'))
+ """returns a Variable proxy if the values exists in the database and
+ returns an UndefinedVariable otherwise"""
+
+ if key in self:
+ return Variable(dict.get(self, key))
+ else:
+ # Note that this does *not* change the contents of the dict,
+ # so that even after we call env['foo'] we still get a
+ # meaningful answer from "'foo' in env" (which
+ # calls dict.__contains__, which we do not override).
+ return UndefinedVariable()
def __setitem__(self, key, item):
+ """intercept the setting of any variable so that we always
+ store strings in the dict"""
dict.__setitem__(self, key, str(item))
def values(self):
- return [ self.Proxy(v) for v in dict.values(self) ]
+ return [ Variable(v) for v in dict.values(self) ]
def itervalues(self):
for value in dict.itervalues(self):
- yield self.Proxy(value)
+ yield Variable(value)
def items(self):
- return [ (k, self.Proxy(v)) for k,v in dict.items(self) ]
+ return [ (k, Variable(v)) for k,v in dict.items(self) ]
def iteritems(self):
for key,value in dict.iteritems(self):
- yield key, self.Proxy(value)
+ yield key, Variable(value)
def get(self, key, default='False'):
- return self.Proxy(dict.get(self, key, str(default)))
+ return Variable(dict.get(self, key, str(default)))
def setdefault(self, key, default='False'):
- return self.Proxy(dict.setdefault(self, key, str(default)))
+ return Variable(dict.setdefault(self, key, str(default)))
+__all__ = [ 'SmartDict' ]