Source code for hwtLib.amba.axi_comp.interconnect.matrixR
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from hwt.interfaces.std import Handshaked
from hwt.interfaces.utils import propagateClkRstn
from hwt.math import log2ceil
from hwt.synthesizer.hObjList import HObjList
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
"""
def _declr(self):
AxiInterconnectCommon._declr(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()
for connected_masters in masters_for_slave:
if len(connected_masters) > 1:
f = HandshakedFifo(Handshaked)
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()
for connected_slaves in self.MASTERS:
if len(connected_slaves) > 1:
f = HandshakedFifo(Handshaked)
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._paramsShared():
self.addr_crossbar = AxiInterconnectMatrixAddrCrossbar(
self.intfCls.AR_CLS)
with self._paramsShared():
c = self.data_crossbar = AxiInterconnectMatrixCrossbar(
self.intfCls.R_CLS)
c.INPUT_CNT = len(self.SLAVES)
c.OUTPUTS = self.MASTERS
def _impl(self):
propagateClkRstn(self)
addr_crossbar = self.addr_crossbar
data_crossbar = self.data_crossbar
master_addr_channels = HObjList([m.ar for m in self.s])
slave_addr_channels = HObjList([s.ar for s in self.m])
addr_crossbar.s(master_addr_channels)
slave_addr_channels(addr_crossbar.m)
master_r_channels = HObjList([m.r for m in self.s])
master_r_channels(data_crossbar.dataOut)
slave_r_channels = HObjList([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():
u = AxiInterconnectMatrixR(Axi4)
# u.MASTERS = ({0, 1}, )
# u.MASTERS = ({0, 1, 2}, )
# u.MASTERS = ({0}, {0}, {0}, )
# u.SLAVES = ((0x1000, 0x1000),
# (0x2000, 0x1000),
# (0x3000, 0x1000),
# )
# u.SLAVES = ((0x1000, 0x1000))
u.MASTERS = ({0, 1}, {0, 1})
u.SLAVES = ((0x1000, 0x1000),
(0x2000, 0x1000),
)
return u
if __name__ == "__main__":
from hwt.synthesizer.utils import to_rtl_str
u = example_AxiInterconnectMatrixR()
print(to_rtl_str(u))