cores/spi/spi_bone: Cosmetic cleanup pass (and remove unreachable ValueErrors).

This commit is contained in:
Florent Kermarrec 2022-10-19 10:48:13 +02:00
parent 296fc7add0
commit eabdc0b7e9
1 changed files with 47 additions and 41 deletions

View File

@ -11,6 +11,8 @@ from migen.genlib.cdc import MultiReg
from litex.soc.integration.doc import ModuleDoc, AutoDoc from litex.soc.integration.doc import ModuleDoc, AutoDoc
from litex.soc.interconnect import wishbone, stream from litex.soc.interconnect import wishbone, stream
# SPIBone Doc for 4, 3 and 2 wires modes ----------------------------------------------------------
class SPI4WireDocumentation(ModuleDoc): class SPI4WireDocumentation(ModuleDoc):
"""4-Wire SPI Protocol """4-Wire SPI Protocol
@ -112,6 +114,8 @@ class SPI2WireDocumentation(ModuleDoc):
]} ]}
""" """
# SPIBone Core -------------------------------------------------------------------------------------
class SPIBone(Module, ModuleDoc, AutoDoc): class SPIBone(Module, ModuleDoc, AutoDoc):
"""Wishbone Bridge over SPI """Wishbone Bridge over SPI
@ -129,14 +133,25 @@ class SPIBone(Module, ModuleDoc, AutoDoc):
self.wishbone = wishbone.Interface() self.wishbone = wishbone.Interface()
# # # # # #
self.__doc__ = self.__doc__.format(wires)
if wires == 4:
self.mod_doc = SPI4WireDocumentation()
elif wires == 3:
self.mod_doc = SPI3WireDocumentation()
elif wires == 2:
self.mod_doc = SPI2WireDocumentation()
# Parameters.
# -----------
if wires not in [2, 3, 4]:
raise ValueError("`wires` must be 2, 3, or 4")
# Doc.
# ----
self.__doc__ = self.__doc__.format(wires)
self.mod_doc = {
4 : SPI4WireDocumentation(),
3 : SPI3WireDocumentation(),
2 : SPI2WireDocumentation(),
}[wires]
# Signals.
# --------
clk = Signal() clk = Signal()
cs_n = Signal() cs_n = Signal()
mosi = Signal() mosi = Signal()
@ -151,31 +166,27 @@ class SPIBone(Module, ModuleDoc, AutoDoc):
wr = Signal() wr = Signal()
sync_byte = Signal(8) sync_byte = Signal(8)
self.specials += [ self.specials += MultiReg(pads.clk, clk)
MultiReg(pads.clk, clk),
]
if wires == 2: if wires == 2:
io = TSTriple() io = TSTriple()
self.specials += io.get_tristate(pads.mosi) self.specials += io.get_tristate(pads.mosi)
self.specials += MultiReg(io.i, mosi) self.specials += MultiReg(io.i, mosi)
self.comb += io.o.eq(miso) self.comb += io.o.eq(miso)
self.comb += io.oe.eq(miso_en) self.comb += io.oe.eq(miso_en)
elif wires == 3: if wires == 3:
self.specials += MultiReg(pads.cs_n, cs_n), self.specials += MultiReg(pads.cs_n, cs_n),
io = TSTriple() io = TSTriple()
self.specials += io.get_tristate(pads.mosi) self.specials += io.get_tristate(pads.mosi)
self.specials += MultiReg(io.i, mosi) self.specials += MultiReg(io.i, mosi)
self.comb += io.o.eq(miso) self.comb += io.o.eq(miso)
self.comb += io.oe.eq(miso_en) self.comb += io.oe.eq(miso_en)
elif wires == 4: if wires == 4:
self.specials += MultiReg(pads.cs_n, cs_n), self.specials += MultiReg(pads.cs_n, cs_n),
self.specials += MultiReg(pads.mosi, mosi) self.specials += MultiReg(pads.mosi, mosi)
if with_tristate: if with_tristate:
self.specials += Tristate(pads.miso, miso, ~cs_n) self.specials += Tristate(pads.miso, miso, ~cs_n)
else: else:
self.comb += pads.miso.eq(miso) self.comb += pads.miso.eq(miso)
else:
raise ValueError("`wires` must be 2, 3, or 4")
clk_last = Signal() clk_last = Signal()
clk_rising = Signal() clk_rising = Signal()
@ -189,18 +200,17 @@ class SPIBone(Module, ModuleDoc, AutoDoc):
self.submodules += fsm self.submodules += fsm
self.comb += fsm.reset.eq(cs_n) self.comb += fsm.reset.eq(cs_n)
# Connect the Wishbone bus up to our values # Connect the Wishbone bus up to our values.
self.comb += [ self.comb += [
self.wishbone.adr.eq(address[2:]), self.wishbone.adr.eq(address[2:]),
self.wishbone.dat_w.eq(value), self.wishbone.dat_w.eq(value),
self.wishbone.sel.eq(2**len(self.wishbone.sel) - 1) self.wishbone.sel.eq(2**len(self.wishbone.sel) - 1)
] ]
# Constantly have the counter increase, except when it's reset # Constantly have the counter increase, except when it's reset in the IDLE state.
# in the IDLE state
self.sync += If(cs_n, counter.eq(0)).Elif(clk_rising, counter.eq(counter + 1)) self.sync += If(cs_n, counter.eq(0)).Elif(clk_rising, counter.eq(counter + 1))
if wires == 2: if wires in [2]:
fsm.act("IDLE", fsm.act("IDLE",
miso_en.eq(0), miso_en.eq(0),
NextValue(miso, 1), NextValue(miso, 1),
@ -213,17 +223,15 @@ class SPIBone(Module, ModuleDoc, AutoDoc):
NextValue(command, mosi), NextValue(command, mosi),
) )
) )
elif wires == 3 or wires == 4: if wires in [3, 4]:
fsm.act("IDLE", fsm.act("IDLE",
miso_en.eq(0), miso_en.eq(0),
NextValue(miso, 1), NextValue(miso, 1),
If(clk_rising, If(clk_rising,
NextState("GET_TYPE_BYTE"), NextState("GET_TYPE_BYTE"),
NextValue(command, mosi), NextValue(command, mosi),
),
) )
else: )
raise ValueError("invalid `wires` count: {}".format(wires))
# Determine if it's a read or a write # Determine if it's a read or a write
fsm.act("GET_TYPE_BYTE", fsm.act("GET_TYPE_BYTE",
@ -343,15 +351,13 @@ class SPIBone(Module, ModuleDoc, AutoDoc):
), ),
) )
if wires == 3 or wires == 4: if wires in [2]:
fsm.act("END",
miso_en.eq(1),
)
elif wires == 2:
fsm.act("END", fsm.act("END",
miso_en.eq(0), miso_en.eq(0),
NextValue(sync_byte, 0), NextValue(sync_byte, 0),
NextState("IDLE") NextState("IDLE")
) )
else: if wires in [3, 4]:
raise ValueError("invalid `wires` count: {}".format(wires)) fsm.act("END",
miso_en.eq(1),
)