X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fpython%2Fm5%2Fparams.py;h=38e320b5302dcd16aa39bd35659351c2149ffccc;hb=69fc2af00600ced942d81dba082d9780e5325c9e;hp=9e5f985c358240cb08e9482d2332b6fff9e235b7;hpb=14cb2264c80eb961eab1f80738e0144b6179d1a3;p=gem5.git diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 9e5f985c3..38e320b53 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1,4 +1,5 @@ # Copyright (c) 2004-2006 The Regents of The University of Michigan +# Copyright (c) 2010 Advanced Micro Devices, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -44,13 +45,40 @@ # ##################################################################### -import sys, inspect, copy -import convert +import copy +import datetime +import re +import sys +import time +import math + +import proxy +import ticks from util import * +def isSimObject(*args, **kwargs): + return SimObject.isSimObject(*args, **kwargs) + +def isSimObjectSequence(*args, **kwargs): + return SimObject.isSimObjectSequence(*args, **kwargs) + +def isSimObjectClass(*args, **kwargs): + return SimObject.isSimObjectClass(*args, **kwargs) + +allParams = {} + +class MetaParamValue(type): + def __new__(mcls, name, bases, dct): + cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct) + assert name not in allParams + allParams[name] = cls + return cls + + # Dummy base class to identify types that are legitimate for SimObject # parameters. class ParamValue(object): + __metaclass__ = MetaParamValue cxx_predecls = [] swig_predecls = [] @@ -67,6 +95,8 @@ class ParamValue(object): # Regular parameter description. class ParamDesc(object): + file_ext = 'ptype' + def __init__(self, ptype_str, ptype, *args, **kwargs): self.ptype_str = ptype_str # remember ptype only if it is provided @@ -100,15 +130,11 @@ class ParamDesc(object): def __getattr__(self, attr): if attr == 'ptype': - try: - ptype = eval(self.ptype_str, objects.__dict__) - if not isinstance(ptype, type): - raise NameError - self.ptype = ptype - return ptype - except NameError: - raise TypeError, \ - "Param qualifier '%s' is not a type" % self.ptype_str + ptype = SimObject.allClasses[self.ptype_str] + assert isSimObjectClass(ptype) + self.ptype = ptype + return ptype + raise AttributeError, "'%s' object has no attribute '%s'" % \ (type(self).__name__, attr) @@ -140,38 +166,86 @@ class ParamDesc(object): # single value. class VectorParamValue(list): + __metaclass__ = MetaParamValue + def __setattr__(self, attr, value): + raise AttributeError, \ + "Not allowed to set %s on '%s'" % (attr, type(self).__name__) + def ini_str(self): return ' '.join([v.ini_str() for v in self]) + def getValue(self): + return [ v.getValue() for v in self ] + def unproxy(self, base): return [v.unproxy(base) for v in self] -class SimObjVector(VectorParamValue): - def print_ini(self): +class SimObjectVector(VectorParamValue): + # support clone operation + def __call__(self, **kwargs): + return SimObjectVector([v(**kwargs) for v in self]) + + def clear_parent(self, old_parent): for v in self: - v.print_ini() + v.clear_parent(old_parent) + + def set_parent(self, parent, name): + if len(self) == 1: + self[0].set_parent(parent, name) + else: + width = int(math.ceil(math.log(len(self))/math.log(10))) + for i,v in enumerate(self): + v.set_parent(parent, "%s%0*d" % (name, width, i)) + + def get_parent(self): + parent_set = set(v._parent for v in self) + if len(parent_set) != 1: + raise RuntimeError, \ + "SimObjectVector elements have inconsistent parent value." + return parent_set.pop() + + # return 'cpu0 cpu1' etc. for print_ini() + def get_name(self): + return ' '.join([v._name for v in self]) + + # By iterating through the constituent members of the vector here + # we can nicely handle iterating over all a SimObject's children + # without having to provide lots of special functions on + # SimObjectVector directly. + def descendants(self): + for v in self: + for obj in v.descendants(): + yield obj class VectorParamDesc(ParamDesc): + file_ext = 'vptype' + # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. def convert(self, value): if isinstance(value, (list, tuple)): # list: coerce each element into new list tmp_list = [ ParamDesc.convert(self, v) for v in value ] - if isSimObjectSequence(tmp_list): - return SimObjVector(tmp_list) - else: - return VectorParamValue(tmp_list) else: - # singleton: leave it be (could coerce to a single-element - # list here, but for some historical reason we don't... - return ParamDesc.convert(self, value) + # singleton: coerce to a single-element list + tmp_list = [ ParamDesc.convert(self, value) ] - def cxx_predecls(self): - return ['#include '] + self.ptype.cxx_predecls + if isSimObjectSequence(tmp_list): + return SimObjectVector(tmp_list) + else: + return VectorParamValue(tmp_list) def swig_predecls(self): - return ['%include "std_vector.i"'] + self.ptype.swig_predecls + return ['%%include "%s_vptype.i"' % self.ptype_str] + + def swig_decl(self): + cxx_type = re.sub('std::', '', self.ptype.cxx_type) + vdecl = 'namespace std { %%template(vector_%s) vector< %s >; }' % \ + (self.ptype_str, cxx_type) + return ['%include "std_vector.i"'] + self.ptype.swig_predecls + [vdecl] + + def cxx_predecls(self): + return ['#include '] + self.ptype.cxx_predecls def cxx_decl(self): return 'std::vector< %s > %s;' % (self.ptype.cxx_type, self.name) @@ -188,15 +262,10 @@ class ParamFactory(object): # E.g., Param.Int(5, "number of widgets") def __call__(self, *args, **kwargs): - caller_frame = inspect.currentframe().f_back ptype = None try: - ptype = eval(self.ptype_str, - caller_frame.f_globals, caller_frame.f_locals) - if not isinstance(ptype, type): - raise TypeError, \ - "Param qualifier is not a type: %s" % ptype - except NameError: + ptype = allParams[self.ptype_str] + except KeyError: # if name isn't defined yet, assume it's a SimObject, and # try to resolve it later pass @@ -225,7 +294,10 @@ class String(ParamValue,str): cxx_predecls = ['#include '] swig_predecls = ['%include "std_string.i"\n' + '%apply const std::string& {std::string *};'] - pass + swig_predecls = ['%include "std_string.i"' ] + + def getValue(self): + return self # superclass for "numeric" parameter values, to emulate math # operations in a type-safe way. e.g., a Latency times an int returns @@ -237,6 +309,12 @@ class NumericParamValue(ParamValue): def __float__(self): return float(self.value) + def __long__(self): + return long(self.value) + + def __int__(self): + return int(self.value) + # hook for bounds checking def _check(self): return @@ -262,7 +340,7 @@ class NumericParamValue(ParamValue): return newobj # Metaclass for bounds-checked integer parameters. See CheckedInt. -class CheckedIntType(type): +class CheckedIntType(MetaParamValue): def __init__(cls, name, bases, dict): super(CheckedIntType, cls).__init__(name, bases, dict) @@ -274,18 +352,18 @@ class CheckedIntType(type): if not cls.cxx_predecls: # most derived types require this, so we just do it here once - cls.cxx_predecls = ['#include "sim/host.hh"'] + cls.cxx_predecls = ['#include "base/types.hh"'] if not cls.swig_predecls: # most derived types require this, so we just do it here once - cls.swig_predecls = ['%import "python/m5/swig/stdint.i"\n' + - '%import "sim/host.hh"'] + cls.swig_predecls = ['%import "stdint.i"\n' + + '%import "base/types.hh"'] 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); + " 'min' and 'max' or 'size' and 'unsigned'\n", + name); if cls.unsigned: cls.min = 0 cls.max = 2 ** cls.size - 1 @@ -308,10 +386,16 @@ class CheckedInt(NumericParamValue): def __init__(self, value): if isinstance(value, str): self.value = convert.toInteger(value) - elif isinstance(value, (int, long, float)): + elif isinstance(value, (int, long, float, NumericParamValue)): self.value = long(value) + else: + raise TypeError, "Can't convert object of type %s to CheckedInt" \ + % type(value).__name__ self._check() + def getValue(self): + return long(self.value) + class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True @@ -332,7 +416,17 @@ class UdpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True class Percent(CheckedInt): cxx_type = 'int'; min = 0; max = 100 class Float(ParamValue, float): - pass + cxx_type = 'double' + + def __init__(self, value): + if isinstance(value, (int, long, float, NumericParamValue, Float)): + self.value = float(value) + else: + raise TypeError, "Can't convert object of type %s to Float" \ + % type(value).__name__ + + def getValue(self): + return float(self.value) class MemorySize(CheckedInt): cxx_type = 'uint64_t' @@ -346,6 +440,7 @@ class MemorySize(CheckedInt): self._check() class MemorySize32(CheckedInt): + cxx_type = 'uint32_t' size = 32 unsigned = True def __init__(self, value): @@ -357,7 +452,6 @@ class MemorySize32(CheckedInt): class Addr(CheckedInt): cxx_type = 'Addr' - cxx_predecls = ['#include "targetarch/isa_traits.hh"'] size = 64 unsigned = True def __init__(self, value): @@ -376,7 +470,7 @@ class Addr(CheckedInt): return self.value + other -class MetaRange(type): +class MetaRange(MetaParamValue): def __init__(cls, name, bases, dict): super(MetaRange, cls).__init__(name, bases, dict) if name == 'Range': @@ -408,6 +502,9 @@ class Range(ParamValue): elif isinstance(args[0], Range): self.first = self.type(args[0].first) self.second = self.type(args[0].second) + elif isinstance(args[0], (list, tuple)): + self.first = self.type(args[0][0]) + self.second = self.type(args[0][1]) else: self.first = self.type(0) self.second = self.type(args[0]) - 1 @@ -426,9 +523,27 @@ class Range(ParamValue): class AddrRange(Range): type = Addr + swig_predecls = ['%include "python/swig/range.i"'] + + def getValue(self): + from m5.objects.params import AddrRange + + value = AddrRange() + value.start = long(self.first) + value.end = long(self.second) + return value class TickRange(Range): type = Tick + swig_predecls = ['%include "python/swig/range.i"'] + + def getValue(self): + from m5.objects.params import TickRange + + value = TickRange() + value.start = long(self.first) + value.end = long(self.second) + return value # Boolean parameter type. Python doesn't let you subclass bool, since # it doesn't want to let you create multiple instances of True and @@ -441,6 +556,9 @@ class Bool(ParamValue): except TypeError: self.value = bool(value) + def getValue(self): + return bool(self.value) + def __str__(self): return str(self.value) @@ -461,17 +579,18 @@ def IncEthernetAddr(addr, val = 1): assert(bytes[0] <= 255) return ':'.join(map(lambda x: '%02x' % x, bytes)) -class NextEthernetAddr(object): - addr = "00:90:00:00:00:01" +_NextEthernetAddr = "00:90:00:00:00:01" +def NextEthernetAddr(): + global _NextEthernetAddr - def __init__(self, inc = 1): - self.value = NextEthernetAddr.addr - NextEthernetAddr.addr = IncEthernetAddr(NextEthernetAddr.addr, inc) + value = _NextEthernetAddr + _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) + return value class EthernetAddr(ParamValue): cxx_type = 'Net::EthAddr' cxx_predecls = ['#include "base/inet.hh"'] - swig_predecls = ['class Net::EthAddr;'] + swig_predecls = ['%include "python/swig/inet.i"'] def __init__(self, value): if value == NextEthernetAddr: self.value = value @@ -492,17 +611,92 @@ class EthernetAddr(ParamValue): def unproxy(self, base): if self.value == NextEthernetAddr: - self.addr = self.value().value + return EthernetAddr(self.value()) return self + def getValue(self): + from m5.objects.params import EthAddr + return EthAddr(self.value) + + def ini_str(self): + return self.value + +time_formats = [ "%a %b %d %H:%M:%S %Z %Y", + "%a %b %d %H:%M:%S %Z %Y", + "%Y/%m/%d %H:%M:%S", + "%Y/%m/%d %H:%M", + "%Y/%m/%d", + "%m/%d/%Y %H:%M:%S", + "%m/%d/%Y %H:%M", + "%m/%d/%Y", + "%m/%d/%y %H:%M:%S", + "%m/%d/%y %H:%M", + "%m/%d/%y"] + + +def parse_time(value): + from time import gmtime, strptime, struct_time, time + from datetime import datetime, date + + if isinstance(value, struct_time): + return value + + if isinstance(value, (int, long)): + return gmtime(value) + + if isinstance(value, (datetime, date)): + return value.timetuple() + + if isinstance(value, str): + if value in ('Now', 'Today'): + return time.gmtime(time.time()) + + for format in time_formats: + try: + return strptime(value, format) + except ValueError: + pass + + raise ValueError, "Could not parse '%s' as a time" % value + +class Time(ParamValue): + cxx_type = 'tm' + cxx_predecls = [ '#include ' ] + swig_predecls = [ '%include "python/swig/time.i"' ] + def __init__(self, value): + self.value = parse_time(value) + + def getValue(self): + from m5.objects.params import tm + + c_time = tm() + py_time = self.value + + # UNIX is years since 1900 + c_time.tm_year = py_time.tm_year - 1900; + + # Python starts at 1, UNIX starts at 0 + c_time.tm_mon = py_time.tm_mon - 1; + c_time.tm_mday = py_time.tm_mday; + c_time.tm_hour = py_time.tm_hour; + c_time.tm_min = py_time.tm_min; + c_time.tm_sec = py_time.tm_sec; + + # Python has 0 as Monday, UNIX is 0 as sunday + c_time.tm_wday = py_time.tm_wday + 1 + if c_time.tm_wday > 6: + c_time.tm_wday -= 7; + + # Python starts at 1, Unix starts at 0 + c_time.tm_yday = py_time.tm_yday - 1; + + return c_time + def __str__(self): - if self.value == NextEthernetAddr: - if hasattr(self, 'addr'): - return self.addr - else: - return "NextEthernetAddr (unresolved)" - else: - return self.value + return time.asctime(self.value) + + def ini_str(self): + return str(self) # Enumerated types are a little more complex. The user specifies the # type as Enum(foo) where foo is either a list or dictionary of @@ -518,9 +712,16 @@ class EthernetAddr(ParamValue): # classes (_ListEnum and _DictEnum) to serve as base classes, then # derive the new type from the appropriate base class on the fly. - +allEnums = {} # Metaclass for Enum types -class MetaEnum(type): +class MetaEnum(MetaParamValue): + def __new__(mcls, name, bases, dict): + assert name not in allEnums + + cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict) + allEnums[name] = cls + return cls + def __init__(cls, name, bases, init_dict): if init_dict.has_key('map'): if not isinstance(cls.map, dict): @@ -541,7 +742,7 @@ class MetaEnum(type): raise TypeError, "Enum-derived class must define "\ "attribute 'map' or 'vals'" - cls.cxx_type = name + '::Enum' + cls.cxx_type = 'Enums::%s' % name super(MetaEnum, cls).__init__(name, bases, init_dict) @@ -549,10 +750,33 @@ class MetaEnum(type): # Note that we wrap the enum in a class/struct to act as a namespace, # so that the enum strings can be brief w/o worrying about collisions. def cxx_decl(cls): - s = 'struct %s {\n enum Enum {\n ' % cls.__name__ - s += ',\n '.join(['%s = %d' % (v,cls.map[v]) for v in cls.vals]) - s += '\n };\n};\n' - return s + name = cls.__name__ + code = "#ifndef __ENUM__%s\n" % name + code += '#define __ENUM__%s\n' % name + code += '\n' + code += 'namespace Enums {\n' + code += ' enum %s {\n' % name + for val in cls.vals: + code += ' %s = %d,\n' % (val, cls.map[val]) + code += ' Num_%s = %d,\n' % (name, len(cls.vals)) + code += ' };\n' + code += ' extern const char *%sStrings[Num_%s];\n' % (name, name) + code += '}\n' + code += '\n' + code += '#endif\n' + return code + + def cxx_def(cls): + name = cls.__name__ + code = '#include "enums/%s.hh"\n' % name + code += 'namespace Enums {\n' + code += ' const char *%sStrings[Num_%s] =\n' % (name, name) + code += ' {\n' + for val in cls.vals: + code += ' "%s",\n' % val + code += ' };\n' + code += '}\n' + return code # Base class for enum types. class Enum(ParamValue): @@ -565,50 +789,38 @@ class Enum(ParamValue): % (value, self.vals) self.value = value + def getValue(self): + return int(self.map[self.value]) + def __str__(self): return self.value -ticks_per_sec = None - # how big does a rounding error need to be before we warn about it? frequency_tolerance = 0.001 # 0.1% -# convert a floting-point # of ticks to integer, and warn if rounding -# discards too much precision -def tick_check(float_ticks): - if float_ticks == 0: - return 0 - int_ticks = int(round(float_ticks)) - err = (float_ticks - int_ticks) / float_ticks - if err > frequency_tolerance: - print >> sys.stderr, "Warning: rounding error > tolerance" - print >> sys.stderr, " %f rounded to %d" % (float_ticks, int_ticks) - #raise ValueError - return int_ticks - -def getLatency(value): - if isinstance(value, Latency) or isinstance(value, Clock): - return value.value - elif isinstance(value, Frequency) or isinstance(value, RootClock): - return 1 / value.value - elif isinstance(value, str): - try: - return convert.toLatency(value) - except ValueError: - try: - return 1 / convert.toFrequency(value) - except ValueError: - pass # fall through - raise ValueError, "Invalid Frequency/Latency value '%s'" % value +class TickParamValue(NumericParamValue): + cxx_type = 'Tick' + cxx_predecls = ['#include "base/types.hh"'] + swig_predecls = ['%import "stdint.i"\n' + + '%import "base/types.hh"'] + def getValue(self): + return long(self.value) -class Latency(NumericParamValue): - cxx_type = 'Tick' - cxx_predecls = ['#include "sim/host.hh"'] - swig_predecls = ['%import "python/m5/swig/stdint.i"\n' + - '%import "sim/host.hh"'] +class Latency(TickParamValue): def __init__(self, value): - self.value = getLatency(value) + if isinstance(value, (Latency, Clock)): + self.ticks = value.ticks + self.value = value.value + elif isinstance(value, Frequency): + self.ticks = value.ticks + self.value = 1.0 / value.value + elif value.endswith('t'): + self.ticks = True + self.value = int(value[:-1]) + else: + self.ticks = False + self.value = convert.toLatency(value) def __getattr__(self, attr): if attr in ('latency', 'period'): @@ -617,17 +829,31 @@ class Latency(NumericParamValue): return Frequency(self) raise AttributeError, "Latency object has no attribute '%s'" % attr + def getValue(self): + if self.ticks or self.value == 0: + value = self.value + else: + value = ticks.fromSeconds(self.value) + return long(value) + # convert latency to ticks def ini_str(self): - return str(tick_check(self.value * ticks_per_sec)) + return '%d' % self.getValue() -class Frequency(NumericParamValue): - cxx_type = 'Tick' - cxx_predecls = ['#include "sim/host.hh"'] - swig_predecls = ['%import "python/m5/swig/stdint.i"\n' + - '%import "sim/host.hh"'] +class Frequency(TickParamValue): def __init__(self, value): - self.value = 1 / getLatency(value) + if isinstance(value, (Latency, Clock)): + if value.value == 0: + self.value = 0 + else: + self.value = 1.0 / value.value + self.ticks = value.ticks + elif isinstance(value, Frequency): + self.value = value.value + self.ticks = value.ticks + else: + self.ticks = False + self.value = convert.toFrequency(value) def __getattr__(self, attr): if attr == 'frequency': @@ -636,41 +862,38 @@ class Frequency(NumericParamValue): return Latency(self) raise AttributeError, "Frequency object has no attribute '%s'" % attr - # convert frequency to ticks per period - def ini_str(self): - return self.period.ini_str() - -# Just like Frequency, except ini_str() is absolute # of ticks per sec (Hz). -# We can't inherit from Frequency because we don't want it to be directly -# assignable to a regular Frequency parameter. -class RootClock(ParamValue): - cxx_type = 'Tick' - cxx_predecls = ['#include "sim/host.hh"'] - swig_predecls = ['%import "python/m5/swig/stdint.i"\n' + - '%import "sim/host.hh"'] - def __init__(self, value): - self.value = 1 / getLatency(value) - - def __getattr__(self, attr): - if attr == 'frequency': - return Frequency(self) - if attr in ('latency', 'period'): - return Latency(self) - raise AttributeError, "Frequency object has no attribute '%s'" % attr + # convert latency to ticks + def getValue(self): + if self.ticks or self.value == 0: + value = self.value + else: + value = ticks.fromSeconds(1.0 / self.value) + return long(value) def ini_str(self): - return str(tick_check(self.value)) + return '%d' % self.getValue() # A generic frequency and/or Latency value. Value is stored as a latency, # but to avoid ambiguity this object does not support numeric ops (* or /). # An explicit conversion to a Latency or Frequency must be made first. class Clock(ParamValue): cxx_type = 'Tick' - cxx_predecls = ['#include "sim/host.hh"'] - swig_predecls = ['%import "python/m5/swig/stdint.i"\n' + - '%import "sim/host.hh"'] + cxx_predecls = ['#include "base/types.hh"'] + swig_predecls = ['%import "stdint.i"\n' + + '%import "base/types.hh"'] def __init__(self, value): - self.value = getLatency(value) + if isinstance(value, (Latency, Clock)): + self.ticks = value.ticks + self.value = value.value + elif isinstance(value, Frequency): + self.ticks = value.ticks + self.value = 1.0 / value.value + elif value.endswith('t'): + self.ticks = True + self.value = int(value[:-1]) + else: + self.ticks = False + self.value = convert.anyToLatency(value) def __getattr__(self, attr): if attr == 'frequency': @@ -679,32 +902,53 @@ class Clock(ParamValue): return Latency(self) raise AttributeError, "Frequency object has no attribute '%s'" % attr + def getValue(self): + return self.period.getValue() + def ini_str(self): return self.period.ini_str() class NetworkBandwidth(float,ParamValue): cxx_type = 'float' def __new__(cls, value): - val = convert.toNetworkBandwidth(value) / 8.0 + # convert to bits per second + val = convert.toNetworkBandwidth(value) return super(cls, NetworkBandwidth).__new__(cls, val) def __str__(self): return str(self.val) + def getValue(self): + # convert to seconds per byte + value = 8.0 / float(self) + # convert to ticks per byte + value = ticks.fromSeconds(value) + return float(value) + def ini_str(self): - return '%f' % (ticks_per_sec / float(self)) + return '%f' % self.getValue() class MemoryBandwidth(float,ParamValue): cxx_type = 'float' - def __new__(self, value): + def __new__(cls, value): + # we want the number of ticks per byte of data val = convert.toMemoryBandwidth(value) return super(cls, MemoryBandwidth).__new__(cls, val) def __str__(self): return str(self.val) + def getValue(self): + # convert to seconds per byte + value = float(self) + if value: + value = 1.0 / float(self) + # convert to ticks per byte + value = ticks.fromSeconds(value) + return float(value) + def ini_str(self): - return '%f' % (ticks_per_sec / float(self)) + return '%f' % self.getValue() # # "Constants"... handy aliases for various values. @@ -731,9 +975,13 @@ class NullSimObject(object): def set_path(self, parent, name): pass + def __str__(self): return 'Null' + def getValue(self): + return None + # The only instance you'll ever need... NULL = NullSimObject() @@ -790,6 +1038,7 @@ class PortRef(object): if self.peer and not proxy.isproxy(self.peer): print "warning: overwriting port", self, \ "value", self.peer, "with", other + self.peer.peer = None self.peer = other if proxy.isproxy(other): other.set_param_desc(PortParamDesc()) @@ -827,12 +1076,21 @@ class PortRef(object): # Call C++ to create corresponding port connection between C++ objects def ccConnect(self): + from m5.objects.params import connectPorts + if self.ccConnected: # already done this return peer = self.peer - internal.main.connectPorts(self.simobj.getCCObject(), self.name, - self.index, peer.simobj.getCCObject(), - peer.name, peer.index) + if not self.peer: # nothing to connect to + return + try: + connectPorts(self.simobj.getCCObject(), self.name, self.index, + peer.simobj.getCCObject(), peer.name, peer.index) + except: + print "Error connecting port %s.%s to %s.%s" % \ + (self.simobj.path(), self.name, + peer.simobj.path(), peer.name) + raise self.ccConnected = True peer.ccConnected = True @@ -952,6 +1210,14 @@ class PortParamDesc(object): ptype_str = 'Port' ptype = Port +baseEnums = allEnums.copy() +baseParams = allParams.copy() + +def clear(): + global allEnums, allParams + + allEnums = baseEnums.copy() + allParams = baseParams.copy() __all__ = ['Param', 'VectorParam', 'Enum', 'Bool', 'String', 'Float', @@ -960,15 +1226,12 @@ __all__ = ['Param', 'VectorParam', 'Counter', 'Addr', 'Tick', 'Percent', 'TcpPort', 'UdpPort', 'EthernetAddr', 'MemorySize', 'MemorySize32', - 'Latency', 'Frequency', 'RootClock', 'Clock', + 'Latency', 'Frequency', 'Clock', 'NetworkBandwidth', 'MemoryBandwidth', 'Range', 'AddrRange', 'TickRange', 'MaxAddr', 'MaxTick', 'AllMemory', + 'Time', 'NextEthernetAddr', 'NULL', 'Port', 'VectorPort'] -# see comment on imports at end of __init__.py. -from SimObject import isSimObject, isSimObjectSequence, isSimObjectClass -import proxy -import objects -import internal +import SimObject