AFON // радиотехник affonya@mail.ru
← Проекты на VHDL

Проект 14. Ждущий мультивибратор

Короткий запуск превращается в импульс нужной длительности, а повторные запуски во время работы игнорируются. Так делают подсветку по нажатию, задержки и таймауты.

Задача

Выдать импульс фиксированной длительности по короткому запуску.

Тип схемы: Конечный автомат с двумя состояниями и счётчиком.
Модуль: one_shot. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования. Теорию по языку смотрите в статье VHDL — язык описания аппаратуры, по самим микросхемам — на странице ПЛИС.

Алгоритм

  1. Из состояния ожидания перейти в рабочее по сигналу запуска.
  2. В рабочем состоянии считать такты до заданной длительности.
  3. Игнорировать новые запуски, пока импульс формируется.
  4. По окончании вернуться в ожидание.

Код на VHDL

Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v14.vhd

--=====================================================
-- Проект 14. Ждущий мультивибратор (одновибратор)
-- По короткому запуску выдаёт импульс заданной
-- длительности; повторные запуски игнорируются.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity one_shot is
    generic (
        PULSE_LEN : integer := 50_000_000               -- 1 секунда при 50 МГц
    );
    port (
        clk     : in  std_logic;
        rst     : in  std_logic;
        trig    : in  std_logic;                        -- запуск
        pulse   : out std_logic;                        -- выходной импульс
        busy    : out std_logic                         -- импульс формируется
    );
end entity one_shot;

architecture rtl of one_shot is
    type state_t is (IDLE, RUN);
    signal state : state_t := IDLE;
    signal cnt   : integer range 0 to PULSE_LEN := 0;
begin
    process (clk, rst)
    begin
        if rst = '1' then
            state <= IDLE;
            cnt   <= 0;
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    if trig = '1' then
                        state <= RUN;                   -- запуск принят
                        cnt   <= 0;
                    end if;
                when RUN =>
                    if cnt = PULSE_LEN - 1 then
                        state <= IDLE;                  -- время вышло
                    else
                        cnt <= cnt + 1;                 -- новые запуски не влияют
                    end if;
            end case;
        end if;
    end process;

    pulse <= '1' when state = RUN else '0';
    busy  <= '1' when state = RUN else '0';
end architecture rtl;

Пояснения

  • Автомат гарантирует, что длительность импульса не зависит от того, как долго удерживался запуск.
  • Выход описан как функция состояния — это автомат Мура, свободный от кратковременных выбросов.
  • Тот же модуль работает таймаутом: запуск от события, а сброс счётчика — от его повторения.

Что дальше

Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.