@@ -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