[X]关闭
3

02使用fdma读写DDR(AXI4 FDMA数据缓存篇)

摘要: 在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,现在我们已经掌握了FDMA的使用,本文我们继续使用FDMA实现对AXI-MIG的读写,以此读写DDR。由于FDMA的读写操作都是基于AXI总线, ...

软件版本:vitis2019.2(vivado2019.2)

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA(本文使用米联客(milianke)MK7160FA开发板)

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

2.1概述    

在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,现在我们已经掌握了FDMA的使用,本文我们继续使用FDMA实现对AXI-MIG的读写,以此读写DDR。由于FDMA的读写操作都是基于AXI总线,所以用户代码部分一致性也非常好,我们的状态机都不需要做修改,基本上只要把前文的BRAM IP换成MIG IP即可。

本文实验目的:

1:利用uiFDMA3.0提供的接口,编写DDR测试程序

2:对MIG接口读写仿真和测试

2.2PL图形化设计

搭建过程我们不再详细描述,不清楚的可以参考前"01使用FDMA读写AXI-BRAM",搭建好的工程如下

我们主要看下MIG的配置

2.3编写FDMA的DDR测试代码

以下代码除来DDR的引脚定义,以及增加来1按键输入复位,其他内容都和"01使用FDMA读写AXI-BRAM"一样。读写状态机完全一样,对PL DDR整个内存地址空间进行测试。

 

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

/*

Company : Liyang Milian Electronic Technology Co., Ltd.

Brand: 绫宠仈瀹?(milianke)

Technical forum:uisrc.com

taobao: https://milianke.taobao.com https://osrc.taobao.com

jd:https://milianke.jd.com

Create Date: 2019/12/17

Module Name: fdma_ddr_test

Description:

Copyright: Copyright (c) milianke

Revision: 1.0

Signal description:

1) _i input

2) _o output

3) _n activ lowpai

4) _dg debug signal

5) _r delay or register

6) _s state mechine

*/

//////////////////////////////////////////////////////////////////////////////////

module fdma_ddr_test(

output [14:0]DDR3_0_addr,

output [2 :0]DDR3_0_ba,

output DDR3_0_cas_n,

output [0 :0]DDR3_0_ck_n,

output [0 :0]DDR3_0_ck_p,

output [0 :0]DDR3_0_cke,

output [0 :0]DDR3_0_cs_n,

output [7 :0]DDR3_0_dm,

inout [63:0]DDR3_0_dq,

inout [7 :0]DDR3_0_dqs_n,

inout [7 :0]DDR3_0_dqs_p,

output [0 :0]DDR3_0_odt,

output DDR3_0_ras_n,

output DDR3_0_reset_n,

output DDR3_0_we_n,

input sysclk_p

);

 

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 [0:0] fdma_rstn;

wire ui_clk;

 

 

parameter TEST_MEM_SIZE = 32'd1024*1024*1024*2;//4GB

parameter FDMA_BURST_LEN = 16'd512;

parameter ADDR_MEM_OFFSET = 0;

parameter ADDR_INC = FDMA_BURST_LEN * 16;

 

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;

assign fdma_rsize = FDMA_BURST_LEN;

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

 

reg [15:0] rst_cnt = 0;

 

always @(posedge ui_clk)

if(~fdma_rstn)begin

rst_cnt <=0;

end

else begin

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

rst_cnt <= rst_cnt + 1'b1;

else

rst_cnt <= rst_cnt;

end

 

always @(posedge ui_clk)begin

if(rst_cnt[15] == 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_wareq <= 1'b1;

t_data <= 0;

end

if(fdma_wareq&&fdma_wbusy)begin

fdma_wareq <= 1'b0;

T_S <= WRITE2;

end

end

WRITE2:begin

if(!fdma_wbusy) begin

T_S <= WAIT;

t_data <= 32'd0;

end

else if(fdma_wvalid) begin

t_data <= t_data + 1'b1;

end

end

WAIT:begin//not needed

T_S <= READ1;

end

READ1:begin

if(!fdma_rbusy)begin

fdma_rareq <= 1'b1;

t_data <= 0;

end

if(fdma_rareq&&fdma_rbusy)begin

fdma_rareq <= 1'b0;

T_S <= READ2;

end

end

READ2:begin

if(!fdma_rbusy) begin

T_S <= WRITE1;

t_data <= 32'd0;

fdma_waddr_r <= fdma_waddr_r + ADDR_INC;//128/8=16

end

else if(fdma_rvalid) begin

t_data <= t_data + 1'b1;

end

end

default:

T_S <= WRITE1;

endcase

end

end

 

wire test_error = (fdma_rvalid && (t_data[31:0] != fdma_rdata[31:0]));

 

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_error})

);

 

system system_i

(.DDR3_0_addr(DDR3_0_addr),

.DDR3_0_ba(DDR3_0_ba),

.DDR3_0_cas_n(DDR3_0_cas_n),

.DDR3_0_ck_n(DDR3_0_ck_n),

.DDR3_0_ck_p(DDR3_0_ck_p),

.DDR3_0_cke(DDR3_0_cke),

.DDR3_0_cs_n(DDR3_0_cs_n),

.DDR3_0_dm(DDR3_0_dm),

.DDR3_0_dq(DDR3_0_dq),

.DDR3_0_dqs_n(DDR3_0_dqs_n),

.DDR3_0_dqs_p(DDR3_0_dqs_p),

.DDR3_0_odt(DDR3_0_odt),

.DDR3_0_ras_n(DDR3_0_ras_n),

.DDR3_0_reset_n(DDR3_0_reset_n),

.DDR3_0_we_n(DDR3_0_we_n),

.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),

.fdma_rstn(fdma_rstn),

.sysclk(sysclk_p),

.ui_clk(ui_clk));

endmodule

2.4RTL仿真

2.4.1仿真tb文件

DDR4的仿真文件在对应的FPGA工程路径uisrc/02_sim路径下,把仿真文件添加进来

2.4.2仿真测试

可以看到DDR4的仿真速度还是很快,在6us左右就可以得到仿真结果了,可以看到test_error信号一直是低电平。

2.5编译测试

添加fpga_pin.xdc文件,不同的开发板IO的约束定义一样,下图仅仅提供演示,具体以自己拿到的配套资料工程路径下的uisrc/04_pin/fpga_pin.xdc为准。当然读者也可以根据原理图自己定义约束。

通过ila在线逻辑分析仪IP-CORE,在线观察波形

通过在线逻辑分析仪查看结果,可以看到test_error信号一直低电平

2.6程序分析

以下关于程序的分析和"01使用FDMA读写AXI-BRAM"一样,重复是为了读者不会因此遗漏这部分重要信息。

2.6.1FDMA的写时序

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。

2.6.2FDMA的读时序

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。

2.6.3读写状态机


路过

雷人

握手

鲜花

鸡蛋
发表评论

最新评论

引用 xdxfkjrg 2022-4-22 15:00
问题解决了,不过是在56us之后才有的反应。如图:https://thumbnail7.baidupcs.com/thumbnail/622a00713n46641bfc5596dc2fd2983e?fid=3466519851-250528-949003930662263&time=1650610800&rt=yt&sign=FDTAER-DCb740ccc5511e5e8fedcff06b081203-v96yFa5jGQX1YNZHtY8cTFRwuEA%3D&expires=24h&chkv=0&chkbd=0&chkpc=&dp-logid=1192909633&dp-callid=0&size=c1536_u864&quality=90&vuk=-&ft=video&autopolicy=1
引用 xdxfkjrg 2022-4-22 11:25
您好,我下载了源码,仿真原工程0~50us的时间段里,发现状态机一直在0状态,数据没法写进去。
我用的源码,发现是mig_7series_0模块输出复位信号:“fdma_rstn复位信号”一直为0,状态机在等待“fdma_rstn复位信号”置高,但是一直没反应
引用 uisrc 2021-8-12 20:29
本章节源码下载地址链接:https://pan.baidu.com/s/1NT-ArWeJuLTtPX-Fv1oGFA 提取码1111

查看全部评论(3)

本文作者
2021-8-12 09:21
  • 7
    粉丝
  • 3299
    阅读
  • 3
    回复
  • 1
  • 2
  • 3
热门评论
排行榜