Testbenches et Simulations

Écrire des testbenches VHDL pour vérifier le comportement de vos circuits avant synthèse.

Qu'est-ce qu'un testbench ?

Un testbench (TB) est un fichier VHDL de simulation qui :

  1. Instancie le composant sous test (DUT — Device Under Test)
  2. Génère les stimuli (signaux d'entrée)
  3. Observe et vérifie les sorties

Un testbench n'a pas de ports — c'est un environnement fermé.

entity tb_mux4to1 is
  -- Pas de port !
end entity tb_mux4to1;

Structure type d'un testbench

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity tb_mux4to1 is
end entity tb_mux4to1;
 
architecture tb of tb_mux4to1 is
 
  -- Constantes de simulation
  constant c_CLK_PERIOD : time := 10 ns;  -- 100 MHz
 
  -- Signaux pour connecter au DUT
  signal w_d0, w_d1, w_d2, w_d3 : std_logic := '0';
  signal w_sel : std_logic_vector(1 downto 0) := "00";
  signal w_y   : std_logic;
 
begin
 
  -- Instanciation du DUT
  DUT : entity work.mux4to1
    port map (
      i_d0  => w_d0,
      i_d1  => w_d1,
      i_d2  => w_d2,
      i_d3  => w_d3,
      i_sel => w_sel,
      o_y   => w_y
    );
 
  -- Process de stimuli
  p_stimuli : process
  begin
    -- Test 1 : sélection d0
    w_d0 <= '1'; w_d1 <= '0'; w_d2 <= '0'; w_d3 <= '0';
    w_sel <= "00";
    wait for 20 ns;
    assert w_y = '1' report "ECHEC: sel=00 devrait sortir d0=1" severity error;
 
    -- Test 2 : sélection d1
    w_sel <= "01";
    wait for 20 ns;
    assert w_y = '0' report "ECHEC: sel=01 devrait sortir d1=0" severity error;
 
    -- Test 3 : sélection d3
    w_d3 <= '1';
    w_sel <= "11";
    wait for 20 ns;
    assert w_y = '1' report "ECHEC: sel=11 devrait sortir d3=1" severity error;
 
    report "Tous les tests passés !" severity note;
    wait;  -- arrêt de la simulation
  end process p_stimuli;
 
end architecture tb;

Génération d'horloge

-- Process de génération d'horloge
p_clk : process
begin
  i_clk <= '0';
  wait for c_CLK_PERIOD / 2;
  i_clk <= '1';
  wait for c_CLK_PERIOD / 2;
end process p_clk;
 
-- Alternative concurrente
i_clk <= not i_clk after c_CLK_PERIOD / 2;

Testbench complet pour circuit séquentiel

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity tb_counter is
end entity tb_counter;
 
architecture tb of tb_counter is
 
  constant c_CLK_PERIOD : time := 10 ns;
 
  signal i_clk : std_logic := '0';
  signal i_rst : std_logic := '1';
  signal o_cnt : std_logic_vector(3 downto 0);
 
begin
 
  -- Génération horloge
  i_clk <= not i_clk after c_CLK_PERIOD / 2;
 
  -- DUT
  DUT : entity work.counter_4bit
    port map (
      i_clk => i_clk,
      i_rst => i_rst,
      o_cnt => o_cnt
    );
 
  -- Stimuli
  p_test : process
  begin
    -- Reset actif pendant 3 cycles
    i_rst <= '1';
    wait for 3 * c_CLK_PERIOD;
    assert unsigned(o_cnt) = 0 report "Reset raté" severity error;
 
    -- Démarrage comptage
    i_rst <= '0';
    wait for 5 * c_CLK_PERIOD;
    assert unsigned(o_cnt) = 5 report "Comptage incorrect" severity error;
 
    -- Attendre l'overflow (16 cycles total = 0)
    wait for 11 * c_CLK_PERIOD;
    assert unsigned(o_cnt) = 0 report "Overflow incorrect" severity error;
 
    report "Testbench terminé avec succès" severity note;
    wait;
  end process p_test;
 
end architecture tb;

Instructions de simulation utiles

InstructionUtilisation
wait for 10 ns;Attendre une durée fixe
wait until rising_edge(i_clk);Attendre un front d'horloge
wait until i_valid = '1';Attendre une condition
wait;Arrêter la simulation
assert condition report "msg" severity level;Vérification

Niveaux de sévérité

NiveauEffet
noteMessage informatif
warningAvertissement, simulation continue
errorErreur, simulation peut continuer
failureArrêt immédiat de la simulation

Bonnes pratiques

  1. Nommer les assertions : message clair pour identifier l'échec
  2. Vérifier après stabilisation : attendre wait for avant assert
  3. Tester les cas limites : valeurs min/max, transitions d'états
  4. Séparer stimuli et vérification : process distincts pour clarté
  5. Fin explicite : terminer par report "... succès" + wait;