summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/RawModule.scala
diff options
context:
space:
mode:
authormergify[bot]2022-06-16 23:15:42 +0000
committerGitHub2022-06-16 23:15:42 +0000
commitd001b34f816f1f65d0625aebf33e5cfc5ba93e49 (patch)
tree7145978904fea41e4a61a14ff3b08d3b243cf951 /core/src/main/scala/chisel3/RawModule.scala
parent13641d95951b189d7f5b0d4d99ace45f8b8f6282 (diff)
Define leading '_' as API for creating temporaries (backport #2580) (#2581)
* Define leading '_' as API for creating temporaries Chisel and FIRRTL have long used signals with names beginning with an underscore as an API to specify that the name does not really matter. Tools like Verilator follow a similar convention and exclude signals with underscore names from waveform dumps by default. With the introduction of compiler-plugin prefixing in Chisel 3.4, the convention remained but was hard for users to use unless the unnnamed signal existed outside of any prefix domain. Notably, unnamed signals are most useful when creating wires inside of utility methods which almost always results in the signal ending up with a prefix. With this commit, Chisel explicitly recognizes signals whos val names start with an underscore and preserve that underscore regardless of any prefixing. Chisel will also ignore such underscores when generating prefixes based on the temporary signal, preventing accidental double underscores in the names of signals that are prefixed by the temporary. (cherry picked from commit bd94366290886f3489d58f88b9768c7c11fa2cb6) * Remove unused defaultPrefix argument from _computeName (cherry picked from commit ec178aa20a830df2c8c756b9e569709a59073554) # Conflicts: # core/src/main/scala/chisel3/Module.scala # core/src/main/scala/chisel3/experimental/hierarchy/ModuleClone.scala * Resolve backport conflicts * Waive false positive binary compatibility errors Co-authored-by: Jack Koenig <koenig@sifive.com>
Diffstat (limited to 'core/src/main/scala/chisel3/RawModule.scala')
-rw-r--r--core/src/main/scala/chisel3/RawModule.scala57
1 files changed, 39 insertions, 18 deletions
diff --git a/core/src/main/scala/chisel3/RawModule.scala b/core/src/main/scala/chisel3/RawModule.scala
index bd04fdc4..f2ce4c70 100644
--- a/core/src/main/scala/chisel3/RawModule.scala
+++ b/core/src/main/scala/chisel3/RawModule.scala
@@ -94,26 +94,26 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
id match {
case id: ModuleClone[_] => id.setRefAndPortsRef(_namespace) // special handling
case id: InstanceClone[_] => id.setAsInstanceRef()
- case id: BaseModule => id.forceName(None, default = id.desiredName, _namespace)
- case id: MemBase[_] => id.forceName(None, default = "MEM", _namespace)
- case id: stop.Stop => id.forceName(None, default = "stop", _namespace)
- case id: assert.Assert => id.forceName(None, default = "assert", _namespace)
- case id: assume.Assume => id.forceName(None, default = "assume", _namespace)
- case id: cover.Cover => id.forceName(None, default = "cover", _namespace)
- case id: printf.Printf => id.forceName(None, default = "printf", _namespace)
+ case id: BaseModule => id.forceName(default = id.desiredName, _namespace)
+ case id: MemBase[_] => id.forceName(default = "MEM", _namespace)
+ case id: stop.Stop => id.forceName(default = "stop", _namespace)
+ case id: assert.Assert => id.forceName(default = "assert", _namespace)
+ case id: assume.Assume => id.forceName(default = "assume", _namespace)
+ case id: cover.Cover => id.forceName(default = "cover", _namespace)
+ case id: printf.Printf => id.forceName(default = "printf", _namespace)
case id: Data =>
if (id.isSynthesizable) {
id.topBinding match {
case OpBinding(_, _) =>
- id.forceName(Some(""), default = "T", _namespace)
+ id.forceName(default = "_T", _namespace)
case MemoryPortBinding(_, _) =>
- id.forceName(None, default = "MPORT", _namespace)
+ id.forceName(default = "MPORT", _namespace)
case PortBinding(_) =>
- id.forceName(None, default = "PORT", _namespace)
+ id.forceName(default = "PORT", _namespace)
case RegBinding(_, _) =>
- id.forceName(None, default = "REG", _namespace)
+ id.forceName(default = "REG", _namespace)
case WireBinding(_, _) =>
- id.forceName(Some(""), default = "WIRE", _namespace)
+ id.forceName(default = "_WIRE", _namespace)
case _ => // don't name literals
}
} // else, don't name unbound types
@@ -189,18 +189,39 @@ package object internal {
/** Marker trait for modules that are not true modules */
private[chisel3] trait PseudoModule extends BaseModule
+ /* Check if a String name is a temporary name */
+ def isTemp(name: String): Boolean = name.nonEmpty && name.head == '_'
+
/** Creates a name String from a prefix and a seed
* @param prefix The prefix associated with the seed (must be in correct order, *not* reversed)
* @param seed The seed for computing the name (if available)
*/
def buildName(seed: String, prefix: Prefix): String = {
- val builder = new StringBuilder()
- prefix.foreach { p =>
- builder ++= p
- builder += '_'
+ // Don't bother copying the String if there's no prefix
+ if (prefix.isEmpty) {
+ seed
+ } else {
+ // Using Java's String builder to micro-optimize appending a String excluding 1st character
+ // for temporaries
+ val builder = new java.lang.StringBuilder()
+ // Starting with _ is the indicator of a temporary
+ val temp = isTemp(seed)
+ // Make sure the final result is also a temporary if this is a temporary
+ if (temp) {
+ builder.append('_')
+ }
+ prefix.foreach { p =>
+ builder.append(p)
+ builder.append('_')
+ }
+ if (temp) {
+ // We've moved the leading _ to the front, drop it here
+ builder.append(seed, 1, seed.length)
+ } else {
+ builder.append(seed)
+ }
+ builder.toString
}
- builder ++= seed
- builder.toString
}
// Private reflective version of "val io" to maintain Chisel.Module semantics without having