📄 codeacq.vhd
字号:
--本程序实现扩频码的捕获与跟踪
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_SIGNED.ALL;
LIBRARY LPM;
USE LPM.LPM_COMPONENTS.ALL;
ENTITY CODEACQ IS
PORT( CLK: IN STD_LOGIC;
IDIN: IN SIGNED(15 DOWNTO 0);
QDIN: IN SIGNED(15 DOWNTO 0);
MAG: IN SIGNED(31 DOWNTO 0);
RESET: IN STD_LOGIC;
THRESHOLD: IN SIGNED(15 DOWNTO 0);
WINDOW: OUT STD_LOGIC;
SYNC: OUT STD_LOGIC;
SYMCLK: OUT STD_LOGIC;
BITRATE: OUT STD_LOGIC;
ACQ: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
DIVE: OUT SIGNED(3 DOWNTO 0);
DIVENA: OUT STD_LOGIC;
HIGH: OUT STD_LOGIC;
LOW: OUT STD_LOGIC;
IOUT: OUT SIGNED(15 DOWNTO 0);
QOUT: OUT SIGNED(15 DOWNTO 0)
);
END CODEACQ;
ARCHITECTURE ACQ_ARCH OF CODEACQ IS
TYPE STATE_TYPE IS (S0,S1,S2);
SIGNAL STATE: STATE_TYPE;
SIGNAL COUNTER: INTEGER RANGE 0 TO 255;
SIGNAL VWINDOW: STD_LOGIC;
SIGNAL LOCATION: INTEGER RANGE 0 TO 255 ;
SIGNAL EXTREMUM: SIGNED(31 DOWNTO 0);
SIGNAL FLAG: INTEGER RANGE 0 TO 255;
SIGNAL STEP: INTEGER RANGE 0 TO 63;
SIGNAL FALSE: INTEGER RANGE 0 TO 127;
SIGNAL POSITION: INTEGER RANGE 0 TO 255;
SIGNAL ACQONE: STD_LOGIC;
SIGNAL ACQTWO: STD_LOGIC;
SIGNAL SIXTEEN: INTEGER RANGE 0 TO 15;
SIGNAL EARLYPRODUCT: SIGNED(31 DOWNTO 0);
SIGNAL LATEPRODUCT: SIGNED(31 DOWNTO 0);
SIGNAL SYM_CLK: STD_LOGIC;
SIGNAL FAST: STD_LOGIC;
SIGNAL SLOW: STD_LOGIC;
SIGNAL CIRCULAR: INTEGER RANGE 0 TO 127;
SIGNAL STOREHIGH: INTEGER RANGE 0 TO 127;
SIGNAL STORELOW: INTEGER RANGE 0 TO 127;
SIGNAL STOREZERO: INTEGER RANGE 0 TO 127;
SIGNAL CYCLE: INTEGER RANGE 0 TO 63;
SIGNAL OFFSET: INTEGER RANGE 0 TO 127;
SIGNAL TRACKCYCLE: INTEGER RANGE 0 TO 127;
SIGNAL TCK: INTEGER RANGE 0 TO 127;
SIGNAL CIRCULARHIGH: INTEGER RANGE 0 TO 127;
SIGNAL CIRCULARLOW: INTEGER RANGE 0 TO 127;
SIGNAL THCOUNTER: INTEGER RANGE 0 TO 255; --计算均值时所用计数器
BEGIN
WINDOW <= VWINDOW;
SYNC <= SYM_CLK;
HIGH <= FAST;
LOW <= SLOW;
OFFSET <= 48;
TCK <= 63;
STORELOW <= 0;
STOREHIGH <= 31;
STOREZERO <= 15;
PROCESS(STATE)
BEGIN
CASE STATE IS
WHEN S0 =>
ACQ <= "00";
WHEN S1 =>
ACQ <= "01";
WHEN S2 =>
ACQ <= "11";
END CASE;
END PROCESS;
PROCESS(CLK,RESET)
BEGIN
IF RESET = '0' THEN
COUNTER <= 0;
ELSE
IF CLK'EVENT AND CLK='1' THEN
IF COUNTER = 255 THEN
COUNTER <= 0;
ELSE
COUNTER <= COUNTER + 1;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,COUNTER,RESET)
BEGIN
IF RESET = '0' THEN
CYCLE <= 0;
SIXTEEN <= 0;
ELSE
IF CLK'EVENT AND CLK='1' THEN
IF COUNTER = 255 THEN
IF SIXTEEN = 15 THEN
SIXTEEN <= 0;
ELSE
SIXTEEN <= SIXTEEN + 1;
END IF;
IF ACQONE = '1' THEN
IF CYCLE = 63 THEN
CYCLE <= 0;
ELSE
CYCLE <= CYCLE + 1;
END IF;
ELSE
CYCLE <= 0;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,COUNTER,CYCLE,RESET,SIXTEEN,STOREZERO)
VARIABLE IMAG: SIGNED(15 DOWNTO 0);
VARIABLE QMAG: SIGNED(15 DOWNTO 0);
VARIABLE IQMAG: SIGNED(15 DOWNTO 0);
VARIABLE THMAG: SIGNED(15 DOWNTO 0);
BEGIN
IF RESET = '0' THEN
ACQONE <= '0';
ACQTWO <= '0';
EXTREMUM <= (OTHERS=>'0');
FLAG <= 0;
LOCATION <= 0;
STEP <= 0;
FALSE <= 0;
POSITION <= 0;
EARLYPRODUCT <= (OTHERS => '0');
LATEPRODUCT <= (OTHERS => '0');
DIVENA <= '0';
DIVE <= "1001";
FAST <= '0';
SLOW <= '0';
CIRCULAR <= STOREZERO;
STATE <= S0;
THCOUNTER <= 0;
ELSE
IF CLK'EVENT AND CLK='1' THEN
CASE STATE IS
WHEN S0 => --当最大值未确定且门限值未超过时
CASE SIXTEEN IS
WHEN 0 => CASE COUNTER IS
WHEN 0 => EXTREMUM <= MAG;
FLAG <= 0;
WHEN 255 => IF MAG > EXTREMUM THEN
EXTREMUM <= MAG;
FLAG <= 255;
LOCATION <= 255;
ELSE
LOCATION <= FLAG;
END IF;
WHEN OTHERS => IF MAG > EXTREMUM THEN
FLAG <= COUNTER;
EXTREMUM <= MAG;
END IF;
END CASE;
WHEN 15 => CASE COUNTER IS
WHEN 0 => EXTREMUM <= MAG;
FLAG <= 0;
WHEN 255 => IF MAG > EXTREMUM THEN
EXTREMUM <= MAG;
FLAG <= 255;
IF LOCATION = 255 AND STEP = 6 THEN
STATE <= S1;
POSITION <= LOCATION;
STEP <= 0;
END IF;
ELSE
IF LOCATION = FLAG AND STEP = 6 THEN
STATE <= S1;
POSITION <= LOCATION;
STEP <= 0;
END IF;
END IF;
WHEN OTHERS => IF MAG > EXTREMUM THEN
EXTREMUM <= MAG;
FLAG <= COUNTER;
END IF;
END CASE;
WHEN OTHERS => CASE COUNTER IS
WHEN 0 => EXTREMUM <= MAG;
FLAG <= 0;
WHEN 255 => IF MAG > EXTREMUM THEN
EXTREMUM <= MAG;
FLAG <= 255;
IF LOCATION = 255 THEN
STEP <= STEP + 1; END IF; ELSE
IF LOCATION = FLAG THEN
STEP <= STEP + 1; END IF;
END IF;
WHEN OTHERS => IF MAG > EXTREMUM THEN
EXTREMUM <= MAG;
FLAG <= COUNTER;
END IF;
END CASE;
END CASE;
WHEN S1 => --最大值已经确定,但未通过门限检验
IF COUNTER = POSITION THEN
IMAG := ABS(IDIN);
QMAG := ABS(QDIN);
IF IMAG > QMAG THEN
IQMAG := IMAG + ('0'&QMAG(15 DOWNTO 1));
ELSE
IQMAG := QMAG + ('0'&IMAG(15 DOWNTO 1));
END IF;
IF THCOUNTER = 255 THEN
IF THMAG > THRESHOLD THEN
STATE <= S2;
ELSE
STATE <= S0;
END IF;
ELSE
THCOUNTER <= THCOUNTER + 1;
THMAG := THMAG - ('0'&'0'&'0'&'0'&'0'&'0'
&THMAG(15 DOWNTO 6)) + ('0'&'0'&'0'&'0'&'0'&'0'&IQMAG(15 DOWNTO 6));
END IF;
ELSIF COUNTER = POSITION - 1 THEN
EARLYPRODUCT <= MAG;
ELSIF COUNTER = POSITION + 1 THEN
LATEPRODUCT <= MAG;
ELSIF COUNTER = 255 THEN
IF CIRCULAR = STOREHIGH THEN
DIVE <= "1010";
CIRCULAR <= STOREZERO;
DIVENA <= '1';
SLOW <= '1';
FAST <= '0';
ELSIF CIRCULAR = STORELOW THEN
DIVE <= "1000";
CIRCULAR <= STOREZERO;
DIVENA <= '1';
FAST <= '1';
SLOW <= '0';
ELSE
IF EARLYPRODUCT > LATEPRODUCT THEN
CIRCULAR <= CIRCULAR - 1;
ELSIF EARLYPRODUCT < LATEPRODUCT THEN
CIRCULAR <= CIRCULAR + 1;
END IF;
DIVE <= "1001";
DIVENA <= '0';
FAST <= '0';
SLOW <= '0';
END IF;
ELSE
DIVENA <= '0';
FAST <= '0';
SLOW <= '0';
DIVE <= "1001";
END IF;
WHEN S2 => --最大值已经锁定,而且门限检验也已经通过
IF COUNTER = POSITION THEN
IMAG := ABS(IDIN);
QMAG := ABS(QDIN);
IF IMAG > QMAG THEN
IQMAG := IMAG + ('0'&QMAG(15 DOWNTO 1));
ELSE
IQMAG := QMAG + ('0'&IMAG(15 DOWNTO 1));
END IF;
IF THCOUNTER = 255 THEN
IF THMAG > THRESHOLD THEN
STATE <= S2;
ELSE
STATE <= S0;
END IF;
ELSE
THCOUNTER <= THCOUNTER + 1;
THMAG := THMAG - ('0'&'0'&'0'&'0'&'0'&'0'
&THMAG(15 DOWNTO 6)) + ('0'&'0'&'0'&'0'&'0'&'0'&IQMAG(15 DOWNTO 6));
END IF;
ELSIF COUNTER = POSITION - 1 THEN
EARLYPRODUCT <= MAG;
ELSIF COUNTER = POSITION + 1 THEN
LATEPRODUCT <= MAG;
ELSIF COUNTER = 255 THEN
IF CIRCULAR = STOREHIGH THEN
DIVE <= "1010";
CIRCULAR <= STOREZERO;
DIVENA <= '1';
SLOW <= '1';
FAST <= '0';
ELSIF CIRCULAR = STORELOW THEN
DIVE <= "1000";
CIRCULAR <= STOREZERO;
DIVENA <= '1';
FAST <= '1';
SLOW <= '0';
ELSE
IF EARLYPRODUCT > LATEPRODUCT THEN
CIRCULAR <= CIRCULAR - 1;
ELSIF EARLYPRODUCT < LATEPRODUCT THEN
CIRCULAR <= CIRCULAR + 1;
END IF;
DIVE <= "1001";
DIVENA <= '0';
FAST <= '0';
SLOW <= '0';
END IF;
ELSE
DIVENA <= '0';
FAST <= '0';
SLOW <= '0';
DIVE <= "1001";
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,COUNTER,STATE,RESET)
BEGIN
IF RESET = '0' THEN
VWINDOW <= '0';
IOUT <= (OTHERS=>'0');
QOUT <= (OTHERS=>'0');
ELSE
IF CLK'EVENT AND CLK='0' THEN
IF STATE = S2 THEN
IF SYM_CLK = '1' THEN
IOUT <= IDIN;
QOUT <= QDIN;
END IF;
END IF;
IF COUNTER = POSITION - 1 OR COUNTER = POSITION OR COUNTER = POSITION + 1 THEN
VWINDOW <= '1';
ELSE
VWINDOW <= '0';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,COUNTER,STATE,RESET)
BEGIN
IF RESET = '0' THEN
SYM_CLK <= '0';
ELSE
IF CLK'EVENT AND CLK='1' THEN
IF STATE = S2 THEN
IF COUNTER = POSITION-1 THEN
SYM_CLK <= '1';
ELSE
SYM_CLK <= '0';
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,COUNTER,POSITION,RESET)
VARIABLE MOBILE: INTEGER RANGE 0 TO 255;
VARIABLE CENTRINO: STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
IF RESET = '0' THEN
MOBILE := 0;
ELSE
IF CLK'EVENT AND CLK='1' THEN
MOBILE := COUNTER - POSITION;
END IF;
END IF;
CENTRINO := CONV_STD_LOGIC_VECTOR(MOBILE,8);
SYMCLK <= CENTRINO(7);
BITRATE <= CENTRINO(6);
END PROCESS;
END ACQ_ARCH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -