mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-12-22 10:29:53 +00:00
buffers (fifo) write from NuBus to Wishbone, to improve write BW
This commit is contained in:
parent
c8e8113c81
commit
3a52ab666f
@ -114,8 +114,8 @@ class GoblinAccel(Module): # AutoCSR ?
|
||||
)
|
||||
]
|
||||
|
||||
led0 = platform.request("user_led", 0)
|
||||
self.comb += led0.eq(~local_reset)
|
||||
#led0 = platform.request("user_led", 0)
|
||||
#self.comb += led0.eq(~local_reset)
|
||||
|
||||
self.ibus = ibus = wishbone.Interface()
|
||||
self.dbus = dbus = wishbone.Interface()
|
||||
|
@ -19,11 +19,28 @@ class NuBus2Wishbone(Module):
|
||||
#nubus.mem_error
|
||||
#nubus.mem_tryagain
|
||||
|
||||
assert(len(wb.dat_r) == 32)
|
||||
assert(len(nubus.mem_wdata) == 32)
|
||||
assert(len(nubus.mem_write) == 4)
|
||||
|
||||
#wb_dat_r_rev = Signal(32)
|
||||
#self.comb += [ wb_dat_r_rev[ 0: 8].eq(wb.dat_r[24:32]),
|
||||
# wb_dat_r_rev[ 8:16].eq(wb.dat_r[16:24]),
|
||||
# wb_dat_r_rev[16:24].eq(wb.dat_r[ 8:16]),
|
||||
# wb_dat_r_rev[24:32].eq(wb.dat_r[ 0: 8]), ]
|
||||
#nubus_mem_wdata_rev = Signal(32)
|
||||
#self.comb += [ nubus_mem_wdata_rev[ 0: 8].eq(nubus.mem_wdata[24:32]),
|
||||
# nubus_mem_wdata_rev[ 8:16].eq(nubus.mem_wdata[16:24]),
|
||||
# nubus_mem_wdata_rev[16:24].eq(nubus.mem_wdata[ 8:16]),
|
||||
# nubus_mem_wdata_rev[24:32].eq(nubus.mem_wdata[ 0: 8]), ]
|
||||
#nubus_mem_write_rev = Signal(4)
|
||||
#self.comb += [ nubus_mem_write_rev[0].eq(nubus.mem_write[3]),
|
||||
# nubus_mem_write_rev[1].eq(nubus.mem_write[2]),
|
||||
# nubus_mem_write_rev[2].eq(nubus.mem_write[1]),
|
||||
# nubus_mem_write_rev[3].eq(nubus.mem_write[0]), ]
|
||||
|
||||
self.comb += wb.cyc.eq(nubus.mem_valid)
|
||||
self.comb += wb.stb.eq(nubus.mem_valid)
|
||||
self.comb += If(nubus.mem_write == 0,
|
||||
wb.sel.eq(0xF)).Else(
|
||||
wb.sel.eq(nubus.mem_write))
|
||||
self.comb += wb.we.eq(nubus.mem_write != 0)
|
||||
|
||||
self.comb += [
|
||||
@ -33,10 +50,20 @@ class NuBus2Wishbone(Module):
|
||||
wb.adr.eq(Cat(nubus.mem_addr[2:24], Signal(8, reset = 0xf0)))), # 24 bits, a.k.a 22 bits of words
|
||||
]
|
||||
|
||||
self.comb += If(nubus.mem_write == 0,
|
||||
wb.sel.eq(0xF)).Else(
|
||||
wb.sel.eq(nubus.mem_write))
|
||||
self.comb += [
|
||||
wb.dat_w.eq(nubus.mem_wdata),
|
||||
nubus.mem_rdata.eq(wb.dat_r),
|
||||
]
|
||||
#self.comb += If(nubus.mem_write == 0,
|
||||
# wb.sel.eq(0xF)).Else(
|
||||
# wb.sel.eq(nubus_mem_write_rev))
|
||||
#self.comb += [
|
||||
# wb.dat_w.eq(nubus_mem_wdata_rev),
|
||||
# nubus.mem_rdata.eq(wb_dat_r_rev),
|
||||
#]
|
||||
|
||||
self.comb += nubus.mem_ready.eq(wb.ack)
|
||||
self.comb += nubus.mem_error.eq(0) # FIXME: TODO: ???
|
||||
|
114
nubus-to-ztex-gateware/nubus_memfifo_wb.py
Normal file
114
nubus-to-ztex-gateware/nubus_memfifo_wb.py
Normal file
@ -0,0 +1,114 @@
|
||||
from migen import *
|
||||
from migen.genlib.fifo import *
|
||||
|
||||
import litex
|
||||
from litex.soc.interconnect import wishbone
|
||||
|
||||
from migen.genlib.cdc import BusSynchronizer
|
||||
|
||||
class NuBus2WishboneFIFO(Module):
|
||||
def __init__(self, platform, nubus, wb_read, wb_write):
|
||||
|
||||
# memory
|
||||
# nubus.mem_valid
|
||||
# nubus.mem_addr
|
||||
# nubus.mem_wdata
|
||||
# nubus.mem_write
|
||||
# nubus.mem_ready
|
||||
# nubus.mem_rdata
|
||||
#nubus.mem_error
|
||||
#nubus.mem_tryagain
|
||||
|
||||
assert(len(wb_read.dat_r) == 32)
|
||||
assert(len(nubus.mem_wdata) == 32)
|
||||
assert(len(nubus.mem_write) == 4)
|
||||
|
||||
write_fifo_layout = [
|
||||
("adr", 32),
|
||||
("data", 32),
|
||||
("sel", 4),
|
||||
]
|
||||
self.submodules.write_fifo = write_fifo = ClockDomainsRenamer({"read": "sys", "write": "nubus"})(AsyncFIFOBuffered(width=layout_len(write_fifo_layout), depth=8))
|
||||
write_fifo_dout = Record(write_fifo_layout)
|
||||
self.comb += write_fifo_dout.raw_bits().eq(write_fifo.dout)
|
||||
write_fifo_din = Record(write_fifo_layout)
|
||||
self.comb += write_fifo.din.eq(write_fifo_din.raw_bits())
|
||||
|
||||
self.comb += wb_read.cyc.eq(nubus.mem_valid & (nubus.mem_write == 0)) # only handle reads
|
||||
self.comb += wb_read.stb.eq(nubus.mem_valid & (nubus.mem_write == 0)) # only handle reads
|
||||
self.comb += wb_read.we.eq(0) #(nubus.mem_write != 0)
|
||||
|
||||
self.comb += [
|
||||
If(~nubus.mem_addr[23], # first 8 MiB of slot space: remap to last 8 Mib of SDRAM
|
||||
wb_read.adr.eq(Cat(nubus.mem_addr[2:23], Signal(1, reset=1), Signal(8, reset = 0x8f))), # 0x8f8...
|
||||
).Else( # second 8 MiB: direct access
|
||||
wb_read.adr.eq(Cat(nubus.mem_addr[2:24], Signal(8, reset = 0xf0)))), # 24 bits, a.k.a 22 bits of words
|
||||
]
|
||||
|
||||
#self.comb += If(nubus.mem_write == 0,
|
||||
# wb_read.sel.eq(0xF)).Else(
|
||||
# wb_read.sel.eq(nubus.mem_write))
|
||||
self.comb += [
|
||||
#wb_read.dat_w.eq(nubus.mem_wdata),
|
||||
wb_read.sel.eq(0xF),
|
||||
nubus.mem_rdata.eq(wb_read.dat_r),
|
||||
]
|
||||
|
||||
write_ack = Signal()
|
||||
self.comb += nubus.mem_ready.eq(wb_read.ack | write_ack)
|
||||
self.comb += nubus.mem_error.eq(0) # FIXME: TODO: ???
|
||||
self.comb += nubus.mem_tryagain.eq(0) # FIXME: TODO: ???
|
||||
|
||||
led0 = platform.request("user_led", 0)
|
||||
led1 = platform.request("user_led", 1)
|
||||
self.comb += [ led0.eq(wb_read.ack),
|
||||
led1.eq(write_ack), ]
|
||||
|
||||
#self.submodules.write_fsm = write_fsm = FSM(reset_state = "Reset")
|
||||
#write_fsm.act("Reset",
|
||||
# NextState("Idle"))
|
||||
#write_fsm.act("Idle",)
|
||||
|
||||
# in NuBus
|
||||
#self.comb += [ write_fifo.we.eq(write_fifo.writable & nubus.mem_valid & (nubus.mem_write != 0)),
|
||||
# write_ack.eq(write_fifo.writable & nubus.mem_valid & (nubus.mem_write != 0))
|
||||
#]
|
||||
#self.comb += [ write_fifo_din.adr.eq(nubus.mem_addr),
|
||||
# write_fifo_din.data.eq(nubus.mem_wdata),
|
||||
# write_fifo_din.sel.eq(nubus.mem_write),
|
||||
#]
|
||||
|
||||
self.submodules.write_fsm = write_fsm = ClockDomainsRenamer("nubus")(FSM(reset_state = "Reset"))
|
||||
write_fsm.act("Reset",
|
||||
NextState("Idle"))
|
||||
write_fsm.act("Idle",
|
||||
If(nubus.mem_valid & (nubus.mem_write != 0), # & write_fifo.writable),
|
||||
NextState("WriteFifo"),
|
||||
)
|
||||
)
|
||||
write_fsm.act("WriteFifo",
|
||||
write_fifo.we.eq(1),
|
||||
write_ack.eq(1), # the one cycle delay is needed for the tmO -> nubus.mem_write -> ack dependency chain
|
||||
NextState("WaitForNuBus"),
|
||||
)
|
||||
write_fsm.act("WaitForNuBus",
|
||||
If(~nubus.mem_valid,
|
||||
NextState("Idle"),
|
||||
)
|
||||
)
|
||||
self.comb += [ write_fifo_din.adr.eq(nubus.mem_addr),
|
||||
write_fifo_din.data.eq(nubus.mem_wdata),
|
||||
write_fifo_din.sel.eq(nubus.mem_write),
|
||||
]
|
||||
|
||||
self.comb += [ wb_write.cyc.eq(write_fifo.readable),
|
||||
wb_write.stb.eq(write_fifo.readable),
|
||||
wb_write.we.eq(1),
|
||||
If(~write_fifo_dout.adr[23], # first 8 MiB of slot space: remap to last 8 Mib of SDRAM
|
||||
wb_write.adr.eq(Cat(write_fifo_dout.adr[2:23], Signal(1, reset=1), Signal(8, reset = 0x8f))), # 0x8f8...
|
||||
).Else( # second 8 MiB: direct access
|
||||
wb_write.adr.eq(Cat(write_fifo_dout.adr[2:24], Signal(8, reset = 0xf0)))), # 24 bits, a.k.a 22 bits of words
|
||||
wb_write.dat_w.eq(write_fifo_dout.data),
|
||||
wb_write.sel.eq(write_fifo_dout.sel),
|
||||
write_fifo.re.eq(wb_write.ack),
|
||||
]
|
@ -35,6 +35,7 @@ import goblin_accel
|
||||
# Wishbone stuff
|
||||
from sbus_wb import WishboneDomainCrossingMaster
|
||||
from nubus_mem_wb import NuBus2Wishbone
|
||||
from nubus_memfifo_wb import NuBus2WishboneFIFO
|
||||
from nubus_cpu_wb import Wishbone2NuBus
|
||||
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
@ -350,8 +351,10 @@ class NuBusFPGA(SoCCore):
|
||||
self.bus.add_master(name="NuBusBridgeToWishbone", master=wishbone_master_sys)
|
||||
|
||||
self.submodules.nubus = nubus.NuBus(platform=platform, cd_nubus="nubus")
|
||||
self.submodules.nubus2wishbone = ClockDomainsRenamer("nubus")(NuBus2Wishbone(nubus=self.nubus,wb=self.wishbone_master_nubus))
|
||||
|
||||
#self.submodules.nubus2wishbone = ClockDomainsRenamer("nubus")(NuBus2Wishbone(nubus=self.nubus,wb=self.wishbone_master_nubus))
|
||||
nubus_writemaster_sys = wishbone.Interface(data_width=self.bus.data_width)
|
||||
self.submodules.nubus2wishbone = NuBus2WishboneFIFO(platform=self.platform,nubus=self.nubus,wb_read=self.wishbone_master_nubus,wb_write=nubus_writemaster_sys)
|
||||
self.bus.add_master(name="NuBusBridgeToWishboneWrite", master=nubus_writemaster_sys)
|
||||
wishbone_slave_nubus = wishbone.Interface(data_width=self.bus.data_width)
|
||||
self.submodules.wishbone2nubus = ClockDomainsRenamer("nubus")(Wishbone2NuBus(nubus=self.nubus,wb=wishbone_slave_nubus))
|
||||
self.submodules.wishbone_slave_sys = WishboneDomainCrossingMaster(platform=self.platform, slave=wishbone_slave_nubus, cd_master="sys", cd_slave="nubus")
|
||||
|
Loading…
Reference in New Issue
Block a user