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が正しく一つだけ点灯していることがわかる.