---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 16:26:11 07/16/2009 -- Design Name: -- Module Name: spi - 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; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity spi is Port ( clk : in STD_LOGIC; clk66 : in std_logic; reset : in STD_LOGIC; address : in STD_LOGIC_VECTOR (31 downto 2); enable : in std_logic; byte_we : in std_logic_vector(3 downto 0); data_read : out std_logic_vector(31 downto 0); data_write : in STD_LOGIC_VECTOR (31 downto 0); spi_miso : out STD_LOGIC; spi_mosi : in STD_LOGIC; spi_clk : in STD_LOGIC; spi_cs : in STD_LOGIC); end spi; architecture Behavioral of spi is signal transmit_buffer_do : std_logic_vector(7 downto 0); signal receive_buffer_do : std_logic_vector(7 downto 0); signal transmit_buffer_wea, receive_buffer_wea : std_logic; signal spi_transmit_buffer_data : std_logic_vector(7 downto 0); signal spi_transmit_buffer_address : std_logic_vector(10 downto 0) := (others=>'0'); signal spi_receive_buffer_data : std_logic_vector(7 downto 0); signal spi_receive_buffer_address : std_logic_vector(10 downto 0) := (others=>'0'); signal spi_receive_buffer_we, spi_receive_buffer_we_last : std_logic; signal spi_bit_counter : std_logic_vector(2 downto 0) := (others=>'0'); signal spi_clk_reg : std_logic_vector(1 downto 0) := (others=>'0'); signal spi_cs_reg : std_logic_vector(1 downto 0) := (others=>'1'); signal spi_bit_in : std_logic_vector(1 downto 0) := (others=>'0'); signal spi_in : std_logic_vector(7 downto 0) := (others=>'0'); signal spi_out : std_logic_vector(7 downto 0) := (others=>'0'); begin -- transmit_buffer_wea<=byte_we(0) and not address(13); -- receive_buffer_wea<=byte_we(0) and address(13); -- data_read(7 downto 0)<=transmit_buffer_do when address(13)='0' else receive_buffer_do; transmit_buffer: RAMB16_S9_S9 port map ( CLKA => clk, ADDRA => address(12 downto 2), ENA => enable, WEA => byte_we(0), DIA => data_write(7 downto 0), DIPA => (others=>'0'), DOA => open, DOPA => open, SSRA => '0', CLKB => clk66, ADDRB => spi_transmit_buffer_address, ENB => '1', WEB => '0', DOB => spi_transmit_buffer_data, DOPB => open, DIB => (others=>'0'), DIPB => (others=>'0'), SSRB => '0' ); receive_buffer: RAMB16_S9_S9 port map ( CLKA => clk, ADDRA => address(12 downto 2), ENA => enable, WEA => '0', DIA => data_write(7 downto 0), DIPA => (others=>'0'), DOA => data_read(7 downto 0), DOPA => open, SSRA => '0', CLKB => clk66, ADDRB => spi_receive_buffer_address, ENB => '1', WEB => spi_receive_buffer_we, DOB => open, DOPB => open, DIB => spi_in, DIPB => (others=>'0'), SSRB => '0' ); spi_clk_sample: process(clk66,spi_clk) is begin if rising_edge(clk66) then spi_clk_reg<=spi_clk_reg(0)&spi_clk; end if; end process; spi_cs_sample: process(clk66,spi_cs) is begin if rising_edge(clk66) then spi_cs_reg<=spi_cs_reg(0)&spi_cs; end if; end process; spi_mosi_sample: process(clk66,spi_mosi) is begin if rising_edge(clk66) then spi_bit_in<=spi_bit_in(0)&spi_mosi; end if; end process; spi_transfer: process(clk66,spi_cs_reg,spi_clk_reg,spi_bit_counter,spi_bit_in) is begin if rising_edge(clk66) then spi_receive_buffer_we<='0'; spi_receive_buffer_we_last<=spi_receive_buffer_we; if(spi_receive_buffer_we_last='1') then spi_receive_buffer_address<=spi_receive_buffer_address+1; end if; case spi_cs_reg is when "11" => spi_bit_counter<=(others=>'0'); spi_transmit_buffer_address<=(others=>'0'); spi_receive_buffer_address<=(others=>'0'); when "10" => spi_out<=spi_transmit_buffer_data; spi_transmit_buffer_address<=spi_transmit_buffer_address+1; when "00" => case spi_clk_reg is when "01" => spi_bit_counter<=spi_bit_counter+1; spi_in<=spi_in(6 downto 0)&spi_bit_in(1); if(spi_bit_counter="111") then spi_receive_buffer_we<='1'; end if; when "10" => if(spi_bit_counter="000") then spi_out<=spi_transmit_buffer_data; spi_transmit_buffer_address<=spi_transmit_buffer_address+1; else spi_out<=spi_out(6 downto 0)&'0'; end if; when others => end case; when others => end case; end if; end process; spi_miso<=spi_out(7); end Behavioral;