diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 3e6022c1d2c..e5a735914c3 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -1207,51 +1207,52 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { * assert(uint === "h12345678".U) // This will pass * }}} */ - final lazy val elements: SeqMap[String, Data] = { - // _elementsImpl is a method, only call it once - val elementsImpl = _elementsImpl - val hardwareFields = elementsImpl.flatMap { - case (name, data: Data) => - if (data.isSynthesizable) { - Some(s"$name: $data") - } else { - None - } - case (name, Some(data: Data)) => - if (data.isSynthesizable) { - Some(s"$name: $data") - } else { + final lazy val elements: SeqMap[String, Data] = _elementsImpl match { + case reflective: VectorMap[String, Data] => reflective + // _elementsImpl is a method, only call it once, see the match above for the 1 call + case elementsImpl => + val hardwareFields = elementsImpl.flatMap { + case (name, data: Data) => + if (data.isSynthesizable) { + Some(s"$name: $data") + } else { + None + } + case (name, Some(data: Data)) => + if (data.isSynthesizable) { + Some(s"$name: $data") + } else { + None + } + case (name, s: scala.collection.Seq[Any]) if s.nonEmpty => + s.head match { + // Ignore empty Seq() + case d: Data => + throwException( + "Public Seq members cannot be used to define Bundle elements " + + s"(found public Seq member '${name}'). " + + "Either use a Vec if all elements are of the same type, or MixedVec if the elements " + + "are of different types. If this Seq member is not intended to construct RTL, mix in the trait " + + "IgnoreSeqInBundle." + ) + case _ => // don't care about non-Data Seq + } None - } - case (name, s: scala.collection.Seq[Any]) if s.nonEmpty => - s.head match { - // Ignore empty Seq() - case d: Data => - throwException( - "Public Seq members cannot be used to define Bundle elements " + - s"(found public Seq member '${name}'). " + - "Either use a Vec if all elements are of the same type, or MixedVec if the elements " + - "are of different types. If this Seq member is not intended to construct RTL, mix in the trait " + - "IgnoreSeqInBundle." - ) - case _ => // don't care about non-Data Seq - } - None - case _ => None - } - if (hardwareFields.nonEmpty) { - throw ExpectedChiselTypeException(s"Bundle: $this contains hardware fields: " + hardwareFields.mkString(",")) - } - VectorMap(elementsImpl.toSeq.flatMap { - case (name, data: Data) => - Some(name -> data) - case (name, Some(data: Data)) => - Some(name -> data) - case _ => None - }.sortWith { - case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) - }: _*) + case _ => None + } + if (hardwareFields.nonEmpty) { + throw ExpectedChiselTypeException(s"Bundle: $this contains hardware fields: " + hardwareFields.mkString(",")) + } + VectorMap(elementsImpl.toSeq.flatMap { + case (name, data: Data) => + Some(name -> data) + case (name, Some(data: Data)) => + Some(name -> data) + case _ => None + }.sortWith { + case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) + }: _*) } /* * This method will be overwritten by the Chisel-Plugin @@ -1261,7 +1262,8 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { for (m <- getPublicFields(classOf[Bundle])) { getBundleField(m) match { case Some(d: Data) => - // Checking for chiselType is done in elements method + requireIsChiselType(d) + if (nameMap contains m.getName) { require(nameMap(m.getName) eq d) } else {