TD6 VHDL et Simulation

TD5 VHDL et CAO << Conception et VHDL


VHDL est un langage de spécification, il est donc très lié à la simulation. Nous allons présenter un certain nombre de façons de simuler. La simulation dépend beaucoup des fournisseurs des simulateurs VHDL.

Test Bench = test en VHDL

Introduction modifier

Nous allons commencer par deux exemples :

entity addit is port (
  a,b,c: in bit;
  s,r: out bit);
end addit;
architecture addit of addit is
begin
  s <= a xor b xor c;
  r <= ((a and b) or (c and (a xor b)));
end addit;

Si l'on veut tester cet additionneur il faut bâtir un fichier destiné à construire les signaux de tests : on appelle cela un Test Bench. On parle classiquement de test bench lorsque la simulation se réalise en VHDL (sauf pour visualiser les résultats). On prendra par exemple : fichier demo1.vhdl

entity demo1 is
end demo1;
architecture demo1 of demo1 is
  signal asig,bsig,csig,sum,carry : bit;
begin
  asig <= not asig after 100 ns;
  bsig <= not bsig after 200 ns;
  csig <= not csig after 400 ns;
  ad1:entity work.addit 
  port map (asig,bsig,csig,sum,carry);
end demo1;

Autre exemple (séquentiel celui-là) :

entity cmpt is port (
  clk: in bit;
  q0,q1: inout bit);
end cmpt;
architecture cmpt of cmpt is
begin
  cmpt1 : process (clk) begin
  if (clk'event and clk='1') then
      q0 <= not q0;
      q1 <= q0 xor q1;
  end if;
  end process;
end cmpt;

Si l'on veut tester ce compteur il faut bâtir un fichier destiné à construire les signaux de tests. On prendra par exemple : fichier demo2.vhdl

entity demo2 is	
end demo2;
architecture demo2 of demo2 is
  signal clksig,q0sig,q1sig : bit;
begin
  clksig <= not clksig after 10 ns;
  cpt1:entity work.cmpt 
  port map (clksig,q0sig,q1sig);
end demo2;

Quelques autres manières de spécifier des valeurs sur les entrées :

process begin
  s_en<='0';
  s_d0<='1';
  wait for 40 ns;
  s_en<='1';
  wait for 40 ns;
  ..
end process;

ou encore

process begin
  wait for 5 ns;
  s_en<='0','1' after 10 ns,'0' after 18 ns,
  '1' after 25 ns; --30 ns ici
  wait; --fin
  ..
end process;

Remarque : la plupart des simulateurs y compris celui de Warp (Aldec) acceptent ce style de test. Pour un simulateur gratuit sous Linux voir FreeVHDL

Méthodes graphiques modifier

Les méthodes graphiques sont intuitives et de ce fait très appréciées par les étudiants. Il n'empêche qu'il est facile de trouver des exemples simples qui sont bien mieux décrits par des méthodes textuelles. L'exercice 1 en fournit un exemple.

Exercice modifier

Exercice 1 : Simulation textIO On donne le programme :

ENTITY Counter_1 IS end;
--library work;use work.textio.all;
library std;use std.textio.all; -- avec warp2
architecture behave of Counter_1 is
  signal clk : bit:='0';
  signal Count : integer:=0;
begin
  process begin 
    wait for 10 ns;
	clk <= not clk;
    if( now > 340 ns) then wait; end if; -- fin
  end process;
  process begin
    wait until (Clk='0');
	if (Count=7) then Count <=0; 
	else Count <=Count+1;
	end if;
  end process;
  process (Count) variable L:LINE; begin
    write(L,now);write(L,STRING'(" Count= "));
    write(L,Count);writeline(Output,L);
  end process;
end behave;

qui donne en simulation :

20 ns Count= 1
40 ns Count= 2
60 ns Count= 3
80 ns Count= 4
100 ns Count= 5
120 ns Count= 6
140 ns Count= 7
160 ns Count= 0
180 ns Count= 1
200 ns Count= 2
220 ns Count= 3
240 ns Count= 4
260 ns Count= 5
280 ns Count= 6
300 ns Count= 7
320 ns Count= 0

On peut remarquer la façon de faire ici : un process décrit le composant à tester et deux autres process sont là pour le test.

1°) Repérer le compteur et le transformer en écrivant le process de comptage dans un style plus familier pour nous : en utilisant une liste de sensibilité et un if clk'event.

2°) Reprendre le test de l'additionneur et le transformer pour avoir une sortie affichée en texte lors de sa simulation. Comment faire pour que sa sortie sur 2 bits apparaisse en décimal (de 0 à 3) ?

3°) Réaliser un module (librairie) qui permet de tester un afficheur 7 segments sur du texte. À faire que si l'on a du temps.

Méthode tabulaire modifier

Elle consiste à construire une table de valeurs. Un exemple sera plus parlant :

ENTITY Counter_1 IS end;
library std;
use std.textio.all; 
architecture behave of Counter_1 is
  signal clk : bit:='0';
  signal Count : integer:=0;
  type test_vector is record
    clk: bit;
    cnt: integer;
  end record;
  type test_vector_array is array(natural range<>) of test_vector;
  constant test_vectors:test_vector_array := (
    (clk=>'0',cnt=>0),
    (clk=>'1',cnt=>0),
    (clk=>'0',cnt=>0),
    (clk=>'1',cnt=>1),
    (clk=>'0',cnt=>1),
    (clk=>'1',cnt=>2),
    (clk=>'0',cnt=>2),
    (clk=>'1',cnt=>3),
    (clk=>'0',cnt=>3)
  );
  
begin
  process 
    variable i:integer:=0;
    variable vector: test_vector;
    variable L:LINE; 
  begin 
    wait for 10 ns;
        vector := test_vectors(i);
        i:=i+1; if i>8 then i:=0;end if;
	clk <= vector.clk;
        if Count /= vector.cnt then
          write(L,now);write(L,STRING'("Erreur : "));
          write(L,Count);write(L,STRING'(" <> "));
          write(L,vector.cnt);writeline(Output,L);
        end if;
    end process;
  process(clk) begin
      if clk'event and clk='0' then
	  if (Count=7) then Count <=0; 
	  else Count <=Count+1;
	  end if;
      end if;
  end process;
end;

La difficulté peut être avec la gestion du temps. Si vous regardez attentivement les tests vous vous apercevez qu'il faut décaler le comptage du front. J'ai essayé avec deux simulateurs (un libre et un payant) qui ont donné le même résultat.

Exercice 2 modifier

Reprendre le test de l'aditionneur avec une méthode tabulaire.

Voir aussi modifier

TD5 VHDL et CAO << Conception et VHDL