Vitis HLS 通过转换区域来应用 DATAFLOW 优化。为了提升生成的数据流网络的可预测性,AMD 建议在此区域内部(称为“规范区域”)使用规范格式来编写代码。数据流优化有 2 种主要的规范形式:
-
适用于未内联的子函数的函数规范形式。这些子函数本身即可作为函数区域内的数据流或循环区域内的数据流。请注意,在规范形式内不包含变量初始化(包括构造函数自动执行的变量初始化)或者将表达式按值传递到进程。如果标准数据类型包含无法重新定义的默认构造函数(例如,std::complex),那么可使用 no_ctor 达成此目的(例如,std::complex<float> arr[SIZE] __attribute__((no_ctor));)。Vitis HLS 会尽可能实现生成的数据流,但如果代码未遵循规范格式,那么您应始终检查 GUI 的数据流查看器和协同仿真时间线轨迹,以确保数据流和达成的性能都与期望相符。
void dataflow(Input0, Input1, Output0, Output1) { #pragma HLS dataflow UserDataType C0, C1, C2; // UserDataType can be scalars or arrays func1(Input0, Input1, C0, C1); // read Input0, read Input1, write C0, write C1 func2(C0, C1, C2); // read C0, read C1, write C2 func3(C2, Output0, Output1); // read C2, write Output0, write Output1 }
- 循环主体内的数据流仅包含一个函数,此函数中除循环外不含任何其他代码。对于
for
循环(内部函数未内联),整型循环变量应包含:- 循环头文件中声明的初始值(设置为 0)。
- 循环边界为包含该循环的函数的非负数常量或标量实参。
- 按 1 递增。
- 数据流编译指示需位于循环内,如下所示。
void dataflow(Input0, Input1, Output0, Output1) { for (int i = 0; i < N; i++) { #pragma HLS dataflow UserDataType C0, C1, C2; // UserDataType can be scalars or arrays func1(Input0, Input1, C0, C1); // read Input0, read Input1, write C0, write C1 func2(C0, C1, C2); // read C0, read C1, write C2 func3(C2, Output0, Output1); // read C2, write Output0, write Output1 } }