集約の例 - 2023.2 日本語

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 日本語

集約されたメモリ マップド インターフェイス

これは、 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 ビットになります。ネストされた構造体 ST は、3 つの 32 ビットのメンバー変数 (p、m、および n) と 1 つのビット/バイトのメンバー変数 (o) を含めるように集約されます。

ヒント: この例では、Vivado IP フローを使用して集約動作を示します。Vitis カーネル フローでは、b ポートが自動的に m_axi ポートとして推論され、compact=bit 設定は許可されません。
Vitis HLS は、ログ ファイルに次のメッセージを表示します。
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)