diff options
| author | Jack Koenig | 2020-10-22 18:40:54 -0700 |
|---|---|---|
| committer | GitHub | 2020-10-22 18:40:54 -0700 |
| commit | 0745dedefea901df029e65aa59846d8b561dfd31 (patch) | |
| tree | c887b28eaa896af282ad91809fac5c511aac3b8a /core/src/main/scala/chisel3/Aggregate.scala | |
| parent | 26deb7703389b78a9b2a61f7e191f3f0e2a6623b (diff) | |
Use Data refs for name prefixing with aggregate elements (#1616)
* Use Data refs for name prefixing with aggregate elements
Vecs set the refs of their elements upon construction of those elements.
In the past, Records haven't set their elements refs until module close,
but it can be done sooner. Doing it upon binding means that refs will at
least be available for Records used in hardware elements. Since only
bound Data can be connected to anyway, Aggregate elements being
connected to will always have a ref which we can then use for creating
naming prefixes.
* Add tighter correctness checks
* Handle more cases in connection prefixing
Add support for forcing setRef to override a previous setting. This
is only used by BlackBox ports which need to drop their io prefix.
Also add a Try() around Data.bindingToString which sometimes throws
exceptions when being used to .toString a Data in an error message.
* Strip trailing spaces in names in compiler plugin
Diffstat (limited to 'core/src/main/scala/chisel3/Aggregate.scala')
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 9ccf7dbb..6c11b2db 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -479,9 +479,21 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId with Source * RTL writers should use [[Bundle]]. See [[Record#elements]] for an example. */ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptions) extends Aggregate { + + // Doing this earlier than onModuleClose allows field names to be available for prefixing the names + // of hardware created when connecting to one of these elements + private def setElementRefs(): Unit = { + // Since elements is a map, it is impossible for two elements to have the same + // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog + // which can cause collisions + val _namespace = Namespace.empty + for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk=true)) } + } + private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = { try { super.bind(target, parentDirection) + setElementRefs() } catch { // nasty compatibility mode shim, where anything flies case e: MixedDirectionAggregateException if !compileOptions.dontAssumeDirectionality => val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection) @@ -633,13 +645,11 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio case _ => false } - // NOTE: This sets up dependent references, it can be done before closing the Module private[chisel3] override def _onModuleClose: Unit = { - // Since Bundle names this via reflection, it is impossible for two elements to have the same - // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog - // which can cause collisions - val _namespace = Namespace.empty - for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk=true)) } + // This is usually done during binding, but these must still be set for unbound Records + if (this.binding.isEmpty) { + setElementRefs() + } } private[chisel3] final def allElements: Seq[Element] = elements.toIndexedSeq.flatMap(_._2.allElements) |
