Three question on AXI transfers, related to disjoint byte access in a single 4 byte word, single transfer.

I have three question on AXI transfers, and these all relate to
a) my understanding of the spec, as all question do, and
b) a single write transfer to a single 32-bit aligned address.

I would like to make a single transfer to write only byte 2 at address 'some_address' across the 4 byte, 32-bit, WDATA bus.
I can see several different ways to do this.

My first question is, does ARM have a recommendation, especially for compatibility with existing implementations, which to use?
Here are the cases, A and B, to update/write byte2 only:

| byte3 | byte2 | byte1 | byte0 | <some_address>, 32-bit aligned (two lower bits normally 2'b00)

A) FIXED or WRAP or INCR | AWLEN == 1 | AWSIZE == 1 | some_address == 0x000000C0 + 2 | WSTRB all bits high
B) FIXED or WRAP or INCR | AWLEN == 1 | AWSIZE == 4 | some_address == 0x000000C0       | WSTRB[3:0] == 4'b0100

In (A), this unaligned single transfer can inform the slave to effectively ignore bytes 3, 1, and 0.
In (B), this aligned single transfer uses the byte enables to inform the slave to attend only to byte 2 (ignore bytes 3, 1, and 0).

If that understanding is correct, I'd like to look at the sixteen cases of single transfers with LEN == 1 for a 32-bit aligned address space.
Below, n means no transfer, Y means transfer this byte.

| n | n | n | n |
This is not and interesting case.

Transfer one byte.
| n | n | n | Y |
| n | n | Y | n |
| n | Y | n | n |
| Y | n | n | n |
Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==1 (A and B above)

Transfer two adjoining bytes.
| n | n | Y | Y |
| n | Y | Y | n |
| Y | Y | n | n |
Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==2 (A and B above)

Transfer three adjoining bytes.
| n | Y | Y | Y |
| Y | Y | Y | n |
Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==3 (A and B above)

Transfer four adjoining bytes.
| Y | Y | Y | Y |
Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==4 (A and B above)

Transfer some combination *not* in the list above, two or three bytes with a disjoint.
| n | Y | n | Y |
| Y | n | n | Y |
| Y | n | Y | n |
| Y | n | Y | Y |
| Y | Y | n | Y |
The problematic cases are these five. They require WSTRBs in order to be done in single transactions. I call them problematic because the specification says:

(page 45 of ARM IHI 0022D (ID102711))
If the AXI bus is wider than the burst size, the AXI interface
must determine from the transfer address which byte lanes
of the data bus to use for each transfer.

That cannot be true for the 5 cases above; that is, one must use information from the transfer data channel (the WSTRBs) and not just the Address Channel. Unless there is another restriction in the specification which says something to the effect "narrow transfers cannot transfer non-contiguous bytes to an aligned address using information determined from the address channel alone." But I cannot find such a statement.

So my second question is, Is my basic understanding of the SIZE and alignment correct in what I've done above?

My third multi-part question is, independent of whether or no anyone thinks it is a wise, necessary, or useful thing to do, what is the situation for those five cases? Is the spec wrong, or incomplete? Did I overlook some related condition? In all five cases, a transfer length of 2 would do the job. But the spec does say what it does and that I should be able to use information from the address channel to select lanes.

Thank you for your patience and help.

DHDHD

Parents
  • Please be careful in how you describe the values you are driving on AWLEN and AWSIZE. I can see that you are describing the actual number of transfers, or the actual number of bytes per transfer, but the binary encodings for these are different, and it could be misunderstood when seeing something like AWSIZE==4 (is this 4 bytes, or indicating an encoding of a 64-bit (8 byte) transfer ?)

    Note that AWBURST cannot be WRAP for a single beat transaction.

    A) would be a protocol violation because you can only assert WSTRB bits within the AWADDR/AWSIZE/AWBURST/AWLEN defined range. As you are signalling AWSIZE==1 (3'b000), only 1 WSTRB bits can be asserted.

    Both A) and B) are perfectly valid ways of implementing this transfer, neither would necessarily be recommended over the other,

    Transfer two adjoining bytes.
    | n | n | Y | Y |
    | n | Y | Y | n |
    | Y | Y | n | n |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==2 (A and B above)

    The middle nYYn transfer would not be possible using SIZE==2 (3'b001) as AWSIZE defines an aligned range of byte lanes. As this second transfer crosses between 2 16-bit aligned halves of the bus you would only be able to signal the wider AWSIZE==4 (3'b010) width.

    Transfer three adjoining bytes.
    | n | Y | Y | Y |
    | Y | Y | Y | n |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==3 (A and B above)

    There is no AWSIZE value to describe 3 bytes, so only the AWSIZE==4 (3'b010) approach can be used.

    Transfer four adjoining bytes.
    | Y | Y | Y | Y |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==4 (A and B above)

    The address would have to be aligned, and all 4 WSTRB bits asserted here.

    If the 4 "adjoining" bytes are not actually in a 32-bit aligned range, you would need to perform 2 transfers on the 32-bit bus. For example if you were writing to addresses 3,4,5 and 6, you would need to perform a 1 byte transfer to address 3 (using A or B), and then a 3 byte transfer to 4,5 and 6.

    For your comments on the "problematic cases", you are correct in that for these specific examples it would be all of AWADDR, AWSIZE, AWBURST, AWLEN and finally WSTRB that would determine exactly which byte lanes contain valid data for each transfer.

    At this point in the spec we haven't yet seen that you can use WSTRB to indicate transfers narrower than the AWSIZE indication (they are covered later), so here it is just trying to show how you need to use multiple address channel signals to work out which parts of the data bus "COULD" contain valid data when the data bus width is wider than AWSIZE.

    So my second question is, Is my basic understanding of the SIZE and alignment correct in what I've done above?

    Mostly, but I can see that you haven't understood that AWSIZE indicates a size aligned range of bytes (as in the nYYn example).

    Hopefully I've answered your third question by my replies to your second.

Reply
  • Please be careful in how you describe the values you are driving on AWLEN and AWSIZE. I can see that you are describing the actual number of transfers, or the actual number of bytes per transfer, but the binary encodings for these are different, and it could be misunderstood when seeing something like AWSIZE==4 (is this 4 bytes, or indicating an encoding of a 64-bit (8 byte) transfer ?)

    Note that AWBURST cannot be WRAP for a single beat transaction.

    A) would be a protocol violation because you can only assert WSTRB bits within the AWADDR/AWSIZE/AWBURST/AWLEN defined range. As you are signalling AWSIZE==1 (3'b000), only 1 WSTRB bits can be asserted.

    Both A) and B) are perfectly valid ways of implementing this transfer, neither would necessarily be recommended over the other,

    Transfer two adjoining bytes.
    | n | n | Y | Y |
    | n | Y | Y | n |
    | Y | Y | n | n |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==2 (A and B above)

    The middle nYYn transfer would not be possible using SIZE==2 (3'b001) as AWSIZE defines an aligned range of byte lanes. As this second transfer crosses between 2 16-bit aligned halves of the bus you would only be able to signal the wider AWSIZE==4 (3'b010) width.

    Transfer three adjoining bytes.
    | n | Y | Y | Y |
    | Y | Y | Y | n |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==3 (A and B above)

    There is no AWSIZE value to describe 3 bytes, so only the AWSIZE==4 (3'b010) approach can be used.

    Transfer four adjoining bytes.
    | Y | Y | Y | Y |
    Use aligned address, SIZE==4 and use WSTRBs; or unaligned with SIZE==4 (A and B above)

    The address would have to be aligned, and all 4 WSTRB bits asserted here.

    If the 4 "adjoining" bytes are not actually in a 32-bit aligned range, you would need to perform 2 transfers on the 32-bit bus. For example if you were writing to addresses 3,4,5 and 6, you would need to perform a 1 byte transfer to address 3 (using A or B), and then a 3 byte transfer to 4,5 and 6.

    For your comments on the "problematic cases", you are correct in that for these specific examples it would be all of AWADDR, AWSIZE, AWBURST, AWLEN and finally WSTRB that would determine exactly which byte lanes contain valid data for each transfer.

    At this point in the spec we haven't yet seen that you can use WSTRB to indicate transfers narrower than the AWSIZE indication (they are covered later), so here it is just trying to show how you need to use multiple address channel signals to work out which parts of the data bus "COULD" contain valid data when the data bus width is wider than AWSIZE.

    So my second question is, Is my basic understanding of the SIZE and alignment correct in what I've done above?

    Mostly, but I can see that you haven't understood that AWSIZE indicates a size aligned range of bytes (as in the nYYn example).

    Hopefully I've answered your third question by my replies to your second.

Children