当前位置: 首页 > news >正文

第6章>>实验7:PS(ARM)端Linux RT与PL端FPGA之间(通过Memory存储器进行通信和交互)《LabVIEW ZYNQ FPGA宝典》

1、实验内容

        上一节实验里面介绍的Reg寄存器通道比较适合在PS端和PL端之间传递标量数据,也就是单个元素,如果要传递多个元素的数组或者连续数据流的话,Reg寄存器通道就不是很合适了。

        本节实验我们向大家讲解如何借助Memory存储器通道在PS(ARM)端Linux RT和PL端FPGA之间传递一定长度的数组或者向量或者图像数据。比如最常见的应用之一就是定长传输,我们可以将PS端Linux RT里面的控制参数、命令、数据等合在一起,形成一个数组,然后通过Memory存储器通道映射到PL端FPGA里面,这样就能批量更新控制FPGA端程序了,当然也可以读取PL端FPGA里面的Memory存储器数据。

        为了方便用户使用,我们提前将8位、16位、32位的无符号和有符号类型的PS2PL下行和PL2PS上行Memory存储器通道封装到ZYNQ PS端和PL端,大家只需要有一点LabVIEW基础,简单拖拽和连线就能实现ZYNQ芯片内部ARM端跟FPGA端的存储器映射交互了。

        提醒:对于FXP定点数传输也很简单,那就是先把FXP定点数先通过“数值至布尔数组”函数去除符号特性,然后再利用“布尔数组至数值”函数转换成U8、U16、U32或者字节数组再发送出去。

2、实验目标

        本节实验需要利用LabVIEW同时开发ZYNQ PS端Linux RT程序和PL端FPGA程序。     先编写一个PL端FPGA VI,将FPGA函数选板里面所有数据类型的Memory存储器通道VI函数拖拽到FPGA VI里面,再在前面板上创建一维输入和显示数组控件,借助LabVIEW FPGA在线前面板交互式运行功能,动态修改这些数组内容以及观察PS端的数组元素是否一致。

        然后编写一个PS端Linux RT程序,调用Memory函数选板里面的读写VI,读取PL端FPGA发送过来的各种类型的数组元素并显示在前面板上,同时将Linux RT程序里面的数组实时发送给PL端FPGA VI,从而实现双向通信和交互。

        最后把写好的PL端FPGA程序框图编译成bit文件,再将Linux RT程序编译部署下载到ZYNQ芯片的PS端ARM里面去运行,利用LabVIEW Linux RT动态加载前面编译好的PL端FPGA bit文件,然后接上Xilinx JTAG下载器和千兆网线或者WiFi模块,就可以同时在线观察到PL端FPGA VI前面板和Linux RT前面板上的控件运行效果了。对于初学者着重复习并熟练掌握ZYNQ芯片PS(ARM)端LabVIEW Linux RT程序开发和PL端FPGA程序开发的过程和原理。

        为了方便讲解,我们设计了3个Memory存储器通道读写交互实验程序,分别是:

  1. PS端Linux RT发送一维数组给PL端FPGA(PS2PL下行)
  2. PL端FPGA发送一维数组给PS端Linux RT(PL2PS上行)
  3. PS端发送一维数组给PL端同时读取回来(PS2PL回环)

3、硬件介绍

        本节实验没有用到其他外设,只需要正点原子领航者ZYNQ开发板,Xilinx JTAG下载器和一根千兆网线即可。       

        其中,Xilinx JTAG下载器可以用来在线观察ZYNQ芯片PL端的FPGA VI前面板实际运行效果也可以动态修改前面板上的数组元素,减少了频繁编译浪费的时间。

        网线是用来将上位机编写好的ZYNQ PS(ARM)端Linux RT程序通过网络方式部署下载到ZYNQ PS端ARM里面去运行。提醒:这里的Xilinx JTAG下载器不需要下载PL端FPGA bit文件,因为PS端可以动态加载编译好的FPGA bit文件,所以如果大家不准备观察FPGA VI前面板上的控件状态,实际上这个Xilinx JTAG下载器也可以不用接。

        图7-1显示的是正点原子领航者ZYNQ开发板实物图。

图7-1:正点原子领航者ZYNQ开发板上实物图

4、原理图介绍

        由于本节实验没有用到ZYNQ开发板上的任何外设,只需要在ZYNQ芯片内部的PS端ARM和PL端FPGA之间进行内部通信和交互,所以,理论上只要ZYNQ芯片没坏,Linux RT系统能正常启动运行就可以了,故此,本节实验不需要原理图。

5、驱动VI函数讲解

5.1:PL端FPGA Memory存储器通道

        对于ZYNQ PL端FPGA来说,要想把一定长度的数组元素发给PS端ARM或者从PS端读取传递过来的数组数据,那么可以借助Memory存储器通道。为了方便客户调用存储器通道,我们将PL侧的Memory存储器通道直接以Socket CLIP的方式封装到FPGA终端下面,如图7-2所示。按照传输方向分为PS2PL和PL2PS,其中,PS2PL指的是PS端Linux RT发送数据给PL端FPGA,那么FPGA VI直接读取这个通道即可,相当于下行;PL2PS则是PL端FPGA将数据通过Memory发送到PS端ARM里面,相当于上行。

图7-2:ZYNQ FPGA终端下的Memory存储器端口信号(最原始的)

        上面这些Memory存储器CLIP端口是最原始的,操作起来不直观,为了方便用户调用,我们将8位、16位和32位的Memory存储器读写操作直接封装成VI,放在了“PL-Mem”函数选板里面了,如图7-3所示。其中,无符号和有符号单独分开,并且不同的数据类型利用多态VI的方式组合在一起,这样用户只需要记住读写两个VI函数就可以了,省时省力。

图7-3:ZYNQ PL端FPGA终端里面的Memory存储器通道读写VI函数

5.2:PS(ARM)端Linux RT驱动函数选板

        正式开始采用LabVIEW编写ZYNQ PS端Linux RT 访问和更新PL端FPGA里面的Memory存储器通道数据之前,我们先来了解一下本节实验要用到的PS端Linux RT下的Memory存储器驱动VI函数功能。

        为了方便用户调用,我们提前将底层负责PS端与PL端沟通的存储器通道函数封装到LabVIEW Linux RT环境下的“PowerGod-RIO-RT”选板里面,变成一个个小图标,一目了然。

        要完成本节实验,我们需要用到4个函数选板,分别是“PS_Load_FPGA_bit”、“PS_Load_KO”、“PS_Reg_Address”和“PS_Memory”,如图7-4所示。

图7-4:本节实验要用到的神电测控“PowerGod-RIO-RT”里面的4个函数选板

        下面,我们分别介绍一下这4个选板里面的VI功能和应用场合。

        1)由于本节实验展示ZYNQ PL端FPGA跟PS端相互通信,所以需要编写FPGA VI编译生成bit文件,然后由PS端Linux RT程序动态加载到ZYNQ芯片里面运行,所以Linux RT程序运行时的第一个VI就是“PS_Load_FPGA_bit.vi”这个函数。凡是需要调用ZYNQ芯片里面PL端FPGA参与的程序,都需要调用这个FPGA bit文件动态加载函数,切记!

        2)为了提高ZYNQ芯片PS端的内存使用率,我们将很多外设KO驱动做成了动态加载和卸载。比如本节实验,我们需要读取PL端FPGA里面的存储器或者将PS端发送过来的数组写入PL端存储器,这个存储器本质上也属于通用IO,也就是GPIO类,所以在Linux RT程序初始化之前,我们需要利用下面图7-5里面的GPIO动态加载“Load_GPIO_KO”函数(PSLoadGPIOKO(SubVI).vi)加载GPIO驱动,等到Linux RT程序停止退出之前,再调用“Unload_GPIO_KO”卸载函数(PSUnloadGPIOKO(SubVI).vi)卸载GPIO驱动以便释放GPIO类占用的内存和资源。

图7-5:GPIO类外设驱动动态加载和卸载函数

        3)本节实验的重点就是要学会使用PS端和PL端之间的存储器通道,因此,PS端少不了要对Memory存储器通道初始化打开,等到Linux RT程序退出的时候,再关闭Memory存储器,这两个VI函数就位于下图7-6所示的“PS_Reg_Address”寄存器函数选板里面。至于下图中间的两个PS端寄存器读写VI,本节实验用不到,因为PS端与PL端进行沟通的Memory存储器读写函数我们单独进行了封装,参考下面的第4)部分内容。

图7-6:ZYNQ芯片PS端ARM寄存器操作函数

        注意:只要是对PS端外设进行操作的场合,都需要调用上面“PS_Reg_Address”函数选板里面的第1个和第4个VI,也就是“PS_reg_Open”和“PS_Reg_Close”,相当于对寄存器函数的初始化和程序退出前的寄存器关闭,至于中间的Reg寄存器读写两个VI,可以根据实际情况选择,后续为了简化编程,我们对很多外设寄存器进行了二次封装,只需要调用相应的函数即可。

        4)为了让ZYNQ PS端ARM能够访问和操作PL端FPGA里面的存储器,我们特地在PS端Linux RT下封装了4个读写函数(多态VI),分别是无符号数据类型的“Mem_Unsigned_Read_Poly.vi”和“Mem_Unsigned_Write_Poly.vi”,以及有符号数据类型的“Mem_Signed_Read_Poly.vi”和“Mem_Signed_Write_Poly.vi”,位于“PS2PL_Memory”函数选板里面,如图7-7所示。其中,第1列的“Mem_xxx_Read_Poly.vi”函数顾名思义,就是PL2PS上行通道,也就是Linux RT可以利用这个函数读取到PL端FPGA里面的存储器数据;反之,第2列的“Mem_xxx_Write_Poly.vi”则是PS2PL下行通道,Linux RT程序可以通过这个VI将PS端的数组写入PL端FPGA的Memory里面去。

图7-7:负责PS端与PL端二者之间通信的Memory存储器通道读写VI函数

        提醒1为了降低用户记忆困难,我们将相同功能的VI组合在一起,封装成多态VI,这样用户只需要点击下拉列表就可以切换不同功能的VI,比如不同位宽的数据,本质上都是数据,所以合并在一起,方便使用。

        提醒2为了更好的区分ZYNQ芯片里面PS端和PL端的VI函数,我们特地在每个子VI图标里面加入了PS或者PL字样,如图7-8所示。如果这个子VI有PS字样,那么这个VI就可以被Linux RT主机端也就是PS端调用,反之如果是PL端字样,那就是被FPGA VI调用。比如,下图中左边就是PS端Linux RT程序可以调用的Memory存储器通道函数,右边则是PL端FPGA里面可以需要调用的Memory存储器操作函数。

图7-8:子VI图标上有PS和PL字样(用于区分该VI是运行在PS端Linux RT里面还是在PL端FPGA里面)

6、ZYNQ程序开发讲解(PL(FPGA)+PS(ARM))

6.1:ZYNQ PL端FPGA程序开发过程

6.1.1:新建或者打开已有的LabVIEW ZYNQ PL FPGA终端

        1)前面第五章里面我们已经新建过了一个LabVIEW ZYNQ FPGA终端了,这里不再重复创建了,不记得的用户可以回顾一下前面第五章5.3.1节里面的相关内容。

        2)打开之前新建的项目浏览器“My_FPGA_Stater_Board_ZYNQ7020_PS+PL.lvproj”,如图7-9所示,可以看到该项目里面有两个终端分别是ZYNQ PL端FPGA部分和PS端Linux RT部分。

图7-9:打开前面新建好的LabVIEW项目浏览器(My_FPGA_Stater_Board_ZYNQ7020_PS+PL.lvproj)

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

        1-右击“FPGA Target(My_FPGA, ZYNQ_XC7Z020_2CLG400_Navigator_MyRIO_V3_All)”,选择“New/新建>>Virtual Folder/虚拟文件夹”,创建一个虚拟文件夹,如图7-10所示;然后重命名为“实验7-PS与PL通过Memory存储器交互(ZYNQ PL端)”,如图7-11所示。

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

图7-11:虚拟文件夹重命名为“实验7-PS与PL通过Memory存储器交互(ZYNQ PL端)”

6.1.2.1:新建FPGA Memory存储器

        为了对FPGA终端下的不同元素进行分类管理,我们将Memory存储器单独存放到1个子虚拟文件夹里面,具体步骤如下:

        1)右击虚拟文件夹“实验7-PS与PL通过Memory存储器交互(ZYNQ PL端)”,选择“New/新建>>Virtual Folder/虚拟文件夹”,如图7-12所示,重命名为“PL-Memory”,如图7-13所示,PL指的就是FPGA。

图7-12:右击ZYNQ PL端FPGA新建1个子虚拟文件夹

图7-13:将子虚拟文件夹重命名为“PL-Memory”

        2)右击“PL-Memory”虚拟文件夹,选择“New/新建>>Memory/存储器”,如图7-14所示;在弹出来的Memory存储器属性配置页面里面将“Name/名称”改成“PS2PL-Memory-U8”;“Requested number of elements/请求元素数量”改成10个元素,这里仅仅是演示功能,为了加快FPGA VI编译速度,所以我们将元素数量改的比较小,具体改成多少,用户可以根据自己的实际项目或者产品需求来定;读取延迟里面改成1,这就意味着在定时循环里面需要1个CLK时钟延迟才能读出数据来,所以在后续FPGA VI编程的时候,需要Memory读取的时候需要加入一个反馈节点或者移位寄存器做一次乒乓操作。配置结果如图7-15所示。

图7-14:右击“PL-Memory”虚拟文件夹新建一个Memory存储器

图7-15:在Memory属性配置页面里面设置名称和元素数量以及读取延迟

        3)切换到“Data Type/数据类型”页面里面,选择无符号8位也就是U8类型,如图7-16所示。创建成功后的Memory所在的FPGA终端效果如图7-17所示。

图7-16:将Memory数据类型选择位无符号U8类型

图7-17:创建一个10个元素的无符号U8类型的PS2PL Memory存储器

        4)再以同样的方式创建5个Memory存储器,数据类型分别是U16、U32、I8、I16、I32,名称也以无符号位宽和有符号位宽表示,以示区分,如图7-18所示。

图7-18:以相同的方式创建另外5个不同数据类型的PS2PL Memory存储器

        5)上面创建的6个Memory前缀是PS2PL,顾名思义,就是用来接收PS端发送过来的数组或者向量数据的,那么PS端如果要读取PL端的Memory怎么处理呢?为了好区分,我们可以将上面6个Memory直接复制一下,然后将前缀名称改成PL2PS,如图7-19,这样后续编写FPGA程序的时候,可以将PL端的数组存放在这些PL2PS Memory里面,然后PS端读取即可。

图7-19:直接复制前面6个FIFO创建出另外6个PL2PS端Memory出来

6.1.2.2:新建FPGA VI应用程序
6.1.2.2.1:创建PS2PL下行方向的Memory存储器通道读取FPGA VI程序

        1)为了方便不同FPGA对象的管理,我们将所有FPGA主VI放在“Main”虚拟文件夹里面,如果存在子VI的话,一般会在“SubVI”虚拟文件夹里面,如果是ngc或者edf网表的话,一般放在“NGC/EDF”网表文件夹里面。

        右击虚拟文件夹“实验7-PS与PL通过Memory存储器交互(ZYNQ PL端)”,选择“New/新建>>Virtual Folder/虚拟文件夹”,如图7-20所示,重命名为“Main”,如图7-21所示。

图7-20:右击ZYNQ PL端FPGA新建1个子虚拟文件夹

图7-21:将子虚拟文件夹重命名为“Main”

        2)右击子虚拟文件夹“Main”,选择“New/新建>>VI”,如图7-22所示;然后保存该VI,命名为“实验7.1-PL端读取PS端的Memory数组(ZYNQ PL端).vi”,如图7-23所示。

图7-22:右击虚拟文件夹“Main”新建一个FPGA主VI程序

图7-23:将VI另存为“实验7.1-PL端读取PS端的Memory数组(ZYNQ PL端).vi”

        3)打开上面新建的FPGA VI,切换到程序框图,然后放置一个定时循环,将定时循环的时钟源切换成“FLCK_CLK0_PS2PL”,如图7-24所示。提醒:这个“FLCK_CLK0_PS2PL”时钟大小是50MHz,是由PS端ARM产生的,路由给PL端FPGA的。

图7-24:放置一个由PS端50MHz时钟驱动的定时循环

        4)然后将LabVIEW FPGA环境下“PowerGod_ZYNQ_FPGA_PL”函数选板里面的“PL-Mem”选板里面的“PS2PL_Memory_Unsigned_Poly.vi”拖到FPGA VI程序框图,点击多态VI下拉列表,选择无符号U8类型,再创建一个Memory存储器常量,选择前面创建好的PS2PL端Memory存储器,最后在定时循环里面利用“Replace Array Subset/替换数组子集”将FPGA端本地的Memory存储器里面的前10个元素读出来放在前面板上进行观察,如图7-25所示。借助我们强大的LabVIEW FPGA在线前面板交互式运行功能,可以动态观察前面板上的数组显示控件里面的元素,看看是不是ZYNQ PS端Linux RT通过Memory通道发送过来的数据。

图7-25:ZYNQ PL端FPGA接收PS端发送的Memory数据并以数组方式显示在前面板上

        5)再以相同的方式,将其余5个U16、U32、I8、I16、I32类型的Memory通道数据读取程序创建出来,当然也可以直接复制上面的U8 Memory框图,然后修改一下参数,最终形成的6个独立的PS2PL下行Memory存储器通道读取FPGA VI程序框图,如图7-26所示。

图7-26:所有类型的PS2PL下行Memory存储器数组读取显示FPGA VI程序框图

        提醒:上面程序框图里面的Memory存储器常量或者控件,需要配置数据类型,这样才能跟FPGA里面的多态VI对应上,并且可以对FPGA终端下创建好的Memory进行过滤,具体方法如下,右击Memory常量,选择“Configure Memory Type/配置存储器数据类型”,如图7-27所示;然后在弹出来的“Memory数据类型”页面里面选择跟使用的多态VI相同的数据类型,比如这里面的有符号32位I32,如图7-28所示。

图7-27:右击Memory常量或者控件,选择“Configure Memory Type/配置存储器类型”

图7-28:根据使用的PS2PL端Memory存储器多态VI选择对应的数据类型

        6)最终,编写完成的ZYNQ PL端FPGA读取PS端Linux RT通过Memory存储器通道发送过来的数组元素FPGA VI程序前面板,如图7-29所示。

图7-29:ZYNQ PL端FPGA读取PS端通过Memory方式发送的数组FPGA VI前面板

6.1.2.2.2:创建PL2PS上行方向的Memory存储器通道发送FPGA VI程序

        上面我们编写的是PS2PL下行,也就是PS端将数组通过Memory通道发给PL端FPGA,为了展示Memory存储器的双向通信能力,这里,我们再编写一个PL2PS上行方向,也就是PL端FPGA将自己的数组通过Memory通道发送给PS端,具体过程与前面6.1.2.2.1节相似,唯一不同的地方就是将FPGA VI程序框图里面的6个“PS2PL_Memory_xxx_Poly.vi”多态VI换成“PL2PS_Memory_xxx_Poly.vi”以及6个Memory存储器通道枚举控件里面的PS2PL也换成PL2PS的Memory即可。这里编写过程,我们就不展示了,直接给出PL2PS上行通信的Memory存储器数据发送FPGA框图和前面板,分别如图7-30和7-31所示。详细过程可以参考后续录制的视频教程,这里不再赘述了。

图7-30:所有类型的PL2PS上行Memory数据发送给PS端的FPGA VI程序框图

图7-31:ZYNQ PL端FPGA将数组通过Memory通道发送给PS端的FPGA VI前面板

6.1.2.2.3:创建PS端与PL端Memory回环通信FPGA VI程序

        前面两个FPGA VI分别展示的是FPGA接收和发送Memory数据的能力,按照以往惯例,为了同时展现双向通信,我们可以将前面PS2PL和PL2PS两个程序结合起来,形成一个回环程序,那么ZYNQ PS端Linux RT可以自发自收,也就是PS端通过Memory存储器通道发送给PL端的数组又原封不动的回来了,以此来验证一下PS端与PL端之间的Memory存储器双向数据交互功能。

      具体编写过程可以参考后续录制的视频教程,程序本身比较简单,将PS2PL下行FPGA端读到的Memory数据通过for循环逐个元素更新到PL2PS端Memory存储器里面即可,对应的ZYNQ PL端Memory存储器通道数据回环交互FPGA程序框图和前面板,分别如图7-32和7-33所示。

图7-32:PS端发送给ZYNQ PL端的Memory通道数据回环通信FPGA程序框图

图7-33:PS端发送给ZYNQ PL端的Memory通道数据回环通信FPGA前面板

        最终编写完成的本节3个ZYNQ PL端Memory存储器通道实验FPGA程序所在的ZYNQ FPGA终端,如图7-34所示。

图7-34:3个PL端Memory存储器数据通信FPGA VI程序

6.1.3:LabVIEW ZYNQ PL端FPGA仿真、编译、下载、运行和调试

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

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

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

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

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

        2)然后打开“实验7.1-PL端读取PS端的Memory数组(ZYNQ PL端).vi”,点击左上角的“运行”箭头按钮,如图7-36所示。此时发现这个VI运行起来了,可以看到前面板上的“Running_FPGA”显示控件里面的数值以非常快的速度在增加,说明FPGA VI程序框图里面的定时循环开始执行了,但是运行速度达不到50MHz,这是因为上位机模拟仿真只是对整个程序框图的功能性仿真,而涉及到FPGA芯片驱动时钟的速度仿真,LabVIEW无法精确模拟时钟频率,但是不影响相对时钟之间的关系和时序结果。当然,用户还可以在程序框图里面用探针去观察每条线上的数据流变化。其他两个FPGA VI也是一样的操作。

图7-36:FPGA VI程序快速运行起来了(功能性仿真和时序仿真)

        提醒1离线仿真模式下,前面板上的数组显示控件里面的数据都是随机的,仿真出来的,并非PS端真正传递过来的,因为我们还没有将FPGA VI编译成bit文件下载到ZYNQ芯片里面运行呢!这里的仿真主要是功能性仿真。

        提醒2如果用LabVIEW FPGA环境下的IP Block节点调用ngc或者edf网表的话,这里的离线仿真模式也是支持的,也能完全仿真出来网表里面的行为特性。

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

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

图7-37:将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项目下的“我的电脑”下面,然后打开点击运行箭头即可,直如图7-38所示。

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

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

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

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

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

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

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

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

图7-40:FPGA编译服务器选择提示框

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

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

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

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

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

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

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

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

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

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

图7-47:Xilinx编译器正在执行综合

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

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

        8)等待综合完成后,切换到“Estimated device utilization(synthesis)/估计设备使用(综合)”,如图7-49所示。可以看到这个VI编译后的资源预估计占用情况。

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

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

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

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

图7-51:Xilinx Vivado编译器正在生成可编程bit文件

        11)编译完成,会自动启动弹出“Preparing for interactive execution/准备交互式运行”提示框,但是不会像第五章那样弹出一个路径选择对话框,这是因为,前面我们将配置Xilinx JTAG下载器下载还是仿真的ini.txt文件里面的1改成0了,所以就LabVIEW就会跳过选择FPGA bit文件和下载这个过程了。接着我们到这个“License-ID-Bitfile-ZYNQ.vi”里面指定的路径下,发现了刚刚编译出来的FPGA bit文件,如图7-52所示。再以同样的方式将实验7.2和7.3的FPGA VI编译一下。

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

        12)如果用户的Xilinx JTAG下载器驱动没有提前安装好,或者没有接入实际的下载器跟ZYNQ开发板的话,那么过一会会弹出一个错误代码位-310601的错误提示框,如图7-53所示。错误代码的意思就是LabVIEW无法识别到Xilinx JTAG下载器通信线缆,如果大家接了Xilinx下载器和板子上电之后还出现这种错误提示,可以参考前面第三章里面的Xilinx下载器驱动安装方法,重新安装一遍驱动即可。我们这里报错是因为我们还没有将Xilinx JTAG下载器跟板子接到电脑上,故意触发这个错误提醒用户的。另外,前面我们将ini.txt里面的1改成0,所以在PS端没有动态加载这里的FPGA bit之前,在线前面板也是无法运行的,切记!!!

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

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

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

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

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

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

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

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

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

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

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

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

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

        提醒:要想让上位机LabVIEW FPGA VI通过Xilinx JTAG下载器自动下载bit文件,需要将ini.txt配置文件里面0改成1,如图7-73所示;如果想通过后续的PS端Linux RT系统动态加载FPGA bit文件的话,这里的下载步骤可以忽略,同时ini.txt文件里面的1要改成0

图7-73:要想通过Xilinx JTAG下载器自动下载FPGA bit文件,ini文件改成1

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

        1)当FPGA VI编译出来的FPGA bit文件自动下载到ZYNQ芯片里面运行之后,此时,可以看到位于开发电脑上的这个ZYNQ PL端FPGA VI(实验7.1-PL端读取PS端的Memory数组(ZYNQ PL端).vi)前面板自动活了,也就是自动进入在线前面板交互式运行模式了,可以观察到FPGA VI前面板上的定时循环的迭代值“Running_FPGA”显示控件里面的数值则是按照50MHz的速度递增,所以一瞬间就到了最大值,如图7-74所示。前面板上的数组显示控件都是0,这是因为我们的PS端Linux RT程序还没写呢,并没有对PL端的Memory存储器进行赋值,默认值都是0。

图7-74(a):实验7.1对应的PS2PL Memory存储器读取FPGA VI程序通过JTAG下载器单独下载到ZYNQ PL里面运行

图7-74(b):实验7.2对应的PL2PS Memory存储器发送FPGA VI程序通过JTAG下载器单独下载到ZYNQ PL里面运行

图7-74(c):实验7.3对应的Loopback Memory存储器回环通信FPGA VI程序通过JTAG下载器单独下载到ZYNQ PL里面运行

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

        提醒:接下来我们会在PS(ARM)端Linux RT里面编写3个LabVIEW程序来跟PL端FPGA的Memory存储器进行数据写入与更新操作。

6.2:ZYNQ PS(ARM)端Linux RT程序开发过程

6.2.0:编程思路(PS端Linux RT)

        要想ZYNQ芯片PS端Linux RT跟PL端FPGA通过存储器通道进行通信和交互,必须按照下面的流程至少调用7个VI函数,调用次序如下,后面Linux RT程序编写就是参考这个流程来的:PS_Load_FPGA_bitàLoad_GPIO_KOàPS_Reg_OpenàPS2PL_Mem_Write/ PS2PL_Mem_ReadàPS_Reg_CloseàUnload_GPIO_KO

        了解完ZYNQ芯片PS端GPIO通用类和Memory存储器类驱动VI和操作流程后,接下来,我们就可以利用LabVIEW编写3个Linux RT程序访问和刷新PL端FPGA的Memory存储器数值了,然后下载到ZYNQ PS端ARM里面去运行。

6.2.1:新建或者打开已有的LabVIEW ZYNQ Linux RT项目

        打开前面第五章我们新建好的LabVIEW ZYNQ项目(My_FPGA_Stater_Board_ZYNQ7020_PS+PL.lvproj),这个项目前面我们在编写ZYNQ PL端FPGA程序时已经打开过了,如图7-75所示。

图7-75:打开前面我们创建好的同时包含ZYNQ PS(ARM)端和PL(FPGA)端的LabVIEW ZYNQ项目

        由于前面FPGA VI已经编写完成了,并且生成了可用的FPGA bit文件,这里为了截图不至于过大,我们暂且先将FPGA Target终端收起来,如图7-76所示。

图7-76:将My FPGA终端暂时收起来(因为前面FPGA VI已经编写好了)

6.2.2:编写LabVIEW Linux RT应用程序(访问和刷新PL端FPGA Memory存储器)
6.2.2.1:编写PS2PL Memory下行方向的PS端Linux RT应用程序(PS发送数组给PL)

        1)右击Linux RT终端(ZYNQ7020_PS_Linux_RT)选择“New/新建”一个“Virtual Folder/虚拟文件夹”,如图7-77所示。将其重命名为“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端)”,如图7-78所示,以示分类管理好区分。

图7-77:右击Linux RT终端选择新建一个虚拟文件夹

图7-78:将刚刚新建出来的虚拟文件夹重命名为“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端)”

        2)接着,右击刚刚创建的虚拟文件夹“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端)”选择“New/新建”一个VI程序,如图7-79所示,然后将这个VI另存为“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端).vi”,如图7-80所示。

图7-79:右击虚拟文件夹新建一个VI

图7-80:将新建出来的VI保存并重命名为“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端).vi”

        3)打开这个新建的VI,将前面第5.2节“PowerGod-RIO-RT”函数选板里面的6个子VI函数拖拽到程序框图里面,然后按照6.2.0节里面的步骤进行排序串联,最后在前面板上创建相应的控件,即可完成PS端通过Memory存储器通道发送数组给PL端FPGA,最终形成完整的Linux RT程序框图,如图7-81所示。提醒:看不清的用户可以缩放一下pdf,因为这里贴的程序框图是直接复制的LabVIEW原始矢量图,不是截图。

图7-81:完整的ZYNQ PS(ARM)端通过Memory通道发送数组给PL端FPGA的
Linux RT程序框图

        提醒:我们将不同数据类型的有符号和无符号Memory存储器通道全部做成了下拉枚举形式,这样大家就能根据PL端FPGA里面使用的存储器通道,直接在PS端Linux RT程序框图的下拉列表里相应的选择一下即可。

        4)ZYNQ PS端通过Memory存储器通道发送数组数据给PL端的Linux RT应用程序前面板,如图7-82所示。

图7-82:ZYNQ PS端通过Memory存储器通道发送数组给PL端的Linux RT程序前面板

        提醒:ZYNQ PS端Linux RT程序前面板上有一个FPGA bit文件加载路径,这个路径“/home/lvuser/natinst/bin/data/”是LabVIEW在Linux RT系统下的默认路径,如果用户自己编译出来的FPGA bit文件名称跟我们的不一样,只需要将路径里面最后的bit文件名称替换一下即可,前面的默认路径最好不要动。

6.2.2.2:编写PL2PS Memory上行方向的PS端Linux RT应用程序(PS读取PL端的数组)

        接下来,我们还需要针对前面PL端实验7.2上行的FPGA VI编写一个对应的PS端读取Memory数组的Linux RT应用程序。过程与上面的6.2.2.1类似,用户可以直接复制上面的FPGA VI框图,然后将前面板上的动态加载的FPGA bit文件换成实验7.2编译出来的bit文件,然后将框图里面的“PS2PL_Mem_Write.vi”全部换成“PS2PL_Mem_Read.vi”,如图7-83所示;相应的Linux RT程序前面板如图7-84所示。

图7-83:完整的ZYNQ PS(ARM)端读取PL端FPGA里面不同数据类型Memory数组的Linux RT程序框图

图7-84:ZYNQ PS端Linux RT读取PL端FPGA里面不同数据类型Memory数组的前面板

6.2.2.3:编写Loopback Memory回环的PS端Linux RT应用程序(PS先发送再回读PL)

        为了展示PS端与PL端之间的Memory存储器双向通信,我们可以将前两个Linux RT程序里面的Memory读写合在一起,然后与实验7.3里面的FPGA VI对应起来,就能实现一个Memory数组发送和回读的回环程序,具体编写过程可以参考后续录制的视频教程,这里直接给出PS端Memory回环实验Linux RT程序框图和前面板,如图7-85和7-86所示。这里只做了无符号U8类型的Memory存储器通道收发验证,至于其他数据类型,直接切换多态VI即可,感兴趣的用户可以自己尝试一下。

图7-85:ZYNQ PS端通过Memory存储器通道发送数组给PL端FPGA再回读回来的Linux RT程序框图

图7-86:ZYNQ PS端通过Memory存储器通道发送数组给PL端FPGA再回读回来的Linux RT前面板

        最终完成的3个PS端Memory存储器访问和操作的Linux RT程序,分别位于ZYNQ PS终端下的效果,如图7-87所示。

图7-87:与前面PL端FPGA里面相对应的3个PS端Memory交互Linux RT程序

7、硬件接线实物图

        提醒:由于本节实验用到了ZYNQ PL端FPGA部分,前面也编写好了FPGA VI程序,如果用户想在线观察ZYNQ PL端FPGA VI前面板实际运行情况,可以将Xilinx JTAG下载器接到ZYNQ开发板上;反之,如果不想观察FPGA VI的在线前面板交互式运行,这里也可以不用接下载器,因为PL端的FPGA bit文件可以通过PS端来动态加载,不需要通过下载器下载都行。

        对于ZYNQ PS端Linux RT程序的部署和下载,则需要一根CAT5+或者CAT6类千兆网线或者通过WiFi无线部署(参考第6章实验2),然后将ZYNQ开发板跟上位机开发电脑互联起来即可,上位机开发电脑通过网线和Xilinx JTAG下载器与正点原子ZYNQ开发板之间的硬件接线实物图,如图7-88所示。

图7-88:完整的硬件接线实物图(千兆网线接到PS端网口里面)

8、程序编译下载

8.1:准备工作(将前面编译好的PL端FPGA bit文件添加到PS端)

        由于本节实验用到了ZYNQ芯片PL端FPGA部分,为了让PS端Linux RT程序可以动态加载PL端的FPGA bit文件,我们需要将前面编译好的FPGA bit文件添加到ZYNQ PS端Linux RT终端里面来,步骤如下。

        右击ZYNQ PS端Linux RT终端下的“ZYNQ PL FPGA bit files”,选择“Add/添加>>File/文件”,如图7-89所示;然后在弹出来的文件选择对话框里面找到前面编译出来的PL端FPGA bit文件,如图7-90所示;添加成功后的效果如图7-91所示。

图7-89:右击Linux RT终端选择添加FPGA bit文件

图7-90:选择前面编译出来的3个PL端FPGA bit文件

图7-91:FPGA bit文件添加成功后的效果

8.2:ZYNQ PS端Linux RT应用程序编译、部署、下载

        1)由于ZYNQ开发板与上位机电脑之间是通过网线直连的,中间没有经过路由器,所以,上位机要利用ZYNQ PS端Linux RT默认的静态IP地址:192.168.2.99来部署下载上位机写好的Linux RT程序,因此,上位机网卡IP地址也要设置成同一个网段,比如192.168.2.10,如图7-92所示。

图7-92:将上位机开发电脑网卡IP地址设置成跟下位机ZYNQ里面的eth0:1虚拟网卡静态IP地址在同一个网段内

        2)然后检查一下LabVIEW ZYNQ PS端Linux RT终端里面的IP地址是否为下位机ZYNQ里面的固定IP地址(192.168.2.99),如果不是,则右击终端选择“Properties/属性”,如图7-93所示;再在属性设置页面里面修改一下即可,如图7-94所示。

图7-93:如果IP地址不一样的话,可以右击LabVIEW Linux RT终端选择属性

图7-94:在Linux RT属性配置里面将IP地址改成ZYNQ直连方式下的固定静态IP地址

        3)右击ZYNQ PS端Linux RT终端(ZYNQ7020_PS_Linux_RT)选择“Connect/连接”,如图7-95所示;不出意外的话,会弹出来一个“Deployment Progress”部署成功的提示框,如图7-96所示;最后点击一下“Close/关闭”该对话框即可,此时,可以看到LabVIEW Linux RT终端左下角的指示灯点亮了,如图7-97所示,表明上位机Linux RT终端与下位机ZYNQ板子通过网线建立起了连接。

图7-95:右击LabVIEW Linux RT终端(ZYNQ7020_PS_Linux_RT)选择“Connect/连接”

图7-96:弹出一个部署进度与部署成功的提示框(Close即可)

图7-97:连接成功后Linux RT终端logo图标指示灯会点亮

        4)右击Linux RT终端(ZYNQ7020_PS_Linux_RT)里面的程序生成规范,选择“New/新建”一个“Real-Time Application/实时应用程序”,如图7-98所示;然后在弹出来的RT应用程序属性配置页面里面,将程序生成规范重命名为“实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端)”,如图7-99所示;再选择左侧目录里面的“Source Files/源文件”里面的本节实验7编写的VI程序(实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端).vi)添加到右侧的“Startup Vis/启动VIs”列表里面,如图7-100所示;最后将中间文件夹“ZYNQ PL FPGA bit files”里面的FPGA bit文件(7.1-PS2PL-Memory.bit)作为附件添加到右下方的“Always Included/总是包含”里面,如图7-101所示。

图7-98:右击Linux RT终端下的程序生成规范新建一个RT应用程序规范

图7-99:将新建出来的Linux RT应用程序生成规范重命名以示区分

       图7-100:将源文件里面本节实验7编写的Linux RT VI添加到右侧启动VIs列表里面

图7-101:将前面编译好的PL端FPGA bit文件添加到右侧“Always Included/总是包含”

        提醒:所有非LabVIEW静态调用的文件都可以放到这个“Always Included/总是包含”里面,这样后续部署下载的时候,上位机LabVIEW会把这些文件自动通过网络下载到下位机ZYNQ Linux RT系统里面去,免去了手动拷贝,简单实用可靠。

        5)接下来,右击刚刚创建的实验7对应的RT应用程序生成规范,选择“Build/编译”,如图7-102所示;大概几秒钟就能编译完成,并且会有一个编译成功的提示框,如图7-103所示;点击“Done/完成”按钮退出这个提示框,再右击实验7程序生成规范,选择“Deploy/部署”将刚刚编译出来的Startup.rtexe以及FPGA bit文件全部部署下载到ZYNQ板子里面去,如图7-104所示;一切顺利的话,会有一个部署进度条和部署成功的提示框出现,如图7-105所示。

图7-102:右击实验7 Linux RT应用程序生成规范进行“Build/编译”

图7-103:编译完成后会有一个编译进度条和编译成功提示框

图7-104:右击Linux RT实验7程序生成规范选择“Deploy/部署”下载

图7-105:ZYNQ PS端Linux RT程序及其组件附件会一起部署下发到ZYNQ里面去

9、实验现象

        1)直接点击本节实验7.1对应的Linux RT程序(实验7.1-PS端发送Memory数组给PL端(ZYNQ PS端).vi)左上角的运行箭头,可以看到上位机LabVIEW会把这个VI程序及其组件、驱动和FPGA bit文件一起部署下载到ZYNQ芯片里面运行,如图7-106所示;同时PS端里面的Linux RT应用前面板活了,自动进入在线前面板交互式运行模式,此时,前面板上的“Running_PS”显示控件里面的数值开始递增,说明PS端的Linux RT程序里面的while循环开始运行起来了,如图7-107所示。

图7-106:上位机实验7.1对应的Linux RT程序和FPGA bit文件成功部署到了下位机ZYNQ芯片里面运行

图7-107:Running_PS显示控件数值递增,表明Linux RT程序里的while循环开始运行了

        2)为了同步观察ZYNQ PL端FPGA VI程序运行情况,我们可以借助Xilinx JTAG下载器和LabVIEW FPGA在线前面板交互式运行功能,由于PS端已经将PL端的FPGA bit加载到ZYNQ芯片里面运行了,所以这里不需要Xilinx下载器去下载FPGA bit文件了,因此,我们需要先将ini.txt文件里面的1改成0,如图7-108所示,让PL端FPGA VI直接进入在线前面板交互式运行,直接运行项目下的ZYNQ PL端My FPGA终端下的实验7.1这个FPGA VI,等待几秒可以看到,FPGA VI前面板活了,同时前面板上的“Running_FPGA”显示控件里面的数值变成了最大值,如图7-109,这是因为这个定时循环迭代值运行速度是50MHz,非常快。

图7-108:将Xilinx JTAG下载器配置文件ini改成0(跳过下载直接进入在线前面板)

图7-109:直接运行ZYNQ PL端My FPGA终端里面的FPGA VI(前面板活了)

        3)接下来,测试一下PS端通过Memory存储器发送数组给PL端,看看PL端FPGA能不能收到。用户可以在前面板上对无符号数组输入正数,有符号数组输入负数,如图7-110所示;然后观察PL端FPGA VI前面板上的数组显示控件里面的数值跟PS端是否完全一致,如图7-111所示。

图7-110:修改ZYNQ PS端Linux RT前面板上的数组输入控件数据

图7-111:ZYNQ PL端FPGA VI前面板上的Memory存储器数组立刻更新了(完全一样)

        4)下面,测试一下PL端是否能够通过Memory存储器通道将FPGA前面板上的数组发送给PS端。实验7.2对应的Linux RT编译和部署方法,跟前面类似,这里不再演示了,直接创建一个Linux RT应用程序生成规范,然后添加实验7.2 Linux RT程序(实验7.2-PS端读取PL端的Memory数组(ZYNQ PS端).vi)和对应的FPGA bit文件(7.2-PL2PS-Memory.bit),然后编译和部署,最后直接点击实验7.2 Linux RT程序左上角的运行箭头开始运行。可以看到前面板上的“Running_PS”显示控件里面的数值开始递增了,如图7-112所示,说明Linux RT程序里面的while循环运行起来了。

图7-112:ZYNQ PS端实验7.2对应的Linux RT程序运行起来了

        接下来,运行一下PL端实验7.2 FPGA VI程序,修改一下FPGA VI前面板上的数组输入控件里面的元素,对无符号和有符号数组分别输入正数和负数,如图7-113所示;然后观察一下PS端实验7.2 Linux RT前面板上的数组显示控件里面的数据,如图7-114所示,可以看出,PS端Linux RT接收到的PL端FPGA通过Memory存储器通道发送过来的数组数据完全一样。

图7-113:修改一下PL端实验7.2 FPGA VI前面板上的数组元素

图7-114:ZYNQ PS端实验7.2 Linux RT前面板上显示的数组元素跟PL端发送的完全一致

        5)最后,我们测试一下PS端与PL端之间的Memory数组能否正常回环。同样需要先创建一个Linux RT应用程序生成规范,将PS端实验7.3 Linux RT程序(实验7.3-PS端发送数组给PL端再回读回来-Memory-Loopback(ZYNQ PS端).vi)和对应的FPGA bit文件(7.3-Loopback-Memory.bit)添加进去,然后编译部署一下,再运行Linux RT程序,可以看到Linux RT程序前面板上的“Running_PS”显示控件里面的数值递增了,说明程序框图里面的while循环开始运行了,如图7-115所示。

图7-115:ZYNQ PS端实验7.3 Linux RT程序开始运行了

        我们可以在实验7.3 Linux RT程序前面板左侧的数组输入控件里面填写任意数值,然后观察一下右侧从PL端FPGA返回来的数组内容是否完全一样,如图7-116所示。可以发现,实际在左侧输入的时候,右侧会跟着实时变化,说明我们的PL端FPGA Memory回环程序起作用了,动态变化过程可以参考后续录制的视频教程。

图7-116:ZYNQ PS端实验7.3 Linux RT程序前面板发送的数组与PL端返回的数组一致

11、实验总结

        我们总结一下本节实验学到的内容和需要注意的事项。

        本节实验我们通过Memory存储器通道实现了ZYNQ芯片内部PL端FPGA部分与PS(ARM)端Linux RT程序之间的数组通信和交互,与前面第五章开发过程类似,程序本身比较简单。但是由于涉及到利用LabVIEW同时开发ZYNQ里面的PL端与PS端部分,对于初学者来说,里面的每个步骤和操作过程都要熟练掌握,虽然都是一些基础知识,但是熟能生巧,后续实验会越来越复杂,功能越来越多,希望大家都能轻松学会掌握。

        本节内容主要是全方位讲解PS端与PL端进行双向通信的所有数据类型的Memory存储器通道,熟悉了这些存储器通道,大家就能打通PS端与PL端之间不同位宽、不同数据类型的数组、向量、图像、簇等数据交互了;下一节实验我们会重点讲解如何通过FIFO队列实现PS端与PL端之间的连续数据流传输。

相关文章:

第6章>>实验7:PS(ARM)端Linux RT与PL端FPGA之间(通过Memory存储器进行通信和交互)《LabVIEW ZYNQ FPGA宝典》

1、实验内容 上一节实验里面介绍的Reg寄存器通道比较适合在PS端和PL端之间传递标量数据,也就是单个元素,如果要传递多个元素的数组或者连续数据流的话,Reg寄存器通道就不是很合适了。 本节实验我们向大家讲解如何借助Memory存储器通道在PS&am…...

通用前端的学习

通用前端的概念 通用前端的概念是我自创的,也是我多年开发全栈时的个人理解,结合自己对各种语言的比较,发现前端都具有几个特征,而这几个特征,很多人只能用具体的表象来描述,比如用安卓方式来说明&#xf…...

git本地仓库关联多个远程仓库时git pull失败问题

目录 问题描述 原因 解决办法 1.多个远程仓库需有继承关系 2.一句命令实现创建本地分支且与远程分支关联 问题描述 今天操作本地仓库时,关联了两个远程仓库,欲在本地仓库创建一个分支,与第二个远程仓库的某个分支关联,然后将…...

人工智能(AI)、Web 3.0和元宇宙三者联系、应用及未来发展趋势的详细分析

人工智能(AI)、Web 3.0和元宇宙作为当前科技领域的热门话题,它们之间存在着紧密的联系,并在各自领域内展现出广泛的应用和未来的发展趋势。以下是对这三者联系、应用及未来发展趋势的详细分析: 一、人工智能&#xff…...

【IEEE出版 | 高校主办】第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024)

第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024) 2024 3rd International Conference on Artificial Intelligence, Internet of Things and Cloud Computing Technology 2024年9月13-15日 | 中国武汉 重要信息 大会官网:www.ic…...

PTA 7-4 BCD解密

7-4 BCD解密(10分) BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位。所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12。但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了。于…...

计算机网络中拥塞控制的门限值怎么设置

拥塞避免的门限值设置主要涉及到加权随机早期检测(‌WRED)‌技术,‌这是一种拥塞避免机制,‌通过为每个队列设定一对低门限和高门限值来实现。‌具体来说,‌当队列长度小于低门限时,‌不丢弃报文&#xff0…...

解锁肥胖焦虑的枷锁:拥抱自我,健康前行

在这个颜值经济盛行、信息爆炸的时代,肥胖似乎成了许多人心中难以言说的痛。社交媒体上满屏的“A4腰”、“锁骨养鱼”,无形中给大众套上了一层名为“肥胖焦虑”的沉重枷锁。但请相信,真正的美丽与幸福,从不以体重秤上的数字为衡量…...

WPF学习(7)- Control基类+ContentControl类(内容控件)+ButtonBase基类

前面给大家介绍完了WPF所有的布局控件,属性以及使用案例,从这里咱们就开始学下内容控件。 Control基类 Control是许多控件的基类。比如最常见的按钮(Button)、单选(RadioButton)、复选(CheckBox)、文本框…...

moka实习生一面0607

java支持哪些数据类型 byte、short、int、long、boolean、char、float、double int取值范围- 2^31~2^31-1 什么是包装类 基础数据类型相应的对象,用于需要对象的地方使用这些基本数据类型。 Integer inull;int ji;会怎样,会报什么错误 会报java.lang.Nul…...

centos开启samba服务

centos开启samba服务 一、安装二、配置 一、安装 1.检查是否已有samba组件,如已经安装则会显示对应信息 rpm -qa|grep samba2.执行安装命令 yum -y install samba二、配置 1.创建samba用户 pdbedit -a centos_smb11.编辑配置文件/etc/samba/smb.conf,替换为如下…...

2024年8月一区SCI-海市蜃楼优化算法Fata morgana algorithm-附Matlab免费代码

引言 本期介绍了一种基于地球物理的高效优化方法名为海市蜃楼优化算法Fata morgana algorithm,FATA的元启发式算法。通过模拟海市蜃楼的形成过程,FATA分别设计了海市蜃楼滤光原理(MLF)和光传播策略(LPS)。该成果于2024年8月最新上线在JCR 1区&#xff0…...

【编程笔记】解决移动硬盘无法访问文件或目录损坏且无法读取

解决移动硬盘无法访问文件或目录损坏且无法读取 只解决:移动硬盘无法访问文件或目录损坏且无法读取 问题 由于频繁下载数据,多次安装虚拟机导致磁盘无法被系统识别。磁盘本身是好的,只是不能被识别,如果将磁盘格式化&#xff0c…...

行为型模式(一)策略模式

目录 1. 介绍 2. 目的 3. 实践 1. 介绍 策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每种算法封装成具体的策略类,并使它们可以互相替换。策略模式使得算法可以独立于客户端而变化&#x…...

JAVA中的Wrapper类

ava中的Wrapper类,也称为包装类,是Java提供的一组特殊类,它们将基本数据类型(如int、char、double等)封装为对象。这种封装提供了基本数据类型所不具备的功能,如类型转换、序列化、以及在集合(如…...

在没有硬盘的情况下进行电脑数据迁移

电脑数据迁移方式 在更换电脑的时候需要进行文件的传输,但是没有硬盘可以选择使用网线直连或者无线文件共享。通用配置 1.将旧电脑的文件夹或者磁盘设置文件共享 找到指定的文件夹右键属》属性,点击共享》点击高级共享 选择共享文件夹以及修改共享用户…...

C++转Java基础知识

目录 1. Java基础知识 1.1 JDK和JVM 1.2 Java基础代码演示 1.3 Java中的注释 1.4 Java中的关键字 1.5 Java中的println和print的区别 2. Java中的数据类型 2.1 常量 2.2 标识符 2.3 变量 2.4 类型转换 2.5 自动类型转换 2.6 强制类型转换 3. 运算符 3.1 自增运算…...

搭建jenkins一键部署java项目

一、搭建jenkins 链接: https://pan.baidu.com/s/1jzx15PiyI8EhLd_vg7q8bw 提取码: ydhl 复制这段内容后打开百度网盘手机App,操作更方便哦 直接使用docker导入镜像,运行就好 docker run -di --name jenkins -p 8080:8080 -v /home/jenkins_home:/var/je…...

从零到一打造自己的大模型(一)模型实现

前言 最近看了很多大模型,也使用了很多大模型。对于大模型理论似乎很了解,但是好像又缺点什么,思来想去决定自己动手实现一个 toy 级别的模型,在实践中加深对大语言模型的理解。 在这个系列的文章中,我将通过亲手实践…...

【开源项目】基于RTP协议的H264码流发送器和接收器

RTP协议 1. 概述1.1 RTP协议1.2 RTP和UDP的关系 2. RTP打包H264码流2.1 RTP单一传输2.2 RTP分片传输2.3 RTP多片合入传输 3.工程3.1 头文件3.1.1 rtp.h3.1.2 utils.h 3.2 cpp文件3.2.1 rtp.cpp3.2.2 utils.cpp 4.测试5.小结 参考: 视音频数据处理入门:UD…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

微信小程序云开发平台MySQL的连接方式

注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...