Prismjs

2019年8月7日水曜日

Vivado HLSで高位合成する手順とポイントメモ


Vivado HLSで簡単な高位合成を行ってみました。
少々クセが強そうな感じです。

チュートリアル

Vivado HLSを起動し、Create new projectをクリックして新規HLSプロジェクトを作成する。

Project nameにプロジェクトの名前、Locationに保存先を指定しNextをクリックする。

そのままでNextをクリックする。

次もそのままでNextをクリックする。

をクリックしてボードファイルを設定する。


ボードファイルを設定したら、Finishをクリックする。数秒でプロジェクトが作成される。

プロジェクト作成画面のProjectNew Sourceをクリックしてソースファイルを追加する。


ソースファイル(ここではtest.cpp)が追加された。このソースファイルに回路記述を書いていく。

ソース例は以下のような感じ。
#include <ap_int.h>

void test(
              ap_uint<32> data_in,
              ap_uint<32> *data_out
              )
{
              *data_out = data_in;
}



ap_int.hをインクルードすればap_uint<n>で幅nの信号を表現できる。
引数のap_uint<n>in(式の右辺)ap_uint<n> *out(式の左辺)となる。
例はdata_indata_outに出力するだけ。

ソースを開いて右側のDirectiveタグを開く。

変数名をダブルクリックでインターフェースを決めることができる。

ProjectProject Settings をクリックしてSynthesisTopFunctionを先ほど作成したソースの関数を設定する。

SolutionRun C SynthesisActive Solutionをクリックし高位合成する。

高位合成が終わると回路規模などが確認できる。

SolutionExport RTLをクリックする。

OKをクリックするとIPが作成される。

プロジェクト/solution/impl/ipに作成されたIPが入っている。


メモ

staticもしくはグローバル変数にすれば前回回路動作時の値を保持し続けられる。これらはRESETプラグマ(#pragma HLS RESET variable=”変数名”)ap_reset時に値を初期化させることができる。逆に初期化したくないならRESETプラグマにoffオプションをつける(#pragma HLS RESET variable=”変数名” off)と初期化しない。
よくよくC言語的に考えたらstaticかグローバル変数は前回関数終了時点での値のままなわけで、当たり前といえば当たり前である。


ap_resetの極性はSolution SettingsGeneralAddconfig_rtlを追加してreset levelを選択することでローアクティブかハイアクティブかを設定可能。ちなみにデフォはハイアクティブ。ローアクティブにするとap_rst_nと信号名にnがつくようになる。


回路に高位合成で作成したIPを仕込み、VivadoLaunch SDKXilinx SDKを起動するとcアプリ用のドライバ(x<ip>.h)を自動生成してくれる。
そのドライバの中にデータ型がu64で定義されたものが出てくることがある。そのままだと多分エラーになる。どっかでtypedef long long u64;と追記しu64long longと定義してやれば問題なく動く。
多分bit幅が32bitより大きく64bit以下の場合はu64で定義されるっぽい。それより大きい幅は複数のu32で構成された構造体で定義されるっぽい。



Vivadoでデザインに配置済のIPHLSにて編集するとき、Synthesisした時点でVivado側で自動でIPの変更を検知して更新するかどうか聞いてくるようになるが、HLSExport RTLを行ってからIPの更新をしたほうが良い。SynthesisしただけでExport RTL せずIPを更新しようとするとエラーが出る。また、たまにVivadoIPの変更を自動で検知しないことがあるが、IPrepositoryrefresh(Settings→IP→Repository→Reflesh Allをクリック)してやると変更が検知される。

0 件のコメント:

コメントを投稿