Source code for hwtLib.abstract.componentBuilder

from typing import Optional, Union

from hwt.hObjList import HObjList
from hwt.hdl.types.bits import HBits
from hwt.hwIO import HwIO
from hwt.hwModule import HwModule
from hwt.synthesizer.interfaceLevel.getDefaultClkRts import getClk, getRst
from hwt.synthesizer.interfaceLevel.hwModuleImplHelpers import getSignalName


[docs] class AbstractComponentBuilder(object): """ Helper class which simplifies instantiation of commonly used components with configuration based on input/output interface :ivar ~.parent: unit in which will be all units created by this builder instantiated :ivar ~.compId: last component sequential number, used to avoid name collisions :ivar ~.lastComp: last builded component :ivar ~.end: last interface of data-path :ivar ~.name: prefix for all instantiated units :attention: input port is taken from self.end """
[docs] def __init__(self, parent: HwModule, srcInterface: Union[HwIO, HObjList], name: Optional[str]=None, master_to_slave:bool=True): """ :param parent: HwModule where all submodules created by this builder will be instantiated :param name: prefix for all instantiated units :param srcInterface: start of data-path :param master_to_slave: if True the circuit is build in natural direction (master to slave, input to output) othervise it is build in reverse direction """ self.parent = parent self.lastComp = None self.end = srcInterface if name is None: assert srcInterface is not None name = "gen_" + getSignalName(srcInterface) self.name = name self.master_to_slave = master_to_slave self.compId = 0
[docs] def getClk(self): """ lookup clock signal on parent """ end = self.end if end is None: return getClk(self.parent) else: return end._getAssociatedClk()
[docs] def getRstn(self): """ lookup reset(n) signal on parent """ end = self.end if end is None: rst = getRst(self.parent) else: rst = end._getAssociatedRst() if isinstance(rst._dtype, HBits) and rst._dtype.negated: return rst else: return ~rst
[docs] def getHwIOCls(self): """ Get class of interface which this builder is currently using. """ return self._getHwIOCls(self.end)
[docs] def _getHwIOCls(self, hwIO: Union[HwIO, HObjList]): """ Get real HwIO class of interface """ if isinstance(hwIO, HObjList): return self._getHwIOCls(hwIO[0]) return hwIO.__class__
[docs] def _findSuitableName(self, name: str, firstWithoutCntrSuffix=False): """ Find a suitable name for component (= name without collisions), add suffix with counter to solve name collisions :param firstWithoutCntrSuffix: if True name is used as is if possible if False counter suffix is always added """ assert name is not None if self.name: namePrefix = f"{self.name:s}_" else: namePrefix = "" if firstWithoutCntrSuffix: _name = f"{namePrefix:s}{name:s}" try: getattr(self.parent, _name) except AttributeError: return _name while True: _name = f"{namePrefix:s}{name:s}_{self.compId:d}" try: getattr(self.parent, _name) except AttributeError: return _name break self.compId += 1 self.compId += 1
[docs] def _propagateClkRstn(self, m: HwModule): """ Connect clock and reset to HwModule "m" """ if hasattr(m, "clk"): m.clk(self.getClk()) if hasattr(m, 'rst_n'): m.rst_n(self.getRstn()) if hasattr(m, "rst"): m.rst(~self.getRstn())