summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/chisel3/Aggregate.scala15
-rw-r--r--core/src/main/scala/chisel3/Bits.scala39
-rw-r--r--core/src/main/scala/chisel3/Clock.scala2
-rw-r--r--core/src/main/scala/chisel3/Data.scala51
-rw-r--r--core/src/main/scala/chisel3/StrongEnum.scala15
-rw-r--r--core/src/main/scala/chisel3/experimental/Analog.scala4
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/IR.scala15
-rw-r--r--src/test/scala/chiselTests/DataPrint.scala56
8 files changed, 125 insertions, 72 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala
index 7c7db1c6..6c6d89c3 100644
--- a/core/src/main/scala/chisel3/Aggregate.scala
+++ b/core/src/main/scala/chisel3/Aggregate.scala
@@ -164,16 +164,14 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int)
extends Aggregate with VecLike[T] {
override def toString: String = {
- val bindingString = topBindingOpt match {
+ topBindingOpt match {
case Some(VecLitBinding(vecLitBinding)) =>
val contents = vecLitBinding.zipWithIndex.map { case ((data, lit), index) =>
s"$index=$lit"
}.mkString(", ")
- s"($contents)"
- case _ => bindingToString
+ s"${sample_element.cloneType}[$length]($contents)"
+ case _ => stringAccessor(s"${sample_element.cloneType}[$length]")
}
- val elementType = sample_element.cloneType
- s"$elementType[$length]$bindingString"
}
private[chisel3] override def typeEquivalent(that: Data): Boolean = that match {
@@ -922,15 +920,14 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio
* }}}
*/
override def toString: String = {
- val bindingString = topBindingOpt match {
+ topBindingOpt match {
case Some(BundleLitBinding(_)) =>
val contents = elements.toList.reverse.map { case (name, data) =>
s"$name=$data"
}.mkString(", ")
- s"($contents)"
- case _ => bindingToString
+ s"$className($contents)"
+ case _ => stringAccessor(s"$className")
}
- s"$className$bindingString"
}
def elements: SeqMap[String, Data]
diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala
index 58ec2585..5ab04d13 100644
--- a/core/src/main/scala/chisel3/Bits.scala
+++ b/core/src/main/scala/chisel3/Bits.scala
@@ -399,11 +399,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
*/
sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[UInt] {
override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
+ litOption match {
+ case Some(value) => s"UInt$width($value)"
+ case _ => stringAccessor(s"UInt$width")
}
- s"UInt$width$bindingString"
}
private[chisel3] override def typeEquivalent(that: Data): Boolean =
@@ -773,11 +772,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
*/
sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[SInt] {
override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
+ litOption match {
+ case Some(value) => s"SInt$width($value)"
+ case _ => stringAccessor(s"SInt$width")
}
- s"SInt$width$bindingString"
}
private[chisel3] override def typeEquivalent(that: Data): Boolean =
@@ -1039,7 +1037,7 @@ object Reset {
* super type due to Bool inheriting from abstract class UInt
*/
final class ResetType(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
- override def toString: String = s"Reset$bindingToString"
+ override def toString: String = stringAccessor("Reset")
def cloneType: this.type = Reset().asInstanceOf[this.type]
@@ -1081,7 +1079,7 @@ object AsyncReset {
* asychronously reset registers.
*/
sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends Element with Reset {
- override def toString: String = s"AsyncReset$bindingToString"
+ override def toString: String = stringAccessor("AsyncReset")
def cloneType: this.type = AsyncReset().asInstanceOf[this.type]
@@ -1121,11 +1119,10 @@ sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends El
*/
sealed class Bool() extends UInt(1.W) with Reset {
override def toString: String = {
- val bindingString = litToBooleanOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
+ litToBooleanOption match {
+ case Some(value) => s"Bool($value)"
+ case _ => stringAccessor("Bool")
}
- s"Bool$bindingString"
}
private[chisel3] override def cloneTypeWidth(w: Width): this.type = {
@@ -1282,11 +1279,10 @@ package experimental {
extends Bits(width) with Num[FixedPoint] with HasBinaryPoint {
override def toString: String = {
- val bindingString = litToDoubleOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
+ litToDoubleOption match {
+ case Some(value) => s"FixedPoint$width$binaryPoint($value)"
+ case _ => stringAccessor(s"FixedPoint$width$binaryPoint")
}
- s"FixedPoint$width$binaryPoint$bindingString"
}
private[chisel3] override def typeEquivalent(that: Data): Boolean = that match {
@@ -1702,11 +1698,10 @@ package experimental {
extends Bits(range.getWidth) with Num[Interval] with HasBinaryPoint {
override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
+ litOption match {
+ case Some(value) => s"Interval$width($value)"
+ case _ => stringAccessor(s"Interval$width")
}
- s"Interval$width$bindingString"
}
private[chisel3] override def cloneTypeWidth(w: Width): this.type =
diff --git a/core/src/main/scala/chisel3/Clock.scala b/core/src/main/scala/chisel3/Clock.scala
index 0400697d..e4be6558 100644
--- a/core/src/main/scala/chisel3/Clock.scala
+++ b/core/src/main/scala/chisel3/Clock.scala
@@ -14,7 +14,7 @@ object Clock {
// TODO: Document this.
sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element {
- override def toString: String = s"Clock$bindingToString"
+ override def toString: String = stringAccessor("Clock")
def cloneType: this.type = Clock().asInstanceOf[this.type]
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index 4ae29ce8..89908401 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -435,27 +435,44 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
_direction = Some(actualDirection)
}
+ private[chisel3] def stringAccessor(chiselType: String): String = {
+ topBindingOpt match {
+ case None => chiselType
+ // Handle DontCares specially as they are "literal-like" but not actually literals
+ case Some(DontCareBinding()) => s"$chiselType(DontCare)"
+ case Some(topBinding) =>
+ val binding: String = _bindingToString(topBinding)
+ val name = earlyName
+ val mod = parentNameOpt.map(_ + ".").getOrElse("")
+
+ s"$mod$name: $binding[$chiselType]"
+ }
+ }
+
// User-friendly representation of the binding as a helper function for toString.
// Provides a unhelpful fallback for literals, which should have custom rendering per
// Data-subtype.
// TODO Is this okay for sample_element? It *shouldn't* be visible to users
- protected def bindingToString: String = Try(topBindingOpt match {
- case None => ""
- case Some(OpBinding(enclosure, _)) => s"(OpResult in ${enclosure.desiredName})"
- case Some(MemoryPortBinding(enclosure, _)) => s"(MemPort in ${enclosure.desiredName})"
- case Some(PortBinding(enclosure)) if !enclosure.isClosed => s"(IO in unelaborated ${enclosure.desiredName})"
- case Some(PortBinding(enclosure)) if enclosure.isClosed =>
- DataMirror.fullModulePorts(enclosure).find(_._2 eq this) match {
- case Some((name, _)) => s"(IO $name in ${enclosure.desiredName})"
- case None => s"(IO (unknown) in ${enclosure.desiredName})"
- }
- case Some(RegBinding(enclosure, _)) => s"(Reg in ${enclosure.desiredName})"
- case Some(WireBinding(enclosure, _)) => s"(Wire in ${enclosure.desiredName})"
- case Some(DontCareBinding()) => s"(DontCare)"
- case Some(ElementLitBinding(litArg)) => s"(unhandled literal)"
- case Some(BundleLitBinding(litMap)) => s"(unhandled bundle literal)"
- case Some(VecLitBinding(litMap)) => s"(unhandled vec literal)"
- }).getOrElse("")
+ @deprecated("This was never intended to be visible to user-defined types", "Chisel 3.5.0")
+ protected def bindingToString: String = _bindingToString(topBinding)
+
+ private[chisel3] def _bindingToString(topBindingOpt: TopBinding): String =
+ topBindingOpt match {
+ case OpBinding(_, _) => "OpResult"
+ case MemoryPortBinding(_, _) => "MemPort"
+ case PortBinding(_) => "IO"
+ case RegBinding(_, _) => "Reg"
+ case WireBinding(_, _) => "Wire"
+ case DontCareBinding() => "(DontCare)"
+ case ElementLitBinding(litArg) => "(unhandled literal)"
+ case BundleLitBinding(litMap) => "(unhandled bundle literal)"
+ case VecLitBinding(litMap) => "(unhandled vec literal)"
+ case _ => ""
+ }
+
+ private[chisel3] def earlyName: String = Arg.earlyLocalName(this)
+
+ private[chisel3] def parentNameOpt: Option[String] = this._parent.map(_.name)
// Return ALL elements at root of this type.
// Contasts with flatten, which returns just Bits
diff --git a/core/src/main/scala/chisel3/StrongEnum.scala b/core/src/main/scala/chisel3/StrongEnum.scala
index 9ae4c889..fa420e80 100644
--- a/core/src/main/scala/chisel3/StrongEnum.scala
+++ b/core/src/main/scala/chisel3/StrongEnum.scala
@@ -72,17 +72,18 @@ import EnumAnnotations._
abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolean = true) extends Element {
+
+ // Use getSimpleName instead of enumTypeName because for debugging purposes
+ // the fully qualified name isn't necessary (compared to for the
+ // Enum annotation), and it's more consistent with Bundle printing.
override def toString: String = {
- val bindingString = litOption match {
+ litOption match {
case Some(value) => factory.nameOfValue(value) match {
- case Some(name) => s"($value=$name)"
- case None => s"($value=(invalid))"
+ case Some(name) => s"${factory.getClass.getSimpleName.init}($value=$name)"
+ case None => stringAccessor(s"${factory.getClass.getSimpleName.init}($value=(invalid))")
}
- case _ => bindingToString
+ case _ => stringAccessor(s"${factory.getClass.getSimpleName.init}")
}
- // Use getSimpleName instead of enumTypeName because for debugging purposes the fully qualified name isn't
- // necessary (compared to for the Enum annotation), and it's more consistent with Bundle printing.
- s"${factory.getClass.getSimpleName.init}$bindingString"
}
override def cloneType: this.type = factory().asInstanceOf[this.type]
diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala
index 6cca81f5..e94bae2d 100644
--- a/core/src/main/scala/chisel3/experimental/Analog.scala
+++ b/core/src/main/scala/chisel3/experimental/Analog.scala
@@ -27,9 +27,7 @@ import scala.collection.mutable
final class Analog private (private[chisel3] val width: Width) extends Element {
require(width.known, "Since Analog is only for use in BlackBoxes, width must be known")
- override def toString: String = {
- s"Analog$width$bindingToString"
- }
+ override def toString: String = stringAccessor(s"Analog$width")
private[chisel3] override def typeEquivalent(that: Data): Boolean =
that.isInstanceOf[Analog] && this.width == that.width
diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
index 1a06cd36..a352c96a 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -86,6 +86,19 @@ case class Node(id: HasId) extends Arg {
}
}
+private[chisel3] object Arg {
+ def earlyLocalName(id: HasId): String = id.getOptionRef match {
+ case Some(Index(Node(imm), Node(value))) => s"${earlyLocalName(imm)}[${earlyLocalName(imm)}]"
+ case Some(Index(Node(imm), arg)) => s"${earlyLocalName(imm)}[${arg.localName}]"
+ case Some(Slot(Node(imm), name)) => s"${earlyLocalName(imm)}.$name"
+ case Some(arg) => arg.name
+ case None => id match {
+ case data: Data => data._computeName(None, Some("?")).get
+ case _ => "?"
+ }
+ }
+}
+
abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg {
private[chisel3] def forcedWidth = widthArg.known
private[chisel3] def width: Width = if (forcedWidth) widthArg else Width(minWidth)
@@ -196,7 +209,7 @@ case class Slot(imm: Node, name: String) extends Arg {
if (immName.isEmpty) name else s"$immName.$name"
}
}
-case class Index(imm: Arg, value: Arg) extends Arg {
+case class Index(imm: Node, value: Arg) extends Arg {
def name: String = s"[$value]"
override def contextualName(ctx: Component): String = s"${imm.contextualName(ctx)}[${value.contextualName(ctx)}]"
override def localName: String = s"${imm.localName}[${value.localName}]"
diff --git a/src/test/scala/chiselTests/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala
index b5f96c4d..7fb790a8 100644
--- a/src/test/scala/chiselTests/DataPrint.scala
+++ b/src/test/scala/chiselTests/DataPrint.scala
@@ -20,6 +20,14 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
val b = Bool()
}
+ class PartialBundleTest extends Bundle {
+ val a = UInt(8.W)
+ val b = Bool()
+ val c = SInt(8.W)
+ val e = FixedPoint(5.W, 3.BP)
+ val f = EnumTest.Type()
+ }
+
"Data types" should "have a meaningful string representation" in {
ChiselStage.elaborate { new RawModule {
UInt().toString should be ("UInt")
@@ -31,18 +39,20 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
Vec(3, UInt(2.W)).toString should be ("UInt<2>[3]")
EnumTest.Type().toString should be ("EnumTest")
(new BundleTest).toString should be ("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>")
+ }}
}
class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes
- Wire(UInt()).toString should be("UInt(Wire in BoundDataModule)")
- Reg(SInt()).toString should be("SInt(Reg in BoundDataModule)")
+ Wire(UInt()).toString should be("BoundDataModule.?: Wire[UInt]")
+ 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("Bool(IO in unelaborated BoundDataModule)")
+ io.toString should be("BoundDataModule.io: IO[Bool]")
val m = Mem(4, UInt(2.W))
- m(2).toString should be("UInt<2>(MemPort in BoundDataModule)")
- (2.U + 2.U).toString should be("UInt<2>(OpResult in BoundDataModule)")
- Wire(Vec(3, UInt(2.W))).toString should be ("UInt<2>[3](Wire in BoundDataModule)")
+ m(2).toString should be("BoundDataModule.?: MemPort[UInt<2>]")
+ (2.U + 2.U).toString should be("BoundDataModule.?: OpResult[UInt<2>]")
+ Wire(Vec(3, UInt(2.W))).toString should be ("BoundDataModule.?: Wire[UInt<2>[3]]")
class InnerModule extends Module {
val io = IO(Output(new Bundle {
@@ -50,8 +60,31 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
}))
}
val inner = Module(new InnerModule)
- inner.clock.toString should be ("Clock(IO clock in InnerModule)")
- inner.io.a.toString should be ("UInt<4>(IO io_a in InnerModule)")
+ inner.clock.toString should be ("InnerModule.clock: IO[Clock]")
+ inner.io.a.toString should be ("InnerModule.io.a: IO[UInt<4>]")
+
+ class FooTypeTest extends Bundle {
+ val foo = Vec(2, UInt(8.W))
+ val fizz = UInt(8.W)
+ }
+ val tpe = new FooTypeTest
+ val fooio: FooTypeTest = IO(Input(tpe))
+ fooio.foo(0).toString should be ("BoundDataModule.fooio.foo[0]: IO[UInt<8>]")
+
+ class NestedBundle extends Bundle {
+ val nestedFoo = UInt(8.W)
+ val nestedFooVec = Vec(2, UInt(8.W))
+ }
+ class NestedType extends Bundle {
+ val foo = new NestedBundle
+ }
+
+ val nestedTpe = new NestedType
+ val nestedio = IO(Input(nestedTpe))
+ (nestedio.foo.nestedFoo.toString should be
+ ("BoundDataModule.nestedio.foo.nestedFoo: IO[UInt<8>]"))
+ (nestedio.foo.nestedFooVec(0).toString should be
+ ("BoundDataModule.nestedio.foo.nestedFooVec[0]: IO[UInt<8>]"))
}
"Bound data types" should "have a meaningful string representation" in {
@@ -67,13 +100,12 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
true.B.toString should be ("Bool(true)")
2.25.F(6.W, 2.BP).toString should be ("FixedPoint<6><<2>>(2.25)")
-2.25.F(6.W, 2.BP).toString should be ("FixedPoint<6><<2>>(-2.25)")
+ Vec(3, UInt(4.W)).toString should be ("UInt<4>[3]")
EnumTest.sNone.toString should be ("EnumTest(0=sNone)")
EnumTest.sTwo.toString should be ("EnumTest(2=sTwo)")
EnumTest(1.U).toString should be ("EnumTest(1=sOne)")
(new BundleTest).Lit(_.a -> 2.U, _.b -> false.B).toString should be ("BundleTest(a=UInt<8>(2), b=Bool(false))")
- new Bundle {
- val a = UInt(8.W)
- }.toString should be ("AnonymousBundle")
+ (new PartialBundleTest).Lit().toString should be ("PartialBundleTest(a=UInt<8>(DontCare), b=Bool(DontCare), c=SInt<8>(DontCare), e=FixedPoint<5><<3>>(DontCare), f=EnumTest(DontCare))")
DontCare.toString should be ("DontCare()")
} }
}