pragma HLS inline - 2024.1 简体中文

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

Document ID
UG1399
Release Date
2024-07-03
Version
2024.1 简体中文

描述

移除层级中作为独立实体的函数。完成内联后,函数将消隐到调用函数内,不再显示为 RTL 中的层级的独立层次。

重要: 内联函数时也会将应用于该函数的所有编译指示或指令消隐掉。在 Vitis HLS 中,忽略应用于内联函数的任意编译指示或指令。

在某些情况下,将函数内联即可使函数内的运算以更有效的方式与调用函数进行共享和优化。但内联函数无法共享或复用,因此如果父函数多次调用内联函数,则可能导致增加 RTL 实现所需的面积。

根据指定 INLINE 编译指示的方式,该编译指示应用到的范围与定义该编译指示的范围会有所不同:

INLINE
如不指定实参,那么该编译指示表示,指定该编译指示的函数应向上内联到任意调用函数内。
INLINE off
该编译指示表示,指定该编译指示的函数应向上内联到任意调用函数内。这表示禁用特定函数的内联操作,此类特定函数原本可能自动内联或者在递归过程中内联。
INLINE recursive
表示将该编译指示应用于它分配到的函数体。它向下应用,以递归方式内联该函数的内容。

默认情况下,内联只能在函数层级的下一级上执行,而不能对子函数执行。但 recursive 选项允许您指定穿过层级的多个层次进行内联。

语法

将 C 语言源代码中的编译指示置于函数或代码区域的主体内。

#pragma HLS inline <recursive | off>

其中:

recursive
默认情况下,仅执行一级函数内联,并且不内联指定函数内部的函数。recursive 选项会在指定函数或区域内按递归方式内联所有函数。
重要: 在数据流区域中执行函数递归内联可能导致该区域内的单个函数不满足数据流的条件。在此情况下,会忽略 INLINE recursive 编译指示或指令。
off
禁用函数内联以防止指定函数发生内联。例如,如果在函数中指定 recursive,该选项会阻止调用的特定函数进行内联,同时所有其他函数均可进行内联。
提示: Vitis HLS 工具会自动内联小型函数,并将 INLINE 编译指示与 off 选项搭配使用以阻止此自动内联操作。

示例 1

以下示例用于对 func_top 主体内部的所有函数执行内联,以递归方式向下内联穿越整个函数层级,但 func_sub 函数不执行内联。递归编译指示置于 func_top 函数内。用于禁用内联的编译指示则置于 func_sub 函数内:

func_sub (p, q) {
#pragma HLS inline off
int q1 = q + 10;
func(p1,q);// foo_3
...
}
void func_top { a, b, c, d} {
  #pragma HLS inline recursive 
  ...
  func(a,b);//func_1
  func(a,c);//func_2
  func_sub(a,d);
  ...
}
提示: 请注意,在此示例中,INLINE RECURSIVE 向下应用于 func_top 函数内容,但 INLINE OFF 则直接应用于 func_sub

示例 2

此示例用于将 copy_output 函数内联到调用 copy_output 的任意函数或区域内。

void copy_output(int *out, int out_lcl[OSize * OSize], int output) {
#pragma HLS INLINE
    // Calculate each work_item's result update location
    int stride = output * OSize * OSize;
    
    // Work_item updates output filter/image in DDR
    writeOut: for(int itr = 0; itr < OSize * OSize; itr++) {
    #pragma HLS PIPELINE
        out[stride + itr] = out_lcl[itr];
    }