
Schnittstellen-Konstrukt modelliert Kommunikationsabläufe
Designs sind derart komplex, dass sogar die Kommunikation zwischen Blöcken in eine separate Einheit ausgelagert werden muss. Um diesen Sachverhalt zu modellieren, gibt es in SystemVerilog das Interface- Konstrukt, welches Anwender sich als ein intelligentes Bündel von Drähten vorstellen können. Es enthält die Konnektivität, Synchronisation und optional auch die Kommunikationsfunktionen zwischen zwei oder mehr Blöcken. Es verbindet Design-Blöcke und Testbenches. Der Bus-Control-Block wird durch Register gesteuert, die über einen einfachen Bus gelesen und beschrieben werden. In Verilog würde das DUT die zu Listing 3 zusammengefasste Portliste besitzen. (Die Tone-Signale sind nicht dargestellt.) Mit steigender Port-Anzahl kann es sehr leicht passieren, dass sich ein Verdrahtungsfehler einschleicht – beispielsweise die Verwechslung der Signale „rw_“ und „enb“. Dies lässt sich vermeiden, wenn man stattdessen diese Signale in einen Interface-Block verlagert und deren Richtwirkungen mit dem Konstrukt „modport“ spezifiziert (siehe Listing 4).
Beachtung finden sollte auch der in SystemVerilog neu definierte Datentyp „logic“. In diesem Zusammenhang muss man wissen, dass das klassische „reg“ in Verilog eine Variable deklariert, die für den RTL- und den Testbench- Code verwendbar ist, aber nicht Module oder Gatter verbinden kann. Die Bezeichnung „reg“ verleitete neue Anwender zu dem Glauben, dass es sich um ein Speicherelement handele – z.B. um ein Flipflop . In SystemVerilog indes sind „logic“ und „reg“ Benennungen für denselben Datentypen. Eine „logic“-Variable kann in RTLund Testbench-Code verwendet werden, außerdem ist sie in der Lage, Module und Gatter zu verbinden, solange es nur einen einzigen Treiber gibt. Ein Signal mit mehreren Treibern, beispielsweise ein bidirektionaler Bus, muss ein Netz wie „wire“ verwenden, um den resultierenden Wert zu ermitteln.
Im Sinne möglichst hoher Produktivität sollten Anwender ihre Testbenches auf einer hohen Abstraktionsebene erstellen. Selbst ein BFM sollte Signale synchron treiben und lesen, so dass die Testbench nicht fortlaufend wieder mit dem Takt in Einklang gebracht werden muss. Designer können das Timing ihrer Interface-Signale mittels eines Taktblocks (clocking block) spezifizieren (siehe Listing 5). Zu beachten ist dabei, wie die Richtungen im taktenden Block relativ zur Testbench definiert sind. Der Programmblock nutzt den Taktblock für die synchrone Kommunikation mit einem Interface. Das in Listing 6 beschriebene Beispiel schreibt einen Wert in Register 6600. Das Top-Level- Modul instanziiert das DUT, die Testbench sowie das Interface, welches DUT und Testbench verbindet. In dem Beispiel gemäß Listing 7 besagt das Kürzel „.*“ in der Portliste, dass die Ports anhand von Namensgleichheiten auf der aktuellen Ebene verbunden werden. Das Programm „test“ hat einen einzigen Port, „ifc“, der mit dem Port „ifc“ des Blocks „ucntrl_ifc“ verbunden ist.