前回、Vivado HLS上でC言語の行列積関数を記述し、それをテストするところまで確認した。今回はこれを論理合成し、C言語とRTLのCosimulationを実施しよう。
Vivado HLSを使用してC言語の関数を論理合成する
論理合成はツールバーから[Run C Synthesis]をクリックした。これだけで一応完成する。
Vivado HLSを使用してC言語の関数と合成語のRTLをCosimulationする
これも、ボタンを一つクリックするだけで良い。ツールバーから[Run C/RTL Cosimulation]をクリックする。ダイアログボックスが出てくるが、特に何も設定しない。
特に問題無くシミュレーションが成功すれば、Finished C/RTL Cosimulation
と表示される。これでIPの開発は終了だ。簡単だ!
開発した回路をExportとしてVivadoで使用できるIPに変換する
さて、せっかく作成した回路なので、Vivadoにエクスポートして、Zynq FPGAのPL部分にインプリし、ARMから制御できるようにしたい。 このためにはどうすれば良いのだろうか?
まず考えられるのは、足回りを調整しなければならないこと。この行列積演算関数では引数を3つ取っており、2つが入力用、1つが出力用だ。
void matrix_mul (const float matrix_a[8][8], const float matrix_b[8][8], float matrix_c[8][8])
これがそのままでは、PL部にAXIのインタフェースを持って接続できないので、これを変換しなければならない。このためには、開発したプログラムにDirectiveを追記し、AXIに変換されるように調整してやる必要がある。
設定しなければならないことは、
- この関数がどのようなインタフェースを持つのか --> AXI Slaveのインタフェース1つのみ
- この関数はどのような引数を取るのか --> 2つの入力、1つの出力。これを1つのAXI Slaveのインタフェースで共有する
ということになる。これをIPの情報として設定し、IPに変換される際にAXIのインタフェースが所望の形になるように調整してやらなければならない。
Vivado HLS上で、開発したIPのインタフェースディレクティブを指定する
まずは、各引数に設定を行っていこう。まずはmatrix_hls.cpp
をVivado HLS上で開き、右側のペインにあるDirective
をクリックする。
matrix_a
を右クリックし、Insert Directive
をクリックする。
ダイアログボックスが表示される。
以下のように設定する。Directive
をINTERFACE
に設定し、mode(optional)
をs_axilite
、bundle(optional)
をslv0
に設定する。
これを全ての引数matrix_a, matrix_b, matrix_c
に対して同様に設定する。
ここで、bundle(optional)
を全て同様の値に設定することで、同一のAXIインタフェースを利用することを指定している(と思う)。
いろいろ調べたのだが、以下のビデオで設定していたので設定してみると、所望の構造でIPが生成されたので良しとする。
Vivado HLS デザインに AXI4 インターフェイスを指定
Vivado IP カタログから使用できるように Vivado HLS IP をパッケージ化
さらに、関数そのものである、matrix_hls
を右クリックし、Insert Directive
をクリックする。
こちらも同様に設定をする。こちらにも、Bundle名としてslv0を設定する。まあ良く見てみると、return文に対する指定っぽいので、ここで指定する必要は無いみたいだが。
これで設定完了だ。ツールバーから[Export RTL]をクリックしてIPをエクスポートする。
生成されたディレクトリから、ip --> verilog --> matrix_mul.v
を開くと、一つのAXIインタフェースs_axi_slv0_xxx
が定義されていることが分かる。
これでIPの設定は完了だ。次は、これをVivadoにIPとしてインポートしよう。