公開日:2026/04/18
title.png

39th Season


#39-1 週刊「スタックマシンを作る」第三号

 新たに、スタックマシンと呼ばれる方式の、新規CPUコアを設計している所です。
 本HPにて、Cmod A7ボード(FPGA)を使って開発しているオリジナル16ビットCPUコアMoscoviumは汎用レジスタを使って処理を進めるCPUなので、汎用レジスタマシンと呼ばれます。スタックマシンは汎用レジスタマシンとは異なる考え方に基づくCPU方式です。

 詳細設計を進め、シミュレーションによる動作確認まで到達したいと思います。

Samariumの設計

ブロック図

 以下にSamariumコアのブロック図を示して、解説を続けます。

a391_cpublk.png

  解説:

内蔵スタック

 汎用レジスタマシンがレジスタファイルを内蔵しているのに対して、スタックマシンはスタックを内蔵しています。
 スタックマシンが内蔵するスタックは、Moscovium等の汎用レジスタマシンがメモリ上に確保するスタックとは少し性格が異なります。スタックマシンの内蔵スタックは、汎用レジスタマシンの汎用レジスタに相当するからです。勿論その他にも、サブルーチン分岐する時の復帰アドレス退避、サブルーチン内の再帰的な汎用レジスタとしても使用されます。

 スタックに局所変数領域を確保する等、汎用レジスタマシンに於ける使用方法は想定しません。よって、内蔵スタックにキロバイト級のメモリを割り当てても使いきれません。スタックは、汎用レジスタ数×サブルーチンの再帰深度、程度のサイズがあれば良いと考えられます。
 以下に、いくつかのCPUコア(汎用レジスタマシン)の汎用レジスタ数をまとめて検討を進めます。

CPUコア 汎用レジスタ数
Moscovium 8個×4バンク
Nihonium 8個×2バンク
SuperH 16個
ARM 16個
MIPS 32個

 サブルーチン呼び出し深度に注意しながらプログラミングすれば、最小8段くらいのスタックがあれば、実用的に使用可能でしょう。最大サイズとしては、32〜64段程を想定して良いのではないでしょうか?念のため、手元のRTLでは、スタックサイズをコンパイルオプションで指定可能としておきたいと思います。
 また、データパスのビット幅16ビットに合わせて、スタックのデータ幅も16ビットです。

エンプティ上昇型

 スタックには、色々な方式が存在しますが、内蔵スタックについては「エンプティ上昇型」とします。

  エンプティ上昇型スタック:

 当然ですが、スタックをオーバランやアンダランさせない様に使う事は大前提です(ソフトウェア責任)。

  例)スタック残量の算出

  例)アンダラン検出

 いずれも、ソフトウェアデバッグ時に適用可能な技術です。

スタックの実装方法

 内蔵スタックを、同一アドレスの同時読み出し/書き込み可能なシングルポートRAMで実装する事とします。読み出しと書き込みを同時に1サイクルで実行可能なので、サイクル性能の向上に寄与します。かつ、デコーダなどの論理回路が1系統で済むため、最小の論理規模で実装できる事が特長です。

 更に演算高速化を目指すなら、読み出し2系統とすれば、add命令等の実行サイクル数を短縮する事が可能です。しかし、ここまで対応してしまうと、「実用的な処理速度の確保」と言う範囲を超えてしまいます。Samariumコアは「小さいことが正義」なので、実行速度より論理規模縮小が第一優先であり、不採用です。

 以上より、サイズ(スタック段数)も大きくないので、RTLによる論理合成可能な記述で良く、精々、分散RAMを推論させる程度の実装で良いでしょう。

論理検証

 Samariumを設計する動機となった、Shrike-Liteに於けるRP2040とのインターフェイスに関しては、まだ準備不足なので、まずSamarium単体で動作を確認して行こうと思います。

プログラム

 SamariumのソフトウェアでLEDを点滅させる、所謂Lチカで動作確認をしたいと思います。しかし、この時点までにShrike-LiteのFPGAを使って2回ほどハードウェアによるLチカを試行済みです。

  1回目: Shrike-Lite GitHubのデータを使用

  2回目: 独自に設計したLチカ回路(RTL)の移植

 単純な点滅パタンではソフトウェアで光らせる旨味が無いので、ハードウェアで設計するのはちょっと面倒臭そうな三三七拍子で光らせるプログラムを組んでみました。以下にリンクしておきます。

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

 Samariumアセンブラを実行してアセンブルするとVerilog-HDLの組み合わせ論理ROM形式で出力されるため、そのままShrike-LiteのFPGAにインスタンスして使用可能です。
 Samarium本体と、組み合わせ論理ROMを組み上げた最上位モジュールは以下となります。

  最上位モジュール:main.v

シミュレーション確認

 Go Configureで、Samarium動作検証用の新規プロジェクトを作成しました。まずはシミュレーションでRTLの動作を確認して行きましょう。
 最上位モジュール(main.v)の「`define SIMULATION」を有効化(手動でコメントを外)して、シミュレーションを実行しました。取得した波形図を以下に示します。

a391_led337.png

 「三三七拍子」って、ご存知ですよね?上の波形から、三三七拍子のリズムで点滅する様子が読み取れましたか?出力信号ledに注目して見てください。シミュレーションでは、想定通りにLEDが点滅することを確認できました。

 なお、上図最下行の信号sptr[15:0]はスタックポインタです。これを「Analog ⇒ Step」表示にすることで、シミュレーション中、アンダランやオーバランしない事を確認しながら検証しました。上図の通り、スタックポインタが規則的に上下しながら、一定の範囲内で処理が進んでいます。正しく、問題ないプログラムの例です。
 もし、プログラムミスなどで、pushとpopの回数を間違えていた場合、スタックポインタが一方的に上昇したり、下降したりする波形となって、いずれアンダランもしくはオーバランに至ります。

 この最上位モジュール(main.v)では、シミュレーションモードを示す信号をCPU_STSの第8ビット(0x0100)に割り当ててあり、Samariumのソフトウェアでdelayサブルーチンのループ回数を短縮しました(以下、該当コード抜粋)。

  コード例:
  // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  // for simulation
  and CPU_STS,0x0100  // シミュレーションモード(0x0100)か?
  njmp sim_not_enb    // シミュレーションモード以外なら分岐。
  lsl     // シミュレーションモードだったら、
  cend     // 7ビット右シフトして、
  and 0xff  // ループ時間を1/128に短縮。
  sim_not_enb:
  // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


 ソフトウェアで短縮動作させているだけなので、FPGAに書き込むハードウェアとしては、一切変更せずにシミュレーションできています。少なくとも論理回路としては、FPGAに書き込む回路と全く同じ回路でシミュレーション動作が確認できたという事です。ここ大事、テストに出ますよ。


 詳細設計で課題にぶち当たると、試行錯誤を繰り返し、頭を悩ます事もありますが、シミュレーションで動作確認できたら一山越えました。後は実機(FPGA)へ書き込んで、実動作を確認できたら完成です。次回最終号です。


btn_arduino.png

btn_prev.png btn_next.png

home