类方法、运算符和数据成员 - 2023.2 简体中文

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

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

一般情况下,支持针对 ap_[u]fixed 类型使用运算符重载来执行在原生 C/C++ 整数数据类型上执行的任意有效操作。除这些重载运算符外,还包含部分特定于类的运算符和方法以简化位级运算。

二进制算术运算符

加法

ap_[u]fixed::RType ap_[u]fixed::operator + (ap_[u]fixed op)

以任意精度定点加上给定操作数 op

该操作数可采用以下任一整数类型:

  • ap_[u]fixed
  • ap_[u]int
  • C/C++

返回类型 ap_[u]fixed::RType 取决于 2 个操作数的类型信息。

ap_fixed<76, 63> Result;

ap_fixed<5, 2> Val1 = 1.125;
ap_fixed<75, 62> Val2 = 6721.35595703125;

Result = Val1 + Val2; //Yields 6722.480957

由于 Val2 的整数部分和小数部分位宽均较大,因此返回类型采用相同位宽加 1 以便存储所有可能的结果值。

指定数据宽度可通过使用幂函数来控制资源,如下所示。在此类情况下,AMD 建议指定存储的结果的宽度,而不是指定定点运算的宽度。

ap_ufixed<16,6> x=5; 
ap_ufixed<16,7>y=hl::rsqrt<16,6>(x+x); 

减法

ap_[u]fixed::RType ap_[u]fixed::operator - (ap_[u]fixed op)

以任意精度定点减去给定操作数 op

返回类型 ap_[u]fixed::RType 取决于 2 个操作数的类型信息。

ap_fixed<76, 63> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Result = Val2 - Val1; // Yields 6720.23057

由于 Val2 的整数部分和小数部分位宽均较大,因此返回类型采用相同位宽加 1 以便存储所有可能的结果值。

乘法

ap_[u]fixed::RType ap_[u]fixed::operator * (ap_[u]fixed op)

以任意精度定点乘以给定操作数 op

ap_fixed<80, 64> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Result = Val1 * Val2; // Yields 7561.525452

这将显示 Val1Val2 的乘法。返回类型为其整数部分位宽与其小数部分位宽之和。

除法

ap_[u]fixed::RType ap_[u]fixed::operator / (ap_[u]fixed op)

以任意精度定点除以给定操作数 op

ap_fixed<84, 66> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Val2 / Val1; // Yields 5974.538628

这将显示 Val2Val1 的除法。为保留足够精度:

  • 返回类型的整数位宽为 Val2 的整数位宽与 Val1 的小数位宽之和。
  • 返回类型的小数位宽等于 Val2 的小数位宽。

按位逻辑运算符

按位 OR

ap_[u]fixed::RType ap_[u]fixed::operator | (ap_[u]fixed op)

对任意精度定点和给定操作数 op 应用按位运算。

ap_fixed<75, 62> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Result = Val1 | Val2; // Yields 6271.480957

按位 AND

ap_[u]fixed::RType ap_[u]fixed::operator & (ap_[u]fixed op)

对任意精度定点和给定操作数 op 应用按位运算。

ap_fixed<75, 62> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Result = Val1 & Val2;  // Yields 1.00000

按位 XOR

ap_[u]fixed::RType ap_[u]fixed::operator ^ (ap_[u]fixed op)

对任意精度定点和给定操作数 op 应用 xor 按位运算。

ap_fixed<75, 62> Result;

ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;

Result = Val1 ^ Val2; // Yields 6720.480957

增量运算符和减量运算符

递增前

ap_[u]fixed ap_[u]fixed::operator ++ ()

此运算符函数前缀会将任意精度定点变量加 1

ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;

Result = ++Val1; // Yields 6.125000

递增后

ap_[u]fixed ap_[u]fixed::operator ++ (int)

此运算符函数后缀:

  • 会将任意精度定点变量加 1
  • 返回此任意精度定点的原始 val。
    ap_fixed<25, 8> Result;
    ap_fixed<8, 5> Val1 = 5.125;
    
    Result = Val1++; // Yields 5.125000

递减前

ap_[u]fixed ap_[u]fixed::operator -- ()

此运算符函数前缀会将任意精度定点变量减 1

ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;

Result = --Val1; // Yields 4.125000

递减后

ap_[u]fixed ap_[u]fixed::operator -- (int)

此运算符函数后缀:

  • 会将任意精度定点变量减 1
  • 返回此任意精度定点的原始 val。
    ap_fixed<25, 8> Result;
    ap_fixed<8, 5> Val1 = 5.125;
    
    Result = Val1--; // Yields 5.125000

一元运算符

加法

ap_[u]fixed ap_[u]fixed::operator + ()

返回任意精度定点变量的自拷贝。

ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;

Result = +Val1;  // Yields 5.125000

减法

ap_[u]fixed::RType ap_[u]fixed::operator - ()

返回任意精度定点变量的负值。

ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;

Result = -Val1; // Yields -5.125000

等于 0

bool ap_[u]fixed::operator ! ()

此运算符函数:

  • 将任意精度定点变量与 0 比较,
  • 返回结果。
    bool  Result;
    ap_fixed<8, 5> Val1 = 5.125;
    
    Result = !Val1; // Yields false

按位反转

ap_[u]fixed::RType ap_[u]fixed::operator ~ ()

返回任意精度定点变量的按位补码。

ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val1 = 5.125;

Result = ~Val1; // Yields -5.25

移位运算符

无符号的左移

ap_[u]fixed ap_[u]fixed::operator << (ap_uint<_W2> op) 

此运算符函数:

  • 按给定整数操作数左移。
  • 返回结果。

此操作数可采用以下 C/C++ 整数类型:

  • char
  • short
  • int
  • long

左移运算的返回类型与移位的类型的宽度相同。

注释: 移位不支持上溢或量化模式。
ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val = 5.375;

ap_uint<4> sh = 2;

Result = Val << sh; // Yields -10.5

结果的位宽为(W = 25I = 15)。由于左移运算返回类型与 Val 类型相同:

  • Val 的高阶 2 位将移出。
  • 结果为 -10.5。

如果需结果为 21.5,Val 必须首先强制转换为 ap_fixed<10, 7> - 例如,ap_ufixed<10, 7>(Val)

有符号的左移

ap_[u]fixed ap_[u]fixed::operator << (ap_int<_W2> op)

此运算符:

  • 按给定整数操作数左移。
  • 返回结果。

移位方向取决于操作数为正还是为负。

  • 如果操作数为正,则执行右移。
  • 如果操作数为负,则执行左移(反方向)。

此操作数可采用以下 C/C++ 整数类型:

  • char
  • short
  • int
  • long

右移运算的返回类型与移位的类型的宽度相同。

ap_fixed<25, 15,  false> Result;
ap_uint<8, 5> Val = 5.375;

ap_int<4> Sh = 2;
Result = Val << sh; // Shift left, yields -10.25

Sh = -2;
Result = Val << sh; // Shift right, yields 1.25

无符号的右移

ap_[u]fixed ap_[u]fixed::operator >> (ap_uint<_W2> op) 

此运算符函数:

  • 按给定整数操作数右移。
  • 返回结果。

此操作数可采用以下 C/C++ 整数类型:

  • char
  • short
  • int
  • long

右移运算的返回类型与移位的类型的宽度相同。

ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val = 5.375;

ap_uint<4> sh = 2;

Result = Val >> sh; // Yields 1.25

如需保留所有有效位,请首先扩展 Val 的小数部分的位宽,例如,ap_fixed<10, 5>(Val)

有符号的右移

ap_[u]fixed ap_[u]fixed::operator >> (ap_int<_W2> op) 

此运算符:

  • 按给定整数操作数右移。
  • 返回结果。

移位方向取决于操作数为正还是为负。

  • 如果操作数为正,则执行右移。
  • 如果操作数为负,则执行左移(反方向)。

此操作数可采用任一 C/C++ 整数类型(charshortintlong)。

右移运算的返回类型与移位的类型的宽度相同。例如:

ap_fixed<25, 15,  false> Result;
ap_uint<8, 5> Val = 5.375;

ap_int<4> Sh = 2;
Result = Val >> sh; // Shift right, yields 1.25

Sh = -2;
Result = Val >> sh; // Shift left,  yields -10.5

1.25

关系运算符

等于

bool ap_[u]fixed::operator == (ap_[u]fixed op)

此运算符会将任意精度定点变量与给定操作数进行比较。

如果两者相等,则返回 true;如果相等,则返回 false

op 操作数的类型可以是 ap_[u]fixedap_int 或 C/C++ 整数类型。例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 == Val2; // Yields  true
Result = Val1 == Val3; // Yields  false

不等于

bool ap_[u]fixed::operator != (ap_[u]fixed op)

此运算符会将此任意精度定点变量与给定操作数进行比较。

如果两者相等,则返回 true;如果相等,则返回 false

op 操作数的类型可以是:

  • ap_[u]fixed
  • ap_int
  • C 或 C++ 整数类型

例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 != Val2; // Yields false
Result = Val1 != Val3; // Yields true

大于或等于

bool ap_[u]fixed::operator >= (ap_[u]fixed op)

此操作数会将变量与给定操作数比较。

如果两者相等或者如果变量大于运算符,则返回 true,否则返回 false

op 操作数的类型可以是 ap_[u]fixedap_int 或 C/C++ 整数类型。

例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 >= Val2; // Yields true
Result = Val1 >= Val3; // Yields false

小于或等于

bool ap_[u]fixed::operator <= (ap_[u]fixed op)

此运算符会将变量与给定操作数比较,如果变量等于或小于操作数,则返回 true,否则返回 false

此 op 操作数的类型可以是 ap_[u]fixedap_int 或 C/C++ 整数类型。

例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 <= Val2; // Yields true
Result = Val1 <= Val3; // Yields true

大于

bool ap_[u]fixed::operator > (ap_[u]fixed op)

此运算符会将变量与给定操作数比较,如果变量大于运算符,则返回 true,否则返回 false

op 操作数的类型可以是 ap_[u]fixedap_int 或 C/C++ 整数类型。

例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 > Val2; // Yields false
Result = Val1 > Val3; // Yields false

小于

bool ap_[u]fixed::operator < (ap_[u]fixed op)

此运算符会将变量与给定操作数比较,如果变量小于运算符,则返回 true,否则返回 false

此 op 操作数的类型可以是 ap_[u]fixedap_int 或 C/C++ 整数类型。例如:

bool Result;

ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;

Result = Val1 < Val2; // Yields false
Result = Val1 < Val3; // Yields true

位运算符

位选择和位设置

af_bit_ref ap_[u]fixed::operator [] (int bit) 

此运算符从任意精度定点值中选择 1 个位,并将其返回。

返回的值为可用于设置或清除 ap_[u]fixed 变量中的对应位的参考值。位实参必须为整数值,它用于指定要选择的位的索引。最低有效位索引为 0。允许的最高索引是 ap_[u]fixed 变量的位宽减 1。

结果类型为 af_bit_ref,值为 01。例如:

ap_int<8, 5> Value = 1.375;

Value[3]; // Yields  1
Value[4]; // Yields  0

Value[2] = 1; // Yields 1.875
Value[3] = 0; // Yields 0.875

位范围

af_range_ref af_(u)fixed::range (unsigned Hi, unsigned Lo)
af_range_ref af_(u)fixed::operator [] (unsigned Hi, unsigned Lo) 

此运算类似于位选择运算符 [],但它对某一范围内的位而不是对单个位进行运算。

它可从任意精度定点变量中选择一组位。Hi 实参可提供要选择的位范围的上半部分。Lo 实参可提供要选择的最低有效位。如果 Lo 大于 Hi,那么所选的位将按逆序返回。

返回类型 af_range_ref 表示引用 HiLo 所指定的 ap_[u]fixed 变量范围。例如:

ap_uint<4> Result = 0;
ap_ufixed<4, 2> Value = 1.25;
ap_uint<8> Repl = 0xAA;

Result = Value.range(3, 0); // Yields: 0x5
Value(3, 0) = Repl(3, 0); // Yields: -1.5

// when Lo > Hi, return the reverse bits string
Result = Value.range(0, 3); // Yields: 0xA

范围选择

af_range_ref af_(u)fixed::range ()
af_range_ref af_(u)fixed::operator []

此运算符是范围选择运算符 [] 的特例。它会按正常顺序选择该任意精度定点值中的所有位。

返回类型 af_range_ref 表示对 Hi = W - 1 和 Lo = 0 所指定的范围的引用。例如:

ap_uint<4> Result = 0;

ap_ufixed<4, 2> Value = 1.25;
ap_uint<8> Repl = 0xAA;

Result = Value.range(); // Yields: 0x5
Value() = Repl(3, 0); // Yields: -1.5

Length

int ap_[u]fixed::length ()

此函数返回的整数值可提供任意精度定点值内的位数。可配合类型或值一起使用。例如:

ap_ufixed<128, 64> My128APFixed;

int bitwidth = My128APFixed.length(); // Yields 128

显式转换方法

定点到双精度

double ap_[u]fixed::to_double ()

此成员函数以 IEEE 双精度格式返回此定点值。例如:

ap_ufixed<256, 77> MyAPFixed = 333.789;
double Result;

Result = MyAPFixed.to_double(); // Yields 333.789

定点到浮点

float ap_[u]fixed::to_float()

此成员函数以 IEEE 浮点格式返回此定点值。例如:

ap_ufixed<256, 77> MyAPFixed = 333.789;
float Result;

Result = MyAPFixed.to_float();  // Yields 333.789

定点到半精度浮点

half ap_[u]fixed::to_half()

此成员函数以 HLS 半精度(16 位)浮点精度格式返回此定点值。例如:

ap_ufixed<256, 77> MyAPFixed = 333.789;
half Result;

Result = MyAPFixed.to_half();  // Yields 333.789

定点到 ap_int

ap_int ap_[u]fixed::to_ap_int ()

此成员函数将此定点值显式转换为 ap_int 以捕获所有整数位(小数位将被截位)。例如:

ap_ufixed<256, 77> MyAPFixed = 333.789;
ap_uint<77> Result;

Result = MyAPFixed.to_ap_int(); //Yields 333

定点到整数

int ap_[u]fixed::to_int ()
unsigned ap_[u]fixed::to_uint ()
ap_slong ap_[u]fixed::to_int64 ()
ap_ulong ap_[u]fixed::to_uint64 ()

此成员函数将此定点值显式转换为 C 内置整数类型。例如:

ap_ufixed<256, 77> MyAPFixed = 333.789;
unsigned int  Result;

Result = MyAPFixed.to_uint(); //Yields 333

unsigned long long Result;
Result = MyAPFixed.to_uint64(); //Yields 333

编译时间访问数据类型属性

ap_[u]fixed<> 类型将随多个静态成员一起提供,以便在编译时判定数据类型的大小和配置。数据类型将随 static const 成员一起提供:widthiwidthqmodeomode

static const int width = _AP_W;
static const int iwidth = _AP_I;
static const ap_q_mode qmode = _AP_Q;
static const ap_o_mode omode = _AP_O;

您可使用这些数据成员从任何现有 ap_[u]fixed<> 数据类型提取以下信息:

width
数据类型宽度。
iwidth
数据类型的整数部分的宽度。
qmode
数据类型的量化模式。
omode
数据类型的上溢模式。

例如,您可使用这些数据成员来抽取现有 ap_[u]fixed<> 数据类型的数据宽度,以在编译时创建另一个 ap_[u]fixed<> 数据类型。

以下示例显示 Res 变量的大小自动定义为比使用相同量化模式的 Val1 变量和 Val2 变量位宽大 1 位:

// Definition of basic data type
#define INPUT_DATA_WIDTH 12
#define IN_INTG_WIDTH 6
#define IN_QMODE AP_RND_ZERO
#define IN_OMODE AP_WRAP
typedef ap_fixed<INPUT_DATA_WIDTH, IN_INTG_WIDTH, IN_QMODE, IN_OMODE> data_t;
// Definition of variables 
data_t Val1, Val2;
// Res is automatically sized at run-time to be 1-bit greater than INPUT_DATA_WIDTH 
// The bit growth in Res will be in the integer bits
ap_int<data_t::width+1, data_t::iwidth+1, data_t::qmode, data_t::omode> Res = Val1 + 
Val2;

这样可确保 Vitis HLS 对加法导致的位增长进行正确建模,即使为 data_t 更新 INPUT_DATA_WIDTH、IN_INTG_WIDTH 或量化模式的值也是如此。