Skip to content

Fix strb of Axi4Master (spinal.lib.bus.amba4.axi.sim) #1692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from

Conversation

Nik-Sch
Copy link
Contributor

@Nik-Sch Nik-Sch commented Mar 26, 2025

Context, Motivation & Description

The strb for the Axi4Master (sim) was wrong for aligned transfers with len>0. I fixed this and added a simple testbench that verifies the Axi4Master against the AxiMemorySim.

Impact on code generation

None

Checklist

  • Unit tests were added
  • API changes are or will be documented:

@Dolu1990
Copy link
Member

Hi,

(~((BigInt(1) << padBack) - 1)) & ((BigInt(1) << bytePerBeat) - 1)

Does it work for burst where size is smaller than the whole bus width ?
Seems like & ((BigInt(1) << bytePerBeat) - 1) will not work in all cases (last beat not finishing at the start of the data word.

@Nik-Sch
Copy link
Contributor Author

Nik-Sch commented Mar 28, 2025

Yes, you are correct, there were some weird bugs...
I added tests for unaligned transfers and fixed the problems. Should I test something else?

@Nik-Sch Nik-Sch force-pushed the fix-axi4-master branch 2 times, most recently from 1cd5f09 to 6e32289 Compare March 28, 2025 11:14
@Nik-Sch Nik-Sch force-pushed the fix-axi4-master branch 2 times, most recently from 3586a0f to e5afb9f Compare April 13, 2025 18:26
case 0 => fullStrb << padFront
case `len` => fullStrb >> padBack
case _ => fullStrb
}) & fullStrb
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall i think there is still two cases which aren't handled (and were not before the pr either ?)

  • Single beat burst with address not being word aligned.
  • burst with size smaller than word size

@KireinaHoro
Can you double check ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test for that and it was already working in my branch. This was handled by padData in line 284.
Did I understand your points correctly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like narrow bursts will be handled in the proposed version (since you use fullStrb).

Not so sure about the unaligned address case -- address is rounded at the beginning through padData... @Dolu1990 can you elaborate?

Copy link
Contributor

@KireinaHoro KireinaHoro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot and sorry for the delay! I don't have time to test this locally yet -- will get back to you.

if (busConfig.useStrb) w.strb #= strb
if (busConfig.useLast) w.last #= beat == len
log("W", f"data ${data.bytesToHex} strb $strb%#x last ${beat == len}")
log("W", f"data ${data.reverse.bytesToHex} strb $strb%#x last ${beat == len}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're reversing the print for W, please also do the same for R... otherwise they won't match and will cause confusions

} else {
len
}
writeSingle(addr, slice, id, burst, thisLen, size)(handleTransaction(addr, transactionId, remaining))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if silently down-capping AxLEN is a good idea, with the current semantics of len. I see one of two ways:

  • change len to something like maxLen, so that it's used to limit the max burst size, or
  • assert false here to complain that the user specified too big of AxLEN

@@ -278,7 +282,8 @@ case class Axi4Master(axi: Axi4, clockDomain: ClockDomain, name: String = "unnam
val bytePerBus = 1 << log2Up(busConfig.dataWidth / 8)

val (roundedAddress, padFront, padBack, paddedData) = padData(address, data)
val realLen = data.length
assert(data.length <= (len + 1) * bytePerBeat, "data is too long and cannot be sent in one transaction")
assert(data.length >= len * bytePerBeat, f"data is too short (${data.length}) for len=$len (would result in erroneous zero transfers)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion is not true: you can have holes in the transaction, e.g. issue a 16B write but use STRB to mask it down.

case 0 => fullStrb << padFront
case `len` => fullStrb >> padBack
case _ => fullStrb
}) & fullStrb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like narrow bursts will be handled in the proposed version (since you use fullStrb).

Not so sure about the unaligned address case -- address is rounded at the beginning through padData... @Dolu1990 can you elaborate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants