summaryrefslogtreecommitdiff
path: root/docs/src/cookbooks
diff options
context:
space:
mode:
authorJack2022-11-11 06:53:04 +0000
committerJack2022-11-11 06:53:04 +0000
commit3ce953c81f06519351c48277e3474b5720ec07ff (patch)
treeac79dcb80d0528c2ae86ca21da4cf424715ab645 /docs/src/cookbooks
parentadccde9998c91875e5490cff6d5822ffacc593ed (diff)
parentc8046636a25474be4c547c6fe9c6d742ea7b1d13 (diff)
Merge branch '3.5.x' into 3.5-release
Diffstat (limited to 'docs/src/cookbooks')
-rw-r--r--docs/src/cookbooks/cookbook.md162
-rw-r--r--docs/src/cookbooks/dataview.md35
-rw-r--r--docs/src/cookbooks/naming.md66
3 files changed, 192 insertions, 71 deletions
diff --git a/docs/src/cookbooks/cookbook.md b/docs/src/cookbooks/cookbook.md
index ab8e76d3..e7485e66 100644
--- a/docs/src/cookbooks/cookbook.md
+++ b/docs/src/cookbooks/cookbook.md
@@ -50,18 +50,23 @@ class MyBundle extends Bundle {
val bar = UInt(4.W)
}
-class Foo extends RawModule {
+class Foo extends Module {
val bundle = Wire(new MyBundle)
bundle.foo := 0xc.U
bundle.bar := 0x3.U
val uint = bundle.asUInt
- printf(p"$uint") // 195
+ printf(cf"$uint") // 195
// Test
assert(uint === 0xc3.U)
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
+
### How do I create a Bundle from a UInt?
Use the [`asTypeOf`](https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asTypeOf[T%3C:chisel3.Data](that:T):T) method to reinterpret the [`UInt`](https://www.chisel-lang.org/api/latest/chisel3/UInt.html) as the type of the [`Bundle`](https://www.chisel-lang.org/api/latest/chisel3/Bundle.html).
@@ -74,11 +79,11 @@ class MyBundle extends Bundle {
val bar = UInt(4.W)
}
-class Foo extends RawModule {
+class Foo extends Module {
val uint = 0xb4.U
val bundle = uint.asTypeOf(new MyBundle)
- printf(p"$bundle") // Bundle(foo -> 11, bar -> 4)
+ printf(cf"$bundle") // Bundle(foo -> 11, bar -> 4)
// Test
assert(bundle.foo === 0xb.U)
@@ -86,6 +91,11 @@ class Foo extends RawModule {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
+
### How can I tieoff a Bundle/Vec to 0?
You can use `asTypeOf` as above. If you don't want to worry about the type of the thing
@@ -100,7 +110,7 @@ class MyBundle extends Bundle {
val bar = Vec(4, UInt(1.W))
}
-class Foo(typ: MyBundle) extends RawModule {
+class Foo(typ: MyBundle) extends Module {
val bundleA = IO(Output(typ))
val bundleB = IO(Output(typ))
@@ -122,11 +132,11 @@ Use [`VecInit`](https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html) gi
```scala mdoc:silent:reset
import chisel3._
-class Foo extends RawModule {
+class Foo extends Module {
val uint = 0xc.U
val vec = VecInit(uint.asBools)
- printf(p"$vec") // Vec(0, 0, 1, 1)
+ printf(cf"$vec") // Vec(0, 0, 1, 1)
// Test
assert(vec(0) === false.B)
@@ -136,6 +146,11 @@ class Foo extends RawModule {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
+
### How do I create a UInt from a Vec of Bool?
Use the builtin function [`asUInt`](https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt():chisel3.UInt)
@@ -143,11 +158,11 @@ Use the builtin function [`asUInt`](https://www.chisel-lang.org/api/latest/chise
```scala mdoc:silent:reset
import chisel3._
-class Foo extends RawModule {
+class Foo extends Module {
val vec = VecInit(true.B, false.B, true.B, true.B)
val uint = vec.asUInt
- printf(p"$uint") // 13
+ printf(cf"$uint") // 13
// Test
// (remember leftmost Bool in Vec is low order bit)
@@ -156,6 +171,11 @@ class Foo extends RawModule {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
+
### How do I connect a subset of Bundle fields?
See the [DataView cookbook](dataview#how-do-i-connect-a-subset-of-bundle-fields).
@@ -220,7 +240,7 @@ For more information, the API Documentation for [`Vec`](https://www.chisel-lang.
```scala mdoc:silent:reset
import chisel3._
-class Foo extends RawModule {
+class Foo extends Module {
val regOfVec = Reg(Vec(4, UInt(32.W))) // Register of 32-bit UInts
regOfVec(0) := 123.U // Assignments to elements of the Vec
regOfVec(1) := 456.U
@@ -234,6 +254,10 @@ class Foo extends RawModule {
val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
### How do I partially reset an Aggregate Reg?
@@ -273,6 +297,12 @@ class MyModule2 extends Module {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new MyModule)
+getVerilogString(new MyModule2)
+```
+
## Bundles
@@ -467,6 +497,11 @@ class DetectTwoOnes extends Module {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new DetectTwoOnes)
+```
+
Note: the `is` statement can take multiple conditions e.g. `is (sTwo1s, sOne1) { ... }`.
### How do I unpack a value ("reverse concatenation") like in Verilog?
@@ -497,7 +532,7 @@ class MyBundle extends Bundle {
The easiest way to accomplish this in Chisel would be:
```scala mdoc:silent
-class Foo extends RawModule {
+class Foo extends Module {
val z = Wire(UInt(9.W))
z := DontCare // This is a dummy connection
val unpacked = z.asTypeOf(new MyBundle)
@@ -507,6 +542,11 @@ class Foo extends RawModule {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
+
If you **really** need to do this for a one-off case (Think thrice! It is likely you can better structure the code using bundles), then rocket-chip has a [Split utility](https://github.com/freechipsproject/rocket-chip/blob/723af5e6b69e07b5f94c46269a208a8d65e9d73b/src/main/scala/util/Misc.scala#L140) which can accomplish this.
### How do I do subword assignment (assign to some bits in a UInt)?
@@ -516,7 +556,7 @@ Below, the left-hand side connection to `io.out(0)` is not allowed.
```scala mdoc:silent:reset
import chisel3._
-import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
+import chisel3.stage.ChiselStage
class Foo extends Module {
val io = IO(new Bundle {
@@ -529,7 +569,7 @@ class Foo extends Module {
If you try to compile this, you will get an error.
```scala mdoc:crash
-(new ChiselStage).execute(Array("-X", "verilog"), Seq(new ChiselGeneratorAnnotation(() => new Foo)))
+getVerilogString(new Foo)
```
Chisel3 *does not support subword assignment*.
@@ -552,6 +592,10 @@ class Foo extends Module {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new Foo)
+```
### How do I create an optional I/O?
@@ -574,6 +618,11 @@ class ModuleWithOptionalIOs(flag: Boolean) extends Module {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new ModuleWithOptionalIOs(true))
+```
+
The following is an example where an entire `IO` is optional:
```scala mdoc:silent:reset
@@ -587,6 +636,11 @@ class ModuleWithOptionalIO(flag: Boolean) extends Module {
}
```
+```scala mdoc:invisible
+// Hidden but will make sure this actually compiles
+getVerilogString(new ModuleWithOptionalIO(true))
+```
+
### How do I create I/O without a prefix?
In most cases, you can simply call `IO` multiple times:
@@ -670,7 +724,9 @@ Use the compiler plugin, and check out the [Naming Cookbook](naming) if that sti
### How do I get Chisel to name the results of vector reads properly?
Currently, name information is lost when using dynamic indexing. For example:
-```scala mdoc:silent
+```scala mdoc:silent:reset
+import chisel3._
+
class Foo extends Module {
val io = IO(new Bundle {
val in = Input(Vec(4, Bool()))
@@ -686,26 +742,9 @@ class Foo extends Module {
```
The above code loses the `x` name, instead using `_GEN_3` (the other `_GEN_*` signals are expected).
-```verilog
-module Foo(
- input clock,
- input reset,
- input io_in_0,
- input io_in_1,
- input io_in_2,
- input io_in_3,
- input [1:0] io_idx,
- input io_en,
- output io_out
-);
- wire _GEN_1; // @[main.scala 15:13]
- wire _GEN_2; // @[main.scala 15:13]
- wire _GEN_3; // @[main.scala 15:13]
- assign _GEN_1 = 2'h1 == io_idx ? io_in_1 : io_in_0; // @[main.scala 15:13]
- assign _GEN_2 = 2'h2 == io_idx ? io_in_2 : _GEN_1; // @[main.scala 15:13]
- assign _GEN_3 = 2'h3 == io_idx ? io_in_3 : _GEN_2; // @[main.scala 15:13]
- assign io_out = _GEN_3 & io_en; // @[main.scala 16:10]
-endmodule
+
+```scala mdoc:verilog
+getVerilogString(new Foo)
```
This can be worked around by creating a wire and connecting the dynamic index to the wire:
@@ -713,28 +752,26 @@ This can be worked around by creating a wire and connecting the dynamic index to
val x = WireInit(io.in(io.idx))
```
+```scala mdoc:invisible
+class Foo2 extends Module {
+ val io = IO(new Bundle {
+ val in = Input(Vec(4, Bool()))
+ val idx = Input(UInt(2.W))
+ val en = Input(Bool())
+ val out = Output(Bool())
+ })
+
+ val x = WireInit(io.in(io.idx))
+ val y = x && io.en
+ io.out := y
+}
+```
+
Which produces:
-```verilog
-module Foo(
- input clock,
- input reset,
- input io_in_0,
- input io_in_1,
- input io_in_2,
- input io_in_3,
- input [1:0] io_idx,
- input io_en,
- output io_out
-);
- wire _GEN_1;
- wire _GEN_2;
- wire x;
- assign _GEN_1 = 2'h1 == io_idx ? io_in_1 : io_in_0;
- assign _GEN_2 = 2'h2 == io_idx ? io_in_2 : _GEN_1;
- assign x = 2'h3 == io_idx ? io_in_3 : _GEN_2;
- assign io_out = x & io_en; // @[main.scala 16:10]
-endmodule
+```scala mdoc:verilog
+getVerilogString(new Foo2)
```
+
### How can I dynamically set/parametrize the name of a module?
You can override the `desiredName` function. This works with normal Chisel modules and `BlackBox`es. Example:
@@ -754,18 +791,15 @@ class Salt extends Module {
val io = IO(new Bundle {})
val drink = Module(new Coffee)
override def desiredName = "SodiumMonochloride"
+
+ drink.io.I := 42.U
}
```
Elaborating the Chisel module `Salt` yields our "desired names" for `Salt` and `Coffee` in the output Verilog:
-```scala mdoc:silent
-import chisel3.stage.ChiselStage
-
-ChiselStage.emitVerilog(new Salt)
-```
```scala mdoc:verilog
-ChiselStage.emitVerilog(new Salt)
+getVerilogString(new Salt)
```
## Directionality
@@ -775,7 +809,9 @@ ChiselStage.emitVerilog(new Salt)
Given a bidirectional port like a `Decoupled`, you will get an error if you try to connect it directly
to a register:
-```scala mdoc:silent
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.stage.ChiselStage
import chisel3.util.Decoupled
class BadRegConnect extends Module {
val io = IO(new Bundle {
@@ -796,7 +832,9 @@ While there is no construct to "strip direction" in Chisel3, wrapping a type in
set all of the individual elements to output direction.
This will have the desired result when used to construct a Register:
-```scala mdoc:silent
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.stage.ChiselStage
import chisel3.util.Decoupled
class CoercedRegConnect extends Module {
val io = IO(new Bundle {
diff --git a/docs/src/cookbooks/dataview.md b/docs/src/cookbooks/dataview.md
index ed969ca1..f970cfe4 100644
--- a/docs/src/cookbooks/dataview.md
+++ b/docs/src/cookbooks/dataview.md
@@ -12,6 +12,7 @@ section: "chisel3"
* [How do I connect a subset of Bundle fields?](#how-do-i-connect-a-subset-of-bundle-fields)
* [How do I view a Bundle as a parent type (superclass)?](#how-do-i-view-a-bundle-as-a-parent-type-superclass)
* [How do I view a Bundle as a parent type when the parent type is abstract (like a trait)?](#how-do-i-view-a-bundle-as-a-parent-type-when-the-parent-type-is-abstract-like-a-trait)
+ * [How can I use `.viewAs` instead of `.viewAsSupertype(type)`?](#how-can-i-use-viewas-instead-of-viewassupertypetype)
## How do I view a Data as a UInt or vice versa?
@@ -177,3 +178,37 @@ As indicated in the comment, abstract methods must still be implemented.
This is the same that happens when one writes `new Bundle {}`,
the curly braces create a new concrete subclass; however, because `Bundle` has no abstract methods,
the contents of the body can be empty.
+
+### How can I use `.viewAs` instead of `.viewAsSupertype(type)`?
+
+While `viewAsSupertype` is helpful for one-off casts, the need to provide a type template object
+each time can be onerous.
+Because of the subtyping relationship, you can use `PartialDataView.supertype` to create a
+`DataView` from a Bundle type to a parent type by just providing the function to construct an
+instance of the parent type from an instance of the child type.
+The mapping of corresponding fields is automatically determined by Chisel to be the fields defined
+in the supertype.
+
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.experimental.dataview._
+
+class Foo(x: Int) extends Bundle {
+ val foo = UInt(x.W)
+}
+class Bar(val x: Int) extends Foo(x) {
+ val bar = UInt(x.W)
+}
+// Define a DataView without having to specify the mapping!
+implicit val view = PartialDataView.supertype[Bar, Foo](b => new Foo(b.x))
+
+class MyModule extends Module {
+ val foo = IO(Input(new Foo(8)))
+ val bar = IO(Output(new Bar(8)))
+ bar.viewAs[Foo] := foo // bar.foo := foo.foo
+ bar.bar := 123.U // all fields need to be connected
+}
+```
+```scala mdoc:verilog
+chisel3.stage.ChiselStage.emitVerilog(new MyModule)
+```
diff --git a/docs/src/cookbooks/naming.md b/docs/src/cookbooks/naming.md
index c7ccdd96..ff3cb892 100644
--- a/docs/src/cookbooks/naming.md
+++ b/docs/src/cookbooks/naming.md
@@ -6,20 +6,66 @@ section: "chisel3"
```scala mdoc:invisible
import chisel3._
-import chisel3.experimental.prefix
-import chisel3.experimental.noPrefix
import chisel3.stage.ChiselStage
```
# Naming Cookbook
+
### 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.
+See the next answer!
+
+### I have so many wires with the same name, like `x`, `x_1` and `x_2`. How can I make them easier to understand?
+
+Signals with `_T` names or names that Chisel has to uniquify
+often are intermediate values generated within loops, function calls, or `when` predicates.
+They can also be consumed by verification statements like `assert` or `prints`.
+In these cases, the compiler plugin often can't find a good prefix for the generated
+intermediate signals and can't name them at all or has to make up a unique name for them.
+
+We recommend you manually insert calls to `prefix` to clarify these cases:
+
+```scala mdoc:silent
+import chisel3.experimental.prefix
+class ExamplePrefix extends Module {
+
+ Seq.tabulate{2} {i =>
+ Seq.tabulate{2}{ j =>
+ prefix(s"loop_${i}_${j}"){
+ val x = WireInit((i*0x10+j).U(8.W))
+ dontTouch(x)
+ }
+ }
+ }
+}
+```
+```scala mdoc:verilog
+ChiselStage.emitVerilog(new ExamplePrefix)
+```
+### How can I get better names for code generated by `when` clauses?
+
+The `prefix` API can help with code inside `when` clauses:
+
+```scala mdoc:silent
+class ExampleWhenPrefix extends Module {
-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!
+ val in = IO(Input(UInt(4.W)))
+ val out = IO(Output(UInt(4.W)))
+
+ out := DontCare
+
+ Seq.tabulate{2}{ i =>
+ val j = i + 1
+ when (in === j.U) { prefix(s"clause_${j}"){
+ val foo = Wire(UInt(4.W))
+ foo := in +& j.U(4.W)
+ out := foo
+ }}
+ }
+}
+```
+```scala mdoc:verilog
+ChiselStage.emitVerilog(new ExampleWhenPrefix)
+```
### I still see _GEN signals, can this be fixed?
@@ -43,11 +89,13 @@ name collisions, which are what triggers all those annoying signal name bumps!
Use the `.suggestName` method, which is on all classes which subtype `Data`.
-### All this prefixing is annoying, how do I fix it?
+### How can I omit the prefix in certain parts of the code?
You can use the `noPrefix { ... }` to strip the prefix from all signals generated in that scope.
```scala mdoc
+import chisel3.experimental.noPrefix
+
class ExampleNoPrefix extends Module {
val in = IO(Input(UInt(2.W)))
val out = IO(Output(UInt()))