The example code below shows a simply SPI slave implementation in VHDL. The Master send and receives only one byte of data at time. The slave also can send and receives only one byte of data. This module can be modified to allow for more bytes of data transfer. This can simply done by just changing the value at which the bicount variable resets: to send and receive two byte, this bitcount variable can be reset at 15.
More info about how the SPI protocol works can be found in my previous posting here:
https://embeddeddesign.org/stm32f4-spi3-interface/
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity spi_slave is port( SPIclk : in std_logic; --spi clk from master
RST_N : in std_logic; --active low reset SPIss_N : in std_logic; --active low slave select SPImosi : in std_logic; --master out, slave in SPImiso : out std_logic); --master in, slave out end spi_slave;
architecture rtl of spi_slave is signal rx_buf : std_logic_vector(7 downto 0) := (others => '0'); --receiver buffer signal tx_buf : std_logic_vector(7 downto 0) := (others => '0'); --transmit buffer begin
----------------------------------------------------------------- --Sampling MISO on Falling rising_edge
------------------------------------------------------------------ process (SPIclk,RST_N) variable bitCount: integer range 0 to 7; begin
if(RST_N='0') then
bitCount:=0;
elsif falling_edge(spiclk) then
if(SPIss_n='0') then
SPImiso<=tx_buf(bitCount); --TX data;
bitCount:=bitCount+1;
if(bitCount=7) then
bitCount:=0;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
--Sampling MOSI Data on rising_edge
--------------------------------------------------------------------
process (SPIclk,RST_N)
variable bitCount: integer range 0 to 7;
begin
if(RST_N='0') then
bitCount:=0;
rx_buf <= (OTHERS => '0');
elsif rising_edge(spiclk) then
if(SPIss_n='0') then
rx_buf(bitCount)<=SPImosi; -- LSB bit is received first
bitCount:=bitCount+1;
if(bitCount=8) then
bitCount:=0;
end if;
end if;
end if;
end process.