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!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer mostafa@sint
Observer
161 Views
Registered: ‎01-01-2019

Zynq memory access problem

Hi All,

I am working with Zynq 7000 on Zedboard. 

I have a simple program that at the beginning I use  following lines to define a 2D array:

 

float **even_odd_arr = (float **)malloc(numrows * sizeof(float *));
for (i=0; i<r; i++)
even_odd_arr[i] = (float *)malloc(numcols * sizeof(float));

 

It works fine and I can access to it form other parts of the code while it is up to 8*256 for  number of rows and number of columns.

But if I want to try 16 as the number of rows or more then I can access to it in a right way. sometimes even at the first row it stops.

I have debugged it and found even in the debugger when I want to access to some of elements I get an error like this:

Size: 4 bytes, Type: float
Address: 0x40e00000
Exception: Cannot read target memory. Memory read error at 0x40E00000. Blocked address 0x40e00000. PL AXI slave ports access is not allowed. This address has not beed added to the memory map

I have to note that the bit file that I used for programming the Zynq contains two DMA and an FFT core and the address map for the dmas is all the DDR memory address. But I have not used FFT or dma in this

code. It is just filling and reading a two dimentional array.

-->> The heap size is 64MB and the stack ssize is 8MB

-->> I have found that it sometimes even works when I give it bigger arrays and sometimes stops. I t seems there is an memory access violations that happens when

I want to access to the memory while another part of the system has blocked it.

Thanks for your help

 

Tags (3)
0 Kudos
2 Replies
Moderator
Moderator
117 Views
Registered: ‎10-06-2016

Re: Zynq memory access problem

Hi mostafa@sint 

Without taking a look at all to your code or linker script the debugger is already pointing out that you have some issues with the pointers. As reported in the error message 0x40e00000 is not pointing out to DDR, it belongs to the PL slave address space.

BTW: is there any reason why you are allocating dynamically the buffer?


Ibai
Don’t forget to reply, kudo, and accept as solution.
0 Kudos
Observer mostafa@sint
Observer
71 Views
Registered: ‎01-01-2019

Re: Zynq memory access problem

H

Thanks for your reply.

First I should show you the snapshot of the block diagram as bellow:

Annotation 2020-02-14 094913.jpg

 

It has an FFT IPcore from xilinx with two separate DMA controollers.

I wanted to be able to send any buffer that I want to FFT core so the address space of theDMAs is all over the 512MB available at the Zedboard.

The address segments are like this:

# Create address segments
create_bd_addr_seg -range 0x20000000 -offset 0x00000000 [get_bd_addr_spaces input_dma/Data_MM2S] [get_bd_addr_segs processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM
create_bd_addr_seg -range 0x20000000 -offset 0x00000000 [get_bd_addr_spaces output_dma/Data_S2MM] [get_bd_addr_segs processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM
create_bd_addr_seg -range 0x00010000 -offset 0x40400000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs input_dma/S_AXI_LITE/Reg] SEG_input_dma_Reg
create_bd_addr_seg -range 0x00010000 -offset 0x40410000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs output_dma/S_AXI_LITE/Reg] SEG_output_dma_Reg

 

But finally in the code that I am working on it now, I have not used the FFT core yet and just working with arrays. I want to have this arrays in the DDR because they can be too big to fit on the zynq,

ans so I had to define them in the dynamic way because I need to check the algorithm for different sizes of arrays.

I cant understand why it gives me error for PL and how I can explicitly force it to put an array at DDR.

the code is same as bellow:

 

/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/

/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xaxidma.h"
#include "xparameters.h"
#include "xil_cache.h"
#include "math.h"
#include "xscugic.h"
#include "xtime_l.h"

#include "util_functions.h"
#include "combined_fft_functions.h"


#include "testMaterial_FFT_256.h"

//static XScuGic s2mm_intr;
//static XScuGic mm2s_intr;
#define NUMBER_OF_TESTS 1
#define FFT_LENGTH 256
static XScuGic intr_ctrl;
static XAxiDma inputDma;
XAxiDma outputDma;

float *AllignArray(float *ptr, int size);
void ConfigureDMA();
void copy_array_1D(float *arr_in, float *dest_arr, int length );
void separate_multiple_even_odd_N_level(float *signal_in, float **dest_arr, int signal_length, int stages_number);

int main()
{

init_platform();

const int rawarraysize = 8192*8;
const int small_array_length = 256;
const int number_of_stages = (int)log2f(rawarraysize / small_array_length) ;
const int numrows = pow(2,number_of_stages); // or rawarraysize / small_array_length
const int numcols = small_array_length;
long i, k, n, m, q;
double w, pi;
xtest = (float *) malloc(rawarraysize * sizeof(float));
float **even_odd_arr = (float **)malloc(numrows * sizeof(float *));
for (i=0; i<numrows; i++)
even_odd_arr[i] = (float *)malloc(numcols * sizeof(float));

for (int i=0;i<rawarraysize;i++)
xtest[i] = i ;
separate_multiple_even_odd_N_level(xtest,even_odd_arr,rawarraysize,number_of_stages);
printf("\r\n separate is done");
fflush(stdout);

fflush(stdout);

return 0;
}

void copy_array_1D(float *arr_in, float *dest_arr, int length )
{
for (int i = 0; i< length ; i++)
dest_arr[i] = arr_in[i];
}

void get_odd_even_elements(float *arr_in, float *even_arr, float *odd_arr, int length)
{
int counter = 0;
for (int i=0;i<length-1;i=i+2)
{
even_arr[counter] = arr_in[i];
odd_arr[counter] = arr_in[i+1];
counter++;
}

}

void separate_multiple_even_odd_N_level(float *signal_in, float **dest_arr, int signal_length, int stages_number)
{
int tempsignal_length = signal_length;
int w = (int)(signal_length/pow(2, stages_number));
int h = pow(2,stages_number);
float *tempsignal;
tempsignal = (float *) malloc(signal_length * sizeof(float));
float *e1;
e1 = (float *) malloc((int)signal_length/2 * sizeof(float));
float *o1;
o1 = (float *) malloc((int)signal_length/2 * sizeof(float));
for(int n =0;n<h;n++)
{
tempsignal = (float *) malloc(signal_length * sizeof(float));
tempsignal_length = signal_length;
copy_array_1D(signal_in,tempsignal,signal_length);

for(int b=0;b<stages_number;b++)
{
get_odd_even_elements(tempsignal,e1,o1,tempsignal_length);
tempsignal_length = (int)tempsignal_length /2;

tempsignal = (float *) malloc(tempsignal_length * sizeof(float));
if(n & (1<<(stages_number-1-b)))
copy_array_1D(o1,tempsignal,tempsignal_length);
else
copy_array_1D(e1,tempsignal,tempsignal_length);
}

copy_array_1D(tempsignal,dest_arr[n],tempsignal_length);
free(tempsignal);
}
}
void SetupInterrupts()
{
XScuGic_Config *intr_ctrl_config;

intr_ctrl_config = XScuGic_LookupConfig(XPAR_SCUGIC_0_DEVICE_ID);

XScuGic_CfgInitialize(&intr_ctrl, intr_ctrl_config, intr_ctrl_config->CpuBaseAddress);

XAxiDma_IntrDisable(&outputDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(&inputDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);

XScuGic_Connect(&intr_ctrl, XPAR_FABRIC_OUTPUT_DMA_S2MM_INTROUT_INTR, (Xil_InterruptHandler)s2mm_ISR, NULL);
XScuGic_Connect(&intr_ctrl, XPAR_FABRIC_INPUT_DMA_MM2S_INTROUT_INTR, (Xil_InterruptHandler)mm2s_ISR, NULL);

XAxiDma_IntrEnable(&outputDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrEnable(&inputDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DMA_TO_DEVICE);

Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, &intr_ctrl);
Xil_ExceptionEnable();

XScuGic_Enable(&intr_ctrl, XPAR_FABRIC_OUTPUT_DMA_S2MM_INTROUT_INTR);
XScuGic_Enable(&intr_ctrl, XPAR_FABRIC_INPUT_DMA_MM2S_INTROUT_INTR);
}


void ConfigureDMA()
{
XAxiDma_Config inputDmaConfig = *XAxiDma_LookupConfigBaseAddr(XPAR_INPUT_DMA_BASEADDR);
XAxiDma_Config outputDmaConfig = *XAxiDma_LookupConfigBaseAddr(XPAR_OUTPUT_DMA_BASEADDR);
printf("cfg_init input dma = %d\n\r", XAxiDma_CfgInitialize(&inputDma, &inputDmaConfig));
printf("cfg_init output dma = %d\n\r", XAxiDma_CfgInitialize(&outputDma, &outputDmaConfig));
}

 

Thanks a lot for your supprt.

 

 

 

 

0 Kudos