Source code for hwtLib.xilinx.slr_crossing

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

from hwt.code import If
from hwt.code_utils import rename_signal
from hwt.hdl.types.bits import HBits
from hwt.hdl.types.defs import BIT
from hwt.hdl.types.struct import HStruct
from hwt.hwIOs.std import HwIODataRdVld
from hwt.hwIOs.utils import addClkRstn, propagateClkRstn
from hwt.hwParam import HwParam
from hwt.math import log2ceil
from hwt.pyUtils.typingFuture import override
from hwtLib.abstract.busBridge import BusBridge
from hwtLib.xilinx.primitive.lutAsShiftReg import LutAsShiftReg


[docs] class HsSlrCrossingIo(BusBridge): """ An abstract class with a declaration of interfaces for handskaked SLR crossings """ @override def hwConfig(self): self.DATA_WIDTH = HwParam(64) @override def hwDeclr(self): addClkRstn(self) with self._hwParamsShared(): self.s = HwIODataRdVld() self.m = HwIODataRdVld()._m()
[docs] class SlrCrossingSrc(HsSlrCrossingIo): """ A part of SLR crossing which should be placed in SLR of producer """ @override def hwImpl(self): s, m = self.s, self.m reg = self._reg("reg", HStruct( (s.data._dtype, "data"), (BIT, "rd"), (BIT, "vld"), ), def_val={"vld": 0, "rd": 0} ) reg.data(s.data) reg.vld(s.vld) s.rd(reg.rd) m.data(reg.data) m.vld(reg.vld) reg.rd(m.rd)
[docs] class SlrCrossingDst(HsSlrCrossingIo): """ A part of SLR crossing which should be placed in SLR of consumer """ @override def hwDeclr(self): super(SlrCrossingDst, self).hwDeclr() self.DEPTH = 4 sh_d = LutAsShiftReg() sh_d.DATA_WIDTH = self.DATA_WIDTH sh_d.ITEMS = self.DEPTH self.shift_reg_data = sh_d sh_vld = LutAsShiftReg() sh_vld.DATA_WIDTH = 1 sh_vld.ITEMS = self.DEPTH self.shift_reg_vld = sh_vld @override def hwImpl(self): DEPTH = self.DEPTH s, m = self.s, self.m out_valid = self._reg("out_valid", def_val=0) out_ce = rename_signal(self, m.rd | ~out_valid, "out_ce") in_ready = self._reg("in_ready", def_val=1) in_ready(out_ce) cross_ce_inreg = self._reg("cross_ce_inreg", def_val=1) cross_ce_inreg(in_ready) cross_ce = self._reg("cross_ce", def_val=1) cross_ce(cross_ce_inreg) sh_addr = self._reg("sh_push", HBits(log2ceil(DEPTH)), def_val=0) If(~out_ce & cross_ce, sh_addr(sh_addr + 1) ).Elif(out_ce & ~cross_ce, sh_addr(sh_addr - 1) ) sh_vld = self.shift_reg_vld sh_data = self.shift_reg_data for sh in [sh_vld, sh_data]: sh.d_in.vld(cross_ce) sh.d_out_addr(sh_addr) sh_vld.d_in.data(s.vld) sh_data.d_in.data(s.data) s.rd(in_ready) data = self._reg("data", m.data._dtype) If(out_ce, data(sh_data.d_out), out_valid(sh_vld.d_out), ) m.data(data) m.vld(out_valid) propagateClkRstn(self)
[docs] class HsSlrCrossing(HsSlrCrossingIo): """ Super Logic Region (SLR) crossing for handshaked interfaces SLR represents one chiplet of FPGA which uses stacked silicon interconnect (SSI) or equivalent. The SLR corssing is required on SLR boundaries to met the timing. The crossing itself is just a pipeline of registers. """ @override def hwDeclr(self): HsSlrCrossingIo.hwDeclr(self) with self._hwParamsShared(): self.src = SlrCrossingSrc() self.dst = SlrCrossingDst() @override def hwImpl(self): propagateClkRstn(self) src, dst = self.src, self.dst src.s(self.s) dst.s(src.m) self.m(dst.m)
if __name__ == "__main__": from hwt.synth import to_rtl_str m = HsSlrCrossing() m.DATA_WIDTH = 4 print(to_rtl_str(m))