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

📄 ip4290307.vhd

📁 接收429码的程序,对军工操作时很有用,希望有人喜欢!
💻 VHD
字号:
--程序功能:接收ARINC429信号,自动识别速度大小,读取的数据不存储,在间歇周期输出
--程序接口:5M时钟输入,片选,复位,同步时钟输入,串行数据输入,输出间歇周期指示,
--		   输出速度指示,输出并行数据
--其他说明:2008年3月7日由徐志兵创建
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_1164.all;

entity ip4290307 is
port(
             clk20m : in    std_logic;
                 cs : in    std_logic;
              reset : in    std_logic;
            syn_clk : in    std_logic;
        serial_data : in    std_logic;
		      speed : out   std_logic_vector(1 downto 0);
		      inter : out   std_logic;
			saveclk : out	std_logic;--增加为了给下级存储器存储用。
--	       tregdata : out   std_logic_vector(31 downto 0);--仿真查看用
--	 	 cchk_count : out   std_logic_vector(7 downto 0);--仿真查看用
      parallel_data : out   std_logic_vector(31 downto 0)
      );
end ip4290307;

architecture a of ip4290307 is

signal   sampling_reg : std_logic_vector(9 downto 0);--采样寄存器,判断间歇周期用
signal          count : std_logic_vector(7 downto 0);--用来做延时1us,读取数据用
signal   sampling_clk : std_logic_vector(6 downto 0);--采用时钟
signal       reg_data : std_logic_vector(31 downto 0);--32位寄存器,读取数据时用
signal      chk_count : std_logic_vector(7 downto 0);--识别速度用
signal     temp_count : std_logic_vector(3 downto 0);--给chk_count清零用
signal       high_low : std_logic_vector(1 downto 0);--速度指示
signal      reg_count : std_logic_vector(7 downto 0);--存储频率计计数值
signal		   clk5ma : std_logic;
signal		   clk10m : std_logic;
signal		   clk5mc : std_logic;
signal		  clk10ma : std_logic;
signal		 divcount : std_logic_vector(1 downto 0);
signal		savecount : std_logic_vector(7 downto 0);
signal      clearance : std_logic;--间歇周期指示

begin

--12.5K 半周期40us  80*4 = 320us  40/0.2=200 1100 1000
--  48K 半周期10us  20*4 =  80us  10/0.2=50    11 0010
-- 100K 半周期 5us  10*4 =  40us   5/0.2=25     1 1001
-- 250K 半周期 2us   4*4 =  16us   2/0.2=10       1010

--	为了测试增加的寄存器
--	cchk_count <= count;
--	tregdata <= reg_data;
	speed <= high_low;
	inter <= clearance;
--	为了测试增加的寄存器

process(clk20m)
begin
if rising_edge(clk20m) then
	divcount <= divcount+1;
end if;
end process;

clk5ma <= not divcount(1);
clk10m <= divcount(0);
clk5mc <= divcount(1);
clk10ma <= not divcount(0);

process(clk5ma,syn_clk,chk_count,temp_count,reg_count)--识别速度,0.2us
begin
if (syn_clk = '1') then
	temp_count <= "0000";
	if falling_edge(clk5ma) then--对同步时钟为高时进行计数相当于频率计
		chk_count <= chk_count + 1;
	end if;
else 
	if temp_count = "0101" then--同步时钟为低时,把计数值存起来,一个低电平只赋一次
		reg_count <= chk_count;	
	end if;
	if falling_edge(clk5ma) then--一个低电平只能赋值一次,不然计数器清零时,寄存器的值跟着变
		if temp_count = "0110" then--一直留在“0110”上
			temp_count <= temp_count;
			chk_count <= "00000000";--低电平时要给高电平计数器清零以备下次频率采集
		else
			temp_count <= temp_count + 1;
		end if;
	end if;
end if;
--本身频率是有误差的,25%的范围,以前没有考虑这个问题
if (reg_count >= "00001000") and (reg_count <= "00001100") then--250k(0.25的余量)
	high_low <= "00";
elsif (reg_count >= "00010011") and (reg_count <= "00011111") then--100k(0.25的余量)
	high_low <= "01";
elsif (reg_count >= "00100110") and (reg_count <= "00111110") then--48k(0.25的余量)
	high_low <= "10";
elsif (reg_count >= "10010110") and (reg_count <= "11111010") then--12.5K(0.25的余量)
	high_low <= "11";
else
	high_low <= "10";
end if;
end process;

--12.5K 半周期40us  80*4 = 320us  40/0.2=200 1100 1000
--  48K 半周期10us  20*4 =  80us  10/0.2=50    11 0010
-- 100K 半周期 5us  10*4 =  40us   5/0.2=25     1 1001
-- 250K 半周期 2us   4*4 =  16us   2/0.2=10       1010

process(clk10m)--分频产生采样周期	sampling_clk(2):1.25M(0.8us),
--                  	            sampling_clk(3):0.625M(1.6us),
--                      	        sampling_clk(4):0.3125M(3.2us),
--                          	    sampling_clk(5):0.15625M(6.4us),
--                              	sampling_clk(6):0.078125M(12.8us),
begin
if rising_edge(clk10m) then
	sampling_clk<=sampling_clk + 1;
end if;
end process;

process(sampling_clk,syn_clk,high_low,cs,reset,sampling_reg)--寻找间歇周期
variable i,j,k,l : natural range 0 to 9 := 0;--从0开始,不是1
begin
if (cs = '1') then--片选
	if (reset = '1') then--非复位
		if (high_low = "00") then--250k   2us   4*4 =  16us   2/0.2=10       1010
			if syn_clk = '1' then--同步时钟过来立即进入非间隙周期
				clearance <= '0';
				i := 0;--不清零会重复启动,复位到初始状态  
			else--同步时钟为低电平时寻找间歇周期
				if rising_edge(sampling_clk(2)) then--sampling_clk(2):1.25M(0.8us)
					if i >= 6 then--因为在非间歇周期的低电平中根本到不了6,所有就没有赋值的过程
						i := 0;
						if sampling_reg = "0000000000" then
							clearance <= '1';
						end if;
					else
						sampling_reg(i)<=syn_clk;
						i := i + 1;
					end if;
				end if;
			end if;
		elsif (high_low = "01") then--100k   5us  10*4 =  40us   5/0.2=25     1 1001
			if syn_clk = '1' then
				clearance <= '0';
				j := 0;
			else
				if rising_edge(sampling_clk(3)) then--sampling_clk(3):0.625M(1.6us)
					if j = 9 then
						j := 0;
						if sampling_reg = "0000000000" then
							clearance <= '1';
						end if;
					else
						sampling_reg(j)<=syn_clk;
						j := j + 1;
					end if;
				end if;
			end if;
		elsif (high_low = "10") then--48k   10us  20*4 =  80us  10/0.2=50    11 0010
			if syn_clk = '1' then
				clearance <= '0';
				k := 0;
			else
				if rising_edge(sampling_clk(4)) then--sampling_clk(4):0.3125M(3.2us)	
					if k = 9 then
						k := 0;
						if sampling_reg = "0000000000" then
							clearance <= '1';
						end if;
					else
						sampling_reg(k)<=syn_clk;
						k := k + 1;
					end if;
				end if;
			end if;
		elsif (high_low = "11") then--12.5k 40us  80*4 = 320us  40/0.2=200 1100 1000
			if syn_clk = '1' then
				clearance <= '0';
				l := 0;
			else
				if rising_edge(sampling_clk(6)) then--sampling_clk(6):0.078125M(12.8us)		
					if l = 9 then
						l := 0;
						if sampling_reg = "0000000000" then
							clearance <= '1';
						end if;
					else
						sampling_reg(l)<=syn_clk;
						l := l + 1;
					end if;
				end if;
			end if;
		end if;
	else--复位
		sampling_reg <= "0000000000";
		clearance <= '0';
		i := 0;
		j := 0;
		k := 0;
		l := 0;
	end if;
else--非片选
	sampling_reg <= "0000000000";
	clearance <= '0';
	i := 0;
	j := 0;
	k := 0;
	l := 0;	
end if;
end process;

--最大的半祯40us,5M 0.2us,40/0.2=200 1100 1000 count至少需8位才能 保证只读1次
process(cs,reset,clearance,clk5mc,syn_clk,reg_data)
variable m : natural range 0 to 31 := 0;
begin
if (cs = '1') then--片选
	if (reset = '1') then--非复位
		if clearance = '1' then--间歇周期
			parallel_data <= reg_data;--输出数据到并口
			m := 0;
		else--非间歇周期
			if syn_clk = '1' then--同步时钟过来
				if rising_edge(clk5mc) then
					count <= count + 1;--只要同步时钟是高电平就不停止计数
					if count = "00000101" then--延时1us
						reg_data(m) <= serial_data;--读取串行数据
						m := m+1;
					end if;
				end if;
			else
				count <= "00000000";
			end if;
		end if;
	else--复位
		m := 0;
		count <= "00000000";
		reg_data <= "00000000000000000000000000000000";
	end if;	
else--非片选			
	m := 0;
	count <= "00000000";
	reg_data <= "00000000000000000000000000000000";
end if;
end process;

process(clk10ma,clearance,savecount)
begin

if clearance = '1' then
	if rising_edge(clk10ma) then
		if savecount = "11111110" then
			savecount <= "11111110";
		else
			savecount <= savecount + 1;
		end if;
	end if;
else
	savecount <= "00000000";
end if;

if savecount = "00101000" then
	saveclk <= '1';
end if;
if savecount = "01111000" then
	saveclk <= '0';		 
end if;

end process;

end a;

⌨️ 快捷键说明

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