Table of Contents
La conception de matériel FPGA et ASIC fiable exige des tests et une validation rigoureux. Les testbenches VHDL sont des outils indispensables pour permettre aux ingénieurs de simuler et de vérifier les conceptions numériques avant de s'engager dans le silicium. Un testbench efficace capture les erreurs fonctionnelles, les violations de calendrier et les bogues de coin tôt dans le cycle de conception, économisant des mois de retravail et réduisant les coûts de développement.
Qu'est-ce qu'un testbench VHDL?
Contrairement à la VHDL synthétisée, qui doit être magné sur le matériel réel, la machine n'a aucune contrainte de synthèse. Elle a pour but de générer des stimuli d'entrée pour la conception en cours de test (DUT), d'appliquer ces stimuli au fil du temps, de surveiller les sorties de la DUT et de vérifier automatiquement si ces sorties correspondent aux résultats attendus. Les testbenches peuvent être aussi simples que quelques lignes qui basculent une horloge et réinitialisent, ou aussi complexes que des milliers de lignes de code qui exécutent des tests dirigés, des séquences aléatoires et même une validation basée sur des scores.
La différence fondamentale entre un testbench et un module synthétisant est que les testbenches ne doivent jamais être implémentés sur un FPGA ou fabriqués comme ASIC. Ils fonctionnent entièrement dans un simulateur tel que Siemens EDA ModelSim/Questa, Aldec Riviera-PRO ou Vivado Simulator. Cette liberté permet aux ingénieurs d'utiliser des constructions comme des E/S de fichiers, des sorties texte et des structures de données complexes qui seraient impraticables dans le matériel.
Pourquoi les testbenches sont critiques pour la validation FPGA et ASIC
De nombreux ingénieurs de vérification consacrent 60 à 80 % du temps de projet à des essais. Sans testbench, la validation d'une conception nécessite une inspection manuelle des formes d'onde, qui est sujette aux erreurs et lente.
- Détection précoce des bogues:[ Les bogues trouvés lors de la simulation coûtent une fraction de ceux trouvés après la fabrication dans les ASIC ou après l'ajout de planches dans les FPGA.
- Essais de régression:[ Lorsque des modifications de conception sont apportées, les bancs de test peuvent être réutilisés pour s'assurer que les fonctionnalités existantes ne sont pas brisées.
- Couverture corner-case: Testbenches peut générer beaucoup plus de combinaisons d'entrée que l'édition manuelle de forme d'onde peut atteindre.
- Documentation: Un banc de test bien écrit sert de référence pour la façon dont le TUD est conçu pour fonctionner.
Pour les modèles ASIC, un testbench est souvent le premier code écrit après la finalisation des spécifications, parfois avant que le RTL lui-même ne soit complet. Cette pratique, connue sous le nom de développement axé sur les tests, garantit que la conception est validée dès le début.
Composantes clés d'un testbench VHDL efficace
Chaque testbench, quelle que soit sa complexité, contient plusieurs éléments fondamentaux. Comprendre ces composants est la première étape vers l'écriture de tests efficaces.
1. Génération d'horloge et de réinitialisation
La plupart des conceptions numériques synchrones nécessitent une horloge et une réinitialisation. Les testbenches incluent généralement un processus qui accumule un signal d'horloge à une fréquence spécifiée. La réinitialisation de génération doit affirmer la réinitialisation pour quelques cycles puis la relâcher. Exemple de modèle:
- Assister à la remise en état basse pour 100 ns.
- Réinitialisez l'assert pendant que l'horloge tourne.
- Laisser quelques cycles d'horloge avant d'appliquer des vecteurs d'essai.
2. Génération de stimulants
Ce composant crée des signaux d'entrée qui représentent des conditions réelles. Stimulus peut être dirigé (chaque vecteur de test explicitement défini) ou aléatoire (en utilisant la génération de nombres pseudo-aléatoire). Stimulus est souvent organisé en un ou plusieurs process ou procesures qui conduisent les ports DUT.
3. L'inoculation DUT
La conception en cours d'essai est innovée à l'intérieur de l'architecture testbench. Ses ports sont reliés aux signaux locaux que le testbench conduit ou surveille. Les conventions de nommage de signaux (p. ex. , ) aident à distinguer les signaux testbench des filets internes DUT.
4. Surveillance et contrôleurs
Les moniteurs observent les sorties DUT et capturent leurs valeurs à des moments de simulation précis. Les vérificateurs comparent les sorties réelles aux valeurs prévues, soit immédiatement, soit après un délai connu. Les testbenches auto-vérifient automatiquement les erreurs en utilisant des instructions d'affirmation () pour les signaler automatiquement.
5. Séquenceur d ' essai
Pour plusieurs scénarios de test, un séquenceur contrôle l'ordre d'exécution, applique des stimuli dans des phases définies et peut inclure des barrières de synchronisation (p. ex. attendre une réponse spécifique avant d'envoyer la prochaine entrée).
6. Rapport et exploitation forestière
Testbenches doit afficher des messages de progression et des résultats finaux sur la console du simulateur ou un fichier journal. Cela permet des simulations par lots sans avoir besoin de voir manuellement les formes d'onde.
Étapes pour créer un testbench VHDL
La construction d'un banc d'essai à partir de zéro suit une approche systématique. Les étapes ci-dessous s'appliquent à la fois aux environnements simples et avancés.
Étape 1: Comprendre l'interface et la spécification DUT
Avant d'écrire une seule ligne, examinez la liste des ports de la DUT, les exigences du protocole, les diagrammes de chronométrage et les spécifications fonctionnelles. Identifiez tous les ports d'entrée et de sortie, leurs largeurs de données et leurs poignées de main. Par exemple, si la DUT est un FIFA AXI Stream, notez la poignée de main prête/valide, le comportement de contrepression et les paramètres de seuil.
Étape 2: Écrire le squelette de testbench
Créer un fichier VHDL avec une entité vide (pas de ports) et une architecture. Déclarer les signaux qui se connecteront aux ports DUT. Instantaner le DUT en tant que composant. Par exemple:
entity tb_fifo is
end entity tb_fifo;
architecture sim of tb_fifo is
signal clk : std_logic := '0';
signal rst_n : std_logic := '0';
signal data_in : std_logic_vector(7 downto 0);
signal wr_en : std_logic;
signal full : std_logic;
-- ... other signals
begin
DUT: entity work.fifo
port map (
clk => clk,
rst_n => rst_n,
data_in => data_in,
wr_en => wr_en,
full => full
);
-- Clock generation process
clk <= not clk after 5 ns;
end architecture sim;
Étape 3: Créer des processus de stimulation
Ajoutez un ou plusieurs processus pour piloter le DUT. Pour un FIFO simple, vous pouvez écrire un processus qui écrit des données dans le FIFO jusqu'à ce qu'il devienne complet, puis le lit. Utilisez ou pour synchroniser avec l'horloge.
Étape 4: Mettre en oeuvre des moniteurs et des vérificateurs
Inclure des processus qui observent les signaux de sortie et les comparent aux valeurs attendues.
assert dout = expected_data
report "Data mismatch at time " & time'image(now)
severity error;
Pour les DUT complexes, envisagez de construire un modèle de référence – une description comportementale qui prédit un comportement correct – et comparez sa sortie au cycle de sortie du DUT par cycle.
Étape 5: Exécuter des simulations et analyser les résultats
Compilez le testbench et le DUT dans votre simulateur choisi. Exécutez la simulation et examinez la transcription pour les défaillances d'affirmation. Utilisez les téléspectateurs de forme d'onde pour déboguer les comportements inattendus. Affiner l'itérative testbench.
Types de stratégies d'essai dans les bancs d'essai VHDL
Différents objectifs de vérification de la conception exigent des méthodes d'essai différentes.
Essais dirigés
Dans les tests dirigés, chaque cas d'essai est conçu manuellement pour vérifier une fonctionnalité spécifique. Ceci est facile à écrire et à déboguer mais ne s'adapte pas à des conceptions complexes.
Essais aléatoires
Les tests aléatoires utilisent des générateurs de nombres pseudo-aléatoire pour créer un grand nombre de séquences d'entrée. Le testbench vérifie automatiquement les sorties, souvent à l'aide d'un modèle de référence. Cette approche découvre des cas d'angle que le specificateur humain pourrait manquer. VHDL fournit la fonction pour générer des nombres aléatoires.
Essais de couverture
Les mesures de couverture (couverture de code, couverture de basculement, couverture fonctionnelle) indiquent quelles parties de la conception ont été effectuées. De nombreux simulateurs peuvent déclarer la couverture. La couverture fonctionnelle peut être mise en œuvre à l'aide de paquets de couverture VHDL (p. ex. OSVVM ou UVVM).
Essai de régression
Au fur et à mesure que la conception évolue, une suite de régression exécute toutes les testbenches passées antérieurement pour s'assurer qu'aucune régression n'est introduite. Cela nécessite un harnais de test automatisé.
Techniques avancées pour les testbenches robustes
Au-delà des mesures de stimulation et de vérification de base, les ingénieurs de vérification chevronnés utilisent plusieurs techniques avancées pour améliorer la productivité et la qualité des essais.
Utilisation des procédures et des fonctions
Encapsuler les schémas de stimulus répétés dans des procédures ou des fonctions. Par exemple, une procédure qui écrit un seul mot à une interface AXI Stream peut être réutilisée pour de nombreux tests. Cette modularité réduit la duplication de code et rend le testbench plus facile à maintenir.
L'invocation d'entités par rapport à l'invocation de composants
L'instantiation directe de l'entité (VHDL-93 et plus tard) est recommandée car elle évite les déclarations de composants distinctes. Utilisez directement dans l'architecture. Ceci est moins sujet aux erreurs et conserve le code de nettoyage testbench.
Caractéristiques VHDL-2008
VHDL-2008 a introduit plusieurs constructions qui améliorent le développement de testbench:
- Types génériques améliorés: Permet des paramètres génériques plus flexibles.
- Expressions booléennes dans les ports: Simplifier la connexion des signaux non résolus.
- Attributions de signaux conditionnelles et sélectionnées : Réduire le besoin de blocs de processus.
- Paquet standard : Fournit et des procédures pour terminer la simulation proprement.
- Améliorations de l'évaluation:[ les énoncés peuvent inclure pour arrêter la simulation.
L'adoption de la norme VHDL-2008 dans les testbenches (même si la DUT doit être écrite dans des normes plus anciennes) améliore la lisibilité et réduit le volume de code.
Fichier E/S pour les vecteurs d'essai
Pour les conceptions qui traitent de gros ensembles de données (p. ex., filtres d'image ou processeurs de paquets), il est essentiel de lire les vecteurs de test à partir de fichiers texte ou binaires. Le paquet de VHDL fournit et procédures.
Tableau de bord et prévision
Un tableau de bord est une structure de données qui suit les transactions en suspens et les vérifie quand les réponses arrivent. Ceci est courant dans les modèles de bus-fonctionnel. Par exemple, dans un testbench de contrôleur DMA, un tableau de bord peut suivre chaque demande écrite et vérifier que les données apparaissent à l'emplacement de la mémoire correcte.
Meilleures pratiques pour maintenir les testbenches VHDL
Les bonnes pratiques de testbench sont payantes à mesure que la conception grandit. Les lignes directrices suivantes aident à maintenir les testbenches robustes et adaptables.
Modularité et réutilisation
Découpez le testbench en fichiers séparés : un pour l'instantiation DUT et la génération horloge/reset, un autre pour les procédures communes, un troisième pour les séquences de test. Utilisez des paquets pour partager des constantes et des types. Cette modularité permet de réutiliser des procédures sur plusieurs testbenches.
Conventions sur la désignation
Utiliser des noms clairs et cohérents. Par exemple :
- préfixe pour les signaux de banc d'essai.
- pour les générateurs.
- pour les vérificateurs.
- pour les constantes spécifiques aux essais.
Paramètreisation par des génériques
Passer les paramètres génériques DUT (p. ex. largeur des données, profondeur FIFO) à l'entité testbench par des cartes génériques, ce qui permet au même testbench de vérifier plusieurs configurations sans changement de code.
Autocontrôle et tolérance zéro
Chaque testbench doit automatiquement échouer si une affirmation échoue. Utilisez pour les erreurs catastrophiques et pour les erreurs d'appariement. Évitez les simulations qui se terminent par un message «succès» si aucune défaillance n'a eu lieu, c'est ambigu. Au lieu de cela, faites imprimer explicitement le testbench «Testbench» seulement après toutes les vérifications.
Documentation et commentaires
Documenter l'objet de chaque test, le comportement attendu et toute exigence de calendrier spécial. De bons commentaires aident les futurs ingénieurs (y compris vous-même six mois plus tard) à comprendre les intentions des tests.
Intégrer les testbenches VHDL avec les outils de simulation modernes
L'utilisation efficace d'un banc d'essai nécessite de comprendre comment interagir avec le simulateur.
Scénarios de simulation
La plupart des outils de simulation supportent le script Tcl (ModelSim, Vivado, Riviera-PRO). Ecrivez un script de compilation qui compile tous les fichiers sources dans l'ordre approprié, met en place des bibliothèques de simulation et exécute le testbench. Par exemple, un fichier ModelSim typique :
vlib work
vcom -2008 dut.vhd
vcom -2008 tb_fifo.vhd
vsim -voptargs=+acc work.tb_fifo
run -all
Mode de lot et régression
Pour les tests de régression, exécutez des simulations en mode batch (pas de GUI) pour gagner du temps. Le testbench devrait afficher un message clair de passage/échec qui peut être analysé par un script externe.
Dumping et débogage de la forme d'onde
Pendant le développement, activez la logage de la forme d'onde pour les signaux de débogage. Utilisez dans ModelSim pour enregistrer tous les signaux hiérarchiques.
Recouvrement
Activer les options de couverture de code dans le simulateur. Dans ModelSim, utilisez puis pour écrire des rapports de couverture. Analysez des lignes non atteintes ou basculez des points pour créer des cas de test supplémentaires.
Pièges courants et comment les éviter
Négligence de la séquence de remise à zéro
De nombreux modèles nécessitent une remise à zéro pour être affirmée pour un nombre spécifique de cycles d'horloge. Toujours suivre la spécification DUT; les testbenches génériques échouent souvent parce que la remise à zéro a été confirmée trop tôt.
Synchronisation incorrecte
Les signaux de conduite dans le mauvais cycle d'horloge sont une source fréquente d'erreurs de simulation. Toujours conduire les entrées immédiatement après un bord d'horloge montant (en utilisant ), pas pendant le bord.
Couverture incomplète
Il est facile de tester le fonctionnement normal mais sautez les conditions d'erreur (p. ex., FIF complet, contrepression, entrée invalide).
Ignorer le temps
La simulation de RTL synthétisant est généralement précise par cycle, mais les testbenches peuvent facilement modéliser les chemins combinés de manière incorrecte. Utilisez des clauses avec soin; préférez la synchronisation à la ligne d'horloge pour les interfaces synchrones.
Retards codés en dur
Évitez à moins de modéliser un comportement purement asynchrone. De tels retards rendent les testbenches sensibles aux changements de fréquence de l'horloge. Utilisez plutôt des cycles d'horloge.
Outils et ressources externes
Pour approfondir votre expertise, explorez les ressources suivantes :
- UVVM: Universal VHDL Verification Methodology[ – Un cadre de vérification VHDL open-source qui fournit des procédures pour gérer des interfaces communes comme AXI, SPI et UART.
- OSVVM: Open Source VHDL Verification Methodology – Offre des fonctionnalités de randomisation, de couverture et de tableau de bord pour augmenter les testbenches VHDL standard.
- VHDL-2008 Designers Guide[ – Référence complète pour les fonctionnalités linguistiques particulièrement utiles dans les testbenches.
Conclusion
En maîtrisant les composants de base – génération de stimulus, surveillance, autocontrôle et couverture – vous pouvez créer des environnements de test qui capturent les bugs tôt et s'assurent que les conceptions répondent aux spécifications avant la construction du matériel. Investir dans des testbenches modulaires, paramétrés et bien documentés qui s'échellent avec complexité de conception. À mesure que les outils et les méthodologies de vérification comme UVVM et OSVVM évoluent, intégrer ces cadres peut augmenter la productivité. En fin de compte, le temps investi dans la construction d'un testbench complet rapporte des dividendes grâce à des cycles de débogage réduits, moins de rechutes et une plus grande confiance dans le matériel qui est finalement déployé.