NEMU DiffTest の基本原理
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
この記事は以下のものに属します
「RISC-V 命令セット差動テスト (DiffTest) シリーズ チュートリアル」1、他の記事をチェックすることを歓迎します。
1 DiffTest 原理の簡単な説明
DiffTest の核となる考え方: 同じ仕様に基づく 2 つの実装では、同じ定義された入力が与えられ、それらの動作は一貫している必要があります。
プロセッサの設計に戻ります。riscv マニュアルによる 2 つの実装では、同じ正しいプログラムが与えられた場合、その状態変化 (レジスタ、メモリ) は 2 つの実装で一貫している必要があります。
- そのうちの 1 つは CPU です。
- あるいは、リファレンス実装としてシミュレーターを選択します。

両者は命令の実行を終了するたびに、それぞれのレジスタやメモリの状態を確認し、状態が矛盾している場合には直ちにエラーを報告し、クライアントプログラムの実行を停止します(アサート判定を行うのと同じです)。各指示)。 - DiffTest = オンラインのコマンドレベルの動作検証方法
- オンライン = プログラムの実行中に検証します
- 命令レベル = 実行されたすべての命令が検証される
- あらゆるプログラムを命令レベルのテストに変換し、ステータスをアサートできます
- 事前に手続きの結果を知る必要はありません
- プログラムのセマンティクスではなく、命令実行の動作を比較しているためです。
DiffTest の最大の用途は次のとおりです。何百、何千もの命令を実行した後にデコードや実行のバグが発生した場合、最初のエラー命令をどのようにして素早く見つけ出すか、これは地獄レベルの困難です。
この記事では、説明する例として次のものを選択します。
- 参照オブジェクト (REF) としての QEMU
- 被験者(DUT)としてのNEMU
もちろん、プロセッサのハードウェアをテストする必要がある場合は、プロセッサを DUT として使用することもできます。
2 NEMU によってサポートされる DiffTest
make menuconfig
次のように、「テストとデバッグ」→「差動テストを有効にする」→「リファレンス デザイン」に入ります。

NEMU を DUT に使用する場合、リファレンス シミュレータ REF として 5 つのシミュレータ モードを選択できます。
- QEMU、ダイナミック ライブラリ モード、コードは NEMU/tools/qemu-dl-diff/ にあります。
- QEMU、ソケット モード、コードは NEMU/tools/qemu-socket-diff/ にあります。
- KVM の場合、コードは NEMU/tools/kvm-diff/ にあります。
- ネム
- スパイク
後の 3 つについては、筆者は特に調査を行っていないため、本稿では紹介しない。
3 QEMU は REF (ダイナミック ライブラリ モード) を作成します
NEMU/tools/を変更できます。qemu-dl-diff/、ダイナミック ライブラリ riscv64-qemu-so にコンパイルされます。
NEMU、動的ライブラリ、および QEMU の関係:

- ダイナミック ライブラリ: riscv64-qemu-so、difftest_xx シリーズの関数インターフェイスをエクスポートします。
- QEMU: qemu-system-riscv64 実行可能ファイルには、cpu_xx、gdb_xx、および qemu_xx シリーズの関数インターフェイスがあります。
- NEMU: riscv64-nemu-interpreter プログラムは動的ライブラリを呼び出し、その後 QEMU を呼び出します。
具体的なプロセス:
- NEMU 実行可能プログラム riscv64-nemu-interpreter は、dlopen 関数を呼び出すことによって riscv64-qemu-so をロードし、後続の呼び出しのために difftest_xx シリーズの関数シンボルを解析します。
- 次に、NEMU は difftest_init 関数を呼び出して初期化します。
- difftest_init 関数では、dlopen 関数が再度呼び出され、qemu-system-riscv64 実行可能ファイルがロードされ、cpu_xx、gdb_xx、および qemu_xx シリーズの関数シンボルが解析されます。これらの関数シンボルは、実際には、difftest_xx シリーズの関数の基礎となる実装コードです。 。
- qemu-system-riscv64 ファイルでは、解析された関数が main 関数であり、difftest_init 関数がそれを呼び出して qemu プログラムを開始します。
- すべてが正常であれば、qemu 関数を呼び出して命令結果を比較できます。
4 REF 用 QEMU (ソケット モード)
NEMU/tools/を変更できます。qemu ソケット diff/、ダイナミック ライブラリ riscv64-qemu-so にコンパイルされます。
NEMU、動的ライブラリ、および QEMU の関係:

- ダイナミック ライブラリ: riscv64-qemu-so、difftest_xx シリーズの関数インターフェイスをエクスポートします。
- QEMU: qemu-system-riscv64 実行可能ファイルには、cpu_xx および gdb_xx シリーズの関数インターフェイスがあります。
- NEMU: riscv64-nemu-interpreter プログラムはダイナミック ライブラリを呼び出します。ダイナミック ライブラリはソケット経由でコマンド パケットを送信し、QEMU がパケットを受信して解析し、特定のコマンドに基づいて実行する関数を決定します。
具体的なプロセス:
- NEMU 実行可能プログラム riscv64-nemu-interpreter は、dlopen 関数を呼び出すことによって riscv64-qemu-so をロードし、後続の呼び出しのために difftest_xx シリーズの関数シンボルを解析します。
- 次に、NEMU は difftest_init 関数を呼び出して初期化します。
- difftest_init 関数では、子プロセスが fork() アウトし、execlp 関数を呼び出して QEMU を開始します。一方、親プロセスは実行を継続し、ソケット経由で QEMU に接続し、init_isa 関数を呼び出して初期化します。
- すべてが正常であれば、ソケットを介してコマンドの結果を比較できます。
参考ドキュメント: