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):
|
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):
|
||||||
|
@ -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():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user