Machines à états en Verilog
Passer d'un diagramme d'états à un RTL lisible, complet et simple à vérifier.
Une FSM sépare la mémoire et les décisions
Une machine à états finis mémorise un état puis choisit le suivant avec les entrées courantes. Une structure à deux blocs rend cette séparation visible :
- un bloc cadencé mémorise l'état ;
- un bloc combinatoire calcule l'état suivant et les sorties.
module request_controller (
input wire i_clk,
input wire i_reset,
input wire i_start,
input wire i_ack,
output reg o_request,
output reg o_done
);
localparam STATE_IDLE = 2'b00;
localparam STATE_WAIT = 2'b01;
localparam STATE_DONE = 2'b10;
reg [1:0] state_reg;
reg [1:0] state_next;
always @(posedge i_clk) begin
if (i_reset)
state_reg <= STATE_IDLE;
else
state_reg <=
o_request reste actif tant que l'acquittement n'arrive pas. o_done forme une impulsion d'un cycle, car l'état DONE retourne ensuite vers IDLE.
Toujours donner des valeurs par défaut
Au début du bloc combinatoire, l'état suivant conserve l'état courant et les sorties prennent une valeur sûre. Chaque branche remplace seulement ce qui change.
Cette méthode évite les latchs et rend les conditions de maintien explicites. La branche default permet aussi de revenir à un état connu si la simulation ou le matériel rencontre un codage illégal.
Moore ou Mealy
Une sortie de Moore dépend uniquement de l'état. Dans l'exemple, o_request et o_done sont de ce type.
Une sortie de Mealy dépend de l'état et d'une entrée. Elle peut réagir dans le même cycle, mais son chemin combinatoire inclut alors cette entrée. Pour une interface, il faut vérifier que cette réaction immédiate ne crée ni boucle combinatoire ni problème de timing.
Choisir le codage des états
Le codage binaire utilise peu de bascules. Un codage one-hot utilise une bascule par état et peut simplifier la logique de décision sur FPGA. Le meilleur choix dépend du nombre d'états, du composant ciblé et des contraintes de timing.
Il est souvent préférable de laisser l'outil recoder la FSM. Si le codage fait partie d'une interface observable ou d'un mécanisme de sûreté, il faut alors le documenter et le contraindre volontairement.
Ajouter un compteur au bon endroit
Lorsqu'un état doit durer plusieurs cycles, un compteur constitue le datapath de la machine. Il doit être initialisé à l'entrée de la séquence, avancer dans l'état concerné et avoir une condition de fin sans ambiguïté.
Comparer avec LIMIT - 1 ou avec LIMIT change la durée d'un cycle. Le testbench doit vérifier les valeurs limites, pas seulement un scénario moyen.
Signaux d'entrée asynchrones
Une FSM ne rend pas une entrée asynchrone sûre. Un bouton, une interruption externe ou un drapeau venant d'une autre horloge doit être synchronisé avant de piloter les transitions. Un bus multi-bit demande un protocole adapté, pas une série de synchroniseurs bit à bit.
Vérifier la machine
Un bon test couvre au moins :
- le reset depuis chaque phase utile ;
- les transitions normales ;
- une entrée qui reste active plusieurs cycles ;
- un acquittement immédiat et un acquittement tardif ;
- les impulsions de sortie, avec leur durée exacte.
À retenir
- Le registre d'état appartient au bloc cadencé.
- La décision de transition appartient au bloc combinatoire.
- Des valeurs par défaut complètes évitent les latchs.
- Une sortie Mealy ajoute un chemin combinatoire depuis une entrée.
- Une entrée asynchrone doit être traitée avant la FSM.
📝 Tester mes connaissances - Quiz du chapitre