SPI Master Mode 0
Microcontrollers and digital signal processors rely on the Serial Peripheral Interface (SPI) to communicate with external flash memory, sensors, and displays. The master dictates the timing by driving a chip select and a serial clock, ensuring the peripheral has enough setup and hold time to latch and emit data reliably.
This module acts as an SPI Master operating in Mode 0. In Mode 0, the clock idles low, data is sampled on the rising edge, and data is shifted on the falling edge. When commanded to start, the module pulls the chip select low, waits one full serial clock period (two system clock cycles), and then begins toggling the serial clock. It shifts out an 8-bit data payload MSB-first on the serial clock's falling edge and captures incoming data on the rising edge. After the final clock edge, it holds the chip select low for one more full serial clock period before returning to an idle state. The system clock (clk) runs at exactly twice the frequency of the generated serial clock (sck).
The system uses a positive-edge triggered clock clk and an active-low synchronous reset rst_n. On reset, the module is idle: ready is 1, cs_n is 1, sck is 0, mosi is 0, and data_out is 8'h00. When ready is 1 and start is asserted, ready drops to 0 on the next cycle and the transaction begins. If start is asserted while ready is 0, it is ignored.
Cycle-by-cycle trace for transmitting 8'hA5 (10100101): • Cycle 1: rst_n=0 → ready=1, cs_n=1, sck=0, mosi=0, data_out=0 • Cycle 2: rst_n=1, start=1, data_in=8'hA5 → ready=1, cs_n=1 (inputs sampled) • Cycle 3: start=0 → ready=0, cs_n=0, sck=0, mosi=1 (Setup 1: MSB driven) • Cycle 4: ready=0, cs_n=0, sck=0, mosi=1 (Setup 2) • Cycle 5: ready=0, cs_n=0, sck=1, mosi=1 (Bit 7 High, MISO sampled) • Cycle 6: ready=0, cs_n=0, sck=0, mosi=0 (Bit 7 Low, MOSI shifts to Bit 6) • ... • Cycle 19: ready=0, cs_n=0, sck=1, mosi=1 (Bit 0 High, MISO sampled) • Cycle 20: ready=0, cs_n=0, sck=0, mosi=1 (Bit 0 Low) • Cycle 21: ready=0, cs_n=0, sck=0, mosi=1 (Hold 1) • Cycle 22: ready=0, cs_n=0, sck=0, mosi=1 (Hold 2) • Cycle 23: ready=1, cs_n=1, sck=0, data_out=rx (Idle)
| Signal | Direction | Width | Description | |---|---|---|---| | clk | input | 1 | Positive-edge system clock (2x SPI clock frequency) | | rst_n | input | 1 | Synchronous active-low reset | | start | input | 1 | Asserted for 1 cycle to begin a transaction | | data_in | input | 8 | Data payload to transmit | | miso | input | 1 | Master In Slave Out (data from peripheral) | | ready | output | 1 | High when idle and ready to accept start | | cs_n | output | 1 | Active-low chip select | | sck | output | 1 | Serial clock | | mosi | output | 1 | Master Out Slave In (data to peripheral) | | data_out | output | 8 | Data received from peripheral, updated at end of transaction |
Constraints
- Positive-edge triggered
clkand synchronous active-lowrst_n. - On reset,
readymust be 1,cs_nmust be 1,sckmust be 0,mosimust be 0, anddata_outmust be 8'h00. - One serial clock cycle equals two
clkcycles. cs_nmust assert (go low) exactly twoclkcycles before the first rising edge ofsck.cs_nmust remain asserted for exactly twoclkcycles after the final falling edge ofsck.mosimust be driven with the MSB (bit 7) as soon ascs_ngoes low, providing setup time before the first rising edge.mositransitions must occur on the falling edge ofsck(which corresponds to aclkrising edge).misomust be sampled on the rising edge ofsck.data_outmust update with the fully received byte on the cyclereadyreturns to 1.startassertions must be ignored ifreadyis 0.
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.