Intel® 高层次综合编译器专业版Pro版: 参考手册

ID 683349
日期 12/04/2023
Public
文档目录

8.1.2. 整数提升(Integer Promotion)和ac_int数据类型整

使用ac_int数据类型时整数提升的规则与标准C/C++规则的整数提升规则不同。您的组件设计应考虑这些不同的规则。

根据操作数的数据类型,整数提升以不同的方式进行:
  • 两个操作数都是标准整数类型(intshortlongunsigned charsigned char):

    如果两个操作数都是标准整数类型(例如char或者short)运算,整数可以按照C/C++标准进行提升。即,运算以最大操作数的数据类型和大小进行,但至少为32位。表达式以较大的数据类型返回结果。

  • 两个操作数都是ac_int数据类型:

    如果两个操作数都是ac_int数据类型,则以最小ac_int数据类型执行的运算需要包含所有值。例如,两个8位ac_int值的乘法以16位运算的形式执行。表达式以该类型返回结果。

  • 一个操作数是标准整数类型,一个操作数是ac_int类型:

    如果表达式有一个标准数据类型和一个ac_int类型,则适合使用ac_int数据类型提升规则。结果表达式类型始终是ac_int数据类型。例如,如果您添加了short数据类型和ac_int<16>数据类型,则结果数据类型为ac_int<17>

运算的数据宽度

C++编译器通常会自动提升窄整数类型,例如charshort转换为32位整数类型(int)用于加法、乘法、除法和位移的算术运算。为了遵守C++语言规范并与其他C++编译器保持一致,在处理本机类型时 Intel® HLS Compiler可能会使用比您预期更大的运算。

如果需要更好地控制算术运算的大小,请使用ac_int数据类型。

请参考如下实例:
component int singlestep_native_signed(char a, char b, char c)
{
   return a * b / c;
}

System Viewer(High-Level Design Reports的一部分)显示除法运算成为32位运算:


注: Intel® HLS Compiler会根据运算的上下文(context),尽可能随时自动缩小运算范围。在本例中,编译器自动将乘法操作缩小到16位。要确认运算的宽度,请在System Viewer中查看您的设计。
如果使用ac_int数据类型的参数和返回数据,则 Intel® HLS Compiler使除法运算变得更窄。
#include <HLS/ac_int.h> 
component int32 singlestep_acint_signed(int8 a, int8 b, int8 c)
{
   return a * b / c;
}

将所有组件变量均定义为ac_int数据类型,这样System Viewer会显示除法运算减少到17位宽:


运算中的literal(字面常量)

在C/C++中,literal被默认为int数据类型,因此当您使用不带任何强制转换的literal时,表达式类型始终至少为32位。例如,如果您的代码类似于如下代码片段,则以32位进行比较:
ac_int<5, true> ap;
...
if (ap < 4) {
...

如果操作数的符号不同,但无符号类型至少与有符号类型一样大,则该运算将按无符号运算执行。否则,无符号操作数将转换为有符号操作数。

例如,如果您有类似以下代码片段,则-1值扩展为32位负数(0xffffffff)而uint3值是一个正32位数字70x00000007):
uint3 x = 7;
if (x != -1) {
   // FAIL
}
为了避免编译器将literal(字面常量)扩展为32位,请将字面常量强制转换为相同的ac_int数据类型。例如:
uint3 x = 7;
if (x != (unit3)-1) {
   // SUCCEED
}