diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 34016eb9f..5b31b604d 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -66,7 +66,7 @@ class SoCCore(Module): integrated_sram_size=4096, integrated_main_ram_size=0, integrated_main_ram_init=[], shadow_base=0x80000000, - csr_data_width=8, csr_address_width=14, + csr_data_width=8, csr_address_width=14, csr_expose=False, with_uart=True, uart_name="serial", uart_baudrate=115200, uart_stub=False, ident="", ident_version=False, reserve_nmi_interrupt=True, @@ -95,6 +95,9 @@ class SoCCore(Module): self.csr_data_width = csr_data_width self.csr_address_width = csr_address_width + self.csr_expose = csr_expose + if csr_expose: + self.csr = csr_bus.Interface(csr_data_width, csr_address_width) self._memory_regions = [] # list of (name, origin, length) self._csr_regions = [] # list of (name, origin, busword, csr_list/Memory) @@ -286,8 +289,12 @@ class SoCCore(Module): self.submodules.csrbankarray = csr_bus.CSRBankArray(self, self.get_csr_dev_address, data_width=self.csr_data_width, address_width=self.csr_address_width) - self.submodules.csrcon = csr_bus.Interconnect( - self.wishbone2csr.csr, self.csrbankarray.get_buses()) + if self.csr_expose: + self.submodules.csrcon = csr_bus.InterconnectShared( + [self.csr, self.wishbone2csr.csr], self.csrbankarray.get_buses()) + else: + self.submodules.csrcon = csr_bus.Interconnect( + self.wishbone2csr.csr, self.csrbankarray.get_buses()) for name, csrs, mapaddr, rmap in self.csrbankarray.banks: self.add_csr_region(name, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, csrs) for name, memory, mapaddr, mmap in self.csrbankarray.srams: diff --git a/litex/soc/interconnect/csr_bus.py b/litex/soc/interconnect/csr_bus.py index 74a84b448..56d66d032 100644 --- a/litex/soc/interconnect/csr_bus.py +++ b/litex/soc/interconnect/csr_bus.py @@ -6,6 +6,9 @@ The CSR-2 bus is a low-bandwidth, resource-sensitive bus designed for accessing the configuration and status registers of cores from software. """ +from functools import reduce +from operator import or_ + from migen import * from migen.genlib.record import * from migen.genlib.misc import chooser @@ -52,6 +55,19 @@ class Interconnect(Module): self.comb += master.connect(*slaves) +class InterconnectShared(Module): + def __init__(self, masters, slaves): + intermediate = Interface.like(masters[0]) + self.comb += [ + intermediate.adr.eq(reduce(or_, [masters[i].adr for i in range(len(masters))])), + intermediate.we.eq(reduce(or_, [masters[i].we for i in range(len(masters))])), + intermediate.dat_w.eq(reduce(or_, [masters[i].dat_w for i in range(len(masters))])) + ] + for i in range(len(masters)): + self.comb += masters[i].dat_r.eq(intermediate.dat_r) + self.comb += intermediate.connect(*slaves) + + class SRAM(Module): def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None): if bus is None: