mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
Added support for constants in ConcatSignal interface
This commit is contained in:
parent
9c605db9f1
commit
fb9255bfa2
@ -119,21 +119,39 @@ class _SliceSignal(_ShadowSignal):
|
||||
|
||||
class ConcatSignal(_ShadowSignal):
|
||||
|
||||
__slots__ = ('_args',)
|
||||
__slots__ = ('_args', '_sigargs', '_initval')
|
||||
|
||||
def __init__(self, *args):
|
||||
assert len(args) >= 2
|
||||
self._args = args
|
||||
### XXX error checks
|
||||
self._sigargs = sigargs = []
|
||||
|
||||
nrbits = 0
|
||||
val = 0
|
||||
for a in args:
|
||||
nrbits += len(a)
|
||||
ini = intbv(0)[nrbits:]
|
||||
hi = nrbits
|
||||
for a in args:
|
||||
lo = hi - len(a)
|
||||
ini[hi:lo] = a
|
||||
hi = lo
|
||||
if isinstance(a, intbv):
|
||||
w = a._nrbits
|
||||
v = a._val
|
||||
elif isinstance(a, _Signal):
|
||||
sigargs.append(a)
|
||||
w = a._nrbits
|
||||
if isinstance(a._val, intbv):
|
||||
v = a._val._val
|
||||
else:
|
||||
v = a._val
|
||||
elif isinstance(a, bool):
|
||||
w = 1
|
||||
v = a
|
||||
elif isinstance(a, str):
|
||||
w = len(a)
|
||||
v = long(a, 2)
|
||||
else:
|
||||
raise TypeError("ConcatSignal: inappropriate argument type: %s" \
|
||||
% type(arg))
|
||||
nrbits += w
|
||||
val = val << w | v & (long(1) << w)-1
|
||||
self._initval = val
|
||||
ini = intbv(val)[nrbits:]
|
||||
_ShadowSignal.__init__(self, ini)
|
||||
gen = self.genfunc()
|
||||
self._waiter = _SignalTupleWaiter(gen)
|
||||
@ -141,25 +159,31 @@ class ConcatSignal(_ShadowSignal):
|
||||
def genfunc(self):
|
||||
set_next = _Signal.next.fset
|
||||
args = self._args
|
||||
sigargs = self._sigargs
|
||||
nrbits = self._nrbits
|
||||
newval = intbv(0)[nrbits:]
|
||||
newval = intbv(self._initval)[nrbits:]
|
||||
while 1:
|
||||
hi = nrbits
|
||||
for a in args:
|
||||
lo = hi - len(a)
|
||||
newval[hi:lo] = a
|
||||
if isinstance(a, bool):
|
||||
w = 1
|
||||
else:
|
||||
w = len(a)
|
||||
lo = hi - w
|
||||
if a in sigargs:
|
||||
newval[hi:lo] = a
|
||||
hi = lo
|
||||
set_next(self, newval)
|
||||
yield args
|
||||
yield sigargs
|
||||
|
||||
def _markRead(self):
|
||||
self._read = True
|
||||
for s in self._args:
|
||||
for s in self._sigargs:
|
||||
s._markRead()
|
||||
|
||||
def _markUsed(self):
|
||||
self._used = True
|
||||
for s in self._args:
|
||||
for s in self._sigargs:
|
||||
s._markUsed()
|
||||
|
||||
def toVHDL(self):
|
||||
|
@ -47,17 +47,53 @@ def bench_ConcatSignal():
|
||||
c.next = k
|
||||
d.next = m
|
||||
yield delay(10)
|
||||
assert s[16:8] == a
|
||||
assert s[13:8] == a
|
||||
assert s[7] == b
|
||||
assert s[7:4] == c
|
||||
assert s[4:] == d
|
||||
|
||||
return check
|
||||
|
||||
|
||||
def test_ConcatSignal():
|
||||
Simulation(bench_ConcatSignal()).run()
|
||||
|
||||
def bench_ConcatSignalWithConsts():
|
||||
|
||||
a = Signal(intbv(0)[5:])
|
||||
b = Signal(bool(0))
|
||||
c = Signal(intbv(0)[3:])
|
||||
d = Signal(intbv(0)[4:])
|
||||
c1 = "10"
|
||||
c2 = '0'
|
||||
c3 = intbv(5)[3:]
|
||||
c4 = bool(1)
|
||||
|
||||
s = ConcatSignal(c1, a, c2, b, c3, c, c4, d)
|
||||
|
||||
@instance
|
||||
def check():
|
||||
for i in range(2**len(a)):
|
||||
for j in (0, 1):
|
||||
for k in range(2**len(c)):
|
||||
for m in range(2**len(d)):
|
||||
a.next = i
|
||||
b.next = j
|
||||
c.next = k
|
||||
d.next = m
|
||||
yield delay(10)
|
||||
assert s[20:18] == long(c1, 2)
|
||||
assert s[18:13] == a
|
||||
assert s[12] == long(c2, 2)
|
||||
assert s[11] == b
|
||||
assert s[11:8] == c3
|
||||
assert s[8:5] == c
|
||||
assert s[4] == c4
|
||||
assert s[4:] == d
|
||||
|
||||
return check
|
||||
|
||||
def test_ConcatSignalWithConsts():
|
||||
Simulation(bench_ConcatSignalWithConsts()).run()
|
||||
|
||||
|
||||
def bench_TristateSignal():
|
||||
|
Loading…
x
Reference in New Issue
Block a user