diff options
| author | Megan Wachs | 2021-03-18 16:47:58 -0700 |
|---|---|---|
| committer | GitHub | 2021-03-18 16:47:58 -0700 |
| commit | f1ad5b58e8a749d558758288d03ce75bf6b8ff9c (patch) | |
| tree | 2150d6f41a55f81c9f4cf3b037b715cb75ea617f /docs/src/explanations/unconnected-wires.md | |
| parent | 2a56c6540e914611ac12647e157aec4c5c595758 (diff) | |
Reorganize website docs (#1806)
Updates to chisel3 documentation for website:
* guard code examples with mdoc and fix errors encountered along the way
* move some website content here vs splitting the content across two repos
* Bring in the interval-types and loading memories content so that it will be visible from the website
* remove all references to the wiki (deprecated)
* Remove reference to Wiki from the README
* fix tabbing and compile of chisel3-vs-chisel2 section
* Appendix: faqs now guarded and compile
* FAQs: move to resources section
Diffstat (limited to 'docs/src/explanations/unconnected-wires.md')
| -rw-r--r-- | docs/src/explanations/unconnected-wires.md | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/docs/src/explanations/unconnected-wires.md b/docs/src/explanations/unconnected-wires.md new file mode 100644 index 00000000..48012d12 --- /dev/null +++ b/docs/src/explanations/unconnected-wires.md @@ -0,0 +1,138 @@ +--- +layout: docs +title: "Unconnected Wires" +section: "chisel3" +--- + +# Unconnected Wires + +The Invalidate API [(#645)](https://github.com/freechipsproject/chisel3/pull/645) adds support to Chisel +for reporting unconnected wires as errors. + +Prior to this pull request, Chisel automatically generated a firrtl `is invalid` for `Module IO()`, and each `Wire()` definition. +This made it difficult to detect cases where output signals were never driven. +Chisel now supports a `DontCare` element, which may be connected to an output signal, indicating that that signal is intentionally not driven. +Unless a signal is driven by hardware or connected to a `DontCare`, Firrtl will complain with a "not fully initialized" error. + +### API + +Output signals may be connected to DontCare, generating a `is invalid` when the corresponding firrtl is emitted. + +```scala mdoc:invisible +import chisel3._ +``` +```scala mdoc:silent + +class Out extends Bundle { + val debug = Bool() + val debugOption = Bool() +} +val io = new Bundle { val out = new Out } +``` + +```scala mdoc:compile-only +io.out.debug := true.B +io.out.debugOption := DontCare +``` + +This indicates that the signal `io.out.debugOption` is intentionally not driven and firrtl should not issue a "not fully initialized" +error for this signal. + +This can be applied to aggregates as well as individual signals: +```scala mdoc:invisible +import chisel3._ +``` +```scala mdoc:silent +import chisel3._ +class ModWithVec extends Module { + // ... + val nElements = 5 + val io = IO(new Bundle { + val outs = Output(Vec(nElements, Bool())) + }) + io.outs <> DontCare + // ... +} + +class TrivialInterface extends Bundle { + val in = Input(Bool()) + val out = Output(Bool()) +} + +class ModWithTrivalInterface extends Module { + // ... + val io = IO(new TrivialInterface) + io <> DontCare + // ... +} +``` + +This feature is controlled by `CompileOptions.explicitInvalidate` and is set to `false` in `NotStrict` (Chisel2 compatibility mode), +and `true` in `Strict` mode. + +You can selectively enable this for Chisel2 compatibility mode by providing your own explicit `compileOptions`, +either for a group of Modules (via inheritance): +```scala mdoc:silent +abstract class ExplicitInvalidateModule extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true)) +``` +or on a per-Module basis: +```scala mdoc:silent +class MyModule extends Module { + override val compileOptions = chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true) + val io = IO(new Bundle { /* ... */ } ) + // ... +} +``` + +Or conversely, disable this stricter checking (which is now the default in pure chisel3): +```scala mdoc:silent +abstract class ImplicitInvalidateModule extends Module()(chisel3.ExplicitCompileOptions.Strict.copy(explicitInvalidate = false)) +``` +or on a per-Module basis: +```scala mdoc:invisible:reset +import chisel3._ +``` +```scala mdoc:silent +class MyModule extends Module { + override val compileOptions = chisel3.ExplicitCompileOptions.Strict.copy(explicitInvalidate = false) + val io = IO(new Bundle { /* ... */ } ) + // ... +} +``` + +Please see the corresponding [API tests](https://github.com/freechipsproject/chisel3/blob/master/src/test/scala/chiselTests/InvalidateAPISpec.scala) +for examples. + +### Determining the unconnected element + +I have an interface with 42 wires. +Which one of them is unconnected? + +The firrtl error message should contain something like: +```bash +firrtl.passes.CheckInitialization$RefNotInitializedException: @[:@6.4] : [module Router] Reference io is not fully initialized. + @[Decoupled.scala 38:19:@48.12] : node _GEN_23 = mux(and(UInt<1>("h1"), eq(UInt<2>("h3"), _T_84)), _GEN_2, VOID) @[Decoupled.scala 38:19:@48.12] + @[Router.scala 78:30:@44.10] : node _GEN_36 = mux(_GEN_0.ready, _GEN_23, VOID) @[Router.scala 78:30:@44.10] + @[Router.scala 75:26:@39.8] : node _GEN_54 = mux(io.in.valid, _GEN_36, VOID) @[Router.scala 75:26:@39.8] + @[Router.scala 70:50:@27.6] : node _GEN_76 = mux(io.load_routing_table_request.valid, VOID, _GEN_54) @[Router.scala 70:50:@27.6] + @[Router.scala 65:85:@19.4] : node _GEN_102 = mux(_T_62, VOID, _GEN_76) @[Router.scala 65:85:@19.4] + : io.outs[3].bits.body <= _GEN_102 +``` +The first line is the initial error report. +Successive lines, indented and beginning with source line information indicate connections involving the problematic signal. +Unfortunately, if these are `when` conditions involving muxes, they may be difficult to decipher. +The last line of the group, indented and beginning with a `:` should indicate the uninitialized signal component. +This example (from the [Router tutorial](https://github.com/ucb-bar/chisel-tutorial/blob/release/src/main/scala/examples/Router.scala)) +was produced when the output queue bits were not initialized. +The old code was: +```scala + io.outs.foreach { out => out.noenq() } +``` +which initialized the queue's `valid` bit, but did not initialize the actual output values. +The fix was: +```scala + io.outs.foreach { out => + out.bits := 0.U.asTypeOf(out.bits) + out.noenq() + } +``` |
