ZYNQ--PL读写PS端DDR数据

server/2024/11/13 14:43:01/

PL 和PS的高效交互是zynq 7000 soc开发的重中之重,我们常常需要将PL端的大量数
据实时送到PS端处理,或者将PS端处理结果实时送到PL端处理,常规我们会想到使用DMA
的方式来进行,但是各种协议非常麻烦,灵活性也比较差,本节课程讲解如何直接通过AXI总
线来读写PS端ddr的数据,这里面涉及到AXI4协议,vivado的FPGA调试等。

1 ZYNQ 的HP端口使用

zynq 7000 SOC 的HP口是 High-Performance Ports的缩写,如下图所示,一共有4
个HP口,HP口是AXI Slave设备,我们可以通过这4个HP接口实现高带宽的数据交互。
在这里插入图片描述

  1. 在vivado的界面中HP的配置如下图(HP0~HP3),这里面有使能控制,数据位宽选择,可选择32或64bit的位宽。
    在这里插入图片描述
    2)我们的实验启用HP0配置为64bit位宽,使用的时钟是150Mhz,HP的带宽是150Mhz
  • 64bit,对于视频处理,ADC数据采集等应用都有足够的带宽。
  • 在这里插入图片描述
  1. 如下图所示,配置完HP端口以后,zynq会多出一个AXI Slave端口,名称为S_AXI_HP0,
    不过这些端口都是AXI3标准的,我们常用的是AXI4协议,这里添加1个AXI Interconnect
    IP,用于协议转换(AXI3<->AXI4)

![](https://img-blog.csdnimg.cn/direct/69d41b22f9444fab83fa00ab42dbf1c1.pn

2 PL 端AXI Master

AXI4 相对复杂,但SOC开发者必须掌握,对于zynq的开发者,笔者建议能够在一些已
有的模板代码基础上修改。AXI协议的具体内容可参考Xilinx UG761 AXI Reference Guide。
在这里我们简单了解一下。
AXI4 所采用的是一种READY,VALID握手通信机制,即主从模块进行数据通信前,先根
据操作对各所用到的数据、地址通道进行握手。主要操作包括传输发送者A等到传输接受者B
的READY信号后,A将数据与VALID信号同时发送给B,这是一种典型的握手机制。
在这里插入图片描述
AXI 总线分为五个通道:
 读地址通道,包含ARVALID, ARADDR, ARREADY信号;
 写地址通道,包含AWVALID,AWADDR, AWREADY信号;
 读数据通道,包含RVALID, RDATA, RREADY, RRESP信号;
 写数据通道,包含WVALID, WDATA,WSTRB, WREADY信号;
 写应答通道,包含BVALID, BRESP, BREADY信号;
 系统通道,包含:ACLK,ARESETN信号;
其中ACLK为axi总线时钟,ARESETN是axi总线复位信号,低电平有效;读写数据与读
写地址类信号宽度都为32bit;READY与VALID是对应的通道握手信号;WSTRB信号为1的
bit 对应WDATA有效数据字节,WSTRB宽度是32bit/8=4bit;BRESP与RRESP分别为写回
应信号,读回应信号,宽度都为2bit,‘h0代表成功,其他为错误。
读操作顺序为主与从进行读地址通道握手并传输地址内容,然后在读数据通道握手并传输
所读内容以及读取操作的回应,时钟上升沿有效。如图所示:
在这里插入图片描述
写操作顺序为主与从进行写地址通道握手并传输地址内容,然后在写数据通道握手并传输
所读内容,最后再写回应通道握手,并传输写回应数据,时钟上升沿有效。如图所示:
在这里插入图片描述
在我们不擅长写FPGA的一些代码时我们往往要借鉴别人的代码或者使用IP core。在这里
笔者从github上找到一个AXI master的代码,地址是
https://github.com/aquaxis/IPCORE/tree/master/aq_axi_vdma。这个工程是一个自己写的
VDMA,里面包含了大量可参考的代码。笔者这里主要使用了aq_axi_master.v这个代码用于
AXI master 读写操作。借鉴别人代码有时会节省很多时间,但如果不能理解的去借鉴,出现问
题了很难解决。具体可以参考aq_axi_master.v代码,有部分修改。

module mem_test
#(parameter MEM_DATA_BITS = 64,parameter ADDR_BITS = 32
)
(input rst,                                 /*复位*/input mem_clk,                               /*接口时钟*/output reg rd_burst_req,                          /*读请求*/output reg wr_burst_req,                          /*写请求*/output reg[9:0] rd_burst_len,                     /*读数据长度*/output reg[9:0] wr_burst_len,                     /*写数据长度*/output reg[ADDR_BITS - 1:0] rd_burst_addr,        /*读首地址*/output reg[ADDR_BITS - 1:0] wr_burst_addr,        /*写首地址*/input rd_burst_data_valid,                  /*读出数据有效*/input wr_burst_data_req,                    /*写数据信号*/input[MEM_DATA_BITS - 1:0] rd_burst_data,   /*读出的数据*/output[MEM_DATA_BITS - 1:0] wr_burst_data,    /*写入的数据*/input rd_burst_finish,                      /*读完成*/input wr_burst_finish,                      /*写完成*/output reg error
);
parameter IDLE = 3'd0;
parameter MEM_READ = 3'd1;
parameter MEM_WRITE  = 3'd2;
parameter BURST_LEN = 128;(*mark_debug="true"*)reg[2:0] state;
(*mark_debug="true"*)reg[7:0] wr_cnt;
reg[MEM_DATA_BITS - 1:0] wr_burst_data_reg;
assign wr_burst_data = wr_burst_data_reg;
(*mark_debug="true"*)reg[7:0] rd_cnt;
reg[31:0] write_read_len;
//assign error = (state == MEM_READ) && rd_burst_data_valid && (rd_burst_data != {(MEM_DATA_BITS/8){rd_cnt}});always@(posedge mem_clk or posedge rst)
beginif(rst)error <= 1'b0;else if(state == MEM_READ && rd_burst_data_valid && rd_burst_data != {(MEM_DATA_BITS/8){rd_cnt}})error <= 1'b1;
end
always@(posedge mem_clk or posedge rst)
beginif(rst)beginwr_burst_data_reg <= {MEM_DATA_BITS{1'b0}};wr_cnt <= 8'd0;endelse if(state == MEM_WRITE)beginif(wr_burst_data_req)beginwr_burst_data_reg <= {(MEM_DATA_BITS/8){wr_cnt}};wr_cnt <= wr_cnt + 8'd1;endelse if(wr_burst_finish)wr_cnt <= 8'd0;end
endalways@(posedge mem_clk or posedge rst)
beginif(rst)beginrd_cnt <= 8'd0;endelse if(state == MEM_READ)beginif(rd_burst_data_valid)beginrd_cnt <= rd_cnt + 8'd1;endelse if(rd_burst_finish)rd_cnt <= 8'd0;endelserd_cnt <= 8'd0;
endalways@(posedge mem_clk or posedge rst)
beginif(rst)beginstate <= IDLE;wr_burst_req <= 1'b0;rd_burst_req <= 1'b0;rd_burst_len <= BURST_LEN;wr_burst_len <= BURST_LEN;rd_burst_addr <= 0;wr_burst_addr <= 0;write_read_len <= 32'd0;endelsebegincase(state)IDLE:beginstate <= MEM_WRITE;wr_burst_req <= 1'b1;wr_burst_len <= BURST_LEN;wr_burst_addr <='h2000000;write_read_len <= 32'd0;endMEM_WRITE:beginif(wr_burst_finish)beginstate <= MEM_READ;wr_burst_req <= 1'b0;rd_burst_req <= 1'b1;rd_burst_len <= BURST_LEN;rd_burst_addr <= wr_burst_addr;write_read_len <= write_read_len + BURST_LEN;endendMEM_READ:beginif(rd_burst_finish)beginif(write_read_len == 32'h2000000)beginrd_burst_req <= 1'b0;state <= IDLE;endelsebeginstate <= MEM_WRITE;wr_burst_req <= 1'b1;wr_burst_len <= BURST_LEN;rd_burst_req <= 1'b0;wr_burst_addr <= wr_burst_addr + BURST_LEN;endendenddefault:state <= IDLE;endcaseend
endendmodule
module aq_axi_master(// Reset, Clockinput           ARESETN,input           ACLK,// Master Write Addressoutput [0:0]  M_AXI_AWID,output [31:0] M_AXI_AWADDR,output [7:0]  M_AXI_AWLEN,    // Burst Length: 0-255output [2:0]  M_AXI_AWSIZE,   // Burst Size: Fixed 2'b011output [1:0]  M_AXI_AWBURST,  // Burst Type: Fixed 2'b01(Incremental Burst)output        M_AXI_AWLOCK,   // Lock: Fixed 2'b00output [3:0]  M_AXI_AWCACHE,  // Cache: Fiex 2'b0011output [2:0]  M_AXI_AWPROT,   // Protect: Fixed 2'b000output [3:0]  M_AXI_AWQOS,    // QoS: Fixed 2'b0000output [0:0]  M_AXI_AWUSER,   // User: Fixed 32'd0output        M_AXI_AWVALID,input         M_AXI_AWREADY,// Master Write Dataoutput [63:0] M_AXI_WDATA,output [7:0]  M_AXI_WSTRB,output        M_AXI_WLAST,output [0:0]  M_AXI_WUSER,output        M_AXI_WVALID,input         M_AXI_WREADY,// Master Write Responseinput [0:0]   M_AXI_BID,input [1:0]   M_AXI_BRESP,input [0:0]   M_AXI_BUSER,input         M_AXI_BVALID,output        M_AXI_BREADY,// Master Read Addressoutput [0:0]  M_AXI_ARID,output [31:0] M_AXI_ARADDR,output [7:0]  M_AXI_ARLEN,output [2:0]  M_AXI_ARSIZE,output [1:0]  M_AXI_ARBURST,output [1:0]  M_AXI_ARLOCK,output [3:0]  M_AXI_ARCACHE,output [2:0]  M_AXI_ARPROT,output [3:0]  M_AXI_ARQOS,output [0:0]  M_AXI_ARUSER,output        M_AXI_ARVALID,input         M_AXI_ARREADY,// Master Read Data input [0:0]   M_AXI_RID,input [63:0]  M_AXI_RDATA,input [1:0]   M_AXI_RRESP,input         M_AXI_RLAST,input [0:0]   M_AXI_RUSER,input         M_AXI_RVALID,output        M_AXI_RREADY,// Local Businput         MASTER_RST,input         WR_START,input [31:0]  WR_ADRS,input [31:0]  WR_LEN, output        WR_READY,output        WR_FIFO_RE,input         WR_FIFO_EMPTY,input         WR_FIFO_AEMPTY,input [63:0]  WR_FIFO_DATA,output        WR_DONE,input         RD_START,input [31:0]  RD_ADRS,input [31:0]  RD_LEN, output        RD_READY,output        RD_FIFO_WE,input         RD_FIFO_FULL,input         RD_FIFO_AFULL,output [63:0] RD_FIFO_DATA,output        RD_DONE,output [31:0] DEBUG
);localparam S_WR_IDLE  = 3'd0;localparam S_WA_WAIT  = 3'd1;localparam S_WA_START = 3'd2;localparam S_WD_WAIT  = 3'd3;localparam S_WD_PROC  = 3'd4;localparam S_WR_WAIT  = 3'd5;localparam S_WR_DONE  = 3'd6;reg [2:0]   wr_state;reg [31:0]  reg_wr_adrs;reg [31:0]  reg_wr_len;reg         reg_awvalid, reg_wvalid, reg_w_last;reg [7:0]   reg_w_len;reg [7:0]   reg_w_stb;reg [1:0]   reg_wr_status;reg [3:0]   reg_w_count, reg_r_count;reg [7:0]   rd_chkdata, wr_chkdata;reg [1:0]   resp;reg rd_first_data;reg rd_fifo_enable;reg[31:0] rd_fifo_cnt;
assign WR_DONE = (wr_state == S_WR_DONE);assign WR_FIFO_RE         = rd_first_data | (reg_wvalid & ~WR_FIFO_EMPTY & M_AXI_WREADY & rd_fifo_enable);
//assign WR_FIFO_RE         = reg_wvalid & ~WR_FIFO_EMPTY & M_AXI_WREADY;
always @(posedge ACLK or negedge ARESETN)
beginif(!ARESETN)rd_fifo_cnt <= 32'd0;else if(WR_FIFO_RE)rd_fifo_cnt <= rd_fifo_cnt + 32'd1;else if(wr_state == S_WR_IDLE)rd_fifo_cnt <= 32'd0;	
endalways @(posedge ACLK or negedge ARESETN)
beginif(!ARESETN)rd_fifo_enable <= 1'b0;else if(wr_state == S_WR_IDLE && WR_START)rd_fifo_enable <= 1'b1;else if(WR_FIFO_RE && (rd_fifo_cnt == RD_LEN[31:3] - 32'd1) )rd_fifo_enable <= 1'b0;		
end// Write Statealways @(posedge ACLK or negedge ARESETN) beginif(!ARESETN) beginwr_state            <= S_WR_IDLE;reg_wr_adrs[31:0]   <= 32'd0;reg_wr_len[31:0]    <= 32'd0;reg_awvalid         <= 1'b0;reg_wvalid          <= 1'b0;reg_w_last          <= 1'b0;reg_w_len[7:0]      <= 8'd0;reg_w_stb[7:0]      <= 8'd0;reg_wr_status[1:0]  <= 2'd0;reg_w_count[3:0]    <= 4'd0;reg_r_count[3:0]  <= 4'd0;wr_chkdata          <= 8'd0;rd_chkdata <= 8'd0;resp <= 2'd0;rd_first_data <= 1'b0;end else beginif(MASTER_RST) beginwr_state <= S_WR_IDLE;end else begincase(wr_state)S_WR_IDLE: beginif(WR_START) beginwr_state          <= S_WA_WAIT;reg_wr_adrs[31:0] <= WR_ADRS[31:0];reg_wr_len[31:0]  <= WR_LEN[31:0] -32'd1;rd_first_data <= 1'b1;endreg_awvalid         <= 1'b0;reg_wvalid          <= 1'b0;reg_w_last          <= 1'b0;reg_w_len[7:0]      <= 8'd0;reg_w_stb[7:0]      <= 8'd0;reg_wr_status[1:0]  <= 2'd0;endS_WA_WAIT: beginif(!WR_FIFO_AEMPTY | (reg_wr_len[31:11] == 21'd0)) beginwr_state          <= S_WA_START;endrd_first_data <= 1'b0;endS_WA_START: beginwr_state            <= S_WD_WAIT;reg_awvalid         <= 1'b1;reg_wr_len[31:11]    <= reg_wr_len[31:11] - 21'd1;if(reg_wr_len[31:11] != 21'd0) beginreg_w_len[7:0]  <= 8'hFF;reg_w_last      <= 1'b0;reg_w_stb[7:0]  <= 8'hFF;end else beginreg_w_len[7:0]  <= reg_wr_len[10:3];reg_w_last      <= 1'b1;reg_w_stb[7:0]  <= 8'hFF;
/*case(reg_wr_len[2:0]) begincase 3'd0: reg_w_stb[7:0]  <= 8'b0000_0000;case 3'd1: reg_w_stb[7:0]  <= 8'b0000_0001;case 3'd2: reg_w_stb[7:0]  <= 8'b0000_0011;case 3'd3: reg_w_stb[7:0]  <= 8'b0000_0111;case 3'd4: reg_w_stb[7:0]  <= 8'b0000_1111;case 3'd5: reg_w_stb[7:0]  <= 8'b0001_1111;case 3'd6: reg_w_stb[7:0]  <= 8'b0011_1111;case 3'd7: reg_w_stb[7:0]  <= 8'b0111_1111;default:   reg_w_stb[7:0]  <= 8'b1111_1111;endcase
*/endendS_WD_WAIT: beginif(M_AXI_AWREADY) beginwr_state        <= S_WD_PROC;reg_awvalid     <= 1'b0;reg_wvalid      <= 1'b1;endendS_WD_PROC: beginif(M_AXI_WREADY & ~WR_FIFO_EMPTY) beginif(reg_w_len[7:0] == 8'd0) beginwr_state        <= S_WR_WAIT;reg_wvalid      <= 1'b0;reg_w_stb[7:0]  <= 8'h00;end else beginreg_w_len[7:0]  <= reg_w_len[7:0] -8'd1;endendendS_WR_WAIT: beginif(M_AXI_BVALID) beginreg_wr_status[1:0]  <= reg_wr_status[1:0] | M_AXI_BRESP[1:0];if(reg_w_last) beginwr_state          <= S_WR_DONE;end else beginwr_state          <= S_WA_WAIT;reg_wr_adrs[31:0] <= reg_wr_adrs[31:0] + 32'd2048;endendendS_WR_DONE: beginwr_state <= S_WR_IDLE;enddefault: beginwr_state <= S_WR_IDLE;endendcase
/*if(WR_FIFO_RE) beginreg_w_count[3:0]  <= reg_w_count[3:0] + 4'd1;endif(RD_FIFO_WE)beginreg_r_count[3:0]  <= reg_r_count[3:0] + 4'd1;endif(M_AXI_AWREADY & M_AXI_AWVALID) beginwr_chkdata <= 8'hEE;end else if(M_AXI_WSTRB[7] & M_AXI_WVALID) beginwr_chkdata <= WR_FIFO_DATA[63:56];endif(M_AXI_AWREADY & M_AXI_AWVALID) beginrd_chkdata <= 8'hDD;end else if(M_AXI_WSTRB[7] & M_AXI_WREADY) beginrd_chkdata <= WR_FIFO_DATA[63:56];endif(M_AXI_BVALID & M_AXI_BREADY) beginresp <= M_AXI_BRESP;end
*/endendendassign M_AXI_AWID         = 1'b0;assign M_AXI_AWADDR[31:0] = reg_wr_adrs[31:0];assign M_AXI_AWLEN[7:0]   = reg_w_len[7:0];assign M_AXI_AWSIZE[2:0]  = 2'b011;assign M_AXI_AWBURST[1:0] = 2'b01;assign M_AXI_AWLOCK       = 1'b0;assign M_AXI_AWCACHE[3:0] = 4'b0011;assign M_AXI_AWPROT[2:0]  = 3'b000;assign M_AXI_AWQOS[3:0]   = 4'b0000;assign M_AXI_AWUSER[0]    = 1'b1;assign M_AXI_AWVALID      = reg_awvalid;assign M_AXI_WDATA[63:0]  = WR_FIFO_DATA[63:0];
//  assign M_AXI_WSTRB[7:0]   = (reg_w_len[7:0] == 8'd0)?reg_w_stb[7:0]:8'hFF;
//  assign M_AXI_WSTRB[7:0]   = (wr_state == S_WD_PROC)?8'hFF:8'h00;assign M_AXI_WSTRB[7:0]   = (reg_wvalid & ~WR_FIFO_EMPTY)?8'hFF:8'h00;assign M_AXI_WLAST        = (reg_w_len[7:0] == 8'd0)?1'b1:1'b0;assign M_AXI_WUSER        = 1;assign M_AXI_WVALID       = reg_wvalid & ~WR_FIFO_EMPTY;
//  assign M_AXI_WVALID       = (wr_state == S_WD_PROC)?1'b1:1'b0;assign M_AXI_BREADY       = M_AXI_BVALID;assign WR_READY           = (wr_state == S_WR_IDLE)?1'b1:1'b0;//  assign WR_FIFO_RE         = (wr_state == S_WD_PROC)?M_AXI_WREADY:1'b0;localparam S_RD_IDLE  = 3'd0;localparam S_RA_WAIT  = 3'd1;localparam S_RA_START = 3'd2;localparam S_RD_WAIT  = 3'd3;localparam S_RD_PROC  = 3'd4;localparam S_RD_DONE  = 3'd5;reg [2:0]   rd_state;reg [31:0]  reg_rd_adrs;reg [31:0]  reg_rd_len;reg         reg_arvalid, reg_r_last;reg [7:0]   reg_r_len;assign RD_DONE = (rd_state == S_RD_DONE) ; // Read Statealways @(posedge ACLK or negedge ARESETN) beginif(!ARESETN) beginrd_state          <= S_RD_IDLE;reg_rd_adrs[31:0] <= 32'd0;reg_rd_len[31:0]  <= 32'd0;reg_arvalid       <= 1'b0;reg_r_len[7:0]    <= 8'd0;end else begincase(rd_state)S_RD_IDLE: beginif(RD_START) beginrd_state          <= S_RA_WAIT;reg_rd_adrs[31:0] <= RD_ADRS[31:0];reg_rd_len[31:0]  <= RD_LEN[31:0] -32'd1;endreg_arvalid     <= 1'b0;reg_r_len[7:0]  <= 8'd0;endS_RA_WAIT: beginif(~RD_FIFO_AFULL) beginrd_state          <= S_RA_START;endendS_RA_START: beginrd_state          <= S_RD_WAIT;reg_arvalid       <= 1'b1;reg_rd_len[31:11] <= reg_rd_len[31:11] -21'd1;if(reg_rd_len[31:11] != 21'd0) beginreg_r_last      <= 1'b0;reg_r_len[7:0]  <= 8'd255;end else beginreg_r_last      <= 1'b1;reg_r_len[7:0]  <= reg_rd_len[10:3];endendS_RD_WAIT: beginif(M_AXI_ARREADY) beginrd_state        <= S_RD_PROC;reg_arvalid     <= 1'b0;endendS_RD_PROC: beginif(M_AXI_RVALID) beginif(M_AXI_RLAST) beginif(reg_r_last) beginrd_state          <= S_RD_DONE;end else beginrd_state          <= S_RA_WAIT;reg_rd_adrs[31:0] <= reg_rd_adrs[31:0] + 32'd2048;endend else beginreg_r_len[7:0] <= reg_r_len[7:0] -8'd1;endendendS_RD_DONE:beginrd_state          <= S_RD_IDLE;endendcaseendend// Master Read Addressassign M_AXI_ARID         = 1'b0;assign M_AXI_ARADDR[31:0] = reg_rd_adrs[31:0];assign M_AXI_ARLEN[7:0]   = reg_r_len[7:0];assign M_AXI_ARSIZE[2:0]  = 3'b011;assign M_AXI_ARBURST[1:0] = 2'b01;assign M_AXI_ARLOCK       = 1'b0;assign M_AXI_ARCACHE[3:0] = 4'b0011;assign M_AXI_ARPROT[2:0]  = 3'b000;assign M_AXI_ARQOS[3:0]   = 4'b0000;assign M_AXI_ARUSER[0]    = 1'b1;assign M_AXI_ARVALID      = reg_arvalid;assign M_AXI_RREADY       = M_AXI_RVALID & ~RD_FIFO_FULL;assign RD_READY           = (rd_state == S_RD_IDLE)?1'b1:1'b0;assign RD_FIFO_WE         = M_AXI_RVALID;assign RD_FIFO_DATA[63:0] = M_AXI_RDATA[63:0];assign DEBUG[31:0] = {reg_wr_len[31:8],1'd0, wr_state[2:0], 1'd0, rd_state[2:0]};endmodule
module top(inout [14:0]DDR_addr,inout [2:0]DDR_ba,inout DDR_cas_n,inout DDR_ck_n,inout DDR_ck_p,inout DDR_cke,inout DDR_cs_n,inout [3:0]DDR_dm,inout [31:0]DDR_dq,inout [3:0]DDR_dqs_n,inout [3:0]DDR_dqs_p,inout DDR_odt,inout DDR_ras_n,inout DDR_reset_n,inout DDR_we_n,inout FIXED_IO_ddr_vrn,inout FIXED_IO_ddr_vrp,inout [53:0]FIXED_IO_mio,inout FIXED_IO_ps_clk,inout FIXED_IO_ps_porb,inout FIXED_IO_ps_srstb,output error);
wire rst_n;	
wire M_AXI_ACLK;
// Master Write Address
wire [0:0]  M_AXI_AWID;
wire [31:0] M_AXI_AWADDR;
wire [7:0]  M_AXI_AWLEN;    // Burst Length: 0-255
wire [2:0]  M_AXI_AWSIZE;   // Burst Size: Fixed 2'b011
wire [1:0]  M_AXI_AWBURST;  // Burst Type: Fixed 2'b01(Incremental Burst)
wire        M_AXI_AWLOCK;   // Lock: Fixed 2'b00
wire [3:0]  M_AXI_AWCACHE;  // Cache: Fiex 2'b0011
wire [2:0]  M_AXI_AWPROT;   // Protect: Fixed 2'b000
wire [3:0]  M_AXI_AWQOS;    // QoS: Fixed 2'b0000
wire [0:0]  M_AXI_AWUSER;   // User: Fixed 32'd0
wire        M_AXI_AWVALID;
wire        M_AXI_AWREADY;// Master Write Data
wire [63:0] M_AXI_WDATA;
wire [7:0]  M_AXI_WSTRB;
wire        M_AXI_WLAST;
wire [0:0]  M_AXI_WUSER;
wire        M_AXI_WVALID;
wire        M_AXI_WREADY;// Master Write Response
wire [0:0]   M_AXI_BID;
wire [1:0]   M_AXI_BRESP;
wire [0:0]   M_AXI_BUSER;
wire         M_AXI_BVALID;
wire         M_AXI_BREADY;// Master Read Address
wire [0:0]  M_AXI_ARID;
wire [31:0] M_AXI_ARADDR;
wire [7:0]  M_AXI_ARLEN;
wire [2:0]  M_AXI_ARSIZE;
wire [1:0]  M_AXI_ARBURST;
wire [1:0]  M_AXI_ARLOCK;
wire [3:0]  M_AXI_ARCACHE;
wire [2:0]  M_AXI_ARPROT;
wire [3:0]  M_AXI_ARQOS;
wire [0:0]  M_AXI_ARUSER;
wire        M_AXI_ARVALID;
wire        M_AXI_ARREADY;// Master Read Data 
wire [0:0]   M_AXI_RID;
wire [63:0]  M_AXI_RDATA;
wire [1:0]   M_AXI_RRESP;
wire         M_AXI_RLAST;
wire [0:0]   M_AXI_RUSER;
wire         M_AXI_RVALID;
wire         M_AXI_RREADY;(*mark_debug="true"*)wire wr_burst_data_req;
(*mark_debug="true"*)wire wr_burst_finish;
(*mark_debug="true"*)wire rd_burst_finish;
(*mark_debug="true"*)wire rd_burst_req;
(*mark_debug="true"*)wire wr_burst_req;
(*mark_debug="true"*)wire[9:0] rd_burst_len;
(*mark_debug="true"*)wire[9:0] wr_burst_len;
(*mark_debug="true"*)wire[31:0] rd_burst_addr;
(*mark_debug="true"*)wire[31:0] wr_burst_addr;
(*mark_debug="true"*)wire rd_burst_data_valid;
(*mark_debug="true"*)wire[63 : 0] rd_burst_data;
(*mark_debug="true"*)wire[63 : 0] wr_burst_data;mem_test
#(.MEM_DATA_BITS(64),.ADDR_BITS(27)
)
mem_test_m0
(.rst(~rst_n),                                 .mem_clk(M_AXI_ACLK),                             .rd_burst_req(rd_burst_req),               .wr_burst_req(wr_burst_req),               .rd_burst_len(rd_burst_len),               .wr_burst_len(wr_burst_len),               .rd_burst_addr(rd_burst_addr),        .wr_burst_addr(wr_burst_addr),        .rd_burst_data_valid(rd_burst_data_valid),  .wr_burst_data_req(wr_burst_data_req),  .rd_burst_data(rd_burst_data),  .wr_burst_data(wr_burst_data),    .rd_burst_finish(rd_burst_finish),   .wr_burst_finish(wr_burst_finish),.error(error)
); 
aq_axi_master u_aq_axi_master
(.ARESETN(rst_n),.ACLK(M_AXI_ACLK),.M_AXI_AWID(M_AXI_AWID),.M_AXI_AWADDR(M_AXI_AWADDR),     .M_AXI_AWLEN(M_AXI_AWLEN),.M_AXI_AWSIZE(M_AXI_AWSIZE),.M_AXI_AWBURST(M_AXI_AWBURST),.M_AXI_AWLOCK(M_AXI_AWLOCK),.M_AXI_AWCACHE(M_AXI_AWCACHE),.M_AXI_AWPROT(M_AXI_AWPROT),.M_AXI_AWQOS(M_AXI_AWQOS),.M_AXI_AWUSER(M_AXI_AWUSER),.M_AXI_AWVALID(M_AXI_AWVALID),.M_AXI_AWREADY(M_AXI_AWREADY),.M_AXI_WDATA(M_AXI_WDATA),.M_AXI_WSTRB(M_AXI_WSTRB),.M_AXI_WLAST(M_AXI_WLAST),.M_AXI_WUSER(M_AXI_WUSER),.M_AXI_WVALID(M_AXI_WVALID),.M_AXI_WREADY(M_AXI_WREADY),.M_AXI_BID(M_AXI_BID),.M_AXI_BRESP(M_AXI_BRESP),.M_AXI_BUSER(M_AXI_BUSER),.M_AXI_BVALID(M_AXI_BVALID),.M_AXI_BREADY(M_AXI_BREADY),.M_AXI_ARID(M_AXI_ARID),.M_AXI_ARADDR(M_AXI_ARADDR),.M_AXI_ARLEN(M_AXI_ARLEN),.M_AXI_ARSIZE(M_AXI_ARSIZE),.M_AXI_ARBURST(M_AXI_ARBURST),.M_AXI_ARLOCK(M_AXI_ARLOCK),.M_AXI_ARCACHE(M_AXI_ARCACHE),.M_AXI_ARPROT(M_AXI_ARPROT),.M_AXI_ARQOS(M_AXI_ARQOS),.M_AXI_ARUSER(M_AXI_ARUSER),.M_AXI_ARVALID(M_AXI_ARVALID),.M_AXI_ARREADY(M_AXI_ARREADY),.M_AXI_RID(M_AXI_RID),.M_AXI_RDATA(M_AXI_RDATA),.M_AXI_RRESP(M_AXI_RRESP),.M_AXI_RLAST(M_AXI_RLAST),.M_AXI_RUSER(M_AXI_RUSER),.M_AXI_RVALID(M_AXI_RVALID),.M_AXI_RREADY(M_AXI_RREADY),.MASTER_RST(~rst_n),.WR_START(wr_burst_req),.WR_ADRS({wr_burst_addr[28:0],3'd0}),.WR_LEN({wr_burst_len,3'd0}), .WR_READY(),.WR_FIFO_RE(wr_burst_data_req),.WR_FIFO_EMPTY(1'b0),.WR_FIFO_AEMPTY(1'b0),.WR_FIFO_DATA(wr_burst_data),.WR_DONE(wr_burst_finish),.RD_START(rd_burst_req),.RD_ADRS({rd_burst_addr[28:0],3'd0}),.RD_LEN({rd_burst_len,3'd0}), .RD_READY(),.RD_FIFO_WE(rd_burst_data_valid),.RD_FIFO_FULL(1'b0),.RD_FIFO_AFULL(1'b0),.RD_FIFO_DATA(rd_burst_data),.RD_DONE(rd_burst_finish),.DEBUG()                                         
);hdmi_out_wrapper ps_block
(.DDR_addr(DDR_addr),.DDR_ba(DDR_ba),.DDR_cas_n(DDR_cas_n),.DDR_ck_n(DDR_ck_n),.DDR_ck_p(DDR_ck_p),.DDR_cke(DDR_cke),.DDR_cs_n(DDR_cs_n),.DDR_dm(DDR_dm),.DDR_dq(DDR_dq),.DDR_dqs_n(DDR_dqs_n),.DDR_dqs_p(DDR_dqs_p),.DDR_odt(DDR_odt),.DDR_ras_n(DDR_ras_n),.DDR_reset_n(DDR_reset_n),.DDR_we_n(DDR_we_n),.FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),.FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),.FIXED_IO_mio(FIXED_IO_mio),.FIXED_IO_ps_clk(FIXED_IO_ps_clk),.FIXED_IO_ps_porb(FIXED_IO_ps_porb),.FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),.S00_AXI_araddr       (M_AXI_ARADDR          ),.S00_AXI_arburst      (M_AXI_ARBURST         ),.S00_AXI_arcache      (M_AXI_ARCACHE         ),.S00_AXI_arid         (M_AXI_ARID            ),.S00_AXI_arlen        (M_AXI_ARLEN           ),.S00_AXI_arlock       (M_AXI_ARLOCK          ),.S00_AXI_arprot       (M_AXI_ARPROT          ),.S00_AXI_arqos        (M_AXI_ARQOS           ),.S00_AXI_arready      (M_AXI_ARREADY         ),//.S00_AXI_arregion     (4'b0000               ),.S00_AXI_arsize       (M_AXI_ARSIZE          ),.S00_AXI_arvalid      (M_AXI_ARVALID         ),.S00_AXI_rdata        (M_AXI_RDATA           ),.S00_AXI_rid          (M_AXI_RID             ),.S00_AXI_rlast        (M_AXI_RLAST           ),.S00_AXI_rready       (M_AXI_RREADY          ),.S00_AXI_rresp        (M_AXI_RRESP           ),.S00_AXI_rvalid       (M_AXI_RVALID          ),.S00_AXI_awaddr       (M_AXI_AWADDR          ),.S00_AXI_awburst      (M_AXI_AWBURST         ),.S00_AXI_awcache      (M_AXI_AWCACHE         ),.S00_AXI_awid         (M_AXI_AWID            ),.S00_AXI_awlen        (M_AXI_AWLEN           ),.S00_AXI_awlock       (M_AXI_AWLOCK          ),.S00_AXI_awprot       (M_AXI_AWPROT          ),.S00_AXI_awqos        (M_AXI_AWQOS           ),.S00_AXI_awready      (M_AXI_AWREADY         ),//.S00_AXI_awregion     (4'b0000               ),.S00_AXI_awsize       (M_AXI_AWSIZE          ),.S00_AXI_awvalid      (M_AXI_AWVALID         ),.S00_AXI_bid          (M_AXI_BID             ),.S00_AXI_bready       (M_AXI_BREADY          ),.S00_AXI_bresp        (M_AXI_BRESP           ),.S00_AXI_bvalid       (M_AXI_BVALID          ),.S00_AXI_wdata        (M_AXI_WDATA           ),.S00_AXI_wlast        (M_AXI_WLAST           ),.S00_AXI_wready       (M_AXI_WREADY          ),.S00_AXI_wstrb        (M_AXI_WSTRB           ),.S00_AXI_wvalid       (M_AXI_WVALID          ),.peripheral_aresetn(rst_n),.FCLK_CLK0(M_AXI_ACLK),.axi_hp_clk(M_AXI_ACLK)
);
endmodule

3下板测试

在这里插入图片描述
在这里插入图片描述

读写分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/server/12135.html

相关文章

联想小新PRO16 ARM-7换固态硬盘和装双系统win11和ubuntu2022.04

联想小新PRO16 ARM-7换固态硬盘和装双系统win11和ubuntu2022.04 前言 记录一下其中的好几个坑。耗时4天&#xff0c;新旧硬盘拆拆卸卸的不止二十次。希望能给各位一点帮助。 步骤 1. 买硬盘 查看电脑后壳的S\N号&#xff0c;在联想官网上查找自己电脑的相关信息&#xff1a;…

【数据结构】排序

参考&#xff1a; 图解算法数据结构 leetcode题解 How to choose&#xff1a;如果对时间复杂度要求比较高并且键的分布范围比较广&#xff0c;可以使用归并排序、快速排序和堆排序。如果不能使用额外的空间&#xff0c;那么快速排序和堆排序都是不错的选择。如果规定了排序的键…

小程序线多点路图绘制

需求 当接口返回一连串地图坐标&#xff0c;需要根据这些坐标串联起来&#xff0c;形成一个线路图&#xff08;本次使用步行导航线路图&#xff09;。 思路 首先优先想到使用小程序Map组件的polyline属性去进行展示。但是我们发现直接使用该属性进行坐标绘制画出来的数据都是…

Android Studio Iguana | 2023.2.1配置优化

一. 前言 本篇文章记录最新版本的Android Studio的配置优化&#xff0c;写这篇文章的是由于电脑中的AS工具更新版本覆盖安装后&#xff0c;AS会经常卡死&#xff0c;Debug的时候也经常莫名其妙的断掉&#xff0c;非常影响工作效率&#xff0c;所以重新把配置环境整理一下&#…

前端实现将二进制文件流,并下载为excel文件

目录 一、关于二进制流二、项目实践三、常见问题及解决 一、关于二进制流 含义&#xff1a;二进制流是一种计算机文件格式&#xff0c;它的数据以二进制形式存储&#xff0c;与文本文件不同。 二进制文件可以包含任意类型的数据&#xff0c;例如&#xff1a;图像、音频、视频…

spring boot 基础案例【1】在页面上打印hellow world

1.在页面上打印hellow world 要在 Spring Boot 中打印 “Hello World” 并理解其代码&#xff0c;你可以创建一个简单的 Spring Boot 应用。这里&#xff0c;我将展示一个基本的示例并逐行解释代码的功能。 1.1 创建 Spring Boot 应用 首先&#xff0c;确保你已经安装了 Jav…

深入探索Android Service:后台服务的终极指南(上)

引言 在Android应用开发中&#xff0c;Service是一个至关重要的组件&#xff0c;它允许开发者执行后台任务&#xff0c;而无需用户界面。然而&#xff0c;Service的启动方式、生命周期管理以及与其他组件的交互&#xff0c;对于很多开发者来说仍然是一个难点。本文将深入剖析S…

表单插件——jquery.form.js

表单插件——jquery.form.js 表单插件(Form Plugin) 下载地址 :http://plugins.jquery.com/form/ 文件名:jquery.form.js version: 3.50.0-2014.02.05(最新版本) 功能:提供表单数据、重置表单项目、使用Ajax提交数据等 获取表单数据&#xff1a; 对于表单而言&#xff0c…