diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala index a22822a78f1..76d0022fac8 100644 --- a/core/src/main/scala/chisel3/Data.scala +++ b/core/src/main/scala/chisel3/Data.scala @@ -424,13 +424,22 @@ 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) => @@ -438,7 +447,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { val name = thiz.earlyName val mod = thiz.parentNameOpt.map(_ + ".").getOrElse("") - s"$mod$name: $binding[$chiselType]" + s"$mod$name: $binding[$chiselTypeWithModifier]" } } diff --git a/src/test/scala/chisel3/TypeEquivalenceSpec.scala b/src/test/scala/chisel3/TypeEquivalenceSpec.scala index 4d22e2ca1ee..c3354cb7a9c 100644 --- a/src/test/scala/chisel3/TypeEquivalenceSpec.scala +++ b/src/test/scala/chisel3/TypeEquivalenceSpec.scala @@ -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 with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo." ) ) } @@ -321,7 +321,7 @@ 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 with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo." ) ) } @@ -329,21 +329,21 @@ class TypeEquivalenceSpec extends AnyFlatSpec { 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 with probeInfo: Some(writeable=true)) and Right (Probe 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) and Right (Probe) 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 with probeInfo: Some(writeable=false)) and Right (Bool with probeInfo: None) have different probeInfo." ) ) } diff --git a/src/test/scala/chiselTests/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala index c61b45867c3..f3f52c60af1 100644 --- a/src/test/scala/chiselTests/DataPrint.scala +++ b/src/test/scala/chiselTests/DataPrint.scala @@ -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>") + probe.RWProbe(UInt(8.W)).toString should be("RWProbe>") 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") new Bundle { val a = UInt(8.W) }.toString should be("AnonymousBundle") new Bundle { val a = UInt(8.W) }.a.toString should be("UInt<8>") } @@ -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>]") 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]") diff --git a/src/test/scala/chiselTests/LayerSpec.scala b/src/test/scala/chiselTests/LayerSpec.scala index 4042806fe2f..393e2a94f01 100644 --- a/src/test/scala/chiselTests/LayerSpec.scala +++ b/src/test/scala/chiselTests/LayerSpec.scala @@ -62,5 +62,4 @@ class LayerSpec extends ChiselFlatSpec with Utils with MatchesAndOmits { ) } - } diff --git a/src/test/scala/chiselTests/ProbeSpec.scala b/src/test/scala/chiselTests/ProbeSpec.scala index 6e65c48528e..f60ec8e10ad 100644 --- a/src/test/scala/chiselTests/ProbeSpec.scala +++ b/src/test/scala/chiselTests/ProbeSpec.scala @@ -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] and ProbeSpec_Anon.io.in[0]: IO[Bool]." ) } @@ -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]) and source (ProbeSpec_Anon.io.in: IO[Bool]) failed @: Sink io.out in ProbeSpec_Anon of Probed type cannot participate in a mono connection (:=)" ) } @@ -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]) and source (ProbeSpec_Anon.io.out: IO[Probe]) failed @: io.in in ProbeSpec_Anon cannot be written from module ProbeSpec_Anon" ) } @@ -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>]) and Right (ProbeSpec_Anon.w: OpResult[Probe]) have different types" ) }