教程:在PYNQ-Z1或PYNQ-Z2上新增硬件设计,以AXI GPIO为例

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

本教程基于《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位流文件的完整文件名。

  • 默认情况下,downloadTrue,当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',
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值