TL;DR: Zynq7000 PS ビルトイン DMA が「Done」信号を返すのが早すぎます。内部の「MFIFO」がいっぱいになり、データソースへのアクセスが不要になるとすぐに通知するようです。しかし、SW は、データの送信が実際にいつ終了したかを知る必要があります。
PS DMA には、送信が終了したかどうかを示すステータス ビットがありますか? ザイリンクスのドキュメントでは、これらの DMA レジスタのいくつかについて不明確です ( http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf、276 ページ) 。
次の C コードを使用して、DMA を使用してデータのチャンクを 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 転送がまだ進行中である間に完了したと言うことがあります (チップスコープから、書き込みバーストがまだ発生している間に読み取りが発生していることがわかるため、わかります)。
DMA が実際にデータ転送を完了するまで待機するようにソフトウェアを設定するにはどうすればよいですか?