mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
ConcatSignal
This commit is contained in:
parent
a0010c904a
commit
56cab73497
@ -23,13 +23,19 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from myhdl._Signal import _Signal
|
from myhdl._Signal import _Signal
|
||||||
|
from myhdl._Waiter import _SignalWaiter, _SignalTupleWaiter
|
||||||
|
from myhdl._intbv import intbv
|
||||||
|
|
||||||
# shadow signals
|
# shadow signals
|
||||||
|
|
||||||
|
|
||||||
class _ShadowSignal(_Signal):
|
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):
|
def __init__(self, sig, left, right=None):
|
||||||
### XXX error checks
|
### XXX error checks
|
||||||
if right is None:
|
if right is None:
|
||||||
_Signal.__init__(self, sig[left])
|
_ShadowSignal.__init__(self, sig[left])
|
||||||
else:
|
else:
|
||||||
_Signal.__init__(self, sig[left:right])
|
_ShadowSignal.__init__(self, sig[left:right])
|
||||||
self.sig = sig
|
self.sig = sig
|
||||||
self.left = left
|
self.left = left
|
||||||
self.right = right
|
self.right = right
|
||||||
@ -50,7 +56,7 @@ class _SliceSignal(_ShadowSignal):
|
|||||||
self.gen = self.genfuncIndex()
|
self.gen = self.genfuncIndex()
|
||||||
else:
|
else:
|
||||||
self.gen = self.genfuncSlice()
|
self.gen = self.genfuncSlice()
|
||||||
self._driven = True
|
self.waiter = _SignalWaiter(self.gen)
|
||||||
|
|
||||||
def genfuncIndex(self):
|
def genfuncIndex(self):
|
||||||
sig, index = self.sig, self.left
|
sig, index = self.sig, self.left
|
||||||
@ -77,3 +83,42 @@ class _SliceSignal(_ShadowSignal):
|
|||||||
return "%s <= %s(%s);" % (self._name, self.sig._name, self.left)
|
return "%s <= %s(%s);" % (self._name, self.sig._name, self.left)
|
||||||
else:
|
else:
|
||||||
return "%s <= %s(%s-1 downto %s);" % (self._name, self.sig._name, self.left, self.right)
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,10 +224,9 @@ def _makeWaiters(arglist):
|
|||||||
raise SimulationError(_error.DuplicatedArg)
|
raise SimulationError(_error.DuplicatedArg)
|
||||||
ids.add(id(arg))
|
ids.add(id(arg))
|
||||||
# add waiters for shadow signals
|
# add waiters for shadow signals
|
||||||
# waiter wrapping done here to avoid circular imports
|
|
||||||
for sig in _signals:
|
for sig in _signals:
|
||||||
if not isinstance(sig, _ShadowSignal):
|
if not isinstance(sig, _ShadowSignal):
|
||||||
continue
|
continue
|
||||||
waiters.append(_SignalWaiter(sig.gen))
|
waiters.append(sig.waiter)
|
||||||
return waiters, cosim
|
return waiters, cosim
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ Simulation -- simulation class
|
|||||||
StopStimulation -- exception that stops a simulation
|
StopStimulation -- exception that stops a simulation
|
||||||
now -- function that returns the current time
|
now -- function that returns the current time
|
||||||
Signal -- class to model hardware signals
|
Signal -- class to model hardware signals
|
||||||
|
ConcatSignal -- class that models a concatenation shadow signal
|
||||||
delay -- callable to model delay in a yield statement
|
delay -- callable to model delay in a yield statement
|
||||||
posedge -- callable to model a rising edge on a signal 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
|
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
|
concat -- function to concat ints, bitstrings, bools, intbvs, Signals
|
||||||
-- returns an intbv
|
-- returns an intbv
|
||||||
instances -- function that returns all instances defined in a function
|
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
|
always_comb -- function that returns an input-sensitive generator
|
||||||
enum -- function that returns an enumeration type
|
enum -- function that returns an enumeration type
|
||||||
traceSignals -- function that enables signal tracing in a VCD file
|
traceSignals -- function that enables signal tracing in a VCD file
|
||||||
@ -110,6 +110,7 @@ from _concat import concat
|
|||||||
from _intbv import intbv
|
from _intbv import intbv
|
||||||
from _join import join
|
from _join import join
|
||||||
from _Signal import posedge, negedge, Signal
|
from _Signal import posedge, negedge, Signal
|
||||||
|
from _ShadowSignal import ConcatSignal
|
||||||
from _simulator import now
|
from _simulator import now
|
||||||
from _delay import delay
|
from _delay import delay
|
||||||
from _Cosimulation import Cosimulation
|
from _Cosimulation import Cosimulation
|
||||||
@ -135,6 +136,7 @@ __all__ = ["bin",
|
|||||||
"posedge",
|
"posedge",
|
||||||
"negedge",
|
"negedge",
|
||||||
"Signal",
|
"Signal",
|
||||||
|
"ConcatSignal",
|
||||||
"now",
|
"now",
|
||||||
"delay",
|
"delay",
|
||||||
"downrange",
|
"downrange",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from myhdl import *
|
from myhdl import *
|
||||||
|
|
||||||
def bench_ShadowSignal():
|
def bench_SliceSignal():
|
||||||
|
|
||||||
s = Signal(intbv(0)[8:])
|
s = Signal(intbv(0)[8:])
|
||||||
a, b, c = s(7), s(5), s(0)
|
a, b, c = s(7), s(5), s(0)
|
||||||
@ -22,6 +22,41 @@ def bench_ShadowSignal():
|
|||||||
return check
|
return check
|
||||||
|
|
||||||
|
|
||||||
def test_ShadowSignal():
|
def test_SliceSignal():
|
||||||
Simulation(bench_ShadowSignal()).run()
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user