From dedaf5aeb52ad3e46c93c3041dec0068d21739aa Mon Sep 17 00:00:00 2001 From: Nandor Licker Date: Tue, 28 Nov 2023 11:13:56 +0200 Subject: [PATCH] Define option groups and instance choices --- include/firrtl.xml | 4 +++ revision-history.yaml | 1 + spec.md | 58 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/include/firrtl.xml b/include/firrtl.xml index 2b0248d3..3059cf93 100644 --- a/include/firrtl.xml +++ b/include/firrtl.xml @@ -7,8 +7,10 @@ extmodule intmodule layer + option + default input type output @@ -27,6 +29,8 @@ intrinsic propassign public + inst_choice + case UInt diff --git a/revision-history.yaml b/revision-history.yaml index 053aded3..7c7bc39c 100644 --- a/revision-history.yaml +++ b/revision-history.yaml @@ -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. diff --git a/spec.md b/spec.md index d5b439da..2cfcf130 100644 --- a/spec.md +++ b/spec.md @@ -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. @@ -516,6 +539,38 @@ 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. @@ -3512,11 +3567,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 ]