碎碎思 · 2023年02月06日

使用 AXI CDMA 制作 FPGA AI 加速器通道

image.png

介绍

使用 AMD-Xilinx FPGA设计一个全连接DNN核心现在比较容易(Vitis AI),但是利用这个核心在 DNN 计算中使用它是另一回事。本项目主要是设计AI加速器,利用Xilinx的CDMA加载权重,输入到PL区的Block Ram。

原理框图

image.png

首先,我们创建了整个系统的示意图。有两个 Block RAW 分别用于存储输入特征和权重数据。每个Block RAM 都连接到一个 CDMA ,允许 DRAM 访问 Bram。每个 Block RAM 还连接到由 8 个 FCN 内核和 FSM 组成的主加速器,控制内核的操作。

完整的激活顺序如下:

  • 在 DDR 内存中存储特征和权重。
  • 使用CDMA 将这些数据分别发送到block ram1 和block ram2。
  • 向 FC core 发送 activate 信号,进行 FCN 计算。
  • 将结果存储在 blcok ram 中。
  • 重复此过程,直到完成第一层前向传播。
  • 重复整个过程,将输入链接到存储在Block RAM 中的结果。

码分多址

为了直接访问内存,我们使用了 cdma。可以在XIinx 网站上参考 xilinx turoial(https://www.xilinx.com/support/university/vivado/vivado-workshops/Vivado-adv-embedded-design-zynq.html)。

首先,配置处理器启用 S_AXI_HP0 接口。

image.png

二、添加cdma和bram模块。Vivado 通过 Run Connection Automation 将 cdma 和 bram 连接到处理器。那么设计应该类似于下图。

image.png

加速器IP

加速器 IP 由 4 个源文件组成。

  • 加速器:连接 AXI4-lite 模块和 bram_to_fc 模块。
  • AXI4-lite :它执行 AXI4-lite 接口将结果值从 PL 传输到 PS。并将 fsm 信号传输到 bram_to_fc 模块。
  • bram_to_fc :它从 bram0、bram1 接收特征图和权重,并将它们发送到 sumproduct_core。
  • sumproduct_core :它使用 8 位输入执行 sumproduct 计算。并返回 32 位输出。

创建 AXI4 外设来制作 AXI4-lite 模板。接口类型是lite版,制作 10 个寄存器。然后修改模板来制作 AXI4-lite 模块。

image.png

添加以上 4 个 Verilog 文件来生成加速器 IP。

image.png

Vivado Block设计

然后我们使用 VIVADO block digram 工具构建整个设计。我们使用具有 64 位数据宽度的双端口 bram 来最大化系统的效率。

在地址编辑器中,将 axi_bram_ctrl 范围从 8k 更改为 64k。

image.png

测试

在 FPGA 板卡上测试了我们的加速器,将硬件导出到 VITIS,为了测试我们的加速器性能,我们比较了软件和硬件之间的相同任务运行时间。

  • HW运行时间:数据发送时间+HW计算时间+数据接收时间
  • SW runtime : SW计算时间

1. 使用 CDMA 将特征图和权重从 DDR3 传输到 BRAM。

//transfer feauture map from DDR3 to Bram0
XAxiCdma_IntrEnable(&xcdma, XAXICDMA_XR_IRQ_ALL_MASK);
Status = XAxiCdma_SimpleTransfer(&xcdma, (u32)source_0, (u32) cdma_memory_destination_0, numofbytes, Example_CallBack, (void *) &xcdma);

//transfer weight from DDR3 to Bram1
XAxiCdma_IntrEnable(&xcdma, XAXICDMA_XR_IRQ_ALL_MASK);
Status = XAxiCdma_SimpleTransfer(&xcdma, (u32)source_1, (u32) cdma_memory_destination_1, numofbytes, Example_CallBack, (void *) &xcdma);

2. 发送 FSM 运行信号和要传输的输入数量。

`Xil_Out32((XPAR_ACCELERATOR_0_BASEADDR) + (CTRL_REG*4), (u32)(numofbytes | 0x80000000));  
`

3. 检查硬件计算结果。

OT_RSLT_HW[0] = Xil_In64((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_0_REG*AXI_DATA_BYTE));
OT_RSLT_HW[1] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_1_REG*AXI_DATA_BYTE));
OT_RSLT_HW[2] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_2_REG*AXI_DATA_BYTE));
OT_RSLT_HW[3] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_3_REG*AXI_DATA_BYTE));
OT_RSLT_HW[4] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_4_REG*AXI_DATA_BYTE));
OT_RSLT_HW[5] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_5_REG*AXI_DATA_BYTE));
OT_RSLT_HW[6] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_6_REG*AXI_DATA_BYTE));
OT_RSLT_HW[7] = Xil_In32((XPAR_ACCELERATOR_0_BASEADDR) + (RESULT_7_REG*AXI_DATA_BYTE));

for (ii=0; ii<8; ii++){
       printf("%d \n", OT_RSLT_HW[ii]);
          }

4. 检查SW计算结果。

可以在下面看到测试结果。

image.png

正如在这个结果中看到的那样,我们加速器的使用时间(11.40+13.44+4.71 us)比在 PS 区域(104.99 us)上要少得多。

代码

https://github.com/Hyunho-Won/cdma_accelerator
原文:OpenFPGA
作者:碎碎思

相关文章推荐

更多FPGA干货请关注FPGA的逻辑技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
10614
内容数
577
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息