diff options
| author | Adam Izraelevitz | 2020-08-21 12:02:26 -0700 |
|---|---|---|
| committer | GitHub | 2020-08-21 19:02:26 +0000 |
| commit | 7edba2d10f980016462f917c6d21d64585ddfd6b (patch) | |
| tree | 3eb2a106b0e528b1ae8ed05b54200f828902de09 /docs/src/wiki-deprecated/functional-module-creation.md | |
| parent | 70fd01d4b0ad18a87bc46558ff246254792aa9b8 (diff) | |
Added website docs and mdoc. (#1560)
* Added website docs and mdoc. Removed all warnings
* Updated README and added build to circle ci
* Added how to build documentation, deprecated wiki
* Fix copypasta
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'docs/src/wiki-deprecated/functional-module-creation.md')
| -rw-r--r-- | docs/src/wiki-deprecated/functional-module-creation.md | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/docs/src/wiki-deprecated/functional-module-creation.md b/docs/src/wiki-deprecated/functional-module-creation.md new file mode 100644 index 00000000..3e2e95bc --- /dev/null +++ b/docs/src/wiki-deprecated/functional-module-creation.md @@ -0,0 +1,79 @@ +--- +layout: docs +title: "Functional Module Creation" +section: "chisel3" +--- +Objects in Scala have a pre-existing creation function (method) called `apply`. +When an object is used as value in an expression (which basically means that the constructor was called), this method determines the returned value. +When dealing with hardware modules, one would expect the module output to be representative of the hardware module's functionality. +Therefore, we would sometimes like the module output to be the value returned when using the object as a value in an expression. +Since hardware modules are represented as Scala objects, this can be done by defining the object's `apply` method to return the module's output. +This can be referred to as creating a functional interface for module construction. +If we apply this on the standard mux2 example, we would to return the mux2 output ports when we used mux2 in an expression. +Implementing this requires building a constructor that takes multiplexer inputs as parameters and returns the multiplexer output: + +```scala +object Mux2 { + def apply(sel: UInt, in0: UInt, in1: UInt) = { + val m = Module(new Mux2) + m.io.in0 := in0 + m.io.in1 := in1 + m.io.sel := sel + m.io.out + } +} +``` + +As we can see in the code example, we defined the `apply` method to take the Mux2 inputs as the method parameters, and return the Mux2 output as the function's return value. +By defining modules in this way, it is easier to later implement larger and more complex version of this regular module. +For example, we previously implemented Mux4 like this: + +```scala +class Mux4 extends Module { + val io = IO(new 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)) + }) + 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 +} +``` + +However, by using the creation function we redefined for Mux2, we can now use the Mux2 outputs as values of the modules themselves +when writing the Mux4 output expression: + +```scala +class Mux4 extends Module { + val io = IO(new 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)) + }) + io.out := Mux2(io.sel(1), + Mux2(io.sel(0), io.in0, io.in1), + Mux2(io.sel(0), io.in2, io.in3)) +} +``` + +This allows to write more intuitively readable hardware connection descriptions, which are similar to software expression evaluation. |
