55
66#include < algorithm>
77#include < array>
8+ #include < cstdint>
89#include < map>
910#include < memory>
1011#include < set>
@@ -1697,6 +1698,8 @@ void InstanceGrid::checkSetup() const
16971698
16981699 if (top != nullptr ) {
16991700 const int top_idx = top->getNumber ();
1701+ std::map<odb::Rect, int64_t > overlap_area;
1702+ std::set<odb::dbTechLayer*> layers;
17001703 for (auto * master_obs : inst_->getMaster ()->getObstructions ()) {
17011704 auto * obs_layer = master_obs->getTechLayer ();
17021705 if (obs_layer == nullptr ) {
@@ -1707,18 +1710,57 @@ void InstanceGrid::checkSetup() const
17071710 }
17081711 if (obs_layer->getNumber () > top_idx) {
17091712 for (const auto & pin : boxes) {
1710- if (pin.intersects (master_obs->getBox ())) {
1711- getLogger ()->error (
1712- utl::PDN,
1713- 6 ,
1714- " Pins on {} are blocked by obstructions on {} for {}" ,
1715- top->getName (),
1716- obs_layer->getName (),
1717- inst_->getName ());
1713+ const odb::Rect mobs = master_obs->getBox ();
1714+
1715+ if (mobs.intersects (pin)) {
1716+ // Determine level of obstruction
1717+ const odb::Rect overlap = mobs.intersect (pin);
1718+ overlap_area[pin] += overlap.area ();
1719+ layers.insert (obs_layer);
17181720 }
17191721 }
17201722 }
17211723 }
1724+
1725+ if (!overlap_area.empty ()) {
1726+ int64_t total_pin_area = 0 ;
1727+ int64_t total_overlap = 0 ;
1728+ std::string layer_txt;
1729+ for (const auto * layer : layers) {
1730+ if (!layer_txt.empty ()) {
1731+ layer_txt += " , " ;
1732+ }
1733+ layer_txt += layer->getName ();
1734+ }
1735+ for (const auto & [pin, overlap] : overlap_area) {
1736+ const int64_t pinarea = pin.area ();
1737+ total_overlap += overlap;
1738+ total_pin_area += pinarea;
1739+
1740+ if (overlap >= pinarea) {
1741+ // pin completely obstructed
1742+ getLogger ()->error (
1743+ utl::PDN,
1744+ 6 ,
1745+ " {} on {} is blocked by obstructions on {} for {}" ,
1746+ iterm->getMTerm ()->getName (),
1747+ top->getName (),
1748+ layer_txt,
1749+ inst_->getName ());
1750+ }
1751+ }
1752+ const float pct
1753+ = 100 * static_cast <float >(total_overlap) / total_pin_area;
1754+ getLogger ()->warn (utl::PDN,
1755+ 7 ,
1756+ " {} on {} is partially blocked ({:.1f}%) by "
1757+ " obstructions on {} for {}" ,
1758+ iterm->getMTerm ()->getName (),
1759+ top->getName (),
1760+ pct,
1761+ layer_txt,
1762+ inst_->getName ());
1763+ }
17221764 }
17231765 }
17241766}
0 commit comments