VHDL SPI slave providing memory mapped access to a 32-bit pipelined Wishbone bus. Use with alpus_wb Wishbone interconnect framework to connect any wishbone ip to an external CPU using a SPI bus. Features include:
- Easy to use synchronous design - component package included
- Provides access to Pipelined Wishbone B4 bus
- SPI burst access support with >10MHz spi bus clock
- All four SPI modes supported
- 32-bit data bus with byte select
- 24-bit address, auto-incrementing within bursts
- Address high bits (31:24) can be preset when instantiating
- Includes SPI master model for simulation in VHDL testbench
- Includes C code for register access from MCU
use work.alpus_wb32_pkg.all;
use work.alpus_spi_slave_phy_pkg.all;
spim: alpus_wb32_spi_slave port map (
clk => clk,
clk_sampling => clk_sampling,
rst => rst,
-- SPI slave
ncs => ncs,
sclk => sclk,
mosi => mosi,
miso => miso,
-- Wishbone master
wb_tos => spim_tos,
wb_tom => spim_tom );
Fully synchronous sampling phy for SPI bus
- Separate sampling clock port
- Sampling clock frequency can be any synchronous multiple of Wishbone bus clock
- Sampling clock usually > 10x SPI clock
Maximum SPI clock is limited by sampling clock. Miso must be output in half sclk cycle, so half cycle must be longer than:
T_sclk/2 > T_in_mosi + sample uncertainty + 2.5*clk_sampling + T_co_miso + T_setup_master
Make sure to constraint max output and input delay to keep skew between sclk and mosi low.
The example design connects an Arduino CPU to an FPGA, which has a GPIO for a led and some registers. The CPU runs a read-write test repeatedly. Arduino sample code for register access is provided. Error-free function is verified on hardware (Trinket M0 and ESP32 CPU, Xilinx and Gowin FPGA). Example results for the SPI slave:
108LUT/224FF/300MHz Artix7
190LUT/225FF/108MHz GW1NR-9
SPI protocol is based on 32-bit words, sent MSB first. First word after asserting ncs selects transfer type and includes address. For write accesses, following words on mosi are write words, autoincrementing addresses during bursts. For read accesses, mosi words are commands: NOP auto-increments addresses, REND ends read bursts. First word after command on miso is a dummy word, during which the Wisbone read is performed, and then the following words are read data.
Register protocol Write:
MOSI: CMD0,WRD0,WRD1,WRD2
MISO: XXXX,XXXX,XXXX,XXXX
Register protocol Read:
MOSI: CMD0,NOP_,NOP_,REND,NOP_
MISO: XXXX,XXXX,RDD0,RDD1,RDD2
CMD 31:24:opcode, 24:0:addr
0000xxxx: NOP
0001xxxx: REND
0010ssss: WR (autoinc until burst end)
0011ssss: RD (autoinc during NOP until REND)
01LLLLLL: BWR (block wr) TODO
10LLLLLL: BRD (block rd) TODO
11000000: AHI (addr high set) TODO
111xxxxx: EXT