PROJECT

APB-Based SPI Master Controller

A parameterized APB-controlled SPI master, taken from RTL through simulation, lint and synthesis.

View on GitHub ↗

Overview

This project implements a parameterized APB-based SPI Master Controller in synthesizable Verilog RTL.

SPI_TOP architecture

The design is organized into four functional blocks plus a top-level integration module:

The current reported synthesis configuration uses WIDTH = 8.

Technical Deep Dive

The GitHub repository contains the implementation and engineering artifacts for the controller: RTL, testbench material, simulation assets, lint flow, synthesis flow, reports and the synthesized netlist.

For the complete design walkthrough, see the companion article:

How to Design an SPI Master Controller in Verilog RTL: APB, Timing, Simulation and Synthesis →

The article follows the controller from SPI and APB fundamentals → modular RTL → behavioral simulation → lint/design checks → synthesis → timing, area and power analysis, including the investigation of the BAUD_RATE_DIV[0] synthesis warning.

Together, the project repository and technical article provide both sides of the work: the source and reports, and the reasoning behind the design.

End-to-end transaction

APB WRITE 178
     │
     ▼
Transmit register
     │
     ▼
SS asserted + SCLK generated
     │
     ▼
MOSI transmission / MISO sampling
     │
     ▼
RX data = 109
     │
     ▼
APB READ 109

Verification

The final top-level Vivado simulation demonstrates the complete APB → SPI → APB path.

The received shift-register value progresses through:

1 → 3 → 6 → 13 → 27 → 54 → 109

and the final APB read returns 109.

A detailed interpretation of the APB transactions, SPI timing, shift-register behavior and final integrated waveform is provided in the technical deep-dive article.

Synthesis snapshot

Metric Reported result
Clock period 20 ns
Slack +1.89 ns
Mapped cell area 2204 units
Switching-power estimate 1.0848 µW

The area value is mapped cell area; a physical total area including interconnect was not reported because no wire-load model was specified. The power report carries a library characterization limitation, so 1.0848 µW is presented as the available switching-power estimate rather than a fully characterized total power value.

A small synthesis-debugging lesson

After synthesis, check_design reported that BAUD_RATE_DIV[0] was not driving internal logic.

The first reaction was: did I leave a connection out?

Tracing the equation showed:

BAUD_RATE_DIV = (SPPR + 1) × 2^(SPR + 1)

Since 2^(SPR + 1) is always even, the complete divider value is always even. Therefore:

BAUD_RATE_DIV[0] = 0

The tool could therefore optimize away a redundant least-significant bit.

That became a useful reminder that a synthesis warning is a starting point for investigation — not automatically a functional failure.

The full debugging story, including the relevant RTL reasoning and the final interpretation of the design-check messages, is covered in the synthesis-debugging section of the technical article.

Tools

Verilog HDL · Xilinx Vivado · Synopsys VC SpyGlass · Synopsys Design Compiler

Source and Documentation

Implementation: APB-Based SPI Master Controller on GitHub →

Technical walkthrough: SPI Master Controller — APB, Timing, Simulation and Synthesis →

Source-of-truth note: The Verilog RTL in the repository defines the exact behavior of the current implementation. The technical article explains the design and analysis around that implementation.