summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/internal
diff options
context:
space:
mode:
authorJack2022-04-26 02:53:08 +0000
committerJack2022-04-26 02:53:08 +0000
commit3a6cc75d72cbf890bbd45a002c31d16abfc6896d (patch)
tree298a39cbdbcd7e89953d75dbd840884f29ff7699 /core/src/main/scala/chisel3/internal
parentbe1ac06bf20c6c3d84c8ce5b0a50e2980e546e7e (diff)
parentd5a964f6e7beea1f38f9623224fc65e2397e1fe7 (diff)
Merge branch '3.5.x' into 3.5-release
Diffstat (limited to 'core/src/main/scala/chisel3/internal')
-rw-r--r--core/src/main/scala/chisel3/internal/BiConnect.scala8
-rw-r--r--core/src/main/scala/chisel3/internal/Binding.scala11
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala49
3 files changed, 40 insertions, 28 deletions
diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala
index a8b425f5..2d6c9e4a 100644
--- a/core/src/main/scala/chisel3/internal/BiConnect.scala
+++ b/core/src/main/scala/chisel3/internal/BiConnect.scala
@@ -285,7 +285,13 @@ private[chisel3] object BiConnect {
case _ => true
}
- typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck
+ // do not bulk connect the 'io' pseudo-bundle of a BlackBox since it will be decomposed in FIRRTL
+ def blackBoxCheck = Seq(source, sink).map(_._parent).forall {
+ case Some(_: BlackBox) => false
+ case _ => true
+ }
+
+ typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck && blackBoxCheck
}
// These functions (finally) issue the connection operation
diff --git a/core/src/main/scala/chisel3/internal/Binding.scala b/core/src/main/scala/chisel3/internal/Binding.scala
index 6431dd23..bab79bc1 100644
--- a/core/src/main/scala/chisel3/internal/Binding.scala
+++ b/core/src/main/scala/chisel3/internal/Binding.scala
@@ -141,11 +141,16 @@ case class DontCareBinding() extends UnconstrainedBinding
private[chisel3] case class ViewBinding(target: Element) extends UnconstrainedBinding
/** Binding for Aggregate Views
- * @param childMap Mapping from children of this view to each child's target
+ * @param childMap Mapping from children of this view to their respective targets
* @param target Optional Data this Aggregate views if the view is total and the target is a Data
+ * @note For any Elements in the childMap, both key and value must be Elements
+ * @note The types of key and value need not match for the top Data in a total view of type
+ * Aggregate
*/
-private[chisel3] case class AggregateViewBinding(childMap: Map[Data, Element], target: Option[Data])
- extends UnconstrainedBinding
+private[chisel3] case class AggregateViewBinding(childMap: Map[Data, Data]) extends UnconstrainedBinding {
+ // Helper lookup function since types of Elements always match
+ def lookup(key: Element): Option[Element] = childMap.get(key).map(_.asInstanceOf[Element])
+}
/** Binding for Data's returned from accessing an Instance/Definition members, if not readable/writable port */
private[chisel3] case object CrossModuleBinding extends TopBinding {
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index 1ffe54ab..4180f580 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -35,7 +35,7 @@ private[chisel3] class Namespace(keywords: Set[String]) {
// TODO what character set does FIRRTL truly support? using ANSI C for now
def legalStart(c: Char) = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
def legal(c: Char) = legalStart(c) || (c >= '0' && c <= '9')
- val res = s.filter(legal)
+ val res = if (s.forall(legal)) s else s.filter(legal)
val headOk = (!res.isEmpty) && (leadingDigitOk || legalStart(res.head))
if (headOk) res else s"_$res"
}
@@ -45,12 +45,9 @@ private[chisel3] class Namespace(keywords: Set[String]) {
// leadingDigitOk is for use in fields of Records
def name(elem: String, leadingDigitOk: Boolean = false): String = {
val sanitized = sanitize(elem, leadingDigitOk)
- if (this contains sanitized) {
- name(rename(sanitized))
- } else {
- names(sanitized) = 1
- sanitized
- }
+ val result = if (this.contains(sanitized)) rename(sanitized) else sanitized
+ names(result) = 1
+ result
}
}
@@ -108,17 +105,16 @@ private[chisel3] trait HasId extends InstanceId {
// Contains the seed computed automatically by the compiler plugin
private var auto_seed: Option[String] = None
- // Prefix at time when this class is constructed
- private val construction_prefix: Prefix = Builder.getPrefix
-
- // Prefix when the latest [[suggestSeed]] or [[autoSeed]] is called
- private var prefix_seed: Prefix = Nil
+ // Prefix for use in naming
+ // - Defaults to prefix at time when object is created
+ // - Overridden when [[suggestSeed]] or [[autoSeed]] is called
+ private var naming_prefix: Prefix = Builder.getPrefix
// Post-seed hooks called to carry the suggested seeds to other candidates as needed
- private val suggest_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String => Unit]
+ private var suggest_postseed_hooks: List[String => Unit] = Nil
// Post-seed hooks called to carry the auto seeds to other candidates as needed
- private val auto_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String => Unit]
+ private var auto_postseed_hooks: List[String => Unit] = Nil
/** Takes the last seed suggested. Multiple calls to this function will take the last given seed, unless
* this HasId is a module port (see overridden method in Data.scala).
@@ -136,8 +132,8 @@ private[chisel3] trait HasId extends InstanceId {
// Bypass the overridden behavior of autoSeed in [[Data]], apply autoSeed even to ports
private[chisel3] def forceAutoSeed(seed: String): this.type = {
auto_seed = Some(seed)
- for (hook <- auto_postseed_hooks) { hook(seed) }
- prefix_seed = Builder.getPrefix
+ for (hook <- auto_postseed_hooks.reverse) { hook(seed) }
+ naming_prefix = Builder.getPrefix
this
}
@@ -153,8 +149,8 @@ private[chisel3] trait HasId extends InstanceId {
*/
def suggestName(seed: => String): this.type = {
if (suggested_seed.isEmpty) suggested_seed = Some(seed)
- prefix_seed = Builder.getPrefix
- for (hook <- suggest_postseed_hooks) { hook(seed) }
+ naming_prefix = Builder.getPrefix
+ for (hook <- suggest_postseed_hooks.reverse) { hook(seed) }
this
}
@@ -183,18 +179,21 @@ private[chisel3] trait HasId extends InstanceId {
*/
def buildName(seed: String, prefix: Prefix): String = {
val builder = new StringBuilder()
- prefix.foreach(builder ++= _ + "_")
+ prefix.foreach { p =>
+ builder ++= p
+ builder += '_'
+ }
builder ++= seed
builder.toString
}
if (hasSeed) {
- Some(buildName(seedOpt.get, prefix_seed.reverse))
+ Some(buildName(seedOpt.get, naming_prefix.reverse))
} else {
defaultSeed.map { default =>
defaultPrefix match {
- case Some(p) => buildName(default, p :: construction_prefix.reverse)
- case None => buildName(default, construction_prefix.reverse)
+ case Some(p) => buildName(default, p :: naming_prefix.reverse)
+ case None => buildName(default, naming_prefix.reverse)
}
}
}
@@ -211,8 +210,8 @@ private[chisel3] trait HasId extends InstanceId {
private[chisel3] def hasAutoSeed: Boolean = auto_seed.isDefined
- private[chisel3] def addSuggestPostnameHook(hook: String => Unit): Unit = suggest_postseed_hooks += hook
- private[chisel3] def addAutoPostnameHook(hook: String => Unit): Unit = auto_postseed_hooks += hook
+ private[chisel3] def addSuggestPostnameHook(hook: String => Unit): Unit = suggest_postseed_hooks ::= hook
+ private[chisel3] def addAutoPostnameHook(hook: String => Unit): Unit = auto_postseed_hooks ::= hook
// Uses a namespace to convert suggestion into a true name
// Will not do any naming if the reference already assigned.
@@ -222,6 +221,8 @@ private[chisel3] trait HasId extends InstanceId {
val candidate_name = _computeName(prefix, Some(default)).get
val available_name = namespace.name(candidate_name)
setRef(Ref(available_name))
+ // Clear naming prefix to free memory
+ naming_prefix = Nil
}
private var _ref: Option[Arg] = None