summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/internal
diff options
context:
space:
mode:
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