RISC-Vを使うにはいろんな手段があります。ASICチップが乗っているボードを買ってくることもできますし、FPGAにデザインを焼いて動作させることもできます。特にFPGAを使う場合は、自分で簡単にカスタマイズすることもできますので独自のRISC-V環境を作ることもできます。
今回は、実際にRISC-Vを使う場合にどのような手段があるのか、特にオープンソースで公開されているものを中心に、RISC-Vプロセッサの実装について見ていきます。
入手できる評価ボード
まだ数は多くありませんが、RISC-Vチップが乗っている評価ボードもすでに製品化されています。有名なものを2つ挙げると、HiFive1という小型のArduinoインタフェースとの互換性のあるボードと、HiFive UnleashedというマルチコアのRISC-Vボード環境です。どちらも、米国のベンチャー企業であるSiFive社が開発・販売しています。
これらのボードに搭載されているデザインは、どちらもSiFive社が開発し、GitHub上に公開されているものがベースになっています。HiFive1はシングルコア・HiFive Unleashedは4コア+1コアで構成されています。
オープンソースのRISC-Vデザイン
オープンソースで公開されているRISC-Vプロセッサはどうでしょうか?実は、RISC-Vの実装についてはRISC-V Foundationがまとまった情報を公開しています。
代表的なものについて見ていきます。
Rocket Core
Rocketは、UCB(カリフォルニア大学バークレイ校)およびSiFive社が開発しているRISC-V実装です(https://github.com/freechipsproject/rocket-chip)。RocketはCPUコアの部分を示しており、L1キャッシュやバスなどを含めてRocket Chipという環境を作ることが出来ます。
Rocketの実装はシンプルです。標準的な5ステージのパイプラインですが、マシンモードやスーパバイザモードなどの各種実行モードをサポートし、64ビット演算、FPU演算なども搭載しています。RISC-V ISAの仕様はほぼすべて実装してあるため、まずは手軽にRISC-Vを動かしてみたいというときはRocketから試してみるのがおすすめです。また、上記のHiFive1やHiFive UnleashedボードもこのRocketコアをベースにしています。
BSDライセンスですので、自由に改造して配布することも可能です。
Rocketコアは手軽なデザインですが、ハードウェア開発の経験がある技術者にとっては、Verilogで記述していないというところが難点になる可能性があります。Rocketはほぼすべての実装部分が、ChiselというScalaをベースにしたDSL(Design Specific Language)で記述されています。なので、Rocketの実装について中身を見るときは、一緒にChisel(しいてはScala)も勉強する必要があるでしょう。
これはコアだけでなく、TileLinkなどのバス実装もChiselで記述されているため必須と言えるでしょう。
Rocketを搭載したSoC環境 Rocket-Chip
RocketはCPUコアの部分だけですが、RocketをCPUコアとしてキャッシュメモリやバスなどを追加してSoC環境を構築することができます。これはRocket-Chipと呼ばれています。FPGAでRISC-Vチップを動作させるためには、このRocket-Chip環境を使用します。
BOOM
上記のRocketコアはシンプルなパイプライン構成ですが、より高性能で高い動作周波数を狙った実装もあります。これがBOOM(Berkeley Out-of Order Machine)です。BOOMはアウトオブオーダ実行で複数命令を同時にデコード、発行する能力を持っており、Rocketよりも高い性能を発揮することができます。BOOMにはv1とv2があり、v2はv1に比べてより高い周波数で動作するように改良されています。
こちらもすべてのデザインがGitHub上で公開されています
BOOMの特徴は、現代のアウトオブオーダプロセッサが性能向上のために取り入れている数々の最新の機能を実装してあるということです。例えば分岐予測、オートプリフェッチなどが実装してあり、ベンチマークスコアもRocket Chipのものよりも高くなっています。
一方で、BOOMもRocketと同様に、VerilogではなくChiselで実装してあります。生成されたVerilogを見ても解析するのかなり困難で、Chiselについてしっかりと勉強しないと改造するのはかなり難しいです。
その他のRISC-V実装について
本章ではUCBおよびSiFiveで開発したRISC-V実装を紹介しましたが、それ以外にも研究・開発用に様々なRISC-Vデザインが開発されています。それらの情報をまとめて調査したい場合には、最初に紹介したRISC-VデザインのまとめられたWikiが参考になります。みなさんも、自分が使いたい用途のRISC-Vデザインを探してみてください。
Rocket-Chipを動かしてみよう
後半では、前半で紹介したRocketコアを実際に動かしてみようと思います。ただ、今回はFPGAではなくRTLシミュレーションにてRocketコアを動かします。
Rocket-Chipのリポジトリは、以下のコマンドで取得してきます。Rocket-Chipにはメインのリポジトリ以外にサブリポジトリも含まれており、これらをすべて取得するとかなりの量になるので注意です(ただしリポジトリの大半はGNUツールチェインですので、すでにRISC-V向けツールチェインをダウンロードしてビルドしている方は不要です)。
riscv-gnu-toolchainをすでにダウンロードしてビルドしている方向け
$ git clone https://github.com/freechipsproject/rocket-chip.git $ cd rocket-chip $ git submodule update --init --recursive chisel3 firrtl hardfloat torture
riscv-gnu-toolchainをダウンロードしていない方向け
$ git clone https://github.com/freechipsproject/rocket-chip.git $ cd rocket-chip $ git submodulp update --init --recursive
Rocket-ChipのビルドとVerilogファイル生成
前述したように、Rocket-ChipはChiselというScalaをベースにしたDSLを使っているため、そのままではシミュレーションができません。そこで、まずはChiselからVerilogにデザインを変換します。変換後にRTLシミュレータを立ち上げるのですが、Rocket-ChipではSynopsys社のVCSか、Verilatorをサポートしています。どのRTLシミュレータを使用するかで作業するリポジトリが変わります。
- VCSを使用する場合
cd vsim
- Verilatorを使用する場合
cd emulator
以下でChiselからVerilogファイルが生成されます。以下では、生成するRocket-Chipとしてはデフォルトの構成を使用しています。
make CONFIG=DefaultConfig
しばらく時間がかかります。手元の環境では、Verilogファイルを生成するまでに約10分程度かかりました。
生成が完了したら、Verilogファイルを見てみましょう。generated-src/freechips.rocketchip.system.DefaultConfig.v
にVerilogファイルが生成されています。中身を見てみましたが、とても人間の読めるレベルのVerilogではありません(配線名なども機械的な名前に変換されており、かなりデバッグが大変そうです…)。やはり、自分でRocket-Chipを改造するとなると、Chiselを触るのが近道なようです。
提供されているベンチマークプログラムを動かしてみました。以下は4並列でベンチマークプログラムを動かしています。それぞれのベンチマークの実行結果及びCPUのトレースファイルは、`output/`ディレクトリに格納されているので、確認してみましょう。
$ make run
カスタムプログラムをコンパイルしてシミュレーションする
つぎに自分のオリジナルプログラムをコンパイルして、シミュレーションしてみましょう。ここでは、オリジナルプログラムと言ってもRocket-Chipのリポジトリで公開されているサンプルプログラムを使用しています。
helloworld.c
#include <stdio.h> int main() { char text[] = "Vafgehpgvba frgf jnag gb or serr!"; int i = 0; while (text[i]) { char lower = text[i] | 32; if (lower >= 'a' && lower <= 'm') text[i] += 13; else if (lower > 'm' && lower <= 'z') text[i] -= 13; i++; } printf("%s\n", text); return 0; }
コンパイルするためには、riscv-tools/riscv-testsリポジトリに含まれているcrt.Sとsyscalls.c、さらにリンカスクリプトであるtest.ld
を使用します。
$ riscv64-unknown-elf-gcc -mcmodel=medany -O2 -fno-builtin-printf -nostartfiles helloworld.c crt.S syscalls.c -Ttest.ld -o helloworld
生成したバイナリを先ほどのシミュレーションディレクトリ`output/`において、シミュレーションを実行してみましょう。
$ cd output $ ln -s ${サンプルプログラムをコンパイルしたディレクトリ}/helloworld $ cd .. $ make CONFIG=DefaultConfig output/helloworld.out ./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/helloworld 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/helloworld.out && [ $PIPESTATUS -eq 0 ] Instruction sets want to be free!
最後に表示されたInstruction sets want to be free!
が出力です。プログラムが正しく動いたことが確認できました。
いかがでしたでしょうか。このように、RISC-VはISAだけでなく、すぐに動かすことができる実装がたくさん公開されています。皆さんもぜひ触ってみてください。
こちらも是非
“もっと見る” RISC-V編
GUIの開発環境を使ってRISC-Vを動かしてみよう
Arduino IDEは他のArduinoプラットフォームとの親和性が良く、Arduinoチップとして楽しむならば十分な環境です。また、Freedom-E-SDKはコンソールを使ってプログラムのコンパイルやアップロードを行う環境で、初心者にはややハードルが高いですが、柔軟なプログラムを開発することができます。
GUIの環境は好きじゃない!Freedom SDKを使ったアプリケーション開発
Arduino IDEを使ってプログラムを書き込む方法をはじめ、EclipseベースのGUI環境であるFreedom Studioを使うとGUI環境でプログラムを開発することが出来ます。その一方で、GUIを使うのは面倒だし、Linuxなどを使っていればコマンドラインからすべて操作したいという人はたくさんいると思います。
Arduino互換RISC-Vプロセッサ“HiFive1”を使ってみる
RISC-Vを使うにはいろんな手段があります。ASICチップが乗っているボードを買ってくることもできますし、FPGAにデザインを焼いて動作させることができます。特にFPGAを使う場合は、自分で簡単にカスタマイズすることもできますので独自のRISC-V環境を作ることもできます。