A is a mutable object passed between the circuits that form a complete Hardcaml design It performs a number of roles Track the current position within a design hierarchy Control how we elaborate a design Provide a means to generate hierarchy aware names Record sub circuits within a database Capture side band data such as properties and assertions We will shortly learn how to generate hierarchical designs in Hardcaml and s play a key role in that Creating Scopes s take a few interesting arguments which control how a design is elaborated if the entire circuit is flattened or inlined If it will retain hierarchy a useful option when using the Hardcaml waveform viewer that allows it to show the hierarchical structure of a design control how names are generated The defaults are set up to work with the value of but can be overridden Flattening a Design By default s set to This is generally what you want when generating RTL For simulation this wont work our simulators do not support hierarchical designs so this argument should be set to Sub scopes A new sub scope can be created from a scope This is how we record a design hierarchy Sub scopes are just s placed at the appropriate point in the hierarchy Naming signals with Scopes We can define a scope aware naming function with And this is what we should do within hierarchical Hardcaml designs Note that name of is aware of its position within Using Scopes The main thing we need to do is pass a scope argument to every function we define Sub scopes are then created when we create other circuits This is how they track the current hierarchy position However you shouldn t really ever need to actually do anything much with scopes except Create them with set to true or false depending on whether you want to generate RTL or run a simulation Pass them to your create functions Scope t Scope # let scope Scope create val scope Scope t <abstr> Scope flatten_design true false auto_label_hierarchical_ports naming_scheme flatten_design Scope flatten_design false true # let scope Scope create flatten_design true auto_label_hierarchical_ports true val scope Scope t <abstr> let scope Scope sub_scope scope foo Scope # let Scope naming scope val loc %call_pos > Signal t > string > Signal t <fun> # let x Signal of_string 0 x val x Signal t const names foo$x width 1 value 0b0 x foo create let create scope Scope t i _ I t let foo Foo create Scope sub_scope scope foo in flatten_design