Skip to content

Commit

Permalink
BoringUtils: Fix tapAndRead to return same type even when not boring. (
Browse files Browse the repository at this point in the history
…#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 0cc1658)

Co-authored-by: Will Dietz <will.dietz@sifive.com>
  • Loading branch information
mergify[bot] and dtzSiFive committed May 24, 2024
1 parent 5d3bdb2 commit 3e4382b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/main/scala/chisel3/util/experimental/BoringUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
23 changes: 23 additions & 0 deletions src/test/scala/chiselTests/BoringUtilsTapSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
Expand Down

0 comments on commit 3e4382b

Please sign in to comment.