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

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

读写分析

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/643495.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“三三裂变”,实体书营销实操细节分享……

“三三裂变”实操细节 一、实验结果 “三三裂变”的实验,结果比较好。就是我们大概有300人报名,但实际行动的只有109人,大概有103人都完成了三个人的目标,也就是说我们通过109人裂变了475人,利润率是1:4.5左右,整个裂变的效率还是可以的,也就是说: 如果你用这种方法有…

MATLAB 数据类型

MATLAB 数据类型 MATLAB 不需要任何类型声明或维度语句。每当 MATLAB 遇到一个新的变量名&#xff0c;它就创建变量并分配适当的内存空间。 如果变量已经存在&#xff0c;那么MATLAB将用新内容替换原始内容&#xff0c;并在必要时分配新的存储空间。 例如&#xff0c; Tota…

哪些因素影响了PCB电路板切割精度?

PCB电路板切割是电子制造过程中一个至关重要的环节&#xff0c;其精度对后续工序的质量和效率具有决定性影响。因此&#xff0c;了解影响PCB电路板切割精度的原因&#xff0c;对于提高电子产品的质量和生产效率具有重要意义。 1. PCB分板机稳定性 PCB分板机的性能直接影响到切…

STM32点灯大师(中断法)

一、使用CubeMX配置 新增加了RCC进行配置 二、代码 需要重写虚函数&#xff0c;给自己引用

架构师核心-云计算云上实战(云计算基础、云服务器ECS、云设施实战、云上高并发Web架构)

文章目录 云计算基础1. 概念1. 云平台优势2. 公有云3. 私有云4. IaaS、PaaS、SaaS 2. 云设施1. 概览2. 核心组件 云服务器ECS1. ECS介绍1. 简介2. 组件3. 概念4. 图解5. 规格6. 场景 2. ECS服务器开通1. 开通服务器2. 连接服务器 3. 云部署准备1. 1Panel介绍2. 安装1Panel3.安全…

【Camera KMD ISP SubSystem笔记】CRM V4L2驱动模型

1. CRM为主设备 /dev/video0&#xff0c;先创建 v4l2_device 设备&#xff0c;再创建 video_device 设备&#xff0c;最后创建 media_device 设备/dev/media0 v4l2_device的mdev指向media_device&#xff0c;v4l2_device的entity链接到media_device的entities上&#xff08…

Linux RTC驱动深入解析

目录标题 实时时钟&#xff08;RTC&#xff09;基础Linux内核中的RTC框架RTC设备类设备树&#xff08;Device Tree&#xff09; 编写Linux RTC驱动1. 初始化和注册2. RTC设备操作函数3. 清理函数 测试RTC驱动驱动开发的挑战总结 在许多嵌入式系统和服务器上&#xff0c;实时时钟…

AI时代的GPU集群网络算力分析

浅谈GPU集群网络、集群规模和集群算力 引言在生成式AI&#xff08;GenAI&#xff09;和大模型时代&#xff0c;不仅需要关注单个GPU卡的算力&#xff0c;更要关注GPU集群的总有效算力。单个GPU卡的有效算力可以通过该卡的峰值算力来测算&#xff0c;例如&#xff0c;对于Nvidia…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之五 简单进行车牌检测和识别

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之五 简单进行车牌检测和识别 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之五 简单进行车牌检测和识别 一、简单介绍 二、简单进行车牌检测和识别实现原理 …

【笔记django】创建一个app

创建app 错误 raise ImproperlyConfigured( django.core.exceptions.ImproperlyConfigured: Cannot import rules. Check that dvadmin.rules.apps.RulesConfig.name is correct.原因 刚创建的rules的app被手动移动到了dvadmin目录下 而dvadmin/rules/apps.py的内容还是&…

S-Edge网关:柔性部署,让物联网接入更统一

S-Edge网关是什么&#xff1f; 网关是在实际物理世界与虚拟网络世界相连接的交叉点&#xff0c;为了让这个交叉点尽可能的复用&#xff0c;无需每种设备都配套一种连接方式&#xff0c;边缘网关主要就是用于传感器等物理设备与网络实现数据交互的通用设备&#xff0c;也称为物…

【STM32+HAL+Proteus】系列学习教程4---GPIO输入模式(独立按键)

实现目标 1、掌握GPIO 输入模式控制 2、学会STM32CubeMX配置GPIO的输入模式 3、具体目标&#xff1a;1、按键K1按下&#xff0c;LED1点亮&#xff1b;2、按键K2按下&#xff0c;LED1熄灭&#xff1b;2、按键K3按下&#xff0c;LED2状态取反&#xff1b; 一、STM32 GPIO 输入…