FPGA開発日記

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

RISC-V Test Generation Framework (Riescue) について調査する (3. Riescue-C試行メモ)

Riescue-C(CTK: Compliance Test Kit)を使ってテストキットを生成してみた。

Riescue-Cとは

RiescueDは単一のテストファイルを処理するフレームワークだが、Riescue-CはCompliance Testを含めて複数のテストを自動生成できる点が本質的な違いだ。

Riescue-Cはctkコマンドまたはriescuecコマンドで実行できる。Compliance Test Kitの略で、RiescueCテストを生成するツールだ。

RiescueDとRiescue-Cの違い

  • RiescueD: ユーザーが記述した単一のテストファイル(.s)を処理し、テストを生成・実行する
  • Riescue-C (CTK): 指定されたISA、特権モード、ページングモード、拡張機能の組み合わせから、複数のテストを自動生成する。特に、Compliance Testを生成できる点が重要

CTKの動作

ctk.pyのコードを見ると、CTKは以下のような動作をする:

  1. CtkCfgで設定を管理
  2. ResourceBuilderTpBuilderを使用してテスト設定を生成
  3. BringupModeを使用してテストを生成
  4. 指定されたISA、特権モード、ページングモード、拡張機能の組み合わせでテストキット(複数のテスト)を生成

ctk.pyのドキュメントには「Generates a directory of RiescueC tests given an ISA and CPU configuration」とあるように、単一のテストではなく、ディレクトリ全体のテストキットを生成する。

実行コマンド

riescuec --mode bringup --iss spike --json ./rv64i.json

rv64i.jsonの内容:

{
    "arch": "rv64i",
    "exclude_groups": [],
    "exclude_instrs": [
        "wfi",
        "ebreak",
        "mret",
        "sret",
        "ecall",
        "fence",
        "fence.i",
        "c.ebreak"
    ],
    "include_extensions": [
        "i_ext"
    ],
    "include_groups": [],
    "include_instrs": []
}

エラー: whisperが見つからない

実行すると以下のエラーが出た:

FileNotFoundError: Could not find whisper in PATH. Add it to your PATH or set WHISPER_PATH environment variable

riescuecwhisperというISS(Instruction Set Simulator)を必要とするようだ。whisperがPATHにない場合、WHISPER_PATH環境変数を設定する必要がある。

--iss spikeオプションを指定しているが、riescuecはデフォルトでwhisperを必要とするようだ。 これはちょっと良く分からない。 とりあえずWhisperをインストールして事なきを得た。

riescuec --mode bringup --iss spike --json ./rv64i.json
fpgen unavailable, skipping
[2025-12-22T01:09:01]INFO riescue.lib.logger:161  Logger initialized, setting log level to INFO
Traceback (most recent call last):
  File "/home/msyksphinz/work/riscv/riscued/.venv/bin/riescuec", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 176, in main
    RiescueC.run_cli()
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 111, in run_cli
    return riescue_c.run_bringup(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 152, in run_bringup
    return bringup_mode.run(bringup_test_json=bringup_test_json, seed=seed, cl_args=args, toolchain=toolchain)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/bringup.py", line 88, in run
    cfg = self.configure(seed=seed, bringup_test_json=bringup_test_json, cl_args=cl_args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/bringup.py", line 104, in configure
    resource_builder.with_bringup_test_json(bringup_test_json)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/config/resource_builder.py", line 50, in with_bringup_test_json
    return BringupTestAdapter().apply(self, bringup_test_json)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/config/adapters/bringup_test_adapater.py", line 22, in apply
    bringup_test = BringupTest.from_json(self.find_config(src))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/config/bringup_case.py", line 73, in from_json
    return cls.from_dict(test)
           ^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/config/bringup_case.py", line 55, in from_dict
    raise ValueError(f"{required_field} must be one of {valid_arch}")
ValueError: arch must be one of ['rv32', 'rv64']
zsh: exit 1     riescuec --mode bringup --iss spike --json ./rv64i.json

"arch": "rv64i"rv64 に修正する必要があるらしい。

{
    "arch": "rv64",
    "exclude_groups": [],
    "exclude_instrs": [
        "wfi",
        "ebreak",
        "mret",
        "sret",
        "ecall",
        "fence",
        "fence.i",
        "c.ebreak"
    ],
    "include_extensions": [
        "i_ext"
    ],
    "include_groups": [],
    "include_instrs": []
}
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 42180000 c000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 10800000 100000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 20800000 100000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 8000000 100000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 9000000 c0000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 90c0000 100 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region a000000 c00000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region a0c0000 37f40000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 10900000 ff00000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 20900000 21880000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 42000000 100000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 421a0000 1000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 42200000 100000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 50000000 20000000 rwx
[2025-12-22T01:11:27]INFO riescue.dtest_framework.lib.pmp:276  Adding region 70000000 10 rwx
[2025-12-22T01:11:27]ERROR riescue.dtest_framework.generator.generator:2066  Unknown section: text
[2025-12-22T01:11:27]INFO riescue.lib.toolchain.tool:97  Running
        /home/msyksphinz/riscv64_251218/bin/riscv64-unknown-elf-gcc -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv64imafdcvh_svinval_zfh_zba_zbb_zbc_zbs_zifencei_zicsr_zvkned_zicbom_zicbop_zicboz_zawrs_zihintpause_zvbb1_zicond_zvkg_zvkn_zvbc_zfa_zk -I /home/msyksphinz/work/riscv/riescuec -T /home/msyksphinz/work/riscv/riescuec/rv64i.ld -o /home/msyksphinz/work/riscv/riescuec/rv64i /home/msyksphinz/work/riscv/riescuec/rv64i.S
[2025-12-22T01:11:28]INFO riescue.lib.toolchain.tool:93  Running
        /home/msyksphinz/riscv64_251218/bin/riscv64-unknown-elf-objdump -D /home/msyksphinz/work/riscv/riescuec/rv64i -M numeric > /home/msyksphinz/work/riscv/riescuec/rv64i.dis
[2025-12-22T01:11:28]INFO riescue.lib.toolchain.tool:93  Running
        /home/msyksphinz/riscv64/bin/spike -l --log-commits --max-instrs=2000000 --priv=msu --pc=0x80000000 --misaligned --isa=RV64IMAFDCVH_zba_zbb_zbc_zfh_zbs_zfbfmin_zvfh_zvbb_zvbc_zvfbfmin_zvfbfwma_zvkg_zvkned_zvknhb_svpbmt_sstc_zicntr --varch=vlen:256,elen:64 /home/msyksphinz/work/riscv/riescuec/rv64i > /home/msyksphinz/work/riscv/riescuec/rv64i_spike.log
Traceback (most recent call last):
  File "/home/msyksphinz/work/riscv/riscued/.venv/bin/riescuec", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 176, in main
    RiescueC.run_cli()
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 111, in run_cli
    return riescue_c.run_bringup(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescuec.py", line 152, in run_bringup
    return bringup_mode.run(bringup_test_json=bringup_test_json, seed=seed, cl_args=args, toolchain=toolchain)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/bringup.py", line 89, in run
    return self.generate(cfg, toolchain)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/bringup.py", line 140, in generate
    first_pass = self._rd_run_iss(Path(testcase.testname), resource.first_pass_iss, resource, toolchain)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/compliance/bringup.py", line 189, in _rd_run_iss
    rd.simulate(resource.featmgr, iss=self._get_iss(simulator, toolchain), whisper_config_json_override=whisper_config_json_override)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/riescued.py", line 412, in simulate
    iss.run_iss(
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 333, in run_iss
    return super().run(output_file=output_file, cwd=cwd, timeout=timeout, args=extra_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 103, in run
    self._classify(process, output_file)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 318, in _classify
    self._raise_toolchain_error(process, ToolFailureType.NONZERO_EXIT)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 114, in _raise_toolchain_error
    raise ToolchainError(tool_name=self.__class__.__name__, cmd=process.args, kind=kind, returncode=process.returncode, error_text=error_text, **kwargs)
riescue.lib.toolchain.exceptions.ToolchainError: Spike Failed:                                                                                                                                                                                                                                                                                                 ran: /home/msyksphinz/riscv64/bin/spike -l --log-commits --max-instrs=2000000 --priv=msu --pc=0x80000000 --misaligned --isa=RV64IMAFDCVH_zba_zbb_zbc_zfh_zbs_zfbfmin_zvfh_zvbb_zvbc_zvfbfmin_zvfbfwma_zvkg_zvkned_zvknhb_svpbmt_sstc_zicntr --varch=vlen:256,elen:64 /home/msyksphinz/work/riscv/riescuec/rv64i
Nonzero exit
None

あれ?今度はSpikeでエラーだ。--iss whisper にしてもなぜかSpike を要求してしまう。

riescuec --mode bringup --iss whisper --run_dir test1 --json ./rv64i.json
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 103, in run
    self._classify(process, output_file)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 318, in _classify
    self._raise_toolchain_error(process, ToolFailureType.NONZERO_EXIT)
  File "/home/msyksphinz/work/riscv/riscued/.venv/lib/python3.12/site-packages/riescue/lib/toolchain/tool.py", line 114, in _raise_toolchain_error
    raise ToolchainError(tool_name=self.__class__.__name__, cmd=process.args, kind=kind, returncode=process.returncode, error_text=error_text, **kwargs)
riescue.lib.toolchain.exceptions.ToolchainError: Spike Failed:
        ran: /home/msyksphinz/riscv64/bin/spike -l --log-commits --max-instrs=2000000 --priv=msu --pc=0x80000000 --misaligned --isa=RV64IMAFDCVH_zba_zbb_zbc_zfh_zbs_zfbfmin_zvfh_zvbb_zvbc_zvfbfmin_zvfbfwma_zvkg_zvkned_zvknhb_svpbmt_sstc_zicntr --varch=vlen:256,elen:64 /home/msyksphinz/work/riscv/riescuec/test1/rv64i
Nonzero exit