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