ZYNQ AXIDMA詳解(一)

一、基本概念

AXIDMA: 官方解釋是爲內存與AXI4-Stream外設之間提供高帶寬的直接存儲訪問,其可選的scatter/gather功能可將CPU從數據搬移任務中解放出來。在ZYNQ中,AXIDMA就是FPGA訪問DDR3的橋樑,不過該過程受ARM的監控和管理。使用其他的IP(也是AXI4-Stream轉AXI4-MM)可以不需要ARM管理,但是在SOC開發時是危險的,這是後話了。

如圖1所示,AXIDMA IP有6個接口,S_AXI_LITE是ARM配置dma寄存器的接口,M_AXI_SG是從(往)存儲器加載(上傳)buffer descriptor的接口,剩下4個構成兩對接口,S2MM和MM2S表示數據的方向,AXI是存儲器一側的接口,AXIS是FPGA一側的接口。AXIDMA IP和ARM自帶的DMA是很像的,只不過不具備從存儲器到存儲器的功能,當然啦如果將S2MM和MM2S的AXIS接口直接連接也是可以實現的。image

圖1

 

scatter gather模式:AXIDMA工作模式分爲兩種,分別是Direct Register Mode和Scatter/Gather Mode。

從圖2可以看出,Direct Register Mode具備DMA的基本功能,除了控制寄存器和狀態寄存器之外,給出源(目的)地址和傳輸長度之後就可以開啓一次傳輸了。Direct Register Mode的特點(也是缺點)是配置完一次寄存器之後只能完成存儲器連續地址空間的讀寫,如果有需求往不同地址空間搬運數據的話,那就需要重新配置寄存器開啓一次新的傳輸。

image

圖2

 

鑑於Direct Register Mode的不足,發展出了Scatter/Gather Mode,其工作方式要複雜得多。Scatter/Gather Mode把關於傳輸的基本參數(比如起始地址、傳輸長度、包信息等)存儲在存儲器中,一套參數稱之爲Buffer Descriptor(簡稱BD),在工作過程中通過上面提到的SG接口來加載BD並且更新BD中的狀態。從圖3可以看出,Scatter/Gather Mode下的寄存器列表中沒有了Address、Length相關的寄存器了,取而代之的是CURDESC、TAILDESC。

image

圖3

 

非多通道模式下的BD如圖4所示,主要有四部分內容:NXTDESC、BUFFER_ADDRESS、CONTROL、STATUS。NXTDESC指定下一個BD的地址,由此可以構成成一個BD鏈條,AXIDMA可以順着該鏈條依次fetch BD。BUFFER_ADDRESS指定傳輸的源(目的)地址,CONTROL主要是length和包信息,STATUS反應該BD完成後的狀態。

image

圖4

 

AXIDMA啓動後,首先從CURDESC指定的位置加載BD,完成當前BD的傳輸任務後根據BD鏈條找到下一個BD,依次完成BD指定的傳輸,直到遇到TAILDESC指定的BD才停止。

Multichannel DMA:在Scatter/Gather Mode下S2MM和MM2S都支持多個通道,Direct Register Mode不支持多通道。如圖5所示,多通道相比非多通道,BD中增加了TID和TDEST,用來區分不同的通道。

image

image

 

圖5

 

多通道模式支持2D-Transfer,如圖6所示,從buffer address開始,讀寫HSIZE後跳過剩餘的Stride - HSIZE個地址單元,下一次從buffer address + Stride位置開始,此過程迭代VSIZE次後結束該BD指定的傳輸。

image

圖6

 

如圖7所示,Multichannel模式下,S2MM有16個通道,每個通道都有獨立的CURDESC和TAILDESC寄存器,而CR和SR則是共用的。令人費解的是,從對稱的角度來說,MM2S理應每個通道也要有獨立的CURDESC和TAILDESC寄存器,但事實是多個通道共用一份。手冊上的說法是:

MM2S is similar to normal AXI DMA operation. When MM2S_CURDESC and
MM2S_TAILDESC are programmed by software, AXI DMA fetches a chain of descriptors and
processes until it reaches tail descriptor. In AXI DMA, TDEST, TID, and TUSER fields are
assumed to remain constant for an entire packet as defined in the descriptors. That is, each
packet transfer across a logical channel defined by (TDEST, TID, TUSER) runs to completion
before the DMA transfers another packet. Although packet transfers for multiple channels
can be interleaved, after started, each must run to completion before another transfer can
occur. It is your responsibility to avoid deadlock scenarios under this assumption. The AXI
DMA does not signal error conditions if the (TDEST, TID, TUSER) fields within the descriptors
do not adhere to these assumptions. It is up to the software to maintain consistency.

從以上文字來看,MM2S端只能等當前包傳輸完才能開始下一次的傳輸,我猜測這與CPU不太容易同時操縱多個通道的數據包發送有關係。所以在實際使用時只能先執行一個通道的發送任務再執行另一個通道的發送任務,雖然很不爽,但是還是能用的。

不知道以上理解是否有誤,如果哪位同學能提供更好的解釋的話,請在評論區留言。

image

圖7

 

Cyclic DMA:循環模式是在Scatter/Gather模式下的一種獨特工作方式,在Multichannel Mode下不可用。正常情況下的Scatter/Gather模式在遇到Tail BD就應該結束當前的傳輸,但是如果使能了Cyclic模式的話,在遇到Tail BD時會忽略completed位,並且回到First BD,這一過程會一直持續直到遇到錯誤或者人爲中止,圖8比較形象地表示了這一過程。Cyclic模式只需要在開啓傳輸前設置好BD鏈條,工作之後就再也不需要管了。要做到遇到Tail BD時返回到First BD,手冊中提供的方法是:

In this setup the Tail BD points back to the first BD. The Tail Descriptor register does not
serve any purpose and is used only to trigger the DMA engine.

Program the Tail Descriptor register with some value which is not a part of the BD chain. Say
for example 0x50.

image

圖8

 

Data Cache:從圖9中可以看出,在ZYNQ內部ARM CPU與DDR3之間存在兩級緩存區,分別是L1 I/D Cache和L2 Cache,它們都是32-byte line size。Data Cache的使用帶來了一個問題,DMA和CPU都與DDR3有數據往來,可CPU的Cache是不知道DMA對DDR3的數據讀寫過程的,也就是說CPU得到的數據很可能是”假的“,這就是著名的Cache一致性問題。解決該問題的辦法是在程序中使用flush函數(invalid函數)及時將Cache的數據寫入到DDR3(從DDR3讀取數據到Cache),也就是說要避免該問題就只能靠我們自己了。image

圖9

參考文獻:

[1]https://www.xilinx.com/support/documentation/ip_documentation/axi_dma/v7_1/pg021_axi_dma.pdf

 

原創聲明:本文版權歸<霸天虎1108>所有,轉載請註明出處。

本文標題:ZYNQ AXIDMA詳解(一)

本文網址:http://www.cnblogs.com/batianhu/p/zynq_axidma_xiangjie1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章