最適な垂直たたみ込み
垂直たたみ込みでは、FPGA 向けのストリーミング データ モデルを記述するのが困難です。データには列ごとにアクセスする必要がありますが、画像全体を格納するのは望ましくありません。ソリューションは、次の図に示すようにライン バッファーを使用することです。

先ほどと同様、サンプルはストリーミング方式で読み込まれますが、この場合は hls::stream の hconv から読み込まれます。このアルゴリズムでは、最初のサンプルを処理するのに少なくとも K-1 行のデータが必要です。この前に実行される計算はすべて、条件を使用することにより破棄します。
ライン バッファーには、K-1 行のデータを格納できます。新しいサンプルが読み込まれるたびに、別のサンプルがライン バッファーから排出されます。つまり、最新のサンプルが計算に使用されると、そのサンプルがライン バッファーに格納され、古いサンプルが排出されます。これにより、K-1 行のみをキャッシュすればよく、ローカル ストレージの使用が最小限に抑えられます。ライン バッファーにはローカルで格納するために複数行が必要ですが、たたみ込みのカーネル サイズ K はフル ビデオ画像の 1080 行よりもかなり小さくなります。
最初の計算は、K 行目にある最初のサンプルが読み込まれると実行されます。その後、最後のピクセルが読み込まれるまで値が出力されます。
// Vertical convolution
phconv=hconv_buffer; // set/reset pointer to start of buffer
pvconv=vconv_buffer; // set/reset pointer to start of buffer
VConvH:for(int col = 0; col < height; col++) {
VConvW:for(int row = 0; row < vconv_xlim; row++) {
#pragma HLS DEPENDENCE variable=linebuf inter false
#pragma HLS PIPELINE
T in_val = *phconv++;
// Reset pixel value on-the-fly - eliminates an O(height*width) loop
T out_val = 0;
VConv:for(int i = 0; i < K; i++) {
T vwin_val = i < K - 1 ? linebuf[i][row] : in_val;
out_val += vwin_val * vcoeff[i];
if (i > 0)
linebuf[i - 1][row] = vwin_val;
}
if (col >= K - 1) {
*pvconv++ = out_val;
}
}
上記のコードでは、デザインのサンプルがすべてストリーミング方式で処理されます。タスクは、継続して実行されます。再読み出し (または再書き込み) の回数を最小限に抑えるコーディング スタイルに従う場合、データをローカルでキャッシュする必要があります。これは、FPGA をターゲットにする場合の理想的なストラテジです。