SPI Master/Slave IP

A memory-mapped SPI core that puts a full master and a full slave behind two independent AXI4-Lite register banks in one core. All four SPI transfer modes standard 4-wire, 3-wire half duplex, Dual and Quad are selected from the register map at run time, with no rebuild between them.

Overview

The RunX SPI Controller (spi_top) instantiates a master that generates chip select and the serial clock, and a slave that is clocked by an external master, each with its own AXI4-Lite register bank and neither wired to the other inside the core. A transfer is set up by writing the clock rate, mode and framing into CFG, the payload into the TXD registers, and the enable/start bits into CTRL; the result appears in the RXD registers once the hardware-owned done indication changes state.

Two build-time generics let one RTL source scale to exactly what an application needs: G_ROLE selects master-only, slave-only or both, and G_MODE can fix a single transfer mode at elaboration instead of leaving it runtime-selectable. Together they cut the core from 3441 LUTs (both roles, every mode runtime-selectable) to 729 LUTs (master-only, STD-only)
a 79% reduction with the same source.

SPI Simplified architecture SPI Simplified architecture

Specifications

SpecificationValue
Bus interfaceAMBA AXI4-Lite × 2 (independent master and slave register banks)
Transfer modesSTD (4-wire) · 3-wire · Dual · Quad runtime-selectable by default
SPI modes0 – 3 (all CPOL/CPHA combinations)
Bit orderMSB-first or LSB-first, run-time selectable
Transfer size1 – 123 bits, over a 128-bit flat payload
Registers12 × 32-bit per side, offsets 0x00 – 0x2C
InterruptOne level-sensitive line per side, driven by a toggling done bit
Clock domains1 (clk_i) the slave oversamples the external SCK rather than using it as a clock
Source languageVHDL, with a Verilog wrapper (IP_spi.v) for packagers
Vendor supportAMD Xilinx (built & timing-closed) · Altera (synthesized) · Lattice · Microchip
Logic (AMD/Xilinx, Zynq UltraScale+)3441 LUT (both roles, runtime) down to 729 LUT (master-only, STD-only)
Fmax (AMD/Xilinx)97.0 MHz tested operating point (reference design, +4.890 ns WNS)

Resource figures are out-of-context Vivado 2025.2 synthesis of spi_top on xck26-sfvc784-2LV-c; Fmax is the routed timing of the reference design and is a tested point, not a swept maximum. Altera (Quartus Prime, Agilex 3) Fmax ranges 222–320 MHz across the same role/mode matrix, from ~800 LUT/ALUT (master-only, STD-only) to ~5000 (both roles, runtime mode).

Standard-mode frame

A standard-mode (4-wire) transfer: the master drives chip select and the serial clock, and MOSI/MISO shift a full-duplex payload for as many clocks as CTRL.data_size selects.

Standard-mode (STD) SPI frame: chip select, serial clock and the full-duplex MOSI/MISO payload.

How it compares

RunX SPIAMD/Xilinx AXI Quad SPIAltera SPI core
Resource usage729 – 3441 LUT / 540-1120 FF (role/mode dependent)442-479 LUT / 676 FF (role/mode dependent)922 ALM / 1320 FF
Fmax97.0 MHz tested (Xilinx)276 MHz302 MHz
Master + slave in one coreYes, independent register banksNo, one has to be selectedNo, one has to be selected
Runtime mode switchingSTD / 3-wire / Dual / Quad, at run timeSTD / Dual / Quad, at elaborationSTD / Dual / Quad, at run time
Software controllable12 registers per side + bare-metal C driverbare-metal C driverbare-metal C driver

Other columns are to be completed from the current vendor datasheets & implementations.. Resource and frequency figures are only comparable when measured on the same device family and speed grade, so each cell should record the part it was taken on.

Parameterisation

ParameterPurpose
G_MODERUNTIME (default) keeps every transfer mode selectable at run time; STD/3WIRE/DUAL/QUAD fixes one mode at elaboration
G_ROLEBOTH (default) instantiates master and slave; MASTER/SLAVE builds a single-role core
G_BIT_SIZEPayload width, 128 bits by default
G_DW / G_AWAXI4-Lite data/address widths, 32-bit / 8-bit by default
G_DEVICEVendor inference hint: Xilinx · Altera · Lattice · Microchip · generic

Verification

AspectDetail
EnvironmentSystemVerilog regression testbench plus a passive protocol checker
Scenario coverage436 regression configurations across all four modes, all CPOL/CPHA combinations, transfer sizes and turnaround positions
Protocol compliance~49,450 passive-checker assertions
Synthesis/timingClean on the Zynq UltraScale+ reference design (Vivado)
Current statusSimulation passing; Validated with various different SPI modules

Deliverables

  • ✓ Synthesizable VHDL RTL source, five modules under spi_top
  • ✓ Verilog wrapper (IP_spi.v) for IP packagers
  • ✓ Bare-metal C driver for both sides (Apache-2.0), blocking and non-blocking
  • ✓ Reference pseudocode documenting the register-level sequence
  • ✓ SystemVerilog regression testbench and protocol checker
  • ✓ Timing constraints (XDC) from the reference design
  • ✓ Product User Guide (PDF)
  • ✓ Block diagram and waveform sources

Why this core

Runtime flexibility, build-time economy. Every transfer mode is register-selectable by default, and when an application only ever needs one mode or one role, G_ROLE/G_MODE recover up to 79% of the LUTs a fully flexible build would cost the same source serves both cases.

Master and slave from one core. Independent AXI4-Lite register banks for each side mean one bitstream can drive external SPI devices, answer an external master, or bridge the two, without instantiating two separate IPs.

Open driver, licensed RTL. The bare-metal C driver is Apache-2.0 and can be redistributed with an end product; the RTL itself is licensed separately, under NDA.

Software included. A complete driver blocking, timeout and non-blocking paths, for both master and slave ships with the core, not just register-level pseudocode.


© 2026 RunX Technology Inc. · Mission-Critical FPGA Design www.run-x.com · info@run-x.com