Soft-CPU-Überprüfung

Ich bin gerade dabei, eine einfache CPU in VHDL mit Xilinx ISE und ISIM zu entwerfen. Der Entwurfsteil läuft bemerkenswert gut, aber ich kann anscheinend keinen Weg finden, die Überprüfung auf konsistente Weise durchzuführen.

Im Moment habe ich eine VHDL-Testbench, die ich aktualisiere, um die Funktion zu testen, an der ich gerade arbeite. Dies ist sehr ad-hoc und hilft mir nicht, Regressionen zu erkennen, und kann nicht verwendet werden, um die Einhaltung der Spezifikation/des Anweisungssatzes zu überprüfen.

Ich habe darüber nachgedacht, eine umfangreiche Testsuite zu entwickeln, aber das Problem ist, dass der potenzielle Status eines Allzweckteils als CPU im Vergleich zu weniger generischen Komponenten riesig ist.

Ich suche nach einer Methode, mit der ich Design und Tests kontrollierter durchführen kann. Eine Art "Hardware-TDD", wenn Sie so wollen. Gibt es so etwas? Kann es relativ einfach auf Allzweckteile wie eine CPU angewendet werden?

Antworten (1)

Das ganze Problem der CPU-Verifizierung ist super groß und schwierig. Es gibt Menschen, die daraus Karriere machen. Ich gebe dir nur den Überblick...

  1. Schreiben Sie ein Assemblerprogramm, das jede Anweisung und jedes kleinste Detail jeder Anweisung testet. Wenn Sie beispielsweise die ADD-Anweisung testen, können Sie sie mit Zahlen testen, die sowohl positiv als auch negativ sind und jeweils eine (zweimal). Sie würden dann das Übertrags-Flag, das Null-Flag usw. testen. Andere spezielle Funktionen der CPU (wie Verzweigungsvorhersage usw.) hätten ihren eigenen speziellen Teil dieses Tests.

  2. Schreiben Sie mit C/C++ oder so ein Modell Ihrer CPU. Dies ist Ihre virtuelle CPU. Dies ist auch Ihre "goldene CPU", was bedeutet, dass dies die CPU ist, mit der alles andere verglichen wird. Idealerweise ist die Person, die die VHDL geschrieben hat, NICHT dieselbe Person, die das C/C++-Modell schreibt.

  3. Schreiben/Erstellen Sie ein System, in dem Sie das C/C++-Modell und das VHDL-Modell nebeneinander ausführen und die Ergebnisse Zyklus für Zyklus vergleichen können. Führen Sie Ihr Montageprogramm ab Schritt 1 aus und vergewissern Sie sich, dass die beiden Modelle übereinstimmen.

  4. Führen Sie Ihre beiden Modelle nach zufälligen "Anweisungen" aus. Füllen Sie im Grunde "RAM" mit zufälligen Daten und führen Sie diese zufälligen Daten aus, als wären es echte Anweisungen. Führen Sie die gleichen Zufallsdaten auf VHDL- und C/C++-Modellen aus und vergleichen Sie die Ergebnisse. Dieses C/C++-Modell würde auf einer Workstation und/oder einem Server laufen (nicht auf der neuen CPU selbst).

  5. Richten Sie eine Maschine oder mehrere Maschinen ein, um Schritt 4 im Wesentlichen für immer zu wiederholen. Selbst wenn Ihre CPU "fertig" ist und seit einem Jahr oder länger in Produktion ist, werden Sie diesen Test noch durchführen.

  6. Wiederholen Sie diese Schritte, wenn Sie mehr Dinge simulieren möchten. Beispielsweise würden Sie es auf der Post-Route-VHDL mit Zeitsteuerung ausführen, wenn diese verfügbar ist.

Es gibt keine Garantie dafür, dass der Vergleich der VHDL- und C/C++-Versionen jeden einzelnen Fehler aufdeckt – aber es gibt wirklich keinen besseren Weg. Und das Testen der CPU auf zufällige Anweisungen braucht Zeit, aber das ist auch sehr nützlich. Die einzige wirkliche Alternative dazu besteht darin, viele Leute einzustellen, die den ganzen Tag nur Code schreiben, um verschiedene Teile der CPU zu testen – und die größeren Unternehmen tun dies, aber sie machen auch das Zeug mit zufälligen Daten.

Für eine einzelne Person, die VHDL-Code schreibt, ist normalerweise nur Schritt 1 erledigt. Aber wenn Sie die CPU verkaufen wollen, sollten zumindest einige der anderen Schritte durchgeführt werden (und eigentlich sollten Sie sie alle tun).

Ausgezeichnete Antwort, danke! Das macht sehr viel Sinn. Die „Goldene CPU“ ist in der Tat das fehlende Puzzleteil, mit dem Sie beim Testen Zyklus-für-Zyklus-Verifikation durchführen können. Da dies hauptsächlich ein Spielzeugprojekt ist, denke ich, dass ich mich an den ersten Satz des letzten Absatzes halten und nur Schritt Nr. 1 ausführen werde. Aber zu wissen, was ich tun sollte , ist von unschätzbarem Wert.
Sie können auch ein goldenes, aber nicht zyklusgenaues C++-Modell haben, das viel einfacher und damit wahrscheinlicher korrekt ist - nützlich zum Beispiel zum Testen der ALU-Funktionalität ("2 + 2 = 4 und einige Flags, I egal wann" statt "2+2=4 nach einem Tick und die Flags nach 2 Ticks")
Führen Sie außerdem Code-Coverage aus (um zu überprüfen, ob Sie alles ausgeführt haben) und Test-Coverage (um zu überprüfen, ob alle Tests sowohl auf Pass als auch auf Fail getestet wurden).
Follow-up: Mit dem "Step One"-Verfahren habe ich es geschafft, viele Fehler zu finden ... in meinem Assembler :P Der Kern selbst scheint relativ ok zu sein.