DMALOOP實驗,用來分析axi stream時序,先將原理圖和實驗ILA所折圖展示如下:
dmaloopdemo實驗是OK的,ILA中時序發現:
stream data fifo M_AXIS接口(即傳給DMA的S2MM):傳輸時,先將tlast下拉,同時刻tvalid上拉,這兩步做完,因tready恆=1,估計下一個時鐘週期上升沿時總線就會認爲開始傳輸數據了;結束時,因tvalid從第一次傳輸開始就一直=1,所以先上拉tlast,一個週期之後tvalid下拉,但要注意:tlast卻沒有下拉,始終還是=1,具體可以看https://my.oschina.net/u/4583591/blog/4701373中所說:“ master將TLAST拉高,TVALID拉低,傳輸結束”。
stream data fifo S_AXIS接口(即DMA的MM2S傳給fifo),用來接收內存通過DMA下發來的數據,tvalid上拉表示數據開始傳輸,當DMA需要結束傳輸數據給stream data fifo時,首先上拉tlast,下個週期上升沿(B)將tvalid和tlast全部都下拉(我分析,應該是B上升沿之前,將數據放到總線上,此時判斷出tlast==1,tvalid和tready都==1,所以B之後需要將tvalid和tlast都下拉)。main.c中代碼如下:
/*
*
* www.osrc.cn
* www.milinker.com
* copyright by li yang mi lian dian zi www.osrc.cn
* axi dma test
*
*/
#include "dma_intr.h"
#include "sys_intr.h"
static XScuGic Intc; //GIC
static XAxiDma AxiDma;
volatile u32 success;
int Tries = NUMBER_OF_TRANSFERS;
int i;
int Index;
u8 *TxBufferPtr= (u8 *)TX_BUFFER_BASE;
u8 *RxBufferPtr=(u8 *)RX_BUFFER_BASE;
u8 Value;
int axi_dma_test()
{
int Status;
TxDone = 0;
RxDone = 0;
Error = 0;
xil_printf("\r\n----DMA Test----\r\n");
xil_printf("PKT_LEN=%d\r\n",MAX_PKT_LEN);
//while(1)
for(i = 0; i < Tries; i ++)
{
Value = TEST_START_VALUE + (i & 0xFF);
for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxBufferPtr[Index] = Value;
Value = (Value + 1) & 0xFF;
}
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait TX done and RX done
*/
while (!TxDone || !RxDone) {
/* NOP */
}
success++;
TxDone = 0;
RxDone = 0;
if (Error) {
xil_printf("Failed test transmit%s done, "
"receive%s done\r\n", TxDone? "":" not",
RxDone? "":" not");
goto Done;
}
/*
* Test finished, check data
*/
Status = DMA_CheckData(MAX_PKT_LEN, (TEST_START_VALUE + (i & 0xFF)));
if (Status != XST_SUCCESS) {
xil_printf("Data check failed\r\n");
goto Done;
}
}
xil_printf("AXI DMA interrupt example test passed\r\n");
xil_printf("success=%d\r\n",success);
/* Disable TX and RX Ring interrupts and return success */
DMA_DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);
Done:
xil_printf("--- Exiting Test --- \r\n");
return XST_SUCCESS;
}
int init_intr_sys(void)
{
DMA_Intr_Init(&AxiDma,0);//initial interrupt system
Init_Intr_System(&Intc); // initial DMA interrupt system
Setup_Intr_Exception(&Intc);
DMA_Setup_Intr_System(&Intc,&AxiDma,TX_INTR_ID,RX_INTR_ID);//setup dma interrpt system
DMA_Intr_Enable(&Intc,&AxiDma);
}
int main(void)
{
init_intr_sys();
axi_dma_test();
}
根據https://wenku.baidu.com/view/a2d9ed1900020740be1e650e52ea551811a6c945.html 中所說,“ready由從設置驅動,表示從設備下一個時鐘週期上升沿到來時能夠接收數據,注意:是下一個時鐘上升沿時接收數據。tlast和數據一起傳輸。”