/adoption
For a hardware team
Would this help a company that develops its own hardware? Where it helps, where it does not, how it would be deployed and what it would need next.
The short answer
As it stands, this is a narrow, verified and budgeted tool for one kind of block, not a general hardware assistant. Its strongest parts for a team are the method around the LLM: numbers that come only from tested code, checks at every level of the ladder, and an evaluation that scores the agent against plain optimisers on the exact answer. The LLM's own measured contribution is modest. A general-purpose coding agent is far more flexible but gives none of those guarantees by itself. The pattern this page recommends is the two together, the general agent as the front end and this graph as a tool it calls: a proposal, not something built.
Where it helps
- Numbers come from code, and every one is labelled. The LLM chooses families and ranges and decides what to do next; deterministic code produces every number, labelled exact estimate measured or simulated. The LLM's structured-output schemas have no field where a number about a design could go. Results are therefore auditable and repeatable in a way that an agent's prose is not. (evidence: README, the design principle) (evidence: schemas.py)
- Verification is built in at every level. A bit-exact golden model; generated RTL checked against it in two simulators (Verilator and Icarus) and with formal proofs; gate-level simulation of the synthesised netlist; measured results fed back into the cost model. (evidence: how it works, the ladder)
- An open-weights model gave useful results. Qwen3.8-27B with reasoning off, in M2: selection regret 4.0% on
dds_250mspsand 3.7% onlow_area_controlagainst NSGA-II's 12.9% and 7.5%, though worse onhigh_precision(17.5% against 10.3%), at $0.036 per spec. That makes a fully on-premises setup plausible, where RTL and specs never leave the company. What was actually run: the model through OpenRouter, a hosted API. On-premises would need the weights served locally; the code has anollamaprovider for that, but no recorded run used it. (evidence: results, M2 tables) (evidence: llm.py providers) - Cost is low and measured. Per spec in M2: $0.036 (Qwen, reasoning off) to $0.32 (Sonnet 5.5), provider-reported. At M4's measured rate, one Qwen graph running back to back would cover about 1,513 specs a day for $13.64: a projection from measured runs, not a run. (evidence: results, throughput)
- People stay in charge, and runs survive. Two
interrupt()gates: an engineer confirms the spec and picks the design. Every step is checkpointed (SQLite), so a paused or crashed run resumes. A fleet of graphs runs unattended, coordinated by code, not by an LLM. (evidence: graph.py) (evidence: cli.py, resume) - An honest evaluation method a team can reuse. The agent is scored against NSGA-II and random search on the same budget, against the exhaustive ground truth, with paired tests and the losses published. The same method answers the question a team should ask first: does an LLM earn its place here at all? (evidence: the write-up)
Where it does not, and its limits
- The LLM's measured contribution is modest. It is a better selector, not a better mapper: in M2 it picked better designs than NSGA-II in 8 of 9 model/spec cells, but mapping the trade-off curve was fixed by code (a front-mapping reserve), not by the model. M3's free-form campaign agent gained nothing at 1.44–2.25× the cost, and M4's fleet mapped less of the curve than one graph (higher hypervolume in 18 of 55 pairs, p = 0.014). (evidence: results, losses first)
- Narrow. One IP block, four families from a fixed registry. A new block needs its own golden model, RTL generator, cost model and calibration: real engineering for each one. (evidence: README, the design space)
- The cost models are estimates, with stated errors. FPGA Fmax is off by up to 17.0% against Vivado; the ASIC model's Fmax is off by up to +39.6% on a held-out design. There is no ASIC place and route (everything is post-synthesis), and no model sees routing: the FPGA winner of
high_precisionloses 17% of its clock to it. (evidence: results, the Vivado runs) - Open-source and single-vendor flows only. Yosys/nextpnr, Vivado on one machine, Yosys/OpenSTA on sky130. No commercial ASIC flow is wired in, and FPGA power is Vivado's vectorless estimate, not switching activity. (evidence: README, limitations)
- Provider drift is real and measured. Qwen on
low_area_control, through a graph that replays its M2 runs identically, had 3.7% mean regret in M2 and 22.8% in an M4 session. Arms are compared only within one session. (evidence: the write-up, limitations)
Against a general-purpose agent
It trades flexibility for trust. A general-purpose agent, such as a coding agent working across a repository and a toolchain, can write RTL and drive tools ad hoc on any block; this graph does one job with guarantees. The two are complements, described here by capability, not by benchmark.
| Aspect | This graph | A general-purpose agent alone | Both together proposal |
|---|---|---|---|
| Scope | One IP block (CORDIC sin/cos), four architecture families from a fixed registry, two targets (Artix-7, sky130). | Any block and any language: it can read a datasheet, write new RTL and drive whatever tools it is given. | The general agent writes a new block's golden model, generator and cost model; the graph explores it. |
| Where numbers come from | Tested code, each number labelled exact, estimate, measured or simulated; the LLM's schemas have no field for one. | From the tools it chooses to run; its own text can restate, round or misremember them. | Numbers about designs only ever come from the graph. |
| Verification | At every level: golden model, two RTL simulators, formal proofs, gate-level simulation, measured back-annotation. | As good as the tests it writes and runs, run by run. | The graph's checks gate whatever the agent generates. |
| Evaluation | A/B against NSGA-II and random search, scored on the exhaustive ground truth, losses published. | No built-in ground truth to score it against. | The same A/B decides whether the LLM earns its place. |
| Cost and budget | Measured per run and per spec; evaluation budgets and round caps enforced in code. | Open-ended sessions; cost depends on the task. | The agent calls a budgeted tool, not an open loop. |
| Repeatability | Checkpointed and replayable: all 60 M2 runs replay identically. | A free-form session is hard to replay exactly. | Replays and traces stay with the graph. |
| A new kind of block | Real engineering per block: golden model, generator, cost model, calibration. | Can start at once. | The agent does the per-block work; people review it. |
The recommended pattern proposal: expose the graph as a tool, for example run_dse(spec) over the Model Context Protocol, with its budget, its gates and its labelled report. The general-purpose agent turns an engineer's request into a spec, calls the tool, reads the report, and writes the new families, generators and cost models the graph does not yet have, which the graph's checks then verify.
How it would be deployed proposal
A container next to the company's EDA farm. Jobs go to the farm's existing scheduler (Slurm or LSF) and draw licences from its licence server. The LLM is an open-weights model on an on-prem server (vLLM or Ollama), or an enterprise API under the company's data terms. The step-through below marks what exists today.
Loading the animation…
| Part | In the repository today | Proposed for a team |
|---|---|---|
| Triggering | the CLI, hw-dse run / hw-dse resume | a spec change on a pull request starts a run; the report lands on the PR |
| Front end | none (the CLI) | a general-purpose agent calling run_dse as an MCP tool |
| LLM | providers for hosted APIs and Ollama; recorded runs via OpenRouter | open weights on an on-prem server (vLLM or Ollama), or an enterprise API |
| State | a SQLite checkpointer per run; an in-memory LangGraph Store for a fleet | Postgres for the checkpointer and a shared Store |
| Human approval | two interrupt() gates, answered in the CLI | the same gates in a web UI or chat |
| Tools | Verilator, Icarus, SymbiYosys, Yosys, nextpnr, OpenSTA; Vivado on one machine | jobs on the farm's scheduler, licences from its licence server; commercial flows behind adapters |
| Budgets and audit | evaluation budgets and round caps in code; the eval harness stops before a spend cap; every LLM call traced, keys redacted | secrets in a vault; trace logs in the company's log store |
| Drift | measured, arms compared within a session | model snapshots pinned; a reference set re-run each session |
How it could be improved
Done after M4
The local Vivado run: high_precision's m=8 misses 50 MSPS at its own 20 ns clock (49.88 post-synthesis, 48.31 post-route), so m=6 stays; the per-family-class path factor was rejected by its pre-set rule; the first measured FPGA power (vectorless) ranks designs as the index does (Spearman 0.982) but is off by 20.6% RMS. (evidence: results)
Next, in the repository's own words
- A routed timing scale and real switching activity on the FPGA. The local Vivado runs are done:
high_precisionmisses 50 MSPS at its own 20 ns clock with m=8 (49.88 MSPS post-synthesis, 48.31 post-route), so the per-family-class path factor, which predicted it feasible (52.5), was rejected by its pre-set rule even though it cut Vivado Fmax leave-one-out from 12.5% to 7.4%. The winner m=6 loses 17% to routing (65.39 → 53.96 MSPS), which no model here sees, and the measured power is vectorless. Next: a post-route timing calibration of its own, and power from simulated switching activity. - Place and route on sky130 (OpenROAD, from its prebuilt release packages pinned by URL and SHA-256, or a container image pinned by digest) for the held-out designs, to see whether the ASIC model's Fmax error is the wire-load model or the structure.
- An ASIC measure-and-re-explore loop: synthesise the selected designs, re-select under the measured numbers, as the FPGA path's L5 loop does. Then decide whether to refit with an
unrolled_kchain term, disclosed, keeping the held-out points held out. - Multi-lane and polyphase families, so that the 400 MSPS spec has an answer.
- Treat provider drift as a first-class measurement: pin model snapshots where the provider allows it, and re-run a fixed reference set each session before comparing arms.
From docs/WRITEUP.md at 80415c6, “What I would do next”. Plans, with no results.
What a hardware team would add proposal
- A plug-in registry API, so a team can add IP blocks (FIR, FFT, NTT, …) with their golden models, generators and cost models.
- Adapters for commercial flows behind the same measured-points schema, so their numbers carry the same provenance.
- Real place and route, and activity-based power from simulated switching (SAIF/VCD) instead of vectorless or toggle-rate power.
- Composition of several blocks into one system spec, explored together.
- Multi-fidelity or Bayesian search as a further baseline, so the LLM is measured against a stronger optimiser too.
- The graph as an MCP tool,
run_dse, for a general-purpose agent to call.
Everything above about this agent is true of HW_Design_Space_Agent at 80415c6; the deployment and the improvements are proposals. See the results, the write-up and the project record.