summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/Chisel/Module.scala6
-rw-r--r--src/main/scala/Chisel/internal/Builder.scala25
-rw-r--r--src/main/scala/Chisel/util/Decoupled.scala2
-rw-r--r--src/main/scala/Chisel/util/TransitName.scala21
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
+ }
+}