I have question about possibility of realising SPI slave on FPGA using VHDL. I know that there is some open cores, free SPI libraries in VHDL, etc., but I think that do it own way gives experiences. When I coding SPI master, it was a little bit trivial, but now I try to solve SPI slave and getting into some trouble.
My question is about how is the best practice for detecting falling edges of SS (in code below CS) signal and then SCK signal for setting MISO signal, when I am using mode 0 (CPHA = 0 and CPOL = 0). I saw some sample codes of SPI slave in VHDL where author using some system clock what frequency was more greater than SCK and between two rising or falling edges of the system clock the author detected changes of relevant signal in actual state of finite state machine and doing some action, but I think there always be some uncertain delay between system clock and changes of signals what comes from SPI master and I think that some integrated circuits what using some form of serial access (not sure that SPI, but I think it) also don't have any own system clock provided by for example crystal. So I tried to code with some logic functions what leads to possibility of detecting falling edge of single signal, but it depends both on SS and SCK, but problem is when I try to detecting SS for deactivate the device and reseting the state, I cannot do it, because ISE gives me error: Cannot have such operands. When I don't detect it, I will not be able get the slave into predicated state between transaction frames if some error in communication occured, for example crosstalk or master for example try to read 9 bits, etc... I also tried for dividing into two processes (first one for falling edge of SS, second one for falling edge of SCK), but in that case I met with problem of multiple drivers on single net MISO...
So I have question, if is it possible to do it without system clock, or no?
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SPI_Slave_Transmitter_not_CPHA is
port( RECEIVE : in STD_LOGIC;
DATA_IN : in STD_LOGIC_VECTOR(7 downto 0);
CSPOL : in STD_LOGIC;
CS : in STD_LOGIC;
MISO : out STD_LOGIC;
SCK : in STD_LOGIC);
end SPI_Slave_Transmitter_not_CPHA;
architecture Behavioral of SPI_Slave_Transmitter_not_CPHA is
shared variable state : INTEGER := 0;
signal preMISO : STD_LOGIC := 'Z';
signal innerCS : STD_LOGIC := '0';
signal innerSCK : STD_LOGIC := '0';
begin
innerCS <= not (CS xor CSPOL);
innerSCK <= ((innerCS) or SCK);
process(RECEIVE,innerCS,innerSCK,DATA_IN)
begin
if(innerCS = 1 or RECEIVE = '0') then
preMISO <= 'Z';
STATE := 0;
elsif(falling_edge(innerSCK)) then
case STATE is
when 0 =>
preMISO <= DATA_IN(0);
when 1 =>
preMISO <= DATA_IN(1);
when 2 =>
preMISO <= DATA_IN(2);
when 3 =>
preMISO <= DATA_IN(3);
when 4 =>
preMISO <= DATA_IN(4);
when 5 =>
preMISO <= DATA_IN(5);
when 6 =>
preMISO <= DATA_IN(6);
when 7 =>
preMISO <= DATA_IN(7);
when 8 =>
preMISO <= 'Z';
when others =>
preMISO <= 'Z';
end case;
if(STATE < 8) then
STATE := STATE + 1;
else
STATE := 0;
end if;
end if;
end process;
MISO <= preMISO;
end Behavioral;
Question
Josef
Hello everyone,
I have question about possibility of realising SPI slave on FPGA using VHDL. I know that there is some open cores, free SPI libraries in VHDL, etc., but I think that do it own way gives experiences. When I coding SPI master, it was a little bit trivial, but now I try to solve SPI slave and getting into some trouble.
My question is about how is the best practice for detecting falling edges of SS (in code below CS) signal and then SCK signal for setting MISO signal, when I am using mode 0 (CPHA = 0 and CPOL = 0). I saw some sample codes of SPI slave in VHDL where author using some system clock what frequency was more greater than SCK and between two rising or falling edges of the system clock the author detected changes of relevant signal in actual state of finite state machine and doing some action, but I think there always be some uncertain delay between system clock and changes of signals what comes from SPI master and I think that some integrated circuits what using some form of serial access (not sure that SPI, but I think it) also don't have any own system clock provided by for example crystal. So I tried to code with some logic functions what leads to possibility of detecting falling edge of single signal, but it depends both on SS and SCK, but problem is when I try to detecting SS for deactivate the device and reseting the state, I cannot do it, because ISE gives me error: Cannot have such operands. When I don't detect it, I will not be able get the slave into predicated state between transaction frames if some error in communication occured, for example crosstalk or master for example try to read 9 bits, etc... I also tried for dividing into two processes (first one for falling edge of SS, second one for falling edge of SCK), but in that case I met with problem of multiple drivers on single net MISO...
So I have question, if is it possible to do it without system clock, or no?
Thanks in advance for your answer
Best regards
Josef
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 22:25:14 11/22/2020
-- Design Name:
-- Module Name: main - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SPI_Slave_Transmitter_not_CPHA is
port( RECEIVE : in STD_LOGIC;
DATA_IN : in STD_LOGIC_VECTOR(7 downto 0);
CSPOL : in STD_LOGIC;
CS : in STD_LOGIC;
MISO : out STD_LOGIC;
SCK : in STD_LOGIC);
end SPI_Slave_Transmitter_not_CPHA;
architecture Behavioral of SPI_Slave_Transmitter_not_CPHA is
shared variable state : INTEGER := 0;
signal preMISO : STD_LOGIC := 'Z';
signal innerCS : STD_LOGIC := '0';
signal innerSCK : STD_LOGIC := '0';
begin
innerCS <= not (CS xor CSPOL);
innerSCK <= ((innerCS) or SCK);
process(RECEIVE,innerCS,innerSCK,DATA_IN)
begin
if(innerCS = 1 or RECEIVE = '0') then
preMISO <= 'Z';
STATE := 0;
elsif(falling_edge(innerSCK)) then
case STATE is
when 0 =>
preMISO <= DATA_IN(0);
when 1 =>
preMISO <= DATA_IN(1);
when 2 =>
preMISO <= DATA_IN(2);
when 3 =>
preMISO <= DATA_IN(3);
when 4 =>
preMISO <= DATA_IN(4);
when 5 =>
preMISO <= DATA_IN(5);
when 6 =>
preMISO <= DATA_IN(6);
when 7 =>
preMISO <= DATA_IN(7);
when 8 =>
preMISO <= 'Z';
when others =>
preMISO <= 'Z';
end case;
if(STATE < 8) then
STATE := STATE + 1;
else
STATE := 0;
end if;
end if;
end process;
MISO <= preMISO;
end Behavioral;
Link to comment
Share on other sites
7 answers to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.