-
Notifications
You must be signed in to change notification settings - Fork 603
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documentation and minor plugin changes. (#1573)
* Added documentation. Bugfix in plugin. Moved plugin APIs to separate package * Revert reg naming behavior (omit underscore) * Added documentation and a test * Addressed reviewer feedback.
- Loading branch information
Showing
9 changed files
with
343 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// See LICENSE for license details. | ||
|
||
package chisel3.internal | ||
|
||
package object plugin { | ||
/** Used by Chisel's compiler plugin to automatically name signals | ||
* DO NOT USE in your normal Chisel code!!! | ||
* | ||
* @param name The name to use | ||
* @param nameMe The thing to be named | ||
* @tparam T The type of the thing to be named | ||
* @return The thing, but now named | ||
*/ | ||
def autoNameRecursively[T <: Any](name: String, nameMe: T): T = { | ||
chisel3.internal.Builder.nameRecursively( | ||
name.replace(" ", ""), | ||
nameMe, | ||
(id: chisel3.internal.HasId, n: String) => id.autoSeed(n) | ||
) | ||
nameMe | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<plugin> | ||
<name>chiselplugin</name> | ||
<classname>chisel3.plugin.ChiselPlugin</classname> | ||
<classname>chisel3.internal.plugin.ChiselPlugin</classname> | ||
</plugin> |
Oops, something went wrong.