其它类方法、运算符和数据成员 - 2021.2 Chinese

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

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

以下章节探讨了其它类方法、运算符和数据成员。

位级运算

以下方法有助于对 ap_[u]int 类型变量中存储的值执行常见位级运算。

Length

int ap_(u)int::length ()

返回整数值,以提供 ap_[u]int 变量中的总位数。

串联

ap_concat_ref ap_(u)int::concat (ap_(u)int low)  
ap_concat_ref ap_(u)int::operator , (ap_(u)int high, ap_(u)int low)

串联 2 个 ap_[u]int 变量,返回的值的宽度为操作数宽度之和。

High 和 Low 实参分别置于结果的高阶位和低阶位;concat() 方法用于将实参置于低阶位。

使用已重载的逗号运算符时,括号是必需的。逗号运算符版本还可显示在赋值的 LHS 上。

ap_uint<10> Rslt;

ap_int<3> Val1 = -3;
ap_int<7> Val2 = 54;

Rslt = (Val2, Val1); // Yields: 0x1B5
Rslt = Val1.concat(Val2); // Yields: 0x2B6
(Val1, Val2) = 0xAB; // Yields: Val1 == 1, Val2 == 43

位选择

ap_bit_ref ap_(u)int::operator [] (int bit)

从任意精度整数值中选择 1 个位,并将其返回。

返回的值为可用于设置或清除此 ap_[u]int 中的对应位的参考值。

位实参必须为 int 值。它用于指定要选择的位的索引。最低有效位为索引 0。允许的最高索引是 ap_[u]int 的位宽减 1。

生成的 ap_bit_ref 类型表示引用该 ap_[u]int 实例的 1 个位(按位指定)。

范围选择

ap_range_ref ap_(u)int::range (unsigned Hi, unsigned Lo)
ap_range_ref ap_(u)int::operator () (unsigned Hi, unsigned Lo)

返回以实参指定的位的范围来表示的值。

Hi 实参用于指定此范围的最高有效位 (MSB) 的位置,Lo 用于指定最低有效位 (LSB)。

源变量的 LSB 为位置 0。如果 Hi 实参的值小于 Lo 的值,则会逆序返回这些位。

ap_uint<4> Rslt;

ap_uint<8> Val1 = 0x5f;
ap_uint<8> Val2 = 0xaa;

Rslt = Val1.range(3, 0); // Yields: 0xF
Val1(3,0) = Val2(3, 0); // Yields: 0x5A
Val1(3,0) = Val2(4, 1); // Yields: 0x55
Rslt = Val1.range(4, 7); // Yields: 0xA; bit-reversed!
注释: 范围选择所返回的对象并非 ap_(u)int 对象,其中缺少运算符,但可用于赋值。要在链式表达式中将范围选择结果与 ap_(u)int 方法搭配使用,请添加显式构造函数,如下所示。
ap_uint<32> v = 0x8fff0000;
bool r = ap_uint<16>(v.range(23, 8)).xor_reduce();

AND 减缩

bool ap_(u)int::and_reduce ()
  • 对此 ap_(u)int 中的所有位应用 AND 运算。
  • 返回生成的单个位。
  • 等效于将该值与 -1 比较(全部为 1),如果匹配,则返回 true,否则返回 false

OR 减缩

bool ap_(u)int::or_reduce ()
  • 对此 ap_(u)int 中的所有位应用 OR 运算。
  • 返回生成的单个位。
  • 等效于将该值与 0 比较(全部为 0),如果匹配,则返回 false,否则返回 true

XOR 减缩

bool ap_(u)int::xor_reduce ()
  • 对此 ap_int 中的所有位应用 XOR 运算。
  • 返回生成的单个位。
  • 等效于计算该值中 1 位的数量,如果计数结果为偶数,则返回 false,如果为奇数,则返回 true

NAND 减缩

bool ap_(u)int::nand_reduce ()
  • 对此 ap_int 中的所有位应用 NAND 运算。
  • 返回生成的单个位。
  • 等效于将该值与 -1 比较(全部为 1),如果匹配,则返回 false,否则返回 true

NOR 减缩

bool ap_int::nor_reduce ()
  • 对此 ap_int 中的所有位应用 NOR 运算。
  • 返回生成的单个位。
  • 等效于将该值与 0 比较(全部为 0),如果匹配,则返回 true,否则返回 false

XNOR 减缩

bool ap_(u)int::xnor_reduce ()
  • 对此 ap_(u)int 中的所有位应用 XNOR 运算。
  • 返回生成的单个位。
  • 等效于计算该值中 1 位的数量,如果计数结果为偶数,则返回 true,如果为奇数,则返回 false

位减缩方法示例

ap_uint<8> Val = 0xaa;

bool t = Val.and_reduce(); // Yields: false
t = Val.or_reduce();       // Yields: true
t = Val.xor_reduce();      // Yields: false
t = Val.nand_reduce();     // Yields: true
t = Val.nor_reduce();      // Yields: false
t = Val.xnor_reduce();     // Yields: true

位反转

void ap_(u)int::reverse ()

ap_[u]int 实例的内容反转:

  • LSB 变为 MSB。
  • MSB 变为 LSB。

反转方法示例

ap_uint<8> Val = 0x12;

Val.reverse(); // Yields: 0x48

测试位值

bool ap_(u)int::test (unsigned i)

检查 ap_(u)int 实例的指定位是否是 1

如果是,则返回 true,如果否,则返回 false。

测试方法示例

ap_uint<8> Val = 0x12;
bool t = Val.test(5); // Yields: true

设置位值

void ap_(u)int::set (unsigned i, bool v)                              
void ap_(u)int::set_bit (unsigned i, bool v)

ap_(u)int 实例的指定位设置为整数 V 的值。

设置位(设为 1)

void ap_(u)int::set (unsigned i)

ap_(u)int 实例的指定位设置为值 1(一)。

清除位(设为 0)。

void ap_(u)int:: clear(unsigned i)

ap_(u)int 实例的指定位设置为值 0(零)。

对位取反

void ap_(u)int:: invert(unsigned i)

ap_(u)int 实例的函数实参中指定的位取反。指定的位原始值如果为 1,则变为 0,反之亦然。

位设置、清除和取反方法示例:

ap_uint<8> Val = 0x12;
Val.set(0, 1); // Yields: 0x13
Val.set_bit(4, false); // Yields: 0x03
Val.set(7); // Yields: 0x83
Val.clear(1); // Yields: 0x81
Val.invert(4); // Yields: 0x91

右转

void ap_(u)int:: rrotate(unsigned n)

ap_(u)int 实例向右旋转 n 位。

左转

void ap_(u)int:: lrotate(unsigned n)

ap_(u)int 实例向左旋转 n 位。

ap_uint<8> Val = 0x12;

Val.rrotate(3); // Yields: 0x42
Val.lrotate(6); // Yields: 0x90

按位 NOT

void ap_(u)int:: b_not()
  • 补足 ap_(u)int 实例的每个位。
ap_uint<8> Val = 0x12;

Val.b_not(); // Yields: 0xED

按位 NOT 示例

测试符号

bool ap_int:: sign()
  • 检查 ap_(u)int 实例是否为负。
  • 如果为负,则返回 true
  • 如果为正,则返回 false

显式转换方法

转换为 C/C++ (u)int 型

int ap_(u)int::to_int ()
unsigned ap_(u)int::to_uint ()
  • 返回 ap_[u]int 中包含的值对应的原生 C/C++(大部分系统上为 32 位)整数。
  • 如果值大于 [unsigned] int 可显示的值,则发生截断。

转换为 C/C++ 64 位 (u)int 型

long long ap_(u)int::to_int64 ()
unsigned long long ap_(u)int::to_uint64 ()
  • 返回 ap_[u]int 中包含的值对应的原生 C/C++ 64 位整数。
  • 如果值大于 [unsigned] int 可显示的值,则发生截断。

转换为 C/C++ double 型

double ap_(u)int::to_double ()
  • 返回 ap_[u]int 中包含的值对应的原生 C/C++ double 64 位浮点表示法。
  • 如果 ap_[u]int 宽度超过 53 位(double 的尾数中的位数),生成的 double 所包含的值可能与期望的值不同。

Sizeof

标准 C++ sizeof() 函数不应搭配 ap_[u]int 或者对象的其它类或实例一起使用。ap_int<> 数据类型为类,sizeof 会返回类或实例对象使用的存储空间。sizeof(ap_int<N>) 始终返回所使用的字节数。例如:

 sizeof(ap_int<127>)=16
 sizeof(ap_int<128>)=16
 sizeof(ap_int<129>)=24
 sizeof(ap_int<130>)=24

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

ap_[u]int<> 类型随静态成员一并提供,此静态成员允许在编译时判定变量大小。数据类型随静态常量成员 width 一并提供,数据类型的宽度将自动赋值给该成员:


static const int width = _AP_W;

您可使用 width 数据成员来提取现有 ap_[u]int<> 数据类型的数据宽度,以在编译时创建另一个 ap_[u]int<> 数据类型。以下示例显示 Res 变量的大小定义为比 Val1 变量和 Val2 变量位宽大 1 位:

// Definition of basic data type
#define INPUT_DATA_WIDTH 8
typedef ap_int<INPUT_DATA_WIDTH> data_t;
// Definition of variables 
data_t Val1, Val2;
// Res is automatically sized at compile-time to be 1-bit greater than data type 
data_t
ap_int<data_t::width+1> Res = Val1 + Val2;

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