- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm trying to stream data from an ADC to my DDR RAM. I’ve hit a roadblock with using the modular SGDMA core to do streaming to memory mapped transfers to DDR RAM. An interrupt that is supposed to go off when the transfer is complete never goes off. This isn’t because the data never stops being written but is actually because the data never begins to be written. I’ve noticed this because I print out some of the memory addresses during the wait for the interrupt -> the values that get written out don’t correspond to the values being fed into the SGDMA. I’ve noticed issues which point to either a software or hardware problem. The software issue is that the IOWR and IORD commands don’t seem to be working correctly. IOWR_32DIRECT(MEM_IF_DDR2_EMIF_0_BASE, testNumber, testNumber); IORD (MEM_IF_DDR2_EMIF_0_BASE, testNumber); /////////////////////////////////////////////////////////////^Doesn’t work memcpy(MEM_IF_DDR2_EMIF_0_BASE + testNumber*sizeof(int), &testNumber, sizeof(testNumber)); ->writing memcpy(&value, (MEM_IF_DDR2_EMIF_0_BASE+testNumber*sizeof(int)), sizeof(int)); ->reading ////////////////////////////////////////////////////////////^Works I’m not sure if this is because in my tests I am writing to RAM, I will look into that, but this is an issue since the data transfer descriptor is initialized using the IOWR_32DIRECT function. I don’t think this is the issue though because I’m able to call these same functions successfully when I do memory-mapped to memory-mapped data transfers. I've attached the c file that I'm using to test the streaming data transfer (main.c), the line that doesn't work is# 74: if (sgdma_interrupt_fired == 1) -> I've changed this to a while check and noticed that the interrupt never gets asserted. The next area that I think might be an issue is the way I collect data from the incrementing register (the one I’m streaming data from). I simply connected the bus streaming data bus to the streaming sink of the write master in the Qsys project. I have an image of that project with the connection circled (Qsys.png). Is that the correct way to connect streaming data to a Qsys project? Is there anything that’s obviously wrong with the way I’ve set up the connections? Any advice on how to approach figuring out why the interrupt I need doesn’t go off?Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your image is so small it's difficult to see. Can you add a signaltap instance on the stream interface to check that anything is actually going through it?
As for your problem with the macros, it's probably because the 32DIRECT versions use a byte offset, while IORD/IOWR use a word offset. Therefore you either need to multiply testNumber by sizeof(int) in your line with IOWR_32DIRECT, or only use IOWR and IORD. This should probably work:IOWR(MEM_IF_DDR2_EMIF_0_BASE, testNumber, testNumber);
IORD (MEM_IF_DDR2_EMIF_0_BASE, testNumber);
Using direct addressing, either with pointers or memcpy work also, but you need to be careful if your CPU has a data cache. Then you need to flush or invalidate it before or after the operation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Daixiwen,
I've attached a screenshot of the signals being tapped from the write master's data sink, it looks like the streaming data is going through correctly. The CSR IRQ also goes off which indicates when the write is complete. However, there is a problem on the software side, the exception does not get handled. The way I have the system set up right now is I "fake" an avalon streaming interface to stream data from an ADC to a FIFO. That fifo is connected to the data sink of the SGDMA using the avalon streaming interface. I used a PIO to allow the NIOS II software to set the valid bit of the top level module's "fake" streaming avalon bus (this signal is tapped and shown in the attached image as "adc_ready_pio_export"). The interrupt signal is also shown as "csr_irq". The interrupt remains at 1 after the standard descriptor register is written to. It seems like the nios 2 processor registers an unhandled exception right after interrupt signal goes up. The following are the instructions that get called prior to the interrupt going off (the PIO that controls the write is set to high) and the assembly instructions of the exception handler. 90 IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 1); 00000320: movi r3,1 00000324: movhi r2,16388 00000328: addi r2,r2,2128 0000032c: stwio r3,0(r2) 96 if(value == 0){ 00000330: ldw r2,-4(fp) alt_exception_unknown: 40000094: break 0 40000098: ldw r5,68(sp) 4000009c: ldw ea,72(sp) 400000a0: ldw ra,0(sp) 400000a4: wrctl estatus,r5 400000a8: ldw at,8(sp) 400000ac: ldw r2,12(sp) 400000b0: ldw r3,16(sp) 400000b4: ldw r4,20(sp) 400000b8: ldw r5,24(sp) 400000bc: ldw r6,28(sp) 400000c0: ldw r7,32(sp) 400000c4: ldw r8,36(sp) 400000c8: ldw r9,40(sp) 400000cc: ldw r10,44(sp) 400000d0: ldw r11,48(sp) 400000d4: ldw r12,52(sp) 400000d8: ldw r13,56(sp) 400000dc: ldw r14,60(sp) 400000e0: ldw r15,64(sp) 400000e4: addi sp,sp,76 400000e8: eret I also printed out the register values at the time the exception occurs: zero 0 at 3735928559 r2 3690725375 r3 488 r4 1 r5 0 r6 2155905152 r7 4278124287 r8 67528 r9 70204 r10 5 r11 3 r12 67532 r13 1073740280 r14 67528 r15 196218880 r16 69016 r17 67552 r18 3735928559 r19 3735928559 r20 3735928559 r21 3735928559 r22 3735928559 r23 3735928559 et 3735928559 bt 4294967295 gp 0x0001a844 sp 0x3ffffeb8 fp 0x3fffff18 ea 0x0bb21004 sstatus 4294967295 ra 0x000001ec pc 0x40000094 status 0 estatus 0 bstatus 4294967295 ienable 5 ipending 1 cpuid 0 ctl6 4294967295 exception 20 pteaddr 4294967295 tlbacc 4294967295 tlbmisc 4294967295 eccinj 4294967295 badaddr 0 config 4294967295 mpubase 4294967295 mpuacc 4294967295 The register that seemed to be the most important was the exception register which held a value of 20. A subset of the exception register corresponds to the cause of the exception. That subset corresponded to cause# 5 which is an "Illegal Instruction Exception". I'm not sure why I'm getting this exception since the instructions being run prior to the interrupt seem valid. Any idea what's causing this problem?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have another update, it seems like I can only write 488 words of data before this exception occurs. This indicates to me that there might be a buffer that's filling up (I don't know why I would be getting an illegal instruction error though). The other strange thing is that the depth of all of my buffers is 1024, I would expect a buffer error to occur at around that number of words being transferred not 488.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page