VivadoHLS中函数的层次设计和优化1函数层次设计中函数调用的优化

  • 格式:pdf
  • 大小:694.31 KB
  • 文档页数:9
上面代码中函数的层次关系如下图 2.1.1 所示,可以看到,顶层函数 hier_func 包含了三个子函数: shift_func 和两个 sumsub_func。
hier_func
sumsub_func
shift_func
sumsub_func
图 2.1.1 函数层次关系 缺省情况下 HLS 综合会对这三个子函数做 inline 处理,HLS 认为这三个子函数都比较小,所以它 缺省做 inline 处理。在 console 中我们可以看到打印信息:
1.1.1 函数层次变化的判别 如何知道 HLS 综合后函数的层次关系发生变化?简单有效的方法是: 1. 查看控制台 Console 打印信息或者 HLS 自动保存的综合 log 文件。如果在综合过程中,HLS 缺省去掉了有些小的函数的层次,都会打印出这些函数被 inline 的信息,同时,对函数增 加 inline 约束的执行,也报告出来。 2. 检查综合报告后 RTL 模块的层次,虽然函数名称不是完全和 RTL 模块名相同,还是可以通 过 RTL 模块名映射函数名,查看层次的变化。
*outSum = *in1 + *in2; *outSub = *in1 - *in2; }
void shift_func(dint_t *in1, dint_t *in2, dout_t *outA, dout_t *outB) {
*outA = *in1 >> 1; *outB = *in2 >> 2; }
1 函数层次设计中函数调用的优化
在 VivadoHLS 中,除了一些小的函数外,工具缺省不会打破层次关系,也就是说函数调用有 几个层次,综合产生的 RTL 的模块 module 之间也会保持相应的层次关系,除非增加约束打乱这 种层次。
1.1 函数层次的合并和优化
像 RTL 层次优化原理一样,HLS 工程也需要顶层函数,跨过边界没法实现资源和性能的优化, 函数的层次有时候阻碍函数之间的逻辑和性能最优化,我们必须通过改变或者保持函数的层次关 系,满足对资源和性能的要求。
Inline 的典型应用就是进入或者退出函数调用时需要 1 个时钟周期的开销,inline 这个函数层 次意味着减小了 latency 并提高了 throughout。Inline 函数还有其它方法的好处,就是提高函数资 源的共享,并且可以对函数内部的单元做更多的硬件结构优化合并。
如下代码:
void sumsub_func(din_t *in1, din_t *in2, dint_t *outSum, dint_t *outSub) {
XFORM-602 信息报告了子函数缺省自动 inline 处理,也可以在 analysis 窗口中查看函数的层次结 构如下图:
上图中只有顶层函数 hier_func 保留,子函数全部 inline 掉。 对上面的工程做子函数的inline off约束(#pragma HLS INLINE off
),增加这个约束的目的是要求 HLS 不需要做子函数的 inline,保持所有 C 函数的层次,综合结果 在 analysis 窗口中图示如下:
void hier_func(din_t A, din_t B, dout_t *C, dout_t *D) {
dint_t tmp_sum, tmp_sub; dint_t tmp_a,tmp_b;
sumsub_func(&A,&B,&tmp_sum,&tmp_sub); sumsub_func(&tmp_sum,&tmp_sub,&tmp_a,&tmp_b); shift_func(&tmp_a,&tmp_b,C,D); }
VivadoHLS 中函数的层次设计和优化
Xilinx DSP specialist: Harvest Guo
VivadoHLS 中对性能的优化是通过 initiative interval 的优化和 latency 的优化来完成。对启动间隔 II 最小化就是尽可能的提高输入数据之间或者输出数据之间的速率。从输入来看,优化 II 就是尽 可能减少输入数据之间的时钟周期间隔,最大的吞吐率可以达到每个时钟周期有新的数据可以输 入或者数据可以输出。
如果从单个函数设计考虑,检查函数中 loop 循环是否需要设置 pipeline 约束,用于提高循环中 数据处理的吞吐率。
如果设计从函数层次关系考虑,当一个函数包含多个平行子函数的串行调用时,子函数之间存 在数据传递通道时,对子函数间可以采用 dataflow pipeline 策略。
在开始分析 vivadoHLS 设计优化之前,先介绍一下 HLS 中对性能的两个指标,延迟和启动间隔 (initiation interval)。延迟 Latency 和启动间隔 initiation interval 这两个指标一般都是针对不同的 层次结构来说的,对于 C/C++程序来说,它的基本层次元素就是函数 function 和常用到的循环结 构 loop,函数调用和循环嵌套具有不同的层次,如果设计中对层次元素进LS 缺省情况下,每个函数生成对应的 RTL 模块,保持和函数调用相同的层次关系,除非有些 小的函数 HLS 自动 inline 掉。同样的,如果上层函数多次调用同一个子函数,这个子函数对应的 RTL 模块也被多次重用,节约了资源,就如同 RTL 设计时这个模块被例化一样。
当函数很小或者很少的几次调用时,inline 这个函数可能更好的共享资源,这个函数中仅有的 几个单元能够更好的被共享。
1.1.2 通过函数 inline 约束合并函数层次提高性能 函数层次的优化通过 inline 约束来实现,对函数增加 inline 约束,此函数的边界被打开,它内
容直接复制到当前调用的函数中,有关此函数的层次将不存在。Inline 主要用来提高延迟的减少函 数调用的吞吐率,同时带来的负面效应就是常常增加资源的消耗,因为但子函数保持层次时,函 数体本身的资源都可以被共享,但 inline 掉层次后,可能只有子涵体中部分的操作可以共享。