Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

Avez-vous déjà voulu exécuter une simulation VHDL incluant un cœur IP Quartus via le framework de vérification VUnit ?

C'est ce que l'ingénieur FPGA Konstantinos Paraskevopoulos avait en tête, mais il n'a pas trouvé de tutoriel adapté. Heureusement, il a utilisé son talent pour comprendre comment faire et a eu la gentillesse de le partager avec VHDLwhiz à travers cet article invité.

Laissons la parole à Konstantinos !

Il est souvent souhaitable d'incorporer des IPs prédéfinis du catalogue IP Quartus dans votre conception lors de la simulation de votre système avec VUnit. Ce tutoriel fournit les connaissances nécessaires pour générer, incorporer et lier des bibliothèques IP Quartus externes à l'environnement VUnit.

Nouveau sur VUnit ? Consultez ce tutoriel : Premiers pas avec VUnit

Vue d'ensemble

Ce tutoriel se compose de trois parties principales :

  1. Une brève description de l'IP sélectionnée
  2. Étapes requises pour générer et lier les bibliothèques appropriées
  3. Vérification en utilisant VUnit et ModelSim

Prérequis

Il suppose également des connaissances de base en VHDL et ModelSim.

Conception sous test

Pour notre scénario, nous utilisons l'IP Additeur Parallèle de la liste IP Arithmétique Entier de Quartus.

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

Notre conception accepte trois vecteurs d'entrée 16 bits et sort le résultat ajouté dans un vecteur 17 bits.

Étape 1 : Générer l'IP

Nous générons notre additeur à la fenêtre du catalogue IP en double-cliquant sur le composant additeur parallèle sous Bibliothèque/Fonctions de base/Arithmétique.

Après avoir fourni un nom et personnalisé notre composant selon nos besoins, nous cliquons sur le bouton Générer HDL en bas à droite.

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

À ce stade, une fenêtre apparaît, comme représenté dans la figure suivante.

Note : Nous devons définir Create simulation model sous la section Simulation sur VHDL ou Verilog pour générer les fichiers de simulation car l'option par défaut est « none ». Si nous n'en choisissons pas un, le fichier given_ip_name.spd ne sera pas généré, causant l'échec de l'étape suivante.

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

Le processus ci-dessus génère un fichier et un dossier sous notre répertoire quartus :

  1. Fichier : given_ip_name.ip
  2. Dossier : given_ip_name

Le dossier contient des fichiers .vhd et .v qui devront être ajoutés plus tard dans notre script run.py.

Étape 2 : Générer les fichiers de simulation IP

  1. GUI : Sélectionner Outils ➤ Générer le script de configuration du simulateur pour IP et spécifier le répertoire de sortie dans la fenêtre de dialogue,
  2. CMD : En utilisant les commandes Qsys, nous pouvons générer les mêmes fichiers en tapant dans le terminal la commande suivante :
ip-setup-simulation --quartus-project= <chemin_fichier_QPF_projet> \ --output-directory= <mon_dossier>

En utilisant l'une des deux méthodes ci-dessus, nous demandons à Quartus de générer un répertoire pour chaque simulateur supporté qui contient un script pour créer et compiler les bibliothèques IP.

Étape 3 : Générer et compiler les bibliothèques IP pour ModelSim

L'étape suivante consiste à trouver le script msim_setup.tcl dans le dossier mentor créé par l'étape précédente et à le dupliquer sous le nom setup.tcl. Ensuite, dans le fichier setup.tcl, décommenter les commandes illustrées et définir la variable $QSYS_SIMDIR.

# # QSYS_SIMDIR est utilisé dans le script de simulation IP généré par Quartus pour # # construire les chemins vers les fichiers requis pour simuler l'IP dans votre projet # # Quartus. Par défaut, le script IP suppose que vous lancez le # # simulateur depuis l'emplacement du script IP. Si lancement depuis un autre # # emplacement, définissez QSYS_SIMDIR sur le répertoire de sortie que vous avez spécifié # # lors de la génération du script IP, relatif au répertoire depuis lequel vous # # lancez le simulateur. # set QSYS_SIMDIR <répertoire_sortie_génération_script> # # # Source le script de simulation IP généré. source $QSYS_SIMDIR/mentor/msim_setup.tcl # # # Définir les options de compilation souhaitées (inhabituel). # set USER_DEFINED_COMPILE_OPTIONS <options_compilation> # set USER_DEFINED_VHDL_COMPILE_OPTIONS <options_compilation_VHDL> # set USER_DEFINED_VERILOG_COMPILE_OPTIONS <options_compilation_Verilog> # # # Appeler la commande pour compiler la bibliothèque de simulation EDA Quartus. dev_com # # # Appeler la commande pour compiler les fichiers de simulation IP générés par Quartus. com # 

Après avoir modifié et enregistré le setup.tcl, nous pouvons exécuter le fichier Tcl en toute sécurité en utilisant la commande vsim.

vsim -c -do "do setup.tcl; quit"

Cela génère les bibliothèques compilées dans le dossier mentor.

Étape 4 : Lien VUnit

Maintenant que les bibliothèques IP ont été générées, nous devons les lier en utilisant le script python run.py.

Consultez la figure ci-dessous pour mieux comprendre la structure de répertoires de notre exemple. La topologie initiale consistait en le dossier racine demo, les dossiers tb, vunit et quartus. Tous les sous-dossiers et fichiers sous le dossier quartus sont générés via le framework Quartus après la création d'un projet et la réalisation des étapes 1 à 3.

Note : Quartus génère plus de fichiers et dossiers, mais l'image ci-dessous montre ceux qui nous intéressent.

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

En utilisant cette vue distincte de la topologie comme référence, nous pouvons spécifier notre chemin ROOT et le(s) chemin(s) vers les bibliothèques générées, comme indiqué ci-dessous.

Notez que sim_files est le répertoire que nous avons spécifié à l'étape 2 où le dossier mentor a été stocké.

from vunit import VUnit from os.path import join, dirname, abspath # ROOT root = join(dirname(__file__), '../') # Path to generated libraries path_2_lib = '/quartus/sim_files/mentor/libraries/' # ROOT

Après avoir créé une instance VUnit appelée vu, nous pouvons spécifier une bibliothèque de conception pour notre code VHDL et lier les bibliothèques externes requises :

# Create VUnit instance by parsing command line arguments vu = VUnit.from_argv() # create design's library my_lib = vu.add_library('my_lib') # Link external library vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")

Et enfin, ajoutez nos fichiers sources. Ceux-ci se trouvent dans trois sous-dossiers sous le répertoire given_ip_name :

  1. parallel_add_191
  2. synth
  3. sim

Les dossiers synth et sim contiennent les mêmes informations, à savoir la conception de niveau supérieur de notre IP. Cependant, le formatage de ces fichiers dans notre cas est en VHDL. Ils pourraient être en Verilog, et cela dépend de la langue choisie à l'étape 1.

Si notre conception de niveau supérieur implique des sous-composants, nous devons également inclure leurs fichiers sources. Ils se trouvent sous des sous-dossiers dans le répertoire given_ip_name, comme le composant parallel_add_191 dans notre cas.

my_lib.add_source_files(join(root,'quartus','parallel_adder','sim','parallel_adder.vhd')) my_lib.add_source_files(join(root,'quartus','parallel_adder','parallel_add_191','sim','parallel_adder_parallel_add_191_oh4guxa.vhd')) my_lib.add_source_files(join(root,'tb','tb_demo.vhd')) testbench = my_lib.entity("tb_demo") vu.main()

Banc de test

Pour commencer, vous pouvez consulter ce lien pour apprendre les bases de la formation de banc de test VUnit.

Revenons à notre banc de test, nous ajoutons les bibliothèques VUnit nécessaires ainsi que toute autre bibliothèque que nous souhaiterions employer et définissons nos signaux.

Note : L'exécution du processus dans notre exemple est séquentielle. Ainsi, les signaux de contrôle (appelés flags) sont utilisés pour notifier un processus s'il doit commencer ou se terminer.

library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; library vunit_lib; context vunit_lib.vunit_context; entity tb_demo is generic ( runner_cfg : string:= runner_cfg_default); end tb_demo; architecture sim of tb_demo is constant clk_period : time := 10 ns; signal clk : std_logic := '0'; signal rst : std_logic := '0'; -- INPUTS signal data_a : std_logic_vector(0 to 15):= (others => '0'); signal data_b : std_logic_vector(0 to 15):= (others => '0'); signal data_c : std_logic_vector(0 to 15):= (others => '0'); -- OUTPUTS signal result : std_logic_vector(0 to 16); -- CONTROL FLAGS signal reset_done :boolean := false; signal sim_done :boolean := false; signal start_sim :boolean := false; 

Ensuite, nous instancions notre UUT. Quartus fournit des exemples d'instanciation de composants pour VHDL et Verilog sous les conventions de nommage de fichiers ip_name_inst.vhd et ip_name_inst.v.

begin -- Unit Under Test UUT : entity work.parallel_adder port map ( data0x => data_a, -- parallel_add_input.data0x data1x => data_b, -- .data1x data2x => data_c, -- .data2x result => result -- parallel_add_output.result );

Les deux premiers processus qui commencent sont clk_process et reset_rel. Alors que le second est suspendu après la réinitialisation et la mise à true du drapeau reset_done, le clk_process fonctionne tout au long du temps de simulation.

clk_process : process begin clk <= '1'; wait for clk_period/2; clk <= '0'; wait for clk_period/2; end process clk_process; reset_rel : process begin rst <= '1'; wait for clk_period*2; wait until rising_edge(clk); rst <= not rst; reset_done <= true; wait; end process reset_rel;

Maintenant que la réinitialisation est faite, nous pouvons invoquer le processus test_runner pour exécuter nos tests. De plus, le test runner reste actif jusqu'à ce que le drapeau sim_done soit mis à true, ce qui se produit dans le dernier processus.

test_runner : process begin test_runner_setup(runner, runner_cfg); wait until reset_done and rising_edge(clk); iterate : while test_suite loop start_sim <= true; if run("test_case_1") then info ("Start"); info (running_test_case); wait until sim_done; end if; end loop; test_runner_cleanup(runner); end process test_runner; 

Enfin, le processus data_generator exécute plusieurs additions en assignant des valeurs aux trois entrées de notre additeur parallèle en utilisant une boucle for.

Note : Ce processus est déclenché lorsque le processus test_runner l'instruit en mettant en place le drapeau start_sim. À la fin de ce processus, il lève le drapeau sim_done, ordonnant au test runner de mettre en pause la simulation.

data_generator : process constant tag2 : log_level_t := new_log_level("INFO", fg => blue, bg => black, style => bright); variable a,b,c,d : integer; begin wait until start_sim; wait until rising_edge(clk); show(display_handler, tag2); if running_test_case = "test_case_1" then for i in 0 to 10 loop data_a <= std_logic_vector(to_unsigned(i+10,data_a'length)); data_b <= std_logic_vector(to_unsigned(i+20,data_a'length)); data_c <= std_logic_vector(to_unsigned(i+30,data_a'length)); wait until rising_edge(clk); a := to_integer(unsigned(data_a)); b := to_integer(unsigned(data_b)); c := to_integer(unsigned(data_c)); d := to_integer(unsigned(result)); log( integer'image(a) &" + " & integer'image(b) &" + " & integer'image(c) &" = " & integer'image(d), tag2); end loop; end if; sim_done <= true; end process data_generator; 

Vérification

Pour exécuter le cas de test et vérifier que tout fonctionne comme prévu, nous pouvons exécuter le script run.py depuis le répertoire où il se trouve en tapant simplement dans le terminal la commande suivante.

python ./run.py -v

Note : Un logger personnalisé a été utilisé pour une meilleure illustration dans notre sortie visible en fournissant l'option verbose -v. De plus, comme un seul cas de test est défini, nous n'avons pas à fournir d'option pour le spécifier.

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

Enfin, pour vérifier nos résultats dans ModelSim, nous pourrions taper la commande suivante :

python ./run.py --gui

Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape

(Cliquez sur l'image pour l'agrandir)

Conclusion

Pour conclure, nous avons appris comment incorporer et tester des IPs Quartus qui résident dans le catalogue IP au sein d'un environnement VUnit. Bien que ce tutoriel ait utilisé une IP prédéfinie, le même processus s'applique aux IPs packagées personnalisées.

Consultez ce tutoriel VUnit si vous ne l'avez pas déjà fait :
Premiers pas avec VUnit

VHDL

  1. SigFox expliqué : Technologie, impact marché et comparaison avec Link Labs
  2. VUnit 101 : Guide pratique pour la vérification VHDL automatisée
  3. Créer des listes de chaînes en VHDL : Bonnes pratiques et exemple
  4. Terminer proprement une simulation de banc de test VHDL
  5. Comment construire un testbench auto-vérifiant en VHDL - Guide pratique
  6. La technologie : clé de chaînes d'approvisionnement transparentes et éthiques
  7. Machine à grillage : fonctionnement et avantages
  8. Comment amorcer une pompe à engrenages hydraulique pour une performance optimale
  9. Guide étape par étape pour amorcer une pompe hydraulique de tracteur Ford