The ability to bridge Wishbone is an incredibly powerful one. However, the various bridges can be rather heavy in terms of resource usage. This presents a simple bridge that operates over SPI.
The Wishbone bus should go in a clock domain that’s roughly 4x that of your clock signal. For example, if your clock signal is 12 MHz, place the bridge in a 48 MHz domain. Finally, add the bridge to your SoCCore
:
class BaseSoC(SoCCore):
def __init__(self, platform, **kwargs):
...
# Add SPI
spi_pads = platform.request("spi")
self.submodules.spibone = ClockDomainsRenamer("clk_48")(spibone.SpiWishboneBridge(spi_pads))
self.add_wb_master(self.spibone.wishbone)
The protocol for the SPI bridge is big-endian. There are two distinct operations: Read and Write.
Read protocol:
Write: 01 | AA | AA | AA | AA
[Wishbone Operation]
Read: 01 | VV | VV | VV | VV
Write protocol:
Write: 00 | AA | AA | AA | AA | VV | VV | VV | VV
[Wishbone Operation]
Read: 00
"AA" is address, "VV" is value. All bytes are big-endian. During the "Wishbone Operation" phase, the host constantly outputs "FF" until it has a response, at which point it outputs "00" (write) or "01" (read). All output is byte-aligned.
It is possible to enable three-wire mode. In this mode, the mosi
wire is used for transmit and receive. During the Wishbone Operation
phase, the wire is changed from an input to an output.