FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6359 Discussions

DMA Controller is not stopping!!!

Altera_Forum
Honored Contributor II
1,800 Views

Hi guys, 

 

 

I had some weired behaviour of this controllers last week and I found out that it was caused by the setting of the allowed transactions. After this the DMA worked perfect (the code snipped below worked perfekt). 

Today I got this behaviour again, after enabling the burst transfer, to increas the throughput. 

The DMA should copy a array of data from one position of the external RAM to another one. The SDRAM Controller has also burst transfer enabled. 

 

The DMA Parameters: 

- Transfer size: 26 

- Burst transfer: enable 

- Maximum burst size(words): 32 

- Data transfer FIFO depth: 128 

- FIFO made of embedded memory blocks 

- Allowed transactions: byte, halfword, word, doubleWord, quadWord; 

 

The weired behaviour: 

the whole address span will be overwritten by the dma controller, as it is not stopping copying data. (i have noticed this behaviour with the memory viewer in the nios ii debug window by pausing the debugger) 

 

 

My code to configure the DMA: 

// Solution ID: spr240514 - When bursting is enabled, the DMA controller must be programmed to perform transactions at its full data width. 

// config: word transfer; transfer enable; transfer ends when length = 0!; 

unsigned int const mask = ALTERA_AVALON_DMA_CONTROL_WORD_MSK | ALTERA_AVALON_DMA_CONTROL_GO_MSK | ALTERA_AVALON_DMA_CONTROL_LEEN_MSK; 

unsigned int counter = 0; 

if(length != 0) 

IOWR_ALTERA_AVALON_DMA_CONTROL(DDR3_DMA_BASE, 0); 

IOWR_ALTERA_AVALON_DMA_STATUS(DDR3_DMA_BASE, 0); 

IOWR_ALTERA_AVALON_DMA_LENGTH(DDR3_DMA_BASE, 0); 

 

//dma 

IOWR_ALTERA_AVALON_DMA_RADDRESS(DDR3_DMA_BASE, DMA_RD_Addr & 0x7FFFFFFF); 

IOWR_ALTERA_AVALON_DMA_WADDRESS(DDR3_DMA_BASE, DMA_WR_Addr & 0x7FFFFFFF); 

IOWR_ALTERA_AVALON_DMA_LENGTH(DDR3_DMA_BASE, length); 

IOWR_ALTERA_AVALON_DMA_CONTROL(DDR3_DMA_BASE, mask); 

 

while((IORD_ALTERA_AVALON_DMA_STATUS(DDR3_DMA_BASE) & ALTERA_AVALON_DMA_STATUS_DONE_MSK) != ALTERA_AVALON_DMA_STATUS_DONE_MSK){ 

return 1; 

 

 

 

i have found a bug report in the knowlegde base:  

 

title  

 

DMA Controller Always Busy in Burst Mode 

description  

The DMA controller component (altera_avalon_dma), when enabled for burst transactions, does not perform transfers at widths other than its full data width. The DMA controller is always busy. 

workaround / fix  

When bursting is enabled, the DMA controller must be programmed to perform transactions at its full data width. 

 

 

 

the workaround is not clearly defined! I can not understand how to solve the problem in my case. 

This bug is still existing in v13.1 SP1 and was found in v10.0. come on!!! 

When the "Go" bit in the control register is enabled, the DMA is not stopping to copy data. It is overwritting the whole adress span --> imagin how  

How embarressing, because I mean it is just an simple DMA IP-Core with a damn bug, which cause me getting a red head. 

 

Q: Can anybody tell me what this workaround mean? 

 

Kind regards, 

Roland
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
325 Views

I have the sample working while back there... 2 years ago. DMA and SGDMA simple C program to execute the DMA or SGDMA.... 

 

 

Best, 

Sean 

 

 

 

 

--- Quote Start ---  

Hi guys, 

 

 

I had some weired behaviour of this controllers last week and I found out that it was caused by the setting of the allowed transactions. After this the DMA worked perfect (the code snipped below worked perfekt). 

Today I got this behaviour again, after enabling the burst transfer, to increas the throughput. 

The DMA should copy a array of data from one position of the external RAM to another one. The SDRAM Controller has also burst transfer enabled. 

 

The DMA Parameters: 

- Transfer size: 26 

- Burst transfer: enable 

- Maximum burst size(words): 32 

- Data transfer FIFO depth: 128 

- FIFO made of embedded memory blocks 

- Allowed transactions: byte, halfword, word, doubleWord, quadWord; 

 

The weired behaviour: 

the whole address span will be overwritten by the dma controller, as it is not stopping copying data. (i have noticed this behaviour with the memory viewer in the nios ii debug window by pausing the debugger) 

 

 

My code to configure the DMA: 

// Solution ID: spr240514 - When bursting is enabled, the DMA controller must be programmed to perform transactions at its full data width. 

// config: word transfer; transfer enable; transfer ends when length = 0!; 

unsigned int const mask = ALTERA_AVALON_DMA_CONTROL_WORD_MSK | ALTERA_AVALON_DMA_CONTROL_GO_MSK | ALTERA_AVALON_DMA_CONTROL_LEEN_MSK; 

unsigned int counter = 0; 

if(length != 0) 

IOWR_ALTERA_AVALON_DMA_CONTROL(DDR3_DMA_BASE, 0); 

IOWR_ALTERA_AVALON_DMA_STATUS(DDR3_DMA_BASE, 0); 

IOWR_ALTERA_AVALON_DMA_LENGTH(DDR3_DMA_BASE, 0); 

 

//dma 

IOWR_ALTERA_AVALON_DMA_RADDRESS(DDR3_DMA_BASE, DMA_RD_Addr & 0x7FFFFFFF); 

IOWR_ALTERA_AVALON_DMA_WADDRESS(DDR3_DMA_BASE, DMA_WR_Addr & 0x7FFFFFFF); 

IOWR_ALTERA_AVALON_DMA_LENGTH(DDR3_DMA_BASE, length); 

IOWR_ALTERA_AVALON_DMA_CONTROL(DDR3_DMA_BASE, mask); 

 

while((IORD_ALTERA_AVALON_DMA_STATUS(DDR3_DMA_BASE) & ALTERA_AVALON_DMA_STATUS_DONE_MSK) != ALTERA_AVALON_DMA_STATUS_DONE_MSK){ 

return 1; 

 

 

 

i have found a bug report in the knowlegde base:  

 

title  

 

DMA Controller Always Busy in Burst Mode 

description  

The DMA controller component (altera_avalon_dma), when enabled for burst transactions, does not perform transfers at widths other than its full data width. The DMA controller is always busy. 

workaround / fix  

When bursting is enabled, the DMA controller must be programmed to perform transactions at its full data width. 

 

 

 

the workaround is not clearly defined! I can not understand how to solve the problem in my case. 

This bug is still existing in v13.1 SP1 and was found in v10.0. come on!!! 

When the "Go" bit in the control register is enabled, the DMA is not stopping to copy data. It is overwritting the whole adress span --> imagin how  

How embarressing, because I mean it is just an simple DMA IP-Core with a damn bug, which cause me getting a red head. 

 

Q: Can anybody tell me what this workaround mean? 

 

Kind regards, 

Roland 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
325 Views

That knowledge database solution is saying that if you enable say 32, 16, and 8 bit transfers in the hardware but enable bursting then you can only perform 32-bit transfers. I also seem to recall an old bug where if you set the burst length to 128 for example then that was the maximum transfer (in beats) that you could perform as well. Hopefully that has been fixed but I haven't used that DMA in years so I can't be certain. 

 

I typically use the mSGDMA that I developed years ago which is offered in Qsys starting in 14.0. Unfortunately the official driver has not been included with the IP yet so you can find it here if you want to switch to a different DMA: http://www.alterawiki.com/wiki/modular_sgdma The programming model for the mSGDMA is similar to how you are bit banging the registers but I give you baremetal APIs to hide those details. One of these days I'll create a frontend for the mSGDMA to make it behave like the old DMA core that you are currently using but I haven't found the time to do so.
0 Kudos
Altera_Forum
Honored Contributor II
325 Views

Hey Sean and BadOmen, 

 

@Sean: thanks for the sample code, I'll have a look at that. I tried to use both ways to configure the DMA, the HAL and accessing the registers directly. Both ways were working fine before activating the burst mode. 

 

@BadOmen: thanks for the hint, that the burst length is the maximum length for one transaction. But, let's say you want to copy an array of 128kBytes then one has to trigger and configure (inclusive incrementing src+dest address) the DMA for 1024 times... This would be overkill and the performance boost and CPU time will be wasted by doing the task of a "normal" behalving DMA. 

But now, I will set the lenght of one transfer to the configured burst length, then we will know more. 

Thank you for the hint with the mSGDMA which sounds resonable to me. The thing is that I have to stick to the standard IP-Core of the v13.1 SP1.  

So I will try to use the SGDMA IP-Core and we will see if this one does the trick ;)  

 

Kind regards, 

Roland
0 Kudos
Altera_Forum
Honored Contributor II
325 Views

Hi again, 

 

so I tested to set the transfer length for DMA to 128 (the same length as the burst length) and it is working properly.
0 Kudos
Altera_Forum
Honored Contributor II
325 Views

I was hoping that bug would have been fixed by now.... 

 

With the SGDMA in 13.1 SP1 if you use bursting be careful with memory alignment. I remember years ago seeing cases where if you performed unaligned transfers and had bursting enabled depending on the transfer length and start address alignment the SGDMA would get stuck. To avoid that altogether I would just align your buffers to whatever width you set the SGDMA to. 

 

By the way you can also typically pull cores from newer versions of Quartus and put them into older versions of the tools as long as the core doesn't rely on a brand new feature. The RTL I put up on the alterawiki are up to date with what is in the 14.0 tools the only difference is the hardware .tcl files for each of the modules.
0 Kudos
Altera_Forum
Honored Contributor II
325 Views

 

--- Quote Start ---  

I have the sample working while back there... 2 years ago. DMA and SGDMA simple C program to execute the DMA or SGDMA.... 

 

 

Best, 

Sean 

--- Quote End ---  

 

 

Sean the code is very helpful, thanks for posting it. I'm having still having issues getting the dma controller to work, the program hangs at  

 

/* wait for transfer to complete */ 

while (!rx_done); 

 

I believe it's a hardware issue and that I don't have my qsys properly configured with the dma controller. How did you setup your qsys with onchip memory, sdram, and dma controller and what did you do for the dma interrupt? Sorry, I know it's been a while since you worked on this but any help is greatly appreciated. Thanks
0 Kudos
Reply