高位合成を使って FPGA 上に回路実装をしていくお話の第二弾になります.
他の回は以下から飛べます.
1. 今回行うこと
全体の流れは以下のようになっています.
- C++ を使って Vitis HLS 用に実行したいコードを書く
- Vitis HLS を使って,シミュレーションをしてデバッグする
- Vitis HLS を使って,Verilog にコンパイルする
- コンパイルしてできた IP を使って,Vivado で回路を組む (これが難しい…)
- Vivado を使ってできた回路から bitstream を作成する (いわゆるジェネビ)
- 生成された bitstream を PYNQ にコピーする
- PYNQ で回路にデータを流して結果を得る
今回は 2. Vitis HLS を使って,シミュレーションをしてデバッグする
,3. Vitis HLS を使って,Verilog にコンパイルする
の手順を解説していきたいと思います.
ソースコードは以下に公開しているので適宜参照してください.
2. Vitis HLS を使って,シミュレーションをしてデバッグする
2.1. テストベンチとメインのファイルを設定する
Vitis HLS の左上の Project > Project Settings...
から設定画面を開き,Simulation
タブに移ります.Add Files
をして,第一弾で作成した gaussian_tb.cpp
を登録しておいてください.
次に,Synthesis
タブに移り,gaussian.cpp
を登録し,右上の方の Browse...
からメインの関数 (今回は gaussian (gaussian.cpp)
) を選んでください.Browse...
を押した先でたくさんの関数が表示されることがありますが,ビビらずに探してください.
多分下の方にあると思います.
また,ヘッダファイル (gaussian.h
) は勝手に読み込まれるので設定しなくて大丈夫です.
最後に OK
を押せば終了です.
2.2. OpenCV の設定
コードを書き終えてファイルも設定して,いよいよコンパイルといきたいところですが,テスト用に画像を読み込むためにはその前に OpenCV を使えるようにしないといけません. (どうしてもうまくいかない場合は 2.3 に進み, C Simulation
をせずに C Synthesis
以降を進めていっても構いません.今回は OpenCV はテストにしか使っていない & 合っていることが保証されている (はずな) のでいいのですが,自分で一からコードを書くときはしっかり C Simulation
をして,デバッグをしましょう.)
ただ,OpenCV の扱いが時を追うごとに変わっていて,自分の環境でどうすれば使えるようになるのか調べるのは残念ながら至難の業です…
Vivado HLS の時代や別の Vitis HLS のバージョンではここで書く方法は通用しないかもしれません.
今回は Vitis HLS 2020.2 を使っているので,参考にしたのは以下のサイトです.
この方は Vivado HLS の時代の設定方法も書いてくださっているので,違うバージョンの場合はこちらも参考にしてみてください.
まずは C++ 用の OpenCV をインストールしてください.
と言いつつ詳しい説明はここでは省略して OpenCV の公式サイト に譲ります.
C++ の OpenCV が使えるようになったら後一息です.Vitis HLS では Vitis Vision Library を使用しているので,まずはこれを clone しておきます.
※追記: テストベンチでしか OpenCV を使わない場合は Vitis Vision Library は必要ないようです.
下のコード (git clone
) の実行も必要ありません.
(marsee101 さんありがとうございます )
$ cd /path/to/any
$ git clone https://github.com/Xilinx/Vitis_Libraries.git
次に,コンパイル時のフラグを設定していきます.
初めに
Vitis_Libraries/vision/L1/include
の絶対パス今回は/path/to/any/Vitis_Libraries/vision/L1/include
- OpenCV の include フォルダの絶対パス
- 筆者の場合は
/usr/local/include
- 筆者の場合は
- OpenCV の lib の絶対パス
- 筆者の場合は
/usr/local/lib
- 筆者の場合は
を調べておいてください.
次に,Vitis HLS の左上の Project > Project Settings...
から設定画面を開き,Simulation
タブに移ります.
今回はテストベンチで画像を読み込むために使うだけなので,テストベンチファイル (gaussian_tb.cpp
) を選んで,Edit CFLAGS...
を選択してください.
ここで,-I/path/to/any/Vitis_Libraries/vision/L1/include -I/usr/local/include -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc
のようにフラグを設定してください. (パスなどは適宜変更してください.)
ちなみに,設定した後もう一度開くと相対パスになっていて,筆者の場合-I../Vitis_Libraries/vision/L1/include -I../../../usr/local/include -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc
と設定されていました.
2.3. シミュレーション・デバッグをする
これでようやくコンパイルができるようになりました.
シミュレーションの方法は簡単で,右上の ▶ の中から C Simulation
を選んで実行するだけです.
オプションなどは基本的に設定しなくて大丈夫だと思います.
INFO: [SIM 2] *************** CSIM start ***************
INFO: [SIM 4] CSIM will launch GCC as the compiler.
Compiling ../../../src/gaussian_tb.cpp in debug mode
Compiling ../../../src/gaussian.cpp in debug mode
Generating csim.exe
Success HW and SW results match
The maximum depth reached by any of the 2 hls::stream() instances in the design is 262144
INFO: [SIM 1] CSim done with 0 errors.
INFO: [SIM 3] *************** CSIM finish ***************
のように出力されれば成功です
もしバグがあると言われていればエラー内容をググってなんとか解決してみてください…
(コメントもらえれば対応できるかもしれません.)
次に右上の ▶ の中から C Synthesis
を実行します.
エラーがなく終了すると Synthesis Summary
が表示されるはずです.Timing Estimate
にはクロック周期が表示されていて,Performance & Resource Estimates
にはループ回数, II (Initiation Interval, 何クロックに一回ループを実行できるか),レイテンシーなどが表示されています./path/to/test/solution1/syn/report/gaussian_csynth.rpt
でもサマリーを見ることができます.
3. Verilog にコンパイルする
章にしてみたはいいものの,この章は大して書くことはありません.
これまでで,合成まで完成しているので,最後は Vivado で読み込めるように Verilog ファイルを出力しておきましょう.
右上の ▶ の中で Export RTL
が実行できるようになっているはずなので,これを実行します.
オプションなどはそのままで大丈夫です.
エラーなく終了すればできたファイルが /path/to/test/solution1/impl/ip
の中に保存されているはずです.
solution1/syn
と solution1/ip
の中身は以下にも上げておいたので見てみてください.
4. まとめ
これで,高位合成まで完了して,Verilog のファイルが作成されました
次はいよいよ Vivado で回路を組んでいきましょう.
Vitis HLS とVivadoを使い始めた初心者です。
とても分かりやすい説明を書いていただきありがとうございます。
本当に助かっております。
このページに沿って進めていましたが
どうしても解決できないことがありお伺いしたいことが二点あります。
①C Simulationを実行した際にERROR: [SIM 211-100] ‘csim_design’ failed: compilation error(s).がでてしまいこの解決方法を知りたい。
②C Synthesisを実行したときfor_y_for_xでTiming Violation がでてしまいこの解決策を知りたい。
お忙しい中大変恐縮ですが、お答えいただけると大変うれしいです。
ケビンさん,コメントありがとうございます!
拙い文章ですが,参考にしてくださっている人がいて嬉しいです!
質問の内容についてですが,私が試している限りでは生じたことがないので,詳しくお答えするのは難しいかもしれませんが,わかる範囲で回答させてもらいます.
まず, 1 について参考になりそうなリンクが3つあったので共有しておきます.
Windows で行っているとそのエラーが出たが, Linux にすると治ったというような内容が書かれていると思います. (https://github.com/Xilinx/BNN-PYNQ/issues/92)
メモリの使用量が多すぎたため,入力のサイズを小さくすると治ったというような内容が書かれていると思います. (http://fpga.blog.jp/archives/82185158.html)
再度プロジェクトごと作り直して,C Simulation の時に Clear Build と Optimizing Compile にチェックを入れると治ったいうような内容が書かれていると思います. (https://www.programmersought.com/article/35044107400/)
個人的には初め手探りで作ったプロジェクトでは何かを忘れていたり,変な履歴が残ってしまったりして動かないというようなこともあると思うので,とりあえずもう一度一から作り直してみるのがいいのではないかと思います.
また,エラーの前後の内容や実施した環境 (OS や Vitis のバージョンなど) やブログの内容と変えた部分があるのかなども教えていただけると,もう少し手伝えるかもしれません. (OS については Linux 以外で実験するのは難しいかもしれませんが…)
次に,2についてですが,手元で動かしても Timing Violation は出ないので,はっきりとはわかりません.
もしかしたらですが,1 つ目の記事 (https://blog.n-hassy.info/2021/05/vitis-hls-to-fpga-1/#4_C_Vitis_HLS) の Solution Configuration のクロックの周期を 10 以上にしてみたりしたら治るのかもしれませんが,あまり役に立たないかもしれないです.
これももう一度作り直したら治ったりするかもしれないので,とりあえず試してもらえるといいかと思います.
取り止めのない回答になってしまって申し訳ありませんが,もう少しチャレンジしてみて,わからなければ詳細も添えて再度コメントいただければと思います.
画像なども添付したい場合は Google Drive などにあげてリンクを貼っていただくか,プロフィールページにメールアドレスがあるので,そちらから送っていただければと思います.
何が原因だったのか知りたいので,もし解決したらそれも教えていただけると嬉しいです!
(Vivado とか Vitis は非自明なことが多いと思うんですけど,頑張ってください…!)