1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

ConcatSignal

This commit is contained in:
Jan Decaluwe 2009-06-12 00:01:48 +02:00
parent a0010c904a
commit 56cab73497
4 changed files with 91 additions and 10 deletions

View File

@ -23,13 +23,19 @@
"""
from myhdl._Signal import _Signal
from myhdl._Waiter import _SignalWaiter, _SignalTupleWaiter
from myhdl._intbv import intbv
# shadow signals
class _ShadowSignal(_Signal):
__slots__ = ('gen', )
__slots__ = ('gen', 'waiter')
def __init__(self, val):
_Signal.__init__(self, val)
self.driven = True
@ -40,9 +46,9 @@ class _SliceSignal(_ShadowSignal):
def __init__(self, sig, left, right=None):
### XXX error checks
if right is None:
_Signal.__init__(self, sig[left])
_ShadowSignal.__init__(self, sig[left])
else:
_Signal.__init__(self, sig[left:right])
_ShadowSignal.__init__(self, sig[left:right])
self.sig = sig
self.left = left
self.right = right
@ -50,7 +56,7 @@ class _SliceSignal(_ShadowSignal):
self.gen = self.genfuncIndex()
else:
self.gen = self.genfuncSlice()
self._driven = True
self.waiter = _SignalWaiter(self.gen)
def genfuncIndex(self):
sig, index = self.sig, self.left
@ -77,3 +83,42 @@ class _SliceSignal(_ShadowSignal):
return "%s <= %s(%s);" % (self._name, self.sig._name, self.left)
else:
return "%s <= %s(%s-1 downto %s);" % (self._name, self.sig._name, self.left, self.right)
class ConcatSignal(_ShadowSignal):
__slots__ = ('_args',)
def __init__(self, *args):
assert len(args) >= 2
self._args = args
### XXX error checks
nrbits = 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
_ShadowSignal.__init__(self, ini)
self.gen = self.genfunc()
self.waiter = _SignalTupleWaiter(self.gen)
def genfunc(self):
set_next = _Signal._set_next
args = self._args
nrbits = self._nrbits
newval = intbv(0)[nrbits:]
while 1:
hi = nrbits
for a in args:
lo = hi - len(a)
newval[hi:lo] = a
hi = lo
set_next(self, newval)
yield args

View File

@ -224,10 +224,9 @@ def _makeWaiters(arglist):
raise SimulationError(_error.DuplicatedArg)
ids.add(id(arg))
# add waiters for shadow signals
# waiter wrapping done here to avoid circular imports
for sig in _signals:
if not isinstance(sig, _ShadowSignal):
continue
waiters.append(_SignalWaiter(sig.gen))
waiters.append(sig.waiter)
return waiters, cosim

View File

@ -24,6 +24,7 @@ Simulation -- simulation class
StopStimulation -- exception that stops a simulation
now -- function that returns the current time
Signal -- class to model hardware signals
ConcatSignal -- class that models a concatenation shadow signal
delay -- callable to model delay in a yield statement
posedge -- callable to model a rising edge on a signal in a yield statement
negedge -- callable to model a falling edge on a signal in a yield statement
@ -36,7 +37,6 @@ bin -- returns a binary string representation.
concat -- function to concat ints, bitstrings, bools, intbvs, Signals
-- returns an intbv
instances -- function that returns all instances defined in a function
processes -- function that returns all processes defined in a function
always_comb -- function that returns an input-sensitive generator
enum -- function that returns an enumeration type
traceSignals -- function that enables signal tracing in a VCD file
@ -110,6 +110,7 @@ from _concat import concat
from _intbv import intbv
from _join import join
from _Signal import posedge, negedge, Signal
from _ShadowSignal import ConcatSignal
from _simulator import now
from _delay import delay
from _Cosimulation import Cosimulation
@ -135,6 +136,7 @@ __all__ = ["bin",
"posedge",
"negedge",
"Signal",
"ConcatSignal",
"now",
"delay",
"downrange",

View File

@ -1,6 +1,6 @@
from myhdl import *
def bench_ShadowSignal():
def bench_SliceSignal():
s = Signal(intbv(0)[8:])
a, b, c = s(7), s(5), s(0)
@ -22,6 +22,41 @@ def bench_ShadowSignal():
return check
def test_ShadowSignal():
Simulation(bench_ShadowSignal()).run()
def test_SliceSignal():
Simulation(bench_SliceSignal()).run()
def bench_ConcatSignal():
a = Signal(intbv(0)[8:])
b = Signal(bool(0))
c = Signal(intbv(0)[3:])
d = Signal(intbv(0)[4:])
s = ConcatSignal(a, b, c, d)
@instance
def check():
for i in range(2**len(a)):
for j in (0, 1):
for k in range(len(c)):
for m in range(len(d)):
a.next = i
b.next = j
c.next = k
d.next = m
yield delay(10)
assert s[16:8] == a
assert s[7] == b
assert s[7:4] == c
assert s[4:] == d
return check
def test_ConcatSignal():
Simulation(bench_ConcatSignal()).run()