Unaligned accesses to AXI read and write slaves wrongly fail 4kbyte boundary check
ru551n opened this issue · 0 comments
When doing unaligned accesses around a 4k boundary, 4k boundary check wrongly fail in AXI read and write slaves.
Example:
Bus width: 32 bits
Start address: 3841
Burst length, beats: 64 beats
Burst length, bytes: 255
When doing unaligned write accesses, by in this case starting from 3841, the first byte in the first beat will have it's strobe bit set to zero, i.e not writing that byte, which is expected.
However, the access is still 64 beats long, as expected, but the check_4kbyte_boundary
method in axi_slave_private_pkg
will count the end address of the access from the start address of the burst, not the aligned address.
This will incorrectly assume that the burst ends at address 3841 + 4 * 64 - 1 = 4096, and not at address 4095 (which is what will happen when writing), but the access is still 64 beats long, one byte is just strobed out in the first beat.
A suggested patch here is to count from the starting address which is aligned.
procedure check_4kbyte_boundary(burst : axi_burst_t) is
variable first_address, last_address : integer;
variable first_page, last_page : integer;
begin
first_address := burst.address - (burst.address mod data_size); -- Aligned
last_address := first_address + burst.size*burst.length - 1;
first_page := first_address / 4096;
last_page := last_address / 4096;
if first_page /= last_page then
fail("Crossing 4KByte boundary. First page = "
& integer'image(first_page) & " (" & to_string(first_address) & "/4096)"
& ", last page = "
& integer'image(last_page) & " (" & to_string(last_address) & "/4096)");
end if;
end procedure;