Intel® High Level Synthesis Compiler Standard Edition: Reference Manual

ID 683310
Date 12/18/2019
Public
Document Table of Contents

8.2. Integer Promotion and ac_int Data Types

The rules of integer promotion when you use ac_int data types are different from standard C/C++ rules. Your component design should account for these differing rules.

Depending on the data type of the operands, integer promotion is carries out differently:
  • Both operands are standard integer types (int, short, long, unsigned char, or signed char):

    If both operands are of standard integer type (for example char or short) operations, integers are promoted following the C/C++ standard. That is, the operation is carried out in the data type and size of the largest operand, but at least 32 bits. The expression returns the result in the larger data type.

  • Both operands are ac_int data types:

    If both operands are ac_int data types, operations are carried out in the smallest ac_int data type needed to contain all values. For example, the multiplication of two 8-bit ac_int values is carried out as an 16-bit operation. The expression returns the result in that type.

  • One operand is a standard integer type and one operand is an ac_int type:

    If the expression has one standard data type and one ac_int type, the rules for ac_int data type promotion apply. The resulting expression type is always an ac_int data type. For example, if you add a short data type and an ap_int<16> data type, the resulting data type is ac_int<17>.

In C/C++, literals are by default an int data type, so when you use a literal without any casting, the expression type is always at least 32 bits. For example, if you have code like following code snippet, the comparison is carried out in 32 bits:
ac_int<5, true> ap;
...
if (ap < 4) {
...

If the operands are signed differently and the unsigned type is at least as large as the signed type, the operation is carried out as an unsigned operations. Otherwise, the unsigned operand is converted to a signed operand.

For example, if you have code like the following snippet, the -1 value expands to a 32-bit negative number (0xffffffff) while the uint3 value is a positive 32-bit number 7 (0x00000007):
uint3 x = 7;
if (x != -1) {
   // FAIL
}