Skip to content

[Bug] Detailed router: regional repair only activates when violations <= 100 — inverted condition leaves dense violation fields without joint repair (DR diverges) #198

Description

@WilliamHHL

Title: [Bug] Detailed router: regional repair only activates when violations
are <= 100 — inverted condition leaves dense violation fields without joint
repair (DR diverges)

Self checks

  • I have searched existing issues, including closed issues.
  • I have read the documentation and development guide.
  • This is a bug report, not a question, feature request, or usage discussion.
  • I will include logs, command output, or reproducer files where they help diagnose the issue.
  • I have removed secrets, private paths, tokens, and other sensitive information from the report.

ECC version

ecc 1f910c3 (openecos-projects/ecc) + ecc-tools f6ee10a, dreamplace 308dcd35
(frozen M1 toolchain; the buggy line is unchanged on current main).

Affected area

Routing (iRT detailed router)

Environment

  • OS: Ubuntu 26.04 LTS, x86_64
  • PDK: ICS55 (icsprout55-pdk)
  • Design: ~94k-cell SoC with two SRAM macros, util 0.65, MET1-5 routing

Steps to reproduce

  1. Run the RTL2GDS flow on any block-scale design whose detail-route first
    iteration leaves more than 100 violations (e.g. ~116k in our case).
  2. Observe the per-iteration log line:
    setDRIterParam] regional_repair: 0 (violations: 116233, threshold: 100)
  3. Watch the end-of-iteration violation table across iterations.

Expected behavior

The regional-repair mechanism — iRT's only joint multi-net repair (rip up all
nets overlapping a violation region and re-solve them together, per
routeDRRegionalRepair) — should engage when violations are NUMEROUS, i.e.
whenever violation_num > threshold.

Actual behavior

DetailedRouter.cpp:199:

dr_iter_param.set_regional_repair(iter > 1 && violation_num > threshold);   // our fix
// baseline:
// dr_iter_param.set_regional_repair(iter > 1 && 0 < violation_num
//                                  && violation_num <= threshold);        // threshold = 100

The baseline comparison is INVERTED: regional repair only activates when
violations are <= 100 (design nearly clean), and NEVER for dense violation
fields — exactly when coordinated repair is needed. All iterations 2-9 on
every run therefore used only the single-net greedy churn path
(updateTaskSchedule selects one net per violation), which in dense pockets
net-ADDS violations:

  • old-netlist run k00: end-DRC 554,844 -> 957,592 (+73%) -> 1,126,568 (+18%)
    — router diverges, never converges
  • safe-netlist run n01: 117,744 -> 178,447 (+52%) -> 242,803 (+36%)

After the one-line flip, regional repair engages from iteration 2
(regional_repair: 1 (violations: 114288, threshold: 100)) and the series
converges:

  • n02: 114,288 -> 99,610 (-12.8%) -> 95,753 (-3.9%) -> 94,711 (-1.1%)
  • n04 (with layout levers): 106,951 -> 90,669 -> 87,202 -> 86,520
  • n10: 100,170 -> 83,781 -> 80,071 -> 78,610 -> 77,604

Suggested fix

Flip the comparison to violation_num > threshold (one line). The threshold
semantics ("activate the expensive joint repair only when there are enough
violations to justify it") match TritonRoute-style repair heuristics.

Related (to file separately)

  1. buildGuidePenaltyMap gate: repair reroutes never follow GRT guides
    (guide_ratio <= 0 || !initial_routing || routed_times > 0 returns early
    in every reroute) — tested, effect neutral in our runs but semantically
    suspect.
  2. updateTaskSchedule selects only ONE net per violation (a break), so
    conflict partners are never ripped in the same round; combined with the
    rip-then-route-one-net-at-a-time flow in routeDRBox, dense pockets
    freeze (measured: 92% of iteration-4 violations already existed at
    iteration 1). Proposed two-phase rip-up fix — being validated in a local
    build before filing.

Environment notes

  • The design also had the floorplan/density issue family (ecc#155,
    ecc-dreamplace#31) addressed separately; this bug is independent — it
    reproduces with a correct, macro-inclusive die.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions