Logique séquentielle

Bascules D, registres, compteurs — les éléments de mémoire de la logique numérique.

De la combinatoire à la séquentielle

La logique combinatoire n'a pas de mémoire. Pour mémoriser un état, on utilise des éléments de mémoire synchronisés sur une horloge.

Circuit synchrone : Entrées → Logique combinatoire → Registres → Sorties (avec rétroaction d'état courant)

Image à ajouter

Ce modèle est la base de tout circuit numérique synchrone.


La bascule D (Flip-Flop D)

La bascule D est l'élément de mémorisation fondamental.

Comportement

ÉvénementAction
Front montant de CLKQ ← D
Entre deux frontsQ conserve sa valeur
RST actif (synchrone)Q ← 0 au prochain front
-- Bascule D simple
process(i_clk)
begin
  if rising_edge(i_clk) then
    r_q <= i_d;
  end if;
end process;

Bascule D avec reset synchrone et enable

process(i_clk)
begin
  if rising_edge(i_clk) then
    if i_rst = '1' then
      r_q <= '0';
    elsif i_en = '1' then
      r_q <= i_d;
    end if;
  end if;
end process;

Registres

Un registre est un groupe de N bascules D partageant la même horloge — mémorise N bits simultanément.

Registre simple N bits

entity registre_8bit is
  port (
    i_clk  : in  std_logic;
    i_rst  : in  std_logic;
    i_en   : in  std_logic;
    i_data : in  std_logic_vector(7 downto 0);
    o_data : out std_logic_vector(7 downto 0)
  );
end entity registre_8bit;
 
architecture rtl of registre_8bit 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');
      elsif i_en = '1' then
        r_data <= i_data;
      end if;
    end if;
  end process;
 
  o_data <= r_data;
end architecture registre_8bit;

Registre à décalage (Shift Register)

architecture rtl of shift_reg is
  signal r_shift : std_logic_vector(7 downto 0);
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_shift <= (others => '0');
      else
        -- Décalage vers la droite, entrée série sur MSB
        r_shift <= i_serial & r_shift(7 downto 1);
      end if;
    end if;
  end process;
 
  o_parallel <= r_shift;         -- sortie parallèle
  o_serial   <= r_shift(0);      -- sortie série
end architecture rtl;

Usage : conversion série/parallèle (UART, SPI), délai de N cycles.


Compteurs

Compteur binaire simple

architecture rtl of counter is
  signal r_count : unsigned(7 downto 0);
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_count <= (others => '0');
      else
        r_count <= r_count + 1;  -- déborde naturellement : 255 → 0
      end if;
    end if;
  end process;
 
  o_count <= std_logic_vector(r_count);
end architecture rtl;

Compteur avec limite (modulo N)

architecture rtl of counter_mod is
  constant c_MAX : integer := 99;  -- compte de 0 à 99
 
  signal r_count : integer range 0 to c_MAX;
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_count <= 0;
      elsif r_count = c_MAX then
        r_count <= 0;
        o_tick  <= '1';   -- impulsion de dépassement
      else
        r_count <= r_count + 1;
        o_tick  <= '0';
      end if;
    end if;
  end process;
end architecture rtl;

Compteur up/down

process(i_clk)
begin
  if rising_edge(i_clk) then
    if i_rst = '1' then
      r_count <= (others => '0');
    elsif i_up = '1' then
      r_count <= r_count + 1;
    elsif i_down = '1' then
      r_count <= r_count - 1;
    end if;
  end if;
end process;

Domaines d'horloge et synchronisation

Lorsque des données traversent des domaines d'horloge différents (CDC — Clock Domain Crossing), des problèmes de métastabilité peuvent survenir.

La solution standard : le double registre (double-flop synchronizer)

-- Synchroniseur 2 étages pour signal 1 bit
signal r_sync1, r_sync2 : std_logic;
 
process(i_clk_dst)
begin
  if rising_edge(i_clk_dst) then
    r_sync1 <= i_signal_src;  -- premier registre : peut être métastable
    r_sync2 <= r_sync1;       -- deuxième registre : stable avec haute probabilité
  end if;
end process;
 
o_signal_dst <= r_sync2;

Le premier registre peut se retrouver en état métastable, mais le second cycle lui laisse le temps de se stabiliser.

Règle : ne jamais utiliser directement un signal issu d'un autre domaine d'horloge sans synchroniseur.