From 3e4382b4b5b863ff31012f9588c50781bc0ead3a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 17:20:16 -0700 Subject: [PATCH] BoringUtils: Fix tapAndRead to return same type even when not boring. (#4084) (#4094) This should always return the same type/alignment regardless of where the original resides, so if the expectation is a fully aligned result then create one if needed. (cherry picked from commit 0cc16586163b0d60809d2bfc658e8b739fdd9f60) Co-authored-by: Will Dietz --- .../util/experimental/BoringUtils.scala | 6 +++++ .../chiselTests/BoringUtilsTapSpec.scala | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/main/scala/chisel3/util/experimental/BoringUtils.scala b/src/main/scala/chisel3/util/experimental/BoringUtils.scala index a916b341644..eee7fbb0e52 100644 --- a/src/main/scala/chisel3/util/experimental/BoringUtils.scala +++ b/src/main/scala/chisel3/util/experimental/BoringUtils.scala @@ -282,6 +282,12 @@ object BoringUtils { } if (parent(source) == thisModule) { // No boring to do + if (createProbe.nonEmpty && !DataMirror.isFullyAligned(source)) { + // Create aligned wire if source isn't aligned. This ensures result has same type regardless of origin. + val bore = Wire(purePortTypeBase) + bore :#= source + return bore + } return source } diff --git a/src/test/scala/chiselTests/BoringUtilsTapSpec.scala b/src/test/scala/chiselTests/BoringUtilsTapSpec.scala index cc0c52ac632..f1919a34bfd 100644 --- a/src/test/scala/chiselTests/BoringUtilsTapSpec.scala +++ b/src/test/scala/chiselTests/BoringUtilsTapSpec.scala @@ -495,6 +495,29 @@ class BoringUtilsTapSpec extends ChiselFlatSpec with ChiselRunners with Utils wi val verilog = circt.stage.ChiselStage.emitSystemVerilog(new Foo) } + it should "work with DecoupledIO locally" in { + import chisel3.util.{Decoupled, DecoupledIO} + class Foo extends RawModule { + val a = WireInit(DecoupledIO(Bool()), DontCare) + val b = BoringUtils.tapAndRead(a) + assert(chisel3.reflect.DataMirror.isFullyAligned(b), "tapAndRead should always return passive data") + } + + val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Foo, Array("--full-stacktrace")) + + matchesAndOmits(chirrtl)( + "module Foo :", + "wire a : { flip ready : UInt<1>, valid : UInt<1>, bits : UInt<1>}", + "wire b : { ready : UInt<1>, valid : UInt<1>, bits : UInt<1>}", + "connect b.bits, a.bits", + "connect b.valid, a.valid", + "connect b.ready, a.ready" + )() + + // Check that firtool also passes + val verilog = circt.stage.ChiselStage.emitSystemVerilog(new Foo) + } + it should "allow tapping a probe" in { class Bar extends RawModule { val a = IO(probe.Probe(Bool()))