deric24
Newbie level 1
- Joined
- Feb 25, 2013
- Messages
- 1
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,323
hi :smile:
i have been working on vhdl code for my spi controller. consisting of a master and slave for data transfer.
this is my code
----------------------------------------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SPI_Master is -- SPI-Modus 0: CPOL=0, CPHA=0
Generic (clk_width : integer := 5; -- Hertz
SPI_rate : integer := 1; -- Hertz / clock divider
lenght : integer := 8 --number of bits transfered
);
Port ( TX_Data : in STD_LOGIC_VECTOR (lenght-1 downto 0); -- send data
RX_Data : out STD_LOGIC_VECTOR (lenght-1 downto 0); -- receive data
MOSI : out STD_LOGIC;
MISO : in STD_LOGIC;
SCLK : out STD_LOGIC;
SS : out STD_LOGIC;
TX_Start : in STD_LOGIC;
TX_Done : out STD_LOGIC;
clk : in STD_LOGIC
);
end SPI_Master;
architecture Behavioral of SPI_Master is
signal delay : integer range 0 to (clk_width/(2*SPI_rate));
constant clock_delay : integer := (clk_width /(2*SPI_rate ))-1;
type spitx_states is (spi_stx,spi_txactive,spi_etx);
signal spitxstate : spitx_states := spi_stx;
signal spiclk : std_logic;
signal spiclklast : std_logic;
signal bitcounter : integer range 0 to Lenght; -- If bitcounter = length --> all bits transferred
signal tx_reg : std_logic_vector(lenght-1 downto 0) := (others=>'0');
signal rx_reg : std_logic_vector(Lenght-1 downto 0) := (others=>'0');
begin
------ /control --------
process begin
wait until rising_edge(CLK);
if(delay>0) then delay <= delay-1;
else delay <= clock_delay;
end if;
spiclklast <= spiclk;
case spitxstate is
when spi_stx =>
SS <= '1'; -- slave select disabled
TX_Done <= '0';
bitcounter <= Lenght;
spiclk <= '0'; -- SPI-Modus 0
if(TX_Start = '1') then
spitxstate <= spi_txactive;
SS <= '0';
delay <= clock_delay;
end if;
when spi_txactive => -- data transferred from tx_reg
if (delay=0) then -- shift
spiclk <= not spiclk;
if (bitcounter=0) then -- All the bits transferred -> Deselect
spiclk <= '0'; -- SPI-Modus 0
spitxstate <= spi_etx;
end if;
if(spiclk='1') then -- SPI-Modus 0
bitcounter <= bitcounter-1;
end if;
end if;
when spi_etx =>
SS <= '1'; -- disable Slave Select
TX_Done <= '1';
if(TX_Start = '0') then -- Handshake: wait until the start flag deleted
spitxstate <= spi_stx;
end if;
end case;
end process;
---- recieve shift register -----
process begin
wait until rising_edge(CLK);
if (spiclk='1' and spiclklast='0') then -- SPI-Modus 0
rx_reg <= rx_reg(rx_reg'left-1 downto 0) & MISO;
end if;
end process;
---- transmit shift register -------
process begin
wait until rising_edge(CLK);
if (spitxstate=spi_stx) then -- Reset, if SS inactive
tx_reg <= TX_Data;
end if;
if (spiclk='0' and spiclklast='1') then -- SPI-Modus 0
tx_reg <= tx_reg(tx_reg'left-1 downto 0) & tx_reg(0);
end if;
end process;
SCLK <= spiclk;
MOSI <= tx_reg(tx_reg'left);
RX_Data <= rx_reg;
end Behavioral;
------------------------------------------------------------------------------------------------------------------------------------------------------------------
i simulated the code using altium designer and it works
generated the test bench and used this stimulus.
------------------------------------------------------------------------------------------------------------------------------------------------------------------
clk <= not clk after 10 ns;
process (sclk, ss)
begin
if (falling_edge(SCLK)) then -- SPI Mode 0
txsrslave <= txsrslave(6 downto 0) & '0';
end if;
end process;
process (ss) begin
if (ss='1') then
txsrslave <= rxsrslave; -- x"80000001" after 3 ns;
end if;
end process;
MISO <= txsrslave(7) after 3 ns;
process (sclk, mosi)
begin
if (rising_edge(SCLK)) then -- SPI Mode 0
rxsrslave <= rxsrslave(6 downto 0) & MOSI;
end if;
end process;
tb ROCESS BEGIN
TX_Data <= "00010101";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100 ns;
TX_Data <= "00001111";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100 ns;
TX_Data <= "00001111";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait;
end process;
-------------------------------------------------------------------------------------------------------------------------------
the test bench compiled correctly but after the simulation i get this
- - - Updated - - -
<a title="Untitled1.jpg" href="http://obrazki.elektroda.pl/7025939700_1361832773.jpg"><img src="http://obrazki.elektroda.pl/7025939700_1361832773_thumb.jpg" alt="Untitled1.jpg" /></a>
[image]
i have been working on vhdl code for my spi controller. consisting of a master and slave for data transfer.
this is my code
----------------------------------------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SPI_Master is -- SPI-Modus 0: CPOL=0, CPHA=0
Generic (clk_width : integer := 5; -- Hertz
SPI_rate : integer := 1; -- Hertz / clock divider
lenght : integer := 8 --number of bits transfered
);
Port ( TX_Data : in STD_LOGIC_VECTOR (lenght-1 downto 0); -- send data
RX_Data : out STD_LOGIC_VECTOR (lenght-1 downto 0); -- receive data
MOSI : out STD_LOGIC;
MISO : in STD_LOGIC;
SCLK : out STD_LOGIC;
SS : out STD_LOGIC;
TX_Start : in STD_LOGIC;
TX_Done : out STD_LOGIC;
clk : in STD_LOGIC
);
end SPI_Master;
architecture Behavioral of SPI_Master is
signal delay : integer range 0 to (clk_width/(2*SPI_rate));
constant clock_delay : integer := (clk_width /(2*SPI_rate ))-1;
type spitx_states is (spi_stx,spi_txactive,spi_etx);
signal spitxstate : spitx_states := spi_stx;
signal spiclk : std_logic;
signal spiclklast : std_logic;
signal bitcounter : integer range 0 to Lenght; -- If bitcounter = length --> all bits transferred
signal tx_reg : std_logic_vector(lenght-1 downto 0) := (others=>'0');
signal rx_reg : std_logic_vector(Lenght-1 downto 0) := (others=>'0');
begin
------ /control --------
process begin
wait until rising_edge(CLK);
if(delay>0) then delay <= delay-1;
else delay <= clock_delay;
end if;
spiclklast <= spiclk;
case spitxstate is
when spi_stx =>
SS <= '1'; -- slave select disabled
TX_Done <= '0';
bitcounter <= Lenght;
spiclk <= '0'; -- SPI-Modus 0
if(TX_Start = '1') then
spitxstate <= spi_txactive;
SS <= '0';
delay <= clock_delay;
end if;
when spi_txactive => -- data transferred from tx_reg
if (delay=0) then -- shift
spiclk <= not spiclk;
if (bitcounter=0) then -- All the bits transferred -> Deselect
spiclk <= '0'; -- SPI-Modus 0
spitxstate <= spi_etx;
end if;
if(spiclk='1') then -- SPI-Modus 0
bitcounter <= bitcounter-1;
end if;
end if;
when spi_etx =>
SS <= '1'; -- disable Slave Select
TX_Done <= '1';
if(TX_Start = '0') then -- Handshake: wait until the start flag deleted
spitxstate <= spi_stx;
end if;
end case;
end process;
---- recieve shift register -----
process begin
wait until rising_edge(CLK);
if (spiclk='1' and spiclklast='0') then -- SPI-Modus 0
rx_reg <= rx_reg(rx_reg'left-1 downto 0) & MISO;
end if;
end process;
---- transmit shift register -------
process begin
wait until rising_edge(CLK);
if (spitxstate=spi_stx) then -- Reset, if SS inactive
tx_reg <= TX_Data;
end if;
if (spiclk='0' and spiclklast='1') then -- SPI-Modus 0
tx_reg <= tx_reg(tx_reg'left-1 downto 0) & tx_reg(0);
end if;
end process;
SCLK <= spiclk;
MOSI <= tx_reg(tx_reg'left);
RX_Data <= rx_reg;
end Behavioral;
------------------------------------------------------------------------------------------------------------------------------------------------------------------
i simulated the code using altium designer and it works
generated the test bench and used this stimulus.
------------------------------------------------------------------------------------------------------------------------------------------------------------------
clk <= not clk after 10 ns;
process (sclk, ss)
begin
if (falling_edge(SCLK)) then -- SPI Mode 0
txsrslave <= txsrslave(6 downto 0) & '0';
end if;
end process;
process (ss) begin
if (ss='1') then
txsrslave <= rxsrslave; -- x"80000001" after 3 ns;
end if;
end process;
MISO <= txsrslave(7) after 3 ns;
process (sclk, mosi)
begin
if (rising_edge(SCLK)) then -- SPI Mode 0
rxsrslave <= rxsrslave(6 downto 0) & MOSI;
end if;
end process;
tb ROCESS BEGIN
TX_Data <= "00010101";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100 ns;
TX_Data <= "00001111";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100 ns;
TX_Data <= "00001111";
wait for 3 ns;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait;
end process;
-------------------------------------------------------------------------------------------------------------------------------
the test bench compiled correctly but after the simulation i get this
- - - Updated - - -
<a title="Untitled1.jpg" href="http://obrazki.elektroda.pl/7025939700_1361832773.jpg"><img src="http://obrazki.elektroda.pl/7025939700_1361832773_thumb.jpg" alt="Untitled1.jpg" /></a>
[image]