SPI Slave to Avalon-MM

Showing results for 
Search instead for 
Did you mean: 

SPI Slave to Avalon-MM

SPI Slave to Avalon-MM


This is a SPI slave to Avalon Memory Master adapter. It has the standard SPI interface signals: mosi – Data Input miso – Data Output sclk – SPI input clock ss_n – SPI slave select signal The design asynchronously samples all of the inputs using a standard metastability register configuration. This is shown in Figure 1 below for the signal mosi. Equivalent structures exist on miso, sclk and mosi. 

                                                                                                                                                                      Figure 1

This design asynchronously samples the input stream (mosi, sclk and ss_n) using what would be considered as the “core” clock of the SOPC fabric. There are other approaches to this problem that could be considered; this core was designed to sample the inputs asynchronously. Because of this you have a latency of 3 clock cycles for the metastability flops and edge detection circuitry. The “core” clock should therefore be 5x that of the SPI clock frequency, at a minimum and can be anything higher than 5x.

Waveform Diagrams

Below is a typical write and read SPI transaction. This core mimics these waveforms. 

The core assumes the first bit sent in represents a write (active high) or read (active low) transaction. The bits immediately next are the address, shifted MSB first. Finally, the data should be sent, MSB first. This ordering can be changed by using the MSB_SELECT setting. The core has the following parameters that are configurable via a GUI in SOPC Builder.

DATA_SIZE – This is the number of data bits to be sent. The default is the same as the waveforms above, 16 bits. This can be any number. ADDRESS_SIZE_EXT – This is the number of address bits to be sent. The default is the same as the waveforms above, 7 bits. This can be any number. SCLK_LEVEL_SELECT – This selects whether the core should look for the data around the positive or negative edge of the clock. A setting of “1” (default) selects the positive edge, “0” is negative edge MSB_SELECT – This selects how the data is shifted in to the core. Default setting is “1” meaning MSB and “0” is LSB.

LEFT_SHIFT – Set this based on DATA_SIZE. When DATA_SIZE is 8, LEFT_SHIFT is 0. When DATA_SIZE is 16, LEFT_SHIFT is 1. When DATA_SIZE is 32, LEFT_SHIFT is 2n … etcetera.

Example Design

Attached above are the IP source and example project files. To use this in a SOPC Builder project extract this into the “ip” sub-directory of your current project. After opening SOPC Builder it should automatically see this peripheral and it will appear on the left under “Project” as below. 

If you do not see the design, click on Tools, Options and complete the “IP Search Path” with the path where this folder “custom_spi_avalon_mm” has been placed. The example design itself is a simple SOPC system with this IP, SPI Slave to Avalon MM, connected to on-chip memory. This is shown below in Figure 2.                                                                                                                                                                                                                      Figure 2

The files in this example design are: Project main directory - sopc_top.v, SPI_Slave_to_Avalon_MM_0.v, onchip_memory2_0.v, sopc_top.qpf, sopc_top.qsf ip/custom_spi_avalon_mm – custom_spi_avalon_mm.qip (add this to your project files), custom_spi_avalon_mm.v, custom_spi_avalon_mm_hw.tcl simulation – sim.do, wave.do and sopc_top_tb.v


The simulation of this core is based on the example design. Various writes and reads are sent over the SPI interface, writing and reading from the on-chip memory. When unzipping the full project you will find the simulation files and simulation script in the “simulation” folder. sopc_top_tb.v – This is the simulation test bench file. It has two tasks that automate the write and reads from the SPI interface. For a spi_write the inputs are write address and write data, e.g. for a write to address 0x2 the command would be “spi_write(0x2,0xDEAD);” for a read command to the same address the command would be “spi_read(0x2);” sim.do – this is an example compilation / simulation script for ModelSim. The design was verified with ModelSim SE v6.5e wave.do – this is the waveform file for ModelSim and is referenced by the sim.do script Shown below in Figure 3 is a write transaction simulation waveform. Figure 4 shows a read transaction waveform.  

Version history
Last update:
‎06-26-2019 08:58 PM
Updated by: