TL;DR:Zynq7000 PS 内置 DMA 过早返回“完成”信号。它似乎在(我假设)填充其内部“MFIFO”并且不再需要访问数据源时立即发出信号。但是我的软件也需要知道它何时真正完成了数据传输。
PS DMA 是否有状态位来指示传输是否完成?Xilinx 文档中的一些 DMA 寄存器不清楚(http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf,第 276 页)
我正在使用 DMA 使用以下 C 代码将大量数据从 DDR 内存泵送到 PL IP:
// Allocate memory in DDR, 1600 bytes PLZ.
char *mem_block = malloc(1600*sizeof(char));
// Fill memory with data (not shown)
// Configure the DMA command
memset(&dmaCmd, 0, sizeof(XDmaPS_Cmd));
dmaCmd.ChanCtrl.SrcBurstSize = 1;
dmaCmd.ChanCtrl.SrcBurstLen = 4;
dmaCmd.ChanCtrl.SrcInc = 1;
dmaCmd.ChanCtrl.DstBurstSize = 1;
dmaCmd.ChanCtrl.DstBurstLen = 4;
dmaCmd.ChanCtrl.DstInc = 0; // Do not increment, (Fixed DST Addr.)
dmaCmd.BD.SrcAddr = (u32)mem_block;
dmaCmd.BD.DstAddr = (u32)0x43c10000; // Destination address (in PL)
dmaCmd.BD.Length = 1600; // Bytes
然后我开始DMA传输......
status = XDmaPs_Start(&dmaInst, 0, &dmaCmd, 0);
if (status != XST_SUCCESS) {
printf("ERROR, could not start DMA Txfer.");
return XST_FAILURE;
}
并等待它完成,然后再从我的 IP 中读取结果。
while (!(Xil_In32(XPAR_PS7_DMA_S_BASEADDR + XDMAPS_INTSTATUS_OFFSET) & 0x00000001)) {
i++; // Waiting for DMA to finish...
}
result = Xil_In32(0x43c10004); // read result from my IP
// Result is available as soon as DMA is finished--on the very next 100MHz fabric clock.
我遇到的问题是,在数据传输完成之前,这个结果经常被过早地读回。显然,DMA 有时会说它在 DMA 传输仍在进行时已完成(我可以说是因为,从chipscope,我可以看到在写入突发仍在发生时发生读取)。
如何将我的软件设置为等到 DMA实际完成数据传输?