搭建YOLO加速模块上板验证工程

搭建YOLO加速模块上板验证工程

目的

- 搭建YOLO加速模块上板验证工程的目的是为了测试和验证YOLO加速模块的功能和性能,确保它能够正确地完成YOLO算法的计算,并且与ZYNQ芯片之间能够正常地通信和协作。
- 搭建YOLO加速模块上板验证工程的方法是先不加摄像头和显示器驱动模块,只在PL端实例化YOLO加速模块,然后在PS端使能SD卡外设,并将YOLO算法需要用到的参数文件和图像输入文件存储在SD卡中,然后通过PS端将这些文件读取到DDR3中,并按照命令控制流程去控制YOLO加速模块进行相关操作,最后将YOLO加速模块的输出结果返回给PS端,并与Python代码中的计算结果进行比较,从而验证YOLO加速模块的正确性和有效性。

思路

- 本工程的思路是先在PS端使能SD卡外设,并将YOLO网络需要用到的参数文件、量化文件和输入图像文件存储在SD卡中,然后通过PS端读取这些文件到DDR3中。
- 然后在PL端实例化YOLO加速模块,并通过AXI接口与PS端进行通信,包括命令控制、数据传输和中断信号。
- 最后通过PS端按照正常的流程控制YOLO加速模块进行前向计算,并将结果返回给PS端,与Python代码中的计算结果进行比较,验证正确性和精度。
  • 本工程的思路是先在Python环境中生成YOLO网络需要用到的参数文件、量化文件和输入图像文件,并保存为.bin格式,然后将这些文件存储在SD卡中。
  • 然后在Vivado中搭建一个包含ZYNQ、YOLO加速模块、DMA和AXI Lite等IP核的工程,并配置相应的时钟、电压、中断、接口等参数,生成比特流文件并烧录到开发板中。
  • 最后在PS端通过SD卡读取参数文件和输入图像文件,并按照命令控制流程通过AXI Lite接口向YOLO加速模块发送控制信号和数据,然后通过AXI Stream接口接收YOLO加速模块返回的结果,并与Python环境中的计算结果进行比较,验证工程的正确性。

步骤

1. 生成参数文件、量化文件和输入图像文件

  • 在Python环境中,根据YOLO网络的结构和量化方法,生成相应的参数文件、量化文件和输入图像文件,并保存为.bin格式。
  • 参数文件包括卷积核参数、激活函数查找表、偏置参数等,每个参数占用一个字节(8位)。
  • 量化文件包括每层网络的输入输出尺度因子等,每个因子占用四个字节(32位)。
  • 输入图像文件是将一张输入图像转换为灰度图,并按照网络输入尺寸进行裁剪或填充,然后将每个像素值保存为一个字节(8位)。
  • 将这些文件按照一定的顺序存储在SD卡中,例如:
    • 参数文件:conv1_w.bin, conv1_b.bin, conv1_lut.bin, …, conv13_w.bin, conv13_b.bin, conv13_lut.bin
    • 量化文件:scale_in.bin, scale_out.bin
    • 输入图像文件:image_in.bin

2. 搭建Vivado工程

  • 在Vivado中创建一个新工程,并添加相应的IP核,包括ZYNQ、YOLO加速模块、DMA和AXI Lite等。

  • 配置ZYNQ的PS端,使能SD卡外设,并设置相应的IO口、电压、时钟等参数。

    PS端使能SD卡外设

    • SD卡是一种存储设备,可以存储YOLO网络中需要用到的卷积参数、激活查找表、偏置参数、量化参数等文件,以及图像的输入数据文件。这些文件都是由Python代码生成的,并保存为.bin格式。
    • PS端需要使能SD卡外设,以便从SD卡中读取这些文件,并将它们存储到DDR3内存中。
    • 为了使能SD卡外设,需要在Vivado中对ZYNQ IP进行配置,勾选SD0外设,并设置对应的MIO引脚和电压。具体如下:
    外设 MIO引脚 电压
    SD0 40-45 1.8V
    SD CD 10 3.3V

    PS端与加速模块之间的连接

    • PS端与加速模块之间需要通过一些接口进行连接,以实现数据和命令的传输和控制。这些接口包括:

      Axi Lite接口

      • Axi Lite接口需要连接到ZYNQ IP的GP Master接口上,并设置对应的地址映射。

      Axi Stream接口

      • Axi Stream接口需要连接到ZYNQ IP的HP Slave接口上,并通过DMA(直接内存访问)控制器进行数据的读写操作。
      • DMA控制器需要配置相应的参数,如数据宽度、地址宽度、突发长度、FIFO深度等。
  • 配置ZYNQ的PL端,将YOLO加速模块与PS端通过AXI Lite接口和AXI Stream接口连接起来,并设置相应的时钟、复位等信号。

    时钟和复位信号

    • 时钟和复位信号是用来同步和初始化PS端和加速模块之间的通信和计算的。
    • 时钟信号可以由ZYNQ IP提供,也可以通过时钟向导IP生成,本项目中使用了200MHz的时钟信号。
    • 复位信号可以由ZYNQ IP提供,也可以通过处理器系统复位IP生成,本项目中使用了ZYNQ IP提供的复位信号。

    中断信号

    • 中断信号是用来通知PS端加速模块的工作状态,如是否完成计算任务等。

    • 中断信号需要连接到ZYNQ IP的中断控制器上,并设置对应的中断ID。

      外设 MIO引脚
      中断 IRQ_F2P[0]
  • 配置DMA模块,将其与YOLO加速模块和ZYNQ的HP接口连接起来,并设置相应的数据宽度、地址宽度、突发长度等参数。

    DMA IP

    • 实现AXI stream接口和AXI memory接口之间的数据传输,支持突发模式

    • 读写数据宽度:64位

      地址宽度:32位

      FIFO深度:4096

      突发长度:14位

  • 验证工程的连接和参数是否正确,生成输出产品,包括比特流文件和硬件描述文件。

3. 烧录比特流文件并运行PS端程序

  • 将比特流文件烧录到开发板中,并将SD卡插入到开发板的SD卡槽中。
  • 在PS端运行一个控制程序,该程序可以通过串口或其他方式与用户交互,接收用户的命令,并执行相应的操作。
  • 操作包括从SD卡中读取参数文件和输入图像文件,并将其存储在DDR3中;通过AXI Lite接口向YOLO加速模块发送控制信号和数据地址;通过AXI Stream接口从YOLO加速模块接收结果数据;通过中断信号判断YOLO加速模块是否完成计算;将结果数据与Python环境中的计算结果进行比较,并输出比较结果。

按照命令控制流程执行YOLO计算

  • 命令控制流程是指PS端通过Axi Lite接口向加速模块发送一系列的命令,控制加速模块进行YOLO网络的前向计算,并通过Axi Stream接口和DMA控制器进行数据的读写操作,最后通过中断信号接收加速模块的计算结果,并与Python代码中的计算结果进行比较,验证加速模块的正确性和有效性。
  • 命令控制流程具体如下:
步骤 命令 说明
1 写入卷积参数地址 PS端向加速模块写入卷积参数在DDR3内存中的起始地址
2 写入激活查找表地址 PS端向加速模块写入激活查找表在DDR3内存中的起始地址
3 写入偏置参数地址 PS端向加速模块写入偏置参数在DDR3内存中的起始地址
4 写入量化参数地址 PS端向加速模块写入量化参数在DDR3内存中的起始地址
5 写入图像输入地址 PS端向加速模块写入图像输入在DDR3内存中的起始地址
6 写入计算结果地址 PS端向加速模块写入计算结果在DDR3内存中的起始地址
7 写入启动命令 PS端向加速模块写入启动命令,使能加速模块开始计算
8 等待中断信号 PS端等待加速模块发送中断信号,表示计算完成
9 读取计算结果 PS端通过DMA控制器从DDR3内存中读取计算结果,并存储到本地文件中
10 比较计算结果 PS端使用Python代码读取本地文件中的计算结果,并与Python代码中的计算结果进行比较,验证加速模块的正确性和有效性

举例

  • 假设用户输入了一个命令,要求PS端运行YOLO网络的第一层卷积,并将结果与Python环境中的结果进行比较,那么PS端程序可能会执行以下操作:
    • 从SD卡中读取conv1_w.bin, conv1_b.bin, conv1_lut.bin, scale_in.bin, scale_out.bin, image_in.bin这六个文件,并将其存储在DDR3的不同地址中,例如:
      • conv1_w.bin -> 0x10000000
      • conv1_b.bin -> 0x10010000
      • conv1_lut.bin -> 0x10020000
      • scale_in.bin -> 0x10030000
      • scale_out.bin -> 0x10030004
      • image_in.bin -> 0x20000000
    • 通过AXI Lite接口向YOLO加速模块发送控制信号和数据地址,例如:
      • 写入0x00000001到0x43C00000,表示启动YOLO加速模块
      • 写入0x00000001到0x43C00004,表示选择第一层卷积
      • 写入0x10000000到0x43C00008,表示卷积核参数的地址
      • 写入0x10010000到0x43C0000C,表示偏置参数的地址
      • 写入0x10020000到0x43C00010,表示激活函数查找表的地址
      • 写入0x10030000到0x43C00014,表示输入尺度因子的地址
      • 写入0x10030004到0x43C00018,表示输出尺度因子的地址
      • 写入0x20000000到0x43C0001C,表示输入图像数据的地址
    • 通过AXI Stream接口从YOLO加速模块接收结果数据,并将其存储在DDR3的另一个地址中,例如:
      • 读取数据流从0x43C00100,并将其存储在0x30000000
    • 通过中断信号判断YOLO加速模块是否完成计算,例如:
      • 等待中断信号从0x43C00104为1,表示计算完成
    • 将结果数据与Python环境中的计算结果进行比较,并输出比较结果,例如:
      • 读取Python环境中的计算结果文件conv1_out.bin,并与DDR3中的结果数据进行逐字节比较
      • 如果比较结果相同,则输出“第一层卷积计算正确”
      • 如果比较结果不同,则输出“第一层卷积计算错误”,并给出不同的字节位置和值
graph TD A[启动Vivado并创建工程] B[添加ZYNQ IP核并配置PS端] C[添加YOLO加速模块IP核并配置PL端] D[添加DMA和FIFO IP核并连接数据通路] E[生成比特流文件并导出硬件] F[启动SDK并创建应用程序工程] G[编写控制代码并生成可执行文件] H[使用Python生成参数文件和图像输入文件] I[将参数文件和图像输入文件存储到SD卡中] J[将SD卡插入开发板并下载可执行文件] K[运行可执行文件并观察输出结果] L[与Python代码中的结果进行比较并分析性能] A --> B B --> C C --> D D --> E E --> F F --> G G --> H H --> I I --> J J --> K K --> L
posted @ 2023-07-19 21:31  李白的白  阅读(179)  评论(0编辑  收藏  举报