概述
本教程主要介绍 Vivado® HLS (HLS)。您可以学习使用图形用户界面(GUI)和 Tcl 环境执行HLS的任务。教程展示了如何使用优化指令将初始 RTL 实现转变为低面积和高吞吐量实现。
实验 1 说明
讲解如何设置HLS(HLS)项目并执行 HLS 设计流程中的所有主要步骤:
验证 C 代码。
识别并合成解决方案。
验证 RTL 并封装 IP。
实验 2 说明
演示如何使用 Tcl 界面。
实验 3 说明
演示如何使用优化指令优化设计。本实验创建多个版本的 RTL 实现,并比较不同的解决方案。
教程设计说明
要获取教程设计文件,请参阅查找教程设计文件。本教程使用教程目录下的设计文件:
Vivado_HLS_Tutorial\Introduction.
本教程中使用的示例设计是一个 FIR 滤波器。此 FIR 设计项目的硬件目标是:
- 创建吞吐量最高的设计版本。
最终的设计必须处理带有输入有效信号的数据,并产生带有输出有效信号的输出数据。滤波器系数将存储在 FIR 设计外部的单端口 RAM 中。
实验 1:创建HLS项目
导言
本实验介绍如何创建HLS项目、验证 C 代码、将设计合成到 RTL 并验证 RTL。
重要: 本教程中的图表和命令假定教程数据目录为 Vivado_HLS_Tutorial ,文件解压缩后放置在 C:\Vivado_HLS_Tutorial 位置。
步骤 1:创建新项目
- 打开 Vivado® HLS 图形用户界面(GUI):
在 Windows 系统上,双击 Vivado HLS 2020.1 打开 Vivado HLS桌面图标。

图 2-1:Vivado HLS 桌面图标
在 Linux 系统上,在命令提示符下键入 vivado_hls。
提示: 还可以使用 Windows 菜单 "开始">"所有程序">"赛灵思设计 "打开 Vivado HLS。工具 > Vivado 2020.1 > Vivado HLS > Vivado HLS 2020.1。
Vivado HLS 打开后会显示欢迎屏幕,如下图所示。如果之前打开过任何项目,则会显示在最近项目窗格中,否则欢迎界面中不会显示此窗口。

图 2-2: Vivado HLS 欢迎页面
在 "欢迎页面 "中,选择 "创建新项目 "打开项目向导。
- 如图 2-3 所示:
- 输入项目名称 fir_prj。
- 单击 "浏览 "导航到 lab1(介绍)目录的位置。
- 选择 lab1 目录,然后单击 "确定"。
- 单击下一步。

图 2-3: 项目配置
该信息定义了 Vivado HLS 项目目录的名称和位置。在本例中,项目目录为 fir_prj,位于 lab1 文件夹中。
- 输入以下信息以指定 C 设计文件:
- 单击添加文件。
- 选择 fir.c,然后单击确定。
- 使用浏览按钮将 fir (fir.c) 指定为顶层函数。
- 单击下一步。

图 2-4:项目设计文件
重要提示: 本实验只有一个 C 设计文件。当有多个 C 文件,您必须在此阶段将所有这些文件添加到项目中。任何存在本地会自动包含在项目中。如果头文件位于其他位置,请使用 "编辑 CFLAGS "按钮添加标准的 gcc/g++ 搜索路径信息(例如,-I<path_to_header_file_dir>)。
图 2-5 显示了指定测试台文件的输入窗口。必须包含测试台和测试台使用的所有文件(头文件除外)。您可以一次添加一个文件,也可以使用 Ctrl 和 Shift 键选择多个文件进行添加。

图 2-5:测试平台文件
- 单击 "添加文件 "按钮,包含两个测试台文件:fir_test.c 和
out.gold.dat。 - 单击下一步。
C 仿真(和 RTL CosSmulation)都在解决方案的子目录下执行。
如果不包括测试台使用的所有文件(例如,测试台读取的数据文件,如 out.gold.dat),C 和 RTL 仿真可能会因无法找到数据文件而失败。
解决方案配置 "窗口(如图 2-6 所示)指定了第一个解决方案的技术规格。
一个项目可以有多个解决方案,每个解决方案使用不同的目标技术、软件包、约束条件和/或合成指令。

图 2-6: 解决方案配置
- 接受默认的解决方案名称(solution1)、时钟周期(10 ns)和时钟不确定性(留空/未定义时默认为时钟周期的 12.5%)。
- 单击部件选择按钮打开部件选择窗口。
- 选择 "零件 "选项卡,然后从可用设备列表中选择 xcvu9p-flgb2104-1-e。从下拉筛选器中选择以下内容,以帮助完善部件列表:
- 产品类别:通用型
- 系列:Virtex® UltraScale™ 系列
- 子系列:Virtex UltraScale+
- 封装: flgb2104
- 速度等级:1
- 温度等级:全部
- 选择 xcvu9p-flgb2104-1-e。
- 单击 "确定"。
在 "解决方案配置 "对话框中(如上图 2-6 所示),所选部件名称现在显示在 "部件选择 "标题下。 - 单击完成打开 Vivado HLS 项目,如图 2-7 所示。

图 2-7:Vivado HLS 项目
- 项目名称显示在资源管理器窗口的顶行。
- Vivado HLS 项目以分层形式排列信息。
- 该项目拥有关于设计源、测试台和解决方案的信息。
- 解决方案中包含有关目标技术、设计指令和结果的信息。
- 一个项目中可以有多个解决方案,每个解决方案都是同一源代码的实现。
提示: 您可以随时使用工具栏中相应的项目设置 和/或解决方案设置按钮更改项目或解决方案设置。
了解图形用户界面(GUI)
在继续操作之前,请查看图形用户界面 (GUI) 中的区域及其功能。图 2-8 显示了各区域的概览,下面将对每个区域进行说明。

图 2-8:Vivado HLS 图形用户界面
资源管理器窗格
显示项目层次结构。随着验证、综合、验证和 IP 封装步骤的进行,解决方案目录内会自动创建包含各步骤结果的子文件夹(分别命名为 csim、syn、sim 和 impl)。
创建新解决方案时,它们会与解决方案 1 一起出现在项目层次结构中。
信息窗格
显示从资源管理器窗格打开的任何文件的内容。操作完成后,报告文件会在此窗格中自动打开。
辅助窗格
与 "信息 "窗格交叉链接。该窗格中显示的信息会根据 "信息 "窗格中打开的文件进行动态调整。
控制台窗格
显示 Vivado HLS 运行时产生的信息。错误和警告显示在控制台窗格选项卡中。
工具栏按钮
您可以使用工具栏按钮执行最常用的操作。
将光标停留在按钮上时,会弹出工具提示,解释按钮的功能。每个按钮都有一个相关的菜单项,可从下拉菜单中选择。
视角
视角提供了在 Vivado HLS GUI 中调整窗口的便捷方法。
- 综合视角
默认视角允许你综合设计、运行仿真和封装 IP。 - 调试视角
包括与调试 C 代码相关的窗格。您可以在 C 代码编译后打开调试视角(除非使用优化编译模式,因为该模式会禁用调试信息)。 - 分析视角
该视角中的窗口是为支持分析合成结果而配置的。只有在合成完成后才能使用分析视角。
步骤 2:验证 C 源代码
HLS 项目的第一步是确认 C 代码是否正确。这一过程称为C 验证或 C 模拟。
在本项目中,测试台将枞树函数的输出数据与已知的良好值进行比较。
- 在资源管理器窗格中展开 Test Bench 文件夹。
- 双击文件 fir_test.c,在 "信息 "窗格中查看该文件。
- 在辅助窗格中,选择 "大纲 "选项卡中的 main(),可直接跳转到 main()。
图 2-9 显示了这些操作的结果

图 2-9:查看测试平台代码
测试台文件 fir_test.c 包含顶层 C 语言函数 main(),而 main() 则调用要综合的函数 (fir)。该测试台的一个有用特性是它具有自检功能:
- 测试台会将 fir 函数的输出保存到输出文件 out.dat。
- 输出文件与存储在文件 out.gold.dat 中的黄金结果进行比较。
- 如果输出结果与黄金数据一致,则会出现一条确认结果正确的信息,同时将测试台 main() 函数的返回值设置为 0。
- 如果输出结果与黄金结果不同,则会显示一条信息,并将 main() 的返回值设为 1。
Vivado HLS 工具可以重复使用 C 测试台,对 RTL 进行验证。
如果测试台具有前面描述的自我检查特性,则会在 RTL 验证期间自动检查 RTL 结果。Vivado HLS 会在 RTL 验证期间重新使用测试台,如果测试台返回值为 0,则确认 RTL 验证成功。如果 main() 返回任何其他值,包括无返回值,则表示 RTL 验证失败。无需创建 RTL 测试台。这提供了一种稳健、高效的验证方法。
- 单击运行 C 仿真按钮,或使用菜单 Project > Run C Simulation,编译并执行 C 设计。
- 在 C 模拟对话框中,单击确定。
控制台窗格(图 2-10)确认模拟成功执行。

图 2-10: C 仿真结果
提示: 如果 C 仿真失败,请在 C 仿真对话框中选择启动调试器选项, 编译设计,并自动切换到调试视角。在这里您可以使用 C调试器来解决任何问题。
C 验证教程模块提供了使用调试环境的更多详细信息。设计现在可以进行综合。
步骤 3:高层合成
在此步骤中,您将把 C 设计综合为 RTL 设计,并查看综合报告
- 单击 "运行 C 合成 "工具栏按钮或使用菜单 "解决方案 > 运行 C 合成
> 主动解决方案。
合成完成后,报告文件会自动打开。因为合成
报告在 "信息 "窗格中打开时,辅助窗格中的 "大纲 "选项卡会自动更新以反映报告信息。 - 单击 "大纲 "选项卡中的 "性能估计"(图 2-11)。
- 在 "性能估算 "的 "详细信息 "部分,展开 "循环 "视图。

图 2-11: 性能估计
在 "性能估计 "窗格(如图 2-11 所示)中,可以看到时钟周期被设置为 10 ns。Vivado HLS 目标时钟周期为时钟目标值减去时钟不确定性(本例中为 10.00-1.25 = 8.75 ns)。
时钟的不确定性可确保有一定的时间余量,以应对(现阶段)由于放置和布线而产生的未知净延迟。
估计时钟周期(最坏情况下的延迟)为 5.772 ns,符合 8.75 ns 的时序要求。
在 "摘要 "部分,您可以看到
- 该设计的延迟时间为 34 个时钟周期:输出结果需要 34 个时钟周期。
- 间隔时间为 34 个时钟周期:34 个时钟周期后读取下一组输入。该设计没有流水线。该函数的下一次执行(或下一个事务)只能在当前事务完成后开始。
详细信息部分显示 - 该设计中没有子模块。展开 "实例 "部分可看到层次结构中没有子模块。
- 所有的延迟都是由名为循环的 RTL 逻辑综合造成的。
Shift_Accum_Loop.该逻辑执行 11 次(跳闸次数)。每次执行
需要 3 个时钟周期(迭代延迟),总共 33 个时钟周期才能执行由该循环合成的逻辑的所有迭代(延迟)。 - 总延迟比循环延迟多一个时钟周期。进入和退出循环需要一个时钟周期(在这种情况下,设计在循环结束时完成,因此没有退出周期)。
- 在 "大纲 "选项卡中,单击 "利用率估计"(图 2-12)。
该设计使用了作为 LUTRAM 实现的单个存储器(因为它包含的元素少于 1024 个)、3 个 DSP48 以及约 200 个触发器和 LUT。在此阶段,设备资源数量为估算值。
资源利用率数字是估计值,因为 RTL 合成可能会执行额外的优化,这些数字在 RTL 合成后可能会发生变化。
综合。

图 2-12: 利用率估算
- 在 "使用情况估算 "的详细信息部分,展开 "表达式 "视图。
表达式视图中显示的乘法器实例包含所有 DSP48。
乘法器是流水线乘法器。它出现在表达式部分
表示它是一个子块。标准组合乘法器没有层次结构
并列在 "表达式 "部分(表示该层级的组件)。
在实验 3:使用解决方案优化设计,您将优化此设计。 - 在 "大纲 "选项卡中,单击 "界面"(图 2-13)。

图 2-13: 接口报告
接口部分显示接口合成创建的端口和 I/O 协议:
- 设计有一个时钟和复位端口(ap_clk 和 ap_reset)。这两个端口与源对象冷杉(即设计本身)相关联。
- 如源对象 fir 所示,设计还关联了其他端口。合成自动添加了一些块级控制端口:ap_start、ap_done、ap_idle 和 ap_ready。
- 接口合成教程提供了有关这些端口的更多信息。
- 函数输出 y 现在是一个 32 位数据端口,并带有相关的输出有效信号指示器 y_ap_vld。
- 函数输入参数 c(一个数组)是作为一个块 RAM 接口实现的,它有一个 4 位输出地址端口、一个输出 CE 端口和一个 32 位输入数据端口。
- 最后,标量输入参数 x 是作为无 I/O 协议的数据端口 (ap_none) 来实现的。
本教程稍后将介绍如何优化端口 x 的 I/O 协议:实验 3:使用解决方案优化设计》将介绍如何优化端口 x 的 I/O 协议。
步骤 4:RTL 验证
HLS可以重新使用 C 测试台,通过仿真验证 RTL。
- 单击 "运行 C/RTL 协同仿真 "工具栏按钮或使用菜单 "解决方案 > 运行 C/RTL 协同仿真"。
- 在 C/RTL 协同仿真对话框中单击 "确定",执行 RTL 仿真。
RTL 协同仿真的默认选项是使用 Vivado 仿真器和 Verilog RTL 执行仿真。要使用不同的仿真器或
语言使用 C/RTL 协同模拟对话框中的选项。
RTL 协同仿真完成后,报告将在 "信息 "窗格中自动打开,控制台将显示如图 2-14 所示的信息。这与
C 模拟结束时产生的信息。
- C 测试台为 RTL 设计生成输入向量。
- 对 RTL 设计进行仿真。
- RTL 的输出向量被应用回 C 测试台,而测试台的结果检查则验证结果是否正确。
- 如果测试台返回值为 0,则 Vivado HLS 表示仿真通过。
模拟成功。重要的是,只有当结果正确时,测试台才会返回 0 值。

图 2-14: RTL 验证结果
第 8 章 RTL 验证教程提供了更多信息。
步骤 5:创建 IP
HLS流程的最后一步是将设计打包为 IP 块,以便与 Vivado Design Suite 中的其他工具配合使用。
- 单击导出 RTL 工具栏按钮或使用菜单解决方案 > 导出 RTL。
- 确保格式选择下拉菜单显示 IP 目录。
- 单击 "确定"。
IP 打包器为 Vivado IP 目录创建一个包。(下拉菜单中的其他选项允许您为 DSP 的 System Generator、Vivado 的合成检查点格式或 Xilinx Platform Studio 的 Pcore 创建 IP 包)。 - 在资源管理器中展开解决方案 1。
- 展开导出 RTL 命令创建的 impl 文件夹。
- 展开 ip 文件夹,找到打包为 zip 文件的 IP,准备添加到 Vivado IP 目录(图 2-15)。

图 2-15: RTL 验证结果
在此阶段,请保持 Vivado HLS GUI 处于打开状态。您将在下一个实验练习中再次看到这一点。
实验 2:使用 Tcl 命令界面
导言
本实验练习演示如何根据现有的 Vivado HLS 项目创建 Tcl 命令文件并使用 Tcl 界面。
步骤 1:创建 Tcl 文件
- 打开 Vivado HLS 命令提示符。
在 Windows 中,使用开始 > 所有程序 > 赛灵思设计工具 > Vivado 2020.1 > Vivado HLS > Vivado HLS 2020.1 命令提示符(图 2-16)。
在 Linux 系统中,打开一个新的 shell。

图 2-16:Vivado HLS 命令提示符
创建 Vivado HLS 项目时,Tcl 文件会自动保存在项目层次结构中。在实验 1 中仍然打开的图形用户界面中,查看项目时会发现项目层次结构中有两个 Tcl 文件(图 2-17)。
- 在仍从实验 1 打开的图形用户界面中,展开 solution1 中的 Constraints 文件夹,双击 script.tcl 文件,在信息窗格中查看该文件。

图 2-17: Vivado HLS 项目 Tcl 文件
- 文件 script.tcl 包含 Tcl 命令,用于使用项目设置时指定的文件创建项目,并运行 HLS 流程的所有阶段。
- directives.tcl 文件包含应用于设计方案的任何优化。实验 1 中没有使用优化指令,因此该文件为空。
在本实验练习中,您将使用实验 1 中的 script.tcl 为实验 2 项目创建一个 Tcl 文件。
- 关闭实验 1 中的 Vivado HLS GUI。该项目已不再需要。
- 在 Vivado HLS 命令提示符中,使用以下命令(如图 2-18 所示)为 Lab 2 创建新的 Tcl 文件。
- 将目录更改为导言教程目录
C:\Vivad_HLS_Tutorial\Introduction. - 使用命令 lab1\fir_prj\solution1\script.tcl lab2\run_hls.tcl 将现有的 Tcl 文件复制到 Lab 2(Windows 命令提示符支持使用 Tab 键自动完成:反复按 Tab 键查看新的选择)。
- 使用 cd lab2 命令进入 lab2 目录。
- 将目录更改为导言教程目录

图 2-18:将 Lab 1 Tcl 文件复制到 Lab 2
- 使用任何文本编辑器,对 lab2 中的 run_hls.tcl 文件进行以下编辑
目录。最终编辑结果如图 2-19 所示。- 在 open_project 命令中添加 -reset 选项。由于您通常会在同一项目上重复运行 Tcl 文件,因此最好覆盖任何现有的项目信息。
- 在 open_solution 命令中添加 -reset 选项。当在同一解决方案上重新运行 Tcl 文件时,该选项会删除任何现有的解决方案信息。
- 保留源代码指令的注释。如果前一个项目中有任何指令需要重复使用,可以直接将指令复制到此文件中。
- 在 Tcl 文件的最后一行添加退出命令。
- 保存并退出。

图 2-19: 实验 2 的 run_hls.tcl 文件已更新
您可以使用此 Tcl 文件以批处理模式运行 Vivado HLS。
- 在 Vivado HLS 命令提示符窗口中,键入 vivado_hls -f run_hls.tcl。
Vivado HLS 会执行 lab1 中的所有步骤。完成后,结果将显示在项目目录 fir_prj 中。
- 综合报告可在 fir_prj\solution1\syn\report 中查阅。
- 模拟结果可在 fir_prj\solution\sim\report 中查阅。
- 输出软件包在 fir_prj\solution1\impl\ip 中提供。
- 最终输出的 RTL 可在 fir_prj\solution1\impl 和 Verilog 或VHDL.
注意! 从 Vivado HLS 项目复制 RTL 结果时,必须使用 impl 目录中的 RTL。Vivado HLS 会在 export_design 过程中执行额外处理,然后才能在其他设计工具中使用此 RTL。
实验 3:使用解决方案优化设计
导言
本实验练习使用实验 1 中的设计并对其进行优化。
步骤 1:创建新项目
- 打开 Vivado HLS 命令提示符。
在 Windows 中,使用开始 > 所有程序 > 赛灵思设计工具 > Vivado 2020.1 > Vivado HLS > Vivado HLS 2020.1 命令提示符。
在 Linux 系统中,打开一个新的 shell。 - 切换到 Lab 3 目录:
cd C:\Vivado_HLS_Tutorial\Introduction\lab3 - 在命令提示符窗口中键入: vivadoo_hls -f run_hls.tcl
项目由此启动。 - 在命令提示符窗口中键入 vivado_hls -p fir_prj,在 Vivado HLS GUI 中打开项目。
打开 Vivado HLS,如图 2-20 所示,解决方案 1 的综合已经完成。

图 2-20:Introduction Lab 3 初始解决方案
如前所述,本设计的设计目标是
- 创建吞吐量最高的设计版本。
- 最终设计应能处理输入有效信号的数据。
- 产生输出数据,并伴有输出有效信号。
滤波器系数将从外部存储到 FIR 设计中的单端口 RAM 中。
步骤 2:优化输入/输出接口
由于设计规格包括 I/O 协议,因此您执行的第一个优化将创建正确的 I/O 协议和端口。您选择的 I/O 协议类型可能会影响哪些设计优化是可能的。如果有 I/O 协议要求,应在设计周期内尽早设置 I/O 协议。
您在实验 1 中查看了该设计的 I/O 协议(图 2-13),您可以通过导航至 solution1\syn 文件夹内的报告文件夹再次查看综合报告。I/O 要求如下
- 端口 C 必须具有单端口 RAM 访问权限。
- 端口 X 必须有输入数据有效信号。
- 端口 Y 必须有输出数据有效信号。
端口 C 已经是单端口 RAM 访问。但是,如果不明确指定 RAM 访问类型,HLS可能会使用双端口接口。如果这样做能使设计具有更高的吞吐量,HLS 就会这样做。如果需要单端口,则应在设计中明确添加 I/O 协议要求,以使用单端口 RAM。
输入端口 X 默认是一个简单的 32 位数据端口。您可以通过指定 I/O 协议 ap_vld 将其作为带相关数据有效信号的输入数据端口来实现。
输出端口 Y 已有相关输出有效信号。这是指针参数的默认设置。您不必为该端口指定明确的端口协议,因为默认实现就是所需的,但如果需要,最好还是指定一下。
要保留现有结果,请创建一个新的解决方案,即解决方案 2。
- 单击 Project > New Solution(项目 > 新解决方案)工具栏按钮,创建新的解决方案。
- 将默认解决方案名称保留为 solution2。不要更改任何技术或时钟设置。
- 单击完成。
这将创建解决方案 2 并将其设置为默认解决方案。要确认这一点,可以查看资源管理器窗格中当前活动的解决方案 2 是否以粗体高亮显示。
要为解决方案添加优化指令以定义所需的 I/O 接口,请执行以下步骤。 - 在资源管理器窗格中,展开源容器(如图 2-21 所示)。
- 双击 fir.c,在 "信息 "窗格中打开该文件。
- 激活辅助窗格中的 "指令 "选项卡,选择顶层函数 fir,跳转到源代码视图中 fir 函数的顶层。

图 2-21: 打开指令选项卡
指令 "选项卡如图 2-21 右侧所示,列出了 "指令 "选项卡中的所有对象。
可以优化的设计。在 "指令 "选项卡中,可以为设计添加优化指令。只有在源代码打开时,才能查看指令选项卡。
- 在指令选项卡中,选择 c 参数/端口(绿点)。
- 右键单击并选择插入指令。
- 通过执行以下操作来实现单端口 RAM 接口:
- 从 "指令 "下拉菜单中选择 "资源"。
- 单击核心框。
- 选择 RAM_1P_BRAM,如图 2-22 所示。然后选择确定。
上述步骤规定阵列 c 使用单端口块 RAM 实现
资源。由于数组 c 位于函数参数列表中,因此在函数之外,因此会自动创建一组数据端口,以访问 RTL 实现之外的单端口块 RAM。
由于 I/O 协议不太可能改变,因此可以将这些优化指令作为实用程序添加到源代码中,以确保在设计中嵌入正确的 I/O 协议。
- 在 "指令编辑器 "的 "Destination "部分,选择 "Source File"。
- 要应用指令,请单击 "确定"。

图 2-22: 添加资源指令
提示:如果要更改任何指令的目的地,请双击指令选项卡中的指令,然后修改目的地。
- 指定端口 x 为相关的有效信号/端口。
- 在 "指令 "选项卡中,选择输入端口 x(绿点)。
- 右键单击并选择插入指令。
- 从 "指令 "下拉菜单中选择 "接口"。
- 从对话框的Destination 部分选择源文件。
- 选择 ap_vld 作为模式。
- 单击 "确定 "应用指令。
- 指定端口 y 为相关的有效信号/端口。
- 在 "指令 "选项卡中,选择输入端口 y(绿点)。
- 右键单击并选择插入指令。
- 从对话框的Destination 部分选择源文件。
- 从 "指令 "下拉菜单中选择 "接口"。
- 为模式选择 ap_vld。
- 单击 "确定 "应用指令。
完成后,验证源代码和指令选项卡是否正确,如图 2-23 所示。右键单击任何不正确的指令进行修改。

图 2-23: 解决方案 2 的输入/输出指令
- 单击运行 C 合成工具栏按钮合成设计。
- 出现提示时,单击 "是 "保存 C 源文件的内容。添加指令作为实用程序修改了源代码。
合成完成后,报告文件将自动打开。 - 单击 "大纲 "选项卡查看界面结果,或直接下拉至报告文件底部。
图 2-24 显示端口现在具有正确的 I/O 协议。

图 2-24: 解决方案 2 的输入/输出协议
步骤 3:分析结果
在优化设计之前,了解当前设计非常重要。实验 1 演示了如何利用综合报告来了解实现情况。然而,分析视角以交互方式提供了更多细节。
按照以下步骤显示分析视角,如图 2-25 所示。
- 单击分析视角按钮。
- 单击计划表查看器窗口中的 Shift_Accum_Loop,展开它。
- 第 6 章 "设计分析 "教程提供了对 "分析 "视角的更全面了解,但下文将解释从该源代码创建最小、最快的 RTL 设计所需的条件。
- 性能窗格视图的左栏显示 RTL 层次结构中该模块的操作。
- 最上面一行列出了设计中的控制状态。控制状态是HLS用于在时钟周期内安排操作的内部状态。其中
控制状态与 RTL 有限状态机 (FSM) 的最终状态之间存在相关性,但并不存在一对一的映射关系。

图 2-25:Solution2 分析视角:性能
这里的一些对象与 C 源代码直接相关。右键单击对象可与 C 代码交叉引用。
- 设计从第一个状态开始,在端口 x 上进行读取操作。
- 在下一个状态中,它开始执行 for 循环创建的逻辑
Shift_Accum_Loop。循环显示为灰色,可以展开或折叠。 - 在第一种状态下,对循环迭代计数器进行检查:加法、比较以及可能的循环退出。
- 对根据阵列数据合成的块 RAM 进行一个周期的内存读取操作。
- c 端口有内存读取。
- 乘法运算需要 1 个周期才能完成。
- for 循环执行了 11 次。
- 在最后一次迭代结束时,循环退出控制步骤 1,并向端口 y 写入数据。
您还可以使用分析视角来分析设计中使用的资源。
- 单击资源视图,如图 2-26 所示。
- 展开所有资源组。

图 2-26:Solution2 分析视角:资源
图 2-26 显示:
- 端口 c 报告在内存部分,因为这也是内存访问(内存在设计之外)。
- 本设计中使用的是单流水线乘法器。
- 其中一个加法器是共享的:在一行上有两个加法器实例。通过分析获得的洞察力,可以继续优化设计。
在结束分析之前,值得对需要多个 DSP48 才能实现的多循环乘法运算进行评论。源代码使用一个 int
数据类型。这是一种 32 位数据类型,会产生较大的乘法器。DSP48 的乘法器为 18 位,需要多个 DSP48 才能实现数据宽度大于 18 位的乘法运算。
任意精度类型教程介绍了如何使用更适合硬件的数据类型创建设计。使用任意精度类型可以定义任意位大小的数据类型(比标准的 C/C++ 8 位、16 位、32 位或 64 位类型更大)。
步骤 4:优化最高吞吐量(最小间隔)
限制这种设计吞吐量的两个问题是
- for 循环默认情况下,循环是滚动的:循环体的一个副本是
合成,并在每次迭代中重复使用。这样可以确保循环的每次迭代都按顺序执行。您可以展开 for 循环,让所有操作并行进行。 - 用于 shift_reg 的 RAM 块。因为变量 shift_reg 是一个数组,在
在 C 源代码中,默认情况下是以块 RAM 的形式实现的。然而,这就阻止了其实现方式为移位寄存器。因此,应将该块 RAM 划分为单个寄存器。
首先创建一个新的解决方案。
- 单击合成视角按钮。
- 单击 "新建解决方案 "按钮。
- 将溶液名称保留为 solution3。
- 单击完成创建新解决方案。
- 在 "项目 "菜单中,选择 "关闭不活动的解决方案选项卡",关闭以前解决方案中的任何现有选项卡。图 2-27 总结了以下步骤,解释了如何展开循环。
- 单击 fir.c 文件,然后在 "指令 "选项卡中选择 Shift_Accum_Loop 循环。 重要:提醒:必须在 "信息 "窗格中打开源代码,才能在 "指令 "选项卡中看到任何代码对象
- 右键单击并选择插入指令。
- 从 "指令 "下拉菜单中选择 "展开"。将 "目的地 "保留为 "指令文件"。 在优化设计时,通常必须进行多次反复优化,才能确定最终的优化结果。将优化添加到指令文件,可以确保它们不会自动转入下一个解决方案。将优化存储在解决方案指令文件中可以使不同的解决方案具有不同的优化。如果在代码中将优化作为实用程序添加,它们将自动延续到新的解决方案中,您必须修改代码才能返回并重新运行以前的解决方案。 不要选中指令窗口中的其他选项,也不要将其留空,以确保循环完全展开。
- 单击 "确定 "应用指令。
- 应用指令将数组划分为单个元素。
- 在 "指令 "选项卡中,选择数组 shift_reg。
- 右键单击并选择插入指令。
- 从指令下拉菜单中选择 Array_Partition。
- 指定类型为完整。
- 选择 "确定 "应用指令。 在解决方案 2 的代码中嵌入指令,并添加两个新指令后,解决方案 3 的指令窗格如图 2-28 所示。在图 2-28 中,注意到在解决方案 2 中作为语法应用的指令的注释(#HLS)与刚刚应用并保存到指令文件中的指令的注释(%HLS)不同。您可以在 Tcl 文件中查看新添加的指令,如下图所示。
- 在资源管理器窗格中,展开解决方案 3 中的约束文件夹,如图 2-29 所示。
- 双击 solution3 directives.tcl 文件,在 "信息 "窗格中打开该文件。
- 单击合成工具栏按钮合成设计。 合成完成后,合成报告将自动打开。
- 比较不同解决方案的结果。单击比较报告工具栏按钮。 或者,使用项目 > 比较报告。
- 在比较中加入solution 1、solution 2 和solution 3。
- 单击 "确定"。

图 2-27: 展开 FOR 循环

图 2-28:Solution3 指令

图 2-29:Solution3 Directives.tcl 文件
解决方案 3 的启动间隔最小,处理数据的速度更快。由于间隔仅为 11 个时钟周期,它每隔 11 个时钟周期就开始处理一组新的输入。

图 2-30: Lab3 解决方案比较
还可以对这一设计进行其他优化。例如,可以使用流水线来进一步提高吞吐量和降低间隔。第 7 章 "设计优化 "教程详细介绍了如何使用流水线来缩短间隔。
如前所述,您可以修改代码本身以使用任意精度类型。例如,如果不要求数据类型必须是 32 位 int 类型,您可以使用位精度类型(例如 6 位、14 位或 22 位类型),只要它们满足要求的精度。有关使用任意精度类型的更多详情,请参阅第 5 章 "任意精度类型 "教程。
结论
在本教程中,您将学会如何
- 在图形用户界面和 Tcl 环境中创建 Vivado HLS项目。
- 执行 HLS 设计流程中的主要步骤。
- 创建并使用 Tcl 文件来运行 Vivado HLS。
- 创建新的解决方案,添加优化指令,并比较不同解决方案的结果。
的设计流程&spm=1001.2101.3001.5002&articleId=162172569&d=1&t=3&u=1b439505932d4cd789889e1b6a4d992e)
544

被折叠的 条评论
为什么被折叠?



