Проектирование конечного автомата в VHDL: практический пример светофора
Конечный автомат (FSM) — это детерминистическая логическая модель, выход которой зависит не только от текущего входа, но также от последовательности прошлых входов и выходов. В проектировании ПЛИС и временнозависимых VHDL-алгоритмах FSM — стандартная абстракция для захвата состоятельного поведения.
FSM в VHDL обычно реализуются как тактированные процессы, использующие сигнал state для запоминания последней конфигурации. Сигнал состояния действует как внутренний регистр, позволяя дизайну реагировать на события, охватывающие несколько тактовых циклов.
Базовые уроки VHDL — Часть 3
Светофор как FSM
Рассмотрим четырехпутевой перекресток, управляемый светофорами. Светофоры циклически проходят через конечный набор видимых состояний — например, Север/Юг красный, Север/Юг зеленый, Запад/Восток красный и т.д. Время каждого состояния (5 с для красного или желтого, 60 с для зеленого) управляется пройденными тактовыми циклами.

Мы моделируем эти поведения, определяя перечислимый тип, перечисляющий все возможные состояния:
type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);
Затем мы объявляем сигнал этого типа для хранения текущего состояния:
signal State : t_State;
С сигналом состояния на месте, логика FSM живет внутри единственного тактированного процесса, использующего оператор case. Каждая ветвь when соответствует отдельному состоянию и содержит присваивания выходов для этого состояния. Счетчик отслеживает прошедшее время и управляет переходом к следующему состоянию, когда его значение достигает предопределенного порога.
Шаблон FSM с одним процессом
process(Clk) is begin if rising_edge(Clk) then if nRst = '0' then State <= <reset_state>; Counter <= 0; else case State is when <state_name> => <set_outputs_for_this_state_here> if <state_change_condition_is_true> then State <= <next_state_name>; end if; ... end case; end if; end if; end process;
Примечание: FSM можно реализовывать с использованием одно-, двух- или трехпроцессных стилей. См. Объяснение стилей FSM.
Практическое упражнение
Ниже приведен полный, синтезируемый пример, реализующий контроллер светофора. Дизайн использует тактовый сигнал 100 Гц для упрощения симуляции, при этом демонстрируя реалистичное время.
Тестбенч
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T20_FiniteStateMachineTb is end entity; architecture sim of T20_FiniteStateMachineTb is constant ClockFrequencyHz : integer := 100; -- 100 Hz constant ClockPeriod : time := 1000 ms / ClockFrequencyHz; signal Clk : std_logic := '1'; signal nRst : std_logic := '0'; signal NorthRed : std_logic; signal NorthYellow : std_logic; signal NorthGreen : std_logic; signal WestRed : std_logic; signal WestYellow : std_logic; signal WestGreen : std_logic; begin i_TrafficLights : entity work.T20_TrafficLights(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map( Clk => Clk, nRst => nRst, NorthRed => NorthRed, NorthYellow => NorthYellow, NorthGreen => NorthGreen, WestRed => WestRed, WestYellow => WestYellow, WestGreen => WestGreen); Clk <= not Clk after ClockPeriod / 2; process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); nRst <= '1'; wait; end process; end architecture;
Модуль автомата состояний
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T20_TrafficLights is generic(ClockFrequencyHz : integer); port( Clk : in std_logic; nRst : in std_logic; -- Active low reset NorthRed : out std_logic; NorthYellow : out std_logic; NorthGreen : out std_logic; WestRed : out std_logic; WestYellow : out std_logic; WestGreen : out std_logic); end entity; architecture rtl of T20_TrafficLights is type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest); signal State : t_State; signal Counter : integer range 0 to ClockFrequencyHz * 60; begin process(Clk) is begin if rising_edge(Clk) then if nRst = '0' then State <= NorthNext; Counter <= 0; NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0'; else -- Default outputs NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0'; Counter <= Counter + 1; case State is when NorthNext => NorthRed <= '1'; WestRed <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= StartNorth; end if; when StartNorth => NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= North; end if; when North => NorthGreen <= '1'; WestRed <= '1'; if Counter = ClockFrequencyHz * 60 - 1 then Counter <= 0; State <= StopNorth; end if; when StopNorth => NorthYellow <= '1'; WestRed <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= WestNext; end if; when WestNext => NorthRed <= '1'; WestRed <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= StartWest; end if; when StartWest => NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= West; end if; when West => NorthRed <= '1'; WestGreen <= '1'; if Counter = ClockFrequencyHz * 60 - 1 then Counter <= 0; State <= StopWest; end if; when StopWest => NorthRed <= '1'; WestYellow <= '1'; if Counter = ClockFrequencyHz * 5 - 1 then Counter <= 0; State <= NorthNext; end if; end case; end if; end if; end process; end architecture;
Запуск симуляции на пять минут производит волновую форму, показывающую FSM, циклически проходящий через свои восемь состояний, с зелеными фазами, длящихся по одной минуте каждая.

Анализ
Ключевые выводы из кода:
- Перечислимые типы ограничивают сигнал
Stateизвестным набором допустимых значений, улучшая безопасность и читаемость. - Все выходы управляются значением по умолчанию в начале процесса; последующие ветви состояний переопределяют только те сигналы, которые меняются.
- Переменная
Counter— это движок тайминга, и ее пороговые значения (5 с, 60 с) выводятся из частоты тактового сигнала.
Результирующая волновая форма подтверждает, что FSM продвигается корректно: сигнал State переключается через восемь определенных состояний, и каждая зеленая фаза длится одну минуту.
Выводы
- Конечные автоматы — стандартный способ реализации последовательной логики в VHDL.
- Оператор
caseвнутри тактированного процесса чисто отображает каждое состояние в его поведение. - Перечислимые типы дают безопасность времени компиляции, ограничивая набор допустимых значений состояния.
Переходите к следующему уроку для продвинутых техник FSM.
VHDL
- Конечный автомат: использование обратной связи для построения программируемых последовательных контроллер…
- Максимизация производительности Qt State Machines
- Создание списков строк в VHDL: лучшие практики и пример
- Создание Tcl-управляемого тестбенча для VHDL-модуля кодового замка
- Корректное завершение симуляции VHDL-тестбенча
- Реализация PWM-контроллера в VHDL: проектирование, симуляция и FPGA-демо
- Генерация случайных чисел в VHDL: от Uniform к OSVVM
- Как создать самопроверяющийся тестбенч в VHDL — практическое руководство
- Реализация динамического связного списка в VHDL с защищенными типами и указателями доступа
- Как лазерный станок OMNI CNC создает персонализированные рождественские подарки