forked from M-Labs/artiq
spi: use misoc SPIMachine, closes #314
This commit is contained in:
parent
9d08011a1f
commit
fc4b3e44d5
|
@ -1,163 +1,8 @@
|
|||
from itertools import product
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.fsm import FSM, NextState
|
||||
from misoc.interconnect import wishbone
|
||||
|
||||
|
||||
class SPIClockGen(Module):
|
||||
def __init__(self, width):
|
||||
self.load = Signal(width)
|
||||
self.bias = Signal() # bias this clock phase to longer times
|
||||
self.edge = Signal()
|
||||
self.clk = Signal(reset=1)
|
||||
|
||||
cnt = Signal.like(self.load)
|
||||
bias = Signal()
|
||||
zero = Signal()
|
||||
self.comb += [
|
||||
zero.eq(cnt == 0),
|
||||
self.edge.eq(zero & ~bias),
|
||||
]
|
||||
self.sync += [
|
||||
If(zero,
|
||||
bias.eq(0),
|
||||
).Else(
|
||||
cnt.eq(cnt - 1),
|
||||
),
|
||||
If(self.edge,
|
||||
cnt.eq(self.load[1:]),
|
||||
bias.eq(self.load[0] & (self.clk ^ self.bias)),
|
||||
self.clk.eq(~self.clk),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class SPIRegister(Module):
|
||||
def __init__(self, width):
|
||||
self.data = Signal(width)
|
||||
self.o = Signal()
|
||||
self.i = Signal()
|
||||
self.lsb = Signal()
|
||||
self.shift = Signal()
|
||||
self.sample = Signal()
|
||||
|
||||
self.comb += [
|
||||
self.o.eq(Mux(self.lsb, self.data[0], self.data[-1])),
|
||||
]
|
||||
self.sync += [
|
||||
If(self.shift,
|
||||
If(self.lsb,
|
||||
self.data[:-1].eq(self.data[1:]),
|
||||
).Else(
|
||||
self.data[1:].eq(self.data[:-1]),
|
||||
)
|
||||
),
|
||||
If(self.sample,
|
||||
If(self.lsb,
|
||||
self.data[-1].eq(self.i),
|
||||
).Else(
|
||||
self.data[0].eq(self.i),
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class SPIBitCounter(Module):
|
||||
def __init__(self, width):
|
||||
self.n_read = Signal(width)
|
||||
self.n_write = Signal(width)
|
||||
self.read = Signal()
|
||||
self.write = Signal()
|
||||
self.done = Signal()
|
||||
|
||||
self.comb += [
|
||||
self.write.eq(self.n_write != 0),
|
||||
self.read.eq(self.n_read != 0),
|
||||
self.done.eq(~(self.write | self.read)),
|
||||
]
|
||||
self.sync += [
|
||||
If(self.write,
|
||||
self.n_write.eq(self.n_write - 1),
|
||||
).Elif(self.read,
|
||||
self.n_read.eq(self.n_read - 1),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class SPIMachine(Module):
|
||||
def __init__(self, data_width, clock_width, bits_width):
|
||||
ce = CEInserter()
|
||||
self.submodules.cg = ce(SPIClockGen(clock_width))
|
||||
self.submodules.reg = ce(SPIRegister(data_width))
|
||||
self.submodules.bits = ce(SPIBitCounter(bits_width))
|
||||
self.div_write = Signal.like(self.cg.load)
|
||||
self.div_read = Signal.like(self.cg.load)
|
||||
self.clk_phase = Signal()
|
||||
self.start = Signal()
|
||||
self.cs = Signal()
|
||||
self.oe = Signal()
|
||||
self.done = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
fsm = CEInserter()(FSM("IDLE"))
|
||||
self.submodules += fsm
|
||||
|
||||
fsm.act("IDLE",
|
||||
If(self.start,
|
||||
If(self.clk_phase,
|
||||
NextState("WAIT"),
|
||||
).Else(
|
||||
NextState("SETUP"),
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("SETUP",
|
||||
self.reg.sample.eq(1),
|
||||
NextState("HOLD"),
|
||||
)
|
||||
fsm.act("HOLD",
|
||||
If(self.bits.done & ~self.start,
|
||||
If(self.clk_phase,
|
||||
NextState("IDLE"),
|
||||
).Else(
|
||||
NextState("WAIT"),
|
||||
)
|
||||
).Else(
|
||||
self.reg.shift.eq(~self.start),
|
||||
NextState("SETUP"),
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT",
|
||||
If(self.bits.done,
|
||||
NextState("IDLE"),
|
||||
).Else(
|
||||
NextState("SETUP"),
|
||||
)
|
||||
)
|
||||
|
||||
write0 = Signal()
|
||||
self.sync += [
|
||||
If(self.cg.edge & self.reg.shift,
|
||||
write0.eq(self.bits.write),
|
||||
)
|
||||
]
|
||||
self.comb += [
|
||||
self.cg.ce.eq(self.start | self.cs | ~self.cg.edge),
|
||||
If(self.bits.write | ~self.bits.read,
|
||||
self.cg.load.eq(self.div_write),
|
||||
).Else(
|
||||
self.cg.load.eq(self.div_read),
|
||||
),
|
||||
self.cg.bias.eq(self.clk_phase),
|
||||
fsm.ce.eq(self.cg.edge),
|
||||
self.cs.eq(~fsm.ongoing("IDLE")),
|
||||
self.reg.ce.eq(self.cg.edge),
|
||||
self.bits.ce.eq(self.cg.edge & self.reg.sample),
|
||||
self.done.eq(self.cg.edge & self.bits.done & fsm.ongoing("HOLD")),
|
||||
self.oe.eq(write0 | self.bits.write),
|
||||
]
|
||||
from misoc.cores.spi.core import SPIMachine
|
||||
|
||||
|
||||
class SPIMaster(Module):
|
||||
|
|
Loading…
Reference in New Issue