Machines à états et séparation contrôle/datapath
Écrire une FSM lisible avec un type énuméré et séparer les décisions des calculs de données.
Trois éléments à reconnaître
Une machine à états synchrone contient généralement :
- un registre d'état ;
- une logique qui choisit l'état suivant ;
- une logique de sortie ou de commande.
SystemVerilog permet de rendre ces rôles visibles avec un type énuméré, always_ff et always_comb.
module burst_controller (
input logic i_clk,
input logic i_rst,
input logic i_start,
input logic i_last,
output logic o_load,
output logic o_busy,
output logic o_done
);
typedef enum logic [1:0] {IDLE, LOAD, RUN, DONE} state_t;
state_t state_q, state_d;
always_ff @(posedge i_clk) begin
if (i_rst)
state_q <= IDLE;
else
state_q <= state_d;
Valeurs par défaut
Le début du bloc combinatoire donne une valeur à chaque sortie. Chaque état qui peut durer plusieurs cycles affecte aussi explicitement sa valeur de maintien. Cette méthode couvre tous les chemins sans latch.
Ici, state_d = IDLE définit la récupération si le codage courant est illégal. L'absence de branche default est volontaire : elle permet au contrôle dynamique de unique case de signaler qu'aucune branche n'a reconnu state_q. Au front suivant, la machine revient à IDLE. La politique exacte doit être choisie selon les besoins de sûreté ; elle ne remplace ni un reset correct ni une assertion dédiée si l'état illégal doit faire échouer la simulation.
unique n'est pas décoratif
unique case annonce qu'au plus une branche doit correspondre et qu'une branche doit être trouvée. Sans branche default, le simulateur peut avertir si aucune branche ou plusieurs branches correspondent. Une branche default attrape toutes les valeurs restantes et supprime donc le diagnostic « aucune correspondance ». La synthèse peut aussi utiliser la promesse de unique pour optimiser.
Il ne faut donc pas écrire unique seulement pour faire joli. Si plusieurs branches peuvent correspondre, ou si une valeur non couverte est normale, le mot-clé ne décrit pas la réalité.
Séparer contrôle et datapath
La FSM devrait produire des commandes simples comme load, clear, enable ou select. Le datapath contient les registres de données, compteurs, multiplexeurs et opérateurs.
Cette séparation facilite les tests : on peut vérifier les transitions de contrôle d'un côté et les calculs de l'autre. Elle évite aussi de placer une longue opération arithmétique au milieu d'une logique de transition déjà complexe.
À retenir
- Un type énuméré donne des noms sûrs aux états.
- Le registre d'état appartient à
always_ff. - Les valeurs par défaut et les maintiens explicites empêchent les latchs.
uniqueexprime une vraie promesse ; une branchedefaultmodifie le diagnostic possible.- Une séparation contrôle/datapath rend le design plus simple à relire et à tester.
📝 Tester mes connaissances - Quiz du chapitre