summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/internal
diff options
context:
space:
mode:
authorJack Koenig2020-10-22 18:40:54 -0700
committerGitHub2020-10-22 18:40:54 -0700
commit0745dedefea901df029e65aa59846d8b561dfd31 (patch)
treec887b28eaa896af282ad91809fac5c511aac3b8a /core/src/main/scala/chisel3/internal
parent26deb7703389b78a9b2a61f7e191f3f0e2a6623b (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/internal')
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala20
1 files changed, 11 insertions, 9 deletions
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index ffa99913..3988ac68 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -198,7 +198,10 @@ private[chisel3] trait HasId extends InstanceId {
}
private var _ref: Option[Arg] = None
- private[chisel3] def setRef(imm: Arg): Unit = _ref = Some(imm)
+ private[chisel3] def setRef(imm: Arg, force: Boolean = false): Unit = {
+ assert(force || _ref.isEmpty, s"Internal Error, setRef for $this called twice! first ${_ref.get}, second $imm")
+ _ref = Some(imm)
+ }
private[chisel3] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name))
private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index)))
private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref))
@@ -369,13 +372,12 @@ private[chisel3] object Builder {
*/
def pushPrefix(d: HasId): Boolean = {
def buildAggName(id: HasId): Option[String] = {
- // TODO This is slow, can we store this information upon binding?
- def getSubName(field: Data, parent: Data): Option[String] = parent match {
- case vec: Vec[_] =>
- val idx = vec.indexOf(field)
- if (idx >= 0) Some(idx.toString) else None
- case rec: Record => rec.elements.collectFirst { case (name, d) if d == field => name }
- case _ => Builder.exception(s"Shouldn't see non-Aggregate $parent as parent in ChildBinding!")
+ def getSubName(field: Data): Option[String] = field.getOptionRef.flatMap {
+ case Slot(_, field) => Some(field) // Record
+ case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing
+ case Index(_, ULit(n, _)) => Some(n.toString) // Vec lit indexing
+ case Index(_, _: Node) => None // Vec dynamic indexing
+ case ModuleIO(_, n) => Some(n) // BlackBox port
}
def map2[A, B](a: Option[A], b: Option[A])(f: (A, A) => B): Option[B] =
a.flatMap(ax => b.map(f(ax, _)))
@@ -384,7 +386,7 @@ private[chisel3] object Builder {
case (_: WireBinding | _: RegBinding | _: MemoryPortBinding | _: OpBinding) => data.seedOpt
case ChildBinding(parent) => recData(parent).map { p =>
// And name of the field if we have one, we don't for dynamic indexing of Vecs
- getSubName(data, parent).map(p + "_" + _).getOrElse(p)
+ getSubName(data).map(p + "_" + _).getOrElse(p)
}
case SampleElementBinding(parent) => recData(parent)
case PortBinding(mod) if Builder.currentModule.contains(mod) => data.seedOpt