diff options
| author | mergify[bot] | 2022-02-01 19:56:13 +0000 |
|---|---|---|
| committer | GitHub | 2022-02-01 19:56:13 +0000 |
| commit | ea1ced34b5c9e42412cc0ac3e7431cd3194ccbc3 (patch) | |
| tree | 2c51bccf3c954b85746e127bf9f7dccca9863a16 /core | |
| parent | 91ad2312cab72442fcfec9c28576b5464669f8fd (diff) | |
Chisel plugin bundle elements handler (#2306) (#2380)
Adds generation of `Bundle.elements` method to the chores done by the compiler plugin
For each `Bundle` find the relevant visible Chisel field members and construct a
hard-coded list of the elements and their names implemented as `_elementsImpl`
For more details: See plugins/README.md
- Should be no change in API
- Handles inheritance and mixins
- Handles Seq[Data]
- Tests in BundleElementSpec
Co-authored-by: chick <chick.markley@sifive.com>
Co-authored-by: Jack Koenig <koenig@sifive.com>
(cherry picked from commit 237200a420581519f29149cbae9b3e968c0d01fc)
Co-authored-by: Chick Markley <chick@qrhino.com>
Diffstat (limited to 'core')
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 50 | ||||
| -rw-r--r-- | core/src/main/scala/chisel3/Data.scala | 2 |
2 files changed, 49 insertions, 3 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 15cdf428..75966a16 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -1208,12 +1208,58 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { * }}} */ final lazy val elements: SeqMap[String, Data] = { + 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 _ => 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 + */ + protected def _elementsImpl: SeqMap[String, Any] = { val nameMap = LinkedHashMap[String, Data]() for (m <- getPublicFields(classOf[Bundle])) { getBundleField(m) match { case Some(d: Data) => - requireIsChiselType(d) - + // Checking for chiselType is done in elements method if (nameMap contains m.getName) { require(nameMap(m.getName) eq d) } else { diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala index 9e9f5dbb..ef43a3b0 100644 --- a/core/src/main/scala/chisel3/Data.scala +++ b/core/src/main/scala/chisel3/Data.scala @@ -480,7 +480,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { protected[chisel3] def binding: Option[Binding] = _binding protected def binding_=(target: Binding) { if (_binding.isDefined) { - throw RebindingException(s"Attempted reassignment of binding to $this") + throw RebindingException(s"Attempted reassignment of binding to $this, from: ${target}") } _binding = Some(target) } |
