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): class ConcatSignal(_ShadowSignal):
__slots__ = ('_args',) __slots__ = ('_args', '_sigargs', '_initval')
def __init__(self, *args): def __init__(self, *args):
assert len(args) >= 2 assert len(args) >= 2
self._args = args self._args = args
### XXX error checks self._sigargs = sigargs = []
nrbits = 0 nrbits = 0
val = 0
for a in args: for a in args:
nrbits += len(a) if isinstance(a, intbv):
ini = intbv(0)[nrbits:] w = a._nrbits
hi = nrbits v = a._val
for a in args: elif isinstance(a, _Signal):
lo = hi - len(a) sigargs.append(a)
ini[hi:lo] = a w = a._nrbits
hi = lo 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) _ShadowSignal.__init__(self, ini)
gen = self.genfunc() gen = self.genfunc()
self._waiter = _SignalTupleWaiter(gen) self._waiter = _SignalTupleWaiter(gen)
@ -141,25 +159,31 @@ class ConcatSignal(_ShadowSignal):
def genfunc(self): def genfunc(self):
set_next = _Signal.next.fset set_next = _Signal.next.fset
args = self._args args = self._args
sigargs = self._sigargs
nrbits = self._nrbits nrbits = self._nrbits
newval = intbv(0)[nrbits:] newval = intbv(self._initval)[nrbits:]
while 1: while 1:
hi = nrbits hi = nrbits
for a in args: for a in args:
lo = hi - len(a) if isinstance(a, bool):
newval[hi:lo] = a w = 1
else:
w = len(a)
lo = hi - w
if a in sigargs:
newval[hi:lo] = a
hi = lo hi = lo
set_next(self, newval) set_next(self, newval)
yield args yield sigargs
def _markRead(self): def _markRead(self):
self._read = True self._read = True
for s in self._args: for s in self._sigargs:
s._markRead() s._markRead()
def _markUsed(self): def _markUsed(self):
self._used = True self._used = True
for s in self._args: for s in self._sigargs:
s._markUsed() s._markUsed()
def toVHDL(self): def toVHDL(self):

View File

@ -47,17 +47,53 @@ def bench_ConcatSignal():
c.next = k c.next = k
d.next = m d.next = m
yield delay(10) yield delay(10)
assert s[16:8] == a assert s[13:8] == a
assert s[7] == b assert s[7] == b
assert s[7:4] == c assert s[7:4] == c
assert s[4:] == d assert s[4:] == d
return check return check
def test_ConcatSignal(): def test_ConcatSignal():
Simulation(bench_ConcatSignal()).run() 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(): def bench_TristateSignal():