Back to Blog

A Practical Guide to Hardware Design Space Exploration

In our previous post, we used 128 synthesis points to compare two pipeline design spaces. That post focused on what the measurements revealed. This continuation explains why the tools behind the experiment fit together.

At first, a sweep can look like a loop over PIPELINE_STAGES. A useful experiment needs a stronger boundary. Each parameter value must become a concrete implementation under the same conditions. Otherwise, the results are not comparable.

Our flow gives each layer one responsibility. Hydra describes the design space. FuseSoC materializes each implementation. OpenROAD measures the result. The complete example is now public in hardmatrix-examples.

Hydra configurations resolved by FuseSoC into OpenROAD implementation runs

Why Hydra fits hardware design exploration

A hardware parameter rarely stands alone. Pipeline depth is the value we change in this experiment, but every point also has a fixed implementation context. Hydra lets us describe both parts in one hierarchical configuration.

This is more useful than hiding the experiment inside a shell loop. A loop can iterate over stage counts, but it does not naturally describe the full job. Hydra treats that job as data. The value being swept and the context around it remain visible together.

The public arx.yaml configuration in hardmatrix-examples starts a sweep of 64 points with one command:

$ uv run hydra-sweep \
  --config \
  tools/hydra-sweeps/area-timing/arx.yaml -m \
  'parameters.PIPELINE_STAGES=range(1,65)'

Hydra resolves a complete configuration for every stage count. Command line overrides remain explicit, while the YAML file stays the source of truth for the experiment. Adding another design dimension changes the configuration rather than the orchestration model.

Hydra does not need to understand SystemVerilog or synthesis. That separation is one of its strengths. It defines which implementation should exist, then passes that resolved request to the hardware build system.

FuseSoC turns a configuration into a design

Hydra produces parameter values, not an implementation. It does not know which source files form a core or which constraints belong to the selected target. FuseSoC owns that boundary.

The fusesoc core file in hardmatrix-examples describes the SystemVerilog blocks and declares PIPELINE_STAGES as a parameter. It also defines a dedicated OpenROAD target for each datapath. The target binds the selected core to its timing constraint.

FuseSoC first resolves the dependency graph. It then materializes the required sources in a dedicated build root. The target selects the top level and the implementation flow. Every Hydra point therefore crosses the same design boundary.

This is where FuseSoC adds more value than a command launcher. The core file is a reusable description of the design. A simulation target can use that same core, while an implementation target can attach different constraints. Both targets keep their intent in metadata stored in version control.

The boundary also makes the experiment portable. Moving the sweep to another core means adding an appropriate target and selecting it from Hydra. We do not need to rewrite the orchestration logic or teach Hydra how hardware sources are organized.

OpenROAD turns each point into evidence

FuseSoC gives every point the same implementation contract. OpenROAD Flow Scripts then applies that contract to a technology platform. In this experiment, every point uses the open ASAP7 platform and the same timing constraint.

The important transition happens here. A pipeline depth stops being only an architectural idea and becomes a mapped implementation. OpenROAD reports how that implementation behaves under the selected target. Area and timing can then be compared across the design space.

We intentionally use the synthesis reporting stage for this experiment. The results are early implementation estimates, not signoff results or completed physical designs. That scope is sufficient for the question raised in the previous post: which pipeline depths deserve further engineering work?

The value does not come from parsing a particular report format. It comes from running each point through the same implementation context. OpenROAD provides the evidence, while Hydra and FuseSoC make the comparison reproducible.

How fusesoc-openroad bridges FuseSoC and OpenROAD

FuseSoC delegates EDA tool integration to Edalize. Edalize already has an OpenROAD backend in its legacy API, but it does not yet provide an OpenROAD tool in the Flow API. We created fusesoc-openroad to fill that gap. The plugin lets FuseSoC select OpenROAD from Edalize's generic flow and translates the resolved design into the input expected by OpenROAD Flow Scripts.

Using the Flow API keeps the integration composable. A frontend such as fusesoc-chisel can generate the SystemVerilog before the same OpenROAD tool node runs. A design that already contains SystemVerilog can enter that node directly. The OpenROAD boundary does not need to change.

The current fusesoc-openroad repository is the working implementation and lets us validate the interface in real projects. Our next step is to prepare a pull request to Edalize with this Flow API backend.

Keep the boundaries reusable

Hydra owns the experiment definition. FuseSoC owns the design description. OpenROAD owns the implementation measurement. fusesoc-openroad connects the last two through the Edalize Flow API.

The same structure could move above RTL. Hydra could select Chisel generator options that define an entire architecture before SystemVerilog exists, rather than varying one RTL parameter. FuseSoC and OpenROAD would then evaluate each generated design through the same boundary.

That separation turns a single sweep into an engineering workflow. A new question begins with a Hydra configuration and a FuseSoC target. OpenROAD then provides comparable evidence for the implementations that those two layers define.