cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pau-bergada
Observer
Observer
4,936 Views
Registered: ‎07-07-2017

AXI DMA S2MM in Zynq Ultrascale

Hi, 

 

we are trying to send some data from the PL logic to DDR memory in a XCZU9EG Zynq UltraScale on a ZCU102 board. We are using an AXI Direct Memory Access IP block configured in Direct Register mode. We have build the following block diagram.

 

DMA_DR_mode.png 

And we canfigured the AXI DMA as follows

DMA_configuration.png 

Our problem is that when configuring AXI-DMA register, as datasheet explains, to start a block data movement to the DDR the processor gets halted when configuring the interruptions. We don't know where can be the problem or whether it is a HW or SW issue.  

 

We would kindly appreciate any help to resolve this issue. 

 

 

Here you can find the code to acces the DMA register and to initiate a S2MM transfer:

 

#define BYTES_REQUESTED 0x00000400

#define XPAR_AXI_DMA_1_BASEADDR 0x80000000
#define XPAR_AXI_DMA_1_HIGHADDR 0x8000FFFF

#define XAXIDMA_RX_OFFSET 0x00000030               //RX channel registers base

#define XAXIDMA_CR_OFFSET 0x00000000   // Channel control

int i;

if( init_dma() && (samples != NULL) )
{

XAxiDma_Out32( XPAR_AXI_DMA_1_BASEADDR + XAXIDMA_RX_OFFSET + XAXIDMA_CR_OFFSET, 0x00000001 );

//Start the S2MM channel running by setting the run/stop bit to 1 (S2MM_DMACR.RS =1)
XAxiDma_Out32( XPAR_AXI_DMA_1_BASEADDR + XAXIDMA_RX_OFFSET + XAXIDMA_CR_OFFSET, 0x00017001 );

//Enable the S2MM interrupt on complete interrupt enable & Interrupt on Delay Timer Interrupt Enable & Interrupt on Error //Interrupt Enable & Interrupt Threshold=0x01

destination = (u32)((u64)samples->data.buffer & 0xFFFFFFFF);
Xil_DCacheInvalidateRange( destination, BYTES_REQUESTED );
XAxiDma_Out32( XPAR_AXI_DMA_1_BASEADDR + XAXIDMA_RX_OFFSET + XAXIDMA_DESTADDR_OFFSET, destination );
//Destination address: 0x00100000
XAxiDma_Out32( XPAR_AXI_DMA_1_BASEADDR + XAXIDMA_RX_OFFSET + XAXIDMA_BUFFLEN_OFFSET, BYTES_REQUESTED );

//Write the length in bytes of the receive buffer in the S2MM_LENGTH register=1024

... 

}

Tags (3)
0 Kudos
5 Replies
kravi
Xilinx Employee
Xilinx Employee
4,879 Views
Registered: ‎02-26-2014

Hi,

 

First of all, verify If there is issue in the AXI_DMA register access itself, it could be because of addressing/clocking/reset. 

You can use xsdb to test the register access.

 

Regards,

Ravi 

0 Kudos
bwiec
Xilinx Employee
Xilinx Employee
4,798 Views
Registered: ‎08-02-2011

What exactly do you mean by "the processor gets halted?" Does it hang on a specific line? Which line? Can you step through with the debugger?

You might also check your linker script to make sure your DMA isn't sending data to where your code is loaded. This will cause very weird behavior.
www.xilinx.com
0 Kudos
pau-bergada
Observer
Observer
4,719 Views
Registered: ‎07-07-2017

Kravi and Bwiec,

 

thank you very much for your comments. I'll try to answer to your questions:

  • We execute the code in one of the processors of the SoC, step by step by means of the debugger.
  • When I say the processor gets halted I mean it hangs and the debugger does not respond to any other command. It always hangs on the same line (when indicating the destination address).

We guess, as you Bwiec have pointed out, the problem is with the destination address (0x00100000), which coincides with the place where the code is loaded. We have increased this address (#define MEM_BASE_ADDR 0x01000000) but we have not seen any evidence of improvement, it still hangs on the same line.

 

The fact is that we have changed our FPGA code since we've been struggling with this issue for a while. We are now testing a more simple approach to this issue. We have focussed on a previous discussion (Getting started with custom AXI Stream peripherals (Vivado)-571249) to try to get some samples saved on the DDR memory from the PL.

 

I'll get you informed.

Thank you very much for your time.    

Pau

0 Kudos
pau-bergada
Observer
Observer
4,624 Views
Registered: ‎07-07-2017

Hi, 

we are still testing the link between the PL and the PS in a Zynq Ultrascale+ through an AXI stream channel (S2MM) and we have found some strange behaviour that we don't understand:

 

  •  The project is based on AR#57561 Example Design- Using AXI DMA in polled mode to transfer data to memory. We only use the write channel (S2MM) in direct register mode with interruptions disabled. Below you can find a snapshot of the block diagram.
  • We have added a custom IP driver (Data_process_0) with a master AXIS port that sends data from a counter to the DMA IP when both, TREADY and TVALID, are equal to '1'.
  • The code that runs on one of the processors requests 32 bytes and the PL code generates TLAST='1' when the number of output words equals 8 (the width of TDATA is 32). 

 

Block diagram

  •  The fact is that at the boot and when the DMA IP is initialized it rises the TREADY for 4 clock periods and the internal counter of Data_process begins to run. It is not a problem anymore since we reset this counter by means of an AXI Lite command.
  • The problem we are facing now is that although the processor requests 32 bytes, TREADY is only  high during 4 clock periods (see the following snapshot of the logic analyzer) when calling:

      Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr, NUM_BYTES_REQUESTED, XAXIDMA_DEVICE_TO_DMA)

 

Time diagram

  •  On the following call to this function TREADY rises again, Data_process_0 sends the remaining data till it reaches the number of output words to transmit, and finally rises TLAST. TREADY deasserts to '0' after some time (~100 clock cycles). 

 

Time diagram 2

 

  • The problem is that we can not call to XAxiDma_SimpleTransfer anymore because the DEVICE_2_DMA channel indefinetily remains busy. We guess the problem is that the PL number of words (of 4 bytes each) to transmit and the number of bytes requested by the PS are not equal and hence the DMA remains busy after a whole data exchange. 

We still don't know how to solve this issue or at least whose fault is it. Could you be so kind to show some light on this issue?

Thank you so much for your time.

Pau  

0 Kudos
pau-bergada
Observer
Observer
4,615 Views
Registered: ‎07-07-2017

Hi,

it seems we have finally resolved this issue. We can see the counter output on the RAM memory. However, we have changed several things on the custom IP that drives the data to the DMA (i.e., Data_process_0 in our case). These changes affect the automated generated code (when creating a new AXI4 peripheral) that rules the master port of the S2MM channel. We list below these changes in case somebody faces these same issues:

 

  • The internal counter (i.e., read_pointer) used to output some data on the TDATA port is defined as an integer whose range is 0 to log2(NUMBER_OF_OUTPUT_WORDS), hence it never reaches NUMBER_OF_OUTPUT_WORDS and never rises TLAST.
  • As you can see on the previous time diagram, on the previous post, TVALID and TREADY are equal to '1' during NUMBER_OF_OUTPUT_WORDS+1 (in our case, NUMBER_OF_OUTPUT_WORDS=8 words, i.e., 32 bytes). To resolve this issue we have deleted the FF on the output of TVALID and TLAST because we haven't seen any latency difference with M_AXIS_TDATA.
  • In order the let this IP drive more than one DMA transfer, read_pointer and tx_done must be reset when leaving SEND_STREAM state.

We hope somebody finds these comments useful.

Thank you,

Pau