本記事の概要
Vitisビジョンライブラリから高位合成したIPをエクスポートし、画像処理した結果をディスプレイに表示するZynqアプリケーションを紹介する。用例のcustomconvに含まれるFilter2D_accelを例にラプラシアンフィルタを実装する。
本記事では、Vivadoで設計したZynq上のブロックデザインを紹介する。
Xilinxの統合ソフトウェア開発環境では、Vitisビジョンライブラリ(以下、ビジョンライブラリ)をインクルードすることによって、画像処理の機能を持つIPを高位合成することができます。
本サイトでは、ビジョンライブラリのFilter2D_accel関数を例に、ラプラシアンフィルタを行う画像処理IPの高位合成を行いました。これまでの記事では、IPの構成やタイミングチャートを解説しています。
画像処理IPを静止画出力のアプリケーションと組み合わせて、実際にZynq上で画像処理した結果をディスプレイに表示しようと思います。静止画出力のアプリケーションの実装方法は以下の記事に掲載しています。
高位合成したIPをエクスポートし、Zynq上でブロックデザインを設計しましたので、本記事で紹介いたします。
- Vitisビジョンライブラリを初めて扱う
- ビジョンライブラリで高位合成したIPを使って、ブロックデザインの設計・実装する方法を知りたい
IPのエクスポートとVivadoへのインポート
IPのエクスポート
前回の記事で、ビジョンライブラリを利用して画像処理を行うIPを高位合成しました。
高位合成したRTLをIPの形でエクスポートし、Vivadoのブロックデザインで利用していきます。
前記事では、高位合成の完了後、その結果をC/RTL協調シミュレーションで確認しました。
高位合成したRTL記述をIPにエクスポートしました。図の通り、[▶]をクリックし、[Export RTL]を選択します。

新しく[Export RTL]ダイアログボックスが立ち上がります。出力フォーマットなどの設定を行い、[OK]をクリックします。今回、特に変更するところはなかったので、そのままOKしました。

もし、Y2K22問題により、出力エラーが発生する方は、以下の記事の通り修正パッチを当てて対応ください。
11秒程度でRTL出力が完了しました。

エクスポートされたIPは以下のパスにあります。

エクスポートされたIPは
PROJECT\solution1\impl\ip
にZipファイルで存在します。ただし、PROJECTはVitis HLSプロジェクトを作成したパス。
Vivadoへのインポート
Vivadoを立ち上げて、このIPをプロジェクトにインポートします。
私の環境のVivado2021.1以降では、以下のフォーラムに報告されている問題が発生し、プロジェクトの処理を完了することができないので、バージョン2020.2のVivadoでブロックデザインを作成しました。
IPのインポートの方法は以前の記事にも記載していますので、関係する記述箇所のみを抜粋しておきます。
Vivadoプロジェクトを作成し、先程高位合成したハードウェアIPを読み込みます。
図のように、[IP Catalog]をProject Managerから選択し、クリックします。
[IP Catalog]上で、[Vivado Repository]を右クリックし、[Add Repositiory…]を選択します。

作成したハードウェアIPを選択します。
ハードウェアIPはVitis HLSプロジェクトの[solution1]>[impl]>[ip]フォルダに格納されているので、それを選択します。

レポジトリに追加されたら、次にブロックデザインに追加していきましょう。
ブロックデザインを立ち上げたら、右クリックで[Add IP]を選択し、作成したIPを選びます。

Vivadoでのデザイン設計
IPの実装イメージ
インポートしたIPをどのように他のビデオ出力系のモジュールと接続するかイメージを共有しておきます。
高位合成したIPには制御信号を入出力するためのバスと画像やフィルタといった配列を入出力するためのバスの2種類が用意されています。それぞれのバスには、プロセッサからのAXI4_Lite、メモリとDMA転送するAXI4を接続しようと思います。
加えて画像出力ロジックも実装します。画像出力ロジックは以前の記事で紹介した静止画出力アプリケーションで用いたものを流用します。ただし、以前はHDMI出力でしたが、今回はVGA出力としました。

実装は評価ボードZyboに行います。
作成したブロックデザイン
ブロックデザインをDefault ViewとInterface Viewそれぞれで示します(画像をクリックすると拡大します)。
Default View

Interface View

構成としては、静止画出力でDigilent社の「Zybo HDMI Output Demo」を読み込んで作成したブロックデザインをベースに作成しています。
ブロックデザインの解説
静止画出力のブロックデザインからの主な変更点は、
- HDMI出力をVGA出力に変更(rgb2dviをrgb2vgaに変更)
- 使っていないGPIO入出力(leds_4bits, sws_4bits, btns_4bits)を削除
- 高位合成したFilter2d_accel IPをインポート
です。Filter2d_accel IPとZynq PS部の接続は
- s_axi_controlとs_axi_control_rはPS部のM_AXI_GP0
- gmem0, gmem1, gmem2をPS部のS_AXI_HP0
に接続しています。GPとHPの違いは次の通りです。
手段 | 推奨する使い方 | スループット(Estimated) |
PL AXI_HP DMA | 大容量のデータセットをDMA形式で伝送 | 1,200 MB/s (複数のインタフェースそれぞれ) |
PL AXI_GP DMA | ・PLとPS間の制御信号の伝送 ・PS I/O ペリフェラルのアクセス | 600MB/s |
この比較表によると、以下のように設定するのが良いかと思います。
- ビデオの送受信は大容量かつ高速な伝送が求められるので、AXI4 Memory MapはHPポートに接続
- 制御信号やステータス信号をやり取りするAXI4-LITEのバスはGPポートに接続
GPとHPを次のブロック図のようにして使い分けをしています。

空間フィルタリング処理に必要な制御に用いる信号は、GPポートを介しAXI4-Liteのプロトコルでプロセッサから送信します。DDRメモリに格納する画像やフィルタの配列などの映像信号は、HPポートを介して直接メモリから読み出しています(DMA転送とは何か?)
次に、画像がどのような流れでメモリから外部ディスプレイまで流れていくかを、これもブロック図で示してみました。

画像とラプラシアンフィルタをメモリから読み出した後、空間フィルタリングをしてメモリに戻します。そのメモリをVDMA IPを使って読み出し、VGA出力することにしています。
この辺の処理は、img_outをメモリに送らず直接外部に出力することができそうなので、改善の余地があります。また、フィルタリングのタイミングと読み出しのタイミングをあまり考慮していないため、今のところ静止画ではうまくいっていますが、動画にしてリアルタイムに画像処理させる場合はもっとタイミングを考慮する必要があると思います
論理合成からXSAファイルの作成まで
それでは、ブロックデザインからVitisに読み込むためのXSAファイルの作成を行います。
といっても、以前の記事で紹介済みですので、改めて確認したい方は[+]マークから詳細をご確認ください。
ブロックデザインからHDL記述への変換
読み込んだブロックデザインをもとにHDL(ハードウェア言語)を作成します。
ブロックデザインのデザイン名(私の場合は[hdmi_out])を右クリックし、[Create HDL Wrapper …]を選択します。

論理合成、配置配線、bitstreamファイルの作成
[Generate Bitstream]をクリックし、論理合成、配置配線、bitstreamファイルの作成までを行います。

ハードウェアデザインのエクスポート(XSAファイルの作成)
[File]から[Export]>[Export Hardware…]を選択

立ち上がった新しいウィンドウ上で、エクスポートの設定を確認していきます。
まず、[Next]をクリックします。

[Include bitstream]を選択し、[Next]をクリックします。

ファイル名とエクスポート先を指定し、[Next]をクリックします。

最後に、[Finish]をクリックして完了です。

まとめ
本記事では、高位合成したFilter2D_accel IPを実際にブロックデザインに組み込んでいます。静止画出力のブロックデザインがそのまま流用できるのでとても楽な作業で済みました。次回は、アプリケーションのソースコードを作っていき、実際にディスプレイに映るかを試してみます。
最後までご覧いただきありがとうございました!
参考:開発環境
- 開発用PC: Windows 10, 64bit
- Vitis コア開発キット – 2021.2
- Vivado – 2020.2
コメント