CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

SPI Slave Oversampling

HardVerilog / SystemVerilogBuild

Routing an external SPI clock directly into the clock network of an FPGA or ASIC introduces severe Clock Domain Crossing (CDC) hazards and timing closure failures. Robust SPI slave interfaces treat the external serial clock as an asynchronous data signal, oversampling it with a fast internal system clock to safely extract data and avoid metastability.

This module acts as an SPI Slave receiver and transmitter using an oversampling architecture. The external signals sclk, cs_n, and mosi are asynchronous to the system clk. They must first pass through a 2-stage synchronizer. A third register stage is used on the synchronized signals to detect rising and falling edges. The SPI protocol uses CPOL=0 and CPHA=0 (Mode 0). The module samples the synchronized mosi on the detected rising edge of the synchronized sclk. It updates the miso output on the detected falling edge of the synchronized sclk, as well as immediately upon the detected falling edge of the synchronized cs_n. Data is transmitted and received MSB first. When 8 bits are received, rx_valid asserts for one system clock cycle, and rx_data holds the complete byte.

| Signal | Direction | Width | Description | |---|---|---|---| | clk | input | 1 | Positive-edge triggered system clock | | rst_n | input | 1 | Synchronous active-low reset; resets all outputs and internal states to 0 | | sclk | input | 1 | Asynchronous SPI clock | | cs_n | input | 1 | Asynchronous chip select (active-low) | | mosi | input | 1 | Asynchronous Master-Out Slave-In | | tx_data | input | 8 | Data byte to transmit; sampled when the synchronized cs_n falls | | miso | output | 1 | Master-In Slave-Out; driven to 0 when synchronized cs_n is high | | rx_data | output | 8 | Received data byte; updates when 8 bits are fully sampled | | rx_valid | output | 1 | Pulses high for 1 clk cycle when 8 bits are received |

Constraints

  • All asynchronous inputs (cs_n, sclk, mosi) must be synchronized to clk using exactly two cascaded flip-flops.
  • Edge detection for sclk and cs_n must use a third flip-flop that delays the output of the second synchronization stage by one clk cycle.
  • A rising edge is detected when the second stage is 1 and the third stage is 0. A falling edge is detected when the second stage is 0 and the third stage is 1.
  • miso must update exactly on the clk cycle where the falling edge of the synchronized sclk is detected, or when the falling edge of the synchronized cs_n is detected.
  • miso must be driven to 0 when the synchronized cs_n is high (i.e., when the second synchronization stage of cs_n is 1).
  • rx_valid must assert for exactly one clk cycle when the 8th bit is sampled (on the detected rising edge of the synchronized sclk).

Topics

FSMClock Domain CrossingSynchronizersInterfaces

Solve this problem

Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.

This problem is part of Codiode Pro. The statement above is free to read.

Sign in to solveSee what Pro unlocks

The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks