spi--master

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:08:05 04/09/2015 
-- Design Name: 
-- Module Name:    spi_master - 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_master is
    generic (
   				CLK_DIV : std_logic_vector(7 downto 0) := x"05"
		);
    Port ( rst 			:	in  	STD_LOGIC;  					-- reset signal, active '1'
           clk 			: 	in  	STD_LOGIC;  					-- 40MHz
			  cs_ctrl		:	in		STD_LOGIC;						-- CS control
           data_in 		: 	in  	STD_LOGIC_VECTOR (7 downto 0);
           data_out 		: 	out 	STD_LOGIC_VECTOR (7 downto 0);
			  data_valid	:	out	STD_LOGIC;
           spi_send 		: 	in  	STD_LOGIC;
			  spi_busy		:	out	STD_LOGIC;
           cs 				: 	out  	STD_LOGIC;						-- same as CS_CTRL
           sclk 			: 	out  	STD_LOGIC;
           mosi 			: 	out  	STD_LOGIC;
           miso			: 	in  	STD_LOGIC);
end spi_master;

architecture Behavioral of spi_master is
    constant RESET_ACTIVE : std_logic := '1';
--    constant CLK_DIV : std_logic_vector(7 downto 0) := x"01";
    signal reg_tx : std_logic_vector(7 downto 0);
    signal reg_rx : std_logic_vector(7 downto 0);
    signal send : std_logic_vector(1 downto 0);
    signal sck : std_logic;
    signal clk_en :  std_logic;
    signal t_clk : std_logic_vector(7 downto 0); --1/2CLK counter
    signal ct_bit : std_logic_vector(7 downto 0);--send bits counter
    type state_type is (idle,tx_prep,tx_state,tx_end); 
    signal currt_state, next_state : state_type;
begin
    process(clk,rst) 										-- SPI send active
    begin
        if rst = RESET_ACTIVE then
            send <= "00";
        elsif rising_edge(clk) then
            send(0) <= spi_send;
            send(1) <= send(0);
        end if;
    end process;
    process(rst,clk) 										--generate SPI SCLK
    begin
        if rst = RESET_ACTIVE then
            t_clk <= x"00";
            ct_bit <= x"00";
            sck <= '0';
        elsif rising_edge(clk) then
            if clk_en = '1' then
                if t_clk = CLK_DIV then
                    t_clk <= x"00";
                    ct_bit <= ct_bit + '1';
                    sck <= not(sck);
                else
                    t_clk <= t_clk + '1';
                end if;
            else
                t_clk <= x"00";
                ct_bit <= x"00";
                sck <= '0';
            end if;            
        end if;
    end process;
    sclk <= sck;            														--64 divider
    
    process(next_state,rst) 														--SPI state meachine
    begin
        if rst = RESET_ACTIVE then
            currt_state <= idle;
        else
            currt_state <= next_state;
        end if;
    end process;
	 
	 cs <= cs_ctrl;
    
    process(clk,rst)
    begin
        if rst = RESET_ACTIVE then
--            cs <= '1';
            mosi <= '0';
            clk_en <= '0';
            reg_tx <= (others => '0');
            reg_rx <= (others => '0');
            data_out <= (others => '0');
            next_state <= idle;
				data_valid <= '0';
				spi_busy <= '0';
        elsif rising_edge(clk) then
            case currt_state is
                when idle =>
--                    cs <= '1';
                    mosi <= '0';
                    clk_en <= '0';
                    reg_tx <= (others => '0');
                    next_state <= idle;                    
                    if send = "01" then 											--	posedge send                   
                        reg_tx <= data_in;
                        clk_en <= '0';
                        next_state <= tx_prep;
                    end if;
						  spi_busy <= '0';
                when tx_prep =>
--                    cs <= '0';
                    mosi <= reg_tx(7);
                    clk_en <= '1';
                    next_state <= tx_state;
						  spi_busy <= '1';
                when tx_state =>
                    if ct_bit(0) = '0' and t_clk = CLK_DIV then 			--SCLK posedge
                        reg_rx <= reg_rx(6 downto 0) & miso;
                        next_state <= tx_state;
                        clk_en <= '1';
                        reg_tx <= reg_tx(6 downto 0) & '0';
                    elsif ct_bit(0) = '1' and t_clk = CLK_DIV then 		--SCLK negedge                       
                        mosi <= reg_tx(7);
                        next_state <= tx_state;
                        clk_en <= '1';
                    elsif ct_bit = x"10" and t_clk = (CLK_DIV-'1') then --the last data
--                        cs <= '0';
                        clk_en <= '0';                    
                        --mosi <= '0';                        
                        next_state <= tx_end;
--                        if CLK_DIV = x"01" then
--                            data_out <= reg_rx;
--                        end if;
                    elsif ct_bit = x"10" then
								data_valid <= '1';
                        data_out <= reg_rx;
                    else
--                        cs <= '0';
                        clk_en <= '1';
                        next_state <= tx_state;
                    end if;
                when tx_end => 
--                    cs <= '1';
                    clk_en <= '0';                    
                    mosi <= '0';						  
                    next_state <= idle;
						  spi_busy <= '0';
						  data_valid <= '0';
            end case;
        end if;
    end process;
end Behavioral;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值