pragma HLS function_instantiate - 2021.1 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2021-06-16
Version
2021.1 English

Description

The FUNCTION_INSTANTIATE pragma is an optimization technique that has the area benefits of maintaining the function hierarchy but provides an additional powerful option: performing targeted local optimizations on specific instances of a function. This can simplify the control logic around the function call and potentially improve latency and throughput.

By default:

  • Functions remain as separate hierarchy blocks in the RTL.
  • All instances of a function, at the same level of hierarchy, make use of a single RTL implementation (block).

The FUNCTION_INSTANTIATE pragma is used to create a unique RTL implementation for each instance of a function, allowing each instance to be locally optimized according to the function call. This pragma exploits the fact that some inputs to a function can be a constant value when the function is called, and uses this to both simplify the surrounding control structures and produce smaller more optimized function blocks.

Without the FUNCTION_INSTANTIATE pragma, the following code results in a single RTL implementation of function foo_sub for all three instances of the function in foo. Each instance of function foo_sub is implemented in an identical manner. This is fine for function reuse and reducing the area required for each instance call of a function, but means that the control logic inside the function must be more complex to account for the variation in each call of foo_sub.

char foo_sub(char inval, char incr) {
#pragma HLS function_instantiate variable=incr
 return inval + incr;
}
void foo(char inval1, char inval2, char inval3,
 char *outval1, char *outval2, char * outval3)
{
 *outval1 = foo_sub(inval1, 1);
 *outval2 = foo_sub(inval2, 2);
 *outval3 = foo_sub(inval3, 3);
}

In the code sample above, the FUNCTION_INSTANTIATE pragma results in three different implementations of function foo_sub, each independently optimized for the incr argument, reducing the area and improving the performance of the function. After FUNCTION_INSTANTIATE optimization, foo_sub is effectively be transformed into three separate functions, each optimized for the specified values of incr.

Syntax

Place the pragma in the C source within the boundaries of the required location.

#pragma HLS function_instantiate variable=<variable>

Where:

variable=<variable>
A required argument that defines the function argument to use as a constant.

Examples

In the following example, the FUNCTION_INSTANTIATE pragma, placed in function swInt, allows each instance of function swInt to be independently optimized with respect to the maxv function argument.

void swInt(unsigned int *readRefPacked, short *maxr, short *maxc, short *maxv){
#pragma HLS function_instantiate variable=maxv
    uint2_t d2bit[MAXCOL];
    uint2_t q2bit[MAXROW];
#pragma HLS array partition variable=d2bit,q2bit cyclic factor=FACTOR

    intTo2bit<MAXCOL/16>((readRefPacked + MAXROW/16), d2bit);
    intTo2bit<MAXROW/16>(readRefPacked, q2bit);
    sw(d2bit, q2bit, maxr, maxc, maxv);
}