公開日:2026/03/21
title.png

38th Season


#38-7 Nihoniumパイプライン実装(Nana)

 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

 競合の回避方法については、以下図およびリンクを参照してください。

a37a_pipe_wbea5.png

 なお、プログラムの実行結果が変わらない様に命令の実行順番を少し入れ替えただけなので、上のプログラムを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  

  考察:

CPUの論理合成・配置配線結果

 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をパイプライン方式で実装する試みは、これにて完結です。


btn_arduino.png

btn_prev.png btn_next.png

home