Shrike-Liteを入手した時、ボード上に搭載されたFPGA(SLG47910)へユーザ論理を書き込んでおき、MCU(RP2040)とFPGA間で通信する事で、FPGA上に書き込んだユーザ論理を制御しようと考えました(以下記事を参照)。
「#38-9 週刊「スタックマシンを作る」創刊号」
最初の発想(上の記事)は色々あって破綻したので、今回はそのテーマの最挑戦に当たります。
破綻した最初の発想はどうだったか?と言うと、下図の通り、FPGAに極小のCPUを搭載して、通信ユニット(下図ではUART)と、肝心なユーザ論理(下図のI/O unitに相当)との橋渡し🥢をするという物でした。

この方式の長所は、MCU(RP2040)とのインターフェイスを柔軟に変更できるところです。
例えば、上図ではUARTでインターフェイスする形式ですが、I2Cスレーブでも何でも通信仕様を選択可能です。また、通信でやり取りするコマンド仕様なども、CPUに実行させるプログラム次第で、いくらでもカスタマイズすることができます。
柔軟性があり、賢明な解でした。
前節の発想を実現すべく、「小さいことが正義」として、オリジナル極小CPUコアSamariumを設計しました。残念ながら、想定以上にFPGAの論理規模が小さかったため、Samariumですら大き過ぎ、Shrike-LiteのFPGAにギリギリ載せるのがやっとでした。
前節で示した図のようなシステムを構築しようとして、CPUだけでFPGAの論理規模を使い切ってしまったので、他に通信ユニットやユーザ論理を搭載する余地が残りませんでした。
まあ、それは良いのです。最初から小容量のFPGAだと判っていたので、大きすぎて載らない可能性もあると思いながら、挑戦してみたい気持ちが抑えられなかっただけなのですから。発想は破綻しましたが、相応の結果が得られたので満足しています。
さて、「最初の発想」の破綻から見えてきた課題は以下の二点でした。
1)は、以下記事にて解決済みです。
「#39-5 Samariumを組み込む」
今回のテーマは2)を解決して、先へ進む事です。たとえ失敗しても、そこから学び、次へつなげるのが一番大事なことでしょう?
失敗から学んだことは、Shrike-LiteのFPGAは思いのほか小容量だという事ですね。CPUを搭載するのは、とても無理なので、もっと単純で簡単な機構によってFPGA内のI/Oユニットへアクセス可能な方法を考える必要がありました。
そこで目を付けたのはSPI通信インターフェイスです。改めて下図の様な系を考えました。

CPUが大きくて載らないなら、上図の様にSPIスレーブ通信を受けて、Moscoviumマイコンのメモリバスを介し、I/Oレジスタへアクセスできる様なブリッジ回路を設計すれば良いと考えました。SPIスレーブ⇔メモリバスブリッジ回路ならば、CPUに比べて遥かに小さく作ることができ、「小容量のFPGAにも問題なく搭載可能なはず」と、言うのが発想の趣旨です。
SPI通信を選択したのには、もう一つ理由があります。
元々、Shrike-Liteでは、MCU(RP2040)からオンボードのFPGA(SLG47910)へ論理回路を書き込むため、SPI端子が接続されているのです。FPGAへ論理回路を書き込んだ後、通信に使ったSPIライブラリを拝借して、そのままFPGAの制御に転用しようとする意図がありました。
なお、RP2040とFPGA間のインターフェイスには、専用のEN,PWR信号があり、この組み合わせで論理回路の書き込みモードと、通常動作モードなどを切り替えています。書き込みモードの時に使ったFPGA側SPI通信端子は、ユーザモードでは解放されて通常のI/Oポートとして割り当て可能なので、上の様な使い回しが可能、な、はずです(想像、実動作は未確認……)。
ここからは、SPIスレーブ⇔メモリバスブリッジSPIBUSユニットの設計を進めて行きます。
以下にSPIBUSユニットのブロック図を示し、解説を続けます。


I/Oユニットの中には、割り込み要求によってCPUに状態を通知するものも多く存在します。この様な割り込み要求も、Shrike-LiteのMCU(RP2040)へ出力しておくと、I/Oユニットの制御が容易になるでしょう。
前節で解説した通り、SPIBUSユニットはCPU2に置き換わる形なので、CPU2に対する割り込み要求IRQ2信号(下図およびリンク)を、そのままFPGAの外部端子に出力すれば良いと考えました。

FPGA外部のMCU(Shrike-LiteのRP2040)が、他のモジュール(複数)からの割り込みを受け取る場合も想定しておくべきです。その様な時、多くの市販モジュールが採用している方式は、オープンドレインによる割り込み信号の集約です(下図)。

複数モジュールからの割り込み要求(上図ではIRQ1〜IRQ3)が、オープンドレインによって1本のIRQ_Nに集約されていることが解ります。なお、上図に於いて各モジュールの割り込み要求IRQ1〜IRQ3は正論理なのに対して、集約されたIRQ_Nは負論理と、論理が反転している事には留意してください。
これに倣って、FPGAからの出力も負論理かつオープンドレイン出力とします。オープンドレイン出力のVerilog-HDL記述は、以下の通りです。
assign spis_irq_n=(irq2)? 1'b0: 1'bz;
引き続き、以下の通りSPIインターフェイスの仕様を確定しておきます。
SPIインターフェイス仕様:
SPI通信は4本ものI/Oポートを占有するので、やっぱり、あまり好かんな〜(※)。信号線2本でバス接続できるI2Cの方が好きです。ただ、SPIは通信周波数を柔軟かつ高速に設定できるし、何より回路が簡単(シフトレジスタで完結可能)なので、小容量FPGAをターゲットにする場合には有利な通信仕様だと思います。それがSPI通信を選択した所以です。
※SPI通信には、MOSI/MISOが双方向の信号線として多重化されている物や、コマンド・データストローブ信号が追加されている物、クロックモードやシフトレジスタのビット数に至るまで、数多の変種が存在する事も、好きになれない理由の一つです。
SPI通信仕様も策定しておきます。
SPI通信仕様:
読み出しアクセスの場合、ダミーデータ8ビットの通信時間を使って、メモリバスから読み出しアクセスを実行しなくてはなりません。
前節で仕様策定した読み出しアクセスに於いて、ダミーデータ8ビット通信中に、メモリバスからの読み出しが終了している必要があります。このタイミング(時間)が一番クリティカルで、SPI通信周波数の上限を決める主要因です。
ダミーデータ通信中の回路動作:
上に洗い出した処理時間が、ダミーデータ通信中のSCK×8サイクルに収まればOKなので、以下の計算で最大通信周波数を概算することができます。
上式より、システムクロックfclk=24MHz、N=0、M=0を見込む場合、fSCK<<36MHzで動作可能なはずです(無保証)。
以上をもって、詳細設計が完了しました。次回、全体をまとめ上げて、完成したいと思います。


