C/C++ベースのFPGA開発をはじめるにあたって,まずはVivado HLSの使い方をFPGAで動作するビットストリームの作り方まで一通り学んでしまいましょう.この章では,とりあえずVivado HLSを使った開発ができるようになるために,ツールを一通り使ってC/C++で書いたコードからFPGAで動作するビットストリームを生成する作業までを一通り体験してみることにします.習うより慣れろ,ですね.
例題
VivaoHLSでは,基本的な制御構文のC/C++コードをHDLモジュールにすることができます.ここでは,簡単なプログラムをハードウェア化してみましょう.
|
|
Vivado HLSプロジェクトの作成
Vivado HLSを起動したところ.Vivado HLSはデスクトップのショートカットアイコンやスタートメニューから起動する.
プロジェクト名と格納フォルダを指定.ここでは.ホームの下のVivadoの下に格納することとし,名前をhls_test_1とした
既存の設計ソースコードがあれば,ここで追加.ないのでNextで次へ.
既存のテストベンチ用のソースコードがあれば,ここで追加.ないのでNextで次へ.
ターゲットFPGAを選択する.Part Selectionの中の…ボタンをクリック
FPGAの型番を選択.xc7z020clg400-1を選択する.検索フィールドにxc7z020と入力していくと楽に探せる.
FPGAを選択し終えたらFinish.
プロジェクトの作成が完了した
Vivado HLS上での設計
左ペインのSourcesアイコンの上で右クリック,New File…をクリック
開いたファイル選択ダイアログに,作成するファイル test.c と入力して保存をクリック
作成したtest.cの中身として,先のソースコードを入力する.
動作確認のために,テストベンチ用のソースコードを追加する.今度はTest Benchアイコンの上で右クリック,New File…をクリック
今度はtest_tb.cというファイルを作成することにする.ファイル名を入力して保存をクリック
テストベンチの中身を記述する.テストベンチは単なるCプログラムなのでstdio.hやprintf関数が使える
メニューのProjectからProject Settings…をクリックして,プロジェクトの設定をする
Synthesisをみると,Top Functionが指定されていないことが確認できる
Browse…ボタンをクリックすると候補がでる.今回は一つだけ.候補に表示されたtest関数を選択してOKをクリック
合成するトップの関数がtestであることを指定できた
Vivado HLSでの動作確認
まずはCレベルでの動作を確認するため,メニューのProjectからRun C Simulationをクリックする
特にオプションは指定せずにOKをクリック
しばらくすると結果が表示される.たとえば0xaの立っているビットは2個で答えが正しいことが確認できた
ツールバーの再生ボタンアイコンをクリックしてCからHDLの合成を開始する
しばらく待つと合成が完了する.ここでは生成された回路のクリティカルパス遅延が3.92nsであると表示されている.また,ひとつの答えを得るために33サイクル必要であることも確認できる.
合成したHDLの動作検証を行う.テストベンチはCシミュレーションのときと同じ
特にオプションは指定せずにOKをクリック
シミュレーションにXSIM(RTLシミュレータ)が使用されていることがわかる
RTLシミュレーションでも望み通りの答えがえられることが確認できた
IPコアの生成
ツールバーの荷物のようなアイコンをクリックしてIPコアを生成する
IPコア生成に関する設定ダイアログが開いたところ.特に変更の必要はないのでOKをクリック
しばらく待つと,Vivadoで利用可能なIPコアが生成される.
生成されたリソースやファイルはsolution1の下のimplの下に格納されていて自由に確認することができる
生成したモジュールをFPGAプロジェクトで利用する
まずはVivadoプロジェクトを作成する
プロジェクト作成ダイアログ.Nextで次へ
プロジェクト名をproject_3として,ホーム下のVivadoフォルダの下に保存することにする
作成するプロジェクトはRTLプロジェクトを選択.
特にここで追加するファイルはないのでNextで次へ
特にここで追加するファイルはないのでNextで次へ
プロジェクトの開発ターゲットはボードリストからZybo Z7-20を選択
設定内容を確認してFinishをクリック.ウィザードを終了する.
PROJECT NAVIGATORのSettingsをクリックして設定画面を呼び出す
リストのIPを展開し,Repositriesを選択する
ここにVivado HLSで作成したIPコアのフォルダを指定すれば利用できるようになる.+アイコンをクリック.
IPコア検索用のフォルダとしてVivado HLSで作成したプロジェクトフォルダ(hls_test_1)の下の,solusion1\yen ipを選択して,Selectをクリック
追加したリポジトリ情報が表示される.TestというIPコアが含まれていれば設定は正しい.OKでダイアログを閉じる
リポジトリに追加できたので,OKで設定ダイアログを閉じる
IP Catalogを選択してIPを呼び出す
IP Catalogの中にVivado HLSで作成したTestがあるので,ダブルクリックする
IPコアの設定画面が開くが,することもない.OKを押してダイアログを閉じる
Vivadoプロジェクト内にIPコア保存用のフォルダを作る確認を求められる.OKをクリック
IPコア関連のファイルをVivadoに生成させるためGenerateをクリック
IPコア関連のファイルをVivadoに生成させるためGenerateをクリック
合成がかかる旨のメッセージが表示されたらOKで閉じる
呼びだしたIPコアのインスタンスを持つためのトップモジュールを作成する.モジュールの作成は,Design Sourcesの上で右クリックしてAdd Sources…選択すればよい
今回はデザインファイルを作るので,Add or create design sourcesを選択
Create Fileをクリック.
VHDLで,topという名前のモジュールを作ることにしてOKをクリック.
作成したモジュールがリストに追加されたのでFinishで終了.
topモジュールの入出力ポートの生成ウィザードが開くので,clkと入出力用のポートを定義してOKをクリックする(あとでテキストで記述してもよいので無視してOKをクリックしても構わない).
生成したトップモジュールをVivadoのエディタで開いたところ
top.vhdの内容は次の内容で書きかえる.
|
|
コードを正しく記述し終えると,top→test_0というデザインツリーが作られる
PROJECT NAVIGATORのRun Synthesisをクリックして合成を開始.ダイアログはOKで閉じてステップを進める.
合成を終えたら,一度Open Synthesized Designで合成結果を開く
メニューのLayoutからI/O Planningをクリックしてピン配置設定モードを呼び出す
クロック(K17),入力4bit(T16,W13,P15,G15),出力4bit(D18,G14,M15,M14)を設定.電圧は,すべてLVCMOS33に設定.
設定を終えたらGenerate Bitstreamをクリック
設定したピン配置を保存していいか聞いてくるので,Saveで保存
設定の保存でSynthesisが無効になる可能性があるという案内がでたら.OKでステップを進める
制約保存用のファイルがないので作成ダイアログに従って作成.名前をtopとしてOKをクリックして完了
Synthesisからやりなおすことの許可を求められるのでYesでステップをすすめる
合成の開始.パラメタはそのままでOKで次へ.
しばらく待つと合成,配置配線が完了してFPGA用のビットストリームが生成される.Open Hardware Managerを選択してOKをクリック.
Hardware Managerが開いたところ.Open targetをクリック.
Auto ConnectでFPGAボードと接続する
Program deviceで生成したbitファイルをFPGAに書き込む
実機で動作を確認
実機での動作を確認できます.DIPスイッチをON/OFFしたときにONの個数がカウントできていることがわかります.が,残念ながらよくみてみると,DIPスイッチを2つONにした状態,つまり1bit目のLEDのみが点灯すべきケースで,0bit目のLEDが若干点灯していることがわかります.これはバグなので原因を探してみましょう.
LEDが一つだけ点灯するはずが0bit目のLEDが若干明るい
ここでは,ILAを使って,実機で動作を確認してみます.まず,topモジュールを次のように書き変えて,いくつかの信号をILAで観測できるようにしましょう.
|
|
コードを書き変えたらRun Synthesisをクリックして合成を行なう
合成がおわったらOpen Synthesized Designで合成結果を開く
ILAの設定をしたいので,メニューのLayoutからDebugを選択
虫のアイコンをクリックしてILA設定ウィザードを開く
ILA設定ウィザードの開始
観測したい信号のクロックをみつけることができずundefinedになっている
クロックを設定したいアイテムの上で右クリックしてSelect Clock Domeinを選ぶ
Global_CLOCKがないという案内が表示されるがOKで閉じる
Global_CLOCKのかわりにALL_CLOCKを選択するとclk_IBUFが見つかるので選択,OKをクリックする
同様の手順で全ての信号のClock Domainをclk_IBUFに設定したらNextで次へ
サンプル数や利用機能はデフォルトのままでよいのでNextで次へ
サマリを確認したらFinishでウィザードを閉じる
ILAの挿入ができたので,あらためてGenerate Bitstreamで合成と配置配線を行なう
ILAに関する設定を保存するか確認を求められたらSaveをクリック
しばらく待つとILAを仕込んだビットストリームが生成される.Open Hardware Managerを選択してOKをクリック
新しく作ったビットストリームを書き込むためにProgram Deviceをクリック
ビットストリームとILA用の定義ファイルがセットされていることを確認してProgramをクリック
二重三角マークをクリックすると内部信号が確認できる
ap_doneが'1’でない間に値がふらふらしていることが確認できた.
Vivado HLSのシミュレーション結果を詳細に確認する
実はILAを挿入するまでもなく,Vivado HLSのC/RTL協調シミュレーションの結果を注意深く確認することで,今回のバグは防ぐことができます.試してみましょう.
Vivado HLSでC/RTLシミュレーションを再度実行する
シミュレーション実行パラメタのDump Traceでallを選択してOKをクリック
シミュレーションが完了すると,ツールバーのOpen Wave Viewerをクリックする
しばらく待つとVivadoシミュレータの波形ビューワが開く.ここでC/RTLシミュレータの結果を確認できる.
結果の信号やap_doneなどを波形ビューワに追加してみたところ.ap_doneが'1’でない場合に値が確定していないため注意しなければならない,ということがみてとれる.
再度実機での動作確認
バグ修正を反映して,もう一度,実機で動作を確認してみましょう.
|
|
コードを書き変えたらGenerate Bitstreamをクリックして,再度ビットストリームを生成する
再び実機で動作を確認したところ.LEDが正しく一つだけ点灯していることがわかる.