ARM技术论坛
直播中

王秀珍

7年用户 1358经验值
私信 关注
[经验]

使用AMD-Xilinx FPGA设计一个AI加速器通道

介绍

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

原理框图

2.jpg

首先,我们创建了整个系统的示意图。有两个 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。

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

2.jpg

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

2.jpg

加速器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 模块。

2.jpg

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

2.jpg

Vivado Block设计

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

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

2.jpg

测试

在 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计算结果。

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

2.jpg

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

原作者:碎碎思

更多回帖

发帖
×
20
完善资料,
赚取积分