From: Gabriel Somlo Date: Wed, 30 Oct 2019 14:37:17 +0000 (-0400) Subject: cpu/rocket, soc_sdram: Connect mem_axi to LiteDRAM, bypass WB bus X-Git-Tag: 24jan2021_ls180~881^2~2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec831f5b631771c660109d2ae8ed9f1b67fc094f;p=litex.git cpu/rocket, soc_sdram: Connect mem_axi to LiteDRAM, bypass WB bus Connect Rocket's dedicated port for cached RAM accesses (mem_axi) directly to the LiteDRAM data port, bypassing the shared LiteX (Wishbone) bus. When both Rocket's mem_axi and LiteDRAM's port have the same data width, use a native point-to-point AXI connection. Otherwise, convert both ends to Wishbone, and use the Wishbone data width converter to bridge the gap. FIXME: In the future, this part should be replaced with a native AXI data width converter! Signed-off-by: Gabriel Somlo --- diff --git a/litex/soc/cores/cpu/rocket/core.py b/litex/soc/cores/cpu/rocket/core.py index 2fa220a9..a7fe578a 100644 --- a/litex/soc/cores/cpu/rocket/core.py +++ b/litex/soc/cores/cpu/rocket/core.py @@ -88,10 +88,9 @@ class RocketRV64(CPU): self.mem_axi = mem_axi = axi.AXIInterface(data_width=64, address_width=32, id_width=4) self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=64, address_width=32, id_width=4) - self.mem_wb = mem_wb = wishbone.Interface(data_width=64, adr_width=29) self.mmio_wb = mmio_wb = wishbone.Interface(data_width=64, adr_width=29) - self.buses = [mem_wb, mmio_wb] + self.buses = [mmio_wb] # # # @@ -207,14 +206,11 @@ class RocketRV64(CPU): ) # adapt axi interfaces to wishbone - mem_a2w = ResetInserter()(axi.AXI2Wishbone(mem_axi, mem_wb, base_address=0)) - mmio_a2w = ResetInserter()(axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0)) # NOTE: AXI2Wishbone FSMs must be reset with the CPU! - self.comb += [ - mem_a2w.reset.eq( ResetSignal() | self.reset), - mmio_a2w.reset.eq(ResetSignal() | self.reset), - ] - self.submodules += mem_a2w, mmio_a2w + mmio_a2w = ResetInserter()(axi.AXI2Wishbone(mmio_axi, mmio_wb, + base_address=0)) + self.comb += mmio_a2w.reset.eq(ResetSignal() | self.reset) + self.submodules += mmio_a2w # add verilog sources self.add_sources(platform, variant) diff --git a/litex/soc/integration/soc_sdram.py b/litex/soc/integration/soc_sdram.py index b373c834..f16e596a 100644 --- a/litex/soc/integration/soc_sdram.py +++ b/litex/soc/integration/soc_sdram.py @@ -11,6 +11,7 @@ from litex.soc.interconnect import wishbone from litex.soc.integration.soc_core import * from litedram.frontend.wishbone import * +from litedram.frontend.axi import * from litedram.core import LiteDRAMCore __all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"] @@ -52,18 +53,39 @@ class SoCSDRAM(SoCCore): clk_freq = self.clk_freq, **kwargs) - # SoC <--> L2 Cache <--> LiteDRAM ---------------------------------------------------------- - if self.with_wishbone: - # LiteDRAM port ------------------------------------------------------------------------ - port = self.sdram.crossbar.get_port() - port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2 - - # Parameters --------------------------------------------------------------------------- - main_ram_size = 2**(geom_settings.bankbits + - geom_settings.rowbits + - geom_settings.colbits)*phy.settings.databits//8 - main_ram_size = min(main_ram_size, 0x20000000) # FIXME: limit to 512MB for now - + # LiteDRAM port ------------------------------------------------------------------------ + port = self.sdram.crossbar.get_port() + port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2 + + # Main RAM size ------------------------------------------------------------------------ + main_ram_size = 2**(geom_settings.bankbits + + geom_settings.rowbits + + geom_settings.colbits)*phy.settings.databits//8 + main_ram_size = min(main_ram_size, 0x20000000) # FIXME: limit to 512MB for now + + # SoC [<--> L2 Cache] <--> LiteDRAM ---------------------------------------------------- + if self.cpu.name == "rocket": + # Rocket has its own I/D L1 cache: connect directly to LiteDRAM, also bypassing MMIO/CSR wb bus: + if port.data_width == self.cpu.mem_axi.data_width: + # straightforward AXI link, no data_width conversion needed: + self.submodules += LiteDRAMAXI2Native(self.cpu.mem_axi, port, + base_address=self.mem_map["main_ram"]) + else: + # FIXME: replace WB data-width converter with native AXI converter!!! + mem_wb = wishbone.Interface(data_width=self.cpu.mem_axi.data_width, + adr_width=32-log2_int(self.cpu.mem_axi.data_width//8)) + # NOTE: AXI2Wishbone FSMs must be reset with the CPU! + mem_a2w = ResetInserter()(AXI2Wishbone(self.cpu.mem_axi, mem_wb, base_address=0)) + self.comb += mem_a2w.reset.eq(ResetSignal() | self.cpu.reset) + self.submodules += mem_a2w + litedram_wb = wishbone.Interface(port.data_width) + self.submodules += LiteDRAMWishbone2Native(litedram_wb, port, + base_address=self.mem_map["main_ram"]) + self.submodules += wishbone.Converter(mem_wb, litedram_wb) + # Register main_ram region (so it will be added to generated/mem.h): + self.add_memory_region("main_ram", self.mem_map["main_ram"], main_ram_size) + elif self.with_wishbone: + # Insert L2 cache inbetween Wishbone bus and LiteDRAM l2_size = max(self.l2_size, int(2*port.data_width/8)) # L2 has a minimal size, use it if lower l2_size = 2**int(log2(l2_size)) # Round to nearest power of 2