首页 > 其他分享 >03使用fdma读写axi-bram测试

03使用fdma读写axi-bram测试

时间:2023-12-30 11:34:00浏览次数:22  
标签:03 begin end fdma IP FDMA test axi

软件版本:vitis2021.1(vivado2021.1)

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA

登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!

3.1概述    

FDMA是米联客基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用FPGA代码直接读写PL的DDR或者ZYNQ/ZYNQMP SOC PS的DDR或者BRAM。在米联客的数据交互方案中,FDMA IP CORE 已经广泛应用于ZYNQ SOC/Artix7/Kintex7/ultrascale/ultrascale+系列FPGA/SOC。

如果用过ZYNQ/ZYNQMP SOC的都知道,要直接操作PS的DDR 通常是DMA 或者VDMA,然而用过XILINX 的DMA IP 和VDMA IP,总有一种遗憾,那就是不够灵活,还需要对寄存器配置,真是麻烦。XILINX 的总线接口是AXI4总线,自定义AXI4 IP挂到总线上就能实现对内存地址空间的读写访问。因此,我们只要掌握AXI4协议就能完成不管是PS还是PL DDR的读写操作。

本文实验目的:

1:掌握基于uiFDMA3.2的FPGA工程设计

2:利用uiFDMA3.2提供的接口,编写BRAM测试程序

3:对AXI-BRAM读写仿真和测试

我们第一入门的demo选择对BRAM仿真测试,是因为不管是仿真还是编译测试,对AXI-BRAM速度都非常快,我们在下面一个DEMO中会给出对DDR的读写仿真测试。

3.2系统框图

本系统中先将测试数据通过Milianke UiFDMA写入Bram,再通过Milianke UiFDMA将Bram中数据读出。将读写数据进行对比。通过在线逻辑分析仪抓取读写数据测试读写正确性。

3.3创建图形化逻辑工程

1:创建工程命名为fpga_prj

双击VIVADO软件图标启动VIVADO

 

设置工程路径,并且命名工程名为fpga_prj

以下设置FPGA或者ZYNQ或者ZYNQ-MPSOC芯片型号,必须和开发板保持一致,如果不清楚的请查阅自己开发板的硬件手册或者根据选型手册上参数确认

2:创建Block Design并且命名为system

 

如下图所示,图形化system就是一个代码容器,接着我们要添加一些图像化的IP

3:添加图形化FPGA IP

首先设置自定义IP的路径,这里读者可以把我们配套工程根路径下的uisrc文件夹复制到目前的工程根路径,单击Settings在弹出的Settings窗口选择IP->Repository 设置如下路径

 

添加+号添加IP

比如输入关键词FDMA就可以搜索到我们米联客uiFDMA IP

用类似的方法添加必要的IP如下图所示:

 

4:完成IP之间的信号自动

这种简单的工程可以先让软件先自动化线,然后根据结果手动一些调整

可以看到连线结果

5:调整IP参数

5-1:BRAM参数设置

首先把IP的配置参数修改下,双击需要设置的IP可以进行参数设置

FDMA设置数据位宽128bit 可以访问内存地址位宽32bit,最大AXI 最大burst的程度为256

BRAM设置,使用BRAM Controller 为真双口RAM

5-2:BRAM Controller参数设置

AXI BRAM Controller设置axi4协议,数据位宽128bit 读延迟1个时钟

5-3:Clocking Wizard参数设置

5-4:AXI Interconnect IP设置

双击AXI Interconnect IP 进行设置

设置AXI Interconnect IP的性能参数,其中Enable Register Slice 用于改善时序,Enable Data FIFO用于增加FIFO大小,增加数据传输效率

6:引出FPGA接口信号

分别右击下图2个IP,然后选择Make External,把需要引出到顶层的FPGA信号引出

为了引出时钟需先右击信号PIN脚断开连接,然后Make External,之后重新连接

修改后重新连接时钟

7:修改复位和信号名字

修改默认的时钟名字,以相同的方法修改其他信号

信号名修改后,修改复位脚的接线

修改完成后

8:视图优化

右击空白处,弹出菜单选择Regenerate Layout优化下视图

9:地址分配

AXI总线必须分配地址,设置uiFDMA的地址空间分配,起始地址可以任意设置,我们设置从0x0000_0000开始,大小64KB

10:自动校验

保存工程

11:校验图形逻辑工程

单击下图中的控件可以对图形化编程进行校验

12:自动产生顶层文件

右击system,在弹出的菜单中选择Create HDL Wrapper

3.4编写FDMA的BRAM测试代码

刚刚以上自动产生的顶层文件,只是引出的信号接口,并不能完成对FDMA的控制,所以我们需要自定义一个顶层文件,可以复制刚才产生的文件,修改,这样可以省一些编写调用接口的时间。

为了方便文件的管理,我们新建一个fdma_bram_test.v文件,并且复制以上代码,到这个文件夹。

右击删除刚刚自动产生的文件

 

添加fdma_bram_test.v文件

fdma_bram_test.v文件

`timescale 1ns / 1ps

 

module fdma_bram_test(

  input sysclk

);

 

 

wire [31:0]   fdma_raddr;

reg           fdma_rareq;

wire          fdma_rbusy;

wire [127:0]  fdma_rdata;

wire [15:0]   fdma_rsize;

wire          fdma_rvalid;

wire [31:0]   fdma_waddr;

reg           fdma_wareq;

wire          fdma_wbusy;

wire [127:0]  fdma_wdata;

wire [15:0]   fdma_wsize;

wire          fdma_wvalid;

wire sysclk;

wire          ui_clk;

wire          test_error;

reg           test_error1=1'b0;

 

parameter TEST_MEM_SIZE   = 32'd64*1024;//64KB//测试内存的地址范围

parameter FDMA_BURST_LEN  = 16'd512; //测试一次的长度

parameter ADDR_MEM_OFFSET = 0; //地址偏移量

parameter ADDR_INC = FDMA_BURST_LEN * 16; //下一次FDMA burst的地址增加

   

parameter WRITE1 = 0;

parameter WRITE2 = 1;

parameter WAIT   = 2;

parameter READ1  = 3;

parameter READ2  = 4;

 

reg [31: 0] t_data;

reg [31: 0] fdma_waddr_r;

reg [2  :0] T_S = 0;

 

assign fdma_waddr = fdma_waddr_r + ADDR_MEM_OFFSET; //写地址

 

assign fdma_raddr = fdma_waddr; //读写地址相同

 

assign fdma_wsize = FDMA_BURST_LEN; //设置FDMA控制器一次写burst的数据长度

assign fdma_rsize = FDMA_BURST_LEN; //设置FDMA控制器一次读burst的数据长度

assign fdma_wdata ={t_data,t_data,t_data,t_data};

   

   

//延迟复位

reg [8:0] rst_cnt = 0;

always @(posedge ui_clk)

    if(rst_cnt[8] == 1'b0)

         rst_cnt <= rst_cnt + 1'b1;

     else

         rst_cnt <= rst_cnt;

 

//FDMA 读写控制器,每次先写后读,读出后对比数据正确性

always @(posedge ui_clk)begin

    if(rst_cnt[8] == 1'b0)begin

        T_S <=0;  

        fdma_wareq  <= 1'b0;

        fdma_rareq  <= 1'b0;

        t_data<=0;

        fdma_waddr_r <=0;      

    end

    else begin

        case(T_S)      

        WRITE1:begin

            if(fdma_waddr_r==TEST_MEM_SIZE) fdma_waddr_r<=0; //超出测试内存范围,重新测试

            if(!fdma_wbusy)begin//当fdma进入空闲,fdma_wbusy=0,请求写

                    fdma_wareq  <= 1'b1; //设置写请求

                    t_data  <= 0; //设置初值

            end

            if(fdma_wareq&&fdma_wbusy)begin//当fdma响应请求后,fdma_wbusy=1,进入下一个状态

                    fdma_wareq  <= 1'b0;

                    T_S         <= WRITE2;

                end

        end

        WRITE2:begin

            if(!fdma_wbusy) begin//当fdma完成请求后,fdma_wbusy=0,进入下一个状态

                 T_S <= WAIT;

                 t_data  <= 32'd0;

            end

            else if(fdma_wvalid) begin//当fdma_wvalid有效期间必须写入有效数据

                t_data <= t_data + 1'b1;

            end

        end

        WAIT:begin//not needed

            T_S <= READ1;

        end

        READ1:begin

            if(!fdma_rbusy)begin//当fdma进入空闲,fdma_rbusy=0,请求读

                fdma_rareq  <= 1'b1; //设置读请求

                t_data   <= 0; //设置初值

            end

            if(fdma_rareq&&fdma_rbusy)begin//当fdma响应请求后,fdma_rbusy=1,进入下一个状态

                 fdma_rareq  <= 1'b0; //清除读请求

                 T_S         <= READ2;

            end

        end

        READ2:begin

            if(!fdma_rbusy) begin//当fdma完成请求后,fdma_rbusy=0,进入下一个状态

                 T_S <= WRITE1;

                 t_data  <= 32'd0;

                 fdma_waddr_r  <= fdma_waddr_r + ADDR_INC; //当本次读写周期完成增加地址,地址以BYTE计算

            end

            else if(fdma_rvalid) begin//当fdma_rvalid有效期间读出的数据有效

                t_data <= t_data + 1'b1;

            end

        end  

        default:

            T_S <= WRITE1;    

        endcase

    end

  end

   

 

 //对比是否有错误数据

assign test_error = (fdma_rvalid && (t_data[15:0] != fdma_rdata[15:0]));

always @(posedge ui_clk)

    test_error1 <= test_error;

 

ila_0 ila_dbg (

    .clk(ui_clk),

    .probe0({fdma_wdata[15:0],fdma_wareq,fdma_wvalid,fdma_wbusy}),

    .probe1({fdma_rdata[15:0],t_data[15:0],fdma_rvalid,fdma_rbusy,T_S,test_error1})

);

 

 

  system system_i

       (.FDMA_S_0_fdma_raddr(fdma_raddr),

        .FDMA_S_0_fdma_rareq(fdma_rareq),

        .FDMA_S_0_fdma_rbusy(fdma_rbusy),

        .FDMA_S_0_fdma_rdata(fdma_rdata),

        .FDMA_S_0_fdma_rready(1'b1),

        .FDMA_S_0_fdma_rsize(fdma_rsize),

        .FDMA_S_0_fdma_rvalid(fdma_rvalid),

        .FDMA_S_0_fdma_waddr(fdma_waddr),

        .FDMA_S_0_fdma_wareq(fdma_wareq),

        .FDMA_S_0_fdma_wbusy(fdma_wbusy),

        .FDMA_S_0_fdma_wdata(fdma_wdata),

        .FDMA_S_0_fdma_wready(1'b1),

        .FDMA_S_0_fdma_wsize(fdma_wsize),

        .FDMA_S_0_fdma_wvalid(fdma_wvalid),

        .sysclk(sysclk),

        .ui_clk(ui_clk)

        );        

 

 

endmodule

 

3.5程序分析

1:总流程图

如下图所示,本文的程序工作流程如下,包括请求写数据、FDMA收到写数据请求、写数据完成、请求读数据、FDMA收到读数据请求和读数据完成、校验。

2:FDMA的读写时序

以下是fdma_test.v中读写fdma ip接口的状态机,由于读写代码对称,对fdma的读写操作可以分为2步完成,分别是:1:发送读/写请求 2:读/写有效数据。

2-1:FDMA的写时序

 

fdma_wready设置为1,当fdma_wbusy=0的时候代表FDMA的总线非忙,可以进行一次新的FDMA传输,这个时候可以设置fdma_wreq=1,同时设置fdma burst的起始地址和fdma_wsize本次需要传输的数据大小(以bytes为单位)。当fdma_wvalid=1的时候需要给出有效的数据,写入AXI总线。当最后一个数写完后,fdma_wvalid和fdma_wbusy变为0。

AXI4总线最大的burst lenth是256,而经过封装后,用户接口的fdma_size可以任意大小的,fdma ip内部代码控制每次AXI4总线的Burst长度,这样极大简化了AXI4总线协议的使用。

2-2:FDMA的读时序

fdma_rready设置为1,当fdma_rbusy=0的时候代表FDMA的总线非忙,可以进行一次新的FDMA传输,这个时候可以设置fdma_rreq=1,同时设置fdma burst的起始地址和fdma_rsize本次需要传输的数据大小(以bytes为单位)。当fdma_rvalid=1的时候需要给出有效的数据,写入AXI总线。当最后一个数写完后,fdma_rvalid和fdma_rbusy变为0。

同样对于AXI4总线的读操作,AXI4总线最大的burst lenth是256,而经过封装后,用户接口的fdma_size可以任意大小的,fdma ip内部代码控制每次AXI4总线的Burst长度,这样极大简化了AXI4总线协议的使用。

3.6RTL仿真

1:仿真tb文件

编写仿真tb文件,fdma_bram_test_tb.v,非常简单,只需要给一个时钟

`timescale 1ns / 1ps

module fdma_bram_test_tb();

 reg sysclk;

 fdma_bram_test fdma_bram_test_inst

(

    .sysclk(sysclk)

 );

initial begin

     sysclk  = 0;

     #100;

end

    always #20 sysclk = ~sysclk;  

endmodule

 

添加fdma_bram_test_tb.v到工程中

2:仿真测试

进行RTL行为仿真

放大后观察数据,我们可以看到test_error有毛刺,但是test_error打拍后,毛刺就没有了。

FDMA 源码部分的分析,在前面课程中已经分析过,这里不再重复。

3.7编译测试

添加ila IP CORE 和fpga pin定义

ila的设置如下

 

 

编译产生bit

下载程序到开发板测试,通过在线逻辑分析仪观察

 

标签:03,begin,end,fdma,IP,FDMA,test,axi
From: https://www.cnblogs.com/milianke/p/17936184.html

相关文章

  • 05uifdma_dbuf 3.0 IP介绍
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!5.1概述        uifdma_dbufIP是米联客研发用于配合FDMA完成数据传输控制的IP模块。FDMA-DBUFIP代码采用"......
  • 3-1-02AXI4-FULL-uiFDMA IP仿真验证
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!2.1概述本文试验中对前面编写的FDMAIP进行仿真验证。2.2saxi_full_memIP介绍这个IP的源码可以基于XILINX提供的ax......
  • 3-1-01 AXI4-FULL-MASTER IP FDMA介绍
    件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1.1概述    FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。本文对AXI4-FULL总线接口进行了封装,同时定义了简......
  • check the manual that corresponds to your MySQL server version for the right syn
    form:{repairstatus:0,name:'',//负责人maintenancetime:newDate().toISOString().split('T')[0],//保修时间equipmentid:'',equipment:'',describe:'',finfishtime:'',repairname:'�......
  • 1-1-03 XILINX JTAG开发工具usb-jtag驱动安装
    1.1概述    一般安装vitis(vivado)的过程中勾选了安装jtagcable驱动就会默认安装好jtag驱动,但是如果vivado无法正确识别到JTAG,那么可以试下重新手动安装驱动1.2准备工作安装驱动前,必须关闭所有的vivado,vitis-sdk并且拔掉USBJTAG以免导致安装失败1.3usb-jtag驱动安装......
  • 代码随想录day03 链表删除 链表类的实现 反转链表
    首先是链表的删除操作热身题这里使用了一个新的头指针这样在删除头指针的时候就不需要进行额外的判断然后是链表类的实现需要一点背诵加上深刻理解有时候理解了但是写起来还是会有些指针边界的小问题应该多写写多记一下就会好了还有就是手写链表要常复习吧学习新......
  • 用python打开文件获取文件属性时,运行报错PermissionError: [Errno 13] Permission den
    一:概述在开发中我们经常会使用python程序去对物理主机平台上的文件进行操作,在这里说明一下,python中获取文件属性时,运行出现的错误。二:具体说明<1>获取文件属性的代码importos#创建一个临时目录temp_dir='temp'os.mkdir(temp_dir)#在临时目录中创建一个文件temp_file=o......
  • OpenEuler22.03安装PostgreSQL15.5并配置一主二从
    环境准备序号IP标识(hostname)CPU/内存配置系统盘数据盘1192.168.8.190pg018C+16G80G500G2192.168.8.191pg028C+16G80G500G3192.168.8.192pg038C+16G80G500G规划的文件夹目录(所有主机):##以下目录为本文规划的目录,可以提前创建,也可以跟着......
  • 【五期李伟平】CCF-B(TFS'23)Consensus Reaching Process With Multiobjective Optimiza
    PengWu,FengenLi,JieZhao,etal.ConsensusReachingProcessWithMultiobjectiveOptimizationforLarge-ScaleGroupDecisionMakingWithCooperativeGame[J].IEEETransactionsonFuzzySystems2023:293-306.  本文针对大规模群体决策(LSGDM)中的共识达成......
  • 【题解】BZOJ 4403序列统计
    tg.BZOJ4403序列统计pj.BZOJ4403序列统计没啥用的题解\(QWQ\)——无脑思考首先要想怎么求单调不上升序列的个数,因为可能会有重复的数,所以不能直接用排列组合。那这道题怎么打呀?我不知道啊\(\dots\)\((~:\)因为原来是单调不下降序列,将第\(i\)位上的数加\(i\),于是......