From f1bc20812edc0eccc4eda2fa79cc96bce873e063 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 26 Jun 2024 11:49:40 -0700 Subject: [PATCH] Fix BoringUtils for identity views --- core/src/main/scala/chisel3/RawModule.scala | 7 +- .../chiselTests/BoringUtilsTapSpec.scala | 112 ++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/RawModule.scala b/core/src/main/scala/chisel3/RawModule.scala index 8981af1bab4..290c6ff854e 100644 --- a/core/src/main/scala/chisel3/RawModule.scala +++ b/core/src/main/scala/chisel3/RawModule.scala @@ -225,7 +225,12 @@ abstract class RawModule extends BaseModule { } private[chisel3] val stagedSecretCommands = collection.mutable.ArrayBuffer[Command]() - private[chisel3] def secretConnection(left: Data, right: Data)(implicit si: SourceInfo): Unit = { + private[chisel3] def secretConnection(left: Data, _right: Data)(implicit si: SourceInfo): Unit = { + val (right: Data, _) = chisel3.experimental.dataview + .reifyIdentityView(_right) + .getOrElse( + throwException(s"BoringUtils currently only support identity views, ${_right} has multiple targets.") + ) val rhs = (left.probeInfo.nonEmpty, right.probeInfo.nonEmpty) match { case (true, true) => ProbeDefine(si, left.lref, Node(right)) case (true, false) if left.probeInfo.get.writable => ProbeDefine(si, left.lref, RWProbeExpr(Node(right))) diff --git a/src/test/scala/chiselTests/BoringUtilsTapSpec.scala b/src/test/scala/chiselTests/BoringUtilsTapSpec.scala index 6bdc2be0804..2bff53ae354 100644 --- a/src/test/scala/chiselTests/BoringUtilsTapSpec.scala +++ b/src/test/scala/chiselTests/BoringUtilsTapSpec.scala @@ -165,6 +165,60 @@ class BoringUtilsTapSpec extends ChiselFlatSpec with ChiselRunners with Utils wi )() } + it should "work for identity views" in { + import chisel3.experimental.dataview._ + class Foo extends RawModule { + private val internalWire = Wire(Bool()) + val view = internalWire.viewAs[Bool] + } + class Top extends RawModule { + val foo = Module(new Foo) + val outProbe = IO(probe.Probe(Bool())) + val out = IO(Bool()) + probe.define(outProbe, BoringUtils.tap(foo.view)) + out := BoringUtils.tapAndRead(foo.view) + } + val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Top) + matchesAndOmits(chirrtl)( + "module Foo :", + "output bore : Probe>", + "output out_bore : Probe>", + "define bore = probe(internalWire)", + "define out_bore = probe(internalWire)", + "module Top :", + "define outProbe = foo.bore", + "connect out, read(foo.out_bore)" + )() + } + + it should "NOT work [yet] for non-identity views" in { + import chisel3.experimental.dataview._ + class MyBundle extends Bundle { + val a = Bool() + val b = Bool() + } + object MyBundle { + implicit val view: DataView[(Bool, Bool), MyBundle] = DataView( + _ => new MyBundle, + _._1 -> _.a, + _._2 -> _.b + ) + } + class Foo extends RawModule { + private val w1, w2 = Wire(Bool()) + val view = (w1, w2).viewAs[MyBundle] + } + class Top extends RawModule { + val foo = Module(new Foo) + val out = IO(new MyBundle) + val outProbe = IO(probe.Probe(new MyBundle)) + probe.define(outProbe, BoringUtils.tap(foo.view)) + out := BoringUtils.tapAndRead(foo.view) + } + val e = the[ChiselException] thrownBy circt.stage.ChiselStage.emitCHIRRTL(new Top) + e.getMessage should include("BoringUtils currently only support identity views") + } + "Writable tap" should "work downwards from grandparent to grandchild" in { class Bar extends RawModule { val internalWire = Wire(Bool()) @@ -527,4 +581,62 @@ class BoringUtilsTapSpec extends ChiselFlatSpec with ChiselRunners with Utils wi )() } + it should "work for identity views" in { + import chisel3.experimental.dataview._ + class Bar extends RawModule { + private val internalWire = Wire(Bool()) + val view = internalWire.viewAs[Bool] + } + class Foo extends RawModule { + val bar = Module(new Bar) + } + class Top extends RawModule { + val foo = Module(new Foo) + val out = IO(Bool()) + out := probe.read(BoringUtils.rwTap(foo.bar.view)) + probe.forceInitial(BoringUtils.rwTap(foo.bar.view), false.B) + } + val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Top) + matchesAndOmits(chirrtl)( + "module Bar :", + "output out_bore : RWProbe>", + "define out_bore = rwprobe(internalWire)", + "module Foo :", + "output out_bore : RWProbe>", + "define out_bore = bar.out_bore", + "module Top :", + "connect out, read(foo.out_bore)", + "force_initial(foo.bore, UInt<1>(0h0))" + )() + } + + it should "NOT work [yet] for non-identity views" in { + import chisel3.experimental.dataview._ + class MyBundle extends Bundle { + val a = Bool() + val b = Bool() + } + object MyBundle { + implicit val view: DataView[(Bool, Bool), MyBundle] = DataView( + _ => new MyBundle, + _._1 -> _.a, + _._2 -> _.b + ) + } + class Bar extends RawModule { + private val w1, w2 = Wire(Bool()) + val view = (w1, w2).viewAs[MyBundle] + } + class Foo extends RawModule { + val bar = Module(new Bar) + } + class Top extends RawModule { + val foo = Module(new Foo) + val out = IO(Bool()) + out := probe.read(BoringUtils.rwTap(foo.bar.view)) + probe.forceInitial(BoringUtils.rwTap(foo.bar.view), false.B) + } + val e = the[ChiselException] thrownBy circt.stage.ChiselStage.emitCHIRRTL(new Top) + e.getMessage should include("BoringUtils currently only support identity views") + } }