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

Comment créer un banc d'essai d'auto-vérification

Un banc d'essai d'auto-vérification est un programme VHDL qui vérifie l'exactitude de l'appareil testé (DUT) sans compter sur un opérateur pour inspecter manuellement la sortie. Le banc de test d'auto-vérification fonctionne entièrement de lui-même et affiche un message "OK" ou "Échec" à la fin.

Chaque module VHDL doit avoir un banc de test d'auto-vérification associé. Il est important de pouvoir vérifier que tous les modules ont le comportement prévu à tout moment. Par exemple, lorsque vous apportez des modifications au DUT, à un sous-module ou à un module d'interfaçage. Nous savons tous que des choses peuvent casser, et votre meilleur outil pour détecter ces problèmes est le banc d'essai d'auto-vérification.

L'appareil testé

Passons directement à l'action et créons un exemple de banc d'essai d'auto-vérification. Tout d'abord, nous avons besoin de quelque chose à tester, un DUT. Pour cela j'ai créé le module dans le code ci-dessous. C'est un convertisseur de code binaire en code Gray.

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 de codage numérique alternatif, différent du codage binaire ordinaire. La principale propriété et le but du code Gray sont qu'un seul bit change lors du comptage entre des valeurs numériques adjacentes.

Décimal Binaire Gris
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

Le tableau ci-dessus montre en quoi le code Gray diffère du code binaire.

Le banc d'essai

Nous allons commencer par créer le banc de test de base et instancier le DUT en son sein. Le code ci-dessous montre le fichier testbench avec le DUT instancié et toutes les importations nécessaires.

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);

begin

  DUT : entity work.gray_converter(rtl)
  port map (
    bin => bin,
    gray => gray
  );

end architecture;

Notez que nous importons std.env.finish qui nécessite VHDL-2008. Si vous essayez de compiler le testbench dans ModelSim sans rien changer, vous obtiendrez l'erreur suivante :

# ** Warning: gray_converter_tb.vhd(6): (vcom-1516)
Package "STD.ENV" does not exist in this language version.

Heureusement, cela peut facilement être résolu en définissant la version VHDL du fichier testbench sur VHDL-2008. Cliquez avec le bouton droit sur le fichier testbench .vhd et sélectionnez Propriétés→VHDL→Utiliser 1076-2008->OK.

Vous n'avez rien à changer pour le DUT. Il est normal d'utiliser une version supérieure de VHDL pour les bancs de test que pour les modules RTL. Vous voulez toujours pouvoir utiliser les dernières constructions VHDL dans votre testbench, mais la plupart des outils de synthèse ne les prennent pas en charge.

Générer l'entrée

Notre prochain ajout au testbench sera le processus qui génère des entrées pour le DUT. Il est toujours préférable de créer un test exhaustif, un test qui essaie toutes les valeurs d'entrée possibles. Cependant, s'il y a trop de permutations, vous pouvez être limité à ne faire que des cas extrêmes.

L'entrée et les sorties de notre DUT sont d'une plage non spécifiée. Cependant, je vais faire une supposition éclairée que le test avec des longueurs de vecteur de quatre bits est suffisant pour révéler tout problème possible avec ce module.

Le code ci-dessous contient l'ensemble du processus de génération de la séquence d'entrée.

PROC_SEQUENCE : process
begin

  -- Test all possible input values
  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;

  -- Finally, test the wrapped value
  bin <= (others => '0');
  wait for 10 ns;

  report "Test: OK";
  finish;

end process;

Le premier bloc de code est une boucle For qui génère la séquence de comptage de la valeur la plus basse possible à la valeur la plus élevée possible. Entre les valeurs, nous attendons 10 nanosecondes pour permettre au DUT de réagir. Cependant, toute valeur de nanoseconde supérieure à 0 aurait fonctionné, car la logique à l'intérieur du DUT est purement combinatoire.

Le deuxième morceau de code sert à tester la situation où le compteur d'entrée revient à 0, qui était la valeur d'entrée initiale. Après cela, il n'est plus nécessaire de procéder à d'autres tests, car le DUT continuera simplement à donner les mêmes résultats encore et encore.

Les deux dernières lignes de code du processus permettent de terminer le test en douceur. Le texte "Test :OK" est imprimé sur la console, puis la simulation est arrêtée en utilisant le mot clé VHDL-2008 "finish".

Notez que si vous exécutez ModelSim avec le bouton Exécuter par défaut, ModelSim vous invitera avec la boîte de dialogue Quitter une fois le banc d'essai terminé avec succès. Ce comportement peut être modifié lors du lancement de Vsim à partir d'un script ou de la ligne de commande. Ajoutez le commutateur "-onfinish stop" à la commande Vsim, comme décrit dans la référence de commande ModelSim.

Vérification de la sortie

Maintenant, nous alimentons le DUT avec des entrées, mais il n'y a aucune vérification de la sortie. Le testbench affichera "Test :OK", que la sortie soit correcte ou non. Faisons quelque chose à ce sujet.

Lors de la création d'un algorithme de vérification, vous devez toujours essayer d'implémenter le test différemment que dans le DUT. Sinon, une faille fondamentale dans la logique peut passer inaperçue car elle est présente dans le DUT ainsi que dans l'algorithme du banc de test.

Suivant ce principe, nous allons tester la sortie du DUT non pas en vérifiant que le code Gray est correct, mais plutôt qu'un seul bit change d'un nombre au suivant. Après tout, c'est toute la raison d'utiliser le code Gray en premier lieu. Le code ci-dessous montre un processus qui effectue ce type de vérification.

PROC_CHECKER : process
    variable prev : std_logic_vector(gray'range);
    variable count : integer;
begin
  wait on bin;

  prev := gray;

  -- Wait for all delta cycles to propagate
  wait for 1 ns;
  
  -- Count the number of changed bits
  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;

Le processus est sensible au bin signal, l'entrée du DUT. Nous aurions pu utiliser une liste de sensibilité avec le même résultat, mais je préfère utiliser uniquement les instructions Wait dans le code de testbench. C'est une convention qui permet de savoir facilement si vous avez affaire à un testbench ou à un module RTL simplement en regardant comment le code est écrit.

Sur la ligne des secondes, nous copions la sortie DUT précédente. N'oubliez pas qu'il s'agit du premier delta-cycle après le bin le signal a changé et le DUT ne peut pas encore réagir. Ainsi, il est prudent de copier la sortie DUT en supposant qu'il s'agit de l'ancienne valeur.

Ensuite, nous attendons 1 nanoseconde pour permettre à toute la logique combinatoire du DUT de se terminer. Maintenant, la sortie du DUT devrait être stable et nous pouvons examiner sa valeur en toute sécurité.

Dans le morceau de code suivant, nous utilisons une boucle For pour compter le nombre de bits modifiés sur la sortie du DUT.

Enfin, vient l'instruction Assert qui vérifie que le nombre de bits modifiés est exactement 1. Les instructions Assert fonctionnent en vérifiant la condition, qui dans ce cas est count = 1 . Si la condition est évaluée à false , une assertion sera générée et le simulateur s'arrêtera avant que le message "Test :OK" ne soit imprimé.

Il est sage d'inclure l'instruction report facultative avec l'instruction assert. Ce texte sera imprimé si l'assertion échoue. Dans notre exemple, je fournis une brève explication de l'événement qui a provoqué l'échec du testbench.

Exécuter le banc d'essai

Il est temps d'exécuter notre testbench pour vérifier que le DUT fonctionne correctement. Après avoir démarré la simulation dans ModelSim et appuyé sur le bouton "run -all", nous voyons que le message "Test :OK" est imprimé sur la console.

VSIM 1> run -all
# ** Note: Test: OK
#    Time: 170 ns  Iteration: 0  Instance: /gray_converter_tb

Tester le banc d'essai

J'aime toujours créer une condition d'échec dans le DUT juste pour voir que le testbench fonctionne. Parfois, cela vient naturellement en raison d'erreurs réelles dans le DUT pendant que vous le développez. Mais si ce n'est pas le cas, créez simplement une erreur brièvement pour tester le testbench.

Pour ce faire, je vais éditer le code DUT pour créer une erreur bloquée à 0 sur le bit numéro 3. Après ce test, je supprimerai l'erreur en sachant que le testbench est capable de détecter de telles erreurs. Le code ci-dessous montre le processus DUT avec la ligne de code supplémentaire.

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;

  -- Emulate a stuck at zero error
  gray(3) <= '0';

end process;

Lorsque nous exécutons le testbench maintenant, nous pouvons voir que le testbench s'arrête et que l'erreur est imprimée avant que la ligne "Test :OK" ne soit atteinte. La transcription de la console ModelSim est présentée ci-dessous.

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 bancs de test d'auto-vérification

Vous devriez être en mesure de créer un banc d'essai d'auto-vérification en utilisant ce que vous avez appris dans cet article. Prenez l'habitude de toujours créer des bancs d'essai autovérifiés pour tous vos modules VHDL. Cela vous fera gagner du temps à long terme.

Il est normal d'être créatif lors de l'écriture de bancs d'essai. Plus que lors de l'écriture de modules RTL car toutes les constructions VHDL ne peuvent pas être synthétisées, mais le testbench n'a pas besoin d'être synthétisable. Attendez-vous à passer au moins autant de temps à écrire des tests qu'à écrire le DUT.

Si vous voulez vous lancer sérieusement dans les tests, vous pourriez être intéressé par mon * prochain cours VHDL et FPGA. Dans le cours, je vous guiderai à travers le processus de conception complet, de l'idée au prototype de FPGA fonctionnel. Nous allons créer plusieurs bancs d'essai autovérifiés.

Mise à jour le 12 octobre 2020 : J'ai terminé le cours. Cliquez sur l'image ci-dessous pour en savoir plus.

Je vais vous enseigner les meilleures pratiques pour créer avec succès des conceptions VHDL et FPGA de la bonne manière. Les connaissances que j'ai acquises au cours de nombreuses années dans le milieu universitaire et après avoir travaillé comme ingénieur matériel dans l'industrie de la défense vous seront transmises.

En savoir plus sur le cours Dot Matrix VHDL et FPGA ici !

Ouvre :

À déterminer .


VHDL

  1. Comment créer un modèle CloudFormation à l'aide d'AWS
  2. Comment créer un centre d'excellence cloud ?
  3. Comment créer une stratégie cloud soigneusement conçue
  4. Comment créer une expérience utilisateur sans friction
  5. Comment créer une liste de chaînes en VHDL
  6. Comment créer un banc d'essai piloté par Tcl pour un module de verrouillage de code VHDL
  7. Comment créer une liste chaînée en VHDL
  8. Comment créer des villes intelligentes centrées sur l'humain
  9. Comment créer un tableau d'objets en Java