ACRi ルームには、Intel の FPGA である MAX10 を搭載した DE10-Lite が9台設置されています。この記事では、Intel の FPGA 開発ツールである Quartus Prime Lite を使って、DE10-Lite 向けの設計をする手順を紹介します。
Quartus Primeの起動
DE10-Lite は、vsA01 から vsA09 までの9台のホストで利用することができます。まずは、そのうちのどれかに リモートデスクトップ や X2Go を使って接続しましょう。
接続方法は、ACRi ルームの FPGA 利用環境の予約・使用方法 や、X2GoでFPGA 利用環境 (ACRi ルーム) を使う を参考にしてください。
なお、2021年12月現在 vsA01 から vsA09 ではリモートデスクトップでの接続がうまくいかない事例が報告されています。この記事では、X2Go で接続して開発をすすめてみます。
ログインしたら、ターミナルを開いて、
$ /tools/Intel/intelFPGA_lite/20.1/quartus/bin/quartus
とコマンドを入力して、Quartusを起動します。
初回の起動時には、次のようにフルバージョンの Quartus Prime や、追加 IP の購入を促すダイアログが表示されます。今回使用する FPGA では、フルバージョンの Quartus Prime は不要です。二番目の Run the Quartus Prime software
にチェックを入れて、OK でダイアログを閉じましょう。
次のように、Quartus Prime が起動しました。よくある IDE と雰囲気は同じです。
プロジェクトの作成
Quartus Prime が起動したら、早速開発をはじめましょう。まずは、File
メニューから、New Project Wizard...
を選択します。
プロジェクト作成用のウィザードがはじまります。最初は、ウィザードのステップの紹介です。Next >
をクリックして次に進みます。
ウィザードでは、最初に、プロジェクトの作成場所とプロジェクト名を入力します。ここでは、プロジェクトの作成場所を /home/tu_miyo/Intel
に、プロジェクト名を my_first_project
としました。プロジェクト名と同名のエンティティをトップモジュールにするように自動的に入力されるのですが、あとで簡単に変更できますので、そのまま放っておきます。入力したら、Next >
で次に進みます。
プロジェクト格納先のディレクトリがない場合(大抵ないと思うのですが)は、ディレクトリを作成するかどうかのダイアログが表示されます。Yes
をクリックしてダイアログを閉じます。
次に、プロジェクトのタイプとして、テンプレートを使用するかどうか尋ねられます。ここでは、テンプレートを使用しない Empty project
ですすめましょう。チェックを確認して Next >
をクリックして次に進みます。
プロジェクトに登録するファイルの選択が求められます。これは、あとから簡単にできますので、ここでは何もせずに、Next >
をクリックして次に進みましょう。
次は、使用する FPGA の選択です。ACRi ルームの vsA01 から vsA09 で利用できる、DE10-Lite に搭載されている FPGA は、MAX 10
シリーズの 10M50DAF48C7G
です。Device Family:
で MAX 10
を選択し、右側の Name filter:
に、10m50daf484c7
と入力すると、デバイスが一意に特定されます。選択した状態で Next >
をクリックしましょう。
最後は、利用するツールの設定です。特に変更の必要はありませんので、そのまま Next >
をクリックして次に進みます。
プロジェクト作成の一連の作業が完了しました。Summaryでは、特に、選択したデバイスが間違いなく 10M50DAF484C7G
であることを確認したら、Finish
をクリックしてウィザードを終了しましょう。
プロジェクトの作成が終わったところです。
ファイルの追加
作成したプロジェクトに、このプロジェクトで使用するファイルを追加していきましょう。Project Navigator
を Heirarchy
から、Files
に変更し、ツリーのルートに相当する Files
を選択・右クリックしてコンテクストメニューを開き、Add/Remove Files in Project...
をクリックします。
次のような、ファイルを管理するダイアログが開きます。
File name:
の右にある ...
ボタンをクリックするとファイル選択ダイアログが開きます。あらかじめて用意しておいたファイル群を選択し、Open
でダイアログを閉じます。
プロジェクトに必要なファイルを追加することが出来ました。このダイアログは、OK
で閉じましょう。
ダイアログを閉じると、プロジェクトに登録したファイルがツリー状に表示されています。ここで、今回のデザインのトップエンティティをセットします。トップエンティティに相当する top.v
を選択・右クリックしてコンテクストメニューを開き、Set as Top-Level Entity
をクリックします。
これでファイルの追加は完了です。
コンパイルする
プロジェクトの作成とファイルの設定が終わったので、コンパイルしてみましょう。あとのために、Project Navicator
を Hierarchy
に戻しておきます。コンパイルは、ツールバーにある、再生ボタンのような三角マークのボタンをクリックして実行します。
コンパイル中は、合成や配置配線などの進捗状況が、ツール左下の Tasks
ペインに表示されます。
タスクが全部完了すると、緑色のチェックマークになります。
ピン配置の指定
さて、これで登録したデザインが正しくコンパイルできることは確認できましたが、コンパイルして作られたビットファイルをFPGA上に書き込んでも所望の動作はしません。ピン配置の設定をしていないからです。
ピン配置を決めるには、ツールバーにある Pin Planner
ボタンをクリックして起動する GUI を使ったやり方があります。
Pin Planner が起動したところです。デザインで定義されていた入出力ポートに、配置配線ツールが適当に FPGA の I/O をマッピングしていることがわかります。
次のように、すべての I/O ポートの Location
を適切に入力したら、File
メニューの Close
をクリックして、Pin Plannerを終了しましょう。
ピン配置の設定を終えると、配置配線以降のタスクが未実行状態になります。
ツールバーの再生ボタンマーク Start Compilation
ボタンをクリックして、再度コンパイルします。
コンパイルが終わると Task
の全てに緑色のチェックマークがつきます。
合成後のリソース使用量は、Project Navigator
で確認することができます。トップエンティティをルートにしたツリーでデザインを構成するインスタンスが表示され、また、それぞれのリソース使用量が右側に表示されています。
FPGAでの実行
コンパイルが終わったら、出来上がったビットファイル (.sof
ファイル) を FPGA にダウンロードして動作させましょう。ツールバーの Programmer
アイコンをクリックして、ダウンロード用のツールを起動します。
次の図が、起動した Programmer
の様子です。起動した直後は、No Hardware
とFPGAにアクセスする JTAG の設定ができていないはず、です。そこで、Hardware Setup...
ボタンをクリックして設定ダイアログを開きましょう。
ハードウェアの設定ダイアログが開いたら、Currently selected hardware:
の右のセレクトボックスで、USB-Blaster
を選択します。設定のためにしばらくダイアログのボタンなどがクリックできなくなりますが、再びボタンなどがクリックできるようになったら、Close
ボタンをクリックしてダイアログを閉じます。
正しく設定できれば、No Hardware
だった部分に、USB-Blaster
が表示されます。左のツールバーの Start
をクリックするとFPGAにビットファイルのダウンロードが開始されます。
右上のプログレスバーが、100% になればダウンロードは完成、FPGA はダウンロードしたデザインで動作を開始します。
シリアル通信の動作確認
テスト用のデザインは、シリアル通信で入力したデータをループバックします。動作確認をしてみましょう。まず、ターミナルで
$ gtkterm &
と入力して、GtkTerm を起動します。GtkTerm を起動したら、メニューの Configuration
から Port
をクリックして、通信ポートの設定を行ないます。次の図のように、Port:
を /dev/ttyUSB0
に、Baud Rate:
を 115200
にセットしてください。セットしたら OK
で設定ダイアログを閉じます。
設定が終わると、GtkTerm上で、キーボードで入力した文字列が、そのまま表示される様子が確認できます。
FPGA内部の動作を観測してみよう
Intel の FPGA では、 Signal Tap Logic Analyzer というツールで、FPGA 内部の動作を観測できます。Xilinx でいうところの ILA ですね。
Signal Tap Logic Analyzer を使うには、まず、メニューの Tools
から Signal Tap Logic Analyzer
を選択してツールを起動します。
ツールが起動したころです。最初は、Signal Tap Logic Analyzer で観測可能な信号が何もないため、次の図のような空っぽの状態でツールが起動するはずです。ここで、観測用のクロック信号および、観測対象の信号を設定します。
まずは、クロック信号の設定です。中央右の Signal Configuration
ペインの Clock:
の右にある ...
ボタンをクリックします。
信号を選択するウィンドウが表示されます。選択の前に、 List
ボタン右の、上向きに>>
という記号が書かれているボタンをクリックしてオプションを表示します。
Opitons
の Filter:
のセレクトボックスをクリックし、Signal Tap: pre-synthesis
を選択します。これで、観測用のクロック信号や観測対象の信号を選ぶ際に、合成前の、すなわち HDL に記述した信号名を利用できるようになります。
Named:
にルールを指定して、List
ボタンをクリックすると、指定したルールに相当する名前の信号が、Matching Nodes:
にリストアップされます。*
はワイルドカードなので、List
の結果は何にでもマッチする、すなわち、全ての信号がリストアップされます。
観測用のクロック信号は、デザインを駆動するメインクロック信号をそのまま流用することにします。リストアップされている clk
を選択して、中央の >
ボタンをクリックすると、Nodes Found:
に選択した clk
がコピーして表示されます。これでクロック信号の選定が終わりました。OK
をクリックしてダイアログを閉じます。
次に、観測対象の信号を選択します。観測対象の信号を選択するには、中央左のペイン Double-click to add nodes
と書かれている箇所で、マウスの左ボタンをダブルクリックしてダイアログを開きます。
ダイアログが開いたら、クロックを選択した時同様に、オプションを表示させ、Filter:
で Signal Tap: pre-synthesis
を選択し、Named:
を *
にした状態で、List
ボタンをクリックします。
HDL で定義した信号が、Matching Nodes:
にリストアップされますので、たとえば、uart_rd
、 uart_wr
、uart_din
、uart_dout
、および、counter
を選択し、中央の >
ボタンをクリックして、Nodes Found:
にコピーします。
コピーしたら、Insert
ボタンをクリックすることで、Nodes Found:
に選択した信号を、観測対象の信号としてデザインに追加することができます。最後に Close
ボタンをクリックしてダイアログを終了します。
設定が終わると、次の画面のようになるはずです。中央左ペインには、選択した観測対象の信号が、中央右ペインには観測用のクロックとして clk
が選択されていることがわかります。
この状態では、クロックや観測対象を選択はしましたが、それを反映した作成されたビットファイルで FPGA がコンフィギュレーションされているわけではありません。そのため、上部のステータス表示が赤色で警告を示しています。
設定が終わったので、設定情報をファイルに保存しコンパイルに反映できるようにプロジェクトに組み込みましょう。メニューのFile
から、Save
をクリックします。
ファイル保存ダイアログが開きます。ファイル名は、デフォルトの stp1.stp
のままでよいでしょう。ファイル保存ダイアログの下の Add file to current project
にチェックが入っていることを確認して、Save
でファイルを保存します。
作成した設定ファイル stp1.stp
をプロジェクトに組み込む確認ダイアログが標示されますので、これには Yes
と答えてください。
一度 Quartus Prime ウィンドウに戻って、ツールバーの再生ボタンマークの、Start Compilation
ボタンをクリックして、再度デザインをコンパイルします。Signal Tap Logic Analyzer のウィンドウを閉じてしまう必要はありません。
Task がすべて緑色のチェックマークになればコンパイルが終了です。これで、Signal Tap Logic Analyzer で信号を観測可能なビットファイルを生成することができました。
Project Navigator
のインスタンスツリーを展開してみると、sld_hub:auto_hub
と sld_signaltap:auto_signaltap_0
というインスタンスが追加されていることがわかります。これらが、Siganl Tap Logic Analyzer で信号を観測するために、デザインに組み込まれたモジュールです。
ふたたび、Signal Tap Logic Analyzer のウィンドウに戻ります。先程は赤色の警告を示していた部分が黄色になりました。これは、JTAGの先に接続されている FPGA が所望の観測用ロジックを含むビットファイルでコンフィギュレーションされたものとは異なっていることを示しています。
ビットファイルをコンパイルはしましたが、FPGA にダウロードしたわけではないので、当然ですね。早速、ビットファイルを FPGA にダウンロードしましょう。
先程と同様に、Programmer を使ってもいいのですが、Signal Tap Logic Analyzer ウィンドウからもビットファイルのダウンロードが可能です。まず、ウィンドウ右側の、SOF Manager:
の横の ...
をクリックして、ダウンロードしたいファイルの選択ダイアログを開きます。
選択すべきファイルは、プロジェクトのディレクトリ(今回は、~/Intel
でした)の output_files
ディレクトリにある、プロジェクト名.sof
という名前のファイル(今回は、my_first_project.sof
)です。
選択したら、Open
をクリックしてダイアログを終了します。SOF Manger:
の右のテキストフィールドに選択したファイル名が標示されます。ここで、SOF Manager:
の右の Program Device
ボタンをクリックすると、FPGAに選択したビットファイルをダウンロードすることができます。
ダウンロードが完了すると、黄色でメッセージが標示されていたステータスの色が消えて、Signal Tap Logic Analyzer が利用できる状態になります。
では、いよいよ FPGA 内部の信号を観測してみましょう。Instance Manager:
の右の Run Analysis
という、再生ボタンとルーペが組み合わさったようなアイコンのボタンをクリックします。
クリックしてしばらく待つと、下の画像のように FPGA 内部の信号の時間変化が観測されます。
赤い線で標示されている観測結果の標示部分にマウスカーソルを持っていくと虫眼鏡カーソルになります。左クリックでズームイン、右クリックでズームアウトすることができます。counter
の値が標示される程度に拡大した様子が次の図です。counter
の値が毎クロック毎クロック、インクリメントされている様子が見て取れます。
その時点の信号の状態を観測するだけではなく、信号の値が特定の条件にマッチした場合を観測することもできます。中央左ペインで Setup
タブを選択すると、観測対象の信号の表が表示されます。たとえば、uart_wr
の信号が立ち上がった時点の信号を観測したい場合には、uart_wr
の行の Trigger Condition
の列のマスで右クリックしてコンテクストメニューを開き、Rising Edge
を選択します。
選択すると、網掛けのようなマークのDon't Care
から、Rising Edge
に切り替わります。
ふたたび、信号観測のために、Instance Manger:
右の Run Analysis
のボタンをクリックします。
今度は、すぐに観測信号の結果が得られるわけではなく、ステータスが、Acquision in progress
という緑色の状態になります。これは、FPGA 内部の信号が指定した条件、すなわち、uart_wr
が立ち上がるまで、ツールが待っている状態です。
ふたたび、GtkTerm を起動してポートの設定をしたら、適当なキー入力をしてみます。先程と同様に入力した文字がエコーバックされて表示されるはずです。
ここで、Signal Tap Logic Analyzer をみてみると、信号の取得を終えて信号変化の様子が観測できています。
これは、 uart_rd
の立ち上がりと共にキー入力されたデータが取り込まれ、その直後に、uart_wr
が立ち上がってエコーバックしている挙動を示しています。
まとめ
ACRi ルームの Intel MAX 10 を搭載した DE10-Lite を利用する手順を紹介しました。普段 Intel の FPGA を使っている人はもちろん、Xilinx の FPGA を使うのがメインの人も、ぜひ試してみてください。また、ACRi ルームにある Xilinx の Arty とぜひ使い比べてみてください。
みよしたけふみ(わさらぼ)