Merge pull request #1817 from enjoy-digital/wishbone_word_byte_addressing

Add wishbone word/byte addressing.
This commit is contained in:
enjoy-digital 2023-10-27 10:12:28 +02:00 committed by GitHub
commit cd3265b16c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 193 additions and 105 deletions

View File

@ -91,7 +91,7 @@ class BlackParrot(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.idbus = idbus = wishbone.Interface(data_width=64, adr_width=37)
self.idbus = idbus = wishbone.Interface(data_width=64, adr_width=37, addressing="word")
self.periph_buses = [idbus]
self.memory_buses = []

View File

@ -64,7 +64,7 @@ class CortexM1(CPU):
self.cpu_params = dict(
# Clk/Rst.
i_HCLK = ClockSignal("sys"),
i_SYSRESETn = ~(ResetSignal() | self.reset),
i_SYSRESETn = ~(ResetSignal("sys") | self.reset),
# Control/Status.
o_LOCKUP = Open(),
@ -85,7 +85,7 @@ class CortexM1(CPU):
# Debug.
p_SMALL_DEBUG = True,
i_DBGRESTART = 0,
i_DBGRESETn = ~(ResetSignal() | self.reset),
i_DBGRESETn = ~(ResetSignal("sys") | self.reset),
p_DEBUG_SEL = 1, # JTAG
o_DBGRESTARTED = Open(),

View File

@ -65,7 +65,7 @@ class CortexM3(CPU):
self.cpu_params = dict(
# Clk/Rst.
i_HCLK = ClockSignal("sys"),
i_SYSRESETn = ~(ResetSignal() | self.reset),
i_SYSRESETn = ~(ResetSignal("sys") | self.reset),
# Control/Status.
p_MPU_PRESENT = 0,
@ -82,7 +82,7 @@ class CortexM3(CPU):
i_CFGITCMEN = 0, # 1 = alias ITCM at 0x0
# Debug.
i_DBGRESETn = ~(ResetSignal() | self.reset),
i_DBGRESETn = ~(ResetSignal("sys") | self.reset),
# Instruction Bus (AXI).
o_AWVALIDC = ibus.aw.valid,

View File

@ -232,7 +232,7 @@ class TraceCollector(LiteXModule):
class TraceDebugger(LiteXModule):
def __init__(self):
self.bus = wishbone.Interface()
self.bus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.source = source = stream.Endpoint([("data", 32)])
self.trace_if = trace_if = Record(trace_layout)
@ -292,8 +292,8 @@ class DebugModule(LiteXModule):
if pads is None:
pads = Record(self.jtag_layout)
self.pads = pads
self.dmbus = wishbone.Interface()
self.sbbus = wishbone.Interface()
self.dmbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.sbbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
dmbus = Record(obi_layout)
sbbus = Record(obi_layout)
@ -382,8 +382,8 @@ class CV32E40P(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = wishbone.Interface()
self.dbus = wishbone.Interface()
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses = [self.ibus, self.dbus]
self.memory_buses = []
self.interrupt = Signal(15)
@ -458,7 +458,7 @@ class CV32E40P(CPU):
def add_debug_module(self, dm):
self.cpu_params.update(i_debug_req_i=dm.debug_req)
self.cpu_params.update(i_rst_ni=~(ResetSignal() | dm.ndmreset))
self.cpu_params.update(i_rst_ni=~(ResetSignal("sys") | dm.ndmreset))
def add_trace_core(self, trace):
trace_if = trace.trace_if

View File

@ -183,8 +183,8 @@ class DebugModule(Module):
if pads is None:
pads = Record(self.jtag_layout)
self.pads = pads
self.dmbus = wishbone.Interface()
self.sbbus = wishbone.Interface()
self.dmbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.sbbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
dmbus = Record(obi_layout)
sbbus = Record(obi_layout)
@ -267,8 +267,8 @@ class CV32E41P(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = wishbone.Interface()
self.dbus = wishbone.Interface()
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses = [self.ibus, self.dbus]
self.memory_buses = []
self.interrupt = Signal(16)
@ -321,7 +321,7 @@ class CV32E41P(CPU):
i_apu_rvalid_i = 0,
# IRQ.
i_irq_i = Cat(self.interrupt_padding,self.interrupt),
i_irq_i = Cat(self.interrupt_padding, self.interrupt),
# Debug.
i_debug_req_i = 0,
@ -335,7 +335,7 @@ class CV32E41P(CPU):
def add_debug_module(self, dm):
self.cpu_params.update(i_debug_req_i=dm.debug_req)
self.cpu_params.update(i_rst_ni=~(ResetSignal() | dm.ndmreset))
self.cpu_params.update(i_rst_ni=~(ResetSignal("sys") | dm.ndmreset))
def set_reset_address(self, reset_address):
self.reset_address = reset_address

View File

@ -85,8 +85,8 @@ class CVA5(CPU):
if variant == "minimal":
# Minimal variant has no caches, no multiply or divide support, and no branch predictor.
# It also uses separate fetch and load-store wishbone interfaces.
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses.append(ibus)
self.periph_buses.append(dbus)
self.cpu_params.update(
@ -117,7 +117,7 @@ class CVA5(CPU):
if variant == "standard":
# Standard variant includes instruction and data caches, multiply and divide support
# along with the branch predictor. It uses a shared wishbone interface.
self.idbus = idbus = wishbone.Interface()
self.idbus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses.append(idbus)
self.cpu_params.update(
o_idbus_adr = idbus.adr,

View File

@ -47,7 +47,7 @@ class EOS_S3(CPU):
self.platform = platform
self.reset = Signal()
self.interrupt = Signal(4)
self.pbus = wishbone.Interface(data_width=32, adr_width=15)
self.pbus = wishbone.Interface(data_width=32, adr_width=15, addressing="byte")
self.periph_buses = [self.pbus]
self.memory_buses = []
@ -84,7 +84,7 @@ class EOS_S3(CPU):
# -----------
i_WB_CLK = ClockSignal("eos_s3_0"),
o_WB_RST = pbus_rst,
o_WBs_ADR = Cat(Signal(2), self.pbus.adr),
o_WBs_ADR = self.pbus.adr,
o_WBs_CYC = self.pbus.cyc,
o_WBs_BYTE_STB = self.pbus.sel,
o_WBs_WE = self.pbus.we,

View File

@ -71,7 +71,7 @@ class FemtoRV(CPU):
self.variant = variant
self.human_name = f"FemtoRV-{variant.upper()}"
self.reset = Signal()
self.idbus = idbus = wishbone.Interface()
self.idbus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -119,7 +119,7 @@ class FemtoRV(CPU):
self.fsm = fsm = FSM(reset_state="WAIT")
fsm.act("WAIT",
# Latch Address + Bytes to Words conversion.
NextValue(idbus.adr, mbus.addr[2:]),
NextValue(idbus.adr, mbus.addr),
# Latch Wdata/WMask.
NextValue(idbus.dat_w, mbus.wdata),

View File

@ -59,7 +59,7 @@ class FireV(CPU):
self.variant = variant
self.human_name = f"FireV-{variant.upper()}"
self.reset = Signal()
self.idbus = idbus = wishbone.Interface()
self.idbus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -115,7 +115,7 @@ class FireV(CPU):
)
self.comb += [
idbus.we.eq(mbus.out_ram_rw),
idbus.adr.eq(mbus.out_ram_addr[2:]),
idbus.adr.eq(mbus.out_ram_addr),
idbus.sel.eq(mbus.out_ram_wmask),
idbus.dat_w.eq(mbus.out_ram_data_in),

View File

@ -168,7 +168,7 @@ class GowinEMCU(CPU):
# Extension AHB -> Wishbone CSR via bridge
self.pbus = wishbone.Interface(data_width=32, adr_width=30)
self.pbus = wishbone.Interface(data_width=32, adr_width=30, addressing="word")
self.periph_buses = [self.pbus]
ahb_targexp0 = ahb.Interface()
for s, _ in ahb_targexp0.master_signals:

View File

@ -57,7 +57,7 @@ class OBI2Wishbone(Module):
# On OBI request:
If(obi.req,
# Drive Wishbone bus from OBI bus.
wb.adr.eq(obi.addr[2:32]),
wb.adr.eq( obi.addr),
wb.stb.eq( 1),
wb.dat_w.eq( obi.wdata),
wb.cyc.eq( 1),
@ -77,7 +77,7 @@ class OBI2Wishbone(Module):
)
fsm.act("ACK",
# Drive Wishbone bus from stored OBI bus values.
wb.adr.eq(addr[2:32]),
wb.adr.eq( addr),
wb.stb.eq( 1),
wb.dat_w.eq( wdata),
wb.cyc.eq( 1),
@ -121,8 +121,8 @@ class Ibex(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = wishbone.Interface()
self.dbus = wishbone.Interface()
self.ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [self.ibus, self.dbus]
self.memory_buses = []
self.interrupt = Signal(15)

View File

@ -51,8 +51,8 @@ class LM32(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.interrupt = Signal(32)
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -68,7 +68,7 @@ class LM32(CPU):
i_interrupt=self.interrupt,
# IBus.
o_I_ADR_O = Cat(Signal(2), ibus.adr),
o_I_ADR_O = ibus.adr,
o_I_DAT_O = ibus.dat_w,
o_I_SEL_O = ibus.sel,
o_I_CYC_O = ibus.cyc,
@ -82,7 +82,7 @@ class LM32(CPU):
i_I_RTY_I = 0,
# DBus.
o_D_ADR_O = Cat(Signal(2), dbus.adr),
o_D_ADR_O = dbus.adr,
o_D_DAT_O = dbus.dat_w,
o_D_SEL_O = dbus.sel,
o_D_CYC_O = dbus.cyc,

View File

@ -84,8 +84,8 @@ class Marocchino(CPU):
self.variant = variant
self.reset = Signal()
self.interrupt = Signal(32)
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -117,13 +117,13 @@ class Marocchino(CPU):
**cpu_args,
# Clk / Rst.
i_wb_clk = ClockSignal("sys"),
i_wb_rst = ResetSignal("sys") | self.reset,
i_wb_clk = ClockSignal("sys"),
i_wb_rst = ResetSignal("sys") | self.reset,
i_cpu_clk = ClockSignal("sys"),
i_cpu_rst = ResetSignal("sys") | self.reset,
# IBus.
o_iwbm_adr_o = Cat(Signal(2), ibus.adr),
o_iwbm_adr_o = ibus.adr,
o_iwbm_stb_o = ibus.stb,
o_iwbm_cyc_o = ibus.cyc,
o_iwbm_sel_o = ibus.sel,
@ -137,7 +137,7 @@ class Marocchino(CPU):
i_iwbm_rty_i = 0,
# DBus.
o_dwbm_adr_o = Cat(Signal(2), dbus.adr),
o_dwbm_adr_o = dbus.adr,
o_dwbm_stb_o = dbus.stb,
o_dwbm_cyc_o = dbus.cyc,
o_dwbm_sel_o = dbus.sel,

View File

@ -71,8 +71,8 @@ class Microwatt(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = ibus = wishbone.Interface(data_width=64, adr_width=29)
self.dbus = dbus = wishbone.Interface(data_width=64, adr_width=29)
self.ibus = ibus = wishbone.Interface(data_width=64, adr_width=29, addressing="word")
self.dbus = dbus = wishbone.Interface(data_width=64, adr_width=29, addressing="word")
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
if "irq" in variant:
@ -240,8 +240,8 @@ class XICSSlave(Module, AutoCSR):
def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), variant="standard"):
self.variant = variant
self.icp_bus = icp_bus = wishbone.Interface(data_width=32, adr_width=12)
self.ics_bus = ics_bus = wishbone.Interface(data_width=32, adr_width=12)
self.icp_bus = icp_bus = wishbone.Interface(data_width=32, adr_width=12, addressing="word")
self.ics_bus = ics_bus = wishbone.Interface(data_width=32, adr_width=12, addressing="word")
# XICS Signals.
self.ics_icp_xfer_src = Signal(4)

View File

@ -48,8 +48,8 @@ class Minerva(CPU):
self.variant = variant
self.reset = Signal()
self.interrupt = Signal(32)
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses = [self.ibus, self.dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).

View File

@ -84,8 +84,8 @@ class MOR1KX(CPU):
self.variant = variant
self.reset = Signal()
self.interrupt = Signal(32)
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -160,7 +160,7 @@ class MOR1KX(CPU):
i_irq_i=self.interrupt,
# IBus.
o_iwbm_adr_o = Cat(Signal(2), ibus.adr),
o_iwbm_adr_o = ibus.adr,
o_iwbm_dat_o = ibus.dat_w,
o_iwbm_sel_o = ibus.sel,
o_iwbm_cyc_o = ibus.cyc,
@ -174,7 +174,7 @@ class MOR1KX(CPU):
i_iwbm_rty_i = 0,
# DBus.
o_dwbm_adr_o = Cat(Signal(2), dbus.adr),
o_dwbm_adr_o = dbus.adr,
o_dwbm_dat_o = dbus.dat_w,
o_dwbm_sel_o = dbus.sel,
o_dwbm_cyc_o = dbus.cyc,

View File

@ -75,7 +75,7 @@ class NEORV32(CPU):
self.variant = variant
self.human_name = f"NEORV32-{variant}"
self.reset = Signal()
self.ibus = idbus = wishbone.Interface()
self.ibus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -98,7 +98,7 @@ class NEORV32(CPU):
i_mext_irq_i = 0,
# I/D Wishbone Bus.
o_wb_adr_o = Cat(Signal(2), idbus.adr),
o_wb_adr_o = idbus.adr,
i_wb_dat_i = idbus.dat_r,
o_wb_dat_o = idbus.dat_w,
o_wb_we_o = idbus.we,

View File

@ -117,8 +117,11 @@ class OpenC906(CPU):
# Peripheral bus (Connected to main SoC's bus).
self.axi_if = axi_if = axi.AXIInterface(data_width=128, address_width=40, id_width=8)
if convert_periph_bus_to_wishbone:
self.wb_if = wishbone.Interface(data_width=axi_if.data_width,
adr_width=axi_if.address_width - log2_int(axi_if.data_width // 8))
self.wb_if = wishbone.Interface(
data_width = axi_if.data_width,
adr_width = axi_if.address_width - log2_int(axi_if.data_width // 8),
addressing = "word",
)
self.submodules += axi.AXI2Wishbone(axi_if, self.wb_if)
self.periph_buses = [self.wb_if]
else:
@ -206,7 +209,7 @@ class OpenC906(CPU):
add_manifest_sources(platform, "gen_rtl/filelists/generic_fpga.fl")
def add_debug(self):
self.debug_bus = wishbone.Interface()
self.debug_bus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
debug_apb = Record(apb_layout)
self.submodules += Wishbone2APB(self.debug_bus, debug_apb)

View File

@ -74,7 +74,7 @@ class PicoRV32(CPU):
self.trap = Signal()
self.reset = Signal()
self.interrupt = Signal(32)
self.idbus = idbus = wishbone.Interface()
self.idbus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -166,7 +166,7 @@ class PicoRV32(CPU):
# Adapt Memory Interface to Wishbone.
self.comb += [
idbus.adr.eq(mem_addr[2:]),
idbus.adr.eq(mem_addr),
idbus.dat_w.eq(mem_wdata),
idbus.we.eq(mem_wstrb != 0),
idbus.sel.eq(mem_wstrb),

View File

@ -130,8 +130,8 @@ class Rocket(CPU):
self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
self.l2fb_axi = l2fb_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8))
self.l2fb_wb = l2fb_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8))
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8), addressing="word")
self.l2fb_wb = l2fb_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8), addressing="word")
self.memory_buses = [mem_axi] # Peripheral buses (Connected to main SoC's bus).
self.periph_buses = [mmio_wb] # Memory buses (Connected directly to LiteDRAM).

View File

@ -59,8 +59,8 @@ class SERV(CPU):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -68,20 +68,20 @@ class SERV(CPU):
self.cpu_params = dict(
# Clk / Rst
i_clk = ClockSignal(),
i_i_rst = ResetSignal() | self.reset,
i_clk = ClockSignal("sys"),
i_i_rst = ResetSignal("sys") | self.reset,
# Timer IRQ.
i_i_timer_irq = 0,
# Ibus.
o_o_ibus_adr = Cat(Signal(2), ibus.adr),
o_o_ibus_adr = ibus.adr,
o_o_ibus_cyc = ibus.cyc,
i_i_ibus_rdt = ibus.dat_r,
i_i_ibus_ack = ibus.ack,
# Dbus.
o_o_dbus_adr = Cat(Signal(2), dbus.adr),
o_o_dbus_adr = dbus.adr,
o_o_dbus_dat = dbus.dat_w,
o_o_dbus_sel = dbus.sel,
o_o_dbus_we = dbus.we,

View File

@ -140,8 +140,8 @@ class VexRiscv(CPU, AutoCSR):
self.external_variant = None
self.reset = Signal()
self.interrupt = Signal(32)
self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()
self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -217,7 +217,7 @@ class VexRiscv(CPU, AutoCSR):
self.transfer_in_progress = Signal()
self.transfer_wait_for_ack = Signal()
self.debug_bus = wishbone.Interface()
self.debug_bus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.sync += self.debug_bus.dat_r.eq(self.o_rsp_data)
self.sync += debug_reset.eq(reset_debug_logic | ResetSignal())
@ -268,10 +268,10 @@ class VexRiscv(CPU, AutoCSR):
]
self.cpu_params.update(
i_reset = ResetSignal() | self.reset | debug_reset,
i_reset = ResetSignal("sys") | self.reset | debug_reset,
i_iBusWishbone_ERR = self.ibus.err | ibus_err,
i_dBusWishbone_ERR = self.dbus.err | dbus_err,
i_debugReset = ResetSignal(),
i_debugReset = ResetSignal("sys"),
i_debug_bus_cmd_valid = self.i_cmd_valid,
i_debug_bus_cmd_payload_wr = self.i_cmd_payload_wr,
i_debug_bus_cmd_payload_address = self.i_cmd_payload_address,

View File

@ -312,7 +312,7 @@ class VexRiscvSMP(CPU):
False : 32,
# Else max of I/DCache-width.
True : max(VexRiscvSMP.icache_width, VexRiscvSMP.dcache_width),
}[VexRiscvSMP.wishbone_memory and not VexRiscvSMP.wishbone_force_32b])
}[VexRiscvSMP.wishbone_memory and not VexRiscvSMP.wishbone_force_32b], addressing="word")
self.periph_buses = [pbus] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
@ -320,8 +320,8 @@ class VexRiscvSMP(CPU):
self.cpu_params = dict(
# Clk / Rst.
i_debugCd_external_clk = ClockSignal(),
i_debugCd_external_reset = ResetSignal() | self.reset,
i_debugCd_external_clk = ClockSignal("sys"),
i_debugCd_external_reset = ResetSignal("sys") | self.reset,
# Interrupts.
i_interrupts = self.interrupt,
@ -352,7 +352,7 @@ class VexRiscvSMP(CPU):
# DMA.
if VexRiscvSMP.coherent_dma:
self.dma_bus = dma_bus = wishbone.Interface(data_width=VexRiscvSMP.dcache_width, address_width=32)
self.dma_bus = dma_bus = wishbone.Interface(data_width=VexRiscvSMP.dcache_width, address_width=32, addressing="word")
dma_bus_stall = Signal()
dma_bus_inhibit = Signal()
self.cpu_params.update(
@ -462,7 +462,7 @@ class VexRiscvSMP(CPU):
soc.add_config("CPU_ITLB_WAYS", VexRiscvSMP.itlb_size)
# Add PLIC as Bus Slave
self.plicbus = plicbus = wishbone.Interface()
self.plicbus = plicbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.cpu_params.update(
i_plicWishbone_CYC = plicbus.cyc,
i_plicWishbone_STB = plicbus.stb,
@ -475,7 +475,7 @@ class VexRiscvSMP(CPU):
soc.bus.add_slave("plic", self.plicbus, region=SoCRegion(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=False))
# Add CLINT as Bus Slave
self.clintbus = clintbus = wishbone.Interface()
self.clintbus = clintbus = wishbone.Interface(data_width=32, address_width=32, addressing="word")
self.cpu_params.update(
i_clintWishbone_CYC = clintbus.cyc,
i_clintWishbone_STB = clintbus.stb,

View File

@ -151,6 +151,11 @@ class SoCBusHandler(LiteXModule):
self.standard = standard
self.data_width = data_width
self.address_width = address_width
self.addressing = {
"wishbone" : "word", # FIXME: Allow selection for Wishbone.
"axi-lite" : "byte",
"axi" : "byte",
}[standard]
self.bursting = bursting
self.interconnect = interconnect
self.interconnect_register = interconnect_register
@ -329,7 +334,8 @@ class SoCBusHandler(LiteXModule):
}[interface_cls]
adapted_interface = interface_cls(
data_width = self.data_width,
address_width = self.address_width
address_width = self.address_width,
addressing = self.addressing,
)
if direction == "m2s":
master, slave = interface, adapted_interface
@ -353,7 +359,8 @@ class SoCBusHandler(LiteXModule):
else:
adapted_interface = main_bus_cls(
data_width = self.data_width,
address_width = self.address_width
address_width = self.address_width,
addressing = self.addressing,
)
if direction == "m2s":
master, slave = interface, adapted_interface
@ -372,10 +379,35 @@ class SoCBusHandler(LiteXModule):
self.submodules += bridge
return adapted_interface
# Addressing conversion helper.
def addressing_convert(interface, direction):
# Same Addressing, return un-modified interface.
if interface.addressing == self.addressing:
return interface
# Different Addressing: Return adapted interface.
else:
assert interface.addressing == "byte" # FIXME: Remove limitation.
assert self.addressing == "word" # FIXME: Remove limitation.
interface_cls = type(interface)
adapted_interface = interface_cls(
data_width = self.data_width,
address_width = self.address_width,
addressing = self.addressing,
)
address_shift = log2_int(interface.data_width//8)
if direction == "m2s":
self.comb += interface.connect(adapted_interface)
self.comb += adapted_interface.adr.eq(interface.adr[address_shift:])
elif direction == "s2m":
self.comb += adapted_interface.connect(interface)
self.comb += interface.adr.eq(adapted_interface.adr[address_shift:])
return adapted_interface
# Interface conversion.
adapted_interface = interface
adapted_interface = data_width_convert(adapted_interface, direction)
adapted_interface = data_width_convert(adapted_interface, direction)
adapted_interface = bus_standard_convert(adapted_interface, direction)
adapted_interface = addressing_convert(adapted_interface, direction)
if type(interface) != type(adapted_interface) or interface.data_width != adapted_interface.data_width:
fmt = "{name} Bus {adapted} from {from_bus} {from_bits}-bit to {to_bus} {to_bits}-bit."

View File

@ -28,6 +28,7 @@ class Interface(Record):
"""Sets up the AHB interface signals for master and slave."""
adr_width = 32
data_width = 32
addressing = "byte"
master_signals = [
("addr", adr_width),
("burst", 3),
@ -56,22 +57,25 @@ class AHB2Wishbone(LiteXModule):
It takes as input an AHB interface and a Wishbone interface and does the conversion.
"""
def __init__(self, ahb, wishbone):
wishbone_adr_shift = log2_int(ahb.data_width // 8)
# Parameters/Checks.
wishbone_adr_shift = {
"word" : log2_int(ahb.data_width//8),
"byte" : 0
}[wishbone.addressing]
assert ahb.data_width == wishbone.data_width
assert ahb.adr_width == wishbone.adr_width + wishbone_adr_shift
self.comb += ahb.resp.eq(wishbone.err)
assert ahb.adr_width == wishbone.adr_width + wishbone_adr_shift
# FSM.
self.fsm = fsm = FSM()
fsm.act("IDLE",
ahb.readyout.eq(1),
If(ahb.sel &
(ahb.size == wishbone_adr_shift) &
(ahb.trans == TransferType.NONSEQUENTIAL),
NextValue(wishbone.adr, ahb.addr[2:]),
NextValue(wishbone.adr, ahb.addr[wishbone_adr_shift:]),
NextValue(wishbone.dat_w, ahb.wdata),
NextValue(wishbone.we, ahb.write),
NextValue(wishbone.sel, 2**len(wishbone.sel) - 1),
NextValue(wishbone.we, ahb.write),
NextValue(wishbone.sel, 2**len(wishbone.sel) - 1),
NextState("ACT"),
)
)
@ -85,3 +89,5 @@ class AHB2Wishbone(LiteXModule):
NextState("IDLE")
)
)
self.comb += ahb.resp.eq(wishbone.err)

View File

@ -54,7 +54,7 @@ def r_description(data_width):
]
class AXIInterface:
def __init__(self, data_width=32, address_width=32, id_width=1, version="axi4", clock_domain="sys",
def __init__(self, data_width=32, address_width=32, addressing="byte", id_width=1, version="axi4", clock_domain="sys",
name = None,
bursting = False,
aw_user_width = 0,
@ -66,12 +66,14 @@ class AXIInterface:
# Parameters checks.
# ------------------
assert data_width in [8, 16, 32, 64, 128, 256, 512, 1024]
assert addressing in ["byte"]
assert version in ["axi3", "axi4"]
# Parameters.
# -----------
self.data_width = data_width
self.address_width = address_width
self.addressing = addressing
self.id_width = id_width
self.version = version
self.clock_domain = clock_domain

View File

@ -44,13 +44,22 @@ def r_lite_description(data_width):
]
class AXILiteInterface:
def __init__(self, data_width=32, address_width=32, clock_domain="sys", name=None, bursting=False):
self.data_width = data_width
self.address_width = address_width
self.clock_domain = clock_domain
def __init__(self, data_width=32, address_width=32, addressing="byte", clock_domain="sys", name=None, bursting=False):
# Parameters checks.
# ------------------
assert addressing == "byte"
if bursting is not False:
raise NotImplementedError("AXI-Lite does not support bursting")
# Parameters.
# -----------
self.data_width = data_width
self.address_width = address_width
self.addressing = addressing
self.clock_domain = clock_domain
# Channels.
# ---------
self.aw = stream.Endpoint(ax_lite_description(address_width), name=name)
self.w = stream.Endpoint(w_lite_description(data_width), name=name)
self.b = stream.Endpoint(b_lite_description(), name=name)

View File

@ -17,10 +17,15 @@ from litex.soc.interconnect.axi.axi_lite import *
class AXILite2Wishbone(LiteXModule):
def __init__(self, axi_lite, wishbone, base_address=0x00000000):
wishbone_adr_shift = log2_int(axi_lite.data_width//8)
# Parameters/Checks.
wishbone_adr_shift = {
"word" : log2_int(axi_lite.data_width//8),
"byte" : 0
}[wishbone.addressing]
assert axi_lite.data_width == len(wishbone.dat_r)
assert axi_lite.address_width == len(wishbone.adr) + wishbone_adr_shift
# Signals.
_data = Signal(axi_lite.data_width)
_r_addr = Signal(axi_lite.address_width)
_w_addr = Signal(axi_lite.address_width)
@ -28,6 +33,7 @@ class AXILite2Wishbone(LiteXModule):
self.comb += _r_addr.eq(axi_lite.ar.addr - base_address)
self.comb += _w_addr.eq(axi_lite.aw.addr - base_address)
# FSM.
self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
If(axi_lite.ar.valid & axi_lite.aw.valid,
@ -92,15 +98,21 @@ class AXILite2Wishbone(LiteXModule):
class Wishbone2AXILite(LiteXModule):
def __init__(self, wishbone, axi_lite, base_address=0x00000000):
wishbone_adr_shift = log2_int(axi_lite.data_width//8)
# Parameters/Checks.
wishbone_adr_shift = {
"word" : log2_int(axi_lite.data_width//8),
"byte" : 0
}[wishbone.addressing]
assert axi_lite.data_width == len(wishbone.dat_r)
assert axi_lite.address_width == len(wishbone.adr) + wishbone_adr_shift
# Signals.
_cmd_done = Signal()
_data_done = Signal()
_addr = Signal(len(wishbone.adr))
self.comb += _addr.eq(wishbone.adr - base_address//4)
# FSM.
self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
NextValue(_cmd_done, 0),

View File

@ -52,6 +52,7 @@ _layout = [
]
class Interface(Record):
addressing = "word"
def __init__(self, data_width=8, address_width=14, alignment=32):
self.data_width = data_width
self.address_width = address_width

View File

@ -45,18 +45,21 @@ CTI_BURST_END = 0b111
class Interface(Record):
def __init__(self, data_width=32, adr_width=30, bursting=False, **kwargs):
def __init__(self, data_width=32, adr_width=30, bursting=False, addressing="word", **kwargs):
self.data_width = data_width
if kwargs.get("address_width", False):
# FIXME: Improve or switch Wishbone to byte addressing instead of word addressing.
adr_width = kwargs["address_width"] - int(log2(data_width//8))
self.adr_width = adr_width
self.address_width = adr_width + int(log2(data_width//8))
self.address_width = adr_width + int(log2(data_width//8))
self.bursting = bursting
assert addressing in ["word", "byte"]
self.addressing = addressing
Record.__init__(self, set_layout_parameters(_layout,
adr_width = adr_width,
adr_width = adr_width + (int(log2(data_width//8)) if (addressing == "byte") else 0),
data_width = data_width,
sel_width = data_width//8))
sel_width = data_width//8,
))
self.adr.reset_less = True
self.dat_w.reset_less = True
self.dat_r.reset_less = True
@ -272,12 +275,16 @@ class DownConverter(Module):
"""
def __init__(self, master, slave):
# Parameters/Checks.
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
dw_from = len(master.dat_w)
dw_to = len(slave.dat_w)
ratio = dw_from//dw_to
# # #
# Signals.
skip = Signal()
done = Signal()
count = Signal(max=ratio)
@ -332,6 +339,9 @@ class DownConverter(Module):
class UpConverter(Module):
"""UpConverter"""
def __init__(self, master, slave):
# Parameters/Checks.
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
dw_from = len(master.dat_w)
dw_to = len(slave.dat_w)
ratio = dw_to//dw_from
@ -359,17 +369,24 @@ class Converter(Module):
def __init__(self, master, slave):
self.master = master
self.slave = slave
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
assert master.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
# # #
# Signals.
dw_from = len(master.dat_r)
dw_to = len(slave.dat_r)
dw_to = len(slave.dat_r)
# DownConverter.
if dw_from > dw_to:
downconverter = DownConverter(master, slave)
self.submodules += downconverter
# UpConverter.
elif dw_from < dw_to:
upconverter = UpConverter(master, slave)
self.submodules += upconverter
# Direct Connect.
else:
self.comb += master.connect(slave)
@ -379,6 +396,7 @@ class SRAM(Module):
def __init__(self, mem_or_size, read_only=None, write_only=None, init=None, bus=None, name=None):
if bus is None:
bus = Interface()
assert bus.addressing == "word" # FIXME: Test/Remove byte addressing limitation.
self.bus = bus
bus_data_width = len(self.bus.dat_r)
if isinstance(mem_or_size, Memory):
@ -510,13 +528,18 @@ class Wishbone2CSR(Module):
# # #
wishbone_adr_shift = {
"word" : 0,
"byte" : log2_int(self.wishbone.data_width//8),
}[self.wishbone.addressing]
# Registered Access.
if register:
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
NextValue(self.csr.dat_w, self.wishbone.dat_w),
If(self.wishbone.cyc & self.wishbone.stb,
NextValue(self.csr.adr, self.wishbone.adr),
NextValue(self.csr.adr, self.wishbone.adr[wishbone_adr_shift:]),
NextValue(self.csr.we, self.wishbone.we & (self.wishbone.sel != 0)),
NextState("WRITE-READ")
)
@ -531,13 +554,13 @@ class Wishbone2CSR(Module):
self.wishbone.dat_r.eq(self.csr.dat_r),
NextState("IDLE")
)
# Un-Registered Access.
else:
fsm = FSM(reset_state="WRITE-READ")
self.submodules += fsm
self.submodules.fsm = fsm = FSM(reset_state="WRITE-READ")
fsm.act("WRITE-READ",
self.csr.dat_w.eq(self.wishbone.dat_w),
If(self.wishbone.cyc & self.wishbone.stb,
self.csr.adr.eq(self.wishbone.adr),
self.csr.adr.eq(self.wishbone.adr[wishbone_adr_shift:]),
self.csr.we.eq(self.wishbone.we & (self.wishbone.sel != 0)),
NextState("ACK")
)