Source code for hwtLib.handshaked.resizer

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from hwt.code import If, Concat, Switch
from hwt.hdl.types.bits import HBits
from hwt.hwIO import HwIO
from hwt.hwIOs.std import HwIORdVldSync
from hwt.hwIOs.utils import addClkRstn
from hwt.math import log2ceil
from hwt.pyUtils.typingFuture import override
from hwt.synthesizer.rtlLevel.rtlSignal import RtlSignal
from hwt.synthesizer.vectorUtils import iterBits
from hwtLib.handshaked.compBase import HandshakedCompBase
from hwtLib.handshaked.reg import HandshakedReg


[docs] class HsResizer(HandshakedCompBase): """ Resize width of handshaked interface .. hwt-autodoc:: _example_HsResizer """
[docs] def __init__(self, hshwIO: HwIORdVldSync, scale, inHwIOConfigFn, outHwIOConfigFn): """ :param hshwIO: class of interface which should be used as interface of this unit :param scale: tuple (in scale, out scale) one of scales has to be 1, f. e. (1,2) means output will be 2x wider :param inHwIOConfigFn: function inHwIOConfigFn(input interface) which will be applied on dataIn :param outHwIOConfigFn: function outHwIOConfigFn(input interface) which will be applied on dataOut """ HandshakedCompBase.__init__(self, hshwIO) assert len(scale) == 2 scale = (int(scale[0]), int(scale[1])) assert scale[0] == 1 or scale[1] == 1 assert scale[0] > 0 and scale[1] > 0 self._scale = scale self._inIntfConfigFn = inHwIOConfigFn self._outIntfConfigFn = outHwIOConfigFn
@override def hwConfig(self): pass @override def hwDeclr(self): addClkRstn(self) self.dataIn = self.hwIOCls() self._inIntfConfigFn(self.dataIn) self.dataOut = self.hwIOCls()._m() self._outIntfConfigFn(self.dataOut)
[docs] def _upscaleDataPassLogic(self, inputRegs_cntr: RtlSignal, ITEMS: int): # valid when all registers are loaded and input with last datapart is valid vld = self.get_valid_signal rd = self.get_ready_signal vld(self.dataOut)(inputRegs_cntr._eq(ITEMS - 1) & vld(self.dataIn)) rd(self.dataIn)((inputRegs_cntr != ITEMS) | rd(self.dataOut)) If(inputRegs_cntr._eq(ITEMS - 1), If(vld(self.dataIn) & rd(self.dataOut), inputRegs_cntr(0) ) ).Else( If(vld(self.dataIn), inputRegs_cntr(inputRegs_cntr + 1) ) )
[docs] def _upscale(self, factor: int): inputRegs_cntr = self._reg("inputRegs_cntr", HBits(log2ceil(factor + 1), False), def_val=0) for din, dout in zip(self.get_data(self.dataIn), self.get_data(self.dataOut)): inputRegs = [self._reg(f"inReg{i:d}_{din._name:s}", din._dtype) for i in range(factor - 1)] # last word will be passed directly for i, r in enumerate(inputRegs): If(inputRegs_cntr._eq(i) & self.get_valid_signal(self.dataIn), r(din) ) dout(Concat(din, *reversed(inputRegs))) self._upscaleDataPassLogic(inputRegs_cntr, factor)
[docs] def _downscale(self, factor: int): inputRegs_cntr = self._reg("inputRegs_cntr", HBits(log2ceil(factor + 1), False), def_val=0) # instantiate HandshakedReg, handshaked builder is not used to avoid dependencies inReg = HandshakedReg(self.hwIOCls) inReg._updateHwParamsFrom(self.dataIn) self.inReg = inReg inReg.clk(self.clk) inReg.rst_n(self.rst_n) inReg.dataIn(self.dataIn) dataIn = inReg.dataOut dataOut = self.dataOut # create output mux for din, dout in zip(self.get_data(dataIn), self.get_data(dataOut)): widthOfPart = din._dtype.bit_length() // factor inParts = iterBits(din, bitsInOne=widthOfPart) Switch(inputRegs_cntr).add_cases( [(i, dout(inPart)) for i, inPart in enumerate(inParts)] ) vld = self.get_valid_signal rd = self.get_ready_signal vld(dataOut)(vld(dataIn)) self.get_ready_signal(dataIn)(inputRegs_cntr._eq(factor - 1) & rd(dataOut)) If(vld(dataIn) & rd(dataOut), If(inputRegs_cntr._eq(factor - 1), inputRegs_cntr(0) ).Else( inputRegs_cntr(inputRegs_cntr + 1) ) )
@override def hwImpl(self): scale = self._scale if scale[0] > scale[1]: self._downscale(scale[0]) elif scale[0] < scale[1]: self._upscale(scale[1]) else: self.dataOut(self.dataIn) return
[docs] def _example_HsResizer(): from hwt.hwIOs.std import HwIODataRdVld def set_dw_in(hwIO:HwIO): hwIO.DATA_WIDTH = 32 def set_dw_out(hwIO:HwIO): hwIO.DATA_WIDTH = 3 * 32 m = HsResizer(HwIODataRdVld, [1, 3], set_dw_in, set_dw_out) return m
if __name__ == "__main__": from hwt.synth import to_rtl_str m = _example_HsResizer() print(to_rtl_str(m))