diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Module.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/Chisel/internal/Builder.scala | 25 | ||||
| -rw-r--r-- | src/main/scala/Chisel/util/Decoupled.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/Chisel/util/TransitName.scala | 21 |
4 files changed, 49 insertions, 5 deletions
diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala index 22c1f9c3..cfcf5a48 100644 --- a/src/main/scala/Chisel/Module.scala +++ b/src/main/scala/Chisel/Module.scala @@ -76,16 +76,18 @@ abstract class Module(_clock: Clock = null, _reset: Bool = null) extends HasId { for ((port, name) <- ports) port.setRef(ModuleIO(this, _namespace.name(name))) + // Suggest names to nodes using runtime reflection val valNames = HashSet[String](getClass.getDeclaredFields.map(_.getName):_*) def isPublicVal(m: java.lang.reflect.Method) = m.getParameterTypes.isEmpty && valNames.contains(m.getName) val methods = getClass.getMethods.sortWith(_.getName > _.getName) for (m <- methods; if isPublicVal(m)) m.invoke(this) match { - case id: HasId => id.setRef(_namespace.name(m.getName)) + case (id: HasId) => id.suggestName(m.getName) case _ => } - _ids.foreach(_.setRef(_namespace.name("T"))) + // All suggestions are in, force names to every node. + _ids.foreach(_.forceName(default="T", _namespace)) _ids.foreach(_._onModuleClose) this } diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala index f9d27a61..c7ecdaa0 100644 --- a/src/main/scala/Chisel/internal/Builder.scala +++ b/src/main/scala/Chisel/internal/Builder.scala @@ -52,9 +52,30 @@ private[Chisel] trait HasId { case _ => false } + // Facilities for 'suggesting' a name to this. + // Post-name hooks called to carry the suggestion to other candidates as needed + private var suggested_name: Option[String] = None + private val postname_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit] + // Only takes the first suggestion! + def suggestName(name: =>String): this.type = { + if(suggested_name.isEmpty) suggested_name = Some(name) + for(hook <- postname_hooks) { hook(name) } + this + } + private[Chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook + + // Uses a namespace to convert suggestion into a true name + // Will not do any naming if the reference already assigned. + // (e.g. tried to suggest a name to part of a Bundle) + private[Chisel] def forceName(default: =>String, namespace: Namespace): Unit = + if(_ref.isEmpty) { + val candidate_name = suggested_name.getOrElse(default) + val available_name = namespace.name(candidate_name) + setRef(Ref(available_name)) + } + private var _ref: Option[Arg] = None private[Chisel] def setRef(imm: Arg): Unit = _ref = Some(imm) - private[Chisel] def setRef(name: => String): Unit = if (_ref.isEmpty) setRef(Ref(name)) private[Chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) private[Chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) private[Chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) @@ -91,7 +112,7 @@ private[Chisel] object Builder { dynamicContextVar.withValue(Some(new DynamicContext)) { errors.info("Elaborating design...") val mod = f - mod.setRef(globalNamespace.name(mod.name)) + mod.forceName(mod.name, globalNamespace) errors.checkpoint() errors.info("Done elaborating.") diff --git a/src/main/scala/Chisel/util/Decoupled.scala b/src/main/scala/Chisel/util/Decoupled.scala index 498af572..faee2a5f 100644 --- a/src/main/scala/Chisel/util/Decoupled.scala +++ b/src/main/scala/Chisel/util/Decoupled.scala @@ -175,6 +175,6 @@ object Queue q.io.enq.valid := enq.valid // not using <> so that override is allowed q.io.enq.bits := enq.bits enq.ready := q.io.enq.ready - q.io.deq + TransitName(q.io.deq, q) } } diff --git a/src/main/scala/Chisel/util/TransitName.scala b/src/main/scala/Chisel/util/TransitName.scala new file mode 100644 index 00000000..ec5a11cc --- /dev/null +++ b/src/main/scala/Chisel/util/TransitName.scala @@ -0,0 +1,21 @@ +package Chisel + +import internal.HasId + +object TransitName { + // The purpose of this is to allow a library to 'move' a name call to a more + // appropriate place. + // For example, a library factory function may create a module and return + // the io. The only user-exposed field is that given IO, which can't use + // any name supplied by the user. This can add a hook so that the supplied + // name then names the Module. + // See Queue companion object for working example + def apply[T<:HasId](from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name)}) + from + } + def withSuffix[T<:HasId](suffix: String)(from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name+suffix)}) + from + } +} |
