SPI Slave Oversampling
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 toclkusing exactly two cascaded flip-flops. - Edge detection for
sclkandcs_nmust use a third flip-flop that delays the output of the second synchronization stage by oneclkcycle. - 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.
misomust update exactly on theclkcycle where the falling edge of the synchronizedsclkis detected, or when the falling edge of the synchronizedcs_nis detected.misomust be driven to 0 when the synchronizedcs_nis high (i.e., when the second synchronization stage ofcs_nis 1).rx_validmust assert for exactly oneclkcycle when the 8th bit is sampled (on the detected rising edge of the synchronizedsclk).
Topics
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.
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.