読者です 読者をやめる 読者になる 読者になる

FPGA開発日記

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

64bit BOOMプロセッサでCoremarkを動作させたい

RISC-V環境であるE51プロセッサを動作させたときに、Coremarkの公称値と実際の値が少し違っているのを見つけた。

msyksphinz.hatenablog.com

はてさて、実際にはどっちが正しいのだろう?RTLでCoremarkをシミュレーションすることはできないだろうか?Coremarkをrocket-chipの環境で動作させるためにはどのようにしたらよいのだろう。

このエントリの情報は古い。以下の記事にてRTLシミュレーションでCoremarkを計測した。

msyksphinz.hatenablog.com

64bit版Coremarkバイナリの生成

BOOMのRTLで実行できるためのバイナリを生成するためには、ちょっとした手順が必要だ。

普段はどのようにリグレッションを行っているかというと、riscv-testsにベンチマークテストパタンとコンパイル方法が記述されており、

github.com

riscv64-unknown-elf-gcc \
    -T ./common/test.ld 
    -I ./../env -I./common -I./median -I./qsort -I./rsort -I./towers -I./vvadd -I./multiply -I./mm -I./dhrystone -I./spmv -I./mt-vvadd -I./mt-matmul  
    dhrystone_main.o  dhrystone.o  syscalls.o  crt.o \
    -o dhrystone.riscv \
    -nostdlib -nostartfiles -ffast-math -lgcc

riscv64-unknown-elf-objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.data dhrystone.riscv > dhrystone.riscv.dump

ということで、リンカスクリプトとしてtest.ldシステムコール系としてsyscalls.oを使っている。

同じ要領でCoremarkもコンパイルできるだろうか。

Coremarkをriscv-testsの環境でコンパイルしてみる

freedom-e-sdkのCoremarkコンパイル用のディレクトリに移動して、以下のようにしてコマンドを叩いてみた。

 /home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DFLAGS_STR=\""-O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4"\" -DITERATIONS=1 -DPERFORMANCE_RUN=1 -g -march=rv64imac -mabi=lp64 -mcmodel=medany -I/home/msyksphinz/work/freedom-e-sdk/bsp/include -I/home/msyksphinz/work/freedom-e-sdk/bsp/drivers/ -I/home/msyksphinz/work/freedom-e-sdk/bsp/env -I/home/msyksphinz/work/freedom-e-sdk/bsp/env/coreplexip-e51-arty /home/msyksphinz/work/freedom-e-sdk/bsp/env/entry.o core_list_join.o core_main.o core_matrix.o core_state.o core_util.o core_portme.o -L/home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/ /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o   -o coremark -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write -Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times -Wl,--wrap=sbrk -Wl,--wrap=_exit -L. -Wl,--start-group -lwrap -lc -Wl,--end-group -T /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/common/test.ld -nostartfiles -L/home/msyksphinz/work/freedom-e-sdk/bsp/env

以下のようなエラーが出た。どうやらターゲットの種類が少し違っているようだ。

/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o: can't link hard-float modules with soft-float modules
/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o のターゲット特有データの併合に失敗しました
/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks//crt.o: can't link hard-float modules with soft-float modules
/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks//crt.o のターゲット特有データの併合に失敗しました
collect2: error: ld returned 1 exit status

おそらく syscalls.o のターゲットが異なっていると思うので、以下のようにriscv-tests内のベンチマークコンパイルMakefileを修正してみる。

diff --git a/benchmarks/Makefile b/benchmarks/Makefile
index bc17927..04878d4 100644
--- a/benchmarks/Makefile
+++ b/benchmarks/Makefile
@@ -50,7 +50,7 @@ HOST_COMP = gcc $(HOST_OPTS)

 RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
 RISCV_GCC ?= $(RISCV_PREFIX)gcc
-RISCV_GCC_OPTS ?= -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf
+RISCV_GCC_OPTS ?= -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -march=rv64imac -mabi=lp64
 RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs)
 RISCV_LINK_MT ?= $(RISCV_GCC) -T $(src_dir)/common/test-mt.ld
 RISCV_LINK_OPTS ?= -nostdlib -nostartfiles -ffast-math -lgcc

これで再度コンパイルすると、エラーは発生するが syscalls.o は作成されているようだ。

/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(adddf3.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(adddf3.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(gedf2.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(gedf2.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(muldf3.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(muldf3.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(subdf3.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(subdf3.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(floatundidf.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(floatundidf.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clzsi2.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clzsi2.o) のターゲット特有データの併合に失敗しました
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clz.o): can't link hard-float modules with soft-float modules
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clz.o) のターゲット特有データの併合に失敗しました

以下のようにして再度Coremarkをコンパイルしてみると、エラー無くコンパイルできた。

${REPO_FREEDOM}/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc \
    -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 \
    -falign-functions=4 -falign-jumps=4 -falign-loops=4 \
    -DFLAGS_STR=\""-O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4"\" \
    -DITERATIONS=1 -DPERFORMANCE_RUN=1 -g -march=rv64imac -mabi=lp64 -mcmodel=medany \
    -I${REPO_FREEDOM}/bsp/include -I${REPO_FREEDOM}/bsp/drivers/ -I${REPO_FREEDOM}/bsp/env -I${REPO_FREEDOM}/bsp/env/coreplexip-e51-arty \
    ${REPO_FREEDOM}/bsp/env/entry.o \
    core_list_join.o core_main.o core_matrix.o core_state.o core_util.o core_portme.o \
    -L/home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/ \
    /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o \
    -o coremark \
    -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write \
    -Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve \
    -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times \
    -Wl,--wrap=sbrk -Wl,--wrap=_exit -L. -Wl,--start-group -lwrap -lc -Wl,--end-group \
    -T ${REPO_RISCV_TESTS}/benchmarks/common/test.ld -nostartfiles -L${REPO_FREEDOM}/bsp/env

RISC-V ISS Spikeでシミュレーション

RISC-VのISSであるSpikeでシミュレーションを行ってみると、以下のようにして実行されていることが分かる。 最後まで到達したから間違いはなさそうかな。

spike -l output/coremark.riscv &> output/coremark.riscv.spike.log

BOOMコアでRTLシミュレーション

同様にBOOMコアで実行してみたのだが、途中でPipelineがHungしてしまった。 メモリストアのところで落ちてしまった。何が悪いのだろうか?

$ make output/coremark.riscv.out CONFIG=BOOMConfig
Assertion failed: Pipeline has hung.
    at core.scala:833 assert (!(idle_cycles.value(13)), "Pipeline has hung.")

$ ../boom/util/pipeview-helper.py -f output/coremark.riscv.out > cleaned_trace.out && ~/work/gem5/util/o3-pipeview.py -o pipeview.out --color cleaned_trace.out

2017/05/23追記:RocketChipとBOOMではソフトウェアのバイナリが異なる。BOOMはCompressedISAをサポートしていないようだ。

msyksphinz.hatenablog.com

2017/05/20追記、よく見てみたらRocketを作成する際にメモリマップなどのコンフィグレーションが表示されていた。

ram {
  0 {
  addr 0x80000000;
  size 0x10000000;
  };
};
plic {
  priority 0xc000000;
  pending 0xc001000;
  ndevs 2;
};
rtc {
  addr 0x200bff8;
};
core {
  0 {
    0 {
      isa rv64imafds;
      timecmp 0x2004000;
      ipi 0x2000000;
      plic {
        m {
         ie 0xc002000;
         thresh 0xc200000;
         claim 0xc200004;
        };
        s {
         ie 0xc002080;
         thresh 0xc201000;
         claim 0xc201004;
        };
      };
    };
  };
};
plic {
  addr 0xc000000;
  size 0x4000000;
}
ExampleRocketTop {
  addr 0x60000000;
  size 0x20000000;
}
debug {
  addr 0x0;
  size 0x1000;
}
ExampleRocketTop {
  addr 0x80000000;
  size 0x10000000;
}
zeros_0 {
  addr 0xa000000;
  size 0x2000000;
}
clint {
  addr 0x2000000;
  size 0x10000;
}
bootrom {
  addr 0x1000;
  size 0x1000;
}

関連記事

以下の記事にてCoremarkの動作に成功した。

msyksphinz.hatenablog.com