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

📄 r429.vhd

📁 另一个读429码操作IP,对军工时很有用,希望有人喜欢!
💻 VHD
字号:
--功能介绍:对429码进行读取,自动识别低速还是高速,读取后存入寄存器
--接口定义:5M时钟输入,片选,同步时钟输入,串行数据输入,地址输入,数据输出,存储状态输出
--修改记录:2008年2月12日由徐志兵创建
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_1164.all;

entity r429 is
port(
              clk5m : in  std_logic;--5M输入 
                 cs : in  std_logic;--片选信号
              reset : in  std_logic;--复位信号
            syn_clk : in  std_logic;--需读的串行数据同步时钟既两个运放输出经过两个或门后的信号
               addr : in  std_logic_vector(7 downto 0);--读取数据地址
        serial_data : in  std_logic;--需读的串行数据
      parallel_data : out std_logic_vector(15 downto 0);--输出16位并行数据
           high_low : out std_logic_vector(1 downto 0);--输出读取的是什么速度的信号
          clearance : out std_logic;--输出间隙周期指示
        half_buffer : out std_logic--'1'表示存储器存储过半
      );
end r429;

architecture a of r429 is
signal      count_clk : std_logic;--控制延时1us的时钟
signal         ot_clk : std_logic;--产生采样时钟sampling_clk
signal   sampling_reg : std_logic_vector(14 downto 0);--采样信息寄存器
signal          count : std_logic_vector(7 downto 0);--计数器大于脉冲(100K传输)宽度
signal   sampling_clk : std_logic_vector(5 downto 0);--不同的采样时钟寻找间隙的时钟
signal       reg_data : std_logic_vector(31 downto 0);--32位寄存器
signal      chk_count : std_logic_vector(7 downto 0);--检测周期计数器
signal      reg_count : std_logic_vector(5 downto 0);--64组32位存储计数器
signal      pul_count : std_logic_vector(4 downto 0);--32位采集计数器

begin

process(clk5m,syn_clk)--识别周期大小,0.2us,用下降沿,上升沿可能会有竞争冒险现象,多出一个周期
begin
if (syn_clk = '1') then
	if falling_edge(clk5m) then
		chk_count <= chk_count + 1;
	end if;
else 
	chk_count <= "00000000";
end if;
end process;

process(chk_count)
begin 
if chk_count =    "00001010" then--250k速度
	high_low <= "00";
elsif chk_count = "00011001" then--100k速度
	high_low <= "01";
elsif chk_count = "00110010" then--48k速度
	high_low <= "10";
elsif chk_count = "11001000" then--12.5K速度
	high_low <= "11";
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(clk5m)--分频产生采样时钟sampling_clk(1):1.25M(0.8us),用来检测间隙,启动读周期
--                              sampling_clk(2):0.625M(1.6us),
--                              sampling_clk(3):0.3125M(3.2us),
--                              sampling_clk(4):0.15625M(6.4us),
--                              sampling_clk(5):0.078125M(12.8us),
begin
if rising_edge(clk5m) then
	sampling_clk<=sampling_clk+1;
end if;
end process;

process(sampling_clk,syn_clk,high_low,cs,reset)--检测间隙周期
begin
if (cs = '1') then--片选
	if (reset = '1') then--低电平复位
		loop--死循环,时刻检测间隙周期
			if (high_low = "00") then--250k  半帧为 2us   4*4 =  16us   2/0.2=10       1010
				for i in 0 to 12 loop--采样10us 
					if sampling_clk(1)='1' then--sampling_clk(1):1.25M(0.8us)
						sampling_reg(i)<=syn_clk;--对同步信号进行采样以寻找间隙周期
					end if;
				end loop;
				if (sampling_reg="000000000000000") then
					clearance <= '1';--读使能信号
				end if;
				if syn_clk = '1' then
					clearance <= '0';
				end if;
			elsif (high_low = "01") then--100k  半帧为 5us  10*4 =  40us   5/0.2=25     1 1001
				for i in 0 to 12 loop--采样20us 
					if sampling_clk(2)='1' then--sampling_clk(2):0.625M(1.6us)
						sampling_reg(i)<=syn_clk;--对同步信号进行采样以寻找间隙周期
					end if;
				end loop;
				if (sampling_reg="000000000000000") then
					clearance <= '1';--读使能信号
				end if;
				if syn_clk = '1' then
					clearance <= '0';
				end if;
			elsif (high_low = "10") then--48k   半帧为10us  20*4 =  80us  10/0.2=50    11 0010
				for i in 0 to 14 loop--采样50us 
					if sampling_clk(3)='1' then--sampling_clk(3):0.3125M(3.2us)
						sampling_reg(i)<=syn_clk;--对同步信号进行采样以寻找间隙周期
					end if;
				end loop;
				if (sampling_reg="000000000000000") then
					clearance <= '1';--读使能信号
				end if;
				if syn_clk = '1' then
					clearance <= '0';
				end if;
			elsif (high_low = "11") then--12.5k 半帧为40us  80*4 = 320us  40/0.2=200 1100 1000
				for i in 0 to 14 loop--采样200us 
					if sampling_clk(5)='1' then--sampling_clk(5):0.078125M(12.8us)
						sampling_reg(i)<=syn_clk;--对同步信号进行采样以寻找间隙周期
					end if;
				end loop;
				if (sampling_reg="000000000000000") then
					clearance <= '1';--读使能信号
				end if;
				if syn_clk = '1' then
					clearance <= '0';
				end if;
			end if;
		end loop;
	else--复位
		sampling_reg <= "000000000000000";
		clearance <= '0';
	end if;
else--非片选
	sampling_reg <= "000000000000000";
	clearance <= '0';
end if;
end process;

--最长的半祯是40us,5M是0.2us,40/0.2=200 1100 1000 所以count至少要8位才能 保证不重复读取
process(cs,reset,clearance,clk5m,syn_clk)--在信号稳定后1us进行读数
begin
if (cs = '1') then--片选
	if (reset = '1') then--低电平复位
		if clearance = '1' then--间隙周期
			pul_count <= "00000";
		else--非间隙周期
			if syn_clk = '1' then--同步时钟
				if rising_edge(clk5m) then--上升沿计数
					if count = "00000101" then--延时1us读数
						reg_data(j) <= serial_data;--读取数据
					else
						count <= count + 1;
					end if;
				end if;
			else
					count <= "00000000";
			end if;
		end if;			



	L1:	loop
		L2:	for k in 0 to 63 loop--设置存储深度为64组
			L3:	for j in 0 to 31 loop--循环读数32次
				if clearance = '1' then--间隙周期
					exit L3;--如果碰到间隙周期,立即退出循环进行下一次读取,防止从数据中部开始
				else--非间隙周期
					if syn_clk = '1' then--同步时钟
						if rising_edge(clk5m) then--上升沿计数
							if count = "00000101" then--延时1us读数
								reg_data(j) <= serial_data;--读取数据
							else
								count <= count + 1;
							end if;
						end if;
					else
							count <= "00000000";
					end if;
				end loop;
			reg_count(k) <= reg_data;
			end if;	
			

parallel_data<=reg_data;

end a;

⌨️ 快捷键说明

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