"I want to create simple tasks to send address and data from the master to the slave without any burst-length violations, making sure to include wstrb.
wstrb
When an AXI4 master and AXI3 slave are connected via an NoC bus and perform transactions, the AXI4 master is set with awburst = 1, awlen = 1, awsize = 2, and wdata is 64-bit. Meanwhile, the AXI3 slave is configured to receive inputs with awburst = 1, awlen = 1, awsize = 2, and wdata is fixed at 32-bit.
awburst = 1
awlen = 1
awsize = 2
wdata
I think that if the master sends a 64-bit transfer in one burst, and the slave receives it as two 32-bit transfers, there shouldn’t be any protocol issues. However, GPT suggests that the awlen of the AXI4 master and AXI3 slave must match to avoid burst-length violations. If I make awlen match, it will change the original behavior I intended.
awlen
In what cases does a burst-length violation occur?"
Can you explain what you don't understand ?
If you know what a 1-beat 64-bit transaction looks like, and you know what a 2-beat 32-bit transaction looks like, that's what happens here. The 64-bit data is converted into 2 32-bit transfers, with the lower 32-bits sent first and then the upper 32-bits.
You also ask about BREADY and BVALID, but don't say what you need help with. The protocol describes these signals, so which part is it you need help with ?
If the BVALID/BREADY question is in relation to the 64:32-bit downsizing, the 32-bit BRESP response will be returned at the end of the 32-bit transaction, and this is what would be returned to the 64-bit source.
I haven't looked at your waveform link as we need the waveform shown in this discussion so others can see what is being discussed. In your waveform is the 64-bit transaction being converted into a 32-bit 2-beat transaction, or is there no downsizer and you were just hoping the data would somehow be converted ?
If only the lower 32-bits is seen at your subordinate it does sound like there is no downsizer there and you are only connecting the subordinate to the lower half of the 64-bit data bus, which will never work.
The issue occurs when the lower 4 bits of the AXI AWADDR are 'hC, where data is not correctly transferred to the slave. For example, if the master sends data to address 'h640_47cc, the slave keeps receiving zeroes, but when the address is 'h640_47c8, the data is transferred correctly.
AWADDR
'hC
'h640_47cc
'h640_47c8
Thinking about it, from the slave's perspective, it is receiving two pieces of data. For instance:
'hxxxxx0
'hxxxx0
'hxxxx4
'hxxxxx4
'hxxxx8
'hxxxxx8
'hxxxxC
'hxxxxxC
'hxxx10
I'm curious about the constraints on AWADDR that could be causing this issue.
I'm not sure I follow what you are describing here now as you are referring to just 2 bytes being written to the destination in your last example, when originally we were talking about a 64-bit transfer being converted into 2 32-bit transfers.
You also seen to have added an extra element of unaligned addresses, so is this a separate issue ?
From this last example it looks like you are looking at 16-bit transfers to addresses 0x0, 0x4, 0x8 and 0xC. If yes, the AxSIZE width indicated relates to an AxSIZE aligned range of byte lanes on the bus, so when read together with AxADDR it tells you which byte lanes can be used by this transfer.
So for this 16-bit transfer example with AxSIZE=0x1, this tells you that before we look at AxADDR that the byte lanes being used on a 32-bit example could be either 0 and 1 (D[15:0]), or 2 and 3 (D[31:16]), both 16-bit aligned 16-bit ranges. Adding AxADDR to this tells which of those two ranges are being used, AND tells you where within that AxSIZE aligned range the start address describes.
Your 4 example lines should then be...
This is correct as the start address points to the lower byte lane on the lower half of the data bus, and both byte lanes then fall within the AxSIZE aligned range.
For this one we are still looking at only the lower half of the data bus, but the AxADDR starting address not aligned to AxSIZE means only byte lane 1 lies within the AxADDR/AxSIZE combination of controls. 0x8 addresses a byte lane outside the original AxADDR/AxSIZE defined combination, so is not included in this transfer.
This is correct as the start address points to the upper byte lane on the lower half of the data bus, and both byte lanes then fall within the AxSIZE aligned range.
For this one we are still looking at only the upper half of the data bus, but the AxADDR starting address not aligned to AxSIZE means only byte lane 3 lies within the AxADDR/AxSIZE combination of controls. 0x10 addresses a byte lane outside the original AxADDR/AxSIZE defined combination, so is not included in this transfer.
Have a read at section A4.2.4 in the current version K of the protocol, and in particular figures A4.6 onwards for descriptions of this. You can see that in A4.7 (possibly the most relevant example here) that each AxSIZE=32-bit transfer looks at only one half of the 64-bit data bus, and that the AxADDR start address defines which byte lanes within that half of the data bus are use for that transfer.
The 2nd example in A4.7 shows a start address of 0x7 with AxSIZE=32-bits, but note that only one byte is actually accessed in this first transfer, as 0x8, 0x9 and 0xA are part of the next AxSIZE aligned range of byte lanes.
Where the SW possibly wanted to access 16 bytes starting at 0x7 in this example, the 4th diagram shows that the HW needs to implement this as 5 transfers, with the 1st accessing just one byte, and the 5th accessing the 3 remaining of the 16 (plus 1 additional byte not needed by the SW request). For a write sequence WSTRB could have indicated 8'b0000_0111 for that final write so as not to corrupt the additional byte at 0x17.
So the AXI implementation of unaligned transfers isn't quite what you might expect from a SW perspective, and you need to understand that only the first transfer in an INCR transaction is unaligned, and all transfers within the transaction remain within AxSIZE aligned AxSIZE byte ranges.
Does that better cover your questions ?
Apologies for the confusion. The first issue regarding the 2-byte transaction has been resolved by using 64-bit data. Initially, I thought that if I sent two 32-bit transactions, I should only provide 32-bit data. So I mistakenly wrote something like this: wdata[63:0] = my_data[31:0] and then wdata[63:0] = my_data[63:32]. This was my mistake—I should have used 64-bit data directly for wdata[63:0]. So this issue has been cleared up.
wdata[63:0] = my_data[31:0]
wdata[63:0] = my_data[63:32]
wdata[63:0]
My last question was about using a 4-byte increment for addressing, but I encountered bus hangs and incorrect results when the addresses were not multiples of 8. After investigating, I realized that the bus only works correctly when the addresses are multiples of 8. I’m now wondering what determines this alignment requirement for bus addressing. and your answer makes me clear. Thanks.