wishbone : add DownConverter
This commit is contained in:
parent
a653a6144b
commit
628fa8ce9e
|
@ -1,7 +1,8 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib import roundrobin
|
from migen.genlib import roundrobin
|
||||||
from migen.genlib.record import *
|
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.bus.transactions import *
|
||||||
from migen.sim.generic import Proxy
|
from migen.sim.generic import Proxy
|
||||||
|
|
||||||
|
@ -111,6 +112,95 @@ class Crossbar(Module):
|
||||||
for column, bus in zip(zip(*access), busses):
|
for column, bus in zip(zip(*access), busses):
|
||||||
self.submodules += Arbiter(column, bus)
|
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):
|
class Tap(Module):
|
||||||
def __init__(self, bus, handler=print):
|
def __init__(self, bus, handler=print):
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
|
|
Loading…
Reference in New Issue