axi4 Fragmenter: align all output accesses
We promised the output is aligned. Make good on that!
This commit is contained in:
parent
84be93f9f3
commit
19064e602b
@ -96,19 +96,17 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: Int = 32, combinational
|
|||||||
// Things that cause us to degenerate to a single beat
|
// Things that cause us to degenerate to a single beat
|
||||||
val fixed = a.bits.burst === AXI4Parameters.BURST_FIXED
|
val fixed = a.bits.burst === AXI4Parameters.BURST_FIXED
|
||||||
val narrow = a.bits.size =/= UInt(lgBytes)
|
val narrow = a.bits.size =/= UInt(lgBytes)
|
||||||
val misaligned = lo =/= UInt(0)
|
val bad = fixed || narrow
|
||||||
val bad = fixed || narrow || misaligned
|
|
||||||
|
|
||||||
// The number of beats-1 to execute
|
// The number of beats-1 to execute
|
||||||
val beats1 = Mux(bad, UInt(0), maxSupported1)
|
val beats1 = Mux(bad, UInt(0), maxSupported1)
|
||||||
val beats = ~(~(beats1 << 1 | UInt(1)) | beats1) // beats1 + 1
|
val beats = ~(~(beats1 << 1 | UInt(1)) | beats1) // beats1 + 1
|
||||||
|
|
||||||
val inc_addr = addr + (beats << a.bits.size) // address after adding transfer
|
val inc_addr = addr + (beats << a.bits.size) // address after adding transfer
|
||||||
val align_addr = ~(~inc_addr | UIntToOH1(a.bits.size, lgBytes)) // AXI4 increments misaligned heads to aligned
|
|
||||||
val wrapMask = ~(~a.bits.len << a.bits.size) // only these bits may change, if wrapping
|
val wrapMask = ~(~a.bits.len << a.bits.size) // only these bits may change, if wrapping
|
||||||
val mux_addr = Wire(init = align_addr)
|
val mux_addr = Wire(init = inc_addr)
|
||||||
when (a.bits.burst === AXI4Parameters.BURST_WRAP) {
|
when (a.bits.burst === AXI4Parameters.BURST_WRAP) {
|
||||||
mux_addr := (align_addr & wrapMask) | ~(~a.bits.addr | wrapMask)
|
mux_addr := (inc_addr & wrapMask) | ~(~a.bits.addr | wrapMask)
|
||||||
}
|
}
|
||||||
when (a.bits.burst === AXI4Parameters.BURST_FIXED) {
|
when (a.bits.burst === AXI4Parameters.BURST_FIXED) {
|
||||||
mux_addr := a.bits.addr
|
mux_addr := a.bits.addr
|
||||||
@ -119,9 +117,15 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: Int = 32, combinational
|
|||||||
out.valid := a.valid
|
out.valid := a.valid
|
||||||
|
|
||||||
out.bits := a.bits
|
out.bits := a.bits
|
||||||
out.bits.addr := addr
|
|
||||||
out.bits.len := beats1
|
out.bits.len := beats1
|
||||||
|
|
||||||
|
// We forcibly align every access. If the first beat was misaligned, the strb bits
|
||||||
|
// for the lower addresses must not have been set. Therefore, rounding the address
|
||||||
|
// down is harmless. We can do this after the address update algorithm, because the
|
||||||
|
// incremented values will be rounded down the same way. Furthermore, a subword
|
||||||
|
// offset cannot cause a premature wrap-around.
|
||||||
|
out.bits.addr := ~(~addr | UIntToOH1(a.bits.size, lgBytes))
|
||||||
|
|
||||||
when (out.fire()) {
|
when (out.fire()) {
|
||||||
busy := !last
|
busy := !last
|
||||||
r_addr := mux_addr
|
r_addr := mux_addr
|
||||||
|
Loading…
Reference in New Issue
Block a user