compute()
引数では、すべての基本 C++ データ型 (bool
、char
、int
、short
、long
、float
、double
) がサポートされています。signed
、unsigned
、short
、long
などの C++ 型修飾子もサポートされています 。
また、Vitis HLS ツールの任意精度データ型に示すように、ap_int<N>
および ap_uint<N>
などの任意精度データ型もサポートされます。ap_int
および ap_uint
は、Vitis HLS で事前定義されたデータ型です (N は最大 1024 の整数)。これにより、より細かいビット幅を制御して、特にデータ パッキングを処理したり、グローバル メモリ データバス幅に合わせることがでます。
compute()
インターフェイス引数は、次に説明するようにスカラー型またはバッファー型の引数に分類できます。
スカラー型
スカラー引数は、compute()
呼び出しに渡される単一のワードを表す基本データ型です。VSC は、前述の基本データ型のいずれかが compute()
の値渡し引数として使用される場合、スカラー引数型を推論します。たとえば、ここでの compute(int size,
float value);
の size
と value
は、スカラーです。
ユーザー定義の C 構造体は、次の規則に従って、値渡しのスカラー引数として使用できます。
-
int field_x:4;
のように、構造体に C++ ビット指示子を持つフィールドを含めることはできません。 - 構造体には、
int* ptr_field;
のようなポインター フィールドを含めることはできません。 - 構造体の合計バイト サイズは、厳密に 2 のべき乗である必要があります。そうでない場合は、残りのバイト数を入力するためにダミー フィールドを宣言する必要があります (例:
char pad[remainder]
)。
compute(int size, float& result_value) // reference argument is not allowed
ただし、PE 関数の引数がまだ参照である場合は、参照の代わりに C++ ポインター型を使用できます。次に例を示します。
my_acc::compute(int inp, data_t *out_p) { // reference not allowed
my_PE(inp, *out_p); // deref the ptr for my_PE out_ref
my_PE_two(inp ... ); // passing inp to multiple PEs is allowed
}
my_acc::my_PE(int in, data_t &out_ref) { // reference is allowed
...
// application code
my_acc::send_while ... { ...
out_p = my_acc::alloc_buf(bp, 1); // required
my_acc::compute(inp, out_p);
VSC は、次のすべての条件が適用される場合に、この出力引数 out_p
のスカラーを推論します。
- 1 つのエレメントのみを指定している必要があります。
- カーネル コードは、
*out_p = result;
のように、1 つの値を書き込みます。 - この引数には VSC ガイダンス マクロが指定されていません。
compute()
のスカラー引数は、複数の PE に渡すことができます。ハードウェアでは、1 つの AXI4-Lite ポートが、このスカラー引数を使用するすべての PE 関数の個々のスカラー レジスタを駆動します。
バッファー型
バッファーは、compute()
関数へのポインターまたは配列引数で、1 つ以上の要素を保持できます。バッファーの内容は、対応するプラットフォーム インターフェイス (SYS_PORT
接続) に基づいてデバイスとの間で転送されます。ポインターまたは配列引数のベース (要素) 型は、前のセクションで説明した任意の基本データ型にできます。また、ユーザー定義の C 構造体データ型も基本要素型として使用できます。
alloc_buf
) を呼び出すアプリケーション コードが必要です。ポインターまたは配列のベース型として C 構造体を使用する場合は、次の規則が適用されます。
-
int field_x:4;
のように、構造体に C++ ビット指示子を持つフィールドを含めることはできません。 - 構造体には、
int* ptr_field;
のようなポインター フィールドを含めることはできません。
const, register, volatile
など) は、compute()
インターフェイスでは使用できません。次は、使用できる例と使用できない例の両方の、バッファー型引数のコーディング スタイルを示しています。
// accelerator interface
my_acc::compute(int A, int *B, int C[10]) {
...
// application code
int S, *BB, *CC;
my_acc::send_while ... { ...
BB = my_acc::alloc_buf( ... ); // required
CC = my_acc::alloc_buf( ... ); // required
compute (S, AA, BB);
上記の例では、compute()
がアプリケーション コードの引数 A と引数 B を同じように処理するため、これらのバッファー引数にメモリを割り当てる必要があります。
compute()
のバッファー引数は、その中の単一の PE 関数にのみ渡すことができます。この例では、A はスカラー入力引数です。呼び出し元は、compute()
呼び出しに整数の引数を渡すだけで、値が AXI4-Lite を使用してデバイスに転送されます。一方、B と C はバッファー引数で、入力、出力、双方向、またはリモートのいずれかになります。呼び出し元は、alloc_buf()
を使用してこのバッファーにメモリを割り当てる必要があります。