summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/src/cookbooks/naming.md62
-rw-r--r--docs/src/explanations/naming.md229
2 files changed, 291 insertions, 0 deletions
diff --git a/docs/src/cookbooks/naming.md b/docs/src/cookbooks/naming.md
new file mode 100644
index 00000000..5f57826f
--- /dev/null
+++ b/docs/src/cookbooks/naming.md
@@ -0,0 +1,62 @@
+---
+layout: docs
+title: "Naming Cookbook"
+section: "chisel3"
+---
+
+```scala mdoc:invisible
+import chisel3.internal.plugin._
+import chisel3._
+import chisel3.experimental.prefix
+import chisel3.experimental.noPrefix
+import chisel3.stage.ChiselStage
+```
+
+### I still have _T signals, can this be fixed?
+
+First check - is the compiler plugin properly enabled? Scalac plugins are enabled via the scalac option
+`-Xplugin:<path/to/jar>`. You can check which compiler plugins are enabled by running `show Compile / scalacOptions` in
+the sbt prompt.
+
+If the plugin is enabled, these signals could be intermediate values which are consumed by either assertions or when
+predicates. In these cases, the compiler plugin often can't find a good prefix for the generated intermediate signals.
+We recommend you manually insert calls to `prefix` to fix these cases. We did this to Rocket Chip and saw huge benefits!
+
+### I still see _GEN signals, can this be fixed?
+
+`_GEN` signals are usually generated from the FIRRTL compiler, rather than the Chisel library. We are working on
+renaming these signals with more context-dependent names, but it is a work in progress. Thanks for caring!
+
+### My module names are super unstable - I change one thing and Queue_1 becomes Queue_42. Help!
+
+This is the infamous `Queue` instability problem. In general, these cases are best solved at the source - the module
+itself! If you overwrite `desiredName` to include parameter information (see the
+[explanation](../explanations/naming.md#set-a-module-name) for more info), then this can avoid this problem permanantly.
+We've done this with some Chisel utilities with great results!
+
+### I want to add some hardware or assertions, but each time I do all the signal names get bumped!
+
+This is the classic "ECO" problem, and we provide descriptions in [explanation](../explanations/naming.md). In short,
+we recommend wrapping all additional logic in a prefix scope, which enables a unique namespace. This should prevent
+name collisions, which are what triggers all those annoying signal name bumps!
+
+### I want to force a signal (or instance) name to something, how do I do that?
+
+Use the `.suggestName` method, which is on all classes which subtype 'Data'.
+
+### All this prefixing is annoying, how do I fix it?
+
+You can use the `noPrefix { ... }` to strip the prefix from all signals generated in that scope.
+
+```scala mdoc
+class ExampleNoPrefix extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = noPrefix { in + in + in }
+
+ out := add
+}
+
+println(ChiselStage.emitVerilog(new Example7))
+```
diff --git a/docs/src/explanations/naming.md b/docs/src/explanations/naming.md
new file mode 100644
index 00000000..69870813
--- /dev/null
+++ b/docs/src/explanations/naming.md
@@ -0,0 +1,229 @@
+---
+layout: docs
+title: "Naming"
+section: "chisel3"
+---
+
+Historically, Chisel has had trouble reliably capturing the names of signals. The reasons for this are due to (1)
+primarily relying on reflection to find names, (2) using `@chiselName` macro which had unreliable behavior.
+
+Chisel 3.4 introduced a custom Scala compiler plugin which enables reliabe and automatic capturing of signal names, when
+they are declared. In addition, this release includes prolific use of a new prefixing API which enables more stable
+naming of signals programmatically generated from function calls.
+
+This document explains how naming now works in Chisel for signal and module names. For cookbook examples on how to fix
+systemic name-stability issues, please refer to the naming [cookbook](../cookbooks/naming.md).
+
+### Compiler Plugin
+
+```scala mdoc
+import chisel3.internal.plugin._
+import chisel3._
+import chisel3.experimental.prefix
+import chisel3.experimental.noPrefix
+import chisel3.stage.ChiselStage
+```
+
+With the release of Chisel 3.4, users should add the following line to their build.sbt settings to get the improved
+naming:
+
+```scala
+addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full)
+```
+
+This plugin will run after the 'typer' phase of the Scala compiler. It looks for any user code which is of the form
+`val x = y`, where `x` is of type `chisel3.Data`, `chisel3.MemBase`, or `chisel3.experimental.BaseModule`. For each
+line which fits this criteria, it rewrites that line. In the following examples, the commented line is the what the
+line above is rewritten to.
+
+If the line is within a bundle declaration or is a module instantiation, it is rewritten to replace the right hand
+side with a call to `autoNameRecursively`, which names the signal/module.
+
+```scala mdoc
+class MyBundle extends Bundle {
+ val foo = Input(UInt(3.W))
+ // val foo = autoNameRecursively("foo", Input(UInt(3.W)))
+}
+class Example1 extends MultiIOModule {
+ val io = IO(new MyBundle())
+ // val io = autoNameRecursively("io", IO(new MyBundle()))
+}
+println(ChiselStage.emitVerilog(new Example1))
+```
+
+Otherwise, it is rewritten to also include the name as a prefix to any signals generated while executing the right-hand-
+side of the val declaration:
+
+```scala mdoc
+class Example2 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ // val in = autoNameRecursively("in", prefix("in")(IO(Input(UInt(2.W)))))
+
+ val out = IO(Output(UInt(2.W)))
+ // val out = autoNameRecursively("out", prefix("out")(IO(Output(UInt(2.W)))))
+
+ def inXin() = in * in
+
+ val add = 3.U + inXin()
+ // val add = autoNameRecursively("add", prefix("add")(3.U + inXin()))
+ // Note that the intermediate result of the multiplication is prefixed with `add`
+
+ out := add + 1.U
+}
+
+println(ChiselStage.emitVerilog(new Example2))
+```
+
+Note that the naming also works if the hardware type is nested in an `Option` or a subtype of `Iterable`:
+
+```scala mdoc
+class Example3 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ // val in = autoNameRecursively("in", prefix("in")(IO(Input(UInt(2.W)))))
+
+ val out = IO(Output(UInt()))
+ // val out = autoNameRecursively("out", prefix("out")(IO(Output(UInt(2.W)))))
+
+ def inXin() = in * in
+
+ val opt = Some(3.U + inXin())
+ // Note that the intermediate result of the inXin() is prefixed with `opt`:
+ // val opt = autoNameRecursively("opt", prefix("opt")(Some(3.U + inXin())))
+
+ out := opt.get + 1.U
+}
+
+println(ChiselStage.emitVerilog(new Example3))
+```
+
+### Prefixing
+
+As shown above, the compiler plugin automatically attempts to prefix some of your signals for you. However, you as a
+user can also add your own prefixes. This is especially for ECO-type fixes where you need to add some logic to a module
+but don't want to influence other names in the module.
+
+In the following example, we prefix additional logic with "ECO", where `Example4` is pre-ECO and `Example5` is post-ECO:
+
+```scala mdoc
+class Example4 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = in + in + in
+
+ out := add + 1.U
+}
+
+class Example5 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = in + in + in
+
+ out := prefix("ECO") { add + 1.U + in }
+}
+
+println(ChiselStage.emitVerilog(new Example4))
+println(ChiselStage.emitVerilog(new Example5))
+
+```
+
+Also note that the prefixes append to each other (including the prefix generated by the compiler plugin):
+
+```scala mdoc
+class Example6 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = prefix("foo") { in + in + in }
+
+ out := add
+}
+
+println(ChiselStage.emitVerilog(new Example6))
+```
+
+Sometimes you may want to disable the prefixing. This might occur if you are writing a library function and
+don't want the prefixing behavior. In this case, you can use the `noPrefix` object:
+
+```scala mdoc
+class Example7 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = noPrefix { in + in + in }
+
+ out := add
+}
+
+println(ChiselStage.emitVerilog(new Example7))
+```
+
+### Suggest a Signal's Name (or the instance name of a Module)
+
+If you want to specify the name of a signal, you can always use the `.suggestName` API. Please note that the suggested
+name will still be prefixed (including by the plugin). You can always use the `noPrefix` object to strip this.
+
+```scala mdoc
+class Example8 extends MultiIOModule {
+ val in = IO(Input(UInt(2.W)))
+ val out = IO(Output(UInt()))
+
+ val add = (in + (in + in).suggestName("foo"))
+
+ out := add
+}
+
+println(ChiselStage.emitVerilog(new Example8))
+```
+
+### Set a Module Name
+
+If you want to specify the module's name (not the instance name of a module), you can always override the `desiredName`
+value. Note that you can parameterize the name by the module's parameters. This is an excellent way to make your module
+names more stable and is highly recommended to do.
+
+```scala mdoc
+class Example9(width: Int) extends MultiIOModule {
+ override val desiredName = s"EXAMPLE9WITHWIDTH$width"
+ val in = IO(Input(UInt(width.W)))
+ val out = IO(Output(UInt()))
+
+ val add = (in + (in + in).suggestName("foo"))
+
+ out := add
+}
+
+println(ChiselStage.emitVerilog(new Example9(8)))
+println(ChiselStage.emitVerilog(new Example9(1)))
+```
+
+### Reflection Naming
+
+Regardless of whether the compiler plugin is enabled or not, after Chisel constructs a module, it attempts to name all
+members of the Module. This will name all vals which are fields of the module class, but it will not name any
+vals in nested functions or scopes.
+
+If the plugin successfully names a signal, the reflection naming will do nothing. We plan to deprecate all reflection
+naming in a future Chisel release, but are leaving it to allow the plugin naming to be optional (but recommended).
+
+For example, the signals in the following module are in a nested scope; the plugin successfully names them, but
+reflection naming cannot:
+
+```scala mdoc
+class Example10 extends MultiIOModule {
+ {
+ val in = IO(Input(UInt(width.W)))
+ val out = IO(Output(UInt()))
+
+ val add = in + in
+
+ out := add
+ }
+}
+```
+
+### @chiselName
+
+This macro is no longer recommended as its functionality is entirely replaced by the compiler plugin. Feel free to
+delete from your Chisel designs! \ No newline at end of file