Comment construire un testbench auto-vérifiant en VHDL - Guide pratique
Un testbench auto-vérifiant est un programme VHDL qui vérifie la correction d'un device under test (DUT) sans inspection manuelle. Une fois exécuté, il signale automatiquement un statut OK ou Échec, en faisant un outil essentiel pour le développement VHDL fiable.
Chaque module VHDL devrait avoir un testbench auto-vérifiant associé. Cela garantit que tout changement - que ce soit au DUT lui-même, à un sous-module, ou à une interface - n'introduit pas silencieusement de régressions. Un testbench bien conçu est la première ligne de défense contre les bogues subtils.
Le Device Under Test
Nous utiliserons un DUT simple mais illustratif : un convertisseur binaire vers code Gray. Voici l'implémentation RTL complète.
library ieee;
use ieee.std_logic_1164.all;
entity gray_converter is
port (
bin : in std_logic_vector;
gray : out std_logic_vector
);
end gray_converter;
architecture rtl of gray_converter is
begin
process(bin) is
begin
gray(gray'high) <= bin(bin'high);
for i in bin'high - 1 downto bin'low loop
gray(i) <= bin(i + 1) xor bin(i);
end loop;
end process;
end architecture;
Le code Gray est un schéma d'encodage binaire où un seul bit change entre les valeurs successives, minimisant la probabilité d'erreur dans la communication série et les compteurs numériques. Le tableau ci-dessous montre la correspondance pour les valeurs 4 bits.
| Décimal | Binaire | Gray |
|---|---|---|
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
Squelette du testbench
Ci-dessous se trouve un testbench minimal qui instancie le DUT et déclare les signaux nécessaires. Remarquez l'inclusion de std.env.finish, une fonctionnalité VHDL-2008 qui termine proprement la simulation.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.finish;
entity gray_converter_tb is
end gray_converter_tb;
architecture sim of gray_converter_tb is
signal bin : std_logic_vector(3 downto 0) := (others => '0');
signal gray : std_logic_vector(3 downto 0);
DUT : entity work.gray_converter(rtl)
port map (
bin => bin,
gray => gray
);
end architecture;
Si vous compilez ce fichier dans un simulateur conforme VHDL-2008 comme ModelSim, vous devrez peut-être définir la version du langage du fichier à 2008. Dans ModelSim, clic droit sur le fichier, choisissez Properties → VHDL → Use 1076-2008.
Génération d'entrées exhaustives
L'étape suivante consiste à produire un balayage complet de toutes les valeurs 4 bits possibles. Un test exhaustif est préféré car il garantit que chaque cas limite est exercé.
PROC_SEQUENCE : process
begin
-- Itérer sur chaque valeur 4 bits
for i in 0 to 2**bin'length - 1 loop
bin <= std_logic_vector(to_unsigned(i, bin'length));
wait for 10 ns;
end loop;
-- Retour à l'état initial
bin <= (others => '0');
wait for 10 ns;
report "Test: OK";
finish;
end process;
Le délai de 10 ns est arbitraire ; toute valeur positive suffit car le DUT est purement combinatoire. L'instruction finish finale termine la simulation proprement.
Vérification de la sortie du DUT
Simplement afficher "Test: OK" serait sans signification si la sortie était fausse. Pour imposer la correction, nous comparons la sortie Gray du DUT à la propriété fondamentale du code Gray : les sorties successives doivent différer exactement d'un bit.
PROC_CHECKER : process
variable prev : std_logic_vector(gray'range);
variable count : integer;
begin
wait on bin;
prev := gray;
-- Permettre à la logique combinatoire de se résoudre
wait for 1 ns;
count := 0;
for i in gray'range loop
if gray(i) /= prev(i) then
count := count + 1;
end if;
end loop;
assert count = 1
report integer'image(count) & " bits changed, should have been 1"
severity failure;
end process;
Ce processus surveille les changements sur bin, capture la sortie Gray précédente, attend la propagation, compte les bits différents, et affirme que le compte est exactement un. Si l'assertion échoue, le simulateur s'arrête immédiatement, empêchant le message "Test: OK" d'apparaître.
Exécution du testbench
Dans ModelSim, démarrez la simulation et exécutez run -all. Une exécution réussie se termine par :
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
Test de la robustesse du testbench
Pour confirmer que le vérificateur détecte les fautes, introduisez temporairement une erreur dans le DUT - par exemple, forcez gray(3) à zéro.
process(bin) is
begin
gray(gray'high) <= bin(bin'high);
for i in bin'high - 1 downto bin'low loop
gray(i) <= bin(i + 1) xor bin(i);
end loop;
-- Émuler une panne bloquée à zéro
gray(3) <= '0';
end process;
L'exécution du testbench déclenche maintenant l'échec de l'assertion, affichant le nombre exact de bits qui ont changé :
VSIM 2> run -all # ** Failure: 0 bits changed, should have been 1 # Time: 81 ns Iteration: 0 Process: /gray_converter_tb/PROC_CHECKER # File: gray_converter_tb.vhd # Break in Process PROC_CHECKER at ray_converter_tb.vhd line 61
Démarrer avec les testbench auto-vérifiants
Adoptez l'habitude d'écrire des testbench auto-vérifiants pour chaque module VHDL. Ils font gagner du temps en détectant les régressions tôt et fournissent un enregistrement clair de l'intention de conception. Bien que les testbench n'aient pas besoin d'être synthétisables, ils doivent être clairs, maintenables, et utiliser les derniers constructs VHDL pour la lisibilité et l'efficacité.
Pour un apprentissage plus approfondi, envisagez des cours avancés qui couvrent le flux de conception complet - de la spécification au prototype FPGA - tout en mettant l'accent sur des pratiques de vérification rigoureuses.
Mis à jour le 12 octobre 2020 : J'ai terminé le cours VHDL et FPGA. Cliquez sur l'image ci-dessous pour en savoir plus.
En savoir plus sur le cours VHDL et FPGA Matrice de Points ici !
Ouverture :
À décider.
VHDL
- Construire votre premier template AWS CloudFormation — Guide pratique
- Construire un Cloud Center of Excellence : Stratégies pour migration réussie et succès client
- Construire un plan stratégique d'adoption du cloud
- Créer des expériences utilisateur sans friction : un guide de conception UX
- Créer des listes de chaînes en VHDL : Bonnes pratiques et exemple
- Créer un banc de test piloté par Tcl pour un module verrou code VHDL
- Implémentation d'une liste chainée dynamique en VHDL avec types protégés et pointeurs d'accès
- Construire des villes intelligentes human-centric : un plan stratégique
- Créer un tableau d'objets en Java : Guide étape par étape