summaryrefslogtreecommitdiff
path: root/docs/src/explanations/reset.md
diff options
context:
space:
mode:
authorMegan Wachs2021-03-18 16:47:58 -0700
committerGitHub2021-03-18 16:47:58 -0700
commitf1ad5b58e8a749d558758288d03ce75bf6b8ff9c (patch)
tree2150d6f41a55f81c9f4cf3b037b715cb75ea617f /docs/src/explanations/reset.md
parent2a56c6540e914611ac12647e157aec4c5c595758 (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/reset.md')
-rw-r--r--docs/src/explanations/reset.md179
1 files changed, 179 insertions, 0 deletions
diff --git a/docs/src/explanations/reset.md b/docs/src/explanations/reset.md
new file mode 100644
index 00000000..a99a39e3
--- /dev/null
+++ b/docs/src/explanations/reset.md
@@ -0,0 +1,179 @@
+---
+layout: docs
+title: "Reset"
+section: "chisel3"
+---
+
+# Reset
+
+```scala mdoc:invisible
+import chisel3._
+
+class Submodule extends Module
+```
+
+As of Chisel 3.2.0, Chisel 3 supports both synchronous and asynchronous reset,
+meaning that it can natively emit both synchronous and asynchronously reset registers.
+
+The type of register that is emitted is based on the type of the reset signal associated
+with the register.
+
+There are three types of reset that implement a common trait `Reset`:
+* `Bool` - constructed with `Bool()`. Also known as "synchronous reset".
+* `AsyncReset` - constructed with `AsyncReset()`. Also known as "asynchronous reset".
+* `Reset` - constructed with `Reset()`. Also known as "abstract reset".
+
+For implementation reasons, the concrete Scala type is `ResetType`. Stylistically we avoid `ResetType`, instead using the common trait `Reset`.
+
+Registers with reset signals of type `Bool` are emitted as synchronous reset flops.
+Registers with reset signals of type `AsyncReset` are emitted as asynchronouly reset flops.
+Registers with reset signals of type `Reset` will have their reset type _inferred_ during FIRRTL compilation.
+
+### Reset Inference
+
+FIRRTL will infer a concrete type for any signals of type abstract `Reset`.
+The rules are as follows:
+1. An abstract `Reset` with only signals of type `AsyncReset`, abstract `Reset`, and `DontCare`
+in both its fan-in and fan-out will infer to be of type `AsyncReset`
+2. An abstract `Reset` with signals of both types `Bool` and `AsyncReset` in its fan-in and fan-out
+is an error.
+3. Otherwise, an abstract `Reset` will infer to type `Bool`.
+
+You can think about (3) as the mirror of (1) replacing `AsyncReset` with `Bool` with the additional
+rule that abstract `Reset`s with neither `AsyncReset` nor `Bool` in their fan-in and fan-out will
+default to type `Bool`.
+This "default" case is uncommon and implies that reset signal is ultimately driven by a `DontCare`.
+
+### Implicit Reset
+
+A `Module`'s `reset` is of type abstract `Reset`.
+Prior to Chisel 3.2.0, the type of this field was `Bool`.
+For backwards compatability, if the top-level module has an implicit reset, its type will default to `Bool`.
+
+#### Setting Implicit Reset Type
+
+_New in Chisel 3.3.0_
+
+If you would like to set the reset type from within a Module (including the top-level `Module`),
+rather than relying on _Reset Inference_, you can mixin one of the following traits:
+* `RequireSyncReset` - sets the type of `reset` to `Bool`
+* `RequireAsyncReset` - sets the type of `reset` to `AsyncReset`
+
+For example:
+
+```scala mdoc:silent
+class MyAlwaysSyncResetModule extends Module with RequireSyncReset {
+ val mySyncResetReg = RegInit(false.B) // reset is of type Bool
+}
+```
+
+```scala mdoc:silent
+class MyAlwaysAsyncResetModule extends Module with RequireAsyncReset {
+ val myAsyncResetReg = RegInit(false.B) // reset is of type AsyncReset
+}
+```
+
+**Note:** This sets the concrete type, but the Scala type will remain `Reset`, so casting may still be necessary.
+This comes up most often when using a reset of type `Bool` in logic.
+
+
+### Reset-Agnostic Code
+
+The purpose of abstract `Reset` is to make it possible to design hardware that is agnostic to the
+reset discipline used.
+This enables code reuse for utilities and designs where the reset discipline does not matter to
+the functionality of the block.
+
+Consider the two example modules below which are agnostic to the type of reset used within them:
+
+```scala mdoc:silent
+class ResetAgnosticModule extends Module {
+ val io = IO(new Bundle {
+ val out = UInt(4.W)
+ })
+ val resetAgnosticReg = RegInit(0.U(4.W))
+ resetAgnosticReg := resetAgnosticReg + 1.U
+ io.out := resetAgnosticReg
+}
+
+class ResetAgnosticRawModule extends RawModule {
+ val clk = IO(Input(Clock()))
+ val rst = IO(Input(Reset()))
+ val out = IO(Output(UInt(8.W)))
+
+ val resetAgnosticReg = withClockAndReset(clk, rst)(RegInit(0.U(8.W)))
+ resetAgnosticReg := resetAgnosticReg + 1.U
+ out := resetAgnosticReg
+}
+```
+
+These modules can be used in both synchronous and asynchronous reset domains.
+Their reset types will be inferred based on the context within which they are used.
+
+### Forcing Reset Type
+
+You can set the type of a Module's implicit reset as described [above](#setting-implicit-reset-type).
+
+You can also cast to force the concrete type of reset.
+* `.asBool` will reinterpret a `Reset` as `Bool`
+* `.asAsyncReset` will reinterpret a `Reset` as `AsyncReset`.
+
+You can then use `withReset` to use a cast reset as the implicit reset.
+See ["Multiple Clock Domains"](../explanations/multi-clock) for more information about `withReset`.
+
+
+The following will make `myReg` as well as both `resetAgnosticReg`s synchronously reset:
+
+```scala mdoc:silent
+class ForcedSyncReset extends Module {
+ // withReset's argument becomes the implicit reset in its scope
+ withReset (reset.asBool) {
+ val myReg = RegInit(0.U)
+ val myModule = Module(new ResetAgnosticModule)
+
+ // RawModules do not have implicit resets so withReset has no effect
+ val myRawModule = Module(new ResetAgnosticRawModule)
+ // We must drive the reset port manually
+ myRawModule.rst := Module.reset // Module.reset grabs the current implicit reset
+ }
+}
+```
+
+The following will make `myReg` as well as both `resetAgnosticReg`s asynchronously reset:
+
+```scala mdoc:silent
+class ForcedAysncReset extends Module {
+ // withReset's argument becomes the implicit reset in its scope
+ withReset (reset.asAsyncReset){
+ val myReg = RegInit(0.U)
+ val myModule = Module(new ResetAgnosticModule) // myModule.reset is connected implicitly
+
+ // RawModules do not have implicit resets so withReset has no effect
+ val myRawModule = Module(new ResetAgnosticRawModule)
+ // We must drive the reset port manually
+ myRawModule.rst := Module.reset // Module.reset grabs the current implicit reset
+ }
+}
+```
+
+**Note:** such casts (`asBool` and `asAsyncReset`) are not checked by FIRRTL.
+In doing such a cast, you as the designer are effectively telling the compiler
+that you know what you are doing and to force the type as cast.
+
+### Last-Connect Semantics
+
+It is **not** legal to override the reset type using last-connect semantics
+unless you are overriding a `DontCare`:
+
+```scala mdoc:silent
+class MyModule extends Module {
+ val resetBool = Wire(Reset())
+ resetBool := DontCare
+ resetBool := false.B // this is fine
+ withReset(resetBool) {
+ val mySubmodule = Module(new Submodule())
+ }
+ resetBool := true.B // this is fine
+ resetBool := false.B.asAsyncReset // this will error in FIRRTL
+}
+```