FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

RISC-V Compliance Task Groupのテストパタンを試す

f:id:msyksphinz:20181016221815p:plain

RISC-V Foundationが公開しているテストパタンには、riscv-toolsリポジトリの中に含まれているriscv-testsテストパタンとは別に、RISC-V Compliance Task Groupのテストパタンが公開されている。

github.com

ダウンロードして試行することができる。デフオルトではriscvOVPsimが動いているようだ。

$ git clone https://github.com/riscv/riscv-compliance.git
$ cd riscv-compliance
$ make
...
make[1]: ディレクトリ '/home/msyksphinz/work/riscv-compliance' に入ります
make \
        RISCV_TARGET=riscvOVPsim \
        RISCV_DEVICE=rv32i \
        RISCV_PREFIX=riscv64-unknown-elf- \
        run -C /home/msyksphinz/work/riscv-compliance/riscv-test-suite/rv32i                                                                                                                                                                 make[2]: ディレクトリ '/home/msyksphinz/work/riscv-compliance/riscv-test-suite/rv32i' に入ります                                                                                                                                             riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -I/home/msyksphinz/work/riscv-compliance/riscv-test-env/ -I/home/msyksphinz/work/riscv-compliance/riscv-test-env/p/ -I/h
ome/msyksphinz/work/riscv-compliance/riscv-target/riscvOVPsim/ -T/home/msyksphinz/work/riscv-compliance/riscv-test-env/p/link.ld src/I-ENDIANESS-01.S -o /home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.elf; riscv64-unknown-elf
-objdump -D /home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.elf > /home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.elf.objdump
/home/msyksphinz/work/riscv-compliance/riscv-ovpsim/bin/Linux64/riscvOVPsim.exe --variant RV32I --program /home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.elf --signaturedump --customcontrol --override riscvOVPsim/cpu/sigdump/
SignatureFile=/home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01_signature.output --override riscvOVPsim/cpu/sigdump/ResultReg=3 --override riscvOVPsim/cpu/simulateexceptions=T --override riscvOVPsim/cpu/defaultsemihost=F --logf
ile /home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.out32 --override riscvOVPsim/cpu/user_version=2.3 --override riscvOVPsim/cpu/priv_version=1.11
Imperas riscvOVPsim

CpuManagerFixedPlatform (64-Bit) v99999999 Open Virtual Platform simulator from www.IMPERAS.com.
Copyright (c) 2005-2018 Imperas Software Ltd.  Contains Imperas Proprietary Information.
Licensed Software, All Rights Reserved.
Visit www.IMPERAS.com for multicore debug, verification and analysis solutions.

CpuManagerFixedPlatform started: Sun Oct 21 09:39:04 2018


Info (OR_OF) Target 'riscvOVPsim/cpu' has object file read from '/home/msyksphinz/work/riscv-compliance/work//I-ENDIANESS-01.elf'
...

00000000ffffffff00000000ffffffff
00000000ffffffff00000000ffffffff
00000000ffffffff00000000ffffffff
00000000ffffffff00000000ffffffff
Test PASSED
Info
Info ---------------------------------------------------
Info CPU 'riscvOVPsim/cpu' STATISTICS
Info   Type                  : riscv (RV64IM)
Info   Nominal MIPS          : 100
Info   Final program counter : 0x80000044
Info   Simulated instructions: 190
Info   Simulated MIPS        : run too short for meaningful result
Info ---------------------------------------------------
Info
Info ---------------------------------------------------
Info SIMULATION TIME STATISTICS
Info   Simulated time        : 0.00 seconds
Info   User time             : 0.00 seconds
Info   System time           : 0.00 seconds
Info   Elapsed time          : 0.02 seconds
Info ---------------------------------------------------

CpuManagerFixedPlatform finished: Sun Oct 21 09:30:52 2018


CpuManagerFixedPlatform (64-Bit) v99999999 Open Virtual Platform simulator from www.IMPERAS.com.
Visit www.IMPERAS.com for multicore debug, verification and analysis solutions.

make[2]: ディレクトリ '/home/msyksphinz/work/riscv-compliance/riscv-test-suite/rv64im' から出ます
riscv-test-env/verify.sh


Compare to reference files ...

Check             DIVW ... OK
Check             MULW ... OK
Check            REMUW ... OK
Check             REMW ... OK
--------------------------------
OK: 4/4
make[1]: ディレクトリ '/home/msyksphinz/work/riscv-compliance' から出ます

最後にチェック項目がOK: 4/4になっているのでOKだと思う。

Spikeを使ってシミュレーションする場合は、RISCV_TARGET=spikeを指定する。

$ make RISCV_TARGET=spike
...
spike --isa=rv64im +signature=/home/msyksphinz/work/riscv-compliance/work//REMUW_signature.output /home/msyksphinz/work/riscv-compliance/work//REMUW.elf 2> /home/msyksphinz/work/riscv-compliance/work//REMUW.out64
riscv64-unknown-elf-gcc -march=rv64im -mabi=lp64 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -I/home/msyksphinz/work/riscv-compliance/riscv-test-env/ -I/home/msyksphinz/work/riscv-compliance/riscv-test-env/p/ -I/home/msyksphinz/work/riscv-compliance/riscv-target/spike/ -T/home/msyksphinz/work/riscv-compliance/riscv-test-env/p/link.ld src/DIVW.S -o /home/msyksphinz/work/riscv-compliance/work//DIVW.elf; riscv64-unknown-elf-objdump -D /home/msyksphinz/work/riscv-compliance/work//DIVW.elf > /home/msyksphinz/work/riscv-compliance/work//DIVW.elf.objdump
spike --isa=rv64im +signature=/home/msyksphinz/work/riscv-compliance/work//DIVW_signature.output /home/msyksphinz/work/riscv-compliance/work//DIVW.elf 2> /home/msyksphinz/work/riscv-compliance/work//DIVW.out64
make[2]: ディレクトリ '/home/msyksphinz/work/riscv-compliance/riscv-test-suite/rv64im' から出ます
riscv-test-env/verify.sh


Compare to reference files ...

Check             DIVW ... OK
Check             MULW ... OK
Check            REMUW ... OK
Check             REMW ... OK
--------------------------------
OK: 4/4
make[1]: ディレクトリ '/home/msyksphinz/work/riscv-compliance' から出ます

自作RISC-Vシミュレータを使ってテストパタンを流してみる

自作シミュレータなど、ターゲットを増やしたいときは以下のようにファイルを追加するらしい。

$ tree riscv-target/ -L 1
riscv-target/
├── Codasip-simulator
├── README.md
├── riscvOVPsim
├── spike
└── swimmer_riscv   # このディレクトリを追加。spikeのものをコピーする。

ディレクトリの中身にはMakefile.includeが入っているので、ここにシミュレータのオプションを書き換えていく。

$ cd riscv-target/swimmer_riscv/
$ tree
.
├── compliance_io.h
├── compliance_test.h
└── device
    ├── rv32i
    │   └── Makefile.include
    ├── rv32im
    │   └── Makefile.include
    ├── rv32imc
    │   └── Makefile.include
    ├── rv32mi
    │   └── Makefile.include
    ├── rv32si
    │   └── Makefile.include
    ├── rv32ua
    │   └── Makefile.include
    ├── rv32uc
    │   └── Makefile.include
    ├── rv32ud
    │   └── Makefile.include
    ├── rv32uf
    │   └── Makefile.include
    ├── rv32ui
    │   └── Makefile.include
    ├── rv64i
    │   └── Makefile.include
    └── rv64im
        └── Makefile.include

13 directories, 14 files
  • riscv-compliance/riscv-target/swimmer_riscv/device/rv32i/Makefile.include
TARGET_SIM ?= swimmer_riscv
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
    $(error Target simulator executable '$(TARGET_SIM)` not found)
endif

RUN_TARGET=\
    $(TARGET_SIM) --bit-mode 32 --stop-host \
        --signature $(work_dir_isa)/$(*)_signature.output \
        --binfile $(work_dir_isa)/$< 2> $(work_dir_isa)/$@

RISCV_PREFIX   ?= riscv32-unknown-elf-
RISCV_GCC      ?= $(RISCV_PREFIX)gcc
RISCV_OBJDUMP  ?= $(RISCV_PREFIX)objdump
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles

COMPILE_TARGET=\
        $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \
                -I$(ROOTDIR)/riscv-test-env/ \
                -I$(ROOTDIR)/riscv-test-env/p/ \
                -I$(ROOTDIR)/riscv-target/$(RISCV_TARGET)/ \
                -T$(ROOTDIR)/riscv-test-env/p/link.ld $$< \
                -o $(work_dir_isa)/$$@; \
        $$(RISCV_OBJDUMP) -D $(work_dir_isa)/$$@ > $(work_dir_isa)/$$@.objdump

これで実行してみる。途中で止まってしまったのだが、これはシミュレータのバグだと思う。環境としてはできたかな。

$ make RISCV_TARGET=swimmer_riscv
for isa in rv32i rv32im rv32imc rv32mi rv32si rv32ua rv32uc rv32ud rv32uf rv32ui rv64i rv64im; do \
        echo $isa; \
        make RISCV_TARGET=swimmer_riscv RISCV_DEVICE=$isa RISCV_ISA=$isa variant; \
                rc=$?; \
                if [ $rc -ne 0 ]; then \
                exit $rc; \
        fi \
done
rv32i
make[1]: Entering directory '/home/msyksphinz/work/riscv/riscv-compliance'
make \
        RISCV_TARGET=swimmer_riscv \
        RISCV_DEVICE=rv32i \
        RISCV_PREFIX=riscv64-unknown-elf- \
        run -C /home/msyksphinz/work/riscv/riscv-compliance/riscv-test-suite/rv32i
make[2]: Entering directory '/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-suite/rv32i'
riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/ -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/p/ -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-target/swimmer_riscv/ -T/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/p/link.ld src/I-ENDIANESS-01.S -o /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01.elf; riscv64-unknown-elf-objdump -D /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01.elf > /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01.elf.objdump
swimmer_riscv --bit-mode 32 --stop-host --signature /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01_signature.output --binfile /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01.elf 2> /home/msyksphinz/work/riscv/riscv-compliance/work//I-ENDIANESS-01.out32
riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/ -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/p/ -I/home/msyksphinz/work/riscv/riscv-compliance/riscv-target/swimmer_riscv/ -T/home/msyksphinz/work/riscv/riscv-compliance/riscv-test-env/p/link.ld src/I-RF_x0-01.S -o /home/msyksphinz/work/riscv/riscv-compliance/work//I-RF_x0-01.elf; riscv64-unknown-elf-objdump -D /home/msyksphinz/work/riscv/riscv-compliance/work//I-RF_x0-01.elf > /home/msyksphinz/work/riscv/riscv-compliance/work//I-RF_x0-01.elf.objdump
...