Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix BoringUtils for identity views #4220

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion core/src/main/scala/chisel3/RawModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down
112 changes: 112 additions & 0 deletions src/test/scala/chiselTests/BoringUtilsTapSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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<UInt<1>>",
"output out_bore : Probe<UInt<1>>",
"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())
Expand Down Expand Up @@ -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<UInt<1>>",
"define out_bore = rwprobe(internalWire)",
"module Foo :",
"output out_bore : RWProbe<UInt<1>>",
"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")
}
}