interconnect/wishbone: simplify DownConverter.

This commit is contained in:
Florent Kermarrec 2020-05-27 17:18:31 +02:00
parent e0d2682055
commit 1fddd0e3d3
1 changed files with 22 additions and 49 deletions

View File

@ -213,8 +213,7 @@ class Crossbar(Module):
class DownConverter(Module): class DownConverter(Module):
"""DownConverter """DownConverter
This module splits Wishbone accesses from a master interface to a smaller This module splits Wishbone accesses from a master interface to a smaller slave interface.
slave interface.
Writes: Writes:
Writes from master are splitted N writes to the slave. Access is acked when the last Writes from master are splitted N writes to the slave. Access is acked when the last
@ -227,30 +226,20 @@ class DownConverter(Module):
""" """
def __init__(self, master, slave): def __init__(self, master, slave):
dw_from = len(master.dat_r) dw_from = len(master.dat_r)
dw_to = len(slave.dat_w) dw_to = len(slave.dat_w)
ratio = dw_from//dw_to ratio = dw_from//dw_to
# # # # # #
read = Signal()
write = Signal()
counter = Signal(max=ratio) counter = Signal(max=ratio)
counter_reset = Signal()
counter_ce = Signal()
self.sync += \
If(counter_reset,
counter.eq(0)
).Elif(counter_ce,
counter.eq(counter + 1)
)
counter_done = Signal()
self.comb += counter_done.eq(counter == ratio-1)
# Main FSM # Control Path
self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm = FSM(reset_state="IDLE")
fsm = ResetInserter()(fsm)
self.submodules.fsm = fsm
self.comb += fsm.reset.eq(~master.cyc)
fsm.act("IDLE", fsm.act("IDLE",
counter_reset.eq(1), NextValue(counter, 0),
If(master.stb & master.cyc, If(master.stb & master.cyc,
If(master.we, If(master.we,
NextState("WRITE") NextState("WRITE")
@ -260,65 +249,49 @@ class DownConverter(Module):
) )
) )
fsm.act("WRITE", fsm.act("WRITE",
write.eq(1), slave.adr.eq(Cat(counter, master.adr)),
slave.we.eq(1), slave.we.eq(1),
slave.cyc.eq(1), slave.cyc.eq(1),
If(master.stb & master.cyc, If(master.stb & master.cyc,
slave.stb.eq(1), slave.stb.eq(1),
If(slave.ack, If(slave.ack,
counter_ce.eq(1), NextValue(counter, counter + 1),
If(counter_done, If(counter == (ratio - 1),
master.ack.eq(1), master.ack.eq(1),
NextState("IDLE") NextState("IDLE")
) )
) )
).Elif(~master.cyc,
NextState("IDLE")
) )
) )
fsm.act("READ", fsm.act("READ",
read.eq(1), slave.adr.eq(Cat(counter, master.adr)),
slave.cyc.eq(1), slave.cyc.eq(1),
If(master.stb & master.cyc, If(master.stb & master.cyc,
slave.stb.eq(1), slave.stb.eq(1),
If(slave.ack, If(slave.ack,
counter_ce.eq(1), NextValue(counter, counter + 1),
If(counter_done, If(counter == (ratio - 1),
master.ack.eq(1), master.ack.eq(1),
NextState("IDLE") NextState("IDLE")
) )
) )
).Elif(~master.cyc,
NextState("IDLE")
) )
) )
# Address # Write Datapath
self.comb += [
If(counter_done,
slave.cti.eq(7) # indicate end of burst
).Else(
slave.cti.eq(2)
),
slave.adr.eq(Cat(counter, master.adr))
]
# Datapath
cases = {} cases = {}
for i in range(ratio): for i in range(ratio):
cases[i] = [ cases[i] = [
slave.sel.eq(master.sel[i*dw_to//8:(i+1)*dw_to]), slave.sel.eq(master.sel[i*dw_to//8:]),
slave.dat_w.eq(master.dat_w[i*dw_to:(i+1)*dw_to]) slave.dat_w.eq(master.dat_w[i*dw_to:]),
] ]
self.comb += Case(counter, cases) self.comb += Case(counter, cases)
# Read Datapath
dat_r = Signal(dw_from, reset_less=True)
self.comb += master.dat_r.eq(Cat(dat_r[dw_to:], slave.dat_r))
self.sync += If(slave.ack, dat_r.eq(master.dat_r))
cached_data = Signal(dw_from, reset_less=True)
self.comb += master.dat_r.eq(Cat(cached_data[dw_to:], slave.dat_r))
self.sync += \
If(read & counter_ce,
cached_data.eq(master.dat_r)
)
class Converter(Module): class Converter(Module):
"""Converter """Converter