如何将C / C++ / OpenCL编译成硬件加速器
扫描二维码
随时随地手机看文章
介绍
在这里,我们提供了一个关于如何生成静态比特流的分步教程。我们以Sobel边缘检测算法为例来演示这一过程。但是,对于您可能想要创建的其他模块,步骤是相同的。
设置
下面列出了我用来生成Sobel算法的静态比特流的工具:
工具使用:
•Vivado 2018.3
•Ubuntu 16.04.5 LTS
•Avnet Ultra96v1开发板
•OpenCL, OpenCV, C/ c++
•Sobel OpenCL代码
使用Vivado HLS创建自定义模块
步骤1 -创建一个新项目
•要创建一个新项目,请转到File > new project
•为项目选择合适的名称和位置。
•接下来,输入程序中主函数的名称。在我们的例子中,这是krnl_sobel。从这里您可以导入源文件。您还可以在稍后的过程中导入源文件,我将指出这一点。
•这同样适用于测试台架文件。
•该屏幕允许我们将模块定制为特定的体系结构。单击下一个窗口的“部件选择”区域中的3个点。从这个窗口,您可以选择一个特定的FPGA或板。在本教程中,我们选择一个特定的板来合成我们的模块。需要注意的是,Vivado 2018.3不包含Ultra96平台的入口。然而,在设计模块时,我们发现使用ZCU102平台可以很好地工作,因为它们都使用相同的ZYNQ FPGA。
•我们不需要担心窗口时钟部分的任何选项。您可以为您的解决方案选择一个不同的名称。
•最后要做的事情是选择Finish按钮。
•从这里右键单击资源管理器菜单中的源文件,然后选择新建文件…从这里导航到包含要导入的源文件的目录。在同一个资源管理器菜单中的“测试台”也是如此。应该注意的是,您应该包含模块需要测试的任何头文件或测试数据。
•您可以通过从source目录打开该文件来查看和修改源代码。对于本教程,源代码将在不修改的情况下自动合成。“杂项”部分包含我们对源代码所做的修改,这样它就可以与更大的项目兼容。
步骤2 - C仿真
步骤3 -合成和创建RTL模块
•开始合成的按钮是绿色三角形。
•如果合成成功,将出现以下选项卡:
•此页签包含生成的接口信息。例如,从和主AXI端口的总线宽度
•要创建在Vivado方框图中使用的RTL模块,只需按下“Export RTL”按钮。
•对于本教程,您可以将这些选项保留为默认值。
在Vivado中使用自定义模块
步骤1 -创建一个新项目
•要创建一个新项目,请转到File > project > new…
•按下next键进入以下屏幕:
•在继续之前,为新项目选择一个合适的名称和位置
•对于本教程,在下一个菜单中选择RTL项目选项
•下一个窗口是将源文件添加到块设计的一种方法:
•在本教程中,我们使用不同的方法。然而,两者是相等的
•在本教程中,我们不会添加任何约束
•对于默认的部件菜单,我们将转到电路板并选择Ultra96v1评估平台
•如果一切正常,您可以单击Finish按钮并开始使用框图
•在下一个窗口中,您可以添加sobel模块。去工具>设置…> IP >存储库
•从这里,转到Add,然后导航到存储sobel模块的位置。注意,只需要选择文件夹,Vivado会自动检测其中的IP。完成后,单击Apply和OK
步骤2 -创建块设计
•从Vivado窗口的Flow Navigator菜单中,您可以选择Create Block Design选项开始
•除了设计名称外,所有内容保持不变,设计名称可以根据您的判断进行更改。
•在Vivado窗口的Diagram部分,您可以单击,或者按CTRL + I,向图中添加新的IP
•首先获得代表您的处理系统的块,PS.对于本教程,我们使用Zynq Ultrascale+ MPSoC PS.然后单击弹出的“运行块自动化”链接。确保选中PS并单击OK
•接下来我们要设置的是一个从和主AXI端口,用于将PS连接到我们创建的Sobel模块。要做到这一点,双击PS块。进入“PS-PL Configuration > PS-PL Interfaces > Master Interface”,选择其中一个选项。然后转到Slave Interface > AXI HP并选择其中一个选项
•现在我们添加我们创建的Sobel模块。为此,导航到菜单,通常选择您想要的IP并搜索您在Vivado HLS中指定的顶级函数的名称。在我们的例子中,这是Krnl_sobel。将其添加到块设计中。
•在弹出的窗口中单击“Run Connection Automation”链接。这将添加必要的连接块,我们需要能够使用Sobel模块。在按OK之前,确保所有的框都被选中了。
步骤3 -生成比特流
•生成比特流是一项简单的任务,但首先,我们需要验证我们的设计。从Diagram窗口的顶部选择Validate Design选项,或者按F6。如果这样做正确,它应该告诉您从AXI端口被排除。
•这可以通过地址编辑器选项卡和打开sobel模块部分,然后排除地址段来修复。要修复验证问题,只需右键单击被排除的地址段并选择Include segment。
重新验证设计
•在生成比特流之前,我们需要为我们的设计创建一个HDL包装器。这很容易做到。转到Vivado屏幕上的源菜单,右键单击要创建包装器的设计文件,然后选择“创建HDL包装器”。保持所有为默认值并选择OK。
•从Flow Navigator菜单中选择Generate Bitstream。保持所有内容为默认值并单击OK。这一步需要一些时间,所以去拿一杯饮料然后回来。
•要查找比特流,请导航到为项目创建的目录。对于我们来说,我们将导航到sobel.runs/impl_1/design_1_wrapper.bit。注意,sobel是我们目录的名称,它将被您命名的目录所替换。
•一旦你找到了。我们需要转换可以加载到FPGA上的图像文件。为此,我们使用Xilinx的Bootgen。这很容易做到。最好在您找到的目录中。比特文件,创建一个名为bitstream.bif的文件。其内容应如下:
一旦比特流。如果文件已创建,只需执行以下命令:
Misc
本节包含在开发过程中可能需要或想要的有用修改
32位和64位接口
采用原始的Sobel OpenCL代码,数据总线为512位。对我们来说,这仍然是可用的,但它可以改变。为此,根据变量的不同,我们修改了函数形参列表,使其传递整型和整型指针。然后,我们将输入参数转换为原始类型的新变量。这使我们能够控制数据总线的宽度。
为了使用64位数据总线,您只需要在合成前向HLS中的配置添加一个选项。在Vivado HLS中,单击两个称为解决方案设置的黄色齿轮…,单击“添加”,在“命令”下拉菜单中选择“config_interface”。确保选中m_axi_addr64选项。
现在在合成之后,您的数据总线应该是64位宽
注:请记住,如果您创建64位接口,模块内部寄存器将是64位。您需要将这些上32位设置为0,否则,模块将使用存储在上32位中的任何值,并导致潜在的任意行为。
HLS中的主、从轴Pragma
掌握语法
如果你发现你需要映射一个参数到内存端口,基本结构如下:
Variable_name是一个表示数组的变量。应该注意的是,您应该只将数组映射到内存端口
本文编译自hackster.io