オリジナル16ビットCPUコアMoscoviumが完成目前ですが、ここで比較対象としてのRISC-Vを試してみようと思います。ここら辺の連載をご覧になっている方にとっては、RISC-Vにも興味があるでしょうから、良い機会だと思います。
今回、後半でオリジナルのMoscoviumコアも完成させますので、そちらもお見逃しなく。
良い呼び方が思いつかないので、「コンパイル」と称していますが、Verilog-HDLをFPGAボードに書き込むための処理を指しています。正しい表現としては、「論理合成および配置配線」です。長ったらしいので、本HPではしばしばコンパイルと呼んでしまいます。
最初にFPGAボードを導入した時に長所として挙げた特徴として、「RISC-Vが移植されている」ことを上げました。SipeedのHPから、「MORE ⇒ GitHub repo」と辿ると、「Tang_E203_Mini」という項目が有ります。これが、FPGAボード(Sipeed Lichee Tang Primer)に移植されたRISC-VのE203と呼ばれるコアです。
調べてみると、RISC-V E203コアは:
と、かなりリッチなCPUコアの様ですね。
まずは、Tang_E203_Miniの下に格納された全ファイルをローカルPCにダウンロードしてください。これには、Cygwinのsvnコマンドを使います。
実験サンプル:【 】内はCygwinシェルウインドウからの実行コマンド
【svn export https://github.com/Lichee-Pi/Tang_E203_Mini/trunk/】
これで、GitHub上Tang_E203_Miniディレクトリ下の全ファイルがローカルPCにダウンロードできました。
※Cygwinで「svnコマンドが見つからない」エラーとなった場合は、こちらを参照して「svn」で検索し、適切なコマンドをインストールしてください。
Cygwinでの作業はこれで終了です。今ダウンロードしたディレクトリ「trunk\」が、Windows上にできているので、TD IDEを使って、以下のファイルを開いてください。
trunk\project\e203egmini_new.al
TD IDEのプロジェクトになっているので、もうこれだけでOKです。TD IDEの「Processメニュー ⇒ Run」でコンパイル(論理合成・配置配線)が実行できます。移植されているだけあって、かなり簡単です。何のエラーもなく、FPGAボードに書き込み可能なe203egmini.bitファイルが完成してしまいました。
ただし、コンパイルはとても時間がかかります。手持ちの環境(Core-i3-8100 @3.60GHz)では、20分以上かかりました。
「Physical Summary」を確認したところ、LUT数15k個、F/F数6.6k個と、かなり大きなコアです。最大19k LUTのFPGAボードに何とか乗っかっている、感じです。「Timing Summary」等と含めて以下にまとめておきます。
タイミング解析結果については、他人の作ったプロジェクトをそのまま実行してみただけなので、本当にちゃんとCPU(RISC-Vコア)にタイミング制約がかかっているのかどうか、わかりませんm(1__)m。このデザインを使う方は、よく吟味してみてください。
Tang_E203_Miniプロジェクトを開いたTD IDEで、モジュール階層を確認してみました(下図、抜粋)。
階層を辿ってみたところ、gpio,uart,pwm,i2c等のモジュール名も見えました。どうやら、単体のRISC-V CPUコアではなくて、SOC(System On Chip)のプロジェクトになっているみたいです。なるほど、この論理構成なら15k LUTとか、コンパイルに20分とか言う規模も納得です。
Season 15で作ろうとしているマイコン(MCU)に匹敵するどころか、はるかに超えるリッチなSOCが既に完成しているみたいです。
これが使えるか?と言うと、使いこなすためには、もう一歩準備が必要となります。このままでは、コンパイルして出来上がったe203egmini.bitファイルをFPGAボードに書き込んでも、動かせません。
RISC-V上で動作させるためのソフトウェアを、FPGAボード上のデザインにダウンロードするツールが別途必要なのです。
RISC-V+JTAGツールで検索(別ウインドウが開きます)
残念ながら、アドバイスできるのはここまでです。具体的に何という名前のどんなツール(ハードウェア)がRISC-Vソフトウェアのデバッグ用に使用可能なのか知りませんし、Windows用のツールなのか?Linuxでなければ動かないのか?も知りません。
ここから先は、興味ある方がご自身で調査して入手してください。
さらに、C言語で開発したい場合には、GCCのRISC-Vツールチェーンを入手してビルドしてください。これも必要な方の各自対応となります。
と、言う状態で、手元にはJTAGデバッガ(ハードウェア)も無いので、RISC-Vではこれ以上先に進めないことが判りました。やはり、自分でCPU作って使うのが一番手っ取り早くて確実な様です(筆者にとっては(1^^;)、です)。
よし、Moscoviumを完成させよう。
前回、以下CPUブロック図に従って、MEM,RGF,ALU,FCHブロックの基本設計を終了しました。
残るは大物、制御CTLブロックです。
何しろ、前回基本設計を終了したMEM,RGF,ALU,FCHブロックは単なる従属モジュールで、外部回路からの指示(コマンド)に従って言われた通りに動くだけの回路だったのですが、CTLブロックはその「指示を出す側」のモジュールなので、ちょいと格が違います。
基本的にはステートマシンとなるので、「#15-2 論理回路を設計する」で作成した、Excel表からVerilog-HDLに変換するスクリプト(tab2v.olv)を使います。
作成したExcel表は以下の様な感じです。
ほんの一部抜粋です。casexコマンド部分の入出力信号数とか、テーブルの行数とかに着目して見てください。
テーブルの入・出力信号について使い道を簡単に説明しておきます。
これですべてのブロックが完成しましたので、最上位モジュールにインスタンスして組み上げました。
※プロジェクトの作り方などに関しては、こちらで詳しく解説してあります。
コンパイル(論理合成・配置配線)してみた結果、以下の様になりました。
ちょっと思いの他、論理規模(LUTおよびF/F数)が大きいと感じました。きっと、汎用レジスタバンク(×4組)と、バレルシフタが原因でしょう。TD IDEの論理合成と配置配線は、全階層をフラット化してから実施しているため、階層毎の論理規模を知ることのできないことが残念です。
`defineマクロによる条件付きコンパイル(`ifdef)で、汎用レジスタバンク数(4バンク→1バンク化)とバレルシフタの有り/無しを切り替えて論理規模をまとめてみました(以下表)。
オプション | バンク数 | バレルシフタ | LUT数 | F/F数 |
デフォルト | 4 | あり(−16〜15ビットシフト) | 1,843 | 575 |
1バンクのみ | 1 | あり(−16〜15ビットシフト) | 1,285 | 181 |
バレルシフタなし | 1 | なし(−1,0,1ビットシフトのみ可能) | 872 | 181 |
思った通り(1^^;)。バンク数を減らして、バレルシフタも削除したところ、半分以下の規模まで縮小しました。
やはり、4バンク+16ビットフルバレルシフタはやり過ぎなのか?そうなのか(1@_@)💫?
でも、このまま行きますo(1^ー^)o、4バンク+バレルシフタありで。アセンブラによるプログラミングのし易さを前提に考えた仕様ですから。上の情報さえ持っておけば、将来論理規模を縮小して、より小さなFPGAチップに搭載することも可能だということが判るので、今はそれでOK。
Verilog-HDLソースファイルの行数は以下表の通りです(空行やコメント行も1行でカウントしました、【wc -l *.v】)。
行数 | ファイル名 | 備考 |
489 | mcvm_alu.v | 算術論理演算ユニットALUブロック |
39 | mcvm_fch.v | フェッチFCHブロック |
224 | mcvm_fsm.v | 制御CTLブロック |
188 | mcvm_mem.v | メモリアクセスMEMブロック |
778 | mcvm_reg.v | レジスタファイルRGFブロック |
166 | moscovium.v | 最上位(トップレベル) |
1,884 | total | トータル |
トータル2,000行に満たない記述量でCPUコアが完成してしまいました。案外簡単でしょう?
以下ページに、本HPで作ろうとしているマイコンのHDLを公開して行きます。まだCPUだけですが、登録しておきました。
FPGAなので、自分で好きなように組み上げて、使うことができます。Moscoviumコアはとても小さいCPUコアなので、何なら、2個使い(デュアルコア)で分散処理させても良いし、使い方次第では面白いことが出来ると思います。
ソフトウェアでシフト演算をしたい時、かつ、そのCPUにバレルシフタ(ハードウェア)が搭載されていなくて、1,2,4,8ビットシフト演算命令(例えばLSL,LSL2,LSL4,LSL8)を持っている場合を考えてみました。
7ビットシフトしたい時は、以下の様になります。
LSL R0
LSL2 R0
LSL4 R0
レジスタR0を1+2+4ビットシフトしたので、合計で7ビットシフトできました。そうなんですよ、2冪数のシフト演算命令が有れば、その組み合わせで、どんなシフト量でも演算できるんですよね。
で、ふと考えました(以下図)。ハードウェアで16ビットのフルバレルシフタを作ろうとしています。
上図左側の様に、Nビット(Moscoviumの場合はN=16ビット)のフルバレルシフタをハードウェアで作ったのだけど、上図右側の様に、1,2,4,8ビットシフト演算器をカスケードに4個繋げて、各ビット毎に演算した方が、論理規模を縮小できるのではないだろうか?
こちらで設計時に検討した様に、上図左側のNビットバレルシフタだと、16ビット64 to 1セレクタというお化けになるのだけど、上図右側だと、各シフタ(bsft1,2,4,8)が16ビット2 to 1セレクタで済むので、だいぶ小さいハズ。
RTLを変更して、コンパイル(論理合成・配置配線)した結果を以下表に示します。
オプション | LUT数 | F/F数 | 備考 |
−16〜15ビットバレルシフト (従来版、上図左) |
1,946 | 567 | Moscovium ver.0.90 |
−1,0,1ビットシフトのみ | 1,456 | 563 | 比較用 |
−16〜15ビットバレルシフト (改修版、上図右) |
1,596 | 565 | Moscovium ver.0.92以降で採用 |
※バレルシフトのオプションしか変えていないのに、F/F数が微妙に増減しているのは、原因不明です(1@_@)。
上の本文中で示したLUT/F/F数(1843/575個)と比べて、微妙に数が異なっていますが、ちょいちょいRTLの修正をしているからです。多少の差分は無視して、上表で考察を進めます。
以上より、Moscovium ver.0.92以降では、改修版バレルシフタを搭載することにしました。