Professional Documents
Culture Documents
SPI Slave VHDL Design - Surf-VHDL
SPI Slave VHDL Design - Surf-VHDL
SPI Slave VHDL Design - Surf-VHDL
com/spi-slave-vhdl-design/
In this post, we are going to design the VHDL code for the SPI slave module
that can be connected to an SPI master.
The SPI is a three or four-wire serial bus as you can see in Figure 1
(https://surf-vhdl.com/wp/wp-content/uploads/2021/11
/SPI_master_single_slave.png)
1 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
The SPI is, basically, a serial to parallel converter controlled by the SS signal.
Input data MOSI (Master Out Serial In) go through an input shift register
when the SS control signal is low. When the SS goes from low to high data in
the input shift register is ready to be read.
The same approach is related to the MISO (Master In Serial Output) output
signal from the slave. In this case, the data in the output shift register is
serialized at each clock cycle by shifting the parallel data.
Figure 2 reports the input-output shift register example for input MOSI and
output MISO SPI slave signal.
(https://surf-vhdl.com/wp/wp-content/uploads/2021/11/spi-slave-serial-to-
parallel-registers.jpg)
2 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
You can find alternate naming, but the functionalities are the same.
(https://surf-vhdl.com/wp/wp-content/uploads/2021/11/SPI-slave-timing.jpg)
SPI timing example is shown in Figure 3. The input MOSI can be clocked
either on the rising or falling edge of SCKL depending on the polarity CPOL
selected. If MOSI is strobed on the rising edge of SCLK, MISO will be
clocked on the falling and vice versa.
From Figure 3, when CPOL=1, the SPI slave data input/output change on the
falling edge of SCLK. The serial data is shifted on the input shift register on
the rising edge of the clock (blue vertical dotted lines) and the output data is
serialized shifting the output shift register on the falling edge of the clock (red
vertical dotted line).
In the case of CPOL=0, the behavior is similar, taking into account the
opposite clock edges.
3 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
the SPI slave VHDL code implements the input and output shift register. The
SPI Slave module works with the SCLK input clock and SS input select
signal.
When you interface this SPI slave VHDL module with your design
components, you must take care of clock domain crossing (CDC) between
the SCLK input serial clock of the SPI slave module and the internal clock of
your VHDL design.
The signal that shall be used to resynchronize the two clock domains, is the
o_busy output signal.
The internal clock that we are going to use in the VHDL design instantiating
the SPI slave module, should run faster than the SPI slave clock. Moreover,
the SPI slave clock is not a continuous clock.
You can detect the falling edge of the o_busy SPI slave select signal to
strobe the parallel data received by the SPI slave module.
You must pay attention to the parallel data to be sent. In this case, the output
parallel shift register is loaded on the first SPI clock edge when the SS signal
is low. The clock edge depends on the CPOL configuration. In this case, you
must guarantee that the parallel data to be shifted is stable before the SS
signal goes low.
4 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
3. use ieee.numeric_std.all;
4.
5. entity spi_slave is
6. generic(
7. N : integer := 2; -- number of
bit to serialize
8. CPOL : std_logic := '0' ); -- clock
polarity
9. port (
10. o_busy : out std_logic; --
receiving data if '1'
11. i_data_parallel : in std_logic_vector(N-1
downto 0); -- data to sent
12. o_data_parallel : out std_logic_vector(N-1
downto 0); -- received data
13. i_sclk : in std_logic;
14. i_ss : in std_logic;
15. i_mosi : in std_logic;
16. o_miso : out std_logic);
17. end spi_slave;
18.
19. architecture rtl of spi_slave is
20.
21. signal r_shift_ena : std_logic;
22. signal r_tx_data :
std_logic_vector(N-2 downto 0); -- data to sent
23. signal r_rx_data :
std_logic_vector(N-1 downto 0); -- received data
24.
25. begin
26. o_data_parallel <= r_rx_data;
27. o_busy <= r_shift_ena;
28.
29. p_spi_slave_input : process(i_sclk)
30. begin
31. if(i_sclk'event and i_sclk=CPOL) then -- CPOL='0' =>
falling edge; CPOL='1' => risinge edge
32. if(i_ss='0') then
33. r_rx_data <= r_rx_data(N-2 downto
0)&i_mosi;
34. end if;
35. end if;
36. end process p_spi_slave_input;
37.
38. p_spi_slave_output : process(i_sclk,i_ss)
39. begin
5 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
The module connected to the SPI slave can use the port signal o_busy to
detect when the input frame has been received. It can be easily done just by
detecting the falling edge of the signal. To detect the falling edge of busy you
can refer to this post (https://surf-vhdl.com/how-to-design-a-good-edge-
detector/) where you can find how to implement a good edge detector
(https://surf-vhdl.com/wp/wp-content/uploads/2021/11/spi-slave-modelsim-
simulation.jpg)
6 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
Figure 4 reports a simulation of the SPI slave module. As you can see the
output port “o_data_parallel” contains the parallel value of the received
serial data. The simulation “o_data_parallel” reports the MOSI serial data
parallelized in the output register. Data is valid on the falling edge of the
“o_busy” signal.
The bit numbering is the first bit is the MSB (most significant bit).
The input port “i_data_parallel” can be used to send back to the SPI master
data from the internal design. In the simulation, the test-bench parallelize the
MISO serial data into the “r_miso_parallel” test register to verify the correct
behavior of the SPI-slave module.
You can easily customize the VHDL of the SPI slave to match your
requirement. For instance, you can connect the SPI slave to an internal
control logic that interprets the “o_data_parallel” value and performs
read/write operation to an internal control register.
As you can understand, if you need to read out a value, you can decode a
read command from the input data stream and, on the next command, you
can send back the read value on the MISO serial line. In other words, the
read value has one command delay latency. This is a common behavior in
the SPI link.
7 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
(https://surf-vhdl.com/wp/wp-content/uploads/2021/11/spi-slave-layout-
example.jpg)
In this example, the value of 4 is used only to better analyze the output
design diagram in Figure 5.
The SPI protocol is driven by the serial clock “i_sclk”. Even if the serial SPI
I/O stream is synchronous with respect to the serial clock, when the signals
i_sclk , i_ss, i_mosi input in the FPGA, the internal logic must be
considered asynchronous.
In this case, you must pay attention to the constraints related to such signals.
From the SPI slave VHDL code and from the figure reporting the related
layout, is clear that “i_ss” is used as asynchronous reset for the control
signal that is used to enable the input and output shift register.
It is also used to drive the o_busy signal used to detect the completion of the
SPI slave serial data burst. So, after the layout, mostly if your device is
congested in terms of FPGA area resources, you must control if the skew
between the input signal is acceptable considering the serial clock constraint.
This can be done using input constraint on the SPI slave input pin to specify
the maximum delay from the FPGA pad to SPI internal registers. Another
8 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
possible solution is to fix the SPI slave register location close to the FPGA
pads to minimize the routing connection of this section.
Conclusion
In this post, we designed a 4-wire SPI slave VHDL module. A Modelsim
simulation has been reported to verify SPI slave correct behavior.
References
[1] https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
(https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus)
LEAVE A REPLY
Your email address will not be published. Required �elds are marked *
Comment *
Name *
Email *
9 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
Website
POST COMMENT
(http://surf-vhdl.teachable.com/)
10 of 12 25/07/22, 18:23
SPI Slave VHDL design - Surf-VHDL https://surf-vhdl.com/spi-slave-vhdl-design/
Privacy
Policy
Q&A#10 RAM
Parallelism
00:00 03:39
Search…
(https://surf-vhdl.com/student-
having-success-with-vhdl/)
11 of 12 25/07/22, 18:23
Join Telegram Channel Closed Group