AXI4控制MIG遍历 1GB的 DDR3
遍历DDR3 test,内存大小1GB
下面代码直接上板测试,遍历整个DDR空间,仅供参考
仿真没有问题,上板测试可能出现问题就是:
连续 读写 MIG 时候,中途 bvalid 不拉高。暂未查到问题,可能是过程中硬件出现问题,DDR传输出现错误。
如果需要仿真的话:
- 使用官方例程 仿真 init 信号在 54us 附近会出现
- 把官方 example_top中的 激励给注释掉,换成自己写的 ddr 驱动
- 要注意 位宽 匹配,复位以及 AXI 总线的连接
- 仿真波形
// 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)!