Задача
Измерить частоту входного сигнала и выдать значение в герцах.
Тип схемы: Синхронная схема: счётчик окна и счётчик событий.
Модуль: freq_meter. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования.
Теорию по языку смотрите в статье VHDL — язык описания аппаратуры,
по самим микросхемам — на странице ПЛИС.
Алгоритм
- Синхронизировать входной сигнал цепочкой триггеров.
- Считать его нарастающие фронты.
- Параллельно отсчитывать секундное окно по тактовой частоте.
- В конце окна защёлкнуть результат, обнулить счётчик и выдать признак готовности.
Код на VHDL
Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v23.vhd
--=====================================================
-- Проект 23. Частотомер
-- Импульсы считаются в измерительном окне ровно
-- в одну секунду; результат защёлкивается в конце окна.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity freq_meter is
generic ( CLK_HZ : integer := 50_000_000 );
port (
clk : in std_logic;
rst : in std_logic;
sig : in std_logic; -- измеряемый сигнал
freq : out std_logic_vector(19 downto 0); -- частота в герцах
ready : out std_logic
);
end entity freq_meter;
architecture rtl of freq_meter is
signal window : integer range 0 to CLK_HZ := 0;
signal cnt : unsigned(19 downto 0) := (others => '0');
signal sync : std_logic_vector(2 downto 0) := "000";
begin
process (clk, rst)
begin
if rst = '1' then
window <= 0; cnt <= (others => '0'); ready <= '0';
elsif rising_edge(clk) then
sync <= sync(1 downto 0) & sig; -- синхронизация входа
ready <= '0';
-- считаем нарастающие фронты измеряемого сигнала
if sync(2) = '0' and sync(1) = '1' then
cnt <= cnt + 1;
end if;
if window = CLK_HZ - 1 then -- окно закрылось
window <= 0;
freq <= std_logic_vector(cnt); -- защёлкиваем результат
cnt <= (others => '0');
ready <= '1';
else
window <= window + 1;
end if;
end if;
end process;
end architecture rtl;
Пояснения
- Результат прямо равен частоте в герцах, потому что окно составляет ровно одну секунду — пересчёт не нужен.
- Для низких частот такой метод даёт большую погрешность: там измеряют период, а частоту вычисляют обратной величиной.
- Входной сигнал обязательно синхронизируют — иначе асинхронные фронты вызовут ложный счёт и метастабильность.
Что дальше
Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.