ZYNQ--PL读写PS端DDR数据

2024-04-24 08:12
文章标签 数据 读写 ps zynq ddr pl

本文主要是介绍ZYNQ--PL读写PS端DDR数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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下板测试

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

读写分析

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

这篇关于ZYNQ--PL读写PS端DDR数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931208

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

10. 文件的读写

10.1 文本文件 操作文件三大类: ofstream:写操作ifstream:读操作fstream:读写操作 打开方式解释ios::in为了读文件而打开文件ios::out为了写文件而打开文件,如果当前文件存在则清空当前文件在写入ios::app追加方式写文件ios::trunc如果文件存在先删除,在创建ios::ate打开文件之后令读写位置移至文件尾端ios::binary二进制方式

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav