PYNQ:使用python进行FPGA开发
前言
PYNQ 就是python+ZYNQ的意思,简单来说就是使用python在Xilinx 的ZYNQ平台上进行开发。是Xilinx开发的一个新的开源框架,使嵌入式编程人员能够在无需设计可编程逻辑电路的情况下即可充分发挥 Xilinx Zynq All Programmable SoC(APSoC)的功能。
PYNQ-Z2开发板是最近刚推出的低成本的支持PYQN开发环境的demo板。淘宝上单板售价是950RMB,买套装的需要一千多,如果各种必要配件手里都有的话,买单板就行了。最近北美天然气价格暴涨,鄙人小赚一笔,用收益入手了一块!感谢北美人民的取暖费!
就是下面这款骚气十足的板子。
PYNQ-Z2.JPG
一、环境搭建
下面这个链接罗列了初次搭建是需要参考的各种资料
http://www.digilent.com.cn/community/411.html
或者直接下载《PYNQ-Z1 官方入门指导手册》就可以按照步骤快速搭建。硬件上只需要8GTF卡+网线+microUSB线。去网上下载最新的镜像,写入到TF,就可以正常启动。
启动后,如果你是用电脑网口和PYNQ直连的话,浏览器地址栏输入PYNQ的默认IP 192.168.2.99即可登录,登录密码是xilinx。登录后的Jupyter界面如下。
登录界面.JPG
程序编写和调试可以在jupyter 里面完成,后面会有图片显示开发的界面。这里要注意,你使用的浏览器要支持Jupyter,最新版的Chrome就可以。
我平常开发都是需要连上VPN,导致无法使用网线直连,我的解决方案是在虚拟机下的ubuntu里面连接,将虚拟机的网络连接设为桥连接,并且去掉VPN的连接就可以无障碍连接,一边上谷歌,一边调试。
PYNQ 开发平台的框架是这样的:
二、Pyhon是如何控制到硬件层
这个问题中间涉及很广泛的知识,我也还有很多细节没有搞清楚,这里只能粗略说一下,以后搞懂了,我再补上这一块。
Python调用底层硬件框架.png
ZYNQ 分为PS和PL两个部分,PS有两个ARM的核,在上面运行linux操作系统,在操作系统上再运行python。PL部分就是FPGA的逻辑资源,开发者在PL中添加IP或者将自己用C或者HDL语言写好的模块封装成IP,这些IP都被连接到PS端,一般都是通过AXI总线。PYNQ有一个特有的库叫overlay,使用这个库可以对连接到PS端的接口进行解析,进而控制FPGA 逻辑资源及IO。
每次当你需要开始一个新的涉及PL端的开发的时候,先在vivado 里面建一个工程,添加你需要的各种IP,然后以ZYNQ为核心连接的设计,经过编译后,生成一个bit文件和一个tcl文件。bit文件就是你的硬件设计,tcl文件描述了接口关系。将这两个文件复制到PYNQ的目录下,即可进行调用。每一次调用的时候,你设计的硬件都是被动态加载的,这一点不同于大家熟悉的加载过程。动态加载无需重启硬件,操作系统无需重启。这一是一个极有优势的设计,我记得当年调试过intel 和Altera共同推出的阿童木平台完全不同。
进过上面的描述,我们可以得知,在PYNQ框架下,可以非常方便地进行FPGA开发,可以充分利用pyhon的灵活性和FPGA的硬件资源。Pyhon可以帮你轻松完成各种复杂设计,比如图像处理和人工智能的算法,FPGA可以为你提供灵活的接口和硬件加速能力。
Python 控制硬件的demo
其实PYNQ的设计就是设计一个属于你自己的overlay,将其放到PYNQ平台上运行。对于我买的PYZQ-Z2 开发板里面已经有一个囊括了板子上所有硬件资源的overlay,叫base overlay。本节描述的是如何构建一个针对你自己硬件设计的overlay。
这个过程可以参考一下两个视屏
1.How to make a custom PYNQ overlay
https://www.youtube.com/watch?v=Dupyek4NUoI
2.PYNQ example of controlling IP using GPIO
https://www.youtube.com/watch?v=UBsCNPWudww&t=2s
下面有个博客链接也可以为你提供很好的参考,只是不是非常详细。
https://blog.csdn.net/bramblewalls/article/details/80045922
我设计的Demo里面添加了三个AXI GPIO的标准IP,分别用来控制LED、读取button和输出测试信号。系统的连线图是这样的:
diagram.JPG连线完成后,IO端口的配置如下:
#LEDs
#set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L6N_T0_VREF_34 Sch=led[0]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L6P_T0_34 Sch=led[1]
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L21N_T3_DQS_AD14N_35 Sch=led[2]
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L23P_T3_35 Sch=led[3]
##Raspberry Digital I/O
#set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { rpio_02_r }]; #IO_L22P_T3_34 Sch=rpio_02_r
#set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { rpio_03_r }]; #IO_L22N_T3_34 Sch=rpio_03_r
#set_property -dict { PACKAGE_PIN Y18 IOSTANDARD LVCMOS33 } [get_ports { rpio_04_r }]; #IO_L17P_T2_34 Sch=rpio_04_r
#set_property -dict { PACKAGE_PIN Y19 IOSTANDARD LVCMOS33 } [get_ports { rpio_05_r }]; #IO_L17N_T2_34 Sch=rpio_05_r
#Switches
#set_property -dict { PACKAGE_PIN M20 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L7N_T1_AD2N_35 Sch=sw[0]
#set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L7P_T1_AD2P_35 Sch=sw[1]
设计完成后导出.bit和.tcl,将这文件重命名,复制到开发板上。PYQN开发板的文件服务器在network 目录下,也可以在文件夹地址栏直接输入pynq来查找,用户名和密码都是xilinx。
image.png
接下来就可以在运行了。
PYNQ 开发的官方文档都在这里
https://pynq.readthedocs.io/en/v2.0/getting_started.html
我们设计的overlay 只用到了axi_gpio,需要用到pynq.lib.axigpio模块,参考文档在这里
https://pynq.readthedocs.io/en/v2.0/pynq_package/pynq.lib/pynq.lib.axigpio.html
测试程序如下:
-
button的测试程序如下:
将两个button都拨到开的位置,读回值就是3,也就是b'11
2.点亮LED0 和LED2:
输出0x05,就是b'0101,表示第一个和第三个LED被点亮。
后记
初次使用PYNQ后感觉很好用。个人觉得至少在以下几方面极具优势:
1.快速验证设计模型,加速开发
2.提升软硬件协同设计
3.高效整合系统资源
工程文件和一些相关资料被上传到百度网盘。
链接:https://pan.baidu.com/s/1F9Ff0oBSYaoiclcTxANs3A
密码:打赏后私信可以获取下载密码,不在意金额,旨在甄别技术爱好者。
目前还没用想到用PYNQ做什么东西,欢迎大家留言交流,提供创意。谢谢!