はじめに
ISA とは何か?
ISAとは命令セットアーキテクチャ(Instruction Set Architecture)のことです。
こちらは、ソフトウェアとハードウェアのインターフェースに関する決まり事を定めた概念で、CPUで実行される機械語の集合である命令セットや、レジスタ、データ型、アドレッシングモード、メモリマネジメント、割り込み処理・例外処理、入出力、、、について定義したものだそうです(参考: Wikipedia先生による「命令セット」に詳しく記載されております)。
難しい話な可能性がございますので、CPU周りの設計を行ったんだな的な感じでとりあえず大丈夫だと思います。
RISC-V のカスタマイズについて
RISC-V の注目すべき点の1つとして、 ISA のカスタマイズが容易であるという点が挙げられます。
Intel や ARM などのプロセッサは、使われなくなった legacy (遺産的) な ISA を含んでおります。
それに対し RISC-V は、1から用途に合わせてライセンスフリー(無料で)で自由にISAを設計できるのです。
その為、RISC-V の登場によって、 特定のアプリケーションに特化したプロセッサのニーズが近年脚光を浴びております。
特定のアプリケーションに合わせて設計するプロセッサは、ASIP (Application Specific Instruction-set Processor)や、少し広義になると Domain Specific Processor などと呼んだりします。
今回はその RISC-V のカスタマイズ方法に関して、2つの機能についてお話をさせていただきます。
モジュール性
RISC-V にはモジュール性という、CPU がその命令セット群をサポートするかしないかを設計者が設定できる機能が備わっております。<図1>
言い換えてしまうと、「CPU で実行できる命令セットを用途に合わせて選択できる」という機能です。
なぜ拡張という機能があるかというと、たくさん命令を備えれば 汎用性 が備わったり、より 高速 にプログラムを実行できるようになります。また、 コードサイズ削減 による メモリ使用量の削減 にも繋がります。
しかし、組み込み機器など、 コスト (=値段や回路面積)が限られたり、実行されるアプリケーションが限られるような状況では、その汎用性が 無駄 だったりします。しかし採用する命令セットを減らしすぎると、先ほども述べましたがコードサイズ(それに伴うメモリ使用量)が大きくなってしまいます。
以上のことから、用途に合わせた命令セットを選択して CPU を開発する必要があるのです。
RISC-V ISA 拡張表。ベースとなるのが RVI で、拡張の例としては整数乗算用のM拡張、アトミック命令用のA拡張、単精度浮動小数点用のF拡張、倍精度浮動小数点用のD拡張などが存在する。(1 の p.i を参照)
カスタム命令用のオペコードが存在している
RISC-V は カスタム命令 用のオペコード(=命令を識別するために必要な値)が存在しており、演算内容を自由に定めた命令を追加することができます。
RISC-Vの命令長は(基本的には)32bitで固定なのですが、そのうち下位7bitがオペコードとして存在しています。<図2>
そして、カスタム命令追加用として、専用のオペコード値 (custom0 ~ custom3) が予め用意されております。<図3>
カスタム命令を実装することで、特定のアプリケーションで頻出する複数命令を1つにまとめることで、命令の呼び出し回数が減り、コードサイズ削減できる上に、より高速で低消費電力な実行が可能となるのです。
RISC-V 命令フォーマット。オペコードは下位7bitに存在している(1 の p.16 を参照)
カスタム命令を追加できるオペコード。カスタム命令用オペコードは custom0 ~ custom3 の合計4つが定義されている。例えば cutom0 を使用する際は「0001011」、custom1 を使用する際はオペコード「0101011」を用いる。(1 の p.129 を参照)
まとめ
以上のことから、モジュール性がありカスタム命令を追加しやすい設計となっている RISC-V の恩恵により、特定のアプリケーションに特化したプロセッサの開発が誰でもできるような環境になりました。
次回は RISC-V コンパイラの代表格である riscv-gnu-toolchain による 「RISC-V コンパイラにカスタム命令を追加する」という記事を書く予定かも(?)です。
ご質問やご指摘などございましたら、是非コメントしてください。