Vitis HLS 学习笔记--Syn Report解读(1)

目录

[1. 介绍](#1. 介绍)

[2. 示例一](#2. 示例一)

[2.1 HLS 代码](#2.1 HLS 代码)

[2.2 Report 解读](#2.2 Report 解读)

[2.2.1 General Information](#2.2.1 General Information)

[2.2.2 Timing Estimate](#2.2.2 Timing Estimate)

[2.2.3 Performance & Resource Estimates](#2.2.3 Performance & Resource Estimates)

[2.2.4 HW interfaces](#2.2.4 HW interfaces)

[2.2.4.1 硬件接口报告](#2.2.4.1 硬件接口报告)

[2.2.4.2 导出至 Vivado 中的 IP](#2.2.4.2 导出至 Vivado 中的 IP)

[2.2.4.3 Port-Level Protocols 端口级协议](#2.2.4.3 Port-Level Protocols 端口级协议)

[2.2.4.4 Block Level Control 块级控制协议](#2.2.4.4 Block Level Control 块级控制协议)

[2.2.5 SW I/O Information](#2.2.5 SW I/O Information)

[2.2.6 Bind Op Report](#2.2.6 Bind Op Report)

[2.2.7 Bind Storage Report](#2.2.7 Bind Storage Report)

[3. 示例二](#3. 示例二)

[3.1 HLS 代码](#3.1 HLS 代码)

[3.2 Report 解读](#3.2 Report 解读)

[3.2.1 HW interfaces](#3.2.1 HW interfaces)

[3.2.1.1 硬件接口报告](#3.2.1.1 硬件接口报告)

[3.2.1.2 导出至 Vivado 中的 IP](#3.2.1.2 导出至 Vivado 中的 IP)

[3.2.2 SW I/O Information](#3.2.2 SW I/O Information)

[3.2.3 Pragma Report](#3.2.3 Pragma Report)

[4. 示例三](#4. 示例三)

[4.1 HLS 代码](#4.1 HLS 代码)

[4.2 Report 解读](#4.2 Report 解读)

[4.2.1 HW interfaces](#4.2.1 HW interfaces)

[4.2.1.1 硬件接口报告](#4.2.1.1 硬件接口报告)

[4.2.1.2 导出至 Vivado 中的 IP](#4.2.1.2 导出至 Vivado 中的 IP)

[4.2.1.3 Block Level Control 块级控制协议](#4.2.1.3 Block Level Control 块级控制协议)

[4.2.2 Pragma Report](#4.2.2 Pragma Report)

[5. 总结](#5. 总结)


1. 介绍

综合报告是Vitis HLS工具链中一个关键的输出,它为开发者提供了关于其HLS设计的重要信息,包括时序估计、性能和资源使用情况、硬件接口细节以及软件到硬件的映射信息。

本文通过三个简单的示例,详细解读这些报告,以便更好地理解 Vitis HLS 工具的输出,并利用这些信息来优化和调试硬件设计。

2. 示例一

2.1 HLS 代码

cpp 复制代码
#include <ap_int.h>

void func(ap_fixed<1,1> *led_o, char reg_in)
{
	if(reg_in == 'o')
        *led_o = 1;
    else
        *led_o = 0;
}

这段代码的功能非常简单,根据输入字符(reg_in)来控制一个LED的开关状态。如果输入是'o',则LED打开;否则,LED关闭。

func 函数接受两个参数:

执行综合后,IDE会自动打开报告,这里介绍两种进入报告的途径。

方法一:

方法二:

第二种方法可以打开文本的报告,比较方便复制。以下的内容从文本报告中复制。

2.2 Report 解读

2.2.1 General Information

cpp 复制代码
+ General Information: 
    * Date:           Fri Apr 10 12:00:50 2022
    * Version:        2022.1 (Build 3526262 on Mon Apr 18 15:47:01 MDT 2022)
    * Project:        example
    * Solution:       solution1 (Vivado IP Flow Target)
    * Product family: zynquplus
    * Target device:  xck26-sfvc784-2LV-c

2.2.2 Timing Estimate

cpp 复制代码
+ Timing: 
    * Summary: 
    +--------+----------+----------+------------+
    |  Clock |  Target  | Estimated| Uncertainty|
    +--------+----------+----------+------------+
    |ap_clk  |  10.00 ns|  0.849 ns|     2.70 ns|
    +--------+----------+----------+------------+

关于Timing的详细解释,请参照下图:

其中,Vitis HLS使用的有效时钟周期,可以理解为Target减去Uncertainty。

2.2.3 Performance & Resource Estimates

cpp 复制代码
+ Performance & Resource Estimates: 
    
    PS: '+' for module; 'o' for loop; '*' for dataflow
    +--------+------+------+---------+--------+----------+---------+------+----------+------+----+---+----------+-----+
    | Modules| Issue|      | Latency | Latency| Iteration|         | Trip |          |      |    |   |          |     |
    | & Loops| Type | Slack| (cycles)|  (ns)  |  Latency | Interval| Count| Pipelined| BRAM | DSP| FF|    LUT   | URAM|
    +--------+------+------+---------+--------+----------+---------+------+----------+------+----+---+----------+-----+
    |+ func  |     -|  6.45|        0|   0.000|         -|        1|     -|        no|     -|   -|  -|  11 (~0%)|    -|
    +--------+------+------+---------+--------+----------+---------+------+----------+------+----+---+----------+-----+

2.2.4 HW interfaces

2.2.4.1 硬件接口报告
cpp 复制代码
================================================================
== HW Interfaces
================================================================
* REGISTER
+-----------+---------+----------+
| Interface | Mode    | Bitwidth |
+-----------+---------+----------+
| led_o     | ap_none | 1        |
| reg_in    | ap_none | 8        |
+-----------+---------+----------+

* TOP LEVEL CONTROL
+-----------+------------+-----------------------------------+
| Interface | Type       | Ports                             |
+-----------+------------+-----------------------------------+
| ap_ctrl   | ap_ctrl_hs | ap_done ap_idle ap_ready ap_start |
+-----------+------------+-----------------------------------+
2.2.4.2 导出至 Vivado 中的 IP

默认块级协议为ap_ctrl_hs,故生成的Vivado IP包含ap_ctrl端口。

2.2.4.3 Port-Level Protocols 端口级协议

端口级协议,即 func 函数的参数:

  • reg_in(标量类型),作为输入,默认是ap_none协议
  • led_o(指针类型),作为输出,默认是ap_vld协议,故包含led_o_ap_vld信号
2.2.4.4 Block Level Control 块级控制协议

Top/Block Level Control:块级控制协议,或者顶层控制协议,也即顶层 func 函数 return 控制的部分。

其modes有四个选项:

  • ap: access protocol,hs: handshake
  • 对于控制驱动的 TLP,ap_ctrl_chain 协议和 ap_ctrl_hs 协议支持顺序执行和流水打拍执行。
  • 对于数据驱动的 TLP,ap_ctrl_none 是必需的控制协议。
  • ap_ctrl_hs 控制协议与 ap_ctrl_chain 具有相同信号,但它将 ap_continue 信号设为 1 以保持高电平。此控制协议支持顺序执行模式和流水打拍执行模式,但不提供来自下游设计模块的反压以控制数据流动。
  • ap_ctrl_none 同样与 ap_ctrl_chain 具有相同信号,但握手信号端口(ap_start、ap_idle、ap_ready 和ap_done)设为高电平并且会被优化掉(不综合成硬件)。

ap_ctrl_chain 接口的行为:

2.2.5 SW I/O Information

cpp 复制代码
================================================================
== SW I/O Information
================================================================
* Top Function Arguments
+----------+-----------+-------------------------------------+
| Argument | Direction | Datatype                            |
+----------+-----------+-------------------------------------+
| led_o    | out       | ap_fixed<1, 1, AP_TRN, AP_WRAP, 0>* |
| reg_in   | in        | char                                |
+----------+-----------+-------------------------------------+

* SW-to-HW Mapping
+----------+--------------+---------+
| Argument | HW Interface | HW Type |
+----------+--------------+---------+
| led_o    | led_o        | port    |
| led_o    | led_o_ap_vld | port    |
| reg_in   | reg_in       | port    |
+----------+--------------+---------+

软件 I/O 信息,显示顶层函数实参:

  • 方向信息,输入或者输出
  • 参数类型

2.2.6 Bind Op Report

此例不涉及此报告。

2.2.7 Bind Storage Report

此例不涉及此报告。

3. 示例二

3.1 HLS 代码

cpp 复制代码
void basic_interface(ap_fixed<1,1> *led_o, char reg_in)
{
#pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=reg_in
    if(reg_in == 'o')
        *led_o = 1;
    else
        *led_o = 0;
}

指令 #pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=reg_in 的作用:

  • 指定 port=reg_in 端口级控制协议为 s_axilite
  • 指定接口命名为 BUS_A

3.2 Report 解读

对于重复报告内容不再分析,重点对比与示例一的差异。

3.2.1 HW interfaces

3.2.1.1 硬件接口报告
cpp 复制代码
================================================================
== HW Interfaces
================================================================
* S_AXILITE Interfaces
+-------------+------------+---------------+--------+----------+
| Interface   | Data Width | Address Width | Offset | Register |
+-------------+------------+---------------+--------+----------+
| s_axi_BUS_A | 32         | 5             | 16     | 0        |
+-------------+------------+---------------+--------+----------+

* S_AXILITE Registers
+-------------+----------+--------+-------+--------+-----------------------+
| Interface   | Register | Offset | Width | Access | Description           |
+-------------+----------+--------+-------+--------+-----------------------+
| s_axi_BUS_A | reg_in   | 0x10   | 32    | W      | Data signal of reg_in |
+-------------+----------+--------+-------+--------+-----------------------+

* REGISTER
+-----------+---------+----------+
| Interface | Mode    | Bitwidth |
+-----------+---------+----------+
| led_o     | ap_none | 1        |
+-----------+---------+----------+

* TOP LEVEL CONTROL
+-----------+------------+-----------------------------------+
| Interface | Type       | Ports                             |
+-----------+------------+-----------------------------------+
| ap_clk    | clock      | ap_clk                            |
| ap_rst_n  | reset      | ap_rst_n                          |
| ap_ctrl   | ap_ctrl_hs | ap_done ap_idle ap_ready ap_start |
+-----------+------------+-----------------------------------+

相比于示例一,增加的内容:

  • S_AXILITE Interfaces
  • S_AXILITE Registers

其中 S_AXILITE Interfaces 和 S_AXILITE Registers 部分参数解释:

  • Data Width: s_axi数据宽度为32位
  • Address Width: 地址宽度是5位,接口寻址的地址空间为2的5次方,即32个不同的地址
  • Offset: 偏移量,16,即0x10
3.2.1.2 导出至 Vivado 中的 IP

与示例一相比:

  • 缺少了 reg_in[7:0] 接口
  • 新增了 s_axi_BUS_A 接口
  • 新增了 ap_clk 和 ap_rst_n 信号

3.2.2 SW I/O Information

cpp 复制代码
================================================================
== SW I/O Information
================================================================
* Top Function Arguments
+----------+-----------+-------------------------------------+
| Argument | Direction | Datatype                            |
+----------+-----------+-------------------------------------+
| led_o    | out       | ap_fixed<1, 1, AP_TRN, AP_WRAP, 0>* |
| reg_in   | in        | char                                |
+----------+-----------+-------------------------------------+

* SW-to-HW Mapping
+----------+--------------+----------+----------------------------------+
| Argument | HW Interface | HW Type  | HW Info                          |
+----------+--------------+----------+----------------------------------+
| led_o    | led_o        | port     |                                  |
| led_o    | led_o_ap_vld | port     |                                  |
| reg_in   | s_axi_BUS_A  | register | name=reg_in offset=0x10 range=32 |
+----------+--------------+----------+----------------------------------+

与示例一相比,reg_in 的 HW Type 由 port 变更为 register,表示 reg_in 不再是一个端口,而是总线 s_axi_BUS_A 的一组寄存器。

3.2.3 Pragma Report

cpp 复制代码
================================================================
== Pragma Report
================================================================
* Valid Pragma Syntax
+-----------+-----------------------------------------+-------------------------------------+
| Type      | Options                                 | Location                            |
+-----------+-----------------------------------------+-------------------------------------+
| interface | mode=s_axilite bundle=BUS_A port=reg_in | mult/src/func.cpp:5 in func, reg_in |
+-----------+-----------------------------------------+-------------------------------------+

生效的自定义端口,汇总在此报告中。

4. 示例三

4.1 HLS 代码

cpp 复制代码
#include <ap_int.h>

void func(ap_fixed<1,1> *led_o, char reg_in)
{
#pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=reg_in
#pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=return

	if(reg_in == 'a')
        *led_o = 1;
    else
        *led_o = 0;
}

指令 #pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=return 的作用:

  • 指定 port=return 块级控制协议为 s_axilite
  • 指定接口命名为 BUS_A

4.2 Report 解读

对于重复报告内容不再分析,重点对比与示例一、二的差异。

4.2.1 HW interfaces

4.2.1.1 硬件接口报告
cpp 复制代码
================================================================
== HW Interfaces
================================================================
* S_AXILITE Interfaces
+-------------+------------+---------------+--------+----------+
| Interface   | Data Width | Address Width | Offset | Register |
+-------------+------------+---------------+--------+----------+
| s_axi_BUS_A | 32         | 5             | 16     | 0        |
+-------------+------------+---------------+--------+----------+

* S_AXILITE Registers
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| Interface   | Register | Offset | Width | Access | Description                      | Bit Fields                                                           |
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| s_axi_BUS_A | CTRL     | 0x00   | 32    | RW     | Control signals                  | 0=AP_START 1=AP_DONE 2=AP_IDLE 3=AP_READY 7=AUTO_RESTART 9=INTERRUPT |
| s_axi_BUS_A | GIER     | 0x04   | 32    | RW     | Global Interrupt Enable Register | 0=Enable                                                             |
| s_axi_BUS_A | IP_IER   | 0x08   | 32    | RW     | IP Interrupt Enable Register     | 0=CHAN0_INT_EN 1=CHAN1_INT_EN                                        |
| s_axi_BUS_A | IP_ISR   | 0x0c   | 32    | RW     | IP Interrupt Status Register     | 0=CHAN0_INT_ST 1=CHAN1_INT_ST                                        |
| s_axi_BUS_A | reg_in   | 0x10   | 32    | W      | Data signal of reg_in            |                                                                      |
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+

* REGISTER
+-----------+---------+----------+
| Interface | Mode    | Bitwidth |
+-----------+---------+----------+
| led_o     | ap_none | 1        |
+-----------+---------+----------+

* TOP LEVEL CONTROL
+-----------+------------+-----------+
| Interface | Type       | Ports     |
+-----------+------------+-----------+
| ap_clk    | clock      | ap_clk    |
| ap_rst_n  | reset      | ap_rst_n  |
| interrupt | interrupt  | interrupt |
| ap_ctrl   | ap_ctrl_hs |           |
+-----------+------------+-----------+
4.2.1.2 导出至 Vivado 中的 IP

与示例一相比:

  • 缺少了 reg_in[7:0] 接口
  • 缺少了 ap_ctrl 接口
  • 新增了 s_axi_BUS_A 接口
  • 新增了 ap_clk 和 ap_rst_n 信号
  • 新增了 interrupt 信号

与示例二相比:

  • 缺少了 ap_ctrl 接口
  • 新增了 interrupt 信号
4.2.1.3 Block Level Control 块级控制协议

指令 #pragma HLS INTERFACE mode=s_axilite bundle=BUS_A port=return 指定了块级控制协议为 s_axilite。

cpp 复制代码
* S_AXILITE Registers
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| Interface   | Register | Offset | Width | Access | Description                      | Bit Fields                                                           |
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+
| s_axi_BUS_A | CTRL     | 0x00   | 32    | RW     | Control signals                  | 0=AP_START 1=AP_DONE 2=AP_IDLE 3=AP_READY 7=AUTO_RESTART 9=INTERRUPT |
| s_axi_BUS_A | GIER     | 0x04   | 32    | RW     | Global Interrupt Enable Register | 0=Enable                                                             |
| s_axi_BUS_A | IP_IER   | 0x08   | 32    | RW     | IP Interrupt Enable Register     | 0=CHAN0_INT_EN 1=CHAN1_INT_EN                                        |
| s_axi_BUS_A | IP_ISR   | 0x0c   | 32    | RW     | IP Interrupt Status Register     | 0=CHAN0_INT_ST 1=CHAN1_INT_ST                                        |
| s_axi_BUS_A | reg_in   | 0x10   | 32    | W      | Data signal of reg_in            |                                                                      |
+-------------+----------+--------+-------+--------+----------------------------------+----------------------------------------------------------------------+

与示例二相比,新增了几组寄存器:

  • CTRL,Control signals
  • GIER,Global Interrupt Enable Register
  • IP_IER,IP Interrupt Enable Register
  • IP_ISR,IP Interrupt Enable Register

这些寄存器的作用,后续博文单独详解。

4.2.2 Pragma Report

cpp 复制代码
================================================================
== Pragma Report
================================================================
* Valid Pragma Syntax
+-----------+-----------------------------------------+-------------------------------------+
| Type      | Options                                 | Location                            |
+-----------+-----------------------------------------+-------------------------------------+
| interface | mode=s_axilite bundle=BUS_A port=reg_in | mult/src/func.cpp:5 in func, reg_in |
| interface | mode=s_axilite bundle=BUS_A port=return | mult/src/func.cpp:6 in func, return |
+-----------+-----------------------------------------+-------------------------------------+

生效的自定义端口,汇总在此报告中。

5. 总结

在本文中,通过三个不同的示例,我们深入探讨了Vitis HLS IDE的综合报告(Synthesis Report),并详细解读了其中的关键部分:

示例一

  • 功能:展示了一个基本的HLS代码,该代码根据输入字符控制LED的开关状态。
  • 报告解读:
    • General Information:提供了综合环境的基本信息,如日期、版本、项目名称等。
    • Timing Estimate:展示了时钟周期的估计,包括目标时钟周期、估计时钟周期和不确定性。
    • Performance & Resource Estimates:提供了性能和资源使用的估计,如模块的发行类型、延迟、流水线间隔等。
    • HW interfaces:描述了硬件接口的详细信息,包括寄存器模式和顶层控制信号。
    • SW I/O Information:展示了软件到硬件的映射信息,包括函数参数的方向、数据类型和硬件接口类型。

示例二

  • 功能增强:通过添加#pragma HLS INTERFACE指令,指定了端口级控制协议为s_axilite,并将端口命名为BUS_A
  • 报告差异:
    • 引入了S_AXILITE InterfacesS_AXILITE Registers,提供了关于AXI Lite接口的详细信息,包括数据宽度、地址宽度、偏移量和寄存器。
    • SW-to-HW Mapping:展示了reg_in参数现在映射到AXI Lite接口的寄存器上。

示例三

  • 功能增强:进一步通过#pragma HLS INTERFACE指令,将块级控制协议也设置为s_axilite,并通过port=return指定了返回值的接口。
  • 报告差异:
    • 新增了中断信号和相关的控制寄存器,如CTRLGIERIP_IERIP_ISR,这些寄存器用于控制信号、全局中断使能、IP中断使能和IP中断状态。
    • TOP LEVEL CONTROL:现在包括了中断信号,表明设计支持中断功能。

通过这三个示例,我们学习了如何在Vitis HLS中使用端口级和块级控制协议来定制硬件接口,并通过综合报告来验证这些自定义设置。这些自定义设置对于FPGA逻辑交互至关重要,因为它们定义了数据和控制信号的交互方式。 可以看到Vitis HLS提供了强大的工具来帮助设计者理解、定制和优化他们的HLS设计,从而在硬件实现中达到预期的性能和功能。

相关推荐
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__3 小时前
Web APIs学习 (操作DOM BOM)
学习
冷眼看人间恩怨4 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
ThreeYear_s5 小时前
基于FPGA 的4位密码锁 矩阵键盘 数码管显示 报警仿真
fpga开发·矩阵·计算机外设
数据的世界016 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐6 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
OopspoO8 小时前
qcow2镜像大小压缩
学习·性能优化
A懿轩A8 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒9 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
kkflash39 小时前
提升专业素养的实用指南
学习·职场和发展