wishbone : add DownConverter
This commit is contained in:
parent
a653a6144b
commit
628fa8ce9e
|
@ -1,7 +1,8 @@
|
|||
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
|
||||
|
||||
|
@ -111,6 +112,95 @@ class Crossbar(Module):
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue