mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Conversion with recursive ShadowSignals (#359)
* _ShadowSignal.py: conversion: enabled taking a ShadowSignal of a ShadowSignal, reworked _setName() to aggregate chained slicing/indexing to a single slice or index marked the shadowed Signal as always 'read' _intbv.py: added the [n:] to __repr__ _toVHDL.py: added a comment * added test for recursive/chained ShadowSignals * added missing returned instance * wrong startvalue * Changed a docstring to launch GitHub actions on origin
This commit is contained in:
parent
0477c7e042
commit
e6ac73214e
@ -17,10 +17,10 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
""" Module that provides the ShadowSignal classes
|
||||
|
||||
|
||||
"""
|
||||
Module that provides the ShadowSignal classes
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from copy import deepcopy
|
||||
|
||||
@ -35,7 +35,7 @@ from myhdl._bin import bin
|
||||
|
||||
class _ShadowSignal(_Signal):
|
||||
|
||||
__slots__ = ('_waiter', )
|
||||
__slots__ = ('_waiter',)
|
||||
|
||||
def __init__(self, val):
|
||||
_Signal.__init__(self, val)
|
||||
@ -58,6 +58,7 @@ class _SliceSignal(_ShadowSignal):
|
||||
else:
|
||||
_ShadowSignal.__init__(self, sig[left:right])
|
||||
self._sig = sig
|
||||
sig._read = True
|
||||
self._left = left
|
||||
self._right = right
|
||||
if right is None:
|
||||
@ -66,6 +67,12 @@ class _SliceSignal(_ShadowSignal):
|
||||
gen = self._genfuncSlice()
|
||||
self._waiter = _SignalWaiter(gen)
|
||||
|
||||
def __repr__(self):
|
||||
if self._right is None:
|
||||
return repr(self._sig) + '({})'.format(self._left)
|
||||
else:
|
||||
return repr(self._sig) + '({}, {})'.format(self._left, self._right)
|
||||
|
||||
def _genfuncIndex(self):
|
||||
sig, index = self._sig, self._left
|
||||
set_next = _Signal.next.fset
|
||||
@ -81,6 +88,24 @@ class _SliceSignal(_ShadowSignal):
|
||||
yield sig
|
||||
|
||||
def _setName(self, hdl):
|
||||
# if we depend on a ShadowSignal ourselves
|
||||
# it would be nice if we 'resolve' the slicing chain
|
||||
# e.g. s[7:4][1:0][1] to s[5]
|
||||
if isinstance(self._sig, _ShadowSignal):
|
||||
# self._sig must have a _left and a _right
|
||||
if self._right is None:
|
||||
# we're a final index
|
||||
self._left = self._sig._right + self._left
|
||||
else:
|
||||
self._right = self._sig._right + self._right
|
||||
self._left = self._sig._right + self._left
|
||||
# step one back up
|
||||
self._sig = self._sig._sig
|
||||
|
||||
else:
|
||||
# we're at the top of the chain
|
||||
pass
|
||||
|
||||
if self._right is None:
|
||||
if hdl == 'Verilog':
|
||||
self._name = "%s[%s]" % (self._sig._name, self._left)
|
||||
@ -91,6 +116,10 @@ class _SliceSignal(_ShadowSignal):
|
||||
self._name = "%s[%s-1:%s]" % (self._sig._name, self._left, self._right)
|
||||
else:
|
||||
self._name = "%s(%s-1 downto %s)" % (self._sig._name, self._left, self._right)
|
||||
# we may have 'shadowed' as well (and further down ...)
|
||||
if self._slicesigs:
|
||||
for sl in self._slicesigs:
|
||||
sl._setName(hdl)
|
||||
|
||||
def _markRead(self):
|
||||
self._read = True
|
||||
@ -306,13 +335,13 @@ class ConcatSignal(_ShadowSignal):
|
||||
hi = lo
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# Tristate signal
|
||||
|
||||
|
||||
class BusContentionWarning(UserWarning):
|
||||
pass
|
||||
|
||||
|
||||
warnings.filterwarnings('always', r".*", BusContentionWarning)
|
||||
|
||||
# def Tristate(val, delay=None):
|
||||
|
@ -24,12 +24,12 @@ from myhdl._bin import bin
|
||||
|
||||
|
||||
class intbv(object):
|
||||
#__slots__ = ('_val', '_min', '_max', '_nrbits', '_handleBounds')
|
||||
# __slots__ = ('_val', '_min', '_max', '_nrbits', '_handleBounds')
|
||||
|
||||
def __init__(self, val=0, min=None, max=None, _nrbits=0):
|
||||
if _nrbits:
|
||||
self._min = 0
|
||||
self._max = 2**_nrbits
|
||||
self._max = 2 ** _nrbits
|
||||
else:
|
||||
self._min = min
|
||||
self._max = max
|
||||
@ -476,14 +476,14 @@ class intbv(object):
|
||||
# I would prefer sign extension with hex format, but to
|
||||
# align with Verilog $display I don't do that
|
||||
if v < 0:
|
||||
v = 2**nrbits + v
|
||||
v = 2 ** nrbits + v
|
||||
w = (nrbits - 1) // 4 + 1
|
||||
return "{:0{w}x}".format(v, w=w)
|
||||
else:
|
||||
return "{:x}".format(v)
|
||||
|
||||
def __repr__(self):
|
||||
return "intbv(" + repr(self._val) + ")"
|
||||
return "intbv(" + repr(self._val) + ")[{}:]".format(self._nrbits)
|
||||
|
||||
def signed(self):
|
||||
''' Return new intbv with the values interpreted as signed
|
||||
@ -541,7 +541,7 @@ class intbv(object):
|
||||
retVal = self._val
|
||||
|
||||
if self._nrbits:
|
||||
M = 2**(self._nrbits - 1)
|
||||
M = 2 ** (self._nrbits - 1)
|
||||
return intbv(retVal, min=-M, max=M)
|
||||
else:
|
||||
return intbv(retVal)
|
||||
@ -561,4 +561,4 @@ class intbv(object):
|
||||
if self._nrbits:
|
||||
return intbv(retVal)[self._nrbits:]
|
||||
else:
|
||||
return intbv(retVal)
|
||||
return intbv(retVal)
|
||||
|
@ -375,6 +375,7 @@ def _writeModuleHeader(f, intf, needPck, lib, arch, useClauses, doc, stdLogicPor
|
||||
if stdLogicPorts and s._type is intbv:
|
||||
s._name = portname + "_num"
|
||||
convertPort = True
|
||||
# override the names given by _analyze.py
|
||||
for sl in s._slicesigs:
|
||||
sl._setName('VHDL')
|
||||
else:
|
||||
|
@ -1,12 +1,14 @@
|
||||
import myhdl
|
||||
from myhdl import *
|
||||
from myhdl import (block, Signal, intbv, delay, always_comb, instance,
|
||||
TristateSignal, ConcatSignal, conversion, StopSimulation,
|
||||
toVerilog, toVHDL)
|
||||
|
||||
|
||||
@block
|
||||
def bench_SliceSignal():
|
||||
|
||||
s = Signal(intbv(0)[8:])
|
||||
a, b, c = s(7), s(5), s(0)
|
||||
d, e, f, g = s(8,5), s(6,3), s(8,0), s(4,3)
|
||||
d, e, f, g = s(8, 5), s(6, 3), s(8, 0), s(4, 3)
|
||||
N = len(s)
|
||||
|
||||
@instance
|
||||
@ -29,6 +31,38 @@ def test_SliceSignal():
|
||||
assert conversion.verify(bench_SliceSignal()) == 0
|
||||
|
||||
|
||||
@block
|
||||
def bench_RecurseShadowSignal():
|
||||
s = Signal(intbv(0)[16:])
|
||||
|
||||
# take some recursive ShadowSignals
|
||||
su = s(16, 8)
|
||||
sl = s(8, 0)
|
||||
suu = su(8, 4)
|
||||
sul = su(4, 0)
|
||||
slu = sl(8, 4)
|
||||
sll = sl(4, 0)
|
||||
|
||||
@instance
|
||||
def check():
|
||||
for i in range(25):
|
||||
s.next = 0x4567 + i * 39
|
||||
yield delay(10)
|
||||
print(s)
|
||||
print(int(su))
|
||||
print(int(sl))
|
||||
print(suu)
|
||||
print(sul)
|
||||
print(slu)
|
||||
print(sll)
|
||||
|
||||
return check
|
||||
|
||||
|
||||
def test_RecurseShadowSignal():
|
||||
assert conversion.verify(bench_RecurseShadowSignal()) == 0
|
||||
|
||||
|
||||
@block
|
||||
def bench_ConcatSignal():
|
||||
|
||||
@ -39,10 +73,11 @@ def bench_ConcatSignal():
|
||||
|
||||
s = ConcatSignal(a, b, c, d)
|
||||
|
||||
I_max = 2**len(a)
|
||||
J_max = 2**len(b)
|
||||
K_max = 2**len(c)
|
||||
M_max = 2**len(d)
|
||||
I_max = 2 ** len(a)
|
||||
J_max = 2 ** len(b)
|
||||
K_max = 2 ** len(c)
|
||||
M_max = 2 ** len(d)
|
||||
|
||||
@instance
|
||||
def check():
|
||||
for i in range(I_max):
|
||||
@ -58,9 +93,11 @@ def bench_ConcatSignal():
|
||||
|
||||
return check
|
||||
|
||||
|
||||
def test_ConcatSignal():
|
||||
assert conversion.verify(bench_ConcatSignal()) == 0
|
||||
|
||||
|
||||
@block
|
||||
def bench_ConcatSignalWithConsts():
|
||||
|
||||
@ -78,17 +115,18 @@ def bench_ConcatSignalWithConsts():
|
||||
|
||||
s = ConcatSignal(c1, a, c2, b, c3, c, c4, d, c5, e)
|
||||
|
||||
I_max = 2**len(a)
|
||||
J_max = 2**len(b)
|
||||
K_max = 2**len(c)
|
||||
M_max = 2**len(d)
|
||||
I_max = 2 ** len(a)
|
||||
J_max = 2 ** len(b)
|
||||
K_max = 2 ** len(c)
|
||||
M_max = 2 ** len(d)
|
||||
|
||||
@instance
|
||||
def check():
|
||||
for i in range(I_max):
|
||||
for j in range(J_max):
|
||||
for k in range(K_max):
|
||||
for m in range(M_max):
|
||||
for n in range(2**len(e)):
|
||||
for n in range(2 ** len(e)):
|
||||
a.next = i
|
||||
b.next = j
|
||||
c.next = k
|
||||
@ -135,7 +173,7 @@ def bench_TristateSignal():
|
||||
b.next = None
|
||||
c.next = None
|
||||
yield delay(10)
|
||||
#print s
|
||||
# print s
|
||||
a.next = 1
|
||||
yield delay(10)
|
||||
print(s)
|
||||
@ -149,7 +187,7 @@ def bench_TristateSignal():
|
||||
print(s)
|
||||
c.next = None
|
||||
yield delay(10)
|
||||
#print s
|
||||
# print s
|
||||
|
||||
return check
|
||||
|
||||
@ -186,7 +224,7 @@ def bench_permute(conv=False):
|
||||
|
||||
@instance
|
||||
def stimulus():
|
||||
for i in range(2**len(a)):
|
||||
for i in range(2 ** len(a)):
|
||||
a.next = i
|
||||
yield delay(10)
|
||||
print("%d %d" % (x, a))
|
||||
@ -197,8 +235,10 @@ def bench_permute(conv=False):
|
||||
|
||||
return dut, stimulus
|
||||
|
||||
|
||||
def test_permute():
|
||||
assert conversion.verify(bench_permute()) == 0
|
||||
|
||||
|
||||
bench_permute(toVHDL)
|
||||
bench_permute(toVerilog)
|
||||
|
Loading…
x
Reference in New Issue
Block a user