函数例化 - 2023.2 简体中文

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文

函数例化是一种最优化技巧,不仅具有维持函数层级的面积优势,还可提供另一个强大的选项:在函数的特定实例上执行针对性局部最优化。这样可以简化围绕函数调用的控制逻辑,也可能改进时延和吞吐量。

鉴于调用函数时,函数的部分输入可能是常量,FUNCTION_INSTANTIATE 编译指示或指令可藉此简化周围控制结构,并生成进一步最优化的、更小的函数块。如下代码所示示例对此进行了最明确的解释。

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);
}
提示: Vitis HLS 工具会将小函数自动分解(或内联)到更高层次的调用函数中。将 INLINE 编译指示与 OFF 选项搭配使用即可阻止此自动内联操作。

很明显,函数 func 已写为执行三次互斥运算(根据 incr 的值)。函数 func 的每个实例都是以相同方式实现的。虽说这对于函数复用和面积最优化很实用,但也意味着函数内部的控制逻辑必须更为复杂,才能容纳两次互斥运算。请参阅 Vitis-HLS-Introductory-Examples/Pipelining/Functions/function_instantiate 以获取此示例的完整版本。

FUNCTION_INSTANTIATE 最优化允许对每个实例进行独立最优化,从而减少功能和面积。完成 FUNCTION_INSTANTIATE 最优化后,以上代码可有效转换为 2 个独立函数,每个函数都针对模式的不同可能值来完成最优化,如下所示:

void func1() {
  // code segment 1
}

void func2() {
  // code segment 2
}

如果在未经大幅内联或代码修改的情况下,在不同层级使用该函数而导致函数难以共享,那么函数例化可提供改进面积的最佳方法:大量小型局部最优化的副本比大量无法共享的大型副本更有效。