diff --git a/404.html b/404.html index 74a1d742097..56a819e8b78 100644 --- a/404.html +++ b/404.html @@ -4,8 +4,8 @@ Page Not Found | Chisel - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/api.htm/index.html b/api.htm/index.html new file mode 100644 index 00000000000..1e99525ae1a --- /dev/null +++ b/api.htm/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/api.html b/api.html index d36e0185419..1cd5dfa7d6a 100644 --- a/api.html +++ b/api.html @@ -4,8 +4,8 @@ API Docs | Chisel - - + +
Skip to main content

Chisel API Documentation

diff --git a/api.html.html b/api.html.html new file mode 100644 index 00000000000..1e99525ae1a --- /dev/null +++ b/api.html.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/assets/js/1ce89024.1e58b840.js b/assets/js/1ce89024.e1594d78.js similarity index 53% rename from assets/js/1ce89024.1e58b840.js rename to assets/js/1ce89024.e1594d78.js index 60766f3473a..38e6f48ea3e 100644 --- a/assets/js/1ce89024.1e58b840.js +++ b/assets/js/1ce89024.e1594d78.js @@ -1 +1 @@ -"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[2431],{6178:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var t=i(5893),o=i(1151);const a={layout:"docs",title:"Hierarchy Cookbook",section:"chisel3"},s="Hierarchy Cookbook",l={id:"cookbooks/hierarchy",title:"Hierarchy Cookbook",description:"* How do I instantiate multiple instances with the same module parameterization, but avoid re-elaboration?",source:"@site/docs/cookbooks/hierarchy.md",sourceDirName:"cookbooks",slug:"/cookbooks/hierarchy",permalink:"/docs/cookbooks/hierarchy",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/cookbooks/hierarchy.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Hierarchy Cookbook",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"DataView Cookbook",permalink:"/docs/cookbooks/dataview"},next:{title:"Naming Cookbook",permalink:"/docs/cookbooks/naming"}},c={},d=[{value:"How do I instantiate multiple instances with the same module parameterization?",id:"how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",level:2},{value:"Using Definition and Instance",id:"using-definition-and-instance",level:3},{value:"Using Instantiate",id:"using-instantiate",level:3},{value:"How do I access internal fields of an instance?",id:"how-do-i-access-internal-fields-of-an-instance",level:2},{value:"How do I make my parameters accessible from an instance?",id:"how-do-i-make-my-parameters-accessible-from-an-instance",level:2},{value:"How do I look up parameters from a Definition, if I don't want to instantiate it?",id:"how-do-i-look-up-parameters-from-a-definition-if-i-dont-want-to-instantiate-it",level:2},{value:"How do I parameterize a module by its children instances?",id:"how-do-i-parameterize-a-module-by-its-children-instances",level:2},{value:"How do I use the new hierarchy-specific Select functions?",id:"how-do-i-use-the-new-hierarchy-specific-select-functions",level:2}];function r(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"hierarchy-cookbook",children:"Hierarchy Cookbook"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",children:"How do I instantiate multiple instances with the same module parameterization, but avoid re-elaboration?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-access-internal-fields-of-an-instance",children:"How do I access internal fields of an instance?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-make-my-parameters-accessable-from-an-instance",children:"How do I make my parameters accessable from an instance?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-reuse-a-previously-elaborated-module-if-my-new-module-has-the-same-parameterization",children:"How do I reuse a previously elaborated module, if my new module has the same parameterization?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-I-parameterize-a-module-by-its-children-instances",children:"How do I parameterize a module by its children instances?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-I-use-the-new-hierarchy-specific-Select-functions",children:"How do I use the new hierarchy-specific Select functions?"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",children:"How do I instantiate multiple instances with the same module parameterization?"}),"\n",(0,t.jsx)(n.p,{children:'Prior to this package, Chisel users relied on deduplication in a FIRRTL compiler to combine\nstructurally equivalent modules into one module (aka "deduplication").\nThis package introduces the following new APIs to enable multiply-instantiated modules directly in Chisel.'}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Definition(...)"})," enables elaborating a module, but does not actually instantiate that module.\nInstead, it returns a ",(0,t.jsx)(n.code,{children:"Definition"})," class which represents that module's definition."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Instance(...)"})," takes a ",(0,t.jsx)(n.code,{children:"Definition"})," and instantiates it, returning an ",(0,t.jsx)(n.code,{children:"Instance"})," object."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Instantiate(...)"})," provides an API similar to ",(0,t.jsx)(n.code,{children:"Module(...)"}),", except it uses\n",(0,t.jsx)(n.code,{children:"Definition"})," and ",(0,t.jsx)(n.code,{children:"Instance"})," to only elaborate modules once for a given set of\nparameters. It returns an ",(0,t.jsx)(n.code,{children:"Instance"})," object."]}),"\n",(0,t.jsxs)(n.p,{children:["Modules (classes or traits) which will be used with the ",(0,t.jsx)(n.code,{children:"Definition"}),"/",(0,t.jsx)(n.code,{children:"Instance"})," api should be marked\nwith the ",(0,t.jsx)(n.code,{children:"@instantiable"})," annotation at the class/trait definition."]}),"\n",(0,t.jsxs)(n.p,{children:["To make a Module's members variables accessible from an ",(0,t.jsx)(n.code,{children:"Instance"})," object, they must be annotated\nwith the ",(0,t.jsx)(n.code,{children:"@public"})," annotation. Note that this is only accessible from a Scala sense\u2014this is not\nin and of itself a mechanism for cross-module references."]}),"\n",(0,t.jsx)(n.h3,{id:"using-definition-and-instance",children:"Using Definition and Instance"}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, use ",(0,t.jsx)(n.code,{children:"Definition"}),", ",(0,t.jsx)(n.code,{children:"Instance"}),", ",(0,t.jsx)(n.code,{children:"@instantiable"})," and ",(0,t.jsx)(n.code,{children:"@public"})," to create\nmultiple instances of one specific parameterization of a module, ",(0,t.jsx)(n.code,{children:"AddOne"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public}\n\n@instantiable\nclass AddOne(width: Int) extends Module {\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass AddTwo(width: Int) extends Module {\n val in = IO(Input(UInt(width.W)))\n val out = IO(Output(UInt(width.W)))\n val addOneDef = Definition(new AddOne(width))\n val i0 = Instance(addOneDef)\n val i1 = Instance(addOneDef)\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:14:2\n input [9:0] in,\t// hierarchy.md:16:23\n output [9:0] out\t// hierarchy.md:17:23\n);\n\n assign out = in + 10'h1;\t// hierarchy.md:14:2, :18:13\nendmodule\n\nmodule AddTwo(\t// hierarchy.md:22:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [9:0] in,\t// hierarchy.md:23:15\n output [9:0] out\t// hierarchy.md:24:15\n);\n\n wire [9:0] _i0_out;\t// hierarchy.md:26:20\n AddOne i0 (\t// hierarchy.md:26:20\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:27:20\n .in (_i0_out),\t// hierarchy.md:26:20\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"using-instantiate",children:"Using Instantiate"}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the above, the following example uses ",(0,t.jsx)(n.code,{children:"Instantiate"})," to create\nmultiple instances of ",(0,t.jsx)(n.code,{children:"AddOne"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.hierarchy.Instantiate\n\nclass AddTwoInstantiate(width: Int) extends Module {\n val in = IO(Input(UInt(width.W)))\n val out = IO(Output(UInt(width.W)))\n val i0 = Instantiate(new AddOne(width))\n val i1 = Instantiate(new AddOne(width))\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:14:2\n input [15:0] in,\t// hierarchy.md:16:23\n output [15:0] out\t// hierarchy.md:17:23\n);\n\n assign out = in + 16'h1;\t// hierarchy.md:14:2, :18:13\nendmodule\n\nmodule AddTwoInstantiate(\t// hierarchy.md:46:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [15:0] in,\t// hierarchy.md:47:15\n output [15:0] out\t// hierarchy.md:48:15\n);\n\n wire [15:0] _i0_out;\t// hierarchy.md:49:23\n AddOne i0 (\t// hierarchy.md:49:23\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:50:23\n .in (_i0_out),\t// hierarchy.md:49:23\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-access-internal-fields-of-an-instance",children:"How do I access internal fields of an instance?"}),"\n",(0,t.jsxs)(n.p,{children:["You can mark internal members of a class or trait marked with ",(0,t.jsx)(n.code,{children:"@instantiable"})," with the ",(0,t.jsx)(n.code,{children:"@public"})," annotation.\nThe requirements are that the field is publicly accessible, is a ",(0,t.jsx)(n.code,{children:"val"})," or ",(0,t.jsx)(n.code,{children:"lazy val"}),", and is a valid type.\nThe list of valid types are:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"IsInstantiable"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"IsLookupable"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Data"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"BaseModule"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Iterable"}),"/",(0,t.jsx)(n.code,{children:"Option "}),"containing a type that meets these requirements"]}),"\n",(0,t.jsxs)(n.li,{children:["Basic type like ",(0,t.jsx)(n.code,{children:"String"}),", ",(0,t.jsx)(n.code,{children:"Int"}),", ",(0,t.jsx)(n.code,{children:"BigInt"})," etc."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To mark a superclass's member as ",(0,t.jsx)(n.code,{children:"@public"}),", use the following pattern (shown with ",(0,t.jsx)(n.code,{children:"val clock"}),")."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{instantiable, public}\n\n@instantiable\nclass MyModule extends Module {\n @public val clock = clock\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You'll get the following error message for improperly marking something as ",(0,t.jsx)(n.code,{children:"@public"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{instantiable, public}\n\nobject NotValidType\n\n@instantiable\nclass MyModule extends Module {\n @public val x = NotValidType\n}\n// error: @public is only legal within a class or trait marked @instantiable, and only on vals of type Data, BaseModule, MemBase, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, Either, or Tuple2\n// val x = circt.stage.ChiselStage.emitCHIRRTL(new Top)\n// ^\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-make-my-parameters-accessible-from-an-instance",children:"How do I make my parameters accessible from an instance?"}),"\n",(0,t.jsxs)(n.p,{children:["If an instance's parameters are simple (e.g. ",(0,t.jsx)(n.code,{children:"Int"}),", ",(0,t.jsx)(n.code,{children:"String"})," etc.) they can be marked directly with ",(0,t.jsx)(n.code,{children:"@public"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Often, parameters are more complicated and are contained in case classes.\nIn such cases, mark the case class with the ",(0,t.jsx)(n.code,{children:"IsLookupable"})," trait.\nThis indicates to Chisel that instances of the ",(0,t.jsx)(n.code,{children:"IsLookupable"})," class may be accessed from within instances."]}),"\n",(0,t.jsxs)(n.p,{children:["However, ensure that these parameters are true for ",(0,t.jsx)(n.strong,{children:"all"})," instances of a definition.\nFor example, if our parameters contained an id field which was instance-specific but defaulted to zero,\nthen the definition's id would be returned for all instances.\nThis change in behavior could lead to bugs if other code presumed the id field was correct."]}),"\n",(0,t.jsxs)(n.p,{children:["Thus, it is important that when converting normal modules to use this package,\nyou are careful about what you mark as ",(0,t.jsx)(n.code,{children:"IsLookupable"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, we added the trait ",(0,t.jsx)(n.code,{children:"IsLookupable"})," to allow the member to be marked ",(0,t.jsx)(n.code,{children:"@public"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, IsLookupable, public}\n\ncase class MyCaseClass(width: Int) extends IsLookupable\n\n@instantiable\nclass MyModule extends Module {\n @public val x = MyCaseClass(10)\n}\n\nclass Top extends Module {\n val inst = Instance(Definition(new MyModule))\n println(s"Width is ${inst.x.width}")\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Width is 10\nCircuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@4fc50bd,MyModule,List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo)),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@1c9e832c,Top,List(Port(Top.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(Top.reset: IO[Bool],Input,UnlocatableSourceInfo)),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@4fc50bd),List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo))), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.clock: IO[Clock]),Node(Top.clock: IO[Clock])), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.reset: IO[Reset]),Node(Top.reset: IO[Bool]))))),List(),firrtl.renamemap.package$MutableRenameMap@7381cd04,List(),List(),List())\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-look-up-parameters-from-a-definition-if-i-dont-want-to-instantiate-it",children:"How do I look up parameters from a Definition, if I don't want to instantiate it?"}),"\n",(0,t.jsxs)(n.p,{children:["Just like ",(0,t.jsx)(n.code,{children:"Instance"}),"s, ",(0,t.jsx)(n.code,{children:"Definition"}),"'s also contain accessors for ",(0,t.jsx)(n.code,{children:"@public"})," members.\nAs such, you can directly access them:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, instantiable, public}\n\n@instantiable\nclass AddOne(val width: Int) extends RawModule {\n @public val width = width\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass Top extends Module {\n val definition = Definition(new AddOne(10))\n println(s"Width is: ${definition.width}")\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Top(\t// hierarchy.md:157:7\n input clock,\t// :12:11\n reset\t// :13:11\n);\n\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-parameterize-a-module-by-its-children-instances",children:"How do I parameterize a module by its children instances?"}),"\n",(0,t.jsx)(n.p,{children:"Prior to the introduction of this package, a parent module would have to pass all necessary parameters\nwhen instantiating a child module.\nThis had the unfortunate consequence of requiring a parent's parameters to always contain the child's\nparameters, which was an unnecessary coupling which lead to some anti-patterns."}),"\n",(0,t.jsxs)(n.p,{children:["Now, a parent can take a child ",(0,t.jsx)(n.code,{children:"Definition"})," as an argument, and instantiate it directly.\nIn addition, it can analyze the parameters used in the definition to parameterize itself.\nIn a sense, now the child can actually parameterize the parent."]}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, we create a definition of ",(0,t.jsx)(n.code,{children:"AddOne"}),", and pass the definition to ",(0,t.jsx)(n.code,{children:"AddTwo"}),".\nThe width of the ",(0,t.jsx)(n.code,{children:"AddTwo"})," ports are now derived from the parameterization of the ",(0,t.jsx)(n.code,{children:"AddOne"})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public}\n\n@instantiable\nclass AddOne(val width: Int) extends Module {\n @public val width = width\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass AddTwo(addOneDef: Definition[AddOne]) extends Module {\n val i0 = Instance(addOneDef)\n val i1 = Instance(addOneDef)\n val in = IO(Input(UInt(addOneDef.width.W)))\n val out = IO(Output(UInt(addOneDef.width.W)))\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:181:2\n input [9:0] in,\t// hierarchy.md:184:23\n output [9:0] out\t// hierarchy.md:185:23\n);\n\n assign out = in + 10'h1;\t// hierarchy.md:181:2, :186:13\nendmodule\n\nmodule AddTwo(\t// hierarchy.md:190:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [9:0] in,\t// hierarchy.md:193:15\n output [9:0] out\t// hierarchy.md:194:15\n);\n\n wire [9:0] _i0_out;\t// hierarchy.md:191:20\n AddOne i0 (\t// hierarchy.md:191:20\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:192:20\n .in (_i0_out),\t// hierarchy.md:191:20\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-use-the-new-hierarchy-specific-select-functions",children:"How do I use the new hierarchy-specific Select functions?"}),"\n",(0,t.jsx)(n.p,{children:"Select functions can be applied after a module has been elaborated, either in a Chisel Aspect or in a parent module applied to a child module."}),"\n",(0,t.jsxs)(n.p,{children:["There are seven hierarchy-specific functions, which (with the exception of ",(0,t.jsx)(n.code,{children:"ios"}),") either return ",(0,t.jsx)(n.code,{children:"Instance"}),"'s or ",(0,t.jsx)(n.code,{children:"Definition"}),"'s:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"instancesIn(parent)"}),": Return all instances directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"instancesOf[type](parent)"}),": Return all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"allInstancesOf[type](root)"}),": Return all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly and indirectly instantiated, locally and deeply, starting from ",(0,t.jsx)(n.code,{children:"root"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"definitionsIn"}),": Return definitions of all instances directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"definitionsOf[type]"}),": Return definitions of all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"allDefinitionsOf[type]"}),": Return all definitions of instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly and indirectly instantiated, locally and deeply, starting from ",(0,t.jsx)(n.code,{children:"root"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"ios"}),": Returns all the I/Os of the provided definition or instance."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To demonstrate this, consider the following. We mock up an example where we are using the ",(0,t.jsx)(n.code,{children:"Select.allInstancesOf"})," and ",(0,t.jsx)(n.code,{children:"Select.allDefinitionsOf"})," to annotate instances and the definition of ",(0,t.jsx)(n.code,{children:"EmptyModule"}),". When converting the ",(0,t.jsx)(n.code,{children:"ChiselAnnotation"})," to firrtl's ",(0,t.jsx)(n.code,{children:"Annotation"}),", we print out the resulting ",(0,t.jsx)(n.code,{children:"Target"}),". As shown, despite ",(0,t.jsx)(n.code,{children:"EmptyModule"})," actually only being elaborated once, we still provide different targets depending on how the instance or definition is selected."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, Hierarchy, instantiable, public}\nimport firrtl.annotations.{IsModule, NoTargetAnnotation}\ncase object EmptyAnnotation extends NoTargetAnnotation\ncase class MyChiselAnnotation(m: Hierarchy[RawModule], tag: String) extends experimental.ChiselAnnotation {\n def toFirrtl = {\n println(tag + ": " + m.toTarget)\n EmptyAnnotation\n }\n}\n\n@instantiable\nclass EmptyModule extends Module {\n println("Elaborating EmptyModule!")\n}\n\n@instantiable\nclass TwoEmptyModules extends Module {\n val definition = Definition(new EmptyModule)\n val i0 = Instance(definition)\n val i1 = Instance(definition)\n}\n\nclass Top extends Module {\n val definition = Definition(new TwoEmptyModules)\n val instance = Instance(definition)\n aop.Select.allInstancesOf[EmptyModule](instance).foreach { i =>\n experimental.annotate(MyChiselAnnotation(i, "instance"))\n }\n aop.Select.allDefinitionsOf[EmptyModule](instance).foreach { d =>\n experimental.annotate(MyChiselAnnotation(d, "definition"))\n }\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Elaborating EmptyModule!\ninstance: ~Top|Top/instance:TwoEmptyModules/i0:EmptyModule\ninstance: ~Top|Top/instance:TwoEmptyModules/i1:EmptyModule\ndefinition: ~Top|EmptyModule\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can also use ",(0,t.jsx)(n.code,{children:"Select.ios"})," on either a ",(0,t.jsx)(n.code,{children:"Definition"})," or an ",(0,t.jsx)(n.code,{children:"Instance"})," to annotate the I/Os appropriately:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'case class MyIOAnnotation(m: Data, tag: String) extends experimental.ChiselAnnotation {\n def toFirrtl = {\n println(tag + ": " + m.toTarget)\n EmptyAnnotation\n }\n}\n\n@instantiable\nclass InOutModule extends Module {\n @public val in = IO(Input(Bool()))\n @public val out = IO(Output(Bool()))\n out := in\n}\n\n@instantiable\nclass TwoInOutModules extends Module {\n val in = IO(Input(Bool()))\n val out = IO(Output(Bool()))\n val definition = Definition(new InOutModule)\n val i0 = Instance(definition)\n val i1 = Instance(definition)\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n\nclass InOutTop extends Module {\n val definition = Definition(new TwoInOutModules)\n val instance = Instance(definition)\n aop.Select.allInstancesOf[InOutModule](instance).foreach { i =>\n aop.Select.ios(i).foreach { io =>\n experimental.annotate(MyIOAnnotation(io, "instance io"))\n }}\n aop.Select.allDefinitionsOf[InOutModule](instance).foreach { d =>\n aop.Select.ios(d).foreach {io =>\n experimental.annotate(MyIOAnnotation(io, "definition io"))\n }}\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"instance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>clock\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>reset\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>in\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>out\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>clock\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>reset\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>in\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>out\ndefinition io: ~InOutTop|InOutModule>clock\ndefinition io: ~InOutTop|InOutModule>reset\ndefinition io: ~InOutTop|InOutModule>in\ndefinition io: ~InOutTop|InOutModule>out\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>s});var t=i(7294);const o={},a=t.createContext(o);function s(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[2431],{6178:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var t=i(5893),o=i(1151);const a={layout:"docs",title:"Hierarchy Cookbook",section:"chisel3"},s="Hierarchy Cookbook",l={id:"cookbooks/hierarchy",title:"Hierarchy Cookbook",description:"* How do I instantiate multiple instances with the same module parameterization, but avoid re-elaboration?",source:"@site/docs/cookbooks/hierarchy.md",sourceDirName:"cookbooks",slug:"/cookbooks/hierarchy",permalink:"/docs/cookbooks/hierarchy",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/cookbooks/hierarchy.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Hierarchy Cookbook",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"DataView Cookbook",permalink:"/docs/cookbooks/dataview"},next:{title:"Naming Cookbook",permalink:"/docs/cookbooks/naming"}},c={},d=[{value:"How do I instantiate multiple instances with the same module parameterization?",id:"how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",level:2},{value:"Using Definition and Instance",id:"using-definition-and-instance",level:3},{value:"Using Instantiate",id:"using-instantiate",level:3},{value:"How do I access internal fields of an instance?",id:"how-do-i-access-internal-fields-of-an-instance",level:2},{value:"How do I make my parameters accessible from an instance?",id:"how-do-i-make-my-parameters-accessible-from-an-instance",level:2},{value:"How do I look up parameters from a Definition, if I don't want to instantiate it?",id:"how-do-i-look-up-parameters-from-a-definition-if-i-dont-want-to-instantiate-it",level:2},{value:"How do I parameterize a module by its children instances?",id:"how-do-i-parameterize-a-module-by-its-children-instances",level:2},{value:"How do I use the new hierarchy-specific Select functions?",id:"how-do-i-use-the-new-hierarchy-specific-select-functions",level:2}];function r(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"hierarchy-cookbook",children:"Hierarchy Cookbook"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",children:"How do I instantiate multiple instances with the same module parameterization, but avoid re-elaboration?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-access-internal-fields-of-an-instance",children:"How do I access internal fields of an instance?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-make-my-parameters-accessable-from-an-instance",children:"How do I make my parameters accessable from an instance?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-reuse-a-previously-elaborated-module-if-my-new-module-has-the-same-parameterization",children:"How do I reuse a previously elaborated module, if my new module has the same parameterization?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-I-parameterize-a-module-by-its-children-instances",children:"How do I parameterize a module by its children instances?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-I-use-the-new-hierarchy-specific-Select-functions",children:"How do I use the new hierarchy-specific Select functions?"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-instantiate-multiple-instances-with-the-same-module-parameterization",children:"How do I instantiate multiple instances with the same module parameterization?"}),"\n",(0,t.jsx)(n.p,{children:'Prior to this package, Chisel users relied on deduplication in a FIRRTL compiler to combine\nstructurally equivalent modules into one module (aka "deduplication").\nThis package introduces the following new APIs to enable multiply-instantiated modules directly in Chisel.'}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Definition(...)"})," enables elaborating a module, but does not actually instantiate that module.\nInstead, it returns a ",(0,t.jsx)(n.code,{children:"Definition"})," class which represents that module's definition."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Instance(...)"})," takes a ",(0,t.jsx)(n.code,{children:"Definition"})," and instantiates it, returning an ",(0,t.jsx)(n.code,{children:"Instance"})," object."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Instantiate(...)"})," provides an API similar to ",(0,t.jsx)(n.code,{children:"Module(...)"}),", except it uses\n",(0,t.jsx)(n.code,{children:"Definition"})," and ",(0,t.jsx)(n.code,{children:"Instance"})," to only elaborate modules once for a given set of\nparameters. It returns an ",(0,t.jsx)(n.code,{children:"Instance"})," object."]}),"\n",(0,t.jsxs)(n.p,{children:["Modules (classes or traits) which will be used with the ",(0,t.jsx)(n.code,{children:"Definition"}),"/",(0,t.jsx)(n.code,{children:"Instance"})," api should be marked\nwith the ",(0,t.jsx)(n.code,{children:"@instantiable"})," annotation at the class/trait definition."]}),"\n",(0,t.jsxs)(n.p,{children:["To make a Module's members variables accessible from an ",(0,t.jsx)(n.code,{children:"Instance"})," object, they must be annotated\nwith the ",(0,t.jsx)(n.code,{children:"@public"})," annotation. Note that this is only accessible from a Scala sense\u2014this is not\nin and of itself a mechanism for cross-module references."]}),"\n",(0,t.jsx)(n.h3,{id:"using-definition-and-instance",children:"Using Definition and Instance"}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, use ",(0,t.jsx)(n.code,{children:"Definition"}),", ",(0,t.jsx)(n.code,{children:"Instance"}),", ",(0,t.jsx)(n.code,{children:"@instantiable"})," and ",(0,t.jsx)(n.code,{children:"@public"})," to create\nmultiple instances of one specific parameterization of a module, ",(0,t.jsx)(n.code,{children:"AddOne"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public}\n\n@instantiable\nclass AddOne(width: Int) extends Module {\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass AddTwo(width: Int) extends Module {\n val in = IO(Input(UInt(width.W)))\n val out = IO(Output(UInt(width.W)))\n val addOneDef = Definition(new AddOne(width))\n val i0 = Instance(addOneDef)\n val i1 = Instance(addOneDef)\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:14:2\n input [9:0] in,\t// hierarchy.md:16:23\n output [9:0] out\t// hierarchy.md:17:23\n);\n\n assign out = in + 10'h1;\t// hierarchy.md:14:2, :18:13\nendmodule\n\nmodule AddTwo(\t// hierarchy.md:22:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [9:0] in,\t// hierarchy.md:23:15\n output [9:0] out\t// hierarchy.md:24:15\n);\n\n wire [9:0] _i0_out;\t// hierarchy.md:26:20\n AddOne i0 (\t// hierarchy.md:26:20\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:27:20\n .in (_i0_out),\t// hierarchy.md:26:20\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"using-instantiate",children:"Using Instantiate"}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the above, the following example uses ",(0,t.jsx)(n.code,{children:"Instantiate"})," to create\nmultiple instances of ",(0,t.jsx)(n.code,{children:"AddOne"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.hierarchy.Instantiate\n\nclass AddTwoInstantiate(width: Int) extends Module {\n val in = IO(Input(UInt(width.W)))\n val out = IO(Output(UInt(width.W)))\n val i0 = Instantiate(new AddOne(width))\n val i1 = Instantiate(new AddOne(width))\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:14:2\n input [15:0] in,\t// hierarchy.md:16:23\n output [15:0] out\t// hierarchy.md:17:23\n);\n\n assign out = in + 16'h1;\t// hierarchy.md:14:2, :18:13\nendmodule\n\nmodule AddTwoInstantiate(\t// hierarchy.md:46:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [15:0] in,\t// hierarchy.md:47:15\n output [15:0] out\t// hierarchy.md:48:15\n);\n\n wire [15:0] _i0_out;\t// hierarchy.md:49:23\n AddOne i0 (\t// hierarchy.md:49:23\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:50:23\n .in (_i0_out),\t// hierarchy.md:49:23\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-access-internal-fields-of-an-instance",children:"How do I access internal fields of an instance?"}),"\n",(0,t.jsxs)(n.p,{children:["You can mark internal members of a class or trait marked with ",(0,t.jsx)(n.code,{children:"@instantiable"})," with the ",(0,t.jsx)(n.code,{children:"@public"})," annotation.\nThe requirements are that the field is publicly accessible, is a ",(0,t.jsx)(n.code,{children:"val"})," or ",(0,t.jsx)(n.code,{children:"lazy val"}),", and is a valid type.\nThe list of valid types are:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"IsInstantiable"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"IsLookupable"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Data"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"BaseModule"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Iterable"}),"/",(0,t.jsx)(n.code,{children:"Option "}),"containing a type that meets these requirements"]}),"\n",(0,t.jsxs)(n.li,{children:["Basic type like ",(0,t.jsx)(n.code,{children:"String"}),", ",(0,t.jsx)(n.code,{children:"Int"}),", ",(0,t.jsx)(n.code,{children:"BigInt"})," etc."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To mark a superclass's member as ",(0,t.jsx)(n.code,{children:"@public"}),", use the following pattern (shown with ",(0,t.jsx)(n.code,{children:"val clock"}),")."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{instantiable, public}\n\n@instantiable\nclass MyModule extends Module {\n @public val clock = clock\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You'll get the following error message for improperly marking something as ",(0,t.jsx)(n.code,{children:"@public"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{instantiable, public}\n\nobject NotValidType\n\n@instantiable\nclass MyModule extends Module {\n @public val x = NotValidType\n}\n// error: @public is only legal within a class or trait marked @instantiable, and only on vals of type Data, BaseModule, MemBase, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, Either, or Tuple2\n// val x = circt.stage.ChiselStage.emitCHIRRTL(new Top)\n// ^\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-make-my-parameters-accessible-from-an-instance",children:"How do I make my parameters accessible from an instance?"}),"\n",(0,t.jsxs)(n.p,{children:["If an instance's parameters are simple (e.g. ",(0,t.jsx)(n.code,{children:"Int"}),", ",(0,t.jsx)(n.code,{children:"String"})," etc.) they can be marked directly with ",(0,t.jsx)(n.code,{children:"@public"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Often, parameters are more complicated and are contained in case classes.\nIn such cases, mark the case class with the ",(0,t.jsx)(n.code,{children:"IsLookupable"})," trait.\nThis indicates to Chisel that instances of the ",(0,t.jsx)(n.code,{children:"IsLookupable"})," class may be accessed from within instances."]}),"\n",(0,t.jsxs)(n.p,{children:["However, ensure that these parameters are true for ",(0,t.jsx)(n.strong,{children:"all"})," instances of a definition.\nFor example, if our parameters contained an id field which was instance-specific but defaulted to zero,\nthen the definition's id would be returned for all instances.\nThis change in behavior could lead to bugs if other code presumed the id field was correct."]}),"\n",(0,t.jsxs)(n.p,{children:["Thus, it is important that when converting normal modules to use this package,\nyou are careful about what you mark as ",(0,t.jsx)(n.code,{children:"IsLookupable"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, we added the trait ",(0,t.jsx)(n.code,{children:"IsLookupable"})," to allow the member to be marked ",(0,t.jsx)(n.code,{children:"@public"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, IsLookupable, public}\n\ncase class MyCaseClass(width: Int) extends IsLookupable\n\n@instantiable\nclass MyModule extends Module {\n @public val x = MyCaseClass(10)\n}\n\nclass Top extends Module {\n val inst = Instance(Definition(new MyModule))\n println(s"Width is ${inst.x.width}")\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Width is 10\nCircuit(Top,List(DefModule(repl.MdocSession$MdocApp5$MyModule@377a5d2e,MyModule,List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo)),Vector()), DefModule(repl.MdocSession$MdocApp5$Top@51cd88c4,Top,List(Port(Top.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(Top.reset: IO[Bool],Input,UnlocatableSourceInfo)),Vector(DefInstance(SourceLine(hierarchy.md,112,22),ModuleClone(repl.MdocSession$MdocApp5$MyModule@377a5d2e),List(Port(MyModule.clock: IO[Clock],Input,UnlocatableSourceInfo), Port(MyModule.reset: IO[Reset],Input,UnlocatableSourceInfo))), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.clock: IO[Clock]),Node(Top.clock: IO[Clock])), Connect(SourceLine(hierarchy.md,112,22),Node(MyModule.inst.reset: IO[Reset]),Node(Top.reset: IO[Bool]))))),List(),firrtl.renamemap.package$MutableRenameMap@43318f64,List(),List(),List())\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-look-up-parameters-from-a-definition-if-i-dont-want-to-instantiate-it",children:"How do I look up parameters from a Definition, if I don't want to instantiate it?"}),"\n",(0,t.jsxs)(n.p,{children:["Just like ",(0,t.jsx)(n.code,{children:"Instance"}),"s, ",(0,t.jsx)(n.code,{children:"Definition"}),"'s also contain accessors for ",(0,t.jsx)(n.code,{children:"@public"})," members.\nAs such, you can directly access them:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, instantiable, public}\n\n@instantiable\nclass AddOne(val width: Int) extends RawModule {\n @public val width = width\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass Top extends Module {\n val definition = Definition(new AddOne(10))\n println(s"Width is: ${definition.width}")\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Top(\t// hierarchy.md:157:7\n input clock,\t// :12:11\n reset\t// :13:11\n);\n\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-parameterize-a-module-by-its-children-instances",children:"How do I parameterize a module by its children instances?"}),"\n",(0,t.jsx)(n.p,{children:"Prior to the introduction of this package, a parent module would have to pass all necessary parameters\nwhen instantiating a child module.\nThis had the unfortunate consequence of requiring a parent's parameters to always contain the child's\nparameters, which was an unnecessary coupling which lead to some anti-patterns."}),"\n",(0,t.jsxs)(n.p,{children:["Now, a parent can take a child ",(0,t.jsx)(n.code,{children:"Definition"})," as an argument, and instantiate it directly.\nIn addition, it can analyze the parameters used in the definition to parameterize itself.\nIn a sense, now the child can actually parameterize the parent."]}),"\n",(0,t.jsxs)(n.p,{children:["In the following example, we create a definition of ",(0,t.jsx)(n.code,{children:"AddOne"}),", and pass the definition to ",(0,t.jsx)(n.code,{children:"AddTwo"}),".\nThe width of the ",(0,t.jsx)(n.code,{children:"AddTwo"})," ports are now derived from the parameterization of the ",(0,t.jsx)(n.code,{children:"AddOne"})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public}\n\n@instantiable\nclass AddOne(val width: Int) extends Module {\n @public val width = width\n @public val in = IO(Input(UInt(width.W)))\n @public val out = IO(Output(UInt(width.W)))\n out := in + 1.U\n}\n\nclass AddTwo(addOneDef: Definition[AddOne]) extends Module {\n val i0 = Instance(addOneDef)\n val i1 = Instance(addOneDef)\n val in = IO(Input(UInt(addOneDef.width.W)))\n val out = IO(Output(UInt(addOneDef.width.W)))\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule AddOne(\t// hierarchy.md:181:2\n input [9:0] in,\t// hierarchy.md:184:23\n output [9:0] out\t// hierarchy.md:185:23\n);\n\n assign out = in + 10'h1;\t// hierarchy.md:181:2, :186:13\nendmodule\n\nmodule AddTwo(\t// hierarchy.md:190:7\n input clock,\t// :14:11\n reset,\t// :15:11\n input [9:0] in,\t// hierarchy.md:193:15\n output [9:0] out\t// hierarchy.md:194:15\n);\n\n wire [9:0] _i0_out;\t// hierarchy.md:191:20\n AddOne i0 (\t// hierarchy.md:191:20\n .in (in),\n .out (_i0_out)\n );\n AddOne i1 (\t// hierarchy.md:192:20\n .in (_i0_out),\t// hierarchy.md:191:20\n .out (out)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"how-do-i-use-the-new-hierarchy-specific-select-functions",children:"How do I use the new hierarchy-specific Select functions?"}),"\n",(0,t.jsx)(n.p,{children:"Select functions can be applied after a module has been elaborated, either in a Chisel Aspect or in a parent module applied to a child module."}),"\n",(0,t.jsxs)(n.p,{children:["There are seven hierarchy-specific functions, which (with the exception of ",(0,t.jsx)(n.code,{children:"ios"}),") either return ",(0,t.jsx)(n.code,{children:"Instance"}),"'s or ",(0,t.jsx)(n.code,{children:"Definition"}),"'s:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"instancesIn(parent)"}),": Return all instances directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"instancesOf[type](parent)"}),": Return all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"allInstancesOf[type](root)"}),": Return all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly and indirectly instantiated, locally and deeply, starting from ",(0,t.jsx)(n.code,{children:"root"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"definitionsIn"}),": Return definitions of all instances directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"definitionsOf[type]"}),": Return definitions of all instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly instantiated locally within ",(0,t.jsx)(n.code,{children:"parent"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"allDefinitionsOf[type]"}),": Return all definitions of instances of provided ",(0,t.jsx)(n.code,{children:"type"})," directly and indirectly instantiated, locally and deeply, starting from ",(0,t.jsx)(n.code,{children:"root"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"ios"}),": Returns all the I/Os of the provided definition or instance."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To demonstrate this, consider the following. We mock up an example where we are using the ",(0,t.jsx)(n.code,{children:"Select.allInstancesOf"})," and ",(0,t.jsx)(n.code,{children:"Select.allDefinitionsOf"})," to annotate instances and the definition of ",(0,t.jsx)(n.code,{children:"EmptyModule"}),". When converting the ",(0,t.jsx)(n.code,{children:"ChiselAnnotation"})," to firrtl's ",(0,t.jsx)(n.code,{children:"Annotation"}),", we print out the resulting ",(0,t.jsx)(n.code,{children:"Target"}),". As shown, despite ",(0,t.jsx)(n.code,{children:"EmptyModule"})," actually only being elaborated once, we still provide different targets depending on how the instance or definition is selected."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\nimport chisel3.experimental.hierarchy.{Definition, Instance, Hierarchy, instantiable, public}\nimport firrtl.annotations.{IsModule, NoTargetAnnotation}\ncase object EmptyAnnotation extends NoTargetAnnotation\ncase class MyChiselAnnotation(m: Hierarchy[RawModule], tag: String) extends experimental.ChiselAnnotation {\n def toFirrtl = {\n println(tag + ": " + m.toTarget)\n EmptyAnnotation\n }\n}\n\n@instantiable\nclass EmptyModule extends Module {\n println("Elaborating EmptyModule!")\n}\n\n@instantiable\nclass TwoEmptyModules extends Module {\n val definition = Definition(new EmptyModule)\n val i0 = Instance(definition)\n val i1 = Instance(definition)\n}\n\nclass Top extends Module {\n val definition = Definition(new TwoEmptyModules)\n val instance = Instance(definition)\n aop.Select.allInstancesOf[EmptyModule](instance).foreach { i =>\n experimental.annotate(MyChiselAnnotation(i, "instance"))\n }\n aop.Select.allDefinitionsOf[EmptyModule](instance).foreach { d =>\n experimental.annotate(MyChiselAnnotation(d, "definition"))\n }\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Elaborating EmptyModule!\ninstance: ~Top|Top/instance:TwoEmptyModules/i0:EmptyModule\ninstance: ~Top|Top/instance:TwoEmptyModules/i1:EmptyModule\ndefinition: ~Top|EmptyModule\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can also use ",(0,t.jsx)(n.code,{children:"Select.ios"})," on either a ",(0,t.jsx)(n.code,{children:"Definition"})," or an ",(0,t.jsx)(n.code,{children:"Instance"})," to annotate the I/Os appropriately:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'case class MyIOAnnotation(m: Data, tag: String) extends experimental.ChiselAnnotation {\n def toFirrtl = {\n println(tag + ": " + m.toTarget)\n EmptyAnnotation\n }\n}\n\n@instantiable\nclass InOutModule extends Module {\n @public val in = IO(Input(Bool()))\n @public val out = IO(Output(Bool()))\n out := in\n}\n\n@instantiable\nclass TwoInOutModules extends Module {\n val in = IO(Input(Bool()))\n val out = IO(Output(Bool()))\n val definition = Definition(new InOutModule)\n val i0 = Instance(definition)\n val i1 = Instance(definition)\n i0.in := in\n i1.in := i0.out\n out := i1.out\n}\n\nclass InOutTop extends Module {\n val definition = Definition(new TwoInOutModules)\n val instance = Instance(definition)\n aop.Select.allInstancesOf[InOutModule](instance).foreach { i =>\n aop.Select.ios(i).foreach { io =>\n experimental.annotate(MyIOAnnotation(io, "instance io"))\n }}\n aop.Select.allDefinitionsOf[InOutModule](instance).foreach { d =>\n aop.Select.ios(d).foreach {io =>\n experimental.annotate(MyIOAnnotation(io, "definition io"))\n }}\n}\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"instance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>clock\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>reset\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>in\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i0:InOutModule>out\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>clock\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>reset\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>in\ninstance io: ~InOutTop|InOutTop/instance:TwoInOutModules/i1:InOutModule>out\ndefinition io: ~InOutTop|InOutModule>clock\ndefinition io: ~InOutTop|InOutModule>reset\ndefinition io: ~InOutTop|InOutModule>in\ndefinition io: ~InOutTop|InOutModule>out\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>s});var t=i(7294);const o={},a=t.createContext(o);function s(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b5bfa87.a9fd9e71.js b/assets/js/7b5bfa87.c6f039ea.js similarity index 99% rename from assets/js/7b5bfa87.a9fd9e71.js rename to assets/js/7b5bfa87.c6f039ea.js index bb05ccc1217..e36ccbe2e10 100644 --- a/assets/js/7b5bfa87.a9fd9e71.js +++ b/assets/js/7b5bfa87.c6f039ea.js @@ -1 +1 @@ -"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[4003],{1235:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>c,toc:()=>i});var l=a(5893),s=a(1151);const t={layout:"docs",title:"Chisel Type vs Scala Type",section:"chisel3"},o="Chisel Type vs Scala Type",c={id:"explanations/chisel-type-vs-scala-type",title:"Chisel Type vs Scala Type",description:"The Scala compiler cannot distinguish between Chisel's representation of hardware such as false.B, Reg(Bool())",source:"@site/docs/explanations/chisel-type-vs-scala-type.md",sourceDirName:"explanations",slug:"/explanations/chisel-type-vs-scala-type",permalink:"/docs/explanations/chisel-type-vs-scala-type",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/explanations/chisel-type-vs-scala-type.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Chisel Type vs Scala Type",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Enumerations",permalink:"/docs/explanations/chisel-enum"},next:{title:"Combinational Circuits",permalink:"/docs/explanations/combinational-circuits"}},p={},i=[{value:"Scala Type vs Chisel Type vs Hardware",id:"scala-type-vs-chisel-type-vs-hardware",level:2},{value:"Chisel Type vs Hardware vs Literals",id:"chisel-type-vs-hardware-vs-literals",level:2},{value:"Chisel Type vs Hardware -- Specific Functions and Errors",id:"chisel-type-vs-hardware----specific-functions-and-errors",level:2},{value:".asInstanceOf vs .asTypeOf vs chiselTypeOf",id:"asinstanceof-vs-astypeof-vs-chiseltypeof",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(n.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(n.code,{children:"false.B"}),", ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(n.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(n.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(n.code,{children:"Bool"}),", ",(0,l.jsx)(n.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(n.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class MyBundle(w: Int) extends Bundle {\n val foo = UInt(w.W)\n val bar = UInt(w.W)\n}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Chisel"})," type of a ",(0,l.jsx)(n.code,{children:"Data"})," is a Scala object. It captures all the fields actually present,\nby names, and their types including widths.\nFor example, ",(0,l.jsx)(n.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(n.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Hardware is ",(0,l.jsx)(n.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(n.code,{children:"false.B"})," or ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),".\nThe binding is what determines the actual directionality of each field, it is not a property of the Chisel type."]}),"\n",(0,l.jsxs)(n.p,{children:["A literal is a ",(0,l.jsx)(n.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(n.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(n.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.BundleLiterals._\n\nclass MyModule(gen: () => MyBundle) extends Module {\n // Hardware Literal\n val xType: MyBundle = new MyBundle(3) // - -\n val dirXType: MyBundle = Input(new MyBundle(3)) // - -\n val xReg: MyBundle = Reg(new MyBundle(3)) // x -\n val xIO: MyBundle = IO(Input(new MyBundle(3))) // x -\n val xRegInit: MyBundle = RegInit(xIO) // x -\n val xLit: MyBundle = xType.Lit( // x x\n _.foo -> 0.U(3.W),\n _.bar -> 0.U(3.W)\n )\n val y: MyBundle = gen() // ? ?\n\n // Need to initialize all hardware values\n xReg := DontCare\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val chiselType = new MyBundle(3)\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val a = 0.U.asTypeOf(chiselType)\n val b = 0.U.asTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n chiselType := DontCare\n})\n// chisel3.package$ExpectedHardwareException: data to be connected 'MyBundle' must be hardware, not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21$$anon$3.(chisel-type-vs-scala-type.md:90)\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21.apply(chisel-type-vs-scala-type.md:88)\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21.apply(chisel-type-vs-scala-type.md:88)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," from hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = IO(new MyBundle(3))\n val moarHardware = Wire(new MyBundle(3))\n moarHardware := DontCare\n hardware := moarHardware\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val hardware = IO(new MyBundle(3))\n val chiselType = new MyBundle(3)\n hardware := chiselType\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$29$$anonfun$apply$27$$anon$5.(chisel-type-vs-scala-type.md:115)\n// \tat repl.MdocSession$MdocApp$$anonfun$29$$anonfun$apply$27.apply(chisel-type-vs-scala-type.md:112)\n// \tat repl.MdocSession$MdocApp$$anonfun$29$$anonfun$apply$27.apply(chisel-type-vs-scala-type.md:112)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Have to pass hardware to ",(0,l.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val chiselType = chiselTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n val crash = chiselTypeOf(chiselType)\n})\n// chisel3.package$ExpectedHardwareException: '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$37$$anonfun$apply$34$$anon$7$$anonfun$39$$anonfun$apply$36.apply(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39$$anonfun$apply$36.apply(chisel-type-vs-scala-type.md:138)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39.apply(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7.(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34.apply(chisel-type-vs-scala-type.md:136)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34.apply(chisel-type-vs-scala-type.md:136)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Have to pass hardware to ",(0,l.jsx)(n.code,{children:"*Init"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val moarHardware = WireInit(hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val crash = WireInit(new MyBundle(3))\n})\n// chisel3.package$ExpectedHardwareException: wire initializer '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$44$$anonfun$apply$40$$anon$9$$anonfun$45$$anonfun$apply$41.apply(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45$$anonfun$apply$41.apply(chisel-type-vs-scala-type.md:160)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45.apply(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9.(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40.apply(chisel-type-vs-scala-type.md:159)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40.apply(chisel-type-vs-scala-type.md:159)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can't pass hardware to a ",(0,l.jsx)(n.code,{children:"Wire"}),", ",(0,l.jsx)(n.code,{children:"Reg"}),", ",(0,l.jsx)(n.code,{children:"IO"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n val crash = Wire(hardware)\n})\n// chisel3.package$ExpectedChiselTypeException: wire type '_44_Anon.hardware: Wire[MyBundle]' must be a Chisel type, not hardware\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51$$anonfun$apply$47.apply(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51$$anonfun$apply$47.apply(chisel-type-vs-scala-type.md:182)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51.apply(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11.(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44.apply(chisel-type-vs-scala-type.md:180)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44.apply(chisel-type-vs-scala-type.md:180)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".Lit"})," can only be called on Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardwareLit = (new MyBundle(3)).Lit(\n _.foo -> 0.U,\n _.bar -> 0.U\n )\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"//Not this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n val crash = hardware.Lit(\n _.foo -> 0.U,\n _.bar -> 0.U\n )\n})\n// chisel3.package$ExpectedChiselTypeException: bundle literal constructor model '_52_Anon.hardware: Wire[MyBundle]' must be a Chisel type, not hardware\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56$$anonfun$apply$55.apply(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56$$anonfun$apply$55.apply(chisel-type-vs-scala-type.md:206)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56.apply(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13.(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52.apply(chisel-type-vs-scala-type.md:204)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52.apply(chisel-type-vs-scala-type.md:204)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only use a Chisel type within a ",(0,l.jsx)(n.code,{children:"Bundle"})," definition:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new Bundle {\n val nested = new MyBundle(3)\n })\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val crash = Wire(new Bundle {\n val nested = Wire(new MyBundle(3))\n })\n})\n// chisel3.package$ExpectedChiselTypeException: Bundle: AnonymousBundle contains hardware fields: nested: _60_Anon.crash_nested: Wire[MyBundle]\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62$$anonfun$apply$61.apply(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62$$anonfun$apply$61.apply(chisel-type-vs-scala-type.md:232)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62.apply(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16.(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60.apply(chisel-type-vs-scala-type.md:231)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60.apply(chisel-type-vs-scala-type.md:231)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only call ",(0,l.jsx)(n.code,{children:"directionOf"})," on Hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.reflect.DataMirror\n\nclass Child extends Module{\n val hardware = IO(new MyBundle(3))\n hardware := DontCare\n val chiselType = new MyBundle(3)\n}\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val child = Module(new Child())\n child.hardware := DontCare\n val direction = DataMirror.directionOf(child.hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\nval child = Module(new Child())\n child.hardware := DontCare\n val direction = DataMirror.directionOf(child.chiselType)\n})\n// chisel3.package$ExpectedHardwareException: node requested directionality on '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$70$$anonfun$apply$68$$anon$19.(chisel-type-vs-scala-type.md:271)\n// \tat repl.MdocSession$MdocApp$$anonfun$70$$anonfun$apply$68.apply(chisel-type-vs-scala-type.md:268)\n// \tat repl.MdocSession$MdocApp$$anonfun$70$$anonfun$apply$68.apply(chisel-type-vs-scala-type.md:268)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can call ",(0,l.jsx)(n.code,{children:"specifiedDirectionOf"})," on hardware or Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val child = Module(new Child())\n child.hardware := DontCare\n val direction0 = DataMirror.specifiedDirectionOf(child.hardware)\n val direction1 = DataMirror.specifiedDirectionOf(child.chiselType)\n})\n"})}),"\n",(0,l.jsxs)(n.h2,{id:"asinstanceof-vs-astypeof-vs-chiseltypeof",children:[(0,l.jsx)(n.code,{children:".asInstanceOf"})," vs ",(0,l.jsx)(n.code,{children:".asTypeOf"})," vs ",(0,l.jsx)(n.code,{children:"chiselTypeOf"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asInstanceOf"})," is a Scala runtime cast, usually used for telling the compiler\nthat you have more information than it can infer to convert Scala types:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class ScalaCastingModule(gen: () => Bundle) extends Module {\n val io = IO(Output(gen().asInstanceOf[MyBundle]))\n io.foo := 0.U\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"This works if we do indeed have more information than the compiler:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new ScalaCastingModule( () => new MyBundle(3)))\n"})}),"\n",(0,l.jsx)(n.p,{children:"But if we are wrong, we can get a Scala runtime exception:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class NotMyBundle extends Bundle {val baz = Bool()}\nelaborate(new ScalaCastingModule(() => new NotMyBundle()))\n// 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 @72d90f16)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.SpecifiedDirection$.specifiedDirection(Data.scala:65)\n// \tat chisel3.Output$.apply(Data.scala:268)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.IO$.apply(IO.scala:34)\n// \tat chisel3.experimental.BaseModule.IO(Module.scala:751)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule.(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)\n// \tat repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," is a conversion from one ",(0,l.jsx)(n.code,{children:"Data"})," subclass to another.\nIt is commonly used to assign data to all-zeros, as described in ",(0,l.jsx)(n.a,{href:"https://www.chisel-lang.org/chisel3/docs/cookbooks/cookbook.html#how-can-i-tieoff-a-bundlevec-to-0",children:"this cookbook recipe"}),", but it can\nalso be used (though not really recommended, as there is no checking on\nwidth matches) to convert one Chisel type to another:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:'class SimilarToMyBundle(w: Int) extends Bundle{\n val foobar = UInt((2*w).W)\n}\n\nChiselStage.emitSystemVerilog(new Module {\n val in = IO(Input(new MyBundle(3)))\n val out = IO(Output(new SimilarToMyBundle(3)))\n\n out := in.asTypeOf(out)\n})\n// res12: String = """// Generated by CIRCT firtool-1.59.0\n// module _82_Anon(\t// chisel-type-vs-scala-type.md:323:47\n// input clock,\t// :4:11\n// reset,\t// :5:11\n// input [2:0] in_foo,\t// chisel-type-vs-scala-type.md:324:14\n// in_bar,\t// chisel-type-vs-scala-type.md:324:14\n// output [5:0] out_foobar\t// chisel-type-vs-scala-type.md:325:15\n// );\n// \n// assign out_foobar = {in_foo, in_bar};\t// chisel-type-vs-scala-type.md:323:47, :327:21\n// endmodule\n// \n// """\n'})}),"\n",(0,l.jsxs)(n.p,{children:["In contrast to ",(0,l.jsx)(n.code,{children:"asInstanceOf"})," and ",(0,l.jsx)(n.code,{children:"asTypeOf"}),",\n",(0,l.jsx)(n.code,{children:"chiselTypeOf"})," is not a casting operation. It returns a Scala object which\ncan be used as shown in the examples above to create more Chisel types and\nhardware with the same Chisel type as existing hardware."]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(r,{...e})}):r(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>c,a:()=>o});var l=a(7294);const s={},t=l.createContext(s);function o(e){const n=l.useContext(t);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),l.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[4003],{1235:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>c,toc:()=>i});var l=a(5893),s=a(1151);const t={layout:"docs",title:"Chisel Type vs Scala Type",section:"chisel3"},o="Chisel Type vs Scala Type",c={id:"explanations/chisel-type-vs-scala-type",title:"Chisel Type vs Scala Type",description:"The Scala compiler cannot distinguish between Chisel's representation of hardware such as false.B, Reg(Bool())",source:"@site/docs/explanations/chisel-type-vs-scala-type.md",sourceDirName:"explanations",slug:"/explanations/chisel-type-vs-scala-type",permalink:"/docs/explanations/chisel-type-vs-scala-type",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/explanations/chisel-type-vs-scala-type.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"Chisel Type vs Scala Type",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Enumerations",permalink:"/docs/explanations/chisel-enum"},next:{title:"Combinational Circuits",permalink:"/docs/explanations/combinational-circuits"}},p={},i=[{value:"Scala Type vs Chisel Type vs Hardware",id:"scala-type-vs-chisel-type-vs-hardware",level:2},{value:"Chisel Type vs Hardware vs Literals",id:"chisel-type-vs-hardware-vs-literals",level:2},{value:"Chisel Type vs Hardware -- Specific Functions and Errors",id:"chisel-type-vs-hardware----specific-functions-and-errors",level:2},{value:".asInstanceOf vs .asTypeOf vs chiselTypeOf",id:"asinstanceof-vs-astypeof-vs-chiseltypeof",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"chisel-type-vs-scala-type",children:"Chisel Type vs Scala Type"}),"\n",(0,l.jsxs)(n.p,{children:["The Scala compiler cannot distinguish between Chisel's representation of hardware such as ",(0,l.jsx)(n.code,{children:"false.B"}),", ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),"\nand pure Chisel types (e.g. ",(0,l.jsx)(n.code,{children:"Bool()"}),"). You can get runtime errors passing a Chisel type when hardware is expected, and vice versa."]}),"\n",(0,l.jsx)(n.h2,{id:"scala-type-vs-chisel-type-vs-hardware",children:"Scala Type vs Chisel Type vs Hardware"}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Scala"})," type of the Data is recognized by the Scala compiler, such as ",(0,l.jsx)(n.code,{children:"Bool"}),", ",(0,l.jsx)(n.code,{children:"Decoupled[UInt]"})," or ",(0,l.jsx)(n.code,{children:"MyBundle"})," in"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class MyBundle(w: Int) extends Bundle {\n val foo = UInt(w.W)\n val bar = UInt(w.W)\n}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.em,{children:"Chisel"})," type of a ",(0,l.jsx)(n.code,{children:"Data"})," is a Scala object. It captures all the fields actually present,\nby names, and their types including widths.\nFor example, ",(0,l.jsx)(n.code,{children:"MyBundle(3)"})," creates a Chisel Type with fields ",(0,l.jsx)(n.code,{children:"foo: UInt(3.W), bar: UInt(3.W))"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Hardware is ",(0,l.jsx)(n.code,{children:"Data"}),' that is "bound" to synthesizable hardware. For example ',(0,l.jsx)(n.code,{children:"false.B"})," or ",(0,l.jsx)(n.code,{children:"Reg(Bool())"}),".\nThe binding is what determines the actual directionality of each field, it is not a property of the Chisel type."]}),"\n",(0,l.jsxs)(n.p,{children:["A literal is a ",(0,l.jsx)(n.code,{children:"Data"})," that is respresentable as a literal value without being wrapped in Wire, Reg, or IO."]}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware-vs-literals",children:"Chisel Type vs Hardware vs Literals"}),"\n",(0,l.jsxs)(n.p,{children:["The below code demonstrates how objects with the same Scala type (",(0,l.jsx)(n.code,{children:"MyBundle"}),") can have different properties."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.experimental.BundleLiterals._\n\nclass MyModule(gen: () => MyBundle) extends Module {\n // Hardware Literal\n val xType: MyBundle = new MyBundle(3) // - -\n val dirXType: MyBundle = Input(new MyBundle(3)) // - -\n val xReg: MyBundle = Reg(new MyBundle(3)) // x -\n val xIO: MyBundle = IO(Input(new MyBundle(3))) // x -\n val xRegInit: MyBundle = RegInit(xIO) // x -\n val xLit: MyBundle = xType.Lit( // x x\n _.foo -> 0.U(3.W),\n _.bar -> 0.U(3.W)\n )\n val y: MyBundle = gen() // ? ?\n\n // Need to initialize all hardware values\n xReg := DontCare\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"chisel-type-vs-hardware----specific-functions-and-errors",children:"Chisel Type vs Hardware -- Specific Functions and Errors"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," works for both hardware and Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val chiselType = new MyBundle(3)\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val a = 0.U.asTypeOf(chiselType)\n val b = 0.U.asTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," to hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n chiselType := DontCare\n})\n// chisel3.package$ExpectedHardwareException: data to be connected 'MyBundle' must be hardware, not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21$$anon$3.(chisel-type-vs-scala-type.md:90)\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21.apply(chisel-type-vs-scala-type.md:88)\n// \tat repl.MdocSession$MdocApp$$anonfun$21$$anonfun$apply$21.apply(chisel-type-vs-scala-type.md:88)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only ",(0,l.jsx)(n.code,{children:":="})," from hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = IO(new MyBundle(3))\n val moarHardware = Wire(new MyBundle(3))\n moarHardware := DontCare\n hardware := moarHardware\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val hardware = IO(new MyBundle(3))\n val chiselType = new MyBundle(3)\n hardware := chiselType\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$29$$anonfun$apply$27$$anon$5.(chisel-type-vs-scala-type.md:115)\n// \tat repl.MdocSession$MdocApp$$anonfun$29$$anonfun$apply$27.apply(chisel-type-vs-scala-type.md:112)\n// \tat repl.MdocSession$MdocApp$$anonfun$29$$anonfun$apply$27.apply(chisel-type-vs-scala-type.md:112)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Have to pass hardware to ",(0,l.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val chiselType = chiselTypeOf(hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val chiselType = new MyBundle(3)\n val crash = chiselTypeOf(chiselType)\n})\n// chisel3.package$ExpectedHardwareException: '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$37$$anonfun$apply$34$$anon$7$$anonfun$39$$anonfun$apply$36.apply(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39$$anonfun$apply$36.apply(chisel-type-vs-scala-type.md:138)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39.apply(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7$$anonfun$39.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34$$anon$7.(chisel-type-vs-scala-type.md:138)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34.apply(chisel-type-vs-scala-type.md:136)\n// \tat repl.MdocSession$MdocApp$$anonfun$37$$anonfun$apply$34.apply(chisel-type-vs-scala-type.md:136)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Have to pass hardware to ",(0,l.jsx)(n.code,{children:"*Init"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n val moarHardware = WireInit(hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val crash = WireInit(new MyBundle(3))\n})\n// chisel3.package$ExpectedHardwareException: wire initializer '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$44$$anonfun$apply$40$$anon$9$$anonfun$45$$anonfun$apply$41.apply(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45$$anonfun$apply$41.apply(chisel-type-vs-scala-type.md:160)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45.apply(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9$$anonfun$45.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40$$anon$9.(chisel-type-vs-scala-type.md:160)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40.apply(chisel-type-vs-scala-type.md:159)\n// \tat repl.MdocSession$MdocApp$$anonfun$44$$anonfun$apply$40.apply(chisel-type-vs-scala-type.md:159)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can't pass hardware to a ",(0,l.jsx)(n.code,{children:"Wire"}),", ",(0,l.jsx)(n.code,{children:"Reg"}),", ",(0,l.jsx)(n.code,{children:"IO"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n val crash = Wire(hardware)\n})\n// chisel3.package$ExpectedChiselTypeException: wire type '_44_Anon.hardware: Wire[MyBundle]' must be a Chisel type, not hardware\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51$$anonfun$apply$47.apply(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51$$anonfun$apply$47.apply(chisel-type-vs-scala-type.md:182)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51.apply(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11$$anonfun$51.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44$$anon$11.(chisel-type-vs-scala-type.md:182)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44.apply(chisel-type-vs-scala-type.md:180)\n// \tat repl.MdocSession$MdocApp$$anonfun$49$$anonfun$apply$44.apply(chisel-type-vs-scala-type.md:180)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".Lit"})," can only be called on Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardwareLit = (new MyBundle(3)).Lit(\n _.foo -> 0.U,\n _.bar -> 0.U\n )\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"//Not this...\nelaborate(new Module {\n val hardware = Wire(new MyBundle(3))\n val crash = hardware.Lit(\n _.foo -> 0.U,\n _.bar -> 0.U\n )\n})\n// chisel3.package$ExpectedChiselTypeException: bundle literal constructor model '_52_Anon.hardware: Wire[MyBundle]' must be a Chisel type, not hardware\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56$$anonfun$apply$55.apply(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56$$anonfun$apply$55.apply(chisel-type-vs-scala-type.md:206)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56.apply(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13$$anonfun$56.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52$$anon$13.(chisel-type-vs-scala-type.md:206)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52.apply(chisel-type-vs-scala-type.md:204)\n// \tat repl.MdocSession$MdocApp$$anonfun$54$$anonfun$apply$52.apply(chisel-type-vs-scala-type.md:204)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only use a Chisel type within a ",(0,l.jsx)(n.code,{children:"Bundle"})," definition:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val hardware = Wire(new Bundle {\n val nested = new MyBundle(3)\n })\n hardware := DontCare\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\n val crash = Wire(new Bundle {\n val nested = Wire(new MyBundle(3))\n })\n})\n// chisel3.package$ExpectedChiselTypeException: Bundle: AnonymousBundle contains hardware fields: nested: _60_Anon.crash_nested: Wire[MyBundle]\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62$$anonfun$apply$61.apply(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62$$anonfun$apply$61.apply(chisel-type-vs-scala-type.md:232)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62.apply(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16$$anonfun$62.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60$$anon$16.(chisel-type-vs-scala-type.md:232)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60.apply(chisel-type-vs-scala-type.md:231)\n// \tat repl.MdocSession$MdocApp$$anonfun$61$$anonfun$apply$60.apply(chisel-type-vs-scala-type.md:231)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can only call ",(0,l.jsx)(n.code,{children:"directionOf"})," on Hardware:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"import chisel3.reflect.DataMirror\n\nclass Child extends Module{\n val hardware = IO(new MyBundle(3))\n hardware := DontCare\n val chiselType = new MyBundle(3)\n}\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Do this...\nelaborate(new Module {\n val child = Module(new Child())\n child.hardware := DontCare\n val direction = DataMirror.directionOf(child.hardware)\n})\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"// Not this...\nelaborate(new Module {\nval child = Module(new Child())\n child.hardware := DontCare\n val direction = DataMirror.directionOf(child.chiselType)\n})\n// chisel3.package$ExpectedHardwareException: node requested directionality on '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$70$$anonfun$apply$68$$anon$19.(chisel-type-vs-scala-type.md:271)\n// \tat repl.MdocSession$MdocApp$$anonfun$70$$anonfun$apply$68.apply(chisel-type-vs-scala-type.md:268)\n// \tat repl.MdocSession$MdocApp$$anonfun$70$$anonfun$apply$68.apply(chisel-type-vs-scala-type.md:268)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Can call ",(0,l.jsx)(n.code,{children:"specifiedDirectionOf"})," on hardware or Chisel type:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new Module {\n val child = Module(new Child())\n child.hardware := DontCare\n val direction0 = DataMirror.specifiedDirectionOf(child.hardware)\n val direction1 = DataMirror.specifiedDirectionOf(child.chiselType)\n})\n"})}),"\n",(0,l.jsxs)(n.h2,{id:"asinstanceof-vs-astypeof-vs-chiseltypeof",children:[(0,l.jsx)(n.code,{children:".asInstanceOf"})," vs ",(0,l.jsx)(n.code,{children:".asTypeOf"})," vs ",(0,l.jsx)(n.code,{children:"chiselTypeOf"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asInstanceOf"})," is a Scala runtime cast, usually used for telling the compiler\nthat you have more information than it can infer to convert Scala types:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class ScalaCastingModule(gen: () => Bundle) extends Module {\n val io = IO(Output(gen().asInstanceOf[MyBundle]))\n io.foo := 0.U\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"This works if we do indeed have more information than the compiler:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"elaborate(new ScalaCastingModule( () => new MyBundle(3)))\n"})}),"\n",(0,l.jsx)(n.p,{children:"But if we are wrong, we can get a Scala runtime exception:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:"class NotMyBundle extends Bundle {val baz = Bool()}\nelaborate(new ScalaCastingModule(() => new NotMyBundle()))\n// 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 @658fa56c)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72$$anonfun$apply$73.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.SpecifiedDirection$.specifiedDirection(Data.scala:65)\n// \tat chisel3.Output$.apply(Data.scala:268)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71$$anonfun$apply$72.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.IO$.apply(IO.scala:34)\n// \tat chisel3.experimental.BaseModule.IO(Module.scala:751)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76$$anonfun$apply$71.apply(chisel-type-vs-scala-type.md:293)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule$$anonfun$76.apply(chisel-type-vs-scala-type.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp$ScalaCastingModule.(chisel-type-vs-scala-type.md:293)\n// \tat repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)\n// \tat repl.MdocSession$MdocApp$$anonfun$79$$anonfun$apply$75.apply(chisel-type-vs-scala-type.md:309)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:".asTypeOf"})," is a conversion from one ",(0,l.jsx)(n.code,{children:"Data"})," subclass to another.\nIt is commonly used to assign data to all-zeros, as described in ",(0,l.jsx)(n.a,{href:"https://www.chisel-lang.org/chisel3/docs/cookbooks/cookbook.html#how-can-i-tieoff-a-bundlevec-to-0",children:"this cookbook recipe"}),", but it can\nalso be used (though not really recommended, as there is no checking on\nwidth matches) to convert one Chisel type to another:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scala",children:'class SimilarToMyBundle(w: Int) extends Bundle{\n val foobar = UInt((2*w).W)\n}\n\nChiselStage.emitSystemVerilog(new Module {\n val in = IO(Input(new MyBundle(3)))\n val out = IO(Output(new SimilarToMyBundle(3)))\n\n out := in.asTypeOf(out)\n})\n// res12: String = """// Generated by CIRCT firtool-1.59.0\n// module _82_Anon(\t// chisel-type-vs-scala-type.md:323:47\n// input clock,\t// :4:11\n// reset,\t// :5:11\n// input [2:0] in_foo,\t// chisel-type-vs-scala-type.md:324:14\n// in_bar,\t// chisel-type-vs-scala-type.md:324:14\n// output [5:0] out_foobar\t// chisel-type-vs-scala-type.md:325:15\n// );\n// \n// assign out_foobar = {in_foo, in_bar};\t// chisel-type-vs-scala-type.md:323:47, :327:21\n// endmodule\n// \n// """\n'})}),"\n",(0,l.jsxs)(n.p,{children:["In contrast to ",(0,l.jsx)(n.code,{children:"asInstanceOf"})," and ",(0,l.jsx)(n.code,{children:"asTypeOf"}),",\n",(0,l.jsx)(n.code,{children:"chiselTypeOf"})," is not a casting operation. It returns a Scala object which\ncan be used as shown in the examples above to create more Chisel types and\nhardware with the same Chisel type as existing hardware."]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(r,{...e})}):r(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>c,a:()=>o});var l=a(7294);const s={},t=l.createContext(s);function o(e){const n=l.useContext(t);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),l.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e1e4a75.46d55ce9.js b/assets/js/7e1e4a75.102883e3.js similarity index 99% rename from assets/js/7e1e4a75.46d55ce9.js rename to assets/js/7e1e4a75.102883e3.js index f767a438598..b04df6297f2 100644 --- a/assets/js/7e1e4a75.46d55ce9.js +++ b/assets/js/7e1e4a75.102883e3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[7462],{9611:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>r});var t=o(5893),i=o(1151);const a={layout:"docs",title:"General Cookbook",section:"chisel3"},l="General Cookbook",s={id:"cookbooks/cookbook",title:"General Cookbook",description:"Please note that these examples make use of Chisel's scala-style printing.",source:"@site/docs/cookbooks/cookbook.md",sourceDirName:"cookbooks",slug:"/cookbooks/cookbook",permalink:"/docs/cookbooks/cookbook",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/cookbooks/cookbook.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"General Cookbook",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Cookbooks",permalink:"/docs/cookbooks/"},next:{title:"DataView Cookbook",permalink:"/docs/cookbooks/dataview"}},c={},r=[{value:"Type Conversions",id:"type-conversions",level:2},{value:"How do I create a UInt from an instance of a Bundle?",id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",level:3},{value:"How do I create a Bundle from a UInt?",id:"how-do-i-create-a-bundle-from-a-uint",level:3},{value:"How can I tieoff a Bundle/Vec to 0?",id:"how-can-i-tieoff-a-bundlevec-to-0",level:3},{value:"How do I create a Vec of Bools from a UInt?",id:"how-do-i-create-a-vec-of-bools-from-a-uint",level:3},{value:"How do I create a UInt from a Vec of Bool?",id:"how-do-i-create-a-uint-from-a-vec-of-bool",level:3},{value:"How do I connect a subset of Bundle fields?",id:"how-do-i-connect-a-subset-of-bundle-fields",level:3},{value:"Vectors and Registers",id:"vectors-and-registers",level:2},{value:"Can I make a 2D or 3D Vector?",id:"can-i-make-a-2d-or-3d-vector",level:3},{value:"How do I create a Vector of Registers?",id:"how-do-i-create-a-vector-of-registers",level:3},{value:"How do I create a Reg of type Vec?",id:"how-do-i-create-a-reg-of-type-vec",level:3},{value:"How do I partially reset an Aggregate Reg?",id:"how-do-i-partially-reset-an-aggregate-reg",level:3},{value:"Bundles",id:"bundles",level:2},{value:" How do I deal with aliased Bundle fields?",id:"-how-do-i-deal-with-aliased-bundle-fields",level:3},{value:"1. 0-arity function parameters",id:"1-0-arity-function-parameters",level:4},{value:"2. By-name function parameters",id:"2-by-name-function-parameters",level:4},{value:"3. Directioned Bundle fields",id:"3-directioned-bundle-fields",level:4},{value:"4. Call .cloneType directly",id:"4-call-clonetype-directly",level:4},{value:" How do I deal with the "unable to clone" error?",id:"-how-do-i-deal-with-the-unable-to-clone-error",level:3},{value:"How do I create a finite state machine (FSM)?",id:"how-do-i-create-a-finite-state-machine-fsm",level:3},{value:"How do I unpack a value ("reverse concatenation") like in Verilog?",id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",level:3},{value:"How do I do subword assignment (assign to some bits in a UInt)?",id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",level:3},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:3},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:3},{value:"How do I minimize the number of bits used in an output vector?",id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",level:3},{value:" How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?",id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",level:3},{value:"Use bit extraction when the index is too wide",id:"use-bit-extraction-when-the-index-is-too-wide",level:4},{value:"Predictable Naming",id:"predictable-naming",level:2},{value:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?",id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",level:3},{value:"How do I get Chisel to name the results of vector reads properly?",id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",level:3},{value:"How can I dynamically set/parametrize the name of a module?",id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",level:3},{value:"Directionality",id:"directionality",level:2},{value:"How do I strip directions from a bidirectional Bundle (or other Data)?",id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,t.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,t.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type Conversions","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Vectors and Registers","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#can-i-make-a-2D-or-3D-Vector",children:"Can I make a 2D or 3D Vector?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Bundles","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#bundle-unable-to-clone",children:'How do I deal with the "unable to clone" error?'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#dynamic-index-too-wide-narrow",children:'How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?'})}),"\n",(0,t.jsxs)(n.li,{children:["Predictable Naming","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Directionality","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"}),"\n",(0,t.jsxs)(n.p,{children:["Call ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})," on the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val bundle = Wire(new MyBundle)\n bundle.foo := 0xc.U\n bundle.bar := 0x3.U\n val uint = bundle.asUInt\n printf(cf"$uint") // 195\n\n // Test\n assert(uint === 0xc3.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asTypeOf%5BT%3C:chisel3.Data%5D(that:T):T",children:(0,t.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,t.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val uint = 0xb4.U\n val bundle = uint.asTypeOf(new MyBundle)\n\n printf(cf"$bundle") // Bundle(foo -> 11, bar -> 4)\n\n // Test\n assert(bundle.foo === 0xb.U)\n assert(bundle.bar === 0x4.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"asTypeOf"})," as above. If you don't want to worry about the type of the thing\nyou are tying off, you can use ",(0,t.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = Vec(4, UInt(1.W))\n}\n\nclass Foo(typ: MyBundle) extends Module {\n val bundleA = IO(Output(typ))\n val bundleB = IO(Output(typ))\n\n // typ is already a Chisel Data Type, so can use it directly here, but you\n // need to know that bundleA is of type typ\n bundleA := 0.U.asTypeOf(typ)\n\n // bundleB is a Hardware data IO(Output(...)) so need to call chiselTypeOf,\n // but this will work no matter the type of bundleB:\n bundleB := 0.U.asTypeOf(chiselTypeOf(bundleB))\n}\n\nChiselStage.emitSystemVerilog(new Foo(new MyBundle))\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,t.jsx)(n.code,{children:"VecInit"})})," given a ",(0,t.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,t.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val uint = 0xc.U\n val vec = VecInit(uint.asBools)\n\n printf(cf"$vec") // Vec(0, 0, 1, 1)\n\n // Test\n assert(vec(0) === false.B)\n assert(vec(1) === false.B)\n assert(vec(2) === true.B)\n assert(vec(3) === true.B)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the builtin function ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val vec = VecInit(true.B, false.B, true.B, true.B)\n val uint = vec.asUInt\n\n printf(cf"$uint") // 13\n\n // Test\n // (remember leftmost Bool in Vec is low order bit)\n assert(0xd.U === uint)\n\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,t.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Yes. Using ",(0,t.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,t.jsx)(n.code,{children:"fill"})," and ",(0,t.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n //2D Fill\n val twoDVec = VecInit.fill(2, 3)(5.U)\n //3D Fill\n val myBundle = Wire(new MyBundle)\n myBundle.foo := 0xc.U\n myBundle.bar := 0x3.U\n val threeDVec = VecInit.fill(1, 2, 3)(myBundle)\n assert(threeDVec(0)(0)(0).foo === 0xc.U && threeDVec(0)(0)(0).bar === 0x3.U)\n\n //2D Tabulate\n val indexTiedVec = VecInit.tabulate(2, 2){ (x, y) => (x + y).U }\n assert(indexTiedVec(0)(0) === 0.U)\n assert(indexTiedVec(0)(1) === 1.U)\n assert(indexTiedVec(1)(0) === 1.U)\n assert(indexTiedVec(1)(1) === 2.U)\n //3D Tabulate\n val indexTiedVec3D = VecInit.tabulate(2, 3, 4){ (x, y, z) => (x + y * z).U }\n assert(indexTiedVec3D(0)(0)(0) === 0.U)\n assert(indexTiedVec3D(1)(1)(1) === 2.U)\n assert(indexTiedVec3D(1)(1)(2) === 3.U)\n assert(indexTiedVec3D(1)(1)(3) === 4.U)\n assert(indexTiedVec3D(1)(2)(3) === 7.U)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,t.jsxs)(n.p,{children:["You create a ",(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,t.jsx)(n.em,{children:"type"})," (like ",(0,t.jsx)(n.code,{children:"UInt"}),", ",(0,t.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,t.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,t.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"}),"\n",(0,t.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,t.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass Foo extends Module {\n val regOfVec = Reg(Vec(4, UInt(32.W))) // Register of 32-bit UInts\n regOfVec(0) := 123.U // Assignments to elements of the Vec\n regOfVec(1) := 456.U\n regOfVec(2) := 789.U\n regOfVec(3) := regOfVec(0)\n\n // Reg of Vec of 32-bit UInts initialized to zero\n // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0\n // VecInit(...) then constructs a Wire of these literals\n // The Reg is then initialized to the value of the Wire (which gives it the same type)\n val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.BundleLiterals._\n\nclass MyBundle extends Bundle {\n val foo = UInt(8.W)\n val bar = UInt(8.W)\n}\n\nclass MyModule extends Module {\n // Only .foo will be reset, .bar will have no reset value\n val reg = RegInit((new MyBundle).Lit(_.foo -> 123.U))\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If your initial value is not a literal, or if you just prefer, you can use a\nWire as the initial value for the Reg. Simply connect fields to ",(0,t.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MyModule2 extends Module {\n val reg = RegInit({\n // The wire could be constructed before the reg rather than in the RegInit scope,\n // but this style has nice lexical scoping behavior, keeping the Wire private\n val init = Wire(new MyBundle)\n init := DontCare // No fields will be reset\n init.foo := 123.U // Last connect override, .foo is reset\n init\n })\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-aliased-bundle-fields",children:[(0,t.jsx)("a",{name:"aliased-bundle-fields"})," How do I deal with aliased Bundle fields?"]}),"\n",(0,t.jsxs)(n.p,{children:["Following the ",(0,t.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AliasedBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AliasedBundle contains aliased fields named (bar,foo)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$Top.(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$$anonfun$55$$anonfun$apply$43.apply(cookbook.md:320)\n// \tat repl.MdocSession$MdocApp17$$anonfun$55$$anonfun$apply$43.apply(cookbook.md:320)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This error is saying that fields ",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," of ",(0,t.jsx)(n.code,{children:"AliasedBundle"})," are the\nexact same object in memory.\nThis is a problem for Chisel because we need to be able to distinguish uses of\n",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," but cannot when they are referentially the same."]}),"\n",(0,t.jsx)(n.p,{children:"Note that the following example looks different but will give you exactly the same issue:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AlsoAliasedBundle[T <: Data](val gen: T) extends Bundle {\n // ^ This val makes `gen` a field, just like `foo`\n val foo = gen\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["By making ",(0,t.jsx)(n.code,{children:"gen"})," a ",(0,t.jsx)(n.code,{children:"val"}),", it becomes a public field of the ",(0,t.jsx)(n.code,{children:"class"}),", just like ",(0,t.jsx)(n.code,{children:"foo"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AlsoAliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AlsoAliasedBundle contains aliased fields named (foo,gen)\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.(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$$anonfun$57$$anonfun$apply$44.apply(cookbook.md:339)\n// \tat repl.MdocSession$MdocApp17$$anonfun$57$$anonfun$apply$44.apply(cookbook.md:339)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsx)(n.p,{children:"There are several ways to solve this issue with their own advantages and disadvantages."}),"\n",(0,t.jsx)(n.h4,{id:"1-0-arity-function-parameters",children:"1. 0-arity function parameters"}),"\n",(0,t.jsx)(n.p,{children:"Instead of passing an object as a parameter, you can pass a 0-arity function (a function with no arguments):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingAFunctionBundle[T <: Data](gen: () => T) extends Bundle {\n val foo = gen()\n val bar = gen()\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that the type of ",(0,t.jsx)(n.code,{children:"gen"})," is now ",(0,t.jsx)(n.code,{children:"() => T"}),".\nBecause it is now a function and not a subtype of ",(0,t.jsx)(n.code,{children:"Data"}),", you can safely make ",(0,t.jsx)(n.code,{children:"gen"})," a ",(0,t.jsx)(n.code,{children:"val"})," without\nit becoming a hardware field of the ",(0,t.jsx)(n.code,{children:"Bundle"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Note that this also means you must pass ",(0,t.jsx)(n.code,{children:"gen"})," as a function, for example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new UsingAFunctionBundle(() => UInt(8.W))))\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)("a",{name:"aliased-warning"})," ",(0,t.jsx)(n.strong,{children:"Warning"}),": you must ensure that ",(0,t.jsx)(n.code,{children:"gen"})," creates fresh objects rather than capturing an already constructed value:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MisusedFunctionArguments extends Module {\n // This usage is correct\n val in = IO(Input(new UsingAFunctionBundle(() => UInt(8.W))))\n\n // This usage is incorrect\n val fizz = UInt(8.W)\n val out = IO(Output(new UsingAFunctionBundle(() => fizz)))\n}\ngetVerilogString(new MisusedFunctionArguments)\n// chisel3.AutoClonetypeException: The bundle plugin was unable to clone UsingAFunctionBundle that has field 'foo' aliased with base UsingAFunctionBundle.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry 'How do I deal with the \"unable to clone\" error?' for more details.\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)\n// \tat chisel3.IO$.apply(IO.scala:34)\n// \tat chisel3.experimental.BaseModule.IO(Module.scala:751)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1.(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In the above example, value ",(0,t.jsx)(n.code,{children:"fizz"})," and fields ",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," of ",(0,t.jsx)(n.code,{children:"out"})," are all the same object in memory."]}),"\n",(0,t.jsx)(n.h4,{id:"2-by-name-function-parameters",children:"2. By-name function parameters"}),"\n",(0,t.jsxs)(n.p,{children:["Functionally the same as (1) but with more subtle syntax, you can use ",(0,t.jsx)(n.a,{href:"https://docs.scala-lang.org/tour/by-name-parameters.html",children:"Scala by-name function parameters"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingByNameParameters[T <: Data](gen: => T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["With this usage, you do not include ",(0,t.jsx)(n.code,{children:"() =>"})," when passing the argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new UsingByNameParameters(UInt(8.W))))\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that as this is just syntactic sugar over (1), the ",(0,t.jsx)(n.a,{href:"#aliased-warning",children:"same warning applies"}),"."]}),"\n",(0,t.jsx)(n.h4,{id:"3-directioned-bundle-fields",children:"3. Directioned Bundle fields"}),"\n",(0,t.jsxs)(n.p,{children:["You can alternatively wrap the fields with ",(0,t.jsx)(n.code,{children:"Output(...)"}),", which creates fresh instances of the passed argument.\nChisel treats ",(0,t.jsx)(n.code,{children:"Output"}),' as the "default direction" so if all fields are outputs, the ',(0,t.jsx)(n.code,{children:"Bundle"})," is functionally equivalent to a ",(0,t.jsx)(n.code,{children:"Bundle"})," with no directioned fields."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class DirectionedBundle[T <: Data](gen: T) extends Bundle {\n val foo = Output(gen)\n val bar = Output(gen)\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This approach is admittedly a little ugly and may mislead others reading the code because it implies that this Bundle is intended to be used as an ",(0,t.jsx)(n.code,{children:"Output"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"4-call-clonetype-directly",children:["4. Call ",(0,t.jsx)(n.code,{children:".cloneType"})," directly"]}),"\n",(0,t.jsxs)(n.p,{children:["You can also just call ",(0,t.jsx)(n.code,{children:".cloneType"})," on your ",(0,t.jsx)(n.code,{children:"gen"})," argument directly.\nWhile we try to hide this implementation detail from the user, ",(0,t.jsx)(n.code,{children:".cloneType"})," is the mechanism by which Chisel creates fresh instances of ",(0,t.jsx)(n.code,{children:"Data"})," objects:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingCloneTypeBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen.cloneType\n val bar = gen.cloneType\n}\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-the-unable-to-clone-error",children:[(0,t.jsx)("a",{name:"bundle-unable-to-clone"}),' How do I deal with the "unable to clone" error?']}),"\n",(0,t.jsx)(n.p,{children:'Most Chisel objects need to be cloned in order to differentiate between the\nsoftware representation of the bundle field from its "bound" hardware\nrepresentation, where "binding" is the process of generating a hardware\ncomponent. For Bundle fields, this cloning is supposed to happen automatically\nwith a compiler plugin.'}),"\n",(0,t.jsxs)(n.p,{children:["In some cases though, the plugin may not be able to clone the Bundle fields. The\nmost common case for when this happens is when the ",(0,t.jsx)(n.code,{children:"chisel3.Data"})," part of the\nBundle field is nested inside some other data structure and the compiler plugin\nis unable to figure out how to clone the entire structure. It is best to avoid\nsuch nested structures."]}),"\n",(0,t.jsxs)(n.p,{children:["There are a few ways around this issue - you can try wrapping the problematic\nfields in Input(...), Output(...), or Flipped(...) if appropriate. You can also\ntry manually cloning each field in the Bundle using the ",(0,t.jsx)(n.code,{children:"chiselTypeClone"})," method\nin ",(0,t.jsx)(n.code,{children:"chisel3.reflect.DataMirror"}),". Here's an example with the Bundle whose fields\nwon't get cloned:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'class CustomBundleBroken(elts: (String, Data)*) extends Record {\n val elements = ListMap(elts: _*)\n\n def apply(elt: String): Data = elements(elt)\n}\n\nclass NewModule extends Module {\n val out = Output(UInt(8.W))\n val recordType = new CustomBundleBroken("fizz" -> UInt(16.W), "buzz" -> UInt(16.W))\n val record = Wire(recordType)\n val uint = record.asUInt\n val record2 = uint.asTypeOf(recordType)\n out := record\n}\ngetVerilogString(new NewModule)\n// chisel3.AutoClonetypeException: The bundle plugin was unable to clone CustomBundleBroken$1 that has field \'fizz\' aliased with base CustomBundleBroken$1.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry \'How do I deal with the "unable to clone" error?\' for more details.\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74$$anonfun$apply$63.apply(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74$$anonfun$apply$63.apply(cookbook.md:444)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74.apply(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1.(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$$anonfun$apply$67.apply(cookbook.md:449)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$$anonfun$apply$67.apply(cookbook.md:449)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"chiselTypeClone"})," to clone the elements as:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.reflect.DataMirror\nimport chisel3.experimental.requireIsChiselType\n\nclass CustomBundleFixed(elts: (String, Data)*) extends Record {\n val elements = ListMap(elts.map {\n case (field, elt) =>\n requireIsChiselType(elt)\n field -> DataMirror.internal.chiselTypeClone(elt)\n }: _*)\n\n def apply(elt: String): Data = elements(elt)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine (FSM)?"}),"\n",(0,t.jsxs)(n.p,{children:["The advised way is to use ",(0,t.jsx)(n.code,{children:"ChiselEnum"})," to construct enumerated types representing the state of the FSM.\nState transitions are then handled with ",(0,t.jsx)(n.code,{children:"switch"}),"/",(0,t.jsx)(n.code,{children:"is"})," and ",(0,t.jsx)(n.code,{children:"when"}),"/",(0,t.jsx)(n.code,{children:".elsewhen"}),"/",(0,t.jsx)(n.code,{children:".otherwise"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.util.{switch, is}\n\nobject DetectTwoOnes {\n object State extends ChiselEnum {\n val sNone, sOne1, sTwo1s = Value\n }\n}\n\n/* This FSM detects two 1's one after the other */\nclass DetectTwoOnes extends Module {\n import DetectTwoOnes.State\n import DetectTwoOnes.State._\n\n val io = IO(new Bundle {\n val in = Input(Bool())\n val out = Output(Bool())\n val state = Output(State())\n })\n\n val state = RegInit(sNone)\n\n io.out := (state === sTwo1s)\n io.state := state\n\n switch (state) {\n is (sNone) {\n when (io.in) {\n state := sOne1\n }\n }\n is (sOne1) {\n when (io.in) {\n state := sTwo1s\n } .otherwise {\n state := sNone\n }\n }\n is (sTwo1s) {\n when (!io.in) {\n state := sNone\n }\n }\n }\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: the ",(0,t.jsx)(n.code,{children:"is"})," statement can take multiple conditions e.g. ",(0,t.jsx)(n.code,{children:"is (sTwo1s, sOne1) { ... }"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'}),"\n",(0,t.jsxs)(n.p,{children:["In Verilog, you can do something like the following which will unpack a the value ",(0,t.jsx)(n.code,{children:"z"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"wire [1:0] a;\nwire [3:0] b;\nwire [2:0] c;\nwire [8:0] z = [...];\nassign {a,b,c} = z;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Unpacking often corresponds to reinterpreting an unstructured data type as a structured data type.\nFrequently, this structured type is used prolifically in the design, and has been declared as in the following example:"}),"\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 a = UInt(2.W)\n val b = UInt(4.W)\n val c = UInt(3.W)\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"The easiest way to accomplish this in Chisel would be:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'class Foo extends Module {\n val z = Wire(UInt(9.W))\n z := DontCare // This is a dummy connection\n val unpacked = z.asTypeOf(new MyBundle)\n printf("%d", unpacked.a)\n printf("%d", unpacked.b)\n printf("%d", unpacked.c)\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["If you ",(0,t.jsx)(n.strong,{children:"really"})," need to do this for a one-off case (Think thrice! It is likely you can better structure the code using bundles), then rocket-chip has a ",(0,t.jsx)(n.a,{href:"https://github.com/freechipsproject/rocket-chip/blob/723af5e6b69e07b5f94c46269a208a8d65e9d73b/src/main/scala/util/Misc.scala#L140",children:"Split utility"})," which can accomplish this."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"}),"\n",(0,t.jsxs)(n.p,{children:["You may try to do something like the following where you want to assign only some bits of a Chisel type.\nBelow, the left-hand side connection to ",(0,t.jsx)(n.code,{children:"io.out(0)"})," is not allowed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass Foo extends Module {\n val io = IO(new Bundle {\n val bit = Input(Bool())\n val out = Output(UInt(10.W))\n })\n io.out(0) := io.bit\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you try to compile this, you will get an error."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Foo)\n// chisel3.package$ChiselException: Cannot reassign to read-only Foo.?: OpResult[Bool]\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp26$Foo.(cookbook.md:589)\n// \tat repl.MdocSession$MdocApp26$$anonfun$104$$anonfun$apply$90.apply(cookbook.md:597)\n// \tat repl.MdocSession$MdocApp26$$anonfun$104$$anonfun$apply$90.apply(cookbook.md:597)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Chisel3 ",(0,t.jsx)(n.em,{children:"does not support subword assignment"}),".\nThe reason for this is that subword assignment generally hints at a better abstraction with an aggregate/structured types, i.e., a ",(0,t.jsx)(n.code,{children:"Bundle"})," or a ",(0,t.jsx)(n.code,{children:"Vec"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["If you must express it this way, one approach is to blast your ",(0,t.jsx)(n.code,{children:"UInt"})," to a ",(0,t.jsx)(n.code,{children:"Vec"})," of ",(0,t.jsx)(n.code,{children:"Bool"})," and back:"]}),"\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 io = IO(new Bundle {\n val in = Input(UInt(10.W))\n val bit = Input(Bool())\n val out = Output(UInt(10.W))\n })\n val bools = VecInit(io.in.asBools)\n bools(0) := io.bit\n io.out := bools.asUInt\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"}),"\n",(0,t.jsxs)(n.p,{children:["The following example is a module which includes the optional port ",(0,t.jsx)(n.code,{children:"out2"})," only if the given parameter is ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass ModuleWithOptionalIOs(flag: Boolean) extends Module {\n val io = IO(new Bundle {\n val in = Input(UInt(12.W))\n val out = Output(UInt(12.W))\n val out2 = if (flag) Some(Output(UInt(12.W))) else None\n })\n\n io.out := io.in\n if (flag) {\n io.out2.get := io.in\n }\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following is an example where an entire ",(0,t.jsx)(n.code,{children:"IO"})," is optional:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass ModuleWithOptionalIO(flag: Boolean) extends Module {\n val in = if (flag) Some(IO(Input(Bool()))) else None\n val out = IO(Output(Bool()))\n\n out := in.getOrElse(false.B)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"}),"\n",(0,t.jsxs)(n.p,{children:["In most cases, you can simply call ",(0,t.jsx)(n.code,{children:"IO"})," multiple times:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyModule extends Module {\n val in = IO(Input(UInt(8.W)))\n val out = IO(Output(UInt(8.W)))\n\n out := in +% 1.U\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule MyModule(\t// cookbook.md:691:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [7:0] in,\t// cookbook.md:692:14\n output [7:0] out\t// cookbook.md:693:15\n);\n\n assign out = in + 8'h1;\t// cookbook.md:691:7, :695:13\nendmodule\n\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you have a ",(0,t.jsx)(n.code,{children:"Bundle"})," from which you would like to create ports without the\nnormal ",(0,t.jsx)(n.code,{children:"val"})," prefix, you can use ",(0,t.jsx)(n.code,{children:"FlatIO"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.FlatIO\n\nclass MyBundle extends Bundle {\n val foo = Input(UInt(8.W))\n val bar = Output(UInt(8.W))\n}\n\nclass MyModule extends Module {\n val io = FlatIO(new MyBundle)\n\n io.bar := io.foo +% 1.U\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"io_"})," is nowhere to be seen!"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule MyModule(\t// cookbook.md:723:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [7:0] foo,\t// cookbook.md:724:18\n output [7:0] bar\t// cookbook.md:724:18\n);\n\n assign bar = foo + 8'h1;\t// cookbook.md:723:7, :726:20\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Use inferred width and a ",(0,t.jsx)(n.code,{children:"Seq"})," instead of a ",(0,t.jsx)(n.code,{children:"Vec"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"Consider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\n// Count the number of set bits up to and including each bit position\nclass CountBits(width: Int) extends Module {\n val bits = IO(Input(UInt(width.W)))\n val countSequence = Seq.tabulate(width)(i => IO(Output(UInt())))\n val countVector = IO(Output(Vec(width, UInt())))\n countSequence.zipWithIndex.foreach { case (port, i) =>\n port := util.PopCount(bits(i, 0))\n }\n countVector := countSequence\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Unlike ",(0,t.jsx)(n.code,{children:"Vecs"})," which represent a singular Chisel type and must have the same width for every element,\n",(0,t.jsx)(n.code,{children:"Seq"})," is a purely Scala construct, so their elements are independent from the perspective of Chisel and can have different widths."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule CountBits(\t// cookbook.md:745:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [3:0] bits,\t// cookbook.md:746:16\n output countSequence_0,\t// cookbook.md:747:50\n output [1:0] countSequence_1,\t// cookbook.md:747:50\n countSequence_2,\t// cookbook.md:747:50\n output [2:0] countSequence_3,\t// cookbook.md:747:50\n countVector_0,\t// cookbook.md:748:23\n countVector_1,\t// cookbook.md:748:23\n countVector_2,\t// cookbook.md:748:23\n countVector_3\t// cookbook.md:748:23\n);\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",children:[(0,t.jsx)("a",{id:"dynamic-index-too-wide-narrow"}),' How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?']}),"\n",(0,t.jsx)(n.p,{children:'Chisel will warn if a dynamic index is not the correctly-sized width for indexing a Vec or UInt.\n"Correctly-sized" means that the width of the index should be the log2 of the size of the indexee.\nIf the indexee is a non-power-of-2 size, use the ceiling of the log2 result.'}),"\n",(0,t.jsxs)(n.p,{children:["When the index does not have enough bits to address all entries or bits in the extractee, you can ",(0,t.jsx)(n.code,{children:".pad"})," the index to increase the width."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooNarrow extends RawModule {\n val extractee = Wire(UInt(7.W))\n val index = Wire(UInt(2.W))\n extractee(index)\n}\ncompile(new TooNarrow)\n// [warn] cookbook.md 788:12: [W003] Dynamic index with width 2 is too small for extractee of width 7\n// [warn] There were 1 warning(s) during hardware elaboration.\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This can be fixed with ",(0,t.jsx)(n.code,{children:"pad"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooNarrowFixed extends RawModule {\n val extractee = Wire(UInt(7.W))\n val index = Wire(UInt(2.W))\n extractee(index.pad(3))\n}\ncompile(new TooNarrowFixed)\n"})}),"\n",(0,t.jsx)(n.h4,{id:"use-bit-extraction-when-the-index-is-too-wide",children:"Use bit extraction when the index is too wide"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWide extends RawModule {\n val extractee = Wire(Vec(8, UInt(32.W)))\n val index = Wire(UInt(4.W))\n extractee(index)\n}\ncompile(new TooWide)\n// [warn] cookbook.md 814:12: [W004] Dynamic index with width 4 is too wide for Vec of size 8 (expected index width 3).\n// [warn] There were 1 warning(s) during hardware elaboration.\n"})}),"\n",(0,t.jsx)(n.p,{children:"This can be fixed with bit extraction:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWideFixed extends RawModule {\n val extractee = Wire(Vec(8, UInt(32.W)))\n val index = Wire(UInt(4.W))\n extractee(index(2, 0))\n}\ncompile(new TooWideFixed)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that size 1 ",(0,t.jsx)(n.code,{children:"Vecs"})," and ",(0,t.jsx)(n.code,{children:"UInts"})," should be indexed by a zero-width ",(0,t.jsx)(n.code,{children:"UInt"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class SizeOneVec extends RawModule {\n val extractee = Wire(Vec(1, UInt(32.W)))\n val index = Wire(UInt(0.W))\n extractee(index)\n}\ncompile(new SizeOneVec)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Because ",(0,t.jsx)(n.code,{children:"pad"})," only pads if the desired width is less than the current width of the argument,\nyou can use ",(0,t.jsx)(n.code,{children:"pad"})," in conjunction with bit extraction when the widths may be too wide or too\nnarrow under different circumstances"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.util.log2Ceil\nclass TooWideOrNarrow(extracteeSize: Int, indexWidth: Int) extends Module {\n val extractee = Wire(Vec(extracteeSize, UInt(8.W)))\n val index = Wire(UInt(indexWidth.W))\n val correctWidth = log2Ceil(extracteeSize)\n extractee(index.pad(correctWidth)(correctWidth - 1, 0))\n}\ncompile(new TooWideOrNarrow(8, 2))\ncompile(new TooWideOrNarrow(8, 4))\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Another option for dynamic bit selection of ",(0,t.jsx)(n.code,{children:"UInts"})," (but not ",(0,t.jsx)(n.code,{children:"Vec"})," dynamic indexing) is to do a dynamic\nright shift of the extractee by the index and then just bit select a single bit:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWideOrNarrowUInt(extracteeSize: Int, indexWidth: Int) extends Module {\n val extractee = Wire(UInt(extracteeSize.W))\n val index = Wire(UInt(indexWidth.W))\n (extractee >> index)(0)\n}\ncompile(new TooWideOrNarrowUInt(8, 2))\ncompile(new TooWideOrNarrowUInt(8, 4))\n"})}),"\n",(0,t.jsx)(n.h2,{id:"predictable-naming",children:"Predictable Naming"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the compiler plugin, and check out the ",(0,t.jsx)(n.a,{href:"naming",children:"Naming Cookbook"})," if that still does not do what you want."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"}),"\n",(0,t.jsx)(n.p,{children:"Currently, name information is lost when using dynamic indexing. For example:"}),"\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 io = IO(new Bundle {\n val in = Input(Vec(4, Bool()))\n val idx = Input(UInt(2.W))\n val en = Input(Bool())\n val out = Output(Bool())\n })\n\n val x = io.in(io.idx)\n val y = x && io.en\n io.out := y\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The above code loses the ",(0,t.jsx)(n.code,{children:"x"})," name, instead using ",(0,t.jsx)(n.code,{children:"_GEN_3"})," (the other ",(0,t.jsx)(n.code,{children:"_GEN_*"})," signals are expected)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Foo(\t// cookbook.md:892:7\n input clock,\t// :4:11\n reset,\t// :5:11\n io_in_0,\t// cookbook.md:893:14\n io_in_1,\t// cookbook.md:893:14\n io_in_2,\t// cookbook.md:893:14\n io_in_3,\t// cookbook.md:893:14\n input [1:0] io_idx,\t// cookbook.md:893:14\n input io_en,\t// cookbook.md:893:14\n output io_out\t// cookbook.md:893:14\n);\n\n wire [3:0] _GEN = {{io_in_3}, {io_in_2}, {io_in_1}, {io_in_0}};\t// cookbook.md:901:13\n assign io_out = _GEN[io_idx] & io_en;\t// cookbook.md:892:7, :901:13\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.p,{children:"This can be worked around by creating a wire and connecting the dynamic index to the wire:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"val x = WireInit(io.in(io.idx))\n"})}),"\n",(0,t.jsx)(n.p,{children:"Which produces:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Foo2(\t// cookbook.md:915:7\n input clock,\t// :4:11\n reset,\t// :5:11\n io_in_0,\t// cookbook.md:916:14\n io_in_1,\t// cookbook.md:916:14\n io_in_2,\t// cookbook.md:916:14\n io_in_3,\t// cookbook.md:916:14\n input [1:0] io_idx,\t// cookbook.md:916:14\n input io_en,\t// cookbook.md:916:14\n output io_out\t// cookbook.md:916:14\n);\n\n wire [3:0] _GEN = {{io_in_3}, {io_in_2}, {io_in_1}, {io_in_0}};\t// cookbook.md:923:19\n assign io_out = _GEN[io_idx] & io_en;\t// cookbook.md:915:7, :923:19, :924:13\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"}),"\n",(0,t.jsxs)(n.p,{children:["You can override the ",(0,t.jsx)(n.code,{children:"desiredName"})," function. This works with normal Chisel modules and ",(0,t.jsx)(n.code,{children:"BlackBox"}),"es. Example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Coffee extends BlackBox {\n val io = IO(new Bundle {\n val I = Input(UInt(32.W))\n val O = Output(UInt(32.W))\n })\n override def desiredName = "Tea"\n}\n\nclass Salt extends Module {\n val io = IO(new Bundle {})\n val drink = Module(new Coffee)\n override def desiredName = "SodiumMonochloride"\n\n drink.io.I := 42.U\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Elaborating the Chisel module ",(0,t.jsx)(n.code,{children:"Salt"}),' yields our "desired names" for ',(0,t.jsx)(n.code,{children:"Salt"})," and ",(0,t.jsx)(n.code,{children:"Coffee"})," in the output Verilog:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\n// external module Tea\n\nmodule SodiumMonochloride(\t// cookbook.md:953:7\n input clock,\t// :9:11\n reset\t// :10:11\n);\n\n Tea drink (\t// cookbook.md:955:23\n .I (32'h2A),\t// cookbook.md:958:16\n .O (/* unused */)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"directionality",children:"Directionality"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"}),"\n",(0,t.jsxs)(n.p,{children:["Given a bidirectional port like a ",(0,t.jsx)(n.code,{children:"Decoupled"}),", you will get an error if you try to connect it directly\nto a register:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\nimport chisel3.util.Decoupled\nclass BadRegConnect extends Module {\n val io = IO(new Bundle {\n val enq = Decoupled(UInt(8.W))\n })\n\n val monitor = Reg(chiselTypeOf(io.enq))\n monitor := io.enq\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"ChiselStage.emitSystemVerilog(new BadRegConnect)\n// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: firtool returned a non-zero exit code. Note that this version of Chisel (0.0.0+1-3944e066-SNAPSHOT) was published against firtool version 1.59.0.\n// ------------------------------------------------------------------------------\n// ExitCode:\n// 1\n// STDOUT:\n// \n// STDERR:\n// cookbook.md:988:20: error: 'firrtl.reg' op result #0 must be a passive non-'const' base type that does not contain analog, but got '!firrtl.bundle, valid: uint<1>, bits: uint<8>>'\n// cookbook.md:988:20: note: see current operation: %4 = \"firrtl.reg\"(%arg0) {annotations = [], name = \"monitor\", nameKind = #firrtl} : (!firrtl.clock) -> !firrtl.bundle, valid: uint<1>, bits: uint<8>>\n// \n// ------------------------------------------------------------------------------\n"})}),"\n",(0,t.jsxs)(n.p,{children:['While there is no construct to "strip direction" in Chisel3, wrapping a type in ',(0,t.jsx)(n.code,{children:"Output(...)"}),"\n(the default direction in Chisel3) will\nset all of the individual elements to output direction.\nThis will have the desired result when used to construct a Register:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\nimport chisel3.util.Decoupled\nclass CoercedRegConnect extends Module {\n val io = IO(new Bundle {\n val enq = Flipped(Decoupled(UInt(8.W)))\n })\n\n // Make a Reg which contains all of the bundle's signals, regardless of their directionality\n val monitor = Reg(Output(chiselTypeOf(io.enq)))\n // Even though io.enq is bidirectional, := will drive all fields of monitor with the fields of io.enq\n monitor := io.enq\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>s,a:()=>l});var t=o(7294);const i={},a=t.createContext(i);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[7462],{9611:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var t=o(5893),i=o(1151);const a={layout:"docs",title:"General Cookbook",section:"chisel3"},l="General Cookbook",s={id:"cookbooks/cookbook",title:"General Cookbook",description:"Please note that these examples make use of Chisel's scala-style printing.",source:"@site/docs/cookbooks/cookbook.md",sourceDirName:"cookbooks",slug:"/cookbooks/cookbook",permalink:"/docs/cookbooks/cookbook",draft:!1,unlisted:!1,editUrl:"https://github.com/chipsalliance/chisel/tree/main/docs/src/cookbooks/cookbook.md",tags:[],version:"current",frontMatter:{layout:"docs",title:"General Cookbook",section:"chisel3"},sidebar:"tutorialSidebar",previous:{title:"Cookbooks",permalink:"/docs/cookbooks/"},next:{title:"DataView Cookbook",permalink:"/docs/cookbooks/dataview"}},c={},d=[{value:"Type Conversions",id:"type-conversions",level:2},{value:"How do I create a UInt from an instance of a Bundle?",id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",level:3},{value:"How do I create a Bundle from a UInt?",id:"how-do-i-create-a-bundle-from-a-uint",level:3},{value:"How can I tieoff a Bundle/Vec to 0?",id:"how-can-i-tieoff-a-bundlevec-to-0",level:3},{value:"How do I create a Vec of Bools from a UInt?",id:"how-do-i-create-a-vec-of-bools-from-a-uint",level:3},{value:"How do I create a UInt from a Vec of Bool?",id:"how-do-i-create-a-uint-from-a-vec-of-bool",level:3},{value:"How do I connect a subset of Bundle fields?",id:"how-do-i-connect-a-subset-of-bundle-fields",level:3},{value:"Vectors and Registers",id:"vectors-and-registers",level:2},{value:"Can I make a 2D or 3D Vector?",id:"can-i-make-a-2d-or-3d-vector",level:3},{value:"How do I create a Vector of Registers?",id:"how-do-i-create-a-vector-of-registers",level:3},{value:"How do I create a Reg of type Vec?",id:"how-do-i-create-a-reg-of-type-vec",level:3},{value:"How do I partially reset an Aggregate Reg?",id:"how-do-i-partially-reset-an-aggregate-reg",level:3},{value:"Bundles",id:"bundles",level:2},{value:" How do I deal with aliased Bundle fields?",id:"-how-do-i-deal-with-aliased-bundle-fields",level:3},{value:"1. 0-arity function parameters",id:"1-0-arity-function-parameters",level:4},{value:"2. By-name function parameters",id:"2-by-name-function-parameters",level:4},{value:"3. Directioned Bundle fields",id:"3-directioned-bundle-fields",level:4},{value:"4. Call .cloneType directly",id:"4-call-clonetype-directly",level:4},{value:" How do I deal with the "unable to clone" error?",id:"-how-do-i-deal-with-the-unable-to-clone-error",level:3},{value:"How do I create a finite state machine (FSM)?",id:"how-do-i-create-a-finite-state-machine-fsm",level:3},{value:"How do I unpack a value ("reverse concatenation") like in Verilog?",id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",level:3},{value:"How do I do subword assignment (assign to some bits in a UInt)?",id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",level:3},{value:"How do I create an optional I/O?",id:"how-do-i-create-an-optional-io",level:3},{value:"How do I create I/O without a prefix?",id:"how-do-i-create-io-without-a-prefix",level:3},{value:"How do I minimize the number of bits used in an output vector?",id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",level:3},{value:" How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?",id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",level:3},{value:"Use bit extraction when the index is too wide",id:"use-bit-extraction-when-the-index-is-too-wide",level:4},{value:"Predictable Naming",id:"predictable-naming",level:2},{value:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?",id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",level:3},{value:"How do I get Chisel to name the results of vector reads properly?",id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",level:3},{value:"How can I dynamically set/parametrize the name of a module?",id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",level:3},{value:"Directionality",id:"directionality",level:2},{value:"How do I strip directions from a bidirectional Bundle (or other Data)?",id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",level:3}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"general-cookbook",children:"General Cookbook"}),"\n",(0,t.jsxs)(n.p,{children:["Please note that these examples make use of ",(0,t.jsx)(n.a,{href:"../explanations/printing#scala-style",children:"Chisel's scala-style printing"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type Conversions","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Vectors and Registers","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#can-i-make-a-2D-or-3D-Vector",children:"Can I make a 2D or 3D Vector?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Bundles","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#aliased-bundle-fields",children:"How do I deal with aliased Bundle fields?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#bundle-unable-to-clone",children:'How do I deal with the "unable to clone" error?'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#dynamic-index-too-wide-narrow",children:'How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?'})}),"\n",(0,t.jsxs)(n.li,{children:["Predictable Naming","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Directionality","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"type-conversions",children:"Type Conversions"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-an-instance-of-a-bundle",children:"How do I create a UInt from an instance of a Bundle?"}),"\n",(0,t.jsxs)(n.p,{children:["Call ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})," on the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})})," instance."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val bundle = Wire(new MyBundle)\n bundle.foo := 0xc.U\n bundle.bar := 0x3.U\n val uint = bundle.asUInt\n printf(cf"$uint") // 195\n\n // Test\n assert(uint === 0xc3.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-bundle-from-a-uint",children:"How do I create a Bundle from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asTypeOf%5BT%3C:chisel3.Data%5D(that:T):T",children:(0,t.jsx)(n.code,{children:"asTypeOf"})})," method to reinterpret the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html",children:(0,t.jsx)(n.code,{children:"UInt"})})," as the type of the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Bundle.html",children:(0,t.jsx)(n.code,{children:"Bundle"})}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n val uint = 0xb4.U\n val bundle = uint.asTypeOf(new MyBundle)\n\n printf(cf"$bundle") // Bundle(foo -> 11, bar -> 4)\n\n // Test\n assert(bundle.foo === 0xb.U)\n assert(bundle.bar === 0x4.U)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-tieoff-a-bundlevec-to-0",children:"How can I tieoff a Bundle/Vec to 0?"}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"asTypeOf"})," as above. If you don't want to worry about the type of the thing\nyou are tying off, you can use ",(0,t.jsx)(n.code,{children:"chiselTypeOf"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = Vec(4, UInt(1.W))\n}\n\nclass Foo(typ: MyBundle) extends Module {\n val bundleA = IO(Output(typ))\n val bundleB = IO(Output(typ))\n\n // typ is already a Chisel Data Type, so can use it directly here, but you\n // need to know that bundleA is of type typ\n bundleA := 0.U.asTypeOf(typ)\n\n // bundleB is a Hardware data IO(Output(...)) so need to call chiselTypeOf,\n // but this will work no matter the type of bundleB:\n bundleB := 0.U.asTypeOf(chiselTypeOf(bundleB))\n}\n\nChiselStage.emitSystemVerilog(new Foo(new MyBundle))\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vec-of-bools-from-a-uint",children:"How do I create a Vec of Bools from a UInt?"}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/VecInit$.html",children:(0,t.jsx)(n.code,{children:"VecInit"})})," given a ",(0,t.jsx)(n.code,{children:"Seq[Bool]"})," generated using the ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/UInt.html#asBools:Seq%5Bchisel3.Bool%5D",children:(0,t.jsx)(n.code,{children:"asBools"})})," method."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val uint = 0xc.U\n val vec = VecInit(uint.asBools)\n\n printf(cf"$vec") // Vec(0, 0, 1, 1)\n\n // Test\n assert(vec(0) === false.B)\n assert(vec(1) === false.B)\n assert(vec(2) === true.B)\n assert(vec(3) === true.B)\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-uint-from-a-vec-of-bool",children:"How do I create a UInt from a Vec of Bool?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the builtin function ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html#asUInt:chisel3.UInt",children:(0,t.jsx)(n.code,{children:"asUInt"})})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Foo extends Module {\n val vec = VecInit(true.B, false.B, true.B, true.B)\n val uint = vec.asUInt\n\n printf(cf"$uint") // 13\n\n // Test\n // (remember leftmost Bool in Vec is low order bit)\n assert(0xd.U === uint)\n\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-connect-a-subset-of-bundle-fields",children:"How do I connect a subset of Bundle fields?"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"dataview#how-do-i-connect-a-subset-of-bundle-fields",children:"DataView cookbook"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"vectors-and-registers",children:"Vectors and Registers"}),"\n",(0,t.jsx)(n.h3,{id:"can-i-make-a-2d-or-3d-vector",children:"Can I make a 2D or 3D Vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Yes. Using ",(0,t.jsx)(n.code,{children:"VecInit"})," you can make Vectors that hold Vectors of Chisel types. Methods ",(0,t.jsx)(n.code,{children:"fill"})," and ",(0,t.jsx)(n.code,{children:"tabulate"})," make these multi-dimensional Vectors."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyBundle extends Bundle {\n val foo = UInt(4.W)\n val bar = UInt(4.W)\n}\n\nclass Foo extends Module {\n //2D Fill\n val twoDVec = VecInit.fill(2, 3)(5.U)\n //3D Fill\n val myBundle = Wire(new MyBundle)\n myBundle.foo := 0xc.U\n myBundle.bar := 0x3.U\n val threeDVec = VecInit.fill(1, 2, 3)(myBundle)\n assert(threeDVec(0)(0)(0).foo === 0xc.U && threeDVec(0)(0)(0).bar === 0x3.U)\n\n //2D Tabulate\n val indexTiedVec = VecInit.tabulate(2, 2){ (x, y) => (x + y).U }\n assert(indexTiedVec(0)(0) === 0.U)\n assert(indexTiedVec(0)(1) === 1.U)\n assert(indexTiedVec(1)(0) === 1.U)\n assert(indexTiedVec(1)(1) === 2.U)\n //3D Tabulate\n val indexTiedVec3D = VecInit.tabulate(2, 3, 4){ (x, y, z) => (x + y * z).U }\n assert(indexTiedVec3D(0)(0)(0) === 0.U)\n assert(indexTiedVec3D(1)(1)(1) === 2.U)\n assert(indexTiedVec3D(1)(1)(2) === 3.U)\n assert(indexTiedVec3D(1)(1)(3) === 4.U)\n assert(indexTiedVec3D(1)(2)(3) === 7.U)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-vector-of-registers",children:"How do I create a Vector of Registers?"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rule! Use Reg of Vec not Vec of Reg!"})}),"\n",(0,t.jsxs)(n.p,{children:["You create a ",(0,t.jsx)(n.a,{href:"#how-do-i-create-a-reg-of-type-vec",children:"Reg of type Vec"}),". Because Vecs are a ",(0,t.jsx)(n.em,{children:"type"})," (like ",(0,t.jsx)(n.code,{children:"UInt"}),", ",(0,t.jsx)(n.code,{children:"Bool"}),") rather than a ",(0,t.jsx)(n.em,{children:"value"}),", we must bind the Vec to some concrete ",(0,t.jsx)(n.em,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-reg-of-type-vec",children:"How do I create a Reg of type Vec?"}),"\n",(0,t.jsxs)(n.p,{children:["For more information, the API Documentation for ",(0,t.jsx)(n.a,{href:"https://www.chisel-lang.org/api/latest/chisel3/Vec.html",children:(0,t.jsx)(n.code,{children:"Vec"})})," provides more information."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass Foo extends Module {\n val regOfVec = Reg(Vec(4, UInt(32.W))) // Register of 32-bit UInts\n regOfVec(0) := 123.U // Assignments to elements of the Vec\n regOfVec(1) := 456.U\n regOfVec(2) := 789.U\n regOfVec(3) := regOfVec(0)\n\n // Reg of Vec of 32-bit UInts initialized to zero\n // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0\n // VecInit(...) then constructs a Wire of these literals\n // The Reg is then initialized to the value of the Wire (which gives it the same type)\n val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-partially-reset-an-aggregate-reg",children:"How do I partially reset an Aggregate Reg?"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way is to use a partially-specified ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#bundle-literals",children:"Bundle Literal"}),"\nor ",(0,t.jsx)(n.a,{href:"#../appendix/experimental-features#vec-literals",children:"Vec Literal"})," to match the type of the Reg."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.BundleLiterals._\n\nclass MyBundle extends Bundle {\n val foo = UInt(8.W)\n val bar = UInt(8.W)\n}\n\nclass MyModule extends Module {\n // Only .foo will be reset, .bar will have no reset value\n val reg = RegInit((new MyBundle).Lit(_.foo -> 123.U))\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If your initial value is not a literal, or if you just prefer, you can use a\nWire as the initial value for the Reg. Simply connect fields to ",(0,t.jsx)(n.code,{children:"DontCare"})," that\nyou do not wish to be reset."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MyModule2 extends Module {\n val reg = RegInit({\n // The wire could be constructed before the reg rather than in the RegInit scope,\n // but this style has nice lexical scoping behavior, keeping the Wire private\n val init = Wire(new MyBundle)\n init := DontCare // No fields will be reset\n init.foo := 123.U // Last connect override, .foo is reset\n init\n })\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"bundles",children:"Bundles"}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-aliased-bundle-fields",children:[(0,t.jsx)("a",{name:"aliased-bundle-fields"})," How do I deal with aliased Bundle fields?"]}),"\n",(0,t.jsxs)(n.p,{children:["Following the ",(0,t.jsx)(n.code,{children:"gen"})," pattern when creating Bundles can result in some opaque error messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AliasedBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AliasedBundle contains aliased fields named (bar,foo)\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50$$anonfun$apply$37.apply(cookbook.md:301)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$Top$$anonfun$50.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$Top.(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$$anonfun$55$$anonfun$apply$43.apply(cookbook.md:320)\n// \tat repl.MdocSession$MdocApp17$$anonfun$55$$anonfun$apply$43.apply(cookbook.md:320)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This error is saying that fields ",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," of ",(0,t.jsx)(n.code,{children:"AliasedBundle"})," are the\nexact same object in memory.\nThis is a problem for Chisel because we need to be able to distinguish uses of\n",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," but cannot when they are referentially the same."]}),"\n",(0,t.jsx)(n.p,{children:"Note that the following example looks different but will give you exactly the same issue:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class AlsoAliasedBundle[T <: Data](val gen: T) extends Bundle {\n // ^ This val makes `gen` a field, just like `foo`\n val foo = gen\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["By making ",(0,t.jsx)(n.code,{children:"gen"})," a ",(0,t.jsx)(n.code,{children:"val"}),", it becomes a public field of the ",(0,t.jsx)(n.code,{children:"class"}),", just like ",(0,t.jsx)(n.code,{children:"foo"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new AlsoAliasedBundle(UInt(8.W))))\n// chisel3.AliasedAggregateFieldException: AlsoAliasedBundle contains aliased fields named (foo,gen)\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.(cookbook.md:301)\n// \tat repl.MdocSession$MdocApp17$$anonfun$57$$anonfun$apply$44.apply(cookbook.md:339)\n// \tat repl.MdocSession$MdocApp17$$anonfun$57$$anonfun$apply$44.apply(cookbook.md:339)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsx)(n.p,{children:"There are several ways to solve this issue with their own advantages and disadvantages."}),"\n",(0,t.jsx)(n.h4,{id:"1-0-arity-function-parameters",children:"1. 0-arity function parameters"}),"\n",(0,t.jsx)(n.p,{children:"Instead of passing an object as a parameter, you can pass a 0-arity function (a function with no arguments):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingAFunctionBundle[T <: Data](gen: () => T) extends Bundle {\n val foo = gen()\n val bar = gen()\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that the type of ",(0,t.jsx)(n.code,{children:"gen"})," is now ",(0,t.jsx)(n.code,{children:"() => T"}),".\nBecause it is now a function and not a subtype of ",(0,t.jsx)(n.code,{children:"Data"}),", you can safely make ",(0,t.jsx)(n.code,{children:"gen"})," a ",(0,t.jsx)(n.code,{children:"val"})," without\nit becoming a hardware field of the ",(0,t.jsx)(n.code,{children:"Bundle"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Note that this also means you must pass ",(0,t.jsx)(n.code,{children:"gen"})," as a function, for example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new UsingAFunctionBundle(() => UInt(8.W))))\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)("a",{name:"aliased-warning"})," ",(0,t.jsx)(n.strong,{children:"Warning"}),": you must ensure that ",(0,t.jsx)(n.code,{children:"gen"})," creates fresh objects rather than capturing an already constructed value:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class MisusedFunctionArguments extends Module {\n // This usage is correct\n val in = IO(Input(new UsingAFunctionBundle(() => UInt(8.W))))\n\n // This usage is incorrect\n val fizz = UInt(8.W)\n val out = IO(Output(new UsingAFunctionBundle(() => fizz)))\n}\ngetVerilogString(new MisusedFunctionArguments)\n// chisel3.AutoClonetypeException: The bundle plugin was unable to clone UsingAFunctionBundle that has field 'foo' aliased with base UsingAFunctionBundle.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry 'How do I deal with the \"unable to clone\" error?' for more details.\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51$$anonfun$apply$52.apply(cookbook.md:370)\n// \tat chisel3.IO$.apply(IO.scala:34)\n// \tat chisel3.experimental.BaseModule.IO(Module.scala:751)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62$$anonfun$apply$51.apply(cookbook.md:370)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1$$anonfun$62.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$MisusedFunctionArguments$1.(cookbook.md:370)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)\n// \tat repl.MdocSession$MdocApp17$$anonfun$59$$anonfun$apply$55.apply(cookbook.md:372)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In the above example, value ",(0,t.jsx)(n.code,{children:"fizz"})," and fields ",(0,t.jsx)(n.code,{children:"foo"})," and ",(0,t.jsx)(n.code,{children:"bar"})," of ",(0,t.jsx)(n.code,{children:"out"})," are all the same object in memory."]}),"\n",(0,t.jsx)(n.h4,{id:"2-by-name-function-parameters",children:"2. By-name function parameters"}),"\n",(0,t.jsxs)(n.p,{children:["Functionally the same as (1) but with more subtle syntax, you can use ",(0,t.jsx)(n.a,{href:"https://docs.scala-lang.org/tour/by-name-parameters.html",children:"Scala by-name function parameters"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingByNameParameters[T <: Data](gen: => T) extends Bundle {\n val foo = gen\n val bar = gen\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["With this usage, you do not include ",(0,t.jsx)(n.code,{children:"() =>"})," when passing the argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Top(new UsingByNameParameters(UInt(8.W))))\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that as this is just syntactic sugar over (1), the ",(0,t.jsx)(n.a,{href:"#aliased-warning",children:"same warning applies"}),"."]}),"\n",(0,t.jsx)(n.h4,{id:"3-directioned-bundle-fields",children:"3. Directioned Bundle fields"}),"\n",(0,t.jsxs)(n.p,{children:["You can alternatively wrap the fields with ",(0,t.jsx)(n.code,{children:"Output(...)"}),", which creates fresh instances of the passed argument.\nChisel treats ",(0,t.jsx)(n.code,{children:"Output"}),' as the "default direction" so if all fields are outputs, the ',(0,t.jsx)(n.code,{children:"Bundle"})," is functionally equivalent to a ",(0,t.jsx)(n.code,{children:"Bundle"})," with no directioned fields."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class DirectionedBundle[T <: Data](gen: T) extends Bundle {\n val foo = Output(gen)\n val bar = Output(gen)\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This approach is admittedly a little ugly and may mislead others reading the code because it implies that this Bundle is intended to be used as an ",(0,t.jsx)(n.code,{children:"Output"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"4-call-clonetype-directly",children:["4. Call ",(0,t.jsx)(n.code,{children:".cloneType"})," directly"]}),"\n",(0,t.jsxs)(n.p,{children:["You can also just call ",(0,t.jsx)(n.code,{children:".cloneType"})," on your ",(0,t.jsx)(n.code,{children:"gen"})," argument directly.\nWhile we try to hide this implementation detail from the user, ",(0,t.jsx)(n.code,{children:".cloneType"})," is the mechanism by which Chisel creates fresh instances of ",(0,t.jsx)(n.code,{children:"Data"})," objects:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class UsingCloneTypeBundle[T <: Data](gen: T) extends Bundle {\n val foo = gen.cloneType\n val bar = gen.cloneType\n}\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-deal-with-the-unable-to-clone-error",children:[(0,t.jsx)("a",{name:"bundle-unable-to-clone"}),' How do I deal with the "unable to clone" error?']}),"\n",(0,t.jsx)(n.p,{children:'Most Chisel objects need to be cloned in order to differentiate between the\nsoftware representation of the bundle field from its "bound" hardware\nrepresentation, where "binding" is the process of generating a hardware\ncomponent. For Bundle fields, this cloning is supposed to happen automatically\nwith a compiler plugin.'}),"\n",(0,t.jsxs)(n.p,{children:["In some cases though, the plugin may not be able to clone the Bundle fields. The\nmost common case for when this happens is when the ",(0,t.jsx)(n.code,{children:"chisel3.Data"})," part of the\nBundle field is nested inside some other data structure and the compiler plugin\nis unable to figure out how to clone the entire structure. It is best to avoid\nsuch nested structures."]}),"\n",(0,t.jsxs)(n.p,{children:["There are a few ways around this issue - you can try wrapping the problematic\nfields in Input(...), Output(...), or Flipped(...) if appropriate. You can also\ntry manually cloning each field in the Bundle using the ",(0,t.jsx)(n.code,{children:"chiselTypeClone"})," method\nin ",(0,t.jsx)(n.code,{children:"chisel3.reflect.DataMirror"}),". Here's an example with the Bundle whose fields\nwon't get cloned:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'class CustomBundleBroken(elts: (String, Data)*) extends Record {\n val elements = ListMap(elts: _*)\n\n def apply(elt: String): Data = elements(elt)\n}\n\nclass NewModule extends Module {\n val out = Output(UInt(8.W))\n val recordType = new CustomBundleBroken("fizz" -> UInt(16.W), "buzz" -> UInt(16.W))\n val record = Wire(recordType)\n val uint = record.asUInt\n val record2 = uint.asTypeOf(recordType)\n out := record\n}\ngetVerilogString(new NewModule)\n// chisel3.AutoClonetypeException: The bundle plugin was unable to clone CustomBundleBroken$1 that has field \'fizz\' aliased with base CustomBundleBroken$1.This likely happened because you tried nesting Data arguments inside of other data structures. Try wrapping the field(s) in Input(...), Output(...), or Flipped(...) if appropriate. As a last resort, you can call chisel3.reflect.DataMirror.internal.chiselTypeClone on any nested Data arguments. See the cookbook entry \'How do I deal with the "unable to clone" error?\' for more details.\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74$$anonfun$apply$63.apply(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74$$anonfun$apply$63.apply(cookbook.md:444)\n// \tat chisel3.experimental.prefix$.apply(prefix.scala:50)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74.apply(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1$$anonfun$74.apply(cookbook.md)\n// \tat chisel3.internal.plugin.package$.autoNameRecursively(package.scala:33)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$NewModule$1.(cookbook.md:444)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$$anonfun$apply$67.apply(cookbook.md:449)\n// \tat repl.MdocSession$MdocApp17$$anonfun$70$$anonfun$apply$67.apply(cookbook.md:449)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"chiselTypeClone"})," to clone the elements as:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.reflect.DataMirror\nimport chisel3.experimental.requireIsChiselType\n\nclass CustomBundleFixed(elts: (String, Data)*) extends Record {\n val elements = ListMap(elts.map {\n case (field, elt) =>\n requireIsChiselType(elt)\n field -> DataMirror.internal.chiselTypeClone(elt)\n }: _*)\n\n def apply(elt: String): Data = elements(elt)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-a-finite-state-machine-fsm",children:"How do I create a finite state machine (FSM)?"}),"\n",(0,t.jsxs)(n.p,{children:["The advised way is to use ",(0,t.jsx)(n.code,{children:"ChiselEnum"})," to construct enumerated types representing the state of the FSM.\nState transitions are then handled with ",(0,t.jsx)(n.code,{children:"switch"}),"/",(0,t.jsx)(n.code,{children:"is"})," and ",(0,t.jsx)(n.code,{children:"when"}),"/",(0,t.jsx)(n.code,{children:".elsewhen"}),"/",(0,t.jsx)(n.code,{children:".otherwise"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.util.{switch, is}\n\nobject DetectTwoOnes {\n object State extends ChiselEnum {\n val sNone, sOne1, sTwo1s = Value\n }\n}\n\n/* This FSM detects two 1's one after the other */\nclass DetectTwoOnes extends Module {\n import DetectTwoOnes.State\n import DetectTwoOnes.State._\n\n val io = IO(new Bundle {\n val in = Input(Bool())\n val out = Output(Bool())\n val state = Output(State())\n })\n\n val state = RegInit(sNone)\n\n io.out := (state === sTwo1s)\n io.state := state\n\n switch (state) {\n is (sNone) {\n when (io.in) {\n state := sOne1\n }\n }\n is (sOne1) {\n when (io.in) {\n state := sTwo1s\n } .otherwise {\n state := sNone\n }\n }\n is (sTwo1s) {\n when (!io.in) {\n state := sNone\n }\n }\n }\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: the ",(0,t.jsx)(n.code,{children:"is"})," statement can take multiple conditions e.g. ",(0,t.jsx)(n.code,{children:"is (sTwo1s, sOne1) { ... }"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-unpack-a-value-reverse-concatenation-like-in-verilog",children:'How do I unpack a value ("reverse concatenation") like in Verilog?'}),"\n",(0,t.jsxs)(n.p,{children:["In Verilog, you can do something like the following which will unpack a the value ",(0,t.jsx)(n.code,{children:"z"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"wire [1:0] a;\nwire [3:0] b;\nwire [2:0] c;\nwire [8:0] z = [...];\nassign {a,b,c} = z;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Unpacking often corresponds to reinterpreting an unstructured data type as a structured data type.\nFrequently, this structured type is used prolifically in the design, and has been declared as in the following example:"}),"\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 a = UInt(2.W)\n val b = UInt(4.W)\n val c = UInt(3.W)\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"The easiest way to accomplish this in Chisel would be:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'class Foo extends Module {\n val z = Wire(UInt(9.W))\n z := DontCare // This is a dummy connection\n val unpacked = z.asTypeOf(new MyBundle)\n printf("%d", unpacked.a)\n printf("%d", unpacked.b)\n printf("%d", unpacked.c)\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["If you ",(0,t.jsx)(n.strong,{children:"really"})," need to do this for a one-off case (Think thrice! It is likely you can better structure the code using bundles), then rocket-chip has a ",(0,t.jsx)(n.a,{href:"https://github.com/freechipsproject/rocket-chip/blob/723af5e6b69e07b5f94c46269a208a8d65e9d73b/src/main/scala/util/Misc.scala#L140",children:"Split utility"})," which can accomplish this."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-do-subword-assignment-assign-to-some-bits-in-a-uint",children:"How do I do subword assignment (assign to some bits in a UInt)?"}),"\n",(0,t.jsxs)(n.p,{children:["You may try to do something like the following where you want to assign only some bits of a Chisel type.\nBelow, the left-hand side connection to ",(0,t.jsx)(n.code,{children:"io.out(0)"})," is not allowed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\n\nclass Foo extends Module {\n val io = IO(new Bundle {\n val bit = Input(Bool())\n val out = Output(UInt(10.W))\n })\n io.out(0) := io.bit\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you try to compile this, you will get an error."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"getVerilogString(new Foo)\n// chisel3.package$ChiselException: Cannot reassign to read-only Foo.?: OpResult[Bool]\n// \tat ... ()\n// \tat repl.MdocSession$MdocApp26$Foo.(cookbook.md:589)\n// \tat repl.MdocSession$MdocApp26$$anonfun$104$$anonfun$apply$90.apply(cookbook.md:597)\n// \tat repl.MdocSession$MdocApp26$$anonfun$104$$anonfun$apply$90.apply(cookbook.md:597)\n// \tat ... ()\n// \tat ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Chisel3 ",(0,t.jsx)(n.em,{children:"does not support subword assignment"}),".\nThe reason for this is that subword assignment generally hints at a better abstraction with an aggregate/structured types, i.e., a ",(0,t.jsx)(n.code,{children:"Bundle"})," or a ",(0,t.jsx)(n.code,{children:"Vec"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["If you must express it this way, one approach is to blast your ",(0,t.jsx)(n.code,{children:"UInt"})," to a ",(0,t.jsx)(n.code,{children:"Vec"})," of ",(0,t.jsx)(n.code,{children:"Bool"})," and back:"]}),"\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 io = IO(new Bundle {\n val in = Input(UInt(10.W))\n val bit = Input(Bool())\n val out = Output(UInt(10.W))\n })\n val bools = VecInit(io.in.asBools)\n bools(0) := io.bit\n io.out := bools.asUInt\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-an-optional-io",children:"How do I create an optional I/O?"}),"\n",(0,t.jsxs)(n.p,{children:["The following example is a module which includes the optional port ",(0,t.jsx)(n.code,{children:"out2"})," only if the given parameter is ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass ModuleWithOptionalIOs(flag: Boolean) extends Module {\n val io = IO(new Bundle {\n val in = Input(UInt(12.W))\n val out = Output(UInt(12.W))\n val out2 = if (flag) Some(Output(UInt(12.W))) else None\n })\n\n io.out := io.in\n if (flag) {\n io.out2.get := io.in\n }\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following is an example where an entire ",(0,t.jsx)(n.code,{children:"IO"})," is optional:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass ModuleWithOptionalIO(flag: Boolean) extends Module {\n val in = if (flag) Some(IO(Input(Bool()))) else None\n val out = IO(Output(Bool()))\n\n out := in.getOrElse(false.B)\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-create-io-without-a-prefix",children:"How do I create I/O without a prefix?"}),"\n",(0,t.jsxs)(n.p,{children:["In most cases, you can simply call ",(0,t.jsx)(n.code,{children:"IO"})," multiple times:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\nclass MyModule extends Module {\n val in = IO(Input(UInt(8.W)))\n val out = IO(Output(UInt(8.W)))\n\n out := in +% 1.U\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule MyModule(\t// cookbook.md:691:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [7:0] in,\t// cookbook.md:692:14\n output [7:0] out\t// cookbook.md:693:15\n);\n\n assign out = in + 8'h1;\t// cookbook.md:691:7, :695:13\nendmodule\n\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you have a ",(0,t.jsx)(n.code,{children:"Bundle"})," from which you would like to create ports without the\nnormal ",(0,t.jsx)(n.code,{children:"val"})," prefix, you can use ",(0,t.jsx)(n.code,{children:"FlatIO"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport chisel3.experimental.FlatIO\n\nclass MyBundle extends Bundle {\n val foo = Input(UInt(8.W))\n val bar = Output(UInt(8.W))\n}\n\nclass MyModule extends Module {\n val io = FlatIO(new MyBundle)\n\n io.bar := io.foo +% 1.U\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"io_"})," is nowhere to be seen!"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule MyModule(\t// cookbook.md:723:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [7:0] foo,\t// cookbook.md:724:18\n output [7:0] bar\t// cookbook.md:724:18\n);\n\n assign bar = foo + 8'h1;\t// cookbook.md:723:7, :726:20\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-minimize-the-number-of-bits-used-in-an-output-vector",children:"How do I minimize the number of bits used in an output vector?"}),"\n",(0,t.jsxs)(n.p,{children:["Use inferred width and a ",(0,t.jsx)(n.code,{children:"Seq"})," instead of a ",(0,t.jsx)(n.code,{children:"Vec"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"Consider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\n\n// Count the number of set bits up to and including each bit position\nclass CountBits(width: Int) extends Module {\n val bits = IO(Input(UInt(width.W)))\n val countSequence = Seq.tabulate(width)(i => IO(Output(UInt())))\n val countVector = IO(Output(Vec(width, UInt())))\n countSequence.zipWithIndex.foreach { case (port, i) =>\n port := util.PopCount(bits(i, 0))\n }\n countVector := countSequence\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Unlike ",(0,t.jsx)(n.code,{children:"Vecs"})," which represent a singular Chisel type and must have the same width for every element,\n",(0,t.jsx)(n.code,{children:"Seq"})," is a purely Scala construct, so their elements are independent from the perspective of Chisel and can have different widths."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule CountBits(\t// cookbook.md:745:7\n input clock,\t// :4:11\n reset,\t// :5:11\n input [3:0] bits,\t// cookbook.md:746:16\n output countSequence_0,\t// cookbook.md:747:50\n output [1:0] countSequence_1,\t// cookbook.md:747:50\n countSequence_2,\t// cookbook.md:747:50\n output [2:0] countSequence_3,\t// cookbook.md:747:50\n countVector_0,\t// cookbook.md:748:23\n countVector_1,\t// cookbook.md:748:23\n countVector_2,\t// cookbook.md:748:23\n countVector_3\t// cookbook.md:748:23\n);\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"-how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-",children:[(0,t.jsx)("a",{id:"dynamic-index-too-wide-narrow"}),' How do I resolve "Dynamic index ... is too wide/narrow for extractee ..."?']}),"\n",(0,t.jsx)(n.p,{children:'Chisel will warn if a dynamic index is not the correctly-sized width for indexing a Vec or UInt.\n"Correctly-sized" means that the width of the index should be the log2 of the size of the indexee.\nIf the indexee is a non-power-of-2 size, use the ceiling of the log2 result.'}),"\n",(0,t.jsxs)(n.p,{children:["When the index does not have enough bits to address all entries or bits in the extractee, you can ",(0,t.jsx)(n.code,{children:".pad"})," the index to increase the width."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooNarrow extends RawModule {\n val extractee = Wire(UInt(7.W))\n val index = Wire(UInt(2.W))\n extractee(index)\n}\ncompile(new TooNarrow)\n// [warn] cookbook.md 788:12: [W003] Dynamic index with width 2 is too small for extractee of width 7\n// [warn] There were 1 warning(s) during hardware elaboration.\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This can be fixed with ",(0,t.jsx)(n.code,{children:"pad"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooNarrowFixed extends RawModule {\n val extractee = Wire(UInt(7.W))\n val index = Wire(UInt(2.W))\n extractee(index.pad(3))\n}\ncompile(new TooNarrowFixed)\n"})}),"\n",(0,t.jsx)(n.h4,{id:"use-bit-extraction-when-the-index-is-too-wide",children:"Use bit extraction when the index is too wide"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWide extends RawModule {\n val extractee = Wire(Vec(8, UInt(32.W)))\n val index = Wire(UInt(4.W))\n extractee(index)\n}\ncompile(new TooWide)\n// [warn] cookbook.md 814:12: [W004] Dynamic index with width 4 is too wide for Vec of size 8 (expected index width 3).\n// [warn] There were 1 warning(s) during hardware elaboration.\n"})}),"\n",(0,t.jsx)(n.p,{children:"This can be fixed with bit extraction:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWideFixed extends RawModule {\n val extractee = Wire(Vec(8, UInt(32.W)))\n val index = Wire(UInt(4.W))\n extractee(index(2, 0))\n}\ncompile(new TooWideFixed)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that size 1 ",(0,t.jsx)(n.code,{children:"Vecs"})," and ",(0,t.jsx)(n.code,{children:"UInts"})," should be indexed by a zero-width ",(0,t.jsx)(n.code,{children:"UInt"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class SizeOneVec extends RawModule {\n val extractee = Wire(Vec(1, UInt(32.W)))\n val index = Wire(UInt(0.W))\n extractee(index)\n}\ncompile(new SizeOneVec)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Because ",(0,t.jsx)(n.code,{children:"pad"})," only pads if the desired width is less than the current width of the argument,\nyou can use ",(0,t.jsx)(n.code,{children:"pad"})," in conjunction with bit extraction when the widths may be too wide or too\nnarrow under different circumstances"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3.util.log2Ceil\nclass TooWideOrNarrow(extracteeSize: Int, indexWidth: Int) extends Module {\n val extractee = Wire(Vec(extracteeSize, UInt(8.W)))\n val index = Wire(UInt(indexWidth.W))\n val correctWidth = log2Ceil(extracteeSize)\n extractee(index.pad(correctWidth)(correctWidth - 1, 0))\n}\ncompile(new TooWideOrNarrow(8, 2))\ncompile(new TooWideOrNarrow(8, 4))\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Another option for dynamic bit selection of ",(0,t.jsx)(n.code,{children:"UInts"})," (but not ",(0,t.jsx)(n.code,{children:"Vec"})," dynamic indexing) is to do a dynamic\nright shift of the extractee by the index and then just bit select a single bit:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"class TooWideOrNarrowUInt(extracteeSize: Int, indexWidth: Int) extends Module {\n val extractee = Wire(UInt(extracteeSize.W))\n val index = Wire(UInt(indexWidth.W))\n (extractee >> index)(0)\n}\ncompile(new TooWideOrNarrowUInt(8, 2))\ncompile(new TooWideOrNarrowUInt(8, 4))\n"})}),"\n",(0,t.jsx)(n.h2,{id:"predictable-naming",children:"Predictable Naming"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-get-chisel-to-name-signals-properly-in-blocks-like-whenwithclockandreset",children:"How do I get Chisel to name signals properly in blocks like when/withClockAndReset?"}),"\n",(0,t.jsxs)(n.p,{children:["Use the compiler plugin, and check out the ",(0,t.jsx)(n.a,{href:"naming",children:"Naming Cookbook"})," if that still does not do what you want."]}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-get-chisel-to-name-the-results-of-vector-reads-properly",children:"How do I get Chisel to name the results of vector reads properly?"}),"\n",(0,t.jsx)(n.p,{children:"Currently, name information is lost when using dynamic indexing. For example:"}),"\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 io = IO(new Bundle {\n val in = Input(Vec(4, Bool()))\n val idx = Input(UInt(2.W))\n val en = Input(Bool())\n val out = Output(Bool())\n })\n\n val x = io.in(io.idx)\n val y = x && io.en\n io.out := y\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The above code loses the ",(0,t.jsx)(n.code,{children:"x"})," name, instead using ",(0,t.jsx)(n.code,{children:"_GEN_3"})," (the other ",(0,t.jsx)(n.code,{children:"_GEN_*"})," signals are expected)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Foo(\t// cookbook.md:892:7\n input clock,\t// :4:11\n reset,\t// :5:11\n io_in_0,\t// cookbook.md:893:14\n io_in_1,\t// cookbook.md:893:14\n io_in_2,\t// cookbook.md:893:14\n io_in_3,\t// cookbook.md:893:14\n input [1:0] io_idx,\t// cookbook.md:893:14\n input io_en,\t// cookbook.md:893:14\n output io_out\t// cookbook.md:893:14\n);\n\n wire [3:0] _GEN = {{io_in_3}, {io_in_2}, {io_in_1}, {io_in_0}};\t// cookbook.md:901:13\n assign io_out = _GEN[io_idx] & io_en;\t// cookbook.md:892:7, :901:13\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.p,{children:"This can be worked around by creating a wire and connecting the dynamic index to the wire:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"val x = WireInit(io.in(io.idx))\n"})}),"\n",(0,t.jsx)(n.p,{children:"Which produces:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\nmodule Foo2(\t// cookbook.md:915:7\n input clock,\t// :4:11\n reset,\t// :5:11\n io_in_0,\t// cookbook.md:916:14\n io_in_1,\t// cookbook.md:916:14\n io_in_2,\t// cookbook.md:916:14\n io_in_3,\t// cookbook.md:916:14\n input [1:0] io_idx,\t// cookbook.md:916:14\n input io_en,\t// cookbook.md:916:14\n output io_out\t// cookbook.md:916:14\n);\n\n wire [3:0] _GEN = {{io_in_3}, {io_in_2}, {io_in_1}, {io_in_0}};\t// cookbook.md:923:19\n assign io_out = _GEN[io_idx] & io_en;\t// cookbook.md:915:7, :923:19, :924:13\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"how-can-i-dynamically-setparametrize-the-name-of-a-module",children:"How can I dynamically set/parametrize the name of a module?"}),"\n",(0,t.jsxs)(n.p,{children:["You can override the ",(0,t.jsx)(n.code,{children:"desiredName"})," function. This works with normal Chisel modules and ",(0,t.jsx)(n.code,{children:"BlackBox"}),"es. Example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:'import chisel3._\n\nclass Coffee extends BlackBox {\n val io = IO(new Bundle {\n val I = Input(UInt(32.W))\n val O = Output(UInt(32.W))\n })\n override def desiredName = "Tea"\n}\n\nclass Salt extends Module {\n val io = IO(new Bundle {})\n val drink = Module(new Coffee)\n override def desiredName = "SodiumMonochloride"\n\n drink.io.I := 42.U\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Elaborating the Chisel module ",(0,t.jsx)(n.code,{children:"Salt"}),' yields our "desired names" for ',(0,t.jsx)(n.code,{children:"Salt"})," and ",(0,t.jsx)(n.code,{children:"Coffee"})," in the output Verilog:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-verilog",children:"// Generated by CIRCT firtool-1.59.0\n// external module Tea\n\nmodule SodiumMonochloride(\t// cookbook.md:953:7\n input clock,\t// :9:11\n reset\t// :10:11\n);\n\n Tea drink (\t// cookbook.md:955:23\n .I (32'h2A),\t// cookbook.md:958:16\n .O (/* unused */)\n );\nendmodule\n\n"})}),"\n",(0,t.jsx)(n.h2,{id:"directionality",children:"Directionality"}),"\n",(0,t.jsx)(n.h3,{id:"how-do-i-strip-directions-from-a-bidirectional-bundle-or-other-data",children:"How do I strip directions from a bidirectional Bundle (or other Data)?"}),"\n",(0,t.jsxs)(n.p,{children:["Given a bidirectional port like a ",(0,t.jsx)(n.code,{children:"Decoupled"}),", you will get an error if you try to connect it directly\nto a register:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\nimport chisel3.util.Decoupled\nclass BadRegConnect extends Module {\n val io = IO(new Bundle {\n val enq = Decoupled(UInt(8.W))\n })\n\n val monitor = Reg(chiselTypeOf(io.enq))\n monitor := io.enq\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"ChiselStage.emitSystemVerilog(new BadRegConnect)\n// circt.stage.phases.Exceptions$FirtoolNonZeroExitCode: firtool returned a non-zero exit code. Note that this version of Chisel (0.0.0+1-ca74d07e-SNAPSHOT) was published against firtool version 1.59.0.\n// ------------------------------------------------------------------------------\n// ExitCode:\n// 1\n// STDOUT:\n// \n// STDERR:\n// cookbook.md:988:20: error: 'firrtl.reg' op result #0 must be a passive non-'const' base type that does not contain analog, but got '!firrtl.bundle, valid: uint<1>, bits: uint<8>>'\n// cookbook.md:988:20: note: see current operation: %4 = \"firrtl.reg\"(%arg0) {annotations = [], name = \"monitor\", nameKind = #firrtl} : (!firrtl.clock) -> !firrtl.bundle, valid: uint<1>, bits: uint<8>>\n// \n// ------------------------------------------------------------------------------\n"})}),"\n",(0,t.jsxs)(n.p,{children:['While there is no construct to "strip direction" in Chisel3, wrapping a type in ',(0,t.jsx)(n.code,{children:"Output(...)"}),"\n(the default direction in Chisel3) will\nset all of the individual elements to output direction.\nThis will have the desired result when used to construct a Register:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scala",children:"import chisel3._\nimport circt.stage.ChiselStage\nimport chisel3.util.Decoupled\nclass CoercedRegConnect extends Module {\n val io = IO(new Bundle {\n val enq = Flipped(Decoupled(UInt(8.W)))\n })\n\n // Make a Reg which contains all of the bundle's signals, regardless of their directionality\n val monitor = Reg(Output(chiselTypeOf(io.enq)))\n // Even though io.enq is bidirectional, := will drive all fields of monitor with the fields of io.enq\n monitor := io.enq\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>s,a:()=>l});var t=o(7294);const i={},a=t.createContext(i);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.94fdc630.js b/assets/js/main.c9ac804a.js similarity index 77% rename from assets/js/main.94fdc630.js rename to assets/js/main.c9ac804a.js index 305c4839b10..b6b921a9289 100644 --- a/assets/js/main.94fdc630.js +++ b/assets/js/main.c9ac804a.js @@ -1,2 +1,2 @@ -/*! For license information please see main.94fdc630.js.LICENSE.txt */ -(self.webpackChunkchisel_lang=self.webpackChunkchisel_lang||[]).push([[179],{830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(7294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(7294);var r=n(8356),a=n.n(r),o=n(6887);const i={"0bba5ab0":[()=>n.e(6685).then(n.bind(n,1878)),"@site/docs/explanations/width-inference.md",1878],"11a69d4a":[()=>n.e(8915).then(n.bind(n,4771)),"@site/docs/appendix/upgrading-from-scala-2-11.md",4771],"11d458a9":[()=>n.e(7792).then(n.bind(n,3217)),"@site/docs/explanations/reset.md",3217],"169af844":[()=>n.e(6483).then(n.bind(n,8729)),"@site/docs/developers/sbt-subproject.md",8729],17896441:[()=>Promise.all([n.e(532),n.e(325),n.e(7918)]).then(n.bind(n,903)),"@theme/DocItem",903],"17dd133b":[()=>n.e(9737).then(n.bind(n,5120)),"@site/docs/resources/faqs.md",5120],"1883c3a9":[()=>n.e(7929).then(n.bind(n,8874)),"@site/docs/explanations/annotations.md",8874],"19ad7e9f":[()=>n.e(4941).then(n.bind(n,4651)),"@site/docs/developers/style.md",4651],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,6675)),"@theme/SearchPage",6675],"1c415a4e":[()=>n.e(7341).then(n.bind(n,5207)),"@site/docs/developers/developers.md",5207],"1ce89024":[()=>n.e(2431).then(n.bind(n,6178)),"@site/docs/cookbooks/hierarchy.md",6178],"1f391b9e":[()=>Promise.all([n.e(532),n.e(325),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],"1f7682ec":[()=>n.e(628).then(n.bind(n,6412)),"@site/docs/explanations/source-locators.md",6412],"2024159c":[()=>n.e(7988).then(n.bind(n,1793)),"@site/docs/explanations/modules.md",1793],"30c88dbf":[()=>n.e(4862).then(n.bind(n,6461)),"@site/docs/explanations/motivation.md",6461],"33364b1e":[()=>n.e(247).then(n.bind(n,3248)),"@site/docs/resources/resources.md",3248],"37a5b604":[()=>n.e(4394).then(n.bind(n,2809)),"@site/docs/explanations/functional-abstraction.md",2809],"3afb3224":[()=>n.e(7770).then(n.bind(n,3030)),"@site/docs/explanations/warnings.md",3030],"407ce553":[()=>n.e(5719).then(n.bind(n,2266)),"@site/docs/explanations/properties.md",2266],"44147ff4":[()=>n.e(7343).then(n.bind(n,399)),"@site/docs/explanations/unconnected-wires.md",399],"44ff0b81":[()=>n.e(7477).then(n.bind(n,2909)),"@site/docs/explanations/data-types.md",2909],"46a40f56":[()=>n.e(6234).then(n.bind(n,7127)),"@site/docs/explanations/operators.md",7127],"54ab625b":[()=>n.e(5769).then(n.bind(n,8505)),"@site/docs/developers/scaladoc.md",8505],"556f9cb0":[()=>n.e(1911).then(n.t.bind(n,3769,19)),"/home/runner/work/chisel/chisel/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"651e9e03":[()=>n.e(5734).then(n.bind(n,8912)),"@site/docs/explanations/blackboxes.md",8912],"6559d260":[()=>n.e(6980).then(n.bind(n,4766)),"@site/docs/explanations/sequential-circuits.md",4766],"67ffb541":[()=>n.e(9560).then(n.bind(n,911)),"@site/docs/explanations/dataview.md",911],"6a9619ba":[()=>n.e(5405).then(n.bind(n,1622)),"@site/docs/explanations/combinational-circuits.md",1622],"7b5bfa87":[()=>n.e(4003).then(n.bind(n,1235)),"@site/docs/explanations/chisel-type-vs-scala-type.md",1235],"7cc2f0dc":[()=>n.e(4930).then(n.bind(n,6056)),"@site/docs/explanations/polymorphism-and-parameterization.md",6056],"7e1e4a75":[()=>n.e(7462).then(n.bind(n,9611)),"@site/docs/cookbooks/cookbook.md",9611],"7fa9ea57":[()=>n.e(5041).then(n.bind(n,6350)),"@site/docs/explanations/ports.md",6350],"806d4637":[()=>n.e(2563).then(n.bind(n,2485)),"@site/docs/cookbooks/serialization.md",2485],"87a95817":[()=>n.e(6300).then(n.bind(n,7919)),"@site/docs/explanations/explanations.md",7919],"87b43d15":[()=>n.e(3142).then(n.t.bind(n,7085,19)),"/home/runner/work/chisel/chisel/website/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"87ed036d":[()=>n.e(1628).then(n.bind(n,25)),"@site/src/pages/generated/contributors.md",25],"8fdf13ba":[()=>n.e(4833).then(n.bind(n,9163)),"@site/docs/appendix/versioning.md",9163],"916cecd1":[()=>n.e(9837).then(n.bind(n,7867)),"@site/docs/cookbooks/naming.md",7867],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"96d1adfe":[()=>n.e(3997).then(n.bind(n,621)),"@site/docs/explanations/intrinsics.md",621],"98ca0ee0":[()=>n.e(3122).then(n.bind(n,3492)),"@site/src/pages/api.md",3492],"9cc76f42":[()=>n.e(6379).then(n.bind(n,7213)),"@site/docs/developers/test-coverage.md",7213],"9cfbec6b":[()=>n.e(6001).then(n.t.bind(n,5745,19)),"/home/runner/work/chisel/chisel/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],a2603a41:[()=>n.e(7730).then(n.bind(n,3922)),"@site/docs/appendix/appendix.md",3922],a26328e3:[()=>n.e(8235).then(n.bind(n,7427)),"@site/docs/explanations/interfaces-and-connections.md",7427],a47e47c7:[()=>n.e(9948).then(n.bind(n,2631)),"@site/docs/cookbooks/troubleshooting.md",2631],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a8f82c73:[()=>n.e(7146).then(n.bind(n,6723)),"@site/docs/explanations/bundles-and-vecs.md",6723],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],a98e3d7d:[()=>n.e(7219).then(n.bind(n,6158)),"@site/docs/explanations/memories.md",6158],b13aa1a2:[()=>n.e(2869).then(n.bind(n,5340)),"@site/docs/explanations/muxes-and-input-selection.md",5340],bc33eb1f:[()=>n.e(619).then(n.bind(n,7444)),"@site/docs/explanations/decoder.md",7444],c377a04b:[()=>n.e(6971).then(n.bind(n,9925)),"@site/docs/index.md",9925],c48de377:[()=>n.e(7131).then(n.bind(n,1716)),"@site/docs/appendix/experimental-features.md",1716],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],c5561474:[()=>n.e(6562).then(n.bind(n,4190)),"@site/docs/explanations/multi-clock.md",4190],c71a47e4:[()=>n.e(9147).then(n.bind(n,4899)),"@site/docs/explanations/functional-module-creation.md",4899],c7666d49:[()=>n.e(3770).then(n.bind(n,8724)),"@site/docs/explanations/layers.md",8724],cdcdfbab:[()=>n.e(4485).then(n.bind(n,4535)),"@site/docs/explanations/chisel-enum.md",4535],d1a683e4:[()=>n.e(2478).then(n.bind(n,1946)),"@site/docs/appendix/upgrading-from-chisel-3-4.md",1946],d1e6e3d8:[()=>n.e(2705).then(n.bind(n,4564)),"@site/docs/explanations/connection-operators.md",4564],d4b6d0e6:[()=>n.e(6715).then(n.bind(n,6275)),"@site/docs/explanations/connectable.md",6275],d50fb5c7:[()=>n.e(7408).then(n.bind(n,3258)),"@site/docs/explanations/naming.md",3258],d9d0021c:[()=>n.e(3133).then(n.bind(n,7573)),"@site/docs/cookbooks/cookbooks.md",7573],e7b22fe0:[()=>n.e(6996).then(n.bind(n,9666)),"@site/src/pages/community.md",9666],f10ce86b:[()=>n.e(5011).then(n.bind(n,2987)),"@site/docs/cookbooks/dataview.md",2987],f416550b:[()=>n.e(2330).then(n.bind(n,6793)),"@site/docs/explanations/supported-hardware.md",6793],f901c241:[()=>n.e(3819).then(n.bind(n,1100)),"@site/docs/explanations/printing.md",1100]};var s=n(5893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(9670),u=n(226);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},p=[],f=[],h=(0,c.Z)(r);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),a().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const p=[{path:"/api",component:d("/api","7b5"),exact:!0},{path:"/community",component:d("/community","afd"),exact:!0},{path:"/generated/contributors",component:d("/generated/contributors","96f"),exact:!0},{path:"/search",component:d("/search","60f"),exact:!0},{path:"/docs",component:d("/docs","3d2"),routes:[{path:"/docs",component:d("/docs","9e3"),routes:[{path:"/docs",component:d("/docs","1ab"),routes:[{path:"/docs",component:d("/docs","f5d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix",component:d("/docs/appendix","b3d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/experimental-features",component:d("/docs/appendix/experimental-features","3ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/upgrading-from-chisel-3-4",component:d("/docs/appendix/upgrading-from-chisel-3-4","f3d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/upgrading-from-scala-2-11",component:d("/docs/appendix/upgrading-from-scala-2-11","5a0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/versioning",component:d("/docs/appendix/versioning","273"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks",component:d("/docs/cookbooks","dfc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/cookbook",component:d("/docs/cookbooks/cookbook","e10"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/dataview",component:d("/docs/cookbooks/dataview","2fe"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/hierarchy",component:d("/docs/cookbooks/hierarchy","457"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/naming",component:d("/docs/cookbooks/naming","489"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/serialization",component:d("/docs/cookbooks/serialization","e5f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/cookbooks/troubleshooting",component:d("/docs/cookbooks/troubleshooting","422"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/developers",component:d("/docs/developers","4f9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/developers/sbt-subproject",component:d("/docs/developers/sbt-subproject","04a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/developers/scaladoc",component:d("/docs/developers/scaladoc","5b9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/developers/style",component:d("/docs/developers/style","74a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/developers/test-coverage",component:d("/docs/developers/test-coverage","61d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations",component:d("/docs/explanations","3ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/annotations",component:d("/docs/explanations/annotations","c76"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/blackboxes",component:d("/docs/explanations/blackboxes","a89"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/bundles-and-vecs",component:d("/docs/explanations/bundles-and-vecs","a9c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/chisel-enum",component:d("/docs/explanations/chisel-enum","345"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/chisel-type-vs-scala-type",component:d("/docs/explanations/chisel-type-vs-scala-type","b7a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/combinational-circuits",component:d("/docs/explanations/combinational-circuits","e4d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/connectable",component:d("/docs/explanations/connectable","977"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/connection-operators",component:d("/docs/explanations/connection-operators","cee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/data-types",component:d("/docs/explanations/data-types","21a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/dataview",component:d("/docs/explanations/dataview","cb9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/decoder",component:d("/docs/explanations/decoder","d5f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/functional-abstraction",component:d("/docs/explanations/functional-abstraction","2b9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/functional-module-creation",component:d("/docs/explanations/functional-module-creation","514"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/interfaces-and-connections",component:d("/docs/explanations/interfaces-and-connections","23c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/intrinsics",component:d("/docs/explanations/intrinsics","8f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/layers",component:d("/docs/explanations/layers","fd0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/memories",component:d("/docs/explanations/memories","b7b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/modules",component:d("/docs/explanations/modules","0c1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/motivation",component:d("/docs/explanations/motivation","879"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/multi-clock",component:d("/docs/explanations/multi-clock","89e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/muxes-and-input-selection",component:d("/docs/explanations/muxes-and-input-selection","1af"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/naming",component:d("/docs/explanations/naming","0b9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/operators",component:d("/docs/explanations/operators","7b9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/polymorphism-and-parameterization",component:d("/docs/explanations/polymorphism-and-parameterization","462"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/ports",component:d("/docs/explanations/ports","781"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/printing",component:d("/docs/explanations/printing","838"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/properties",component:d("/docs/explanations/properties","99b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/reset",component:d("/docs/explanations/reset","514"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/sequential-circuits",component:d("/docs/explanations/sequential-circuits","703"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/source-locators",component:d("/docs/explanations/source-locators","bfe"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/supported-hardware",component:d("/docs/explanations/supported-hardware","f47"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/unconnected-wires",component:d("/docs/explanations/unconnected-wires","5a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/warnings",component:d("/docs/explanations/warnings","84b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/explanations/width-inference",component:d("/docs/explanations/width-inference","d2e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/resources",component:d("/docs/resources","2ce"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/resources/faqs",component:d("/docs/resources/faqs","78b"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/",component:d("/","77f"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var r=n(7294),a=n(5893);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),a=n(745),o=n(3727),i=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790),p=n(5893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var h=n(5742),m=n(2263),g=n(4996),b=n(6668),y=n(833),v=n(4711),x=n(9727),w=n(3320),k=n(8780),S=n(197);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,m.Z)(),r=(0,v.l)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(h.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,m.Z)(),{pathname:r}=(0,u.TH)();return e+(0,k.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,p.jsxs)(h.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:a}),(0,p.jsx)("link",{rel:"canonical",href:a})]})}function C(){const{i18n:{currentLocale:e}}=(0,m.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(h.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:x.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(_,{}),(0,p.jsx)(E,{}),(0,p.jsx)(S.Z,{tag:w.HX,locale:e}),(0,p.jsx)(h.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var N=n(8934),j=n(8940),L=n(469);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const O=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,L.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),P("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(O,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const F=I,M="__docusaurus-base-url-issue-banner-container",D="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(9670);const Q=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Q.has(e))(e))return!1;Q.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),R(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(o.VK,{children:(0,p.jsx)(q,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)r.startTransition((()=>{a.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=a.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{o.render(t)}))}};R(window.location.pathname).then(s)}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"appendix/appendix","path":"/docs/appendix/","sidebar":"tutorialSidebar"},{"id":"appendix/experimental-features","path":"/docs/appendix/experimental-features","sidebar":"tutorialSidebar"},{"id":"appendix/upgrading-from-chisel-3-4","path":"/docs/appendix/upgrading-from-chisel-3-4","sidebar":"tutorialSidebar"},{"id":"appendix/upgrading-from-scala-2-11","path":"/docs/appendix/upgrading-from-scala-2-11","sidebar":"tutorialSidebar"},{"id":"appendix/versioning","path":"/docs/appendix/versioning","sidebar":"tutorialSidebar"},{"id":"cookbooks/cookbook","path":"/docs/cookbooks/cookbook","sidebar":"tutorialSidebar"},{"id":"cookbooks/cookbooks","path":"/docs/cookbooks/","sidebar":"tutorialSidebar"},{"id":"cookbooks/dataview","path":"/docs/cookbooks/dataview","sidebar":"tutorialSidebar"},{"id":"cookbooks/hierarchy","path":"/docs/cookbooks/hierarchy","sidebar":"tutorialSidebar"},{"id":"cookbooks/naming","path":"/docs/cookbooks/naming","sidebar":"tutorialSidebar"},{"id":"cookbooks/serialization","path":"/docs/cookbooks/serialization","sidebar":"tutorialSidebar"},{"id":"cookbooks/troubleshooting","path":"/docs/cookbooks/troubleshooting","sidebar":"tutorialSidebar"},{"id":"developers/developers","path":"/docs/developers/","sidebar":"tutorialSidebar"},{"id":"developers/sbt-subproject","path":"/docs/developers/sbt-subproject","sidebar":"tutorialSidebar"},{"id":"developers/scaladoc","path":"/docs/developers/scaladoc","sidebar":"tutorialSidebar"},{"id":"developers/style","path":"/docs/developers/style","sidebar":"tutorialSidebar"},{"id":"developers/test-coverage","path":"/docs/developers/test-coverage","sidebar":"tutorialSidebar"},{"id":"explanations/annotations","path":"/docs/explanations/annotations","sidebar":"tutorialSidebar"},{"id":"explanations/blackboxes","path":"/docs/explanations/blackboxes","sidebar":"tutorialSidebar"},{"id":"explanations/bundles-and-vecs","path":"/docs/explanations/bundles-and-vecs","sidebar":"tutorialSidebar"},{"id":"explanations/chisel-enum","path":"/docs/explanations/chisel-enum","sidebar":"tutorialSidebar"},{"id":"explanations/chisel-type-vs-scala-type","path":"/docs/explanations/chisel-type-vs-scala-type","sidebar":"tutorialSidebar"},{"id":"explanations/combinational-circuits","path":"/docs/explanations/combinational-circuits","sidebar":"tutorialSidebar"},{"id":"explanations/connectable","path":"/docs/explanations/connectable","sidebar":"tutorialSidebar"},{"id":"explanations/connection-operators","path":"/docs/explanations/connection-operators","sidebar":"tutorialSidebar"},{"id":"explanations/data-types","path":"/docs/explanations/data-types","sidebar":"tutorialSidebar"},{"id":"explanations/dataview","path":"/docs/explanations/dataview","sidebar":"tutorialSidebar"},{"id":"explanations/decoder","path":"/docs/explanations/decoder","sidebar":"tutorialSidebar"},{"id":"explanations/explanations","path":"/docs/explanations/","sidebar":"tutorialSidebar"},{"id":"explanations/functional-abstraction","path":"/docs/explanations/functional-abstraction","sidebar":"tutorialSidebar"},{"id":"explanations/functional-module-creation","path":"/docs/explanations/functional-module-creation","sidebar":"tutorialSidebar"},{"id":"explanations/interfaces-and-connections","path":"/docs/explanations/interfaces-and-connections","sidebar":"tutorialSidebar"},{"id":"explanations/intrinsics","path":"/docs/explanations/intrinsics","sidebar":"tutorialSidebar"},{"id":"explanations/layers","path":"/docs/explanations/layers","sidebar":"tutorialSidebar"},{"id":"explanations/memories","path":"/docs/explanations/memories","sidebar":"tutorialSidebar"},{"id":"explanations/modules","path":"/docs/explanations/modules","sidebar":"tutorialSidebar"},{"id":"explanations/motivation","path":"/docs/explanations/motivation","sidebar":"tutorialSidebar"},{"id":"explanations/multi-clock","path":"/docs/explanations/multi-clock","sidebar":"tutorialSidebar"},{"id":"explanations/muxes-and-input-selection","path":"/docs/explanations/muxes-and-input-selection","sidebar":"tutorialSidebar"},{"id":"explanations/naming","path":"/docs/explanations/naming","sidebar":"tutorialSidebar"},{"id":"explanations/operators","path":"/docs/explanations/operators","sidebar":"tutorialSidebar"},{"id":"explanations/polymorphism-and-parameterization","path":"/docs/explanations/polymorphism-and-parameterization","sidebar":"tutorialSidebar"},{"id":"explanations/ports","path":"/docs/explanations/ports","sidebar":"tutorialSidebar"},{"id":"explanations/printing","path":"/docs/explanations/printing","sidebar":"tutorialSidebar"},{"id":"explanations/properties","path":"/docs/explanations/properties","sidebar":"tutorialSidebar"},{"id":"explanations/reset","path":"/docs/explanations/reset","sidebar":"tutorialSidebar"},{"id":"explanations/sequential-circuits","path":"/docs/explanations/sequential-circuits","sidebar":"tutorialSidebar"},{"id":"explanations/source-locators","path":"/docs/explanations/source-locators","sidebar":"tutorialSidebar"},{"id":"explanations/supported-hardware","path":"/docs/explanations/supported-hardware","sidebar":"tutorialSidebar"},{"id":"explanations/unconnected-wires","path":"/docs/explanations/unconnected-wires","sidebar":"tutorialSidebar"},{"id":"explanations/warnings","path":"/docs/explanations/warnings","sidebar":"tutorialSidebar"},{"id":"explanations/width-inference","path":"/docs/explanations/width-inference","sidebar":"tutorialSidebar"},{"id":"index","path":"/docs/","sidebar":"tutorialSidebar"},{"id":"resources/faqs","path":"/docs/resources/faqs","sidebar":"tutorialSidebar"},{"id":"resources/resources","path":"/docs/resources/","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/","label":"index"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"3.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.0.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.0"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.0.0"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.0.0"}}}');var c=n(5893);const u={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(7452),l=n(5893);function c(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(f,{fallback:()=>(0,l.jsx)(c,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,l.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);var r=n(405),a=n(5893);function o(e){return(0,a.jsx)(r.ql,{...e})}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(3727),o=n(8780),i=n(2263),s=n(3919),l=n(412),c=n(5893);const u=r.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:h,isActive:m,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:x}}=(0,i.Z)(),{withBaseUrl:w}=(0,d.C)(),k=(0,r.useContext)(u),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const E=p||f;const _=(0,s.Z)(E),C=E?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?w(A):A):void 0;var A;T&&_&&(T=(0,o.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:x}));const N=(0,r.useRef)(!1),j=n?a.OL:a.rU,L=l.Z.canUseIntersectionObserver,P=(0,r.useRef)(),O=()=>{N.current||null==T||(window.docusaurus.preload(T),N.current=!0)};(0,r.useEffect)((()=>(!L&&_&&null!=T&&window.docusaurus.prefetch(T),()=>{L&&P.current&&P.current.disconnect()})),[P,T,L,_]);const R=T?.startsWith("#")??!1,I=!T||!_||R;return I||g||k.collectLink(T),I?(0,c.jsx)("a",{ref:S,href:T,...E&&!_&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,c.jsx)(j,{...y,onMouseEnter:O,onTouchStart:O,innerRef:e=>{S.current=e,L&&e&&_&&(P.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(P.current.unobserve(e),P.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),P.current.observe(e))},to:T,...n&&{isActive:m,activeClassName:h}})}const f=r.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(7294),a=n(5893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(7529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>i});var r=n(7294),a=n(5893);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:s,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>h,_r:()=>d,Jo:()=>y,zh:()=>p,yW:()=>g,gB:()=>m});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function h(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function m(e){return p(e).versions}function g(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,r.TH)();return c(t,n)}function y(e){const t=p(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(4965),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(4262)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},7955:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(7294);var r=n(6010),a=n(5999),o=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(5893);function c(e){let{as:t,id:n,...c}=e;const{navbar:{hideOnScroll:u}}=(0,o.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...c,id:void 0});const d=(0,a.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,l.jsxs)(t,{...c,className:(0,r.Z)("anchor",u?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(5893);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},7452:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Lt});var r=n(7294),a=n(6010),o=n(4763),i=n(833),s=n(6550),l=n(5999),c=n(5936),u=n(5893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const h=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??h,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(5281),b=n(9727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(m,{className:y.skipToContent})}var x=n(6668),w=n(9689);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:a,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,x.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,x.L)(),{isActive:t,close:n}=(0,w.nT)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),o&&(0,u.jsx)(E,{onClick:n,className:T.announcementBarClose})]})}var N=n(3163),j=n(2466);var L=n(902),P=n(3102);const O=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,N.e)(),t=(0,P.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,L.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,u.jsx)(O.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(O);if(!e)throw new L.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,P.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:I(o)})),[a,o,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var D=n(2949),z=n(2389);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,z.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,a.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,x.L)().navbar.style,r=(0,x.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,D.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var q=n(1327);function G(){return(0,u.jsx)(q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,N.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Q=n(9960),X=n(4996),J=n(3919),ee=n(8022),te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...c}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(a,{forcePrependBaseUrl:!0}),h=o&&a&&!(0,J.Z)(a),m=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,h&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return a?(0,u.jsx)(Q.Z,{href:l?f:a,...c,...m}):(0,u.jsx)(Q.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},...c,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,u.jsx)(ne,{className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,a.Z)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,u.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(6043),se=n(8596),le=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ze,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function de(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:h}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&h(!d)}),[c,d,h]),(0,u.jsxs)("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Ze,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?de:ue;return(0,u.jsx)(r,{...n})}var fe=n(4711);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const me="iconLanguage_nlXk";function ge(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var be=n(830),ye=["translations"];function ve(){return ve=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var Se="Ctrl";var Ee=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=ke(e,ye),i=a.buttonText,s=void 0===i?"Search":i,l=a.buttonAriaLabel,c=void 0===l?"Search":l,u=xe((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Se))}),[]),r.createElement("button",ve({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(be.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Se?r.createElement(ge,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),_e=n(5742),Ce=n(6177),Te=n(239),Ae=n(3320);var Ne=n(3935);const je={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Le=null;function Pe(e){let{hit:t,children:n}=e;return(0,u.jsx)(Q.Z,{to:t.url,children:n})}function Oe(e){let{state:t,onClose:n}=e;const r=(0,Ce.M)();return(0,u.jsx)(Q.Z,{to:r(t.query),onClick:n,children:(0,u.jsx)(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Re(e){let{contextualSearch:t,externalUrlRegex:a,...o}=e;const{siteMetadata:i}=(0,le.Z)(),l=(0,Te.l)(),c=function(){const{locale:e,tags:t}=(0,Ae._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,d):d,f={...o.searchParameters,facetFilters:p},h=(0,s.k6)(),m=(0,r.useRef)(null),g=(0,r.useRef)(null),[b,y]=(0,r.useState)(!1),[v,x]=(0,r.useState)(void 0),w=(0,r.useCallback)((()=>Le?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,1426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((e=>{let[{DocSearchModal:t}]=e;Le=t}))),[]),k=(0,r.useCallback)((()=>{w().then((()=>{m.current=document.createElement("div"),document.body.insertBefore(m.current,document.body.firstChild),y(!0)}))}),[w,y]),S=(0,r.useCallback)((()=>{y(!1),m.current?.remove()}),[y]),E=(0,r.useCallback)((e=>{w().then((()=>{y(!0),x(e.key)}))}),[w,y,x]),_=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(a,t)?window.location.href=t:h.push(t)}}).current,C=(0,r.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:l(e.url)}))))).current,T=(0,r.useMemo)((()=>e=>(0,u.jsx)(Oe,{...e,onClose:S})),[S]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:b,onOpen:k,onClose:S,onInput:E,searchButtonRef:g}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(_e.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(Ee,{onTouchStart:w,onFocus:w,onMouseOver:w,onClick:k,ref:g,translations:je.button}),b&&Le&&m.current&&(0,Ne.createPortal)((0,u.jsx)(Le,{onClose:S,initialScrollY:window.scrollY,initialQuery:v,navigator:_,transformItems:C,hitComponent:Pe,transformSearchClient:A,...o.searchPagePath&&{resultsFooterComponent:T},...o,searchParameters:f,placeholder:je.placeholder,translations:je.modal}),m.current)]})}function Ie(){const{siteConfig:e}=(0,le.Z)();return(0,u.jsx)(Re,{...e.themeConfig.algolia})}const Fe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Me(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,a.Z)(n,Fe.navbarSearchContainer),children:t})}var De=n(143),ze=n(2802);var Be=n(373);const $e=e=>e.docs.find((t=>t.id===e.mainDocId));const Ue={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,fe.l)(),{search:f,hash:h}=(0,s.TH)(),m=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${h}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(pe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:me}),g]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Me,{className:n,children:(0,u.jsx)(Ie,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,u.jsx)(i,{className:(0,a.Z)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,De.Iw)(r),i=(0,ze.vY)(t,r),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,De.Iw)(r),i=(0,ze.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,ze.lO)(r)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,u.jsx)(oe,{...a,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:c,hash:d}=(0,s.TH)(),p=(0,De.Iw)(n),f=(0,De.gB)(n),{savePreferredVersionName:h}=(0,Be.J)(n),m=[...a,...f.map((e=>{const t=p.alternateDocVersions[e.name]??$e(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>h(e.name)}})),...o],g=(0,ze.lO)(n)[0],b=t&&m.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,y=t&&m.length>1?void 0:$e(g).path;return m.length<=1?(0,u.jsx)(oe,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(pe,{...i,mobile:t,label:b,to:y,items:m,isActive:r?()=>!1:void 0})}};function Ze(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ue[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(a,{...n})}function He(){const e=(0,N.e)(),t=(0,x.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ze,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ve(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function We(){const e=0===(0,x.L)().navbar.items.length,t=F();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ve,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,N.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(He,{}),secondaryMenu:(0,u.jsx)(We,{})}):null}const Ge={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ke(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.Z)("navbar-sidebar__backdrop",e.className)})}function Ye(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,x.L)(),i=(0,N.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,j.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ge.navbarHideable,!d&&Ge.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ke,{onClick:i.toggle}),(0,u.jsx)(qe,{})]})}var Qe=n(8780);const Xe={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Je(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function et(e){let{error:t}=e;const n=(0,Qe.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Xe.errorBoundaryError,children:n})}class tt extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const nt="right";function rt(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function at(){const{toggle:e,shown:t}=(0,N.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(rt,{})})}const ot={colorModeToggle:"colorModeToggle_DEke"};function it(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(tt,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ze,{...e})},t)))})}function st(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function lt(){const e=(0,N.e)(),t=(0,x.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??nt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,u.jsx)(st,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(at,{}),(0,u.jsx)(G,{}),(0,u.jsx)(it,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(it,{items:r}),(0,u.jsx)(W,{className:ot.colorModeToggle}),!a&&(0,u.jsx)(Me,{children:(0,u.jsx)(Ie,{})})]})})}function ct(){return(0,u.jsx)(Ye,{children:(0,u.jsx)(lt,{})})}function ut(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,s=(0,X.Z)(n),l=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Q.Z,{className:"footer__link-item",...r?{href:o?l:r}:{to:s},...i,children:[a,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function dt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(ut,{item:t})},t.href??t.to)}function pt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(dt,{item:e},t)))})]})}function ft(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(pt,{column:e},t)))})}function ht(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function mt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(ut,{item:t})}function gt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(mt,{item:e}),t.length!==n+1&&(0,u.jsx)(ht,{})]},n)))})})}function bt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ft,{columns:t}):(0,u.jsx)(gt,{links:t})}var yt=n(9965);const vt={footerLogoLink:"footerLogoLink_BH7S"};function xt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(yt.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function wt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Q.Z,{href:t.href,className:vt.footerLogoLink,target:t.target,children:(0,u.jsx)(xt,{logo:t})}):(0,u.jsx)(xt,{logo:t})}function kt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function St(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function Et(){const{footer:e}=(0,x.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(St,{style:a,links:n&&n.length>0&&(0,u.jsx)(bt,{links:n}),logo:r&&(0,u.jsx)(wt,{logo:r}),copyright:t&&(0,u.jsx)(kt,{copyright:t})})}const _t=r.memo(Et),Ct=(0,L.Qc)([D.S,w.pl,j.OC,Be.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(P.n2,{children:(0,u.jsx)(N.M,{children:(0,u.jsx)(R,{children:t})})})}]);function Tt(e){let{children:t}=e;return(0,u.jsx)(Ct,{children:t})}var At=n(7955);function Nt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(At.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Je,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(et,{error:t})})]})})})}const jt={mainWrapper:"mainWrapper_z2l0"};function Lt(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(Tt,{children:[(0,u.jsx)(i.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(ct,{}),(0,u.jsx)("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,jt.mainWrapper,r),children:(0,u.jsx)(o.Z,{fallback:e=>(0,u.jsx)(Nt,{...e}),children:t})}),!n&&(0,u.jsx)(_t,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(9960),a=n(4996),o=n(2263),i=n(6668),s=n(9965),l=n(5893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.Z)(t.src),dark:(0,a.Z)(t.srcDark||t.src)},i=(0,l.jsx)(s.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,o.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,a.Z)(s?.href||"/"),h=n?"":t,m=s?.alt??h;return(0,l.jsxs)(r.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:m,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);var r=n(5742),a=n(5893);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.Z,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),a=n(6010),o=n(2389),i=n(2949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(5893);function c(e){let{className:t,children:n}=e;const c=(0,o.Z)(),{colorMode:u}=(0,i.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:o},e)}))})}function u(e){const{sources:t,className:n,alt:r,...a}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(7294),a=n(412),o=n(469),i=n(1442),s=n(5893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return p(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function h(e){if(!a.Z.canUseDOM)return e?u:d}function m(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:u,style:c?void 0:h(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:l,children:a})}function g(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[l,c]=(0,r.useState)(t);return(0,o.Z)((()=>{t||i(!0)}),[t]),(0,o.Z)((()=>{a&&c(t)}),[a,t]),a?(0,s.jsx)(m,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const r=t?g:m;return(0,s.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>h});var r=n(7294),a=n(2389),o=n(12),i=n(902),s=n(6668),l=n(5893);const c=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function h(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),s=n(6668),l=n(5893);const c=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,h=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{d.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(h(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[a,i])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b,Oh:()=>x});var r=n(7294),a=n(143),o=n(9935),i=n(6668),s=n(2802),l=n(902),c=n(12),u=n(5893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const h=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return(0,u.jsx)(h.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(g,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(h);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function x(){const e=(0,a._r)(),[t]=y();function n(n){const r=e[n],{preferredVersionName:a}=t[n];return r.versions.find((e=>e.name===a))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var r=n(7294),a=n(902),o=n(5893);const i=Symbol("EmptyContext"),s=r.createContext(i);function l(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(s);if(e===i)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var r=n(7294),a=n(902),o=n(5893);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(null===e)throw new a.i6("DocsVersionProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(1980),s=n(6668),l=n(902),c=n(5893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>s});var r=n(7294),a=n(902),o=n(5893);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},6177:(e,t,n)=>{"use strict";n.d(t,{K:()=>s,M:()=>l});var r=n(7294),a=n(2263),o=n(1980);const i="q";function s(){return(0,o.Nc)(i)}function l(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,a.Z)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){const[e,t]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){t(function(){if(!a.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?o.desktop:o.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{LM:()=>f,_F:()=>g,cE:()=>p,SN:()=>E,lO:()=>w,vY:()=>S,oz:()=>k,s1:()=>x,f:()=>y});var r=n(7294),a=n(6550),o=n(8790),i=n(143),s=n(373),l=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),m=(e,t)=>e.some((e=>g(e,t)));function g(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||m(e.items,t))}function b(e,t){switch(e.type){case"category":return g(e,t)||e.items.some((e=>b(e,t)));case"link":return!e.unlisted||g(e,t);default:return!1}}function y(e,t){return(0,r.useMemo)((()=>e.filter((e=>b(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function x(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function k(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function S(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t}=e;const n=(0,a.TH)(),r=(0,l.E)(),i=t.routes,s=i.find((e=>(0,a.LX)(n.pathname,e)));if(!s)return null;const c=s.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,o.H)(i),sidebarName:c,sidebarItems:u}}},2128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(2263);function a(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:a}=t;return e?.trim().length?`${e.trim()} ${a} ${n}`:n}},1980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>l,Rb:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){!function(e){const t=(0,a.k6)(),n=(0,o.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,a.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function l(e){const t=s(e)??"",n=function(){const e=(0,a.k6)();return(0,r.useCallback)(((t,n,r)=>{const a=new URLSearchParams(e.location.search);n?a.set(t,n):a.delete(t),(r?.push?e.push:e.replace)({search:a.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>h});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2128),u=n(5893);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const s=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=a?d(a,{absolute:!0}):void 0;return(0,u.jsxs)(o.Z,{children:[t&&(0,u.jsx)("title",{children:s}),t&&(0,u.jsx)("meta",{property:"og:title",content:s}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),s=(0,a.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:s,children:[(0,u.jsx)(o.Z,{children:(0,u.jsx)("html",{className:s})}),n]})}function h(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,a.Z)(r,o),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>i});var r=n(7294),a=n(469),o=n(5893);function i(e){const t=(0,r.useRef)(e);return(0,a.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,a.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},8022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>c,RF:()=>p});var r=n(7294),a=n(412),o=n(2389),i=(n(469),n(902)),s=n(5893);const l=r.createContext(void 0);function c(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,s.jsx)(l.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const d=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),a=(0,r.useRef)(d()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var r=n(143),a=n(2263),o=n(373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,a.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,a=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(r??a??o).name)}))];return{locale:e.currentLocale,tags:c}}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),a=n(6550),o=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,a.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){const{siteConfig:{themeConfig:e}}=(0,r.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(7294),a=n(8022),o=n(4996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,r.useCallback)((r=>{const o=new URL(r);if((0,a.F)(t,o.href))return r;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>x,q_:()=>C,ob:()=>f,PP:()=>A,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,m(),x.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(x.entries[x.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=x.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var a=f(n);a&&a!==h&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),m=l(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var h=e[i],m=n[2],g=n[3],b=n[4],y=n[5],v=n[6],x=n[7];s&&(r.push(s),s="");var w=null!=m&&null!=h&&h!==m,k="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||u,_=b||y;r.push({name:g||o++,prefix:m||"",delimiter:E,optional:S,repeat:k,partial:w,asterisk:!!x,pattern:_?c(_):x?".*":"[^"+l(E)+"]+?"})}}return i{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),h=p.indexOf(f);if(h>-1){++a;var m=p.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(h+f.length),y=[];m&&y.push.apply(y,i([m])),y.push(g),b&&y.push.apply(y,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(Prism)},2886:()=>{Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant},7251:()=>{Prism.languages.verilog={comment:{pattern:/\/\/.*|\/\*[\s\S]*?\*\//,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"kernel-function":{pattern:/\B\$\w+\b/,alias:"property"},constant:/\B`\w+\b/,function:/\b\w+(?=\()/,keyword:/\b(?:alias|and|assert|assign|assume|automatic|before|begin|bind|bins|binsof|bit|break|buf|bufif0|bufif1|byte|case|casex|casez|cell|chandle|class|clocking|cmos|config|const|constraint|context|continue|cover|covergroup|coverpoint|cross|deassign|default|defparam|design|disable|dist|do|edge|else|end|endcase|endclass|endclocking|endconfig|endfunction|endgenerate|endgroup|endinterface|endmodule|endpackage|endprimitive|endprogram|endproperty|endsequence|endspecify|endtable|endtask|enum|event|expect|export|extends|extern|final|first_match|for|force|foreach|forever|fork|forkjoin|function|generate|genvar|highz0|highz1|if|iff|ifnone|ignore_bins|illegal_bins|import|incdir|include|initial|inout|input|inside|instance|int|integer|interface|intersect|join|join_any|join_none|large|liblist|library|local|localparam|logic|longint|macromodule|matches|medium|modport|module|nand|negedge|new|nmos|nor|noshowcancelled|not|notif0|notif1|null|or|output|package|packed|parameter|pmos|posedge|primitive|priority|program|property|protected|pull0|pull1|pulldown|pullup|pulsestyle_ondetect|pulsestyle_onevent|pure|rand|randc|randcase|randsequence|rcmos|real|realtime|ref|reg|release|repeat|return|rnmos|rpmos|rtran|rtranif0|rtranif1|scalared|sequence|shortint|shortreal|showcancelled|signed|small|solve|specify|specparam|static|string|strong0|strong1|struct|super|supply0|supply1|table|tagged|task|this|throughout|time|timeprecision|timeunit|tran|tranif0|tranif1|tri|tri0|tri1|triand|trior|trireg|type|typedef|union|unique|unsigned|use|uwire|var|vectored|virtual|void|wait|wait_order|wand|weak0|weak1|while|wildcard|wire|with|within|wor|xnor|xor)\b/,important:/\b(?:always|always_comb|always_ff|always_latch)\b(?: *@)?/,number:/\B##?\d+|(?:\b\d+)?'[odbh] ?[\da-fzx_?]+|\b(?:\d*[._])?\d+(?:e[-+]?\d+)?/i,operator:/[-+{}^~%*\/?=!<>&|]+/,punctuation:/[[\];(),.:]/}},4262:(e,t,n)=>{var r={"./prism-java":2503,"./prism-scala":2886,"./prism-verilog":7251};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=4262},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(3840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n