| from migen.fhdl.std import *
from migen.bus import wishbone
from migen.genlib.fsm import FSM, NextState
from migen.genlib.cdc import MultiReg
class FSMCBridge(Module):
def __init__(self, fsmc_pins):
self.master = master = wishbone.Interface(16)
fsmc_a = Signal(11)
self.d_in = fsmc_d_in = Signal(16)
self.d_out = fsmc_d_out = Signal(16)
fsmc_bl = Signal(2)
fsmc_e = Signal()
fsmc_oe = Signal()
fsmc_we = Signal()
d_ts = TSTriple(16)
self.specials += d_ts.get_tristate(fsmc_pins.d)
self.comb += d_ts.oe.eq(~fsmc_pins.ne & ~fsmc_pins.noe)
self.comb += d_ts.o.eq(fsmc_d_out)
self.specials += MultiReg(fsmc_pins.a, fsmc_a)
self.specials += MultiReg(d_ts.i, fsmc_d_in)
self.specials += MultiReg(~fsmc_pins.nbl, fsmc_bl)
self.specials += MultiReg(~fsmc_pins.ne, fsmc_e)
self.specials += MultiReg(~fsmc_pins.noe, fsmc_oe)
self.specials += MultiReg(~fsmc_pins.nwe, fsmc_we)
start_read_cycle = Signal()
start_write_cycle = Signal()
end_cycle = Signal()
sample_data = Signal()
fsm = FSM()
fsm.act('IDLE',
If(fsmc_e,
# Read
If(fsmc_oe,
start_read_cycle.eq(1),
NextState('READ_WAIT_ACK'),
),
# Write
If(fsmc_we,
start_write_cycle.eq(1),
NextState('WRITE_WAIT_ACK'),
),
),
)
fsm.act('WRITE_WAIT_ACK',
If(master.ack,
end_cycle.eq(1),
NextState('WRITE_WAIT'),
),
)
fsm.act('WRITE_WAIT',
If(~fsmc_we,
NextState('IDLE'),
),
)
fsm.act('READ_WAIT_ACK',
If(master.ack,
sample_data.eq(1),
end_cycle.eq(1),
NextState('READ_WAIT'),
),
)
fsm.act('READ_WAIT',
If(~fsmc_oe,
NextState('IDLE'),
),
)
self.submodules.fsm = fsm
self.sync += If(start_read_cycle,
master.cyc.eq(1),
master.stb.eq(1),
master.adr.eq(fsmc_a),
master.sel.eq(fsmc_bl),
master.we.eq(0),
)
self.sync += If(start_write_cycle,
master.cyc.eq(1),
master.stb.eq(1),
master.adr.eq(fsmc_a),
master.sel.eq(fsmc_bl),
master.we.eq(1),
master.dat_w.eq(fsmc_d_in),
)
self.sync += If(end_cycle,
fsmc_d_out.eq(master.dat_r),
)
self.sync += If(end_cycle,
master.cyc.eq(0),
master.stb.eq(0),
)
|