cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Observer
Observer
6,215 Views
Registered: ‎10-18-2013

MicroBlaze DMA never idle

Jump to solution

I am designing an FPGA image to connect to 4GB of DDR3. I am attempting to connect to the DDR from the MicroBlaze through a DMA. I am using Vivado 2012.4 and an xc7v585tffg1761-3 fpga.

I have the AXI Lite control interface connected to the MicroBlaze through an AXI interconnect. The MM2S and S2MM interfaces on the DMA are connected as masters to another AXI Interconnect where the MIG Interface to the DDR is connected as a slave. All blocks are using a 200 MHz clock output from the MIG. 

My problem comes from the software side. I am able to configure the DMA, but the DMA never becomes idle. The  XAxiDma_Busy API function always returns 1/TRUE. Reading the Status Register for either transfer direction shows the same thing, the DMA is always busy. I have added ILA cores to my design and I am seeing transfers on the AXI Lite interface but nothing else. There are also no errors asserting as far as I can tell.

I have seen some other posts that seem to see the same problem; however, those posts all seem to end with the user finding a bad connection somewhere in the design. I have checked and rechecked my design and I am fairly confident that it is correct.

Is there any reason the DMA would be stuck in a non-idle state immediately after start/reset?

1 Solution

Accepted Solutions
Highlighted
Observer
Observer
7,955 Views
Registered: ‎10-18-2013

I believe that I have solved my problem and in the interest of helping anyone who encounters a similar problem I will include some of my findings here.

 

I believe that the reason why the DMA never became idle after issuing a transfer was due to the device that it was getting the data from. I was using a very convoluted FPGA design to try to verify a piece of a custom board (DDR). I have since switched to using a traffic generator and the DMA now works.

 

My design has a Microblaze as a master over one AXI Interconnect. The slaves to that interconnect are: Traffic Generator Control Interface, DMA Control Interface, and a BRAM Controller (which is connected to a Dual-port BRAM). The Traffic Generator's streaming output is connected to the streaming input of the DMA. THe MM2s and S2MM Memory Mapped interfaces on the DMA are Masters over a second AXI Interconnect. The slave to that interconnect is the second port of the dual-port BRAM. This configuration is working for me.

 

My plan now is to replace the dual-port BRAM with a MIG that will interface to the DDR. 

 

I hope this helps anyone who may have been struggling with this problem.

View solution in original post

0 Kudos
5 Replies
Highlighted
Xilinx Employee
Xilinx Employee
6,206 Views
Registered: ‎08-02-2011

Are you talking about mm2s or s2mm?

If s2mm, make sure to drive tlast and tkeep appropriately.

 

Also, are you referring to the example c code? interrupt driven or polled? how are you connecting the hardware?

www.xilinx.com
Highlighted
Observer
Observer
6,203 Views
Registered: ‎10-18-2013

Both the MM2S and S2MM channels are always busy. I will check that the tlast and tkeep signals are being driven correctly.

 

I am using my own code but I have found some example code that I have modeled it after. That example code is the xaxidma_example_simple_poll.c file that I have seen mentioned in some documentation. I am using simple DMA mode rather than scatter-gather as I thought it would be easier to get started with. I have interrupts disabled.

 

Here is the pertinent code

 

XAxiDma dma_inst;
XAxiDma * dma_inst_ptr = &dma_inst;
XAxiDma_Config *cfg_inst = 0;
cfg_inst = XAxiDma_LookupConfig(XPAR_MEM_SUBSYSTEM_AXI_DMA_0_DEVICE_ID);
int Status = XAxiDma_CfgInitialize(dma_inst_ptr, cfg_inst);
XAxiDma_IntrDisable(dma_inst_ptr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(dma_inst_ptr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
busy = XAxiDma_Busy(dma_inst_ptr, XAXIDMA_DEVICE_TO_DMA); busy = XAxiDma_Busy(dma_inst_ptr, XAXIDMA_DMA_TO_DEVICE); Status = XAxiDma_ResetIsDone(dma_inst_ptr); Status = XAxiDma_ReadReg((dma_inst_ptr)->RegBase + (XAXIDMA_RX_OFFSET * XAXIDMA_DMA_TO_DEVICE), XAXIDMA_CR_OFFSET); mm2s_stat = XAxiDma_ReadReg((dma_inst_ptr)->RegBase + (XAXIDMA_RX_OFFSET * XAXIDMA_DMA_TO_DEVICE), XAXIDMA_SR_OFFSET);
busy = XAxiDma_Busy(dma_inst_ptr, XAXIDMA_DEVICE_TO_DMA); busy = XAxiDma_Busy(dma_inst_ptr, XAXIDMA_DMA_TO_DEVICE);

 busy is always 1. I am using the SDK debugger to step through.

 

I have a MicroBlaze that is a master over an AXI Interconnect where the DMA AXI Lite Control interface is connected as a slave. I have an axi stream interface connected from the MicroBlaze to the S2MM/MM2S AXI Stream interfaces on the DMA. The AXI MM2S/S2MM ports are masters of a secondary AXI Interconnect to which a MIG is connected as a slave. All clocks are connected to the ui clock output from the MIG which is fed by a differential 200MHz clock external input. I have the interrupts from the DMA connected to an AXI Interrupt Controller but I have those disabled anyway. Is there any other hardware connections that would be useful for you to know?

0 Kudos
Highlighted
Observer
Observer
6,177 Views
Registered: ‎10-18-2013

After re-reading the product guide for the DMA I realize I missed the note on the idle bit in the statusregister description. That indicates that the idle bt will be 0 in Simple DMA mode before the first transaction. That explains why the DMA is busy before the transaction; however, the DMA never becomes idle after the transaction either.

0 Kudos
Highlighted
Observer
Observer
6,165 Views
Registered: ‎10-18-2013

I should also mention that the transaction submits successfully, but never actually completes. I have been trying several different configurations with some ILA debugging mixed in. I see activity on the AXI Lite Control Interface, but none of the other interfaces ever seem to do anything. I assume this is another effect of the DMA always being busy.

0 Kudos
Highlighted
Observer
Observer
7,956 Views
Registered: ‎10-18-2013

I believe that I have solved my problem and in the interest of helping anyone who encounters a similar problem I will include some of my findings here.

 

I believe that the reason why the DMA never became idle after issuing a transfer was due to the device that it was getting the data from. I was using a very convoluted FPGA design to try to verify a piece of a custom board (DDR). I have since switched to using a traffic generator and the DMA now works.

 

My design has a Microblaze as a master over one AXI Interconnect. The slaves to that interconnect are: Traffic Generator Control Interface, DMA Control Interface, and a BRAM Controller (which is connected to a Dual-port BRAM). The Traffic Generator's streaming output is connected to the streaming input of the DMA. THe MM2s and S2MM Memory Mapped interfaces on the DMA are Masters over a second AXI Interconnect. The slave to that interconnect is the second port of the dual-port BRAM. This configuration is working for me.

 

My plan now is to replace the dual-port BRAM with a MIG that will interface to the DDR. 

 

I hope this helps anyone who may have been struggling with this problem.

View solution in original post

0 Kudos