diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/src/explanations/annotations.md (renamed from docs/src/wiki-deprecated/annotations.md) | 22 | ||||
| -rw-r--r-- | docs/src/explanations/blackboxes.md (renamed from docs/src/wiki-deprecated/blackboxes.md) | 36 | ||||
| -rw-r--r-- | docs/src/explanations/bundles-and-vecs.md (renamed from docs/src/wiki-deprecated/bundles-and-vecs.md) | 129 |
3 files changed, 109 insertions, 78 deletions
diff --git a/docs/src/wiki-deprecated/annotations.md b/docs/src/explanations/annotations.md index 4b55d44d..19d24605 100644 --- a/docs/src/wiki-deprecated/annotations.md +++ b/docs/src/explanations/annotations.md @@ -20,24 +20,21 @@ import chisel3.internal.InstanceId import firrtl._ import firrtl.annotations.{Annotation, SingleTargetAnnotation} -import firrtl.annotations.{CircuitName, ComponentName, ModuleName, Named} +import firrtl.annotations.{CircuitTarget, ModuleTarget, InstanceTarget, ReferenceTarget, Target} ``` ### Define an `Annotation` and a `Transform` -First, define an `Annotation` that contains a string associated with a `Named` thing in the Chisel circuit. +First, define an `Annotation` that contains a string associated with a `Target` thing in the Chisel circuit. This `InfoAnnotation` extends [`SingleTargetAnnotation`](https://www.chisel-lang.org/api/firrtl/1.2.0/firrtl/annotations/SingleTargetAnnotation.html), an `Annotation` associated with *one* thing in a FIRRTL circuit: ```scala mdoc:silent /** An annotation that contains some string information */ -case class InfoAnnotation(target: Named, info: String) extends SingleTargetAnnotation[Named] { - def duplicate(newTarget: Named) = this.copy(target = newTarget) +case class InfoAnnotation(target: Target, info: String) extends SingleTargetAnnotation[Target] { + def duplicate(newTarget: Target) = this.copy(target = newTarget) } ``` -> Note: `Named` is currently deprecated in favor of the more specific `Target`. -> Currently, `Named` is still the advised approach for writing `Annotation`s. - Second, define a `Transform` that consumes this `InfoAnnotation`. This `InfoTransform` simply reads all annotations, prints any `InfoAnnotation`s it finds, and removes them. @@ -61,13 +58,16 @@ class InfoTransform() extends Transform with DependencyAPIMigration { println("Starting transform 'IdentityTransform'") val annotationsx = state.annotations.flatMap{ - case InfoAnnotation(a: CircuitName, info) => + case InfoAnnotation(a: CircuitTarget, info) => println(s" - Circuit '${a.serialize}' annotated with '$info'") None - case InfoAnnotation(a: ModuleName, info) => + case InfoAnnotation(a: ModuleTarget, info) => println(s" - Module '${a.serialize}' annotated with '$info'") None - case InfoAnnotation(a: ComponentName, info) => + case InfoAnnotation(a: InstanceTarget, info) => + println(s" - Instance '${a.serialize}' annotated with '$info'") + None + case InfoAnnotation(a: ReferenceTarget, info) => println(s" - Component '${a.serialize} annotated with '$info''") None case a => @@ -98,7 +98,7 @@ This annotator also mixes in the `RunFirrtlTransform` trait (abstract in the `tr object InfoAnnotator { def info(component: InstanceId, info: String): Unit = { annotate(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = InfoAnnotation(component.toNamed, info) + def toFirrtl: Annotation = InfoAnnotation(component.toTarget, info) def transformClass = classOf[InfoTransform] }) } diff --git a/docs/src/wiki-deprecated/blackboxes.md b/docs/src/explanations/blackboxes.md index 686c9719..7064c7bb 100644 --- a/docs/src/wiki-deprecated/blackboxes.md +++ b/docs/src/explanations/blackboxes.md @@ -15,8 +15,6 @@ Ports declared in the IO Bundle will be generated with the requested name (ie. n ### Parameterization -**This is an experimental feature and is subject to API change** - Verilog parameters can be passed as an argument to the BlackBox constructor. For example, consider instantiating a Xilinx differential clock buffer (IBUFDS) in a Chisel design: @@ -54,7 +52,8 @@ IBUFDS #(.DIFF_TERM("TRUE"), .IOSTANDARD("DEFAULT")) ibufds ( ``` ### Providing Implementations for Blackboxes -Chisel provides the following ways of delivering the code underlying the blackbox. Consider the following blackbox that adds two real numbers together. The numbers are represented in chisel3 as 64-bit unsigned integers. +Chisel provides the following ways of delivering the code underlying the blackbox. Consider the following blackbox that + adds two real numbers together. The numbers are represented in chisel3 as 64-bit unsigned integers. ```scala mdoc:silent:reset import chisel3._ class BlackBoxRealAdd extends BlackBox { @@ -80,7 +79,7 @@ endmodule ``` ### Blackboxes with Verilog in a Resource File -In order to deliver the verilog snippet above to the backend simulator, chisel3 provides the following tools based on the chisel/firrtl [annotation system](annotations.md). Add the trait ```HasBlackBoxResource``` to the declaration, and then call a function in the body to say where the system can find the verilog. The Module now looks like +In order to deliver the verilog snippet above to the backend simulator, chisel3 provides the following tools based on the chisel/firrtl [annotation system](../explanations/annotations.md). Add the trait ```HasBlackBoxResource``` to the declaration, and then call a function in the body to say where the system can find the verilog. The Module now looks like ```mdoc scala:silent:reset class BlackBoxRealAdd extends BlackBox with HasBlackBoxResource { val io = IO(new Bundle() { @@ -91,13 +90,17 @@ class BlackBoxRealAdd extends BlackBox with HasBlackBoxResource { setResource("/real_math.v") } ``` -The verilog snippet above gets put into a resource file names ```real_math.v```. What is a resource file? It comes from a java convention of keeping files in a project that are automatically included in library distributions. In a typical chisel3 project, see [chisel-template](https://github.com/ucb-bar/chisel-template), this would be a directory in the source hierarchy +The verilog snippet above gets put into a resource file names ```real_math.v```. What is a resource file? It comes from + a java convention of keeping files in a project that are automatically included in library distributions. In a typical + chisel3 project, see [chisel-template](https://github.com/ucb-bar/chisel-template), this would be a directory in the + source hierarchy ``` src/main/resources/real_math.v ``` ### Blackboxes with In-line Verilog -It is also possible to place this verilog directly in the scala source. Instead of ```HasBlackBoxResource``` use ```HasBlackBoxInline``` and instead of ```setResource``` use ```setInline```. The code will look like this. +It is also possible to place this verilog directly in the scala source. Instead of ```HasBlackBoxResource``` use + ```HasBlackBoxInline``` and instead of ```setResource``` use ```setInline```. The code will look like this. ```scala mdoc:silent:reset import chisel3._ import chisel3.util.HasBlackBoxInline @@ -123,9 +126,22 @@ class BlackBoxRealAdd extends BlackBox with HasBlackBoxInline { This technique will copy the inline verilog into the target directory under the name ```BlackBoxRealAdd.v``` ### Under the Hood -This mechanism of delivering verilog content to the testing backends is implemented via chisel/firrtl annotations. The two methods, inline and resource, are two kinds of annotations that are created via the ```setInline``` and ```setResource``` methods calls. Those annotations are passed through to the chisel-testers which in turn passes them on to firrtl. The default firrtl verilog compilers have a pass that detects the annotations and moves the files or inline test into the build directory. For each unique file added, the transform adds a line to a file black_box_verilog_files.f, this file is added to the command line constructed for verilator or vcs to inform them where to look. -The [dsptools project](https://github.com/ucb-bar/dsptools) is a good example of using this feature to build a real number simulation tester based on black boxes. +This mechanism of delivering verilog content to the testing backends is implemented via chisel/firrtl annotations. The +two methods, inline and resource, are two kinds of annotations that are created via the ```setInline``` and +```setResource``` methods calls. Those annotations are passed through to the chisel-testers which in turn passes them +on to firrtl. The default firrtl verilog compilers have a pass that detects the annotations and moves the files or +inline test into the build directory. For each unique file added, the transform adds a line to a file +black_box_verilog_files.f, this file is added to the command line constructed for verilator or vcs to inform them where +to look. +The [dsptools project](https://github.com/ucb-bar/dsptools) is a good example of using this feature to build a real +number simulation tester based on black boxes. ### The interpreter -The [firrtl interpreter](https://github.com/ucb-bar/firrtl-interpreter) uses a separate system that allows users to construct scala implementations of the black boxes. The scala implementation code built into a BlackBoxFactory which is passed down to the interpreter by the execution harness. The interpreter is a scala simulation tester. Once again the dsptools project uses this mechanism and is a good place to look at it. -> It is planned that the BlackBoxFactory will be replaced by integration with the annotation based blackbox methods stuff soon. + +***Note that the FIRRTL Interpreter is deprecated. Please use Treadle, the new Chisel/FIRRTL simulator*** +The [firrtl interpreter](https://github.com/ucb-bar/firrtl-interpreter) uses a separate system that allows users to +construct scala implementations of the black boxes. The scala implementation code built into a BlackBoxFactory which is +passed down to the interpreter by the execution harness. The interpreter is a scala simulation tester. Once again the +dsptools project uses this mechanism and is a good place to look at it. +> It is planned that the BlackBoxFactory will be replaced by integration with the annotation based blackbox methods +>stuff soon. diff --git a/docs/src/wiki-deprecated/bundles-and-vecs.md b/docs/src/explanations/bundles-and-vecs.md index 0a0e2a43..4b1eb196 100644 --- a/docs/src/wiki-deprecated/bundles-and-vecs.md +++ b/docs/src/explanations/bundles-and-vecs.md @@ -3,40 +3,54 @@ layout: docs title: "Bundles and Vecs" section: "chisel3" --- +``` + +``` + `Bundle` and `Vec` are classes that allow the user to expand the set of Chisel datatypes with aggregates of other types. -Bundles group together several named fields of potentially different types into a coherent unit, much like a `struct` in C. Users define their own bundles by defining a class as a subclass of `Bundle`. -```scala +Bundles group together several named fields of potentially different types into a coherent unit, much like a `struct` in +C. Users define their own bundles by defining a class as a subclass of `Bundle`. +```scala mdoc:silent +import chisel3._ class MyFloat extends Bundle { val sign = Bool() val exponent = UInt(8.W) val significand = UInt(23.W) } -val x = Wire(new MyFloat) -val xs = x.sign +class ModuleWithFloatWire extends RawModule { + val x = Wire(new MyFloat) + val xs = x.sign +} ``` -> Currently, there is no way to create a bundle literal like ```8.U``` for ```UInt```s. Therefore, in order to create literals for bundles, we must declare a [[wire|Combinational-Circuits#wires]] of that bundle type, and then assign values to it. We are working on a way to declare bundle literals without requiring the creation of a Wire node and assigning to it. - -```scala -// Floating point constant. -val floatConst = Wire(new MyFloat) -floatConst.sign := true.B -floatConst.exponent := 10.U -floatConst.significand := 128.U +> Currently, there is no way to create a bundle literal like ```8.U``` for ```UInt```s. Therefore, in order to create +>literals for bundles, we must declare a [[wire|Combinational-Circuits#wires]] of that bundle type, and then assign +>values to it. We are working on a way to declare bundle literals without requiring the creation of a Wire node and +>assigning to it. + +```scala mdoc:silent +class ModuleWithFloatConstant extends RawModule { + // Floating point constant. + val floatConst = Wire(new MyFloat) + floatConst.sign := true.B + floatConst.exponent := 10.U + floatConst.significand := 128.U +} ``` A Scala convention is to capitalize the name of new classes and we suggest you follow that convention in Chisel too. -Vecs create an indexable vector of elements, and are constructed as -follows: -```scala -// Vector of 5 23-bit signed integers. -val myVec = Wire(Vec(5, SInt(23.W))) +Vecs create an indexable vector of elements, and are constructed as follows: +```scala mdoc:silent +class ModuleWithVec extends RawModule { + // Vector of 5 23-bit signed integers. + val myVec = Wire(Vec(5, SInt(23.W))) -// Connect to one element of vector. -val reg3 = myVec(3) + // Connect to one element of vector. + val reg3 = myVec(3) +} ``` (Note that we specify the number followed by the type of the `Vec` elements. We also specifiy the width of the `SInt`) @@ -49,7 +63,7 @@ superclass, `Data`. Every object that ultimately inherits from Bundles and Vecs can be arbitrarily nested to build complex data structures: -```scala +```scala mdoc:silent class BigBundle extends Bundle { // Vector of 5 23-bit signed integers. val myVec = Vec(5, SInt(23.W)) @@ -63,53 +77,48 @@ Note that the builtin Chisel primitive and aggregate classes do not require the `new` when creating an instance, whereas new user datatypes will. A Scala `apply` constructor can be defined so that a user datatype also does not require `new`, as described in -[Function Constructor](functional-module-creation.md). +[Function Constructor](../wiki-deprecated/functional-module-creation.md). ### Flipping Bundles The `Flipped()` function recursively flips all elements in a Bundle/Record. This is very useful for building bidirectional interfaces that connect to each other (e.g. `Decoupled`). See below for an example. -```scala -import chisel3.experimental.RawModule -class MyBundle extends Bundle { +```scala mdoc:silent +class ABBundle extends Bundle { val a = Input(Bool()) val b = Output(Bool()) } -class MyModule extends RawModule { +class MyFlippedModule extends RawModule { // Normal instantiation of the bundle // 'a' is an Input and 'b' is an Output - val normalBundle = IO(new MyBundle) + val normalBundle = IO(new ABBundle) normalBundle.b := normalBundle.a // Flipped recursively flips the direction of all Bundle fields // Now 'a' is an Output and 'b' is an Input - val flippedBundle = IO(Flipped(new MyBundle)) + val flippedBundle = IO(Flipped(new ABBundle)) flippedBundle.a := flippedBundle.b } ``` This generates the following Verilog: -```verilog -module MyModule( // @[:@3.2] - input normalBundle_a, // @[:@4.4] - output normalBundle_b, // @[:@4.4] - output flippedBundle_a, // @[:@5.4] - input flippedBundle_b // @[:@5.4] -); - assign normalBundle_b = normalBundle_a; - assign flippedBundle_a = flippedBundle_b; -endmodule +```scala mdoc +import chisel3.stage.ChiselStage + +println(ChiselStage.emitVerilog(new MyFlippedModule())) ``` ### MixedVec (Chisel 3.2+) -All elements of a `Vec` must be of the same type. If we want to create a Vec where the elements have different types, we can use a MixedVec: +All elements of a `Vec` must be of the same type. If we want to create a Vec where the elements have different types, we +can use a MixedVec: -```scala -class MyModule extends Module { +```scala mdoc:silent +import chisel3.util.MixedVec +class ModuleMixedVec extends Module { val io = IO(new Bundle { val x = Input(UInt(3.W)) val y = Input(UInt(10.W)) @@ -122,8 +131,8 @@ class MyModule extends Module { We can also programmatically create the types in a MixedVec: -```scala -class MyModule(x: Int, y: Int) extends Module { +```scala mdoc:silent +class ModuleProgrammaticMixedVec(x: Int, y: Int) extends Module { val io = IO(new Bundle { val vec = Input(MixedVec((x to y) map { i => UInt(i.W) })) // ... @@ -134,12 +143,16 @@ class MyModule(x: Int, y: Int) extends Module { ### A note on `cloneType` -Since Chisel is built on top of Scala and the JVM, it needs to know how to construct copies of bundles for various purposes (creating wires, IOs, etc). If you have a parametrized bundle and Chisel can't automatically figure out how to clone your bundle, you will need to create a custom `cloneType` method in your bundle. Most of the time, this is as simple as `override def cloneType = (new YourBundleHere(...)).asInstanceOf[this.type]`. +Since Chisel is built on top of Scala and the JVM, it needs to know how to construct copies of bundles for various +purposes (creating wires, IOs, etc). If you have a parametrized bundle and Chisel can't automatically figure out how to +clone your bundle, you will need to create a custom `cloneType` method in your bundle. Most of the time, this is as +simple as `override def cloneType = (new YourBundleHere(...)).asInstanceOf[this.type]`. -Note that in the vast majority of cases, **this is not required** as Chisel can figure out how to clone most bundles automatically. +Note that in the vast majority of cases, **this is not required** as Chisel can figure out how to clone most bundles +automatically. Here is an example of a parametrized bundle (`ExampleBundle`) that features a custom `cloneType`. -```scala +```scala mdoc:silent class ExampleBundle(a: Int, b: Int) extends Bundle { val foo = UInt(a.W) val bar = UInt(b.W) @@ -170,31 +183,33 @@ class Top extends Module { Generally cloneType can be automatically defined if all arguments to the Bundle are vals e.g. -```scala -class MyBundle(val width: Int) extends Bundle { - val field = UInt(width.W) +```scala mdoc:silent +class MyCloneTypeBundle(val bitwidth: Int) extends Bundle { + val field = UInt(bitwidth.W) // ... } ``` -The only caveat is if you are passing something of type Data as a "generator" parameter, in which case you should make it a `private val`. +The only caveat is if you are passing something of type Data as a "generator" parameter, in which case you should make +it a `private val`. -For example, consider the following Bundle: +For example, consider the following Bundle. Because its `gen` variable is not a `private val`, the user has to +explicitly define the `cloneType` method. -```scala -class RegisterWriteIO[T <: Data](gen: T) extends Bundle { +```scala mdoc:silent +import chisel3.util.{Decoupled, Irrevocable} +class RegisterWriteIOExplicitCloneType[T <: Data](gen: T) extends Bundle { val request = Flipped(Decoupled(gen)) - val response = Irrevocable(Bool()) // ignore .bits - - override def cloneType = new RegisterWriteIO(gen).asInstanceOf[this.type] + val response = Irrevocable(Bool()) + override def cloneType = new RegisterWriteIOExplicitCloneType(gen).asInstanceOf[this.type] } ``` We can make this this infer cloneType by making `gen` private since it is a "type parameter": -```scala +```scala mdoc:silent class RegisterWriteIO[T <: Data](private val gen: T) extends Bundle { val request = Flipped(Decoupled(gen)) - val response = Irrevocable(Bool()) // ignore .bits + val response = Irrevocable(Bool()) } ``` |
