Vitis Model Composer の SUPPORTS_STREAMING
プラグマは、関数の配列パラメーターがストリーミング データをサポートすることを示します。配列の各要素は厳密な順序で 1 回ずつアクセスされ、デザインが Model Composer でストリーミング データ用に最適化されます。SUPPORTS_STREAMING
プラグマが指定された関数のスカラーでない引数は、ランダムにアクセスすることはできません。
次の例に、ランダム アクセスと順次アクセスの違いを示します。create_transform_matrix
関数の transform_matrix
出力配列は、ランダムにアドレス指定されます。まず transform_matrix
の最後の行にアクセスし、次に最初の行および 2 番目の行にアクセスします。そのため、ブロックでストリーミング データをサポートすることはできません。
void create_transform_matrix(const float angle, const float center_x,
const float center_y, float transform_matrix[3][3]) {
float a = hls::cosf(angle);
float b = hls::sinf(angle);
transform_matrix[2][0] = 0;
transform_matrix[2][1] = 0;
transform_matrix[2][2] = 0;
transform_matrix[0][0] = a;
transform_matrix[0][1] = b;
transform_matrix[0][2] = (1-a)*center_x-b*center_y;
transform_matrix[1][0] = -b;
transform_matrix[1][1] = a;
transform_matrix[1][2] = b*center_x +(1-a)*center_y;
}
この関数でストリーミング データがサポートされるようにするには、次に示すように、transform_matrix
出力配列が順にアドレス指定されるように変更します。
#pragma XMC SUPPORTS_STREAMING
void create_transform_matrix(const float angle, const float center_x,
const float center_y, float transform_matrix[3][3]) {
float a = hls::cosf(angle);
float b = hls::sinf(angle);
transform_matrix[0][0] = a;
transform_matrix[0][1] = b;
transform_matrix[0][2] = (1-a)*center_x-b*center_y;
transform_matrix[1][0] = -b;
transform_matrix[1][1] = a;
transform_matrix[1][2] = b*center_x +(1-a)*center_y;
transform_matrix[2][0] = 0;
transform_matrix[2][1] = 0;
transform_matrix[2][2] = 0;
}
上記の例に示すように、C または C++ ヘッダー ファイルの関数宣言の前に
SUPPORTS_STREAMING
プラグマを追加して、インポートした関数がストリーミングをサポートするようにします。#pragma XMC SUPPORTS_STREAMING
関数に順次アクセスされる配列引数が含まれているが SUPPORTS_STREAMING
が指定されていない場合、そのブロックを使用するサブシステムはストリーミング アーキテクチャではインプリメントされません。そのため、関数のパフォーマンスは最適化されません。
重要: 関数の配列引数がランダムな順序でアクセスされる場合は、
SUPPORTS_STREAMING
プラグマは指定しないでください。指定すると、出力の生成時またはデザインの検証時にエラーが返されます。次に、配列引数が厳密な順序でアクセスされ、データのストリーミングがサポートされる関数の例を示します。この関数は、入力画像の行を水平方向に反転します。入力画像に順次アクセスし、入力画像の 2 行を循環バッファーに格納します。2 行がバッファーに格納されると、バッファーの内容を関数引数に順番に書き込みます。この関数ではストリーミングがサポートされるので、
SUPPORTS_STREAMING
プラグマを使用してそれを指定します。#ifndef _MY_FUNCS
#define _MY_FUNCS
#include <stdint.h>
#pragma XMC INPORT in1
#pragma XMC OUTPORT out1
#pragma XMC SUPPORTS_STREAMING
#pragma XMC BUFFER_DEPTH 4+2*WIDTH
// This function reverses each of the rows of the input image.
template<int WIDTH, int HEIGHT>
void
flip(uint8_t in1[HEIGHT][WIDTH],
uint8_t out1[HEIGHT][WIDTH])
{
#pragma HLS dataflow
uint8_t buf[2][WIDTH];
int readBuf = 0;
int writeBuf = 0;
for (int row = 0; row < HEIGHT + 2; ++row) {
for (int col = 0; col < WIDTH; ++col) {
#pragma HLS DEPENDENCE array inter false
#pragma HLS PIPELINE II=1
if (row < HEIGHT) {
buf[writeBuf][col] = in1[row][col];
if (col == WIDTH-1) {
++writeBuf;
writeBuf = (3 == writeBuf) ? 0 : writeBuf;
}
}
if (row > 1) {
out1[row - 2][col] = buf[readBuf][WIDTH- 1 - col];
if (col == WIDTH-1) {
++readBuf;
readBuf = (3 == readBuf) ? 0 : readBuf;
}
}
}
}
}
#endif