Configurations¶
Real projects rarely have a single build. You need a debug build and a
release build; you switch between simulator vendors; you target different
platforms; you run a quick smoke test or a full regression. Configurations
let you capture these variants in one package – selecting them at run time with
-c – instead of duplicating the flow or hand-editing parameters.
A configuration is a named overlay on the base package: it can set parameter values, override tasks, inject new tasks into existing ones, extend tasks, and add imports, fragments, types, or tasks – all without touching the base definition.
dfm run build # default
dfm run build -c debug # the 'debug' variant
dfm run build -c release # the 'release' variant
Defining a Configuration¶
Configurations are declared in the package’s configs field. Each entry
adjusts the base package for one variant:
package:
name: my_project
with:
debug:
type: bool
value: false
tasks:
- name: build
uses: std.Message
with:
msg: "Building in default mode"
configs:
- name: debug
with:
debug:
value: true
tasks:
- name: build
override: build
with:
msg: "Building in debug mode"
- name: release
with:
debug:
value: false
overrides:
- override: hdlsim
with: hdlsim.xcelium
A configuration can specify:
with – parameter values for this configuration.
uses – a base configuration to inherit from (see Inheriting Configurations).
overrides – package/parameter overrides.
extensions – task extensions (see Modifying Tasks with Extensions).
tasks – additional or overriding tasks (including tasks that inject data via
feeds– see Injecting Options with feeds).types – additional or overriding types.
imports / fragments – additional imports or fragments for this configuration.
Selecting a Configuration¶
Choose a configuration on the command line with -c / --config:
dfm run build -c debug
When a configuration is selected, the merged definition is built in this order:
The base package is loaded.
Configuration parameters override package parameters.
Configuration overrides are applied.
Configuration tasks, types, imports, and fragments are merged.
The task graph is built from the merged definition.
Configuration values participate in the normal parameter resolution
order, and command-line -D overrides still take precedence
over the selected configuration.
Inheriting Configurations¶
A configuration can build on another with uses. This lets you layer
variants – for example a debug configuration that starts from a shared
instrumented base:
configs:
- name: instrumented
with:
trace:
type: bool
value: true
- name: debug
uses: instrumented
with:
opt_level:
value: 0
debug inherits everything from instrumented (here, trace: true) and
adds its own settings.
Injecting Options with feeds¶
A configuration often needs to add arguments, options, or data files to tasks
that are defined elsewhere (in the base package or an imported package). The
cleanest way to do this is the feeds field: a config adds a new task whose
output is injected into an existing task, without modifying that task’s
definition.
feeds is the inverse of needs – where needs names a task’s
dependencies, feeds declares “my output is an input to that task.” Expressed
from a config, it connects a config-specific task into the base flow:
package:
name: my_project
tasks:
- root: build
uses: sim.SimImage
needs: [rtl, tb]
with:
top: [tb_top]
- root: run
uses: sim.SimRun
needs: [build]
configs:
- name: debug
tasks:
- name: debug_compile_args
uses: hdlsim.SimCompileArgs
with:
args: ["-debug_access+all"]
feeds: [my_project.build]
- name: debug_run_args
uses: hdlsim.SimRunArgs
with:
args: ["-gui"]
feeds: [my_project.run]
With -c debug, the build task additionally receives the
-debug_access+all compile arguments and run receives -gui – yet
neither build nor run was edited.
Key points:
feedsinjects data “from the side” into a task without changing its definition.The feed target is a fully-qualified task name (
package_name.task_name).It is equivalent to adding the feeding task to the target’s
needslist, but expressed from the producer’s perspective.This keeps the base flow clean: the configuration only adds tasks that connect to existing ones, which is easy to read and maintain.
Use feeds (inject from the side) when you want to add inputs/options to a
task; use overrides or extensions when you need to change a task’s own
parameters or base.
Modifying Tasks with Extensions¶
Where feeds adds a new upstream input, an extension modifies an existing
task in place – adding parameters, dependencies, or changing its base – without
replacing the whole task. Extensions are typically defined inside a
configuration and are especially useful for augmenting tasks from imported
packages.
package:
name: my_project
imports:
- hdlsim.vlt
configs:
- name: coverage
extensions:
- task: hdlsim.vlt.SimImage
with:
coverage:
type: bool
value: true
needs:
- coverage_setup
The extension above adds a coverage parameter and an extra dependency to the
imported hdlsim.vlt.SimImage task.
Extensions can:
Add parameters – introduce new options on the task.
Add dependencies – include additional
needs.Change the base – specify a different
usesbase task.
Extensions can themselves inherit from other extensions with uses, letting
you build up instrumentation incrementally:
configs:
- name: base_instrumentation
extensions:
- task: my_tool.Compile
with:
verbose:
type: bool
value: false
- name: debug_instrumentation
uses: base_instrumentation
extensions:
- task: my_tool.Compile
uses: base_instrumentation.my_tool.Compile
with:
verbose:
value: true
trace:
type: bool
value: true
Per-Configuration Imports¶
An import can itself select a configuration of the imported package via the
config key, so a variant can propagate down the dependency tree:
imports:
- name: hdlsim.vlt
config: gui
What Configurations Enable¶
Build variants – debug, release, profiling builds.
Tool selection – switch between simulator/tool vendors.
Target platforms – customize for different deployment targets.
Test modes – normal vs. regression vs. continuous integration.
See Also¶
Parameters and Configuration – parameter declarations, overrides, and resolution order.
Packages – the package namespace that hosts configurations.
Running Flows – selecting a configuration with
-cat run time.