From 82127043c3c6bd7b23791a03525b7c950be1f0a4 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 14 Nov 2022 09:08:28 +0100 Subject: [PATCH] interconnect: Add data_width/address_width checks on InterconnectShared/Crossbar and also propagate address_width. --- litex/soc/interconnect/axi/axi_full.py | 21 +++++++++++++++++++-- litex/soc/interconnect/axi/axi_lite.py | 21 +++++++++++++++++++-- litex/soc/interconnect/wishbone.py | 21 +++++++++++++++++++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/litex/soc/interconnect/axi/axi_full.py b/litex/soc/interconnect/axi/axi_full.py index 82197d1c7..b68179d59 100644 --- a/litex/soc/interconnect/axi/axi_full.py +++ b/litex/soc/interconnect/axi/axi_full.py @@ -553,6 +553,21 @@ class AXIDecoder(Module): # AXI Interconnect --------------------------------------------------------------------------------- +def get_check_parameters(ports): + # Data-Width. + data_width = ports[0].data_width + if len(ports) > 1: + for port in ports[1:]: + assert port.data_width == data_width + + # Address-Width. + address_width = ports[0].address_width + if len(ports) > 1: + for port in ports[1:]: + assert port.address_width == address_width + + return data_width, address_width + class AXIInterconnectPointToPoint(Module): """AXI point to point interconnect""" def __init__(self, master, slave): @@ -561,7 +576,8 @@ class AXIInterconnectPointToPoint(Module): class AXIInterconnectShared(Module): """AXI shared interconnect""" def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): - shared = AXIInterface(data_width=masters[0].data_width) + data_width, address_width = get_check_parameters(ports=masters + [s for _, s in slaves]) + shared = AXIInterface(data_width=data_width, address_width=address_width) self.submodules.arbiter = AXIArbiter(masters, shared) self.submodules.decoder = AXIDecoder(shared, slaves) if timeout_cycles is not None: @@ -573,8 +589,9 @@ class AXICrossbar(Module): MxN crossbar for M masters and N slaves. """ def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): + data_width, address_width = get_check_parameters(ports=masters + [s for _, s in slaves]) matches, busses = zip(*slaves) - access_m_s = [[AXIInterface(data_width=masters[0].data_width) for j in slaves] for i in masters] # a[master][slave] + access_m_s = [[AXIInterface(data_width=data_width, address_width=address_width) for j in slaves] for i in masters] # a[master][slave] access_s_m = list(zip(*access_m_s)) # a[slave][master] # Decode each master into its access row. for slaves, master in zip(access_m_s, masters): diff --git a/litex/soc/interconnect/axi/axi_lite.py b/litex/soc/interconnect/axi/axi_lite.py index a7def4956..1bfad55eb 100644 --- a/litex/soc/interconnect/axi/axi_lite.py +++ b/litex/soc/interconnect/axi/axi_lite.py @@ -745,6 +745,21 @@ class AXILiteDecoder(Module): # AXI-Lite Interconnect ---------------------------------------------------------------------------- +def get_check_parameters(ports): + # Data-Width. + data_width = ports[0].data_width + if len(ports) > 1: + for port in ports[1:]: + assert port.data_width == data_width + + # Address-Width. + address_width = ports[0].address_width + if len(ports) > 1: + for port in ports[1:]: + assert port.address_width == address_width + + return data_width, address_width + class AXILiteInterconnectPointToPoint(Module): """AXI Lite point to point interconnect""" def __init__(self, master, slave): @@ -753,7 +768,8 @@ class AXILiteInterconnectPointToPoint(Module): class AXILiteInterconnectShared(Module): """AXI Lite shared interconnect""" def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): - shared = AXILiteInterface(data_width=masters[0].data_width) + data_width, address_width = get_check_parameters(ports=masters + [s for _, s in slaves]) + shared = AXILiteInterface(data_width=data_width, address_width=address_width) self.submodules.arbiter = AXILiteArbiter(masters, shared) self.submodules.decoder = AXILiteDecoder(shared, slaves) if timeout_cycles is not None: @@ -765,8 +781,9 @@ class AXILiteCrossbar(Module): MxN crossbar for M masters and N slaves. """ def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): + data_width, address_width = get_check_parameters(ports=masters + [s for _, s in slaves]) matches, busses = zip(*slaves) - access_m_s = [[AXILiteInterface(data_width=masters[0].data_width) for j in slaves] for i in masters] # a[master][slave] + access_m_s = [[AXILiteInterface(data_width, address_width=address_width) for j in slaves] for i in masters] # a[master][slave] access_s_m = list(zip(*access_m_s)) # a[slave][master] # Decode each master into its access row. for slaves, master in zip(access_m_s, masters): diff --git a/litex/soc/interconnect/wishbone.py b/litex/soc/interconnect/wishbone.py index ade297c76..81e3f7b1a 100644 --- a/litex/soc/interconnect/wishbone.py +++ b/litex/soc/interconnect/wishbone.py @@ -143,6 +143,21 @@ class Timeout(Module): # Wishbone Interconnect ---------------------------------------------------------------------------- +def get_check_parameters(ports): + # Data-Width. + data_width = ports[0].data_width + if len(ports) > 1: + for port in ports[1:]: + assert port.data_width == data_width + + # Address-Width. + adr_width = ports[0].adr_width + if len(ports) > 1: + for port in ports[1:]: + assert port.adr_width == adr_width + + return data_width, adr_width + class InterconnectPointToPoint(Module): def __init__(self, master, slave): self.comb += master.connect(slave) @@ -222,7 +237,8 @@ class Decoder(Module): class InterconnectShared(Module): def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): - shared = Interface(data_width=masters[0].data_width) + data_width, adr_width = get_check_parameters(ports=masters + [s for _, s in slaves]) + shared = Interface(data_width=data_width, adr_width=adr_width) self.submodules.arbiter = Arbiter(masters, shared) self.submodules.decoder = Decoder(shared, slaves, register) if timeout_cycles is not None: @@ -231,8 +247,9 @@ class InterconnectShared(Module): class Crossbar(Module): def __init__(self, masters, slaves, register=False, timeout_cycles=1e6): + data_width, adr_width = get_check_parameters(ports=masters + [s for _, s in slaves]) matches, busses = zip(*slaves) - access = [[Interface(data_width=masters[0].data_width) for j in slaves] for i in masters] + access = [[Interface(data_width=data_width, adr_width=adr_width) for j in slaves] for i in masters] # decode each master into its access row for row, master in zip(access, masters): row = list(zip(matches, row))