《LabVIEW ZYNQ FPGA开发宝典》第5章-5.3:LabVIEW ZYNQ芯片内部的PL(FPGA)程序开发实战演示

        下面我们按照前面5.2.1节介绍的流程来分步实现具体每一个环节和步骤。大家看仔细了!跟着我们的思绪开始LabVIEW ZYNQ芯片里面的PL端FPGA开发之旅吧!

    5.3.1:LabVIEW ZYNQ PL端FPGA项目创建(项目浏览器)

        1)启动LabVIEW 2020 SP1,如图5-44所示。

图5-44:启动LabVIEW 2020 SP1

        2)然后点击左上角的“File/文件”,选择下拉菜单里面的“New/新建(N)”选项,打开“New/新建”窗口,如图5-45所示。

图5-45:打开“New/新建”窗口

        3)展开图5-45中的“Project/项目”一栏,双击“Empty Project/空白项目”图标,新建一个空白的LabVIEW项目浏览器,如图5-46所示。点击工具栏里面的“Save All(this Project)/保存全部”,将这个项目保存为“My_FPGA_Stater_Board_ZYNQ7020_PS+PL.lvproj”。

图5-46:新建一个普通的LabVIEW项目浏览器

        4)右击“My Computer/我的电脑”选项,选择“New/新建>> Targets and Devices/终端和设备”,如图5-47所示。

图5-47:右击新建一个“Targets and Devices/终端和设备”

        5)在弹出来的“Add Targets and Devices on My Computer/在我的电脑上添加终端和设备”窗口里面,选择“New target or device/新建终端或设备”这个选项之后,就能在“Targets and Device Types/终端和设备类型”下拉列表里面看到我们精心为用户准备的Xilinx ZYNQ芯片了,如图5-48所示。从里面可以看到Xilinx所有ZYNQ家族不同型号不同封装的芯片归类。展开文件夹之后,可以看到每个系列里面都有不同速度等级、不同资源门数和不同封装的ZYNQ FPGA芯片。

图5-48:点击“New target and device/新终端和设备”

        6)由于本宝典(My FPGA ZYNQ Pro20系列)配套的FPGA开发板是正点原子领航者ZYNQ7020开发板,上面用到的芯片型号是XC7Z020_2CLG400。因此,这里我们可以展开文件夹“My_FPGA_ZYNQ_XC7Z020”,然后选择里面的“ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All”,这是一个涵盖了PS端与PL端之间Reg、Memory、FIFO、DMA、UART、CAN、IIC、SPI、PWM、Ethernet全部驱动封装出来的FPGA终端,如图5-49所示。

图5-49:选择“ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All”FPGA终端

        7)点击上图5-49窗口里面的“OK/确定”按钮,即可创建一个FPGA目标终端设备,如图5-50所示。

图5-50:创建出来的“ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All”FPGA终端

        可以看到这个FPGA终端设备依附于“我的电脑”,并非是一个独立的RT设备,因为我们还没有创建Linux RT项目。点击展开FPGA终端前面的“+”号,可以看到FPGA里面有一个“OnboardClock”时钟资源,这个板载时钟就是挂在ZYNQ PL端FPGA引脚上的晶振,一般多是50MHz或者40MHz的有源晶振,比如本书配套的原子领航者ZYNQ7020开发板上PL端时钟晶振连接的FPGA引脚是BANK34上的U18,对应的原理图如图5-51所示。

图5-51:挂在ZYNQ芯片PL端晶振连接的FPGA引脚是U18(BANK34)

        而后续介绍的ZYNQ芯片PS端ARM引脚上也有一个33.333333MHz时钟晶振,这是给整个ARM内核提供时钟驱动的。对应的PS端引脚一般是固定的,通常ZYNQ芯片有一个BANK500,上面有一个名为“PS_CLK_500”时钟引脚,就像单片机引脚,这个PS端时钟引脚不能随意更改。对应的PS端时钟引脚与晶振原理图,如图5-52所示。

图5-52:给ZYNQ芯片PS端ARM部分提供时钟的晶振原理图和引脚(BANK500)

        提醒:网上有些卖家做的ZYNQ板子只有PS端连了33.333333MHz晶振,而PL端FPGA部分一个晶振都没有预留,那么FPGA里面的逻辑代码还能不能运行呢?实际上,这是为了节省硬件成本的一种做法,PS端可以将外部33.333333MHz晶振进行倍频之后升到766MHz或者866MHz驱动整个ARM电路,同时PS端IP核还可以通过配置生成一路时钟给到PL端驱动FPGA电路工作。默认情况下,PS端会习惯生成一路50MHz时钟通过内部连线路由给到PL(FPGA)端,这样一来,就算PL端FPGA没有外置独立晶振也能工作了。但是为了让PL端FPGA部分即使在没有配置PS端的前提下也能独立自主运行的话,建议还是参考大众设计,给PL端FPGA的某个MRCC或者SRCC引脚挂上一个独立晶振。

        8)修改ZYNQ PLFPGA)端晶振时钟引脚或者晶振频率来适配用户自己的板子。

        注意1需要提醒用户的是,我们提供的所有通用FPGA终端包含的xdc约束文件里面的晶振默认接的是FPGA芯片序号最小的第一个BANK上的MRCC这个引脚。如果用户自己做的ZYNQ板子或者买的第三方ZYNQ硬件不是接的这个引脚,可以参考下面的方式进行修改适配,以便让我们的ZYNQ PL端FPGA VI可以正常下载运行起来。

        注意2如果用户自己设计的或者购买的ZYNQ PL端FPGA部分接的是差分晶振,那么下面选择和修改的引脚必须是FPGA芯片上带P(正极)的引脚,不能选择N(负极)。因为Xilinx FPGA对应的ISE和Vivado编译器默认情况下只支持正极性单端时钟。当然,我们现在解决了可以直接在xdc约束文件里面添加差分晶振的时钟信号了。

        如果用户自己做的板子或者购买别家的ZYNQ板子上面的晶振引脚不是这个,比如,之前有个日本客户,做了一款基于FPGA的高速PLC板卡,FPGA时钟输入是20MHz晶振,还有像广州创龙的板子用的是24MHz非标准的这种晶振,再比如Digilent公司的ZYNQ开发板,板载晶振频率是100MHz。无论硬件怎么变,都可以进行修改适配新的FPGA硬件。这也再次说明了我们开发这个My FPGA软件工具包的初衷:让用户充分自由开发和定制属于自己的FPGA硬件,我们专注于做通用LabVIEW FPGA软件工具包

    5.3.2:LabVIEW ZYNQ PL端FPGA应用程序编写(VI)

        1)右击“FPGA Target(My_FPGA, ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All)”,选择“New/新建>>Virtual Folder/虚拟文件夹”,创建一个虚拟文件夹,如图5-53所示;然后重命名为“实验1-FPGA入门实验(ZYNQ PL端)”,如图5-54所示。

图5-53:右击FPGA终端新建一个虚拟文件夹

图5-54:将虚拟文件夹重命名为“实验1-FPGA入门实验(ZYNQ PL端)”

        2)右击虚拟文件夹“实验1-FPGA入门实验(ZYNQ PL端)”,选择“New/新建>>VI”,如图5-55所示;然后保存该VI,命名为“实验1-FPGA入门实验(ZYNQ PL端).vi”,如图5-56所示。

图5-55:将VI另存为“实验1-FPGA入门实验(ZYNQ PL端).vi”

        3)我们需要演示一下如何控制挂在PL端FPGA部分的ZYNQ核心板上1个LED灯和底板上的2个LED灯亮灭。因此,我们需要根据原理图找到这3个LED灯对应的ZYNQ芯片PL端的FPGA I/O引脚。这里面的I/O资源在我们另外一本书《STM32开发实战:LabVIEW卷》里面反复介绍过,叫Elemental I/O,简称EIO节点。其实ARM里面的EIO引脚节点正是来源于NI FPGA工具包。

        右击“FPGA Target(My_FPGA, ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All)”或者虚拟文件夹“实验1-FPGA入门实验(ZYNQ PL端)”,然后选择“New/新建>>FPGA I/O”,如图5-56所示。

图5-56:新建一个FPGA I/O资源

        4)然后在弹出来的“新建FPGA I/O”窗口里面,可以看到这款ZYNQ芯片PL端FPGA部分所有可以使用的IO引脚资源情况,如图5-57所示。我们(神电测控)将Xilinx FPGA芯片本身不可用的VCC和GND引脚除外,其余所有I/O引脚全部封装成EIO提供给用户进行自由选择。可以看出,ZYNQ7020-CLG400这个封装的ZYNQ芯片PL端FPGA部分有3个BANK的IO引脚可以使用,分别是BANK13、BANK14、BANK35。

        Xilinx FPGA的IO分布一般会分为几个BANK区域,这个用户在后期绘制原理图的时候,可以看到Xilinx官方提供的FPGA原理图库也是按照BANK来划分的,因此我们根据Xilinx官网上的引脚分布列表进行划分。

图5-57:FPGA I/O可用资源

        5)可以看到,可用资源里面共有9个虚拟文件夹,实际上只有3个BANK,因为我们把同一个BANK分成了3个虚拟BANK文件夹(IN、OUT、ENA),分别对应同一个物理IO引脚的输入、输出和输出使能3种状态。这种表示FPGA引脚IO的方式属于NI后来推出的,可以在一个CLK周期之内实现高阻态切换的新型EIO节点模式,我们称之为“新型EIO节点”。而传统的类似ARM那种EIO节点,只有一个EIO,无法快速实现高阻态的切换,在第一本书《LabVIEW FPGA开发宝典:Spartan6》里面已经详细介绍了,本书就不再重复了,不记得的用户可以回顾一下。

        注意1之所以在7系列和ZYNQ系列FPGA里面我们把所有可用的FPGA IO全部封装成新型EIO节点,而Spartan6、Spartan3E、Virtex5里面没有全部封装,是因为Xilinx ISE编译器有bug,不支持一次性将所有EIO节点变成3个状态全部写到ucf文件里面编译,而新推出的Vivado 2014.4/Vivado2017.2/Vivado 2019.1/Vivado 2021.1编译器(LabVIEW FPGA 2015/2018/2020/2022版本对应的Vivado编译器版本)目前来看,不存在这个问题,软件用到多少,就会编译多少,而且不会出现因为使用IO引脚多导致编译失败的情况。所以我们推出的LabVIEW My FPGA ZYNQ工具包以及Artix7、Spartan7、KINTEX7、Virtex7、KU、KU+、VU、VU+都会沿用这种方式,全部采用新型EIO节点,这样FPGA芯片的每个IO都能实现单总线、IIC这类需要双向通信的协议。

        注意2有些用户编写的FPGA程序不需要对一个IO进行快速双向读写,更习惯于传统EIO节点的使用,那怎么满足这部分用户的需求呢?其实非常简单,就是我们封装的新型EIO节点里面,只要不去调用OUTENA,每个引脚对应的IN节点其实本质上就是传统的EIO节点,因此大家可以直接把IN节点当成一个传统的EIO节点来使用即可!后缀为INEIO节点通过切换读取或者写入方向就能完成输入或者输出了,也很方便。如果要实现非单周期内的IO引脚高阻态切换,可以使用FPGA IO函数选板里面的方法属性节点(设置输出数据和设置输出启用)来完成,具体的方法跟Pro1第一本书里面介绍的传统EIO节点完全一样;如果要实现单周期高阻态切换,可以使用新型EIO节点的OUTENA来组合完成,这类EIO节点一般用于单总线或者IIC总线之类需要快速切换的应用场合,可以看出,新型EIO节点要比传统的EIO节点更加灵活方便。

      下面我们对新型EIO节点方式的功能和用法进行详细的讲解

        新型EIO节点:适用于inout数据类型,可与IP Node进行结合,输入输出模式切换速度快,一个CLK时钟周期内可完成工作模式切换。

        为了让用户后期可以方便的实现诸如单总线、IIC总线通信,类似这种占用同一个引脚的数据线,在读入引脚状态的时候,需要设置引脚为高阻态。其实也就是想办法将传统VHDL/Verilog里面定义的inout类型,用LabVIEW里面的FPGA语法实现。由于NI FPGA软件提供的IP Node(类似DLL函数调用节点)本身不支持inout类型,所以我们将传统EIO节点进行升级改造,将一个EIO资源同时拆分为3个独立的I/O资源:输入、输出、使能。这样做的目的是可以通过“使能”这个开关来控制I/O当前是输出状态还是高阻态(输入)。默认情况下,我们将支持Vivado编译器的7代Xilinx FPGA芯片ZYNQ、ARTIX7、Spartan7、KINTEX7、Virtex7、KU、VU、KU+、VU+所有I/O引脚,全部封装成这种EIO节点。

        举例说明,譬如我们将BANK13里面的V5这个引脚涉及的3种EIO资源:使能(ENA)、输入(IN)、输出(OUT)分别添加到右侧的表格里面,如图5-58所示。

图5-58:添加V5引脚对应3种状态的EIO资源

        点击“OK/确定”按钮后,这3个EIO资源被添加到了FPGA终端项目里面,如图5-59所示。

图5-59:同一个物理引脚V5对应3个EIO资源

    如果用户想要读取V5引脚上的高低电平,需要先设置“使能状态”EIO(V5_IO_L6N_T0_VREF_ENA)为“假”,将V5切换为输入模式,也就是高阻态,然后再通过读取“输入”EIO(V5_IO_L6N_T0_VREF_IN)返回值就可以了。按住鼠标左键,将FPGA项目下的EIO节点拖拽到程序框图里面,然后将ENA节点右击选择“转换为写入”切换成赋值模式,如图5-60所示。可以看出与传统EIO节点不同,新型EIO节点需要同时控制两个EIO才能完成一个工作模式。具体的实现过程,可参考本书配套的视频教程(第5章:LabVIEW ZYNQ FPGA开发流程)。

图5-60:ENA设置为 “假”,切换至高阻态模式,读取引脚电平状态

    如果用户想要控制V5引脚输出高低电平,需要先设置“使能状态”EIO(V5_IO_L6N_T0_VREF_ENA)为“真”,将V5切换为输出模式,然后再赋值给“输出”EIO(V5_IO_L6N_T0_VREF_OUT)就可以了,如图5-61所示。具体的实现过程,可参考本书配套的视频教程(第5章:LabVIEW ZYNQ FPGA开发流程)。可以看出与传统的EIO节点不同,新型EIO节点同样需要同时控制两个EIO才能完成输出工作模式。

图5-61:ENA设置为“真”,切换至输出模式,输出控制引脚电平状态

        注意:如果用户程序里面用到的I/O只要一直处于输入或者输出模式,那么可以在初始化的时候将“使能ENA”设置为假或者真,放在循环外面执行一次就可以了,而需要连续读取或者写入EIO的节点可以放在循环里面。这样更节省FPGA资源,如图5-62所示。

图5-62:初始化确定EIO工作模式

        6)上面介绍的这种EIO节点,在后续的第6章里面会给大家具体演示怎么使用。

        接着前面未完成的实验,我们要控制原子领航者ZYNQ开发板上的3个PL(FPGA)端LED灯亮灭,所以,先打开本书配套云盘里面的1号文件夹里面的ZYNQ开发板原理图(分为底板+核心板),如图5-63所示。然后找到挂在PL端ZYNQ核心板上1个名为“PL_LED”关联的FPGA芯片引脚,如图5-64所示;再到底板原理图上找到名为“PL_LED0”和“PL_LED1”这2个指示灯关联的FPGA芯片引脚,如图5-65所示。

图5-63:打开云盘里面的1号文件夹-原子领航者ZYNQ底板和核心板原理图

图5-64:找到挂在PL端ZYNQ核心板上的1个指示灯(PL_LED)对应的FPGA引脚

图5-65:找到PL端ZYNQ底板上的2个指示灯(PL_LED0、PL_LED1)对应的FPGA引脚

        当然,还可以通过查看原子汇总后的ZYNQ IO引脚分配Excel总表,可以快速找到每个外设对应的ZYNQ芯片引脚,如图5-66所示。这里之所以带着大家看原理图,希望大家多学一点知识。

图5-66:直接通过原子提供的汇总后的ZYNQ开发板引脚分配表格查看

        7)通过上面的原理图或者引脚分配Excel表格,可知ZYNQ开发板上挂在PL端FPGA部分的3个用户LED灯对应的引脚分别是:J16、H15、L15。接下来,我们就可以通过右击添加FPGA I/O的方式,在FPGA可用资源列表里面找到这3个PL(FPGA)端引脚对应的使能和读写EIO资源,添加到右侧的表格里面,重命名为“PL_Core_LED”、“PL_Carryboard_LED1”和“PL_Carryboard_LED2”,如图5-67所示。注释:Core意为核心板的意思,Carryboard意为载板底板的意思,以示区分这3LED的用户含义

图5-67:找出3个PL端LED灯对应的FPGA引脚

        点击“OK/确定”按钮后,即可将这3个LED灯添加到FPGA终端里面,如图5-68所示。

图5-68:将这3个PL端用户LED灯对应的EIO资源添加至FPGA终端

        8)鼠标左键按住这3个EIO节点将其拖到程序框图里面,然后右击LED灯EIO节点切换为输出模式,如图5-69所示。

图5-69:将LED灯EIO节点拖拽至程序框图并切换成输出模式

        9)然后放置一个while循环将PL_Core_LED_OUT灯包含进去实现循环连续控制,利用移位寄存器周期性取反控制PL_Core_LED_OUT亮灭,用这个指示灯的闪烁来判断后续FPGA程序是否正常加载和运行了;再在while循环前面放置一个初始化顺序帧,通过对PL_Core_LED_ENA使能节点进行赋值,将PL_Core_LED_OUT设置为输出模式,如图5-70所示。

图5-70:添加while循环和EIO初始化设置代码

        10)在程序框图空白处右击找到“Timing/定时”函数选板里面的“Loop Timer/循环定时器”函数,将其添加到程序里面,如图5-71所示;然后在弹出来的“Configure Loop Timer/配置循环定时器”对话框里面将计时器单位设置为ms,如图5-72所示。

图5-71:右击添加“Timing/定时”函数选拔里面的“Loop Timer/循环定时器”函数

图5-72:将计数器单位设置为ms

        11)最后右击循环定时器创建一个默认值位100的输入控件,如图5-73所示。这样我们这个while循环周期就是100ms,后续我们可以利用LabVIEW FPGA在线前面板交互式运行功能,动态修改这个while循环周期来观察一下实际的LED灯闪烁频率和FPGA运行状态。至此一个简单的LED灯闪烁ZYNQ FPGA程序就编写完成了。对应的FPGA VI前面板如图5-74所示。

图5-73:创建一个常量控制while循环周期为100ms

图5-74:对应的ZYNQ FPGA VI前面板控件

        11)上面ZYNQ核心板上的LED灯是由FPGA本身来驱动的,用的时钟也是FPGA端板载的50MHz晶振时钟驱动的;余下的两个PL(FPGA)端指示灯,如果我们想要通过PS(ARM)端的Linux RT程序来控制二者点亮或者熄灭,该怎么写呢?

        这里就涉及到了,我们给ZYNQ芯片封装映射到PL(FPGA)端的Socket CLIP端口了,比如控制LED,PS(ARM)端可以通过对Bool类型的Reg寄存器进行赋值来实现对PL(FPGA)端的IO引脚控制。

        这里用到的负责沟通PS与PL之间的Reg通道,位于FPGA终端下“PS_System_Reg Data”的这个CLIP,展开之后,可以看到里面我们给大家封装了4对8位、4对16位、4对32位和32对Bool类型的Reg寄存器通道,每一对表达的是双向通信的意思,如图5-75所示。提醒:其中CLIP里面的端口信号名称前缀带PS2PL说明这个通道方向是由PS(ARM)发送数据给PL(FPGA),我们称之为“下行”,因为PS端一般是Host主机端,PL端一般是Slave从机;反之,如果CLIP端口前缀是PL2PS,那就是FPGA发送数据给PS(ARM),俗称“上行”。

图5-75:ZYNQ PL FPGA终端下我们封装好的双向Reg寄存器通道

        12)显然,如果PS(ARM)端要想控制PL(FPGA)端,肯定是下行,也就是PS端发送指令或者数据给PL端。由于本节实验里面要控制的是PL端的两个LED灯,属于布尔类型,因此,我们可以从FPGA终端里面的32路Bool类型随便挑选2个拖拽到FPGA程序框图里面,然后将其与FPGA里面的“PL_Carryboard_LED1”和“PL_Carryboard_LED2”关联起来,比如这里,我们选择“lv_PS2PL_Reg_Bool_1”和“lv_PS2PL_Reg_Bool_2”这两个寄存器通道,如图5-76所示。

图5-76:PS(ARM)端控制PL(FPGA)端的2个用户LED灯

        需要注意的是:由于这些Socket CLIP通道负责PS(ARM)与PL(FPGA)之间的交互,因此它们需要一个共同的时钟来驱动,这里我们需要用到PS端产生的内部时钟FCLK,作为FPGA里面读写Socket CLIP下所有端口信号的时钟,虽然这个FLCK时钟频率我们之前配置的也是50MHz,但是这个FCLK跟前面的板子50MHz晶振不是一回事,切记不要弄混了。那么这个FCLK时钟在哪呢?就在PWM这个Socket CLIP下面“Clock lv_FCLK_CLK0_PS2PL”,如图5-77所示。

图5-77:PWM这个CLIP里面有PS(ARM)端产生的给到PL(FPGA)端的时钟FCLK

        注意:图5-77里面的定时循环时钟源“Clock lv_FCLK_CLK0_PS2PL”对于含有A7架构的ZYNQ7020来说,实际上是50MHz;对于含有K7架构的ZYNQ7100来说,则是100MHz。这个时钟是由PS端ARM生成驱动PL端FPGA的。

        因此,FPGA VI程序框图里面包含了CLIP端口的while循环,必须要用定时循环,并且这个定时循环的时钟必须是这个FCLK(Clock lv_FCLK_CLK0_PS2PL),如图5-78所示。

图5-78:包含PS与PL互通的端口节点必须要用定时循环和FCLK这个时钟来驱动

        13)最终,编写完成的ZYNQ PL端FPGA VI程序前面板,如图5-79所示;对应的FPGA VI程序框图,如图5-80所示。

图5-79:ZYNQ PL端入门实验FPGA VI程序前面板

图5-80:ZYNQ PL端入门实验FPGA VI程序框图

    5.3.3:LabVIEW ZYNQ PL端FPGA仿真、编译、下载、在线前面板交互式运行和调试

        一般情况下,为了减少FPGA VI的编译次数和提高调试效率缩短开发周期,用户可以参考下面的5个步骤进行:仿真、编译、下载、在线前面板交互式运行和调试。

        其中:

       “仿真”是指FPGA VI运行在PC机上,可以借助LabVIEW在线模拟,快速调试代码的功能来消除bug;“编译”阶段指的是LabVIEW将FPGA VI转换成VHDL然后传递给Xilinx的ISE或者Vivado编译器进行编译生成可执行的bit位文件。

       “下载”阶段则是LabVIEW可以自动将编译完成的位文件通过JTAG下载器直接下载到FPGA芯片里面。

       “运行”阶段则是,如果FPGA板载时钟没有问题,下载后的FPGA VI前面板会自动处于运行状态。

       “调试”阶段则是,用户可以借助LabVIEW前面板上的输入输出控件来调试这个FPGA VI,注意:不能借助程序框图里面的探针,这是因为FPGA VI已经下载到FPGA芯片里面了,FPGA运行速度非常快,程序框图相当于无效了。

        在线前面板交互式运行(重点):

        重大更新:除了Spartan3E/Spartan6/Virtex5等传统的5系列、6系列FPGA芯片外,我们还支持Xilinx 7系列(Artix7Kintex7Virtex7)、KUVUKU+VU+ZYNQ等家族FPGALabVIEW在线前面板交互式运行调试。

        我们神电测控是真正在不破坏板子、对市面上已有的任何厂家的Xilinx FPGA板子不做任何改动,不做任何飞线的情况下,借助大家所熟知的低成本的Xilinx JTAG下载器,实现了真正意义上的FPGA VI在线前面板交互式运行调试。

        我们的LabVIEW My FPGA图形化开发方案具有普适性,因为我们没有对FPGA硬件做任何改造,也没有借助任何NI芯片,只有这样,才能让广大用户自由选择市面上已有的海量的FPGA板子或者自己设计的板子,而不是被NI或者其他友商固定的硬件绑架了。

        因为我们一贯秉承的理念是:

       “为所有想用又不敢用、正在使用和将要使用FPGA的用户,提供一套通用的国产化、图形化、开源化RIO解决方案。”

        当然了,传统的FPGA开发和调试方法,一般都是通过串口、网口或者按键进行代码运行调试,这种传统方式我们不抛弃也不放弃,只是相比强大的LabVIEW FPGA VI在线前面板交互式运行调试而言,传统调试方法的效率太低了,因为它需要反复编译FPGA VI,费时费力。

        下面我们带着大家按照上面的5个阶段分别进行讲解和演示。

        5.3.3.1:LabVIEW ZYNQ PL端FPGA VI离线仿真

        1)前面我们编写好的VI程序虽然比较简单,只有1个while循环、1个定时循环和3个IO控制,但是在编译下载前,我们还可以借助上位机LabVIEW对其进行功能性仿真,做到心中有数。如果程序有复杂的算法(比如FFT)或者时序(FIFO溢出),更需要如此。如果用户对LabVIEW非常熟练精通的话,也可以跳过这个步骤,直接进入编译下载环节。

        右击FPGA终端,选择“Select Execution Mode/执行VI>>Simulation(Simulated I/O)/带仿真I/O的计算机”,如图5-81所示。一旦切换到这个模式,表明位于该ZYNQ FPGA终端项目下的所有VI都会在PC机上进行在线模拟运行。

图5-81:将VI执行模式切换到计算机仿真模式

        2)然后打开“实验1-FPGA入门实验(ZYNQ PL端).vi”,点击左上角的“运行”箭头按钮,如图5-82所示。此时发现这个VI运行起来了,可以看到前面板上的“Running_FPGA”显示控件里面的数值不变化始终为1,而“Running_FCLK”显示控件里面的数值是以非常快的速度在增加,说明当同时存在while循环和定时循环的情况下,while循环得到的模拟时间比较少;如果大家将程序框图里面的定时循环禁用掉,如图5-83所示,再次运行FPGA VI的话,可以看到while循环的迭代值开始变化了,如图5-84所示,但是while循环并非按照100ms的周期变化,即使用户修改循环周期运行时间,依然控制不了运行速度,说明这里的在线仿真还是对整个程序框图的功能性仿真,而涉及到FPGA运行时钟的速度仿真,LabVIEW无法精确模拟,但是不影响时序结果。当然,用户还可以在程序框图里面用探针去观察每条连线上的数据流变化。

图5-82:运行在计算机仿真模式下的VI执行效果(定时循环优先级更高)

图5-83:将仿真模式下的定时循环暂时先禁用掉

图5-84:此时单个while循环就快速运行起来了(功能性仿真和时序仿真)

        5.3.3.2:LabVIEW ZYNQ PL端FPGA VI程序编译

        1)在计算机仿真模式下,用户无法测量FPGA真实的I/O电平,因为仿真计算机上没有对应的物理I/O引脚。所以,我们需要将VI执行模式切换回FPGA终端运行模式。右击FPGA终端,选择“Select Execution Mode/执行VI>>FPGA Target/FPGA终端”,如图5-85所示。

图5-85:将FPGA VI执行模式切换回FPGA终端模式

        2)提醒:开始编译前的准备工作(重要步骤)

        用过NI LabVIEW FPGA的用户知道,LabVIEW FPGA默认编译出来的是NI加密过的lvbitx文件,而不是最原始的FPGA bit位文件,因此,我们需要想办法将FPGA编译完成后最原始的bit文件弄出来,为此,我们专门给大家提供了一个名为“License-ID-Bitfile-ZYNQ.vi”程序,只要在FPGA VI编译过程中一直打开运行这个VI就可以得到最原始的FPGA bit位文件了。为了防止用户忘记打开运行这个VI,我们可以将这个VI添加到LabVIEW项目下的“我的电脑”下面,然后打开点击运行箭头即可,直如图5-86所示。

图5-86:将获取原始ZYNQ FPGA bit文件的VI(License-ID-Bitfile-ZYNQ.vi)拖拽到项目里面的“我的电脑”下面,而不是拖到FPGA终端(切记)

        然后,在LabVIEW FPGA Bit文件导出路径里面选择一个电脑存在的路径,至于导出来的FPGA bit文件名称,可以自己随意取,比如,我们将实验1编译出来的ZYNQ FPGA bit文件存放到这个目录下(E:\ZYNQ FPGA Bit Files\1-PS2PL-LED.bit),并取名为“1-PS2PL-LED.bit”,如图5-87所示。唯一需要注意的是:导出来的FPGA bit文件存放路径最好不放在C盘根目录下,因为很多系统的C盘根目录没有复制权限会导致保存失败,选择其他的盘符会更保险。

图5-87:选择合适的路径将编译成功后的原始的ZYNQ FPGA bit文件保存下来
(这个VI一直开着运行即可)

        需要注意的是:设置的FPGA bit文件路径不能太深,而且bit文件名称里面不能有中文字符,切记,否则后续下载会失败!

        3)然后点击FPGA VI前面板上的“运行”箭头按钮,LabVIEW会启动编译服务器提示对话框,如图5-88所示。里面有3行,分别是:

  1. 本地编译服务器:顾名思义,就是调用安装在本地计算机上的Xilinx ISE或者Vivado编译器来编译这个VI。这个最为常用。
  2. 连接至网络编译服务器:这个相当于将这个VI生成的VHDL代码传送给远程服务器上的ISE或者Vivado编译器进行编译,需要用户提前配置好一台安装有Xilinx编译环境的服务器。目的是可以借助服务器强大的性能来加速编译过程,缩短编译时间。需要联网,因此,这个用的很少。
  3. 连接至LabVIEW FPGA编译云服务:这个是NI官方提供的远程服务器,需要付费才能使用,而且编译速度也没有想象中快多少,所以这个功能基本上也就是NI内部使用的多。如果用户报名参考NI FPGA认证考试或者提供购买过NI硬件产品序列号的话,NI会提供一个试用期为30天的LabVIEW FPGA编译云服务,编译速度跟本地基本一样,没有多大优势。因此,用的也很少。

图5-88:FPGA编译服务器选择提示框

        此时,先不着急点击上图里面的“OK/确定”按钮,让我看看自动产生的程序生成规范里面是不是还有什么特殊的地方需要设置。因此,这里,我们选择“Cancel/取消”按钮,如图5-89所示。

图5-89:先取消编译(因为我们要检查一下程序生成规范)

        4)展开FPGA终端里面的“Build Specifications/程序生成规范”,如图5-90所示;然后双击打开这个程序生成规范(实验1-FPGA入门实验(ZYNQ PL端)),将里面的一个重要选项“Run when loaded to FPGA/加载至FPGA时运行”勾选上,如图5-91,否则后续编译出来的ZYNQ FPGA bit文件下载到FPGA芯片里面是运行不了的,所以这里一定要检查一下是否打勾了。最后点击“OK/确定”关闭程序生成规范对话框。

图5-90:展开FPGA终端里面的程序生成规范,然后直接双击打开即可

图5-91:将“加载至FPGA时运行”勾选上(一定要勾上,切记!!!

        5)接下来,再次点击FPGA VI左上角的运行箭头,触发重新编译对话框,这次就可以安心点击里面的“OK/确定”按钮了,如图5-92所示;然后就会自动进入“正在生成中间文件”对话框,如图5-93和5-94所示。里面一共有5个阶段,主要就是将LabVIEW编写的FPGA VI程序框图转换为VHDL代码,然后进行压缩传递给Xilinx编译器进行编译。

图5-92:再次点击FPGA VI左上角运行箭头触发重新编译对话框(这次点击OK)

图5-93:LabVIEW FPGA VI程序框图正在生成中间VHDL文件

图5-94:正在压缩打包生成好的中间VHDL文件

        6)等待中间文件生成完毕后,LabVIEW会启动“Compilation Status/编译状态”窗口,如图5-95所示。里面一共经历5个步骤:配置、综合、布局、时钟约束、时钟布线。如果是6代FPGA,例如,Spartan6,需要经过每一步的编译,每个步骤都不能报错,否则会无法生成bit文件。但是对于7系列FPGA来说,例如ZYNQ、A7、K7、V7,如果FPGA VI里面用的是普通while循环,或者用的定时循环时钟源是默认的,那么后面两项“估计定时”和“最终定时”是不起作用的,LabVIEW会跳过检查,直接生成可以运行的原始FPGA bit文件;如果定时循环用到了创建的衍生时钟,那么最后两项定时约束还是会进行的,在后续第6章里面我们将会看到。

图5-95:Xilinx编译器正在执行综合

        7)在“Reports/报表”的下拉列表里面选择“Configuration/配置”,可以看到配置页面里面的信息汇总,如图5-96所示。可以发现LabVIEW FPGA调用的是64位的Xilinx Vivado 2019.1这个版本的编译器,7系列FPGA基本上只支持Vivado编译器。

图5-96:Xilinx编译器“配置”页面里面的信息汇总

        8)等待综合完成后,切换到“Estimated device utilization(synthesis)/估计设备使用(综合)”,如图5-97所示。可以看到这个VI编译后的资源预估计占用情况,因为FPGA VI程序框图里面用了普通while循环,没有对循环内部的代码进行时钟约束,所以编译器默认会使用更多的资源来完成这个时钟约束。

图5-97:Xilinx编译器“Synthesis/综合”页面里面的资源预估计

        9)等待转换和映射完成之后,就能在“Final device utilization(placement)/最终设备使用(布局)”页面里面,看到Xilinx编译器反馈的这个FPGA芯片实际资源使用情况,如图5-98所示。可以看出实际编译的结果与前面的资源预估计相差无几,这样,用户可以根据在资源预估计阶段里面的资源占用情况,来判断是否直接结束编译过程,避免浪费编译时间。例如,如果预估计的资源使用严重超过100%的话,那么建议用户直接终止编译,返回去优化程序后再编译。

图5-98:Xilinx编译器“placement/映射”页面里面的最终资源占用结果

        10)当用户在“Status/状态”提示框里面看到“Generating programming file/正在生成编程文件”,说明LabVIEW FPGA正在生成可执行bit文件,如图5-99所示。而且到这一步的时间只花了两分半钟,相同的代码要比之前Spartan6里面的ISE编译器快了一倍多。这也是Vivado编译器改变编译策略后的一大优势。

图5-99:Xilinx Vivado编译器正在生成可编程文件

        11)编译完成,会自动启动弹出“Preparing for interactive execution/准备交互式运行”提示框,同时会弹出一个路径选择对话框,让你选择一下刚刚编译出来的原始FPGA bit文件,如图5-100所示。比如,这里我们可以看到先前这个“License-ID-Bitfile-ZYNQ.vi”里面设置好的路径下出现了一个刚刚编译出来的FPGA bit文件,选中之后,点击“OK/确定”按钮,如图5-101所示。

图5-100:编译成功后会自动弹出“交互式运行提示框”和“FPGA bit文件选择对话框”

图5-101:到先前设置的路径里面找到刚刚编译出来的ZYNQ FPGA bit文件

        12)如果用户的Xilinx JTAG下载器驱动没有提前安装好,或者没有接入实际的下载器跟ZYNQ开发板的话,那么过一会会弹出一个错误代码位-310601的错误提示框,如图5-101所示。里面的核心意思就是LabVIEW无法识别到Xilinx JTAG下载器通信线缆,如果大家接了Xilinx下载器和板子上电之后还出现这种错误提示,可以参考前面第三章里面的Xilinx下载器驱动安装方法,重新安装一遍驱动即可。我们这里报错是因为我们还没有将Xilinx JTAG下载器跟板子接到电脑上,故意触发这个错误提醒用户的。

图5-102:弹出-310601错误(提示LabVIEW没有识别到Xilinx JTAG下载器通信线缆)

        至此,关于LabVIEW ZYNQ FPGA VI程序的编译过程就结束了,并且我们成功得到了原始的ZYNQ FPGA bit文件,这为用户产品的批量部署奠定了基础。

        5.3.3.3:将Xilinx下载器跟ZYNQ开发板连到电脑上

        为了验证一下上面编译出来的ZYNQ PL端FPGA bit文件功能是否正常,我们将其下载到真实的ZYNQ芯片里面跑一下看看实验现象,比如本书配套的是正点原子的领航者ZYNQ开发板。由于现在验证的是PL端FPGA VI程序,所以只需要JTAG下载器跟ZYNQ板子就可以了,至于网线现在接不接都行,网线会在后续的PS(ARM)端Linux RT实验里面才会用到,这里暂时不需要,而且学会后续PS端Linux RT程序开发和部署之后,其实连这里面的Xilinx下载器不接都行,因为PS端可以动态加载FPGA bit文件。

        下面将Xilinx DLC10 JTAG下载器跟原子领航者ZYNQ开发板连接之后接到电脑上,实物接线如图5-103所示。

图5-103:将Xilinx下载器接到ZYNQ开发板上(板子未上电)

        此时,设备管理器会自动识别加载Xilinx USB Cable驱动,如图5-104所示,如果用户的电脑没有出现这个设备名称,那么应该前面第三章里面的下载器驱动安装一节看漏了,回过去重新参考里面的驱动安装方法安装一遍Xilinx JTAG下载器驱动就可以了。

图5-104:设备管理器里面识别出来的Xilinx JTAG下载器名称

        然后给ZYNQ开发板上电,此时Xilinx JTAG下载器上的指示灯由黄色变成了绿色,说明我们的硬件接线和驱动基本正常了,如图5-105所示。

图5-105:FPGA板子上电之后,Xilinx JTAG下载器指示灯会变成绿色才是正常的

        5.3.3.4:利用Vivado手动下载LabVIEW FPGA程序(传统下载方式,效率低、不推荐,可以跳过这一节,直接参考5.3.3.5节)

        1)下面,我们通过利用Vivado工具把这个编译出来的bit文件下载到正点原子领航者ZYNQ开发板上测试一下,看看之前编写的LabVIEW ZYNQ PL端的FPGA VI是否能够正常运行,功能是否正常。

        2)然后,找到NIFPGA安装目录下的Vivado.bat批处理文件,如果LabVIEW FPGA工具包安装在C盘,那么默认的路径就是:C:\NIFPGA\programs\Vivado2019_1\bin,如图5-106所示。双击运行这个bat文件,就可以启动Vivado工具,启动成功后的Vivado软件如图5-107所示。

图5-106:找到启动Vivado工具的批处理文件

图5-107:启动成功后的Vivado工具界面

        3)由于Vivado下载工具引入了所谓的硬件服务器的概念,具体什么东西,感兴趣的用户可以百度一下。这个服务hw_server经常由于系统防火墙或者杀毒软件或者win10实时防护等原因导致未开启,用户可以打开任务管理器,如果里面没有hw_server这个进程,表明这个服务没有启动。那么我们可以直接使用TCL Console命令手动重启一下这个hw_server服务。

        在Vivado软件界面最下方的Tcl Console里面输入hw_server -s TCP::3121 -d,如图5-108所示。然后按下回车键,就能看到hw_server application启动成功的提示,如图5-109所示。

图5-108:通过TCL命令手动重启hw_server服务器

图5-109:hw_server application服务启动成功

        4)接着,单击首页面里面的“Open Hardware Manager”按钮启动下载页面,打开FPGA硬件管理器,然后点击“Open target”,选择下拉列表里面的“Open New Target”,如图5-110所示。在弹出来的硬件选择对话框里面,点击“Next”,如图5-111所示。

图5-110:启动Vivado FPGA硬件管理器

图5-111:进入FPGA硬件目标配置页面

        5)进入硬件服务器设置页面之后,可以看到有两个服务器供用户选择,一是“Local server”本地服务器和“Remote server”远程服务器。一般情况下,默认选择“Local server”,然后点击Next,如图5-112所示。此时会弹出一个进度条,提示正在Connect连接服务器,如图5-113所示。如果连接成功则继续跳到后面步骤7如果出现图5-114所示的结果,说明本地服务器无法连接成功,此时我们需要采取另外一种方式,也就是“Remote server”,参考步骤6。

图5-112:FPGA硬件服务器选择页面

图5-113:硬件服务器连接中

图5-114:本地服务器连接失败

        6)既然本地服务连接不了,那我们就选择Remote server远程服务器,如图5-115所示。其中Host name需要填与FPGA相连的计算ID名称,用户可以单击开始菜单,右击“计算机”选择属性,如图5-116所示,然后在弹出来的属性对话框页面的最下方,找到计算机ID名称,如图5-117所示。将其复制到图5-115里面来,端口号保持默认的3121不变。

图5-115:填写远程服务器主机名称和端口号

图5-116:右击计算机选择属性

图5-117:在属性页面里找到计算机名称

        7)点击Next下一步之后,可以看到立刻发现了Xilinx JTAG下载器和Xilinx ZYNQ7020主芯片,如图5-118所示。为了提高下载速度,我们可以将JTAG Clock Frequency时钟频率拉到最大值12MHz,然后点击Next下一步,进入汇总页面,如图5-119所示。

图5-118:识别出来的Xilinx JTAG下载器和ZYNQ7020芯片

图5-119:FPGA硬件目标汇总页面

        8)接下来,在Hardware窗口里面,右击ZYNQ7020芯片,选择“Program Device...”,如图5-120所示。然后在弹出来的位流文件路径选择对话框里面,单击右侧的浏览按钮,如图5-121所示。找到E盘下面编译成功的LabVIEW ZYNQ PL端 FPGA原始bit文件,如图5-122所示。点击OK按钮,然后回到路径选择页面,再点击“Program”按钮即可将这个bit文件烧写到FPGA芯片里面运行,如图5-123所示。烧写过程非常快,原因是因为前面我们把Xilinx JTAG下载器的时钟频率设置成了最大的12MHz,所以一瞬间就下载完成了,如图5-124所示。

图5-120:右击FPGA芯片选择Program Device

图5-121:点击浏览按钮选择bit文件

图5-122:找到先前编译成功的LabVIEW FPGA原始bit文件(1-PS2PL-LED.bit)

图5-123:单击Program按钮下载bit文件(1-PS2PL-LED.bit)

图5-124:FPGA bit文件下载过程

        5.3.3.5:LabVIEW自动下载ZYNQ PL端FPGA VI程序(强烈推荐

        可以看出,上面传统的手动Vivado下载FPGA bit文件非常的不智能,每一步都需要自己手动去操作Vivado实现,对于很多不熟悉Vivado工具的用户来说,还要花时间摸索一下,那么有没有一种简便的方式来完成下载和运行调试呢?答案是肯定的!

        为了让用户能够享受到跟使用NI FPGA板卡一样的自动下载和交互式运行效果。我们将底层FPGA bit文件的自动下载和交互式运行全部集成到LabVIEW里面了。用户只需要点击编译好的FPGA VI左上角的运行箭头即可自动弹出选择FPGA bit文件对话框,如图5-125所示,然后在对话框里面找到这个FPGA VI对应编译出来的bit文件,然后点击“OK/确定”按钮即可进入自动下载页面,等待一会就可以看到ZYNQ核心板上的PL端FPGA指示灯闪烁了,如图5-126所示。说明我们的自动下载和自动运行完全OK,爽!

图5-125:运行FPGA VI会弹出FPGA bit文件选择对话框

图5-126:正点原子领航者ZYNQ核心板上的LED灯按照10Hz频率快速闪烁起来了

        提醒:ZYNQ底板上的另外两个LED灯没有变化,是因为前面编写的FPGA VI程序里面将底板上的这两个LED灯与PS端的Reg进行关联了,所以这两个LED灯会受到ZYNQ PS(ARM)端的控制,在后续5.4节里面,我们会教大家通过LabVIEW编写Linux RT程序来控制PL端的两个LED灯。

        5.3.3.6:LabVIEW ZYNQ PL端FPGA程序运行与在线调试(在线前面板交互式运行,直观方便)

        1)当FPGA VI编译出来的FPGA bit文件自动下载到ZYNQ芯片里面运行之后,此时,可以看到位于开发电脑上的这个ZYNQ PL端FPGA VI(实验1-FPGA入门实验(ZYNQ PL端).vi)前面板自动活了,也就是自动进入在线前面板交互式运行模式了,可以明显的观察到FPGA VI前面板上的“PL_Core_LED”这个状态指示灯与ZYNQ核心板上的PL端LED灯同步闪烁,并且while循环的迭代值“Running_FPGA”显示控件里面的数值也在按照100ms的速度递增,而定时循环的“Running_FCLK”显示控件里面的数值则是按照50MHz的速度递增,所以一瞬间就到了最大值,如图5-127所示。

图5-127:FPGA VI自动进入在线前面板交互式运行

        2)如果我们将FPGA VI前面板上的“Count(mSec)”输入控件里面的100改成1000,此时前面板上的“PL_Core_LED”与ZYNQ核心板上的PL端LED指示灯闪烁变慢了,如图5-128所示,变成了1s闪烁一次了。说明我们用LabVIEW开发的FPGA VI程序达到了预期设计要求。

图5-128:直接在FPGA VI前面板上动态实时修改控件参数(无须反复编译FPGA VI)

        3)同理,如果将这个数值改成1,你会发现ZYNQ核心板上的PL端LED指示灯变成常亮了,这是因为我们人眼是无法看清楚1KHz的频率变化的,如图5-129所示。

图5-129:将while循环延时改成1ms,ZYNQ核心板上的PL端LED灯变成了常亮

        结论:可以看出,在不需要编写LabVIEW上位机的情况下,我们就能借助FPGA VI的在线前面板交互式运行方式快速的观察和控制我们的FPGA VI程序,不需要反复去编译这个FPGA VI,从而可以大幅减少FPGA程序开发调试的时间,降低开发调试成本,提高了调试效率,真正做到了降本增效。   

        提醒:接下来我们会在PS(ARM)端Linux RT里面编写LabVIEW程序来控制上面图5-129里面ZYNQ底板上两个PL端的LED指示灯。

    5.3.4:LabVIEW ZYNQ PL端FPGA bit程序固化(直接将编译好的FPGA bit文件交给PS端Linux RT部署到TF卡里面存放,然后由PS端ARM动态加载PL端FPGA bit文件运行,简单省事

        对于看过我们之前编写的LabVIEW开发纯FPGA宝典的用户来说,应该有印象,那就是FPGA芯片断电之后,里面的VI就没有了,所以我们需要将编译出来的FPGA bit文件先转成成bin文件或者mcs文件,然后再固化到Flash芯片里面永久存放,当FPGA上电时,会自动从Flash读取FPGA可执行文件到FPGA芯片里面运行,有点类似单片机程序加载运行一样。

        但是ZYNQ架构的芯片与以往的纯FPGA bit文件固化不同,ZYNQ芯片如果PS(ARM)端运行Linux系统的话,PL端编译出来的FPGA bit文件是不需要固化的,只需要将多个不同功能的FPGA bit文件部署到TF卡里面,然后由PS端ARM根据具体的情况动态加载相应路径的FPGA bit文件即可。所以也就没有了固化一说,取而代之的是FPGA bit文件的更新、升级和覆盖。比如,在很多工厂的产线项目上,由于被测对象的经常更换,需要动态加载相对应的DUT FPGA bit文件,以实现不同对象不同功能的柔性测试。

        结论:关于如何将编译好的ZYNQ PL端FPGA bit文件部署下发到TF卡指定的路径里面,以及如何通过PS(ARM)端Linux RT动态加载FPGA bit到FPGA里面运行,这些我们会在接下来的5.4节(LabVIEW ZYNQ PS(ARM)端Linux RT程序开发)里面给大家做详细的讲解和演示。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值