diff options
Diffstat (limited to 'python/m5')
-rw-r--r-- | python/m5/config.py | 339 | ||||
-rw-r--r-- | python/m5/convert.py | 203 | ||||
-rw-r--r-- | python/m5/objects/BaseCache.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Bus.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Ethernet.mpy | 4 | ||||
-rw-r--r-- | python/m5/objects/Root.mpy | 2 | ||||
-rw-r--r-- | python/m5/smartdict.py | 156 |
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' ] |