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)
|
#led0 = platform.request("user_led", 0)
|
||||||
self.comb += led0.eq(~local_reset)
|
#self.comb += led0.eq(~local_reset)
|
||||||
|
|
||||||
self.ibus = ibus = wishbone.Interface()
|
self.ibus = ibus = wishbone.Interface()
|
||||||
self.dbus = dbus = wishbone.Interface()
|
self.dbus = dbus = wishbone.Interface()
|
||||||
|
@ -19,11 +19,28 @@ class NuBus2Wishbone(Module):
|
|||||||
#nubus.mem_error
|
#nubus.mem_error
|
||||||
#nubus.mem_tryagain
|
#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.cyc.eq(nubus.mem_valid)
|
||||||
self.comb += wb.stb.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 += wb.we.eq(nubus.mem_write != 0)
|
||||||
|
|
||||||
self.comb += [
|
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
|
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 += [
|
self.comb += [
|
||||||
wb.dat_w.eq(nubus.mem_wdata),
|
wb.dat_w.eq(nubus.mem_wdata),
|
||||||
nubus.mem_rdata.eq(wb.dat_r),
|
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_ready.eq(wb.ack)
|
||||||
self.comb += nubus.mem_error.eq(0) # FIXME: TODO: ???
|
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
|
# Wishbone stuff
|
||||||
from sbus_wb import WishboneDomainCrossingMaster
|
from sbus_wb import WishboneDomainCrossingMaster
|
||||||
from nubus_mem_wb import NuBus2Wishbone
|
from nubus_mem_wb import NuBus2Wishbone
|
||||||
|
from nubus_memfifo_wb import NuBus2WishboneFIFO
|
||||||
from nubus_cpu_wb import Wishbone2NuBus
|
from nubus_cpu_wb import Wishbone2NuBus
|
||||||
|
|
||||||
# CRG ----------------------------------------------------------------------------------------------
|
# CRG ----------------------------------------------------------------------------------------------
|
||||||
@ -350,8 +351,10 @@ class NuBusFPGA(SoCCore):
|
|||||||
self.bus.add_master(name="NuBusBridgeToWishbone", master=wishbone_master_sys)
|
self.bus.add_master(name="NuBusBridgeToWishbone", master=wishbone_master_sys)
|
||||||
|
|
||||||
self.submodules.nubus = nubus.NuBus(platform=platform, cd_nubus="nubus")
|
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)
|
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.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")
|
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