Skip to content

Commit f4f68a3

Browse files
authored
Merge pull request #10123 from gadfort/check-overlaps
pad: check overlap layers on placement checks
2 parents 9aa5818 + ec3ccb3 commit f4f68a3

57 files changed

Lines changed: 1223 additions & 90 deletions

Some content is hidden

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

src/mpl/test/fixed_covers.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[INFO ODB-0227] LEF file: ./Nangate45_io/dummy_pads.lef, created 29 library cells
2+
[INFO ODB-0227] LEF file: ./Nangate45_io/dummy_pads.lef, created 30 library cells
33
[INFO ODB-0227] LEF file: ./testcases/orientation_improve1.lef, created 10 library cells
44
[INFO ODB-0128] Design: boundary_push1
55
[INFO ODB-0131] Created 152 components and 904 component-terminals.

src/mpl/test/io_pads1.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 29 library cells
2+
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 30 library cells
33
[INFO ODB-0227] LEF file: testcases/macro_only.lef, created 9 library cells
44
[INFO ODB-0128] Design: io_pads1
55
[INFO ODB-0130] Created 1 pins.

src/mpl/test/macros_without_pins1.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[INFO ODB-0227] LEF file: ./Nangate45_io/dummy_pads.lef, created 29 library cells
2+
[INFO ODB-0227] LEF file: ./Nangate45_io/dummy_pads.lef, created 30 library cells
33
[INFO ODB-0227] LEF file: ./testcases/orientation_improve1.lef, created 10 library cells
44
[INFO ODB-0128] Design: boundary_push1
55
[INFO ODB-0131] Created 402 components and 2402 component-terminals.

src/pad/src/ICeWall.cpp

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -518,33 +518,6 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
518518

519519
const odb::Rect row_bbox = row->getBBox();
520520

521-
// Check for instances overlapping the corner site
522-
bool place_inst = true;
523-
for (auto* check_inst : block->getInsts()) {
524-
if (check_inst == inst) {
525-
continue;
526-
}
527-
if (!check_inst->isFixed()) {
528-
continue;
529-
}
530-
if (check_inst->getMaster()->isCover()) {
531-
continue;
532-
}
533-
const odb::Rect check_rect = check_inst->getBBox()->getBox();
534-
if (row_bbox.overlaps(check_rect)) {
535-
place_inst = false;
536-
break;
537-
}
538-
}
539-
if (!place_inst) {
540-
logger_->warn(
541-
utl::PAD,
542-
44,
543-
"Skipping corner cell placement in {} due to overlapping instances",
544-
row->getName());
545-
continue;
546-
}
547-
548521
const bool create_inst = inst == nullptr;
549522
if (create_inst) {
550523
inst = odb::dbInst::create(block, master, corner_name.c_str());
@@ -554,20 +527,20 @@ void ICeWall::placeCorner(odb::dbMaster* master, int ring_index)
554527
inst->setLocation(row_bbox.xMin(), row_bbox.yMin());
555528
inst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
556529

557-
const CheckerOnlyPadPlacer checker(logger_, block, row);
530+
const CheckerOnlyPadPlacer checker(logger_, block, row, {inst});
558531
if (!checker.check(inst)) {
559532
if (create_inst) {
560533
logger_->warn(utl::PAD,
561534
45,
562535
"Skipping corner cell generation for {} due to "
563-
"overlapping bump cell",
536+
"overlapping instances",
564537
inst->getName());
565538
odb::dbInst::destroy(inst);
566539
} else {
567540
logger_->warn(utl::PAD,
568541
46,
569542
"Skipping corner cell placement for {} due to "
570-
"overlapping bump cell",
543+
"overlapping instances",
571544
inst->getName());
572545
inst->setPlacementStatus(odb::dbPlacementStatus::UNPLACED);
573546
}

src/pad/src/PadPlacer.cpp

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ PadPlacer::PadPlacer(utl::Logger* logger,
3737
{
3838
populateInstWidths();
3939
populateObstructions();
40+
41+
addInstsOverlapCache(insts);
4042
}
4143

4244
void PadPlacer::populateInstWidths()
@@ -398,8 +400,10 @@ void PadPlacer::populateObstructions()
398400
covers.insert(check_inst);
399401
continue;
400402
}
401-
instance_obstructions_.insert(
402-
{check_inst->getBBox()->getBox(), check_inst});
403+
404+
instance_obstructions_.insert({check_inst->getBBox()->getBox(),
405+
getInstanceOutline(check_inst),
406+
check_inst});
403407
}
404408
}
405409
}
@@ -411,9 +415,83 @@ void PadPlacer::populateObstructions()
411415
}
412416
}
413417

418+
std::optional<odb::Polygon> PadPlacer::getMasterOutline(
419+
odb::dbMaster* master) const
420+
{
421+
std::vector<odb::Rect> master_obs;
422+
for (auto* obs : master->getObstructions()) {
423+
auto* layer = obs->getTechLayer();
424+
if (layer != nullptr) {
425+
if (layer->getType() != odb::dbTechLayerType::OVERLAP) {
426+
continue;
427+
}
428+
master_obs.push_back(obs->getBox());
429+
}
430+
}
431+
432+
if (master_obs.empty()) {
433+
return std::nullopt;
434+
}
435+
436+
if (master_obs.size() == 1) {
437+
return odb::Polygon(master_obs.front());
438+
}
439+
440+
const auto overlaps = odb::Polygon::merge(master_obs);
441+
if (overlaps.size() == 1) {
442+
return overlaps.front();
443+
}
444+
445+
return std::nullopt;
446+
}
447+
448+
std::optional<odb::Polygon> PadPlacer::getInstanceOutline(
449+
odb::dbInst* inst) const
450+
{
451+
const auto checker = master_overlap_cache_.find(inst->getMaster());
452+
if (checker != master_overlap_cache_.end()) {
453+
if (!checker->second) {
454+
return std::nullopt;
455+
}
456+
457+
odb::Polygon poly = checker->second.value();
458+
const odb::dbTransform xform = inst->getTransform();
459+
xform.apply(poly);
460+
return poly;
461+
}
462+
463+
const auto master_outline = getMasterOutline(inst->getMaster());
464+
if (!master_outline) {
465+
return std::nullopt;
466+
}
467+
468+
const odb::dbTransform xform = inst->getTransform();
469+
odb::Polygon poly = master_outline.value();
470+
xform.apply(poly);
471+
return poly;
472+
}
473+
474+
void PadPlacer::addInstsOverlapCache(const std::vector<odb::dbInst*>& insts)
475+
{
476+
for (auto* inst : insts) {
477+
addInstOverlapCache(inst);
478+
}
479+
}
480+
481+
void PadPlacer::addInstOverlapCache(odb::dbInst* inst)
482+
{
483+
if (master_overlap_cache_.find(inst->getMaster())
484+
!= master_overlap_cache_.end()) {
485+
return;
486+
}
487+
master_overlap_cache_[inst->getMaster()]
488+
= getMasterOutline(inst->getMaster());
489+
}
490+
414491
void PadPlacer::addInstanceObstructions(odb::dbInst* inst)
415492
{
416-
instance_obstructions_.insert({inst->getBBox()->getBox(), inst});
493+
instance_obstructions_.insert(
494+
{inst->getBBox()->getBox(), getInstanceOutline(inst), inst});
417495
if (inst->getMaster()->isCover()) {
418496
for (const auto& [layer, shapes] : getInstanceObstructions(inst)) {
419497
term_obstructions_[layer].insert(shapes.begin(), shapes.end());
@@ -426,6 +504,8 @@ PadPlacer::checkInstancePlacement(odb::dbInst* inst,
426504
bool return_intersect) const
427505
{
428506
const odb::Rect inst_rect = inst->getBBox()->getBox();
507+
const std::optional<odb::Polygon> inst_poly = getInstanceOutline(inst);
508+
429509
for (auto itr = blockage_obstructions_.qbegin(
430510
boost::geometry::index::intersects(inst_rect));
431511
itr != blockage_obstructions_.qend();
@@ -446,11 +526,29 @@ PadPlacer::checkInstancePlacement(odb::dbInst* inst,
446526
boost::geometry::index::intersects(inst_rect));
447527
itr != instance_obstructions_.qend();
448528
itr++) {
449-
const auto& [check_rect, check_inst] = *itr;
529+
const auto& [check_rect, check_poly, check_inst] = *itr;
450530
if (check_rect.overlaps(inst_rect)) {
451531
if (check_inst == inst) {
452532
continue;
453533
}
534+
if (check_poly && inst_poly) {
535+
// Both have overlap polygons, check them for a more accurate result
536+
if (!boost::geometry::intersects(*check_poly, *inst_poly)) {
537+
continue;
538+
}
539+
} else if (check_poly) {
540+
// Only the obstruction has an overlap polygon, check it for a more
541+
// accurate result
542+
if (!boost::geometry::intersects(inst_rect, *check_poly)) {
543+
continue;
544+
}
545+
} else if (inst_poly) {
546+
// Only the instance has an overlap polygon, check it for a more
547+
// accurate result
548+
if (!boost::geometry::intersects(check_rect, *inst_poly)) {
549+
continue;
550+
}
551+
}
454552
debugPrint(getLogger(),
455553
utl::PAD,
456554
"Check",
@@ -570,10 +668,12 @@ void UniformPadPlacer::place()
570668

571669
///////////////////////////////////////////
572670

573-
CheckerOnlyPadPlacer::CheckerOnlyPadPlacer(utl::Logger* logger,
574-
odb::dbBlock* block,
575-
odb::dbRow* row)
576-
: PadPlacer(logger, block, {}, odb::Direction2D::North, row)
671+
CheckerOnlyPadPlacer::CheckerOnlyPadPlacer(
672+
utl::Logger* logger,
673+
odb::dbBlock* block,
674+
odb::dbRow* row,
675+
const std::vector<odb::dbInst*>& insts)
676+
: PadPlacer(logger, block, insts, odb::Direction2D::North, row)
577677
{
578678
}
579679

src/pad/src/PadPlacer.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class PadPlacer
6464
int getTotalInstWidths() const;
6565

6666
protected:
67-
using InstObsValue = std::pair<odb::Rect, odb::dbInst*>;
67+
using InstObsValue
68+
= std::tuple<odb::Rect, std::optional<odb::Polygon>, odb::dbInst*>;
6869
using TermObsValue = std::tuple<odb::Rect, odb::dbNet*, odb::dbInst*>;
6970
using BlockageObsTree
7071
= boost::geometry::index::rtree<odb::Rect,
@@ -95,10 +96,14 @@ class PadPlacer
9596
}
9697
LayerTermObsTree getInstanceObstructions(odb::dbInst* inst,
9798
bool bloat = false) const;
99+
std::optional<odb::Polygon> getInstanceOutline(odb::dbInst* inst) const;
98100
void addInstanceObstructions(odb::dbInst* inst);
99101

100102
private:
101103
void populateInstWidths();
104+
void addInstOverlapCache(odb::dbInst* inst);
105+
void addInstsOverlapCache(const std::vector<odb::dbInst*>& inst);
106+
std::optional<odb::Polygon> getMasterOutline(odb::dbMaster* master) const;
102107

103108
utl::Logger* logger_;
104109
odb::dbBlock* block_;
@@ -113,14 +118,18 @@ class PadPlacer
113118
BlockageObsTree blockage_obstructions_;
114119
InstObsTree instance_obstructions_;
115120
LayerTermObsTree term_obstructions_;
121+
122+
// overlap cache
123+
std::map<odb::dbMaster*, std::optional<odb::Polygon>> master_overlap_cache_;
116124
};
117125

118126
class CheckerOnlyPadPlacer : public PadPlacer
119127
{
120128
public:
121129
CheckerOnlyPadPlacer(utl::Logger* logger,
122130
odb::dbBlock* block,
123-
odb::dbRow* row);
131+
odb::dbRow* row,
132+
const std::vector<odb::dbInst*>& insts);
124133
~CheckerOnlyPadPlacer() override = default;
125134

126135
void place() override {};

src/pad/test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ COMPULSORY_TESTS = [
2626
"place_bondpad_stagger",
2727
"place_corners_avoid_bumps",
2828
"place_corners_avoid_overlap",
29+
"place_corners_avoid_overlap_with_overlapobs",
2930
"place_io_terminals_empty_call",
3031
"place_pad",
3132
"place_pad_hv",

src/pad/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ or_integration_tests(
1919
place_bondpad_stagger
2020
place_corners_avoid_bumps
2121
place_corners_avoid_overlap
22+
place_corners_avoid_overlap_with_overlapobs
2223
place_io_terminals_empty_call
2324
place_pad
2425
place_pad_hv

src/pad/test/assign_bumps.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 29 library cells
2+
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 30 library cells
33
[INFO ODB-0128] Design: soc_bsg_black_parrot
44
[INFO ODB-0130] Created 135 pins.
55
[INFO ODB-0131] Created 267 components and 2277 component-terminals.

src/pad/test/assign_bumps_two_pins.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
2-
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 29 library cells
2+
[INFO ODB-0227] LEF file: Nangate45_io/dummy_pads.lef, created 30 library cells
33
[INFO ODB-0128] Design: soc_bsg_black_parrot
44
[INFO ODB-0130] Created 135 pins.
55
[INFO ODB-0131] Created 267 components and 2277 component-terminals.

0 commit comments

Comments
 (0)