Source code for hwtLib.amba.axi_comp.interconnect.matrixR

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

from hwt.hObjList import HObjList
from hwt.hwIOs.hwIOArray import HwIOArray
from hwt.hwIOs.std import HwIODataRdVld
from hwt.hwIOs.utils import propagateClkRstn
from hwt.math import log2ceil
from hwt.pyUtils.typingFuture import override
from hwtLib.amba.axi4 import Axi4
from hwtLib.amba.axi_comp.interconnect.common import AxiInterconnectCommon
from hwtLib.amba.axi_comp.interconnect.matrixAddrCrossbar import AxiInterconnectMatrixAddrCrossbar
from hwtLib.amba.axi_comp.interconnect.matrixCrossbar import AxiInterconnectMatrixCrossbar
from hwtLib.handshaked.fifo import HandshakedFifo


[docs] class AxiInterconnectMatrixR(AxiInterconnectCommon): """ Read only AXI3/4/Lite interconnect with supports transaction overlapping and guarantees the order order of transactions on the bus :ivar ~.order_m_index_for_s_data: list, FIFOs for each slave which keeps the information about which master accessed slave on this index, to keep the order of transactions coherent :ivar ~.order_s_index_for_m_data: list, FIFOs for each master which keeps the information about where master should expect data .. hwt-autodoc:: example_AxiInterconnectMatrixR """ @override def hwDeclr(self): AxiInterconnectCommon.hwDeclr(self, has_r=True, has_w=False) masters_for_slave = AxiInterconnectMatrixCrossbar._masters_for_slave( self.MASTERS, len(self.SLAVES)) # fifo for master index for each slave so slave knows # which master did read and where is should send it order_m_index_for_s_data: HObjList[HandshakedFifo] = HObjList() for connected_masters in masters_for_slave: if len(connected_masters) > 1: f = HandshakedFifo(HwIODataRdVld) f.DEPTH = self.MAX_TRANS_OVERLAP f.DATA_WIDTH = log2ceil(len(self.MASTERS)) else: f = None order_m_index_for_s_data.append(f) self.order_m_index_for_s_data = order_m_index_for_s_data # fifo for slave index for each master # so master knows where it should expect the data order_s_index_for_m_data: HObjList[HandshakedFifo] = HObjList() for connected_slaves in self.MASTERS: if len(connected_slaves) > 1: f = HandshakedFifo(HwIODataRdVld) f.DEPTH = self.MAX_TRANS_OVERLAP f.DATA_WIDTH = log2ceil(len(self.SLAVES)) else: f = None order_s_index_for_m_data.append(f) self.order_s_index_for_m_data = order_s_index_for_m_data with self._hwParamsShared(): self.addr_crossbar = AxiInterconnectMatrixAddrCrossbar( self.hwIOCls.AR_CLS) with self._hwParamsShared(): c = self.data_crossbar = AxiInterconnectMatrixCrossbar( self.hwIOCls.R_CLS) c.INPUT_CNT = len(self.SLAVES) c.OUTPUTS = self.MASTERS @override def hwImpl(self): propagateClkRstn(self) addr_crossbar = self.addr_crossbar data_crossbar = self.data_crossbar master_addr_channels = HwIOArray(m.ar for m in self.s) slave_addr_channels = HwIOArray(s.ar for s in self.m) addr_crossbar.s(master_addr_channels) slave_addr_channels(addr_crossbar.m) master_r_channels = HwIOArray(m.r for m in self.s) master_r_channels(data_crossbar.dataOut) slave_r_channels = HwIOArray(s.r for s in self.m) data_crossbar.dataIn(slave_r_channels) for m_i, f in enumerate(self.order_s_index_for_m_data): if f is None: continue f.dataIn(addr_crossbar.order_s_index_for_m_data_out[m_i]) data_crossbar.order_din_index_for_dout_in[m_i](f.dataOut) for s_i, f in enumerate(self.order_m_index_for_s_data): if f is None: continue f.dataIn(addr_crossbar.order_m_index_for_s_data_out[s_i]) data_crossbar.order_dout_index_for_din_in[s_i](f.dataOut)
[docs] def example_AxiInterconnectMatrixR(): m = AxiInterconnectMatrixR(Axi4) # m.MASTERS = ({0, 1}, ) # m.MASTERS = ({0, 1, 2}, ) # m.MASTERS = ({0}, {0}, {0}, ) # m.SLAVES = ((0x1000, 0x1000), # (0x2000, 0x1000), # (0x3000, 0x1000), # ) # m.SLAVES = ((0x1000, 0x1000)) m.MASTERS = ({0, 1}, {0, 1}) m.SLAVES = ((0x1000, 0x1000), (0x2000, 0x1000), ) return m
if __name__ == "__main__": from hwt.synth import to_rtl_str m = example_AxiInterconnectMatrixR() print(to_rtl_str(m))