⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc104_spi.vhd

📁 介绍了如何用vhdl语言实现处理器的spi接口
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

entity spi_top is
port( clk, wr_n, rd_n, misoi : in std_logic;
            irq, mosio, scko : out std_logic
                        addr : in std_logic_vector(9 downto 0);
                        data : inout std_logic_vector(7 downto 0);
                         rdy : in std_logic_vector(2 downto 0);
                     slv_sel : out std_logic_vector(2 downto 0));
end spi_top;

architecture spi of spi_top is
begin 

data <= shift_reg when addr=SPIFT_ADDR and rd_n='0' else
         stat_reg when addr=SPISR_ADDR and rd_n='0' else 
        "ZZZZZZZZ";
mosio <= shift_dataout when open_drain ='0' else 'Z';
sr_proc : process(clk)
begin
    if(clk'event and clk='1')then
       if(spi_go='1')then shift_reg<=data_reg;
       elsif(shift_clk='1')then
        shift_reg <= shift_reg(6 downto 0) & shift_datain;
       end if;
    end if;
end process;


neg_proc : process(clk)
begin
    if (clk'event and clk='1') then
       if (shift_clk_negedge='1') then
       shift_negative_edge <= shift_negative_edge_nxt;
       elsif (spi_go='1') then
       shift_negative_edge <= shift_reg(7);
       end if;
    end if;
end process;


shift_negative_edge_nxt <= shift_reg(7) when phase='1' else misoi;
shift_dataout <= shift_negative_edge when phase='1' else shift_reg(7);
shift_datain <= shift_negative_edge when phase='0' else misoi;


tr_proc : process(clk)
begin
     if (clk'event and clk='1') then
        if (tx_start='1') then tx_run <= '1';
        elsif (tx_end='1') then tx_run <= '0';
        end if;
     end if;
end process;


bc_proc : process(clk)
begin
      if (clk'event and clk='1') then
         if (tx_start='1') then bit_ctr <= bit_counter;
         elsif (shift_clk='1') then bit_ctr <= bit_ctr-1;
         end if;
      end if;
end process;

  tx_end <= '1' when bit_ctr=001 and shift_clk='1' and tx_run='1' else '0';
  tx_start <= '1' when spi_go='1' else '0';


elr_proc : process(clk)
begin
      if (clk'event and clk='1') then
         if (tx_end ='1')then irq_flag <='1';
         elsif (tx_run='1')then irq_flag <='0';
         end if;
      end if;
end process;


dvd_proc : process(clk)
begin
      if (clk'event and clk='1') then
         if (not (tx_run='1' ) or tx_end='1') then
         dvd_ctr <= "00000", dvd2 <= '0';
         else
           if (dvd_ctr=00000) then dvd_ctr <= clock_div;
             if(tx_start_r1 ='0')then dvd2 <= not dvd2;
             end if;
           else dvd_ctr <= dvd_ctr-1;
           end if;
         end if;
       end if;
end process;

         dvd_zero <= '1' when dvd_ctr=00000 else '0';
        shift_clk <= dvd_zero and dvd2 and tx_run and not tx_start_r1;
shift_clk_negedge <= dvd_zero and not dvd2 and tx_run;
             scko <= dvd2 xor polck;

wr_data : process(wr_n,tx_run)
begin
      if(tx_run='1')then spi_go<='0';
      elsif (wr_n'event and wr_n='1' ) then
         if( addr=spift_addr) then
         data_reg <= data, spi_go <='1';
         end if;
      end if;
end process;

wr_ctl : process(wr_n)
begin
     if (wr_n'event and wr_n='1') then
       if addr=spic_addr then ctl_reg <= data;
       end if;
     end if;
end process;

slv_sel(2 downto 0)<= ctl_reg(2 downto 0);
            irq_en <= ctl_reg(7), open_drain <= ctl_reg(6);
             phase <= ctl_reg(5), polck <= ctl_reg(4);
               irq <= irq_flag and ctl_reg(7);

stat_proc:process(rdy,irq_flag)
begin
stat_reg <= irq_flag & "0000" & rdy(2 downto 0);
end process;
end spi;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -