TrueClock: recursive AI for chip design, proven by rebuilding at every predicted speed
AI flow tuners rank every setting by one number: the clock a run claims it could hit, which is the clock it asked for minus its worst slack. OpenROAD’s AutoTuner scores runs this way by default,11J. Jung et al., METRICS2.1 and Flow Tuning in the IEEE CEDA Robust Design Flow and OpenROAD, ICCAD 2021. AutoTuner’s default score is clock period minus worst slack, and it can tune the clock period too. and the LLM agents built on these flows inherit the habit. The tuner never builds the design at that claimed clock. I did, across 2,957 routed runs on 20 open designs, and the claim was off by up to 48%.
So I fixed the number before adding more AI. Every winner gets rebuilt at the clock it claims, and only a build that passes at that clock counts. Under that judge, AI improved AI: Claude beat Bayesian search on 6 of 7 held-out designs after I had written down that it would lose, the search rules it wrote beat plain Bayesian search in 9 of 10 races, and its rewrite of an MD5 core from the routed critical path reached 1.75× the clock.
TLDR: one rule, rebuild every winner at its predicted clock. Open-source flow (LibreLane and OpenROAD) on SkyWater 130 nm, every clock checked at 9 corners after routing. Follow-up work added open DRC, LVS and antenna checks on eight selected builds, a formal proof, checks at 7 nm and 2 nm, a law for how far the claim misses, and rebuilds of other groups’ published winners: all 14 reproduced their published claim, and 6 failed when rebuilt at it.
01The number tuners trust
A place-and-route run is asked for a clock, say 10 ns, and reports its worst setup slack across corners, say 2 ns. A tuner turns that into a claimed clock, 8 ns, and ranks settings by it. Checking that claim would mean running the whole flow again at 8 ns with the same settings, so loops don’t.
asked clock 10.00 ns worst slack − 2.00 ns 9 corners, after routing ────────── claimed clock 8.00 ns ranked by this, never built
The claim is a guess because a new clock target builds a different circuit. The flow budgets 20% of the clock for logic outside each I/O port, so a port path’s slack moves 0.8 ns for every 1 ns of clock. And synthesis, placement and repair all work harder at a tighter target. One run’s slack can’t tell you what another build will do.
The audit
I measured the error on 60 settings run at several targets each, 328 runs in all, against the clock each setting can actually meet, read between its passing and failing builds. Runs pushed too hard overclaimed by a median 15%, runs asked gently left 8 to 14% on the table, and the worst error either way was 48%.
Then the winners. Rebuilt at the clock they claimed, 3 of 8 Bayesian-tuned winners failed: PicoRV32 missed by 0.32 ns, BM64 by 0.39 ns and y_huff by 1.74 ns. The error runs the other way too. In a separate race, 33 of 40 winners turned out faster than they claimed, by a median 1.12× and up to 1.50×. Slack alone doesn’t tell you which way a claim will miss: two of the three failures had finished with slack to spare.
Other people’s winners, too. I also rebuilt the field’s own published winners, each in its authors’ own pinned image: the eleven final published agent configurations of EDA-env22EDA-env (Ghose et al., ICCAD 2026, doi:10.1145/3831252.3848500); ORFS-agent’s run database at github.com/ABKGroup/ORFS-Agent, commit 730f1fa. and the three best runs of ORFS-agent’s published run database. All fourteen reproduced their published claim exactly. Rebuilt at the clock they claimed, 6 of 14 failed: all four whose claim came from a run that missed timing, ORFS-agent’s three with claims 6 to 8% too fast, and two more by about a picosecond. The other eight held at their claim, including EDA-env’s headline AES result. I had registered that the typical claim would be at least 3% optimistic; by the rebuilds’ own claims the median was 1.5% pessimistic, so that prediction failed (test F in section 09). The score misses both ways: too fast when the claim comes from a run that missed timing, conservative when it comes from one that met it.
This matters because each try is a full place-and-route run, up to 3.6 hours here, so search loops lean on one run per setting. And an AI that improves itself compounds whatever its score gets wrong.
Aside: every wave of automation trusted an estimate
Masks were cut by hand until Calma’s digitizers and GDS in 1971.33S. Leibson, A Brief and Personal History of EDA, Part 2: Calma, Applicon, Computervision and the CAD Era. EE Journal, 2024. Silicon compilers faded, and synthesis plus place-and-route won. Around 2000, synthesis still estimated wire delay from fanout tables, and at 0.18 µm wires dominated the delay and timing closure broke.44O. Coudert, Timing and Design Closure in Physical Design Flows. ISQED 2002. Physical synthesis fixed it by putting real timing back inside the loop.
AI for chip design is replaying the story. ChipNeMo, AlphaChip, PrefixRL and AlphaEvolve each optimize a score. TrueClock puts the real check back inside the loop again, this time for the AI.
02The question, inverted
Most AI-for-EDA projects pick a stage and ask where AI could help. I asked the opposite: where is AI already wrong, and why? Four answers framed the project.
- Objective
- A higher clock from better flow settings or rewritten RTL, where every reported clock passed nine-corner timing after routing.
- Idea
- AI is wrong about the clock it claims, because a new target builds a different circuit. Fix the score first by rebuilding each winner at its claim, then let AI improve itself under that judge.
- Inspiration
- CAD escaped its timing-closure crisis by checking real layouts inside the loop. AI gets the same check, plus an LLM that can read it.
- State of the art
- AutoTuner, FastTuner55H.-H. Hsiao, Y.-C. Lu, P. Vanna-Iampikul, S. K. Lim, FastTuner: Transferable Physical Design Parameter Optimization using Fast Reinforcement Learning. ISPD 2024. and LLM agents66ORFS-agent (A. Ghose et al., arXiv:2506.08332); Dr. RTL (W. Fang et al., arXiv:2604.14989); RTLScout (F. Arnold et al., NeurIPS 2026 Workshop on AI for Chip Design, to appear). all optimize an estimate while they search: a run’s claimed clock, a learned predictor, or a synthesis report. FastTuner does check its final picks with full place-and-route; rebuilding at the claimed clock is the step added here. Also new: every winner is rebuilt at its predicted clock, and AI improves AI at three levels under that judge.
The designs
Everything runs on open benchmarks through LibreLane 3.0.16 and OpenROAD on the SkyWater sky130A PDK, on a GitHub Actions build farm. Here are thirteen of the routed designs, drawn to one scale.













Aside: one routed block, layer by layer

PicoRV32, a RISC-V CPU, routed in this flow: 412 × 423 µm, with 1,597 flip-flops, 265 clock-tree cells, 3,097 buffers and 4,903 logic cells.
03Rebuild at the predicted speed
The fix is one rule, and it wraps any tuner: take the winner’s claimed clock, rebuild at it with the same settings, and keep rebuilding at each new claim while it passes.
claim = asked_clock - worst_slack # the number a tuner ranks by target = round_up(claim, 0.05 ns) repeat at most 4 times: run = build(same_settings, clock=target) # full RTL-to-GDS flow if passes(run): # the judge, below keep = target target = round_up(target - run.worst_slack, 0.05 ns) # its new claim else: step back (at most twice), or stop report keep # only a clock that passed counts
The judge is strict on purpose: setup and hold met at 9 corners (three PVT corners times three RC extraction corners, with OpenRCX parasitics), zero router DRC errors, and slew and capacitance no worse than the stock flow. Signoff DRC and LVS were off during the study to save run time. I ran them afterward on every headline build (section 08).
One setting, four rebuilds: XTEA
XTEA’s run 1 asked for 13.12 ns, finished with 6.65 ns of slack, and so claimed 6.47 ns (155 MHz). Rebuilt at that clock, 6.50 ns after rounding, it passed at 154 MHz. Each rebuild then asked for the clock the last one claimed: 194, 204 and 213 MHz, all passing. That is 1.38× the first checked clock, with the same settings and no new search, and the chain stopped at its cap while still passing. One caveat: the benchmark’s XTEA RTL never writes its outputs, so these are real builds of a small control loop rather than of a cipher, and the clearest case of the bookkeeping below (see Caveats).
Two mechanisms
Bookkeeping. With I/O delays budgeted at 20% of the clock, a port path’s slack moves 0.8 ns per ns of target, so its claim drifts with the target. On XTEA that arithmetic accounts for 208 of the 213 MHz.
Physics. Register-to-register paths have no I/O budget, yet their claimed clock still moved a median 0.44 ns per ns of target across 48 settings, because repair effort depends on the target. Pushed too hard, those paths overclaimed by 15%.
Not just the constraints. A registered follow-up (test B in section 09) held each design’s I/O delay fixed and rebuilt all 48 tuned winners at their new claims. 47 of 48 came out as before. BM64 still failed on register-to-register setup, and y_huff still failed, now on hold at its inputs, which the smaller fixed input delay made harder; PicoRV32 now passed. Port-limited claims moved a lot, XTEA’s by about a quarter, but whether a winner survives a rebuild at its claim barely did, and rebuilding again still gained a median 1.09× (1.0885) over the 46 chains that passed a rebuild.
A cheaper forecast is tempting, so I tried one, with the test written down first. A learned model lost to a simple line through two builds, which lands within a median 2.3%. But even that line called “pass” on builds that then failed setup 28 of 89 times. A forecast tells you where to rebuild; only a rebuild tells you it passes.
04A law for the claim
Section 01 showed the claim missing in both directions. I then measured the shape of the miss, and it is simpler than I expected: slack is not distance.
Call F the clock a setting can actually meet, read between its passing and failing builds as in the audit. A run asks for T and reports its worst slack. The claim, T − slack, treats that slack as the distance to F, as if the circuit stayed put while the target moved. It doesn’t. Every target builds a different circuit, so the claim follows the ask part of the way, and how far it follows is a slope, s. The claim’s error is that slope times how far the ask sat from F:
# how hard the run was pushed r = T / F # claim error: slope s⁻ below F, s⁺ above error = (claim - F) / F = s · (r - 1) # what it can meet (the claim uses k = 1) F = T - k · slack, k = 1 / (1 - s)
If s were 0, slack would be distance and the claim would be exact. If s were 1, the claim would only echo the ask. I fitted s on each side of F separately, through zero, on the 328 audit runs from section 01. On LibreLane at 130 nm, runs asked for more than their setting could do follow at s⁻ = 0.59, and runs asked for less at s⁺ = 0.29. So the clock a setting can meet sits 2.4 slacks from the target when the run failed, and 1.4 slacks when it passed, never one. A run that misses by 0.1 ns is really 0.24 ns short of its target; a run that passes with 0.1 ns to spare can go 0.14 ns faster.
At 7 nm the asymmetry flips. On the 44 ASAP7 runs of section 08, OpenROAD-flow-scripts gives s⁻ = 0.20 and s⁺ = 0.65: k = 1.25 for a failing run and 2.9 for a passing one. There a failing run’s claim is nearly right, and a passing run leaves far more on the table. My first guess was synthesis. LibreLane hands the clock target to synthesis; that ORFS flow doesn’t, and it produced the same netlist at every target. I registered that guess as a test, beside the plainer question of whether it is the node or the flow (test A in section 09). My prediction for the plainer half, that OpenROAD at 130 nm would behave like OpenROAD at 7 nm, failed. Rerunning the 7 nm protocol on a 130 nm library inside the same OpenROAD flow and image, with synthesis still blind to the clock, the tight side moved at s⁻ = 0.601, close to LibreLane’s nine-corner 0.586 rather than 7 nm’s 0.20. In these flows the tight-side slope tracked the platform, not the tool; with three small designs at one corner, and technology, library and conditions changing together, that is an observation, not a cause. The loose side stayed with the flow (s⁺ = 0.58, near OpenROAD’s 0.65 at 7 nm rather than LibreLane’s 0.29). The synthesis guess then failed directly: handing synthesis the clock at 7 nm gave s⁻ = 0.298, short of the 0.35 I had registered.
Two slopes per flow reproduce both audits. Tight asks, at a median 0.72 of F on sky130, should overclaim by 16% and did by 14.5%; loose asks, at 1.24, should underclaim by 7% and did by 8.2%. At 7 nm the law gives −5.9% and +17%, against −5.6% and +15.2% measured. The law also says which winners fail at their claim: those whose search run missed its target. The sign of the search run’s slack called the first rebuild in 58 of 61 sky130 chains and 7 of 9 at 7 nm, though not every failure: two of the audit’s three had finished with slack to spare. And on the 50 rebuild chains of section 06, T − 1.4 × slack at the first passing rebuild lands a median 2.5% from where each chain ended, against 4.7% for the claim.
The first prospective test is in. In test E (section 09) the law forecast the rebuilds of 35 runs from four held-out design families, rebuilds that had never been built, and those forecasts were pushed to the repository before the rebuilds were dispatched. Its pass/fail calls, the sign of each run’s slack, got 29 of 35 right, and nothing beat them. Its slopes did worse: Claude reading the run’s summary or its raw record, and a simple I/O rule, all forecast how far the claim moved better than the law did (median slope error 0.133, 0.119 and 0.141 against 0.165), and its error was large on two of the four families. So as a forecast of how far the claim moves, the law is not confirmed. Its constants did see older runs of those families, so for the law these were fresh rebuilds rather than unseen designs. Both halves of test A went against my predictions, as above: the tight-side slope tracked the platform rather than the flow, and handing synthesis the clock gave 0.298, not 0.35. Its re-time test held: all nine 7 nm layouts met their corrected claim (section 08). That covers retiming existing layouts, not rebuilding them: in the pushed AES case the existing layout met 385 ps, but a fresh build of the same recipe at 385 ps failed.
05The AI under test
Three proposers search the same 15 flow knobs, and every proposal goes through the same rebuild judge. None of them places or routes anything: LibreLane does, and ordinary code decides which clock counts.
- period_frac
- clock target as a fraction of the default, 0.45–1.0
- FP_CORE_UTIL · density_delta
- core utilisation 20–50%, placement density above it
- SYNTH_STRATEGY
- AREA 0–3 or DELAY 0–4 Yosys/ABC script
- SYNTH_ABC_BUFFERING · SYNTH_SIZING
- buffering and sizing during synthesis
- PL_TIMING_DRIVEN · PL_ROUTABILITY_DRIVEN
- global placement modes
- RUN_POST_GRT_RESIZER_TIMING · _DESIGN_REPAIR
- repair again after global routing
- PL_ · GRT_RESIZER_SETUP_SLACK_MARGIN
- extra setup margin repair aims for, 0–0.4 ns
- DESIGN_REPAIR_MAX_SLEW_PCT · _CAP_PCT
- repair aims 10–40% below the limits
- RC_MODEL
- wire RC before routing: stock, cap213 or orfs
1. Bayesian search
Optuna’s TPE sampler77T. Akiba et al., Optuna: A Next-generation Hyperparameter Optimization Framework. KDD 2019. proposes settings from past scores. It sees one number per run.
2. Claude, reading every run
Claude Opus 5.5, a fresh instance each round, gets a structured summary of every earlier run’s timing report and returns a short rationale and the next two settings. Here is what it read and wrote, verbatim apart from trimming, in three places: round 1 on the divider, round 4 on the NES audio unit, and a rule it rewrote in round 3 of a QSPI race (part 3 below).
GOAL. Find settings that let this design pass signoff at the shortest clock period. Each run is scored by its effective clock T_eff = (clock target it was given) - (worst setup slack over 9 signoff corners); lower is better. […] Note: T_eff from a run aimed at a much looser or tighter target can be optimistic; the best run will later be re-checked at its T_eff. DESIGN. zipdiv: ZipCPU integer divider. Default clock period 19.09 ns. - start blabla [x6z-zipdiv-001] clock target 17.72 ns -> T_eff 8.246 ns, FEASIBLE setup: worst slack +9.474 ns at ss 100C 1.60V max-RC (reg-to-reg worst +11.097 ns; the worst path touches an input/output port); TNS 0.00 ns; 0 violating endpoints at the target hold: worst slack +0.094 ns at ff -40C 1.95V min-RC; 0 violations; 0 hold buffers inserted electrical: 0 slew/cap pins summed over corners (bar 295); worst corner max-slew 0, max-cap 0 cells: 2222 std cells, 282 timing-repair buffers; std-cell area 15,265 um2; utilisation 35% routing: wirelength 35,814 um (pre-route estimate 32,398); detailed-route DRC by iteration [422, 94, 111, 14, 0], final 0 clock: skew 0.269 ns (setup) / -0.324 ns (hold); power 1.04 mW; flow runtime 2.3 min [… seven more runs in the same format …]
{
"rationale": "AREA 3 is the netlist to keep: AREA 2 and DELAY 3/4 needed timing repair and stalled at 8.9-12.4 ns, while every AREA 3 run kept large positive slack, so T_eff there is natural delay shaped by electrical repair. Blabla (orfs RC, 39% slew margin) had the fastest reg-to-reg path (6.62 ns), but its loose 17.7 ns target inflated port delays, so an I/O path set T_eff=8.25. Setting 1 reruns blabla at the minimum target (8.59 ns), where port delays shrink and reg-to-reg should limit. Setting 2 keeps AREA 3 and maximal slew margin but adds cap213, timing-driven placement, post-GRT design repair and stronger cap repair.",
"settings": [
{ "period_frac": 0.45, "FP_CORE_UTIL": 27, "density_delta": 25, "SYNTH_STRATEGY": "AREA 3", "PL_ROUTABILITY_DRIVEN": true, "PL_RESIZER_SETUP_SLACK_MARGIN": 0.4, "DESIGN_REPAIR_MAX_SLEW_PCT": 40, "RC_MODEL": "orfs", … },
{ "period_frac": 0.45, "FP_CORE_UTIL": 27, "SYNTH_STRATEGY": "AREA 3", "PL_TIMING_DRIVEN": true, "RUN_POST_GRT_DESIGN_REPAIR": true, "DESIGN_REPAIR_MAX_CAP_PCT": 35, "RC_MODEL": "cap213", … }
]
}
GOAL. Find settings that let this design pass signoff at the shortest clock period. Each run is scored by its effective clock T_eff = (clock target it was given) - (worst setup slack over 9 signoff corners); lower is better. […] DESIGN. APU: NES audio processing unit. Default clock period 17.0 ns. Stock flow: about 4608 standard cells. Bar: 850 slew/cap pins. HISTORY on this design (14 runs so far: 8 'start' runs are settings found on other designs and applied unchanged; 'round' runs are your own earlier proposals, with your rationale). […] [… the 8 start runs and rounds 1 and 2 …] - round 3 [x8a-APU-005] clock target 8.16 ns -> T_eff 8.842 ns, FEASIBLE setting {"period_frac": 0.48, "FP_CORE_UTIL": 30, "SYNTH_STRATEGY": "AREA 3", … } setup: worst slack -0.682 ns at ss 100C 1.60V max-RC (reg-to-reg worst -0.073 ns; the worst path touches an input/output port); TNS -2.40 ns; 20 violating endpoints at the target [… hold, electrical, cells, routing, clock …] - round 3 [x8a-APU-006] clock target 8.16 ns -> T_eff 8.697 ns, FEASIBLE setting {"period_frac": 0.48, "FP_CORE_UTIL": 30, "SYNTH_STRATEGY": "DELAY 1", … } setup: worst slack -0.537 ns at ss 100C 1.60V max-RC (reg-to-reg worst -0.537 ns); TNS -7.41 ns; 59 violating endpoints at the target [… hold, electrical, cells, routing, clock …] (your rationale then: Strong runs (AREA 3, ABC buffering+sizing, timing-driven placement, post-GRT repairs, cap213) are capped at ss 100C by a port path whose slack moves ~0.8 ns per ns of target (scaled IO delays): T_eff ~ 0.2*target + D, D ~ 7.2-7.35 ns regardless of die size; reg-to-reg floors near 8.3 ns. […]) TASK. Round 4 of 4. Propose exactly 2 NEW settings for this design (different from every setting above), chosen to lower the best feasible T_eff, using what the signoff summaries tell you […]
{
"rationale": "Round 3's two runs differed only in synthesis script. AREA 3 stays port-limited: port delay ~7.2 ns, and port slack moves ~0.8 ns per ns of target, so its true period is near 9 ns. DELAY 1 shortened the port path (slack better than -0.54 vs -0.68) and gave the best T_eff, 8.70, now reg-to-reg-limited. Die size and margins shifted results only ~0.1-0.2 ns; DELAY 3/4 bloated wiring. Hold, DRC and slew/cap (0 vs 850) have headroom. Both settings keep the round-3 physical recipe at 8.16 ns and try the untested siblings DELAY 2 and DELAY 0, seeking DELAY 1's short port path with better reg-to-reg depth.",
"settings": [
{ "period_frac": 0.48, "FP_CORE_UTIL": 30, "SYNTH_STRATEGY": "DELAY 2", "PL_TIMING_DRIVEN": true, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.05, "RC_MODEL": "cap213", … },
{ "period_frac": 0.48, "FP_CORE_UTIL": 30, "SYNTH_STRATEGY": "DELAY 0", "PL_TIMING_DRIVEN": true, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.05, "RC_MODEL": "cap213", … }
]
}
HOW THE SEARCH WORKS. The optimizer proposes 2 settings per round, for 4 rounds (8 runs), and learns from every run's score and feasibility (including the start runs below). You do not propose settings. You write a POLICY: you may PIN up to 8 knobs to fixed values. […] This is a revision: you see the results of the rounds run under the earlier policies, and you may keep the policy, change pinned values, add pins or remove pins. DESIGN. wbqspiflash: Wishbone quad-SPI flash controller (ZipCPU). Default clock period 18.86 ns. Stock flow: about 2808 standard cells. Bar: 953 slew/cap pins. [… the 8 start runs and round 1's two runs …] - round 2 [xah2-wbqspiflash-003] clock target 8.49 ns -> T_eff 7.966 ns, FEASIBLE pinned by the policy then: {"period_frac": 0.45, "RC_MODEL": "cap213", … "PL_RESIZER_SETUP_SLACK_MARGIN": 0.4, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.4, "PL_TIMING_DRIVEN": true} setup: worst slack +0.524 ns at ss 100C 1.60V max-RC (reg-to-reg worst +0.544 ns; the worst path touches an input/output port); TNS 0.00 ns; 0 violating endpoints at the target cells: 3333 std cells, 571 timing-repair buffers; std-cell area 27,339 um2; utilisation 46% routing: wirelength 82,873 um (pre-route estimate 72,001); detailed-route DRC by iteration [17, 19, 18, 0, 0], final 0 - round 2 [xah2-wbqspiflash-004] clock target 8.49 ns -> T_eff 7.988 ns, FEASIBLE setup: worst slack +0.502 ns at ss 100C 1.60V max-RC (reg-to-reg worst +0.502 ns); TNS 0.00 ns; 0 violating endpoints at the target [… the rest of each run’s summary …] POLICIES SO FAR (yours, with your rationale then): [… round 1 …] - round 2: pins {"period_frac": 0.45, "RC_MODEL": "cap213", "RUN_POST_GRT_RESIZER_TIMING": true, "SYNTH_STRATEGY": "DELAY 4", "PL_ROUTABILITY_DRIVEN": false, "PL_RESIZER_SETUP_SLACK_MARGIN": 0.4, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.4, "PL_TIMING_DRIVEN": true}; rationale: […] Pin both setup slack margins to the 0.4 maximum so repair aims ~0.4 ns past the floor target, and turn on timing-driven placement to shorten critical/port nets at the max-RC corner. TASK. Write the policy for round 3 of 4, using what the signoff summaries tell you […]
{
"rationale": "At the 8.49 ns floor, signoff slack ~ GRT margin + 0.10-0.13 ns in all four runs (0.33->0.456, 0.35->0.451, 0.40->0.524/0.502): repair stops at the margin, so period_frac 0.45, both margins 0.4, cap213 and post-GRT timing repair stay. Setup is limited at ss 100C max-RC with port and reg-to-reg paths co-critical (0.524 vs 0.544), so shorter wires help both and the later tighter re-runs. Higher utilisation won within each round (37>31, 25>23) and util 31-37 cut wirelength ~13% vs 23-25; DRC still converges to 0, hold (+0.09, 0 buffers) and slew/cap (0 vs 953) are not binding. Pin FP_CORE_UTIL 40, keep TDP and DELAY 4; drop the routability pin (top runs chose false).",
"pins": {
"period_frac": 0.45, "RC_MODEL": "cap213", "RUN_POST_GRT_RESIZER_TIMING": true, "SYNTH_STRATEGY": "DELAY 4",
"PL_RESIZER_SETUP_SLACK_MARGIN": 0.4, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.4, "PL_TIMING_DRIVEN": true, "FP_CORE_UTIL": 40
}
}
Look at what the divider’s round-1 rationale does. It notices that a loose target inflated the port delays on the best run, so an I/O path set its score, and it asks for the tightest target instead. That is the bookkeeping mechanism from section 03, found by reading the reports.
By round 4 on the NES audio unit it had written that bookkeeping down as an equation, T_eff ≈ 0.2 × target + D, and concluded that one of its own best scores was optimistic: “its true period is near 9 ns.” The other run it was reading, the DELAY 1 setting at 8.70 ns, is the audio-unit clock in the results below, checked by rebuilding. In the QSPI race it noticed that repair stops at its margin, signoff slack landing 0.10 to 0.13 ns past it in all four runs, and pinned both margins at their maximum.
3. Claude, writing the rules Bayesian search runs under
In a later test, Claude stopped proposing settings and wrote rules instead. It read the start runs’ reports once and pinned up to 8 knobs, and Bayesian search set the rest. A real rule, for the divider:
{
"rationale": "Setup is always limited at ss 100C 1.60V max-RC; hold, slew/cap (0 vs bar 295) and DRC are non-issues. AREA 3 produced all five best runs; DELAY/AREA 2 were worse. Loose targets let port paths dominate and inflate T_eff uncertainty, so pin the tightest target (0.45 = 8.59 ns) for r2r-limited, re-run-honest scores. Stock RC under-predicted wire delay (aes missed by 1.4 ns); cap213 tracked signoff (des landed near its margin) and was used by the two best runs. Timing-driven placement, post-GRT timing repair and moderate margins should keep the later re-run at T_eff passing. Util 40 gave the shortest wirelength and best T_eff. Leave buffering, sizing, density and repair knobs to TPE.",
"pins": {
"period_frac": 0.45, "SYNTH_STRATEGY": "AREA 3", "RC_MODEL": "cap213", "FP_CORE_UTIL": 40,
"PL_TIMING_DRIVEN": true, "RUN_POST_GRT_RESIZER_TIMING": true,
"PL_RESIZER_SETUP_SLACK_MARGIN": 0.3, "GRT_RESIZER_SETUP_SLACK_MARGIN": 0.2
}
}
All 10 of Claude’s first rules pinned the clock target at or next to the tightest allowed, without being told: 8 at the floor of 0.45× the reference period, the others at most 0.47×. In the earlier test Claude asked for the tightest target in 44 of 56 proposals; Bayesian search alone never did.
4. Claude, rewriting RTL
Finally, Claude got a design’s Verilog and its routed critical path and rewrote the RTL. That is section 07.
06Results
Every clock in this section is a routed run that passed at that clock.
Head to head: Claude against Bayesian search
This test was registered before its runs, with the prediction that the LLM would lose. Both searchers started from the same 8 runs and got 8 more each, on seven designs held out from developing the methods. A win means more than 2% faster after both winners were rebuilt at their claims. Claude won 6 of 7.
| Held-out design | Bayesian search | Claude, reading reports | Claude’s margin |
|---|---|---|---|
| Dividerzipdiv | 7.40 ns135 MHz | 5.70 ns175 MHz | +29.8% |
| QSPI flash controllerwbqspiflash | 7.65 ns131 MHz | 6.65 ns150 MHz | +15.0% |
| CIC decimation filtercic_decimator | 4.60 ns217 MHz | 4.00 ns250 MHz | +15.0% |
| USB deviceusb_cdc_core | 6.10 ns164 MHz | 5.85 ns171 MHz | +4.3% |
| XTEAxtea | 4.55 ns220 MHz | 4.45 ns225 MHz | +2.2% |
| NES audio unitAPU | never passedslower than 9.45 ns | 8.70 ns115 MHz | passes; Bayesian didn’t |
| NES video unitPPU | 13.20 ns76 MHz | never passedslower than 13.45 ns | loss |
Clocks after the rebuild chains. Equal flow-run budgets; Claude also used 4.7 hours of model time in total. On the NES audio unit, Bayesian search’s pick never passed in the range it tried. On the NES video unit, Claude’s never did.
A language model can win on 16 runs because of what it sees. Bayesian search gets one number per run. Claude sees why a run missed: which path, which corner, cell or wire delay, setup or hold. So it can move several coupled knobs at once.
AI improves AI: Claude writes the search rules
Ten races, five designs with two seeds each, and four searchers with equal budgets and the same rebuild rule: plain Bayesian search; Bayesian search with my hand-coded tight-clock habit; Bayesian search under rules Claude wrote once from the start runs’ reports; and the same rules, rewritten by Claude after every round.
| Race | Plain Bayesian | + my tight-clock pin | + Claude’s rules, written once | + Claude’s rules, rewritten each round |
|---|---|---|---|---|
| 5.05 ns198 MHz | 4.60 ns217 MHz | 4.65 ns215 MHz | 4.20 ns238 MHz | |
plainclaim 6.52→6.55 ✓→5.45 ✓→5.20 ✓→5.05 ✓kept 5.05 ns + my pinclaim 6.21→6.25 ✓→5.15 ✓→4.90 ✓→4.60 ✓kept 4.60 ns + Claude, onceclaim 6.37→6.40 ✓→5.35 ✓→5.00 ✓→4.65 ✓kept 4.65 ns + Claude, each roundclaim 6.01→6.05 ✓→4.90 ✓→4.55 ✓→4.20 ✓kept 4.20 ns | ||||
| 4.50 ns222 MHz | 4.95 ns202 MHz | 4.25 ns235 MHz | 4.25 ns235 MHz | |
plainclaim 6.73→6.75 ✓→5.25 ✓→4.85 ✓→4.50 ✓kept 4.50 ns + my pinclaim 6.24→6.25 ✓→5.20 ✓→5.05 ✓→4.95 ✓kept 4.95 ns + Claude, onceclaim 5.93→5.95 ✓→4.80 ✓→4.50 ✓→4.25 ✓kept 4.25 ns + Claude, each roundclaim 5.95→5.95 ✓→4.80 ✓→4.45 ✓→4.25 ✓kept 4.25 ns | ||||
| 4.70 ns213 MHz | 4.40 ns227 MHz | 4.00 ns250 MHz | 4.00 ns250 MHz | |
plainclaim 4.83→4.85 ✓→4.80 ✓→4.70 ✓kept 4.70 ns + my pinclaim 4.24→4.25 ✗→4.35 ✗→4.40 ✓kept 4.40 ns + Claude, onceclaim 4.13→4.15 ✓→4.00 ✓→3.85 ✗kept 4.00 ns + Claude, each roundclaim 3.95→4.00 ✓→3.95 ✗kept 4.00 ns | ||||
| 4.60 ns217 MHz | 4.00 ns250 MHz | 4.10 ns244 MHz | 3.90 ns256 MHz | |
plainclaim 4.78→4.80 ✓→4.65 ✓→4.60 ✓kept 4.60 ns + my pinclaim 4.23→4.25 ✓→4.00 ✓→3.90 ✗kept 4.00 ns + Claude, onceclaim 4.10→4.10 ✓→3.95 ✗kept 4.10 ns + Claude, each roundclaim 3.95→4.00 ✓→3.90 ✓kept 3.90 ns | ||||
| 6.55 ns153 MHz | 5.65 ns177 MHz | 6.10 ns164 MHz | 5.70 ns175 MHz | |
plainclaim 7.53→7.55 ✓→7.25 ✓→6.90 ✓→6.55 ✓kept 6.55 ns + my pinclaim 7.18→7.20 ✓→6.50 ✓→6.05 ✓→5.65 ✓kept 5.65 ns + Claude, onceclaim 7.23→7.25 ✓→6.80 ✓→6.35 ✓→6.10 ✓kept 6.10 ns + Claude, each roundclaim 6.67→6.70 ✓→6.30 ✓→6.00 ✓→5.70 ✓kept 5.70 ns | ||||
| 6.50 ns154 MHz | 6.75 ns148 MHz | 5.95 ns168 MHz | 5.60 ns179 MHz | |
plainclaim 7.70→7.75 ✓→7.30 ✓→6.85 ✓→6.50 ✓kept 6.50 ns + my pinclaim 6.99→7.00 ✓→6.85 ✓→6.80 ✓→6.75 ✓kept 6.75 ns + Claude, onceclaim 7.22→7.25 ✓→6.75 ✓→6.35 ✓→5.95 ✓kept 5.95 ns + Claude, each roundclaim 6.81→6.85 ✓→6.45 ✓→5.95 ✓→5.60 ✓kept 5.60 ns | ||||
| 5.85 ns171 MHz | 5.70 ns175 MHz | 5.60 ns179 MHz | 5.90 ns169 MHz | |
plainclaim 6.64→6.65 ✓→6.15 ✓→5.85 ✓→5.65 ✗kept 5.85 ns + my pinclaim 6.34→6.35 ✓→6.05 ✓→5.90 ✓→5.70 ✓kept 5.70 ns + Claude, onceclaim 6.32→6.35 ✓→5.80 ✓→5.65 ✓→5.60 ✓kept 5.60 ns + Claude, each roundclaim 6.19→6.20 ✓→5.90 ✓kept 5.90 ns | ||||
| 7.35 ns136 MHz | 5.55 ns180 MHz | 5.90 ns169 MHz | 5.90 ns169 MHz | |
plainclaim 7.33→7.35 ✓kept 7.35 ns + my pinclaim 6.33→6.35 ✓→5.90 ✓→5.65 ✓→5.55 ✓kept 5.55 ns + Claude, onceclaim 6.33→6.35 ✓→5.90 ✓→5.80 ✗kept 5.90 ns + Claude, each roundclaim 6.33→6.35 ✓→5.90 ✓→5.80 ✗kept 5.90 ns | ||||
| 7.25 ns138 MHz | 6.45 ns155 MHz | 7.60 ns132 MHz | 7.60 ns132 MHz | |
plainclaim 8.54→8.55 ✓→8.10 ✓→7.65 ✓→7.25 ✓kept 7.25 ns + my pinclaim 7.94→7.95 ✓→7.45 ✓→6.85 ✓→6.45 ✓kept 6.45 ns + Claude, onceclaim 7.97→8.00 ✓→7.70 ✓→7.60 ✓kept 7.60 ns + Claude, each roundclaim 7.96→8.00 ✓→7.65 ✓→7.60 ✓kept 7.60 ns | ||||
| 7.90 ns127 MHz | 8.10 ns123 MHz | 7.70 ns130 MHz | 8.00 ns125 MHz | |
plainclaim 8.54→8.55 ✓→8.30 ✓→8.15 ✓→7.90 ✓kept 7.90 ns + my pinclaim 8.25→8.25 ✓→8.15 ✓→8.10 ✓→8.05 ✗kept 8.10 ns + Claude, onceclaim 7.98→8.00 ✓→7.85 ✓→7.70 ✓kept 7.70 ns + Claude, each roundclaim 7.97→8.00 ✓→7.65 ✗kept 8.00 ns | ||||
| Faster than plain by >2% | — | 7 of 10 | 9 of 10 | 7 of 10 |
The clock each searcher’s winner reached after its rebuild chain. Green is more than 2% faster than plain Bayesian search in that race; red is more than 2% slower. Open a race to see all four chains, from the winner’s claim through every rebuild: 137 rebuilds in all, 11 of which missed.
Claude’s one-time rules beat plain Bayesian search in 9 of 10 races, a median 1.08× the clock. Given only a quarter of the search runs, they still won 8 of 10. Against my hand-coded habit they went 4 wins, 4 losses. Rewriting the rules every round, 30 rewrites with 27 real changes, didn’t add more: it failed both registered tests, as I had predicted.
Rebuilding again
Every winner I have, rebuilt again after its first passing rebuild: 42 of 50 gained more than 2%, a median 1.10× and up to 1.50×, with the same settings.
Searched flows against the timing preset
Standard Bayesian search, up to 72 runs per design, against LibreLane’s own timing preset at five clock targets, both checked at their own clock: 1.2 to 1.7× the clock, a median 1.51×, at a median 3% more area. Much of that comes from searching at all. At equal runs, random search beat Bayesian search outright on two designs, which is why I lean on the head-to-head races above, with equal budgets and the same judge.
What the speed cost: energy × delay improved a median 5% under Claude’s rules, and 28% for the searched flows against the preset. These use the flow’s default switching activity, so treat them as estimates.
07AI improves the design
The last turn of the loop. Claude got MD5’s Verilog and its routed critical path, about 60 cells and 14 ns in one MD5 step, and rewrote the RTL under a +15% area cap. It added the message word and round constant a cycle early, computed the round function both ways ahead of time so it becomes one mux, and used carry-save and Kogge-Stone adders. Textbook moves, found from the report.
// F written as a mux on b: {F(b=1), F(b=0)} from c, d and round function [63:0] fsplit; input [31:0] c, d; input [1:0] g; case (g) 2'd0: fsplit = {c, d}; 2'd1: fsplit = {c | d, c & ~d}; 2'd2: fsplit = {~(c ^ d), c ^ d}; default: fsplit = {~c, ~(c ^ d)}; endcase endfunction // ---------------- step datapath ---------------- wire [31:0] fr = (br & fc1) | (~br & fc0); // F(br, cr, dr) of the current round wire [31:0] aux = ksa(pre, fr); wire [31:0] rot = rotf(aux, {round64[5:4], round64[1:0]}); wire [31:0] fo = ksa(br, rot); // func_out
Both versions then went through the same rebuild rule with the same allowance. The original stopped at 15.50 ns (64.5 MHz); one step faster had failed. The rewrite reached 8.85 ns (113 MHz) and was still passing when it hit the four-rebuild cap: 1.75× the clock at the same cycles per hash, +19% area and +47% performance per area. Inside the +15% area cap it reached 1.68× at 9.20 ns.
Correctness is proven, not sampled. An unbounded formal proof, k-induction in SymbiYosys, shows the rewrite is cycle-for-cycle equivalent to the original at its outputs for every input sequence after reset. A million random inputs and a gate-level simulation of the routed 8.85 ns netlist agree with it.
Put together, that is four turns of AI improving AI, each checked by rebuilds:
- 01AI searchesBayesian search over the 15 knobs, every clock rebuilt1.2–1.7×
- 02AI reads the runsClaude reading timing reports, head to head6 of 7
- 03AI improves AIClaude writes the rules the search runs under9 of 10
- 04AI improves the designClaude rewrites RTL from the routed critical path1.75×
08Follow-up checks
After the main study I registered six more tests, each with its prediction written down before its runs. These are their recorded results so far, including the predictions that failed.
Full signoff on every headline build
I rebuilt the eight builds behind the headline clocks with identical settings and LibreLane’s open-source signoff switched on: Magic and KLayout DRC, Netgen LVS and the antenna check. All eight are clean, and place-and-route reproduced bit-for-bit, so none of the clocks change.
| Headline build | Clock | Magic DRC | KLayout DRC | LVS | Antenna | Setup slack | Hold slack |
|---|---|---|---|---|---|---|---|
| MD5, original | 15.50 ns65 MHz | 0 | 0 | match | 0 | +0.069 ns | +0.090 ns |
| MD5, Claude’s rewrite | 9.20 ns109 MHz | 0 | 0 | match | 0 | +0.368 ns | +0.089 ns |
| MD5, Claude’s rewrite | 8.85 ns113 MHz | 0 | 0 | match | 0 | +0.307 ns | +0.092 ns |
| XTEA | 4.70 ns213 MHz | 0 | 0 | match | 0 | +0.237 ns | +0.096 ns |
| Divider | 5.70 ns175 MHz | 0 | 0 | match | 0 | +0.293 ns | +0.089 ns |
| QSPI controller | 6.65 ns150 MHz | 0 | 0 | match | 0 | +0.388 ns | +0.083 ns |
| CIC filter | 4.00 ns250 MHz | 0 | 0 | match | 0 | +0.152 ns | +0.093 ns |
| USB device | 5.85 ns171 MHz | 0 | 0 | match | 0 | +0.072 ns | +0.070 ns |
Worst setup and hold slack over the 9 corners. Signoff added under five minutes per build.
Is it noise?
Replays of the same settings are bit-identical, down to the routed netlist. Nudging the clock target by 1 to 40 ps moved the claimed clock by at most 2.3% on XTEA and 1.1% on the divider, and all 14 nudged builds passed. That is several times smaller than any effect above.
7 nm: ASAP7
Then the obvious question: does it hold at an advanced node? I rebuilt the audit with OpenROAD-flow-scripts on ASAP7, the open 7 nm predictive PDK,88L. T. Clark et al., ASAP7: A 7-nm finFET predictive process design kit. Microelectronics Journal 53, 2016. on three designs, took AutoTuner’s top three settings on each, and rebuilt them at their claimed clock.
| 7 nm winner | Asked | Claimed | Rebuilt at | Slack there | Claim moved | Kept clock | Limiting path |
|---|---|---|---|---|---|---|---|
| gcdas shipped | 215 ps | 326.4 ps | 330 psfail | -20.4 ps | +7.4% | none | I/O |
| gcdutilization 50% | 250 ps | 333.7 ps | 335 psfail | -15.4 ps | +5.0% | 355 ps | I/O |
| gcdas shipped | 265 ps | 337.9 ps | 340 psfail | -9.9 ps | +3.5% | none | I/O |
| AESas shipped | 380 ps | 382.5 ps | 385 psfail | -15.2 ps | +4.6% | none | reg-to-reg |
| AESutilization 55% | 305 ps | 383.7 ps | 385 psfail | -5.3 ps | +1.7% | none | reg-to-reg |
| AESas shipped | 265 ps | 383.9 ps | 385 psfail | -15.2 ps | +4.2% | none | reg-to-reg |
| Ibexas shipped | 900 ps | 913.7 ps | 915 psfail | -4.9 ps | +0.7% | 920 ps | reg-to-reg |
| Ibexdensity +0.40 | 720 ps | 914.7 ps | 915 pspass | +0.9 ps | -0.1% | 915 ps | reg-to-reg |
| Ibexas shipped | 765 ps | 925.1 ps | 930 pspass | +4.8 ps | +0.0% | 930 ps | reg-to-reg |
ASAP7 winners rebuilt at their claim, rounded up to 5 ps. Judged at the one corner ORFS uses for ASAP7, with no margins.
On GCD and AES, all six of the tuner’s top picks failed at their claimed clock, which was a median 4.4% too optimistic, as registered beforehand. On AES the failing paths are register-to-register, so this is the circuit changing rather than I/O arithmetic: those paths came out 6.6 to 17.7 ps slower at the rebuild clock. On Ibex the claims held to within 0.7%. You can’t tell from the claim which case you’re in, and one rebuild can.
With the I/O budget held fixed. A registered follow-up (test B in section 09) reran this grid with the I/O delays frozen at a fifth of each design’s default clock. GCD, limited by an output path, then kept clocks within 2% of its picks’ claims, and at the same asks its claims stopped falling with the target (346.2, 349.4 and 343.7 ps at 215, 265 and 310 ps, against 326.4, 337.9 and 343.7 ps with the stock budget): its miss had been the I/O budget sliding with the target. All three AES picks still failed at their claim, as predicted, so AES’s miss is physics. Ibex mostly held, but one of its three picks, asked at 0.7× its default clock, kept a clock 1.5% slower than it claimed, outside the 1% I had registered.
Re-timing the layout in hand. Another registered test (test A in section 09) asked whether a pushed 7 nm layout already meets its corrected claim, the claim with port paths counted at 0.8 ps of slack per ps of clock, without any rebuild. All nine winners did, re-timed in place with only the clock changed; I had predicted at least eight, and one of the nine had been seen in a smoke test before registration. The AES layout asked for 265 ps runs at 385 ps, while its rebuild chain never passed below 530 ps. The price is area: each pushed layout is 1 to 19% larger than the rebuild at its claim. So the claim is a fair statement about the layout that was built, and a guess about the cheaper layout a rebuild makes. That is ASAP7 at one corner; the sky130 layouts were never kept, so they weren’t re-timed.
2 nm: GT2N
As a smoke test I also ran GT2N, Georgia Tech’s open 2 nm nanosheet PDK.99D. Jang et al., GT2N: An Open-Source 2nm Nanosheet PDK Enabling Multi-Width/VT Benchmarking. ISCAS 2026. Its own example design needs about 55 GB of memory to route, so I ran a small GCD block with the kit’s flow settings. The best run, at 330 ps, claimed 316.94 ps. Rebuilt at 317 ps it passed with 14.6 ps to spare, and the chain went on to 294 ps, 3.4 GHz. As the target tightened, the tool made the critical path itself faster, from 251 to 231 ps.
09Reading the chip
A recent post from MIT1010R. Takehi, J. Teoh, A. Zhang, O. Khattab, Sparks of Weight-Space Programming: LLMs can natively read & write neural network weights. MIT CSAIL, November 2, 2026. showed a language model reading a neural network’s raw weights and saying what the network does without running it: which game a policy was trained on, which shape a diffusion model draws. Forward passes become a budget, and the budget can be zero. A routed block has the same structure, and the whole project has been about what you can and cannot know without running the flow again. A retrospective test of the idea found no advantage. I fit small timing models to each run’s routed nets, then gave a second model their coefficients to predict the claim at a new clock target. Across 239 historical cases from 66 settings, holding out six design families in turn, it missed by 5.90% of the source period on average, against 5.80% from summaries alone and 5.32% from a simple median-slope rule. Removing nonphysical unconstrained timing values after the fact made the coefficients worse (6.65%). No model read or edited raw weights blind, and the test produced no PPA gain.
- Weights
- One routed run’s raw record: for every net, its driver cell, position, slew and slack, wire length on each metal layer, local density, and capacitance at all 9 corners.
- Forward pass
- One flow run, 10 minutes to 3.6 hours here. It is the budget I count.
- Reading
- Saying what the next build will do before it exists: whether a rebuild at the claim passes, and where its chain lands.
- Editing
- Proposing one change from the record, here an arrangement of the block’s I/O pins, and letting a rebuild judge it.
The question. From one routed run’s record and zero new runs, can a reader say how the flow will respond when the target moves to the run’s own claim: whether that rebuild passes, how far the claim moves, and where the rebuild chain lands? The test set is 35 runs of four held-out designs, re-run with every file captured. The reader climbs a ladder of what it may see, and each rung has its own registered prediction:
- 0ArithmeticThe claim, the law and an I/O-aware rule, computed from the run’s worst slacks. No model. This is the bar.slacks
- 1The reportThe timing summary Claude read as a proposer in section 05, plus a 9-corner table. Predicted: ties or loses to the law.summary
- 2The raw recordEvery net of that one run, its layout, parasitics and timing reports, with a Python sandbox. Predicted: ties the law on pass/fail, and beats it on slope error by 20% or more.every net
- 3A written ruleA Python formula Claude writes from the training designs’ records and outcomes, hashed before it sees a test design. Predicted: slope error at least 25% below the law’s.training runs
No hindsight, by construction. Each test’s registration, and then every reader’s forecast, is committed and pushed to the public repository with its SHA-256 before the rebuilds that label them are dispatched, so GitHub’s own timestamps show the forecast came first. When the forecasts are written, the labels don’t exist anywhere: each run’s first rebuild is at a clock its setting was never run at. The four test designs were picked by a fixed rule, sorting the design families by a hash of their names, and the reader sees pseudonyms in place of every design, port, net and instance name; a leak test must pass before any packet is handed over.
- 1 · write it down
- question, runs, the exact metric, the prediction, and a pass/fail test a named script computes
- 2 · hash it
- the file’s SHA-256 committed and pushed; GitHub stamps the time
- 3 · then run
- the rebuilds that label the predictions are dispatched only after the forecasts are committed
- 4 · score it
- by the registered script; misses stay in the record, as in section 10
Learned coefficients, retrospectively. A separate retrospective test asked whether coefficients of small per-run timing models, fitted to the routed nets, help predict the claim at a new target. Across 239 historical cases, with six design families held out in turn, the error (mean absolute, as a percent of the source period; lower is better) was 6.65% with coefficients, 5.80% from summaries alone and 5.32% for a median-slope rule, after a post hoc filter removed nonphysical unconstrained STA values (5.90% before it). No weights were read or edited blind, and the test changes no PPA.
Result: the raw-record prediction held. Claude reading one run’s raw record forecast how far the claim moves 28% better than the law: its median slope error was 0.72 times the law’s (0.119 against 0.165), inside the registered bar of 0.80. It tied the law on pass/fail, and on the 28 chains that kept a clock its forecast of that clock was the best of any arm, a median 3.7% off against the law’s 12.2%. Beside that, nothing beat the sign of the run’s own slack on whether the first rebuild passes: the law, the written formula, a hand-picked feature and an independently written baseline all made exactly those calls, 29 of 35 right. The raw-record reader got 25 right, with 3 false passes in its 22 pass calls against the law’s 1 in 20; at 35 runs the registered test scores that a tie, not a difference. The rich record forecast where a chain lands more closely; the simple rule made more correct pass/fail calls.
The order of events held: the 311 forecasts were pushed before the rebuild run was created, 16 seconds later, and all 35 chains landed, 99 rebuilds with no infrastructure loss. Two other predictions failed. The formula Claude wrote from the training designs did not transfer: its slope error was 1.42 times the law’s, against a bar of 0.75. And the summary reader, which I predicted would tie or lose to the law, beat it on the kept clock (6.7% against 12.2%); the raw record added a little more (3.7%). Two small controls, 6 renamed and 6 shuffled packets, can’t tell whether per-net detail carried that extra gain. The independent baseline, plain code fitted only on training designs and frozen by hash, matched the law’s pass/fail calls but had the largest slope error. The scope is small: four design families, and the raw-record reader beat the law on slope in only two.
One edit, judged by a rebuild. The last test turns reading into a decision. It takes ten winners whose limiting path ran through an I/O port. For each, a fresh Claude reads one routed run and says where the block’s pin groups should go; the tool’s own pin placement and a simple rule that puts each critical group on the edge nearest its logic get the same menu of legal moves, and all three are judged by the same rebuild chain at the winner’s settings. The registered prediction: Claude’s pins beat the tool’s on at least 6 of the 10, with a median kept-clock gain of at least 3%, and beat the rule on at least 5. The I/O delays stay at 20% of each build’s clock in every arm, and the top-level wire a real pin plan trades is not modeled.
Result: the prediction failed. Five of the ten readers kept every pin where the tool put it, which alone ruled out 6 of 10. Of the five that moved pins, one beat the tool, by 2.7%, so Claude beat the tool’s pins on 1 of 10, with a median gain of 0.0%, and the rule on 2 of 10. The rule did no better against the tool: one win, one loss. Moving pins inside these blocks shifts the verified clock a few percent either way, whoever moves them. On XTEA, all three readers worked out, without any names, that the 64 outputs are copies of one flip-flop, and left the pins alone. This is a negative on these 10 blocks and this menu of moves, not a general verdict on pin placement.
The reading test (E) and the pin test (IO) are two of seven further tests, each registered before its runs, after the six in section 08. Here are all seven.
| Test | What it asks | Prediction, as registered | Status |
|---|---|---|---|
| AThe law, predicted | Do the law’s constants belong to the flow or to the node, does handing synthesis the clock change them, and does re-timing a pushed layout at its corrected claim replace the rebuild? | OpenROAD on sky130 gives s⁻ ≤ 0.35 and s⁺ ≥ 0.45 (the flow, not the node); with the clock handed to synthesis at 7 nm, s⁻ ≥ 0.35; at least 8 of 9 ASAP7 winners meet their corrected claim when re-timed. Also a labelled retrodiction: at least 13 of E5’s 16 rebuild calls right. | scored: 1 of 4 parts heldsha256 e5c71b21… + Amendment 1 (pilots run one per runner; no prediction changed)smoke passed (plumbing)✗ T1 scored, FAIL (a retrodiction): 10 of 16 rebuild calls right, needed 13; median claim error 3.5%, needed ≤ 3%✗ T2a, FAIL: OpenROAD at 130 nm gave s⁻ 0.60 and s⁺ 0.58, so the tight side follows the node (LibreLane’s 0.59), not the flow; synthesis was blind to the clock throughout✓ T3, PASS: all 9 ASAP7 winners, re-timed in place at their corrected claim, passed (needed 8); the pushed layouts are 1–19% larger than their rebuilds✗ T2b, FAIL: with the clock handed to synthesis, s⁻ was 0.298 (needed ≥ 0.35). Caveat on T3: AES’s pushed layout met 385 ps in place, but a fresh build of its recipe at 385 ps failed |
| BFrozen I/O budgets | With the I/O budget held fixed, the way a PD engineer would hold it, does the one-run claim still miss, and do tuned winners still fail at their claim? | Tight asks still overclaim, median beyond −8% (point −12%); at least 2 of the 3 audit failures, and 2 of all 48 tuned winners, still fail at their claim, and rebuilding again still gains a median 1.05× or more; at 7 nm, GCD’s picks hold within 2% or turn register-limited, at least 2 of AES’s 3 still fail, and Ibex’s hold within 1%. | registeredsha256 e8134105… + amendmentsmoke passed (controls bit-identical)✓ C0 scored, PASS (retrospective): re-scored by register slack alone, the audit’s tight asks still overclaim by 15.2%✓ C3 GCD, PASS: all 3 picks kept clocks within 2% of their claims (2 of 10 grid runs repeated smoke runs)✓ C3 AES, PASS: all 3 picks failed their first rebuild (register-to-register)✗ C3 Ibex, FAIL: 1 of 3 picks kept a clock 1.5% slower than claimed (registered: within 1%)✓ C2a, PASS: 2 of the 3 audit failures still fail (y_huff now on input hold; on setup alone, 1 of 3), 3 of 48 in all; 47 of 48 verdicts as before✓ C2a rebuild-again, PASS (final): median 1.09× (1.0885) over the 46 chains that passed a rebuild (bar 1.05×)the remaining registered parts have no scored result and count neither way |
| CMethod, not model | How much of the AI’s edge in the races comes from the timing reports it reads, from the model itself, or from a rule a four-line script could write? | The four-line script and a small open model (Qwen3.5-9B on a CPU runner) tie Opus within ±2 races; the reports buy the proposer 2–3 of 7 designs. | final stage scored: reports did not beat scores onlysha256 e28db918…Final stage, matched allowed budgets (eight settings plus at most four verification builds), 2% margin, 10 races (5 designs × 2 seeds): the Opus rule with historical reports vs the Opus rule from scores only went 1–4–5 (wins–losses–within margin). The bar was ≥5 wins and ≤2 losses, so it was not met. At the median, the report-informed rule was about 1% slower. Without XTEA (sensitivity only): 1–3–4. At first confirmation it had gone 1–1–8. The follow-up completed 30 chains with 76 additional routed builds.final stage against plain Bayesian search: the four-line deterministic rule went 8–2–0 (pass, median +6.3%) and the Qwen3.5-9B rule with reports went 6–2–2 (pass, median +3.2%). Without XTEA (sensitivity only): 7–1–0 and 6–1–1. At first confirmation these controls went 10–0 and 6–3–1. A separate report comparison, run proposal by proposal with the scores-only settings proposer, has no matched final-stage confirmation yet, so that result is pending |
| DThree nodes, one flow | Repeat the 7 nm protocol at 130 nm (sky130hd) and 2 nm (GT2N) inside the same OpenROAD flow: is it the node or the flow that sets how often winners fail? | At least 55% of the new winners fail their first rebuild, and OpenROAD at 130 nm overclaims tight asks by nearer ASAP7’s 5.6% than LibreLane’s 14.5%. | registeredsha256 e5c71b21… + Amendment 1 (with A)smoke passed (plumbing)main batch not scored; no three-node verdict |
| EReading the chip | From one routed run’s record and zero new runs, how does the flow respond when the target moves to the run’s own claim: does the rebuild pass, how far does the claim move, where does the chain land? | Reports alone tie or lose to the law; the raw record ties the law on pass/fail and beats it on slope error by 20% or more; a formula written from training designs beats it by 25% or more. | scored: 1 of 3 predictions heldsha256 ae1b4b20… + 12 clarifications, no prediction changedsmoke passed; leak test: 0 leaks in 82 packet views311 forecasts pushed Nov 3, 01:14 ET; rebuilds dispatched 16 s later; all 35 chains landed (99 rebuilds, 0 infrastructure losses)✓ R2, PASS: the raw-record reader’s slope error was 0.72× the law’s (0.119 vs 0.165; bar 0.80×), pass/fail tied, best kept clock (3.7% median error)✗ R1, FAIL in the readers’ favour: the summary reader tied the law on pass/fail and beat it on kept clock (6.7% vs 12.2%)✗ R3, FAIL: the written formula’s slope error was 1.42× the law’s (bar 0.75×)pass/fail: nothing beat the slack sign (29 of 35); rung 2 had 3 false passes, the law 135 runs, 4 families; rung 2 beat the law on slope in 2 of themindependently re-scored from the locked files: every number reproduced |
| FThe field’s winners | Built exactly as published, each in its own publication’s pinned image, do 14 published ORFS winners (11 published EDA-env agent configurations, 3 runs from ORFS-agent’s database) reproduce their claimed clock, and do they pass when rebuilt at it? | Of the winners that reproduce within 2%, the median claim is optimistic by at least 3% at the first rebuild, and at least one fails at its claim. | prediction failedsha256 ba4d1510…smoke passed (a published run replayed bit-identically)all 14 published winners reproduced their published claim exactly✗ P1, FAIL: at the first rebuild the median claim moved −1.5% (needed +3% or more)✓ P2, PASS: 6 of 14 failed at their claimed clockclaims from runs that missed timing: 4 of 4 failed (+5.9%); from runs that met it: 2 of 10 (−2.7%)rebuild chains unfinished; no final chain figure |
| IOPins from the reading | Can a blind reader of one routed run choose I/O pin positions that verify a faster clock than the tool’s own pins and a nearest-side rule, all judged by the same rebuild chain? | Claude’s pins beat the tool’s on at least 6 of 10 cases, with a median kept-clock gain of at least 3%, and beat the rule on at least 5 of 10. | prediction failedsha256 5977e649…smoke passed (no-op replay bit-identical)✗ scored, FAIL: beat the tool’s pins on 1 of 10 (needed 6), median gain 0.0% (needed 3%), beat the rule on 2 of 10 (needed 5)5 of 10 readers kept every pin |
How to read this table: the Prediction column is frozen as registered and states hypotheses, not results. Status records what was observed. A ✓ or ✗ marks a part scored by its registered script; parts labelled a retrodiction or retrospective re-checked data already in the record, the others were scored on new runs. Unmarked lines are receipts, observed counts outside a registered verdict, or say what is still open. Every registration was committed to the repository before its runs.
10Caveats
Open tools, open PDKs, small blocks. Everything here is LibreLane and OpenROAD on sky130A, on blocks from 321 to 67,877 cells, all standard cells: none has a hard macro or an SRAM. Commercial flows and production blocks may behave differently, and I don’t claim every commercial tool scores runs this way.
Open-source signoff. Magic, KLayout and Netgen at block level, not a foundry deck. LVS compares the layout with the flow’s own netlist, and the formal proof covers the RTL.
The advanced-node checks are small. ASAP7 is a predictive kit, judged at one fast corner with no margins, and its synthesis doesn’t see the clock target; that test covered three designs. GT2N has 72 cells and one corner, I ran one design, and its backside power grid wasn’t built.
Reusable heuristic: try the tightest clock early and often. Claude asked for the tightest clock far more often than Bayesian search did. I turned that habit into a deterministic four-line script. It pins the clock at the tight end of the range and carries over three settings from the highest-scoring starting run. At the final stage it beat plain Bayesian search in 8 of 10 paired races, with a median verified gain of +6.3%, and it makes no model calls during search. The historical 4–4–2 record for Claude’s rules came from a different, older control that only pins the clock.
Choosing an RTL rewrite: speed versus area. The MD5 rewrite reached 1.75× the clock at +19% area, above the +15% area cap. The best version within the cap reached 1.68×. When area is the hard limit, the 1.68× design fits. When clock speed matters more, the 1.75× design gives more speed for more area. Section 09 keeps the full register, including the negative studies.
Power is estimated. The flow’s default power estimate pointed the wrong way on the MD5 rewrite, so for MD5 I simulated switching gate by gate. Elsewhere the energy numbers use default activity.
XTEA is a control loop here, not a cipher. The benchmark’s XTEA is OpenLane’s example RTL, used as shipped; its state machine never reaches the states that write its outputs, so synthesis correctly removes the cipher. Every XTEA run routed a loop of 26 flip-flops whose 65 outputs are constant 0 (the 192 data and key inputs are unconnected), with its clock set by a path from one flip-flop to the output ports. Those clocks are real measurements of the flow, and the clearest case of the bookkeeping in section 03, but not the speed of a cipher. I checked the other 34 blocks I built, and none lost its function; MD5’s 1.75×, the audit, the preset comparison and the 7 nm and 2 nm checks don’t include XTEA. Here are the main numbers it is part of, with and without it:
| Number | As recorded | Without XTEA |
|---|---|---|
| Claude vs Bayesian searchheld-out designs · section 06 | 6 of 7 | 5 of 6 |
| Claude’s rules vs plain searchraces · section 06 | 9 of 10median 1.08× | 7 of 8median 1.08× |
| …on a quarter of the runssection 06 | 8 of 10 | 7 of 8 |
| Winners faster than claimedrace winners · section 01 | 33 of 40 | 25 of 32 |
| Gain from rebuilding againmedian · section 06 | 1.10×50 winners | 1.07×40 winners |
| …when register-limitedmedian · section 06 | 9%33 winners | 6%29 winners |
| Where chains land, law vs claimmedian miss · section 04 | 2.5% vs 4.7% | 2.6% vs 3.3% |
The same records, recounted with XTEA’s runs left out. Every conclusion holds without XTEA, most by a smaller margin.
The law is fitted, and as a forecast it is mixed. Its slopes come from runs I had already seen; the 7 nm side rests on 44 runs of three designs at one corner, and single settings scatter widely around it. Its first registered check, a retrodiction at 7 nm, fell short of its bar, and in its first prospective test its pass/fail calls were as good as any arm’s but its slopes lost to Claude’s readers and a simple I/O rule (section 04). Treat it as a description of the record, not a forecast of slopes.
The reading tests are small. The reading test scored 35 runs from four design families. Runs within a family are not independent, and its slope result held in two of the four families. The pin test used 10 cases on four small designs. The rule tests used five small designs and two seeds. The historical report-informed Opus arm, the plain Bayesian control and the hand-pinned control all come from earlier runs (section 09).
Random search is a strong baseline. At equal runs it beat Bayesian search on two designs, so I don’t credit the 1.2–1.7× to Bayesian search itself.
11Takeaways
- Fix the judge before adding AI. A tuner’s claimed clock is a guess until a build at it passes, and it misses both ways.
- One rebuild per winner is cheap insurance. It runs in parallel and caught every false claim in the audit. Rebuilding past the first pass found a median 10% more clock.
- Slack is not distance. On LibreLane the clock a setting can meet sits about 2.4 slacks from the target after a failing run and 1.4 after a passing one; at 7 nm on OpenROAD it is the other way round. A median, not a judge: its retrodiction fell short of its bar, and in the first prospective test its slack-sign pass/fail calls held up while its slopes were beaten.
- Simple search rules that beat plain Bayesian search. Both Opus-written search rules beat plain Bayesian search in 9 of the same 10 paired races. The median verified clock-frequency gain was +8.0% for the rule written with reports and +10.2% for the rule written from scores alone. A four-line rule beat the same baseline in 8 of 10 races (+6.3% median) without any model calls during search. These results do not show that reading reports causes the gain. They do show that, on these designs, a short, explicit search rule is a practical upgrade over plain Bayesian search.
- Reading the chip predicts how far, not whether. In a registered test, Claude read one routed run's raw record and forecast the clock a chain finally keeps with a median error of 3.7%. Summaries gave 6.7% and a fixed rule 12.2%, across 28 eligible chains. The slack's sign still made more correct calls on whether the first rebuild passes. In a separate retrospective test, learned timing-model coefficients added nothing over summaries or a median-slope rule. The rebuild still decides.
- Next: one matched-build ablation that turns report reading on and off inside the same direct proposer, on held-out designs, scored by fastest passing period and false passes; then larger held-out blocks at 7 nm and 2 nm.
Try it yourself
The farm, the flow settings, the job specs and every design are in the repository at github.com/Avi-Patel-1/beforeroute-farm. Each experiment is a JSON job spec that a GitHub Actions workflow runs inside a pinned LibreLane image, and every test was written down, with its prediction, before its runs.
Citation
@misc{patel2026trueclock,
title = {TrueClock: Recursive AI for Chip Design,
Proven by Rebuilding at Every Predicted Speed},
author = {Patel, Avi},
year = {2026},
howpublished = {\url{https://borrowedtime.dev/}}
}
Notes
- J. Jung et al., METRICS2.1 and Flow Tuning in the IEEE CEDA Robust Design Flow and OpenROAD, ICCAD 2021. AutoTuner’s default score is clock period minus worst slack, and it can tune the clock period too. ↩︎
- EDA-env (Ghose et al., ICCAD 2026, doi:10.1145/3831252.3848500); ORFS-agent’s run database at github.com/ABKGroup/ORFS-Agent, commit 730f1fa. ↩︎
- S. Leibson, A Brief and Personal History of EDA, Part 2: Calma, Applicon, Computervision and the CAD Era. EE Journal, 2024. ↩︎
- O. Coudert, Timing and Design Closure in Physical Design Flows. ISQED 2002. ↩︎
- H.-H. Hsiao, Y.-C. Lu, P. Vanna-Iampikul, S. K. Lim, FastTuner: Transferable Physical Design Parameter Optimization using Fast Reinforcement Learning. ISPD 2024. ↩︎
- ORFS-agent (A. Ghose et al., arXiv:2506.08332); Dr. RTL (W. Fang et al., arXiv:2604.14989); RTLScout (F. Arnold et al., NeurIPS 2026 Workshop on AI for Chip Design, to appear). ↩︎
- T. Akiba et al., Optuna: A Next-generation Hyperparameter Optimization Framework. KDD 2019. ↩︎
- L. T. Clark et al., ASAP7: A 7-nm finFET predictive process design kit. Microelectronics Journal 53, 2016. ↩︎
- D. Jang et al., GT2N: An Open-Source 2nm Nanosheet PDK Enabling Multi-Width/VT Benchmarking. ISCAS 2026. ↩︎
- R. Takehi, J. Teoh, A. Zhang, O. Khattab, Sparks of Weight-Space Programming: LLMs can natively read & write neural network weights. MIT CSAIL, November 2, 2026. ↩︎