Vivado HLS最典型的用法是创建初始设计,然后执行优化以满足所需的资源和性能目标。解决方案提供了一种方便的方法,以确保早期综合运行的结果可以被保存和比较。
新解决方案向导具有与New Project向导中的最终窗口相同的选项,另外还有一个附加选项,允许将应用于现有解决方案的任何指令和相关约束方便地复制到新解决方案中,在新解决方案中可以修改或删除它们。
创建新解决方案之后,可以添加优化指令(如果是从以前的解决方案复制的,则可以修改它们)。下一节将解释如何将指令添加到解决方案中。使用配置选项应用自定义约束,并在优化设计时进行讨论。
添加优化指令的第一步是打开信息窗口中的源代码。展开位于资源管理器窗格顶部的源容器,双击源文件以打开它,以便在信息窗格中进行编辑。如下图所示:
在Information pane中激活源代码后,选择“显示和修改文件的指令右侧的Directives选项卡。directive选项卡包含当前开放源代码中可以应用指令的所有对象和范围。
注意:要将指令应用于其他C文件中的对象,必须打开该文件并使其在Information窗格中处于活动状态。
虽然可以在Vivado HLS GUI中选择对象并应用指令,但Vivado HLS将所有指令应用于包含该对象的范围。例如,您可以将接口指令应用于Vivado HLS GUI中的接口对象。Vivado HLS将指令应用于顶层函数(作用域),并在指令中标识接口端口(对象)。在下面的示例中,函数foo上的data_in端口被指定为一个AXI4-Lite接口。
可以将优化指令应用于以下对象和范围:
在Vivado HLS Directive Editor对话框中,可以指定以下任一目标设置:
在C综合期间,该工具对variables, functions, and loops验证pragmas。这个验证还包括pragma是否冲突。
例如,在声明数组时,默认情况下它被映射到block RAM。您可以对数组进行分区或重新构造,但这些都是相互排斥的选项。如果在同一个变量上错误地指定数组分区和重新塑造,工具就会出错,合成将失败,并显示以下消息
下图显示了添加到指令文件中的DATAFLOW指令。指令。tcl文件位于“解决方案约束”文件夹中,并使用生成的tcl命令在“信息”窗格中打开。
当指令作为Tcl命令应用时,Tcl命令指定该范围或该范围内的范围和对象。对于循环和区域,Tcl命令要求标记这些范围。如果循环或区域当前没有标签,则弹出对话框请求标签。
下面展示了标记和未标记循环和区域的示例。
提示:命名循环使综合报告易于阅读。自动生成标签被分配给没有标签的循环。
下图显示了添加到源文件中的DATAFLOW指令以及在information窗格中打开的结果源代码。源代码现在包含一个pragma,它指定了优化指令。
在这两种情况下,都会应用指令,并在执行综合时执行优化。如果修改了代码,通过插入标签或pragma,会弹出一个对话框,提醒您在合成之前保存代码。
指令只能应用于范围内的范围或对象。因此,它们不能直接应用于任何函数范围之外声明的全局变量。
要将指令应用于全局变量,请将该指令应用于使用全局变量的范围(函数、循环或区域)。在使用变量的范围上打开directive选项卡,应用指令并在directive Editor中手动输入变量名。
优化指令也可以应用于类中定义的对象或范围。不同之处在于,类通常是在头文件中定义的。使用以下操作之一打开头文件
然后用头文件中的对象填充instructions选项卡,可以应用指令。
注意!当将指令作为pragmas应用于头文件时,应该小心。该文件可能被其他人使用或用于其他项目。每次在设计中包含头文件时,都会应用作为pragma添加的任何指令。
要在使用Tcl命令时手动对模板应用优化指令,请在引用类方法时指定模板参数和类。例如,给定以下c++代码
使用下面的Tcl命令指定函数的 INLINE指令:
Pragma指令本身不支持使用define语句指定的值。下面的代码试图使用define语句指定流的深度,但无法编译。
提示:使用显式值指定depth参数。
如果不需要#define,可以使用常量,例如const int
可以在C代码中使用宏来实现此功能。使用宏的关键是在宏中使用层次结构。这允许正确地执行扩展。代码可按以下步骤编译:
当应用优化指令时,Vivado HLS将信息输出到控制台(和日志文件),其中详细描述了过程。在下面的示例中,Pipeline指令应用于II=1(迭代间隔为1)的C函数,但是综合不能满足这个目标。
注意!如果Vivado HLS不能满足优化指令,它会自动放松优化目标,并寻求创建一个性能目标较低的设计。如果它不能找到该目标,它将报错停止。
通过寻求创建满足较低优化目标的设计,Vivado HLS能够提供三种重要类型的信息:
在message SCHED-69中,未能到达目标II的原因是端口有限。设计必须访问一个块RAM,而一个块RAM最多只有两个端口。
这样的失败之后,下一步就是分析问题所在。在本例中,分析代码的第52行并/或使用Analysis透视图确定瓶颈,以及是否可以减少对两个以上端口的需求,或者确定如何增加端口的数量。
通过优化设计,达到了预期的性能,验证了RTL的正确性,并将合成结果封装为IP。
使用C/RTL cosimulation工具栏按钮或菜单 Solution > Run C/RTL cosimulation验证RTL结果。
验证完成后,控制台显示消息SIM-1000以确认验证成功。C测试台中任何printf命令的结果都会被回显到控制台。
仿真报告在信息窗格中自动打开,显示通过或失败状态以及延迟和II的测量数据。
重要!只有当C测试台返回0值时,C/RTL联合模拟才会通过。协同仿真在测试台上测试场景,如果返回True或0,则通过。如果失败,则返回False或1。
当RTL验证完成时,将在解决方案文件夹中创建一个sim目录。下图显示了创建的子文件夹。
如果在C/RTL联合仿真对话框中选择了Setup Only选项,则会在验证文件夹中创建可执行文件,但不会运行仿真。通过在命令提示符处执行模拟可执行文件,可以手动运行仿真。
Vivado HLS设计流中的最后一步是将RTL输出打包为IP。使用Export RTL工具栏按钮或菜单Solution > Export RTL打开Export RTL对话框,如图所示。
当 Export RTL过程完成时,将在解决方案文件夹中创建文件夹impl
在所有情况下,输出包括:
重要!Xilinx不建议将verilog或vhdl文件夹中的文件直接用于您自己的RTL合成项目。相反,Xilinx建议使用下面讨论的打包的IP输出文件。
在Vivado HLS在设计中使用Xilinx IP的情况下,例如使用浮点设计,RTL目录包含一个脚本,用于在RTL合成期间创建IP。如果将verilog或vhdl文件夹中的文件复制出来并用于RTL合成,则您有责任正确使用这些文件夹中出现的任何脚本文件。如果使用包IP,则此过程由design Xilinx工具自动执行。
Format Selection下拉框确定创建了哪些其他文件夹。提供了以下格式:IP Catalog, System Generator for DSP, and Synthesized Checkpoint (.dcp)。
要将Vivado HLS项目存档为行业标准ZIP文件,请选择file > archive。使用Archive Name选项为指定的ZIP文件命名。您可以按照以下方式修改默认设置
在Windows上,Vivado HLS命令提示符可以从“开始”菜单中调用Xilinx
Design Tools → Vivado 2018.x → Vivado HLS → Vivado HLS 2018.x Command Prompt.
在Windows和Linux上,使用vivado_hls命令中的-i选项可以在交互模式下打开Vivado HLS。然后Vivado HLS等待输入Tcl命令。
默认情况下,Vivado HLS在当前目录中创建一个vivado_hls.log文件。要为日志文件指定不同的名称,可以使用-1
help命令用于访问关于这些命令的文档。所有命令的完整列表提供使用:
使用命令名可以对任何单个命令提供帮助。
任何命令或命令选项都可以使用自动完成功能来完成。在指定了单个字符之后,按tab键会导致Vivado HLS列出完成命令或命令选项的可能选项。输入更多字符可以改进对可能选项的筛选。例如,在键入open之后按tab键列出以open开头的所有命令。
在键入open_p自动完成open_project命令后选择Tab键,因为没有其他可能的选项。
键入exit命令退出交互模式并返回到shell提示符
Vivado HLS的其他选项包括:
嵌入到Tcl脚本中的命令以批处理模式执行,使用-f
在GUI中创建项目的所有Tcl命令都存储在脚本中。解决方案中的tcl文件。如果希望开发Tcl批处理脚本,请使用该脚本。tcl文件是一个理想的起点。
在Windows操作系统上,Vivado HLS命令提示符是使用最简单的GNU for Windows (minGW)环境实现的,该环境允许使用标准的Windows DOS命令和/或Linux命令的子集。
下图显示了Linux ls命令和DOS dir命令都用于列出目录的内容。
请注意,并非所有Linux命令和行为都支持minGW环境。下面是一些已知的支持方面的共同差异.
Vivado HLS分级调度操作。循环中的操作被调度,然后循环、子函数和带有函数的操作被调度。当下面情况,Vivado HLS的运行时间将增加:
Vivado HLS调度对象。无论对象是浮点乘法操作还是单寄存器,它仍然是一个要调度的对象。浮点乘法可能需要多个周期来完成并使用许多资源来实现,但是在调度级别上它仍然是一个对象。