Skip to content

Commit

Permalink
Add Probes to .toString Data methods (#4478) (#4480)
Browse files Browse the repository at this point in the history
* Add probe string to .toString Data methods

* Update chisel tests with new probe toString

(cherry picked from commit 8c718b2)

Co-authored-by: Adam Izraelevitz <adam.izraelevitz@sifive.com>
  • Loading branch information
mergify[bot] and azidar authored Nov 26, 2024
1 parent e339593 commit b84d108
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 12 deletions.
13 changes: 11 additions & 2 deletions core/src/main/scala/chisel3/Data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -424,21 +424,30 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
_directionVar = actualDirection
}

// Specializes the .toString method of a [[Data]] for conditions such as
// DataView, Probe modifiers, a DontCare, and whether it is bound or a pure chisel type
private[chisel3] def stringAccessor(chiselType: String): String = {
// Add probe (if it exists) to the returned String
val chiselTypeWithModifier =
probeInfo match {
case None => chiselType
case Some(ProbeInfo(writeable)) =>
(if (writeable) "RWProbe" else "Probe") + s"<$chiselType>"
}
// Trace views to give better error messages
// Reifying involves checking against ViewParent which requires being in a Builder context
// Since we're just printing a String, suppress such errors and use this object
val thiz = Try(reifySingleTarget(this)).toOption.flatten.getOrElse(this)
thiz.topBindingOpt match {
case None => chiselType
case None => chiselTypeWithModifier
// Handle DontCares specially as they are "literal-like" but not actually literals
case Some(DontCareBinding()) => s"$chiselType(DontCare)"
case Some(topBinding) =>
val binding: String = thiz._bindingToString(topBinding)
val name = thiz.earlyName
val mod = thiz.parentNameOpt.map(_ + ".").getOrElse("")

s"$mod$name: $binding[$chiselType]"
s"$mod$name: $binding[$chiselTypeWithModifier]"
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/test/scala/chisel3/TypeEquivalenceSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ class TypeEquivalenceSpec extends AnyFlatSpec {
it should "detect differences between Probe and Not-Probe" in {
Probe(Bool()).findFirstTypeMismatch(Bool(), true, true, true) should be(
Some(
": Left (Bool with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
": Left (Probe<Bool> with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
)
)
}
Expand All @@ -321,29 +321,29 @@ class TypeEquivalenceSpec extends AnyFlatSpec {
it should "detect differences between Probe and Not-Probe within a Bundle" in {
new BundleWithProbe(true).findFirstTypeMismatch(new BundleWithProbe(false), true, true, true) should be(
Some(
".maybeProbe: Left (Bool with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
".maybeProbe: Left (Probe<Bool> with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
)
)
}

it should "detect differences between probe types" in {
RWProbe(Bool()).findFirstTypeMismatch(Probe(Bool()), true, true, true) should be(
Some(
": Left (Bool with probeInfo: Some(writeable=true)) and Right (Bool with probeInfo: Some(writeable=false)) have different probeInfo."
": Left (RWProbe<Bool> with probeInfo: Some(writeable=true)) and Right (Probe<Bool> with probeInfo: Some(writeable=false)) have different probeInfo."
)
)
}

it should "detect differences through probes" in {
Probe(Bool()).findFirstTypeMismatch(Probe(Clock()), true, true, true) should be(
Some(": Left (Bool) and Right (Clock) have different types.")
Some(": Left (Probe<Bool>) and Right (Probe<Clock>) have different types.")
)
}

it should "detect differences in probe within a Vector" in {
Vec(3, Probe(Bool())).findFirstTypeMismatch(Vec(3, Bool()), true, true, true) should be(
Some(
"[_]: Left (Bool with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
"[_]: Left (Probe<Bool> with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo."
)
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/scala/chiselTests/DataPrint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
new RawModule {
UInt().toString should be("UInt")
UInt(8.W).toString should be("UInt<8>")
probe.Probe(UInt(8.W)).toString should be("Probe<UInt<8>>")
probe.RWProbe(UInt(8.W)).toString should be("RWProbe<UInt<8>>")
SInt(15.W).toString should be("SInt<15>")
Bool().toString should be("Bool")
Clock().toString should be("Clock")
Vec(3, UInt(2.W)).toString should be("UInt<2>[3]")
EnumTest.Type().toString should be("EnumTest")
(new BundleTest).toString should be("BundleTest")
(probe.Probe(new BundleTest)).toString should be("Probe<BundleTest>")
new Bundle { val a = UInt(8.W) }.toString should be("AnonymousBundle")
new Bundle { val a = UInt(8.W) }.a.toString should be("UInt<8>")
}
Expand All @@ -45,6 +48,7 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {

class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes
Wire(UInt()).toString should be("BoundDataModule.?: Wire[UInt]")
Wire(probe.Probe(UInt(1.W))).toString should be("BoundDataModule.?: Wire[Probe<UInt<1>>]")
Reg(SInt()).toString should be("BoundDataModule.?: Reg[SInt]")
val io = IO(Output(Bool())) // needs a name so elaboration doesn't fail
io.toString should be("BoundDataModule.io: IO[Bool]")
Expand Down
1 change: 0 additions & 1 deletion src/test/scala/chiselTests/LayerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,4 @@ class LayerSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
)

}

}
8 changes: 4 additions & 4 deletions src/test/scala/chiselTests/ProbeSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class ProbeSpec extends ChiselFlatSpec with Utils {
)
}
exc.getMessage should include(
"mismatched probe/non-probe types in ProbeSpec_Anon.io.out[0]: IO[Bool] and ProbeSpec_Anon.io.in[0]: IO[Bool]."
"mismatched probe/non-probe types in ProbeSpec_Anon.io.out[0]: IO[Probe<Bool>] and ProbeSpec_Anon.io.in[0]: IO[Bool]."
)
}

Expand All @@ -253,7 +253,7 @@ class ProbeSpec extends ChiselFlatSpec with Utils {
)
}
exc.getMessage should include(
"Connection between sink (ProbeSpec_Anon.io.out: IO[Bool]) and source (ProbeSpec_Anon.io.in: IO[Bool]) failed @: Sink io.out in ProbeSpec_Anon of Probed type cannot participate in a mono connection (:=)"
"Connection between sink (ProbeSpec_Anon.io.out: IO[Probe<Bool>]) and source (ProbeSpec_Anon.io.in: IO[Bool]) failed @: Sink io.out in ProbeSpec_Anon of Probed type cannot participate in a mono connection (:=)"
)
}

Expand Down Expand Up @@ -284,7 +284,7 @@ class ProbeSpec extends ChiselFlatSpec with Utils {
)
}
exc.getMessage should include(
"Connection between sink (ProbeSpec_Anon.io.in: IO[Bool]) and source (ProbeSpec_Anon.io.out: IO[Bool]) failed @: io.in in ProbeSpec_Anon cannot be written from module ProbeSpec_Anon"
"Connection between sink (ProbeSpec_Anon.io.in: IO[Probe<Bool>]) and source (ProbeSpec_Anon.io.out: IO[Probe<Bool>]) failed @: io.in in ProbeSpec_Anon cannot be written from module ProbeSpec_Anon"
)
}

Expand Down Expand Up @@ -354,7 +354,7 @@ class ProbeSpec extends ChiselFlatSpec with Utils {
}
exc.getMessage should include("Cannot define a probe on a non-equivalent type.")
exc.getMessage should include(
"Left (ProbeSpec_Anon.p: IO[UInt<4>]) and Right (ProbeSpec_Anon.w: OpResult[Bool]) have different types"
"Left (ProbeSpec_Anon.p: IO[Probe<UInt<4>>]) and Right (ProbeSpec_Anon.w: OpResult[Probe<Bool>]) have different types"
)

}
Expand Down

0 comments on commit b84d108

Please sign in to comment.