from migen.fhdl.std import *
from migen.genlib import roundrobin
from migen.genlib.record import *
-from migen.genlib.misc import optree
+from migen.genlib.misc import optree, chooser
+from migen.genlib.fsm import FSM, NextState
from migen.bus.transactions import *
from migen.sim.generic import Proxy
for column, bus in zip(zip(*access), busses):
self.submodules += Arbiter(column, bus)
+class DownConverter(Module):
+ # DownConverter splits Wishbone accesses of N bits in M accesses of L bits where:
+ # N is the original data-width
+ # L is the target data-width
+ # M = N/L
+ def __init__(self, dw_i, dw_o):
+
+ self.wishbone_i = Interface(dw_i)
+ self.wishbone_o = Interface(dw_o)
+ self.ratio = dw_i//dw_o
+
+ ###
+
+ rst = Signal()
+
+ # generate internal write and read ack
+ write_ack = Signal()
+ read_ack = Signal()
+ ack = Signal()
+ self.comb += [
+ ack.eq(self.wishbone_o.cyc & self.wishbone_o.stb & self.wishbone_o.ack),
+ write_ack.eq(ack & self.wishbone_o.we),
+ read_ack.eq(ack & ~self.wishbone_o.we)
+ ]
+
+ # accesses counter logic
+ cnt = Signal(max=self.ratio)
+ self.sync += If(rst, cnt.eq(0)).Elif(ack, cnt.eq(cnt + 1))
+
+ # read data path
+ dat_r = Signal(dw_i)
+ self.sync += If(ack, dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o])))
+
+ # write data path
+ dat_w = Signal(dw_i)
+ self.comb += dat_w.eq(self.wishbone_i.dat_w)
+
+ # errors generation
+ err = Signal()
+ self.sync += If(ack, err.eq(self.wishbone_o.err))
+
+ # direct connection of wishbone_i --> wishbone_o signals
+ for name, size, direction in self.wishbone_i.layout:
+ if direction == DIR_M_TO_S and name not in ["adr", "dat_w"]:
+ self.comb += getattr(self.wishbone_o, name).eq(getattr(self.wishbone_i, name))
+
+ # adaptation of adr & dat signals
+ self.comb += [
+ self.wishbone_o.adr[0:flen(cnt)].eq(cnt),
+ self.wishbone_o.adr[flen(cnt):].eq(self.wishbone_i.adr)
+ ]
+
+ self.comb += chooser(dat_w, cnt, self.wishbone_o.dat_w, reverse=True)
+
+ # fsm
+ fsm = FSM(reset_state="IDLE")
+ self.submodules += fsm
+
+ fsm.act("IDLE",
+ If(write_ack,
+ NextState("WRITE_ADAPT")
+ ),
+ If(read_ack,
+ NextState("READ_ADAPT")
+ )
+ )
+
+ fsm.act("WRITE_ADAPT",
+ If(write_ack & (cnt == self.ratio-1),
+ NextState("IDLE"),
+ rst.eq(1),
+ self.wishbone_i.err.eq(err | self.wishbone_o.err),
+ self.wishbone_i.ack.eq(1),
+ )
+ )
+
+ master_i_dat_r = Signal(dw_i)
+ self.comb += master_i_dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o]))
+
+ fsm.act("READ_ADAPT",
+ If(read_ack & (cnt == self.ratio-1),
+ NextState("IDLE"),
+ rst.eq(1),
+ self.wishbone_i.err.eq(err | self.wishbone_o.err),
+ self.wishbone_i.ack.eq(1),
+ self.wishbone_i.dat_r.eq(master_i_dat_r)
+ )
+ )
+
class Tap(Module):
def __init__(self, bus, handler=print):
self.bus = bus