summaryrefslogtreecommitdiff
path: root/docs/src/wiki-deprecated/modules.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/wiki-deprecated/modules.md')
-rw-r--r--docs/src/wiki-deprecated/modules.md141
1 files changed, 141 insertions, 0 deletions
diff --git a/docs/src/wiki-deprecated/modules.md b/docs/src/wiki-deprecated/modules.md
new file mode 100644
index 00000000..1d85b88e
--- /dev/null
+++ b/docs/src/wiki-deprecated/modules.md
@@ -0,0 +1,141 @@
+---
+layout: docs
+title: "Modules"
+section: "chisel3"
+---
+Chisel *modules* are very similar to Verilog *modules* in
+defining a hierarchical structure in the generated circuit.
+
+The hierarchical module namespace is accessible in downstream tools
+to aid in debugging and physical layout. A user-defined module is
+defined as a *class* which:
+
+ - inherits from ```Module```,
+ - contains an interface wrapped in a Module's ```IO()``` method and stored in a port field named ```io```, and
+ - wires together subcircuits in its constructor.
+
+As an example, consider defining your own two-input multiplexer as a
+module:
+```scala mdoc:silent
+import chisel3._
+class Mux2IO extends Bundle {
+ val sel = Input(UInt(1.W))
+ val in0 = Input(UInt(1.W))
+ val in1 = Input(UInt(1.W))
+ val out = Output(UInt(1.W))
+}
+
+class Mux2 extends Module {
+ val io = IO(new Mux2IO)
+ io.out := (io.sel & io.in1) | (~io.sel & io.in0)
+}
+```
+
+The wiring interface to a module is a collection of ports in the
+form of a ```Bundle```. The interface to the module is defined
+through a field named ```io```. For ```Mux2```, ```io``` is
+defined as a bundle with four fields, one for each multiplexer port.
+
+The ```:=``` assignment operator, used here in the body of the
+definition, is a special operator in Chisel that wires the input of
+left-hand side to the output of the right-hand side.
+
+### Module Hierarchy
+
+We can now construct circuit hierarchies, where we build larger modules out
+of smaller sub-modules. For example, we can build a 4-input
+multiplexer module in terms of the ```Mux2``` module by wiring
+together three 2-input multiplexers:
+
+```scala mdoc:silent
+class Mux4IO extends Bundle {
+ val in0 = Input(UInt(1.W))
+ val in1 = Input(UInt(1.W))
+ val in2 = Input(UInt(1.W))
+ val in3 = Input(UInt(1.W))
+ val sel = Input(UInt(2.W))
+ val out = Output(UInt(1.W))
+}
+class Mux4 extends Module {
+ val io = IO(new Mux4IO)
+
+ val m0 = Module(new Mux2)
+ m0.io.sel := io.sel(0)
+ m0.io.in0 := io.in0
+ m0.io.in1 := io.in1
+
+ val m1 = Module(new Mux2)
+ m1.io.sel := io.sel(0)
+ m1.io.in0 := io.in2
+ m1.io.in1 := io.in3
+
+ val m3 = Module(new Mux2)
+ m3.io.sel := io.sel(1)
+ m3.io.in0 := m0.io.out
+ m3.io.in1 := m1.io.out
+
+ io.out := m3.io.out
+}
+```
+
+We again define the module interface as ```io``` and wire up the
+inputs and outputs. In this case, we create three ```Mux2```
+children modules, using the ```Module``` constructor function and
+the Scala ```new``` keyword to create a
+new object. We then wire them up to one another and to the ports of
+the ```Mux4``` interface.
+
+Note: Chisel `Module`s have an implicit clock (called `clock`) and
+an implicit reset (called `reset`). For different behavior, Chisel
+provides both `MultiIOModule` and `RawModule`.
+
+### `MultiIOModule`
+
+A `MultiIOModule` allows you to define as many different `IO` as needed
+and does not require you to implement an abstract member `io`.
+This can be useful when programmatically adding `IO` or adding `IO` via inheritance.
+An artifact of this is that Verilog generated from a `MultiIOModule` will
+*not* have the `io_` prefix. `MultiIOModule`s still have an implicit
+clock and reset like `Module`.
+
+<!-- TODO: Some example -->
+
+### `RawModule`
+
+A `RawModule` is a module that allows you to define as much `IO` as needed
+(like `MultiIOModule`) but **does not provide an implicit clock and reset.**
+This can be useful when interfacing a Chisel module with a design that expects
+a specific naming convention for clock or reset.
+
+Then we can use it in place of *Module* usage :
+```scala mdoc:silent
+import chisel3.{RawModule, withClockAndReset}
+
+class Foo extends Module {
+ val io = IO(new Bundle{
+ val a = Input(Bool())
+ val b = Output(Bool())
+ })
+ io.b := !io.a
+}
+
+class FooWrapper extends RawModule {
+ val a_i = IO(Input(Bool()))
+ val b_o = IO(Output(Bool()))
+ val clk = Input(Clock())
+ val rstn = Input(Bool())
+
+ val foo = withClockAndReset(clk, !rstn){ Module(new Foo) }
+
+ foo.io.a := a_i
+ b_o := foo.io.b
+}
+```
+
+In the example above, the `RawModule` is used to change the reset polarity
+of module `SlaveSpi`. Indeed, the reset is active high by default in Chisel
+modules, then using `withClockAndReset(clock, !rstn)` we can use an active low
+reset in entire design.
+
+The clock is just wired as it, but if needed, `RawModule` can be used in
+conjunction with `BlackBox` to connect a differential clock input for example.