Skip to content

Commit

Permalink
Define option groups and instance choices
Browse files Browse the repository at this point in the history
  • Loading branch information
nandor committed Nov 28, 2023
1 parent dcd6318 commit 50ac363
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/firrtl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
<item>extmodule</item>
<item>intmodule</item>
<item>layer</item>
<item>option</item>
</list>
<list name="keywords">
<item>default</item>
<item>input</item>
<item>type</item>
<item>output</item>
Expand All @@ -27,6 +29,8 @@
<item>intrinsic</item>
<item>propassign</item>
<item>public</item>
<item>inst_choice</item>
<item>case</item>
</list>
<list name="types">
<item>UInt</item>
Expand Down
1 change: 1 addition & 0 deletions revision-history.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ revisionHistory:
- Add section "Circuit Components".
- Reorganized statements section.
- Rewrite of the Types section.
- Add options and instance choices.
abi:
- Add ABI for public modules and filelist output.
- Changed ABI for group and ref generated files.
Expand Down
63 changes: 63 additions & 0 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,29 @@ circuit:
Layer blocks will be compiled to modules whose ports are derived from what they capture from their visible scope.
For full details of the way layers are compiled, see the FIRRTL ABI specification.

## Options

The option mechanism declares configurable parameters with a pre-defined set of values.
Options are primarily intended to enable target-specific (ASIC or FPGA) lowerings, but they can also be used specify parameters which are present in the output and can be selected after emission (for example, to tweak a design for size or performance).
Specialization can occur either in the compiler or in the output via the ABI. For full details, consult the FIRRTL ABI.

The `option`{.firrtl} keyword declares an option group, which contains `case`{.firrtl} declarations naming the settings allotted to that option.
The circuit can be specialized for a single case of a given option at any time. Multiple option groups can be declared to capture orthogonal dimensions of configuration.
Constructs that rely on options assume an implicit default, which is selected when no specific case is specified.

``` firrtl
circuit:
option Platform:
case FPGA:
case ASIC:
option Performance:
case Slow:
case Fast
```

Statements and declarations which are configurable, `inst_choice`{.firrtl} for example, refer to option declarations to map custom behaviour to specific cases.

## Externally Defined Modules

Externally defined modules are modules whose implementation is not provided in the current circuit.
Expand Down Expand Up @@ -516,6 +539,37 @@ The type of the submodule instance `passthrough`{.firrtl} above is thus:
{ flip in : UInt<8>, out : UInt<8> }
```

#### Instance Choices

FIRRTL supports the specialization of designs by allowing instances to target a module chosen based on an `option`{.firrtl}.

Example:

``` firrtl
circuit:
option Platform:
case FPGA:
case ASIC:
module InstanceChoice:
inst_choice clock_gate option Platform
when FPGA FPGATarget default DefaultTarget
module DefaultTarget:
module FPGATarget:
```

The instance choice declaration specifies the instance name and names the option group based on which the choices are selected.
It introduces mappings with the `when`{.firrtl} keyword, attaching a module to a specific case allowed by the option group.
A default option must always be provided, to be implicitly used when no specialisation is requested at any stage.
The mapping does not need to be exhaustive, cases can be left unspecified, resorting to the default mapping.
Only modules or extmodules can be targeted.

Probes or properties are not allowed on modules which are part of instance choices.
The type of the instance bundle is determined identically to regular instances.
The port lists of all modules must match.

### Memories

Memories are stateful elements of a design.
Expand Down Expand Up @@ -3462,6 +3516,7 @@ decl =
| decl_extmodule
| decl_intmodule
| decl_layer
| decl_option
| decl_type_alias ;
decl_module =
Expand Down Expand Up @@ -3491,6 +3546,11 @@ decl_layer =
{ decl_layer , newline } ,
dedent ;
decl_option =
"option" , id , ":" , [info] , newline, indent ,
{ "case" , id , ":" , [ info ] , newline } ,
dedent ;
decl_type_alias = "type", id, "=", type ;
port = ( "input" | "output" ) , id , ":" , (type | type_property) , [ info ] ;
Expand All @@ -3512,11 +3572,14 @@ circuit_component =
| circuit_component_wire
| circuit_component_reg
| circuit_component_inst
| circuit_component_inst_choice
| circuit_component_mem ;
circuit_component_node = "node" , id , "=" , expr , [ info ] ;
circuit_component_wire = "wire" , id , ":" , type , [ info ] ;
circuit_component_inst = "inst" , id , "of" , id , [ info ] ;
circuit_component_inst_choice =
"inst_choice" , id , "option" , id , { "when" , id , id } , "default" , id ;
conditional_reg =
"reg" , id , ":" , type , expr , [ info ]
Expand Down

0 comments on commit 50ac363

Please sign in to comment.