Skip to content

Commit a47d549

Browse files
committed
pad: move check placement to single function
Signed-off-by: Peter Gadfort <[email protected]>
1 parent bba6193 commit a47d549

File tree

2 files changed

+90
-85
lines changed

2 files changed

+90
-85
lines changed

src/pad/include/pad/ICeWall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class ICeWall
160160
odb::dbInst* inst,
161161
const std::map<odb::dbInst*, std::set<odb::dbITerm*>>&
162162
iterm_connections) const;
163+
odb::dbInst* checkInstancePlacement(odb::dbInst* inst, odb::dbRow* row) const;
163164

164165
// Data members
165166
odb::dbDatabase* db_ = nullptr;

src/pad/src/ICeWall.cpp

Lines changed: 89 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,6 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
520520

521521
// Check for instances overlapping the corner site
522522
bool place_inst = true;
523-
std::set<odb::dbInst*> covers;
524523
for (auto* check_inst : block->getInsts()) {
525524
if (check_inst == inst) {
526525
continue;
@@ -529,7 +528,6 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
529528
continue;
530529
}
531530
if (check_inst->getMaster()->isCover()) {
532-
covers.insert(check_inst);
533531
continue;
534532
}
535533
const odb::Rect check_rect = check_inst->getBBox()->getBox();
@@ -556,58 +554,7 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
556554
inst->setLocation(row_bbox.xMin(), row_bbox.yMin());
557555
inst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
558556

559-
// Check if inst overlaps with bumps
560-
std::map<odb::dbTechLayer*, std::set<odb::Rect>> check_shapes;
561-
if (!covers.empty()) {
562-
// populate map as needed
563-
const auto xform = inst->getTransform();
564-
for (auto* obs : inst->getMaster()->getObstructions()) {
565-
odb::Rect obs_rect = obs->getBox();
566-
xform.apply(obs_rect);
567-
check_shapes[obs->getTechLayer()].insert(obs_rect);
568-
}
569-
for (auto* iterm : inst->getITerms()) {
570-
for (const auto& [layer, box] : iterm->getGeometries()) {
571-
check_shapes[layer].insert(box);
572-
}
573-
}
574-
}
575-
576-
bool remove = false;
577-
for (auto* check_inst : covers) {
578-
const auto xform = check_inst->getTransform();
579-
for (auto* obs : check_inst->getMaster()->getObstructions()) {
580-
odb::Rect obs_rect = obs->getBox();
581-
xform.apply(obs_rect);
582-
for (const auto& inst_rect : check_shapes[obs->getTechLayer()]) {
583-
if (inst_rect.intersects(obs_rect)) {
584-
remove = true;
585-
break;
586-
}
587-
}
588-
}
589-
if (remove) {
590-
break;
591-
}
592-
for (auto* iterm : check_inst->getITerms()) {
593-
for (const auto& [layer, box] : iterm->getGeometries()) {
594-
for (const auto& inst_rect : check_shapes[layer]) {
595-
if (inst_rect.intersects(box)) {
596-
remove = true;
597-
break;
598-
}
599-
}
600-
}
601-
if (remove) {
602-
break;
603-
}
604-
}
605-
if (remove) {
606-
break;
607-
}
608-
}
609-
610-
if (remove) {
557+
if (checkInstancePlacement(inst, row) != nullptr) {
611558
if (create_inst) {
612559
logger_->warn(utl::PAD,
613560
45,
@@ -1202,38 +1149,27 @@ int ICeWall::placeInstance(odb::dbRow* row,
12021149
row_bbox.yMax() / dbus);
12031150
}
12041151

1205-
// check for overlaps with other instances
1206-
for (auto* check_inst : block->getInsts()) {
1207-
if (check_inst == inst) {
1208-
continue;
1209-
}
1210-
if (!check_inst->isFixed()) {
1211-
continue;
1212-
}
1213-
if (check_inst->getMaster()->isCover()) {
1214-
continue;
1215-
}
1152+
odb::dbInst* check_inst = checkInstancePlacement(inst, row);
1153+
if (!allow_overlap && check_inst != nullptr) {
12161154
const odb::Rect check_rect = check_inst->getBBox()->getBox();
1217-
if (!allow_overlap && inst_rect.overlaps(check_rect)) {
1218-
logger_->error(utl::PAD,
1219-
1,
1220-
"Unable to place {} ({}) at ({:.3f}um, {:.3f}um) - "
1221-
"({:.3f}um, {:.3f}um) as it "
1222-
"overlaps with {} ({}) at ({:.3f}um, {:.3f}um) - "
1223-
"({:.3f}um, {:.3f}um)",
1224-
inst->getName(),
1225-
inst->getMaster()->getName(),
1226-
inst_rect.xMin() / dbus,
1227-
inst_rect.yMin() / dbus,
1228-
inst_rect.xMax() / dbus,
1229-
inst_rect.yMax() / dbus,
1230-
check_inst->getName(),
1231-
check_inst->getMaster()->getName(),
1232-
check_rect.xMin() / dbus,
1233-
check_rect.yMin() / dbus,
1234-
check_rect.xMax() / dbus,
1235-
check_rect.yMax() / dbus);
1236-
}
1155+
logger_->error(utl::PAD,
1156+
1,
1157+
"Unable to place {} ({}) at ({:.3f}um, {:.3f}um) - "
1158+
"({:.3f}um, {:.3f}um) as it "
1159+
"overlaps with {} ({}) at ({:.3f}um, {:.3f}um) - "
1160+
"({:.3f}um, {:.3f}um)",
1161+
inst->getName(),
1162+
inst->getMaster()->getName(),
1163+
inst_rect.xMin() / dbus,
1164+
inst_rect.yMin() / dbus,
1165+
inst_rect.xMax() / dbus,
1166+
inst_rect.yMax() / dbus,
1167+
check_inst->getName(),
1168+
check_inst->getMaster()->getName(),
1169+
check_rect.xMin() / dbus,
1170+
check_rect.yMin() / dbus,
1171+
check_rect.xMax() / dbus,
1172+
check_rect.yMax() / dbus);
12371173
}
12381174
inst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
12391175

@@ -1973,4 +1909,72 @@ void ICeWall::routeRDLDebugNet(const char* net)
19731909
}
19741910
}
19751911

1912+
odb::dbInst* ICeWall::checkInstancePlacement(odb::dbInst* inst,
1913+
odb::dbRow* row) const
1914+
{
1915+
std::set<odb::dbInst*> covers;
1916+
auto* block = getBlock();
1917+
if (block) {
1918+
for (auto* check_inst : block->getInsts()) {
1919+
if (check_inst == inst) {
1920+
continue;
1921+
}
1922+
if (!check_inst->isFixed()) {
1923+
continue;
1924+
}
1925+
if (check_inst->getMaster()->isCover()) {
1926+
covers.insert(check_inst);
1927+
continue;
1928+
}
1929+
}
1930+
}
1931+
1932+
// Check if inst overlaps with bumps
1933+
std::map<odb::dbTechLayer*, std::set<std::pair<odb::Rect, odb::dbNet*>>>
1934+
check_shapes;
1935+
if (!covers.empty()) {
1936+
// populate map as needed
1937+
const auto xform = inst->getTransform();
1938+
for (auto* obs : inst->getMaster()->getObstructions()) {
1939+
odb::Rect obs_rect = obs->getBox();
1940+
xform.apply(obs_rect);
1941+
check_shapes[obs->getTechLayer()].emplace(obs_rect, nullptr);
1942+
}
1943+
for (auto* iterm : inst->getITerms()) {
1944+
for (const auto& [layer, box] : iterm->getGeometries()) {
1945+
check_shapes[layer].emplace(box, iterm->getNet());
1946+
}
1947+
}
1948+
}
1949+
1950+
for (odb::dbInst* check_inst : covers) {
1951+
const auto xform = check_inst->getTransform();
1952+
for (auto* obs : check_inst->getMaster()->getObstructions()) {
1953+
odb::Rect obs_rect = obs->getBox();
1954+
xform.apply(obs_rect);
1955+
for (const auto& [inst_rect, check_net] :
1956+
check_shapes[obs->getTechLayer()]) {
1957+
if (inst_rect.intersects(obs_rect)) {
1958+
return check_inst;
1959+
}
1960+
}
1961+
}
1962+
1963+
for (auto* iterm : check_inst->getITerms()) {
1964+
for (const auto& [layer, box] : iterm->getGeometries()) {
1965+
for (const auto& [inst_rect, check_net] : check_shapes[layer]) {
1966+
const bool nets_match
1967+
= iterm->getNet() == check_net
1968+
&& (check_net != nullptr || iterm->getNet() != nullptr);
1969+
if (!nets_match && inst_rect.intersects(box)) {
1970+
return check_inst;
1971+
}
1972+
}
1973+
}
1974+
}
1975+
}
1976+
1977+
return nullptr;
1978+
}
1979+
19761980
} // namespace pad

0 commit comments

Comments
 (0)