?? 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 + -