指针 - 2023.2 简体中文

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文

指针在 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;