はじめに
RasPi から FPGA に、簡単にコンフィグデータをダウンロードする方法を説明します。
JTAG でやってもいいのですが、手間とピン数が惜しいので、SPI バスでダウンロードを行います。
SPI バスを使うと、JTAG よりも圧倒的に高速にダウンロードできます。
コンフィグ後、SPI バスを RasPi - FPGA 間の通信にも利用すれば、使用ピン数も最小限で済みます。
激安 FPGA 開発ボード "Wukong" の導入 (Xilinx Artix-7 XC7A100T)
で解説した Wukong 基板を使って、RasPi からのダウンロード方法を説明します。
実験環境
FPGA 基板 "Wukong" (Xilinx Artix-7 XC7A100T-2FGG676I 搭載)
RasPi 3B+
FPGA コンフィグ方法の説明
Artix-7 でサポートされているコンフィグレーション方法を示します (UG470 Table 2-1)
FPGA が起動時にどのモードで起動するかは、M[2:0] ピンで設定します。
FPGA が自分でコンフィグデータを読みに行くのが Master Mode で、
FPGA が外部からコンフィグされるのは Slave Mode です。
このモード設定を、M[2:0] で決めています。
ちゃんとした評価基板だと、DIP-SW とかショートプラグとかで、起動モードを選択できるようになっています。
残念ながら、Wukong 基板では Master SPI モード( M[2:0]=001 )で固定されていて、起動モードを変更することができません (下記、回路図)
この Master SPI モードでは、FPGA 起動時に SPI フラッシュを読みにゆきます。
フラッシュに有効なデータが書き込まれていれば、そのデータを読み込んで FPGA を設定して、起動します。
デバッグでダウンロードケーブルを使用する場合は、JTAG で接続され、M[2:0] の設定によらず、任意でコンフィグを上書きすることができます (強制ダウンロード)
Wukong 基板のコンフィグ動作
Wukong 基板は、出荷時には SPI フラッシュには何も書かれていません。
電源を投入しただけでは何も起こらず、JTAG からのダウンロードで動作を開始します。
SPI フラッシュに書き込めば、電源投入時に Master SPI モードで読み込んで自動起動します。
RasPi からコンフィグレーションする方法
RasPi が FPGA のコンフィグレーションデータを保持しておき、FPGA にダウンロードして起動する方法を考えます。
FPGA を外部からコンフィグレーションする方法は、
(a) Slave Serial Mode
(b) JTAG Mode
(c) Slave SelectMAP Mode
の3種類が用意されています(UG470 Figure 1-1)
Vivado でダウンロードするときと同じ JTAG ストリームを RasPi から吐ければ、M[2:0] の設定を無視してダウンロードできます。
しかし、専用のソフトウエアを用意して、JTAG の 4 本の信号線の制御が必要になるため、面倒です。
ここでは、最も簡単な (a) Slave Serial Mode によるコンフィグレーションを実施したいと思います。
Slave Serial で必要な信号は下記4つです。
PROGRAM_B: FPGA の設定リセットを行う。マイコンのリセットピン相当。
CCLK: シリアル信号のクロックを入力する。
DIN: シリアル信号のデータを入力する。立ち上がりでデータ取り込み。
DONE: コンフィグが完了して FPGA が起動すると、L → H に変化する。
Wukong 基板では、PROGRAM_B は SW1 で入力可能、DONE には LED D1 が接続されています。
RasPi からは、CCLK と DIN の 2 つの信号を与えれば良いです。
Slave Serial Mode と SPI の信号を比較してみると、クロックとデータの波形は同一であることがわかります (UG470 Figure 2-3 と、Wikipedia SPI 波形図)
CCLK の最大周波数は、Artix-7 の各スピードグレード共通で 100MHz です (DS181 Table 66)
コンフィグレーションモードの変更
前述の通り、Wukong 基板では、コンフィグレーションモード設定ピン M[2:0] が Master SPI ( M[2:0] = 001 )に固定されています。
M2_0 (W9) = GND
M1_0 (Y9) = GND
M0_0 (AB7) = +3.3V
M2 と M1 を +3.3V 接続に変更してやれば、Slave Serial ( M[2:0] = 111 ) モードで起動します。
Table2-1 によると、M[2:0] は内部でプルアップされているため、M2 と M1 を GND から切り離すだけでもよいはずです。
基板を見た感じでは、BGA パッケージの直下で GND に接続されているらしく、プルダウン抵抗を外して、というわけにはいきません。
Wukong 基板の改造
さて、通常の BGA 基板の配線でピンを GND へ接続する場合、BGA のパッドの隙間にビアを打って、内層 GND へ接続するのがセオリーです。
(XAPP157 の図2)
このビアのスルーホール内側の銅めっきを剥がしてしまえば、該当ピンと内層 GND の接続を切ることができます。
Wukong 基板の FPGA 下面を調べて、M2, M1, M0 付近で GND/VCC と接続されているビアを探したところ、下図のピンが該当するようです。
M2, M1 と思われるビアを、ピンバイスとφ0.5 のドリルで広げて、GND との接続を切ります。
M2 / M1 と GND との接続が切れたかどうかを確認するには、Master SPI で起動するかしないかを見るのがよいです。
作業前に、SPI フラッシュに正常起動するコンフィグデータを書いておき、電源を入れます。
Master SPI が有効な間はコンフィグ完了の LED = D1 が点灯します。
D1 が点灯しなくなれば、GND との接続が絶てたと思って大丈夫そうです。
何度かドリルを通して、Slave Serial 状態に変更できたらしい基板は下記のようになりました。
RasPi と Wukong の接続
うまく起動モードが変更できたら、RasPi の 40pin バスから、Slave Serial 信号線 3 本(CCLK, DIN, GND) を Wukong 基板の SPI フラッシュの該当信号ピンに接続します。
下の図と写真を参考にしてください。
FPGA を壊したくないので、先に Wukong 基板の電源を入れてから、RasPi の電源を入れます。
Passive Serial 用のコンフィグレーションファイル(.bin)の作成
FPGA にダウンロードするプロジェクトは、
激安 FPGA 開発ボード "Wukong" の導入 (Xilinx Artix-7 XC7A100T)
で使用したサンプル Test06_HDMI_OUT を使います。
Vivado で、通常のコンパイルを行うと、JTAG ダウンロード用の top.bit ファイルが生成されます。
このファイルは、ダウンロードケーブルで JTAG ダウンロードするときに使う形式で、ヘッダー情報などが含まれています。
Passive Serial ダウンロードでは、ヘッダー情報などが含まれていない生のコンフィグレーションデータ(top.bin)を使用します (UG570 Table 5-1)
この top.bin ファイルを生成するよう、オプションをオンにします。
Generate Bitstream で右クリックして、BitStream Settings を開きます。
Settings で、-bin_file にチェックを入れて OK します。
ここから、Generate Bitstream すると、top.bit が生成されたのと同じフォルダに、top.bin も生成されます。
デスクトップにサンプルプロジェクトを展開した場合、場所は下記に。
C:/Users/(user)/Desktop/Test06_HDMI_OUT/Test06_HDMI_OUT/Test06_HDMI_OUT.runs/impl_1/top.bin
生成した .bin ファイルの大きさは、3,825,788 バイトになりました。
Table1-1 に、XC7A100T の Configuration Bitstream Length (bits) で示されている数値(30,606,304 bis = 3,825,788 Bytes)と一致します (UG470 Table 1-1)
RasPi からのダウンロード
FPGA への SPI ダウンロードを実行するプログラムは、
RasPi 3B+ で最新の spidev_test を使う
で用意した最新版の spidev_test を使用します。
コンフィグレーションデータの大きさは 3.64MB ありますので、バッファサイズも最大(4MB)まで拡張しておきます。
samba 経由で RasPi に top.bin をコピーしたら、
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin -s 50000000
でダウンロードを開始します。
50MHz の Slave Serial でコンフィグレーションが完了して、D1 が点灯します。
直後に、HDMI からカラーバー出力が出てきます。
ダウンロードにかかる時間は、640ms ほどで、ほぼ一瞬です。
Vivado から JTAG でダウンロードすると 12秒ほどかかります(※)ので、圧倒的に早いです。
※ダウンロードケーブルへの接続を 12MHz に変更すると 7 秒ほど
SW1 を押すと FPGA がリセットされ、再度 Slave Serial のコンフィグ待ちに戻ります。
再度、上記コマンドでダウンロードできます。
何度でも再コンフィグできます。
ダウンロード中の SPI 信号の波形を示します。
RasPi の OS 側の処理の都合で、途中で CLK/DATA が一時停止する期間が生じます。
都度、ランダムな場所に1~3回ほど発生しますが、FPGA へのダウンロードには影響しません。
ダウンロードは100発100中で成功します。
100MHz でも試してみます。
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin -s 100000000
こちらも、問題無くダウンロードできました。
ダウンロードにかかる時間は、410ms ほどです。
CLK/DATA の停止期間が複数回発生しても、100% 成功します。
単純なシフトレジスタで SRAM に格納されてゆく仕組みで、クロックとデータが同時に停止する分には影響を受けない、ということでしょうか。
まとめ
RasPi の SPI バスから、Artix-7 FPGA に Slave Serial でのダウンロードが実現できました。
RasPi + FPGA のシステムを構築する際、FPGA のコンフィグを RasPi から行う事ができます。
FPGA を SPI フラッシュから起動する仕組みだと、FPGA の更新やバグ修正の際には、SPI フラッシュの書き換えが必要になります。
FPGA を RasPi からダウンロードして起動できると、RasPi のソフトウェアに FPGA データを抱かせておけばよいので、更新が非常に楽になります。
今回の例では Xilinx FPGA での例を説明しました。
Intel(Altera) FPGA でも Passive Serial がサポートされており、全く同じ仕組みでダウンロードが可能と思います。