介绍
使用 AMD-Xilinx FPGA设计一个全连接DNN核心现在比较容易(Vitis AI),但是利用这个核心在 DNN 计算中使用它是另一回事。本项目主要是设计AI加速器,利用Xilinx的CDMA加载权重,输入到PL区的Block Ram。
原理框图
首先,我们创建了整个系统的示意图。有两个 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 接口。
二、添加cdma和bram模块。Vivado 通过 Run Connection Automation 将 cdma 和 bram 连接到处理器。那么设计应该类似于下图。
加速器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 模块。
添加以上 4 个 Verilog 文件来生成加速器 IP。
Vivado Block设计
然后我们使用 VIVADO block digram 工具构建整个设计。我们使用具有 64 位数据宽度的双端口 bram 来最大化系统的效率。
在地址编辑器中,将 axi_bram_ctrl 范围从 8k 更改为 64k。
测试
在 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计算结果。
可以在下面看到测试结果。
正如在这个结果中看到的那样,我们加速器的使用时间(11.40+13.44+4.71 us)比在 PS 区域(104.99 us)上要少得多。
代码
https://github.com/Hyunho-Won/cdma_accelerator
原文:OpenFPGA
作者:碎碎思
相关文章推荐
更多FPGA干货请关注FPGA的逻辑技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。