Skip to content

Commit

Permalink
wavie and squeeze
Browse files Browse the repository at this point in the history
  • Loading branch information
sequencer committed Jul 13, 2023
1 parent 1ea3edd commit 4244995
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
20 changes: 16 additions & 4 deletions src/main/scala/amba/axi4/Fragmenter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,16 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule
// Irrevocable queues in front because we want to accept the request before responses come back
val (in_ar, ar_last, _) = fragment(Queue.irrevocable(in.ar, 1, flow=true), readSizes1)
val (in_aw, aw_last, w_beats) = fragment(Queue.irrevocable(in.aw, 1, flow=true), writeSizes1)
in_ar.ready := DontCare

// AXI ready may not depend on valid of other channels
// We cut wready here along with awready and arready before AXI4ToTL
val in_w = Queue.irrevocable(in.w, 1, flow=true)

// AR flow control; super easy
out.ar.bits.waiveAs[AXI4BundleA]() :<>= in_ar.bits
Connectable.waiveUnmatched(out.ar.bits, in_ar.bits) match {
case (lhs, rhs) => lhs :<>= rhs
}
out.ar.bits.echo(AXI4FragLast) := ar_last

// When does W channel start counting a new transfer
Expand All @@ -161,7 +164,9 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule
out.aw.valid := in_aw.valid && (wbeats_ready || wbeats_latched)
in_aw.ready := out.aw.ready && (wbeats_ready || wbeats_latched)
wbeats_valid := in_aw.valid && !wbeats_latched
out.aw.bits.waiveAs[AXI4BundleA](_.user) :<>= in_aw.bits
Connectable.waiveUnmatched(out.aw.bits, in_aw.bits) match {
case (lhs, rhs) => lhs :<>= rhs
}
out.aw.bits.echo(AXI4FragLast) := aw_last

// We need to inject 'last' into the W channel fragments, count!
Expand All @@ -183,12 +188,19 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule

// R flow control
val r_last = out.r.bits.echo(AXI4FragLast)
in.r :<>= out.r
Connectable.waiveUnmatched(in.r, out.r) match {
case (lhs, rhs) => lhs :<>= rhs
}

in.r.bits.last := out.r.bits.last && r_last

// B flow control
val b_last = out.b.bits.echo(AXI4FragLast)
in.b :<>= out.b

Connectable.waiveUnmatched(in.b, out.b) match {
case (lhs, rhs) => lhs :<>= rhs
}

in.b.valid := out.b.valid && b_last
out.b.ready := in.b.ready || !b_last

Expand Down
21 changes: 16 additions & 5 deletions src/main/scala/amba/axi4/IdIndexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,22 @@ class AXI4IdIndexer(idBits: Int)(implicit p: Parameters) extends LazyModule
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>

// Leave everything mostly untouched
out.ar :<>= in.ar
out.aw :<>= in.aw
out.w :<>= in.w
in.b :<>= out.b
in.r :<>= out.r

Connectable.waiveUnmatched(out.ar, in.ar) match {
case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll
}
Connectable.waiveUnmatched(out.aw, in.aw) match {
case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll
}
Connectable.waiveUnmatched(out.w, in.w) match {
case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll
}
Connectable.waiveUnmatched(in.b, out.b) match {
case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll
}
Connectable.waiveUnmatched(in.r, out.r) match {
case (lhs, rhs) => lhs.squeezeAll :<>= rhs.squeezeAll
}

val bits = log2Ceil(edgeIn.master.endId) - idBits
if (bits > 0) {
Expand Down
10 changes: 8 additions & 2 deletions src/main/scala/amba/axi4/ToTL.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ class AXI4ToTL(wcorrupt: Boolean)(implicit p: Parameters) extends LazyModule
r_out.valid := in.ar.valid
r_out.bits :<= edgeOut.Get(r_id, r_addr, r_size)._2

r_out.bits.user :<= in.ar.bits.user
Connectable.waiveUnmatched(r_out.bits.user, in.ar.bits.user) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}

r_out.bits.user.lift(AMBAProt).foreach { rprot =>
rprot.privileged := in.ar.bits.prot(0)
rprot.secure := !in.ar.bits.prot(1)
Expand Down Expand Up @@ -146,7 +149,10 @@ class AXI4ToTL(wcorrupt: Boolean)(implicit p: Parameters) extends LazyModule
w_out.bits :<= edgeOut.Put(w_id, w_addr, w_size, in.w.bits.data, in.w.bits.strb)._2
in.w.bits.user.lift(AMBACorrupt).foreach { w_out.bits.corrupt := _ }

w_out.bits.user :<= in.aw.bits.user
Connectable.waiveUnmatched(w_out.bits.user, in.aw.bits.user) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}

w_out.bits.user.lift(AMBAProt).foreach { wprot =>
wprot.privileged := in.aw.bits.prot(0)
wprot.secure := !in.aw.bits.prot(1)
Expand Down
16 changes: 12 additions & 4 deletions src/main/scala/amba/axi4/UserYanker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,17 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e
val ar_ready = VecInit(rqueues.map(_.enq.ready))(arid)
in .ar.ready := out.ar.ready && ar_ready
out.ar.valid := in .ar.valid && ar_ready
out.ar.bits :<= in .ar.bits
Connectable.waiveUnmatched(out.ar.bits, in.ar.bits) match {
case (lhs, rhs) => lhs :<= rhs
}

val rid = out.r.bits.id
val r_valid = VecInit(rqueues.map(_.deq.valid))(rid)
val r_bits = VecInit(rqueues.map(_.deq.bits))(rid)
assert (!out.r.valid || r_valid) // Q must be ready faster than the response
in.r :<>= out.r
Connectable.waiveUnmatched(in.r, out.r) match {
case (lhs, rhs) => lhs :<>= rhs
}
in.r.bits.echo :<= r_bits

val arsel = UIntToOH(arid, edgeIn.master.endId).asBools
Expand All @@ -78,13 +82,17 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e
val aw_ready = VecInit(wqueues.map(_.enq.ready))(awid)
in .aw.ready := out.aw.ready && aw_ready
out.aw.valid := in .aw.valid && aw_ready
out.aw.bits :<= in .aw.bits
Connectable.waiveUnmatched(out.aw.bits, in.aw.bits) match {
case (lhs, rhs) => lhs :<= rhs
}

val bid = out.b.bits.id
val b_valid = VecInit(wqueues.map(_.deq.valid))(bid)
val b_bits = VecInit(wqueues.map(_.deq.bits))(bid)
assert (!out.b.valid || b_valid) // Q must be ready faster than the response
in.b :<>= out.b
Connectable.waiveUnmatched(in.b, out.b) match {
case (lhs, rhs) => lhs :<>= rhs
}
in.b.bits.echo :<= b_bits

val awsel = UIntToOH(awid, edgeIn.master.endId).asBools
Expand Down
9 changes: 7 additions & 2 deletions src/main/scala/tilelink/RegisterRouter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ case class TLRegisterNode(
in.bits.index := edge.addr_hi(a.bits)
in.bits.data := a.bits.data
in.bits.mask := a.bits.mask
in.bits.extra :<= a.bits.echo
Connectable.waiveUnmatched(in.bits.extra, a.bits.echo) match {
case (lhs, rhs) => lhs :<= rhs
}

val a_extra = in.bits.extra(TLRegisterRouterExtra)
a_extra.source := a.bits.source
Expand All @@ -91,7 +93,10 @@ case class TLRegisterNode(

// avoid a Mux on the data bus by manually overriding two fields
d.bits.data := out.bits.data
d.bits.echo :<= out.bits.extra
Connectable.waiveUnmatched(d.bits.echo, out.bits.extra) match {
case (lhs, rhs) => lhs :<= rhs
}

d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck)

// Tie off unused channels
Expand Down
24 changes: 18 additions & 6 deletions src/main/scala/tilelink/ToAXI4.scala
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,12 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String
arw.cache := 0.U // do not allow AXI to modify our transactions
arw.prot := AXI4Parameters.PROT_PRIVILEGED
arw.qos := 0.U // no QoS
arw.user :<= in.a.bits.user
arw.echo :<= in.a.bits.echo
Connectable.waiveUnmatched(arw.user, in.a.bits.user) match {
case (lhs, rhs) => lhs :<= rhs
}
Connectable.waiveUnmatched(arw.echo, in.a.bits.echo) match {
case (lhs, rhs) => lhs :<= rhs
}
val a_extra = arw.echo(AXI4TLState)
a_extra.source := a_source
a_extra.size := a_size
Expand Down Expand Up @@ -228,10 +232,18 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String

val r_d = edgeIn.AccessAck(r_source, r_size, 0.U, denied = r_denied, corrupt = r_corrupt || r_denied)
val b_d = edgeIn.AccessAck(b_source, b_size, denied = b_denied)
r_d.user :<= out.r.bits.user
r_d.echo :<= out.r.bits.echo
b_d.user :<= out.b.bits.user
b_d.echo :<= out.b.bits.echo
Connectable.waiveUnmatched(r_d.user, out.r.bits.user) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}
Connectable.waiveUnmatched(r_d.echo, out.r.bits.echo) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}
Connectable.waiveUnmatched(b_d.user, out.b.bits.user) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}
Connectable.waiveUnmatched(b_d.echo, out.b.bits.echo) match {
case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll
}

in.d.bits := Mux(r_wins, r_d, b_d)
in.d.bits.data := out.r.bits.data // avoid a costly Mux
Expand Down

0 comments on commit 4244995

Please sign in to comment.