ZYNQ AXI GPIO中断实验——FPGA Vitis篇

本文转载自: FpgaHome微信公众号

1. 前言

使用ZYNQ最大的疑问就是如何把PS和PL结合起来使用。本实验使用两个AXI GPIO的IP核,一个GPIO IP核连接4个LED灯;另一个GPIO IP核用于接收4个按键(拨码开关)的中断,通过该中断来控制相应LED灯的亮灭。

2. Vivado工程的编写

2.1 Block Design工程设计

(1)本实验使用的Vivado工程延用《ZYNQ 串口打印输出——FPGA Vitis篇》中使用的Vivado工程,大家可以查看该文章来了解Vivado工程的建立。

(2)修改Vivado工程,增加一个AXI GPIO IP核。该IP核用于控制4个LED灯的亮灭,因此“GPIO Width”参数设置为“4”;勾选“ALL Outputs”选项。

(3)点击“Run Connection Automation”选项,完成部分自动连线。

(4)可以看到多了两个模块,一个是“Processor System Reset”模块,为同步复位模块,提供同一时钟域的复位信号。“AXI Interconnect”模块为AXI总线互联模块,用于AXI模块的交叉互联。

在这个应用中,我们可以看到用到了ZYNQ的GP口,M_AXI_GP0,M代表的是 master,此接口用于访问PL端数据。

复位信号由ZYNQ的复位输出提供,在较大规模的电路设计中,最好是每个时钟域电路都加一个复位模块。

(5)修改GPIO端口的名称为“gpio_led”。

(6)再添加一个AXI GPIO,连接PL端按钮。配置GPIO参数,将其设置为“All Inputs”,宽度为4,使能中断。点击“Run Connection Automation”选项,完成部分自动连线。

(7)修改GPIO端口的名称为“gpio_keys”。

(8)由于是PL端过来的中断,根据共享外设中断(SPI)表

在这里需要配置ZYNQ处理器的中断,勾选IRQ_F2P。

(9)连接ip2intc_irpt到IRQ_F2P

(10)保存设计,右键点击.bd文件,选择“Generate Output Products…”。

(11)右键点击.bd文件,选择“Create HDL Wrapper…”。弹出的窗口中选择“Let Vivado manage wrapper and auto-update”,点击“OK”。

(12)在生成的Verilog文件中,可以看到有个“gpio_led_tri_o”和“gpio_keys_tri_i”的端口,要为他们分配管脚,在绑定引脚时,以这个文件里的引脚名称为准。

2.2 创建XDC管脚约束

(1)创建一个新的XDC约束文件,XDC文件名可以自己随便取。

(2)此处创建了一个名为“TOP”的XDC约束文件,双击打开该文件,添加管脚约束。

添加的约束如下:

# ------------ LEDPins ------------

set_property PACKAGE_PIN T22 [get_ports{gpio_led_tri_o[0]}]

set_property PACKAGE_PIN T21 [get_ports{gpio_led_tri_o[1]}]

set_property PACKAGE_PIN U22 [get_ports{gpio_led_tri_o[2]}]

set_property PACKAGE_PIN U21 [get_ports{gpio_led_tri_o[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_led_tri_o[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_led_tri_o[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_led_tri_o[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_led_tri_o[3]}]

# ------------ BtnPins ------------

set_property PACKAGE_PIN F22 [get_ports{gpio_keys_tri_i[0]}]

set_property PACKAGE_PIN G22 [get_ports{gpio_keys_tri_i[1]}]

set_propertyPACKAGE_PIN H22 [get_ports{gpio_keys_tri_i[2]}]

set_property PACKAGE_PIN F21 [get_ports{gpio_keys_tri_i[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_keys_tri_i[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_keys_tri_i[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_keys_tri_i[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports{gpio_keys_tri_i[3]}]

(3)点击Vivado “Flow Navigator”一栏里的“Generate Bitstream”,等待Vivado生成好bit文件后,在菜单栏“File -> Export -> ExportHardware...”导出硬件信息(.xsa文件),这里就包含了PS端的配置信息。该步骤如有疑问,可以参考以前的文章《ZYNQ串口打印输出——FPGA Vitis篇》。

3. Vitis工程的编写

(1)点击 Vivado 菜单“Tools-> Launch Vitis IDE”,启动 Vitis。

(2)新建 Vitis平台工程。Vitis工程的建立可以参考以前的文章《ZYNQ串口打印输出——FPGA Vitis篇》。

(3)新建 Vitis应用工程,创建一个名为“AXI_GPIO_INTR”的工程,工程模板可以选择“Hello World”。

(4)面对一个不熟悉的GPIO模块,我们可以尝试一下Vitis自带的官方工程。

(5)双击打开“platform.spr”,点击“axi_gpio_1”的“Import Examples”。

选择“xgpio_intr_tapp_example”例程。

(6)由于我们按键中断是接在axi_gpio_1上,我们需要修改该例程的宏定义,将GPIO_0改为GPIO_1。

(7)例程的GPIO中断代码说明如下:

(8)修改例程的GPIO中断服务函数“GpioHandler”,使其完成4个拨码开关分别控制4个LED灯的亮灭功能:

其中“XPAR_GPIO_1_BASEADDR”为拨码开关GPIO IP核的地址、“XPAR_GPIO_0_BASEADDR”为LED GPIO IP核的地址。

“Xil_In32”为从该地址读取寄存器的值,“Xil_Out32”为向该地址对应的寄存器写入相应的值。

(9)编译工程,将工程下载到硬件板卡上(编译和下载方式见《ZYNQ 串口打印输出——FPGA Vitis篇》)。

实验结果为:4个拨码开关通过中断分别控制4个LED灯的亮灭功能;

4. 实验小结

本实验介绍了如何通过PL端的GPIO给PS端发送中断,再通过该中断控制LED灯的亮灭。

虽然该实验很简单,但有着其重要的意义。比如PL端可以给PS发送中断信号,这提高了PL和PS数据交互的效率,在需要大数量、低延时的应用中需要用到该中断处理。

A. 工程源码下载

该工程对应的源码可以在公众号输入ZYNQ_AXI_GPIO来获取工程的下载链接,工程采用的是Vivado2021.1版本。

---------------------------------------------

参考文献:

[1] http://www.alinx.com.cn/.

[2] Zynq-7000 SoC Technical Reference Manual(UG585). Xilinx官方文档

[3] ZYNQ 串口打印输出——FPGA Vitis篇. FpgaHome

最新文章

最新文章