- Latest (6.6.0) -
- Snapshot +
- Snapshot
- 7.0.0-M2
- 6.6.0
- 5.3.0 diff --git a/index.html b/index.html index eaedb1ed2b..94c01d0139 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@
diff --git a/404.html b/404.html index fefd4c99a0..e9bd026cc8 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(a){const e={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,t.R)(),...a.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(e.header,{children:(0,l.jsx)(e.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"})}),"\n",(0,l.jsxs)(e.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(e.code,{children:"false.B"}),", ",(0,l.jsx)(e.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(e.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(e.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(e.p,{children:["The ",(0,l.jsx)(e.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(e.code,{children:"Bool"}),", ",(0,l.jsx)(e.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(e.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.p,{children:["The ",(0,l.jsx)(e.em,{children:"Chisel"})," type of a ",(0,l.jsx)(e.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)(e.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(e.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(e.p,{children:["Hardware is ",(0,l.jsx)(e.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(e.code,{children:"false.B"})," or ",(0,l.jsx)(e.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)(e.p,{children:["A literal is a ",(0,l.jsx)(e.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(e.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(e.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(e.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(e.p,{children:[(0,l.jsx)(e.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.p,{children:["Can only ",(0,l.jsx)(e.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.pre,{children:(0,l.jsx)(e.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(a){const e={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,t.R)(),...a.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(e.header,{children:(0,l.jsx)(e.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"})}),"\n",(0,l.jsxs)(e.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(e.code,{children:"false.B"}),", ",(0,l.jsx)(e.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(e.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(e.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(e.p,{children:["The ",(0,l.jsx)(e.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(e.code,{children:"Bool"}),", ",(0,l.jsx)(e.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(e.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.p,{children:["The ",(0,l.jsx)(e.em,{children:"Chisel"})," type of a ",(0,l.jsx)(e.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)(e.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(e.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(e.p,{children:["Hardware is ",(0,l.jsx)(e.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(e.code,{children:"false.B"})," or ",(0,l.jsx)(e.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)(e.p,{children:["A literal is a ",(0,l.jsx)(e.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(e.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(e.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(e.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(e.p,{children:[(0,l.jsx)(e.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.p,{children:["Can only ",(0,l.jsx)(e.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.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)(e.pre,{children:(0,l.jsx)(e.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:2},{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:2},{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:2},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:2},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:2},{value:"How do I override the implicit clock or reset within a Module?",id:"how-do-i-override-the-implicit-clock-or-reset-within-a-module",level:2},{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:2},{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:2},{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 u(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{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","\n",(0,t.jsx)(l.A,{toc:d}),"\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._\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"})}),"\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.jsx)(n.h3,{id:"how-do-i-deal-with-aliased-bundle-fields",children:"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 (foo,bar)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:298)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:298)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:298)\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:2},{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:2},{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:2},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:2},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:2},{value:"How do I override the implicit clock or reset within a Module?",id:"how-do-i-override-the-implicit-clock-or-reset-within-a-module",level:2},{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:2},{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:2},{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 u(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{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","\n",(0,t.jsx)(l.A,{toc:d}),"\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._\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"})}),"\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.jsx)(n.h3,{id:"how-do-i-deal-with-aliased-bundle-fields",children:"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 (foo,bar)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:298)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:298)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:298)\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.import chisel3._
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
}
getVerilogString(new BadRegConnect)
// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: /home/runner/.cache/llvm-firtool/1.99.2/bin/firtool returned a non-zero exit code. Note that this version of Chisel (7.0.0-M2+244-841dc010-SNAPSHOT) was published against firtool version 1.99.2.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:1013: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:1013: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>>
//
// ------------------------------------------------------------------------------
getVerilogString(new BadRegConnect)
// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: /home/runner/.cache/llvm-firtool/1.99.2/bin/firtool returned a non-zero exit code. Note that this version of Chisel (7.0.0-M2+263-08b3342c-SNAPSHOT) was published against firtool version 1.99.2.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:1013: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:1013: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 5e839ab089..1d2271b2d6 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@32fb33d7,MyModule,false,List(),List(Port(MyModule.clock: IO[Clock],Input,SourceLine(hierarchy.md,105,2)), Port(MyModule.reset: IO[Reset],Input,SourceLine(hierarchy.md,105,2))),chisel3.internal.firrtl.ir$Block@69a66d1f), DefModule(repl.MdocSession$MdocApp5$Top@c681747,Top,true,List(),List(Port(Top.clock: IO[Clock],Input,SourceLine(hierarchy.md,111,7)), Port(Top.reset: IO[Bool],Input,SourceLine(hierarchy.md,111,7))),chisel3.internal.firrtl.ir$Block@1ca659b3)),List(),firrtl.renamemap.package$MutableRenameMap@7728b47b,List(),List(),List(Layer(UnlocatableSourceInfo,Verification,Extract(Some(verification)),List(Layer(UnlocatableSourceInfo,Assert,Extract(Some(verification/assert)),List(),chisel3.layers.Verification$Assert$@5ce17d85), Layer(UnlocatableSourceInfo,Assume,Extract(Some(verification/assume)),List(),chisel3.layers.Verification$Assume$@3d085d39), Layer(UnlocatableSourceInfo,Cover,Extract(Some(verification/cover)),List(),chisel3.layers.Verification$Cover$@6ca23849)),chisel3.layers.Verification$@9c03f7b)),List())
Width is 10
Circuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@4e0555a0,MyModule,false,List(),List(Port(MyModule.clock: IO[Clock],Input,SourceLine(hierarchy.md,105,2)), Port(MyModule.reset: IO[Reset],Input,SourceLine(hierarchy.md,105,2))),chisel3.internal.firrtl.ir$Block@62078259), DefModule(repl.MdocSession$MdocApp5$Top@7f9b98e0,Top,true,List(),List(Port(Top.clock: IO[Clock],Input,SourceLine(hierarchy.md,111,7)), Port(Top.reset: IO[Bool],Input,SourceLine(hierarchy.md,111,7))),chisel3.internal.firrtl.ir$Block@779e1ff9)),List(),firrtl.renamemap.package$MutableRenameMap@1352ecff,List(),List(),List(Layer(UnlocatableSourceInfo,Verification,Extract(Some(verification)),List(Layer(UnlocatableSourceInfo,Assert,Extract(Some(verification/assert)),List(),chisel3.layers.Verification$Assert$@77ba0861), Layer(UnlocatableSourceInfo,Assume,Extract(Some(verification/assume)),List(),chisel3.layers.Verification$Assume$@1e8bb807), Layer(UnlocatableSourceInfo,Cover,Extract(Some(verification/cover)),List(),chisel3.layers.Verification$Cover$@6f796f43)),chisel3.layers.Verification$@739ef53)),List())
For case classes containing Data
, BaseModule
, MemBase
or Instance
types, you can provide an implementation of the Lookupable
typeclass.
Note that Lookupable for Modules is deprecated, please cast to Instance instead (with .toInstance
).
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 @621a06a)
// 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(DataImpl.scala:73)
// at chisel3.Output$.apply(DataImpl.scala:320)
// 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:34)
// at chisel3.experimental.BaseModule.IO(ModuleImpl.scala:927)
// 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 chisel3.ObjectModuleImpl.evaluate(ModuleImpl.scala:97)
// at chisel3.ObjectModuleImpl.evaluate$(ModuleImpl.scala:63)
// at chisel3.Module$.evaluate(Module.scala:10)
// at chisel3.ObjectModuleImpl._applyImpl(ModuleImpl.scala:36)
// at chisel3.ObjectModuleImpl._applyImpl$(ModuleImpl.scala:34)
// at chisel3.Module$._applyImpl(Module.scala:10)
// at chisel3.Module$.do_apply(Module.scala:22)
// at chisel3.stage.phases.Elaborate.$anonfun$transform$2(Elaborate.scala:58)
// at chisel3.internal.Builder$.$anonfun$buildImpl$1(Builder.scala:1090)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at chisel3.internal.Builder$.buildImpl(Builder.scala:1080)
// at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:1072)
// at logger.Logger$.$anonfun$makeScope$4(Logger.scala:148)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at logger.Logger$.makeScope(Logger.scala:146)
// at logger.Logger$.makeScope(Logger.scala:133)
// 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 @57ca15a8)
// 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(DataImpl.scala:73)
// at chisel3.Output$.apply(DataImpl.scala:320)
// 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:34)
// at chisel3.experimental.BaseModule.IO(ModuleImpl.scala:927)
// 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 chisel3.ObjectModuleImpl.evaluate(ModuleImpl.scala:97)
// at chisel3.ObjectModuleImpl.evaluate$(ModuleImpl.scala:63)
// at chisel3.Module$.evaluate(Module.scala:10)
// at chisel3.ObjectModuleImpl._applyImpl(ModuleImpl.scala:36)
// at chisel3.ObjectModuleImpl._applyImpl$(ModuleImpl.scala:34)
// at chisel3.Module$._applyImpl(Module.scala:10)
// at chisel3.Module$.do_apply(Module.scala:22)
// at chisel3.stage.phases.Elaborate.$anonfun$transform$2(Elaborate.scala:58)
// at chisel3.internal.Builder$.$anonfun$buildImpl$1(Builder.scala:1090)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at chisel3.internal.Builder$.buildImpl(Builder.scala:1080)
// at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:1072)
// at logger.Logger$.$anonfun$makeScope$4(Logger.scala:148)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at logger.Logger$.makeScope(Logger.scala:146)
// at logger.Logger$.makeScope(Logger.scala:133)
// 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 15b26ab5c4..15d474460b 100644
--- a/docs/explanations/combinational-circuits.html
+++ b/docs/explanations/combinational-circuits.html
@@ -4,7 +4,7 @@