The-OpenROAD-Project / The-OpenROAD-Project/OpenROAD

pad: rdl_route gives a different result after write_db/read_db — is assign_io_bump's assignment meant to be session state?

Open
#11,297 1 comment 0 reactions 1 assignee View on GitHub

@gadfort is already working on this.

Since Sep 10, 2026.

pad
Dominant language
Verilog
Stars
3.1k
Forks
1k
Avg merge
2d 23h
Merged PRs (30d)
136

Description

While reading src/pad/src/ICeWall.cpp and src/pad/src/RDLRouter.cpp we noticed that
assign_io_bump's -terminal and -dont_route are recorded in ICeWall::routing_map_, a member
of the command object, and that nothing corresponding is written to the database.
RDLRouter::buildIntialRouteSet then reads that map to decide the shape of the routing problem: an
entry mapping to a terminal gives the bump exactly one destination instead of every terminal on the
net, and a null entry — which is what -dont_route stores — leaves iterm_pairs empty so the bump
gets no routing segment at all.

The effect is that rdl_route produces a different result depending on whether it runs in the same
process as the assign_io_bump calls, with no warning either way.

The reproducer is an existing test, split in two. Taking src/pad/test/rdl_route_assignments.tcl
unmodified:

No differences found.

Now split it at the rdl_route line — everything above it (lines 1–572, ending with the last
assign_io_bump) plus a write_db:

# ... lines 1-572 of rdl_route_assignments.tcl, unchanged ...
write_db [make_result_file "assignments_checkpoint.odb"]

and the rest in a second openroad process:

source "helpers.tcl"
read_db [make_result_file "assignments_checkpoint.odb"]
rdl_route -layer metal10 -width 4 -spacing 4 "DVDD"
set def_file [make_result_file "rdl_route_assignments.def"]
write_def $def_file
diff_files $def_file "rdl_route_assignments.defok"
Differences found at line 2521.

DVDD goes from 226 special-wire lines to 245, and the whole DEF differs by 99 lines. With
-debug PAD Router 2 the routing attempts go from 34 to 43, and the nine extra attempts are
between the nine bumps that carry -dont_route:

assign_io_bump -net DVDD BUMP_5_9  -dont_route
...
assign_io_bump -net DVDD BUMP_7_11 -dont_route

In the second process those nine bumps are routed to each other, because the map that said not to
route them did not survive write_db. We checked whether anything else carries the intent:
on the checkpointed database odb::dbBoolProperty::find(iterm, "RDL_ROUTE") is null both on a
-dont_route bump and on an ordinary one, and dbProperty::getProperties returns nothing for
either the iterm or its instance — the two are indistinguishable once written.

-terminal is stored in the same member and read by the same code, so we would expect it to behave
the same way, but we have not observed it: in rdl_route_assignments_overlapping_iterms the two
nets assigned with -terminal are identical across the checkpoint and only DVDD moves. We mention
it because it shares the channel, not because we have a symptom for it.

Our question is whether this is intended. There is a reading in which it is: assign_io_bump and
rdl_route may be meant as one session, the way add_global_connection and global_connect are,
and persisting a bump-to-pad assignment would add database state that only one tool reads.

If that is the intent, would a diagnostic be welcome — rdl_route warning when the block contains
COVER_BUMP instances but the routing map is empty? That is the case where the result silently
changes, and it is cheap to detect.

If it is not the intent, we would be happy to open a PR. The smallest faithful shape we can see is
a pair of properties on the iterm written by assignBump and read by buildIntialRouteSet,
alongside a test in the existing style — the split above, reusing rdl_route_assignments and its
.defok, with no new library data. We would rather ask first than send a patch that adds
persistent state you deliberately kept out of the database.

Observed on 945a9f48dc6e5cc91d865daa92c45a1094cb682c; we can re-check on master if that would
help.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.