@@ -520,6 +520,7 @@ 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;
523524 for (auto * check_inst : block->getInsts ()) {
524525 if (check_inst == inst) {
525526 continue ;
@@ -528,6 +529,7 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
528529 continue ;
529530 }
530531 if (check_inst->getMaster ()->isCover ()) {
532+ covers.insert (check_inst);
531533 continue ;
532534 }
533535 const odb::Rect check_rect = check_inst->getBBox ()->getBox ();
@@ -545,13 +547,83 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
545547 continue ;
546548 }
547549
548- if (inst == nullptr ) {
550+ const bool create_inst = inst == nullptr ;
551+ if (create_inst) {
549552 inst = odb::dbInst::create (block, master, corner_name.c_str ());
550553 }
551554
552555 inst->setOrient (row->getOrient ());
553556 inst->setLocation (row_bbox.xMin (), row_bbox.yMin ());
554557 inst->setPlacementStatus (odb::dbPlacementStatus::FIRM);
558+
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) {
611+ if (create_inst) {
612+ logger_->warn (utl::PAD,
613+ 45 ,
614+ " Skipping corner cell generation for {} due to "
615+ " overlapping bump cell" ,
616+ inst->getName ());
617+ odb::dbInst::destroy (inst);
618+ } else {
619+ logger_->warn (utl::PAD,
620+ 46 ,
621+ " Skipping corner cell placement for {} due to "
622+ " overlapping bump cell" ,
623+ inst->getName ());
624+ inst->setPlacementStatus (odb::dbPlacementStatus::UNPLACED);
625+ }
626+ }
555627 }
556628}
557629
0 commit comments