Cmod A7ボード(FPGA)を使って、オリジナル16ビットCPUコアMoscoviumの開発を進めています。
前回、減量したMoscovium-BSコアを設計しました。今回は引き続き、除算コプロセッサDIVC32を減量👗して行きます。
Blockly for Moscovium開発環境(以下単に、Blocklyと記載する)では、四則演算にCPUの命令を使用しています。つまり、割り算を実行したければ、除算命令が機能する必要があります。Moscoviumは除算器を内蔵していないため、外付けのコプロセッサで除算命令を実行しています。現在存在する除算コプロセッサは、32ビット除算に対応したDIVC32です。
前回考察にて、Moscovium-BSの様に論理を削減して減量(スリム化)を図る上では、除算コプロセッサの減量も必要だと解りました。課題は「Blocklyで開発できる小さなCPUを作ること」ですので、以下のコンセプトに従って、除算コプロセッサDIVC32も減量したいと思います。
つまり、由緒正しき(?)ステップ除算方式を採用します。
16ビットのステップ除算器なので、16÷16ビット除算だけで16ステップ(サイクル)かかります。その他、CPU ⇔ コプロセッサ間のデータ通信(被除数、除数、商、剰余の転送)サイクルが追加で必要なので、除算命令としての実行サイクル数は、18〜22サイクルと、なります。
DIVC32に比べて演算速度は、がた落ちしますが、今回の減量では除算命令が使える事と、論理規模の減量が最優先なので、実行速度低下には目を瞑ります。
※それでも、ソフトウェアでシフト除算サブルーチンを作って使うよりは高速なので、存在意義は十分にあります。
16÷16ビットステップ除算器をDIVC16コプロセッサとして設計してみます。以下にブロック図を示し、各ブロックの動作について解説を続けます。
教科書通りのステップ除算器です。どの程度の論理規模で仕上がるでしょうか?
Moscoviumと除算コプロセッサの減量が完了したので、CPUとコプロセッサの組み合わせで結果を検証したのが、以下表です。
論理規模比較 | LUT数 | FF数 | 備考 | |
Moscovium | 2,640 | 816 | 通常版。 | |
CORE | 2,000 | 630 | 汎用レジスタバンク4組。 | |
MULC16 | 50 | 16 | 乗算器マクロ1個使用。 | |
DIVC32 | 590 | 170 | ハイブリッド型。 | |
Moscovium-BS | 1,790 | 436 | Blocklyスリム版。 | |
CORE | 1,600 | 360 | 汎用レジスタバンク2組。 | |
MULC16 | 50 | 16 | 乗算器マクロ1個使用。 | |
DIVC16 | 140 | 60 | ステップ型。 |
まず注目すべきは、DIVC16とDIVC32の論理規模です。DIVC16はDIVC32の1/4以下のLUT数に収まりました。Goodです。
その除算コプロセッサを含んだCPU全体に目を移すと、Blocklyスリム版Moscovium-BSは乗除算コプロセッサ込みで1,800LUTを下回ることができました。これまでのMoscovium(通常版)と比較して、LUT数で約32%、FF数で約47%の減量に成功です。
なお、特に触れて来ませんでしたが、乗算コプロセッサMULC16に関しては、FPGAの乗算器マクロが推論されて終了のため、上表の通りLUT数は小さく、減量余地がありませんでした。
Moscovium-BSコアと、16ビット除算コプロセッサDIVC16を搭載したマイコンとして、MBOC115BY1608を起こしました。型名規則はこちらです。
DIVC16に関しては、以下コンパイルオプションの組み合わせで選択されるようにしてあります。
`define MCOC_CORE_MCBS // define: Blocklyスリム版
//`define MCVM_COPR_NODIV // undefine: 除算コプロセッサあり
Cmod A7ボード用Moscoviumマイコンの設計データ(Vivadoプロジェクト)は、GitHubにて配布しております。以下バナーよりアクセスしてください。
デザイン(回路)をCmod A7ボードに書き込む手順については、こちらをご確認ください。
Moscovium-BS+DIVC16を搭載したMBOC115BY1608を、コンパイル(論理合成・配置配線)してみました。結果は以下の通りです。
コンパイル結果:
今回は、Cmod A7ボード(FPGA)へは書き込まず、Vivadoの論理シミュレーションで決着します。シミュレーションの実行手順については、こちらをご参照ください。
まずはCPU判定プログラムを使って、Moscovium-BSコアを識別できるかどうか試しておきます。新たにMoscovium-BSに対応したCPU判定プログラムを以下にリンクします。
CPU判定プログラム:mcoc_cpu_recg.asm
状態レジスタsrのML,DR,SD,NHビットに1を書き込む事で、CPU種を判定するプログラムです。詳細は、こちらの記事を改定しておきましたので、ご参照ください。
シミュレーションしてみましょう。
実験サンプル:シミュレーション結果ログ
CPU#0: Moscovium-BS core
Test Pass
CPI: 296/ 219( 0)= 1351/1000
finish: 31680 ns
正しく「Moscovium-BS core」が検出されました。良い様です。
従来のMoscovium用セルフテストプログラムを使い、アセンブルオプションで、スリム版に合わせてカスタマイズできる様に改定しました。
equ mcvm_has_mulc,1 // 0 for `define MCVM_COPR_NOMUL
equ mcvm_has_divc,1 // 0 for `define MCVM_COPR_NODIV
equ mcvm_has_divl,0 // 0 for `define MCVM_COPR_NODIV or Nh
ここまでは、既存のオプション設定で対応できます。32ビット除算命令の回避は、mcvm_has_divl=0にて可能です。
equ mcvm_blky_slim,1 // 1 for `define MCOC_CORE_MCBS
新規追加したオプションmcvm_blky_slim=1による改定内容は、以下の通りです。
改定版プログラムを以下にリンクしておきます。
CPUセルフテストプログラム:mcvm_self.asm
シミュレーションしてみましょう。
実験サンプル:シミュレーション結果ログ
Test Pass
CPI: 1388/ 1194( 0)= 1162/1000
finish: 75360 ns
淡々と全命令をセルフテストして結果だけが表示される簡単なテストなので、面白みは無いですが、上ログの通りテストはパス(成功)しました。
ランダムに発生した被除数、除数と、商および剰余の期待値テーブルを作り、自己テストプログラムで検証します。
除算ロードテストプログラム:mcvm_ldt_divsr.asm
こちら「#16-3 除算器の設計」で作成したロードテストプログラムと同等の内容です。元のプログラムでは、SrレジスタのDRビットを設定していましたが、DRビット廃止に伴い、divsr命令に置換しました。シミュレーション結果を以下に示します。
実験サンプル:シミュレーション結果ログ
f849 e086 0000 f849 0000 f849
189b 727a 0000 189b 0000 189b
a535 fa2a 000f fcbf 000f fcbf
f2e7 6708 0000 f2e7 0000 f2e7
:
: (中略)
:
6ef8 d87d fffe 1ff2 fffe 1ff2
6674 5c3f 0001 0a35 0001 0a35
8561 09fd fff4 fd3d fff4 fd3d
3cd5 ef4d fffd 0abc fffd 0abc
Test Pass
CPI: 13585/ 5916( 0)= 2296/1000
finish: 563240 ns
表示された16進数値の意味は、被除数,除数,商(期待値),剰余(期待値),商(計算値),剰余(計算値)、です。従って、中央と右側2組の16進数値がそれぞれ一致していれば、期待値通りの計算結果だったと解ります。期待値との照合はプログラムでセルフテストしており、不一致した時点で失敗して「Test Fail」と、なりますので、最後まで実行されて「Test Pass」が表示されたら、全パタン成功しています。
リンクしたプログラムでは256パタンですが、乱数を変えながら数1,000パタンのロードテストを実施し、全て成功を確認しました。
Moscoviumシリーズは、命令コード互換のシリーズ故、CPUコアに新しい命令や機能を追加しようとすると、全CPUコアへの追加が必要となって作業がN倍化します。今回Moscovium-BSコアを追加してしまったため、Nが+1増加してしまいました(1^^;)。