Example 1: Agent-driven timing repair
After detecting timing violations, the Agent calls iSTA for root-cause diagnosis, iTO for ECO proposals, and iSTA to verify fixes—a complete closed-loop optimization.
Scenario
Post-route WNS = -0.15ns on critical paths. iSTA diagnoses three violating paths: two oversized buffers (resize) and one long detour (local reroute).
Agent decision chain
Step 1: iSTA.diagnose(WNS, path) → root cause: buffer_oversized x2, route_detour x1
Step 2: iTO.propose(resize=2, reroute=1) → 3 candidates
Step 3: Evaluation.gate(candidates) → candidate_2 selected (best WNS+area trade-off)
Step 4: iSTA.verify(candidate_2) → WNS=-0.02ns, PASS
Python implementation
from ieda import AgentClient from ieda.evaluation import Gate client = AgentClient() # Step 1: Diagnose timing root causes timing = client.call("iSTA.analyze", design_ref="post_route_snap") if timing.wns < 0: # Step 2: Get diagnostic & generate ECO diagnosis = client.call("iSTA.diagnose", path=timing.critical_paths[0]) eco = client.call("iTO.propose", diagnosis=diagnosis) # Step 3: Evaluate all candidates through gate for candidate in eco.candidates: result = client.call("iTO.apply", candidate=candidate) gate = Gate.judge(before="post_route_snap", after=result.design_ref) if gate.wns >= -0.05 and gate.drc_count == 0: best_candidate = candidate break # Step 4: Verify and commit verify = client.call("iSTA.verify", design_ref=best_candidate.design_ref) print(f"Timing closed: WNS={verify.wns}ns") client.call("iDB.commit", design_ref=best_candidate.design_ref)
Example 2: Agent-driven placement optimization
After placement, the Agent detects local congestion and timing violations, iterating iPL local optimization with iSTA incremental analysis in a feedback loop.
Scenario
After global iPL placement, iSTA finds a region with both congestion and setup violations. The Agent uses iPL local moves—fine-tuning cell positions to improve congestion and timing with minimal global HPWL impact.
Agent decision chain
Step 1: iPL.place(region) + iSTA.analyze(snap) → congestion hotspot + WNS violation
Step 2: iPL.propose_local_move(hotspot, max_displacement=50um) → 5 candidates
Step 3: iSTA.incremental(candidates, dirty_set) → candidate_3: WNS=-0.01ns, congestion improved 30%
Step 4: iDB.commit(candidate_3) → local optimization complete; global HPWL increased only 0.3%
Python implementation
from ieda import AgentClient client = AgentClient() # Step 1: Global place + analyze place = client.call("iPL.place", design_ref="snap_fp") timing = client.call("iSTA.analyze", design_ref=place.design_ref) # Step 2: Detect hotspot region hotspot = (timing.wns < 0 and place.congestion_map["max_bin"] > 0.85) if hotspot: # Step 3: Iterative local optimization with feedback loop best_hpwl = place.hpwl for iteration in range(5): move = client.call( "iPL.propose_local_move", design_ref=place.design_ref, region=hotspot.bbox, max_displacement_nm=50000, ) incr = client.call( "iSTA.analyze", design_ref=move.design_ref, incremental=True, dirty_set=move.dirty_set, ) if incr.wns >= 0 and move.hpwl <= best_hpwl * 1.05: best_hpwl = min(best_hpwl, move.hpwl) client.call("iDB.commit", design_ref=move.design_ref) print(f"Iteration {iteration}: WNS={incr.wns}, HPWL={move.hpwl}") break
Example 3: Agent full flow
From RTL, the Agent drives the full physical design flow—synthesis, floorplan, power, placement, clock tree, optimization, routing, timing, DRC—deciding at each stage under the Evaluation gate.
Full-flow toolchain
iMap (Synthesis) → iFP (Floorplan) → iPDN (Power) → iPL (Place) → iCTS (Clock) → iTO (Opt) → iRT (Route) → iSTA (Timing) → iDRC (Check)
Between stages the Agent uses the Evaluation gate to proceed or roll back.
Agent role in full flow
The Agent is not a passive script runner—it checks intermediate results, compares candidates, decides rollback or skip (e.g., skip repair if DRC is clean). Agent Planner orchestrates; Runtime manages branches and transactions.
Python implementation (full-flow skeleton)
from ieda import AgentClient from ieda.planner import FlowPlanner client = AgentClient() planner = FlowPlanner(client) # Define the full flow with exit criteria at each stage flow = [ {"tool": "iMap", "op": "synthesize", "gate": {"area": "< 1.2e6"}}, {"tool": "iFP", "op": "floorplan", "gate": {"util": "< 0.80"}}, {"tool": "iPDN", "op": "power_grid", "gate": {"ir_drop": "< 5%"}}, {"tool": "iPL", "op": "place", "gate": {"density": "< 0.85"}}, {"tool": "iCTS", "op": "build_clock", "gate": {"skew": "< 50ps"}}, {"tool": "iTO", "op": "optimize", "gate": {"wns": ">= -0.05"}}, {"tool": "iRT", "op": "route", "gate": {"drc_count": "== 0"}}, {"tool": "iSTA", "op": "signoff", "gate": {"wns": ">= 0"}}, {"tool": "iDRC", "op": "signoff", "gate": {"drc_count": "== 0"}}, ] # Execute flow: Agent Planner handles retry, rollback, branch result = planner.execute( flow=flow, design_ref="riscv_core", auto_recover=True, max_retries_per_stage=3, ) if result.all_stages_passed: print("Full RTL-to-GDS flow completed successfully!") print(f"Final design_ref: {result.design_ref}") else: print(f"Failed at stage: {result.failed_stage}") print(f"Gate failures: {result.gate_failures}")