9. 运行 RISC-V 官方的测试(上)

0. 概述

0.1 RISC-V 官方的测试分两个层级

  • Unit tests for RISC-V processors: riscv-tests
  • RISC-V Architecture Test SIG(SIG: Special Interest Group)
    • 核心是 RISCOF, RISCOF 支撑了架构测试的工作流。
      • RISCOF [Repo] [Doc] is a RISC-V Architectural Test Framework.
      • RISCOF - The RISC-V Compatibility Framework is a python based framework which enables testing of a RISC-V target (hard or soft implementations) against a standard RISC-V golden reference model using a suite of RISC-V architectural assembly tests.
    • 相关的其他库

0.2 相关缩写

  • riscv-arch-test: RISC-V Architecture Test
  • riscv-isac: RISC-V ISA Coverage
  • riscv-ctg: RISC-V Compatibility Test Generator
  • RISCOF: RISC-V Compatibility Framework

1. 单元测试

  • 使用 riscv-test 生成的测试程序,先要搞清楚的问题:

    • 怎样退出? ---- target 中, 使用编号为 93 的 ecall 表示程序运行结束.
    • 怎样判断结果?---- target 上 application 的退出值为 0 表示 pass。
  • 生成单元测试 case

$ git clone https://github.com/riscv/riscv-tests
$ cd riscv-tests
$ git submodule update --init --recursive
$ autoconf
$ ./configure --prefix=$RISCV/target
$ make
$ make install
  • 运行 riscv tests 中 rv32ui-p-* 的 test cases
#!/bin/bash

set -e

# Specify the folder path
# RISCV is the path of the RISCV toolchain installation
folder_path="$RISCV/target/share/riscv-tests/isa"

echo -e "\n========= Running $0 starting ========="

cargo build

file_count=0

# Loop through all files in the specified folder
for file in "$folder_path"/rv32ui-p-*; do
    # Extract the filename without the path
    filename=$(basename -- "$file")
    
    # Check if the filename does not end with .dump
    if [[ $filename != *.dump ]]; then
        # If the filename does not end with .dump, process the file
        echo -e "\nRun $filename in rrv-iss."
        if [[ $filename == rv32ui-p-fence_i ]]; then
            continue
        fi

        file_count=$((file_count + 1))

        # ./target/debug/rrv-iss -l debug -f "$file" -i tmp.instr
        output=$(./target/debug/rrv-iss -f "$file")
        exit_code=$(echo "$output" | grep "Target application exit code:" | awk -F': ' '{print $2}')

        echo "$output"
        if [ "$exit_code" -ne 0 ]; then
            echo -e "\nTarget application exit code is not 0, it is $exit_code"
            echo "Total number of processed files: $file_count"
            echo -e "Test FAILED"
            echo -e "========= Running $0 Done =========\n"
            exit 1
        fi
    fi
done

echo -e "\nTotal number of processed files: $file_count"
echo -e "Test PASSED"
echo -e "========= Running  $0 Done =========\n"

2. 探索架构测试流程

  • RISC-V Architecture Test:riscv-arch-test 中包含了 framework,老的 framework 是基于 Makefile 的,RISCOF 是 riscv-arch-test 使用的新 framework
  • RISCOF 的工作流串起了riscv-arch-test 的各个部分。RISCOF 有两种工作流:
    • 面向架构测试 case 使用者的工作流
      • 两个输入:yaml 格式的 RISCV CONFIG 文件;User DUT plugin
      • riscv-config 把用户提供的 yaml 文件转换为 standardized/normalized YAML spec
      • Test Selector 根据 std yaml 和 Test DataBase yaml 生成 Test-list yaml file
      • 根据 std yaml spec 和 test-list 在 reference model 和 DUT model 逐个运行 test case
      • reference model 和 DUT model 运行 test case时,会在内存中生成签名
        • produces a signature in the memory region of the test which captures the essence that particular test
      • RISCOF generates an HTML report which provides details of the implementation and tests that were passed/failed by the implementation.
    • 面向架构测试 case 开发者的工作流
      • 手写或者使用 RISCV-CTG 生成 test cases,test cases 需要遵守 Test Format Spec
      • 以 coverage mode 运行 RISCOF 来分析 test cases 的 coverage 和 quality
        • coverage mode 只会在 reference model 上运行 test cases
        • 把 execution trace 和 CGF-File (Cover Group Format File) 作为 RISCV-ISAC 的输入, RISCV-ISAC 输出 coverage report。
      • 开发好的 test cases 可以 pull request 到 riscv-arch-test/riscv-test-suite

2.1 准备 RISCOF 的运行依赖

安装 RISCOF 相关软件

~/python-venv$ sudo apt install python3-venv
~/python-venv$ python3 -m venv python3.6.0

zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ source ~/python-venv/python3.6.0/bin/activate

(python3.6.0) zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ git checkout -b local_dev d38859f
(python3.6.0) zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ pip3 install --editable .
(python3.6.0) zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ riscof --version
RISC-V Architectural Test Framework., version 1.25.3
  • install riscv-ctg: (python3.6.0) :~/xtools/source_tools/tests_for_riscv/riscv-arch-test/riscv-ctg$ pip install --editable .

  • install riscv-isac: (python3.6.0) :~/xtools/source_tools/tests_for_riscv/riscv-arch-test/riscv-isac$ pip install --editable .

  • install SAIL (SAIL C-emulator)

$ sudo apt-get install build-essential libgmp-dev z3 pkg-config zlib1g-dev
# $ bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
$ wget https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh
$ chmod +x install.sh
$ sudo ./install.sh

$ opam init -y --disable-sandboxing
$ eval $(opam env --switch=default)
# $ opam switch create ocaml-base-compiler.4.06.1
$ opam switch create ocaml-base-compiler
$ eval $(opam env --switch=ocaml-base-compiler)
$ opam update && opam upgrade
$ opam install sail -y
$ eval $(opam config env)

$ git clone https://github.com/riscv/sail-riscv.git
$ cd sail-riscv
$ make && ARCH=RV32 make

$ ln -s `realpath c_emulator/riscv_sim_RV32` ~/xtools/riscv/bin/riscv_sim_RV32
$ ln -s `realpath c_emulator/riscv_sim_RV64` ~/xtools/riscv/bin/riscv_sim_RV64

2.2 使用 spike 和 sail 来验证 riscof 的工作流程

2.2.1 创建 Env Files 和 Architectural Tests

inputs to the RISCOF framework

步骤记录

  • 浏览器中打开 https://github.com/riscv/riscv-arch-test 会跳转到 https://github.com/riscv-non-isa/riscv-arch-test , 需要修改 RISCOF 源码,重新 install RISCOF
(python3.6.0) zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ git diff --staged
diff --git a/riscof/constants.py b/riscof/constants.py
index 3cff010..c0e9e6e 100644
--- a/riscof/constants.py
+++ b/riscof/constants.py
@@ -13,8 +13,8 @@ suite = os.path.join(root,"suite/")
 #        if os.path.isfile(full_path):
 #            cgf_file.append(full_path)

-https_url = 'https://github.com/riscv/riscv-arch-test.git'
-ssh_url = 'git@github.com:riscv/riscv-arch-test.git'
+https_url = 'https://github.com/riscv-non-isa/riscv-arch-test.git'
+ssh_url = 'git@github.com:riscv-non-isa/riscv-arch-test.git'

 framework_db = os.path.join(root, "framework/database.yaml")
 cwd = os.getcwd()
 
(python3.6.0) zsw@zsw:~/xtools/source_tools/tests_for_riscv/riscof$ pip install --editable .
  • Create Neccesary Env Files
  • Clone or update the Architectural Tests
zsw@zsw:~/workspace/ws_develop/riscof_work_space/example$ source ~/python-env/python3.6.0/bin/activate

# Create Neccesary Env Files
(python3.6.0) zsw@zsw:~/workspace/ws_develop/riscof_work_space/example$ riscof setup --dutname=spike

# Clone the Architectural Tests
zsw@zsw:~/xtools/source_tools/tests_for_riscv$ git clone https://github.com/riscv-non-isa/riscv-arch-test.git

# or update the Architectural Tests
# (python3.6.0) zsw@zsw:~/workspace/ws_develop/riscof_work_space/example$ riscof --verbose info arch-test --dir ~/xtools/source_tools/tests_for_riscv --update
(python3.6.0) zsw@zsw:~/workspace/ws_develop/riscof_work_space/example$ riscof setup --dutname=spike
    INFO | ****** RISCOF: RISC-V Architectural Test Framework 1.25.3 *******
    INFO | using riscv_isac version : 0.18.0
    INFO | using riscv_config version : 3.18.3
    INFO | Setting up sample plugin requirements [Old files will be overwritten]
    INFO | Creating sample Plugin directory for [DUT]: spike
    INFO | creating /home/zsw/workspace/ws_develop/riscof_work_space/example/spike
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/model/model_platform.yaml -> /home/zsw/workspace/ws_develop/riscof_work_space/example/spike
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/model/riscof_model.py -> /home/zsw/workspace/ws_develop/riscof_work_space/example/spike
    INFO | creating /home/zsw/workspace/ws_develop/riscof_work_space/example/spike/env
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/model/env/model_test.h -> /home/zsw/workspace/ws_develop/riscof_work_space/example/spike/env
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/model/env/link.ld -> /home/zsw/workspace/ws_develop/riscof_work_space/example/spike/env
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/model/model_isa.yaml -> /home/zsw/workspace/ws_develop/riscof_work_space/example/spike
    INFO | Creating sample Plugin directory for [REF]: sail_cSim
    INFO | creating /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/sail_cSim/__init__.py -> /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/sail_cSim/riscof_sail_cSim.py -> /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim
    INFO | creating /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim/env
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/sail_cSim/env/model_test.h -> /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim/env
    INFO | copying /home/zsw/xtools/source_tools/tests_for_riscv/riscof/riscof/Templates/setup/sail_cSim/env/link.ld -> /home/zsw/workspace/ws_develop/riscof_work_space/example/sail_cSim/env
    INFO | Creating Sample Config File
    INFO | **NOTE**: Please update the paths of the reference and plugins in the config.ini file
  • 修改生成文件中的交叉编译工具名称,改动的文件见下面的 git diff 输出
diff --git a/sail_cSim/riscof_sail_cSim.py b/sail_cSim/riscof_sail_cSim.py
index 3ee8659..c253dd6 100644
--- a/sail_cSim/riscof_sail_cSim.py
+++ b/sail_cSim/riscof_sail_cSim.py
@@ -41,8 +41,8 @@ class sail_cSim(pluginTemplate):
     def initialise(self, suite, work_dir, archtest_env):
         self.suite = suite
         self.work_dir = work_dir
-        self.objdump_cmd = 'riscv{1}-unknown-elf-objdump -D {0} > {2};'
-        self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \
+        self.objdump_cmd = 'riscv64-unknown-elf-objdump -D {0} > {2};'
+        self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \
          -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\
          -T '+self.pluginpath+'/env/link.ld\
          -I '+self.pluginpath+'/env/\
@@ -63,11 +63,11 @@ class sail_cSim(pluginTemplate):
             self.isa += 'f'
         if "D" in ispec["ISA"]:
             self.isa += 'd'
-        objdump = "riscv{0}-unknown-elf-objdump".format(self.xlen)
+        objdump = "riscv64-unknown-elf-objdump".format(self.xlen)
         if shutil.which(objdump) is None:
             logger.error(objdump+": executable not found. Please check environment setup.")
             raise SystemExit(1)
-        compiler = "riscv{0}-unknown-elf-gcc".format(self.xlen)
+        compiler = "riscv64-unknown-elf-gcc".format(self.xlen)
         if shutil.which(compiler) is None:
             logger.error(compiler+": executable not found. Please check environment setup.")
             raise SystemExit(1)
diff --git a/spike/riscof_spike.py b/spike/riscof_spike.py
index 1e5ed76..8c791eb 100644
--- a/spike/riscof_spike.py
+++ b/spike/riscof_spike.py
@@ -72,7 +72,7 @@ class spike(pluginTemplate):
        # Note the march is not hardwired here, because it will change for each
        # test. Similarly the output elf name and compile macros will be assigned later in the
        # runTests function
-       self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \
+       self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \
          -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g\
          -T '+self.pluginpath+'/env/link.ld\
          -I '+self.pluginpath+'/env/\

2.2.2 Running RISCOF

validateyaml, testlist, run

  • riscof 是比较 signatures 文件,不是 trace 文件
# CWD --- (python3.6.0) zsw@zsw-xa:~/workspace/ws_develop/riscof_work_space/example

# The RISCOF run is divided into three steps as shown in the overview Figure. 
# The first step is to check if the input yaml files are configured correctly. 
# This step internally calls the riscv-config on both the isa and platform yaml files indicated in the config.ini file.
$ riscof validateyaml --config=config.ini

$ export RISCV_ARCH_TEST_ROOT=/home/zsw/xtools/source_tools/tests_for_riscv/riscv-arch-test

# The next step is to generate the list of tests that need to be run on the models.
$ riscof testlist --config=config.ini --suite=${RISCV_ARCH_TEST_ROOT}/riscv-test-suite/ --env=${RISCV_ARCH_TEST_ROOT}/riscv-test-suite/env

# The last step is to run the tests on the each of the models and compare the signature values to guarantee correctness.
$ riscof run --config=config.ini --suite=${RISCV_ARCH_TEST_ROOT}/riscv-test-suite/ --env=${RISCV_ARCH_TEST_ROOT}/riscv-test-suite/env
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容