Function instantiation 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.
The FUNCTION_INSTANTIATE pragma or directive exploits the fact that some inputs to a function may 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. This is best explained by example as shown in the following code.
char func(char inval, char incr) {
#pragma HLS INLINE OFF
#pragma HLS FUNCTION_INSTANTIATE variable=incr
return inval + incr;
}
void top(char inval1, char inval2, char inval3,
char *outval1, char *outval2, char *outval3)
{
*outval1 = func(inval1, 0);
*outval2 = func(inval2, 1);
*outval3 = func(inval3, 100);
}
OFF
option can be used to prevent this automatic inlining.It is clear that function func
has been written to perform three exclusive
operations (depending on the value of incr
). Each instance of function
func
is implemented in an identical manner. While this is great for
function reuse and area optimization, it also means that the control logic inside the function
must be more complex to account for the two exclusive operations. Refer to
Vitis-HLS-Introductory-Examples/Pipelining/Functions/function_instantiate
for the full version of this example.
The FUNCTION_INSTANTIATE optimization allows each instance to be independently optimized, reducing the functionality and area. After FUNCTION_INSTANTIATE optimization, the code above can effectively be transformed to have two separate functions, each optimized for different possible values of mode, as shown:
void func1() {
// code segment 1
}
void func2() {
// code segment 2
}
If the function is used at different levels of hierarchy such that function sharing is difficult without extensive inlining or code modifications, function instantiation can provide the best means of improving area: many small locally optimized copies are better than many large copies that cannot be shared.