VUnit / vunit

VUnit is a unit testing framework for VHDL/SystemVerilog

Home Page:http://vunit.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unaligned accesses to AXI read and write slaves wrongly fail 4kbyte boundary check

ru551n opened this issue · 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;