前回の続き: msyksphinz.hatenablog.com
RVVI-APIの概要
RVVI-APIは、リファレンスモデルDVサブシステムのインターフェースとして、RISC-Vプロセッサの検証において重要な役割を果たす。 単純なPC値の比較ではなく、完全な非同期動作を含む全てのISAアーキテクチャ機能とオプションを考慮した包括的な検証を可能にする。
RVVI-APIの設計思想
抽象化レイヤーとしての役割
RVVI-APIは、プロセッサリファレンスモデルの詳細を抽象化し、テストベンチとリファレンスモデルを分離する設計となっている。 これにより、特定のリファレンスモデルに依存しない汎用的なテストベンチの構築が可能になる。
マルチプラットフォーム対応
- C/C++ API: C/C++テストベンチで使用可能
- SystemVerilog DPIラッパー: SystemVerilogテストベンチでも使用可能
RVVI-APIの主要機能カテゴリ
1. リファレンスモデル管理
rvviRefModelCreate()
リファレンスモデルのインスタンスを作成する。
rvviRefModel rvviRefModelCreate( const char* config, // 設定ファイルパス const char* isa, // ISA文字列(例:"rv64gc") const char* options // 追加オプション );
戻り値: リファレンスモデルハンドル 説明: 指定されたISAと設定でリファレンスモデルを初期化する。
rvviRefModelDestroy()
リファレンスモデルのインスタンスを破棄する。
void rvviRefModelDestroy(rvviRefModel ref);
引数: ref - 破棄するリファレンスモデルハンドル
2. レジスタ操作
rvviRefModelGetGPR()
汎用レジスタの値を取得する。
uint64_t rvviRefModelGetGPR(rvviRefModel ref, int hart, int reg);
引数:
- ref - リファレンスモデルハンドル
- hart - HART番号
- reg - レジスタ番号(0-31)
戻り値: レジスタの値
rvviRefModelSetGPR()
汎用レジスタの値を設定する。
void rvviRefModelSetGPR(rvviRefModel ref, int hart, int reg, uint64_t value);
引数:
- ref - リファレンスモデルハンドル
- hart - HART番号
- reg - レジスタ番号(0-31)
- value - 設定する値
rvviRefModelGetFPR()
浮動小数点レジスタの値を取得する。
uint64_t rvviRefModelGetFPR(rvviRefModel ref, int hart, int reg);
rvviRefModelSetFPR()
浮動小数点レジスタの値を設定する。
void rvviRefModelSetFPR(rvviRefModel ref, int hart, int reg, uint64_t value);
rvviRefModelGetCSR()
CSR(制御・状態レジスタ)の値を取得する。
uint64_t rvviRefModelGetCSR(rvviRefModel ref, int hart, uint32_t csr);
引数:
- csr - CSRアドレス(12ビット)
rvviRefModelSetCSR()
CSRの値を設定する。
void rvviRefModelSetCSR(rvviRefModel ref, int hart, uint32_t csr, uint64_t value);
3. メモリ操作
rvviRefModelGetMemory()
メモリからデータを読み出す。
uint64_t rvviRefModelGetMemory(rvviRefModel ref, int hart, uint64_t addr, int size);
引数:
- addr - メモリアドレス
- size - 読み出しサイズ(1, 2, 4, 8バイト)
rvviRefModelSetMemory()
メモリにデータを書き込む。
void rvviRefModelSetMemory(rvviRefModel ref, int hart, uint64_t addr, int size, uint64_t value);
4. 命令実行
rvviRefModelStep()
リファレンスモデルで1命令を実行する。
int rvviRefModelStep(rvviRefModel ref, int hart);
戻り値: 実行結果(0: 成功、非0: エラー)
rvviRefModelRun()
リファレンスモデルで指定されたアドレスまで実行する。
int rvviRefModelRun(rvviRefModel ref, int hart, uint64_t addr);
引数: addr - 実行停止アドレス
5. 状態比較
rvviRefModelCompareState()
DUTとリファレンスモデルの状態を比較する。
int rvviRefModelCompareState( rvviRefModel ref, int hart, uint64_t dut_pc, uint64_t dut_gpr[32], uint64_t dut_fpr[32], uint64_t dut_csr[4096] );
引数:
- dut_pc - DUTのPC値
- dut_gpr - DUTの汎用レジスタ値配列
- dut_fpr - DUTの浮動小数点レジスタ値配列
- dut_csr - DUTのCSR値配列
戻り値: 比較結果(0: 一致、非0: 不一致)
6. 割り込み・例外処理
rvviRefModelSetInterrupt()
割り込みを設定する。
void rvviRefModelSetInterrupt(rvviRefModel ref, int hart, int irq, int level);
引数:
- irq - 割り込み番号
- level - 割り込みレベル(0: 非アクティブ、1: アクティブ)
rvviRefModelGetException()
例外情報を取得する。
int rvviRefModelGetException(rvviRefModel ref, int hart, rvviException* exc);
引数: exc - 例外情報を格納する構造体ポインタ
7. デバッグ機能
rvviRefModelSetBreakpoint()
ブレークポイントを設定する。
void rvviRefModelSetBreakpoint(rvviRefModel ref, int hart, uint64_t addr);
rvviRefModelClearBreakpoint()
ブレークポイントをクリアする。
void rvviRefModelClearBreakpoint(rvviRefModel ref, int hart, uint64_t addr);
SystemVerilog DPIラッパー
RVVI-APIは、SystemVerilogテストベンチで使用するためのDPI(Direct Programming Interface)ラッパーも提供している。
DPI関数の例
// DPI関数の宣言
import "DPI-C" function chandle rvviRefModelCreate(
input string config,
input string isa,
input string options
);
import "DPI-C" function void rvviRefModelDestroy(
input chandle ref
);
import "DPI-C" function longint unsigned rvviRefModelGetGPR(
input chandle ref,
input int hart,
input int reg
);
import "DPI-C" function void rvviRefModelSetGPR(
input chandle ref,
input int hart,
input int reg,
input longint unsigned value
);
使用例
C/C++での使用例
#include "rvvi_api.h" int main() { // リファレンスモデルの作成 rvviRefModel ref = rvviRefModelCreate("config.json", "rv64gc", ""); // 初期状態の設定 rvviRefModelSetGPR(ref, 0, 1, 0x1000); // x1 = 0x1000 rvviRefModelSetGPR(ref, 0, 2, 0x2000); // x2 = 0x2000 // メモリの初期化 rvviRefModelSetMemory(ref, 0, 0x1000, 4, 0x12345678); // 命令実行 rvviRefModelStep(ref, 0); // 状態比較 uint64_t dut_gpr[32]; // DUTからレジスタ値を取得... int result = rvviRefModelCompareState(ref, 0, dut_pc, dut_gpr, dut_fpr, dut_csr); // リファレンスモデルの破棄 rvviRefModelDestroy(ref); return 0; }
SystemVerilogでの使用例
module testbench; import "DPI-C" function chandle rvviRefModelCreate(input string config, input string isa, input string options); import "DPI-C" function void rvviRefModelDestroy(input chandle ref); import "DPI-C" function longint unsigned rvviRefModelGetGPR(input chandle ref, input int hart, input int reg); chandle ref_model; initial begin // リファレンスモデルの作成 ref_model = rvviRefModelCreate("config.json", "rv64gc", ""); // テスト実行... // リファレンスモデルの破棄 rvviRefModelDestroy(ref_model); end endmodule