Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20736 Discussions

URGENT: Peripheral to Memory DMA Transaction

Altera_Forum
Honored Contributor II
5,165 Views

Hello, may I know how to transfer data from peripheral to memory using DMA? It is quite confusing from memory-to-memory transfer. please help! thanks!

0 Kudos
111 Replies
Altera_Forum
Honored Contributor II
1,070 Views

DMA is Avalon-MM (memory map) and SGDMA is Avalon-ST (streaming memory) 

 

memory-to-memory (onchip to sdram, sram to sdram) 

stream-to-memory (buffer array to sdram, buffer to sram) 

memory-to-stream (sdram to buffer array, sram to buffer). 

 

You should read more about Avalon Interface Spec. 

 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

So, is it cannot use DMA to transfer data between peripheral and memory?

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

What are you trying to do with DMA? You can transfer data from peripheral to your sdram, but you have to write your interface protocols and make connected to it.

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I am trying to transfer data from peripheral (adding number) to SDRAM. Is there any reference or tutorial to write the interface protocol?

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

If you are using DMA (Avalon-MM), there is Avalon-MM templates already at Altera website. 

 

If you are using SGDMA (Avalon-ST), then you have to write your own protocols to connect your peripheral to Avalon-ST. 

 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

In my SOPC, i saw everything is Avalon MM Slave/Master. So is it consider as Avalon MM? Besides, my SDRAM is Avalon MM too, how to change to Avalon ST? Sorry, i am new. I can hardly understand. Thanks!

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I would use the following rather than the stock ACDS SGDMA: 

 

http://www.altera.com/support/examples/nios2/exm-modular-scatter-gather-dma.html 

 

 

Cheers, 

 

slacker
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I have done my DMA, which means I have to re-do to use SGDMA?

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

For Avalon-ST the typical minimal signals are data, ready, and valid. You connect a ST source (provider of data) to a ST sink (receiver of data). The data transfers between the source and sink when valid (from source) and ready (from sink) are both high. So if you have a component that provides/accepts a stream of data then ST is probably your best choice for an interface. 

 

There are three DMAs discussed in this thread: 

 

1) DMA on ACDS (old DMA that only supports MM transfers) 

2) SGDMA on ACDS (DMA that supports MM and MM to/from ST transfers) 

3) mSGDMA design example (hybrid of# 1 and# 2.... kinda) 

 

All three DMAs are not software compatible so before choosing a DMA make sure you are picking the right one for the task. So figure out what interface your custom component is going to use first then pick the DMA that makes the most sense to pair up with it. Also consider if you need scatter-gather or if having the CPU starting up the DMA for each transfer is sufficient for what you are doing. # 1 and# 3 have similar usage models whereas# 2 in my opinion is very different and the most difficult to program software around it. We won't be able to make a recommendation until knowing more about what your requirements are.
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

My requirement is connecting the DMA to a peripheral(eg adder of 2 number) to SDRAM. The input to the peripheral is user defined and once the adding process is completed, it will transfer the result to SDRAM. I wish to use DMA on the transferring of the result. Of course, real project is for image processing. I just used simple example to enhance understanding since I am starting from zero.

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

is it ok to use the method in this post? http://www.alteraforum.com/forum/showthread.php?t=13023

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I tried out some code from this forum. I cannot write the result from peripheral to SDRAM. my code is as follow: 

 

 

--- Quote Start ---  

# include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h"# include "sys/alt_timestamp.h" 

# ifndef datax 

# define datax 0x0# endif# ifndef datay 

# define datay 0x1# endif# ifndef datau 

# define datau 0x2# endif 

/* 

unsigned long add_h(unsigned long a, unsigned long b); 

 

unsigned long add_h(unsigned long a, unsigned long b) 

long result;  

IOWR(AVALON_0_BASE,datax,a); 

IOWR(AVALON_0_BASE,datay,b); 

result = IORD(AVALON_0_BASE,datau); 

return result; 

*/ 

static volatile int rx_done = 0; 

static void transfer_done (void* handle, void* data) 

rx_done++; 

 

void mem2mem_DMA(unsigned int dst, int length, unsigned long a, unsigned long b) 

void *rx_data = (void *) dst; 

alt_dma_rxchan rxchan; 

int ret_code; 

IOWR(AVALON_0_BASE,datax,a); // Data x 

IOWR(AVALON_0_BASE,datay,b); // Data y 

 

/* Create the receive channel */ 

if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) 

printf("Failed to open receive channel\n"); 

exit (1); 

ret_code = alt_dma_rxchan_ioctl(rxchan, ALT_DMA_SET_MODE_32, NULL); 

if (ret_code) 

printf("Error: SET_MODE_32: %d.\n", ret_code); 

exit(1); 

 

ret_code = alt_dma_rxchan_ioctl(rxchan, ALT_DMA_RX_ONLY_ON, (void*)(AVALON_0_BASE)); 

if (ret_code) 

printf("Error: ALT_DMA_RX_STREAM_ON: %d.\n", ret_code); 

exit(1); 

/* Post the receive request */ 

if ((ret_code = alt_dma_rxchan_prepare(rxchan, rx_data, length, transfer_done, NULL)) < 0) 

printf("Failed to post read request, reason = %i\n", ret_code); 

exit (1); 

 

/* wait for transfer to complete */ 

while (!rx_done); 

printf("Transfer successful!\n\n");  

 

int main(void) 

printf("\nThis is 32bits addition operation \n\n"); 

unsigned int dst = SDRAM_BASE + 0x600000; 

unsigned long number[100]; 

//unsigned long output1[100]; 

int i=0; 

int w; 

 

printf("Please specify number of sets of random number:\t "); 

scanf("%d", &w); 

 

for (i=0;i<w;i++) 

number= 300000000; 

mem2mem_dma(dst, w, number, number); 

 

for(i=0; i<w; i++)  

{  

printf("%ld\t %ld\n",number, IORD(dst, i)); 

 

return 0; 

 

--- Quote End ---  

 

My peripheral address is AVALON_0_BASE. This peripheral will add up 2 number, x and y. In this case, I set both x and y to be number[i], that is 300000000. Please assist. Thanks! really headache dealing with DMA.
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I think, what you are trying to do is not possible in this way. 

 

First, your periphereal is memory mapped, so you are correct using the DMA. 

But DMA only makes sense when transferring multiple data in one run. 

 

Let me give you an example: 

For a serial interface, you could have the DMA transferring the contents of a buffer to the periphereal.  

For the opposite direction, you could use the DMA too, but not at the same time.  

(You could use a second DMA, if you wanted to send and receive parallel, allthough I don't think that would be neccessary). 

As a DMA is typically much faster than the periphereal, the DMA had to wait until the periphereal finished processing a value, before delivering the next one. Therefore, periphereals usually employ a buffer (e.g. a FIFO), so the DMA can write or read an amount of data in one run. The more data you can transfer at once, the more efficient it gets to use a DMA. 

 

Your code seems to use the DMA to deliver one value at a time.  

It does not make sense to setup the DMA to transfer 1 value of x, one value of y and one value of z. It would make more sense to add a fifo to your periphereal, and transmit the whole array of number[] for x, then for y, then have your periphereal calulate the result, and then again fetch the whole result[] via DMA. 

 

So you'd have to add 3 FIFOs to your periphereal, and some control to start a calculation once you have all data transmitted.
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

I see.. no wonder i cant get anything... what is FIFO? so, now i need to change my peripheral only? is there any example?

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

Not really. 

I used the megawizard to create a custom megafunction dcFifo, and used that in my code. 

It will be a bit tricky, because you will need to implement logic that fetches data for your periphereal, but the Avalon side is pretty straightforward.
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

do you mind to explain further? or maybe is there any tutorial about this? i have to understand the simple one like now, so i can implement in image processing... thanks!

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

FIFO is a type of RAM, namely First In First Out. 

You can use it to queue data for processing. 

Have a look at the user guide from altera (http://www.altera.com/literature/ug/ug_fifo.pdf).
0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

Thanks, correct me if I am wrong: For my peripheral now, I have to create a memory to fit in the peripheral, all the result of computation is stored in the memory first, then, use DMA to transfer it to SDRAM. Am I right? is that consider as peripheral to memory transfer or still memory to memory transfer?

0 Kudos
Altera_Forum
Honored Contributor II
1,070 Views

It is a periphereal to memory transfer, as the DMA dosn't know about what your periphereal does with the data. 

The difference between memory and periphereal access is, that the DMA increments addresses for memory access, but not for periphereal access. 

 

(Just a side note: If your periphereal implements a memory interface (e.g. like the Opencores I2S does), it would be neccessary to use memory-to-memory transfer.)
0 Kudos
Altera_Forum
Honored Contributor II
939 Views

I am trying to make a peripheral to memory transfer. So, I add a RAM from Megawizard to my peripheral. Is that it? Besides, what are the differences between FIFO and RAM1port in Megawizard?  

 

Besides, if DMA does not increase the memory address for peripheral, how does it transfer the data?
0 Kudos
Reply