Conception d'une machine d'état finie en VHDL : Exemple pratique de feu tricolore
Une machine d'état finie (FSM) est un modèle logique déterministe dont la sortie dépend non seulement de l'entrée actuelle mais aussi de la séquence des entrées et sorties passées. Dans la conception FPGA et les algorithmes VHDL dépendants du temps, une FSM est l'abstraction de référence pour capturer un comportement à états.
Les FSM en VHDL sont généralement implémentées comme des processus horlogés qui utilisent un signal state pour se souvenir de la dernière configuration. Le signal d'état agit comme un registre interne, permettant au design de réagir à des événements qui s'étendent sur plusieurs cycles d'horloge.
Tutoriels VHDL de Base - Partie 3
Feux tricolores comme FSM
Considérez un carrefour à quatre voies contrôlé par des feux tricolores. Les feux passent par un ensemble fini d'états visibles - par exemple, Nord/Sud rouge, Nord/Sud vert, Ouest/Est rouge, etc. La chronologie de chaque état (5 s pour le rouge ou jaune, 60 s pour le vert) est pilotée par les cycles d'horloge écoulés.

Nous modélisons ces comportements en définissant un type énuméré qui liste tous les états possibles :
type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);
Puis nous déclarons un signal de ce type pour maintenir l'état actuel :
signal State : t_State;
Avec le signal d'état en place, la logique FSM vit à l'intérieur d'un unique processus horlogé qui utilise une instruction case. Chaque branche when correspond à un état distinct et contient les affectations de sortie pour cet état. Un compteur suit le temps écoulé et pilote la transition vers l'état suivant quand sa valeur atteint un seuil prédéfini.
Modèle FSM à un processus
process(Clk) is
begin
if rising_edge(Clk) then
if nRst = '0' then
State <= ;
Counter <= 0;
else
case State is
when =>
if then
State <= ;
end if;
...
end case;
end if;
end if;
end process;
Note : Vous pouvez implémenter des FSM en utilisant des styles à un, deux ou trois processus. Voir Styles FSM Expliqués.
Exercice pratique
Ci-dessous se trouve un exemple complet et synthétisable qui implémente un contrôleur de feu tricolore. Le design utilise une horloge 100 Hz pour simplifier la simulation tout en démontrant un timing réaliste.
Testbench
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;
Module Machine d'État
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; -- Reset actif bas
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
-- Sorties par défaut
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;
L'exécution de la simulation pendant cinq minutes produit une forme d'onde qui montre la FSM passant par ses huit états, avec des phases vertes d'une minute chacune.

Analyse
Points clés du code :
- Les types énumérés restreignent le signal
Stateà un ensemble connu de valeurs valides, améliorant la sécurité et la lisibilité. - Toutes les sorties sont pilotées avec une valeur par défaut au début du processus ; les branches d'état subséquentes ne remplacent que les signaux qui changent.
- La variable
Counterest le moteur de chronométrage, et ses valeurs de seuil (5 s, 60 s) sont dérivées de la fréquence d'horloge.
La forme d'onde résultante confirme que la FSM avance correctement : le signal State bascule à travers les huit états définis, et chaque phase verte persiste pendant une minute.
À retenir
- Les machines d'état finies sont la façon standard d'implémenter la logique séquentielle en VHDL.
- Une instruction
caseà l'intérieur d'un processus horlogé mappe proprement chaque état à son comportement. - Les types énumérés donnent une sécurité à la compilation en limitant l'ensemble des valeurs d'état permises.
Passez au tutoriel suivant pour des techniques FSM avancées.
VHDL
- Machine à états finis : exploiter la rétroaction pour construire des contrôleurs de séquence programmables
- Maximiser la performance des machines d'états Qt
- Créer des listes de chaînes en VHDL : Bonnes pratiques et exemple
- Créer un banc de test piloté par Tcl pour un module verrou code VHDL
- Terminer proprement une simulation de banc de test VHDL
- Implémenter un contrôleur PWM en VHDL : Conception, simulation et démo FPGA
- Comment construire un testbench auto-vérifiant en VHDL - Guide pratique
- Implémentation d'une liste chainée dynamique en VHDL avec types protégés et pointeurs d'accès
- Comment la machine laser OMNI CNC crée des cadeaux de Noël personnalisés