Skip to content

Commit fe6efde

Browse files
committed
Merge remote-tracking branch 'origin/master' into TR-rules
2 parents 0d1370f + a00a575 commit fe6efde

181 files changed

Lines changed: 6200 additions & 5119 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/agents/coding.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@
2525
### Null Safety
2626
- Avoid adding too defensive null checks if the object cannot be null
2727

28+
## Service Interfaces
29+
30+
Abstract interfaces published through `utl::ServiceRegistry` use the
31+
`Service` suffix (e.g. `est::ParasiticsService`, `drt::PinAccessService`).
32+
Each interface lives in its owning module's public `include/<module>/`
33+
directory and is exposed as a small header-only Bazel target that
34+
consumers can depend on without pulling in the full implementation
35+
library. This keeps module dependency graphs acyclic and the decoupling
36+
visible at the build layer.
37+
38+
Note that this is distinct from the `Abstract*` prefix used for
39+
graphics/visualization mock-swappable classes (e.g.
40+
`AbstractSteinerRenderer`); those are inherited for test/headless modes
41+
rather than looked up through a registry.
42+
2843
## Common Coding Mistakes
2944

3045
### OpenROAD Message ID Duplicate Checker

etc/Dockerfile.claude

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#
44
# Usage: see claude.sh at the repo root.
55

6-
ARG fromImage=openroad/ubuntu22.04-dev:latest
6+
# Ubuntu 24.04 provides glibc 2.39, required by the LLVM 20 toolchain
7+
# that Bazel downloads (needs __isoc23_* symbols from glibc >= 2.38).
8+
ARG fromImage=openroad/ubuntu24.04-dev:latest
79

810
FROM ${fromImage}
911

include/ord/OpenRoad.hh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class ICeWall;
108108

109109
namespace utl {
110110
class Logger;
111-
class CallBackHandler;
111+
class ServiceRegistry;
112112
} // namespace utl
113113

114114
namespace dst {
@@ -151,7 +151,7 @@ class OpenRoad
151151

152152
Tcl_Interp* tclInterp() { return tcl_interp_; }
153153
utl::Logger* getLogger() { return logger_; }
154-
utl::CallBackHandler* getCallBackHandler() { return callback_handler_; }
154+
utl::ServiceRegistry* getServiceRegistry() { return service_registry_; }
155155
odb::dbDatabase* getDb() { return db_; }
156156
sta::dbSta* getSta() { return sta_; }
157157
sta::dbNetwork* getDbNetwork();
@@ -288,7 +288,7 @@ class OpenRoad
288288
dft::Dft* dft_ = nullptr;
289289
est::EstimateParasitics* estimate_parasitics_ = nullptr;
290290
web::WebServer* web_server_ = nullptr;
291-
utl::CallBackHandler* callback_handler_ = nullptr;
291+
utl::ServiceRegistry* service_registry_ = nullptr;
292292

293293
int threads_ = 1;
294294

packaging/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ sh_binary(
88
name = "install",
99
srcs = ["//bazel:install.sh"],
1010
data = [":tarfile"],
11+
visibility = ["//visibility:public"],
1112
)
1213

1314
pkg_tar(

src/OpenRoad.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@
8383
#include "tap/MakeTapcell.h"
8484
#include "tap/tapcell.h"
8585
#include "upf/MakeUpf.h"
86-
#include "utl/CallBackHandler.h"
8786
#include "utl/Logger.h"
8887
#include "utl/MakeLogger.h"
8988
#include "utl/Progress.h"
9089
#include "utl/ScopedTemporaryFile.h"
90+
#include "utl/ServiceRegistry.h"
9191
#include "utl/decode.h"
9292
#include "web/MakeWeb.h"
9393
#include "web/web.h"
@@ -150,7 +150,7 @@ OpenRoad::~OpenRoad()
150150
delete web_server_;
151151
delete logger_;
152152
delete verilog_reader_;
153-
delete callback_handler_;
153+
delete service_registry_;
154154
}
155155

156156
sta::dbNetwork* OpenRoad::getDbNetwork()
@@ -195,7 +195,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
195195
// Make components.
196196
utl::Progress::setBatchMode(batch_mode);
197197
logger_ = new utl::Logger(log_filename, metrics_filename);
198-
callback_handler_ = new utl::CallBackHandler(logger_);
198+
service_registry_ = new utl::ServiceRegistry(logger_);
199199
db_->setLogger(logger_);
200200
sta_ = new sta::dbSta(tcl_interp, db_, logger_);
201201
verilog_network_ = new dbVerilogNetwork(sta_);
@@ -204,7 +204,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
204204
antenna_checker_ = new ant::AntennaChecker(db_, logger_);
205205
opendp_ = new dpl::Opendp(db_, logger_);
206206
global_router_ = new grt::GlobalRouter(logger_,
207-
callback_handler_,
207+
service_registry_,
208208
stt_builder_,
209209
db_,
210210
sta_,
@@ -213,7 +213,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
213213
grt::initGui(global_router_, db_, logger_);
214214

215215
estimate_parasitics_ = new est::EstimateParasitics(
216-
logger_, callback_handler_, db_, sta_, stt_builder_, global_router_);
216+
logger_, service_registry_, db_, sta_, stt_builder_, global_router_);
217217
est::initGui(estimate_parasitics_);
218218

219219
resizer_ = new rsz::Resizer(logger_,
@@ -240,7 +240,7 @@ void OpenRoad::init(Tcl_Interp* tcl_interp,
240240
extractor_ = new rcx::Ext(db_, logger_, getVersion());
241241
distributer_ = new dst::Distributed(logger_);
242242
detailed_router_ = new drt::TritonRoute(
243-
db_, logger_, callback_handler_, distributer_, stt_builder_);
243+
db_, logger_, service_registry_, distributer_, stt_builder_);
244244
drt::initGui(detailed_router_);
245245

246246
replace_ = new gpl::Replace(db_, sta_, resizer_, global_router_, logger_);

src/dpl/include/dpl/Opendp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ class Opendp
238238
GridX x_end,
239239
GridY y_end) const;
240240
bool checkMasterSym(unsigned masterSym, unsigned cellOri) const;
241+
bool checkRowPowerCompatible(const Node* cell, GridY y) const;
241242
bool ripUpAndReplace(Node* cell);
242243
bool diamondMove(Node* cell);
243244
bool diamondMove(Node* cell, const GridPt& grid_pt);

src/dpl/src/CheckPlacement.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ bool Opendp::checkInRows(const Node& cell) const
350350
}
351351
}
352352
}
353-
return true;
353+
return !cell.getMaster()->isMultiRow()
354+
|| checkRowPowerCompatible(&cell, grid_rect.ylo);
354355
}
355356

356357
// Return the cell this cell overlaps.

src/dpl/src/Place.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "infrastructure/Grid.h"
2828
#include "infrastructure/Objects.h"
2929
#include "infrastructure/Padding.h"
30+
#include "infrastructure/architecture.h"
3031
#include "infrastructure/network.h"
3132
#include "odb/db.h"
3233
#include "odb/dbTransform.h"
@@ -1089,9 +1090,26 @@ bool Opendp::checkPixels(const Node* cell,
10891090
return false;
10901091
}
10911092

1093+
// For multi-row cells, the bottom-row site/orient check above only covers
1094+
// the bottom row; it doesn't ensure the master's power pin stack lines up
1095+
// with the PDN rail stack across the span. Reject wrong-parity landings.
1096+
if (cell->getMaster()->isMultiRow() && !checkRowPowerCompatible(cell, y)) {
1097+
return false;
1098+
}
1099+
10921100
return drc_engine_->checkDRC(cell, x, y, orient);
10931101
}
10941102

1103+
bool Opendp::checkRowPowerCompatible(const Node* cell, const GridY y) const
1104+
{
1105+
const int row_idx = arch_->find_closest_row(grid_->gridYToDbu(y));
1106+
if (row_idx >= arch_->getNumRows()) {
1107+
return false;
1108+
}
1109+
bool flip = false;
1110+
return arch_->powerCompatible(cell, arch_->getRow(row_idx), flip);
1111+
}
1112+
10951113
bool Opendp::checkMasterSym(unsigned masterSym, unsigned cellOri) const
10961114
{
10971115
using odb::dbOrientType;

src/dpl/src/dbToOpendp.cpp

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
#include <limits>
77
#include <map>
88
#include <memory>
9+
#include <optional>
910
#include <string>
1011
#include <unordered_set>
12+
#include <utility>
1113
#include <vector>
1214

1315
#include "PlacementDRC.h"
@@ -111,6 +113,59 @@ bool bboxIntersectsOuterShell(const Rect& bbox,
111113
});
112114
}
113115

116+
// Look at single-row CORE masters and return a canonical R0-row (topPwr,
117+
// botPwr). Requires top != bot so the convention is unambiguous;
118+
// symmetric-power cells cannot anchor the convention. Returns (UNK, UNK) if
119+
// none found.
120+
std::pair<int, int> inferR0RowPower(const Network* network,
121+
const Grid* grid,
122+
odb::dbBlock* block)
123+
{
124+
for (odb::dbInst* inst : block->getInsts()) {
125+
odb::dbMaster* db_master = inst->getMaster();
126+
if (db_master->getType() != odb::dbMasterType::CORE) {
127+
continue;
128+
}
129+
if (grid->isMultiHeight(db_master)) {
130+
continue;
131+
}
132+
const Master* dpl_master
133+
= const_cast<Network*>(network)->getMaster(db_master);
134+
if (dpl_master == nullptr) {
135+
continue;
136+
}
137+
const int bot = dpl_master->getBottomPowerType();
138+
const int top = dpl_master->getTopPowerType();
139+
if (bot != Architecture::Row::Power_UNK
140+
&& top != Architecture::Row::Power_UNK && bot != top) {
141+
return {top, bot};
142+
}
143+
}
144+
return {Architecture::Row::Power_UNK, Architecture::Row::Power_UNK};
145+
}
146+
147+
// Whether the orientation flips the master's Y axis (swapping top and bottom
148+
// power rails). Only the axis-aligned orientations are expected for standard
149+
// cell rows; rotations return nullopt so row power stays unknown.
150+
std::optional<bool> orientFlipsY(const odb::dbOrientType& orient)
151+
{
152+
using odb::dbOrientType;
153+
switch (orient.getValue()) {
154+
case dbOrientType::MX:
155+
case dbOrientType::R180:
156+
return true;
157+
case dbOrientType::R0:
158+
case dbOrientType::MY:
159+
return false;
160+
case dbOrientType::R90:
161+
case dbOrientType::R270:
162+
case dbOrientType::MXR90:
163+
case dbOrientType::MYR90:
164+
return std::nullopt;
165+
}
166+
return std::nullopt;
167+
}
168+
114169
} // namespace
115170

116171
void Opendp::importDb()
@@ -292,7 +347,8 @@ void Opendp::createArchitecture()
292347
archRow->setSiteWidth(DbuX{site->getWidth()});
293348
archRow->setHeight(DbuY{site->getHeight()});
294349

295-
// Set defaults. Top and bottom power is set below.
350+
// Start with UNK; resolved after all rows are created using an inferred
351+
// R0 row convention.
296352
archRow->setBottomPower(Architecture::Row::Power_UNK);
297353
archRow->setTopPower(Architecture::Row::Power_UNK);
298354

@@ -356,6 +412,29 @@ void Opendp::createArchitecture()
356412
arch_->setPadding(padding_.get());
357413
arch_->setSiteWidth(grid_->getSiteWidth());
358414

415+
// Populate each row's top/bottom power rail from an inferred R0 convention.
416+
// Without this, row power stays Power_UNK and Architecture::powerCompatible
417+
// degenerates to "always true", letting multi-row cells land on wrong-parity
418+
// rows (VDD pin on VSS stripe, etc.).
419+
const auto [ref_r0_top, ref_r0_bot]
420+
= inferR0RowPower(network_.get(), grid_.get(), block);
421+
if (ref_r0_bot != Architecture::Row::Power_UNK) {
422+
for (int r = 0; r < arch_->getNumRows(); r++) {
423+
Architecture::Row* archRow = arch_->getRow(r);
424+
const auto flipped = orientFlipsY(archRow->getOrient());
425+
if (!flipped.has_value()) {
426+
continue; // Rotation — leave as UNK.
427+
}
428+
if (*flipped) {
429+
archRow->setBottomPower(ref_r0_top);
430+
archRow->setTopPower(ref_r0_bot);
431+
} else {
432+
archRow->setBottomPower(ref_r0_bot);
433+
archRow->setTopPower(ref_r0_top);
434+
}
435+
}
436+
}
437+
359438
arch_->postProcess(network_.get());
360439
}
361440

src/dpl/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ or_integration_tests(
4747
mirror2
4848
mirror3
4949
multi_height_one_site_gap_disallow
50+
multi_height_power_align
5051
multi_height_rows
5152
obstruction1
5253
obstruction2

0 commit comments

Comments
 (0)