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
Did you mean:
4,348 Views
Registered: ‎01-13-2015

I'm just testing HLS code to implement AXI master in HLS, and I refer to AR# 59228, https://www.xilinx.com/support/answers/59228.html

in that code, the address is divided by 4 like memcpy(buff, m+(BASE_ADDR/4), N*sizeof(uint32));.

Can anyone tell me why?

Thank you

5 Replies
Scholar
4,337 Views
Registered: ‎04-26-2015

m is a pointer to a 32-bit value, so m + 1 is actually four bytes further along in memory than m was.

BASE_ADDR is an address measured in bytes. Since adding 1 to m effectively shifts four bytes, you need to divide the number of bytes by four before adding. This way, if BASE_ADDR = 4, BASE_ADDR / 4 = 1, and m + BASE_ADDR/4 will be m + 1 (which, as above, is four bytes further along than m).

Teacher
4,311 Views
Registered: ‎03-31-2012

@u4223374 but this doesn't explain why it's not "m*4 + BASE_ADDR". memcpy addresses are supposed to be byte addresses, not element counts, no?

Give Kudos to a post which you think is helpful and reply oriented.
Scholar
4,300 Views
Registered: ‎04-26-2015

@muzaffer

Good point, there's a bit more complexity to it.

When you add a value (N) to a uint32*, the actual result is that the byte address of the uint32* is moved by 4*N bytes (ie so you move N uint32s further along in memory).

`m + (BASE_ADDR/4)*4`

An alternative would be to cast to uint8* first, so that adding one to it is exactly the same as shifting by one byte.

`((uint8*) m) + BASE_ADDR`

This should yield exactly the same result.

4,261 Views
Registered: ‎01-13-2015

I understand what you guys are saying, but I think that BASE_ADDR should not be divided by 4.

Is there any references of memcpy() function with explanation of why that address has to be unit of 4-byte?

And here below is my quick codes

Between A code and B code, which one is correct one???

//***** Target Board: ZC702 Board *****
#define BYTE_P_PIXEL    2
#define HSIZE_IMAGE    640
#define VSIZE_IMAGE    480
#define SIZE_IMAGE    HSIZE_IMAGE*VSIZE_IMAGE //307200=0x4B000
#define LEN_IMAGE    SIZE_IMAGE*BYTE_P_PIXEL //614400=0x96000
#define SIZE_BURST    4
#define LEN_BURST    SIZE_BURST*4
#define LOOP_CNT    LEN_IMAGE/(LEN_BURST)

int i=0;

//================ Code A ================
for(i=0; i<LOOP_CNT; i++){
LEN_BURST/*Len in 4-byte*/);
}

//================ Code B ================
for(i=0; i<LOOP_CNT; i++){
LEN_BURST/*Len in 4-byte*/);
}

Thank you

Highlighted
Teacher
4,250 Views
Registered: ‎03-31-2012

>> I understand what you guys are saying, but I think that BASE_ADDR should not be divided by 4.

Those two statements are contradictory ;-)

>> Is there any references of memcpy() function with explanation of why that address has to be unit of 4-byte?

This is not about memcpy but a C language design feature where pointers to different objects are incremented by the size of the object to which they point, how arrays & pointers are the same thing and another feature called casting. To wit, assume uint32 * p = x, then the next object is at p+1 (not p+sizeof(uint32)). You can see this as uint32 pa[100]; pa[1] is one after pa[0] but the &pa[1] = &pa[0] + 4.

So if you have a uint32* you need to add object counts to it to advance it, not byte offsets and when you cast it to a char* the compiler does the proper multiplication for you.

PS the address does not have a unit of 4-byte but sizeof(uint32). If your axi master had 64 bit data path, you would need to divide by 8.