Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

So erstellen Sie eine selbstüberprüfende Testbench

Eine selbstprüfende Testbench ist ein VHDL-Programm, das die Korrektheit des zu testenden Geräts (DUT) überprüft, ohne sich auf einen Bediener zu verlassen, der die Ausgabe manuell überprüft. Die selbstüberprüfende Testbench läuft völlig selbstständig und gibt am Ende eine „OK“- oder „Failed“-Meldung aus.

Jedes VHDL-Modul sollte eine zugehörige selbstüberprüfende Testbench haben. Es ist wichtig, jederzeit verifizieren zu können, dass alle Module das beabsichtigte Verhalten aufweisen. Zum Beispiel, wenn Sie Änderungen am DUT, einem Submodul oder einem Schnittstellenmodul vornehmen. Wir alle wissen, dass Dinge kaputt gehen können, und Ihr bestes Werkzeug, um diese Probleme zu erkennen, ist die selbstüberprüfende Testbench.

Das zu testende Gerät

Lassen Sie uns direkt einsteigen und ein Beispiel für eine selbstüberprüfende Testbench erstellen. Zuerst brauchen wir etwas zum Testen, ein DUT. Dafür habe ich das Modul im folgenden Code erstellt. Es ist ein Binär-zu-Gray-Code-Konverter.

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;

Gray-Code ist ein alternatives Zahlencodierungsschema, das sich von der regulären Binärcodierung unterscheidet. Die Haupteigenschaft und der Hauptzweck des Gray-Codes besteht darin, dass sich beim Zählen zwischen benachbarten Zahlenwerten nur ein Bit ändert.

Dezimalzahl Binär Grau
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

Die obige Tabelle zeigt, wie sich Gray-Code von Binärcode unterscheidet.

Die Prüfbank

Wir beginnen mit der Erstellung der grundlegenden Testbench und der Instanziierung des DUT darin. Der folgende Code zeigt die Testbench-Datei mit dem instanziierten DUT und allen erforderlichen Importen.

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;

Beachten Sie, dass wir std.env.finish importieren was VHDL-2008 erfordert. Wenn Sie versuchen, die Testbench in ModelSim zu kompilieren, ohne etwas zu ändern, erhalten Sie die folgende Fehlermeldung:

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

Glücklicherweise kann dies leicht behoben werden, indem die VHDL-Version für die Testbench-Datei auf VHDL-2008 gesetzt wird. Klicken Sie mit der rechten Maustaste auf die .vhd-Datei der Testbench und wählen Sie Properties→VHDL→Use 1076-2008->OK.

Für das DUT müssen Sie nichts ändern. Es ist normal, für Testbenches eine höhere Version von VHDL zu verwenden als für die RTL-Module. Sie möchten immer die neuesten VHDL-Konstrukte in Ihrer Testbench verwenden können, aber die meisten Synthese-Tools unterstützen sie nicht.

Eingabe generieren

Unsere nächste Erweiterung der Testbench wird der Prozess sein, der Eingaben für das DUT generiert. Es ist immer am besten, einen umfassenden Test zu erstellen, einen Test, der alle möglichen Eingabewerte ausprobiert. Wenn es jedoch zu viele Permutationen gibt, sind Sie möglicherweise darauf beschränkt, nur Eckfälle zu bearbeiten.

Die Ein- und Ausgänge unseres DUT liegen in einem nicht spezifizierten Bereich. Ich gehe jedoch davon aus, dass das Testen mit Vektorlängen von vier Bit ausreicht, um mögliche Probleme mit diesem Modul aufzudecken.

Der folgende Code enthält den gesamten Prozess zum Generieren der Eingabesequenz.

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;

Der erste Code-Chunk ist eine For-Schleife, die die Zählsequenz vom kleinstmöglichen zum höchstmöglichen Wert generiert. Zwischen den Werten warten wir 10 Nanosekunden, damit das DUT reagieren kann. Allerdings hätte jeder Nanosekundenwert größer als 0 funktioniert, da die Logik innerhalb des DUT rein kombinatorisch ist.

Der zweite Codeabschnitt dient zum Testen der Situation, in der der Eingabezähler auf 0 zurückgeht, was der anfängliche Eingabewert war. Danach sind keine weiteren Tests mehr erforderlich, da das DUT immer wieder dieselben Ergebnisse liefert.

Die letzten beiden Codezeilen innerhalb des Prozesses dienen dazu, den Test ordnungsgemäß zu beenden. Der Text „Test:OK“ wird auf der Konsole ausgegeben, und dann wird die Simulation mit dem VHDL-2008-Schlüsselwort „finish“ beendet.

Beachten Sie, dass, wenn Sie ModelSim mit der standardmäßigen Run-Schaltfläche ausführen, ModelSim Sie mit dem Beenden-Dialog auffordert, nachdem die Testbench erfolgreich abgeschlossen wurde. Dieses Verhalten kann geändert werden, wenn Vsim über ein Skript oder über die Befehlszeile gestartet wird. Fügen Sie den Schalter „-onfinish stop“ zum Vsim-Befehl hinzu, wie in der ModelSim-Befehlsreferenz beschrieben.

Überprüfen der Ausgabe

Jetzt versorgen wir das DUT mit Eingängen, aber es findet überhaupt keine Überprüfung des Ausgangs statt. Die Testbench druckt „Test:OK“, unabhängig davon, ob die Ausgabe korrekt ist oder nicht. Lassen Sie uns etwas dagegen unternehmen.

Beim Erstellen eines Verifikationsalgorithmus sollte man immer versuchen, den Test anders zu implementieren als im DUT. Andernfalls kann ein grundlegender Fehler in der Logik unbemerkt bleiben, da er sowohl im DUT als auch im Testbench-Algorithmus vorhanden ist.

Nach diesem Prinzip testen wir den DUT-Ausgang nicht, indem wir prüfen, ob der Gray-Code korrekt ist, sondern dass sich nur ein Bit von einer Zahl zur nächsten ändert. Schließlich ist das der ganze Grund für die Verwendung von Gray-Code überhaupt. Der folgende Code zeigt einen Prozess, der diese Art von Überprüfung durchführt.

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;

Der Prozess ist empfindlich gegenüber bin Signal, der Eingang zum DUT. Wir hätten eine Sensitivitätsliste mit demselben Ergebnis verwenden können, aber ich ziehe es vor, nur Wait-Anweisungen im Testbench-Code zu verwenden. Es ist eine Konvention, die es einfach macht zu erkennen, ob Sie es mit einer Testbench oder einem RTL-Modul zu tun haben, indem Sie sich ansehen, wie der Code geschrieben ist.

In der zweiten Zeile kopieren wir die vorherige DUT-Ausgabe. Denken Sie daran, dass dies der erste Delta-Zyklus nach bin ist Signal hat sich geändert, und das DUT kann unmöglich noch reagieren. Daher ist es sicher, die DUT-Ausgabe mit der Annahme zu kopieren, dass dies der alte Wert ist.

Dann warten wir 1 Nanosekunde, damit die gesamte kombinatorische Logik im DUT abgeschlossen werden kann. Jetzt sollte die DUT-Ausgabe stabil sein und wir können ihren Wert sicher untersuchen.

Im nächsten Codeabschnitt verwenden wir eine For-Schleife, um die Anzahl der geänderten Bits am DUT-Ausgang zu zählen.

Schließlich kommt die Assert-Anweisung, die überprüft, ob die Anzahl der geänderten Bits genau 1 ist. Assert-Anweisungen funktionieren, indem sie die Bedingung überprüfen, die in diesem Fall count = 1 ist . Wenn die Bedingung zu false ausgewertet wird , wird eine Assertion ausgelöst und der Simulator stoppt, bevor die Meldung „Test:OK“ ausgegeben wird.

Es ist ratsam, die optionale Report-Anweisung in die Assertion-Anweisung aufzunehmen. Dieser Text wird ausgedruckt, wenn die Assertion fehlschlägt. In unserem Beispiel erkläre ich kurz das Ereignis, das zum Fehlschlagen der Testbench geführt hat.

Laufen der Testbench

Es ist an der Zeit, unsere Testbench auszuführen, um zu überprüfen, ob das DUT ordnungsgemäß funktioniert. Nach dem Starten der Simulation in ModelSim und dem Drücken der Schaltfläche „run -all“ sehen wir, dass die Meldung „Test:OK“ auf der Konsole ausgegeben wird.

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

Testen der Testbench

Ich erzeuge immer gerne eine fehlerhafte Bedingung im DUT, nur um zu sehen, dass die Testbench funktioniert. Manchmal ist dies ganz natürlich auf tatsächliche Fehler im DUT zurückzuführen, während Sie es entwickeln. Sollte dies nicht der Fall sein, erstellen Sie einfach kurz einen Fehler, um die Testbench zu testen.

Um dies zu erreichen, werde ich den DUT-Code bearbeiten, um einen „Steh bei 0“-Fehler auf Bit Nummer 3 zu erzeugen. Nach diesem Test werde ich den Fehler mit dem Wissen entfernen, dass die Testbench solche Fehler erkennen kann. Der folgende Code zeigt den DUT-Prozess mit der zusätzlichen Codezeile.

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;

Wenn wir die Testbench jetzt ausführen, können wir sehen, dass die Testbench stoppt und der Fehler ausgegeben wird, bevor die Zeile „Test:OK“ erreicht wird. Das Transkript von der ModelSim-Konsole ist unten gezeigt.

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

Erste Schritte mit selbstprüfenden Testbenches

Sie sollten in der Lage sein, eine selbstüberprüfende Testbench zu erstellen, indem Sie das verwenden, was Sie in diesem Artikel gelernt haben. Machen Sie es sich zur Gewohnheit, immer selbstüberprüfende Testbenches für alle Ihre VHDL-Module zu erstellen. Es wird Ihnen langfristig Zeit sparen.

Es ist in Ordnung, beim Schreiben von Testbenches kreativ zu sein. Mehr als beim Schreiben von RTL-Modulen, da nicht alle VHDL-Konstrukte synthetisiert werden können, aber die Testbench nicht synthetisierbar sein muss. Rechnen Sie damit, mindestens so viel Zeit mit dem Schreiben von Tests zu verbringen wie mit dem Schreiben des DUT.

Wenn Sie sich ernsthaft mit dem Testen befassen möchten, könnten Sie an meinem * interessiert sein kommender VHDL- und FPGA-Kurs. In diesem Kurs begleite ich Sie durch den gesamten Designprozess von der Idee bis zum physisch funktionierenden FPGA-Prototypen. Wir werden mehrere selbstprüfende Testbenches erstellen.

Aktualisiert am 12. Oktober 2020: Ich habe den Kurs abgeschlossen. Klicken Sie auf das Bild unten, um mehr zu erfahren.

Ich werde Ihnen die Best Practices für die erfolgreiche Erstellung von VHDL- und FPGA-Designs auf die richtige Weise beibringen. Wissen, das ich mir in vielen Jahren in der Wissenschaft und nach meiner Tätigkeit als Hardware-Ingenieur in der Verteidigungsindustrie angeeignet habe, gebe ich an Sie weiter.

Lesen Sie hier mehr über den Dot-Matrix-VHDL- und FPGA-Kurs!

Öffnet:

Noch zu entscheiden .


VHDL

  1. So erstellen Sie eine CloudFormation-Vorlage mit AWS
  2. Wie erstelle ich ein Cloud-Kompetenzzentrum?
  3. So erstellen Sie eine sorgfältig entworfene Cloud-Strategie
  4. Wie man reibungslose UX erstellt
  5. So erstellen Sie eine Liste von Zeichenfolgen in VHDL
  6. So erstellen Sie eine Tcl-gesteuerte Testbench für ein VHDL-Code-Sperrmodul
  7. So stoppen Sie die Simulation in einer VHDL-Testbench
  8. So erstellen Sie eine verknüpfte Liste in VHDL
  9. So schaffen Sie menschenzentrierte intelligente Städte
  10. So erstellen Sie ein Array von Objekten in Java