Design Configuration System (hlsfactory.toml)¶
This document describes the hlsfactory.toml design metadata specification, which provides a structured way for HLS designs to declare their supported flows and flow-specific configuration.
Overview¶
Each HLS design in HLSFactory can include an hlsfactory.toml file that serves as a single, authoritative source of metadata. This file enables:
Flow Declaration: Explicitly declare which HLSFactory flows a design supports
Script Configuration: Specify paths to flow-specific scripts (TCL files, etc.)
Design Metadata: Store canonical name, dataset association, tags, and environment variables
Early Validation: Fail fast with clear errors if required configuration is missing
Configuration File Format¶
Basic Structure¶
design_name = "k2mm"
dataset_name = "polybench"
tags = ["linalg", "matrix"]
[env_vars]
CUSTOM_VAR = "value"
[[flow_configs]]
flow_name = "VitisHLSSynthFlow"
synth_tcl = "dataset_hls.tcl"
[[flow_configs]]
flow_name = "VitisHLSImplFlow"
impl_tcl = "dataset_hls_ip_export.tcl"
[[flow_configs]]
flow_name = "OptDSLv2"
opt_dsl_file = "opt_template.tcl"
Required Fields¶
Field |
Type |
Description |
|---|---|---|
|
string |
Canonical name of the design |
|
string |
Name of the parent dataset |
Optional Fields¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
list[string] |
|
Descriptive tags for categorization |
|
table |
|
Environment variables for flow execution |
|
array of tables |
|
Flow-specific configurations |
Supported Flows and Required Settings¶
Each flow type has specific required settings that must be provided:
Flow Name |
Required Setting |
Description |
|---|---|---|
|
|
TCL script for Catapult HLS synthesis |
|
|
Stratus project and module/configuration to synthesize |
|
|
DSLX source file and top-level function to synthesize |
|
|
TCL script for HLS synthesis |
|
|
TCL script for IP export/implementation |
|
|
TCL script for C simulation |
|
|
TCL script for co-simulation setup |
|
|
TCL script for co-simulation |
|
|
Optimization DSL template file |
|
|
Existing Vitis HLS solution directory to simulate |
Flow Configuration Examples¶
# Catapult HLS Synthesis
[[flow_configs]]
flow_name = "CatapultHLSSynthFlow"
synth_tcl = "synth.tcl"
# Cadence Stratus HLS Synthesis
[[flow_configs]]
flow_name = "StratusHLSSynthFlow"
project_tcl = "project.tcl"
hls_module = "fir"
hls_config = "BASIC"
# makefile = "Makefile" # Optional; this is the default.
# Google XLS HLS Synthesis
[[flow_configs]]
flow_name = "XLSHLSSynthFlow"
dslx_file = "adder.x"
top = "add"
# generator = "pipeline" # Optional; this is the default.
# pipeline_stages = "1" # Optional; pipeline generator only.
# delay_model = "unit" # Optional; pipeline generator only.
# reset = "rst" # Optional reset port; required by stateful procs.
# Vitis HLS Synthesis
[[flow_configs]]
flow_name = "VitisHLSSynthFlow"
synth_tcl = "dataset_hls.tcl"
# Vitis HLS Implementation (IP Export + Vivado)
[[flow_configs]]
flow_name = "VitisHLSImplFlow"
impl_tcl = "dataset_hls_ip_export.tcl"
# C Simulation
[[flow_configs]]
flow_name = "VitisHLSCsimFlow"
csim_tcl = "dataset_hls_csim.tcl"
# Co-Simulation Setup
[[flow_configs]]
flow_name = "VitisHLSCosimSetupFlow"
cosim_setup_tcl = "dataset_hls_cosim_setup.tcl"
# Co-Simulation
[[flow_configs]]
flow_name = "VitisHLSCosimFlow"
cosim_tcl = "dataset_hls_cosim.tcl"
# Optimization DSL Frontend
[[flow_configs]]
flow_name = "OptDSLv2"
opt_dsl_file = "opt_template.tcl"
# LightningSim
[[flow_configs]]
flow_name = "LightningSimFlow"
solution_dir_name = "hls_k2mm/solution1"
XLS Flow Settings¶
Setting |
Required |
Default |
Description |
|---|---|---|---|
|
Yes |
— |
DSLX source file relative to the design directory |
|
Yes |
— |
Top-level DSLX function or proc |
|
No |
|
|
|
No |
|
Positive stage count used by the pipeline generator |
|
No |
|
XLS scheduling delay model used by the pipeline generator |
|
No |
unset |
Reset port name for pipeline codegen; required by the packaged stateful proc examples |
|
No |
|
Write an IR snapshot after every optimizer pass |
|
No |
|
Write an IR snapshot after every scheduling/codegen pass |
|
No |
|
Write optimizer and codegen pprof pass profiles |
pipeline_stages controls scheduler partitioning, but it is not necessarily the
same as externally visible latency because XLS may add input and output
registers. Read latency_cycles from the generated data_hls.json for the
module-signature value. Combinational signatures do not express cycle latency
or initiation interval, so those JSON fields are null for combinational
designs.
The three diagnostic switches are string-valued booleans because all flow
settings are strings. Accepted true values are true, yes, on, and 1;
accepted false values are false, no, off, and 0. IR dumps can create
hundreds of files per design and are disabled by default.
Python API¶
Reading and Writing Configs¶
from pathlib import Path
from hlsfactory.design_config import (
DesignConfig,
FlowConfig,
FlowName,
read_design_config,
write_design_config,
)
# Read a config file
config = read_design_config(Path("design_dir/hlsfactory.toml"))
# Access design metadata
print(config.design_name) # "k2mm"
print(config.dataset_name) # "polybench"
print(config.tags) # ["linalg"]
# Check flow support
if config.supports_flow("VitisHLSSynthFlow"):
synth_tcl = config.require_flow_setting(
FlowName.VITIS_HLS_SYNTH, "synth_tcl"
)
print(f"Synthesis TCL: {synth_tcl}")
# Get flow config object
flow_config = config.get_flow_config("VitisHLSSynthFlow")
if flow_config:
print(flow_config.flow_settings)
# Create and write a new config
new_config = DesignConfig(
design_name="my_design",
dataset_name="my_dataset",
tags=["example"],
flow_configs=[
FlowConfig(
flow_name=FlowName.VITIS_HLS_SYNTH.value,
flow_settings={"synth_tcl": "run_synth.tcl"},
),
],
)
write_design_config(Path("output/hlsfactory.toml"), new_config)
Design and DesignDataset Integration¶
from hlsfactory.framework import Design, DesignDataset
# Load a single design with its config
design = Design.from_dir_with_config(Path("path/to/design"))
print(design.config.design_name)
# Access config from design (raises if not loaded)
config = design.require_config()
synth_tcl = config.require_flow_setting("VitisHLSSynthFlow", "synth_tcl")
# Load a dataset with automatic config loading (default behavior)
dataset = DesignDataset.from_dir("polybench", Path("path/to/dataset"))
for design in dataset.designs:
print(f"{design.name}: {design.config.flow_names}")
# Load without requiring configs (for migration/compatibility)
dataset = DesignDataset.from_dir(
"polybench",
Path("path/to/dataset"),
require_config=False
)
Using Config in Custom Flows¶
from hlsfactory.framework import Design, ToolFlow
from hlsfactory.design_config import FlowName
class MyCustomFlow(ToolFlow):
name = "MyCustomFlow"
def execute(self, design: Design, timeout: float | None = None) -> list[Design]:
# Get config from design
config = design.require_config()
# Get flow-specific settings
my_script = config.require_flow_setting("MyCustomFlow", "script_path")
# Optional settings with defaults
optional_param = config.get_flow_setting(
"MyCustomFlow", "optional_param", default="default_value"
)
# Execute flow logic...
return [design]
Data Classes¶
DesignConfig¶
The main configuration class representing an hlsfactory.toml file.
Attributes:
design_name: str- Design identifier (required)dataset_name: str- Parent dataset name (required)tags: list[str]- Descriptive tags (optional)env_vars: dict[str, str]- Environment variables (optional)flow_configs: list[FlowConfig]- Flow configurations (optional)
Methods:
supports_flow(flow_name)- Check if design supports a flowget_flow_config(flow_name)- Get FlowConfig or Nonerequire_flow_config(flow_name)- Get FlowConfig or raise errorget_flow_setting(flow_name, setting, default=None)- Get setting valuerequire_flow_setting(flow_name, setting)- Get setting or raise errorflow_names- Property returning tuple of all flow names
FlowConfig¶
Configuration for a single flow.
Attributes:
flow_name: str- Name of the flowflow_settings: dict[str, str]- Flow-specific key-value settings
Methods:
has_setting(key)- Check if setting existsget_setting(key, default=None)- Get setting valuerequire_setting(key)- Get setting or raise erroris_known_flow- Property indicating if flow is in FlowName enumrequired_settings- Property returning required settings for this flow type
FlowName Enum¶
Enumeration of known flow names:
class FlowName(StrEnum):
OPT_DSL_V2 = "OptDSLv2"
CATAPULT_HLS_SYNTH = "CatapultHLSSynthFlow"
STRATUS_HLS_SYNTH = "StratusHLSSynthFlow"
XLS_HLS_SYNTH = "XLSHLSSynthFlow"
VITIS_HLS_SYNTH = "VitisHLSSynthFlow"
VITIS_HLS_CSIM = "VitisHLSCsimFlow"
VITIS_HLS_IMPL = "VitisHLSImplFlow"
VITIS_HLS_COSIM = "VitisHLSCosimFlow"
VITIS_HLS_COSIM_SETUP = "VitisHLSCosimSetupFlow"
VITIS_HLS_IMPL_REPORT = "VitisHLSImplReportFlow"
LIGHTNING_SIM = "LightningSimFlow"
Migration Script¶
A CLI tool is provided to generate hlsfactory.toml files for existing designs.
Usage¶
# Preview what would be created (recommended first step)
uv run python -m hlsfactory.scripts.generate_design_configs --dry-run
# Preview with verbose output showing each design
uv run python -m hlsfactory.scripts.generate_design_configs --dry-run --verbose
# Generate configs for all designs
uv run python -m hlsfactory.scripts.generate_design_configs
# Generate configs for a specific dataset only
uv run python -m hlsfactory.scripts.generate_design_configs --dataset polybench
# Generate configs for a specific dataset with preview
uv run python -m hlsfactory.scripts.generate_design_configs \
--dataset machsuite --dry-run
TCL File Detection¶
The migration script automatically detects existing TCL files:
Detected File |
Flow |
Setting |
|---|---|---|
|
VitisHLSSynthFlow |
|
|
VitisHLSImplFlow |
|
|
VitisHLSCsimFlow |
|
|
VitisHLSCosimSetupFlow |
|
|
VitisHLSCosimFlow |
|
|
OptDSLv2 |
|
Error Handling¶
DesignConfigError¶
Raised for configuration-level errors:
Missing required fields (
design_name,dataset_name)Invalid field types
Duplicate flow configurations
Missing config file when required
FlowConfigError¶
Raised for flow configuration errors:
Missing required flow settings
Invalid flow setting types
Empty flow name
Example Error Messages¶
DesignConfigError: Required config file hlsfactory.toml not found in /path/to/design
DesignConfigError: Design 'my_design' at /path has no loaded configuration.
Ensure hlsfactory.toml exists and was loaded.
FlowConfigError: Flow `VitisHLSSynthFlow` is missing required setting(s): synth_tcl.
Directory Structure¶
design_directory/
├── hlsfactory.toml # Design configuration (required)
├── dataset_hls.tcl # Synthesis script
├── dataset_hls_ip_export.tcl # Implementation script
├── opt_template.tcl # OptDSL template
├── hls_template.tcl # HLS project template
└── src/
├── kernel.cpp
└── kernel.h
Best Practices¶
Always include
hlsfactory.toml- All designs should have a config fileUse descriptive tags - Help categorize designs by domain, features, etc.
Validate with dry-run - Use
--dry-runbefore generating configsKeep TCL names consistent - Follow naming conventions for easy migration
Check flow support - Use
supports_flow()before accessing flow settings
Extending the System¶
Adding a New Flow Type¶
Add the flow name to
FlowNameenum indesign_config.py:class FlowName(StrEnum): MY_NEW_FLOW = "MyNewFlow"
Add required settings to
_REQUIRED_SETTINGSinFlowConfig:_REQUIRED_SETTINGS = { FlowName.MY_NEW_FLOW.value: frozenset({"my_script"}), }
Update flow implementation to read from config:
def execute(self, design: Design, timeout=None): config = design.require_config() my_script = config.require_flow_setting("MyNewFlow", "my_script") # ...
Update migration script if needed (
TCL_PATTERNSdict)
File References¶
File |
Purpose |
|---|---|
|
Core config classes and parsing |
|
Design/DesignDataset integration |
|
Siemens Catapult synthesis and report parsing |
|
Google XLS DSLX-to-Verilog synthesis and metrics parsing |
|
Vitis flow implementations |
|
OptDSL frontend implementation |
|
Migration CLI tool |
|
Test suite for config system |