Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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

Status
Not open for further replies.

msdarvishi

Full Member level 4
Joined
Jul 30, 2013
Messages
230
Helped
1
Reputation
2
Reaction score
1
Trophy points
18
Activity points
2,349
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 View attachment system.pdf





My C code written in SDK :

Code:
/***************************** 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 :


uart1.png


The result shown by XSDB :


xsdb1.png
 

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 View attachment 149395





My C code written in SDK :

Code:
/***************************** 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 :


View attachment 149393


The result shown by XSDB :


View attachment 149394

Isn't there any experience or hint in this regards?
 

You can simulate whole design including Microblaze core and your compiled program using Vivado simulator. Start the simulation and see if the AXI master from Microblaze asks for whole 32 bits. Remove all unnecessary functions from C code (all printfs, etc). Try using Xil_In32, Xil_Out32 macros/functions.
 

I would insert an AXI bfm into the design and just perform AXI 32-bit transactions to the DMA with that, no need to use the Microblaze to perform them in a simulation. If the bfm performs the operations correctly then it's the Microblaze software (or compile switch) that is to blame.
 

I would insert an AXI bfm into the design and just perform AXI 32-bit transactions to the DMA with that, no need to use the Microblaze to perform them in a simulation. If the bfm performs the operations correctly then it's the Microblaze software (or compile switch) that is to blame.

Dear @ads-ee,

Thanks for your reply. AS far as I see in my searches, AXI BFM stands for AXI Bus Functional Model which is available also for the Zynq. However, I could not find any link to order its IP through my Xilinx Account gateway. Do you have any idea about ordering this IP?

Thanks
 
Last edited:

Dear @ads-ee,

Thanks for your reply. AS far as I see in my searches, AXI BFM stands for AXI Bus Functional Model which is available also for the Zynq. However, I could not find any link to order its IP through my Xilinx Account gateway. Do you have any idea about ordering this IP?

Thanks

Sorry, but I don't have any idea how to order it. I rolled my own as the company I work for is too cheap to spend money on VIP. They barely want to let me run verification on my FPGAs before I load them on a board. (but the seem to be okay with me wasting time writing my own BFM for it, go figure)

I have seen a few systemverilog versions, which I couldn't try at the time....Vivado at the time did not support enough of systemverilog to even compile the simulation.
 

Here is a place which I trust has a bunch of BFMs. See if the one you are looking for his here.
http://syswip.com/
 

The problem is probably in this row:
Code:
*dma_addr1 = *(unsigned int*)0x41e00000 = *ddr3_addr1;

Without optimization, the compiler will probably do this:
Code:
*(unsigned int*)0x41e00000 = *ddr3_addr1;
*dma_addr1 = *(unsigned int*)0x41e00000;

Is that what you want?
Is it possible to both read and write location 0x41e00000 ?
 

The problem is probably in this row:
Code:
*dma_addr1 = *(unsigned int*)0x41e00000 = *ddr3_addr1;

Without optimization, the compiler will probably do this:
Code:
*(unsigned int*)0x41e00000 = *ddr3_addr1;
*dma_addr1 = *(unsigned int*)0x41e00000;

Is that what you want?
Is it possible to both read and write location 0x41e00000 ?

@std_match,

Thanks for your reply. The logic of your hint is correct. The AXI DMA wants to read from DDR3 through MM2S port and write into the BRAM through S2MM port. While I did your hint, I still have the same problem ! Seems to wrird to me!

'
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top