📄 r429.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 + -