From 62ff7d0c66a69ea2391d20819ee016ebb7854fa3 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 15 Nov 2019 11:00:55 -0800 Subject: [PATCH 1/3] Create chisel3-vs-compat.md --- .../src/main/tut/chisel3/chisel3-vs-compat.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/src/main/tut/chisel3/chisel3-vs-compat.md diff --git a/docs/src/main/tut/chisel3/chisel3-vs-compat.md b/docs/src/main/tut/chisel3/chisel3-vs-compat.md new file mode 100644 index 000000000..6a825807a --- /dev/null +++ b/docs/src/main/tut/chisel3/chisel3-vs-compat.md @@ -0,0 +1,148 @@ +--- +layout: docs +title: "chisel3 vs. compatibility mode" +section: "chisel3" +--- + +Chisel 3 supports "compatibility mode" which serves the purpose of bridging +the semantic gap between Chisel 2 and Chisel 3 with Chisel2-like semantics. +Chisel code using this mode depends on Chisel 3, yet the Scala code has +`import Chisel._` instead of the normal `import chisel3._`. This page serves +to document the differences for helping migrate from compatibility mode to the +safer and more modern Chisel 3 semantics. + +### Connections + +#### Compatibility mode + +In compatibility mode, both connection operators `:=` and `<>` are actually the same. +They both are bidirectional and noncommutative--the right side will be treated as +the source and the left side will be treated as the sink. + +```scala +import Chisel._ +class MyModule extends Module { + val io = new Bundle { + val in = Decoupled(UInt(width = 4)).flip + val out = Decoupled(UInt(width = 4)) + } + io.in <> io.out // This works + io.in := io.out // This is equivalent + io.out <> io.in // This will error +} +``` +Furthermore, error detection and reporting is defered to FIRRTL compilation. + +#### Chisel 3 + +In Chisel 3, `:=` is refered to as "monoconnect" and `<>` is called "bulkconnect". + +* Monoconnect +`:=` treats everything on the left-hand side as a sink, even if the type is +bidirectional. This means it cannot be used to drive bidirectional output ports, +but can be used to drive wires from bidirectional inputs or outputs to "monitor" +the the full aggregate, ignoring directions. + +* Bulkconnect +`<>` performs bidirectional connections and is commutative. At least one of the +arguments must be a port. +It will determine the correct leaf-level connections based on the directions of +its port arguments. +It cannot be used to connect two components _inside_ of a module. + +```scala +import chisel3._ +import chisel3.util._ +class MyModule extends Module { + val io = IO(new Bundle { + val in = Flipped(Decoupled(UInt(4.W))) + val out = Decoupled(UInt(4.W)) + val x = Output(UInt(8.W)) + }) + io.out <> io.in // This works + io.in <> io.out // So does this + io.out := io.in // Error, cannot drive io.out.ready + + val w = Wire(Decoupled(UInt(4.W))) + w := io.in // This works, w can be seen as "monitoring" io.in + 4.U <> io.x // This also works but is stylistically suspect +} +``` + +### Width Declaration + +#### Compatibility mode +```scala +val x = UInt(width = 8) +``` +#### Chisel 3 +```scala +val x = UInt(8.W) +``` +Notably, widths are now a type rather than a byname argument to the `UInt` +constructor. + + +### Literals + +#### Compatibility mode +```scala +val x = UInt(2) +val y = SInt(-1, width = 8) +``` +#### Chisel 3 +```scala +val x = 2.U +val y = 0.S(8.W) +``` + +### Direction + +#### Compatibility mode +```scala +val x = UInt(INPUT, 8) +val y = Bool(OUTPUT) +val z = (new MyBundle).flip +``` +#### Chisel 3 +```scala +val x = Input(UInt(8.W)) +val y = Output(Bool()) +val z = Flipped(new MyBundle) +``` + +### Module IO +#### Compatibility mode +```scala +class MyModule extends Module { + val io = new Bundle { ... } +} +``` +#### Chisel 3 + +In Chisel 3, all declared ports must be wrapped in `IO(...)`. For `Modules`, +this is just `val io`. +```scala +class MyModule extends Module { + val io = IO(new Bundle { ... } ) +} +``` +But in Chisel 3, `MultiIOModules` have the ability to declare multiple "ios". +While `val io` is not required, the implicit `clock` and `reset` are still there. +```scala +class MyModule2 extends MultiIOModule { + val foo = IO(Input(UInt(8.W))) +} +``` +Chisel 3 also has `RawModule` which allows arbitrary ports and has no implicit +`clock` nor `reset`. +```scala +class MyModule3 extends RawModule { + val foo = IO(Output(Vec(8, Bool()))) +} +``` + +### Utilities + +Many constructs originally available via `import Chisel._` are now located in +`chisel3.util`. They can be imported From 2089c3f24c8b8b835b6d203148d7e6cf6ffa1c37 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 15 Nov 2019 13:33:38 -0800 Subject: [PATCH 2/3] Make SInt literal negative It makes the example more useful Co-Authored-By: edwardcwang --- docs/src/main/tut/chisel3/chisel3-vs-compat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/tut/chisel3/chisel3-vs-compat.md b/docs/src/main/tut/chisel3/chisel3-vs-compat.md index 6a825807a..b3502462b 100644 --- a/docs/src/main/tut/chisel3/chisel3-vs-compat.md +++ b/docs/src/main/tut/chisel3/chisel3-vs-compat.md @@ -93,7 +93,7 @@ val y = SInt(-1, width = 8) #### Chisel 3 ```scala val x = 2.U -val y = 0.S(8.W) +val y = -1.S(8.W) ``` ### Direction From fb98f43a0009623126821666d3a0ad80439cd1e6 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 15 Nov 2019 19:41:51 -0800 Subject: [PATCH 3/3] Expand Connections section in chisel3 vs. compat --- .../src/main/tut/chisel3/chisel3-vs-compat.md | 77 ++++++++++++++++--- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/docs/src/main/tut/chisel3/chisel3-vs-compat.md b/docs/src/main/tut/chisel3/chisel3-vs-compat.md index b3502462b..8c017c99a 100644 --- a/docs/src/main/tut/chisel3/chisel3-vs-compat.md +++ b/docs/src/main/tut/chisel3/chisel3-vs-compat.md @@ -26,16 +26,39 @@ class MyModule extends Module { val in = Decoupled(UInt(width = 4)).flip val out = Decoupled(UInt(width = 4)) } - io.in <> io.out // This works - io.in := io.out // This is equivalent - io.out <> io.in // This will error + io.out <> io.in // This works + io.out := io.in // This is equivalent + io.in <> io.out // This will error +} +``` +For Bundles, elements with matching names will be connected and unmatching elements +will be ignored. For example: +```scala +import Chisel._ +class BundleA extends Bundle { + val foo = UInt(width = 8) } +class BundleB extends Bundle { + val foo = UInt(width = 8) + val bar = UInt(width = 8) +} +class MyModule extends Module { + val io = new Bundle { + val in = (new BundleA).asInput + val out = (new BundleB).asOutput + } + io.out <> io.in + // Equivalent to + io.out.foo := io.in.foo + // bar is ignored because it doesn't match +} ``` + Furthermore, error detection and reporting is defered to FIRRTL compilation. #### Chisel 3 -In Chisel 3, `:=` is refered to as "monoconnect" and `<>` is called "bulkconnect". +In Chisel 3, `:=` is refered to as "monoconnect" and `<>` is called "biconnect". * Monoconnect `:=` treats everything on the left-hand side as a sink, even if the type is @@ -43,7 +66,7 @@ bidirectional. This means it cannot be used to drive bidirectional output ports, but can be used to drive wires from bidirectional inputs or outputs to "monitor" the the full aggregate, ignoring directions. -* Bulkconnect +* Biconnect `<>` performs bidirectional connections and is commutative. At least one of the arguments must be a port. It will determine the correct leaf-level connections based on the directions of @@ -68,6 +91,26 @@ class MyModule extends Module { 4.U <> io.x // This also works but is stylistically suspect } ``` +In contrast to compatibility mode, every field of two connected Bundles must match. +For example: +```scala +import chisel3._ +class BundleA extends Bundle { + val foo = UInt(8.W) +} +class BundleB extends Bundle { + val foo = UInt(8.W) + val bar = UInt(8.W) +} +class MyModule extends Module { + val io = new Bundle { + val in = Input(new BundleA) + val out = Output(new BundleB) + } + io.out <> io.in // This is an error because io.in.bar doesn't match +} +``` +Additionally, errors are caught during Chisel elaboration. ### Width Declaration @@ -100,15 +143,27 @@ val y = -1.S(8.W) #### Compatibility mode ```scala -val x = UInt(INPUT, 8) -val y = Bool(OUTPUT) -val z = (new MyBundle).flip +class MyBundle { + val foo = UInt(8.W).asInput + val bar = UInt(8.W) // Default direction is Output +} +val a = UInt(INPUT, 8) +val b = Bool(OUTPUT) +val c = Bool() // Equivalent to above, default direction is OUTPUT +val d = new MyBundle +val e = (new Bundle).flip ``` #### Chisel 3 ```scala -val x = Input(UInt(8.W)) -val y = Output(Bool()) -val z = Flipped(new MyBundle) +// Directions are required +class MyBundle { + val foo = Input(UInt(8.W)) + val bar = Output(UInt(8.W)) +} +val a = Input(UInt(8.W)) +val b = Output(Bool()) +val c = new MyBundle +val d = Flipped(new MyBundle) ``` ### Module IO