From 681df95015277f51817d9ec82c4d5ec152706ef5 Mon Sep 17 00:00:00 2001 From: Will Dietz Date: Thu, 23 May 2024 16:09:12 -0500 Subject: [PATCH] BoringUtils: Fix tapAndRead to return same type even when not boring. 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. --- .../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 7215335fbb4..93ca1691dab 100644 --- a/src/main/scala/chisel3/util/experimental/BoringUtils.scala +++ b/src/main/scala/chisel3/util/experimental/BoringUtils.scala @@ -296,6 +296,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 add2b7a5963..28f66744aa2 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()))