Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,324 Views

mSGDMA Transmission Data Missing

I am trying to transfer data using the mSGDMA QSYS cores in Quartus 17 from on-chip memory on an Arria V FPGA to a buffer allocated in Windows through PCIe and Jungo’s Windriver. Typically, the core works exactly as expected, however, part of the way through the DMA transmissions I am seeing a block of all zeroes or just junk data before seeing correct data again. 

 

The data is streaming into the FPGA and being processed and stored into the on-chip memory then transferred via DMA to the Windows PC. We do not have enough on-chip memory to hold all of the data so the code is setup to repeatedly do individual DMA transfers once a page in the memory is filled with a short window of time between each transfer. 

 

Has anyone seen this before or have any clue what could be causing this?
0 Kudos
5 Replies
Altera_Forum
Honored Contributor I
62 Views

Do you have an enabled data cache on the CPU? If yes did you remember to flush the cache before starting the DMA?

Altera_Forum
Honored Contributor I
62 Views

I have tried it both enabled and disabled. The code always flushes the cpu cache before starting a DMA transfer.

Altera_Forum
Honored Contributor I
62 Views

Then the only way I see to debug this is to use signal tap and check what the DMA is actually doing on the Avalon memory mapped master interface.

Altera_Forum
Honored Contributor I
62 Views

Part of the problem is that we are doing many hundred DMA transfers back to back and we never know when the bad data will show up. It makes it difficult to watch the Avalon MM bus when you cannot know which transfer will have the problem in it. 

 

Any clue on what we could trigger on?
Altera_Forum
Honored Contributor I
62 Views

If you see blocks of zeroes, maybe you could make sure that your software only uses non-zero data and then trigger on a null data word? 

Something else that could be worth checking is that the buffer that you use for the DMA transfer is not sharing its cache line with another variable. This means obviously that it can't be on the stack (i.e. a local variable). If it is a global or static variable, you can use the compiler's __attribute__ ((aligned(32))) to align it's address, but you must also make sure that its size is a multiple of 32. If it is an allocated buffer, some C libraries provide an aligned malloc, or else allocate a bigger buffer and use some bit manipulations to use an aligned zone within the buffer.
Reply