Technologieaustausch

Grundprinzipien von NEMU DiffTest

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


Dieser Artikel gehört zu„Tutorials zur RISC-V-Befehlssatz-Differentialtest-Reihe (DiffTest)“1. Gerne können Sie auch andere Artikel lesen.

1 Kurze Beschreibung des DiffTest-Prinzips

Die Kernidee von DiffTest: Für zwei Implementierungen, die auf derselben Spezifikation basieren und dieselbe definierte Eingabe haben, sollte ihr Verhalten konsistent sein.
Zurück zum Prozessordesign: Für die beiden Implementierungen gemäß dem riscv-Handbuch sollten bei gleichem korrekten Programm ihre Zustandsänderungen (Register, Speicher) für die beiden Implementierungen konsistent sein:

  • Einer davon ist unsere CPU;
  • Alternativ können Sie einen Simulator als Referenzimplementierung wählen.
    Fügen Sie hier eine Bildbeschreibung ein
    Jedes Mal, wenn beide Parteien mit der Ausführung einer Anweisung fertig sind, überprüfen sie den Status ihrer jeweiligen Register und ihres Speichers. Wenn sie feststellen, dass der Status inkonsistent ist, melden sie sofort einen Fehler und stoppen die Ausführung des Client-Programms (entspricht einer Bestätigungsbeurteilung). jede Anweisung).
  • DiffTest = Online-Verhaltensüberprüfungsmethode auf Befehlsebene
    • Online = Überprüfen, während das Programm ausgeführt wird
    • Befehlsebene = Jeder ausgeführte Befehl wird überprüft
  • Kann jedes Programm in Tests auf Befehlsebene umwandeln und den Status bestätigen
    • Unterstützen Sie Programme, die nicht enden, wie z. B. OS
  • Es ist nicht erforderlich, den Ausgang des Verfahrens im Voraus zu kennen
    • Weil wir das Verhalten der Befehlsausführung vergleichen, nicht die Semantik des Programms

Die größten Einsatzmöglichkeiten von DiffTest sind:Wenn nach der Ausführung von Hunderten oder Tausenden von Anweisungen Fehler bei der Dekodierung oder Ausführung auftreten, wie können wir dann schnell die erste fehlerhafte Anweisung finden? Das ist ein höllischer Schwierigkeitsgrad.

In diesem Artikel wählen wir zur Veranschaulichung Folgendes als Beispiel:

  • QEMU als Referenzobjekt (REF)
  • NEMU als Testobjekt (DUT)

Wenn Sie die Prozessorhardware testen müssen, kann der Prozessor natürlich auch als Prüfling verwendet werden.

2 DiffTest unterstützt von NEMU

make menuconfig
  • 1

Geben Sie „Testen und Debuggen“ -> „Differenzialtests aktivieren“ -> „Referenzdesign“ wie folgt ein:

Fügen Sie hier eine Bildbeschreibung ein
Wenn NEMU für DUT verwendet wird, können Sie 5 Simulatormodi als Referenzsimulator REF wählen.

  • QEMU, dynamischer Bibliotheksmodus, der Code befindet sich in NEMU/tools/qemu-dl-diff/
  • QEMU, Socket-Modus, der Code befindet sich in NEMU/tools/qemu-socket-diff/
  • KVM, der Code befindet sich in NEMU/tools/kvm-diff/
  • NEMU
  • SPITZE

Zu den letzten drei hat der Autor keine spezifischen Untersuchungen durchgeführt, daher wird dieser Artikel sie nicht vorstellen.

3 QEMU macht REF (dynamischer Bibliotheksmodus)

Sie können NEMU/tools/ ändernqemu-dl-diff/, kompiliert in die dynamische Bibliothek riscv64-qemu-so.
Die Beziehung zwischen NEMU, dynamischen Bibliotheken und QEMU:
Fügen Sie hier eine Bildbeschreibung ein

  • Dynamische Bibliothek: riscv64-qemu-so, die die difftest_xx-Reihe von Funktionsschnittstellen exportiert.
  • QEMU: In der ausführbaren Datei qemu-system-riscv64 gibt es Funktionsschnittstellen der Serien cpu_xx, gdb_xx und qemu_xx.
  • NEMU: Das Programm riscv64-nemu-interpreter ruft die dynamische Bibliothek auf, die dann QEMU aufruft.

Spezifischer Prozess:

  • Das ausführbare NEMU-Programm riscv64-nemu-interpreter lädt riscv64-qemu-so durch Aufrufen der dlopen-Funktion und analysiert die Funktionssymbole der difftest_xx-Serie für nachfolgende Aufrufe.
  • Anschließend ruft NEMU die Funktion difftest_init zur Initialisierung auf.
  • In der Funktion difftest_init wird die Funktion dlopen erneut aufgerufen, um die ausführbare Datei qemu-system-riscv64 zu laden und die Funktionssymbolreihen cpu_xx, gdb_xx und qemu_xx zu analysieren. Diese Funktionssymbole sind tatsächlich der zugrunde liegende Implementierungscode der Funktionsreihe difftest_xx .
  • In der Datei qemu-system-riscv64 ist die analysierte Funktion die Hauptfunktion, die dann von der Funktion difftest_init aufgerufen wird, um das qemu-Programm zu starten.
  • Wenn dann alles normal ist, können Sie die Funktion qemu aufrufen, um die Ergebnisse der Anweisung zu vergleichen.

4 QEMU für REF (Socket-Modus)

Sie können NEMU/tools/ ändernQEMU-Socket-Diff/, kompiliert in die dynamische Bibliothek riscv64-qemu-so.
Die Beziehung zwischen NEMU, dynamischen Bibliotheken und QEMU:
Fügen Sie hier eine Bildbeschreibung ein

  • Dynamische Bibliothek: riscv64-qemu-so, die die difftest_xx-Reihe von Funktionsschnittstellen exportiert.
  • QEMU: Die ausführbare Datei qemu-system-riscv64 verfügt über Funktionsschnittstellen der Serien cpu_xx und gdb_xx.
  • NEMU: Das Programm riscv64-nemu-interpreter ruft die dynamische Bibliothek auf, indem es ein Befehlspaket über den Socket sendet, es analysiert und anhand des spezifischen Befehls entscheidet, welche Funktion aufgerufen werden soll.

Spezifischer Prozess:

  • Das ausführbare NEMU-Programm riscv64-nemu-interpreter lädt riscv64-qemu-so durch Aufrufen der dlopen-Funktion und analysiert die Funktionssymbole der difftest_xx-Serie für nachfolgende Aufrufe.
  • Anschließend ruft NEMU die Funktion difftest_init zur Initialisierung auf.
  • In der Funktion difftest_init führt ein untergeordneter Prozess fork() aus und startet QEMU, indem er die Funktion execlp aufruft, während der übergeordnete Prozess die Ausführung fortsetzt, über den Socket eine Verbindung zu QEMU herstellt und die Funktion init_isa zur Initialisierung aufruft.
  • Wenn dann alles normal ist, können Sie die Befehlsergebnisse über den Socket vergleichen.

Referenzdokumentation: