📄 pn_correlation_fsm.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.ch_fifo_pack.all;
entity pn_correlation_fsm is
port (
clk, reset, pn_fnd : in std_logic;
wr_addr_srst : out std_logic;
pn_lock, pn_acq, wr : out std_logic);
end pn_correlation_fsm;
architecture rtl of pn_correlation_fsm is
type states is (init, pn_search, pn_fnd1, locked);
signal ns, cs : states;
signal pn_addr_cntr : std_logic_vector(10 downto 0);
signal eight_cnt : std_logic_vector (2 downto 0);
signal pn_acq_q0 : std_logic;
signal eight_cnt_tc : std_logic;
signal pn_acq_i : std_logic;
begin -- rtl
process (clk, reset)
begin -- process
if reset = '1' then
cs <= init;
elsif rising_edge(clk) then
cs <= ns;
end if;
end process;
--_____________________________________________________________________
-- pn_correlation_fsm
--_____________________________________________________________________
process (cs, pn_fnd, pn_addr_cntr, eight_cnt_tc, pn_acq_q0)
begin
-- default
ns <= cs;
case cs is
when init =>
ns <= pn_search;
when pn_search =>
if pn_fnd = '1' then
ns <= pn_fnd1;
end if;
when pn_fnd1 =>
if (pn_fnd and pn_acq_q0) /= '0' and (pn_addr_cntr /= conv_std_logic_vector(0, 11)) then
ns <= locked;
elsif ((not pn_fnd and pn_acq_q0) /= '0') and (pn_addr_cntr /= conv_std_logic_vector(0, 11)) then
ns <= pn_search;
end if;
when locked =>
if pn_fnd = '0' and pn_acq_q0 = '1' then
ns <= pn_search;
end if;
when others =>
ns <= init;
end case;
end process;
pn_lock <= '1' when (cs = locked) else '0';
wr_addr_srst <= '1' when (cs = pn_search) else '0';
--_____________________________________________________________________
-- Count eight clock cycles. After eight clock cycles, tc = 1 which enables
-- the writing of data into fifo (once a pn_fnd is true) and enables the big
-- counter which counts through 256 8bit data samples. After every 256 8bit
-- data samples, pn is searched for.
--_____________________________________________________________________
eight_cnt_tc <= and_reduce(eight_cnt);
count_eight_bits: process (clk, reset)
begin
if (reset = '1') then
eight_cnt <= (others => '0');
elsif rising_edge(clk) then
-- default
eight_cnt <= (others => '0');
case ns is
when pn_search =>
if pn_fnd = '1' then
eight_cnt <= eight_cnt + 1;
end if;
when pn_fnd1 | locked =>
eight_cnt <= eight_cnt + 1;
when others => null;
end case;
end if;
end process;
--_____________________________________________________________________
-- Create pn_addr_cntr which counts the number of clock cycles since the
-- first pn_fnd occured. This address indicates the locations where the
-- next pn should be found.
--_____________________________________________________________________
create_pn_addr_cntr: process (clk, reset)
begin
if reset = '1' then
pn_addr_cntr <= (others => '0');
elsif rising_edge(clk) then
case ns is
when pn_search =>
if pn_fnd = '1' then
pn_addr_cntr <= pn_addr_cntr + 1;
else
pn_addr_cntr <= (others => '0');
end if;
when pn_fnd1 | locked =>
if (eight_cnt_tc = '1') then
pn_addr_cntr <= pn_addr_cntr + 1;
end if;
when others =>
pn_addr_cntr <= (others => '0');
end case;
end if;
end process create_pn_addr_cntr;
--_____________________________________________________________________
-- Create pn_acq signal to indicate to the pn_correlator to search for pn
--_____________________________________________________________________
pn_acq <= pn_acq_i;
create_pn_acq: process (clk, reset)
begin
if reset = '1' then
pn_acq_i <= '0';
pn_acq_q0 <= '0';
elsif rising_edge(clk) then
-- defaults
pn_acq_i <= '0';
pn_acq_q0 <= pn_acq_i;
for j in 0 to 8 loop
if j = 0 and cs = pn_fnd1 then -- this prevents the fsm from looking for a pn on two consecutive 8bit samples
pn_acq_i <= '0';
elsif (pn_addr_cntr = (j*256 -1) and eight_cnt = "110") or ns = pn_search then
pn_acq_i <= '1';
end if;
end loop; -- j
end if;
end process create_pn_acq;
--_____________________________________________________________________
-- Create wr signal for fifo
--_____________________________________________________________________
create_wr: process (clk, reset)
begin
if reset = '1' then
wr <= '0';
elsif rising_edge(clk) then
-- default
wr <= '0';
if (eight_cnt = "110") then -- enabled only every 8 clock cycles (clock enable = eight_cnt_tc)
wr <= '1';
for k in 0 to 8 loop
if pn_addr_cntr = k*256 -1 then -- disable when it is time
-- to look for PN code
wr <= '0';
end if;
end loop; -- k
end if;
end if;
end process create_wr;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -