Skip to content

Commit

Permalink
Add custom mdoc modifier for emitted Verilog (#1666)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkoenig authored Nov 11, 2020
1 parent 9f1d6cb commit e6192ea
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 35 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ generated/
.idea_modules/
.project
target/
docs-target/
*.iml
*.swp
*.fir
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chisel3.docs.VerilogMdocModifier
34 changes: 34 additions & 0 deletions docs-target/src/main/scala/chisel3/docs/VerilogMdocModifier.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package chisel3.docs

import java.nio.file.Files
import java.nio.file.Paths
import mdoc._
import scala.meta.inputs.Position

/** Custom modifier for rendering Chisel-generated Verilog
*
* See chisel3/docs/README.md for use
*/
class VerilogMdocModifier extends PostModifier {
val name = "verilog"
def process(ctx: PostModifierContext): String = {
val result =
ctx.variables.foldLeft(Option("")) {
case (Some(acc), variable) if variable.staticType == "String" =>
Some(acc + variable.runtimeValue)
case (Some(_), badVar) =>
ctx.reporter.error(
badVar.pos,
s"""type mismatch:
|expected: String
|received: ${badVar.runtimeValue}""".stripMargin
)
None
case (None, _) => None
}
result match {
case Some(content) => s"```verilog\n$content```"
case None => ""
}
}
}
50 changes: 47 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# chisel3/docs/README.md
# Chisel 3 Documentation

This directory contains documentation on the code within this repository.
Documents can either be written directly in markdown, or
Expand Down Expand Up @@ -26,8 +26,52 @@ Our documentation strategy for this repository is as follows:
* Old documentation is contained in the `src/wiki-deprecated` directory and is being incrementally converted to these
categories.

To build the documentation, run `docs/mdoc` from SBT in the root directory. The generated documents
This documentation is hosted on the Chisel [website](https://www.chisel-lang.org).

## mdoc

### Basic Use

To build the documentation, run `docs/mdoc` via SBT in the root directory. The generated documents
will appear in the `docs/generated` folder. To iterate on the documentation, you can run `docs/mdoc --watch`. For
more `mdoc` instructions you can visit their [website](https://scalameta.org/mdoc/).

This documentation is hosted on the Chisel [website](https://www.chisel-lang.org).
### Custom `verilog` modifier

mdoc supports [custom modifiers](https://scalameta.org/mdoc/docs/modifiers.html#postmodifier).
We have created a custom `verilog` modifier to enable displaying the Verilog output of Chisel.

Example use:
````
```scala mdoc:silent
class MyModule extends RawModule {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
out := in + 1.U
}
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new MyModule)
```
````
The `verilog` modifier tells mdoc to run the Scala block, requiring that each Statement returns a String.
It will then concatenate the resulting Strings and wrap them in triple backticks with the language set to `verilog`:
````
```scala
class MyModule extends RawModule {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
out := in + 1.U
}
```
```verilog
module MyModule(
input [7:0] in,
output [7:0] out
);
assign out = in + 8'h1; // @[main.scala 9:13]
endmodule
```
````

Note that `imports` are okay in `mdoc:verilog` blocks, but any utility Scala code should be in a separate block.
11 changes: 6 additions & 5 deletions docs/src/cookbooks/naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ section: "chisel3"
---

```scala mdoc:invisible
import chisel3.internal.plugin._
import chisel3._
import chisel3.experimental.prefix
import chisel3.experimental.noPrefix
Expand Down Expand Up @@ -57,8 +56,9 @@ class ExampleNoPrefix extends MultiIOModule {

out := add
}

println(ChiselStage.emitVerilog(new ExampleNoPrefix))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new ExampleNoPrefix)
```

### I am still not getting the name I want. For example, inlining an instance changes my name!
Expand Down Expand Up @@ -88,8 +88,9 @@ class MyLeaf extends MultiIOModule {
val out = IO(Output(UInt(3.W)))
out := in
}

println(ChiselStage.emitVerilog(new WrapperExample))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new WrapperExample)
```

This can be used to rename instances and non-aggregate typed signals.
4 changes: 2 additions & 2 deletions docs/src/explanations/bundles-and-vecs.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ class MyFlippedModule extends RawModule {

This generates the following Verilog:

```scala mdoc
```scala mdoc:verilog
import chisel3.stage.ChiselStage

println(ChiselStage.emitVerilog(new MyFlippedModule()))
ChiselStage.emitVerilog(new MyFlippedModule())
```

### MixedVec
Expand Down
58 changes: 34 additions & 24 deletions docs/src/explanations/naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ systemic name-stability issues, please refer to the naming [cookbook](../cookboo
### Compiler Plugin

```scala mdoc
import chisel3.internal.plugin._
// Imports used by the following examples
import chisel3._
import chisel3.experimental.prefix
import chisel3.experimental.noPrefix
import chisel3.experimental.{prefix, 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
// chiselVersion is the String version (eg. "3.4.0")
addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full)
```

Expand All @@ -48,7 +48,9 @@ class Example1 extends MultiIOModule {
val io = IO(new MyBundle())
// val io = autoNameRecursively("io")(IO(new MyBundle()))
}
println(ChiselStage.emitVerilog(new Example1))
```
```scala mdoc:verilog
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-
Expand All @@ -70,8 +72,9 @@ class Example2 extends MultiIOModule {

out := add + 1.U
}

println(ChiselStage.emitVerilog(new Example2))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example2)
```

Note that the naming also works if the hardware type is nested in an `Option` or a subtype of `Iterable`:
Expand All @@ -92,8 +95,9 @@ class Example3 extends MultiIOModule {

out := opt.get + 1.U
}

println(ChiselStage.emitVerilog(new Example3))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example3)
```

There is also a slight variant (`autoNameRecursivelyProduct`) for naming hardware with names provided by an unapply:
Expand All @@ -105,9 +109,11 @@ class UnapplyExample extends MultiIOModule {

out := in
}

println(ChiselStage.emitVerilog(new UnapplyExample))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new UnapplyExample)
```

Note that the compiler plugin will not insert a prefix in these cases because it is ambiguous what the prefix should be.
Users who desire a prefix are encouraged to provide one as [described below](#prefixing).

Expand Down Expand Up @@ -137,11 +143,11 @@ class Example5 extends MultiIOModule {

out := prefix("ECO") { add + 1.U + in }
}

println(ChiselStage.emitVerilog(new Example4))
println(ChiselStage.emitVerilog(new Example5))

```
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example4)
ChiselStage.emitVerilog(new Example5)
```

Also note that the prefixes append to each other (including the prefix generated by the compiler plugin):

Expand All @@ -154,8 +160,9 @@ class Example6 extends MultiIOModule {

out := add
}

println(ChiselStage.emitVerilog(new Example6))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example6)
```

Sometimes you may want to disable the prefixing. This might occur if you are writing a library function and
Expand All @@ -170,8 +177,9 @@ class Example7 extends MultiIOModule {

out := add
}

println(ChiselStage.emitVerilog(new Example7))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example7)
```

### Suggest a Signal's Name (or the instance name of a Module)
Expand All @@ -188,8 +196,9 @@ class Example8 extends MultiIOModule {

out := add
}

println(ChiselStage.emitVerilog(new Example8))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example8)
```

### Set a Module Name
Expand All @@ -208,9 +217,10 @@ class Example9(width: Int) extends MultiIOModule {

out := add
}

println(ChiselStage.emitVerilog(new Example9(8)))
println(ChiselStage.emitVerilog(new Example9(1)))
```
```scala mdoc:verilog
ChiselStage.emitVerilog(new Example9(8))
ChiselStage.emitVerilog(new Example9(1))
```

### Reflection Naming
Expand Down

0 comments on commit e6192ea

Please sign in to comment.