FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V Vector拡張のデバッグ支援:ベクトルレジスタダンプ関数の実装

RISC-V Vector拡張のIntrinsicを使用してベクトルレジスタの内容をダンプする簡易なC++関数を用意した。

実装概要

以下のコードは、ベクトル整数レジスタ(vireg)とベクトルマスクレジスタ(vmreg)の内容を人間が読みやすい形式で出力する関数である。

inline void dump_vecregs(char *name, vireg in) {
    int64_t arrays[32];
    const size_t vlmax = __riscv_vsetvlmax_e64m1();
    __riscv_vse64_v_i64m1 (arrays, in, vlmax);

    printf("%s : ", name);
    for (int i = vlmax-1; i >= 0; i--) {
        printf("%016lx_", arrays[i]);
    }
    printf("\n");
}

inline void dump_mvecregs(char *name, vmreg in) {
    uint32_t tmp;
    const size_t vlmax = __riscv_vsetvlmax_e64m1();
    __riscv_vsm_v_b64((uint8_t *)(&tmp), in, vlmax);
    printf("%s : %016x\n", name, tmp);
}

関数の詳細説明

dump_vecregs関数

この関数は、ベクトル整数レジスタ(vireg)の内容をダンプする関数である。

  • 引数

    • name: レジスタ名を表す文字列
    • in: ダンプ対象のベクトル整数レジスタ
  • 処理内容

    1. 64ビット整数の配列(32要素)を宣言する
    2. __riscv_vsetvlmax_e64m1()で最大ベクトル長を取得する
    3. __riscv_vse64_v_i64m1()でベクトルレジスタの内容をメモリにストアする
    4. 各要素を16進数形式で出力する(上位要素から順に表示)

dump_mvecregs関数

この関数は、ベクトルマスクレジスタ(vmreg)の内容をダンプする関数である。

  • 引数

    • name: レジスタ名を表す文字列
    • in: ダンプ対象のベクトルマスクレジスタ
  • 処理内容

    1. 32ビット整数の一時変数を宣言する
    2. __riscv_vsetvlmax_e64m1()で最大ベクトル長を取得する
    3. __riscv_vsm_v_b64()でマスクレジスタの内容をメモリにストアする
    4. マスク値を16進数形式で出力する

使用例

#include <riscv_vector.h>

int main() {
    // ベクトルレジスタの初期化
    vint64m1_t v1 = __riscv_vmv_v_x_i64m1(0x1234567890ABCDEF, 4);
    vbool64_t mask = __riscv_vmsne_vx_i64m1_b64(v1, 0, 4);
    
    // レジスタの内容をダンプ
    dump_vecregs("v1", v1);
    dump_mvecregs("mask", mask);
    
    return 0;
}

出力例

v1 : 0000000000000000_0000000000000000_0000000000000000_1234567890ABCDEF_
mask : 00000001

注意事項

  • この実装は64ビット要素(e64m1)を前提としている
  • 異なる要素幅を使用する場合は、適切なIntrinsic関数に変更する必要がある
  • マスクレジスタのダンプは、64ビット要素の場合32ビットの値として出力される