ZYNQ--AXI_DMA使用

手册阅读

在这里插入图片描述

典型连接图

在这里插入图片描述

SG模式关闭时的寄存器地址

在这里插入图片描述

SG模式开启时的寄存器地址

在这里插入图片描述
在这里插入图片描述
关于各个bit的功能,具体看数据手册。

BD设计

通过PL侧设计一个流输出接口的主机(可以借助打包一个stream流接口的主机
),将流数据写入到DMA在转换为AXI_FULL类型送入到PS端的HP接口;PS端通过GP接口输出控制DMA的寄存器。

在这里插入图片描述
Axi_Stream_Master的代码如下


`timescale 1 ns / 1 ps

module Axi_Stream_Master#
(
	parameter   integer                                 C_M_AXIS_TDATA_WIDTH = 64,
	parameter   integer                                 C_M_START_COUNT	     = 32
)
(
	input       wire                                    M_AXIS_ACLK     ,
	input       wire                                    M_AXIS_ARESETN  ,
	output      wire                                    M_AXIS_TVALID   ,    
	output      wire [C_M_AXIS_TDATA_WIDTH-1 : 0]       M_AXIS_TDATA    ,		
	output      wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0]   M_AXIS_TSTRB    ,
	output      wire                                    M_AXIS_TLAST    ,
	input       wire                                    M_AXIS_TREADY
);

reg                                         ro_M_AXIS_TVALID    ;
reg  [C_M_AXIS_TDATA_WIDTH-1 : 0]           ro_M_AXIS_TDATA     ;                             
reg  [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0]       ro_M_AXIS_TSTRB     ;	
reg                                         ro_M_AXIS_TLAST     ;

reg                                         wr_action           ;
reg   [5:0]                                 wr_cnt              ;

assign  M_AXIS_TVALID  = ro_M_AXIS_TVALID;    
assign  M_AXIS_TDATA   = ro_M_AXIS_TDATA ;
assign  M_AXIS_TSTRB   = ro_M_AXIS_TSTRB ;
assign  M_AXIS_TLAST   = ro_M_AXIS_TLAST ;
assign  wr_action      = M_AXIS_TVALID & M_AXIS_TREADY ;

always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
    if(!M_AXIS_ARESETN)
        wr_cnt <= 'd0;
    else if(wr_cnt == 511)
        wr_cnt <= 'd0;
    else if(wr_action)
        wr_cnt <= wr_cnt + 1;
    else
        wr_cnt <= wr_cnt;
end

always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
    if(!M_AXIS_ARESETN)
        ro_M_AXIS_TVALID <= 'd0;
    else if(wr_cnt == 511)
        ro_M_AXIS_TVALID <= 'd0;
    else if(wr_cnt == 0)
        ro_M_AXIS_TVALID <= 'd1;
    else
        ro_M_AXIS_TVALID <= ro_M_AXIS_TVALID;    
end

always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
    if(!M_AXIS_ARESETN)begin
        ro_M_AXIS_TDATA <= 'd0;  
        ro_M_AXIS_TSTRB <= 'd0;
    end
    else if(ro_M_AXIS_TLAST && wr_action)begin
        ro_M_AXIS_TDATA <= 'd0;
        ro_M_AXIS_TSTRB <= 'd0;        
    end
    else if(wr_action)begin
        ro_M_AXIS_TDATA <= ro_M_AXIS_TDATA + 1;
        ro_M_AXIS_TSTRB <= 8'b1111_1111;       
    end
    else begin
        ro_M_AXIS_TDATA <= ro_M_AXIS_TDATA; 
        ro_M_AXIS_TSTRB <= ro_M_AXIS_TSTRB;        
    end   
end

always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
    if(!M_AXIS_ARESETN)
        ro_M_AXIS_TLAST <= 'd0;
    else if(wr_cnt == 511 && wr_action == 1)
        ro_M_AXIS_TLAST <= 'd0;
    else if(wr_cnt == 510 && wr_action == 1)
        ro_M_AXIS_TLAST <= 'd1;
    else
        ro_M_AXIS_TLAST <= ro_M_AXIS_TLAST;       
end
endmodule

PS端设计

对于DMA寄存器的控制

在BD中,有ZYNQ核引出GP口去控制DMA,映射到PS端就是DMA设备。对于DMA寄存器的操作就是DMA的初始化等一系列操作。下图是GP所分配的地址空间,与PS端DMA设备的基址一致。
在这里插入图片描述
在这里插入图片描述

对DMA进行初始化

int Axi_Dma_Initial(XAxiDma* xdma)
{
	int status = 0;
	XAxiDma_Config *xaxidmafig;
	xaxidmafig = XAxiDma_LookupConfig(XPAR_AXI_DMA_0_DEVICE_ID);
	status = XAxiDma_CfgInitialize(xdma,xaxidmafig);
	if(status != XST_SUCCESS)
	{
		return XST_FAILURE;
	}
	XAxiDma_Reset(xdma);
	while(!XAxiDma_ResetIsDone(xdma));
	return status;
}
    	status = XAxiDma_SimpleTransfer(xdma,XPAR_PS7_RAM_0_S_AXI_BASEADDR,512,XAXIDMA_DEVICE_TO_DMA);
    	usleep(5000);

数据分析:在PL侧写入了512个64bit的数据,等于512Byte个字节。
由于BASE_ADDRESS=0x00000000,所以HIGH_ADDRESS=0x00000200,也就是512个字节单位。
在这里插入图片描述
从图中可以看出,起始数据从0x0000000开始,也就是少写了8个64bit数据。再看末尾地址,也是对应的上8个64位地址,所以写数据操作整体没有问题。但开始会丢失8个数据。
目前这个BUG还没有找到原因,希望有大神能有解答。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Zynq SoC 上,AXI DMA(Direct Memory Access)是一种能够在外设和存储器之间进行高速数据传输的IP核。Cyclic DMA 模式允许通过循环传输数据,从而实现连续的数据流。下面是一些关于在 Zynq SoC 上编程 AXI DMA 的基本步骤: 1. 配置 AXI DMA IP:首先,在 Vivado 中配置和实例化 AXI DMA IP 核,并连接到 Zynq SoC 的 PS(Processing System)部分。确保正确连接 AXI DMA 的信号和端口,包括数据输入/输出端口、中断线和控制寄存器。 2. 设置 DMA 控制寄存器:使用 AXI DMA 的控制寄存器来配置 DMA 的工作模式和参数。在 Cyclic DMA 模式下,你需要设置循环传输模式,并指定传输的数据长度和起始地址。 3. 配置 DMA 缓冲区:为 DMA 设置输入和输出缓冲区。这些缓冲区将用于在外设和存储器之间传输数据。 4. 启动 DMA 传输:通过设置 AXI DMA 控制寄存器中的位来启动数据传输。在 Cyclic DMA 模式下,你可以选择是否在每次传输完成后自动重启传输。 5. 处理中断:如果需要,在 AXI DMA 完成传输时,你可以使用中断机制来通知处理器。在中断处理程序中,你可以执行必要的操作,如处理传输的数据或触发下一次传输。 需要注意的是,以上步骤只是一个基本的框架,具体的实现可能因应用需求而有所差异。你可以参考 Xilinx 提供的文档和示例代码来详细了解 AXI DMA 的编程和配置方法。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值