I've created a Xillybus core with a bidirectional memory-mapped interface on a B core, 64-bits data with 32-bit address width on an Ultrascale system.
I understand that if I use lseek to go to a file position, I need to do it in multiples of 8: so if I want to go to the upper quarter of the address space (0xC000_0000), I would do something like
- Code: Select all
off_t addr = 0x600000000;
lseek(fd, addr, SEEK_SET);
This is on a system where sizeof(off_t) == 8, so this should be fine. However, when I do that, in the FPGA I actually see the address come out as 0x4000_0000 with the addr_update. A little playing around with addresses seems like what happens is that if I send a 64-bit integer to lseek, for a 32-bit address space, bits[33:3] are output as user_xx_addr[30:0], but nothing I can do seems to ever set bit 31 - in other words, it looks like it's a 31-bit address space.
There's a bit of a note in the revision B user notes:
When using these wider data interfaces, it's important to observe that since the natural data element of the PCIe bus is a 32-bits, some software safeguards that prevent erroneous use of streams do not apply when the data width goes above 32 bits. For example, any read() or write() call for a 64-bit stream must have a lengh that is a multiple of 8. Likewise, the seek positions for a seekable 64-bit wide stream must be a multiple of 8 to achieve any meaningful result. The software will however only enforce that it's a multiple of 4.
which makes me wonder whether this might be intentional (like, the address space is 32-bits address, 32-bits data underneath, but mapped to 31-bit address, 64-bit data at the interface) but it'd be nice to confirm that.