Vivado工程搭建
1. 創(chuàng)建基礎(chǔ)工程
新建Vivado項目,選擇目標(biāo)FPGA型號。
添加Zynq Processing System IP核,配置DDR控制器和時鐘。7000系列的Zynq可以參考正點原子DMA回環(huán)測試設(shè)置。


2. 添加AXI DMA IP核
配置AXI DMA為Simple模式。
設(shè)置數(shù)據(jù)位寬(如32/64位)和Width of Buffer Lenghth Register(26最大可以存2^26 bit)。

3. 添加Stream Data FIFO
這里看需要設(shè)置FIFO 深度

4. 添加自定義ip用于產(chǎn)生數(shù)據(jù)
這里可以參考https://fpga.eetrend.com/blog/2023/100568155.html,由于工程需要,對ip進行修改,使得傳輸?shù)臄?shù)據(jù)位寬是16位,一共傳輸320*256個數(shù)據(jù)。修改位寬后re-package可能會出現(xiàn)報錯,請自行查找解決辦法。


5. 添加自定義ip用于產(chǎn)生dma_start信號
由于dma傳輸過程中會出現(xiàn)數(shù)據(jù)丟失情況,這里借鑒了以下博主的解決方法:ZYNQ踩坑日記:AXI_DMA傳輸問題詳解——問題再續(xù)篇-物聯(lián)沃-IOTWORD物聯(lián)網(wǎng)對于vivado中使用DMA傳輸數(shù)據(jù)時會丟數(shù)據(jù)的解決辦法_vivado dma-CSDN博客

對數(shù)據(jù)產(chǎn)生ip進行了修改(右鍵ip->edit in packager),使得dma初始化之后再開始傳輸數(shù)據(jù),避免數(shù)據(jù)丟失

在關(guān)鍵代碼中進行如下修改:

最后再Re-Package IP,可以參考https://cloud.tencent.com/developer/article/1813652創(chuàng)建并修改自定義ip。
6. 連接IP核與總線
總體block design如下

PS端軟件設(shè)計(Vitis/SDK)
1. 初始化DMA
#include"xaxidma.h"#include"xparameters.h"#include"xil_cache.h"#include"xil_printf.h"#include"my_dma_start_s.h"#include"sleep.h"#defineDMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID#defineDDR_BASE_ADDR XPAR_PSU_DDR_0_S_AXI_BASEADDR#defineRX_BUFFER_BASE (DDR_BASE_ADDR + 0x01000000)#defineDATA_LENGTH 81920// 與 PL 端對應(yīng)#defineMY_DMA_START_ADDR XPAR_MY_DMA_START_S_0_S00_AXI_BASEADDR#defineMY_DMA_OFFSET MY_DMA_START_S_S00_AXI_SLV_REG0_OFFSETintmain() { XAxiDma AxiDma; XAxiDma_Config *Config; intstatus, i; u16 *RxBufferPtr = (u16 *)RX_BUFFER_BASE; xil_printf("---- Start DMA Receive Test ---- "); Config = XAxiDma_LookupConfig(DMA_DEV_ID); if(!Config) { xil_printf("No DMA config found! "); returnXST_FAILURE; } status = XAxiDma_CfgInitialize(&AxiDma, Config); if(status != XST_SUCCESS) { xil_printf("DMA Init Failed "); returnXST_FAILURE; } if(XAxiDma_HasSg(&AxiDma)) { xil_printf("DMA configured as SG mode! "); returnXST_FAILURE; } // 啟動接收 status = XAxiDma_SimpleTransfer(&AxiDma, (UINTPTR)RxBufferPtr, DATA_LENGTH *sizeof(u16), XAXIDMA_DEVICE_TO_DMA); if(status != XST_SUCCESS) { xil_printf("DMA Receive Config Failed "); returnXST_FAILURE; } //這里用于通知PL端開始發(fā)送數(shù)據(jù) MY_DMA_START_S_mWriteReg(MY_DMA_START_ADDR,MY_DMA_OFFSET,1); usleep(5); MY_DMA_START_S_mWriteReg(MY_DMA_START_ADDR,MY_DMA_OFFSET,0); // 等待DMA完成(這里簡單用while輪詢)while(XAxiDma_Busy(&AxiDma, XAXIDMA_DEVICE_TO_DMA)); // 失效 Cache,保證讀到 DDR 最新數(shù)據(jù) Xil_DCacheInvalidateRange((UINTPTR)RxBufferPtr, DATA_LENGTH *sizeof(u16)); // 打印接收數(shù)據(jù)for(i =0; i < DATA_LENGTH; i++) { ? ? ? ? xil_printf("DDR[%d] = 0x%04x ", i, RxBufferPtr[i]); ? ? } ? ? ?xil_printf("---- DMA Receive Done ---- "); ? ?return?XST_SUCCESS; }
2. 數(shù)據(jù)傳輸流程
啟動debug,在return XST_SUCCESS處打斷點,并查看memory中ddr的數(shù)據(jù):

測試結(jié)果如下:

ila信號如下:

可以看到結(jié)果符合要求。
-
控制器
+關(guān)注
關(guān)注
114文章
17621瀏覽量
190027 -
DDR
+關(guān)注
關(guān)注
11文章
747瀏覽量
68483 -
AXI
+關(guān)注
關(guān)注
1文章
142瀏覽量
17771 -
Vivado
+關(guān)注
關(guān)注
19文章
846瀏覽量
70423
原文標(biāo)題:基于AXI DMA IP核的DDR數(shù)據(jù)存儲與PS端讀取
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設(shè)計論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
ZYNQ SOC案例開發(fā):AXI DMA使用解析及環(huán)路測試
DDR3 SDRAM控制器IP核的寫命令和寫數(shù)據(jù)間關(guān)系講解
【ZYNQ Ultrascale+ MPSOC FPGA教程】第三十二章PL讀寫PS端DDR數(shù)據(jù)
有關(guān)PL端利用AXI總線控制PS端DDR進行讀寫(從機wready信號一直不拉高)
PCIE XDMA IP核介紹
AXI FIFO和AXI virtual FIFO這兩個IP的使用方法
ZYNQ的ARM和FPGA數(shù)據(jù)交互——AXI交互最重要的細節(jié)
Xilinx FPGA里面的AXI DMA IP核的簡單用法
ZYNQ基礎(chǔ)---AXI DMA使用

基于AXI DMA IP核的DDR數(shù)據(jù)存儲與PS端讀取
評論