Aligned address and wrap boundary calculation in AXI4

Is aligned address and wrap boundary are same in context to AXI4 ? I found both aligned address and wrap boundary to be 4096 (decimal)for a wrapping burst with 4 beats, transfer size 4 bytes and start address 4098 (decimal). I used the below formula's given in AXI4 to calculate aligned address and wrap boundary.

Aligned_Address = (INT(Start_Address / Number_Bytes) ) x Number_Bytes ( I rounded down 1024.5 to 1024)

Wrap_Boundary = (INT(Start_Address / (Number_Bytes × Burst_Length)))    ( i rounded down 256.125 to 256)
× (Number_Bytes × Burst_Length).

  • They are different things.

    An "aligned address" is an address used to calculate transfer addresses after the first transfer in an INCR transaction. AXI INCR transactions can use an unaligned start address, but you cannot just add an AxSIZE number of bytes to the start address to calculate the next transfer address because the next transfer in the transaction must be to an AxSIZE aligned address. So this is what the "aligned address" calculates.

    For example you could have a 4-beat INCR transaction of width 32-bits, starting at 0x13. The first transfer is to address 0x13 (only transferring 1 byte max), but the second, third and fourth transfers are to 0x14, 0x18 and 0x1C.

    So using the "Aligned_Address" calculation we have Aligned_Address = (INT(0x13/4))*4 = 0x10 (Number_Bytes = 4). And so the addresses for the 2nd, 3rd and 4th transfers are just the "Aligned_Address" value with 0x4 added each time.

    Note that FIXED transaction types can also use unaligned start addresses, but as the address for each transfer in the transaction is "fixed", it remains unaligned for each transfer, so "Aligned_Address" is not relevant. And WRAP burst types do not allow unaligned addresses.

    And mentioning WRAP burst types then nicely brings us on to look at "Wrap_Boundary".

    A WRAP transaction is the type of transaction sequence you would normally see with cache accesses, where the critical data item is accessed first, and then the other entries in the cache line are accessed, incrementing up through the cache line addresses and then wrapping back to the start of the cache line to complete the remaining cache line entries. The "Wrap_Boundary" calculates the address the cache line wraps back to.

    So an example again, if we have a WRAP transaction, 4 transfers, transfer size is 4 bytes, start address is 0x18, we will access 0x18, then 0x1C, before wrapping back to 0x10 and finally 0x14.

    Using the "Wrap_Boundary" calculation we have Wrap_Boundary = (INT(0x18/(4*4)) * 4*4 = 0x10.

    But where the two calculations could appear to return the same figure would be when a WRAP burst starts at an aligned address, so in my cache example we start at the start of the cache line 0x10 and subsequently access 0x14, 0x18 and 0x1C. There is no wrapping point, so the "Wrap_Boundary" is the start address.

    However you cannot have an unaligned start address for WRAP transactions, so there is no need to calculate an "Aligned_Address" as the start address is already aligned to AxSIZE.

    So for your "Aligned_Address" calculation you had (INT(4098/4))*4 = (INT(1024.5)*4 = 1024*4 = 4096. There is no "rounding" required as that is what the INT function does.

    But the "Wrap_Boundary" calculation is invalid because you cannot have an unaligned start address in a WRAP transaction. 4096 would be the correct start address, and as that is the value the "Wrap_Boundary" calculation would give you, it tells you that this transaction does not wrap.

    I've never liked these pseudo code calculations in the specification as they can be confusing, so I prefer to just understand what the different burst types are, and how the addresses change during the transaction, and then just ignore these "calculations".

    INCR bursts use AxSIZE values to increment the address for each transfer based on the AxSIZE aligned start address.

    WRAP bursts will always start with an AxSIZE aligned address, and will access AxSIZE aligned addresses in a byte range specified by AxSIZE*AxLEN, with this byte range also being aligned to an AxSIZE*AxLEN address. The address increments in AxSIZE steps from the start address, usually wrapping back to the start of the AxSIZE*AxLEN byte range to complete the transaction transfers (remembering that a WRAP burst that starts at the beginning of the AxSIZE*AxLEN byte range will not wrap, and so will just look like an INCR sequence).