一般情况下,支持针对 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
这将显示 Val1
与 Val2
的乘法。返回类型为其整数部分位宽与其小数部分位宽之和。
除法
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
这将显示 Val2
与 Val1
的除法。为保留足够精度:
- 返回类型的整数位宽为
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 = 25
,I
= 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++ 整数类型(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 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]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 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]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 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 true
Result = Val1 <= Val3; // Yields true
大于
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 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
位运算符
位选择和位设置
af_bit_ref ap_[u]fixed::operator [] (int bit)
此运算符从任意精度定点值中选择 1 个位,并将其返回。
返回的值为可用于设置或清除 ap_[u]fixed
变量中的对应位的参考值。位实参必须为整数值,它用于指定要选择的位的索引。最低有效位索引为 0
。允许的最高索引是 ap_[u]fixed
变量的位宽减 1。
结果类型为 af_bit_ref
,值为 0
或 1
。例如:
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
表示引用 Hi
和 Lo
所指定的 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
转换为其他数据类型。编译时间访问数据类型属性
ap_[u]fixed<>
类型将随多个静态成员一起提供,以便在编译时判定数据类型的大小和配置。数据类型将随 static const
成员一起提供:width
、iwidth
、qmode
和 omode
:
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 或量化模式的值也是如此。