首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

不同的AXI总线卷积加速模块

不同的AXI总线卷积加速模块

版本一版本一主要是用来测试AXI总线IP核的实现可能。
  • 该模块拥有19个32位寄存器
  • 其中前9个寄存器用来保存需要计算的值
  • 后面9个寄存器用来保存卷积核
  • 在读取第19个寄存器的地址的时候计算9个寄存器的卷积和(该计算可以在一个时钟周期内完成)
  • 9个寄存器单独赋值,程序中分别向对应地址写入内容,通过总线进行传输。
  • 故乐观的来算,需要10个总线周期可以获取一个输出
可以从驱动的书写简单理解一下:
void Conv_HW(int filter[3][3], int arr[100][100],        int filterW, int filterH, int arrW, int arrH) {    int i, j;    for (i = 2; i < filterH + arrH - 3; i++) {        for (j = 2; j < filterW + arrW - 3; j++) {            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR, arr[j]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+4, arr[j - 1]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+8, arr[j - 2]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+12, arr[i - 1][j]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+16, arr[i - 1][j - 1]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+20, arr[i - 1][j - 2]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+24, arr[i - 2][j]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+28, arr[i - 2][j - 1]);            Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR+32, arr[i - 2][j - 2]);            res[j] = Xil_In32(XPAR_CONV_0_S00_AXI_BASEADDR + 72);        }        if (i % 15 == 0)            printf("=");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
版本一性能
  • 版本一性能最惨,由于没有时间戳,目测软件计算速度远远快于FPGA核心运算速度。
  • 版本一的改进速度就是引入滑动窗口,能够最大程度减少总线周期。
版本二版本二引入滑动窗口,和初期设计的概念相同。

  • 该模块拥有19个32位寄存器
  • 其中前9个寄存器用来保存需要计算的值
  • 后面9个寄存器用来保存卷积核
  • 在读取第19个寄存器的地址的时候计算9个寄存器的卷积和(该计算可以在一个时钟周期内完成)
  • 三个寄存器滑动赋值,该计算窗口在计算矩阵上滑动 除了冷启动多余两个周期用来预载寄存器,后面的每一个计算只需要四个总线周期
    可以通过写的驱动简单理解一下:
    void Conv_HW(int filter[3][3], int arr[100][100], int arrW, int arrH) {int i, j;i = 2; j = 2;for (i = 2; i < arrH; i++) {    //pre load    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 8, arr[i - 1][j - 1]);    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 20, arr[j - 1]);    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 32, arr[i + 1][j - 1]);    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 8, arr[i - 1][j]);    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 20, arr[j]);    Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 32, arr[i + 1][j]);    for (j = 2; j <  arrW; j++) {        Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 8, arr[i - 1][j + 1]);        Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 20, arr[j + 1]);        Xil_Out32(XPAR_CONV_0_S00_AXI_BASEADDR + 32, arr[i + 1][j + 1]);        res[j] = Xil_In32(XPAR_CONV_0_S00_AXI_BASEADDR + 72);    }}}
版本二性能测试样本 500*500的32bit单位的矩阵 计算200次。
软件消耗33.78秒,卷积IP核心40.25秒
这样的结果还是非常不乐观,分析可能有两种限制了IP核的速度。
  • 两个寄存器的乘法LUT太大,无法硬件优化
  • 总线周期太慢太慢
版本三对于这两种可能进行探索。
返回列表