FPGA開発日記

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

Vivado-HLSを使って高位合成でCPUを作ってみる(5. リグレッションテスト環境の構築)

Vivado-HLSを使って簡単なRISC-V CPUを作ってみている。

一つのテストパタンが動作するようになったので、全てのテストパタンを動作させて実装の確認を行っていく。 追加していない命令はたくさんあるので、テストは完走はしないだろうが、一応チェックしておくことにした。

テストパタンはrv32ui-p-xxxのテストを使用する。 このパタンをVivado-HLS上で流し、動作を確認することにした。

github.com

リグレッション環境をどのように構築するか考えたのだが、いちいちテストのたびにシェルスクリプトか何かでディレクトリを作るのが面倒なので、なるべくVivado-HLSの構成に則って構築したい どうやらVivado-HLSにはプロジェクトの下にソリューションという項目があり、こちらで最適化オプション毎の処理を行ったりするらしい。 折角なのでソリューションを活用させてもらう。つまり、テストパタン毎にソリューションを構築し、その環境下でテストを流すことにした。

f:id:msyksphinz:20190222010203p:plain
Vivado-HLS上でのリグレッション環境の構成

以下のようにMakefileを作成し、テストパタン毎にmakeを実行する。やろうと思えば並列にも走る、はず。でも共通ディレクトリが必要だから、やっぱりダメかな。

TEST_PATTERNS = $(wildcard ./riscv-tests/isa/rv32ui-p-*.hex)
RUN_PATTERNS = $(addsuffix _run,$(notdir $(basename $(TEST_PATTERNS))))
...
regression: | $(RUN_PATTERNS)

%_run:
        make -f ../common/csim.mk HLS_SOLUTION=$(subst _run,,$@) TEST_PATTERN=$(subst _run,.hex,$@) > /dev/null

run_csim.tcl は以下のように構成し、ソリューション名とテストパタン名を変えてリグレッションテストを流す。 これにより、テスト結果はcpu_hls/${HLS_SOLUTION}/csim/build/に格納され、テストパタンも別々のディレクトリに格納されるのでリグレッション結果をすぐに一覧で確認できる。

  • run_csim.tcl
open_project $env(HLS_TARGET)
set_top $env(HLS_TARGET)
add_files $env(HLS_SRC)
add_files -tb test_$env(HLS_TARGET).cpp
add_files -tb ./riscv-tests/isa/$env(TEST_PATTERN)
open_solution $env(HLS_SOLUTION)

create_clock -period 10 -name default
source "./directives.tcl"

puts $env(TEST_PATTERN)

csim_design -argv $env(TEST_PATTERN)

一応すべてのテストパタンを実行した。Result=1となればPASSを意味する。 結果は以下。やはりバイト・ハーフワードのメモリアクセスをさぼっているのが痛い。結構落ちている。 ちゃんと修正しなければ。

$ make regression
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-srai TEST_PATTERN=rv32ui-p-srai.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-lw TEST_PATTERN=rv32ui-p-lw.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-fence_i TEST_PATTERN=rv32ui-p-fence_i.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-lbu TEST_PATTERN=rv32ui-p-lbu.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-jalr TEST_PATTERN=rv32ui-p-jalr.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-beq TEST_PATTERN=rv32ui-p-beq.hex > /dev/null
...
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-bge TEST_PATTERN=rv32ui-p-bge.hex > /dev/null
make -f ../common/csim.mk HLS_SOLUTION=rv32ui-p-bne TEST_PATTERN=rv32ui-p-bne.hex > /dev/null
$ grep Result cpu_hls/rv32ui-p-*/csim/report/cpu_hls_csim.log
cpu_hls/rv32ui-p-add/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-addi/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-and/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-andi/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-auipc/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-beq/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-bge/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-bgeu/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-blt/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-bltu/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-bne/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-fence_i/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-jal/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-jalr/csim/report/cpu_hls_csim.log:Result = 0
cpu_hls/rv32ui-p-lb/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-lbu/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-lh/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-lhu/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-lui/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-lw/csim/report/cpu_hls_csim.log:Result = 5
cpu_hls/rv32ui-p-or/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-ori/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sb/csim/report/cpu_hls_csim.log:Result = 9
cpu_hls/rv32ui-p-sh/csim/report/cpu_hls_csim.log:Result = 7
cpu_hls/rv32ui-p-simple/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sll/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-slli/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-slt/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-slti/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sltiu/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sltu/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sra/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-srai/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-srl/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-srli/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sub/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-sw/csim/report/cpu_hls_csim.log:Result = 13
cpu_hls/rv32ui-p-xor/csim/report/cpu_hls_csim.log:Result = 1
cpu_hls/rv32ui-p-xori/csim/report/cpu_hls_csim.log:Result = 1