联合体 - 2022.1 Chinese

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

Document ID
UG1399
Release Date
2022-06-07
Version
2022.1 简体中文

在以下代码示例中,已创建含 doublestruct 的联合体 (union)。不同于 C/C++ 编译,综合并不保证针对 union 中的所有字段使用相同存储器(对于综合,则不保证使用相同寄存器)。Vitis HLS 通过执行最优化来提供最优硬件。

#include "types_union.h"

dout_t types_union(din_t N, dinfp_t F)
{
 union {
    struct {int a; int b; } intval;
    double fpval;
 } intfp;
 unsigned long long one, exp;

 // Set a floating-point value in union intfp
 intfp.fpval = F;

 // Slice out lower bits and add to shifted input
 one = intfp.intval.a;
 exp = (N & 0x7FF);

 return ((exp << 52) + one) & (0x7fffffffffffffffLL);
}

Vitis HLS 支持:

  • 顶层函数接口上的联合体。
  • 重新解读指针以供综合。因此,联合体不能保存不同类型的指针,也不能保存指向不同类型的阵列的指针。
  • 通过其它变量访问联合体。同样使用上述示例中的联合体,不支持:
    for (int i = 0; i < 6; ++i)
    if (i<3) 
     A[i] = intfp.intval.a + B[i];
     else
     A[i] = intfp.intval.b + B[i];
    }
  • 但可将其显式重编码为:
     A[0] = intfp.intval.a + B[0];
     A[1] = intfp.intval.a + B[1];
     A[2] = intfp.intval.a + B[2];
     A[3] = intfp.intval.b + B[3];
     A[4] = intfp.intval.b + B[4];
     A[5] = intfp.intval.b + B[5];

对联合体进行综合不支持原生 C/C++ 类型与用户定义的类型之间进行强制类型转换。

Vitis HLS 设计中,联合体常用于转换原始位元的数据类型。通常在顶层端口接口处使用浮点值时,需使用此原始位元转换。请参阅以下示例:

typedef float T;
unsigned int value; // the "input"€ of the conversion
T myhalfvalue; // the "output" of the conversion
union
{
  unsigned int as_uint32;
  T as_floatingpoint;
} my_converter;
my_converter.as_uint32 = value;
myhalfvalue = my_converter. as_floatingpoint;

这种类型的代码适用于 C/C++ 语言的浮点 (float) 数据类型,通过修改还可用于双精度 (double) 数据类型。将 typedefint 更改为 short 对于 half 数据类型无效,但由于 half 属于类,因此在联合体中无法使用。可改用以下代码:

typedef half T;
short value;
T myhalfvalue = static_cast<T>(value);

同样,相反方式的转换使用的是 value=static_cast<ap_uint<16> >(myhalfvalue)static_cast< unsigned short >(myhalfvalue)

ap_fixed<16,4> afix = 1.5;
ap_fixed<20,6> bfix = 1.25;
half ahlf = afix.to_half();
half bhlf = bfix.to_half();

另一种方法是使用帮助程序类 fp_struct<half> 来通过 data()to_int() 方法进行转换。使用 hls/utils/x_hls_utils.h 头文件。