|
|
|
|
@@ -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,8 @@ 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))
|
|
|
|
|
raise e.__class__, "%s\nError setting param %s.%s to %s\n" % \
|
|
|
|
|
(e, cls.__name__, attr, value)
|
|
|
|
|
cls._values[attr] = value
|
|
|
|
|
elif isConfigNode(value) or isSimObjSequence(value):
|
|
|
|
|
cls._values[attr] = value
|
|
|
|
|
@@ -837,7 +837,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 +909,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 +929,17 @@ 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 +974,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 +995,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 +1102,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 +1120,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 +1136,47 @@ 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(MemorySize):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def RangeSize(start, size):
|
|
|
|
|
return Pair(start, start + size - 1)
|
|
|
|
|
|
|
|
|
|
class AddrRange(Range): type = Addr
|
|
|
|
|
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
|
|
|
|
|
#def __new__(cls, value):
|
|
|
|
|
# return super(MemorySize, cls).__new__(cls, toBool(value))
|
|
|
|
|
|
|
|
|
|
if t == int or t == long:
|
|
|
|
|
return bool(value)
|
|
|
|
|
def _convert(cls, value):
|
|
|
|
|
return toBool(value)
|
|
|
|
|
_convert = classmethod(_convert)
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
raise TypeError, 'Bool parameter (%s) of invalid type %s' % (v, t)
|
|
|
|
|
_convert = staticmethod(_convert)
|
|
|
|
|
|
|
|
|
|
def _string(value):
|
|
|
|
|
def _string(cls, value):
|
|
|
|
|
if value:
|
|
|
|
|
return "true"
|
|
|
|
|
else:
|
|
|
|
|
return "false"
|
|
|
|
|
_string = staticmethod(_string)
|
|
|
|
|
_string = classmethod(_string)
|
|
|
|
|
|
|
|
|
|
# String-valued parameter.
|
|
|
|
|
class String(ParamType):
|
|
|
|
|
@@ -1291,13 +1346,9 @@ class Enum(ParamType):
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
# 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)
|
|
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
|
|
@@ -1337,6 +1388,6 @@ __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',
|
|
|
|
|
'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory', 'NULL',
|
|
|
|
|
'NextEthernetAddr', 'instantiate']
|
|
|
|
|
|