pragma HLS function_instantiate - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 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, or is decomposed (or inlined) into a higher level function.
  • 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 func_sub for all three instances of the function in func. Each instance of function func_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 func_sub.

char func_sub(char inval, char incr) {
#pragma HLS INLINE OFF
#pragma HLS FUNCTION_INSTANTIATE variable=incr
 return inval + incr;
}
void func(char inval1, char inval2, char inval3,
 char *outval1, char *outval2, char * outval3)
{
 *outval1 = func_sub(inval1, 1);
 *outval2 = func_sub(inval2, 2);
 *outval3 = func_sub(inval3, 3);
}
Tip: The Vitis HLS tool automatically decomposes (or inlines) small functions into higher-level calling functions. This is true even for function instantiations. Using the INLINE pragma with the OFF option can be used to prevent this automatic inlining.

In the code sample above, the FUNCTION_INSTANTIATE pragma results in three different implementations of function func_sub, each optimized for the specified values of incr, reducing the area and improving the performance of the function implementation.

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);
}