Cmod A7ボード(FPGA)を使って開発しているオリジナル32ビットCPUコアNihoniumの実装方式として、パイプライン方式を採用してみたいと思います。
前回、全体を組み上げて🏗️、コーディングを完了しました。今回はシミュレーションによる動作検証を実施して、テーマを閉じたいと思います。
CPUセルフテストプログラムを使って動作確認しておきましょう。
今回使用したセルフテストプログラムは以下の3本です。それぞれに必要なI/Oユニットがあるので、適切にVerilogヘッダファイル(npoc113mn0408.vh)の`defineマクロを設定しながらシミュレーションした事を申し添えておきます。
Vivadoのシミュレーションで動作確認して行きます。以下にシミュレーション結果ログのサンプルを示します。
実験サンプル:シミュレーション結果ログ
【mcvm_self.asm】
Test Pass
CPI: 1400/ 1253( 0)= 1117/1000
finish: 75840 [ns]
【niho_self.asm】
Test Pass
CPI: 1586/ 1189( 0)= 1333/1000
finish: 83280 [ns]
【niho_self_b.asm】
Test Pass
CPI: 642/ 317( 0)= 2025/1000
finish: 45520 [ns]
全3本のプログラムがパス(合格)しました。このプログラム、検証カバレッジとしてはスカスカなのですが、Nihoniumの全命令を余さず実装してセルフテストしていますので、それなりの安心材料では、あります。
円周率の計算プログラムを使って、より実践に近いプログラムで動作確認しておこうと思います。12桁ほどの円周率をVivadoのシミュレーションで計算させ、実行時間を比較してみましょう。プログラム(calc_pi.asm)先頭付近の設定を以下の様に変更してからアセンブルして使います。
プログラムの設定:
def s,"" // simulation="" / fpga="#"
def k,"" // use Klingenstierna if ""
def m,"#" // use Machin if ""
# Moscovium: mc="" n0="#" n1="#"
# Nihonium (NH=0): mc="" n0="" n1="#"
# Nihonium (NH=1): mc="#" n0="#" n1=""
def mc,"#" // for Moscovium if ""
def n0,"#" // for Nihonium (NH=0) if ""
def n1,"" // for Nihonium (NH=1) if ""
以下にシミュレーション結果ログを示します。
実験サンプル:シミュレーション結果ログ
RDY
OK: calc_pi ver.1.10
--------
OK+ start calculation
OK+ Klingenstierna's formula
OK+ pi=3.
1415
9265
3591
OK+ digits= 12 (size= 4)
OK: pi time[us]=0x00000160
--------
Test Pass
CPI: 11285/ 6903( 0)= 1634/1000
finish: 471240 [ns]
小数点以下12桁の指定で計算しました。演算結果は、π=3.141592653591ということで、小数点以下10桁まで正しく計算できています。このプログラムは原理上、指定桁より下位桁の計算を実施しないため、下位桁からの桁上がりが無い分、最下位数桁は正しくありません。
計算結果としては、ステートマシン方式のNihonium等と同じ値であると確認できたので、演算内容に相違は在りません。
ステートマシン方式Nihoniumに比べて、パイプライン方式Nihonium-PIは、
Nihonium-PIのパフォーマンスを活かすため、WBとEXのレジスタ競合を解消したプログラムを作成しました。以下にリンクしておきます。
競合解消プログラム:calc_pi_pi.asm
競合の回避方法については、以下図およびリンクを参照してください。

なお、プログラムの実行結果が変わらない様に命令の実行順番を少し入れ替えただけなので、上のプログラムをNihoniumで実行しても同じ結果が得られます。実行時間に関しては、Nihoniumで実行しても元のプログラムと全く変わりませんが、Nihonium-PIで実行すると高速化されているはずです。以下の結果で確認しましょう。
ステートマシン方式Nihonium、スーパスケイラ版Nihonium-SS、パイプライン方式Nihonium-PIに関して、各々シミュレーションしてデータを取得し、以下表にまとめてみました。
| Core | Program | Time[ns] | CPI | Memo | |
| Nihonium | calc_pi.asm | 459,040 | ×1.02 | 1.59 | |
| Nihonium-PI | calc_pi.asm | 471,240 | ×1.05 | 1.63 | |
| calc_pi_pi.asm | 449,880 | ×1.00 | 1.56 | WB×EX競合解消版プログラム | |
| Nihonium-SS | calc_pi.asm | 387,000 | ×0.86 | 1.36 | |
考察:
NPOC113MN0408をベースに、CPUコアだけをNihonium/-SS/-PIに変更しながら、STA結果と、CPU単体の論理規模を比較した表を以下に示します。
| Core |
fCPU [MHz] |
STA | Logic | Memo | |||
| Setup | Hold | fCPU’ | LUT | FF | |||
| Nihonium | 25 | 8.008 | 0.057 | 31.3 | 3,527 | 934 | |
| Nihonium-PI | 25 | 9.778 | 0.032 | 33.1 | 4,254 | 1,119 | Pipeline 4 stages |
| Nihonium-SS | 25 | 2.049 | 0.069 | 26.3 | 8,112 | 1,365 | Super Scaler |
| Nihonium | 40 | −0.425 | 0.049 | 39.3 | 3,608 | 934 | STA error |
| Nihonium-PI | 40 | 0.503 | 0.078 | 40.8 | 4,304 | 1,119 | MET |
| Nihonium-SS | 40 | −7.508 | 0.059 | 30.8 | 8,777 | 1,365 | STA error |
※上表は、RTLから論理合成・配置配線した結果。
考察:
すっごく苦労してサイクル性能を上げたスーパスケイラより、サクッとパイプライン方式で実装した方が費用対効果は大きかった、と言う身も蓋も無い結論にガックシです……。ともあれ、Nihoniumをパイプライン方式で実装する試みは、これにて完結です。


