Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

SGDMA debug

Altera_Forum
Honored Contributor II
4,097 Views

Hello, 

I am trying to learn how to use SGDMA to transfer data to memory. First of all, I am trying to connect SGDMA TX directly to SGDMA RX and check results. You can find the source code ->here<- (http://www.codeupload.com/4051) (I've edited the code found on forum, so thanks the guy who provided it). 

In order to check what is written to the memory, I've connected the SGDMA modules to ONCHIP memory (size: 32768 bytes) and enabled memory content reader on the on-chip memory options. You can see my connections ->here<- (http://i51.tinypic.com/1zz6fj5.png). 

The problem is that this dma design doesn't work. The data I get is corrupted. 

I've tried to disconnect cpu.instruction_master and cpu.data_master from onchip memory, then the memory start address goes to 0x00, but results are the same. 

 

If I connect the DMA to the DDR memory, then the data passes correctly, Screenshot is ->here<- (http://i53.tinypic.com/2heak61.png). 

 

Now why I get this situation: 

either I try to read or write from/to onchip memory or DDR memory, the core always tries to read/write from/to address 0x800xxxxx. Obviously when it is connected to DDR ram it works, but when to onchip ram it doesn't. Why is this happening? Nios memory bus bugs? How can I check what is written to the memory? If I use only onchip memory for the whole system and DMA it also works fine, but I want a clear vision without Nios stuff in the memory. 

 

Thanks.
0 Kudos
55 Replies
Altera_Forum
Honored Contributor II
203 Views

* edit misinterpreted what you said. 

 

200MS/s would require a memory of equal width or wider operating over 200MHz (SGDMA would need to be just as fast). Normally you take the ADC data, feed it through a data format adapter to make it wider and make the SGDMA and memory path wide to accomidate the data rate. That said I think Nios II will have a hard time keeping up with interrupts coming in that fast unless you allocate huge buffers to hold the data. The SGDMA is limited to under 64kB buffer transfers due to the descriptor limitations. 

 

Perhaps your buffer length is 64kB or larger? That would be a problem for that SGDMA to handle.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

The ADC is 200Msps 8-bit, and the DDR2 clock frequency is 150MHz, 16-bit data bus. 

Bufffers are defined as follows:# define number_of_data (1024*1024) # define number_of_buffer 10# define length_of_buffer 12
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

So do you have 1MB of data split into 10 individual buffers (so ~100KB each)? If so then you'll need to use smaller buffers since the SGDMA can't transfer any more than 65535 bytes because the transfer field of the descriptor is only 16 bits wide. I might be misinterpreting what number_of_buffer and length_of_buffer represent. 

 

Do you have to continuosly sample? I ask because it sounds like you have enough SGDMA and memory bandwidth to handle 200MS/s but you might need some long descriptor chains in order for Nios II to be able to keep up with the maintence (asumming you use ping-pong buffering). Also if you continously sample and need to ship the data offchip over Ethernet Nios II will not be able to keep up with that over TCP (it'll struggle to do that with UDP).
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Thanks for your reply. 

 

The number_of_data defines the memory for ADC data. In my test design, only part of the memory are used. The number_of_buffer and length_of_buffer represent the number of descriptors in the descriptor list and number of bytes transmitted for one descriptor respectively. 

 

So the defination is OK. 

 

I don't need to continuously smple, just sample several MB bytes and then stream out . 

 

 

Now, SGDMA is the bottleneck of my design. I'm really confused.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

I created a Avalon stream component for ADC, consisting of a LVDS_RX module and other conduits. Maybe there is some flaw in my ADC component. Is there any examples ?

0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Hi nwyfauq, 

 

I was wondering how you "set the last descriptor in the chain to point to the first one"?. I'm using the mSGDMA and wondering if the same functionality is possible.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

nwyfauq would have pointed the next descriptor field to the start of the descriptor chain. The SGDMA uses linked-list descriptors where one descriptor points to the next so to have the DMA wrap back around the end of the chain just needs to point to the start. When the SGDMA consumes descriptors it sets the owned by hardware bit to 0 so if you wrap the end of the descriptor list to the start and want the SGDMA to immediately start consuming those descriptor again you have to set the park control bit as well. This park bit prevents the SGDMA from setting the owned by hardware bit to 0 after it's consumed (i.e. the descriptor remains owned by the SGDMA after the SGDMA is done processing it). 

 

The mSGDMA doesn't use linked-list so there is no direct way to have it recycle descriptors. It has park bits in the descriptor field but the behavior is different. The mSGDMA re-uses the same descriptor if the park bit is enabled and there are no other descriptors buffered. For example if you want to transfer 1MB and keep transfering 1MB from the same location(s) in memory as soon as the 1MB has been transferred the mSGDMA will reuse the same descriptor to transfer the data again. To stop it from re-using the same descriptor you simply write a new descriptor and it will switch over (after the current transfer completes).
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Thanks for your reply. I had worried something like this might be the case. In the last couple of days my plan has been to hack the "fifo_with_byteenables" block in the dispatcher to restart the chain.  

 

My understanding is that the descriptors are held in a ram ("the_dp_ram"), so I'm trying to reset the read address to 0 at the end of my descriptor chain. So when "pop" is asserted and read address is at the end of my chain, reset the read address for the descriptor ram to 0 and set the "internal_used" back to its value at the beginning of the chain (I have 8 descriptors for 8 different memory locations). So far it seems to be working well, but I havent finished testing it yet.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

That should work as long as you plan on that to be the behavior all the time. I haven't thought this through much but the way I would implement it is use a falling edge detector on the fifo_empty signal and use that to reset the tail (read) address of the FIFO while leaving the head (write) address alone. Having a host keep track of where you are at might be a pain unless you have the last descriptor firing off an interrupt but I'm not sure if that matters to you. 

 

The way I planned to tackle this was to have a prefetch block sit in front of the dispatcher and have it responsible for fetching descriptors out of memory and shoveling them into the dispatcher. I became sidetracked with a new and improved DMA that I'm perodically working on that should kill two birds with one stone so I never got back to making that prefetch block.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Hi, 

 

Is it possible to cycle multiple descriptors using the mSGDMA park feature? For example, in a MM-ST and/or ST-MM configuration, if the descriptor queue has two descriptors, and then "park" the queue so it becomes a circular queue? 

 

It would be a good feature for ping-pong buffers, for example... 

 

Cheers, 

Nestor
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Unfortunately it doesn't have that type of functionality, my plans were to add a frontend that would provide this type of behavior instead using linked-list descriptors. If you set the park on multiple descriptors this is the type of behavior you should expect (assume the mSGDMA is sitting idle before these steps): 

 

1) descriptor# 1 has park bit set 

2) mSGDMA continues to keep reusing descriptor# 1 

3) descriptor# 2 has been written with the part bit set 

4) mSGDMA switches over to using descriptor# 2 until another descriptor is written 

 

With the existing hardware the only way to ping-pong between two buffers is that you need to keep writting the two descriptors over and over to the dispatcher. You could make a frontend hardware block that you write to the two descriptors and it manages stuffing the descriptors into the dispatcher. If you made this custom hardware master width the same as the dispatcher descriptor port issueing the descriptors should be really easy to do using a single write operation.
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

 

--- Quote Start ---  

Unfortunately it doesn't have that type of functionality, my plans were to add a frontend that would provide this type of behavior instead using linked-list descriptors. If you set the park on multiple descriptors this is the type of behavior you should expect (assume the mSGDMA is sitting idle before these steps): 

 

1) descriptor# 1 has park bit set 

2) mSGDMA continues to keep reusing descriptor# 1 

3) descriptor# 2 has been written with the part bit set 

4) mSGDMA switches over to using descriptor# 2 until another descriptor is written 

 

With the existing hardware the only way to ping-pong between two buffers is that you need to keep writting the two descriptors over and over to the dispatcher. You could make a frontend hardware block that you write to the two descriptors and it manages stuffing the descriptors into the dispatcher. If you made this custom hardware master width the same as the dispatcher descriptor port issueing the descriptors should be really easy to do using a single write operation. 

--- Quote End ---  

 

 

Thank you for your reply! We have already implemented the descriptor recycler. I only proposed the circular FIFO as an enhancement suggestion. Who will be maintaining the mSGDMA moving forward, now that it will be pulled into the Altera Embedded IP suite?
0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Someone other than me :) Altera will support the mSGDMA moving forward as an embedded IP just like the rest of the soft IP cores that are available in Qsys. I think the right approach is to have a frontend unit become part of the mSGDMA instead of trying to make the dispatcher handle this since the dispatcher is really designed to just execute descriptors in the order that it sees them. With a frontend that handles linked-lists then this becomes a more robust solution. This will also give similar functionality to the SGDMA that has been in Qsys for years except it's just an optional feature for those who want linked-list descriptor prefetching.

0 Kudos
Altera_Forum
Honored Contributor II
203 Views

Hello 

 

I'm also trying to learn how to use mSGDMA.  

Since the codes uploaded in the first, and second pages are no longer available I find it hard to understand the context. Is it possible for someone to reupload the codes just for learning purposes? This thread would've been the perfect starting point for someone trying to learn how to use the component.  

Apparently writing a program to control the mSGDMA requires more than just using the API given, seeing how you guys talked about allocating buffer using malloc and stuff...
0 Kudos
Reply