
Verifikation mit System-Verilog und VMM
Wer ein anderes Land besuchen will, liest meist in Reiseführern nach, welche Sehenswürdigkeiten zur Besichtigung empfohlen werden, damit die Reise zum Erfolg wird. Ähnlich verhält es sich, wenn Designer beginnen, eine neue Sprache wie SystemVerilog einzusetzen: Sie sollten sich auf eine Methodik verlassen, die ihnen den besten Weg zur Entwicklung ihrer Testbench aufzeigt. Sollten sie gezielte oder zufällige Tests generieren? Wie stimulieren sie den RTL-Code – einschließlich Fehlerinjektion und Protokollverletzungen –, ohne ein über die Maßen kompliziertes funktionales Bus-Modell schreiben zu müssen? Wie können sie sicherstellen, dass für Block-Level-Tests geschriebener Code auf Systemebene sowie in zukünftigen Projekten wiederverwendet werden kann?
Ein sinnvoller Ansatz könnte sein, sich bei der Lösungsfindung vom Verification-Methodology-Manual (VMM) for SystemVerilog leiten zu lassen. Das VMM hält System-on-a- Chip-Teams (SoC) durch Erstellen einer wiederverwendbaren Verifikationsumgebung dazu an, dass sie die Vorteile von Design-for-Verification- Techniken, Constrained-Random-Stimulus- Generierung, Coverage-Driven- Verification, formaler Verifikation und anderen modernen Techniken voll ausschöpfen. Es hilft auf diese Weise bei der Lösung aktueller sowie zukünftiger Verifikationsprobleme – und zwar so gut, dass Synopsys-Kunden das VMM mittlerweile bei fast hundert Entwurfsprojekten erfolgreich eingesetzt haben.
Um das Design-under-Test (DUT) gründlich zu verifizieren, müssen umfassende sowie korrekte Stimuli für das Design generiert und die Antworten so sorgfältig wie möglich überprüft werden. Dies geschah bislang, indem Chipdesigner ihre Hardware-Entwürfe mit zielgerichteten Tests verifiziert haben – sich also einen genauen Überblick über alle Features verschafft, Stimuli zum Test einer Teilmenge dieser Features geschrieben und die zugehörige Antwort des DUT manuell geprüft haben. Sobald sie überzeugt sind, die erste Feature-Teilmenge gründlich getestet zu haben, gehen sie zur nächsten über, dann zur übernächsten – bis schließlich alle Features abgedeckt sind.
Bei komplexen SoC-Designs dürfte es aber sehr schwierig werden, sämtliche Features innerhalb einer vernünftigen Zeit zu testen, weil die Anzahl der Features ihre Möglichkeiten, Tests zu entwickeln, deutlich übersteigt. Stattdessen ist es notwendig, Constrained- Random-Stimuli anzuwenden, welche einfache Fehler ebenso aufspüren wie solche, die durch komplexe Interaktionen von Features hervorgerufen werden.
OOP und Random-Stimulus
In SystemVerilog werden Stimuli in Transaktionen gruppiert, die in Klassen enthalten sind. Die beiden grundlegenden Transaktionsklassen des Bus- Control-Blocks sind „bus_msg“ und „bus_byte“. Genau wie ein Bauplan den Grundriss eines Hauses spezifiziert, so spezifiziert eine Klasse die Variablen und Routinen, welche diese Variablen verarbeiten. Aber Chipdesigner können ja nicht in einem Bauplan leben; sie müssen vielmehr auf Basis dieser Pläne ein Haus konstruieren. Ebenso können sie eine Klasse nicht direkt verwenden; sie müssen ein Objekt erzeugen, welches eine Instanz dieser Klasse ist. Dies ist ähnlich der Instanziierung eines Moduls in Verilog, außer dass die Objekterzeugung in OOP dynamisch (zur Laufzeit) erfolgt, während Verilog-Module statisch (während der Compilierung) instanziiert werden. Die Funktion zur Objekterzeugung ist „new()“. Ein Handle erlaubt den Anwendern, ein Objekt und seine Inhalte zu referenzieren, genauso wie sie eine Postadresse verwenden, um ein Haus zu lokalisieren. Es gibt zwei verschiedene Arten von Nachrichten: „TX“ (nur Senden) und „TXRX“ (Senden mit Antwort). Die Variable „kind“ ist spezifiziert als „rand“ – was bedeutet, dass ihr ein zufälliger Wert zugewiesen wird. Listing 1 erzeugt beispielhaft ein Objekt, belegt es zufällig und ruft dann einen vom Anwender definierten Task auf, um es auf den Bus zu übertragen.