Using Arbitrary Precision Data Types

Vitis HLS provides arbitrary precision integer data types that manage the value of the integer numbers within the boundaries of the specified width, as shown in the following table.

Table 1. Arbitrary Precision Data Types
Language Integer Data Type Required Header
C++ ap_[u]int<W> (1024 bits)

Can be extended to 4K bits wide as explained in C++ Arbitrary Precision Integer Types.

#include “ap_int.h”
C++ ap_[u]fixed<W,I,Q,O,N> #include “ap_fixed.h”

The header files define the arbitrary precision types are also provided with Vitis HLS as a standalone package with the rights to use them in your own source code. The package, xilinx_hls_lib_<release_number>.tgz, is provided in the include directory in the Vitis HLS installation area.

Arbitrary Integer Precision Types with C++

The header file ap_int.h defines the arbitrary precision integer data type for the C++ ap_[u]int data types. To use arbitrary precision integer data types in a C++ function:

  • Add header file ap_int.h to the source code.
  • Change the bit types to ap_int<N> for signed types or ap_uint<N> for unsigned types, where N is a bit-size from 1 to 1024.

The following example shows how the header file is added and two variables implemented to use 9-bit integer and 10-bit unsigned integer types:


#include "ap_int.h"

void foo_top (…) {
  
 ap_int<9>  var1;           // 9-bit
 ap_uint<10>  var2;         // 10-bit unsigned

Arbitrary Precision Fixed-Point Data Types

In Vitis HLS, it is important to use fixed-point data types, because the behavior of the C++ simulations performed using fixed-point data types match that of the resulting hardware created by synthesis. This allows you to analyze the effects of bit-accuracy, quantization, and overflow with fast C-level simulation.

These data types manage the value of real (non-integer) numbers within the boundaries of a specified total width and integer width, as shown in the following figure.

Figure 1: Fixed-Point Data Type

Fixed-Point Identifier Summary

The following table provides a brief overview of operations supported by fixed-point types.

Table 2. Fixed-Point Identifier Summary
Identifier Description
W Word length in bits
I The number of bits used to represent the integer value, that is, the number of integer bits to the left of the binary point. When this value is negative, it represents the number of implicit sign bits (for signed representation), or the number of implicit zero bits (for unsigned representation) to the right of the binary point. For example,
ap_fixed<2, 0> a = -0.5;    // a can be -0.5,

ap_ufixed<1, 0> x = 0.5;    // 1-bit representation. x can be 0 or 0.5
ap_ufixed<1, -1> y = 0.25;  // 1-bit representation. y can be 0 or 0.25
const ap_fixed<1, -7> z = 1.0/256;  // 1-bit representation for z = 2^-8
Q Quantization mode: This dictates the behavior when greater precision is generated than can be defined by smallest fractional bit in the variable used to store the result.
ap_fixed Types Description
AP_RND Round to plus infinity
AP_RND_ZERO Round to zero
AP_RND_MIN_INF Round to minus infinity
AP_RND_INF Round to infinity
AP_RND_CONV Convergent rounding
AP_TRN Truncation to minus infinity (default)
AP_TRN_ZERO Truncation to zero
O

Overflow mode: This dictates the behavior when the result of an operation exceeds the maximum (or minimum in the case of negative numbers) possible value that can be stored in the variable used to store the result.

ap_fixed Types Description
AP_SAT1 Saturation
AP_SAT_ZERO1 Saturation to zero
AP_SAT_SYM1 Symmetrical saturation
AP_WRAP Wrap around (default)
AP_WRAP_SM Sign magnitude wrap around
N This defines the number of saturation bits in overflow wrap modes.
  1. Using the AP_SAT* modes can result in higher resource usage as extra logic will be needed to perform saturation and this extra cost can be as high as 20% additional LUT usage.

Example Using ap_fixed

In this example the Vitis HLS ap_fixed type is used to define an 18-bit variable with 6 bits representing the numbers above the decimal point and 12-bits representing the value below the decimal point. The variable is specified as signed, the quantization mode is set to round to plus infinity and the default wrap-around mode is used for overflow.

#include <ap_fixed.h>
...
ap_fixed<18,6,AP_RND > my_type;
...