UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

DMA transfer failure

Reply
Visitor
Posts: 14
Registered: ‎10-04-2017

DMA transfer failure

Hello everyone,

 

I am currently trying to perform some image processing on a custom platform with a Zynq 7015 core.

 

I want to calculate a depth estimation of two pre-stored images. The processing function takes their addresses (+output address) as inputs and stores the result, which is accessed via VDMA.

 

So far, only using the ARM prozessor produces the desired result. However, trying to HW-accelerate the image-processing function results in an error when starting the function is called:

 

 

ERROR: Simple DMA transfer failure accessing address 0x3d400000 : {Decode }

The address is where the second image is stored. It always returns the address of the second image, independent of the location.

 

 

What could be possible reasons for this failure?

 

I am using SDx 2017.1.

 

Thanks in advance,

Seek

Highlighted
Explorer
Posts: 118
Registered: ‎09-19-2017

Re: DMA transfer failure

Hi seek,

 

Can you please post a code snippet with the accelerated function definition, callsite, memory allocation, and memory freeing?

 

Thanks!
Sam

Visitor
Posts: 14
Registered: ‎10-04-2017

Re: DMA transfer failure

Good Morning Sam,

 

yes, I can. The images are included in the .bif file as 32-bit rgba-data.

 

There werde 4 subfunctions originally, but I reduced them to one simple function, in order to locate the problem.

 

The declaration goes as follows:

 

#pragma SDS data mem_attribute(left_img:PHYSICAL_CONTIGUOUS|NON_CACHEABLE, right_img:PHYSICAL_CONTIGUOUS|NON_CACHEABLE, output_img:PHYSICAL_CONTIGUOUS|NON_CACHEABLE)
#pragma SDS data access_pattern(left_img:SEQUENTIAL, right_img:SEQUENTIAL, output_img:SEQUENTIAL)
#pragma SDS data data_mover(left_img:AXIDMA_SIMPLE, right_img:AXIDMA_SIMPLE, output_img:AXIDMA_SIMPLE)
#pragma SDS data copy(left_img[0:IMG_SIZE], right_img[0:IMG_SIZE], output_img[0:IMG_SIZE])
void image_processing(unsigned int *left_img, unsigned int *right_img, unsigned int *output_img); . .  

 

Function itself:

void image_processing(unsigned int *left_img, unsigned int *right_img, unsigned int *output_img){

	// Some Definitions

	// I use a pixel buffer, since information is being streamed
        // The buffer only stores some previous pixels of the right image
	PX_N_BUFFER rightPxBuffer;

	for ("every Pixel") {
		for("Pixel in Buffer") {

#pragma HLS LOOP_FLATTEN
PRAGMA_wDEFINE(HLS PIPELINE II = 1)

			if("First Iteration/New Pixel") {
PRAGMA_wDEFINE(HLS OCCURRENCE cycle = LESS)	

			        left_pix = left_img[ID];
				right_pix = right_img[ID];
                         }

	                 Do some Calculations...

			if("Last Iteration"){

PRAGMA_wDEFINE(HLS OCCURRENCE cycle = LESS)	
					output_img[ID] = result;
					rightPxBuffer.shift_right();
					rightPxBuffer.insert(right_pix, 0, N-1);
			}
		} 
	}
}

 

Buffer:

typedef ap_window<unsigned char, 1, N> PX_N_BUFFER;

 

Callsite:

image_processing((unsigned int*)(ADDRESS_IN_LEFT), (unsigned int*)(ADDRESS_IN_RIGHT), (unsigned int*)ReadCfg.FrameStoreStartAddr[0]);

By memory allocation, do you mean the location for the output image? If so, I only specified some address during the initialization of the VDMA.

 

ReadCfg.FrameStoreStartAddr[0] = ADDRESS_OUT;

 

Thanks a lot,

 

Seek

 

 

 

Explorer
Posts: 118
Registered: ‎09-19-2017

Re: DMA transfer failure

Hi Seek,

 

I think the problem is related to your buffer allocation. Im not a video/linux expert, so my knowledge of memory allocation is limited to: 

 

Everything normally works file when you use sds_alloc/sds_free to manage your buffers between accelerators

 

As far as using VDMAs and then handing off one of the buffers filled by a VDMA to an accelerator, I think you have to use dmabuf (and maybe register the buffer with SDSoC somehow). You can look at the MPSoC TRD example for how to use SDSoC with a VDMA in the platform and sharing a frame buffer between the VDMA and the SDSoC inserted accelerator DMA. Heres a link to the doc:

 

https://www.xilinx.com/support/documentation/boards_and_kits/zcu102/2017_2/ug1221-zcu102-base-trd.pdf

 

Sam

Xilinx Employee
Posts: 10
Registered: ‎05-23-2016

Re: DMA transfer failure

The reporting of a decode error indicates that the address being accessed doesn't have a valid address segment mapping in the design.  You can think of it as analogous to a bus error as observed from a CPU.

 

For example, if you've got 1 gig of DRAM that has been assigned addressing starting from 0x0, and no other assigned segments, you can assume you'd get a decode error if you attempt to instruct the DMA to access address 0x4000_0001 (1 gig + 1).

 

There are a few possibilities here.  One is that the address is truly invalid, in which case the fault likely resides somewhere deep inside the linux video drivers for passing you a garbage address.  This is unlikely, since the problem would very likely have blown up long before you got access to it.  More likely is that, for whatever reason, a mapping was improperly established during generation of the underlying vivado project.  To check this, you can open the vivado project located at <build_area>_sds\p0\_vpl\ipi\ipiprj\ipiprj.xpr, and check in the address editor.  Check what mapping it provided for the DMA throwing errors, and assert that the address you're passing is validl.  Normally, when we lay out IP, we just auto-assign addresses, and under all circumstances that we test this is sufficient.  There are times when we find it isn't sufficient, but we make a point of resolving those issues by fixing auto-assignment before it goes out the door.

 

Software quite naturally contains bugs though, in spite of all efforts.  It's best to double check to make sure we aren't talking about one.

Visitor
Posts: 14
Registered: ‎10-04-2017

Re: DMA transfer failure

Hey Sam,

 

thanks a lot for the link. I will have a look into that.

 

Regards,

seek

Visitor
Posts: 14
Registered: ‎10-04-2017

Re: DMA transfer failure

Hello gill,

 

thanks a lot for the reply.

 

The address range of the VDMA is set to 1G, which should include the failing address. I've attached a screenshot of the settings.

 

However, he address range was initially set to 32M in the original project. I set it to 1G, as the sequences would have been to big otherwise.

 

I am still wondering why it works for the CPU-only build though, but not for the accelerated function. My only guess might be that the simultaneous access might cause the issue.

 

Oh and the project was located in _sds\p0\ipi\prj.xpr, the "_vpl" folder did not exist.

 

Regards,

Seek

VDMA_Address_Editor.JPG
Xilinx Employee
Posts: 10
Registered: ‎05-23-2016

Re: DMA transfer failure

We don't insert VDMAs, so the dma info you're showing in your screenshot isn't the one that is throwing the error.  Also, is there a reason why a single DMA is being attached to two different HP ports?

 

Mind posting more of your design, and a more complete memory map?  I suspect we're actually looking at the problem [forcing HP ports to have strange addressing by having a single device master two of them], but it'd be good to confirm.

 

 

Visitor
Posts: 14
Registered: ‎10-04-2017

Re: DMA transfer failure

Hello gill,

 

since I merely adopted the vivado-project and built my SDx-project based on it, I do not know if there was a special reason behind this. 

 

I have attached the Block Design and the full Address Editor.

 

Regards,

seek

Explorer
Posts: 118
Registered: ‎09-19-2017

Re: DMA transfer failure

Hi Seek,

The HP ports should have the exact same address mapping. Also, if your platform has 1GB of DDR it will normally be mapped into the 0x00000000 - 0x3FFFFFFF address range. So the mapping for HP1 to 0x40000000 - 0x41FFFFFF doesn't make sense to me. That is probably whats causing your problem.

Looking at the block design it looks like your platform creator was trying to increase bandwidth to the VDMA by using two HP ports for the M_AXI_MM2S and M_AXI_S2MM interfaces. But then connects these two interfaces to the same AXI Interconnect. And then from that interconnect to the two HP ports. The problem with that is that both HP ports have the same address space (they go to DDR). So there is no way for the AXI Interconnect to be able to direct requests from one interface on the VDMA to HP0 or HP1. Vivado probably gave an error, which is why HP1 is mapped to a different address range.

So theres a few problems with the platform here.

1. If you want to use two HP ports for the VDMA you need two AXI Interconnects. One from M_AXI_MM2S to HP0, and one from M_AXI_S2MM to another HP port. This way the requests from each interface will go into the correct HP port.

2. Both HP ports must have the same address mapping to DDR for your board (which is likely 0x00000000 - 0x3FFFFFFF)

The error that your seeing (decode) is when the DMA that SDSoC inserts has a problem reading data at runtime. This is almost always caused by the DMA not having the correct address space mapping so that it can access the buffer that is allocated using sds_alloc().

Sam