diff --git a/src/main/scala/amba/ahb/AHBLite.scala b/src/main/scala/amba/ahb/AHBLite.scala index b8811dd0619..633b46fc594 100644 --- a/src/main/scala/amba/ahb/AHBLite.scala +++ b/src/main/scala/amba/ahb/AHBLite.scala @@ -5,7 +5,6 @@ package freechips.rocketchip.amba.ahb import chisel3._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AHBLite()(implicit p: Parameters) extends LazyModule { val node = AHBMasterAdapterNode( @@ -29,8 +28,8 @@ class AHBLite()(implicit p: Parameters) extends LazyModule { out.hprot := in.hprot out.haddr := in.haddr out.hwdata := in.hwdata - out.hauser :<> in.hauser - in.hduser :<> out.hduser + out.hauser :<>= in.hauser + in.hduser :<>= out.hduser in.hrdata := out.hrdata } } diff --git a/src/main/scala/amba/ahb/Xbar.scala b/src/main/scala/amba/ahb/Xbar.scala index f7ef7d1bc19..8922c838dcd 100644 --- a/src/main/scala/amba/ahb/Xbar.scala +++ b/src/main/scala/amba/ahb/Xbar.scala @@ -7,7 +7,6 @@ import chisel3.util._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AHBFanout()(implicit p: Parameters) extends LazyModule { val node = new AHBFanoutNode( @@ -47,7 +46,7 @@ class AHBFanout()(implicit p: Parameters) extends LazyModule { when (in.hready) { d_sel := a_sel } (a_sel zip io_out) foreach { case (sel, out) => - out :<> in + out :<>= in out.hsel := in.hsel && sel out.hmaster.map { _ := 0.U } } diff --git a/src/main/scala/amba/apb/Xbar.scala b/src/main/scala/amba/apb/Xbar.scala index e4828900a24..de82ae15b13 100644 --- a/src/main/scala/amba/apb/Xbar.scala +++ b/src/main/scala/amba/apb/Xbar.scala @@ -7,7 +7,6 @@ import chisel3.util._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign class APBFanout()(implicit p: Parameters) extends LazyModule { val node = new APBNexusNode( @@ -44,7 +43,7 @@ class APBFanout()(implicit p: Parameters) extends LazyModule { val sel = VecInit(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _))) (sel zip io_out) foreach { case (sel, out) => - out :<> in + out :<>= in out.psel := sel && in.psel out.penable := sel && in.penable } diff --git a/src/main/scala/amba/axi4/Credited.scala b/src/main/scala/amba/axi4/Credited.scala index e91f218ba5c..e2a0d59776d 100644 --- a/src/main/scala/amba/axi4/Credited.scala +++ b/src/main/scala/amba/axi4/Credited.scala @@ -8,7 +8,6 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.subsystem.CrossingWrapper import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AXI4CreditedBuffer(delay: AXI4CreditedDelay)(implicit p: Parameters) extends LazyModule { @@ -19,11 +18,11 @@ class AXI4CreditedBuffer(delay: AXI4CreditedDelay)(implicit p: Parameters) exten lazy val module = new Impl class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - out.aw :<> in.aw.pipeline(delay.aw) - out.w :<> in.w.pipeline(delay.w) - in.b :<> out.b.pipeline(delay.b) - out.ar :<> in.ar.pipeline(delay.ar) - in.r :<> out.r.pipeline(delay.r) + out.aw :<>= in.aw.pipeline(delay.aw) + out.w :<>= in.w.pipeline(delay.w) + in.b :<>= out.b.pipeline(delay.b) + out.ar :<>= in.ar.pipeline(delay.ar) + in.r :<>= out.r.pipeline(delay.r) } } } @@ -44,11 +43,11 @@ class AXI4CreditedSource(delay: AXI4CreditedDelay)(implicit p: Parameters) exten class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val tld = edgeOut.delay - out.aw :<> CreditedIO.fromSender(in.aw, tld.aw.total).pipeline(delay.aw) - out.w :<> CreditedIO.fromSender(in.w, tld.w.total).pipeline(delay.w) - in.b :<> out.b.pipeline(delay.b).toReceiver(tld.b.total) - out.ar :<> CreditedIO.fromSender(in.ar, tld.ar.total).pipeline(delay.ar) - in.r :<> out.r.pipeline(delay.r).toReceiver(tld.r.total) + out.aw :<>= CreditedIO.fromSender(in.aw, tld.aw.total).pipeline(delay.aw) + out.w :<>= CreditedIO.fromSender(in.w, tld.w.total).pipeline(delay.w) + in.b :<>= out.b.pipeline(delay.b).toReceiver(tld.b.total) + out.ar :<>= CreditedIO.fromSender(in.ar, tld.ar.total).pipeline(delay.ar) + in.r :<>= out.r.pipeline(delay.r).toReceiver(tld.r.total) } } } @@ -69,11 +68,11 @@ class AXI4CreditedSink(delay: AXI4CreditedDelay)(implicit p: Parameters) extends class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val tld = edgeIn.delay - out.aw :<> in.aw.pipeline(delay.aw).toReceiver(tld.aw.total) - out.w :<> in.w.pipeline(delay.w).toReceiver(tld.w.total) - in.b :<> CreditedIO.fromSender(out.b, tld.b.total).pipeline(delay.b) - out.ar :<> in.ar.pipeline(delay.ar).toReceiver(tld.ar.total) - in.r :<> CreditedIO.fromSender(out.r, tld.r.total).pipeline(delay.r) + out.aw :<>= in.aw.pipeline(delay.aw).toReceiver(tld.aw.total) + out.w :<>= in.w.pipeline(delay.w).toReceiver(tld.w.total) + in.b :<>= CreditedIO.fromSender(out.b, tld.b.total).pipeline(delay.b) + out.ar :<>= in.ar.pipeline(delay.ar).toReceiver(tld.ar.total) + in.r :<>= CreditedIO.fromSender(out.r, tld.r.total).pipeline(delay.r) } } } diff --git a/src/main/scala/amba/axi4/Deinterleaver.scala b/src/main/scala/amba/axi4/Deinterleaver.scala index 2f0a47d8857..27f99823a5e 100644 --- a/src/main/scala/amba/axi4/Deinterleaver.scala +++ b/src/main/scala/amba/axi4/Deinterleaver.scala @@ -8,7 +8,6 @@ import chisel3.util.{Cat, isPow2, log2Ceil, ReadyValidIO, import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.leftOR -import freechips.rocketchip.util.EnhancedChisel3Assign /** This adapter deinterleaves read responses on the R channel. * @@ -48,14 +47,14 @@ class AXI4Deinterleaver(maxReadBytes: Int, buffer: BufferParams = BufferParams.d val beats = maxBeats(edgeOut.slave) // This adapter passes through the AR/AW control + W/B write data channels - out.ar :<> in.ar - out.aw :<> in.aw - out.w :<> in.w - in.b :<> out.b + out.ar :<>= in.ar + out.aw :<>= in.aw + out.w :<>= in.w + in.b :<>= out.b // Only the R channel has the possibility of being changed if (nothingToDeinterleave(edgeOut.slave)) { - in.r.asInstanceOf[ReadyValidIO[AXI4BundleR]] :<> buffer.irrevocable(out.r) + in.r.asInstanceOf[ReadyValidIO[AXI4BundleR]] :<>= buffer.irrevocable(out.r) } else { // We only care to deinterleave ids that are actually in use val maxFlightPerId = Seq.tabulate(endId) { i => diff --git a/src/main/scala/amba/axi4/Filter.scala b/src/main/scala/amba/axi4/Filter.scala index 0ac42283e85..77833e2594d 100644 --- a/src/main/scala/amba/axi4/Filter.scala +++ b/src/main/scala/amba/axi4/Filter.scala @@ -4,7 +4,6 @@ package freechips.rocketchip.amba.axi4 import org.chipsalliance.cde.config._ import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AXI4Filter( Sfilter: AXI4SlaveParameters => Option[AXI4SlaveParameters] = AXI4Filter.Sidentity, @@ -33,7 +32,7 @@ class AXI4Filter( lazy val module = new Impl class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - out :<> in + out :<>= in } } } diff --git a/src/main/scala/amba/axi4/Fragmenter.scala b/src/main/scala/amba/axi4/Fragmenter.scala index 846b72f2fa8..60ec2dc5597 100644 --- a/src/main/scala/amba/axi4/Fragmenter.scala +++ b/src/main/scala/amba/axi4/Fragmenter.scala @@ -7,7 +7,6 @@ import chisel3.util._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign case object AXI4FragLast extends ControlKey[Bool]("real_last") case class AXI4FragLastField() extends SimpleBundleField(AXI4FragLast)(Output(Bool()), false.B) @@ -148,7 +147,9 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule val in_w = Queue.irrevocable(in.w, 1, flow=true) // AR flow control; super easy - out.ar :<>: in_ar + Connectable.waiveUnmatched(out.ar, in_ar) match { + case (lhs, rhs) => lhs :<>= rhs + } out.ar.bits.echo(AXI4FragLast) := ar_last // When does W channel start counting a new transfer @@ -162,7 +163,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 :<>: 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! @@ -184,12 +187,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 diff --git a/src/main/scala/amba/axi4/IdIndexer.scala b/src/main/scala/amba/axi4/IdIndexer.scala index 9c49613d34a..49cb9d92974 100644 --- a/src/main/scala/amba/axi4/IdIndexer.scala +++ b/src/main/scala/amba/axi4/IdIndexer.scala @@ -7,7 +7,6 @@ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import chisel3.util.{log2Ceil, Cat} -import freechips.rocketchip.util.EnhancedChisel3Assign case object AXI4ExtraId extends ControlKey[UInt]("extra_id") case class AXI4ExtraIdField(width: Int) extends SimpleBundleField(AXI4ExtraId)(Output(UInt(width.W)), 0.U) @@ -61,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) { diff --git a/src/main/scala/amba/axi4/RegisterRouter.scala b/src/main/scala/amba/axi4/RegisterRouter.scala index 2f11416731f..5a7f9e916b2 100644 --- a/src/main/scala/amba/axi4/RegisterRouter.scala +++ b/src/main/scala/amba/axi4/RegisterRouter.scala @@ -48,8 +48,8 @@ case class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes aw.ready := in.ready && !ar.valid && w .valid w .ready := in.ready && !ar.valid && aw.valid - ar_extra.partialAssignL(ar.bits.echo) - aw_extra.partialAssignL(aw.bits.echo) + ar_extra :<= ar.bits.echo + aw_extra :<= aw.bits.echo ar_extra(AXI4RRId) := ar.bits.id aw_extra(AXI4RRId) := aw.bits.id val addr = Mux(ar.valid, ar.bits.addr, aw.bits.addr) diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala index aabf8b5adda..54ef0f0029c 100644 --- a/src/main/scala/amba/axi4/ToTL.scala +++ b/src/main/scala/amba/axi4/ToTL.scala @@ -9,7 +9,6 @@ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign case class AXI4ToTLIdMapEntry(tlId: IdRange, axi4Id: IdRange, name: String) extends IdMapEntry @@ -111,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) @@ -147,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) @@ -183,7 +188,7 @@ class AXI4ToTL(wcorrupt: Boolean)(implicit p: Parameters) extends LazyModule ok_r.bits.user :<= out.d.bits.user // AXI4 needs irrevocable behaviour - in.r :<> Queue.irrevocable(ok_r, 1, flow=true) + in.r :<>= Queue.irrevocable(ok_r, 1, flow=true) ok_b.bits.id := out.d.bits.source >> addedBits ok_b.bits.resp := d_resp diff --git a/src/main/scala/amba/axi4/UserYanker.scala b/src/main/scala/amba/axi4/UserYanker.scala index 532ef55f8bd..0e209cecd46 100644 --- a/src/main/scala/amba/axi4/UserYanker.scala +++ b/src/main/scala/amba/axi4/UserYanker.scala @@ -8,7 +8,6 @@ import freechips.rocketchip.util.CompileOptions.NotStrictInferReset import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign /** This adapter prunes all user bit fields of the echo type from request messages, * storing them in queues and echoing them back when matching response messages are received. @@ -58,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 @@ -79,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 @@ -96,7 +103,7 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e q.enq.bits :<= in.aw.bits.echo } - out.w :<> in.w + out.w :<>= in.w } } } diff --git a/src/main/scala/amba/axi4/Xbar.scala b/src/main/scala/amba/axi4/Xbar.scala index e70d67dac47..2f2d066aaf6 100644 --- a/src/main/scala/amba/axi4/Xbar.scala +++ b/src/main/scala/amba/axi4/Xbar.scala @@ -9,7 +9,6 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import freechips.rocketchip.unittest._ import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util.EnhancedChisel3Assign /** * AXI4 Crossbar. It connects multiple AXI4 masters to slaves. @@ -86,7 +85,7 @@ class AXI4Xbar( // Transform input bundles val in = Wire(Vec(io_in.size, new AXI4Bundle(wide_bundle))) for (i <- 0 until in.size) { - in(i) :<> io_in(i) + in(i) :<>= io_in(i) // Handle size = 1 gracefully (Chisel3 empty range is broken) def trim(id: UInt, size: Int) = if (size <= 1) 0.U else id(log2Ceil(size)-1, 0) @@ -169,7 +168,7 @@ class AXI4Xbar( // Transform output bundles val out = Wire(Vec(io_out.size, new AXI4Bundle(wide_bundle))) for (i <- 0 until out.size) { - io_out(i) :<> out(i) + io_out(i) :<>= out(i) if (io_in.size > 1) { // Block AW if we cannot record the W source diff --git a/src/main/scala/amba/axis/Buffer.scala b/src/main/scala/amba/axis/Buffer.scala index c9c9c99a552..a9ea9198d17 100644 --- a/src/main/scala/amba/axis/Buffer.scala +++ b/src/main/scala/amba/axis/Buffer.scala @@ -3,7 +3,6 @@ package freechips.rocketchip.amba.axis import org.chipsalliance.cde.config._ -import freechips.rocketchip.util._ import freechips.rocketchip.diplomacy._ class AXISBuffer(val params: BufferParams)(implicit p: Parameters) extends LazyModule @@ -12,7 +11,7 @@ class AXISBuffer(val params: BufferParams)(implicit p: Parameters) extends LazyM lazy val module = new Impl class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - out :<>: params.irrevocable(in) + out.waiveAs[chisel3.Data]() :<>= params.irrevocable(in).waiveAs[chisel3.Data]() } } } diff --git a/src/main/scala/amba/axis/Xbar.scala b/src/main/scala/amba/axis/Xbar.scala index b6371ebee71..7338bb4287c 100644 --- a/src/main/scala/amba/axis/Xbar.scala +++ b/src/main/scala/amba/axis/Xbar.scala @@ -5,10 +5,8 @@ package freechips.rocketchip.amba.axis import chisel3._ import chisel3.util._ import org.chipsalliance.cde.config._ -import freechips.rocketchip.util._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AXISXbar(beatBytes: Int, policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule { @@ -43,14 +41,14 @@ class AXISXbar(beatBytes: Int, policy: TLArbiter.Policy = TLArbiter.roundRobin)( // Transform input bundle sources (dest uses global namespace on both sides) val in = Wire(Vec(io_in.size, AXISBundle(wide_bundle))) for (i <- 0 until in.size) { - in(i) :<> io_in(i) + in(i) :<>= io_in(i) in(i).bits.lift(AXISId) foreach { _ := io_in(i).bits.id | inputIdRanges(i).start.U } } // Transform output bundle sinks (id use global namespace on both sides) val out = Wire(Vec(io_out.size, AXISBundle(wide_bundle))) for (o <- 0 until out.size) { - io_out(o) :<> out(o) + io_out(o) :<>= out(o) io_out(o).bits.lift(AXISDest) foreach { _ := trim(out(o).bits.dest, outputIdRanges(o).size) } } @@ -78,7 +76,7 @@ object AXISXbar if (sources.isEmpty) { sink.valid := false.B } else if (sources.size == 1) { - sink :<> sources.head + sink :<>= sources.head } else { // The number of beats which remain to be sent val idle = RegInit(true.B) @@ -107,14 +105,18 @@ object AXISXbar val allowed = Mux(idle, readys, state) (sources zip allowed) foreach { case (s, r) => s.ready := sink.ready && r } sink.valid := Mux(idle, valids.reduce(_||_), Mux1H(state, valids)) - sink.bits :<= Mux1H(muxState, sources.map(_.bits)) + Connectable.waiveUnmatched(sink.bits, Mux1H(muxState, sources.map(_.bits))) match { + case (lhs, rhs) => lhs.squeezeAll :<= rhs.squeezeAll + } } } def fanout(input: AXISBundle, select: Seq[Bool]): Seq[AXISBundle] = { val filtered = Wire(Vec(select.size, chiselTypeOf(input))) for (i <- 0 until select.size) { - filtered(i).bits :<= input.bits + Connectable.waiveUnmatched(filtered(i).bits, input.bits) match { + case (lhs, rhs) => lhs :<= rhs + } filtered(i).valid := input.valid && (select(i) || (select.size == 1).B) } input.ready := Mux1H(select, filtered.map(_.ready)) diff --git a/src/main/scala/regmapper/RegisterRouter.scala b/src/main/scala/regmapper/RegisterRouter.scala index 971d577cf6f..0bd43a7fd06 100644 --- a/src/main/scala/regmapper/RegisterRouter.scala +++ b/src/main/scala/regmapper/RegisterRouter.scala @@ -6,7 +6,6 @@ import chisel3._ import chisel3.util.{isPow2} import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.EnhancedChisel3Assign /** Parameters which apply to any RegisterRouter. */ case class RegisterRouterParams( diff --git a/src/main/scala/tilelink/AddressAdjuster.scala b/src/main/scala/tilelink/AddressAdjuster.scala index e73859912e4..d4a1fc7bbf1 100644 --- a/src/main/scala/tilelink/AddressAdjuster.scala +++ b/src/main/scala/tilelink/AddressAdjuster.scala @@ -6,7 +6,6 @@ import chisel3._ import chisel3.util._ import org.chipsalliance.cde.config._ import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.EnhancedChisel3Assign class AddressAdjuster( val params: ReplicatedRegion, // only devices in this region get adjusted diff --git a/src/main/scala/tilelink/Arbiter.scala b/src/main/scala/tilelink/Arbiter.scala index 045e1ac1d8e..452c1ba2665 100644 --- a/src/main/scala/tilelink/Arbiter.scala +++ b/src/main/scala/tilelink/Arbiter.scala @@ -7,7 +7,6 @@ import chisel3.util._ import chisel3.util.random.LFSR import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign object TLArbiter { @@ -51,7 +50,7 @@ object TLArbiter if (sources.isEmpty) { sink.bits := DontCare } else if (sources.size == 1) { - sink :<> sources.head._2 + sink :<>= sources.head._2 } else { val pairs = sources.toList val beatsIn = pairs.map(_._1) diff --git a/src/main/scala/tilelink/BlockDuringReset.scala b/src/main/scala/tilelink/BlockDuringReset.scala index 77a80b028e1..ec676b6fff4 100644 --- a/src/main/scala/tilelink/BlockDuringReset.scala +++ b/src/main/scala/tilelink/BlockDuringReset.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tilelink import chisel3._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.{BlockDuringReset, EnhancedChisel3Assign} +import freechips.rocketchip.util.BlockDuringReset /** BlockDuringReset ensures that no channel admits to be ready or valid while reset is raised. */ class TLBlockDuringReset(stretchResetCycles: Int = 0) @@ -16,12 +16,12 @@ class TLBlockDuringReset(stretchResetCycles: Int = 0) lazy val module = new Impl class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - out.a :<> BlockDuringReset(in .a, stretchResetCycles) - in .d :<> BlockDuringReset(out.d, stretchResetCycles) + out.a :<>= BlockDuringReset(in .a, stretchResetCycles) + in .d :<>= BlockDuringReset(out.d, stretchResetCycles) if (edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe) { - in .b :<> BlockDuringReset(out.b, stretchResetCycles) - out.c :<> BlockDuringReset(in .c, stretchResetCycles) - out.e :<> BlockDuringReset(in .e, stretchResetCycles) + in .b :<>= BlockDuringReset(out.b, stretchResetCycles) + out.c :<>= BlockDuringReset(in .c, stretchResetCycles) + out.e :<>= BlockDuringReset(in .e, stretchResetCycles) } else { in.b.valid := false.B in.c.ready := true.B diff --git a/src/main/scala/tilelink/Credited.scala b/src/main/scala/tilelink/Credited.scala index cec73f04593..30c73486012 100644 --- a/src/main/scala/tilelink/Credited.scala +++ b/src/main/scala/tilelink/Credited.scala @@ -8,7 +8,6 @@ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.subsystem.CrossingWrapper import freechips.rocketchip.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign class TLCreditedBuffer(delay: TLCreditedDelay)(implicit p: Parameters) extends LazyModule { @@ -19,11 +18,11 @@ class TLCreditedBuffer(delay: TLCreditedDelay)(implicit p: Parameters) extends L lazy val module = new Impl class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - out.a :<> in.a.pipeline(delay.a) - in.b :<> out.b.pipeline(delay.b) - out.c :<> in.c.pipeline(delay.c) - in.d :<> out.d.pipeline(delay.d) - out.e :<> in.e.pipeline(delay.e) + out.a :<>= in.a.pipeline(delay.a) + in.b :<>= out.b.pipeline(delay.b) + out.c :<>= in.c.pipeline(delay.c) + in.d :<>= out.d.pipeline(delay.d) + out.e :<>= in.e.pipeline(delay.e) } } } @@ -44,11 +43,11 @@ class TLCreditedSource(delay: TLCreditedDelay)(implicit p: Parameters) extends L class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val tld = edgeOut.delay - out.a :<> CreditedIO.fromSender(in.a, tld.a.total).pipeline(delay.a) - in.b :<> Decoupled(out.b.pipeline(delay.b).toReceiver(tld.b.total)) - out.c :<> CreditedIO.fromSender(in.c, tld.c.total).pipeline(delay.c) - in.d :<> Decoupled(out.d.pipeline(delay.d).toReceiver(tld.d.total)) - out.e :<> CreditedIO.fromSender(in.e, tld.e.total).pipeline(delay.e) + out.a :<>= CreditedIO.fromSender(in.a, tld.a.total).pipeline(delay.a) + in.b :<>= Decoupled(out.b.pipeline(delay.b).toReceiver(tld.b.total)) + out.c :<>= CreditedIO.fromSender(in.c, tld.c.total).pipeline(delay.c) + in.d :<>= Decoupled(out.d.pipeline(delay.d).toReceiver(tld.d.total)) + out.e :<>= CreditedIO.fromSender(in.e, tld.e.total).pipeline(delay.e) } } } @@ -69,11 +68,11 @@ class TLCreditedSink(delay: TLCreditedDelay)(implicit p: Parameters) extends Laz class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val tld = edgeIn.delay - out.a :<> Decoupled(in.a.pipeline(delay.a).toReceiver(tld.a.total)) - in.b :<> CreditedIO.fromSender(out.b, tld.b.total).pipeline(delay.b) - out.c :<> Decoupled(in.c.pipeline(delay.c).toReceiver(tld.c.total)) - in.d :<> CreditedIO.fromSender(out.d, tld.d.total).pipeline(delay.d) - out.e :<> Decoupled(in.e.pipeline(delay.e).toReceiver(tld.e.total)) + out.a :<>= Decoupled(in.a.pipeline(delay.a).toReceiver(tld.a.total)) + in.b :<>= CreditedIO.fromSender(out.b, tld.b.total).pipeline(delay.b) + out.c :<>= Decoupled(in.c.pipeline(delay.c).toReceiver(tld.c.total)) + in.d :<>= CreditedIO.fromSender(out.d, tld.d.total).pipeline(delay.d) + out.e :<>= Decoupled(in.e.pipeline(delay.e).toReceiver(tld.e.total)) } } } diff --git a/src/main/scala/tilelink/Fragmenter.scala b/src/main/scala/tilelink/Fragmenter.scala index fd07b2639bb..c38554d0fb8 100644 --- a/src/main/scala/tilelink/Fragmenter.scala +++ b/src/main/scala/tilelink/Fragmenter.scala @@ -313,7 +313,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = val fullMask = ((BigInt(1) << beatBytes) - 1).U assert (!repeater.io.full || in_a.bits.mask === fullMask) out.a.bits.mask := Mux(repeater.io.full, fullMask, in.a.bits.mask) - out.a.bits.user.partialAssignL(in.a.bits.user.subset(_.isData)) + out.a.bits.user :<= in.a.bits.user.subset(_.isData) // Tie off unused channels in.b.valid := false.B diff --git a/src/main/scala/tilelink/HintHandler.scala b/src/main/scala/tilelink/HintHandler.scala index 7f4c66e3632..3b581a84621 100644 --- a/src/main/scala/tilelink/HintHandler.scala +++ b/src/main/scala/tilelink/HintHandler.scala @@ -7,7 +7,6 @@ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import freechips.rocketchip.devices.tilelink.TLROM -import freechips.rocketchip.util.EnhancedChisel3Assign // Acks Hints for managers that don't support them or Acks all Hints if !passthrough class TLHintHandler(passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule @@ -56,8 +55,8 @@ class TLHintHandler(passthrough: Boolean = true)(implicit p: Parameters) extends val mux = Wire(chiselTypeOf(in.a)) repeater.io.repeat := mapPP && !edgeIn.last(out.a) - repeater.io.enq :<> in.a - out.a :<> mux + repeater.io.enq :<>= in.a + out.a :<>= mux // Only some signals need to be repeated mux.bits.opcode := in.a.bits.opcode // ignored when full @@ -71,7 +70,7 @@ class TLHintHandler(passthrough: Boolean = true)(implicit p: Parameters) extends // Hints have no data fields; use defaults for those mux.bits.user :<= in.a.bits.user - mux.bits.user.partialAssignL(repeater.io.deq.bits.user.subset(_.isControl)) + mux.bits.user :<= repeater.io.deq.bits.user.subset(_.isControl) mux.bits.echo :<= repeater.io.deq.bits.echo // control only mux.valid := repeater.io.deq.valid diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index ae43d77e802..76b6f6ad7dc 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -73,7 +73,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 @@ -94,7 +96,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 diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala index 98b637f4eb3..5f960aa944c 100644 --- a/src/main/scala/tilelink/ToAHB.scala +++ b/src/main/scala/tilelink/ToAHB.scala @@ -11,7 +11,6 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import AHBParameters._ import chisel3.util.{RegEnable, Queue, Cat, log2Ceil} -import freechips.rocketchip.util.EnhancedChisel3Assign case class TLToAHBNode(supportHints: Boolean)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AHBImpMaster)( dFn = { cp => @@ -208,7 +207,7 @@ class TLToAHB(val aFlow: Boolean = false, val supportHints: Boolean = true, val // a_ready and htrans, we add another entry for aFlow=false. val depth = if (aFlow) 2 else 3 val d = Wire(new DecoupledIO(new TLBundleD(edgeIn.bundle))) - in.d :<> Queue(d, depth, flow=true) + in.d :<>= Queue(d, depth, flow=true) assert (!d.valid || d.ready) val d_flight = RegInit(0.U(2.W)) diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala index 11ee0f25533..91c172d658a 100644 --- a/src/main/scala/tilelink/ToAPB.scala +++ b/src/main/scala/tilelink/ToAPB.scala @@ -9,7 +9,6 @@ import freechips.rocketchip.amba.apb._ import freechips.rocketchip.amba._ import APBParameters._ import chisel3.util._ -import freechips.rocketchip.util.EnhancedChisel3Assign case class TLToAPBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, APBImp)( dFn = { cp => @@ -65,7 +64,7 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod // phase result. Whenever we have a queued response, we can not allow // APB to present new responses, so we must quash the address phase. val d = Wire(Decoupled(new TLBundleD(edgeIn.bundle))) - in.d :<> Queue(d, 1, flow = true) + in.d :<>= Queue(d, 1, flow = true) // We need an irrevocable input for APB to stall val a = Queue(in.a, 1, flow = aFlow, pipe = !aFlow) @@ -90,7 +89,9 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod out.pprot := PROT_DEFAULT out.pwdata := a.bits.data out.pstrb := Mux(a_write, a.bits.mask, 0.U) - out.pauser :<= a.bits.user + Connectable.waiveUnmatched(out.pauser, a.bits.user) match { + case (lhs, rhs) => lhs :<= rhs + } a.bits.user.lift(AMBAProt).foreach { x => val pprot = Wire(Vec(3, Bool())) pprot(0) := x.privileged @@ -111,8 +112,12 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod d.bits.denied := d_write && out.pslverr d.bits.data := out.prdata d.bits.corrupt := !d_write && out.pslverr - d.bits.user :<= out.pduser - d.bits.echo :<= d_echo + Connectable.waiveUnmatched(d.bits.user, out.pduser) match { + case (lhs, rhs) => lhs :<= rhs + } + Connectable.waiveUnmatched(d.bits.echo, d_echo) match { + case (lhs, rhs) => lhs :<= rhs + } } } } diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index 6d99ed917a5..92cc088516d 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -9,7 +9,6 @@ import freechips.rocketchip.util._ import freechips.rocketchip.amba.axi4._ import freechips.rocketchip.amba._ import chisel3.util.{log2Ceil, UIntToOH, Queue, Decoupled, Cat} -import freechips.rocketchip.util.EnhancedChisel3Assign class AXI4TLStateBundle(val sourceBits: Int) extends Bundle { val size = UInt(4.W) @@ -149,7 +148,7 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String val depth = if (combinational) 1 else 2 val out_arw = Wire(Decoupled(new AXI4BundleARW(out.params))) val out_w = Wire(chiselTypeOf(out.w)) - out.w :<> Queue.irrevocable(out_w, entries=depth, combinational) + out.w :<>= Queue.irrevocable(out_w, entries=depth, combinational) val queue_arw = Queue.irrevocable(out_arw, entries=depth, combinational) // Fan out the ARW channel to AR and AW @@ -175,8 +174,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 @@ -232,10 +235,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 diff --git a/src/main/scala/util/package.scala b/src/main/scala/util/package.scala index d1babb70029..bacaf5b7b17 100644 --- a/src/main/scala/util/package.scala +++ b/src/main/scala/util/package.scala @@ -286,59 +286,4 @@ package object util { case x if x == n => in case _ => throw new Exception(s"must provide exactly 1 or $n of some field, but got:\n$in") } - -/** provides operators useful for working with bidirectional [[Bundle]]s - * - * In terms of [[Flipped]] with a producer 'p' and 'consumer' c: - * c :<= p // means drive all unflipped fields of 'c' from 'p' (e.g.: c.valid := p.valid) - * c :=> p // means drive all flipped fields of 'p' from 'c' (e.g.: `p.ready := c.ready`) - * c :<> p // do both of the above - * p :<> c // do both of the above, but you'll probably get a Flow error later. - * - * This utility class is needed because in [[chisel3]]: - * c := p // only works if there are no directions on fields. - * c <> p // only works if one of those is an [[IO]] (not a [[Wire]]). - * - * Compared with [[chisel3]] operators: - * c <> p is an 'actual-direction'-inferred 'c :<> p' or 'p :<> c' - * c := p is equivalent to 'c :<= p' + 'p :=> c'. In other words, drive ALL fields of 'c' from 'p' regardless of their direction. - * - * Contrast this with 'c :<> p' which will connect a ready-valid producer - * 'p' to a consumer 'c'. - * If you flip this to 'p :<> c', it works the way you would expect (flipping the role of producer/consumer). - * This is how Chisel._ (compatability mode) and firrtl work. - * Some find that ':<>' has superior readability (even if the direction can be inferred from an IO), - * because it clearly states the intended producer/consumer relationship. - * You will get an appropriate error if you connected it the wrong way - * (usually because you got the IO direction wrong) instead of silently succeeding. - * - * What if you want to connect all of the signals (e.g. ready/valid/bits) - * from producer 'p' to a monitor 'm'? - * For example in order to tap the connection to monitor traffic on an existing connection. - * In that case you can do 'm :<= p' and 'p :=> m'. - */ - implicit class EnhancedChisel3Assign[T <: Data](private val x: T) extends AnyVal { - /** Assign all output fields of x from y; note that the actual direction of x is irrelevant */ - def :<= (y: T): Unit = FixChisel3.assignL(x, y) - /** Assign all input fields of y from x; note that the actual direction of y is irrelevant */ - def :=> (y: T): Unit = FixChisel3.assignR(x, y) - /** Bulk connect which will work between two [[Wire]]s (in addition to between [[IO]]s) */ - def :<> (y: T): Unit = { - FixChisel3.assignL(x, y) - FixChisel3.assignR(x, y) - } - - - // Versions of the operators that use the type from the RHS - // y :<=: x -> x.:<=:(y) -> y :<= x -> FixChisel3.assignL(y, x) - /** version of the :<= operator that uses the type from the RHS */ - def :<=: (y: T): Unit = { FixChisel3.assignL(y, x) } - /** version of the :=> operator that uses the type from the RHS */ - def :>=: (y: T): Unit = { FixChisel3.assignR(y, x) } - /** version of the :<> operator that uses the type from the RHS */ - def :<>: (y: T): Unit = { - FixChisel3.assignL(y, x) - FixChisel3.assignR(y, x) - } - } }