1
0
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:
Jan Decaluwe 2015-05-23 01:13:39 +02:00
parent 9c605db9f1
commit fb9255bfa2
2 changed files with 77 additions and 17 deletions

View File

@ -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):

View File

@ -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():