点击蓝字关注我们
关注、星标公众号,精彩内容每日送达
来源:网络素材
使用UART与ZYBO进行通信
ZYNQ学习过程中一个重要环节是进行调试,当然在SDK中进行调试时,设置断点进行单步调试非常高效。但是ZYNQ中毕竟涉及到FPGA的硬件部分,于是如果可以通过UART与ZYNQ器件进行双向的通信会使得调试非常方便。
Step1: 确认ZYBO板上硬件连接。
在ZYBO的用户手册中有以下描述,如图 21所示。
![fdc3d41344bffda32b649ae99975e690.png](https://i-blog.csdnimg.cn/blog_migrate/719eb97f35650e0091dfa28ec8e001a0.png)
图 21
其ZYBO开发板的原理图也可知MIO Bank的电压为1.8V。
于是可以得到以下几点:
硬件上连接串口的IO为MIO48和MIO49。
IO的电压为1.8V。
默认使用的参数为:115200波特率以及其他对应参数,见图 21。
Step2: 在Vivado的Block Design中配置ZYNQ7 Processing System时,需要配置UART外设,如图 22所示。
![3a26301f71006b6a7a360dc2e10e3c6b.jpeg](https://i-blog.csdnimg.cn/blog_migrate/359265bbcaf7e819751b527f0000083c.jpeg)
图 22
Step3: 按照“Vivado中进行ZYNQ硬件部分设计”中介绍的,直到在SDK中编写C代码步骤。需要使用UART进行通行,分为通过UART向外发送数据和通过UART接收数据。
Step4: PC上安装串口调试助手,硬件上连接串口线到PC。向ZYNQ中下载硬件配置后,在Windows Device Manager查看UART所使用的端口,如图 23所示。
![f0bcb02111f9154847f235bfbb2c333f.png](https://i-blog.csdnimg.cn/blog_migrate/2b5b969f5d5daef89fe5459ae89cc831.png)
图 23
并将串口调试助手设置成相应的配置,如图 24所示。
![db0ad27a7aab473284f2798c0c5bb39e.png](https://i-blog.csdnimg.cn/blog_migrate/04ddaa975b4d0a39d5ec44b029c8b2f5.png)
图 24
Step5: 至此就可以在C代码中发送或者读取数据了,下面给出一段示例代码。
![9e9bb11d6377acd14070985fac0576a7.png](https://i-blog.csdnimg.cn/blog_migrate/0839ac01fe463bc6e7182909e785e911.png)
图 25
程序首先运行,输出” Please enter any number from 0~9”。此后会停在等待输入处,直到通过串口助手键入了数字之后,才会跳到下一行代码,并将键入的数字输出在串口调试助手中。
![c38ec4511235bb48286d6b43133c24dc.png](https://i-blog.csdnimg.cn/blog_migrate/90d3504694db075c24f16a73dd53076d.png)
图 26
至此可以通过串口输出各种信息(因为可以输出字符串),同时也可以通过串口输入进行菜单选择,因为虽然不能接收字符串,但可以键入10个数字以及26个英文字母,这也应该足够了。
Step6: 除了使用外部的串口调试助手外,SDK内部也提供了Terminal工具。通过如下图所示的方式显示Terminal窗口且进行配置,同样可以当作串口调试助手使用,如图 28所示。
![bbb08f1127a1106aa6c97e2f8576de00.jpeg](https://i-blog.csdnimg.cn/blog_migrate/ec07592f816f01830ed34c62a0aa428e.jpeg)
图 27
![5d7fb2cf6571a25e9eab4f865043b801.png](https://i-blog.csdnimg.cn/blog_migrate/46c73e63cd0c7404a51cc4065e26189d.png)
图 28
将用户逻辑设计封装成IP
参考工程见“ZYBO_demo_packageIP.xpr”。
ZYNQ中PS与PL的联系主要有两个,分别是GP端口和HP端口。其中HP端口可以理解为PS和PL可以访问同一片存储空间,于是可以以DDR空间为中介,进行大量的数据通信。而平时在纯FPGA设计中的那些逻辑模块与PS的通信方式就是依靠GP端口完成的。
纯RTL逻辑模块的控制或者输出都是通过模块的输入输出端口实现的。在ZYNQ的架构下,就是将这些输入输出端口改为寄存器,原来的输入端口改为只写的控制寄存器;原来的输出端口改为只读的状态寄存器。于是每个逻辑模块都有一个标准的AXI-Lite Slave接口,用于与PS相连接,使得PS可以控制读写逻辑模块内的寄存器。于是每一个逻辑模块就相当于PS的一个外设,与PS自带的外设,如UART、I2C控制器控制器来是一样的。这就是ZYNQ的硬件可扩展性,通俗的说就是当ARM需要各种要求的外设时,都可以通过在PL端进行逻辑设计实现。
下面就介绍如何一步一步的完成一个PL端的逻辑设计,并将其封装成为IP,并在ZYNQ的Block Design中加入到硬件设计中,并在SDK中通过代码来控制该外设。
本例中所涉及的逻辑模块功能为:IP的外部接口为4盏LED,内部寄存器有3个,分别是工作模式寄存器(MODE),使能寄存器(ENABLE)和状态寄存器(STATUS),如图 29所示。
![6a362280b580419635e9021385dac047.png](https://i-blog.csdnimg.cn/blog_migrate/09bc422ff51e68ef6dcdff6712f31dd4.png)
图 29
Step1: 在Vivado GUI中,选择ToolCreate and Package New IP…。一般情况下,选择“Create a new AXI4 Peripheral”,这种IP就是之前提到的,由PS读写寄存器进而控制的IP,在后面的菜单中选择该IP的Interface接口以及内部需要多少寄存器,如图 30所示。
![09774979f2bac0190b4463d9a81edb34.jpeg](https://i-blog.csdnimg.cn/blog_migrate/c91c757a6f8ad23318986cf4dc777c23.jpeg)
图 30
一般来说,IP首先需要一个AXI-Lite的Slave接口,用于与PS连接。除此以外还可以增加其他AXI接口,例如增加一个AXI4的Master接口,用于逻辑设计中访问PS端的存储器;又比如可以增加一个AXI-Lite的Master,用于读写其他逻辑模块的寄存器等等。在这里选择好接口后,工具在生成IP的时候会自动生成相应的AXI接口代码,用户可以直接使用或者稍作修改即可。
另外就是选择寄存器的个数,因为稍后生成的代码中会自动完成指定数量寄存器的读写控制代码,于是如果设置少了,后面需要手工添加代码,会比较麻烦,不如配置时将寄存器个数设置的多一些。
Step2: 完成配置后工具自动生成代码,在生成的代码中进行修改。
![a8a5d7536a87825363c66d4b7996a0e9.png](https://i-blog.csdnimg.cn/blog_migrate/8f93bf5955faaf6fa3418fdd532d39ae.png)
图 31
在自动生成的代码中,结构如下:
![145e31c5ea6f6281081463ae6421ec63.jpeg](https://i-blog.csdnimg.cn/blog_migrate/cd10e5c6a20e7fc1560d78760362bb0a.jpeg)
图 32
需要注意的是自动生成的代码只是简单完成了指定数量寄存器的读写时序,至于每个寄存器的逻辑功能和含义是没有的,需要用户将这些寄存器引到S00_AXI模块的上层,与用户设计的逻辑进行通信。同时自动生成的代码中所有的寄存器都是可读可写的,如果需要设置只读或者只写的寄存器,需要在S00_AXI模块中自行修改代码。
Step3: 为逻辑设计增加外部接口以及全局参数。
该例程中需要设置4个外部输出管脚,控制外部LED。并且设置一个全局参数为4盏LED的初始状态。首先在代码中指定位置进行修改,如图 33所示。
![c30c8b55dd141509a7734a69a5713723.png](https://i-blog.csdnimg.cn/blog_migrate/b0da9c05a15b16bda294520355021351.png)
图 33
保存修改后,会在GUI界面中看到“Customization Parameter”、“Ports and Interfaces”以及“Customization GUI”的标识都变了,代表检测到了代码中的变化。
![c99d3cd3d10d0509091757c2b0a447fa.png](https://i-blog.csdnimg.cn/blog_migrate/e0aee06f05aa05ca6e58bff3ac89b697.png)
图 34
点击GUI中如下所示的指令后,工具自动完成更新。
![f656bb28167acf01aece05ed6588042a.png](https://i-blog.csdnimg.cn/blog_migrate/660047ef086cefceb0255040684d18c8.png)
图 35
Step4: 在GUI如图 34所示的界面中修改参数设置,对IP进行配置。
Step5: 完成IP的封装,如图 36所示,在Review and Package中点击Re-Package IP。
![5dd3c0fd932ef23260161fb74406d4da.jpeg](https://i-blog.csdnimg.cn/blog_migrate/9fb214003950b3853afae3423a85160a.jpeg)
图 36
此时会关闭IP封装界面,回到ZYNQ Block Design界面。在IP Catalog中会出现刚才封装完成的IP。
![786a248e616c24fe9a7280b388c33af9.jpeg](https://i-blog.csdnimg.cn/blog_migrate/7872d5235e75a994c40842a2db4da55b.jpeg)
图 37
此后的操作就和“Vivado中进行ZYNQ硬件部分设计”中介绍的一样,将该IP当成与其他IP一样的外设,进行Block Design设计,同样需要对于外接接口添加约束文件,之后生成Bit文件。
Step6: 在Block Design中需要将封装的逻辑模块IP需要引到外部的IO进行设置。
右击需要引出的端口,点击“Make External”。之后重新生成HDL Wrapper即可。
![05daebf2c46001c8379d71472b136394.jpeg](https://i-blog.csdnimg.cn/blog_migrate/27910006e8162e2af8822f7b212b2f92.jpeg)
图 38
Step7: 在Block Design中的Address Editor中给IP分配总线地址。
![1a60a62e1e3195f1ae6eb3886186b9ba.png](https://i-blog.csdnimg.cn/blog_migrate/25297adc78f8525afe1da6df726f1546.png)
图 39
Step8: 封装好的IP进行底层修改。
如果需要对已经设计好的IP进行底层修改,就在IP Catalog中显示的该IP处右击,选择“Customize IP”。需要注意的是,工具会默认弹出一个路径,作为修改IP的工作路径,但是该路径是一个临时路径,与之前存放IP的路径不同。
![a8368ccba665d5e37c2c2fd8da92c2cc.png](https://i-blog.csdnimg.cn/blog_migrate/d56f4b1f19905122e5f1b17cb6745a79.png)
图 40
IP底层修改完成之后,重新Re-Package IP后,回到Block Design中工具自动检测到IP有更新,只要通过工具的提示进行IP的更新即可。
![0c25dfb9fe958f1725e39c05ac66fb3d.png](https://i-blog.csdnimg.cn/blog_migrate/1a50eaeef924cc5685eee228b7cba444.png)
图 41
Step9: 封装好的IP的BSP以及SDK程序的编写。
首先封装的IP有自己在AXI总线上的地址,于是IP内部的所有寄存器的地址就是IP的Base地址加上各个寄存器的偏移量。于是在SDK代码中就可以通过唯一的地址访问到这些寄存器。由于内部的寄存器都是用户自己设计的,所以不需要BSP封装太多的函数,BSP也无法知道用户设计的逻辑,从而也无法自动封装API。用户直接通过底层调用Xil_Out32()和Xil_In32()完成对于封装逻辑模块IP的控制。如果需要,用户可以自行封装更上层的API函数。
使用Zynq processor仿真Customized IP
由于ZYNQ中除了常用的FPGA逻辑部分外还有ARM内核部分,所以在进行类似于FPGA设计仿真时会遇到问题,就是如果仿真ARM内核部分。Xilinx提供的一个方案是Zynq BFM(Bus Functional Model),其介绍如下。
![c9122e08ffe4f6ffc26058e13123505e.jpeg](https://i-blog.csdnimg.cn/blog_migrate/479b40f86414e14a4a9f4138f5d43a6a.jpeg)
图 42
但是该Model是需要额外购买的,该章节介绍一种无需购买Zynq BFM就可以仿真Customized IP的方法。基本思路是对于PL端的Customized IP而言,控制端是ZYNQ中的ARM内核还是普通FPGA中的MicroBlaze都是一样的,所以可以将Customized IP例化到以MicroBlaze为处理器的Block Design中,由于MicroBlaze的仿真无需额外的License,所以可以将SDK的程序导入到MicroBlaze的内核,进而仿真Customized IP。
Step1: 按照“将用户逻辑设计封装成IP”中介绍的,完成Customized IP的设计和封装;在Block Design中加入MicroBlaze和Customized IP,完成Block Design设计;完成硬件平台的综合、实现、生成Bit文件,并导入SDK;在SDK中完成软件设计。综上就是完成“将用户逻辑设计封装成IP”中的Step9,区别只是用MicroBlaze替代了ZYNQ Processing System。
![147317efb60b52d91348933af2fdc311.jpeg](https://i-blog.csdnimg.cn/blog_migrate/c6b648487fcfd7668200379dc9a4bd53.jpeg)
图 43
Step2:对SDK中设计的软件程序完成编译,工具自动生成elf文件。默认的存放地址为SDK project下Src文件夹中。例如:C:***\A7_microblaze\A7_microblaze.sdk\microblaze_customized_ip\Debug
![f344b1035d41a3401785798e77d621f6.png](https://i-blog.csdnimg.cn/blog_migrate/544c8849ebee40cc9b8d097e5fbdcc81.png)
图 44
Step3:回到Vivado开发平台,将elf文件导入至Simulation Source中。
![ddb04181e7ccd63eaf1265c6875c364d.jpeg](https://i-blog.csdnimg.cn/blog_migrate/f4bd2cb4b3e87c5d536e74bee6509147.jpeg)
图 45
Step4:将导入的elf文件链接到对应的处理器,使其作为该处理器的启动程序。注意,elf文件只允许associate至Microblaze,工具不支持链接到ZYNQ。
![d32f525ba62c152044e975d1785d0d71.jpeg](https://i-blog.csdnimg.cn/blog_migrate/9d926b2b78e7283ae989f1c7f143e715.jpeg)
图 46
Step5:正常启动仿真。
可以看到MicroBlaze核发出的AXI通信协议,如图 47所示。
![f0caf3c642121b981ff988dc0c419a14.jpeg](https://i-blog.csdnimg.cn/blog_migrate/1b971bc98367fa94fe0e21db6d2e3421.jpeg)
图 47
于是对应的IP的输出可以看到如“将用户逻辑设计封装成IP”中模式2设计的一样,输出的4路LED不断反转。
![40ef67e9b74750f3374119c345238135.png](https://i-blog.csdnimg.cn/blog_migrate/ccee4d270a603465ae96522ef45dfe48.png)
图48
想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索