Короче наваял велосипед.
1. Детектит отсутствие клока в течении Alarm_Time тактов опорной частоты (за счёт синхронизатора выходной сигнал задержан на 2 такта относительно реально отсутствующей частоты. Т.е. частоты нет N тактов но об этом мы узнаём на N+2 такте)
2. Входная частота полностью асинхронная единственое условие Fвх < Fоп/2. Метастабильность учтена.
3. Единичный входной импульс считает наличием частоты.
4. На сигнал Not_Use нужно повесить таймспек на минимальную длинну. Для Xilinx MaxDelay.
Замечания и предложения приветствуются.
Код
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:52:23 06/08/2015
-- Design Name:
-- Module Name: Clock_Detector - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Clock_Detector is
Generic (
Alarm_time : integer range 2 to 250000 := 4
);
Port ( ClkX : in STD_LOGIC;
Clk : in STD_LOGIC;
Detect : out STD_LOGIC);
end Clock_Detector;
architecture Behavioral of Clock_Detector is
function getlog2 (int : in integer) return integer is
variable log2 : natural := 0;
begin
if (int = 0) then
log2 := 0;
elsif (int <= 2) then
log2 := 1;
else
log2 := getlog2((int/2) + (int rem 2)) + 1;
end if;
return log2;
end function getlog2;
constant Count_MSB : natural := getlog2(Alarm_Time);
signal Not_Use :std_logic;
signal ClkX_Shift : std_logic;
signal ClkX_Shift1 : std_logic;
signal ClkX_Rise_Sync: std_logic;
signal Count :std_logic_vector(Count_MSB downto 0);
alias Overflow: std_logic is Count(Count_MSB);
begin
process (Clk)
begin
if (Clk'event and Clk = '1') then
Not_Use <= ClkX;
ClkX_Shift <= Not_Use;
ClkX_Shift1 <= ClkX_Shift;
end if;
end process;
ClkX_Rise_Sync <= not ClkX_Shift1 and ClkX_Shift;
process (Clk, ClkX_Rise_Sync)
begin
if ClkX_Rise_Sync='1' then
Count <= conv_std_logic_vector((2**Count_MSB-Alarm_Time),Count_MSB+1);
elsif Clk='1' and Clk'event then
if (not Overflow)='1' then
Count <= Count + 1;
end if;
end if;
end process;
Detect <= not Overflow;
end Behavioral;
И ещё: чтобы эта дрянь не преобразовывала триггеры в сдвиговый регистр дописать вот это:
-- Synplify Pro: disable shift-register LUT (SRL) extraction
attribute syn_srlstyle : string;
attribute syn_srlstyle of NOT_USE : signal is "registers";
attribute syn_srlstyle of ClkX_Shift : signal is "registers";
-- Xilinx XST: disable shift-register LUT (SRL) extraction
attribute shreg_extract : string;
attribute shreg_extract of NOT_USE : signal is "no";
attribute shreg_extract of ClkX_Shift : signal is "no";