集約されたメモリ マップド インターフェイス
これは、 m_axi
インターフェイスの AGGREGATE プラグマまたは指示子の例です。次は、GitHub で公開されている aggregation_of_m_axi_ports の例です。
struct A {
char foo; // 1 byte
short bar; // 2 bytes
};
int dut(A* arr) {
#pragma HLS interface m_axi port=arr depth=10
#pragma HLS aggregate variable=arr compact=auto
int sum = 0;
for (unsigned i=0; i<10; i++) {
auto tmp = arr[i];
sum += tmp.foo + tmp.bar;
}
return sum;
}
上記の例では、m_axi
インターフェイス ポート arr
のサイズは 3 バイト (または 24 ビット) ですが、AGGREGATE
compact=auto
プラグマのため、ポートのサイズは最も近い 2 のべき乗の 4 バイト (または 32 ビット) にアライメントされます。Vitis HLS は、ログ ファイルに次のメッセージを表示します。
INFO: [HLS 214-241] Aggregating maxi variable 'arr' with compact=none mode in 32-bits (example.cpp:19:0)
AGGREGATE
プラグマが指定されている場合にのみ表示されます。ただし、プラグマがなくても、ツールは自動的に集約し、AXI インターフェイス ポートのデフォルト動作として、arr
インターフェイス ポートを 4 バイトにパディングします。インターフェイスの集約構造体
これは、ap_fifo
インターフェイスの AGGREGATE プラグマまたは指示子の例です。次は、GitHub で公開されている aggregation_of_struct の例です。
struct A {
int myArr[3]; // 4 bytes per element (12 bytes total)
ap_int<23> length; // 23 bits
};
int dut(A arr[N]) {
#pragma HLS interface ap_fifo port=arr
#pragma HLS aggregate variable=arr compact=auto
int sum = 0;
for (unsigned i=0; i<10; i++) {
auto tmp = arr[i];
sum += tmp.myArr[0] + tmp.myArr[1] + tmp.myArr[2] + tmp.length;
}
return sum;
}
ap_fifo
インターフェイスの場合、構造体はビット レベルで、集約プラグマの有無に関係なくパックされます。
上記の例では、AGGREGATE
プラグマにより、arr
ポートにサイズ 119 ビットのポートが作成されます。myArr
配列は 12 バイト (96 ビット) で、length
要素は 23 ビットで合計 119 ビットになります。Vitis HLS は、ログ ファイルに次のメッセージを表示します。
INFO: [HLS 214-241] Aggregating fifo (array-to-stream) variable 'arr' with compact=bit mode
in 119-bits (example.cpp:19:0)
集約型のネストされた構造体ポート
これは、Vivado IP フローの AGGREGATE プラグマまたは指示子の例です。次は、GitHub で公開されている aggregation_of_m_axi_ports の例です。
#define N 8
struct T {
int m; // 4 bytes
int n; // 4 bytes
bool o; // 1 byte
};
struct S {
int p; // 4 bytes
T q; // 9 bytes
};
void top(S a[N], S b[N], S c[N]) {
#pragma HLS interface bram port=c
#pragma HLS interface ap_memory port=a
#pragma HLS aggregate variable=a compact=byte
#pragma HLS aggregate variable=b compact=bit
#pragma HLS aggregate variable=c compact=byte
for (int i=0; i<N; i++) {
c[i].q.m = a[i].q.m + b[i].q.m;
c[i].q.n = a[i].q.n - b[i].q.n;
c[i].q.o = a[i].q.o || b[i].q.o;
c[i].p = a[i].q.n;
}
}
上記の例では、compact=byte
オプションが AGGREATE プラグマで指定されたので、集約アルゴリズムによってサイズが 104 ビットの a
ポートと c
ポートが作成されますが、b
ポートの場合デフォルトの compact=bit
オプションが使用され、パック サイズは 97 ビットになります。ネストされた構造体 S
と T
は、3 つの 32 ビットのメンバー変数 (p、m、および n) と 1 つのビット/バイトのメンバー変数 (o
) を含めるように集約されます。
b
ポートが自動的に m_axi
ポートとして推論され、compact=bit
設定は許可されません。INFO: [HLS 214-241] Aggregating bram variable 'b' with compact=bit mode in 97-bits (example.cpp:19:0)
INFO: [HLS 214-241] Aggregating bram variable 'a' with compact=byte mode in 104-bits (example.cpp:19:0)
INFO: [HLS 214-241] Aggregating bram variable 'c' with compact=byte mode in 104-bits (example.cpp:19:0)