cores/cpu/cv32e40p/core: rewrite OBI2Wishbone to reduce write/read latency by 1 cycle.

This commit is contained in:
Florent Kermarrec 2020-11-30 12:18:59 +01:00
parent 18f66a79f2
commit d193092e16
1 changed files with 45 additions and 19 deletions

View File

@ -78,27 +78,53 @@ def add_manifest_sources(platform, manifest):
class OBI2Wishbone(Module): class OBI2Wishbone(Module):
def __init__(self, obi, wb): def __init__(self, obi, wb):
dat_r_d = Signal().like(wb.dat_r) addr = Signal.like(obi.addr)
addr_d = Signal().like(obi.addr) be = Signal.like(obi.be)
ack_d = Signal() we = Signal.like(obi.we)
wdata = Signal.like(obi.wdata)
self.sync += [ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
dat_r_d.eq(wb.dat_r), fsm.act("IDLE",
ack_d.eq(wb.ack), # On OBI request:
addr_d.eq(obi.addr), If(obi.req,
] # Drive Wishbone bus from OBI bus.
self.comb += [
wb.adr.eq(obi.addr[2:32]), wb.adr.eq(obi.addr[2:32]),
wb.stb.eq(obi.req & (~ack_d)), wb.stb.eq( 1),
wb.dat_w.eq(obi.wdata), wb.dat_w.eq( obi.wdata),
wb.cyc.eq(obi.req), wb.cyc.eq( 1),
wb.sel.eq(obi.be), wb.sel.eq( obi.be),
wb.we.eq(obi.we), wb.we.eq( obi.we),
obi.gnt.eq(wb.ack & (addr_d == obi.addr)),
obi.rvalid.eq(ack_d), # Store OBI bus values.
obi.rdata.eq(dat_r_d), NextValue(addr, obi.addr),
] NextValue(be, obi.be),
NextValue(we, obi.we),
NextValue(wdata, obi.wdata),
# Now we need to wait Wishbone Ack.
NextState("ACK")
),
obi.gnt.eq(1), # Always ack OBI request in Idle.
)
fsm.act("ACK",
# Drive Wishbone bus from stored OBI bus values.
wb.adr.eq(addr[2:32]),
wb.stb.eq( 1),
wb.dat_w.eq( wdata),
wb.cyc.eq( 1),
wb.sel.eq( be),
wb.we.eq( we),
# On Wishbone Ack:
If(wb.ack,
# Generate OBI response.
obi.rvalid.eq(1),
obi.rdata.eq(wb.dat_r),
# Return to Idle.
NextState("IDLE")
)
)
class Wishbone2OBI(Module): class Wishbone2OBI(Module):
def __init__(self, wb, obi): def __init__(self, wb, obi):