void cnn( int *pixel, // Input pixel
int *weights, // Input Weight Matrix
int *out, // Output pixel
... // Other input or Output ports
上記の例では、カーネル関数に pixel
、weights
、out
というの 3 つのポインターが含まれます。デフォルトでは、Vitis コンパイラによりこれら 3 つのパラメーターは同じ AXI4 インターフェイス (m_axi
) にマップされます。
コンパイラで推論されるデフォルトのインターフェイス マップは、次の INTERFACE プラグマと同等です。
#pragma HLS INTERFACE m_axi port=pixel offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=out offset=slave bundle=gmem
INTERFACE プラグマの bundle
キーワードは、ポート名を定義します。Vitis コンパイラにより各バンドル名に対してポートが作成され、1 つの AXI インターフェイス (m_axi_gmem
) を使用するカーネル オブジェクト (XO) ファイルにコンパイルされます。同じ bundle
名を別のインスタンスに使用した場合は、それらのインターフェイスが同じポートにマップされます。
gmem
はグローバル メモリを表しますが、これはキーワードではなく、一貫性を保つために使用されています。バンドルには、任意の名前を使用できます。ポートを共有すると、AXI インターフェイスを取り除くことにより FPGA リソースを節約できますが、すべてのメモリ転送が 1 つのポートを介して実行されるので、カーネルのパフォーマンスが制限される可能性があります。m_axi
ポートには独立した読み出しチャネルと書き込みチャネルがあるので、1 つの m_axi
ポートで読み出しと書き込みを同時に実行できます。カーネルの帯域幅とスループットは、複数のポートを作成し、異なるバンドル名を使用して、複数のメモリ バンクに接続することにより増加できます。
pragma HLS interface
に説明されているように、INTERFACE の設定用に多数のオプションがあります。コードで INTERFACE プラグマを手動で定義するのには、次のような理由が考えられます。
- INTERFACE プラグマのバンドルを指定して、AXI 信号を別のバンドルに分ける。
- インターフェイスの幅をデフォルトの int = 64 バイト (512 ビット) 以外に設定する。
- バースト トランザクション用に AXI プロパティを指定する。
void cnn( int *pixel, // Input pixel
int *weights, // Input Weight Matrix
int *out, // Output pixel
... // Other input or Output ports
#pragma HLS INTERFACE m_axi port=pixel offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi port=out offset=slave bundle=gmem
上記の例の場合、2 つの bundle
名が gmem
と gmem1
の 2 つのポートを作成します。カーネルは gmem
ポートを介して pixel
および out
にアクセスしますが、weights
には gmem1
ポートを介してアクセスされます。このため、カーネルが pixel
と weights
に並列にアクセスできるようになるので、カーネルのスループットが改善される可能性があります。
bundle=
で名前を指定する場合は、connectivity.sp オプションを使用して特定のメモリ バンクに割り当てることができるように、すべて小文字を使用してください。
v++
コンパイル中に INTERFACE プラグマが使用されると、2 つの AXI インターフェイス (m_axi_gmem
および m_axi_gmem1
) を含むコンパイル済みのカーネル オブジェクト (XO) ファイルが作成され、必要に応じてグローバル メモリに接続できます。カーネル ポートのメモリへのマップ で説明するようにリンク中にコンフィギュレーション ファイルで connectivity.sp オプションを使用すると、別のインターフェイスを異なるメモリ バンクにマップできます。