描述
FUNCTION_INSTANTIATE 编译指示化是一种优化技巧,不仅具有维持函数层级的面积优势,还可提供另一个强大的选项:在函数的特定实例上执行针对性的局部优化。这样可以简化围绕函数调用的控制逻辑,也可能改进时延和吞吐量。
默认情况下:
- 函数在 RTL 中作为独立层级块保留,或者分解(或内联)到更高层次的函数中。
- 同一层级上的任一函数的所有实例都使用单一 RTL 实现(块)。
FUNCTION_INSTANTIATE 编译指示用于为函数的每个实例创建唯一的 RTL 实现,允许根据函数调用对每个实例进行局部优化。鉴于调用函数时部分函数输入可能是常量,此编译指示可藉此简化周围控制结构,并生成进一步优化的、更小的函数块。
如不使用 FUNCTION_INSTANTIATE 编译指示,则以下代码会为 func
中的函数的全部 3 个实例生成函数 func_sub
的单一 RTL 实现。函数 func_sub
的每个实例都是以相同方式实现的。这对于函数复用并无影响,并且可以减少函数的每次实例调用所需的面积,但是函数内部的控制逻辑必须更复杂,以便应对每次调用 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);
}
提示:
Vitis HLS 工具会将小函数自动分解(或内联)到更高层次的调用函数中。即使对于函数例化也同样如此。将 INLINE 编译指示与
OFF
选项搭配使用即可阻止此自动内联操作。在以上代码样本中,FUNCTION_INSTANTIATE 编译指示会生成函数 func_sub
的 3 个不同实现,每个实现都会按 incr
指定值进行优化,从而减少面积并改善函数实现的性能。
语法
将 C 语言源代码中的编译指示置于所需位置的边界内。
#pragma HLS FUNCTION_INSTANTIATE variable=<variable>
其中:
-
variable=<variable>
- 这是必需的实参,用于定义要用作为常量的函数实参。
示例
在以下示例中,布局在函数 swInt
内的 FUNCTION_INSTANTIATE
编译指示允许按 maxv
函数实参来对函数 swInt
的每个实例进行独立优化。
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);
}