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 Bits
from hwt.interfaces.utils import addClkRstn
from hwt.math import log2ceil
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, hsIntfCls, scale, inIntfConfigFn, outIntfConfigFn):
"""
:param hsIntfCls: 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 inIntfConfigFn: function inIntfConfigFn(input interface)
which will be applied on dataIn
:param outIntfConfigFn: function outIntfConfigFn(input interface)
which will be applied on dataOut
"""
HandshakedCompBase.__init__(self, hsIntfCls)
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 = inIntfConfigFn
self._outIntfConfigFn = outIntfConfigFn
def _config(self):
pass
def _declr(self):
addClkRstn(self)
self.dataIn = self.intfCls()
self._inIntfConfigFn(self.dataIn)
self.dataOut = self.intfCls()._m()
self._outIntfConfigFn(self.dataOut)
[docs] def _upscaleDataPassLogic(self, inputRegs_cntr, ITEMS):
# 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):
inputRegs_cntr = self._reg("inputRegs_cntr",
Bits(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):
inputRegs_cntr = self._reg("inputRegs_cntr",
Bits(log2ceil(factor + 1), False),
def_val=0)
# instantiate HandshakedReg, handshaked builder is not used to avoid dependencies
inReg = HandshakedReg(self.intfCls)
inReg._updateParamsFrom(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)
)
)
def _impl(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.interfaces.std import Handshaked
def set_dw_in(intf):
intf.DATA_WIDTH = 32
def set_dw_out(intf):
intf.DATA_WIDTH = 3 * 32
u = HsResizer(Handshaked,
[1, 3],
set_dw_in,
set_dw_out)
return u
if __name__ == "__main__":
from hwt.synthesizer.utils import to_rtl_str
u = _example_HsResizer()
print(to_rtl_str(u))