从2022年开始,我决定浏览我积压的项目想法的无穷无尽的列表,并决定打破这些很酷的老式QDSP-6061 5位气泡显示从惠普和创建一个驱动程序在Verilog。
我从Digilent公司拿出了我的Arty Z7板,并在Vivado/Vitis 2021.2中创建了一个项目来让它工作,你可以在我的上一个项目帖子中阅读,我在QDSP-6061的5位数上显示滚动文本,上面写着“Hello 2022”。
我最终创建的Verilog驱动程序非常简单,因为它在FPGA上电复位后立即开始运行,并且永远运行。所以我想添加几个功能1)控制,当驱动程序开始从arm内核上的C应用程序运行时,Zynq和2)能够发送驱动程序数据字符串,从C应用程序在显示器上滚动,而不是将其硬编码为“你好2022”。这两个功能都需要在arm内核上运行的C应用程序和在Zynq SoC FPGA的可编程逻辑中运行的Verilog驱动程序之间建立通信通道。
最简单和最直接的方法是将AMBA®AXI4(高级可扩展接口4)协议接口添加到QDSP-6061气泡显示的Verilog驱动程序中。现在,AXI接口是一组非常简单的握手信号,可以用简单的状态机在Verilog或VHDL的RTL端复制,但是从应用程序端编写相应的C驱动程序并不简单。
然而,Vivado/Vitis有一个方便的特性,它可以自动生成RTL和C代码与所需的AXI参数。我将演示如何在本项目中使用它。
值得注意的是,有三种主要的AXI4接口实现:
•Full AXI4
•AXI4-Lite
•AXI4-Stream
每种类型更适合不同的用例。在QDSP-6061气泡显示驱动程序的这种情况下,所有需要的是写一些值到一对寄存器,这不是大量的数据正在传输,没有任何严格的时序要求。因此,ax4 - lite是我选择为此实现的AXI接口的版本。
创建新的AXI4外设
从我上一篇文章中为Arty Z7创建的Vivado项目开始,你会看到我刚刚用Add模块直接将QDSP-6061驱动程序Verilog模块添加到块设计中…在编辑块设计时,右键菜单中可用的功能。
现在的目标是使用Vivado内置的包IP特性,用新的AXI4-Lite自定义IP版本替换它。因此,第一步是为QDSP-6061冒泡显示驱动程序创建一个新的AXI4外设IP块。
要在Vivado中创建一个新的axis4外设IP,请选择Tools b> create and Package new IP…
将在当前的Vivado项目中弹出一个窗口,该窗口打开后显示可用选项的简要摘要,包括创建新AXI4外设的选项。单击Next继续。
在第二页上,选择Create a new AXI4外设选项,然后在下面的页面上为外设提供所需的名称、版本和描述信息。
注意:不要在name字段中使用破折号或其他非法字符。因为在Name字段中传递的任何内容都被用作IP的Verilog模块名称。
下一页允许您设置自定义外设所需的主和从AXI接口的数量。这包括每个接口的AXI类型。在这种情况下,只需要一个从AXI4-Lite接口,因为我们只需要C应用程序能够写入RTL中的寄存器。
此外,在这个页面上,还有一些需要配置的设置,比如AXI接口的数据总线的宽度和可用的寄存器的数量。默认的数据宽度是32位,这就是我坚持的。最小寄存器数为4,这对于C应用程序将数据传递给QDSP-6061驱动程序来说已经足够了。
最后的摘要页面为下一步提供了一个新选项。在这种情况下,仍然需要添加气泡显示驱动程序的Verilog,因此我们选择Edit IP选项。
点击Finish并选择Edit IP选项后,将打开第二个Vivado项目:
对于一个AXI4-Lite IP项目,生成了两个Verilog文件:
顶层文件是外设实际功能的逻辑直接编码或实例化的地方。第二个在名称后面加上S00_AXI的是实现AXI握手信令逻辑的地方。这也是为外设添加自定义逻辑的地方,以便将数据拉入并发送到AXI总线,然后将其传递回顶级文件,以供外设的代码功能RTL使用。
自动生成的代码有很好的注释,并且清楚地标记了何时添加自定义RTL(包括在哪里添加端口和信号声明),并带有“在这里添加用户逻辑”注释部分。
AXI4-Lite自定义IP Verilog
我建议首先为自定义IP的核心功能添加逻辑,然后关注它将如何与AXI接口交互。因此,我从生成的顶级Verilog文件axi_qdsp_6061_controller_v1_0开始。v添加我写的Verilog来驱动QDSP-6061。
您可以像在普通的Vivado项目中一样导入现有的Verilog源文件,并在axis4外设项目的顶级源文件中实例化它,也可以直接编写自己的逻辑。
由于我需要对QDSP-6061驱动程序的Verilog代码进行一些更改,所以我选择直接将其复制+粘贴到顶级Verilog模块axi_qdsp_6061_controller_v1_0.v中
在复制粘贴我以前的Verilog之后,我添加了一个使能信号,只要使能信号是低逻辑电平(零),它就会使驱动程序处于复位状态。为了让这个项目的帖子写,它不会比它已经是更长,我决定离开可加载字符串配置另一天的滚动文本。
将核心功能添加到顶级文件后,很明显,需要与AXI接口交互的唯一信号是启用信号。因此,我将它作为一个端口添加到ax_qdsp_6061_controller_v1_0_s00_axis .v描述的AXI接口模块
同样,在文件的末尾是添加任何自定义逻辑的地方,而在顶部的端口声明是声明从顶级文件中的逻辑输入的任何信号的地方。
回想一下,我将axis4 - lite从接口配置为有四个寄存器用于写/读。我决定,为主驱动程序逻辑生成启用信号的最简单方法是,当C应用程序将值0xFFFFFFFF写入偏移量0x0的第一个寄存器时,将启用设置为高。
注意:寄存器彼此的偏移量为4,因此寄存器0的偏移量为0x0,寄存器1的偏移量为0x4,寄存器2的偏移量为0x8,寄存器3的偏移量为0x12。
基于在偏移量0x0处写入AXI从接口控制寄存器的0xFFFFFFFF值设置使能信号高的逻辑:
至此,已经添加了axis4 QDSP-6061驱动程序IP的所有自定义逻辑,我们可以继续进行最终配置。
切换到Package IP选项卡,有一系列的打包步骤。第一个参数只是前面设置的名称、描述和版本信息。在这里,您可以返回并根据需要编辑信息。
默认情况下,当调用选项Create and Package New IP时,IP仅与Vivado项目所针对的FPGA芯片兼容。由于我从我为Arty板创建的Vivado项目中选择了创建和封装新IP选项,因此默认情况下,AXI4 QDSP-6061驱动程序IP仅与Zynq-7000芯片兼容。这可以在打包步骤的Compatibility步骤中更改。
要使AXI4 IP与所有Xilinx fpga兼容,请单击Compatibility步骤中的+按钮,并选择Add Family explicit…
在“添加家族”弹出窗口中,选择您希望与AXI4 IP兼容的所有FPGA芯片。我刚刚检查了所有家庭和部件选项,但如果你担心这一点,这会使IP占用更多的硬盘空间。我还建议为生命周期选择生产选项,因为您很可能会使用生产级FPGA芯片。
通过其余的选项卡,不需要为axis4 QDSP-6061驱动程序IP编辑任何内容。但是,您可以看到这个创建和打包新IP工具将生成的所有文件,包括C应用程序源文件。你也可以做一些很酷的事情,比如在Vivado块设计中使用IP块时,在其上添加一个自定义徽标。
最后一步是打包IP(我的截图只说重新打包IP,因为我忘记在第一次打包之前抓取截图)。
在最后的打包步骤中单击Package IP按钮后,将出现一个弹出窗口,询问是否要关闭AXI外设的Vivado项目。您可以随时重新打开这个Vivado项目来修改/更新IP,方法是从包含自定义IP的存储库已添加到的任何Vivado项目中打开IP Catalog,并在IP Packager中选择Edit。
创建和打包新IP工具将在Settings > IP > Repository中自动添加自定义IP的原始Vivado项目。但是您需要将其手动添加到将来想要使用该IP的任何新Vivado项目中。
将AXI QDSP-6061 IP添加到Vivado框图中
随着AXI4 QDSP-6061驱动程序IP本身的完成,我回到原来的Vivado项目,用新的支持AXI的模块IP替换块设计中的RTL模块。
删除RTL模块后,在模块设计中使用+键或右键单击,选择“Add IP…”查找ax4 QDSP-6061驱动IP。在列表中双击它,将其添加到块设计中。
几分钟后,Vivado将在块设计中检测到新的AXI接口,并且连接自动化将弹出在块设计窗口的顶部。单击绿色横幅中的Run Connection Automation超链接,将出现一个弹出窗口,显示Vivado将如何将axis4 QDSP-6061驱动程序IP连接到带有Zynq处理系统IP的AXI总线。单击OK以运行连接。
我还选择将ila添加到axis4 QDSP-6061 Driver IP的AXI接口及其输出信号中,最初是为了进行故障排除,方法是右键单击每条线路并选择Debug,然后运行似乎生成ila的连接自动化。
新的积木设计是这样的:
验证设计(块设计窗口顶部带有复选框的按钮),然后保存并关闭块设计。
生成比特流和出口硬件平台
现在,块设计已经更新,运行合成,实现,并生成一个新的比特流。如果你没有读过我以前的任何Vivado 2021.2项目帖子,你需要点击生成比特流按钮,它将自动运行合成和实现,以避免无法找到板定义文件的关键警告(但这个警告是完全良性的,可以忽略,它只是激怒了我,所以我避免它)。
生成新的比特流后导出硬件平台,选择“File > Export > Export hardware…”
在弹出窗口中,确保选择包含比特流的选项。我选择导出硬件平台来覆盖之前的硬件平台。
最后,通过选择Tools > launch Vitis IDE启动Vitis
更新Vitis平台硬件规格
因为我已经为这个项目有了一个现有的Vitis工作空间,所以我重新打开了它,并用从Vivado导出的新硬件平台更新了平台项目(因为即使我重写了它,Vitis也不会自动检测和更新它的修改)。
右键单击Vitis项目的Explorer窗口中的平台项目(记得我在上一篇文章中将平台项目命名为arty_z7),然后选择Update Hardware Specification。
从Vivado导出的XSA硬件文件的目录路径可以保持不变,因为我只是覆盖了旧的路径。然后单击“确定”。
一旦平台项目显示过时,就清理它。一旦完成,立即运行一个清理应用程序项目。
清理完平台和应用程序项目后,构建平台项目,然后构建应用程序项目。
始终在应用程序项目之前清理/构建平台项目是很重要的,因为应用程序项目依赖于平台项目。
重要的是要注意,在Vitis工作空间中更新硬件平台的方法通常总是不同于每个版本的Vitis。我发现这种方法在2021.2有效,但在2019.2,如果不关闭并重新启动Vitis,就无法更新硬件平台。
Vitis应用程序C代码
最后是编写C应用程序来控制ax4 QDSP-6061驱动程序IP的时候了。这段代码将通过写入0xFFFFFFFF来在IP块中注册零来断言/取消断言RTL中的启用信号。
正如我前面提到的,有四个寄存器被写入偏移量0x0、0x4、0x8和0x12。由于我对Verilog进行了编码,以便在偏移量0x0的寄存器的所有32位设置为0xFFFFFFFF时将启用信号设置为气泡显示驱动程序高,因此C代码需要将0xFFFFFFFF写入偏移量0x0的寄存器。
为自定义AXI4外设自动生成的源文件出现在Vitis平台项目中的几个不同位置,但是您需要在以下位置编辑源文件,以便全局更新它们,并可用于应用程序项目中的主函数://ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0/libsrc//src
一定要在头文件中包含函数声明(在本例中为axi_qdsp_6061_controller.h),然后在相应的C文件中编写函数体(axi_qdsp_6061_controller.c)。
还生成了一个自测源文件,您可以将其用作模板。但是您需要记住,它自动生成的代码是尽可能一般化的。因此,它可能会为您的自定义应用程序抛出警告和信息消息(基本上,我警告任何新手不要将自测中的自动生成代码视为黄金,这可能对您的应用程序是错误的)。例如,将axis4 QDSP-6061驱动程序IP的基址作为空类型指针传递,会导致各种问题。因此,我将其更改为在实际写寄存器函数中作为简单的整数值类型转换为u32传递:
我的主函数变得非常简单,因为所有需要发生的是一次写0xFFFFFFFF以在偏移量0x0处注册零:
保存所有文件并构建应用程序项目。
调试应用程序
启动调试运行应用程序来测试它。将Arty板插入主机PC,然后从资源管理器窗口右键单击应用程序,并选择Debug As b>在硬件上启动(单个应用程序调试)。这将打开Vitis中的调试视图,并在main函数的入口处设置一个断点,以允许您逐行执行应用程序。
如果您将ila添加到块设计中,请切换回Vivado并在硬件管理器中打开它们,然后在Vitis中逐步执行应用程序。在Vivado的Flow Navigator窗口中,选择Open Hardware Manager > Open Target > Auto Connect, Vivado将为您打开ILA窗口。
我为AXI ILA窗口设置了写地址通道有效(AWVALID)、写数据通道有效(WVALID)和写响应通道有效(BVALID)信号上的触发器,以便在执行寄存器写函数时捕获来自C应用程序的实际写事务。
我还在AXI4 QDSP-6061驱动IP的输出线上设置触发器,以查看何时/是否开始驱动阴极和阳极线,以验证写入值0xFFFFFFFF以注册零确实设置了逻辑高的使能信号。
本文编译自hackster.io