FPGA開発日記

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

AWS F1インスタンス上のFireSimでBOOMコアをシミュレーションする試行(7. Firechipでオリジナルデザインを設計してシミュレーションする)

f:id:msyksphinz:20190405012417p:plain

FireSimの環境で、どうにかRocketシングルコアを動かすことができた。ここまでできれば、今度は様々なハードウェアをf1インスタンスで動かしてみたい。RocketはChiselというハードウェア記述言語で設計されているが、ChiselでオリジナルのモジュールをRocketに追加して、オリジナルのRocketコアを作れば、f1インスタンス上で動作させることができると思う。

FireSimのコアデザイン"Firechip"

FireSimは、RISC-Vコアを動作させるための環境そのものを指す。FireSimのリポジトリにはChiselで記述されたいくつかのデザインは入っているが、コアそのものではなく、周辺IPだったり、SoCを構成するための部品がメインになる。一方で、シミュレーションするコア自体は別のリポジトリで管理されている。それが"firechip"というリポジトリになる。

FireSimのリポジトリのサブリポジトリとして、"firechip"リポジトリが配置されている。

firesim
├── deploy
├── docs
├── platforms
│   └── f1
├── riscv-tools-install
├── scripts
├── sim
├── sw
├── target-design
│   ├── firechip
│   └── switch

このfirechipリポジトリは、Rocket-Chipのリポジトリと同様、単体でRTLシミュレーションを行うことができる。また、Rocket-Chipと同様、カスタマイズも可能だ。

cd firesim
cd target-design/firechip/verisim   # Verilatorを使う。VCSを使う場合はtarget-design/firechip/vsim
make clean && make run-regression-tests

つまり、FireChipを改造すればAWS f1インスタンス上でFireSimを使い、オリジナルに改造したRISC-Vコアを走らせることができる。どのように進めればよいか見ていく。

FireChipにカスタマイズアクセレレータを実装する

さて、実装方針が決まったので、FireChipに行列積アクセラレータを実装する。あらかじめ、今回はGitHubに公開されているfirechipのリポジトリをforkし、msyksphinz/firechip.gitで作業を行う。FireChipリポジトリをcloneし、セットアップを行う。この作業はAWSインスタンス上で行う必要はなく、ローカルマシンで実行しても問題ない。

git clone https://github.com/msyksphinz/firechip.git
cd firechip
git submodule update --init
cd rocket-chip
git submodule update --init
cd ..

行列アクセラレータを実装するために、以下のファイルを作成・修正する。

src/main/scala/example/Configs.scala
src/main/scala/example/MatrixMul.scala
  • src/main/scala/example/Configs.scala
class RoccMatrixMulConfig extends Config(
  new WithRoccMatrixMul ++ new DefaultExampleConfig)
  • src/main/scala/example/MatrixMul.scala
class MatrixMul(opcodes: OpcodeSet, val n: Int = 4)(implicit p: Parameters) extends LazyRoCC(opcodes) {
  override lazy val module = new MatrixMulModuleImp(this)
}

class MatrixMulModuleImp(outer: MatrixMul, n: Int = 4)(implicit p: Parameters) extends LazyRoCCModuleImp(outer)
    with HasCoreParameters {
...

コンフィグレーションはRoccMatrixMulConfigを指定した。Verilog生成時に、CONFIGオプションでRoccMatrixMulConfigを指定すると、所望のVerilogが生成される。

cd firechip/verisim
make CONFIG=RoccMatrixMulConfig

そして、上記で示したテストプログラムを実行する。プログラムは自前でコンパイルしても良いだが、firechip/testsに配置してMakefileを追加すると自動的にコンパイルしてくれる。

diff --git a/tests/Makefile b/tests/Makefile
index a199743..1102ecf 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -3,7 +3,7 @@ OBJDUMP=riscv64-unknown-elf-objdump
 CFLAGS=-mcmodel=medany -std=gnu99 -O2 -fno-common -fno-builtin-printf -Wall
 LDFLAGS=-static -nostdlib -nostartfiles -lgcc

-PROGRAMS = pwm blkdev accum charcount nic-loopback pingd big-blkdev input-stream
+PROGRAMS = pwm blkdev accum charcount nic-loopback pingd big-blkdev input-stream matrixmul

 default: $(addsuffix .riscv,$(PROGRAMS))

RTLシミュレーションを実行する。SW実行と比べて、ハードウェアアクセラレータを付加した場合にどれくらい高速化されるか検証した。

make CONFIG=FireSimRocketChipMatrixMulConfig
./simulator-example-RoccMatrixMulConfig ../tests/matrixmul.riscv

シミュレーションで正しく実行されることを確認した。

                    SW          HW
----------------------------------
 2 x 2 x 2 :        278        152
 4 x 4 x 4 :       1238        521
 8 x 8 x 8 :       9185       2691
16 x16 x16 :      70288      17621
18 x24 x28 :     209390      47615