Beginning FPGA Programming - Partie72
Beginning FPGA Programming - Partie72
15.3.3.4 Read/Write Cycle
Once the first eight bits of SPI DATA are in the shift register (spi_datain_shifter), we can design it is a read
cycle or write cycle. We need to make this decision when the spi_clk_counter is equal to 8 and the spi_clk_
falling_edge is '1.' This allows us enough time before the ninth rising clock edge comes in. Figure 15-14
shows the VHDL code that will set the spi_write_cycle equal to '1' when we receive a byte value of 0x00 in the
first byte from the Master SPI. The spi_write_cycle value will remain stable until the slave select is equal to '1'
which is when the cycle is finished.
355
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI
15.3.3.6 Read Output
If the first byte from Raspberry Pi, which is stored in spi_datain_shifter, is equal to 0x01(hex), which means
read cycle, then it is time to provide a byte to Raspberry Pi. It copies the FPGA data (data_in) from other logic
to an 8-bit shift register (spi_dataout_shifter).
In Figure 15-16, lines 130-131, shift the data to the left (high bit) when SPI clock is falling edge after it
copied the FPGA data_in to the shift register. Line 136 connects the most significant bit of the shift register
(bit 7) to the rspi_miso pin which connected to Raspberry Pi 3 SPI data input.
356
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI
Listing 15-1 provides the whole spi_slave module VHDL design file.
entity spi_slave is
port(
-- general purpose
sys_clock : in std_logic; -- system clock
sys_rst : in std_logic; -- system reset active low
-- serial I/O side
rspi_sclk : in std_logic; -- SPI clock from raspberry SPI Master
rspi_ss : in std_logic; -- SPI chip select from raspberry SPI Master
rspi_mosi : in std_logic; -- SPI data from raspberry SPI Master
rspi_miso : out std_logic; -- SPI data to raspberry SPI Master
-- Register read/write interface
wr_enable : out std_logic; -- Write Enable: Data_out data is valid
data_out : out std_logic_vector(7 downto 0); -- 8 Bit data from raspberry
data_in : in std_logic_vector(7 downto 0) -- 8 bit data read back
);
end entity;
--=============================================================================
-- architecture declaration
--=============================================================================
357
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI
begin
-- Rising edge detected when two clock cycles low and then two clock cycles
High
if(spi_clk_dly_line(2) = '0' and spi_clk_dly_line(1) = '0' and
spi_clk_dly_line(0) = '1' and rspi_sclk = '1') then
spi_clk_rising_edge <= '1';
else
spi_clk_rising_edge <= '0';
end if;
-- Falling edge detected when two clock cycles high and then two clock
cycles Low
if(spi_clk_dly_line(2) = '1' and spi_clk_dly_line(1) = '1' and
spi_clk_dly_line(0) = '0' and rspi_sclk = '0') then
spi_clk_falling_edge <= '1';
else
spi_clk_falling_edge <= '0';
end if;
end if;
end process;
spi_clock_cycles_counter_p : process(sys_clock)
begin
if(rising_edge(sys_clock)) then
if(rspi_ss = '1') then -- reset counter to zero when not chip select
spi_clk_count <= (others =>'0');
else
if(spi_clk_rising_edge = '1') then -- every rising edge add one
if(spi_clk_count = 16) then
spi_clk_count <= (others => '0');
else
spi_clk_count <= spi_clk_count + 1;
end if;
end if;
end if;
end if;
end process;
358
Chapter 15 ■ Two-Way Communications with Your Raspberry Pi: SPI
-- Every time SPI chip select go low, it will have 16 bit data (Read/Write(8bit)+data(8it)
spi_in_p : process(sys_clock)
begin
if(rising_edge(sys_clock)) then
if(spi_clk_rising_edge = '1') then
spi_datain_shifter <= spi_datain_shifter(6 downto 0) & rspi_mosi;
end if;
end if;
end process;
359