The-OpenROAD-Project / The-OpenROAD-Project/OpenROAD
mpl: should updateChildrenRealLocation shift IO clusters, whose positions are already absolute?
@joaomai is already working on this.
Since Aug 27, 2026.
- Dominant language
- Verilog
- Stars
- 3.1k
- Forks
- 1k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 136
Description
While evaluating mpl's placement stage we traced a coordinate path we cannot convince ourselves is intended, and we would rather ask than assume. All references are to 945a9f48dc6e5cc91d865daa92c45a1094cb682c.
The chain
Four steps, each reasonable on its own:
-
An IO cluster's position is absolute.
ClusteringEngine::createIOBundlebuilds it fromdie.xMin()/xMax()/yMin()/yMax()and hands it toCluster::setAsIOBundle, which constructs the cluster's ownSoftMacrothere (object.cpp~296).setAsIOPadClusterandsetAsClusterOfUnplacedIOPinsdo the same. -
HierRTLMP::placeChildrenrebases it onto the parent's outline for the annealer's macro list —io_cluster->getX() - outline.xMin()(hier_rtlmp.cpp~1362). That newSoftMacrolives in the localmacrosvector; the cluster's own is untouched. -
updateChildrenShapesAndLocationsdeliberately skips IO clusters (hier_rtlmp.cpp~2193), with a comment explaining that their shapes and locations should not be updated. So the cluster's ownSoftMacrostill holds the absolute position from step 1. -
updateChildrenRealLocationthen adds the outline's origin to every child (hier_rtlmp.cpp~2204).Cluster::setXwrites through tosoft_macro_, and an IO cluster has one — so it becomes absolute + origin.
Why we think it is observable
We first assumed this was latent, because in the mpl regression suite nothing reads an IO cluster's position afterwards. That turned out to be a property of the test designs rather than of mpl:
-max_num_leveldefaults to2;ClusteringEngine::setBaseThresholdsresets it to1only when the design has 150 macros or fewer, or has fixed macros;- every design in
src/mpl/testhas between one and four macros, so all 31 cluster placements we traced are on the root and only the root.
On a two-level tree, placeChildren recurses into a mixed child, and that call reaches createFixedTerminals with a non-null parent->getParent(). It then walks the root's other children — IO clusters among them — and turns each into a fixed terminal from cluster->getCenter(), or from getX/getY/getWidth/getHeight for a cluster of unplaced IO pins. Those are the step-4 coordinates, and they feed the wirelength term of the child cluster's placement.
The offset is the root outline's lower-left corner, i.e. the core's. A core at the die origin makes it zero; a core inset from the die makes it the inset.
What we checked
After placeChildren, nothing else reads a cluster position rather than a HardMacro's:
| stage | reads a cluster position? |
|---|---|
boundary push (pusher.cpp) |
no — macro-cluster boxes, hard-macro boxes, and io_blockages_ |
| orientation correction | no — HardMacro and its dbInst throughout |
commit (updateMacrosOnDb, commitMacroPlacementToDb) |
no — getRealX / getRealY / getOrientation / getBBox |
So createFixedTerminals on a deeper level looks like the only consumer, which is exactly the path the current tests do not exercise.
The question
Is updateChildrenRealLocation meant to shift IO clusters at all? Step 3 excludes them from the shape-and-location update because their geometry is authoritative; step 4 includes them without an equivalent exclusion, and we could not tell from the source whether that is deliberate.
If it is not, we would be glad to contribute a regression case — a design large enough to build a two-level tree, with a core inset from the die and at least one IO bundle, asserting the fixed-terminal positions a deeper placeChildren sees. Happy to shape it however you would find most useful.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.