cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
joancab
Advisor
Advisor
557 Views
Registered: ‎05-11-2015

Problem reading IP-written data from Linux userspace

I have an HLS IP that writes into PS memory using a master AXI port. Then I want to read that data from a Linux app.

The IP block seems to work, looking at the following ILA capture:

joancab_0-1617617642696.png

Although locations are not consecutive (here there is an increment of 0x50), all consecutive positions are eventually written. Below shows, for example, 0x7F00_0004 being written:

joancab_1-1617617846657.png

To read that memory from Linux I use the /dev/mem pseudo-driver and mmap. In a nutshell, I do:

 

 

 

int fd = open("/dev/mem", O_RDWR | O_SYNC);

u32 *mem = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_base);

memcpy(buff, mem, SIZE);

 

 

 

Where:

SIZE is the memory area size in bytes (8k)

page_base is the physical address (0x7F00_0000)

buff is a u32 pointer

Now the weirdest about it: I first pre-write buff[] with 0x0a0a0a0a, 0x0b0b0b0b ... 0x0f0f0f0f to recognize changes. When I run the application, only one every four words are written. And data written is not even in the right location: 0x7F00_0000 should have 0x8629e8e4 but that value appears at buff[44]. also, according to ILA, 0x7F00_0004 should contain 0xa7a392dd but is unchanged and that value appears at buff[76].

joancab_2-1617618438970.png

 

0 Kudos
11 Replies
joancab
Advisor
Advisor
491 Views
Registered: ‎05-11-2015

I'm thinking it could be a problem with address alignment at the master AXI side. All successful writes are aligned to 16 bytes (address 0xXXX.XX0), is it possible to change that in an HLS block?

0 Kudos
randyh
Xilinx Employee
Xilinx Employee
469 Views
Registered: ‎01-04-2013

joancab
Advisor
Advisor
433 Views
Registered: ‎05-11-2015

@randyh 

Thanks, that helps a bit, although at first it doesn't seem to work. I re-built the HLS IP with 0 alignment:

joancab_0-1617789854527.png

I also have 16 outstanding writes that I believe is enough

joancab_2-1617791092795.png

 

I'm still getting data written at one out of four 32-bit words, apparently:

joancab_1-1617790506368.png

The above is obtained with mmap and memcpy to an array in user space.

I checked with ILA that the addresses showing 0 are written something else.

Originally I wrote 32-bit words, in this case I also changed to writing bytes to see if that was the reason, but doesn't seem to be.

I rebuilt everything: HLS IP, Vivado bitstream, linux images, application.

 

 

0 Kudos
joancab
Advisor
Advisor
383 Views
Registered: ‎05-11-2015

I changed the IP to write bytes instead of u32 and tried with alignment 1 (byte) on the HLS settings, I get the same results: 4 bytes are written following 12 aren't:

joancab_0-1617873387220.png

 

0 Kudos
shahzadb
Xilinx Employee
Xilinx Employee
355 Views
Registered: ‎07-12-2019

Hi Joan,

   Can you please try to keep the alignment on IP side at-least which you can achieve in host code. Can you please try to align IP on 4-byte ( 32-bits) and see how it works?

0 Kudos
joancab
Advisor
Advisor
340 Views
Registered: ‎05-11-2015

@shahzadb That would be weird that 4-byte alignment does what 1-byte doesn't.

I tried, weirdest things I have seen, below settings:

joancab_0-1617912999078.png

Similar results:

joancab_1-1617913028462.png

 

 

0 Kudos
shahzadb
Xilinx Employee
Xilinx Employee
311 Views
Registered: ‎07-12-2019

@joancab  The Alignment size is in bits so I was expecting a value of 32 not 4. Please check here :https://www.xilinx.com/html_docs/xilinx2020_2/vitis_doc/lls1585342611108.html#lls1585342611108__ae410299

0 Kudos
joancab
Advisor
Advisor
272 Views
Registered: ‎05-11-2015

Holy moly, then the name m_axi_alignment_byte_size is misleading. It makes people think of size in bytes.

0 Kudos
joancab
Advisor
Advisor
259 Views
Registered: ‎05-11-2015

I set the alignment to 8 (bits) as my current IP block version addreses bytes:

joancab_0-1617958484475.png

Result, again 4 bytes written, 12 not.

joancab_2-1617958828795.png

Interestingly, if I copy the mapped area into an array with:

 

memcpy((void *)(buff), (void *)(mem), 400);

 

And print the array values with

 

printf("%02X%s", buff[i], ((i%16)==15)? "\n" : " ");

 

I get the above values, while if I use the pointer to the mapped memory (mem) like:

 

printf("%02X%s", mem[i], ((i%16)==15)? "\n" : " ");

 

I get slightly different results (?) where only one byte (first column) every 16 is different (??)

joancab_3-1617958941359.png

Is memcpy not working properly?

 

0 Kudos
joancab
Advisor
Advisor
247 Views
Registered: ‎05-11-2015

And similar for an alignment of 32. It seems only addresses type 0xXXXX_XX0X are written (or read back)

0 Kudos
joancab
Advisor
Advisor
155 Views
Registered: ‎05-11-2015

Back to this problem, I tried an even simpler IP core that just writes 16 words in consecutive addresses:

void test(	uint32_t* dout	){
#pragma HLS INTERFACE m_axi port=dout offset=off
#pragma HLS INTERFACE s_axilite port=return

	uint32_t i;
	uint32_t d = 0x0;

	for(i=0; i<16; i++){
		dout[0x1fc00000 + i] = d;
		d += 0x01010101;
	}
}

And ILA shows it should be writing those values (0x00000000, 0x01010101 ... 0x0f0f0f0f)

joancab_1-1618232353447.png

But what I get, again when reading from Linux user space is this below. Again it looks like skipping 3 every four words.

joancab_0-1618232272798.png

So I'm beginning to think the problem is Linux (?)

 

0 Kudos