- Latest (6.0.0-RC1) -
- Snapshot +
- Snapshot
- 6.0.0-RC1
- 5.1.0
- 3.6.0 diff --git a/index.html b/index.html index 79764a20f1..69107d16c0 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@
diff --git a/404.html b/404.html index 98bbbcd8b4..72f27cfffa 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@
Please see the page about Versioning for more information about major and minor versioning and binary compatibility.
.asInstanceOf
vs .asTypeOf
vs chiselTypeOf
",id:"asinstanceof-vs-astypeof-vs-chiseltypeof",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(n.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(n.code,{children:"false.B"}),", ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(n.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(n.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(n.code,{children:"Bool"}),", ",(0,l.jsx)(n.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(n.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class MyBundle(w: Int) extends Bundle {\n val foo = UInt(w.W)\n val bar = UInt(w.W)\n}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Chisel"})," type of a ",(0,l.jsx)(n.code,{children:"Data"})," is a Scala object. It captures all the fields actually present,\nby names, and their types including widths.\nFor example, ",(0,l.jsx)(n.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(n.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Hardware is ",(0,l.jsx)(n.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(n.code,{children:"false.B"})," or ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),".\nThe binding is what determines the actual directionality of each field, it is not a property of the Chisel type."]}),"\n",(0,l.jsxs)(n.p,{children:["A literal is a ",(0,l.jsx)(n.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(n.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(n.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.BundleLiterals._\n\nclass MyModule(gen: () => MyBundle) extends Module {\n // Hardware Literal\n val xType: MyBundle = new MyBundle(3) // - -\n val dirXType: MyBundle = Input(new MyBundle(3)) // - -\n val xReg: MyBundle = Reg(new MyBundle(3)) // x -\n val xIO: MyBundle = IO(Input(new MyBundle(3))) // x -\n val xRegInit: MyBundle = RegInit(xIO) // x -\n val xLit: MyBundle = xType.Lit( // x x\n _.foo -> 0.U(3.W),\n _.bar -> 0.U(3.W)\n )\n val y: MyBundle = gen() // ? ?\n\n // Need to initialize all hardware values\n xReg := DontCare\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val chiselType = new MyBundle(3)\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val a = 0.U.asTypeOf(chiselType)\n val b = 0.U.asTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n chiselType := DontCare\n})\n// chisel3.package$ExpectedHardwareException: data to be connected 'MyBundle' must be hardware, not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21$$anon$3..asInstanceOf
vs .asTypeOf
vs chiselTypeOf
",id:"asinstanceof-vs-astypeof-vs-chiseltypeof",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(n.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(n.code,{children:"false.B"}),", ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(n.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(n.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(n.code,{children:"Bool"}),", ",(0,l.jsx)(n.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(n.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class MyBundle(w: Int) extends Bundle {\n val foo = UInt(w.W)\n val bar = UInt(w.W)\n}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Chisel"})," type of a ",(0,l.jsx)(n.code,{children:"Data"})," is a Scala object. It captures all the fields actually present,\nby names, and their types including widths.\nFor example, ",(0,l.jsx)(n.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(n.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Hardware is ",(0,l.jsx)(n.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(n.code,{children:"false.B"})," or ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),".\nThe binding is what determines the actual directionality of each field, it is not a property of the Chisel type."]}),"\n",(0,l.jsxs)(n.p,{children:["A literal is a ",(0,l.jsx)(n.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(n.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(n.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.BundleLiterals._\n\nclass MyModule(gen: () => MyBundle) extends Module {\n // Hardware Literal\n val xType: MyBundle = new MyBundle(3) // - -\n val dirXType: MyBundle = Input(new MyBundle(3)) // - -\n val xReg: MyBundle = Reg(new MyBundle(3)) // x -\n val xIO: MyBundle = IO(Input(new MyBundle(3))) // x -\n val xRegInit: MyBundle = RegInit(xIO) // x -\n val xLit: MyBundle = xType.Lit( // x x\n _.foo -> 0.U(3.W),\n _.bar -> 0.U(3.W)\n )\n val y: MyBundle = gen() // ? ?\n\n // Need to initialize all hardware values\n xReg := DontCare\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val chiselType = new MyBundle(3)\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val a = 0.U.asTypeOf(chiselType)\n val b = 0.U.asTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n chiselType := DontCare\n})\n// chisel3.package$ExpectedHardwareException: data to be connected 'MyBundle' must be hardware, not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21$$anon$3..cloneType
directly",id:"4-call-clonetype-directly",level:4},{value:" How do I deal with the "unable to clone" error?",id:"-how-do-i-deal-with-the-unable-to-clone-error",level:3},{value:"How do I create a finite state machine (FSM)?",id:"how-do-i-create-a-finite-state-machine-fsm",level:3},{value:"How do I unpack a value ("reverse concatenation") like in Verilog?",id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",level:3},{value:"How do I do subword assignment (assign to some bits in a UInt)?",id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",level:3},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:3},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:3},{value:"How do I minimize the number of bits used in an output vector?",id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",level:3},{value:" How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?",id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",level:3},{value:"Use bit extraction when the index is too wide",id:"use-bit-extraction-when-the-index-is-too-wide",level:4},{value:"Predictable Naming",id:"predictable-naming",level:2},{value:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?",id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",level:3},{value:"How do I get Chisel to name the results of vector reads properly?",id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",level:3},{value:"How can I dynamically set/parametrize the name of a module?",id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",level:3},{value:"Directionality",id:"directionality",level:2},{value:"How do I strip directions from a bidirectional Bundle (or other Data)?",id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,t.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,t.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type Conversions","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Vectors and Registers","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#can-i-make-a-2D-or-3D-Vector",children:"Can I make a 2D or 3D Vector?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Bundles","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#bundle-unable-to-clone",children:'How do I deal with the "unable to clone" error?'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#dynamic-index-too-wide-narrow",children:'How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?'})}),"\n",(0,t.jsxs)(n.li,{children:["Predictable Naming","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Directionality","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"}),"\n",(0,t.jsxs)(n.p,{children:["Call ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})," on the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val bundle = Wire(new MyBundle)\n bundle.foo := 0xc.U\n bundle.bar := 0x3.U\n val uint = bundle.asUInt\n printf(cf"$uint") // 195\n\n // Test\n assert(uint === 0xc3.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asTypeOf%5BT%3C:chisel3.Data%5D(that:T):T",children:(0,t.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,t.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val uint = 0xb4.U\n val bundle = uint.asTypeOf(new MyBundle)\n\n printf(cf"$bundle") // Bundle(foo -> 11, bar -> 4)\n\n // Test\n assert(bundle.foo === 0xb.U)\n assert(bundle.bar === 0x4.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"asTypeOf"})," as above. If you don't want to worry about the type of the thing\nyou are tying off, you can use ",(0,t.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = Vec(4, UInt(1.W))\n}\n\nclass Foo(typ: MyBundle) extends Module {\n val bundleA = IO(Output(typ))\n val bundleB = IO(Output(typ))\n\n // typ is already a Chisel Data Type, so can use it directly here, but you\n // need to know that bundleA is of type typ\n bundleA := 0.U.asTypeOf(typ)\n\n // bundleB is a Hardware data IO(Output(...)) so need to call chiselTypeOf,\n // but this will work no matter the type of bundleB:\n bundleB := 0.U.asTypeOf(chiselTypeOf(bundleB))\n}\n\nChiselStage.emitSystemVerilog(new Foo(new MyBundle))\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,t.jsx)(n.code,{children:"VecInit"})})," given a ",(0,t.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,t.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val uint = 0xc.U\n val vec = VecInit(uint.asBools)\n\n printf(cf"$vec") // Vec(0, 0, 1, 1)\n\n // Test\n assert(vec(0) === false.B)\n assert(vec(1) === false.B)\n assert(vec(2) === true.B)\n assert(vec(3) === true.B)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the builtin function ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val vec = VecInit(true.B, false.B, true.B, true.B)\n val uint = vec.asUInt\n\n printf(cf"$uint") // 13\n\n // Test\n // (remember leftmost Bool in Vec is low order bit)\n assert(0xd.U === uint)\n\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,t.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Yes. Using ",(0,t.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,t.jsx)(n.code,{children:"fill"})," and ",(0,t.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n //2D Fill\n val twoDVec = VecInit.fill(2, 3)(5.U)\n //3D Fill\n val myBundle = Wire(new MyBundle)\n myBundle.foo := 0xc.U\n myBundle.bar := 0x3.U\n val threeDVec = VecInit.fill(1, 2, 3)(myBundle)\n assert(threeDVec(0)(0)(0).foo === 0xc.U && threeDVec(0)(0)(0).bar === 0x3.U)\n\n //2D Tabulate\n val indexTiedVec = VecInit.tabulate(2, 2){ (x, y) => (x + y).U }\n assert(indexTiedVec(0)(0) === 0.U)\n assert(indexTiedVec(0)(1) === 1.U)\n assert(indexTiedVec(1)(0) === 1.U)\n assert(indexTiedVec(1)(1) === 2.U)\n //3D Tabulate\n val indexTiedVec3D = VecInit.tabulate(2, 3, 4){ (x, y, z) => (x + y * z).U }\n assert(indexTiedVec3D(0)(0)(0) === 0.U)\n assert(indexTiedVec3D(1)(1)(1) === 2.U)\n assert(indexTiedVec3D(1)(1)(2) === 3.U)\n assert(indexTiedVec3D(1)(1)(3) === 4.U)\n assert(indexTiedVec3D(1)(2)(3) === 7.U)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,t.jsxs)(n.p,{children:["You create a ",(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,t.jsx)(n.em,{children:"type"})," (like ",(0,t.jsx)(n.code,{children:"UInt"}),", ",(0,t.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,t.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,t.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"}),"\n",(0,t.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,t.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass Foo extends Module {\n val regOfVec = Reg(Vec(4, UInt(32.W))) // Register of 32-bit UInts\n regOfVec(0) := 123.U // Assignments to elements of the Vec\n regOfVec(1) := 456.U\n regOfVec(2) := 789.U\n regOfVec(3) := regOfVec(0)\n\n // Reg of Vec of 32-bit UInts initialized to zero\n // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0\n // VecInit(...) then constructs a Wire of these literals\n // The Reg is then initialized to the value of the Wire (which gives it the same type)\n val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.BundleLiterals._\n\nclass MyBundle extends Bundle {\n val foo = UInt(8.W)\n val bar = UInt(8.W)\n}\n\nclass MyModule extends Module {\n // Only .foo will be reset, .bar will have no reset value\n val reg = RegInit((new MyBundle).Lit(_.foo -> 123.U))\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If your initial value is not a literal, or if you just prefer, you can use a\nWire as the initial value for the Reg. Simply connect fields to ",(0,t.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MyModule2 extends Module {\n val reg = RegInit({\n // The wire could be constructed before the reg rather than in the RegInit scope,\n // but this style has nice lexical scoping behavior, keeping the Wire private\n val init = Wire(new MyBundle)\n init := DontCare // No fields will be reset\n init.foo := 123.U // Last connect override, .foo is reset\n init\n })\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-aliased-bundle-fields",children:[(0,t.jsx)("a",{name:"aliased-bundle-fields"})," How do I deal with aliased Bundle fields?"]}),"\n",(0,t.jsxs)(n.p,{children:["Following the ",(0,t.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AliasedBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AliasedBundle contains aliased fields named (bar,foo)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$Top..cloneType
directly",id:"4-call-clonetype-directly",level:4},{value:" How do I deal with the "unable to clone" error?",id:"-how-do-i-deal-with-the-unable-to-clone-error",level:3},{value:"How do I create a finite state machine (FSM)?",id:"how-do-i-create-a-finite-state-machine-fsm",level:3},{value:"How do I unpack a value ("reverse concatenation") like in Verilog?",id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",level:3},{value:"How do I do subword assignment (assign to some bits in a UInt)?",id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",level:3},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:3},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:3},{value:"How do I minimize the number of bits used in an output vector?",id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",level:3},{value:" How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?",id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",level:3},{value:"Use bit extraction when the index is too wide",id:"use-bit-extraction-when-the-index-is-too-wide",level:4},{value:"Predictable Naming",id:"predictable-naming",level:2},{value:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?",id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",level:3},{value:"How do I get Chisel to name the results of vector reads properly?",id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",level:3},{value:"How can I dynamically set/parametrize the name of a module?",id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",level:3},{value:"Directionality",id:"directionality",level:2},{value:"How do I strip directions from a bidirectional Bundle (or other Data)?",id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,t.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,t.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type Conversions","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Vectors and Registers","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#can-i-make-a-2D-or-3D-Vector",children:"Can I make a 2D or 3D Vector?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Bundles","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#bundle-unable-to-clone",children:'How do I deal with the "unable to clone" error?'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#dynamic-index-too-wide-narrow",children:'How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?'})}),"\n",(0,t.jsxs)(n.li,{children:["Predictable Naming","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Directionality","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"}),"\n",(0,t.jsxs)(n.p,{children:["Call ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})," on the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val bundle = Wire(new MyBundle)\n bundle.foo := 0xc.U\n bundle.bar := 0x3.U\n val uint = bundle.asUInt\n printf(cf"$uint") // 195\n\n // Test\n assert(uint === 0xc3.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asTypeOf%5BT%3C:chisel3.Data%5D(that:T):T",children:(0,t.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,t.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val uint = 0xb4.U\n val bundle = uint.asTypeOf(new MyBundle)\n\n printf(cf"$bundle") // Bundle(foo -> 11, bar -> 4)\n\n // Test\n assert(bundle.foo === 0xb.U)\n assert(bundle.bar === 0x4.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"asTypeOf"})," as above. If you don't want to worry about the type of the thing\nyou are tying off, you can use ",(0,t.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = Vec(4, UInt(1.W))\n}\n\nclass Foo(typ: MyBundle) extends Module {\n val bundleA = IO(Output(typ))\n val bundleB = IO(Output(typ))\n\n // typ is already a Chisel Data Type, so can use it directly here, but you\n // need to know that bundleA is of type typ\n bundleA := 0.U.asTypeOf(typ)\n\n // bundleB is a Hardware data IO(Output(...)) so need to call chiselTypeOf,\n // but this will work no matter the type of bundleB:\n bundleB := 0.U.asTypeOf(chiselTypeOf(bundleB))\n}\n\nChiselStage.emitSystemVerilog(new Foo(new MyBundle))\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,t.jsx)(n.code,{children:"VecInit"})})," given a ",(0,t.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,t.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val uint = 0xc.U\n val vec = VecInit(uint.asBools)\n\n printf(cf"$vec") // Vec(0, 0, 1, 1)\n\n // Test\n assert(vec(0) === false.B)\n assert(vec(1) === false.B)\n assert(vec(2) === true.B)\n assert(vec(3) === true.B)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the builtin function ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val vec = VecInit(true.B, false.B, true.B, true.B)\n val uint = vec.asUInt\n\n printf(cf"$uint") // 13\n\n // Test\n // (remember leftmost Bool in Vec is low order bit)\n assert(0xd.U === uint)\n\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,t.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Yes. Using ",(0,t.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,t.jsx)(n.code,{children:"fill"})," and ",(0,t.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n //2D Fill\n val twoDVec = VecInit.fill(2, 3)(5.U)\n //3D Fill\n val myBundle = Wire(new MyBundle)\n myBundle.foo := 0xc.U\n myBundle.bar := 0x3.U\n val threeDVec = VecInit.fill(1, 2, 3)(myBundle)\n assert(threeDVec(0)(0)(0).foo === 0xc.U && threeDVec(0)(0)(0).bar === 0x3.U)\n\n //2D Tabulate\n val indexTiedVec = VecInit.tabulate(2, 2){ (x, y) => (x + y).U }\n assert(indexTiedVec(0)(0) === 0.U)\n assert(indexTiedVec(0)(1) === 1.U)\n assert(indexTiedVec(1)(0) === 1.U)\n assert(indexTiedVec(1)(1) === 2.U)\n //3D Tabulate\n val indexTiedVec3D = VecInit.tabulate(2, 3, 4){ (x, y, z) => (x + y * z).U }\n assert(indexTiedVec3D(0)(0)(0) === 0.U)\n assert(indexTiedVec3D(1)(1)(1) === 2.U)\n assert(indexTiedVec3D(1)(1)(2) === 3.U)\n assert(indexTiedVec3D(1)(1)(3) === 4.U)\n assert(indexTiedVec3D(1)(2)(3) === 7.U)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,t.jsxs)(n.p,{children:["You create a ",(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,t.jsx)(n.em,{children:"type"})," (like ",(0,t.jsx)(n.code,{children:"UInt"}),", ",(0,t.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,t.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,t.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"}),"\n",(0,t.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,t.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass Foo extends Module {\n val regOfVec = Reg(Vec(4, UInt(32.W))) // Register of 32-bit UInts\n regOfVec(0) := 123.U // Assignments to elements of the Vec\n regOfVec(1) := 456.U\n regOfVec(2) := 789.U\n regOfVec(3) := regOfVec(0)\n\n // Reg of Vec of 32-bit UInts initialized to zero\n // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0\n // VecInit(...) then constructs a Wire of these literals\n // The Reg is then initialized to the value of the Wire (which gives it the same type)\n val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.BundleLiterals._\n\nclass MyBundle extends Bundle {\n val foo = UInt(8.W)\n val bar = UInt(8.W)\n}\n\nclass MyModule extends Module {\n // Only .foo will be reset, .bar will have no reset value\n val reg = RegInit((new MyBundle).Lit(_.foo -> 123.U))\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If your initial value is not a literal, or if you just prefer, you can use a\nWire as the initial value for the Reg. Simply connect fields to ",(0,t.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MyModule2 extends Module {\n val reg = RegInit({\n // The wire could be constructed before the reg rather than in the RegInit scope,\n // but this style has nice lexical scoping behavior, keeping the Wire private\n val init = Wire(new MyBundle)\n init := DontCare // No fields will be reset\n init.foo := 123.U // Last connect override, .foo is reset\n init\n })\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-aliased-bundle-fields",children:[(0,t.jsx)("a",{name:"aliased-bundle-fields"})," How do I deal with aliased Bundle fields?"]}),"\n",(0,t.jsxs)(n.p,{children:["Following the ",(0,t.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AliasedBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AliasedBundle contains aliased fields named (bar,foo)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$Top.type mismatch
specifying width/value of a UInt
/SInt
",id:"type-mismatch-specifying-widthvalue-of-a-uintsint",level:3}];function d(e){const n={code:"code",em:"em",h1:"h1",h3:"h3",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.p,{children:"This page is a starting point for recording common and not so common problems in developing with Chisel3. In particular, those situations where there is a work around that will keep you going."}),"\n",(0,o.jsxs)(n.h3,{id:"type-mismatch-specifying-widthvalue-of-a-uintsint",children:[(0,o.jsx)(n.code,{children:"type mismatch"})," specifying width/value of a ",(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["I have some old code that used to work correctly in chisel2 (and still does if I use the ",(0,o.jsx)(n.code,{children:"import Chisel._"})," compatibility layer)\nbut causes a ",(0,o.jsx)(n.code,{children:"type mismatch"})," error in straight chisel3:"]})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"class TestBlock extends Module {\n\tval io = IO(new Bundle {\n\t\tval output = Output(UInt(width=3))\n\t})\n}\n"})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"produces"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"type mismatch;\n[error] found : Int(3)\n[error] required: chisel3.internal.firrtl.Width\n[error] \t\tval output = Output(UInt(width=3))\n"})}),"\n",(0,o.jsx)(n.p,{children:"The single argument, multi-function object/constructors from chisel2 have been removed from chisel3.\nIt was felt these were too prone to error and made it difficult to diagnose error conditions in chisel3 code."}),"\n",(0,o.jsxs)(n.p,{children:["In chisel3, the single argument to the ",(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})," object/constructor specifies the ",(0,o.jsx)(n.em,{children:"width"})," and must be a ",(0,o.jsx)(n.code,{children:"Width"})," type.\nAlthough there are no automatic conversions from ",(0,o.jsx)(n.code,{children:"Int"})," to ",(0,o.jsx)(n.code,{children:"Width"}),", an ",(0,o.jsx)(n.code,{children:"Int"})," may be converted to a ",(0,o.jsx)(n.code,{children:"Width"})," by applying the ",(0,o.jsx)(n.code,{children:"W"})," method to an ",(0,o.jsx)(n.code,{children:"Int"}),".\nIn chisel3, the above code becomes:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass TestBlock extends Module {\n\tval io = IO(new Bundle {\n\t\tval output = Output(UInt(3.W))\n\t})\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})," literals may be created from an ",(0,o.jsx)(n.code,{children:"Int"})," with the application of either the ",(0,o.jsx)(n.code,{children:"U"})," or ",(0,o.jsx)(n.code,{children:"S"})," method."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"UInt(42)\n// error: type mismatch;\n// found : Int(42)\n// required: chisel3.internal.firrtl.Width\n// UInt(42)\n// ^^\n"})}),"\n",(0,o.jsx)(n.p,{children:"in chisel2, becomes"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"42.U\n"})}),"\n",(0,o.jsx)(n.p,{children:"in chisel3"}),"\n",(0,o.jsxs)(n.p,{children:["A literal with a specific width is created by calling the ",(0,o.jsx)(n.code,{children:"U"})," or ",(0,o.jsx)(n.code,{children:"S"})," method with a ",(0,o.jsx)(n.code,{children:"W"})," argument.\nUse:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"1.S(8.W)\n"})}),"\n",(0,o.jsx)(n.p,{children:"to create an 8-bit wide (signed) literal with value 1."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>c});var o=t(7294);const i={},s=o.createContext(i);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
+"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[9948],{2631:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=t(5893),i=t(1151);const s={layout:"docs",title:"Troubleshooting",section:"chisel3"},c="Troubleshooting",r={id:"cookbooks/troubleshooting",title:"Troubleshooting",description:"This page is a starting point for recording common and not so common problems in developing with Chisel3. In particular, those situations where there is a work around that will keep you going.",source:"@site/docs/cookbooks/troubleshooting.md",sourceDirName:"cookbooks",slug:"/cookbooks/troubleshooting",permalink:"/docs/cookbooks/troubleshooting",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/cookbooks/troubleshooting.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Troubleshooting",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Serialization Cookbook",permalink:"/docs/cookbooks/serialization"},next:{title:"Explanations",permalink:"/docs/explanations/"}},l={},d=[{value:"type mismatch
specifying width/value of a UInt
/SInt
",id:"type-mismatch-specifying-widthvalue-of-a-uintsint",level:3}];function a(e){const n={code:"code",em:"em",h1:"h1",h3:"h3",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.p,{children:"This page is a starting point for recording common and not so common problems in developing with Chisel3. In particular, those situations where there is a work around that will keep you going."}),"\n",(0,o.jsxs)(n.h3,{id:"type-mismatch-specifying-widthvalue-of-a-uintsint",children:[(0,o.jsx)(n.code,{children:"type mismatch"})," specifying width/value of a ",(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["I have some old code that used to work correctly in chisel2 (and still does if I use the ",(0,o.jsx)(n.code,{children:"import Chisel._"})," compatibility layer)\nbut causes a ",(0,o.jsx)(n.code,{children:"type mismatch"})," error in straight chisel3:"]})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"class TestBlock extends Module {\n\tval io = IO(new Bundle {\n\t\tval output = Output(UInt(width=3))\n\t})\n}\n"})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"produces"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"type mismatch;\n[error] found : Int(3)\n[error] required: chisel3.internal.firrtl.Width\n[error] \t\tval output = Output(UInt(width=3))\n"})}),"\n",(0,o.jsx)(n.p,{children:"The single argument, multi-function object/constructors from chisel2 have been removed from chisel3.\nIt was felt these were too prone to error and made it difficult to diagnose error conditions in chisel3 code."}),"\n",(0,o.jsxs)(n.p,{children:["In chisel3, the single argument to the ",(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})," object/constructor specifies the ",(0,o.jsx)(n.em,{children:"width"})," and must be a ",(0,o.jsx)(n.code,{children:"Width"})," type.\nAlthough there are no automatic conversions from ",(0,o.jsx)(n.code,{children:"Int"})," to ",(0,o.jsx)(n.code,{children:"Width"}),", an ",(0,o.jsx)(n.code,{children:"Int"})," may be converted to a ",(0,o.jsx)(n.code,{children:"Width"})," by applying the ",(0,o.jsx)(n.code,{children:"W"})," method to an ",(0,o.jsx)(n.code,{children:"Int"}),".\nIn chisel3, the above code becomes:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass TestBlock extends Module {\n\tval io = IO(new Bundle {\n\t\tval output = Output(UInt(3.W))\n\t})\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"UInt"}),"/",(0,o.jsx)(n.code,{children:"SInt"})," literals may be created from an ",(0,o.jsx)(n.code,{children:"Int"})," with the application of either the ",(0,o.jsx)(n.code,{children:"U"})," or ",(0,o.jsx)(n.code,{children:"S"})," method."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"UInt(42)\n// error: type mismatch;\n// found : Int(42)\n// required: chisel3.Width\n// UInt(42)\n// ^^\n"})}),"\n",(0,o.jsx)(n.p,{children:"in chisel2, becomes"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"42.U\n"})}),"\n",(0,o.jsx)(n.p,{children:"in chisel3"}),"\n",(0,o.jsxs)(n.p,{children:["A literal with a specific width is created by calling the ",(0,o.jsx)(n.code,{children:"U"})," or ",(0,o.jsx)(n.code,{children:"S"})," method with a ",(0,o.jsx)(n.code,{children:"W"})," argument.\nUse:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-scala",children:"1.S(8.W)\n"})}),"\n",(0,o.jsx)(n.p,{children:"to create an 8-bit wide (signed) literal with value 1."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>c});var o=t(7294);const i={},s=o.createContext(i);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/d1e6e3d8.e91ac924.js b/assets/js/d1e6e3d8.c2676c71.js
similarity index 99%
rename from assets/js/d1e6e3d8.e91ac924.js
rename to assets/js/d1e6e3d8.c2676c71.js
index 0e867426a1..bf7fb7f2aa 100644
--- a/assets/js/d1e6e3d8.e91ac924.js
+++ b/assets/js/d1e6e3d8.c2676c71.js
@@ -1 +1 @@
-"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[2705],{4564:(n,e,o)=>{o.r(e),o.d(e,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var i=o(5893),t=o(1151);const a={layout:"docs",title:"Deep Dive into <> and := Connection Operators",section:"chisel3"},c="Deep Dive into Connection Operators",s={id:"explanations/connection-operators",title:"Deep Dive into <> and := Connection Operators",description:"Chisel contains two connection operators, := and `. This document provides a deeper explanation of the differences of the two and when to use one or the other. The differences are demonstrated with experiments using Scastie examples which use DecoupledIO`.",source:"@site/docs/explanations/connection-operators.md",sourceDirName:"explanations",slug:"/explanations/connection-operators",permalink:"/docs/explanations/connection-operators",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/explanations/connection-operators.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Deep Dive into <> and := Connection Operators",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Connectable Operators",permalink:"/docs/explanations/connectable"},next:{title:"Chisel Data Types",permalink:"/docs/explanations/data-types"}},r={},l=[{value:"Experiment Setup",id:"experiment-setup",level:3},{value:"Concept 1: <>
is Commutative",id:"concept-1--is-commutative",level:2},{value:"Conclusion:",id:"conclusion",level:3},{value:"Concept 2: :=
means assign ALL LHS signals from the RHS, regardless of the direction on the LHS.",id:"concept-2--means-assign-all-lhs-signals-from-the-rhs-regardless-of-the-direction-on-the-lhs",level:2},{value:"Conclusion:",id:"conclusion-1",level:3},{value:"Concept 3: Always Use :=
to assign DontCare to Wires",id:"concept-3-always-use--to-assign-dontcare-to-wires",level:2},{value:"Conclusion:",id:"conclusion-2",level:3},{value:"Concept 4: You can use <>
or :=
to assign DontCare
to directioned things (IOs)",id:"concept-4-you-can-use--or--to-assign-dontcare-to-directioned-things-ios",level:2},{value:"Conclusion:",id:"conclusion-3",level:3},{value:"Concept 5: <>
works between things with at least one known flow (An IO or child's IO).",id:"concept-5---works-between-things-with-at-least-one-known-flow-an-io-or-childs-io",level:2},{value:"Conclusion:",id:"conclusion-4",level:3},{value:"Concept 6: <>
and :=
connect signals by field name.",id:"concept-6--and--connect-signals-by-field-name",level:2},{value:"Conclusion:",id:"conclusion-5",level:3}];function d(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,t.a)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"deep-dive-into-connection-operators",children:"Deep Dive into Connection Operators"}),"\n",(0,i.jsxs)(e.p,{children:["Chisel contains two connection operators, ",(0,i.jsx)(e.code,{children:":="})," and ",(0,i.jsx)(e.code,{children:"<>"}),". This document provides a deeper explanation of the differences of the two and when to use one or the other. The differences are demonstrated with experiments using Scastie examples which use ",(0,i.jsx)(e.code,{children:"DecoupledIO"}),"."]}),"\n",(0,i.jsx)(e.h3,{id:"experiment-setup",children:"Experiment Setup"}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:"// Imports used by the following examples\nimport chisel3._\nimport chisel3.util.DecoupledIO\nimport circt.stage.ChiselStage\n"})}),"\n",(0,i.jsxs)(e.p,{children:["The diagram for the experiment can be viewed ",(0,i.jsx)(e.a,{href:"https://docs.google.com/document/d/14C918Hdahk2xOGSJJBT-ZVqAx99_hg3JQIq-vaaifQU/edit?usp=sharing",children:"here"}),".\n",(0,i.jsx)(e.img,{src:"https://raw.githubusercontent.com/chipsalliance/chisel3/master/docs/src/images/connection-operators-experiment.svg?sanitize=true",alt:"Experiment Image"})]}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:"\nclass Wrapper extends Module{\n val io = IO(new Bundle {\n val in = Flipped(DecoupledIO(UInt(8.W)))\n val out = DecoupledIO(UInt(8.W))\n })\n val p = Module(new PipelineStage)\n val c = Module(new PipelineStage)\n // connect Producer to IO\n p.io.a <> io.in\n // connect producer to consumer\n c.io.a <> p.io.b\n // connect consumer to IO\n io.out <> c.io.b\n}\nclass PipelineStage extends Module{\n val io = IO(new Bundle{\n val a = Flipped(DecoupledIO(UInt(8.W)))\n val b = DecoupledIO(UInt(8.W))\n })\n io.b <> io.a\n}\n"})}),"\n",(0,i.jsx)(e.p,{children:"Below we can see the resulting Verilog for this example:"}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:'ChiselStage.emitSystemVerilog(new Wrapper)\n// res0: String = """// Generated by CIRCT firtool-1.62.0\n// module PipelineStage(\t// connection-operators.md:36:7\n// output io_a_ready,\t// connection-operators.md:37:14\n// input io_a_valid,\t// connection-operators.md:37:14\n// input [7:0] io_a_bits,\t// connection-operators.md:37:14\n// input io_b_ready,\t// connection-operators.md:37:14\n// output io_b_valid,\t// connection-operators.md:37:14\n// output [7:0] io_b_bits\t// connection-operators.md:37:14\n// );\n// \n// assign io_a_ready = io_b_ready;\t// connection-operators.md:36:7\n// assign io_b_valid = io_a_valid;\t// connection-operators.md:36:7\n// assign io_b_bits = io_a_bits;\t// connection-operators.md:36:7\n// endmodule\n// \n// module Wrapper(\t// connection-operators.md:20:7\n// input clock,\t// <>
is Commutative",id:"concept-1--is-commutative",level:2},{value:"Conclusion:",id:"conclusion",level:3},{value:"Concept 2: :=
means assign ALL LHS signals from the RHS, regardless of the direction on the LHS.",id:"concept-2--means-assign-all-lhs-signals-from-the-rhs-regardless-of-the-direction-on-the-lhs",level:2},{value:"Conclusion:",id:"conclusion-1",level:3},{value:"Concept 3: Always Use :=
to assign DontCare to Wires",id:"concept-3-always-use--to-assign-dontcare-to-wires",level:2},{value:"Conclusion:",id:"conclusion-2",level:3},{value:"Concept 4: You can use <>
or :=
to assign DontCare
to directioned things (IOs)",id:"concept-4-you-can-use--or--to-assign-dontcare-to-directioned-things-ios",level:2},{value:"Conclusion:",id:"conclusion-3",level:3},{value:"Concept 5: <>
works between things with at least one known flow (An IO or child's IO).",id:"concept-5---works-between-things-with-at-least-one-known-flow-an-io-or-childs-io",level:2},{value:"Conclusion:",id:"conclusion-4",level:3},{value:"Concept 6: <>
and :=
connect signals by field name.",id:"concept-6--and--connect-signals-by-field-name",level:2},{value:"Conclusion:",id:"conclusion-5",level:3}];function d(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,t.a)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"deep-dive-into-connection-operators",children:"Deep Dive into Connection Operators"}),"\n",(0,i.jsxs)(e.p,{children:["Chisel contains two connection operators, ",(0,i.jsx)(e.code,{children:":="})," and ",(0,i.jsx)(e.code,{children:"<>"}),". This document provides a deeper explanation of the differences of the two and when to use one or the other. The differences are demonstrated with experiments using Scastie examples which use ",(0,i.jsx)(e.code,{children:"DecoupledIO"}),"."]}),"\n",(0,i.jsx)(e.h3,{id:"experiment-setup",children:"Experiment Setup"}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:"// Imports used by the following examples\nimport chisel3._\nimport chisel3.util.DecoupledIO\nimport circt.stage.ChiselStage\n"})}),"\n",(0,i.jsxs)(e.p,{children:["The diagram for the experiment can be viewed ",(0,i.jsx)(e.a,{href:"https://docs.google.com/document/d/14C918Hdahk2xOGSJJBT-ZVqAx99_hg3JQIq-vaaifQU/edit?usp=sharing",children:"here"}),".\n",(0,i.jsx)(e.img,{src:"https://raw.githubusercontent.com/chipsalliance/chisel3/master/docs/src/images/connection-operators-experiment.svg?sanitize=true",alt:"Experiment Image"})]}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:"\nclass Wrapper extends Module{\n val io = IO(new Bundle {\n val in = Flipped(DecoupledIO(UInt(8.W)))\n val out = DecoupledIO(UInt(8.W))\n })\n val p = Module(new PipelineStage)\n val c = Module(new PipelineStage)\n // connect Producer to IO\n p.io.a <> io.in\n // connect producer to consumer\n c.io.a <> p.io.b\n // connect consumer to IO\n io.out <> c.io.b\n}\nclass PipelineStage extends Module{\n val io = IO(new Bundle{\n val a = Flipped(DecoupledIO(UInt(8.W)))\n val b = DecoupledIO(UInt(8.W))\n })\n io.b <> io.a\n}\n"})}),"\n",(0,i.jsx)(e.p,{children:"Below we can see the resulting Verilog for this example:"}),"\n",(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:"language-scala",children:'ChiselStage.emitSystemVerilog(new Wrapper)\n// res0: String = """// Generated by CIRCT firtool-1.62.0\n// module PipelineStage(\t// connection-operators.md:36:7\n// output io_a_ready,\t// connection-operators.md:37:14\n// input io_a_valid,\t// connection-operators.md:37:14\n// input [7:0] io_a_bits,\t// connection-operators.md:37:14\n// input io_b_ready,\t// connection-operators.md:37:14\n// output io_b_valid,\t// connection-operators.md:37:14\n// output [7:0] io_b_bits\t// connection-operators.md:37:14\n// );\n// \n// assign io_a_ready = io_b_ready;\t// connection-operators.md:36:7\n// assign io_b_valid = io_a_valid;\t// connection-operators.md:36:7\n// assign io_b_bits = io_a_bits;\t// connection-operators.md:36:7\n// endmodule\n// \n// module Wrapper(\t// connection-operators.md:20:7\n// input clock,\t// getVerilogString(new Top(new UsingAFunctionBundle(() => UInt(8.W))))
Warning: you must ensure that gen
creates fresh objects rather than capturing an already constructed value:
class MisusedFunctionArguments extends Module {
// This usage is correct
val in = IO(Input(new UsingAFunctionBundle(() => UInt(8.W))))
// This usage is incorrect
val fizz = UInt(8.W)
val out = IO(Output(new UsingAFunctionBundle(() => fizz)))
}
getVerilogString(new MisusedFunctionArguments)
// chisel3.AutoClonetypeException: The bundle plugin was unable to clone UsingAFunctionBundle that has field 'foo' aliased with base UsingAFunctionBundle.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry 'How do I deal with the "unable to clone" error?' for more details.
// at ... ()
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)
// at chisel3.IO$.apply(IO.scala:35)
// at chisel3.experimental.BaseModule.IO(Module.scala:765)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)
// at chisel3.experimental.prefix$.apply(prefix.scala:50)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1.<init>(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)
// at repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
class MisusedFunctionArguments extends Module {
// This usage is correct
val in = IO(Input(new UsingAFunctionBundle(() => UInt(8.W))))
// This usage is incorrect
val fizz = UInt(8.W)
val out = IO(Output(new UsingAFunctionBundle(() => fizz)))
}
getVerilogString(new MisusedFunctionArguments)
// chisel3.AutoClonetypeException: The bundle plugin was unable to clone UsingAFunctionBundle that has field 'foo' aliased with base UsingAFunctionBundle.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry 'How do I deal with the "unable to clone" error?' for more details.
// at ... ()
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)
// at chisel3.IO$.apply(IO.scala:35)
// at chisel3.experimental.BaseModule.IO(Module.scala:760)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)
// at chisel3.experimental.prefix$.apply(prefix.scala:50)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1.<init>(cookbook.md:370)
// at repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)
// at repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
In the above example, value fizz
and fields foo
and bar
of out
are all the same object in memory.
Functionally the same as (1) but with more subtle syntax, you can use Scala by-name function parameters:
@@ -239,7 +239,7 @@import chisel3._
import circt.stage.ChiselStage
import chisel3.util.Decoupled
class BadRegConnect extends Module {
val io = IO(new Bundle {
val enq = Decoupled(UInt(8.W))
})
val monitor = Reg(chiselTypeOf(io.enq))
monitor := io.enq
}
ChiselStage.emitSystemVerilog(new BadRegConnect)
// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: /home/runner/.cache/llvm-firtool/1.62.0/bin/firtool returned a non-zero exit code. Note that this version of Chisel (6.0.0-RC1+27-7b8ffad1-SNAPSHOT) was published against firtool version 1.62.0.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:985:20: error: 'firrtl.reg' op result #0 must be a passive non-'const' base type that does not contain analog, but got '!firrtl.bundle<ready flip: uint<1>, valid: uint<1>, bits: uint<8>>'
// cookbook.md:985:20: note: see current operation: %4 = "firrtl.reg"(%arg0) {annotations = [], name = "monitor", nameKind = #firrtl<name_kind interesting_name>} : (!firrtl.clock) -> !firrtl.bundle<ready flip: uint<1>, valid: uint<1>, bits: uint<8>>
//
// ------------------------------------------------------------------------------
ChiselStage.emitSystemVerilog(new BadRegConnect)
// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: /home/runner/.cache/llvm-firtool/1.62.0/bin/firtool returned a non-zero exit code. Note that this version of Chisel (6.0.0-RC1+28-77a3bff4-SNAPSHOT) was published against firtool version 1.62.0.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:985:20: error: 'firrtl.reg' op result #0 must be a passive non-'const' base type that does not contain analog, but got '!firrtl.bundle<ready flip: uint<1>, valid: uint<1>, bits: uint<8>>'
// cookbook.md:985:20: note: see current operation: %4 = "firrtl.reg"(%arg0) {annotations = [], name = "monitor", nameKind = #firrtl<name_kind interesting_name>} : (!firrtl.clock) -> !firrtl.bundle<ready flip: uint<1>, valid: uint<1>, bits: uint<8>>
//
// ------------------------------------------------------------------------------
While there is no construct to "strip direction" in Chisel3, wrapping a type in Output(...)
(the default direction in Chisel3) will
set all of the individual elements to output direction.
diff --git a/docs/cookbooks/dataview.html b/docs/cookbooks/dataview.html
index ba44198227..53ed9342d9 100644
--- a/docs/cookbooks/dataview.html
+++ b/docs/cookbooks/dataview.html
@@ -4,7 +4,7 @@
import chisel3._
import chisel3.experimental.hierarchy.{Definition, Instance, instantiable, IsLookupable, public}
case class MyCaseClass(width: Int) extends IsLookupable
@instantiable
class MyModule extends Module {
@public val x = MyCaseClass(10)
}
class Top extends Module {
val inst = Instance(Definition(new MyModule))
println(s"Width is ${inst.x.width}")
}
Width is 10
Circuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@52879e53,MyModule,List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo)),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@2d4b8cb5,Top,List(Port(Top.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(Top.reset: IO[Bool],Input,UnlocatableSourceInfo)),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@52879e53),List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo))), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.clock: IO[Clock]),Node(Top.clock: IO[Clock])), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.reset: IO[Reset]),Node(Top.reset: IO[Bool]))))),List(),firrtl.renamemap.package$MutableRenameMap@510546e6,List(),List(),List(),List())
Width is 10
Circuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@1595343,MyModule,List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo)),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@5d389d9b,Top,List(Port(Top.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(Top.reset: IO[Bool],Input,UnlocatableSourceInfo)),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@1595343),List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo))), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.clock: IO[Clock]),Node(Top.clock: IO[Clock])), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.reset: IO[Reset]),Node(Top.reset: IO[Bool]))))),List(),firrtl.renamemap.package$MutableRenameMap@3f0acbef,List(),List(),List(),List())
Just like Instance
s, Definition
's also contain accessors for @public
members.
As such, you can directly access them:
import chisel3._
class TestBlock extends Module {
val io = IO(new Bundle {
val output = Output(UInt(3.W))
})
}
UInt
/SInt
literals may be created from an Int
with the application of either the U
or S
method.
UInt(42)
// error: type mismatch;
// found : Int(42)
// required: chisel3.internal.firrtl.Width
// UInt(42)
// ^^
UInt(42)
// error: type mismatch;
// found : Int(42)
// required: chisel3.Width
// UInt(42)
// ^^
in chisel2, becomes
42.U
in chisel3
diff --git a/docs/developers.html b/docs/developers.html index 6a5faec4d3..a3503aa23b 100644 --- a/docs/developers.html +++ b/docs/developers.html @@ -4,7 +4,7 @@elaborate(new ScalaCastingModule( () => new MyBundle(3)))
But if we are wrong, we can get a Scala runtime exception:
-class NotMyBundle extends Bundle {val baz = Bool()}
elaborate(new ScalaCastingModule(() => new NotMyBundle()))
// java.lang.ClassCastException: class repl.MdocSession$MdocApp$$anonfun$79$NotMyBundle$1 cannot be cast to class repl.MdocSession$MdocApp$MyBundle (repl.MdocSession$MdocApp$$anonfun$79$NotMyBundle$1 and repl.MdocSession$MdocApp$MyBundle are in unnamed module of loader scala.reflect.internal.util.AbstractFileClassLoader @303d47d)
// at ... ()
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.SpecifiedDirection$.specifiedDirection(Data.scala:66)
// at chisel3.Output$.apply(Data.scala:269)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.IO$.apply(IO.scala:35)
// at chisel3.experimental.BaseModule.IO(Module.scala:765)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.experimental.prefix$.apply(prefix.scala:50)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp$ScalaCastingModule.<init>(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)
// at repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
class NotMyBundle extends Bundle {val baz = Bool()}
elaborate(new ScalaCastingModule(() => new NotMyBundle()))
// java.lang.ClassCastException: class repl.MdocSession$MdocApp$$anonfun$79$NotMyBundle$1 cannot be cast to class repl.MdocSession$MdocApp$MyBundle (repl.MdocSession$MdocApp$$anonfun$79$NotMyBundle$1 and repl.MdocSession$MdocApp$MyBundle are in unnamed module of loader scala.reflect.internal.util.AbstractFileClassLoader @3fcf636a)
// at ... ()
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.SpecifiedDirection$.specifiedDirection(Data.scala:66)
// at chisel3.Output$.apply(Data.scala:269)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.IO$.apply(IO.scala:35)
// at chisel3.experimental.BaseModule.IO(Module.scala:760)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)
// at chisel3.experimental.prefix$.apply(prefix.scala:50)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp$ScalaCastingModule.<init>(chisel-type-vs-scala-type.md:293)
// at repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)
// at repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
.asTypeOf
is a conversion from one Data
subclass to another.
It is commonly used to assign data to all-zeros, as described in this cookbook recipe, but it can
also be used (though not really recommended, as there is no checking on
diff --git a/docs/explanations/combinational-circuits.html b/docs/explanations/combinational-circuits.html
index e206076d2f..7d8c6472bd 100644
--- a/docs/explanations/combinational-circuits.html
+++ b/docs/explanations/combinational-circuits.html
@@ -4,7 +4,7 @@
import chisel3._
import chisel3.util.DecoupledIO
import circt.stage.ChiselStage
class Wrapper extends Module{
val io = IO(new Bundle {
val in = Flipped(DecoupledIO(UInt(8.W)))
val out = DecoupledIO(UInt(8.W))
})
val p = Module(new PipelineStage)
val c = Module(new PipelineStage)
// connect producer to I/O
p.io.a := io.in
// connect producer to consumer
c.io.a := p.io.b
// connect consumer to I/O
io.out := c.io.b
}
class PipelineStage extends Module{
val io = IO(new Bundle{
val a = Flipped(DecoupledIO(UInt(8.W)))
val b = DecoupledIO(UInt(8.W))
})
io.a := io.b
}
Below we can see the resulting error message for this example:
-ChiselStage.emitSystemVerilog(new Wrapper)
// chisel3.package$ChiselException: Connection between sink (PipelineStage.io.a: IO[DecoupledIO]) and source (PipelineStage.io.b: IO[DecoupledIO]) failed @: .bitsio.a.bits in PipelineStage cannot be written from module PipelineStage.
// at ... ()
// at repl.MdocSession$MdocApp3$PipelineStage.<init>(connection-operators.md:133)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30$$anonfun$apply$20.apply(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30$$anonfun$apply$20.apply(connection-operators.md:117)
// at chisel3.Module$.evaluate(Module.scala:91)
// at chisel3.Module$.do_apply(Module.scala:38)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30.apply(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30.apply(connection-operators.md:117)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp3$Wrapper.<init>(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$$anonfun$39$$anonfun$apply$25.apply(connection-operators.md:141)
// at repl.MdocSession$MdocApp3$$anonfun$39$$anonfun$apply$25.apply(connection-operators.md:141)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
ChiselStage.emitSystemVerilog(new Wrapper)
// chisel3.package$ChiselException: Connection between sink (PipelineStage.io.a: IO[DecoupledIO]) and source (PipelineStage.io.b: IO[DecoupledIO]) failed @: .bitsio.a.bits in PipelineStage cannot be written from module PipelineStage.
// at ... ()
// at repl.MdocSession$MdocApp3$PipelineStage.<init>(connection-operators.md:133)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30$$anonfun$apply$20.apply(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30$$anonfun$apply$20.apply(connection-operators.md:117)
// at chisel3.Module$.evaluate(Module.scala:88)
// at chisel3.Module$.do_apply(Module.scala:35)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30.apply(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$Wrapper$$anonfun$30.apply(connection-operators.md:117)
// at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)
// at repl.MdocSession$MdocApp3$Wrapper.<init>(connection-operators.md:117)
// at repl.MdocSession$MdocApp3$$anonfun$39$$anonfun$apply$25.apply(connection-operators.md:141)
// at repl.MdocSession$MdocApp3$$anonfun$39$$anonfun$apply$25.apply(connection-operators.md:141)
// at ... ()
// at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
The := operator goes field-by-field on the LHS and attempts to connect it to the same-named signal from the RHS. If something on the LHS is actually an Input, or the corresponding signal on the RHS is an Output, you will get an error as shown above.
:=
to assign DontCare to Wires​