ZYNQ--PS_PL交互(AXI_HP)

AXI_HP接口

通过AXI_HP接口,可直接通过AXI_FULL协议向DDR中通过DMA传输数据。

BD设计

在这里插入图片描述
AXI_HP接口设置
在这里插入图片描述
AXI_Master代码

module axi_full_master #
	(
		parameter  			C_M_TARGET_SLAVE_BASE_ADDR	= 32'h40000000,
		parameter integer	C_M_AXI_BURST_LEN			= 16,
		parameter integer	C_M_AXI_ID_WIDTH			= 1,
		parameter integer	C_M_AXI_ADDR_WIDTH			= 32,
		parameter integer	C_M_AXI_DATA_WIDTH			= 64,
		parameter integer	C_M_AXI_AWUSER_WIDTH		= 0,
		parameter integer	C_M_AXI_ARUSER_WIDTH		= 0,
		parameter integer	C_M_AXI_WUSER_WIDTH			= 0,
		parameter integer	C_M_AXI_RUSER_WIDTH			= 0,
		parameter integer	C_M_AXI_BUSER_WIDTH			= 0
	)
    //编码测试       
	(
		input 	wire  								M_AXI_ACLK			,
		input 	wire  								M_AXI_ARESETN		,    
		output 	wire [C_M_AXI_ID_WIDTH-1 : 0] 		M_AXI_AWID			,
		output 	wire [C_M_AXI_ADDR_WIDTH-1 : 0]     M_AXI_AWADDR		,
		output 	wire [7 : 0] 						M_AXI_AWLEN			,
		output 	wire [2 : 0] 						M_AXI_AWSIZE		,
		output 	wire [1 : 0] 						M_AXI_AWBURST		,
		output 	wire  								M_AXI_AWLOCK		,
		output 	wire [3 : 0] 						M_AXI_AWCACHE		,
		output 	wire [2 : 0] 						M_AXI_AWPROT		,
		output 	wire [3 : 0] 						M_AXI_AWQOS			,
		output 	wire [C_M_AXI_AWUSER_WIDTH-1 : 0] 	M_AXI_AWUSER		,
		output 	wire  								M_AXI_AWVALID		,
		input 	wire  								M_AXI_AWREADY		,
		output 	wire [C_M_AXI_DATA_WIDTH-1 : 0] 	M_AXI_WDATA			,
		output 	wire [C_M_AXI_DATA_WIDTH/8-1 : 0] 	M_AXI_WSTRB			,
		output 	wire  								M_AXI_WLAST			,
		output 	wire [C_M_AXI_WUSER_WIDTH-1 : 0] 	M_AXI_WUSER			,
		output 	wire  								M_AXI_WVALID		,
		input 	wire  								M_AXI_WREADY		,
		input 	wire [C_M_AXI_ID_WIDTH-1 : 0] 		M_AXI_BID			,
		input 	wire [1 : 0] 						M_AXI_BRESP			,
		input 	wire [C_M_AXI_BUSER_WIDTH-1 : 0] 	M_AXI_BUSER			,
		input 	wire  								M_AXI_BVALID		,
		output 	wire  								M_AXI_BREADY		,
		output 	wire [C_M_AXI_ID_WIDTH-1 : 0] 		M_AXI_ARID			,
		output 	wire [C_M_AXI_ADDR_WIDTH-1 : 0] 	M_AXI_ARADDR		,
		output 	wire [7 : 0] 						M_AXI_ARLEN			,
		output 	wire [2 : 0] 						M_AXI_ARSIZE		,
		output 	wire [1 : 0] 						M_AXI_ARBURST		,
		output 	wire  								M_AXI_ARLOCK		,
		output 	wire [3 : 0] 						M_AXI_ARCACHE		,
		output 	wire [2 : 0] 						M_AXI_ARPROT		,
		output 	wire [3 : 0] 						M_AXI_ARQOS			,
		output 	wire [C_M_AXI_ARUSER_WIDTH-1 : 0] 	M_AXI_ARUSER		,	
		output 	wire  								M_AXI_ARVALID		,
		input 	wire  								M_AXI_ARREADY		,
		input 	wire [C_M_AXI_ID_WIDTH-1 : 0] 		M_AXI_RID			,
		input 	wire [C_M_AXI_DATA_WIDTH-1 : 0] 	M_AXI_RDATA			,
		input 	wire [1 : 0] 						M_AXI_RRESP			,
		input 	wire  								M_AXI_RLAST			,
		input 	wire [C_M_AXI_RUSER_WIDTH-1 : 0] 	M_AXI_RUSER			,
		input 	wire  								M_AXI_RVALID		,
		output 	wire  								M_AXI_RREADY
	);

function integer clogb2(input [4:0] data_width);
	begin
		for(clogb2 = 0;data_width > 0;clogb2 = clogb2 + 1)begin
			data_width = data_width >> 1;
		end
	end
endfunction

/* parameter */
parameter 	P_BYTE_NUM_WIDTH = clogb2((C_M_AXI_DATA_WIDTH/8) - 1)  ; //假设数据位宽64,7需要三个位宽表示
parameter   P_BYTE_NUM       = C_M_AXI_DATA_WIDTH/8 ;

/* output reg */
reg [C_M_AXI_ID_WIDTH-1 : 0] 		ro_M_AXI_AWID		;
reg [C_M_AXI_ADDR_WIDTH-1 : 0]     	ro_M_AXI_AWADDR		;
reg [7 : 0] 						ro_M_AXI_AWLEN		;
reg [2 : 0] 						ro_M_AXI_AWSIZE		;
reg [1 : 0] 						ro_M_AXI_AWBURST	;
reg  								ro_M_AXI_AWLOCK		;
reg [3 : 0] 						ro_M_AXI_AWCACHE	;
reg [2 : 0] 						ro_M_AXI_AWPROT		;
reg [3 : 0] 						ro_M_AXI_AWQOS		;
reg [C_M_AXI_AWUSER_WIDTH-1 : 0] 	ro_M_AXI_AWUSER		;
reg  								ro_M_AXI_AWVALID	;
reg [C_M_AXI_DATA_WIDTH-1 : 0] 		ro_M_AXI_WDATA		;
reg [C_M_AXI_DATA_WIDTH/8-1 : 0] 	ro_M_AXI_WSTRB		;
reg  								ro_M_AXI_WLAST		;
reg [C_M_AXI_WUSER_WIDTH-1 : 0] 	ro_M_AXI_WUSER		;
reg  								ro_M_AXI_WVALID		;
reg  								ro_M_AXI_BREADY		;
reg [C_M_AXI_ID_WIDTH-1 : 0] 		ro_M_AXI_ARID		;
reg [C_M_AXI_ADDR_WIDTH-1 : 0] 		ro_M_AXI_ARADDR		;
reg [7 : 0] 						ro_M_AXI_ARLEN		;
reg [2 : 0] 						ro_M_AXI_ARSIZE		;
reg [1 : 0] 						ro_M_AXI_ARBURST	;
reg  								ro_M_AXI_ARLOCK		;
reg [3 : 0] 						ro_M_AXI_ARCACHE	;
reg [2 : 0] 						ro_M_AXI_ARPROT		;
reg [3 : 0] 						ro_M_AXI_ARQOS		;
reg [C_M_AXI_ARUSER_WIDTH-1 : 0] 	ro_M_AXI_ARUSER		;
reg  								ro_M_AXI_ARVALID	;
reg  								ro_M_AXI_RREADY		;

/* input reg */
reg [C_M_AXI_DATA_WIDTH-1 : 0] 		ri_M_AXI_RDATA		;
/* user reg */
reg [7:0]							write_cnt			;
reg [7:0]							read_cnt			;
reg									check_err			;

/* wire */
wire AW_action	;
wire W_action	; 
wire WB_action	;
wire AR_action	;
wire R_action	;

assign M_AXI_AWID		= ro_M_AXI_AWID 	;
assign M_AXI_AWADDR		= ro_M_AXI_AWADDR 	;
assign M_AXI_AWLEN		= ro_M_AXI_AWLEN 	;
assign M_AXI_AWSIZE		= ro_M_AXI_AWSIZE 	;
assign M_AXI_AWBURST	= ro_M_AXI_AWBURST 	;
assign M_AXI_AWLOCK		= ro_M_AXI_AWLOCK 	;
assign M_AXI_AWCACHE	= ro_M_AXI_AWCACHE 	;
assign M_AXI_AWPROT		= ro_M_AXI_AWPROT 	;
assign M_AXI_AWQOS		= ro_M_AXI_AWQOS 	;
assign M_AXI_AWUSER		= ro_M_AXI_AWUSER 	;
assign M_AXI_AWVALID	= ro_M_AXI_AWVALID 	;
assign M_AXI_WDATA		= ro_M_AXI_WDATA 	;
assign M_AXI_WSTRB		= ro_M_AXI_WSTRB 	;
assign M_AXI_WLAST		= ro_M_AXI_WLAST 	;
assign M_AXI_WUSER		= ro_M_AXI_WUSER 	;
assign M_AXI_WVALID		= ro_M_AXI_WVALID 	;
assign M_AXI_BREADY		= ro_M_AXI_BREADY 	;
assign M_AXI_ARID		= ro_M_AXI_ARID 	;
assign M_AXI_ARADDR		= ro_M_AXI_ARADDR 	;
assign M_AXI_ARLEN		= ro_M_AXI_ARLEN 	;
assign M_AXI_ARSIZE		= ro_M_AXI_ARSIZE 	;
assign M_AXI_ARBURST	= ro_M_AXI_ARBURST 	;
assign M_AXI_ARLOCK		= ro_M_AXI_ARLOCK 	;
assign M_AXI_ARCACHE	= ro_M_AXI_ARCACHE 	;
assign M_AXI_ARPROT		= ro_M_AXI_ARPROT 	;
assign M_AXI_ARQOS		= ro_M_AXI_ARQOS 	;
assign M_AXI_ARUSER		= ro_M_AXI_ARUSER 	;
assign M_AXI_ARVALID	= ro_M_AXI_ARVALID 	;
assign M_AXI_RREADY		= ro_M_AXI_RREADY 	;
assign AW_action 		= M_AXI_AWVALID & M_AXI_AWREADY;
assign W_action  		= M_AXI_WVALID  & M_AXI_WREADY ;
assign WB_action 		= M_AXI_BVALID  & M_AXI_BREADY ;
assign AR_action 		= M_AXI_ARVALID & M_AXI_ARREADY;
assign R_action  		= M_AXI_RVALID  & M_AXI_RREADY ;


always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN) begin
		ro_M_AXI_AWID 		<= 'd0;
		ro_M_AXI_AWADDR 	<= C_M_TARGET_SLAVE_BASE_ADDR;
		ro_M_AXI_AWLEN 		<= C_M_AXI_BURST_LEN - 1;
		ro_M_AXI_AWSIZE 	<= P_BYTE_NUM_WIDTH;
		ro_M_AXI_AWBURST 	<= 2'b01;
		ro_M_AXI_AWLOCK 	<= 'd0;
		ro_M_AXI_AWCACHE 	<= 'd2;
		ro_M_AXI_AWPROT 	<= 'd0;
		ro_M_AXI_AWQOS 		<= 'd0;
		ro_M_AXI_AWUSER 	<= 'd0;
		ro_M_AXI_AWVALID 	<= 'd1;
	end
	else if(AW_action) begin
		ro_M_AXI_AWID 		<= 'd0;
		ro_M_AXI_AWADDR 	<= 'd0;
		ro_M_AXI_AWLEN 		<= 'd0;
		ro_M_AXI_AWSIZE 	<= 'd0;
		ro_M_AXI_AWBURST 	<= 'd0;
		ro_M_AXI_AWLOCK 	<= 'd0;
		ro_M_AXI_AWCACHE 	<= 'd0;
		ro_M_AXI_AWPROT 	<= 'd0;
		ro_M_AXI_AWQOS 		<= 'd0;
		ro_M_AXI_AWUSER 	<= 'd0;
		ro_M_AXI_AWVALID 	<= 'd0;
	end
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		write_cnt <= 'd0;
	else if(write_cnt == (C_M_AXI_BURST_LEN - 1) && W_action)
		write_cnt <= 'd0;
	else if(W_action)
		write_cnt <= write_cnt + 1;
	else
		write_cnt <= write_cnt;
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)begin
		ro_M_AXI_WSTRB	 <= 'd0;  
		ro_M_AXI_WUSER	 <= 'd0; 
		ro_M_AXI_WVALID	 <= 'd0; 
	end
	else if(M_AXI_WLAST)begin
		ro_M_AXI_WSTRB	 <= 'd0; 
		ro_M_AXI_WUSER	 <= 'd0; 
		ro_M_AXI_WVALID	 <= 'd0; 		
	end
	else if(AW_action)begin
		ro_M_AXI_WSTRB	 <= {P_BYTE_NUM{1'd1}}; 
		ro_M_AXI_WUSER	 <= 'd0; 
		ro_M_AXI_WVALID	 <= 'd1; 		
	end
	else begin
		ro_M_AXI_WSTRB	 <= ro_M_AXI_WSTRB ; 
		ro_M_AXI_WUSER	 <= ro_M_AXI_WUSER ; 
		ro_M_AXI_WVALID	 <= ro_M_AXI_WVALID; 		
	end
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		ro_M_AXI_WDATA <= 'd0;
	else if(M_AXI_WLAST && W_action)
		ro_M_AXI_WDATA <= 'd0;
	else if(W_action)
		ro_M_AXI_WDATA <= ro_M_AXI_WDATA + 1;
	else
		ro_M_AXI_WDATA <= ro_M_AXI_WDATA;
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		ro_M_AXI_WLAST <= 'd0;
	else if(ro_M_AXI_WLAST && W_action)
		ro_M_AXI_WLAST <= 'd0;
	else if(write_cnt == (C_M_AXI_BURST_LEN - 2) && W_action)
		ro_M_AXI_WLAST <= 'd1;
	else
		ro_M_AXI_WLAST <= ro_M_AXI_WLAST;	
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		ro_M_AXI_BREADY <= 'd0;
	else if(WB_action)
		ro_M_AXI_BREADY <= 'd0;
	else if(ro_M_AXI_WLAST && W_action)
		ro_M_AXI_BREADY <= 'd1;
	else
		ro_M_AXI_BREADY <= ro_M_AXI_BREADY;	
end
/*
always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)begin
		ro_M_AXI_ARID	  <= 'd0 ;
		ro_M_AXI_ARADDR	  <= 'd0 ;
		ro_M_AXI_ARLEN	  <= 'd0 ;
		ro_M_AXI_ARSIZE	  <= 'd0 ;
		ro_M_AXI_ARBURST  <= 'd0 ;
		ro_M_AXI_ARLOCK	  <= 'd0 ;
		ro_M_AXI_ARCACHE  <= 'd0 ;
		ro_M_AXI_ARPROT	  <= 'd0 ;
		ro_M_AXI_ARQOS	  <= 'd0 ;
		ro_M_AXI_ARUSER	  <= 'd0 ;
		ro_M_AXI_ARVALID  <= 'd0 ; 
	end
	else if(AR_action)begin
		ro_M_AXI_ARID	  <= 'd0 ;
		ro_M_AXI_ARADDR	  <= 'd0 ;
		ro_M_AXI_ARLEN	  <= 'd0 ;
		ro_M_AXI_ARSIZE	  <= 'd0 ;
		ro_M_AXI_ARBURST  <= 'd0 ;
		ro_M_AXI_ARLOCK	  <= 'd0 ;
		ro_M_AXI_ARCACHE  <= 'd0 ;
		ro_M_AXI_ARPROT	  <= 'd0 ;
		ro_M_AXI_ARQOS	  <= 'd0 ;
		ro_M_AXI_ARUSER	  <= 'd0 ;
		ro_M_AXI_ARVALID  <= 'd0 ; 	
	end
	else if(WB_action)begin
		ro_M_AXI_ARID	  <= 'd0 ;
		ro_M_AXI_ARADDR	  <= C_M_TARGET_SLAVE_BASE_ADDR ;
		ro_M_AXI_ARLEN	  <= C_M_AXI_BURST_LEN - 1;
		ro_M_AXI_ARSIZE	  <= P_BYTE_NUM_WIDTH ;
		ro_M_AXI_ARBURST  <= 2'b01 ;
		ro_M_AXI_ARLOCK	  <= 'd0 ;
		ro_M_AXI_ARCACHE  <= 4'd2 ;
		ro_M_AXI_ARPROT	  <= 'd0 ;
		ro_M_AXI_ARQOS	  <= 'd0 ;
		ro_M_AXI_ARUSER	  <= 'd0 ;
		ro_M_AXI_ARVALID  <= 'd1 ;
	end
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		ro_M_AXI_RREADY <= 'd0;
	else if(M_AXI_RLAST && R_action)
		ro_M_AXI_RREADY <= 'd0;
	else if(AR_action)
		ro_M_AXI_RREADY <= 'd1;
	else
		ro_M_AXI_RREADY <= ro_M_AXI_RREADY;
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		read_cnt <= 'd0;
	else if(M_AXI_RLAST && R_action)
		read_cnt <= 'd0;
	else if(R_action)
		read_cnt <= read_cnt + 1;
	else
		read_cnt <= read_cnt;	
end

always @(posedge M_AXI_ACLK or negedge M_AXI_ARESETN) begin
	if(!M_AXI_ARESETN)
		check_err <= 'd0;
	else if(R_action)begin
		if(read_cnt != M_AXI_RDATA)
			check_err <= 'd1;
	end
	else
		check_err <= 'd0;
end
*/
endmodule

注意顶层中必须把Axi_Master模块数据位宽,突发长度,基址,SIZE设置对应好
在这里插入图片描述
在PS中进行读:


#include "xparameters.h"
#include "xil_io.h"
#include "xil_cache.h"

int main()
{
	u64 data[16];
	int i;
	Xil_DCacheDisable();
	Xil_ICacheDisable();
	while(1){
	for(i=0;i<16;i++)
		data[i] = Xil_In64(XPAR_PS7_RAM_0_S_AXI_BASEADDR + i*8);
	}
	return 0;
}

在这里插入图片描述
读出的数据正确

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值