ubuntu系统&XDMA&HLS-一个简单的gemm小示例

使用pcie做加速是现在比较火的关于FPGA方向的一个业务,今天用一个简单的示例介绍一下开发的流程及整个加速流程:

硬件:xilinx的k7325t

软件:HLS 2018.3  vivado 2020.2  ubuntu 18.04

FPGA的代码贴在最后面~~~~

1.功能介绍

--两个4x4矩阵相乘,得到一个4x4矩阵结果

因为现在人工智能的关系,卷积运算转矩阵运算可以对整个深度学习的流程进行加速,所以现在的深度学习业务,关于ima2col,gemm,脉动阵列矩阵等等都是需要做深度学习掌握的技术。

2.HLS

本文由于是一个简单的示例,我们在chatGPT找一个:),简单的矩阵乘法运算。然后生成IP核心(当然还需要自己修改一点点内容),代码如下:

gemm_ip.c

#include <stdio.h>
#include <ap_cint.h>

#define M 4 // 矩阵A的行数
#define N 4 // 矩阵B的列数和矩阵C的行数
#define P 4 // 矩阵B的行数和矩阵C的列数

// 使用HLS标注来指导硬件逻辑
void gemm_ip(int A[M][N], int B[N][P], int C[M][P]) {
#pragma HLS INTERFACE s_axilite port=A bundle=control
#pragma HLS INTERFACE s_axilite port=B bundle=control
#pragma HLS INTERFACE s_axilite port=C bundle=control
#pragma HLS INTERFACE s_axilite port=return bundle=control

    // 循环展开和流水线优化
#pragma HLS PIPELINE
    int i, j, k;
    static int result[M][P];
    // 初始化结果矩阵
    for (i = 0; i < M; i++) {
        for (j = 0; j < P; j++) {
            result[i][j] = 0;
        }
    }
    // 执行矩阵乘法
    for (i = 0; i < M; i++) {
        for (j = 0; j < P; j++) {
            for (k = 0; k < N; k++) {
                result[i][j] += A[i][k] * B[k][j];
            }
            C[i][j] = result[i][j];
        }
    }
}

此代码实现的功能为:两个4x4矩阵相乘,得到一个4x4矩阵的结果。

其中输入及输出都使用axi_lite接口。(因为我们用的xdma,封装的接口就是axi相关的,ip核和XDMA交互更方便)。

tb_gemm_ip.c----测试代码

#include <stdio.h>
#include <ap_cint.h>


#define M 4 // 矩阵A的行数
#define N 4 // 矩阵B的列数和矩阵C的行数
#define P 4 // 矩阵B的行数和矩阵C的列数

// 主函数用于测试
int main() {
    int A[M][N] = {
//            {1, 2 ,3},
//            {5, 6, 7}
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };
    int B[N][P] = {
//    		{17, 18},
//			{21, 22},
//			{24, 26}
        {17, 18, 19, 20},
        {21, 22, 23, 24},
        {25, 26, 27, 28},
        {29, 30, 31, 32}
    };
    int C[M][P];

    gemm_ip(A, B, C);

    printf("Result matrix C:\n");
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < P; j++) {
            printf("%d ", C[i][j]);
        }
        printf("\n");
    }

    return 0;
}

下一步我们需要对c代码进行综合:

我们能得到一个综合报告:

从报告中,我们可以到ip核的相关信息:

运算的花费时间及延迟:

消耗的FPGA资源:

以及使用此IP核的相关信号接口:

我们在生成一个IP核的时候,可能不知道怎么去使用,我们可以使用HLS的C/RTL 联合仿真,这里我用的是modelsim,也可以用vivado自带的仿真工具,看下波形图:

看到这个,表示联合仿真完成。

然后我们去找到波形图文件,右键open,然后打开:

找到DUT,然后查看IP核对应的输入输出接口的波形:

首先我们看下aw和w通道:

我们有两个输入矩阵,从波形图可以看出:

1.每个矩阵一共16个数据需要打入。

2.A矩阵的地址从40开始。

3.B矩阵的地址从80开始。

4.相邻两个数据之间隔了4,因为我们数据是32位(4个字节)。

5.最后需要往地址0传入1,作为启动信号。

然后我们看下ar和r通道:

1.这里写入完数据之后,等待一段时间。

2.上面写入最后一个数据的地址是bc,所以这里从c0开始读。

3.中间穿插地址0的读取。

4.这里读出来的数据需要和实际运算数据进行对比。

进行数据比对之后,如果正确,那证明这个HLS是成功的。

接着我们生成IP核:

生成之后 ,我们找到这个IP核:

解压出来,然后我们在工程里面进行导入:

添加之后,我们就可以在BD或者IP Catalog里面找到这个IP核:

我们HLS的部分就完成了~

3.FPGA部分

a.XDMA IP核生成

我们先例化一个XDMA IP核:

lane选一根就行了,因为是一个小测试,实际开发根据需求来配置。

这里我们使用AXI_MEmoryMapped,其实用AXI_Stream也可以会更简单一些。不过作者为了练习,所以用的mm。

后面几页的配置就是最基础的了,因为这个例子用不到。通道(H2C C2H)也只用了一对。

这里面最重要的IP核就是XDMA,其他的就是两个FIFO,一个用来缓存FPGA接收的数据,一个缓存FPGA发送的数据。

这里就不提出来了。

b.简单介绍一下数据流的走向:

上位机发送32个字节的数据(两个4x4矩阵,32个8bit数据)----> 通过H2C(Host to card)通道传输到FPGA---->数据流通过XDMA IP核桥接的AXI接口进行输出(4个64bit数据)---->经过rx_fifo(4个64bit数据)---->输出到gemm_ip核进行加速运算(32个32bit数据)--->运算结果输出到tx_fifo(16个32bit数据)--->根据axi_full接口的ar(读地址)和r(读数据)通道进行输出(16个64bit数据)--->上位机接收到数据,存入一个buffer,然后从buffer取出存入一个bin文件。

注意:这里还需要注意一下大端序和小端序的问题,返回数据的字节需要调整位置。

c.上位机的操作

这里我用的是xilinx官方的xdma驱动,测试机是ubuntu系统。驱动程序的操作可以概括为:

1.找到h2c,c2h通道。

2.找到发送数据的文件和接收数据的文件

3.创建一个发送buffer和一个接收buffer。

4.从发送数据文件将数据写入到发送buffer。

5.从发送buffer取出数据从h2c通道发出。

6.从c2h通道接收数据。

7.接收数据存入接收buffer。

6.将接收buffer的数据写入接收数据文件。

这里还涉及到xdma驱动的测试,不算复杂,但是涉及驱动下载,安装,以及测试文件的对应改动等等。

这里贴出一位大佬的参考帖子:XDMA linux平台调试过程记录-CSDN博客

这个示例的难点在于:

1.HLS生成的IP核使用。(借助HLS的c/rtl联合仿真)

2.XDMA IP核的使用。

3.相关上位机驱动的下载,安装及使用。

4.输入数据,输出数据的位宽设置等。

最后贴一下测试结果:

上面的从FPGA传回的计算结果。

下面是运行测试脚本指令和相关的运行信息。

总的来说,例子很简单,但是这里面的涉及知识点还是比较多。hls  xdma, ubuntu操作等等~~~

仅作参考,如有错误,欢迎指出~~~

工程地址:xdma_hls_simple_gemm: 使用pcie进行矩阵乘法加速--两个4x4矩阵相乘,得到一个4x4矩阵结果 - Gitee.com

### 回答1: xdma h2c-_test是一种通信接口协议,用于在数据传输过程中将数据从主机传输到外设。其中,xdma代表可扩展的直接内存访问(eXtended Direct Memory Access),用于提供高性能的数据传输,而h2c代表从主机到外设(Host to Card)的传输方式,_test表示这是一个测试版本。 在使用xdma h2c-_test协议时,主机可以通过直接内存访问技术将数据从主机内存传输到外设(如显卡、网络接口卡等)。这种方式能够提供高带宽和低延迟的数据传输,适用于需要快速处理大量数据的应用场景。 xdma h2c-_test协议的实现可能需要通过特定的驱动程序和软件库来完成,这些软件工具可以帮助主机与外设进行通信和数据传输。用户可以根据具体需求配置传输的参数,如传输方向、数据大小、起始地址等。 需要注意的是,xdma h2c-_test通常为测试版本,可能存在一些局限性或不稳定的问题。因此,在实际应用中,建议使用更稳定和成熟的版本来确保数据传输的可靠性和性能。 总之,xdma h2c-_test是一种用于高性能数据传输的通信接口协议,适用于需要快速传输大量数据的应用场景,并且可以通过特定的驱动程序和软件库来实现。 ### 回答2: xdma h2c-_test 是一种数据传输协议,它在计算机之间传输数据时使用。具体来说,xdma表示通过DMA(直接内存访问)引擎进行数据传输,而h2c表示从主机(host)到协处理器(co-processor)的数据传输,-test则表示这是一种用于测试的传输方式。 在计算机系统中,DMA引擎可以在主机和协处理器之间直接传输数据,而无需CPU的干预。这样可以提高数据传输的效率和性能。xdma h2c-_test 协议就是利用这一特性,提供一种高效的数据传输方式。 通过这种协议,主机可以将数据发送到协处理器,协处理器可以将数据存储在自己的内存中,并进行相应的处理。这种方式在处理大量数据或需要高速传输的应用中非常有用,例如图像处理、信号处理等。 使用xdma h2c-_test协议进行数据传输需要在主机和协处理器之间建立合适的硬件和软件环境,包括配置DMA引擎、编写相应的驱动程序等。通过合理的设置和优化,可以实现数据传输的最佳性能。 总之,xdma h2c-_test是一种用于测试的数据传输协议,通过利用DMA引擎实现主机到协处理器的高效数据传输。它在处理大量数据和需要高速传输的应用中具有重要的作用。 ### 回答3: xdma h2c-_test是一个Xilinx设计工具中的一个核心功能,用于进行高性能数据传输。xdma代表跨域DMA,是一种用于在不同的处理器之间高速传输数据的技术。h2c-_test则代表从主机(Host)到片上设备(FPGA)的数据传输测试。 在FPGA设计中,数据传输是一个非常重要的任务,特别是在高性能计算和数据处理领域。xdma h2c-_test提供了一种简单而有效的方法来测试FPGA系统的数据传输性能。 通过xdma h2c-_test,我们可以将数据从主机传输到FPGA中的特定逻辑模块。这个测试可以帮助我们评估数据传输的吞吐量、延迟以及系统的稳定性。 xdma h2c-_test的实现通常需要以下步骤: 1. 配置主机和FPGA之间的数据通道(此处为h2c)。 2. 在主机上编写相应的测试程序,用于生成测试数据,并将其通过h2c通道发送到FPGA。 3. 在FPGA上编写接收数据的逻辑,并进行数据处理或存储。 4. 在测试过程中,可以记录数据传输的性能指标,例如传输速度和延迟。 5. 根据测试结果,可以根据需要进行性能优化或修改设计。 综上所述,xdma h2c-_test是一种用于测试主机到FPGA的高性能数据传输性能的工具。通过该工具,我们可以评估FPGA系统的数据传输性能,并根据测试结果进行性能优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值