cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
dawatson
Observer
Observer
6,148 Views
Registered: ‎05-15-2012

XPS DMA Central and BRAM endianness

Jump to solution

Hi all

 

I have an EDK project with a Microblaze, XPS DMA central controller, and a dual port BRAM with slave PLB at one end and LMB at the other. The idea is to use the DMA to transfer data to the BRAM so the MIcroblaze can process it. However, when reading the data back from the BRAM, after a successfull DMA transfer, it is in big-endian format. I can write to the BRAM normally and read back the same value. Here is some terminal output to illustrate the point a bit better:

 

Capture.PNG

 

This is the reading of the source and destination buffers for 8 (and 32) bytes using u32 and u8 types respectively. Basically, on the right you can see the bytes are copied from memory into the BRAM in the correct order. On the left, when reading the data back as a u32 data type (4 bytes) you get the big endian representation of the data stored in memory, but the u32 read from memory yields little endian.
Has anyone came across this sort of thing before? The Microblaze uses big endian by default and when looking at the ports for the BRAM it appears to also be big endian [0:31]. So why would the terminal printout give (what appears to be) little for memory reads and big for BRAM reads?
Any input would be greatly appreciated.
Cheers
David

 

0 Kudos
1 Solution

Accepted Solutions
dawatson
Observer
Observer
7,774 Views
Registered: ‎05-15-2012

I've solved the problem but I've no idea why it's happening. If I offset the destination buffer by 2 bytes before starting the transfer then the bytes align properly and eveything's fine.

 

If anyone wants to explain that one then feel free!

View solution in original post

0 Kudos
6 Replies
dawatson
Observer
Observer
6,137 Views
Registered: ‎05-15-2012

OK. Think I've not initialised the BRAM - this may be the problem...

 

But since I'm using a xps_bram_controller and a lmb_controller, does that mean I have to initialise both these controllers, or the BRAM itself, or...?

 

Any ideas?

0 Kudos
dawatson
Observer
Observer
6,125 Views
Registered: ‎05-15-2012

Got more results and insight into what's happening:

/* Code for the following results */
xil_printf("unsigned char\t\tint\n");
for(i=0;i<4;i++){
	xil_printf("%d: %x = %x\t\t",i,Xil_In8(BUFFER_ONE+i),Xil_In8(BRAM_BUFFER_ONE+i));
	xil_printf("%d: %x = %x\t\t\n",i,Xil_In32(BUFFER_ONE+i),Xil_In32(BRAM_BUFFER_ONE+i));
}

/* Results */
unsigned char		unsigned int
0: 0 = 0		0: 9B = 9B0000		
1: 9B = 9B		1: 9B = 9B0000		
2: 0 = 0		2: 13D = 9B0000		
3: 0 = 0		3: 13D = 9B0000	

/* Code for the following results */
xil_printf("unsigned char\t\tunsigned short\n");
for(i=0;i<4;i++){
	xil_printf("%d: %x = %x\t\t",i,Xil_In8(BUFFER_ONE+i),Xil_In8(BRAM_BUFFER_ONE+i));
	xil_printf("%d: %x = %x\t\t\n",i,Xil_In16(BUFFER_ONE+i),Xil_In16(BRAM_BUFFER_ONE+i));
}

/* Results */
unsigned char	unsigned short
0: 0 = 0		0: 9B = 9B		
1: 9B = 9B		1: 9B = 9B		
2: 0 = 0		2: 0 = 0		
3: 0 = 0		3: 0 = 0

Trying to eliminate any possible type errors I've used the buffer addresses to index and the XIo functions to read the memory locations. What I've noticed is that if you try access 4 bytes (an integer) then you get the bytes in reverse order but you also get the same access for the first 4 indexes of that location. So (ignoring the lack of casting) the first test shows that for the first four access you get the same reversed byte order of the actual value 4 times, whereas with the (uncasted) memory access you get it only twice. In the second test the 2 byte access give the value twice, the same as the memory access. 

I reckon this is a software issue and not hardware but I have no idea what is going on here, does anyone? 

0 Kudos
dawatson
Observer
Observer
6,110 Views
Registered: ‎05-15-2012

Here's another round of results for anyone reading this thread. Code:

 

xil_printf("u8\t\tu16\t\tu32\t\tu64\n");
for(i=0;i<12;i++){
	xil_printf("%d: %x \t\t",i,*((u8*)DestBuffer+i));
	xil_printf("%x \t\t",*((u16*)DestBuffer+i));
	xil_printf("%x \t\t",*(DestBuffer+i));
	xil_printf("%x \t\t\n",*((u64*)DestBuffer+i));
}

 Output (I did format this):

u8		u16		u32		        u64
0: 0 		9B 		9B0000 		        9B0000 		
1: 9B 		0 		13D0000 		1CB0000 		
2: 0 		13D 		1CB0000 		2F20000 		
3: 0 		0 		2510000 		3FC0000 		
4: 1 		1CB 		2F20000 		48B0000 		
5: 3D 		0 		3810000 		5710000 		
6: 0 		251 		3FC0000 		67E0000 		
7: 0 		0 		44C0000 		7800000 		
8: 1 		2F2 		48B0000 		89A0000 		
9: CB 		0 		50E0000 		98B0000 		
10: 0 		381 		5710000 		9B40000 		
11: 0 		0 		5E60000 		9D40000 

 So as you can see (again), the bytes are in the BRAM in the correct order. Accessing 2-bytes gives the correct output. 4- and 8-byte accesses give bytes in the wrong order. These accesses are only taking place over the PLB as I disabled prt B until I sort this out.

 

Any input is appreciated.

0 Kudos
dawatson
Observer
Observer
6,106 Views
Registered: ‎05-15-2012

OK guys, I went through the XMD console to look at the memory locations and they aren't the same:

 

First 4 bytes:

MemoryBRAM

XMD% mrd 0x9F71735A XMD% mrd 0X00080000
9F717358: 0000009B 80000: 009B0000

 

 

Second 4 bytes:

MemoryBRAM

XMD% mrd 0x9F71735E XMD% mrd 0X00080004
9F71735C: 0000013D 80004: 013D0000

 

It looks like its writing to the BRAM on a 2-byte boundary for some reason. Is that configured anywhere?

 

 



Does anyone know why the DMA wouldn't write the bytes in the same order?

0 Kudos
dawatson
Observer
Observer
7,775 Views
Registered: ‎05-15-2012

I've solved the problem but I've no idea why it's happening. If I offset the destination buffer by 2 bytes before starting the transfer then the bytes align properly and eveything's fine.

 

If anyone wants to explain that one then feel free!

View solution in original post

0 Kudos
asciicom
Visitor
Visitor
6,063 Views
Registered: ‎08-27-2012

Hi dawatson,

 

I am afraid I cannot be helpful to you, but I would really like to know how could you manage to make the DMA controller to communicate with the BRAM.

I think I am more or less in the same situation as you, I have a microblaze and I would like to transfer some dat from DDR to BRAM through the Central DMA, but I have no idea how to arrange the connections!

It looks like the BRAM block can communicate only on the LMB bus, so how to make it communicate through the PLB?

Thank you for your attention I am having an hard time finding examples in this sense.

0 Kudos