指针在 C/C++ 语言代码中使用广泛,也支持用于综合,但通常建议避免在代码中使用指针。在以下情况下使用指针时尤其如此:
- 在同一函数内多次访问(读取或写入)指针时。
- 使用指针阵列时,每个指针都必须指向 1 个标量或标量阵列(而不是另一指针)。
- 仅支持标准 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);
}
指针阵列同样可进行综合。请参阅以下代码示例,其中使用指针阵列来存储全局阵列的第二维度的起始位置。指针阵列中的指针只能指向标量或标量阵列,不能指向其他指针。
#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;