/*******************************MILIANKE******************************* *Company : MiLianKe Electronic Technology Co., Ltd. *Create Date: 2019/12/17 *Module Name:fdma_ddr_test *File Name:fdma_ddr_test.v *Description: *The reference demo provided by Milianke is only used for learning. *We cannot ensure that the demo itself is free of bugs, so users *should be responsible for the technical problems and consequences *caused by the use of their own products. *Copyright: Copyright (c) MiLianKe *All rights reserved. *Revision: 1.0 *Signal description *1) _i input *2) _o output *3) _n activ low *4) _dg debug signal *5) _r delay or register *6) _s state mechine *********************************************************************/ `timescale 1ns / 1ps module fdma_ddr_test( output [13: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 [3 :0]DDR3_0_dm, inout [31:0]DDR3_0_dq, inout [3 :0]DDR3_0_dqs_n, inout [3 :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 I_sysclk_p );
wire [31:0] fdma_waddr; //FDMA写通道地址 reg fdma_wareq; //FDMA写通道请求 wire [15:0] fdma_wsize; //FDMA写通道一次FDMA的传输大小 wire fdma_wbusy; //FDMA处于BUSY状态,AXI总线正在写操作 wire [127:0] fdma_wdata; //FDMA写数据 wire fdma_wvalid;//FDMA写有效 wire [31:0] fdma_raddr; //FDMA读通道地址 reg fdma_rareq; //FDMA读通道请求 wire [15:0] fdma_rsize; //FDMA读通道一次FDMA的传输大小 wire fdma_rbusy; //FDMA处于BUSY状态,AXI总线正在读操作 wire [127:0] fdma_rdata; //FDMA读数据 wire fdma_rvalid;//FDMA 读有效
wire ui_clk; //系统时钟 wire fdma_rstn; reg test_error;
parameter TEST_MEM_SIZE = 32'd1024*1024*256;;//256MB; //设置内存总的测试范围,以字节为单位 parameter FDMA_BURST_LEN = 16'd512; //设置FDMA BURST 长度,该参数最大65535 parameter ADDR_MEM_OFFSET = 0; //设置内存的偏移地址 parameter ADDR_INC = FDMA_BURST_LEN*16; //设置每次AXI BURST增加的地址
//状态机 parameter WRITE1 = 0; parameter WRITE2 = 1; parameter WAIT = 2; parameter READ1 = 3; parameter READ2 = 4;
reg [2 :0] T_S = 0;//状态机 reg [31: 0] t_data;//产生测试数据 reg [31: 0] fdma_waddr_r;//地址
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 [8:0] rst_cnt = 0; always @(posedge ui_clk or negedge fdma_rstn) if(fdma_rstn == 1'b0) rst_cnt <= 0; else if(rst_cnt[8] == 1'b0) rst_cnt <= rst_cnt + 1'b1;
//演示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 //写状态1 if(fdma_waddr_r==TEST_MEM_SIZE) fdma_waddr_r<=0; //当测试范围到达,继续从初始地址开始 if(!fdma_wbusy)begin //如果FDMA写总线非忙 fdma_wareq <= 1'b1; //请求一次FDMA写 t_data <= 0; //测试数据清0 end if(fdma_wareq&&fdma_wbusy)begin //当FDMA的写请求为1,并且总线忙,代表FDMA响应了写请求 fdma_wareq <= 1'b0; //清除写请求 T_S <= WRITE2; //进入下一个状态 end end WRITE2:begin //写状态2 if(!fdma_wbusy) begin//如果FDMA总线非忙,代表数据已经写完 T_S <= WAIT; //进入下一个状态 t_data <= 32'd0; //清测试数据 end else if(fdma_wvalid) begin //如果FDMA总线忙,并且fdma_wvalid代表了数据必须有效,则写入测试数据 t_data <= t_data + 1'b1; //以计数器方式写入测试数据 end end WAIT:begin//该状态机不是必须的,可以直接跳过 T_S <= READ1; end READ1:begin//读状态机1 if(!fdma_rbusy)begin //当fdma读总线非忙 fdma_rareq <= 1'b1; //发送读请求 t_data <= 0;//清测试数据 end if(fdma_rareq&&fdma_rbusy)begin ////当FDMA的读请求为1,并且总线忙,代表FDMA响应了读请求 fdma_rareq <= 1'b0; //清除读请求 T_S <= READ2; //进入下一个状态 end end READ2:begin //读状态机2 if(!fdma_rbusy) begin //当FDMA 读总线非忙,代表读完成 T_S <= WRITE1; //进入下一个写状态,循环测试 t_data <= 32'd0; //清测试数据 fdma_waddr_r <= fdma_waddr_r + ADDR_INC;//计算下一次FDMA BURST的地址 end else if(fdma_rvalid) begin //当读有效 t_data <= t_data + 1'b1; //产生测试数据用于和读出的数据对比 end end default: T_S <= WRITE1; endcase end end
always @(posedge ui_clk)begin test_error <= (fdma_rvalid && (t_data[31:0] != fdma_rdata[31:0])); end
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(I_sysclk_p), .ui_clk(ui_clk)); endmodule |