Vitis HLS 学习笔记--循环边界包含变量

目录

1. 简介

2. 分析与详解

2.1 未优化

2.2 LOOP_TRIPCOUNT 优化指令

2.3 重写变量循环边界

3. 总结


1. 简介

在硬件设计中,循环的迭代次数通常需要是固定的,因为这有助于资源的预分配和时序分析。

循环边界包含变量意味着循环的迭代次数不是固定的,而是由程序运行时的某个变量值决定。这种情况下,编译器无法预先知道循环的确切迭代次数,从而影响代码的优化和性能分析。

当循环包含变量边界时,将禁止执行 Vitis HLS 可应用的某些最优化操作。

int example(int A[32], int n) {

...
    for (i = 0; i < n; i++) {
        out_accum += A[i];
    }
...
}

其中,循环边界由顶层输入驱动的变量 n 来判定。在此情况下,循环被视为包含变量边界,因为 Vitis HLS 无从知晓循环将何时完成。

本文探讨如何解决这种问题。

2. 分析与详解

2.1 未优化

Vitis HLS 工具会尝试循环进行进行最优化,并且最终的报告包含变量循环边界造成的问题。

#include "ap_int.h"

ap_int<13> example(ap_int<8> A[32], ap_uint<5> n) {

    ap_int<13> out_accum = 0;
    ap_uint<5> i;

LOOP:
    for (i = 0; i < n; i++) {
        out_accum += A[i];
    }

    return out_accum;
}

变量循环边界的第一个问题是阻止 Vitis HLS 判定循环时延。

Vitis HLS 可判定完成一次循环迭代所需的时延,但由于它无法静态判定精确的变量宽度值 n,因此无从知晓执行的迭代次数,因而无法报告循环时延(即完全执行循环的所有迭代的周期数)。

存在变量循环边界时,Vitis HLS 会将时延报告为问号 (?) 而不是使用精确值。以下显示了示例的综合后的结果: 

* Loop: 
+----------+---------+---------+----------+-----------+-----------+------+----------+
|          |  Latency (cycles) | Iteration|  Initiation Interval  | Trip |          |
| Loop Name|   min   |   max   |  Latency |  achieved |   target  | Count| Pipelined|
+----------+---------+---------+----------+-----------+-----------+------+----------+
|- LOOP    |        ?|        ?|         2|          1|          1|     ?|       yes|
+----------+---------+---------+----------+-----------+-----------+------+----------+

2.2 LOOP_TRIPCOUNT 优化指令

loop_tripcount 语法

#pragma HLS loop_tripcount min=<int> max=<int> avg=<int>

克服此问题的方法是使用 LOOP_TRIPCOUNT 指令来为循环指定最小和/或最大迭代计数。 

#include "ap_int.h"

ap_int<13> example(ap_int<8> A[32], ap_uint<5> n) {

    ap_int<13> out_accum = 0;
    ap_uint<5> i;

LOOP:
    for (i = 0; i < n; i++) {
#pragma HLS loop_tripcount min=32 max=32 avg=32
        out_accum += A[i];
    }

    return out_accum;
}

循环次数(tripcount) 表示循环的迭代次数。优化后的是示例中,tripcount 最大值 32,那么报告将更新为显示如下内容:

* Loop: 
+----------+---------+---------+----------+-----------+-----------+------+----------+
|          |  Latency (cycles) | Iteration|  Initiation Interval  | Trip |          |
| Loop Name|   min   |   max   |  Latency |  achieved |   target  | Count| Pipelined|
+----------+---------+---------+----------+-----------+-----------+------+----------+
|- LOOP    |       32|       32|         2|          1|          1|    32|       yes|
+----------+---------+---------+----------+-----------+-----------+------+----------+

LOOP_TRIPCOUNT 指令提供的值仅用于报告,或者用于支持 PERFORMANCE 编译指示或指令。指定的循环次数值使 Vitis HLS 能够在报告中判定时延值,以便对来自不同解决方案的值进行比较。要将此循环边界信息用于综合,必须使用断言更新 C/C++ 语言代码,这样会影响综合,由于断言条件假定为 true,因此必须谨慎使用。

由于变量边界循环无法完全展开,因此不仅阻止应用展开 (unroll) 指令,而且还会阻止循环上层的层级的流水打拍操作。

2.3 重写变量循环边界

这里的解决方案是将循环的迭代次数设置为一个固定的最大值(此处为32),然后在循环体内部使用条件语句来决定是否执行循环的主体。

#include "ap_int.h"

ap_int<13> example(ap_int<8> A[32], ap_uint<5> n) {

    ap_int<13> out_accum = 0;
    ap_uint<5> i;

LOOP:
    for (i = 0; i < 32; i++) {
    	if (i < n) {
    		out_accum += A[i];
    	}
    }

    return out_accum;
}

在 LOOP 循环中,i 从0迭代到 32,但只有当 i 小于 n 时,才会将 A[i] 加到累加器 out_accum 上。这样,即使 n 是一个变量,循环的迭代次数也是固定的,满足硬件设计的要求。 

示例中的 for 循环 (LOOP) 则可完全展开。由于此循环的上限固定,因此 Vitis HLS 知晓需创建的硬件数量。在 RTL设计中包含 32 份循环主体副本。每份循环主体副本都包含与之关联的条件逻辑,并根据变量 n 值来执行。

3. 总结

在硬件设计中,固定的循环迭代次数对于资源分配和时序分析至关重要。Vitis HLS 在处理包含变量边界的循环时面临挑战,因为这限制了某些优化操作的执行。通过使用 LOOP_TRIPCOUNT 指令指定迭代次数的范围,可以帮助工具更好地进行时延分析。此外,将循环重写为固定次数的迭代,同时在循环体内部使用条件语句来控制执行,可以满足硬件设计的需求,允许循环展开和流水线化,从而提高性能。这些方法为变量边界循环提供了有效的解决方案,使得即使在变量驱动的情况下,也能实现硬件设计的优化。

相关推荐

  1. 新人学习笔记之(变量

    2024-06-10 10:16:06       6 阅读
  2. Shell 学习笔记 - 变量的类型 + 变量的赋值

    2024-06-10 10:16:06       5 阅读
  3. python学习笔记10(循环结构2)

    2024-06-10 10:16:06       40 阅读
  4. 机器学习笔记——循环神经网络

    2024-06-10 10:16:06       8 阅读
  5. C# 学习笔记-基础与变量

    2024-06-10 10:16:06       30 阅读
  6. Rust 学习笔记 - 变量声明与使用

    2024-06-10 10:16:06       25 阅读
  7. python保存中间变量学习笔记

    2024-06-10 10:16:06       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-10 10:16:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-10 10:16:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-10 10:16:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-10 10:16:06       18 阅读

热门阅读

  1. TCP复用:原理、应用与优势

    2024-06-10 10:16:06       8 阅读
  2. 【学习笔记】linux解压缩文件小记

    2024-06-10 10:16:06       10 阅读
  3. ObjectARX打印当前图纸为PDF(亲测有效)

    2024-06-10 10:16:06       8 阅读
  4. PDF格式分析(八十四)——小部件注释(Widget)

    2024-06-10 10:16:06       9 阅读
  5. Docker in Docker(DinD)原理与实践

    2024-06-10 10:16:06       8 阅读
  6. 怎么开发vscode插件

    2024-06-10 10:16:06       9 阅读