Vor der Evaluierung oder Fehlersuche in der Hardware steht natürlich die Simulation. Ein Ansatz wäre der Einsatz eines »Bus Functional Models«, das käuflich erworben werden müsste. Um solch eine Investition zu vermeiden, gibt es ein anderes Testkonzept, bei dem der SERDES-Block durch einen Stimuli-Generator ersetzt wird. Das im Folgenden beschriebene Konzept verwendet diesen Ansatz. Die Verbindung zwischen SERDES- und Protokoll-Block (8-Bit-+ K-Leitung) wird als Abgriffspunkt für die Simulation herangezogen. Die Aktivität an dieser parallelen Schnittstelle lässt sich erheblich leichter stimulieren und überwachen (Monitore) als an den RX/TX-Differenzialleitungen. Ziel der Simulation ist es in erster Linie, die Applikationslogik zu testen.
Aufbau der Simulationsumgebung
Den Aufbau der Simulationsumgebung zeigt Bild 3. Der PCIe-Stimuli-Generator hat genau die gleiche Portbelegung und VHDL-Entity-Namen wie das SERDES-Modul im IP-Core. Der Stimuli-Generator wird aber in eine andere VHDL-Bibliothek kompiliert, als die Bibliothek, die die Projektlogik enthält. Hier beispielsweise kommt eine Bibliothek namens »pcie_ stimgen_lib« zum Einsatz. Durch Einfügen der folgenden Zeilen in die Top-Level-Datei des IP-Cores wird für die Simulation automatisch der Stimuli-Generator als SERDES und für die Synthese im »ispLever«-Tool nach wie vor das SERDES-Modul von Lattice gewählt:
-- synopsys translate_off
Library pcie_stimgen_lib;
Use pcie_stimgen_lib.pcs_pipe_top;
-- synopsys translate_on
Zielsetzung des Simulationskonzepts ist es, wesentlich mehr Testfälle zu ermöglichen, als nur durch einfache Loop-Back-Tests machbar wäre. Loop-Back-Tests erlauben nur selten die Durchführung von komplexen Lastszenarien (z.B. mehrere DMA-Kanäle aktiv und gleichzeitige externe Zugriffe über den PCIe-Link).
Kern des PCI-Express-Stimulators ist natürlich der Transaktionsgenerator. Der Stimuli-Generator stellt eine Reihe von VHDL-Prozeduren bereit, die der Entwickler verwenden kann, um die einzelnen Testszenarien zu beschreiben. Es sind so gut wie alle PCIe-Zugriffe aus der Sicht eines Upstream-Ports implementiert.
Ein solches Testszenario wird exemplarisch in Listing 1 gezeigt. Hier ist zu sehen, wie ein Adressbereich über ein Basis-Adressregister eingerichtet wird und anschließend zufällige Daten in den Bereich geschrieben beziehungsweise gelesen werden, um Buslast zu erzeugen.
Die in Zeile 35 beginnende for-Schleife führt dazu, dass Schreibpakete vom Upstream-Por t und Lese-Anwortpaketen (Completions) vom End-Point simultan aktiv sind. Es werden also die Puffer in beiden Richtungen gleichzeitig beansprucht.
Im Falle von »non-posted«-Anforderungen (Memory Read, I/O-Read/Write, Configuration-Read/Write) trägt der Transaktionsgenerator eine Kopie des erwarteten Antwortpakets in die Completion-Liste ein. Hierdurch überprüft der Stimuli-Generator folgende Punkte automatisch:
Ein PCIe-Teilnehmer kann mehrere Leseanforderungen stellen, bevor die ersten Quittierungspakete zurückgeliefert werden (z.B. DMA-Controller mit mehreren Kanälen). Die Zuordnung der zurückgelieferten Daten zu der ursprünglichen Anforderung wird über die Tags sowie Requester-ID-Felder im Paket-Header koordiniert (Bild 2). Das Statusfeld im Completion-Header zeigt an, ob die Anforderung erfolgreich durchgeführt wurde oder ob Fehler aufgetreten sind. Als Fehlerzustände gelten nur nicht unterstützte Anforderungen (Unsupported Request) oder Abbruch (Completer-Abort, ähnlich Target-Abort aus klassischer PCI). PCI-Express kennt keinen »Retry«-Zustand.
Wenn hohe Anforderungen an die Datenintegrität vorliegen, lässt sich das Datenpaket durch eine 32-Bit-ECRC aus der Transaktionsschicht absichern. Diese Prüfsumme begleitet das Paket auf dem ganzen Weg vom Datenerzeuger bis zum Endabnehmer (z.B. von einer Steckkarte durch eine/mehrere Switches oder Bridges bis zum Hauptspeicher). Die LCRC-Prüfsumme der Datensicherungsschicht dagegen sichert nur die Übertragung zwischen zwei unmittelbar benachbarten PCIe-Teilnehmern ab.