|
|
VHDL Testbench[Bearbeiten] EinleitungWarum benötigt man beim Beschreiben von Hardware eine Testbench, wie es immer wieder empfohlen wird? Beim Programmieren von Software kann man sein Programm meistens schnell übersetzen und ausprobieren. Wenn etwas nicht läuft, wird der Debugger angeschmissen, ein Breakpoint gesetzt und sich der Inhalt von Variablen, Speicher und Prozessorregistern angeschaut, um dem Fehler auf die Spur zu kommen. Im FPGA geht das nicht ganz so einfach. Die Synthese kann für ein komplexes Design auf einem großen FPGA mehrere Stunden benötigen. Statt einem Debugger würde man einen Logikanalysator verwenden (extern oder als FPGA Soft Core) und könnte trotzdem nur sehr mühsam nach Fehlern suchen. Daher wird beim Entwurf normalerweise zu jedem Modul eine Testbench erstellt. Mit dieser soll sich die Funktionalität des Modules vor der Synthese mittels Simulation prüfen lassen. Die Testbench generiert alle Eingangssignale, auch Testvektoren genannt, für das zu testende Modul (device under test) und prüft ggf. die Resultate. Folgende Grafik zur Veranschaulichung:
Guter Stil ist es, erst die Testbench zu erstellen und dann das eigentliche Modul ("Test Driven Development"). Dieser Ansatz zwingt dazu, sich vor der Implementierung Gedanken über die genauen Aufgaben eines Moduls zu machen, und hilft dabei eine hohe Testabdeckung zu erzielen. [Bearbeiten] Beispiel: Mini-DDSFür Module, die nur Signale erzeugen, kann die Testbench sehr einfach aussehen. Ein Merkmal von Testbenches ist, daß ihre entity-Beschreibung leer ist. Hier ist als Beispiel die Testbench für ein kleines DDS-Modul:
Die Komponente mini_DDS wird instanziiert und die Testbench erzeugt nur ein Taktsignal (clk) und ein Resetsignal. Die Ausgänge (sinus, saegezahn, rechteck) von mini_DDS werden auf entsprechend benannte Signale geführt. Nun das Modul, welches die eigentliche Arbeit verrichtet:
Hier wird ein asynchroner Reset zum Initialisieren verwendet. "phase" stellt einen Zähler dar. Aus diesem werden die weiteren Signale generiert. Das Sinussignal wird aus einer Tabelle erzeugt, der Zähler selbst ist ein Sägezahn und das oberste Bit des Zählers wird als Rechtecksignal verwendet. Bei diesem Modul wurde bewußt ieee.numeric_std.all zum Rechnen verwendet. Die Ein- und Ausgänge sind dagegen als std_logic definiert um Probleme mit einigen Synthesetools zu umgehen. Die ausführlichen Typkonvertierungen im unteren Teil mögen zwar nicht so schnell hinzuschreiben sein, aber sie schränken logische Fehler stark ein, weil man doch etwas mehr nachdenken muß. Das Resultat der Simulation ist im folgenden Bild zu erkennen: Ob die vom Modul erzeugten Signale richtig sind muß in diesem Beispiel der Betrachter entscheiden. In vielen Fällen, gerade im Hobbybereich, ist das sicher ausreichend. to be continued... |