Merge pull request #300 from gsomlo/gls-rocket-axi
RFC: Direct link between Rocket/mem_axi <--> LiteDRAM dataport
This commit is contained in:
commit
2da421f64e
|
@ -50,6 +50,13 @@ GCC_FLAGS = {
|
||||||
"full": "-march=rv64imafdc -mabi=lp64 ",
|
"full": "-march=rv64imafdc -mabi=lp64 ",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AXI_DATA_WIDTHS = {
|
||||||
|
# variant : (mem, mmio)
|
||||||
|
"standard": ( 64, 64),
|
||||||
|
"linux": ( 64, 64),
|
||||||
|
"full": ( 64, 64),
|
||||||
|
}
|
||||||
|
|
||||||
class RocketRV64(CPU):
|
class RocketRV64(CPU):
|
||||||
name = "rocket"
|
name = "rocket"
|
||||||
data_width = 64
|
data_width = 64
|
||||||
|
@ -85,13 +92,14 @@ class RocketRV64(CPU):
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
self.interrupt = Signal(4)
|
self.interrupt = Signal(4)
|
||||||
|
|
||||||
self.mem_axi = mem_axi = axi.AXIInterface(data_width=64, address_width=32, id_width=4)
|
mem_dw, mmio_dw = AXI_DATA_WIDTHS[self.variant]
|
||||||
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.mem_axi = mem_axi = axi.AXIInterface(data_width= mem_dw, address_width=32, id_width=4)
|
||||||
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=64, adr_width=29)
|
self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
|
||||||
|
|
||||||
self.buses = [mem_wb, mmio_wb]
|
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8))
|
||||||
|
|
||||||
|
self.buses = [mmio_wb]
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
@ -207,14 +215,11 @@ class RocketRV64(CPU):
|
||||||
)
|
)
|
||||||
|
|
||||||
# adapt axi interfaces to wishbone
|
# 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!
|
# NOTE: AXI2Wishbone FSMs must be reset with the CPU!
|
||||||
self.comb += [
|
mmio_a2w = ResetInserter()(axi.AXI2Wishbone(mmio_axi, mmio_wb,
|
||||||
mem_a2w.reset.eq( ResetSignal() | self.reset),
|
base_address=0))
|
||||||
mmio_a2w.reset.eq(ResetSignal() | self.reset),
|
self.comb += mmio_a2w.reset.eq(ResetSignal() | self.reset)
|
||||||
]
|
self.submodules += mmio_a2w
|
||||||
self.submodules += mem_a2w, mmio_a2w
|
|
||||||
|
|
||||||
# add verilog sources
|
# add verilog sources
|
||||||
self.add_sources(platform, variant)
|
self.add_sources(platform, variant)
|
||||||
|
|
|
@ -11,6 +11,7 @@ from litex.soc.interconnect import wishbone
|
||||||
from litex.soc.integration.soc_core import *
|
from litex.soc.integration.soc_core import *
|
||||||
|
|
||||||
from litedram.frontend.wishbone import *
|
from litedram.frontend.wishbone import *
|
||||||
|
from litedram.frontend.axi import *
|
||||||
from litedram.core import LiteDRAMCore
|
from litedram.core import LiteDRAMCore
|
||||||
|
|
||||||
__all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"]
|
__all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"]
|
||||||
|
@ -52,18 +53,38 @@ class SoCSDRAM(SoCCore):
|
||||||
clk_freq = self.clk_freq,
|
clk_freq = self.clk_freq,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
# SoC <--> L2 Cache <--> LiteDRAM ----------------------------------------------------------
|
# LiteDRAM port ------------------------------------------------------------------------
|
||||||
if self.with_wishbone:
|
port = self.sdram.crossbar.get_port()
|
||||||
# LiteDRAM port ------------------------------------------------------------------------
|
port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2
|
||||||
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 ------------------------------------------------------------------------
|
||||||
main_ram_size = 2**(geom_settings.bankbits +
|
main_ram_size = 2**(geom_settings.bankbits +
|
||||||
geom_settings.rowbits +
|
geom_settings.rowbits +
|
||||||
geom_settings.colbits)*phy.settings.databits//8
|
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 = 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
|
l2_size = 2**int(log2(l2_size)) # Round to nearest power of 2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue