自学内容网 自学内容网

AXI4控制MIG遍历 1GB的 DDR3

遍历DDR3 test,内存大小1GB
下面代码直接上板测试,遍历整个DDR空间,仅供参考

仿真没有问题,上板测试可能出现问题就是:
连续 读写 MIG 时候,中途 bvalid 不拉高。暂未查到问题,可能是过程中硬件出现问题,DDR传输出现错误。

如果需要仿真的话:

  1. 使用官方例程 仿真 init 信号在 54us 附近会出现
  2. 把官方 example_top中的 激励给注释掉,换成自己写的 ddr 驱动
  3. 要注意 位宽 匹配,复位以及 AXI 总线的连接
  4. 仿真波形
    在这里插入图片描述
// Author : felixgao      遍历DDR test
// File   : ddr_test_20240812.v
// Create : 2024-08-12 11:48:14
// Revise : 2024-08-12 11:48:14
// -----------------------------------------------------------------------------
module ddr_test_20240812 
#(parameter AXI_WRITE_BASEADDR = 0,
AXI_READ_BASEADDR  = 0,
DDR_STROBE_CAP     = 256*1024*1024*16*2/8    //256M X 32 bit /8      BYTE
)
(
    inputi_clk_p, //100MHZ
    inputi_clk_n,

    inputsys_clk_p,//200MHZ   MIG sys_clk
    inputsys_clk_n,

    output[14:0]ddr3_addr , 
    output[2:0]ddr3_ba  ,
    outputddr3_cas_n  ,
    output[0:0]ddr3_ck_n,
    output[0:0]ddr3_ck_p,
    output[0:0]ddr3_cke  ,
    outputddr3_ras_n,
    outputddr3_reset_n,
    outputddr3_we_n,
    inout[31:0]ddr3_dq,
    inout[3:0]ddr3_dqs_n,
    inout[3:0]ddr3_dqs_p,
//    (*mark_debug = "true"*) outputinit_calib_complete,
    output[0:0]ddr3_cs_n,
    output[3:0]ddr3_dm,
    output[0:0]ddr3_odt

);

/*------------------------------------------*\
                调试
\*------------------------------------------*/

vio_0 your_instance_name (
  .clk(clk_ref_i),                // input wire clk
  .probe_out0(vio)  // output wire [0 : 0] probe_out0
);
    reg[15:0]r_rst_cnt;
regi_rst;
wirer_sys_rst;

// assign r_sys_rst = vio;

always @ (posedge clk_ref_i) begin
if (vio == 1)
r_rst_cnt <= 0;
else if (r_rst_cnt == 1024 )
r_rst_cnt <= r_rst_cnt;
else if (r_rst_cnt < 1024)
r_rst_cnt <= r_rst_cnt + 1'b1;
else
r_rst_cnt <= r_rst_cnt;
end

always @ (posedge clk_ref_i) begin
if (r_rst_cnt < 1024 )
i_rst <= 1;
else
i_rst <= 0;
end

assign ui_clk_sync_rst = i_rst || ddr_ui_clk_sync_rst ;
/*------------------------------------------*\
                  main code
\*------------------------------------------*/

parameter DDR_IDLE       = 0,
  DDR_INIT_DONE  = 1,
  DDR_WRITE      = 2,
  DDR_WRITE_RESP = 3,
  DDR_WRITE_ADDR = 4,
  DDR_WRITE_DELAY= 5,
  DDR_WAIT_READ  = 6,
  DDR_READ       = 7,
  DDR_READ_ADDR  = 8,
  DDR_END        = 9;

parameter AXI_DATA_WIDTH     = 256;
parameter AXI_BURST_LEN      = 128;
parameter AXI_SEND_ONETIME   = AXI_DATA_WIDTH * AXI_BURST_LEN /8  ;  // data size * burst len
// parameter DDR_SEND_ALL_TIMES = DDR_STROBE_CAP / AXI_SEND_ONETIME ;
parameter DDR_SEND_ALL_TIMES = 262144;

wirelocked;

wire[3:0]s_axi_awid;
(*mark_debug = "true"*) reg[29:0]s_axi_awaddr;
reg[7:0]s_axi_awlen;
reg[2:0]s_axi_awsize;
reg[1:0]s_axi_awburst;
wire[0:0]s_axi_awlock;
wire[3:0]s_axi_awcache;
wire[2:0]s_axi_awprot;
wire[3:0]s_axi_awqos;
regs_axi_awvalid;
wires_axi_awready;

(*mark_debug = "true"*) reg[255:0]s_axi_wdata;
reg[31:0]s_axi_wstrb;
(*mark_debug = "true"*) regs_axi_wlast;
(*mark_debug = "true"*) regs_axi_wvalid;
(*mark_debug = "true"*) wires_axi_wready;

wire[3:0]s_axi_bid;
(*mark_debug = "true"*) wire[1:0]s_axi_bresp;
(*mark_debug = "true"*) wires_axi_bvalid;
(*mark_debug = "true"*) regs_axi_bready;

wire[3:0]s_axi_arid;
(*mark_debug = "true"*) reg[29:0]s_axi_araddr;
wire[7:0]s_axi_arlen;
reg[2:0]s_axi_arsize;
reg[1:0]s_axi_arburst;
wire[0:0]s_axi_arlock;
wire[3:0]s_axi_arcache;
wire[2:0]s_axi_arprot;
wire[3:0]s_axi_arqos;
(*mark_debug = "true"*) regs_axi_arvalid;
(*mark_debug = "true"*) wires_axi_arready;

wire[3:0]s_axi_rid;
(*mark_debug = "true"*) wire[255:0]s_axi_rdata;
(*mark_debug = "true"*) wire[1:0]s_axi_rresp;
(*mark_debug = "true"*) wires_axi_rlast;
(*mark_debug = "true"*) wires_axi_rvalid;
(*mark_debug = "true"*) regs_axi_rready;


(*mark_debug = "true"*) reg[3:0]r_ddr_cu_state;
reg[3:0]r_ddr_nx_state;
reg[15:0]r_ddr_state_cnt;
(*mark_debug = "true"*) reg[31:0]r_send_times;
(*mark_debug = "true"*) reg[31:0]r_recv_times;
reg[15:0]r_wr_data_cnt;
(*mark_debug = "true"*) wire init_calib_complete;
reg [255:0] r_ddr_read_data;

  clk_wiz_0 clk_wiz_0_inst
   (
    // Clock out ports
    .clk_out1(clk_ref_i),     // output clk_out1
    // Status and control signals
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1_p(i_clk_p),    // input clk_in1_p
    .clk_in1_n(i_clk_n));    // input clk_in1_n

  mig_7series_0 u_mig_7series_0 (

    // Memory interface ports

    .ddr3_addr                      (ddr3_addr),  //           output [14:0]ddr3_addr  
    .ddr3_ba                        (ddr3_ba),    //           output [2:0]ddr3_ba  
    .ddr3_cas_n                     (ddr3_cas_n), //           outputddr3_cas_n  
    .ddr3_ck_n                      (ddr3_ck_n),  //           output [0:0]ddr3_ck_n
    .ddr3_ck_p                      (ddr3_ck_p),  //           output [0:0]ddr3_ck_p
    .ddr3_cke                       (ddr3_cke),  //            output [0:0]ddr3_cke  
    .ddr3_ras_n                     (ddr3_ras_n), //           outputddr3_ras_n
    .ddr3_reset_n                   (ddr3_reset_n),  //        outputddr3_reset_n
    .ddr3_we_n                      (ddr3_we_n),  //           outputddr3_we_n
    .ddr3_dq                        (ddr3_dq),  //             inout [31:0]ddr3_dq
    .ddr3_dqs_n                     (ddr3_dqs_n),  //          inout [3:0]ddr3_dqs_n
    .ddr3_dqs_p                     (ddr3_dqs_p),  //          inout [3:0]ddr3_dqs_p
    .init_calib_complete            (init_calib_complete),  // outputinit_calib_complete
.ddr3_cs_n                      (ddr3_cs_n),  //           output [0:0]ddr3_cs_n
    .ddr3_dm                        (ddr3_dm),  //             output [3:0]ddr3_dm
    .ddr3_odt                       (ddr3_odt),  //            output [0:0]ddr3_odt

    // Application interface ports

    .ui_clk                         (ui_clk),  // outputui_clk
    .ui_clk_sync_rst                (ddr_ui_clk_sync_rst),  // outputui_clk_sync_rst
    .mmcm_locked                    (mmcm_locked),  // outputmmcm_locked
    .aresetn                        (~ui_clk_sync_rst),  // inputaresetn
    .app_sr_req                     (0),  // inputapp_sr_req
    .app_ref_req                    (0),  // inputapp_ref_req
    .app_zq_req                     (0),  // inputapp_zq_req
    .app_sr_active                  (),  // outputapp_sr_active
    .app_ref_ack                    (),  // outputapp_ref_ack
    .app_zq_ack                     (),  // outputapp_zq_ack
    // Slave Interface Write Address Ports
    .s_axi_awid                     (0),    // input [3:0]s_axi_awid
    .s_axi_awaddr                   (s_axi_awaddr),  // input [29:0]s_axi_awaddr
    .s_axi_awlen                    (s_axi_awlen),   // input [7:0]s_axi_awlen
    .s_axi_awsize                   (s_axi_awsize  ),  // input [2:0]s_axi_awsize
    .s_axi_awburst                  (s_axi_awburst ), // input [1:0]s_axi_awburst
    .s_axi_awlock                   (0),  // input [0:0]s_axi_awlock
    .s_axi_awcache                  (0), // input [3:0]s_axi_awcache
    .s_axi_awprot                   (0),  // input [2:0]s_axi_awprot
    .s_axi_awqos                    (0),   // input [3:0]s_axi_awqos
    .s_axi_awvalid                  (s_axi_awvalid), // inputs_axi_awvalid
    .s_axi_awready                  (s_axi_awready), // outputs_axi_awready

    // Slave Interface Write Data Ports

    .s_axi_wdata                    (s_axi_wdata),  // input [255:0]s_axi_wdata
    .s_axi_wstrb                    (s_axi_wstrb),  // input [31:0]s_axi_wstrb
    .s_axi_wlast                    (s_axi_wlast),  // inputs_axi_wlast
    .s_axi_wvalid                   (s_axi_wvalid), // inputs_axi_wvalid
    .s_axi_wready                   (s_axi_wready), // outputs_axi_wready

    // Slave Interface Write Response Ports

    .s_axi_bid                      (),     // output [3:0]s_axi_bid
    .s_axi_bresp                    (s_axi_bresp),   // output [1:0]s_axi_bresp
    .s_axi_bvalid                   (s_axi_bvalid),  // outputs_axi_bvalid
    .s_axi_bready                   (s_axi_bready),  // inputs_axi_bready

    // Slave Interface Read Address Ports

    .s_axi_arid                     (0),    // input [3:0]s_axi_arid
    .s_axi_araddr                   (s_axi_araddr),  // input [29:0]s_axi_araddr
    .s_axi_arlen                    (s_axi_arlen),   // input [7:0]s_axi_arlen
    .s_axi_arsize                   (s_axi_arsize  ),  // input [2:0]s_axi_arsize
    .s_axi_arburst                  (s_axi_arburst ), // input [1:0]s_axi_arburst
    .s_axi_arlock                   (0),  // input [0:0]s_axi_arlock
    .s_axi_arcache                  (0), // input [3:0]s_axi_arcache
    .s_axi_arprot                   (0),  // input [2:0]s_axi_arprot
    .s_axi_arqos                    (0),   // input [3:0]s_axi_arqos
    .s_axi_arvalid                  (s_axi_arvalid), // inputs_axi_arvalid
    .s_axi_arready                  (s_axi_arready), // outputs_axi_arready

    // Slave Interface Read Data Ports

    .s_axi_rid                      (),    // output [3:0]s_axi_rid
    .s_axi_rdata                    (s_axi_rdata),  // output [255:0]s_axi_rdata
    .s_axi_rresp                    (s_axi_rresp),  // output [1:0]s_axi_rresp
    .s_axi_rlast                    (s_axi_rlast),  // outputs_axi_rlast
    .s_axi_rvalid                   (s_axi_rvalid), // outputs_axi_rvalid
    .s_axi_rready                   (s_axi_rready), // inputs_axi_rready

    // System Clock Ports

    .sys_clk_p                       (sys_clk_p),  // inputsys_clk_p
    .sys_clk_n                       (sys_clk_n),  // inputsys_clk_n

    // Reference Clock Ports

    // .clk_ref_i                      (clk_ref_i),
    .sys_rst                        (1) // input sys_rst

    );


always @ (posedge ui_clk) begin
if (ui_clk_sync_rst) begin
s_axi_arsize  <= 3'b000 ;
s_axi_arburst <= 2'b00 ;
s_axi_awsize  <= 3'b000;
        s_axi_awburst <= 2'b00 ;
        s_axi_wstrb   <= 0;
end else begin
s_axi_arsize  <= 3'b101 ;
s_axi_arburst <= 2'b01 ;
s_axi_awsize  <= 3'b101;
        s_axi_awburst <= 2'b01 ;
        s_axi_wstrb   <= 32'hffffffff;
end
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_ddr_state_cnt <= 0;
else if (r_ddr_cu_state !=  r_ddr_nx_state)
r_ddr_state_cnt <= 0;
else 
r_ddr_state_cnt <= r_ddr_state_cnt + 1;
end
 
 always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_recv_times <= 0;
else if (r_ddr_cu_state == DDR_IDLE)
r_recv_times <= 0;
else if (r_ddr_cu_state == DDR_READ && r_ddr_state_cnt == 0)
r_recv_times <= r_recv_times + 1;
else
r_recv_times <= r_recv_times;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_send_times <= 0;
else if (r_ddr_cu_state == DDR_IDLE)
r_send_times <= 0;
else if (r_ddr_cu_state == DDR_WRITE && r_ddr_state_cnt == 0)
r_send_times <= r_send_times + 1;
else
r_send_times <= r_send_times;
end

(*mark_debug = "true"*) reg r_complate_flag;

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_complate_flag <= 0;
else if (r_ddr_cu_state == DDR_WAIT_READ || r_ddr_cu_state == DDR_END )
r_complate_flag <= 0;
else if ((r_ddr_cu_state == DDR_WRITE && r_send_times == DDR_SEND_ALL_TIMES )||(r_ddr_cu_state == DDR_READ && r_recv_times == DDR_SEND_ALL_TIMES))
r_complate_flag <= 1;
else 
r_complate_flag <= r_complate_flag;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_ddr_cu_state <= DDR_IDLE;
else
r_ddr_cu_state <= r_ddr_nx_state;
end

always @ (*) begin
case (r_ddr_cu_state)
DDR_IDLE     :begin  
if (init_calib_complete)
r_ddr_nx_state <= DDR_INIT_DONE;
else
r_ddr_nx_state <= r_ddr_cu_state;
 end    
DDR_INIT_DONE:begin 
r_ddr_nx_state <= DDR_WRITE;
end
DDR_WRITE    : begin  
if (s_axi_wlast)
r_ddr_nx_state <= DDR_WRITE_RESP;
else
r_ddr_nx_state <= r_ddr_cu_state;
end
DDR_WRITE_RESP    : begin  
if (s_axi_bresp == 2'b00 && s_axi_bready && s_axi_bvalid && r_complate_flag)
r_ddr_nx_state <= DDR_WAIT_READ;
else if (s_axi_bresp == 2'b00 && s_axi_bready && s_axi_bvalid )
r_ddr_nx_state <= DDR_WRITE_ADDR;
else
r_ddr_nx_state <= r_ddr_cu_state;
end
DDR_WRITE_ADDR    : begin 
r_ddr_nx_state <= DDR_WRITE_DELAY;     
end
DDR_WRITE_DELAY : begin
if (r_ddr_state_cnt == 10)
r_ddr_nx_state <= DDR_WRITE;
    else
r_ddr_nx_state <= r_ddr_cu_state;     
end
DDR_WAIT_READ    :begin 
r_ddr_nx_state <= DDR_READ; 
end
DDR_READ     : begin 
if (s_axi_rlast && s_axi_rvalid && s_axi_rready && s_axi_rresp == 2'b00 )
r_ddr_nx_state <= DDR_READ_ADDR;
else 
r_ddr_nx_state <= r_ddr_cu_state; 
end
DDR_READ_ADDR    : begin
if (r_complate_flag) 
r_ddr_nx_state <= DDR_END;
else  
r_ddr_nx_state <= DDR_READ;
end
DDR_END      : begin 
r_ddr_nx_state <= DDR_IDLE;
end
default:begin
r_ddr_nx_state <= DDR_IDLE;
end
endcase
end


/*------------------------------------------*\
                   DDR WRITE
\*------------------------------------------*/

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_awaddr <= 0;
else if (r_ddr_cu_state == DDR_IDLE)
s_axi_awaddr <= 0;
else if (r_ddr_cu_state == DDR_WRITE_ADDR)
s_axi_awaddr <= s_axi_awaddr + (AXI_BURST_LEN << 5);
else
s_axi_awaddr <= s_axi_awaddr;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_awlen <= 0;
else if (r_ddr_cu_state == DDR_INIT_DONE)
s_axi_awlen <= AXI_BURST_LEN - 1;
else
s_axi_awlen <= s_axi_awlen;
end


always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_awvalid <= 0;
else if (s_axi_awvalid && s_axi_awready)
s_axi_awvalid <= 0;
else if (r_ddr_cu_state == DDR_WRITE && r_ddr_state_cnt == 0)
s_axi_awvalid <= 1;
else
s_axi_awvalid <= 0;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_wdata <= 0;
else if (s_axi_wvalid && s_axi_wready)
s_axi_wdata <= s_axi_wdata + 1;
else
s_axi_wdata <= s_axi_wdata;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_wvalid <= 0;
else if (s_axi_wvalid && s_axi_wready && s_axi_wlast)
s_axi_wvalid <= 0;
else if (r_ddr_cu_state == DDR_WRITE && r_ddr_state_cnt == 0)
s_axi_wvalid <= 1;
else
s_axi_wvalid <= s_axi_wvalid;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_wr_data_cnt <= 0;
else if (r_wr_data_cnt == AXI_BURST_LEN - 1)
r_wr_data_cnt <= 0;
else if (s_axi_wvalid && s_axi_wready)
r_wr_data_cnt <= r_wr_data_cnt + 1;
else
r_wr_data_cnt <= r_wr_data_cnt;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_wlast <= 0;
else if (s_axi_wvalid && s_axi_wready && r_wr_data_cnt == AXI_BURST_LEN - 2)
s_axi_wlast <= 1;
else
s_axi_wlast <= 0;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_bready <= 0;
else if (s_axi_bready && s_axi_bvalid)
s_axi_bready <= 0;
else if (r_ddr_cu_state == DDR_WRITE_RESP)
s_axi_bready <= 1;
else
s_axi_bready <= s_axi_bready;
end



/*------------------------------------------*\
                  DDR READ
\*------------------------------------------*/

assign s_axi_arlen = AXI_BURST_LEN -1;

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_araddr <= 0;
else if (r_ddr_cu_state == DDR_WAIT_READ)
s_axi_araddr <= 0;
else if (r_ddr_cu_state == DDR_READ_ADDR)
s_axi_araddr <= s_axi_araddr + (AXI_BURST_LEN << 5);
else
s_axi_araddr <= s_axi_araddr;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_arvalid <= 0;
else if (s_axi_arvalid && s_axi_arready)
s_axi_arvalid <= 0;
else if (r_ddr_cu_state == DDR_READ && r_ddr_state_cnt == 0)
s_axi_arvalid <= 1;
else
s_axi_arvalid <= 0;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
r_ddr_read_data <= 0;
else if (r_ddr_cu_state == DDR_READ && s_axi_rvalid && s_axi_rready)
r_ddr_read_data <= s_axi_rdata;
else
r_ddr_read_data <= r_ddr_read_data;
end

always @ (posedge ui_clk) begin
if (ui_clk_sync_rst)
s_axi_rready <= 0;
else if (r_ddr_cu_state == DDR_END)
s_axi_rready <= 0;
else if (r_ddr_cu_state == DDR_WAIT_READ)
s_axi_rready <= 1;
else
s_axi_rready <= s_axi_rready;
end

endmodule

原文地址:https://blog.csdn.net/gw123456780/article/details/144360530

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!