《LabVIEW ZYNQ FPGA开发宝典》第5章:5.2:LabVIEW ZYNQ FPGA开发流程简介(分为PS(ARM)和PL(FPGA))

        在正式开始用LabVIEW开发ZYNQ芯片程序之前,我们有必要花一点时间对ZYNQ里面的PS端Linux RT程序和PL端的FPGA程序以及二者之间的通信过程和原理做个简单的开发流程说明。

        其中,ZYNQ PL端FPGA程序开发跟我们之前的My FPGA Pro1345里面的纯FPGA编程非常类似,而ZYNQ PS端 Linux RT程序的开发则跟上位机LabVIEW开发类似,二者之间的交互则是通过我们开发好的Reg寄存器、Memory存储器、FIFO、DMA等方式进行通信,PL端FPGA可以看成是PS端Linux RT的一个从设备。

        本章我们会设计一个小实验:ZYNQ PSLinux RT一方面控制自己的PS引脚(MIO)关联的LED灯,同时又通过Reg寄存器映射的方式控制PLFPGAIO引脚,实现对挂在PLFPGA引脚上的LED实现操控,相当于PS端可以既可以控制自己的引脚也可以控制PL端的引脚,二者之间的交互采用最简单最直接的Reg寄存器映射访问。

        当然了,如果用户的项目里面用不到FPGA,只需要ARM端跑Linux RT程序的话,那么实际上这颗ZYNQ芯片里面的FPGA就浪费了,变得跟普通的ARM芯片一样,显然这不是我们选择ZYNQ芯片的初衷。我们就是要充分发挥出ZYNQ芯片里面的PS(ARM)处理器与PL(FPGA)端的强大互补优势。

   5.2.1:ZYNQ芯片里面的PL部分FPGA开发过程简介

        在开始下面的5.3节具体实验编程之前,用户需要了解和掌握LabVIEW开发FPGA的一些基础知识、开发流程、编程技巧和注意事项。跟NI其他嵌入式硬件开发一样,我们将其划分为以下4个步骤。在后续的ZYNQ PL端程序开发部分,我们也会同样按照下面的这4个步骤进行讲解,这样层次会比较分明。建议用户学以致用,参考和借鉴本节的思路利用LabVIEW开发实际ZYNQ FPGA项目或者产品,做到心中有数。

        1)ZYNQ PL端FPGA项目创建(项目浏览器)。

        2)ZYNQ PL端FPGA应用程序开发(VI)。

        3)ZYNQ PL端FPGA程序仿真、编译、下载、运行、调试。

        4)ZYNQ PL端FPGA程序固化(Bit位文件,直接交给PS端即可,由PS端动态加载)。

        考虑到有些用户是LabVIEW初学者或者零基础,因此,我们本着从基础到入门到精通的态度,来帮助用户快速学习和掌握这门高级编程语言LabVIEW FPGA。下面简单了解一下以上这4个步骤的含义。

        1)ZYNQ PL端FPGA项目创建(项目浏览器)

        早期LabVIEW开发应用程序是没有项目这个概念的,直接一上来就是新建一个VI应用程序,后来大家发现这种方式非常不利于开发、管理和维护一个综合性的大型项目或者产品。因此,后来新版本LabVIEW就引入了项目浏览器这个独立窗口。这个项目浏览器与我们平时常用的IDE开发软件里面的project很类似,只不过LabVIEW里面的项目窗口不仅可以用来管理组织各类不同的文件,还可以创建各种库文件以及对VI进行编译下载等。LabVIEW项目浏览器后缀名是.lvproj。用户可以右击通过记事本打开,项目本质上是一个文本格式的记录文件。

        LabVIEW里面的项目浏览器是最顶层的,里面除了默认“我的电脑”外,还可以创建出各种NI嵌入式硬件设备,例如RT、FPGA等。因此,我们这本书里面的FPGA终端设备就是依附于LabVIEW项目浏览器而存在的。需要注意的是:新建FPGA终端需要在“我的电脑”上右击新建“终端和设备”而不是lvproj项目名称上,切记!

        2)ZYNQ PL端FPGA应用程序开发(VI)

        编写一个ZYNQ PL端FPGA应用程序,对于LabVIEW来说就是一个非常普通的VI,这个VI相当于传统硬件描述语言(VHDL/Verilog)开发的top顶层文件,至于ucf或者xdc管脚约束文件,LabVIEW已经全部封装好了,用户只需要掌握LabVIEW程序的基本数据流编程,就可以开发出FPGA程序了,相对于VHDL/Verilog来说,要简单很多。毕竟掌握精通一门硬件描述语言的难度比C语言还难,更别说LabVIEW了。

        前面第1章也提到过LabVIEW开发FPGA的基本工作原理,虽然我们可以非常轻松写意的编写LabVIEW程序,实际上是NI帮助大家将LabVIEW的数据流程序框图,转换成了一个个小的VHDL代码,然后传递给Xilinx的ISE或者Vivado编译器进行编译。简化了开发和调试过程。

        3)ZYNQ PL端FPGA程序仿真、编译、下载、运行、调试

        LabVIEW FPGA VI编写完成后,如果这个FPGA程序里面的逻辑非常复杂或者包含类似FFT这种复杂的算法,用户直接先编译下载再去调试的话,效率非常差,因为FPGA VI编译花费的时间会比较长,而且FPGA的调试也没有LabVIEW上位机那么简单灵活。

        因此,我们在正式编译之前,可以选择LabVIEW FPGA里面特有的“执行VI>>带仿真I/O的开发计算机”,这样就可以提前通过将FPGA程序放在计算机上进行在线模拟分析调试,利用LabVIEW自带的探针、前面板、模拟信号源等方式,尽可能排除一些低级或者语法错误,减少不必要的编译次数。等到基本的功能仿真完成,没有明显的bug之后,再去编译下载,心里就更有底了。这个功能是NI特有的,虽然PC无法真实代替FPGA芯片的高速运行,但是可以模拟FPGA的运行工作状态,所以非常适合功能性的纯软件仿真。

        仿真结束之后,我们通过选择“执行VI>>FPGA终端”再切换回FPGA运行模式,然后点击VI左上角的运行按钮,就可以触发弹出编译对话框,然后选择本地或者服务器上的编译器,点击确定之后就能看到FPGA VI的整个编译过程,包括“资源预估”、“映射”、“时钟频率优化”、“生成bit文件”等。编译成功后,LabVIEW会自动将这个VI下载到ZYNQ PL端FPGA芯片里面运行,同时电脑上的LabVIEW FPGA VI前面板活了,也就是说可以借助LabVIEW前面板在线交互式运行来调试这个FPGA程序,非常方便一旦调试OK之后,为了节约FPGA资源和加快FPGA编译速度,用户可以将前面板上的控件删除掉再重新编译一次就可以了。

        4)FPGA程序固化(Bit位文件)

        LabVIEW FPGA程序默认是直接下载到FPGA里面运行的,一旦掉电或者复位就没有了,所以为了像单片机那样能够上电或者复位之后直接加载运行程序,用户需要将可执行文件下载到一颗片外Flash或者TF卡里面进行保存,上电的时候FPGA自动从Flash或者TF卡里面加载程序运行。这个过程我们称之为“FPGA程序固化”。

        一旦LabVIEW FPGA VI程序编译完成后,就会形成最终的FPGA可执行文件,这个可执行文件一般称之为bit位文件。不过用户看到的不是原始的bit文件,而是经过NI包装过一层的lvbit文件。这个lvbit文件是没有办法直接用传统的IMPACT.exe或者Vivado或者Adept工具进行下载的。但是,我们(神电测控)开发的LabVIEW My FPGA工具包可以帮助用户轻松完成一键lvbit文件转换为bitmcs或者bin文件,方便用户后期批量部署。这样一来,用户既可以利用LabVIEW对板子上的Flash进行bit文件下载,也可以利用传统的IMPACT.exe或者Vivado工具或者Digilent Adept进行独立下载。

        提醒:与纯FPGA固化bit文件不同,ZYNQ架构的芯片里面由于集成了ARM处理器,FPGA可以看成是ARM处理器的一个从设备,因此,我们可以将编译出来的FPGA bit文件通过右击部署下载到TF卡的Linux RT系统的任意一个目录里面,然后通过我们封装的PS端Linux RT下的动态加载bit文件VI函数,可以实现对任意FPGA bit文件的动态加载、覆盖和切换,因此,理论上讲,ZYNQ里面的PL端FPGA bit不存在固化一说了,随时拷贝随时部署即可。

   5.2.2:ZYNQ芯片里面的PS部分ARM开发过程简介

        相比ZYNQ PL端FPGA部分的开发,这里PS(ARM)端LabVIEW Linux RT程序开发相对简单很多,步骤是相似的,就是下面这个5个流程。之所以多了1个步骤,是因为我们需要将前面编译好的ZYNQ PL端FPGA bit文件提前部署下载到PS端Linux RT系统里面去,不然,后续PS端因无法找到FPGA bit导致加载失败,就控制不了FPGA部分了。

        1)ZYNQ PS(ARM)端Linux RT项目创建(项目浏览器)。

        2)ZYNQ PS(ARM)端Linux RT部署下发前面编译好的FPGA bit文件(提前准备)。

        2)ZYNQ PS(ARM)端Linux RT应用程序开发(VI)。

        3)ZYNQ PS(ARM)端Linux RT程序部署、下载、运行、调试。

        4)ZYNQ PS(ARM)端Linux RT生成rtexe开机自启动。

        考虑到有些用户是LabVIEW初学者或者零基础,因此,我们本着从基础到入门到精通的态度,来帮助用户快速学习和掌握这门高级编程语言LabVIEW Linux RT。下面简单了解一下以上这5个步骤的含义。

        1)ZYNQ PS(ARM)端Linux RT项目创建(项目浏览器)

        跟前面新建FPGA终端不同的是,ZYNQ里面的PS端Linux RT因为是一个系统,跟Windows是平级的,所以需要直接在lvproj项目名称上右击新建“终端和设备”,千万不能在“我的电脑”上右击,否则你不会找不到任何Linux RT终端的。新建出来的Linux RT只需要给定下位机ZYNQ开发板PS(ARM)端的IP地址就可以实现程序的部署和下载了。

        2)ZYNQ PS(ARM)端Linux RT部署下发前面编译好的FPGA bit文件(提前准备)

        ZYNQ芯片里面除了PS端ARM,还有一个从设备FPGA部分,为了让PS端Linux RT能够操控PL端FPGA,所以我们需要提前将上面编译出来的FPGA bit文件通过LabVIEW Linux RT项目特有的部署下载功能,将其提前部署到Linux RT指定的目录下,这样,后面我们在编写PS端Linux RT程序的时候就能直接动态加载这些FPGA bit文件了。提醒:当然了,我们还可以借助前面安装过的MobaXterm软件将FPGA bit文件复制到ZYNQ开发板上的TF卡里面,这种方式不推荐,效率低,直接用LabVIEW里面的RT部署功能更简单、更方便。

        3)ZYNQ PS(ARM)端Linux RT应用程序开发(VI)

        用LabVIEW编写ZYNQ Linux RT程序,跟开发上位机类似,没有FPGA语法那么严苛,除了NI提供的Linux RT环境下丰富的函数选板外,如果想要在PS端Linux RT里面控制PL端FPGA部分,那么还需要在Linux RT程序调用我们给大家封装的FPGA bit文件动态加载VI、相关外设寄存器的驱动KO加载VI等,这些VI所在的函数选板和功能简介在前面3.5节里面做过讲解。因此,只要有一点LabVIEW基础就能开发Linux RT程序,因为二者都是系统层面的LabVIEW程序开发,只不过一个是Windows系统一个是Linux RT系统,本质上是一样的。

        4)ZYNQ PS(ARM)端Linux RT程序部署、下载、运行、调试

        相比于需要花费一点时间来编译FPGA VI程序,Linux RT程序写完之后,直接点击运行箭头就会自动将该RT VI通过网络部署下载到下位机ZYNQ Linux RT系统里面运行,基本看不到编译过程,就跟Windows系统上的LabVIEW VI一样。而且LabVIEW Linux RT程序支持前面板调试和探针调试,更重要的是还支持单步运行和断点调试以及高亮运行等功能,就跟大家平时在Windows系统上位机开发一模一样,很轻切,无需额外的学习成本。正是因为ZYNQ PS端Linux RT程序开发调试方便,不需要反复编译,所以将一些对实时性要求不高的任务放在ARM里面跑,可以极大的降低PL端FPGA部分的开发和调试工作量。提醒:ZYNQ PS端Linux RT程序部署是通过网络下载到ARM里面运行的,不需要下载器。

        5)ZYNQ PS(ARM)端Linux RT生成rtexe开机自启动。

        当我们把ZYNQ PS端Linux RT开发调试完成后,在完成最后一步的交付时,肯定希望我们ZYNQ芯片里面的Linux RT程序能够开机自启动,就像单片机一样,上电就能自动加载运行。跟上位机LabVIEW程序生成exe一样,Linux RT程序也可以在程序生成规范里面生成一个后缀是rtexe的可执行文件,并且可以直接右击这个程序生成规范选择“开机自启动”,然后LabVIEW就会自动把这个rtexe部署到ZYNQ里面上电自动加载运行了,非常简单方便。

        唯一需要注意的是:生成rtexe开机自启动可执行文件之前,原始Linux RT VI里面最开始最好加一个10s~20s的延时VI,这是因为每次开机的时候,Linux系统加载比纯ARM裸机要慢的多,为了让我们的Linux RT系统充分运行起来之后,再来执行的我们的Linux RT exe程序更保险,但是在开发阶段是不需要这个延时的,因为开发阶段,下位机Linux RT系统肯定是早就运行起来的,准备好的。

   5.2.3:ZYNQ芯片内部的PS与PL之间的交互原理简介

        为了充分发挥出ZYNQ芯片SOC架构的优势,我们通常会把一些ns级的需要高速、高精度定时的采集、信号处理、PID闭环算法等任务放在ZYNQ芯片里面的PL端FPGA里面运行;而对于一些非实时的us级或者ms级的应用程序可以放在ZYNQ芯片的PS端ARM里面运行,这样可以节约PL端FPGA宝贵的LUT可编程逻辑门资源。那么二者之间到底是如何进行交互的呢?

        看过我们My FPGA Pro5宝典的用户知道,单独的ARM或者单独的X86 CPU与单独的FPGA之间是通过PCIe进行高速互联的,典型的就是NI的cRIO架构。而对于ZYNQ芯片,由于ARM跟FPGA集成在了一个芯片内部,二者之间采用了高吞吐率的AXI总线进行互联,而非PCIe总线。因此,我们可以在PL端FPGA里面调用AXI总线IP核来完成与PS端ARM部分的通信。

        具体说来,一般有以下4种应用场景和交互方式:

        1)对于刷新速度要求不高的标量或者开关量或者状态量或者过程量可以通过Reg寄存器作为PS端(ARM)与PL端(FPGA)之间的沟通桥梁,PS端只需要访问已知的Reg寄存器地址就可以等效于操作PL端FPGA里面映射出来的CLIP Reg寄存器端口了。

        2)对于一些固定长度的参数或者数组或者矩阵或者图像参数需要在PS与PL之间传递的话,最高效的方式是通过Memory存储器映射方式。PS端直接将一个数组写入到Memory里面,那么PL端FPGA里面的Memory地址和Memory数据就会依次被接收到,根据Memory地址和数据将其存放到FPGA自己的Memory存储器里面,就实现了二者之间的Memory互通和映射联系,这里表述有点抽象,后续我们在第6章实验里面结合具体的案例程序给大家讲解,读取也是反之亦然。

        3)对于一些连续的数据流需要在PS与PL之间流转的话,可以借助FIFO通道来实现,比如PL端FPGA实时逐点采集外部ADC信号,然后依次逐点放到FPGA端自己的FIFO里面,此时,PS端可以监测到我们封装的FIFO通道里面数据量有多少,类似串口缓冲区字节长度的概念,然后根据实际情况将其读取出来;再比如,PS端ARM需要将不定长度的任意波形数据或者伪随机数扰动噪声传递给PL端FPGA作为AWG信号发生器或者某些特殊算法的参数,那么PS端可以直接往FIFO里面写入数据即可,PL端可以从FIFO里面读出来数据。提醒:其实后续我们封装的UART、CAN总线本质上都是通过FIFO实现数据传输和交互的,实际上所有的通信协议里面基本上都有缓冲区FIFO的影子。

        4)对于一些高速数据流应用来说,用上面提到的普通FIFO就胜任不了了,为此,我们将ZYNQ里面的DMA FIFO也封装进来了,让PS端ARM跟PL端FPGA之间可以走高速DMA FIFO通道,实测速率可以到180MB/s左右,基本上可以满足一些复杂项目或者产品开发了。比如,ZYNQ芯片PL端高速ADC采集原始数据,然后通过DMA FIFO快速传递给PS端ARM里面做信号处理或者特殊的算法,比如高斯拟合、多项式拟合,互相关算法、不限制点数的双精度FFT频谱变换、包络检测、波峰波谷检测、相位差测量等这些在FPGA里面实现起来非常费劲的算法,而在PS(ARM)段Linux RT里面都是有现成的VI函数,拖一拖就搞定了,非常简单。

        提醒1这也正是我们选择ZYNQ芯片的优势,对于那些在纯FPGA没有现成的算法或者实现起来非常难的算法,对实时要求又不高的算法,可以交给PS端轻松完成,这样PL端FPGA就可以专注于做自己的事情了。

        提醒2由于ZYNQ芯片PS(ARM)里面可以运行Linux RT实时系统,因此,像经常用到的千兆TCP、UDP、WiFi、Modbus、MQTT等很多实用的通信协议都可以直接调用NI现成提供好的VI函数,不需要用户自己开发,而这些协议如果放在PL端FPGA里面实现,会极大的消耗FPGA宝贵的可编程LUT逻辑门资源。

        后面第6章、第7章、第8章我们会通过一个一个具体的实验程序向大家展示一下以上4种通信方式的具体应用和实现方式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值