UCBの開発しているシミュレータSpikeは、RISC-Vの命令セットをシミュレーションすることのできるISSで、サイクル精度を出すことはできないが最初のアプリケーションのデバッグに有用なツールだ。
そして、RISC-Vにはカスタム命令 (custom0 - custom3)が用意されており、Rocket Chipの場合にはこの命令フィールドを用いてRoCCインタフェース上にアクセラレータを搭載することが出来る。
どうせ元はChiselなのだから、この辺をうまくマージすることが出来ないだろうかといろいろ調査していたのだが、どうやらRoCCインタフェースをSpikeシミュレータではシミュレーションすることが出来るようだ。
まず、サンプルプログラムとして dummy_rocc/
ディレクトリにサンプルが存在している。
dummy_rocc/ ├── dummy_rocc.ac ├── dummy_rocc.cc ├── dummy_rocc.mk.in └── dummy_rocc_test.c 0 directories, 4 files
この実装 dummy_rocc.cc
は rocc_t
を継承する形で実装されている。
https://github.com/riscv/riscv-isa-sim/blob/master/dummy_rocc/dummy_rocc.cc
class dummy_rocc_t : public rocc_t { public: const char* name() { return "dummy_rocc"; } reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2) { reg_t prev_acc = acc[insn.rs2]; if (insn.rs2 >= num_acc) ...
これを拡張して memtotal_rocc.cc
を作成してビルドを行ってみる。そのために memtotal_rocc/
ディレクトリを作成する。
$ tree memtotal_rocc/ -L 2 memtotal_rocc/ ├── memtotal_rocc.ac ├── memtotal_rocc.cc ├── memtotal_rocc.mk.in └── memtotal_rocc_test.c 0 directories, 4 files
class memtotal_rocc_t : public rocc_t { public: const char* name() { return "memtotal_rocc"; } ... reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2) { switch (insn.funct) { case 0: c0_reg_lengthM = xs1; break; case 1: c0_reg_lengthK = xs1; break; case 2: reg_t total = 0; for (reg_t i = 0; i < c0_reg_lengthK; i++) { total += p->get_mmu()->load_int32(xs1) * p->get_mmu()->load_int32(xs2); xs1 += sizeof(int32_t); xs2 += c0_reg_lengthK * sizeof(int32_t); } break; } return 0; }
ここで custom0 ()
の実装で、メモリアクセスを p->get_mmu()->load_int32(xs1) * p->get_mmu()->load_int32(xs2)
としている。
さらにこの memtotal_rocc をコンパイルするようにサブモジュールとして登録する。
riscv-isa-sim/configure.ac
diff --git a/configure.ac b/configure.ac index e361877..64759fa 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,7 @@ AC_SUBST([CXXFLAGS],["-Wall -Wno-unused -g -O2 -std=c++11"]) # The '*' suffix indicates an optional subproject. The '**' suffix # indicates an optional subproject which is also the name of a group. -MCPPBS_SUBPROJECTS([ riscv, dummy_rocc, softfloat, spike_main ]) +MCPPBS_SUBPROJECTS([ riscv, dummy_rocc, memtotal_rocc, softfloat, spike_main ]) #------------------------------------------------------------------------- # MCPPBS subproject groups
これでビルドするとlibmemtotal.so
が作成される。
build$ ls -1 *.so libdummy_rocc.so libmemtotal_rocc.so libriscv.so libsoftfloat.so libspike_main.so
これをオプションとして指定することで、extensionとして使用できるようになる。が、--extension=memtotal_rocc
で何故か認識されなかった。要解析。
$ ./spike --extension=dummy_rocc usage: spike [host options] <target program> [target options] Host Options: -p<n> Simulate <n> processors [default 1] -m<n> Provide <n> MiB of target memory [default 2048] -m<a:m,b:n,...> Provide memory regions of size m and n bytes at base addresses a and b (with 4 KiB alignment) -d Interactive debug mode -g Track histogram of PCs -l Generate a log of execution -h Print this help message -H Start halted, allowing a debugger to connect --isa=<name> RISC-V ISA string [default rv32ima] --pc=<address> Override ELF entry point --ic=<S>:<W>:<B> Instantiate a cache model with S sets, --dc=<S>:<W>:<B> W ways, and B-byte blocks (with S and --l2=<S>:<W>:<B> B both powers of 2). --extension=<name> Specify RoCC Extension --extlib=<name> Shared library to load --rbb-port=<port> Listen on <port> for remote bitbang connection --dump-dts Print device tree string and exit $ ./spike --extension=memtotal_rocc couldn't find extension 'memtotal_rocc' (or library 'libmemtotal_rocc.so')