diff --git a/404.html b/404.html index 4c5a436d4a..43ed9a5fc7 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 p(e){const a={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(a.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(a.code,{children:"false.B"}),", ",(0,l.jsx)(a.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(a.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(a.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(a.p,{children:["The ",(0,l.jsx)(a.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(a.code,{children:"Bool"}),", ",(0,l.jsx)(a.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(a.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.p,{children:["The ",(0,l.jsx)(a.em,{children:"Chisel"})," type of a ",(0,l.jsx)(a.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)(a.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(a.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(a.p,{children:["Hardware is ",(0,l.jsx)(a.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(a.code,{children:"false.B"})," or ",(0,l.jsx)(a.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)(a.p,{children:["A literal is a ",(0,l.jsx)(a.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(a.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(a.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(a.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(a.p,{children:[(0,l.jsx)(a.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.p,{children:["Can only ",(0,l.jsx)(a.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.pre,{children:(0,l.jsx)(a.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 p(e){const a={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(a.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(a.code,{children:"false.B"}),", ",(0,l.jsx)(a.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(a.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(a.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(a.p,{children:["The ",(0,l.jsx)(a.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(a.code,{children:"Bool"}),", ",(0,l.jsx)(a.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(a.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.p,{children:["The ",(0,l.jsx)(a.em,{children:"Chisel"})," type of a ",(0,l.jsx)(a.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)(a.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(a.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(a.p,{children:["Hardware is ",(0,l.jsx)(a.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(a.code,{children:"false.B"})," or ",(0,l.jsx)(a.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)(a.p,{children:["A literal is a ",(0,l.jsx)(a.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(a.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(a.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(a.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(a.p,{children:[(0,l.jsx)(a.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.p,{children:["Can only ",(0,l.jsx)(a.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.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)(a.pre,{children:(0,l.jsx)(a.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",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,i.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,i.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n","\n","\n",(0,i.jsx)(a.A,{toc:d}),"\n",(0,i.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,i.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,i.jsxs)(n.p,{children:["Call ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,i.jsx)(n.code,{children:"asUInt"})})," on the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,i.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use the ",(0,i.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,i.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,i.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,i.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,i.jsxs)(n.p,{children:["You can use ",(0,i.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,i.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,i.jsx)(n.code,{children:"VecInit"})})," given a ",(0,i.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,i.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use the builtin function ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,i.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,i.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,i.jsxs)(n.p,{children:["Yes. Using ",(0,i.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,i.jsx)(n.code,{children:"fill"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,i.jsxs)(n.p,{children:["You create a ",(0,i.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,i.jsx)(n.em,{children:"type"})," (like ",(0,i.jsx)(n.code,{children:"UInt"}),", ",(0,i.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,i.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,i.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,i.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,i.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,i.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,i.jsx)(n.a,{href:"../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,i.jsx)(n.a,{href:"../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,i.jsx)(n.h3,{id:"how-do-i-deal-with-aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"}),"\n",(0,i.jsxs)(n.p,{children:["Following the ",(0,i.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.pre,{children:(0,i.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: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: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",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,i.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,i.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n","\n","\n",(0,i.jsx)(a.A,{toc:d}),"\n",(0,i.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,i.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,i.jsxs)(n.p,{children:["Call ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,i.jsx)(n.code,{children:"asUInt"})})," on the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,i.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use the ",(0,i.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,i.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,i.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,i.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,i.jsxs)(n.p,{children:["You can use ",(0,i.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,i.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,i.jsx)(n.code,{children:"VecInit"})})," given a ",(0,i.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,i.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["Use the builtin function ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,i.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,i.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,i.jsxs)(n.p,{children:["Yes. Using ",(0,i.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,i.jsx)(n.code,{children:"fill"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,i.jsxs)(n.p,{children:["You create a ",(0,i.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,i.jsx)(n.em,{children:"type"})," (like ",(0,i.jsx)(n.code,{children:"UInt"}),", ",(0,i.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,i.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,i.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,i.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,i.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,i.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,i.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,i.jsx)(n.a,{href:"../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,i.jsx)(n.a,{href:"../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.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,i.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,i.jsx)(n.h3,{id:"how-do-i-deal-with-aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"}),"\n",(0,i.jsxs)(n.p,{children:["Following the ",(0,i.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.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,i.jsx)(n.pre,{children:(0,i.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: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.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.81.1/bin/firtool returned a non-zero exit code. Note that this version of Chisel (7.0.0-M2+50-f347914d-SNAPSHOT) was published against firtool version 1.81.1.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:1029: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:1029: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.81.1/bin/firtool returned a non-zero exit code. Note that this version of Chisel (7.0.0-M2+51-706af8a8-SNAPSHOT) was published against firtool version 1.81.1.
// ------------------------------------------------------------------------------
// ExitCode:
// 1
// STDOUT:
//
// STDERR:
// cookbook.md:1029: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:1029: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 2e7dbb13b0..a835c1ed44 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@5b6d1953,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))),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@7590e65b,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))),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@5b6d1953),List(Port(MyModule.clock: IO[Clock],Input,SourceLine(hierarchy.md,105,2)), Port(MyModule.reset: IO[Reset],Input,SourceLine(hierarchy.md,105,2)))), 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@207b07c1,List(),List(),List(Layer(UnlocatableSourceInfo,Verification,Extract(Some(Verification)),List(Layer(UnlocatableSourceInfo,Assert,Extract(Some(Verification/Assert)),List()), Layer(UnlocatableSourceInfo,Assume,Extract(Some(Verification/Assume)),List()), Layer(UnlocatableSourceInfo,Cover,Extract(Some(Verification/Cover)),List())))),List())
Width is 10
Circuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@1b052081,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))),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@6add0883,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))),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@1b052081),List(Port(MyModule.clock: IO[Clock],Input,SourceLine(hierarchy.md,105,2)), Port(MyModule.reset: IO[Reset],Input,SourceLine(hierarchy.md,105,2)))), 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@3be89b70,List(),List(),List(Layer(UnlocatableSourceInfo,Verification,Extract(Some(Verification)),List(Layer(UnlocatableSourceInfo,Assert,Extract(Some(Verification/Assert)),List()), Layer(UnlocatableSourceInfo,Assume,Extract(Some(Verification/Assume)),List()), Layer(UnlocatableSourceInfo,Cover,Extract(Some(Verification/Cover)),List())))),List())
Just like Instance
s, Definition
's also contain accessors for @public
members.
As such, you can directly access them:
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 @3a39a49f)
// 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:75)
// at chisel3.Output$.apply(Data.scala:316)
// 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(Module.scala:878)
// 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.Module$.evaluate(Module.scala:94)
// at chisel3.Module$.do_apply(Module.scala:37)
// at chisel3.stage.phases.Elaborate.$anonfun$transform$2(Elaborate.scala:54)
// at chisel3.internal.Builder$.$anonfun$buildImpl$1(Builder.scala:1081)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at chisel3.internal.Builder$.buildImpl(Builder.scala:1071)
// at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:1063)
// 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 @62885e0)
// 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:75)
// at chisel3.Output$.apply(Data.scala:316)
// 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(Module.scala:878)
// 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.Module$.evaluate(Module.scala:94)
// at chisel3.Module$.do_apply(Module.scala:37)
// at chisel3.stage.phases.Elaborate.$anonfun$transform$2(Elaborate.scala:54)
// at chisel3.internal.Builder$.$anonfun$buildImpl$1(Builder.scala:1081)
// at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
// at chisel3.internal.Builder$.buildImpl(Builder.scala:1071)
// at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:1063)
// 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 9bd514b7c9..c074f8c5c9 100644
--- a/docs/explanations/combinational-circuits.html
+++ b/docs/explanations/combinational-circuits.html
@@ -4,7 +4,7 @@
Consider a use case where a design or design verification engineer would like to add some asserts and debug prints to a module. The logic necessary for the asserts and debug prints requires additional computation. All of this code -should not be included in the final Verilog. The engineer can use three layers -to do this.
-There are four layers that emerge from this example.
+should selectively included at Verilog elaboration time (not at Chisel +elaboration time). The engineer can use three layers to do this. +There are three layers used in this example:
Verification
layerAssert
layer which is nested under the built-in Verification
layerCover
layer which is also nested under the built-in
+Debug
layer which is also nested under the built-in
Verification
layerDebug
layerThe Verification
layer can be used to store common logic used by both the
-Assert
and Cover
layers. The Assert
and Cover
layers contain,
-respectively, assertions and cover statements. The Debug
layer contains
-debugging prints.
Assert
and Debug
layers. The latter two layers allow for separation of,
+respectively, assertions from prints.
One way to write this in Scala is the following:
-import chisel3._
import chisel3.layer.{Layer, LayerConfig, block}
import chisel3.layers.Verification
// User-defined layers are declared here. Built-in layers do not need to be declared.
object Debug extends Layer(LayerConfig.Extract())
class Foo extends Module {
val a = IO(Input(UInt(32.W)))
val b = IO(Output(UInt(32.W)))
b := a +% 1.U
// This adds a `Verification` layer block inside Foo.
block(Verification) {
// Some common logic added here. The input port `a` is "captured" and
// used here.
val a_d0 = RegNext(a)
// This adds an `Assert` layer block.
block(Verification.Assert) {
chisel3.assert(a >= a_d0, "a must always increment")
}
// This adds a `Cover` layer block.
block(Verification.Cover) {
chisel3.cover(a === 8.U, "a_ took a value of 8")
chisel3.cover(a_d0 === 8.U, "a_d0 took a value of 8")
}
}
// This adds a `Debug` layer block.
block(Debug) {
printf("a: %x", a)
}
}
import chisel3._
import chisel3.layer.{Layer, LayerConfig, block}
import chisel3.layers.Verification
// User-defined layers are declared here. Built-in layers do not need to be declared.
object UserDefined {
// Define an implicit val `root` of type `Layer` to cause layers which can see
// this to use `root` as their parent layer. This allows us to nest the
// user-defined `Debug` layer under the built-in `Verification` layer.
implicit val root = Verification
object Debug extends Layer(LayerConfig.Extract())
}
class Foo extends Module {
val a = IO(Input(UInt(32.W)))
val b = IO(Output(UInt(32.W)))
b := a +% 1.U
// This adds a `Verification` layer block inside Foo.
block(Verification) {
// Some common logic added here. The input port `a` is "captured" and
// used here.
val a_d0 = RegNext(a)
// This adds an `Assert` layer block.
block(Verification.Assert) {
chisel3.assert(a >= a_d0, "a must always increment")
}
// This adds a `Debug` layer block.
block(UserDefined.Debug) {
printf("a: %x, a_d0: %x", a, a_d0)
}
}
}
After compilation, this will produce three layer include files with the following filenames. One file is created for each layer:
layers_Foo_Verification.sv
layers_Foo_Verification_Assert.sv
layers_Foo_Verification_Cover.sv
layers_Foo_Debug.sv
layers_Foo_Verification_Debug.sv
A user can then include any combination of these files in their design to
-include the optional functionality describe by the Verification
, Assert
,
-Cover
, or Debug
layers. The Assert
and Cover
bind files automatically
-include the Verification
bind file for the user.
Verification
, Assert
, or
+Debug
layers. The Assert
and Debug
bind files automatically include the
+Verification
bind file for the user.
Note: the names of the modules and the names of any files that contain these
modules are FIRRTL compiler implementation defined! The only guarantee is the
@@ -109,19 +106,18 @@ These will typically be created in separate files with names that match the
modules, i.e., Impleme
Foo_Verification
Foo_Verification_Assert
Foo_Verification_Cover
Foo_Debug
Foo_Verification_Debug
Foo.sv
, Foo_Verification.sv
, Foo_Verification_Assert.sv
,
-Foo_Verification_Cover.sv
, and Foo_Debug.sv
.Foo_Verification_Debug.sv
.
The ports of each module created from a layer block will be automatically
determined based on what that layer block captured from outside the layer block.
In the example above, the Verification
layer block captured port a
. Both
-the Assert
and Cover
layer blocks captured a
and a_d0
. The Debug
-layer only captured a
. Layer blocks may be optimized to remove/add ports or
-to move logic into a layer block.
Assert
and Debug
layer blocks captured a
and a_d0
. Layer blocks may
+be optimized to remove/add ports or to move logic into a layer block.
The complete Verilog output for this example is reproduced below:
-// Generated by CIRCT firtool-1.81.1
module Foo(
input clock,
reset,
input [31:0] a,
output [31:0] b
);
assign b = a + 32'h1;
endmodule
// ----- 8< ----- FILE "Debug/layers_Foo_Verification_Debug.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Debug
`define layers_Foo_Verification_Debug
`endif // layers_Foo_Verification_Debug
// ----- 8< ----- FILE "Verification/Assume/layers_Foo_Verification_Assume.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Assume
`define layers_Foo_Verification_Assume
`endif // layers_Foo_Verification_Assume
// ----- 8< ----- FILE "Verification/Cover/layers_Foo_Verification_Cover.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Cover
`define layers_Foo_Verification_Cover
bind Foo Foo_Verification_Cover verification_cover (
.a (Foo.verification.a_probe_0),
.reset (reset),
.clock (Foo.verification.clock_probe_0),
.a_d0 (Foo.verification.a_d0_probe_0)
);
`endif // layers_Foo_Verification_Cover
// ----- 8< ----- FILE "Verification/Assert/layers_Foo_Verification_Assert.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Assert
`define layers_Foo_Verification_Assert
bind Foo Foo_Verification_Assert verification_assert (
.a (Foo.verification.a_probe),
.a_d0 (Foo.verification.a_d0_probe),
.reset (reset),
.clock (Foo.verification.clock_probe)
);
`endif // layers_Foo_Verification_Assert
// ----- 8< ----- FILE "Verification/layers_Foo_Verification.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`ifndef layers_Foo_Verification
`define layers_Foo_Verification
bind Foo Foo_Verification verification (
.clock (clock),
.a (a)
);
`endif // layers_Foo_Verification
// ----- 8< ----- FILE "Verification/Assert/Foo_Verification_Assert.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
// Users can define 'STOP_COND' to add an extra gate to stop conditions.
`ifndef STOP_COND_
`ifdef STOP_COND
`define STOP_COND_ (`STOP_COND)
`else // STOP_COND
`define STOP_COND_ 1
`endif // STOP_COND
`endif // not def STOP_COND_
// Users can define 'ASSERT_VERBOSE_COND' to add an extra gate to assert error printing.
`ifndef ASSERT_VERBOSE_COND_
`ifdef ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ (`ASSERT_VERBOSE_COND)
`else // ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ 1
`endif // ASSERT_VERBOSE_COND
`endif // not def ASSERT_VERBOSE_COND_
module Foo_Verification_Assert(
input [31:0] a,
a_d0,
input reset,
clock
);
`ifndef SYNTHESIS
always @(posedge clock) begin
if (~reset & a < a_d0) begin
if (`ASSERT_VERBOSE_COND_)
$error("Assertion failed: a must always increment\n");
if (`STOP_COND_)
$fatal;
end
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule
// ----- 8< ----- FILE "Verification/Cover/Foo_Verification_Cover.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
module Foo_Verification_Cover(
input [31:0] a,
input reset,
clock,
input [31:0] a_d0
);
always @(posedge clock) begin
if (~reset) begin
cover__cover: cover(a == 32'h8);
cover__cover_1: cover(a_d0 == 32'h8);
end
end // always @(posedge)
endmodule
// ----- 8< ----- FILE "Verification/Foo_Verification.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
module Foo_Verification(
input clock,
input [31:0] a
);
wire clock_probe = clock;
wire [31:0] a_probe = a;
wire clock_probe_0 = clock;
wire [31:0] a_probe_0 = a;
reg [31:0] a_d0;
wire [31:0] a_d0_probe = a_d0;
wire [31:0] a_d0_probe_0 = a_d0;
always @(posedge clock)
a_d0 <= a;
endmodule
// ----- 8< ----- FILE "Debug/Foo_Debug.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
// Users can define 'PRINTF_COND' to add an extra gate to prints.
`ifndef PRINTF_COND_
`ifdef PRINTF_COND
`define PRINTF_COND_ (`PRINTF_COND)
`else // PRINTF_COND
`define PRINTF_COND_ 1
`endif // PRINTF_COND
`endif // not def PRINTF_COND_
module Foo_Debug(
input reset,
clock,
input [31:0] a
);
`ifndef SYNTHESIS
always @(posedge clock) begin
if ((`PRINTF_COND_) & ~reset)
$fwrite(32'h80000002, "a: %x", a);
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule
// ----- 8< ----- FILE "Debug/layers_Foo_Debug.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
bind Foo Foo_Debug debug (
.reset (reset),
.clock (clock),
.a (a)
);
// Generated by CIRCT firtool-1.81.1
module Foo(
input clock,
reset,
input [31:0] a,
output [31:0] b
);
assign b = a + 32'h1;
endmodule
// ----- 8< ----- FILE "Verification/Cover/layers_Foo_Verification_Cover.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Cover
`define layers_Foo_Verification_Cover
`endif // layers_Foo_Verification_Cover
// ----- 8< ----- FILE "Verification/Assume/layers_Foo_Verification_Assume.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Assume
`define layers_Foo_Verification_Assume
`endif // layers_Foo_Verification_Assume
// ----- 8< ----- FILE "Verification/Debug/layers_Foo_Verification_Debug.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Debug
`define layers_Foo_Verification_Debug
bind Foo Foo_Verification_Debug verification_debug (
.reset (reset),
.clock (Foo.verification.clock_probe_0),
.a (Foo.verification.a_probe_0),
.a_d0 (Foo.verification.a_d0_probe_0)
);
`endif // layers_Foo_Verification_Debug
// ----- 8< ----- FILE "Verification/Assert/layers_Foo_Verification_Assert.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`include "Verification/layers_Foo_Verification.sv"
`ifndef layers_Foo_Verification_Assert
`define layers_Foo_Verification_Assert
bind Foo Foo_Verification_Assert verification_assert (
.a (Foo.verification.a_probe),
.a_d0 (Foo.verification.a_d0_probe),
.reset (reset),
.clock (Foo.verification.clock_probe)
);
`endif // layers_Foo_Verification_Assert
// ----- 8< ----- FILE "Verification/layers_Foo_Verification.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
`ifndef layers_Foo_Verification
`define layers_Foo_Verification
bind Foo Foo_Verification verification (
.clock (clock),
.a (a)
);
`endif // layers_Foo_Verification
// ----- 8< ----- FILE "Verification/Assert/Foo_Verification_Assert.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
// Users can define 'STOP_COND' to add an extra gate to stop conditions.
`ifndef STOP_COND_
`ifdef STOP_COND
`define STOP_COND_ (`STOP_COND)
`else // STOP_COND
`define STOP_COND_ 1
`endif // STOP_COND
`endif // not def STOP_COND_
// Users can define 'ASSERT_VERBOSE_COND' to add an extra gate to assert error printing.
`ifndef ASSERT_VERBOSE_COND_
`ifdef ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ (`ASSERT_VERBOSE_COND)
`else // ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ 1
`endif // ASSERT_VERBOSE_COND
`endif // not def ASSERT_VERBOSE_COND_
module Foo_Verification_Assert(
input [31:0] a,
a_d0,
input reset,
clock
);
`ifndef SYNTHESIS
always @(posedge clock) begin
if (~reset & a < a_d0) begin
if (`ASSERT_VERBOSE_COND_)
$error("Assertion failed: a must always increment\n");
if (`STOP_COND_)
$fatal;
end
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule
// ----- 8< ----- FILE "Verification/Debug/Foo_Verification_Debug.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
// Users can define 'PRINTF_COND' to add an extra gate to prints.
`ifndef PRINTF_COND_
`ifdef PRINTF_COND
`define PRINTF_COND_ (`PRINTF_COND)
`else // PRINTF_COND
`define PRINTF_COND_ 1
`endif // PRINTF_COND
`endif // not def PRINTF_COND_
module Foo_Verification_Debug(
input reset,
clock,
input [31:0] a,
a_d0
);
`ifndef SYNTHESIS
always @(posedge clock) begin
if ((`PRINTF_COND_) & ~reset)
$fwrite(32'h80000002, "a: %x, a_d0: %x", a, a_d0);
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule
// ----- 8< ----- FILE "Verification/Foo_Verification.sv" ----- 8< -----
// Generated by CIRCT firtool-1.81.1
module Foo_Verification(
input clock,
input [31:0] a
);
wire clock_probe = clock;
wire [31:0] a_probe = a;
wire [31:0] a_probe_0 = a;
wire clock_probe_0 = clock;
reg [31:0] a_d0;
wire [31:0] a_d0_probe = a_d0;
wire [31:0] a_d0_probe_0 = a_d0;
always @(posedge clock)
a_d0 <= a;
endmodule