summaryrefslogtreecommitdiff
path: root/docs/src/cookbooks
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/cookbooks')
-rw-r--r--docs/src/cookbooks/cookbook.md9
-rw-r--r--docs/src/cookbooks/dataview.md179
2 files changed, 186 insertions, 2 deletions
diff --git a/docs/src/cookbooks/cookbook.md b/docs/src/cookbooks/cookbook.md
index 1b47ad14..f033c285 100644
--- a/docs/src/cookbooks/cookbook.md
+++ b/docs/src/cookbooks/cookbook.md
@@ -9,12 +9,13 @@ section: "chisel3"
Please note that these examples make use of [Chisel's scala-style printing](../explanations/printing#scala-style).
-* Converting Chisel Types to/from UInt
+* Type Conversions
* [How do I create a UInt from an instance of a Bundle?](#how-do-i-create-a-uint-from-an-instance-of-a-bundle)
* [How do I create a Bundle from a UInt?](#how-do-i-create-a-bundle-from-a-uint)
* [How can I tieoff a Bundle/Vec to 0?](#how-can-i-tieoff-a-bundlevec-to-0)
* [How do I create a Vec of Bools from a UInt?](#how-do-i-create-a-vec-of-bools-from-a-uint)
* [How do I create a UInt from a Vec of Bool?](#how-do-i-create-a-uint-from-a-vec-of-bool)
+ * [How do I connect a subset of Bundle fields?](#how-do-i-connect-a-subset-of-bundle-fields)
* Vectors and Registers
* [How do I create a Vector of Registers?](#how-do-i-create-a-vector-of-registers)
* [How do I create a Reg of type Vec?](#how-do-i-create-a-reg-of-type-vec)
@@ -27,7 +28,7 @@ Please note that these examples make use of [Chisel's scala-style printing](../e
* [How do I get Chisel to name the results of vector reads properly?](#how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly)
* [How can I dynamically set/parametrize the name of a module?](#how-can-i-dynamically-setparametrize-the-name-of-a-module)
-## Converting Chisel Types to/from UInt
+## Type Conversions
### How do I create a UInt from an instance of a Bundle?
@@ -148,6 +149,10 @@ class Foo extends RawModule {
}
```
+### How do I connect a subset of Bundle fields?
+
+See the [DataView cookbook](dataview#how-do-i-connect-a-subset-of-bundle-fields).
+
## Vectors and Registers
### How do I create a Vector of Registers?
diff --git a/docs/src/cookbooks/dataview.md b/docs/src/cookbooks/dataview.md
new file mode 100644
index 00000000..ed969ca1
--- /dev/null
+++ b/docs/src/cookbooks/dataview.md
@@ -0,0 +1,179 @@
+---
+layout: docs
+title: "DataView Cookbook"
+section: "chisel3"
+---
+
+# DataView Cookbook
+
+* [How do I view a Data as a UInt or vice versa?](#how-do-i-view-a-data-as-a-uint-or-vice-versa)
+* [How do I create a DataView for a Bundle has a type parameter?](#how-do-i-create-a-dataview-for-a-bundle-has-a-type-parameter)
+* [How do I create a DataView for a Bundle with optional fields?](#how-do-i-create-a-dataview-for-a-bundle-with-optional-fields)
+* [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 do I view a Data as a UInt or vice versa?
+
+Subword viewing (using concatenations or bit extractions in `DataViews`) is not yet supported.
+We intend to implement this in the future, but for the time being, use regular casts
+(`.asUInt` and `.asTypeOf`).
+
+## How do I create a DataView for a Bundle has a type parameter?
+
+Instead of using a `val`, use a `def` which can have type parameters:
+
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.experimental.dataview._
+
+class Foo[T <: Data](val foo: T) extends Bundle
+class Bar[T <: Data](val bar: T) extends Bundle
+
+object Foo {
+ implicit def view[T <: Data]: DataView[Foo[T], Bar[T]] = {
+ DataView(f => new Bar(f.foo.cloneType), _.foo -> _.bar)
+ // .cloneType is necessary because the f passed to this function will be bound hardware
+ }
+}
+```
+
+```scala mdoc:invisible
+// Make sure this works during elaboration, not part of doc
+class MyModule extends RawModule {
+ val in = IO(Input(new Foo(UInt(8.W))))
+ val out = IO(Output(new Bar(UInt(8.W))))
+ out := in.viewAs[Bar[UInt]]
+}
+chisel3.stage.ChiselStage.emitVerilog(new MyModule)
+```
+If you think about type parameterized classes as really being a family of different classes
+(one for each type parameter), you can think about the `implicit def` as a generator of `DataViews`
+for each type parameter.
+
+## How do I create a DataView for a Bundle with optional fields?
+
+Instead of using the default `DataView` apply method, use `DataView.mapping`:
+
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.experimental.dataview._
+
+class Foo(val w: Option[Int]) extends Bundle {
+ val foo = UInt(8.W)
+ val opt = w.map(x => UInt(x.W))
+}
+class Bar(val w: Option[Int]) extends Bundle {
+ val bar = UInt(8.W)
+ val opt = w.map(x => UInt(x.W))
+}
+
+object Foo {
+ implicit val view: DataView[Foo, Bar] =
+ DataView.mapping(
+ // First argument is always the function to make the view from the target
+ f => new Bar(f.w),
+ // Now instead of a varargs of tuples of individual mappings, we have a single function that
+ // takes a target and a view and returns an Iterable of tuple
+ (f, b) => List(f.foo -> b.bar) ++ f.opt.map(_ -> b.opt.get)
+ // ^ Note that we can append options since they are Iterable!
+
+ )
+}
+```
+
+```scala mdoc:invisible
+// Make sure this works during elaboration, not part of doc
+class MyModule extends RawModule {
+ val in = IO(Input(new Foo(Some(8))))
+ val out = IO(Output(new Bar(Some(8))))
+ out := in.viewAs[Bar]
+}
+chisel3.stage.ChiselStage.emitVerilog(new MyModule)
+```
+
+## How do I connect a subset of Bundle fields?
+
+Chisel 3 requires types to match exactly for connections.
+DataView provides a mechanism for "viewing" one `Bundle` object as if it were the type of another,
+which allows them to be connected.
+
+### How do I view a Bundle as a parent type (superclass)?
+
+For viewing `Bundles` as the type of the parent, it is as simple as using `viewAsSupertype` and providing a
+template object of the parent type:
+
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.experimental.dataview._
+
+class Foo extends Bundle {
+ val foo = UInt(8.W)
+}
+class Bar extends Foo {
+ val bar = UInt(8.W)
+}
+class MyModule extends Module {
+ val foo = IO(Input(new Foo))
+ val bar = IO(Output(new Bar))
+ bar.viewAsSupertype(new 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)
+```
+
+### How do I view a Bundle as a parent type when the parent type is abstract (like a trait)?
+
+Given the following `Bundles` that share a common `trait`:
+
+```scala mdoc:silent:reset
+import chisel3._
+import chisel3.experimental.dataview._
+
+trait Super extends Bundle {
+ def bitwidth: Int
+ val a = UInt(bitwidth.W)
+}
+class Foo(val bitwidth: Int) extends Super {
+ val foo = UInt(8.W)
+}
+class Bar(val bitwidth: Int) extends Super {
+ val bar = UInt(8.W)
+}
+```
+
+`Foo` and `Bar` cannot be connected directly, but they could be connected by viewing them both as if
+they were instances of their common supertype, `Super`.
+A straightforward approach might run into an issue like the following:
+
+```scala mdoc:fail
+class MyModule extends Module {
+ val foo = IO(Input(new Foo(8)))
+ val bar = IO(Output(new Bar(8)))
+ bar.viewAsSupertype(new Super) := foo.viewAsSupertype(new Super)
+}
+```
+
+The problem is that `viewAs` requires an object to use as a type template (so that it can be cloned),
+but `traits` are abstract and cannot be instantiated.
+The solution is to create an instance of an _anonymous class_ and use that object as the argument to `viewAs`.
+We can do this like so:
+
+```scala mdoc:silent
+class MyModule extends Module {
+ val foo = IO(Input(new Foo(8)))
+ val bar = IO(Output(new Bar(8)))
+ val tpe = new Super { // Adding curly braces creates an anonymous class
+ def bitwidth = 8 // We must implement any abstract methods
+ }
+ bar.viewAsSupertype(tpe) := foo.viewAsSupertype(tpe)
+}
+```
+By adding curly braces after the name of the trait, we're telling Scala to create a new concrete
+subclass of the trait, and create an instance of it.
+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.