对ddr进行读写实验,用了vivado的ddr的模型进行仿真
1 创建AXI_mig的ip核
选择axi
选择自己的型号,这里是ddr的位宽32,但是axi的话是256位宽
选择nobuffer,没有缓冲器
选择自己匹配引脚
默认
后面默认即可
生成ip,时间很长。
2 打开mig的工程寻找模型文件
仿真模型 这个tb是xlinx自己的仿真代码以及模型
根据路径找到需要的代码
需要的文件如下都拷到自己的工程
3.写驱动模块代码
顶层模块
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2025/04/01 20:38:55 // Design Name: // Module Name: axi_ddr // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module axi_ddr_top( input clk , input rst , input wen , input [31:0] wr_len , input rd_en , input [31:0] rd_len, output [15:0] ddr3_addr, output [2:0] ddr3_ba, output ddr3_cas_n, output [0:0] ddr3_ck_n, output [0:0] ddr3_ck_p, output [0:0] ddr3_cke, output ddr3_ras_n, output ddr3_reset_n, output ddr3_we_n, inout [31:0] ddr3_dq, inout [3:0] ddr3_dqs_n, inout [3:0] ddr3_dqs_p, input init_calib_complete, output [0:0] ddr3_cs_n, output [3:0] ddr3_dm, output [0:0] ddr3_odt ); localparam integer C_S_AXI_ID_WIDTH = 4; localparam integer C_S_AXI_DATA_WIDTH = 256; localparam integer C_S_AXI_ADDR_WIDTH = 31; localparam integer C_S_AXI_AWUSER_WIDTH = 0; localparam integer C_S_AXI_ARUSER_WIDTH = 0; localparam integer C_S_AXI_WUSER_WIDTH = 0; localparam integer C_S_AXI_RUSER_WIDTH = 0; localparam integer C_S_AXI_BUSER_WIDTH = 0; wire S_AXI_ACLK; wire S_AXI_ARESETN; wire [C_S_AXI_ID_WIDTH-1 : 0] S_AXI_AWID; wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR; wire [7 : 0] S_AXI_AWLEN; wire [2 : 0] S_AXI_AWSIZE; wire [1 : 0] S_AXI_AWBURST; wire S_AXI_AWLOCK; wire [3 : 0] S_AXI_AWCACHE; wire [2 : 0] S_AXI_AWPROT; wire [3 : 0] S_AXI_AWQOS; wire [3 : 0] S_AXI_AWREGION; wire [C_S_AXI_AWUSER_WIDTH-1 : 0] S_AXI_AWUSER; wire S_AXI_AWVALID; wire S_AXI_AWREADY; wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA; wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB; wire S_AXI_WLAST; wire [C_S_AXI_WUSER_WIDTH-1 : 0] S_AXI_WUSER; wire S_AXI_WVALID; wire S_AXI_WREADY; wire [C_S_AXI_ID_WIDTH-1 : 0] S_AXI_BID; wire [1 : 0] S_AXI_BRESP; wire [C_S_AXI_BUSER_WIDTH-1 : 0] S_AXI_BUSER; wire S_AXI_BVALID; wire S_AXI_BREADY; wire [C_S_AXI_ID_WIDTH-1 : 0] S_AXI_ARID; wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR; wire [7 : 0] S_AXI_ARLEN; wire [2 : 0] S_AXI_ARSIZE; wire [1 : 0] S_AXI_ARBURST; wire S_AXI_ARLOCK; wire [3 : 0] S_AXI_ARCACHE; wire [2 : 0] S_AXI_ARPROT; wire [3 : 0] S_AXI_ARQOS; wire [3 : 0] S_AXI_ARREGION; wire [C_S_AXI_ARUSER_WIDTH-1 : 0] S_AXI_ARUSER; wire S_AXI_ARVALID; wire S_AXI_ARREADY; wire [C_S_AXI_ID_WIDTH-1 : 0] S_AXI_RID; wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA; wire [1 : 0] S_AXI_RRESP; wire S_AXI_RLAST; wire [C_S_AXI_RUSER_WIDTH-1 : 0] S_AXI_RUSER; wire S_AXI_RVALID; wire S_AXI_RREADY; axi_addr_m axi_addr_m_inst ( .clk ( ui_clk ), .rst ( rst ), .wen ( wen ), .wr_len ( wr_len ), .rd_en ( rd_en ), .rd_len ( rd_len ), .init_calib_complete (init_calib_complete) , .s_axi_awid ( S_AXI_AWID ), .s_axi_awaddr ( S_AXI_AWADDR ), .s_axi_awlen ( S_AXI_AWLEN ), .s_axi_awsize ( S_AXI_AWSIZE ), .s_axi_awburst ( S_AXI_AWBURST ), .s_axi_awlock ( S_AXI_AWLOCK ), .s_axi_awcache ( S_AXI_AWCACHE ), .s_axi_awprot ( S_AXI_AWPROT ), .s_axi_awqos ( S_AXI_AWQOS ), .s_axi_awvalid ( S_AXI_AWVALID ), .s_axi_awready ( S_AXI_AWREADY ), .s_axi_wdata ( S_AXI_WDATA ), .s_axi_wstrb ( S_AXI_WSTRB ), .s_axi_wlast ( S_AXI_WLAST ), .s_axi_wvalid ( S_AXI_WVALID ), .s_axi_wready ( S_AXI_WREADY ), .s_axi_bid ( S_AXI_BID ), .s_axi_bresp ( S_AXI_BRESP ), .s_axi_bvalid ( S_AXI_BVALID ), .s_axi_bready ( S_AXI_BREADY ), .s_axi_arid ( S_AXI_ARID ), .s_axi_araddr ( S_AXI_ARADDR ), .s_axi_arlen ( S_AXI_ARLEN ), .s_axi_arsize ( S_AXI_ARSIZE ), .s_axi_arburst ( S_AXI_ARBURST ), .s_axi_arlock ( S_AXI_ARLOCK ), .s_axi_arcache ( S_AXI_ARCACH ), .s_axi_arprot ( S_AXI_ARPROT ), .s_axi_arqos ( S_AXI_ARQOS ), .s_axi_arvalid ( S_AXI_ARVALID ), .s_axi_arready ( S_AXI_ARREADY ), .s_axi_rid ( S_AXI_RID ), .s_axi_rdata ( S_AXI_RDATA ), .s_axi_rresp ( S_AXI_RRESP ), .s_axi_rlast ( S_AXI_RLAST ), .s_axi_rvalid ( S_AXI_RVALID ), .s_axi_rready ( S_AXI_RREADY ) ); // //axi_full_test_v1_0_S00_AXI # ( // .C_S_AXI_ID_WIDTH(C_S_AXI_ID_WIDTH), // .C_S_AXI_DATA_WIDTH(C_S_AXI_DATA_WIDTH), // .C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH), // .C_S_AXI_AWUSER_WIDTH(C_S_AXI_AWUSER_WIDTH), // .C_S_AXI_ARUSER_WIDTH(C_S_AXI_ARUSER_WIDTH), // .C_S_AXI_WUSER_WIDTH(C_S_AXI_WUSER_WIDTH), // .C_S_AXI_RUSER_WIDTH(C_S_AXI_RUSER_WIDTH), // .C_S_AXI_BUSER_WIDTH(C_S_AXI_BUSER_WIDTH) //) //axi_full_test_v1_0_S00_AXI_inst ( // .S_AXI_ACLK ( clk ), // .S_AXI_ARESETN ( rst ), // .S_AXI_AWID (S_AXI_AWID ), // .S_AXI_AWADDR (S_AXI_AWADDR ), // .S_AXI_AWLEN (S_AXI_AWLEN ), // .S_AXI_AWSIZE (S_AXI_AWSIZE ), // .S_AXI_AWBURST (S_AXI_AWBURST ), // .S_AXI_AWLOCK (S_AXI_AWLOCK ), // .S_AXI_AWCACHE (S_AXI_AWCACHE ), // .S_AXI_AWPROT (S_AXI_AWPROT ), // .S_AXI_AWQOS (S_AXI_AWQOS ), // .S_AXI_AWREGION (S_AXI_AWREGION ), // .S_AXI_AWUSER (S_AXI_AWUSER ), // .S_AXI_AWVALID (S_AXI_AWVALID ), // .S_AXI_AWREADY (S_AXI_AWREADY ), // .S_AXI_WDATA (S_AXI_WDATA ), // .S_AXI_WSTRB (S_AXI_WSTRB ), // .S_AXI_WLAST (S_AXI_WLAST ), // .S_AXI_WUSER (S_AXI_WUSER ), // .S_AXI_WVALID (S_AXI_WVALID ), // .S_AXI_WREADY (S_AXI_WREADY ), // .S_AXI_BID (S_AXI_BID ), // .S_AXI_BRESP (S_AXI_BRESP ), // .S_AXI_BUSER (S_AXI_BUSER ), // .S_AXI_BVALID (S_AXI_BVALID ), // .S_AXI_BREADY (S_AXI_BREADY ), // .S_AXI_ARID (S_AXI_ARID ), // .S_AXI_ARADDR (S_AXI_ARADDR ), // .S_AXI_ARLEN (S_AXI_ARLEN ), // .S_AXI_ARSIZE (S_AXI_ARSIZE ), // .S_AXI_ARBURST (S_AXI_ARBURST ), // .S_AXI_ARLOCK (S_AXI_ARLOCK ), // .S_AXI_ARCACHE (S_AXI_ARCACH ), // .S_AXI_ARPROT (S_AXI_ARPROT ), // .S_AXI_ARQOS (S_AXI_ARQOS ), // .S_AXI_ARREGION (S_AXI_ARREGION ), // .S_AXI_ARUSER (S_AXI_ARUSER ), // .S_AXI_ARVALID (S_AXI_ARVALID ), // .S_AXI_ARREADY (S_AXI_ARREADY ), // .S_AXI_RID (S_AXI_RID ), // .S_AXI_RDATA (S_AXI_RDATA ), // .S_AXI_RRESP (S_AXI_RRESP ), // .S_AXI_RLAST (S_AXI_RLAST ), // .S_AXI_RUSER (S_AXI_RUSER ), // .S_AXI_RVALID (S_AXI_RVALID ), // .S_AXI_RREADY (S_AXI_RREADY ) //); mig_7series_0 u_mig_7series_0 ( // Memory interface ports .ddr3_addr ( ddr3_addr ), // output [15:0] ddr3_addr .ddr3_ba ( ddr3_ba ), // output [2:0] ddr3_ba .ddr3_cas_n ( ddr3_cas_n ), // output ddr3_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 ), // output ddr3_ras_n .ddr3_reset_n ( ddr3_reset_n ), // output ddr3_reset_n .ddr3_we_n ( ddr3_we_n ), // output ddr3_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 ), // output init_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 ), // output ui_clk .ui_clk_sync_rst ( ui_clk_sync_rst ), // output ui_clk_sync_rst .mmcm_locked ( mmcm_locked ), // output mmcm_locked .aresetn ( ~ui_clk_sync_rst ), // input aresetn .app_sr_req ( 1'b0 ), // input app_sr_req .app_ref_req ( 1'b0 ), // input app_ref_req .app_zq_req ( 1'b0 ), // input app_zq_req .app_sr_active ( app_sr_active ), // output app_sr_active .app_ref_ack ( app_ref_ack ), // output app_ref_ack .app_zq_ack ( app_zq_ack ), // output app_zq_ack // Slave Interface Write Address Ports .s_axi_awid ( S_AXI_AWID ), // input [3:0] s_axi_awid .s_axi_awaddr ( S_AXI_AWADDR ), // input [31: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 ( S_AXI_AWLOCK ), // input [0:0] s_axi_awlock .s_axi_awcache ( S_AXI_AWCACHE ), // input [3:0] s_axi_awcache .s_axi_awprot ( S_AXI_AWPROT ), // input [2:0] s_axi_awprot .s_axi_awqos ( S_AXI_AWQOS ), // input [3:0] s_axi_awqos .s_axi_awvalid ( S_AXI_AWVALID ), // input s_axi_awvalid .s_axi_awready ( S_AXI_AWREADY ), // output s_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 ), // input s_axi_wlast .s_axi_wvalid ( S_AXI_WVALID ), // input s_axi_wvalid .s_axi_wready ( S_AXI_WREADY ), // output s_axi_wready // Slave Interface Write Response Ports .s_axi_bid ( 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 ), // output s_axi_bvalid .s_axi_bready ( S_AXI_BREADY ), // input s_axi_bready // Slave Interface Read Address Ports .s_axi_arid ( S_AXI_ARID ), // input [3:0] s_axi_arid .s_axi_araddr ( S_AXI_ARADDR ), // input [31: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 ( S_AXI_ARLOCK ), // input [0:0] s_axi_arlock .s_axi_arcache ( S_AXI_ARCACH ), // input [3:0] s_axi_arcache .s_axi_arprot ( S_AXI_ARPROT ), // input [2:0] s_axi_arprot .s_axi_arqos ( S_AXI_ARQOS ), // input [3:0] s_axi_arqos .s_axi_arvalid ( S_AXI_ARVALID ), // input s_axi_arvalid .s_axi_arready ( S_AXI_ARREADY ), // output s_axi_arready // Slave Interface Read Data Ports .s_axi_rid ( 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 ), // output s_axi_rlast .s_axi_rvalid ( S_AXI_RVALID ), // output s_axi_rvalid .s_axi_rready ( S_AXI_RREADY ), // input s_axi_rready // System Clock Ports .sys_clk_i ( clk ), // Reference Clock Ports .clk_ref_i ( clk ), .sys_rst ( rst ) // input sys_rst axi低电平复位 ); endmodule
axi_addr_m模块代码
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2025/04/01 20:49:57 // Design Name: // Module Name: axi_addr_m // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module axi_addr_m( input clk, input rst, input wen, input [31:0] wr_len, input rd_en, input [31:0] rd_len, input init_calib_complete, // Slave Interface Write Address Ports output [3:0] s_axi_awid , output [30:0] s_axi_awaddr , output [7:0] s_axi_awlen , output [2:0] s_axi_awsize , output [1:0] s_axi_awburst , output s_axi_awlock , output [3:0] s_axi_awcache , output [2:0] s_axi_awprot , output [3:0] s_axi_awqos , output s_axi_awvalid , input s_axi_awready , // Slave Interface Write Data Ports output [255:0] s_axi_wdata , output [31:0] s_axi_wstrb , output s_axi_wlast , output s_axi_wvalid , input s_axi_wready , // Slave Interface Write Response Ports input [3:0] s_axi_bid , input [1:0] s_axi_bresp , input s_axi_bvalid , output s_axi_bready , // Slave Interface Read Address Ports output [3:0] s_axi_arid , output [30:0] s_axi_araddr , output [7:0] s_axi_arlen , output [2:0] s_axi_arsize , output [1:0] s_axi_arburst , output [0:0] s_axi_arlock , output [3:0] s_axi_arcache , output [2:0] s_axi_arprot , output [3:0] s_axi_arqos , output s_axi_arvalid , input s_axi_arready , // Slave Interface Read Data Ports input [3:0] s_axi_rid , input [255:0] s_axi_rdata , input [1:0] s_axi_rresp , input s_axi_rlast , input s_axi_rvalid , output s_axi_rready ); (* syn_keep = "true", mark_debug = "true" *) reg [31:0] w_cnt ; (* syn_keep = "true", mark_debug = "true" *) reg [31:0] r_cnt ; (* syn_keep = "true", mark_debug = "true" *) reg [31:0] wr_cnt_num ; (* syn_keep = "true", mark_debug = "true" *) reg [31:0] rd_cnt_num ; (* syn_keep = "true", mark_debug = "true" *) reg [255:0] s_axi_rdata_d ; (* syn_keep = "true", mark_debug = "true" *) reg s_axi_awvalid_r ; (* syn_keep = "true", mark_debug = "true" *) reg [30:0] s_axi_awaddr_r ; (* syn_keep = "true", mark_debug = "true" *) reg s_axi_wvalid_r ; (* syn_keep = "true", mark_debug = "true" *) reg s_axi_wlast_r ; (* syn_keep = "true", mark_debug = "true" *) reg [255:0] s_axi_wdata_r ; (* syn_keep = "true", mark_debug = "true" *) reg s_axi_arvalid_r ; (* syn_keep = "true", mark_debug = "true" *) reg [30:0] s_axi_araddr_r ; (* syn_keep = "true", mark_debug = "true" *) reg s_axi_rready_r ; (* syn_keep = "true", mark_debug = "true" *) reg wen_d1; (* syn_keep = "true", mark_debug = "true" *) reg wen_d2; (* syn_keep = "true", mark_debug = "true" *) reg rd_en_d1; (* syn_keep = "true", mark_debug = "true" *) reg rd_en_d2; (* syn_keep = "true", mark_debug = "true" *) (* syn_keep = "true", mark_debug = "true" *) reg [7:0] s_axi_awlen_d1 ; (* syn_keep = "true", mark_debug = "true" *) reg [7:0] s_axi_arlen_d1 ; (* syn_keep = "true", mark_debug = "true" *) reg init_calib_complete_d1; (* syn_keep = "true", mark_debug = "true" *) reg init_calib_complete_d2; (* syn_keep = "true", mark_debug = "true" *) wire wr_en_flag; (* syn_keep = "true", mark_debug = "true" *) wire rd_en_flag; reg [7:0] test_cnt; assign s_axi_awid =4'd0 ; assign s_axi_awlen =8'd255 ; assign s_axi_awsize =3'd5 ; assign s_axi_awburst =2'b01 ; assign s_axi_awlock =1'b0 ; assign s_axi_awcache =4'b0010 ; assign s_axi_awprot =3'd0 ; assign s_axi_awqos =4'd0 ; assign s_axi_wstrb =32'hffffffff ; assign s_axi_arid = 4'd0 ; assign s_axi_arlen = 8'd255 ; assign s_axi_arsize = 3'd5 ; assign s_axi_arburst = 2'b01 ; assign s_axi_arlock = 1'b0 ; assign s_axi_arcache = 4'b0010 ; assign s_axi_arprot = 3'd0 ; assign s_axi_arqos = 4'd0 ; assign s_axi_bready = 1'b1 ; assign s_axi_awvalid = s_axi_awvalid_r ; assign s_axi_awaddr = s_axi_awaddr_r ; assign s_axi_wvalid = s_axi_wvalid_r ; assign s_axi_wlast = s_axi_wlast_r ; assign s_axi_wdata = s_axi_wdata_r ; assign s_axi_arvalid = s_axi_arvalid_r ; assign s_axi_araddr =s_axi_araddr_r ; assign s_axi_rready = s_axi_rready_r ; assign wr_en_flag = wen_d1 & (~wen_d2) ; assign rd_en_flag = rd_en_d1 & (~rd_en_d2) ; always @(posedge clk or negedge rst) begin if (rst == 1'b0) begin init_calib_complete_d1 <= 1'b0; init_calib_complete_d2 <= 1'b0; end else begin init_calib_complete_d1<= init_calib_complete; init_calib_complete_d2<= init_calib_complete_d1; end end //always @(posedge clk or negedge rst) begin // if (rst == 1'b0) begin // wen_d1 <= 1'b0; // wen_d2 <= 1'b0; // end // else begin // wen_d1<= wen; // wen_d2<= wen_d1; // end //end // // //always @(posedge clk or negedge rst) begin // if (rst == 1'b0) begin // rd_en_d1 <= 1'b0; // rd_en_d2 <= 1'b0; // end // else begin // rd_en_d1<= rd_en; // rd_en_d2<= rd_en_d1; // end //end //==============test================== always @(posedge clk or negedge rst) begin if (rst == 1'b0) test_cnt <=8'd0; else if( init_calib_complete_d2 == 1'b1 ) test_cnt <= test_cnt + 8'd1; else if (test_cnt == 8'd100) test_cnt <=8'd0; else; end //===========写地址========== always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_awvalid_r <= 1'b0; else if(s_axi_awvalid && s_axi_awready ) s_axi_awvalid_r <= 1'b0; else if (s_axi_wlast_r == 1'b1 && wr_cnt_num != wr_len -1'b1 ) s_axi_awvalid_r <= 1'b1; else if (test_cnt == 8'd100 && init_calib_complete_d2 == 1'b1 ) //wen_d2 == 1'b1 s_axi_awvalid_r <= 1'b1; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_awaddr_r <=31'd0; else if(s_axi_awvalid_r && s_axi_awready ) s_axi_awaddr_r <= s_axi_awaddr_r + 31'd256; else; end //==========写数据=========== always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_wvalid_r <= 1'b0; else if(s_axi_awvalid_r && s_axi_awready ) s_axi_wvalid_r <= 1'b1; else if (s_axi_wlast == 1'b1) s_axi_wvalid_r <= 1'b0; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) w_cnt <= 32'd0; else if (s_axi_wlast_r == 1'b1) w_cnt <= 32'd0; else if(s_axi_wvalid_r == 1'b1 && s_axi_wready == 1'b1 ) w_cnt <= w_cnt + 1'b1; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) wr_cnt_num <= 32'd0; else if (wr_cnt_num == wr_len -1'b1 ) wr_cnt_num <= 32'd0; else if(s_axi_wvalid_r == 1'b1 && s_axi_wready == 1'b1 ) wr_cnt_num <= wr_cnt_num + 1'b1; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_wlast_r <= 1'b0; else if(w_cnt == 8'd254 ) s_axi_wlast_r <= 1'b1; else s_axi_wlast_r <= 1'b0; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_wdata_r <= 256'd0; else if(s_axi_wvalid_r == 1'b1 && s_axi_wready == 1'b1 ) s_axi_wdata_r <= s_axi_wdata_r + 1'b1; else; end //==========响应============= //==========读地址=========== always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_arvalid_r <= 1'b0; else if( s_axi_wlast_r == 1'b1 && init_calib_complete_d2 == 1'b1 ) //rd_en == 1'b1 s_axi_arvalid_r <= 1'b1; else if (s_axi_arvalid_r == 1'b1 && s_axi_arready == 1'b1 ) s_axi_arvalid_r <= 1'b0; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_araddr_r <= 31'd0; else if(s_axi_arvalid_r == 1'b1 && s_axi_arready == 1'b1 ) s_axi_araddr_r <=s_axi_araddr_r + 31'd256; else; end //==========读数据============= always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_rready_r <= 1'b0; else if(s_axi_arvalid_r == 1'b1 && s_axi_arready == 1'b1 ) s_axi_rready_r <= 1'b1; else if (s_axi_rlast == 1'b1) s_axi_rready_r <= 1'b0; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) s_axi_rdata_d <= 256'd0; else if (s_axi_rlast == 1'b1) s_axi_rdata_d <= 256'd0; else if(s_axi_rvalid == 1'b1 && s_axi_rready == 1'b1 ) s_axi_rdata_d <=s_axi_rdata; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) r_cnt <= 32'd0; else if (s_axi_rlast == 1'b1) r_cnt <= 32'd0; else if(s_axi_rvalid == 1'b1 && s_axi_rready == 1'b1 ) r_cnt <= r_cnt + 1'b1; else; end always @(posedge clk or negedge rst) begin if (rst == 1'b0) rd_cnt_num <= 32'd0; else if (rd_cnt_num == rd_len -1'b1 ) rd_cnt_num <= 32'd0; else if(s_axi_rvalid == 1'b1 && s_axi_rready == 1'b1 ) rd_cnt_num <= rd_cnt_num + 1'b1; else; end endmodule
4.仿真
需要把xilinx的tb文件中的顶层改成自己的顶层
改成自己的
5仿真结果
尤其是注意ddr的init_calib_complete 信号拉高,表示ddr初始化完成,但是对于模型的初始地址并不是0 ,这个仿真是需要10分钟左右才能看到他拉高。
写入0-255 读0-255
写
读