mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
soc/cpu: add memory_buses to cpus and use them in add_sdram.
This allows the CPU to have direct buses to the memory and replace the Rocket specific code.
This commit is contained in:
parent
467fee3e23
commit
5ef869b9eb
11 changed files with 81 additions and 43 deletions
|
@ -26,6 +26,8 @@ class CPUNone(CPU):
|
|||
data_width = 32
|
||||
reset_address = 0x00000000
|
||||
io_regions = {0x00000000: 0x100000000} # origin, length
|
||||
periph_buses = []
|
||||
memory_buses = []
|
||||
|
||||
# CPUS ---------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ class BlackParrotRV64(CPU):
|
|||
self.interrupt = Signal(4)
|
||||
self.idbus = idbus = wishbone.Interface(data_width=64, adr_width=37)
|
||||
self.periph_buses = [idbus]
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class LM32(CPU):
|
|||
self.dbus = d = wishbone.Interface()
|
||||
self.interrupt = Signal(32)
|
||||
self.periph_buses = [i, d]
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ class Microwatt(CPU):
|
|||
self.wb_insn = wb_insn = wishbone.Interface(data_width=64, adr_width=28)
|
||||
self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=28)
|
||||
self.periph_buses = [wb_insn, wb_data]
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -34,10 +34,11 @@ class Minerva(CPU):
|
|||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(32)
|
||||
self.ibus = wishbone.Interface()
|
||||
self.dbus = wishbone.Interface()
|
||||
self.periph_buses = [self.ibus, self.dbus]
|
||||
self.interrupt = Signal(32)
|
||||
self.memory_buses = []
|
||||
|
||||
# TODO: create variants
|
||||
self.with_icache = False
|
||||
|
|
|
@ -66,10 +66,12 @@ class MOR1KX(CPU):
|
|||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(32)
|
||||
self.ibus = i = wishbone.Interface()
|
||||
self.dbus = d = wishbone.Interface()
|
||||
self.periph_buses = [i, d]
|
||||
self.interrupt = Signal(32)
|
||||
self.memory_buses = []
|
||||
|
||||
|
||||
if variant == "linux":
|
||||
self.mem_map = self.mem_map_linux
|
||||
|
|
|
@ -58,11 +58,12 @@ class PicoRV32(CPU):
|
|||
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.trap = Signal()
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(32)
|
||||
self.idbus = idbus = wishbone.Interface()
|
||||
self.periph_buses = [idbus]
|
||||
self.interrupt = Signal(32)
|
||||
self.trap = Signal()
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ class RocketRV64(CPU):
|
|||
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8))
|
||||
|
||||
self.periph_buses = [mmio_wb]
|
||||
self.memory_buses = [mem_axi]
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class SERV(CPU):
|
|||
self.ibus = ibus = wishbone.Interface()
|
||||
self.dbus = dbus = wishbone.Interface()
|
||||
self.periph_buses = [ibus, dbus]
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
|
|
|
@ -103,10 +103,13 @@ class VexRiscv(CPU, AutoCSR):
|
|||
self.variant = variant
|
||||
self.external_variant = None
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(32)
|
||||
self.ibus = ibus = wishbone.Interface()
|
||||
self.dbus = dbus = wishbone.Interface()
|
||||
self.periph_buses = [ibus, dbus]
|
||||
self.interrupt = Signal(32)
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
|
||||
self.cpu_params = dict(
|
||||
i_clk = ClockSignal(),
|
||||
|
|
|
@ -991,6 +991,7 @@ class LiteXSoC(SoC):
|
|||
**kwargs):
|
||||
|
||||
# Imports
|
||||
from litedram.common import LiteDRAMNativePort
|
||||
from litedram.core import LiteDRAMCore
|
||||
from litedram.frontend.wishbone import LiteDRAMWishbone2Native
|
||||
from litedram.frontend.axi import LiteDRAMAXI2Native
|
||||
|
@ -1004,27 +1005,34 @@ class LiteXSoC(SoC):
|
|||
**kwargs)
|
||||
self.csr.add("sdram")
|
||||
|
||||
# LiteDRAM port
|
||||
port = self.sdram.crossbar.get_port()
|
||||
port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2
|
||||
|
||||
# SDRAM size
|
||||
# Compute/Check SDRAM size
|
||||
sdram_size = 2**(module.geom_settings.bankbits +
|
||||
module.geom_settings.rowbits +
|
||||
module.geom_settings.colbits)*phy.settings.databits//8
|
||||
if size is not None:
|
||||
sdram_size = min(sdram_size, size)
|
||||
|
||||
# Add SDRAM region
|
||||
self.bus.add_region("main_ram", SoCRegion(origin=origin, size=sdram_size))
|
||||
|
||||
# SoC [<--> L2 Cache] <--> LiteDRAM --------------------------------------------------------
|
||||
if self.cpu.name == "rocket":
|
||||
# Rocket has its own I/D L1 cache: connect directly to LiteDRAM when possible.
|
||||
if port.data_width == self.cpu.mem_axi.data_width:
|
||||
if len(self.cpu.memory_buses):
|
||||
# When CPU has at least a direct memory bus, connect them directly to LiteDRAM.
|
||||
for mem_bus in self.cpu.memory_buses:
|
||||
# Request a LiteDRAM native port.
|
||||
port = self.sdram.crossbar.get_port()
|
||||
port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2.
|
||||
|
||||
# Check if bus is an AXI bus and connect it.
|
||||
if isinstance(mem_bus, axi.AXIInterface):
|
||||
# If same data_width, connect it directly.
|
||||
if port.data_width == mem_bus.data_width:
|
||||
self.logger.info("Matching AXI MEM data width ({})\n".format(port.data_width))
|
||||
self.submodules += LiteDRAMAXI2Native(
|
||||
axi = self.cpu.mem_axi,
|
||||
port = port,
|
||||
base_address = self.bus.regions["main_ram"].origin)
|
||||
# If different data_width, do the adaptation and connect it via Wishbone.
|
||||
else:
|
||||
self.logger.info("Converting MEM data width: {} to {} via Wishbone".format(
|
||||
port.data_width,
|
||||
|
@ -1046,8 +1054,24 @@ class LiteXSoC(SoC):
|
|||
port = port,
|
||||
base_address = origin)
|
||||
self.submodules += wishbone.Converter(mem_wb, litedram_wb)
|
||||
elif self.with_wishbone:
|
||||
# Wishbone Slave SDRAM interface
|
||||
# Check if bus is a Native bus and connect it.
|
||||
if isinstance(mem_bus, LiteDRAMNativePort):
|
||||
# If same data_width, connect it directly.
|
||||
if port.data_width == mem_bus.data_width:
|
||||
self.comb += mem_bus.cmd.connect(port.cmd)
|
||||
self.comb += mem_bus.wdata.connect(port.wdata)
|
||||
self.comb += port.rdata.connect(mem_bus.rdata)
|
||||
# Else raise Error.
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
# When CPU has no direct memory interface, create a Wishbone Slave interface to LiteDRAM.
|
||||
|
||||
# Request a LiteDRAM native port.
|
||||
port = self.sdram.crossbar.get_port()
|
||||
port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2.
|
||||
|
||||
# Create Wishbone Slave.
|
||||
wb_sdram = wishbone.Interface()
|
||||
self.bus.add_slave("main_ram", wb_sdram)
|
||||
|
||||
|
|
Loading…
Reference in a new issue