La distinction fondamentale entre logique combinatoire (sans mémoire) et logique séquentielle (avec horloge).
Pour choisir le modèle d'un bloc, demande-toi s'il doit conserver une information. Une fonction combinatoire utilise les entrées actuelles ; une fonction séquentielle utilise aussi un état mémorisé.
Cette logique ne demande pas d'horloge. Sa sortie se stabilise après le délai de propagation. Sur FPGA, le synthétiseur la réalise notamment avec des LUT et leurs connexions.
Mémoriser sur un front d'horloge
Dans la logique séquentielle synchrone présentée ici, le front montant ou descendant commande la mise à jour de l'état :
architecture rtl of registre is signal r_data : std_logic_vector(7 downto 0);begin process(i_clk) begin if rising_edge(i_clk) then if i_rst = '1' then r_data <= (others => '0'); else r_data <= i_data; end if; end if; end process; o_data <= r_data;end architecture rtl;
Le préfixe r_ indique ici un signal enregistré. Les bascules D réalisent cette mémoire : sur le front actif, Q prend la valeur de D ; entre les fronts, Q conserve la valeur capturée.
Événement
Valeur de Q
Front montant
Valeur de D au front
Aucun front montant
Valeur précédente de Q
process(i_clk)begin if rising_edge(i_clk) then r_q <= i_d; -- bascule D simple end if;end process;
La logique séquentielle désigne plus largement les circuits à état ; elle n'est pas nécessairement synchrone dans tous les cas.
Choisir le reset et la sensibilité
Un reset synchrone est pris en compte au front d'horloge :
process(i_clk)begin if rising_edge(i_clk) then if i_rst = '1' then r_q <= '0'; -- reset sur le front else r_q <= i_d; end if; end if;end process;
Un reset asynchrone peut agir sans attendre ce front :
process(i_clk, i_rst)begin if i_rst = '1' then r_q <= '0'; -- reset immédiat, sans attendre le front elsif rising_edge(i_clk) then r_q <= i_d; end if;end process;
Le choix dépend des ressources du FPGA et des besoins du circuit. Un reset synchrone convient à beaucoup de blocs RTL, mais réinitialiser tous les registres peut gêner l'inférence de certaines RAM ou de certains DSP. Pour un reset asynchrone, organise une désassertion synchronisée dans chaque domaine.
Dans un process combinatoire, la liste de sensibilité doit contenir tous les signaux lus :
-- Combinatoire : i_a, i_b, i_sel dans la listeprocess(i_a, i_b, i_sel)begin if i_sel = '0' then w_y <= i_a; else w_y <= i_b; end if;end process;
Dans un process sur front, elle contient l'horloge et, s'il existe, le reset asynchrone :
-- Séquentiel : uniquement i_clkprocess(i_clk)begin if rising_edge(i_clk) then r_q <= i_d; end if;end process;
VHDL-2008 permet process(all) pour calculer automatiquement la sensibilité. Vérifie que ce mode est activé dans l'outil.