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