`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
|