wishbone : add DownConverter

This commit is contained in:
Florent Kermarrec 2013-08-26 14:22:54 +02:00 committed by Sebastien Bourdeauducq
parent a653a6144b
commit 628fa8ce9e
1 changed files with 91 additions and 1 deletions

View File

@ -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