Jump to content
  • 0

Why AXI DMAreads only 16 bit from DDR3 instead of 32 bits in my design?


daryon

Question

Dear all,

 

I am working with Vivado 2017.3 targeting a KC705 evaluation board (with Kintex-7 xc7k325ffg900 FPGA).

 

I have block design omprised of a DDR3, an AXI DMA and a BRAM connected through AXI Interconnect all of them controlled by a Microblaze.

 

My Objectives :

a) I want to write some data to the DDR3 with Microblaze through a C code writtenin SDK ---> This part was successfull.

 

b) Then, I want to read back those data from DDR3 and write them to the BRAM through an AXI DMA connected to a AXIStream FIFO.  ----> The connections are as shown in the attached photo of my design and the bitstream was generated successfully.

 

c) I wrote a code in SDK in C to write some data to first 16 addresses of DDR3 which was successfullbecause when I verify the content of DDR3 via Microblaze, my written data are there.

 

d) finnally, in my C code I have defined a function to read data fom DDR3 into the AXI DMA ----> My problem is hear when I read the content of the first address in AXI DMA, it contains ONLY 16 bits of my data instead of 32-bit written data in it. As you see in the XSDB result and also UART result, instead of the value 0xBABABEE0 writtnenin the first AXI DMA address (0x41E00000), I receive 0xBABA3002 !!!!

 

For more clarification, I put the schematic of my design, my C code in SDK and the results shown on UART and XSDB.

 

Can anyone help me to resolve this problem? I am really confused! Thank in advance for your kind replies and helps.

 

Bests,

Daryon

 

 

 

My design schematic : Attachedsystem.pdf file

 

 

My C code written in SDK :

 

/***************************** Include Files *********************************/

#include "xparameters.h"
#include <xil_printf.h>
#include <stdio.h>
#include "xil_exception.h"
#include "xuartlite.h"
#include "xbram.h"




int DDR3datawriting( int *ddr3_addr1,  int *ddr3_addr2,  int *ddr3_addr3,  int *ddr3_addr4,  int *ddr3_addr5,  int *ddr3_addr6,  int *ddr3_addr7,  int *ddr3_addr8,  int *ddr3_addr9,  int *ddr3_addr10,  int *ddr3_addr11,  int *ddr3_addr12,  int *ddr3_addr13,  int *ddr3_addr14,  int *ddr3_addr15,  int *ddr3_addr16);
int DDR3datareading( int *dma_addr1,  int *ddr3_addr1);


/************************** Variable Definitions *****************************/


//Global variables
//unsigned int *ddr3_addr1, *ddr3_addr2, *ddr3_addr3, *ddr3_addr4, *ddr3_addr5, *ddr3_addr6, *ddr3_addr7, *ddr3_addr8, *ddr3_addr9, *ddr3_addr10, *ddr3_addr11, *ddr3_addr12, *ddr3_addr13, *ddr3_addr14, *ddr3_addr15, *ddr3_addr16;

//



int main()
{

	//Local variable
	int Status;
	 int ddr3_addr1, ddr3_addr2, ddr3_addr3, ddr3_addr4, ddr3_addr5, ddr3_addr6, ddr3_addr7, ddr3_addr8, ddr3_addr9, ddr3_addr10, ddr3_addr11, ddr3_addr12, ddr3_addr13, ddr3_addr14, ddr3_addr15, ddr3_addr16;
	 int dma_addr1;

	
	// Writing data into DDR3 memory
	Status = DDR3datawriting(&ddr3_addr1, &ddr3_addr2, &ddr3_addr3, &ddr3_addr4, &ddr3_addr5, &ddr3_addr6, &ddr3_addr7, &ddr3_addr8, &ddr3_addr9, &ddr3_addr10, &ddr3_addr11, &ddr3_addr12, &ddr3_addr13, &ddr3_addr14, &ddr3_addr15, &ddr3_addr16);

	//Checking the validity of returned variables value to the main function
	xil_printf("\n\r****** Returned valued of ddr3_addr1 to the main() function = %x\n\r",ddr3_addr1);
	xil_printf("\n\r The address of ddr3_addr1 = %x\n\r", &ddr3_addr1);

	// Reading data from DDR3 into the AXI DMA (axi_dma_0)
	Status = DDR3datareading(&dma_addr1,&ddr3_addr1);

    //End of program
	return Status;
}

/****************************************************************************/

int DDR3datawriting( int *ddr3_addr1, int *ddr3_addr2, int *ddr3_addr3, int *ddr3_addr4, int *ddr3_addr5, int *ddr3_addr6, int *ddr3_addr7, int *ddr3_addr8, int *ddr3_addr9, int *ddr3_addr10, int *ddr3_addr11, int *ddr3_addr12, int *ddr3_addr13, int *ddr3_addr14, int *ddr3_addr15, int *ddr3_addr16)
{

	//unsigned int ddr3_addr1, ddr3_addr2, ddr3_addr3, ddr3_addr4, ddr3_addr5, ddr3_addr6, ddr3_addr7, ddr3_addr8, ddr3_addr9,ddr3_addr10,ddr3_addr11,ddr3_addr12,ddr3_addr13,ddr3_addr14,ddr3_addr15,ddr3_addr16;

	xil_printf("\n\rStarting to write some data into DDR3 memory...\n\r");
	xil_printf("The BaseAddress for DDR3 Memory is 0x8000_0000\n\r");

	//ddr3_addr1  = *(int*)0x80000000;
	//ddr3_addr1  = 0xDEADBEE0;
	*ddr3_addr1  = *(int*)0x80000000 = 0xBABABEE0;
	*ddr3_addr2  = *(int*)0x80000004 = 0xDEADBEE1;
	*ddr3_addr3  = *(int*)0x80000008 = 0xDEADBEE2;
	*ddr3_addr4  = *(int*)0x8000000C = 0xDEADBEE3;
	*ddr3_addr5  = *(int*)0x80000010 = 0xDEADBEE4;
	*ddr3_addr6  = *(int*)0x80000014 = 0xDEADBEE5;
	*ddr3_addr7  = *(int*)0x80000018 = 0xDEADBEE6;
	*ddr3_addr8  = *(int*)0x8000001C = 0xDEADBEE7;
	*ddr3_addr9  = *(int*)0x80000020 = 0xDEADBEE8;
	*ddr3_addr10 = *(int*)0x80000024 = 0xDEADBEE9;
	*ddr3_addr11 = *(int*)0x80000028 = 0xDEADBEEA;
	*ddr3_addr12 = *(int*)0x8000002C = 0xDEADBEEB;
	*ddr3_addr13 = *(int*)0x80000030 = 0xDEADBEEC;
	*ddr3_addr14 = *(int*)0x80000034 = 0xDEADBEED;
	*ddr3_addr15 = *(int*)0x80000038 = 0xDEADBEEE;
	*ddr3_addr16 = *(int*)0x8000003C = 0xDEADBEEF;

	xil_printf("\n\r Data written at 0x80000000 is %6x\n\r",*ddr3_addr1);
	xil_printf("\n\r Data written at 0x80000004 is %6x\n\r",*ddr3_addr2);
	xil_printf("\n\r Data written at 0x80000008 is %6x\n\r",*ddr3_addr3);
	xil_printf("\n\r Data written at 0x8000000C is %6x\n\r",*ddr3_addr4);
	xil_printf("\n\r Data written at 0x80000010 is %6x\n\r",*ddr3_addr5);
	xil_printf("\n\r Data written at 0x80000014 is %6x\n\r",*ddr3_addr6);
	xil_printf("\n\r Data written at 0x80000018 is %6x\n\r",*ddr3_addr7);
	xil_printf("\n\r Data written at 0x8000001C is %6x\n\r",*ddr3_addr8);
	xil_printf("\n\r Data written at 0x80000020 is %6x\n\r",*ddr3_addr9);
	xil_printf("\n\r Data written at 0x80000024 is %6x\n\r",*ddr3_addr10);
	xil_printf("\n\r Data written at 0x80000028 is %6x\n\r",*ddr3_addr11);
	xil_printf("\n\r Data written at 0x8000002C is %6x\n\r",*ddr3_addr12);
	xil_printf("\n\r Data written at 0x80000030 is %6x\n\r",*ddr3_addr13);
	xil_printf("\n\r Data written at 0x80000034 is %6x\n\r",*ddr3_addr14);
	xil_printf("\n\r Data written at 0x80000038 is %6x\n\r",*ddr3_addr15);
	xil_printf("\n\r Data written at 0x8000003C is %6x\n\r",*ddr3_addr16);
	xil_printf("\n\r-----------------------------------------------------------------------\n\r");

	return *ddr3_addr1;

}
/*****************************************************************************/
int DDR3datareading(int *dma_addr1, int *ddr3_addr1)
{
	//dma_addr2,dma_addr3,dma_addr4,dma_addr5,dma_addr6,dma_addr7,dma_addr8,dma_addr9,dma_addr10,dma_addr11,dma_addr12,dma_addr13,dma_addr14,dma_addr15,dma_addr16;

	xil_printf("\n\rStarting to read some data from DDR3 memory into the AXI DMA...\n\r");
	xil_printf("The BaseAddress for AXI DMA is 0x41E0_0000\n\r");


	//*dma_addr1  = *(int*)ddr3_addr1;
	//*(int*)0x41e00000 = *(int*)ddr3_addr1;
	*dma_addr1 = *(unsigned int*)0x41e00000 = *ddr3_addr1;

	xil_printf("\n\r Data read from 0x41E00000 is %6x\n\r",*dma_addr1);
	xil_printf("\n\r-----------------------------------------------------------------------\n\r");
	xil_printf("\n\r new value of 0x41E00000 is %6x\n\r",*(int*)0x41e00000);
	return *dma_addr1;
}

 

The result shown on UART Interface : (attached uart1.png file)

The result shown on UART Interface : (attached xsdb1.png file)

uart1.png

xsdb1.png

system.pdf

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

Hi,

I think your C code does not do what it suggests it does.

Here...

int ddr3_addr1, ddr3_addr2, ddr3_addr3, ddr3_addr4, ddr3_addr5, ddr3_addr6, ddr3_addr7, ddr3_addr8, ddr3_addr9, ddr3_addr10, ddr3_addr11, ddr3_addr12, ddr3_addr13, ddr3_addr14, ddr3_addr15, ddr3_addr16;

... you create variables ddr3_addr on the stack.

Here ...

Status = DDR3datawriting(&ddr3_addr1, &ddr3_addr2, &ddr3_addr3, &ddr3_addr4, &ddr3_addr5, &ddr3_addr6, &ddr3_addr7, &ddr3_addr8, &ddr3_addr9, &ddr3_addr10, &ddr3_addr11, &ddr3_addr12, &ddr3_addr13, &ddr3_addr14, &ddr3_addr15, &ddr3_addr16);

...

you give the address of the variables (still on the stack!) to the function and here ...

*ddr3_addr1 = *(int*)0x80000000 = 0xBABABEE0;

you write the value 0xBABABEE0 into abovementioned stack variable ddr3_addr1 in main(). This is not what you want, probably.

Further, the same value goes into memory address 0x80000000 (this looks meaningful - base address of your DRAM).

Here...

xil_printf("\n\r Data written at 0x80000000 is %6x\n\r",*ddr3_addr1);

you read it from the stack variable.

My suggestion: Clean up the code to the essentials, five lines plus headers. And use volatile  for pointers to force hardware IO (otherwise the processor cache may delay the write and / or intercept the read).

Link: Discussion on chained assignments in C. In a nutshell: Do not use unless you feel you are entitled to a different opinion ?

Link to comment
Share on other sites

>> Can you please do the modifications that you mean on my initial C code posted here and reply to me that might help to overcome this problem??

I'm sure I could but it might be disrespectful to lots of other folks on this forum eager to do your work for you. I suggest let's wait and give them a chance :)

 

 

Link to comment
Share on other sites

That's the spirit :)

And I'm sure people will be willing to help when you're stuck.

Just as a reality check: writing that above mail took me about 30 min (for whatever reasons, maybe it just beats crossword puzzles). How long did you spend to read it?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...