Skip to content

dbSta: read cross-die parasitics on 3D-IC designs - #11189

Open
dsengupta0628 wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:stitch_spef_natively
Open

dbSta: read cross-die parasitics on 3D-IC designs#11189
dsengupta0628 wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:stitch_spef_natively

Conversation

@dsengupta0628

Copy link
Copy Markdown
Contributor

Problem

A cross-die net is one physical wire, but the 3D RCX flow writes it as three SPEF pieces — each die's wiring, plus the die-to-die bond resistor:

graph LR
    D["driver"] ---|"top.die1.spef"| PA["bump pad"]
    PA ---|"top.bonds.spef"| PB["bump pad"]
    PB ---|"top.die2.spef"| R["receiver"]
    style PA fill:#fef7e0,stroke:#f9ab00
    style PB fill:#fef7e0,stroke:#f9ab00
Loading

Reading all three left the pieces on three different nets. The delay calculator fetches parasitics by the driver pin's net, so it saw one third of the wire and cross-die paths came out optimistic.

Fix

The top chip already holds a dbChipNet per bond. That is the net above both dies, and the net the bonds SPEF is written against. Three dbNetwork overrides now ascend to it, so all three pieces land on one net and every driver finds them:

function before after
net(const Pin*) on a chiplet boundary port nullptr the dbChipNet above
highestConnectedNet() on a bonded die net the die net the dbChipNet above
highestNetAbove() on a bonded die net the die net the dbChipNet above

net() is what SpefReader::dspfBegin climbs to decide which net owns a parasitic network, so that one makes the merge happen. highestConnectedNet() is what Parasitics::findParasiticNet canonicalizes through, so that one makes the driver find it. highestNetAbove() decides whether a parasitic node is "external" and has to give the same answer, or every node of a merged network is dropped.

Usage

read_3dbx top.3dbx
read_spef top.bonds.spef                        ;# top scope, read FIRST
read_spef -path die_1  top.die1.spef
read_spef -path die_2 top.die2.spef
report_checks ...                               ;# carries cross-die wire RC

Order matters. A top-scope read replaces a net's parasitic network where a -path read merges into it, so reading the bonds SPEF last silently discards the die contributions. Documented in dbNetwork.hh; making it order-independent is a SpefReader change and out of scope here.

Test

src/dbSta/test/3dic_spef — reuses the existing 3dic_cross two-chiplet fixture with three hand-written SPEFs: 2 fF near side, 2 kΩ bond, 100 fF far side. The far-side capacitance sits behind the bond, so the driver only sees it if the merge worked: arrival 0.15 ns → 0.41 ns, and its load reads 102.97 fF in the golden.

Uses hand-written SPEFs rather than extraction, so it does not depend on the unmerged rcx half of #11124.

Verified: full dbSta and est suites pass (2560 tests); dmp_ceff_elmore, arnoldi and prima all run on the merged network.

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass.
  • My code follows the repository's formatting guidelines.
  • I have included tests to prevent regressions.
  • I have signed my commits (DCO).

Related Issues

#10664

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
@dsengupta0628 dsengupta0628 self-assigned this Aug 20, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances 3DIC support in dbNetwork by correctly mapping and resolving chip-nets above chiplet boundaries, which prevents stack overflows and crashes during parasitic annotation and delay calculation. It also adds a regression test suite for cross-die parasitics. The review feedback highlights a potential safety issue in the three-argument overload of staToDb, where a dbChipNet could be unsafely cast to a dbNet* without validation, and suggests a robust fallback mechanism in highestNetAbove.

Comment on lines 6139 to 6141
staToDb(net, dbnet, modnet);

if (dbnet) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The three-argument overload staToDb(const Net* net, dbNet*& dbnet, dbModNet*& modnet) does not currently check if net is a dbChipNet before casting it to dbNet*. If net is a dbChipNet, dbnet will be populated with a pointer to a dbChipNet object but typed as dbNet*. This is unsafe and can cause undefined behavior or crashes if callers of the three-argument overload attempt to use dbnet as a real dbNet.

To make this robust, please:

  1. Update staToDb(const Net* net, dbNet*& dbnet, dbModNet*& modnet) to only set dbnet if the object type is odb::dbNetObj (similar to the fix in the single-argument staToDb).
  2. Update highestNetAbove to handle the case where net is a dbChipNet (and thus both dbnet and modnet are null) by returning net as a fallback.
  staToDb(net, dbnet, modnet);

  if (net && !dbnet && !modnet) {
    return net;
  }

  if (dbnet) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of Gemini's points are already handled. Assessment:

Point 1 — incorrect. The 3-arg staToDb never blind-casts. It reads getObjectType() and branches, with an explicit dbChipNetObj case that leaves both outputs null. Note the else clause errors with ORD-2034 on anything unexpected, so an unhandled type would be loud, not silent. Nothing to fix.

Point 2 — already the behavior, via a different mechanism. You propose an early if (net && !dbnet && !modnet) return net;. The function already ends in return net;, so a chip net falls through both blocks and comes back unchanged. The suggested code is functionally identical — it would be dead.

@dsengupta0628
dsengupta0628 marked this pull request as ready for review August 20, 2026 02:33
@dsengupta0628
dsengupta0628 requested a review from a team as a code owner August 20, 2026 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant