----------------------------------------------
-- MSS copyright 2013
-- Filename: FREQ_SCAN.VHD
-- VHDL code for receiver frequency scan
-- Author: Alain Zarembowitch / MSS
-- Edit date:  3/19/13
-- Revision: 0
-- Inheritance: n/a
--
-- scanning frequency pattern: 0, +1, -1, +2, -2,   up to +N_STEPS then again
----------------------------------------------      
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FREQ_SCAN is
	port (  
	--// GLOBAL CLOCKS
   CLK : in std_logic;				-- System clock for this FPGA
	SYNC_RESET: in std_logic;

	--// INPUTS
	FREQUENCY_STEP: in std_logic_vector(31 downto 0);
		-- typically 10% of the modulation symbol rate
	N_STEPS: in std_logic_vector(7 downto 0);
		-- number of frequency acquisition steps in each direction
		-- total number of frequencies is thus 2*N_STEPS+1
		-- Step size is (symbol rate / 16)
	STEP_TRIGGER: in std_logic;
		-- 1 CLK-wide pulse to jump to the next frequency
		
	--// OUTPUT
	FREQUENCY_OUT: out std_logic_vector(31 downto 0)
);
end entity;  

architecture behavioral of FREQ_SCAN is
-----------------------------------------------------------------
-- COMPONENTS
-----------------------------------------------------------------
-----------------------------------------------------------------
-- SIGNALS
-----------------------------------------------------------------
-- Suffix _D denotes one CLK clock delayed version of the name with the same name
-- Suffix _N denotes the inverted (not) version of the net with the same name
-- Suffix _X denotes the precision extended version of the net with the same name

signal STEP_INDEX: std_logic_vector(N_STEPS'length downto 0) := (others => '0');
	-- twice the size of N_STEPS. LSb is the frequency sign
signal FREQUENCY: std_logic_vector(31 downto 0)  := (others => '0');
-----------------------------------------------------------------
-- IMPLEMENTATION
-----------------------------------------------------------------
begin   

-- scanning frequency pattern: 0, +1, -1, +2, -2,   up to +N_STEPS then again
SCANNING_PATTERN_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(SYNC_RESET = '1') then
			STEP_INDEX <= (others => '0');
			FREQUENCY <= (others => '0');
		elsif(STEP_TRIGGER = '1') then
			if(STEP_INDEX(N_STEPS'length downto 1) = N_STEPS) then
				-- restart from 0
				STEP_INDEX <= (others => '0');
				FREQUENCY <= (others => '0');
			else
				STEP_INDEX <= STEP_INDEX + 1;
				if(STEP_INDEX(0) = '0') then
					FREQUENCY <= FREQUENCY + FREQUENCY_STEP;
				end if;
			end if;
		end if;
	end if;
end process;

-- alternate positive and negative frequencies (outwards spiral pattern)
SCANNING_PATTERN_002: process(CLK)
begin
	if rising_edge(CLK) then
		if(STEP_INDEX(0) = '1') then
			FREQUENCY_OUT <= FREQUENCY;
		else
			FREQUENCY_OUT <= not FREQUENCY;
		end if;
	end if;
end process;


				
end behavioral;					