ポインターは C/C++ コードで広範囲に使用され、合成でもサポートされていますが、コード内でのポインターの使用は避けることをお勧めします。これは、次の状況でポインターを使用する場合に特に当てはまります。
- ポインターが同じ関数内で複数回アクセス (読み出しまたは書き込み) される場合。
- ポインター配列を使用する場合、各ポインターが別のポインターではなく、スカラーまたはスカラー配列を指定する必要あり。
- ポインターの型変換は標準 C/C++ 型間の変換の場合にのみサポートあり。
注記: ポインター ツー ポイントはサポートされません。
次のコード例に、複数のオブジェクトをポイントするポインターの合成サポートを示します。
#include "pointer_multi.h"
dout_t pointer_multi (sel_t sel, din_t pos) {
static const dout_t a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
static const dout_t b[8] = {8, 7, 6, 5, 4, 3, 2, 1};
dout_t* ptr;
if (sel)
ptr = a;
else
ptr = b;
return ptr[pos];
}
Vitis HLS のポインター トゥ ポインターは合成ではサポートされますが、最上位インターフェイスでは (最上位関数への引数としては) サポートされません。ポインター トゥ ポインターを複数の関数で使用する場合、Vitis HLS でポインター トゥ ポインターを使用する関数すべてがインライン展開されます。複数の関数をインライン展開すると、実行時間が長くなります。
#include "pointer_double.h"
data_t sub(data_t ptr[10], data_t size, data_t**flagPtr)
{
data_t x, i;
x = 0;
// Sum x if AND of local index and pointer to pointer index is true
for(i=0; i<size; ++i)
if (**flagPtr & i)
x += *(ptr+i);
return x;
}
data_t pointer_double(data_t pos, data_t x, data_t* flag)
{
data_t array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
data_t* ptrFlag;
data_t i;
ptrFlag = flag;
// Write x into index position pos
if (pos >=0 & pos < 10)
*(array+pos) = x;
// Pass same index (as pos) as pointer to another function
return sub(array, 10, &ptrFlag);
}
ポインターの配列も合成できます。次のコード例では、ポインターの配列がグローバル配列の 2 次元の開始位置を格納するために使用されています。ポインターの配列内のポインターは、スカラーまたはスカラーの配列のみを指定でき、ほかのポインターを指定することはできません。
#include "pointer_array.h"
data_t A[N][10];
data_t pointer_array(data_t B[N*10]) {
data_t i,j;
data_t sum1;
// Array of pointers
data_t* PtrA[N];
// Store global array locations in temp pointer array
for (i=0; i<N; ++i)
PtrA[i] = &(A[i][0]);
// Copy input array using pointers
for(i=0; i<N; ++i)
for(j=0; j<10; ++j)
*(PtrA[i]+j) = B[i*10 + j];
// Sum input array
sum1 = 0;
for(i=0; i<N; ++i)
for(j=0; j<10; ++j)
sum1 += *(PtrA[i] + j);
return sum1;
}
ポインターの型変換は、ネイティブ C/C++ 型が使用される場合に合成でサポートされます。次のコード例では、int
型が char
型に変換されています。
#define N 1024
typedef int data_t;
typedef char dint_t;
data_t pointer_cast_native (data_t index, data_t A[N]) {
dint_t* ptr;
data_t i =0, result = 0;
ptr = (dint_t*)(&A[index]);
// Sum from the indexed value as a different type
for (i = 0; i < 4*(N/10); ++i) {
result += *ptr;
ptr+=1;
}
return result;
}
Vitis HLS では、一般的なデータ型間のポインター型変換はサポートされません。たとえば、符号付きの値の struct
複合型が作成されると、ポインターを型変換して符号なしの値を代入することはできません。
struct {
short first;
short second;
} pair;
// Not supported for synthesis
*(unsigned*)(&pair) = -1U;
このような場合、値はネイティブ型を使用して代入する必要があります。
struct {
short first;
short second;
} pair;
// Assigned value
pair.first = -1U;
pair.second = -1U;