公開日:2026/05/30
title.png

39th Season


#39-5 Samariumを組み込む

 Shrike-LiteのFPGAに載せて使おうと設計したオリジナル極小CPUコアSamariumに関しては、Shrike-Liteの小さなFPGAに搭載するには論理規模が大きくて活用できず、宙に浮いていました。
 16ビットデータパスとは言え、約450LUTと言う論理規模は武器ですし、折角設計したのに勿体ないので、Cmod A7ボード(FPGA)を使って開発しているオリジナル16ビットCPUコアMoscoviumシリーズを使ったマイコンに組み入れて使いたいと思います。

課題

 Moscoviumシリーズはオブジェクトコード上位互換なので、8ビットのTennessine、16ビットのMoscovium、32ビットのNihoniumまで、同じプログラム(オブジェクトコード)を実行させることができます(演算結果が8ビット以下の場合に限る)。それ故に、非対称デュアルコアマイコンでも2つのCPUが同じ命令ROM、すなわち同じプログラムを参照していました。
 そこへSamariumを横並びでCPUの品揃えに追加するのは否定的です。MoscoviumシリーズとSamariumシリーズでは、命令コードに互換性がありませんから。

  組み込み前提条件1)

 言い換えると、MoscoviumシリーズとSamariumシリーズを混合した非対称並列処理(AMP;Asymmetric Multi-Processing)型のマルチコアマイコンは作らない、と言う事になります。これは大きな制約では無いと考えられます。

ブートローダ

 命令コードが異なるので、ブートローダ👢はSamariumの命令コード版を用意する必要があります。以下にSamarium用のブートローダプログラムをリンクしておきます。インターフェイスや機能(即ち使い勝手)については、Moscoviumシリーズのブートローダと互換としてあります。

  Samarium用ブートローダ:mcoc_boot_sm.asm

 Samarium用アセンブラでアセンブルすると、組み合わせ論理ROMのRTLが出力されますので、それを組み込みました。
 これまでに、8ビットのTennessineにも専用のブートローダが必要だったので、都合、Moscovium/Nihonium用(mcoc_boot)、Tennessine用(mcoc_boot_ts)、Samarium用(mcoc_boot_sm)、3種類のブートローダから、コンパイルオプションに従って必要な物を選択することになります。

互換性

 「命令コードに互換性が無い」というのが、前節の課題でした。命令コード以外の仕様に関しては、MoscoviumシリーズとSamariumシリーズは多くの点で互換性を有しています。

  相互に互換性のある仕様:

 周辺回路のほとんどが、MoscoviumシリーズとSamariumシリーズで共通して使用可能なのです。新規CPUシリーズを組み込むと言っても、「周辺回路をごっそり作り直す」、みたいな破滅的な状況は回避できるはずです。

  組み込み前提条件2)

命令ROMと命令RAM

 Samariumは8ビット命令コードです。CPUコアの論理規模を最小化するため、フェッチバスが8ビット幅と言う仕様になっています。
 一方、Moscovium用の命令ROMは現在16ビット幅または32ビット幅なので、命令ROMと命令RAMだけは8ビットフェッチに対応して改定が必要となります。この改定に伴い、フェッチバスコマンドfcmdにバイトフェッチコマンドfcmd[2](別名fcmdb)を追加しました。

  フェッチバスコマンドfcmd仕様:

 また、今後の開発環境整備や拡張を鑑み、Samariumシリーズでは命令RAM(I-RAM、4Kバイト)の搭載を必須とすることに決めました。
 命令RAMはCPUからフェッチ可能であると共に、通常のRAMとしても使用可能なので、応用が利くことが理由の1つです。また、通常のRAMユニットは最小の容量が8Kバイトで少し冗長気味に大きいことも、I-RAMを選択する理由として挙げられます。

 ただし、通常のRAMを非搭載(0Kバイト)とするのは、ソフトウェア的にも影響が大きいため、分散RAMを使って小容量のRAM(〜256バイトを想定)を搭載する事とします。

Samariumの改定

スタックサイズ

 当初の設計時点でSamariumの内蔵スタックサイズは、RTLのコンパイルオプションで調整可能な様にしてありました。スタックは読み出しレイテンシ0、シングルポートRAM、RTLによる分散RAM実装です。なので「スタックサイズによって論理規模が違ってくるはず」と言う予想に基づいて、コンパイルオプションとしました。
 しかし、実際にShrike-Liteの時に試した範囲では、スタックサイズを大きくしても必ずしも論理規模が増加しないという不思議な現象が観測されました。どうも通常論理と異なり、分散RAM用のLUT素子が相当効率的に効いている様なのです。何しろ、分散RAMを論理合成するために特化されたLUT素子ですから、「然も有りなん」と言う感じです。

 以下、スタックサイズを変化させながら、分散RAM用LUT数を調べた表を示します。

Samarium 分散RAM(内数) 備考
スタックサイズ LUT数 FF数 バイト数 LUT数
8 440 84 16 16 64段までLUT数に変化なし。
16 440 84 32 16
32 440 84 64 16
64 440 84 128 16
96 475 84 192 32 非2冪数だから?(※)
128 457 84 256 32  
256 490 84 512 64  
512 615 84 1,024 128  
1,024 753 84 2,048 256  

 Xilinx Vivadoを使い、CPU単体で論理合成した結果です。分散RAM用のLUT数は、SamariumのLUT数の内数です。なお、スタックは16ビット幅なので、スタックサイズ1段当たり2バイトの分散RAMを要します。8段なら16バイトと言った具合です。
 上表より、スタック64段(128バイト)まではLUT数に変化有りませんでした。分散RAMが推論された場合に発生する「基本料金」でしょうか?その後は、64段(128バイト)毎に分散RAM用LUT数が16LUTづつ増加する「従量課金」と見て良い様です。
 以下にまとめます。

  まとめ:

※96段のLUT数が128段のLUT数と逆転したのは、分散RAM用LUTではなく、通常の論理回路用LUT数が増えたため。非2冪数だったので、恐らく大小比較回路等、通常論理回路の増大が原因と推定。

 Cmod A7ボードに組み込んで活用するにしても、Samariumの魅力は論理規模の小ささだと思っています。よって、論理規模が増大しない範囲で、最大のスタックサイズ64段を標準サイズと決めます。
 64段は、当初想定していたサイズの中でも上限に近いです。しかし64段未満に設定しても結局、論理規模に変化無いので、「大は小を兼ねる」と言う事で良いでしょう。
 また、スタックサイズの異なる構成があり得るのは、何かとソフトウェアへの負担が大きくなる恐れがあるので、余程の差し迫った事情が生じない限り、64段一本に絞る事としました。

符号化即値

 現時点で、符号化即値psei命令には、未割り当ての符号が存在しています。Moscoviumマイコンに組み込むに当たり、有効な符合化即値を追加する検討を進めて行きます。

  符号化即値の検討:

 懸念事項としては、Moscoviumマイコンと言う特定の環境(メモリマップ)に合わせて、「CPUの仕様」を策定して良い物か?慎重に吟味する必要がある事です。
 符号化即値は正に、このような使用頻度の高い定数へ対処するための機能ですから、未割り当てのまま放置するのは、逆に勿体ない事だと思いました。「Moscoviumマイコンに組み込む」と言う、今回のテーマで拡張するのが、一番ふさわしいと考えられます。

 ここまで、とても良い考えだと思ったのですが……。上の検討に則してRTLを改定後、論理合成して見たところ、50LUTもの増加が認められました!「小さいことが正義」なSamariumで、50LUT(約10%)もの論理増加は許容できません。
 Samarium以外のCPUだったら、迷わず採用していたと思います。パフォーマンスの向上が期待できる良い方法ですから……。ここは涙を呑んで、不採用と決めます。

CPU_STS信号割り当て

 符号化即値psei命令のCPU_STS符号で参照される値は、Samariumコアの最上位モジュール記述のインターフェイス信号cpu_sts[15:0]に入力された値です。従って、「psei CPU_STS」によってスタックへ積まれるデータは実装依存と、なります。
 MoscoviumマイコンへSamariumを組み込むに当たり、cpu_sts[15:0]への信号割り当てを以下表の通りとします。

フィールド 割り当て 意味
cpu_sts[15:7] 予約(未割り当て)。
cpu_sts[6] sama_sts_hfpu H-FPUが接続されていれば1が読み出せる。
cpu_sts[5] sama_sts_divc DIVC16が接続されていれば1が読み出せる。
cpu_sts[4] sama_sts_mulc MULC16が接続されていれば1が読み出せる。
cpu_sts[3:0] sama_sts_id_0〜15 多コア版の時、CPU ID番号が読み出される。

 今回のリリースでは多コア版に対応していないため、cpu_sts[3:0]も将来の拡張を前提とした「予約」です。sama_sts_hfpu等の識別子は、アセンブラのインクルードファイル(mcoc115.incl)で定義されています。

デザイン

 追加したコンパイルオプション(`defineマクロ)は、MCOC_CORE_SMです。このマクロを設定しておくと、CPUとしてSamariumコアが選択されます。

 サンプルのマイコンですが、Samariumコアが小さいことはすでに検証済みで判っています。周辺I/Oユニットなどを絞った最小構成のマイコンを作っても、結論は見えている訳です。

  「うんうん、小さいね」と、なるだけの事。

 結果の見えている事を改めて確認する意味はありませんので、逆に、すごく贅沢な構成にしてみようと思います(以下の通り)。

 こちらの型名規則に従うと、SMOC062TF66L8と、なりました。設計データはGitHubで提供しています。以下バナーよりアクセスしてください。

btn_moscovium.png

 デザイン(回路)をCmod A7ボードに書き込む手順については、こちらをご確認ください。

コンパイル

 SMOC062TF66L8マイコンのコンパイル(論理合成・配置配線)結果を以下に示します。

  コンパイル結果:

 浮動小数演算可能な極小CPUコアは、いかがでしょうか?ちなみに、コプロセッサとしてCPUの外部に接続した半精度浮動小数演算ユニットH-FPUは約680LUT、Samariumコアは約450LUTと言う事で、CPUの方がコプロセッサより小さいです(1^_^;)v。

小さい実験

シミュレーション

 まずはシミュレーションで確認してみます。以下にSamarium用のCPUセルフテストプログラムをリンクしておきます。

  Samariumセルフテストプログラム:sama_self.asm

 具体的なアセンブル方法や、Vivadoプロジェクトへの反映方法、ブートローダを使ったMoscoviumマイコン(FPGA上)へのプログラム転送方法に関しては、こちらを参照してください。

 シミュレーション結果は以下の通りです。

  実験サンプル:シミュレーション結果ログ
  Test Pass
  CPI: 802/ 655( 0)= 1224/1000
  STK_PTR: 5 (MAX)
  finish: 51920 [ns]

 Pass/Failしか返さないので、面白みのないシミュレーションログですが、検証結果としては合格(Pass)です。
 なお、Samariumコアを使ったシミュレーションでは、シミュレーション中に到達した、最大のスタック深度(STK_PTR値)が表示されます。上の例だと、最大で5段使用したと報告されています。Samariumの内蔵スタックサイズは64段ですので、まだまだ余裕があると解ります。

FPGAボード

 Cmod A7ボード(FPGA)で動作確認しておきましょう。Shrike-Liteの時に作成した、LEDを三三七拍子で光らせるプログラムを以下にリンクします。

  Lチカプログラム:shrk_blink_337.asm

 一部、動作周波数などの引数を変更する必要があります。

  Shrike-Lite用 → Cmod A7ボード用、変更点:
  asm "shrk_blink_337.v"
  equ fcpu_go,12_000_000  // [Hz]
  equ led_on,0x01  // LED ON
  equ led_off,0x00  // LED OFF

    ↓ (変更)
  asm "mcoc_irom.mem"
  equ fcpu_go,24_000_000  // [Hz]
  equ led_on,0x06  // LED ON
  equ led_off,0x07  // LED OFF


 上に示した変更の後、アセンブルしてください。Verilog-HDLのMEMファイルが出力されるので、FPGAに書き込んだSamariumマイコンブートモードで転送して実行してみました。



※別な方法で撮影した時の動画(使い回し)ですが、見た目は、ほとんど変わらないと思いますm(1^^)m。

 Samarium用のブートモード(従ってブートローダプログラム)が正常に機能する事、Samariumが想定通りに動作する事、等が確認できました。合格です。


 ひとまず、SamariumコアをMoscoviumマイコンに組み込みました。今後期待しているのは、多コアへの対応で、コア数をいくつまで増加できるか?なのですが、多コア対応は別な機会に。


btn_arduino.png

btn_prev.png btn_next.png

home