Forum Discussion
SGDMA debug
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.55 Replies
- Altera_Forum
Honored Contributor
I don't see anything wrong so I recommend simulating this system so that you can watch the read and write masters to see what they are doing. You should only have to simulate around 300us worth of time.
Also when you compile the code how much room is being reported for the stack and heap? You said your memory is 32kB so I'm thinking you could be running out of memory. What you could try doing is putting just the heap into the on-chip memory and all the other code sections in SDRAM and see if the problem goes away (that would suggest that in your test case the stack and heap collided). - Altera_Forum
Honored Contributor
--- Quote Start --- I don't see anything wrong so I recommend simulating this system so that you can watch the read and write masters to see what they are doing. You should only have to simulate around 300us worth of time. --- Quote End --- Oh.. Will take some time, but I will try :) --- Quote Start --- Also when you compile the code how much room is being reported for the stack and heap? You said your memory is 32kB so I'm thinking you could be running out of memory. What you could try doing is putting just the heap into the on-chip memory and all the other code sections in SDRAM and see if the problem goes away (that would suggest that in your test case the stack and heap collided). --- Quote End --- The reported size is also about 32kB, but I've left the system vectors @ DDR RAM, only SGDMA is connected to the onchip-mem, so I suppose the whole system runs from DDR memory, but DMA stuff should go through onchip-mem? I've tried to connect only descriptors to onchip-mem, but that did not help either. How could I check the memory contents without simulation? Or maybe I should use fixed addresses and provide the address for SGDMA? - Altera_Forum
Honored Contributor
The code that you based your design on allocates memory buffers and SGDMA descriptors in the heap. So not only does the processor need to be connected to the same memory as the SGDMA but you need to make sure your place the heap section in the memory you want the transfers and descriptors to be placed.
So if you hook up the Nios II data master to the on-chip memory, place the heap section into the on-chip memory then the transfer should work fine. You would then place .text, .rodata, .rwdata, stack in the DDR SDRAM. Alternatively you could hack up the code and placed the data buffers and descriptors anywhere you want and remove the malloc() calls that are doing this today (malloc() allocates memory from the heap). So I would try the system/software changes first before running the simulation, I think this is just a matter of making sure the CPU and SGDMA have the right visibility to the shared memory. - Altera_Forum
Honored Contributor
Oh, I will have to find out how to prepare memory without malloc() then :) Well, time to learn C anyway.
Thanks for Your help. - Altera_Forum
Honored Contributor
Are you also allowing for any cpu cache?
The DMA won't snoop the cache. - Altera_Forum
Honored Contributor
--- Quote Start --- Are you also allowing for any cpu cache? The DMA won't snoop the cache. --- Quote End --- The system is left as default when added, so yes: Instruction cache = 4kbytes, Data cache = 2kbytes, data cache line size=32bytes. --- Quote Start --- ------------------- --- Quote End --- Ok, so I've placed heap into onchip memory and it works now, I can see contents in the memory content editor. Contents a bit strange, I've not done any investigations on that. I've found more interesting thing (->output log here<- (http://www.codeupload.com/4059)). I create random 32bit pattern data using rand()&0xFFFFFFFF. This creates correct random data as it is seen in log lines 6 to 70. Now when I try to read the data, it is read the same for 4 times: lines 117-120, 121-124, 125-128 etc. Why is this happening? Wrong memory address increase step? - Altera_Forum
Honored Contributor
Assuming the code hasn't changed much there is a flush after the buffers are populated.
The code previously populated the buffer 8 bits at a time (I think) so when you modified the code did you make sure to take that into account when populating 32 bit data? - Altera_Forum
Honored Contributor
Well, I've changed the source to populate 32bit data. E.g. all pointers use 32bit allocation - check create_test_data(), however I am not sure if I am doing it correctly. In the validate part, I am reading the data using iord_32direct() instead of iord_8direct().
You can check the current source ->here<- (http://www.codeupload.com/4061). Test data creation is between lines 131-155 and I am reading the memory in lines 205-206. Maybe I need to use a higher offset when reading with iord_32direct() instead of iord_8direct? ---- EDIT: right, so I suppose the problem was 8bit read/write instead of moving the cycle every 4 bytes to work with 32bit data and iord_32direct(). ---- Now my task is to get 32bit packets from my packet source (I have Avalon-ST component, which takes packet data from logic and moves to Avalon-ST) and place it in Nios. I suppose I should use SGDMA stream-to-memory, then read the data using iord_direct32() in Nios. I will fill the TSE buffer in function ip_send() with that data and send it over ethernet. If I understart correctly, I need to do sync transfer in SGDMA, because my component generates packet start and packet stop signals. Maybe there is an example of such thing, when only Avalon-ST source and SGDMA RX are used? P.S. The data is video stream, I have to use something faster than simple DMA + I want to learn to use SGDMA, since I will have to receive the same data on the other end and parse it back to logic. - Altera_Forum
Honored Contributor
Besides ethernet I don't know of a good ST-->MM SGDMA example. I have one for MM-->ST but that uses my own SGDMA up on the alterawiki. If you want to see that video design search for the "Modular SGDMA" and a link to a video design should appear in the results. The software API for the mSGDMA is much different than the one you are using (mine is much simplier since it doesn't rely on descriptor fetching).
- Altera_Forum
Honored Contributor
Hm, which example exactly is MM->ST? I've found mSGDMA example on the Wiki, but that one had ST->MM->ST with timing measurement. Too bad there are no examples on simple SGDMA :| That descriptor allocation and set up stuff is quite hard to understand and fulfill.