Vivado工程搭建
1. 創(chuàng)建基礎(chǔ)工程
新建Vivado項(xiàng)目,選擇目標(biāo)FPGA型號(hào)。
添加Zynq Processing System IP核,配置DDR控制器和時(shí)鐘。7000系列的Zynq可以參考正點(diǎn)原子DMA回環(huán)測(cè)試設(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,由于工程需要,對(duì)ip進(jìn)行修改,使得傳輸?shù)臄?shù)據(jù)位寬是16位,一共傳輸320*256個(gè)數(shù)據(jù)。修改位寬后re-package可能會(huì)出現(xiàn)報(bào)錯(cuò),請(qǐng)自行查找解決辦法。


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

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

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

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

PS端軟件設(shè)計(jì)(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 端對(duì)應(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; } // 啟動(dòng)接收 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端開(kāi)始發(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完成(這里簡(jiǎn)單用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ù)傳輸流程
啟動(dòng)debug,在return XST_SUCCESS處打斷點(diǎn),并查看memory中ddr的數(shù)據(jù):

測(cè)試結(jié)果如下:

ila信號(hào)如下:

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