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 :
- Instancie le composant sous test (DUT — Device Under Test)
- Génère les stimuli (signaux d'entrée)
- 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
| Instruction | Utilisation |
|---|---|
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é
| Niveau | Effet |
|---|---|
note | Message informatif |
warning | Avertissement, simulation continue |
error | Erreur, simulation peut continuer |
failure | Arrêt immédiat de la simulation |
Bonnes pratiques
- Nommer les assertions : message clair pour identifier l'échec
- Vérifier après stabilisation : attendre
wait foravantassert - Tester les cas limites : valeurs min/max, transitions d'états
- Séparer stimuli et vérification : process distincts pour clarté
- Fin explicite : terminer par
report "... succès"+wait;