Skip to content

Commit

Permalink
Handle define on views of Probes (#4308) (#4311)
Browse files Browse the repository at this point in the history
(cherry picked from commit 73e96ea)

Co-authored-by: Jack Koenig <koenig@sifive.com>
  • Loading branch information
mergify[bot] and jackkoenig authored Nov 25, 2024
1 parent 0167e9e commit ad6ee73
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
16 changes: 11 additions & 5 deletions core/src/main/scala/chisel3/probe/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import chisel3.internal.Builder.pushCommand
import chisel3.internal.firrtl.ir._
import chisel3.Data.ProbeInfo
import chisel3.experimental.{requireIsHardware, SourceInfo}
import chisel3.experimental.dataview.reifyIdentityView
import chisel3.reflect.DataMirror.{checkTypeEquivalence, collectAllMembers, hasProbeTypeModifier}

import scala.language.experimental.macros
Expand All @@ -33,7 +34,12 @@ package object probe extends SourceInfoDoc {
* @param probeExpr value to initialize the sink to
*/
def define[T <: Data](sink: T, probeExpr: T)(implicit sourceInfo: SourceInfo): Unit = {
val typeCheckResult = sink.findFirstTypeMismatch(
val (realSink, writable) = reifyIdentityView(sink).getOrElse {
Builder.error(s"Define only supports identity views for the sink, $sink has multiple targets.")
return // This error is recoverable and this function returns Unit, just continue elaboration.
}
writable.reportIfReadOnlyUnit(())
val typeCheckResult = realSink.findFirstTypeMismatch(
probeExpr,
strictTypes = true,
strictWidths = true,
Expand All @@ -42,16 +48,16 @@ package object probe extends SourceInfoDoc {
typeCheckResult.foreach { msg =>
Builder.error(s"Cannot define a probe on a non-equivalent type.\n$msg")
}
requireHasProbeTypeModifier(sink, "Expected sink to be a probe.")
requireNotChildOfProbe(sink, "Expected sink to be the root of a probe.")
requireHasProbeTypeModifier(realSink, "Expected sink to be a probe.")
requireNotChildOfProbe(realSink, "Expected sink to be the root of a probe.")
requireHasProbeTypeModifier(probeExpr, "Expected source to be a probe expression.")
if (sink.probeInfo.get.writable) {
if (realSink.probeInfo.get.writable) {
requireHasWritableProbeTypeModifier(
probeExpr,
"Cannot use a non-writable probe expression to define a writable probe."
)
}
pushCommand(ProbeDefine(sourceInfo, sink.lref, probeExpr.ref))
pushCommand(ProbeDefine(sourceInfo, realSink.lref, probeExpr.ref))
}

/** Access the value of a probe.
Expand Down
19 changes: 18 additions & 1 deletion src/test/scala/chiselTests/experimental/DataView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,24 @@ class DataViewSpec extends ChiselFlatSpec {
chirrtl should include("define a = rwprobe(w)")
}

it should "error if attempting to define a viewed a Probe as a RWProbe" in {
it should "support defining identity views of Probes" in {
class InnerBundle extends Bundle {
val a = Bool()
}
class OuterBundle extends Bundle {
val a = Probe(new InnerBundle)
}
class MyModule extends Module {
val p = Wire(new OuterBundle)
val view = p.viewAs[OuterBundle]
val w = Wire(new InnerBundle)
define(view.a, ProbeValue(w))
}
val chirrtl = ChiselStage.emitCHIRRTL(new MyModule)
chirrtl should include("define p.a = probe(w)")
}

it should "error if attempting to define a Probe viewed as a RWProbe" in {
class MyModule extends Module {
val a = IO(Output(RWProbe(Bool())))
val w = WireInit(Bool(), false.B)
Expand Down

0 comments on commit ad6ee73

Please sign in to comment.