--
-- VHDL Architecture FACT_FAD_lib.REFCLK_counter.behavior
--
-- Created:
--          by - dneise.UNKNOWN (E5B-LABOR6)
--          at - 12:10:57 28.01.2011
--
-- using Mentor Graphics HDL Designer(TM) 2009.2 (Build 10)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;

library FACT_FAD_lib;
use FACT_FAD_lib.fad_definitions.all;

-- REFCLK counter counts rising edges on asynch REFCLK signal 
-- every ms a new value is returned.
-- expected REFCLK frequency: up to 3.3MHz --> 12bit should be enough
-- if the REFCLK id too low or too high, alarm outputs are generated

ENTITY REFCLK_counter IS
  PORT ( 
    clk : in std_logic;       -- 50MHz!
    refclk_in : in std_logic; -- asychronous signal
    counter_result : out std_logic_vector(11 downto 0) := (others => '0');
    
    alarm_refclk_too_high : out std_logic := '1';
    alarm_refclk_too_low : out std_logic := '1'
  );    
END ENTITY REFCLK_counter;

--
ARCHITECTURE behavior OF REFCLK_counter IS
  constant FREQ_UPPER_LIMIT : integer := 3000;
  constant FREQ_LOWER_LIMIT : integer := 300;
  constant TIMER_MAX : integer := 100000;
  
  signal refclk_in_sr : std_logic_vector(1 downto 0) := "00";
  signal gate_sr : std_logic_vector(1 downto 0) := "00";
  
  signal gate : std_logic := '0';
  signal time_sig : integer range 0 to TIMER_MAX-1; --2ms clock
  
  signal counter : integer range 0 to 4095 :=0 ;
BEGIN
  
  process (clk)
  begin
    if rising_edge( clk ) then
		refclk_in_sr <= refclk_in_sr(0) & refclk_in; -- synchronize REFCLK in
		gate_sr <= gate_sr(0) & gate;
		case gate_sr is
		when "00" =>
		when "01" => --rising edge
			counter <= 0;
		when "10" =>
			counter_result <= std_logic_vector( to_unsigned(counter,12) );
			if (counter < FREQ_LOWER_LIMIT ) then
			  alarm_refclk_too_low <= '1';
			else
			  alarm_refclk_too_low <= '0';
			end if;
			if (counter > FREQ_UPPER_LIMIT ) then
			  alarm_refclk_too_high <= '1';
			else
			  alarm_refclk_too_high <= '0';
			end if;
		when "11" =>
			if (refclk_in_sr = "01") then
				counter <= counter +1;
			end if;
		WHEN OTHERS =>
		end case;
	end if;
end process;    
  
  -- timer proc; generates 1ms gate
  gate_timer : process (clk)
  
  begin
    if rising_edge(clk) then
      if (time_sig < TIMER_MAX-1) then 
       time_sig <= time_sig + 1;
      else 
        time_sig <= 0;
      end if;
  
      if (time_sig = 0) then 
        gate <= '1';
      end if;
      if (time_sig = (TIMER_MAX/2)-1) then
        gate <= '0';
      end if;
    end if;
  end process gate_timer; 

END ARCHITECTURE behavior;

