在电子设计中,通常我们会遇到FPGA和MCU联合开发的问题,而SPI是一种用于二者通信的好方式。在本代码中,并行输入可变长度的数据,串行输出,实用性非常好,可作为模块进行移植。(以128位为例)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity SPI is
port(
Data_Bus: in std_logic_vector(127 downto 0); --数据输入
Data_Valid: in std_logic; --数据发送有效,检测到下降沿开始发送
Sys_Rst,Sys_Clk: in std_logic; --复位端,高电平复位;时钟信号
SPI_CE,SPI_Clk,SPI_Data: out std_logic); --SPI的三条线
end entity;
architecture Behavior_SPI_Port of SPI is
signal Data_Int,Data_Res: std_logic; --
signal SPI_Reg: std_logic_vector(127 downto 0); --发送数据缓存
signal Bit_Cnt: integer range 0 to 128; --发送数据位
signal Step_cnt: integer range 0 to 5; --状态机
signal start,spi_clk_temp,spi_ce_temp,spi_data_temp: std_logic:='0';
begin
SPI_CE<=spi_ce_temp;
SPI_Clk<=SPI_clk_temp;
spi_Data<=spi_data_temp;
process(Data_Valid,Sys_Clk)
begin
if(Sys_Clk'event and Sys_Clk='0') then
start<=Data_Valid;
end if;
end process;
process(start,Data_Res)
begin
if(Data_Res='1' or Sys_Rst='1')then
Data_Int<='0';
elsif(start'event and start='0')then
SPI_Reg<=Data_Bus;
Data_Int<='1';
end if;
end process;
process(Sys_Rst,Sys_Clk,Data_Int)
begin
if(Sys_Rst='1')then
Step_Cnt<=0;
spi_ce_temp<='0';
spi_clk_temp<='0';
Bit_Cnt<=0;
elsif(Sys_Clk'event and Sys_Clk='1')then
case Step_Cnt is
when 0=> if(Data_Int='1')then
Step_Cnt<=Step_Cnt+1;
Data_Res<='1';
Bit_Cnt<=0;
end if;
when 1=> spi_ce_temp<='1';
Step_Cnt<=Step_Cnt+1;
when 2=> spi_data_temp<=SPI_Reg(Bit_Cnt);
Step_Cnt<=Step_Cnt+1;
when 3=> spi_clk_temp<='1';
Step_Cnt<=Step_Cnt+1;
when 4=> spi_clk_temp<='0';
if(Bit_Cnt=127)then
Step_Cnt<=Step_Cnt+1;
else
Bit_Cnt<=Bit_Cnt+1;
Step_Cnt<=2;
end if;
when 5=> Data_Res<='0';
Step_Cnt<=0;
when others=>Step_Cnt<=0;
end case;
end if;
end process;
end Behavior_SPI_Port;