本教程基于《Tutorial: Using a new hardware design with PYNQ (AXI GPIO)》编写。本教程有些地方与原文有出入,比如原文使用的板子是PYNQ-Z2,本文写的是PYNQ-Z1或者PYNQ-Z2,这是因为我使用PYNQ-Z1也完成了本实验。其他不一致的地方同理。
本教程将向您展示如何将上一篇教程中创建的Vivado硬件设计用于PYNQ。本教程是前一篇教程的后续,前一篇教程介绍了如何为PYNQ创建一个新的硬件设计。
环境说明
- 开发板:PYNQ-Z1或者PYNQ-Z2
- v2.4 PYNQ 镜像
- vivado 2018.2或者vivado2019.1
原文链接:https://discuss.pynq.io/t/tutorial-using-a-new-hardware-design-with-pynq-axi-gpio/146
相关资源:
- ipynb源文件:https://discuss.pynq.io/uploads/short-url/g8O85AMwDcYgspPkqDpG1cH4xWm.ipynb
- 硬件设计文件:https://discuss.pynq.io/uploads/short-url/gjwp4jNJzWGot5lJkeaT2mn8YGW.zip
1 使用pynq Overaly类将Overlay实例化。
Overlay类的原型为:Overlay(bitfile_name, download=True, ignore_version=False)
bitfile_name是FPGA位流文件的完整文件名。
- 默认情况下,
download为True,当Overlay被实例化时,位流将被下载到PL。 - 也可以将
download设置为False,以便在不下载比特流的情况下实例化Overlay。
Overlay类将自动为已知的IP分配一个驱动(如果可用)。每个PYNQ image都是用Vivado的一个版本来验证的。每个Vivado版本在IP目录中可能有不同版本的IP。PYNQ假定Vivado设计与经PYNQ image验证的Vivado版本相匹配。其他版本的Vivado可用于创建设计,但它们不被支持,也不保证它们能够工作。
设计中的任何IP的版本应该与为之编写的驱动程序的版本相同。Overlay类可以在分配驱动程序之前检查IP版本,也可以跳过版本检查。ignore_version可以被设置为True,以强制Overlay类在分配驱动前检查IP版本。
在没有PYNQ驱动的情况下,Overlay类会给一个IP分配一个默认的驱动(DefaultIP),为该IP的地址空间提供基本的MMIO(Memory mapping I/O,内存映射I/O)读写功能。这对于不需要完整的PYNQ驱动的简单IP来说很有用,或者对于新IP的原型设计来说也很有用。
!pwd
/home/xilinx/jupyter_notebooks/workspace
1.1 实例化Overlay
实例化前面教程中创建的设计。只指定了比特流,但Overlay类也会读取相应的.hwh或.tcl文件。如果这两个文件都没有提供,Overlay类将出现错误。
from pynq import Overlay
tutorial = Overlay("../../hardware/pynq_tutorial_new_hardware_files_v2_4/pynq_tutorial_new_hardware.bit")
2 Check list of IP in the design
在使用设计之前,你需要知道有哪些IP可用。你可以根据你创建的Vivado设计来确定这一点。你需要记住确切的IP名称和层次结构。对于一个简单的设计,这是直接的,但对于一个较大的设计,这就变得比较复杂了。
可以通过查询覆盖层来确定可用的IP。
tutorial?
请注意,在Vivado中使用AXI GPIO IP的按钮、开关和LED已经被分配到pynq.lib.axigpio.AxiGPIO驱动。
BRAM被分配到pynq.Overlay.DefaultIP驱动。这是因为DefaultIP提供了对IP的MMIO访问。在BRAM这个内存的情况下,只需要MMIO来读写内存位置。
Overlay的IP信息也可以从 "ip_dict "中读取。这将打印出设计中的IP的完整列表,以及各种属性。这些信息来自于与Overlay一起提供的Hardware Hand-off文件(.hwh)。
tutorial.ip_dict
{'buttons': {'fullpath': 'buttons',
'type': 'xilinx.com:ip:axi_gpio:2.0',
'bdtype': None,
'state': None,
'addr_range': 65536,
'phys_addr': 1092616192,
'mem_id': 'S_AXI',
'memtype': 'REGISTER',
'gpio': {},
'interrupts': {},
'parameters': {'C_FAMILY': 'zynq',
'C_S_AXI_ADDR_WIDTH': '9',
'C_S_AXI_DATA_WIDTH': '32',
'C_GPIO_WIDTH': '4',
'C_GPIO2_WIDTH': '32',
'C_ALL_INPUTS': '1',
'C_ALL_INPUTS_2': '0',
'C_ALL_OUTPUTS': '0',
'C_ALL_OUTPUTS_2': '0',
'C_INTERRUPT_PRESENT': '0',
'C_DOUT_DEFAULT': '0x00000000',
'C_TRI_DEFAULT': '0xFFFFFFFF',
'C_IS_DUAL': '0',
'C_DOUT_DEFAULT_2': '0x00000000',
'C_TRI_DEFAULT_2': '0xFFFFFFFF',
'Component_Name': 'pynq_tutorial_axi_gpio_0_0',
'USE_BOARD_FLOW': 'true',
'GPIO_BOARD_INTERFACE': 'btns_4bits',
'GPIO2_BOARD_INTERFACE': 'Custom',
'EDK_IPTYPE': 'PERIPHERAL',
'C_BASEADDR': '0x41200000',
'C_HIGHADDR': '0x4120FFFF'},
'registers': {'GPIO_DATA': {'address_offset': 0,
'size': 4,
'access': 'read-write',
'description': 'Channel-1 AXI GPIO Data register',
'fields': {'Channel-1 GPIO DATA': {'bit_offset': 0,
'bit_width': 4,
'description': 'Channel-1 AXI GPIO Data register',
'access': 'read-write'}}},
'GPIO_TRI': {'address_offset': 4,
'size': 4,
'access': 'read-write',
'description': 'Channel-1 AXI GPIO 3-State Control register',
'fields': {'Channel-1 GPIO TRI': {'bit_offset': 0,
'bit_width': 4,
'description': 'Channel-1 AXI GPIO 3-State Control register',
'access': 'read-write'}}},
'GPIO2_DATA': {'address_offset': 8,
'size': 32,
'access': 'read-write',
'description': 'Channel-2 AXI GPIO Data register',
'fields': {'Channel-2 GPIO DATA': {'bit_offset': 0,
'bit_width': 32,
'description': 'Channel-2 AXI GPIO Data register',
'access': 'read-write'}}},
'GPIO2_TRI': {'address_offset': 12,
'size': 32,
'access': 'read-write',
'description': 'Channel-2 AXI GPIO 3-State Control register',
'fields': {'Channel-2 GPIO TRI': {'bit_offset': 0,
'bit_width': 32,
'description': 'Channel-2 AXI GPIO 3-State Control register',
'access': 'read-write'}}},
'GIER': {'address_offset': 284,
'size': 32,
'access': 'read-write',
'description': 'Global Interrupt Enable register',
'fields': {'Global Interrupt Enable': {'bit_offset': 31,
'bit_width': 1,
'description': 'Global Interrupt Enable register',
'access': 'read-write'}}},
'IP_IER': {'address_offset': 296,
'size': 32,
'access': 'read-write',
'description': 'IP Interrupt Enable register',
'fields': {'Channel-1 Interrupt Enable': {'bit_offset': 0,
'bit_width': 1,
'description': 'IP Interrupt Enable register',
'access': 'read-write'},
'Channel-2 Interrupt Enable': {'bit_offset': 1,
'bit_width': 1,
'description': 'IP Interrupt Enable register',
'access': 'read-write'}}},
'IP_ISR': {'address_offset': 288,
'size': 32,
'access': 'read-write',
'description': 'IP Interrupt Status register',
'fields': {'Channel-1 Interrupt Status': {'bit_offset': 0,
'bit_width': 1,
'description': 'IP Interrupt Status register',
'access': 'read-write'},
'Channel-2 Interrupt Status': {'bit_offset': 1,
'bit_width': 1,
'description': 'IP Interrupt Status register',
'access': 'read-write'}}}},
'device': <pynq.pl_server.embedded_device.EmbeddedDevice at 0xaf59c7d8>,
'driver': pynq.lib.axigpio.AxiGPIO},
'switches': {'fullpath': 'switches',
'type': 'xilinx.com:ip:axi_gpio:2.0',
'bdtype': None,
'state': None,
'addr_range': 65536,
'phys_addr': 1092681728,
'mem_id': 'S_AXI',
'memtype': 'REGISTER',
'gpio': {},
'interrupts': {},
'parameters': {'C_FAMILY': 'zynq',
'C_S_AXI_ADDR_WIDTH': '9',
'C_S_AXI_DATA_WIDTH': '32',
'C_GPIO_WIDTH': '2',
'C_GPIO2_WIDTH': '32',
'C_ALL_INPUTS': '1',
'C_ALL_INPUTS_2': '0',
'C_ALL_OUTPUTS': '0',
'C_ALL_OUTPUTS_2': '0',
'C_INTERRUPT_PRESENT': '0',
'C_DOUT_DEFAULT': '0x00000000',
'C_TRI_DEFAULT': '0xFFFFFFFF',
'C_IS_DUAL': '0',
'C_DOUT_DEFAULT_2': '0x00000000',
'C_TRI_DEFAULT_2': '0xFFFFFFFF',
'Component_Name': 'pynq_tutorial_axi_gpio_0_1',
'USE_BOARD_FLOW': 'true',
'GPIO_BOARD_INTERFACE': 'sws_2bits',
'GPIO2_BOARD_INTERFACE': 'Custom',
'EDK_IPTYPE': 'PERIPHERAL',
'C_BASEADDR': '0x41210000',
'C_HIGHADDR': '0x4121FFFF'},
'registers': {'GPIO_DATA': {'address_offset': 0,
'size': 2,
'access': 'read-write',
'description': 'Channel-1 AXI GPIO Data register',
'fields': {'Channel-1 GPIO DATA': {'bit_offset': 0,
'bit_width': 2,
'description': 'Channel-1 AXI GPIO Data register',
'access': 'read-write'}}},
'GPIO_TRI': {'address_offset': 4,
'size': 2,
'access': 'read-write',
'description': 'Channel-1 AXI GPIO 3-State Control register',
'fields': {'Channel-1 GPIO TRI': {'bit_offset': 0,
'bit_width': 2,
'description': 'Channel-1 AXI GPIO 3-State Control register',
'access': 'read-write'}}},
'GPIO2_DATA': {'address_offset': 8,
'size': 32,
'access': 'read-write',
'description': 'Channel-2 AXI GPIO Data register',
'fields': {'Channel-2 GPIO DATA': {'bit_offset': 0,
'bit_width': 32,
'description': 'Channel-2 AXI GPIO Data register',
'access': 'read-write'}}},
'GPIO2_TRI': {'address_offset': 12,
'size': 32,
'access': 'read-write',
'description': 'Channel-2 AXI GPIO 3-State Control register',
'fields': {'Channel-2 GPIO TRI': {'bit_offset': 0,
'bit_width': 32,
'description': 'Channel-2 AXI GPIO 3-State Control register',
'access': 'read-write'}}},
'GIER': {'address_offset': 284,
'size': 32,
'access': 'read-write',
'description': 'Global Interrupt Enable register',
'fields': {'Global Interrupt Enable': {'bit_offset': 31,
'bit_width': 1,
'description': 'Global Interrupt Enable register',
'access': 'read-write'}}},
'IP_IER': {'address_offset': 296,
'size': 32,
'access': 'read-write',
'description': 'IP Interrupt Enable register',
'fields': {'Channel-1 Interrupt Enable': {'bit_offset': 0,
'bit_width': 1,
'description': 'IP Interrupt Enable register',
'access': 'read-write'},
'Channel-2 Interrupt Enable': {'bit_offset': 1,
'bit_width': 1,
'description': 'IP Interrupt Enable register',
'access': 'read-write'}}},
'IP_ISR': {'address_offset': 288,
'size': 32,
'access': 'read-write',
'description': 'IP Interrupt Status register',
'fields': {'Channel-1 Interrupt Status': {'bit_offset': 0,
'bit_width': 1,
'description': 'IP Interrupt Status register',
'access': 'read-write'},
'Channel-2 Interrupt Status': {'bit_offset': 1,
'bit_width': 1,
'description': 'IP Interrupt Status register',
'access': 'read-write'}}}},
'device': <pynq.pl_server.embedded_device.EmbeddedDevice at 0xaf59c7d8>,
'driver': pynq.lib.axigpio.AxiGPIO},
'leds': {'fullpath': 'leds',
'type': 'xilinx.com:ip:axi_gpio:2.0',
'bdtype': None,
'state': None,
'addr_range': 65536,
'phys_addr': 1092747264,
'mem_id': 'S_AXI',
'memtype': 'REGISTER',
'gpio': {},
'interrupts': {},
'parameters': {'C_FAMILY': 'zynq',
'C_S_AXI_ADDR_WIDTH': '9',
'C_S_AXI_DATA_WIDTH': '32',
'C_GPIO_WIDTH': '4',
'C_GPIO2_WIDTH': '32',
'C_ALL_INPUTS': '0',
'C_ALL_INPUTS_2': '0',
'C_ALL_OUTPUTS': '0',
'C_ALL_OUTPUTS_2': '0',
'C_INTERRUPT_PRESENT': '0',
'C_DOUT_DEFAULT': '0x00000000',
'C_TRI_DEFAULT': '0xFFFFFFFF',
'C_IS_DUAL': '0',
'C_DOUT_DEFAULT_2': '0x00000000',
'C_TRI_DEFAULT_2': '0xFFFFFFFF',

本教程指导用户如何将自定义的Vivado硬件设计应用于PYNQ平台,重点介绍了PYNQ-Z1或PYNQ-Z2板上使用AXIGPIOIP核的实例化过程。通过加载比特流文件至FPGA,解析硬件设计中的IP,配置Overlay,演示了基本的输入输出操作,如读取按钮状态与控制LED,展示了PYNQ在硬件加速与原型设计中的灵活性。
最低0.47元/天 解锁文章
7570

被折叠的 条评论
为什么被折叠?



