RISC-VのRocket Chipを使う構成で、FPGAにインプリメントするためのパッケージとしては以下の2つがあるだろう。
- UCBのfpga-zynqリポジトリを利用する (https://github.com/ucb-bar/fpga-zynq)
- SiFiveのfreedomリポジトリを利用する (https://github.com/sifive/freedom)
それぞれに特徴があるだろう。Freedomのリポジトリを利用すると、Arty, VC707 がメインになるがSiFiveのデバッグツールなどを利用することができる。 一方で、UCBのfpga-zynqでは、ZedBoard, Zybo, ZC706などのボードのための構成が用意されている。
今回は、より一般的な構成(になっていそうな)fpga-zynqリポジトリを使って、RoCCのアクセラレータを搭載したRISC-VのFPGAデザインを作るためにはどうしたらよいのか調査した。
RISC-VのRocket Chipには様々なコンフィギュレーションが存在し、その中に、RoCC(Rocket Custom Coprocessor)にアクセラレータを接続した構成が存在する。
今回私がRoCCの試行に使用しているのもその構成の一つだ。RoccExampleConfig
という構成でRocket Chipをコンパイルすれば、アクセラレータ付きのデザインがコンパイルされVerilogが生成される。
fpga-zynq
のREADME.mdには、make rocket CONFIG=MyFPGAConfig
などと例が載っており、自分の必要なRocket Chipの構成してFPGAを作成することができる。
デフォルトでは、コンフィグレーションはZynqConfig
となっている。これは、リポジトリ内の、common/Makefrag
から分かる。
- common/Makefrag
CONFIG ?= ZynqConfig
それ以外に、いくつか構成が存在する。良く知られたところではDefaultConfigなどがRocket Chipのシミュレーションなどに使用される。
これらのコンフィグレーションはどこで定義されているかというと、common/src/main/scala/Configs.scala
を参照すれば分かる。
... class ZynqConfig extends Config(new WithZynqAdapter ++ new DefaultFPGAConfig) class ZynqSmallConfig extends Config(new WithSmallCores ++ new ZynqConfig) ...
つまりZynqConfig
というのは、DefaultFPGAConfig
というものと、WithZynqAdapterというコンフィグレーションから構成されている。ではこのDefaultFPGAConfig
とは何なのかというと、rocket-chip/src/main/scala/rocketchip/Configs.scala
に定義されてある。
class DefaultFPGAConfig extends Config(new FPGAConfig ++ new BaseConfig)
ベースのコンフィグレーションに対して、FPGAConfig
というものを付け加えたものがDefaultFPGAConfig
というものになるらしい。同様に、RoccExampleConfig
はどのようになっているのかというと、
class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig)
と定義されており、ベースのコンフィグレーションに対して、RoCCのアクセラレータを付加したものになっている。 では、これにFPGAConfigを付け加えてFPGA向けのRoCCアクセラレータ付きのコンフィグレーションとして定義できるだろうか。 以下を付け加えた。
diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index e253bfb..a7b93f0 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -146,6 +146,8 @@ class DualChannelDualBankL2Config extends Config( class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig) +class RoccFPGAConfig extends Config(new FPGAConfig ++ new WithRoccExample ++ new BaseConfig) + class WithEdgeDataBits(dataBits: Int) extends Config( (pname, site, here) => pname match { case EdgeDataBits => dataBits
RoccFPGAConfig
を作成した。これをさらにfpga-zynq
側のリポジトリでFPGA合成用の構成として定義する。
ここでは新たにRoccZynqConfig
を作成した。
diff --git a/common/src/main/scala/Configs.scala b/common/src/main/scala/Configs.scala index 7ae2c38..bf52376 100644 --- a/common/src/main/scala/Configs.scala +++ b/common/src/main/scala/Configs.scala @@ -41,6 +41,8 @@ class WithSmallCores extends Config( class ZynqConfig extends Config(new WithZynqAdapter ++ new DefaultFPGAConfig) class ZynqSmallConfig extends Config(new WithSmallCores ++ new ZynqConfig) +class RoccZynqConfig extends Config(new WithZynqAdapter ++ new RoccFPGAConfig) + class WithIntegrationTest extends Config( (pname, site, here) => pname match { case BuildSerialDriver =>
これでFPGA用のVerilogファイルを生成してみよう。以下で実行可能だ。
make rocket CONFIG=RoccZynqConfig
make project
make vivado
これでVivadoのGUIが立ち上がり、合成が可能となる。Verilogファイルを確認し、RoCCアクセラレータが含まれていること、一応合成を試行し、FPGAのbitファイルが生成されることを確認した。