Add support for assigning lists of ports or proxies to VectorPorts.
Includes support for printing readable VectorPort and Proxy names (via __str__). --HG-- extra : convert_revision : c48534a498b3036fe6ac45ff1606656546c79afb
This commit is contained in:
parent
886c7f7458
commit
a7e8a78958
|
@ -776,23 +776,25 @@ class PortRef(object):
|
||||||
|
|
||||||
# Full connection is symmetric (both ways). Called via
|
# Full connection is symmetric (both ways). Called via
|
||||||
# SimObject.__setattr__ as a result of a port assignment, e.g.,
|
# SimObject.__setattr__ as a result of a port assignment, e.g.,
|
||||||
# "obj1.portA = obj2.portB", or via VectorPortRef.__setitem__,
|
# "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__,
|
||||||
# e.g., "obj1.portA[3] = obj2.portB".
|
# e.g., "obj1.portA[3] = obj2.portB".
|
||||||
def connect(self, other):
|
def connect(self, other):
|
||||||
if isinstance(other, VectorPortRef):
|
if isinstance(other, VectorPortRef):
|
||||||
# reference to plain VectorPort is implicit append
|
# reference to plain VectorPort is implicit append
|
||||||
other = other._get_next()
|
other = other._get_next()
|
||||||
if not (isinstance(other, PortRef) or proxy.isproxy(other)):
|
|
||||||
raise TypeError, \
|
|
||||||
"assigning non-port reference '%s' to port '%s'" \
|
|
||||||
% (other, self)
|
|
||||||
if self.peer and not proxy.isproxy(self.peer):
|
if self.peer and not proxy.isproxy(self.peer):
|
||||||
print "warning: overwriting port", self, \
|
print "warning: overwriting port", self, \
|
||||||
"value", self.peer, "with", other
|
"value", self.peer, "with", other
|
||||||
self.peer = other
|
self.peer = other
|
||||||
assert(not isinstance(self.peer, VectorPortRef))
|
if proxy.isproxy(other):
|
||||||
if isinstance(other, PortRef) and other.peer is not self:
|
other.set_param_desc(PortParamDesc())
|
||||||
other.connect(self)
|
elif isinstance(other, PortRef):
|
||||||
|
if other.peer is not self:
|
||||||
|
other.connect(self)
|
||||||
|
else:
|
||||||
|
raise TypeError, \
|
||||||
|
"assigning non-port reference '%s' to port '%s'" \
|
||||||
|
% (other, self)
|
||||||
|
|
||||||
def clone(self, simobj, memo):
|
def clone(self, simobj, memo):
|
||||||
if memo.has_key(self):
|
if memo.has_key(self):
|
||||||
|
@ -847,6 +849,9 @@ class VectorPortRef(object):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.elements = []
|
self.elements = []
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '%s.%s[:]' % (self.simobj, self.name)
|
||||||
|
|
||||||
# for config.ini, print peer's name (not ours)
|
# for config.ini, print peer's name (not ours)
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return ' '.join([el.ini_str() for el in self.elements])
|
return ' '.join([el.ini_str() for el in self.elements])
|
||||||
|
@ -870,8 +875,25 @@ class VectorPortRef(object):
|
||||||
self[key].connect(value)
|
self[key].connect(value)
|
||||||
|
|
||||||
def connect(self, other):
|
def connect(self, other):
|
||||||
# reference to plain VectorPort is implicit append
|
if isinstance(other, (list, tuple)):
|
||||||
self._get_next().connect(other)
|
# Assign list of port refs to vector port.
|
||||||
|
# For now, append them... not sure if that's the right semantics
|
||||||
|
# or if it should replace the current vector.
|
||||||
|
for ref in other:
|
||||||
|
self._get_next().connect(ref)
|
||||||
|
else:
|
||||||
|
# scalar assignment to plain VectorPort is implicit append
|
||||||
|
self._get_next().connect(other)
|
||||||
|
|
||||||
|
def clone(self, simobj, memo):
|
||||||
|
if memo.has_key(self):
|
||||||
|
return memo[self]
|
||||||
|
newRef = copy.copy(self)
|
||||||
|
memo[self] = newRef
|
||||||
|
newRef.simobj = simobj
|
||||||
|
assert(isSimObject(newRef.simobj))
|
||||||
|
newRef.elements = [el.clone(simobj, memo) for el in self.elements]
|
||||||
|
return newRef
|
||||||
|
|
||||||
def unproxy(self, simobj):
|
def unproxy(self, simobj):
|
||||||
[el.unproxy(simobj) for el in self.elements]
|
[el.unproxy(simobj) for el in self.elements]
|
||||||
|
@ -915,6 +937,14 @@ class VectorPort(Port):
|
||||||
def makeRef(self, simobj):
|
def makeRef(self, simobj):
|
||||||
return VectorPortRef(simobj, self.name)
|
return VectorPortRef(simobj, self.name)
|
||||||
|
|
||||||
|
# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
|
||||||
|
# proxy objects (via set_param_desc()) so that proxy error messages
|
||||||
|
# make sense.
|
||||||
|
class PortParamDesc(object):
|
||||||
|
__metaclass__ = Singleton
|
||||||
|
|
||||||
|
ptype_str = 'Port'
|
||||||
|
ptype = Port
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Param', 'VectorParam',
|
__all__ = ['Param', 'VectorParam',
|
||||||
|
|
|
@ -39,6 +39,15 @@ class BaseProxy(object):
|
||||||
self._search_up = search_up
|
self._search_up = search_up
|
||||||
self._multiplier = None
|
self._multiplier = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self._search_self and not self._search_up:
|
||||||
|
s = 'Self'
|
||||||
|
elif not self._search_self and self._search_up:
|
||||||
|
s = 'Parent'
|
||||||
|
else:
|
||||||
|
s = 'ConfusedProxy'
|
||||||
|
return s + '.' + self.path()
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
def __setattr__(self, attr, value):
|
||||||
if not attr.startswith('_'):
|
if not attr.startswith('_'):
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
|
@ -102,6 +111,9 @@ class BaseProxy(object):
|
||||||
return obj
|
return obj
|
||||||
getindex = staticmethod(getindex)
|
getindex = staticmethod(getindex)
|
||||||
|
|
||||||
|
# This method should be called once the proxy is assigned to a
|
||||||
|
# particular parameter or port to set the expected type of the
|
||||||
|
# resolved proxy
|
||||||
def set_param_desc(self, pdesc):
|
def set_param_desc(self, pdesc):
|
||||||
self._pdesc = pdesc
|
self._pdesc = pdesc
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue