VUnit 101 : Guide pratique pour la vérification VHDL automatisée
VUnit est un framework de vérification VHDL open-source de premier plan qui couple un lanceur de suite de tests Python avec une bibliothèque VHDL dédiée. Ensemble, ils automatisent la compilation des bancs de test, l'exécution et le rapport de résultats, permettant aux ingénieurs de suivre un cycle de développement piloté par les tests.
Dans ce tutoriel, Ahmadmunthar Zaklouta, l'auteur derrière VHDLwhiz, vous guide à travers tout le flux de travail VUnit – de l'installation et la configuration à la création d'un banc de test, l'écriture de cas de test et leur exécution dans ModelSim. Un projet d'exemple prêt à l'emploi est disponible en téléchargement.
Vue d'ensemble
Utilisez la barre latérale ou le bouton de navigation mobile pour passer d'une section à l'autre. Le tutoriel inclut des captures d'écran pour référence visuelle.
Prérequis
- Intel ModelSim – Installer gratuitement comme décrit ici. L'ajouter à votre
PATHsystème. - Python 3.6+ – Télécharger et ajouter au
PATH. - Git (optionnel) – Télécharger.
- Windows Terminal (optionnel) – Télécharger.
Une maîtrise de base du VHDL et de ModelSim est supposée.
Installation de VUnit
Cloner le dépôt avec les sous-modules :
git clone --recurse-submodules https://github.com/VUnit/vunit.git
Ou télécharger le ZIP, l'extraire dans C:\vunit, puis installer via :
cd C:\vunit python setup.py install
Configurer les variables d'environnement :
VUNIT_MODELSIM_PATH– Chemin vers l'exécutable ModelSim.VUNIT_SIMULATOR– Définir surModelsim.
Exemple de capture d'écran :

Télécharger le projet d'exemple
Extraire le ZIP dans C:\vunit_tutorial et exécuter les scripts inclus.
Introduction à VUnit
VUnit simplifie la vérification HDL en fournissant :
- Une bibliothèque Python pour l'automatisation des tests, la configuration et l'administration.
- Une bibliothèque VHDL contenant des composants de vérification réutilisables.
Le côté VHDL inclut six bibliothèques ; ce tutoriel se concentre sur les bibliothèques logging et check.

Conception sous test (DUT)
Le DUT d'exemple, motor_start, pilote trois LEDs (ROUGE, JAUNE, VERT) pour représenter une séquence de démarrage de moteur. Son interface utilise des types record pour les entrées et sorties.

Le processus de démarrage comporte trois étapes :
- Chargement de la configuration (LED ROUGE)
- Calibration (LED JAUNE)
- Rotation (LED VERTE)
Séquence de démarrage
- LED ROUGE – Clignote cinq fois, puis reste allumée.
- LED JAUNE – S'allume pendant dix cycles après l'interrupteur 2, puis s'éteint avec la ROUGE.
- LED VERTE – S'allume tant que l'interrupteur 3 est actif.
Développement du banc de test
- Configurer le script Python
run.py. - Construire le squelette VUnit.
- Instancier le DUT et piloter les signaux.
Script Python Run
Le script run.py définit les chemins, crée une instance VUnit et ajoute les bibliothèques de conception et de banc de test :
# ROOT directory ROOT = Path(__file__).resolve().parent # Source paths DUT_PATH = ROOT / "design" TEST_PATH = ROOT / "testbench" # VUnit instance VU = VUnit.from_argv() VU.enable_location_preprocessing() # Libraries design_lib = VU.add_library("design_lib") design_lib.add_source_files([DUT_PATH / "*.vhdl"]) tb_lib = VU.add_library("tb_lib") tb_lib.add_source_files([TEST_PATH / "*.vhdl"])
Squelette VUnit
Dans l'entité du banc de test, ajoutez le contexte VUnit et un générique obligatoire :
LIBRARY VUNIT_LIB; CONTEXT VUNIT_LIB.VUNIT_CONTEXT; ENTITY motor_start_tb IS GENERIC(runner_cfg : string := runner_cfg_default); END ENTITY motor_start_tb;
L'architecture héberge le processus test runner :
ARCHITECTURE tb OF motor_start_tb IS test_runner : PROCESS BEGIN test_runner_setup(runner, runner_cfg); WHILE test_suite LOOP -- test cases END LOOP; test_runner_cleanup(runner); END PROCESS; END ARCHITECTURE;
Les cas de test individuels sont définis avec des blocs IF run("case_name") THEN.
Déclarations de signaux & Instanciation du DUT
Définir horloges, réinitialisations et enregistrements d'interface :
CONSTANT C_CLK_PERIOD : time := 10 ns; SIGNAL clk, reset : STD_LOGIC := '0'; SIGNAL motor_start_in : MOTOR_START_IN_RECORD_TYPE := (switch_1 => '0', switch_2 => '0', switch_3 => '0'); SIGNAL motor_start_out : MOTOR_START_OUT_RECORD_TYPE;
Instancier le DUT :
motor_start_tb_inst : ENTITY DESIGN_LIB.motor_start(rtl) PORT MAP( clk => clk, reset => reset, motor_start_in => motor_start_in, motor_start_out => motor_start_out );
Piloter horloge et réinitialisation :
clk <= NOT clk after C_CLK_PERIOD / 2; reset <= '0' after 5 * (C_CLK_PERIOD / 2);
Développement des cas de test
Nous explorons trois styles de vérification : driver & checker inline, checker contrôlé, et checker auto-vérifiant.
Driver & Checker Inline
Un cas de test simple qui pilote switch_1 et vérifie les états des LEDs en utilisant la famille check de VUnit :
IF run("switch_1_on_output_check") THEN WAIT UNTIL reset = '0'; WAIT UNTIL falling_edge(clk); motor_start_in.switch_1 <= '1'; FOR i IN 0 TO 4 LOOP WAIT UNTIL rising_edge(clk); check(motor_start_out.red_led = '1', "Red LED should be on"); check_false(motor_start_out.yellow_led, "Yellow LED should be off"); check_equal(motor_start_out.green_led, '0', "Green LED should be off"); END LOOP; END IF;
Checker Contrôlé
Ici, le driver reste dans le cas de test tandis que le checker s'exécute dans un processus séparé, contrôlé par des événements de début/fin. Par exemple, vérifier la LED JAUNE après l'activation de switch_2 :
check_stable(clock => clk, en => enable, start_event => yellow_low_start_event, end_event => yellow_low_end_event, expr => motor_start_out.yellow_led, msg => "YELLOW LED low before switch_2");
Checker Auto-Vérifiant
Encapsuler la logique de vérification dans un processus dédié qui utilise check ou check_stable en interne. Une procédure de driver simplifie le stimulus :
PROCEDURE switch_driver( SIGNAL switches : OUT MOTOR_START_IN_RECORD_TYPE; CONSTANT clk_period : IN TIME; CONSTANT sw1_delay : IN INTEGER; CONSTANT sw2_delay : IN INTEGER; CONSTANT sw3_delay : IN INTEGER) IS BEGIN IF sw1_delay >= 0 THEN WAIT FOR clk_period * sw1_delay; switches.switch_1 <= '1'; END IF; IF sw2_delay >= 0 THEN WAIT FOR clk_period * sw2_delay; switches.switch_2 <= '1'; END IF; IF sw3_delay >= 0 THEN WAIT FOR clk_period * sw3_delay; switches.switch_3 <= '1'; END IF; END PROCEDURE;
Exécution des tests
Depuis le terminal :
python .\run.py *switch_1_on_output_check
VUnit compile la conception, découvre les bancs de test et exécute le cas spécifié. La sortie est journalisée dans C:\vunit_tutorial\vunit_out\test_output.
Utilisez -v pour logs verbeux, -l pour lister tous les cas, --clean pour purger les résultats précédents, ou -g pour lancer ModelSim avec une fenêtre d'ondes (nécessite un fichier wave.do).
Résumé
VUnit offre un framework robuste et léger qui accélère les équipes de conception et de vérification. Son harnais de test piloté par Python, ses riches bibliothèques VHDL et son API de checker flexible en font un ajout précieux à tout flux de travail HDL.
Prochaines étapes
- Lire la documentation officielle.
- Suivre le blog VUnit pour les mises à jour.
- Rejoindre la communauté sur Gitter.
Téléchargez le projet d'exemple complet via le formulaire ci-dessous.
VHDL
- Code-Ready Containers : Guide Pratique d'Automatisation Cloud-Native avec Red Hat OpenShift
- Guide pratique de l'impression 3D céramique : techniques, matériaux et conseils de conception
- Comprendre les colorants basiques : usages, sécurité et applications industrielles
- Démarrage avec TJBot : Construire, Configurer et Contrôler par la Voix Votre Propre Robot IA
- Guide Pas à Pas pour Déployer une Passerelle LoRa RAK 831 sur Raspberry Pi 3
- Construire une passerelle LoRa avec le module RAK831 sur Raspberry Pi 3 – Guide pas à pas
- L'IoT à l'ère de l'Edge : croissance, données, sécurité et stratégie partenaires
- IA dans l'assurance : Guide pratique de démarrage pour une implémentation réelle
- Tutoriel Arduino Débutant 01 : Démarrez votre Premier Projet