Source code for hwt.synthesizer.interfaceLevel.utils
from collections.abc import Container, Callable
from typing import Union, Optional
from hwt.constants import DIRECTION
from hwt.hObjList import HObjList
from hwt.hdl.types.bits import HBits
from hwt.hdl.types.bitsConst import HBitsConst
from hwt.mainBases import HwIOBase
from hwt.mainBases import RtlSignalBase
[docs]
class NotSpecifiedError(Exception):
"""
This error means that you need to implement this function
to use this functionality
e.g. you have to implement Simulation agent for interface
when you create new one and you can not use existing
"""
pass
[docs]
def HwIO_walkSignals(hwio: HwIOBase):
if hwio._hwIOs or isinstance(hwio, HObjList):
for sHwIO in hwio._hwIOs:
yield from HwIO_walkSignals(sHwIO)
else:
yield hwio
[docs]
def HwIO_connectPacked(srcPacked: RtlSignalBase,
dstInterface: Union[HwIOBase, RtlSignalBase],
exclude:Optional[Container[Union[HwIOBase, RtlSignalBase]]]=None):
"""
Connect 1D vector signal to this structuralized interface
(LSB of first interface is LSB of result)
:param packedSrc: vector which should be connected
:param dstInterface: structuralized interface where should
packedSrc be connected to
:param exclude: sub interfaces of self which should be excluded
"""
offset = 0
connections = []
for i in list(HwIO_walkSignals(dstInterface)):
if exclude is not None and i in exclude:
continue
sig = i._sig
t = sig._dtype
w = t.bit_length()
if w == 1:
if srcPacked._dtype.bit_length() == 1:
# avoid indexing on single bit
assert offset == 0, srcPacked
s = srcPacked
else:
# select bit from bit vector
assert offset < srcPacked._dtype.bit_length(), ("Insufficient amount of bits in srcPacked", srcPacked, w, offset, i)
s = srcPacked[offset]
offset += 1
else:
# select bit slice from bit vector
assert srcPacked._dtype.bit_length() >= w + offset, ("Insufficient amount of bits in srcPacked", srcPacked, w, offset, i)
s = srcPacked[(w + offset): offset] # src is likely to have insufficient amount of bits if
offset += w
assert sig._dtype.bit_length() == s._dtype.bit_length(), (sig, s, sig._dtype, s._dtype)
connections.append(sig(s._reinterpret_cast(sig._dtype)))
assert srcPacked._dtype.bit_length() == offset, ("Assert src not having width > than dst - exclude", srcPacked._dtype, offset)
return connections
[docs]
def HwIO_walkFlatten(hwio: HwIOBase, shouldEnterHwIOFn: Optional[Callable[[HwIOBase], tuple[bool, bool]]]):
"""
:param shouldEnterHwIOFn: function (actual hwio)
returns tuple (shouldEnter, shouldYield)
"""
_shouldEnter, _shouldYield = shouldEnterHwIOFn(hwio)
if _shouldYield:
yield hwio
if shouldEnterHwIOFn:
for sHwIO in hwio._hwIOs:
yield from HwIO_walkFlatten(sHwIO, shouldEnterHwIOFn)
[docs]
def HwIO_pack(hio: HwIOBase,
masterDirEqTo=DIRECTION.OUT,
exclude:Optional[Container[Union[HwIOBase, RtlSignalBase]]]=None) -> Union[HBitsConst, RtlSignalBase[HBits]]:
"""
Concatenate all signals to one big signal, recursively
(LSB of first interface is LSB of result)
:param masterDirEqTo: only signals with this direction are packed
:param exclude: sequence of signals/interfaces to exclude
"""
if not hio._hwIOs:
if hio._masterDir == masterDirEqTo:
return hio._sig
return None
res = None
for sHwIO in hio._hwIOs:
if exclude is not None and sHwIO in exclude:
continue
if sHwIO._hwIOs:
if sHwIO._masterDir == DIRECTION.IN:
d = DIRECTION.opposite(masterDirEqTo)
else:
d = masterDirEqTo
s = HwIO_pack(sHwIO, masterDirEqTo=d, exclude=exclude)
else:
if sHwIO._masterDir == masterDirEqTo:
s = sHwIO._sig
else:
s = None
if s is not None:
if not isinstance(s._dtype, HBits) or s._dtype.signed is not None:
s = s._reinterpret_cast(HBits(s._dtype.bit_length()))
if res is None:
res = s
else:
res = s._concat(res)
return res