--=====================================================
-- Проект 30. Измеритель частоты
-- За эталонную секунду считаем импульсы входного
-- сигнала — получаем частоту в герцах.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity freq_counter is
    generic (
        CLK_HZ : integer := 50_000_000                  -- тактовая частота
    );
    port (
        clk     : in  std_logic;
        rst     : in  std_logic;
        sig_in  : in  std_logic;                        -- измеряемый сигнал
        freq    : out std_logic_vector(23 downto 0);    -- частота, Гц
        valid   : out std_logic                         -- результат обновлён
    );
end entity freq_counter;

architecture rtl of freq_counter is
    signal gate    : integer range 0 to CLK_HZ := 0;    -- отсчёт секунды
    signal pulses  : unsigned(23 downto 0) := (others => '0');
    signal sync    : std_logic_vector(2 downto 0) := "000";
begin
    process (clk, rst)
    begin
        if rst = '1' then
            gate   <= 0;
            pulses <= (others => '0');
            valid  <= '0';
            sync   <= "000";
        elsif rising_edge(clk) then
            sync  <= sync(1 downto 0) & sig_in;         -- синхронизация входа
            valid <= '0';

            -- считаем нарастающие фронты входного сигнала
            if sync(2) = '0' and sync(1) = '1' then
                pulses <= pulses + 1;
            end if;

            if gate = CLK_HZ - 1 then                   -- секунда истекла
                freq   <= std_logic_vector(pulses);
                valid  <= '1';
                pulses <= (others => '0');
                gate   <= 0;
            else
                gate <= gate + 1;
            end if;
        end if;
    end process;
end architecture rtl;
