Introduction aux machines d'État VHDL

VHDL (VHSIC Hardware Description Language) est l'un des langages les plus utilisés pour concevoir des systèmes numériques, surtout lors de la mise en œuvre de la logique de contrôle. Les machines d'état – les machines à état fini (FSM) – sont l'épine dorsale de nombreuses unités de contrôle dans les protocoles de communication, les processeurs embarqués, les contrôleurs de mémoire et les pipelines complexes de traitement des signaux numériques.Une machine d'état mal conçue peut conduire à des problèmes, des blocages ou des comportements imprévisibles, faisant de la fiabilité une priorité absolue.

Comprendre les deux architectures principales : Moore vs. Mealy

Le choix entre les architectures Moore et Mealy influe fondamentalement sur la façon dont les sorties sont générées. Dans une machine Moore, les sorties dépendent uniquement de l'état actuel, tandis que dans une machine Mealy, les sorties dépendent à la fois de l'état actuel et des entrées.

Machines d'État Moore

Les machines Moore sont plus simples à raisonner parce que les sorties changent uniquement aux transitions d'état, synchronisées au bord de l'horloge. Elles sont donc intrinsèquement libres de glissades sur les lignes de sortie tant que l'encodage d'état est stable. Elles sont idéales pour la logique de contrôle où la stabilité de sortie est critique, comme dans les contrôleurs de feux de circulation ou l'accès à la mémoire séquentiel.

Machines d'État à repassage

Les machines à repas peuvent produire des sorties immédiatement en réponse aux changements d'entrée, même dans le même cycle d'horloge. Cela peut conduire à des diagrammes d'état plus compacts – parfois la moitié du nombre d'états par rapport à un équivalent Moore. Cependant, le chemin combinatoire des entrées aux sorties doit être soigneusement vérifié pour les glissades, les retards de propagation et les conditions de course potentielles.

Une bonne règle : commencer par une architecture Moore pour une logique de contrôle critique en matière de sécurité; considérer Mealy seulement lorsque l'avantage de vitesse ou de zone est essentiel et que vous avez vérifié le plan de synchronisation.

Synchronous vs. Asynchrone Design: Pourquoi Synchronous gagne

Les machines d'état VHDL les plus fiables sont synchrones – toutes les transitions d'état se produisent sur un seul bord d'horloge global. La conception synchrone simplifie l'analyse de la chronologie, la fermeture statique du timing et la réutilisation d'outils. Les machines d'état asynchrones (sans horloge commune) sont notoirement difficiles à mettre en œuvre correctement dans VHDL; elles nécessitent une analyse minutieuse de l'état de la course, l'élimination des risques et souvent des contraintes de mise en page manuelles.

process(clk, rst_n)
begin
 if rst_n = '0' then
 state <= IDLE;
 elsif rising_edge(clk) then
 state <= next_state;
 end if;
end process;

Pour les modèles multi-horloges, synchronisez toujours les entrées asynchrones avant de les alimenter dans la machine d'état (voir la section métastabilité ci-dessous).

Styles d'encodage d'état: Binary, One-Hot, Gray

La façon dont vous assignez des codes binaires aux états affecte la zone, la vitesse, la puissance et la fiabilité. VHDL se soucie uniquement de l'énumération; l'outil de synthèse décide de l'encodage à moins de la forcer. Cependant, vous pouvez guider l'outil en utilisant des attributs de synthèse ou en définissant manuellement le vecteur d'état.

Encodage binaire

Le codage binaire utilise les moins de tongs (nombre d'états log2) ; il est efficace pour les machines d'état à plusieurs états (p. ex. 64+). L'inconvénient est que le décodage de la logique de l'état suivant peut être plus lent et que les transitions entre états peuvent impliquer des tongs multiples, augmentant la puissance due au basculement.

Encodage à une seule tête

One‐hot utilise une tongue par état, donc une seule tongue est haute à tout moment. Cela rend la logique de décodage de l'état suivant très rapide (un simple OU de transitions entrantes) et réduit le potentiel de glissade. One‐hot est l'encodage par défaut recommandé par la plupart des fournisseurs de FPGA pour les machines d'état ayant jusqu'à 16 états. L'échange est plus d'utilisation de tongue et de puissance de ralentie supérieure.

Codage gris

L'encodage gris permet de s'assurer qu'un seul bit change entre les états adjacents. Ceci est utile lorsque les transitions d'état doivent minimiser la puissance ou lorsque l'on traverse des domaines d'horloge avec un bus multibit (bien que cela nécessite des synchroniseurs supplémentaires).

En pratique, commencez par un seul chaud pour les petits FSM (généralement moins de 20 états) et binaire pour les plus grands. Laissez votre outil de synthèse gérer le reste par défaut – mais vérifiez par des rapports de simulation et de synchronisation.

Utilisation de types énumérés pour la lisibilité et la sécurité

La définition d'états avec un type énuméré est une pratique exemplaire qui améliore la lisibilité et la maintenance du code. Au lieu d'utiliser des constantes numériques (p. ex. ), écrire :

type state_type is (IDLE, WAIT, READ, WRITE, DONE);
signal state, next_state : state_type;

Les types énumérés permettent à l'outil de synthèse d'attribuer automatiquement l'encodage, et le compilateur affiche toute valeur d'état illégale si elle est utilisée avec une instruction de cas qui couvre tous les états. Cela permet également un débogage de simulation facile car les téléspectateurs de forme d'onde affichent le nom d'état au lieu d'un code binaire.

Stratégies de remise en état : Initialisation fiable

Chaque FSM doit avoir un mécanisme de réinitialisation bien défini. Sans réinitialisation, le registre d'état se développe dans un état inconnu, ce qui peut entraîner des sorties lock-up ou fallacieuses.

Réinitialisation asynchrone

La réinitialisation asynchrone (soumission de la réinitialisation indépendamment de l'horloge) force la machine à se mettre en état de sécurité connu immédiatement. Ceci est vital pour les systèmes critiques de sécurité où la récupération de puissance ou d'erreur doit se produire sans attendre un bord de l'horloge.

process(clk, rst_n)
begin
 if rst_n = '0' then
 state <= IDLE;
 elsif rising_edge(clk) then
 state <= next_state;
 end if;
end process;

Cependant, sachez que la désassertion de réinitialisation asynchrone doit être synchronisée pour éviter la métastabilité (un problème de chronométrage de la récupération de réinitialisation de -).

Réinitialisation synchrone

La réinitialisation synchrone ne prend effet que sur un bord de l'horloge. Cela élimine le problème de synchronisation de récupération et simplifie l'analyse statique de la synchronisation. L'inconvénient : si l'horloge s'arrête ou est lente, la machine ne peut pas se réinitialiser rapidement. Utilisez la réinitialisation synchrone pour les conceptions où la réinitialisation de l'horloge pourrait arrêter le système – mais toujours s'assurer que l'horloge tourne pendant la réinitialisation.

Pour une fiabilité maximale, combinez les deux : utilisez une réinitialisation asynchrone pour forcer immédiatement un état sûr, puis la transition vers une opération entièrement synchrone. Considérez également l'inclusion d'un --watchdog, qui peut générer une réinitialisation si le FSM est coincé dans un état illégal ou inaccessible (voir l'approche --safe state---) ci-dessous.

Synchronisation et métastabilité des entrées

Lorsqu'une machine d'état reçoit des entrées asynchrones (par exemple, à partir d'un bouton ou d'un autre domaine d'horloge), le signal d'entrée doit être synchronisé avec l'horloge FSM, afin d'éviter la métastabilité – une condition où une sortie flip-flop=s oscille entre les niveaux logiques. La solution standard est un synchroniseur à deux ou trois tons :

signal async_in : std_logic;
signal sync_meta : std_logic;
signal sync_out : std_logic;
process(clk)
begin
 if rising_edge(clk) then
 sync_meta <= async_in;
 sync_out <= sync_meta;
 end if;
end process;

N'utilisez PAS le signal asynchrone brut directement dans la logique combinatoire de l'état suivant du FSM, utilisez toujours la version synchronisée. Pour les bus multibits traversant des domaines d'horloge, envisagez d'utiliser un protocole FIFO ou poignée de main. Xilinx="s blanc paper on metastability fournit des conseils approfondis.

Débauchage des entrées mécaniques

Pour les FSM entraînés par des boutons-poussoirs ou des commutateurs, une seule presse peut générer plusieurs bords en raison du rebond du contact. La machine d'état peut interpréter ceux-ci comme de multiples impulsions courtes, provoquant un fonctionnement erratique. La débouncing peut être faite dans le domaine numérique en utilisant un minuteur qui attend que le signal d'entrée se règle (p. ex. 10 à 20 ms). Une approche simple consiste à échantillonner l'entrée à un rythme beaucoup plus bas (p. ex. 1 kHz) et exiger que le signal soit stable pour les échantillons consécutifs de N. Utilisez aussi une IP de débonflage dédiée ou un petit FSM compteur.

Styles de codage : deux procédés contre trois procédés

Il existe deux styles de codage VHDL largement adoptés pour les ESF : le style à deux processus et le style à trois processus. Tous deux sont synthétisés et fiables; le choix est essentiellement une question de lisibilité et de préférence personnelle.

Deux procédés FSM

Le style à deux processus utilise un processus séquentiel pour le registre et la réinitialisation de l'état, et un processus combinatoire pour la logique de l'état et de la sortie suivante. Le processus combinatoire est sensible à l'état et aux entrées seulement – pas d'horloge. Ce style sépare clairement la logique combinatoire, ce qui facilite la vérification du timing :

-- Sequential process (state update)
seq: process(clk, rst_n)
begin
 if rst_n = '0' then
 state <= IDLE;
 elsif rising_edge(clk) then
 state <= next_state;
 end if;
end process;

-- Combinatorial process (next state & outputs)
comb: process(state, input1, input2)
begin
 next_state <= state; -- default to staying
 output1 <= '0';
 case state is
 when IDLE =>
 if input1 = '1' then
 next_state <= WORK;
 end if;
 when WORK =>
 output1 <= '1';
 if input2 = '1' then
 next_state <= DONE;
 end if;
 when DONE =>
 next_state <= IDLE;
 when others =>
 next_state <= IDLE;
 end case;
end process;

Remarquez comment les sorties sont données par défaut avant le cas ; cela empêche les verrous et garantit que chaque sortie est attribuée à chaque état (même si la valeur est la même).

Trois processus FSM

Le style à trois processus sépare le registre d'état, la logique d'état suivant et la logique de sortie en trois processus distincts. Cela peut améliorer l'organisation du code pour les machines complexes avec de nombreuses sorties.

-- State register
seq_state: process(clk, rst_n)
...
-- Next state combinatorial
seq_next: process(state, inputs)
...
-- Output combinatorial (or registered)
comb_output: process(state, inputs)
...

Les deux styles sont également fiables lorsqu'ils sont correctement codés. Évitez le style monoprocess (où tout est à l'intérieur d'un processus à horloges) car il mélange les tâches combinatoires et enregistrées, rendant la simulation et la synthèse plus difficiles à détecter.

État défaillant et récupération "État sûr"

Même avec une remise à zéro et un encodage appropriés, il est possible pour la machine d'état d'entrer dans un état illégal en raison d'un événement unique perturbé (SEU) dans des applications spatiales, ou en raison d'un bug dans la conception. Pour améliorer la fiabilité, implémenter un mécanisme de récupération "safe state".

case state is
 when IDLE => ...
 when WORK => ...
 when others => next_state <= IDLE;
end case;

Pour les VHDL synthétisées, les outils traitent comme un accrocheur pour toutes les valeurs binaires non assignées. Cependant, l'outil de synthèse peut créer un décodage coûteux pour chaque motif de bits possible. Une alternative est d'utiliser un «détecteur d'état illégal» : un compteur ou un contrôle de parité qui réinitialise la machine si un motif inattendu est vu.

Tests et stratégies de vérification

Une simulation minutieuse est essentielle pour une conception fiable de la machine. Créez un banc de test qui exerce chaque transition d'état, y compris la remise à zéro, le ralenti et toutes les combinaisons d'entrée. Utilisez des assertions pour vérifier que la machine n'entre jamais dans un état inaccessible et que les sorties respectent le timing prévu. Par exemple, vous pouvez vérifier qu'après la remise à zéro la machine est IDLE dans un cycle d'horloge:

wait until rising_edge(clk);
assert state = IDLE report "Reset failed" severity failure;

De nombreux outils soutiennent les mesures de couverture FSM qui montrent quels états et transitions ont été exercés. Doulos=" Les techniques de testbench VHDL fournissent un bon point de départ pour la construction d'environnements de vérification complets.

Pièges courants et comment les éviter

  • Liste de sensibilité incomplète :[ Dans les processus combinatoires, l'oubli d'un signal dans la liste de sensibilité peut causer une inadéquation simulation-synthèse. Vivado et d'autres outils peuvent avertir au sujet de listes incomplètes. VHDL‐2008 permet d'inclure automatiquement tous les signaux – utilisez-le si vos outils le supportent.
  • Missing des attributions de sortie par défaut:[ Si un signal n'est pas assigné dans chaque branche d'un cas ou si une instruction, l'outil de synthèse peut inférer un verrou au lieu d'un multiplexeur. Toujours fournir une affectation par défaut au sommet du processus combinatoire.
  • L'utilisation d'instructions d'attente dans le code synthésisable:[ n'est pas synthésisable pour la plupart des flux FPGA. Utilisez plutôt des processus horlogérés et des cessions conditionnelles.
  • Logique de l'état suivant trop complexe :[ Si le chemin combinatoire devient trop profond, la fermeture du timing en souffre.
  • Ignorer les avertissements de synthèse:[ Les avertissements concernant les serrures inférées, les déclarations incomplètes de cas ou les états inutilisés sont des drapeaux rouges.

Applications réelles et modèles avancés

La conception fiable des machines d'état n'est pas seulement académique – elle est utilisée dans tout, des contrôleurs USB (qui nécessitent un suivi précis de l'état pour chaque paquet) aux protocoles de communication des engins spatiaux. Par exemple, le contrôleur JTAG TAP est un modèle classique de Moore FSM défini par la norme IEEE 1149.1. De nombreux concepteurs l'implémentent en utilisant un style à deux procédés avec un codage à chaud pour la vitesse.

Pour les modèles nécessitant un débit très élevé, envisagez d'utiliser un « FSM avec sorties en pipeline » : enregistrez les signaux de sortie afin qu'ils changent un cycle d'horloge après la transition d'état. Cela ajoute de la latence, mais élimine les problèmes combinatoires sur les lignes de bus. Intel=» Les lignes directrices de conception FSM offrent des conseils supplémentaires pour les FPGA Altera/Intel.

Conclusion

En comprenant les compromis entre les architectures Moore et Mealy, en choisissant un codage d'état approprié, en utilisant des types énumérés, et en mettant en œuvre des stratégies de réinitialisation et de synchronisation robustes, vous pouvez créer une logique de contrôle à la fois durable et robuste. Simulez toujours soigneusement, incluez la récupération d'état sûr et résistez à la tentation de couper des coins sur la réinitialisation ou la synchronisation de signaux. Ces modèles ont été éprouvés dans des milliers de conceptions de production – des appareils IoT de faible puissance aux équipements de réseau haute performance.