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;
end
always_comb begin
state_d = state_q;
o_load = 1'b0;
o_busy = 1'b0;
o_done = 1'b0;
unique case (state_q)
IDLE: if (i_start) state_d = LOAD;
LOAD: begin
o_load = 1'b1;
state_d = RUN;
end
RUN: begin
o_busy = 1'b1;
if (i_last) state_d = DONE;
end
DONE: begin
o_done = 1'b1;
state_d = IDLE;
end
default: state_d = IDLE;
endcase
end
endmoduleValeurs par défaut
Le début du bloc combinatoire donne une valeur à chaque sortie et conserve l'état si aucune transition ne s'applique. Cette méthode évite les latchs et rend chaque branche plus courte.
La branche default ramène la machine vers un état connu si la représentation binaire devient illégale. La stratégie exacte dépend des besoins de sûreté et du comportement de l'outil.
unique n'est pas décoratif
unique case annonce qu'une seule branche doit correspondre et que les cas prévus couvrent les valeurs utiles. Le simulateur peut avertir si cette promesse est violée. La synthèse peut aussi utiliser cette information 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 du bloc combinatoire empêchent les latchs.
uniqueexprime une vraie promesse que la simulation peut contrôler.- Une séparation contrôle/datapath rend le design plus simple à relire et à tester.
📝 Tester mes connaissances - Quiz du chapitre