From da204039386dcf8bf1800a60a2b43d42bb307e7d Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Tue, 9 Apr 2024 15:22:47 +0200 Subject: [PATCH 1/6] closes The-OpenROAD-Project/OpenROAD#4904 Signed-off-by: osamahammad21 --- src/drt/src/db/tech/frConstraint.cc | 2 + src/drt/src/db/tech/frConstraint.h | 39 +++++++++++ src/drt/src/db/tech/frLayer.h | 37 ++++++++++ src/drt/src/frBaseTypes.h | 1 + src/drt/src/gc/FlexGC_cut.cpp | 96 ++++++++++++++++++++++++++ src/drt/src/gc/FlexGC_impl.h | 3 + src/drt/src/gc/FlexGC_main.cpp | 4 +- src/drt/src/io/io.cpp | 100 ++++++++++++++++++++++++++++ src/drt/test/fixture.cpp | 21 ++++++ src/drt/test/fixture.h | 6 ++ src/drt/test/gcTest.cpp | 27 ++++++++ 11 files changed, 335 insertions(+), 1 deletion(-) diff --git a/src/drt/src/db/tech/frConstraint.cc b/src/drt/src/db/tech/frConstraint.cc index d3faf739bba..8a80639bf87 100644 --- a/src/drt/src/db/tech/frConstraint.cc +++ b/src/drt/src/db/tech/frConstraint.cc @@ -154,6 +154,8 @@ std::string frConstraint::getViolName() const return "KeepOutZone"; case frConstraintTypeEnum::frcSpacingRangeConstraint: return "SpacingRange"; + case frConstraintTypeEnum::frcLef58EnclosureConstraint: + return "Lef58Enclosure"; } return ""; } diff --git a/src/drt/src/db/tech/frConstraint.h b/src/drt/src/db/tech/frConstraint.h index 2d53fed540d..43fe96e47ea 100644 --- a/src/drt/src/db/tech/frConstraint.h +++ b/src/drt/src/db/tech/frConstraint.h @@ -2186,6 +2186,45 @@ class frLef58KeepOutZoneConstraint : public frConstraint private: odb::dbTechLayerKeepOutZoneRule* db_rule_; }; + +class frLef58EnclosureConstraint : public frConstraint +{ + public: + frLef58EnclosureConstraint(odb::dbTechLayerCutEnclosureRule* ruleIn) + : db_rule_(ruleIn) + { + } + void setCutClassIdx(int in) { cut_class_idx_ = in; } + int getCutClassIdx() const { return cut_class_idx_; } + bool isAbove() const { return db_rule_->isAbove(); } + bool isBelow() const { return db_rule_->isBelow(); } + bool isValidOverhang(frCoord endOverhang, frCoord sideOverhang) const + { + if (db_rule_->getType() == odb::dbTechLayerCutEnclosureRule::ENDSIDE) { + return endOverhang >= db_rule_->getFirstOverhang() + && sideOverhang >= db_rule_->getSecondOverhang(); + } else { + return (endOverhang >= db_rule_->getFirstOverhang() + && sideOverhang >= db_rule_->getSecondOverhang()) + || (endOverhang >= db_rule_->getSecondOverhang() + && sideOverhang >= db_rule_->getFirstOverhang()); + } + } + frCoord getWidth() const { return db_rule_->getMinWidth(); } + void report(utl::Logger* logger) const override + { + logger->report("LEF58_ENCLOSURE"); + } + frConstraintTypeEnum typeId() const override + { + return frConstraintTypeEnum::frcLef58EnclosureConstraint; + } + + private: + odb::dbTechLayerCutEnclosureRule* db_rule_; + int cut_class_idx_; +}; + class frNonDefaultRule { public: diff --git a/src/drt/src/db/tech/frLayer.h b/src/drt/src/db/tech/frLayer.h index bcbeeac1a68..a0f274d976b 100644 --- a/src/drt/src/db/tech/frLayer.h +++ b/src/drt/src/db/tech/frLayer.h @@ -703,6 +703,41 @@ class frLayer return lef58DefaultInterCutSpacingTableConstraint_; } + void addLef58EnclosureConstraint(frLef58EnclosureConstraint* con) + { + int cutClassIdx = con->getCutClassIdx(); + if (lef58EncConstraints_.size() <= cutClassIdx) { + lef58EncConstraints_.resize(cutClassIdx + 1); + } + lef58EncConstraints_[cutClassIdx][con->getWidth()].push_back(con); + } + + bool hasLef58EnclosureConstraint(int cutClassIdx) const + { + if (cutClassIdx < 0 || lef58EncConstraints_.size() <= cutClassIdx) { + return false; + } + return !lef58EncConstraints_.at(cutClassIdx).empty(); + } + + std::vector getLef58EnclosureConstraints( + int cutClassIdx, + frCoord width) const + { + // initialize with empty vector + std::vector result; + // check class and size match first + if (hasLef58EnclosureConstraint(cutClassIdx)) { + const auto& mmap = lef58EncConstraints_.at(cutClassIdx); + auto it = mmap.upper_bound(width); + if (it != mmap.begin()) { + it--; + result = it->second; + } + } + return result; + } + void setDrEolSpacingConstraint(frCoord width, frCoord space, frCoord within) { drEolCon_.eolWidth = width; @@ -795,6 +830,8 @@ class frLayer std::vector spacingRangeConstraints_; std::vector twForbiddenSpcConstraints_; + std::vector>> + lef58EncConstraints_; drEolSpacingConstraint drEolCon_; friend class io::Parser; diff --git a/src/drt/src/frBaseTypes.h b/src/drt/src/frBaseTypes.h index c743f5c21fc..1b2e4301049 100644 --- a/src/drt/src/frBaseTypes.h +++ b/src/drt/src/frBaseTypes.h @@ -205,6 +205,7 @@ enum class frConstraintTypeEnum frcMetalWidthViaConstraint, frcLef58AreaConstraint, frcLef58KeepOutZoneConstraint, + frcLef58EnclosureConstraint, frcSpacingRangeConstraint }; diff --git a/src/drt/src/gc/FlexGC_cut.cpp b/src/drt/src/gc/FlexGC_cut.cpp index 83b66a1ad08..8fa2b48b5e8 100644 --- a/src/drt/src/gc/FlexGC_cut.cpp +++ b/src/drt/src/gc/FlexGC_cut.cpp @@ -691,4 +691,100 @@ void FlexGCWorker::Impl::checkMetalWidthViaTable() } } +void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* viaRect, + gcRect* encRect) +{ + auto layer = getTech()->getLayer(viaRect->getLayerNum()); + auto cutClassIdx = layer->getCutClassIdx(viaRect->width(), viaRect->length()); + bool above = encRect->getLayerNum() > viaRect->getLayerNum(); + frCoord sideOverhang = 0; + frCoord endOverhang = 0; + sideOverhang = std::min(gtl::xh(*encRect) - gtl::xh(*viaRect), + gtl::xl(*viaRect) - gtl::xl(*encRect)); + endOverhang = std::min(gtl::yh(*encRect) - gtl::yh(*viaRect), + gtl::yl(*viaRect) - gtl::yl(*encRect)); + if (gtl::delta(*viaRect, gtl::orientation_2d_enum::HORIZONTAL) + > gtl::delta(*viaRect, gtl::orientation_2d_enum::VERTICAL)) { + std::swap(sideOverhang, endOverhang); + } + frLef58EnclosureConstraint* lastCon = nullptr; + for (auto con : + layer->getLef58EnclosureConstraints(cutClassIdx, encRect->width())) { + if (con->isAbove() && !above) { + continue; + } + if (con->isBelow() && above) { + continue; + } + if (con->isValidOverhang(endOverhang, sideOverhang)) { + return; // valid overhangs + } + lastCon = con; + } + Rect markerBox(gtl::xl(*viaRect), + gtl::yl(*viaRect), + gtl::xh(*viaRect), + gtl::yh(*viaRect)); + auto net = viaRect->getNet(); + auto marker = std::make_unique(); + marker->setBBox(markerBox); + marker->setLayerNum(encRect->getLayerNum()); + marker->setConstraint(lastCon); + marker->addSrc(net->getOwner()); + frCoord llx = gtl::xl(*encRect); + frCoord lly = gtl::yl(*encRect); + frCoord urx = gtl::xh(*encRect); + frCoord ury = gtl::xh(*encRect); + marker->addAggressor(net->getOwner(), + std::make_tuple(encRect->getLayerNum(), + Rect(llx, lly, urx, ury), + encRect->isFixed())); + llx = gtl::xl(*viaRect); + lly = gtl::yl(*viaRect); + urx = gtl::xh(*viaRect); + ury = gtl::xh(*viaRect); + marker->addVictim(net->getOwner(), + std::make_tuple(viaRect->getLayerNum(), + Rect(llx, lly, urx, ury), + viaRect->isFixed())); + marker->addSrc(net->getOwner()); + addMarker(std::move(marker)); + return; +} +void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* rect) +{ + if (rect->isFixed()) { + return; + } + auto layer = getTech()->getLayer(rect->getLayerNum()); + auto cutClassIdx = layer->getCutClassIdx(rect->width(), rect->length()); + if (!layer->hasLef58EnclosureConstraint(cutClassIdx)) { + return; + } + auto getEnclosure = [this](gcRect* rect, frLayerNum layerNum) { + std::vector> results; + auto& workerRegionQuery = getWorkerRegionQuery(); + workerRegionQuery.queryMaxRectangle(*rect, layerNum, results); + gcRect* encRect = nullptr; + for (auto& [box, ptr] : results) { + if (ptr->getNet() != rect->getNet()) { + continue; + } + if (!gtl::contains(*ptr, *rect)) { + continue; + } + if (encRect == nullptr) { + encRect = ptr; + } else if (ptr->width() > encRect->width()) { + encRect = ptr; + } + } + return encRect; + }; + gcRect* belowEnc = getEnclosure(rect, layer->getLayerNum() - 1); + checkLef58Enclosure_main(rect, belowEnc); + gcRect* aboveEnc = getEnclosure(rect, layer->getLayerNum() + 1); + checkLef58Enclosure_main(rect, aboveEnc); +} + } // namespace drt diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index 137386f9687..377676d7cff 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -486,6 +486,9 @@ class FlexGCWorker::Impl bool checkLef58CutSpacing_spc_hasTwoCuts_helper( gcRect* rect, frLef58CutSpacingConstraint* con); + // LEF58_ENCLOSURE + void checkLef58Enclosure_main(gcRect* rect); + void checkLef58Enclosure_main(gcRect* via, gcRect* enc); // LEF58_KEEPOUTZONE void checKeepOutZone_main(gcRect* rect, frLef58KeepOutZoneConstraint* con); diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index b3a00eac39b..ac301b6896a 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -3519,6 +3519,7 @@ void FlexGCWorker::Impl::checkCutSpacing() for (auto& pin : targetNet_->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { checkCutSpacing_main(maxrect.get()); + checkLef58Enclosure_main(maxrect.get()); } } } @@ -3537,6 +3538,7 @@ void FlexGCWorker::Impl::checkCutSpacing() for (auto& pin : net->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { checkCutSpacing_main(maxrect.get()); + checkLef58Enclosure_main(maxrect.get()); } } } @@ -4036,7 +4038,7 @@ int FlexGCWorker::Impl::main() checkMetalShape(false); // check eolSpc based on polygon checkMetalEndOfLine(); - // check CShort, cutSpc + // check CShort, cutSpc, enclosure checkCutSpacing(); // check SpacingTable Influence checkMetalSpacingTableInfluence(); diff --git a/src/drt/src/io/io.cpp b/src/drt/src/io/io.cpp index c22c9f6c25c..b75099a37a7 100644 --- a/src/drt/src/io/io.cpp +++ b/src/drt/src/io/io.cpp @@ -442,6 +442,7 @@ void io::Parser::createNDR(odb::dbTechNonDefaultRule* ndr) fnd->addViaRule(design_->getTech()->getViaRule(via->getName()), z); } } + void io::Parser::setNDRs(odb::dbDatabase* db) { for (auto ndr : db->getTech()->getNonDefaultRules()) { @@ -459,6 +460,7 @@ void io::Parser::setNDRs(odb::dbDatabase* db) layer->getLayerNum() / 2 - 1)); } } + void io::Parser::getSBoxCoords(odb::dbSBox* box, frCoord& beginX, frCoord& beginY, @@ -1825,6 +1827,103 @@ void io::Parser::setCutLayerProperties(odb::dbTechLayer* layer, tech_->addUConstraint(std::move(uCon)); tmpLayer->addKeepOutZoneConstraint(rptr); } + for (auto rule : layer->getTechLayerCutEnclosureRules()) { + if (rule->getType() == odb::dbTechLayerCutEnclosureRule::EOL) { + logger_->warn( + DRT, + 340, + "LEF58_ENCLOSURE EOL is not supported. Skipping for layer {}", + layer->getName()); + continue; + } + if (rule->getType() == odb::dbTechLayerCutEnclosureRule::HORZ_AND_VERT) { + logger_->warn(DRT, + 341, + "LEF58_ENCLOSURE HORIZONTAL/VERTICAL is not supported. " + "Skipping for layer {}", + layer->getName()); + continue; + } + if (rule->isIncludeAbutted()) { + logger_->warn(DRT, + 342, + "LEF58_ENCLOSURE INCLUDEABUTTED is not supported. Skipping " + "for layer {}", + layer->getName()); + continue; + } + if (rule->isOffCenterLine()) { + logger_->warn(DRT, + 343, + "LEF58_ENCLOSURE OFFCENTERLINE is not supported. Skipping " + "for layer {}", + layer->getName()); + continue; + } + if (rule->isLengthValid()) { + logger_->warn( + DRT, + 344, + "LEF58_ENCLOSURE LENGTH is not supported. Skipping for layer {}", + layer->getName()); + continue; + } + if (rule->isExtraCutValid()) { + logger_->warn( + DRT, + 345, + "LEF58_ENCLOSURE EXTRACUT is not supported. Skipping for layer {}", + layer->getName()); + continue; + } + if (rule->isRedundantCutValid()) { + logger_->warn(DRT, + 346, + "LEF58_ENCLOSURE REDUNDANTCUT is not supported. Skipping " + "for layer {}", + layer->getName()); + continue; + } + if (rule->isParallelValid()) { + logger_->warn( + DRT, + 347, + "LEF58_ENCLOSURE PARALLEL is not supported. Skipping for layer {}", + layer->getName()); + continue; + } + if (rule->isConcaveCornersValid()) { + logger_->warn(DRT, + 348, + "LEF58_ENCLOSURE CONCAVECORNERS is not supported. Skipping " + "for layer {}", + layer->getName()); + continue; + } + if (!rule->isCutClassValid()) { + logger_->warn(DRT, + 349, + "LEF58_ENCLOSURE with no CUTCLASS is not supported. " + "Skipping for layer {}", + layer->getName()); + continue; + } + if (!rule->isWidthValid()) { + logger_->warn(DRT, + 350, + "LEF58_ENCLOSURE with no WIDTH is not supported. Skipping " + "for layer {}", + layer->getName()); + continue; + } + std::unique_ptr uCon + = std::make_unique(rule); + auto rptr = static_cast(uCon.get()); + rptr->setCutClassIdx( + tmpLayer->getCutClassIdx(rule->getCutClass()->getName())); + tech_->addUConstraint(std::move(uCon)); + tmpLayer->addLef58EnclosureConstraint(rptr); + } } void io::Parser::addDefaultMasterSliceLayer() @@ -3452,6 +3551,7 @@ void io::Writer::updateTrackAssignment(odb::dbBlock* block) } } } + void io::Writer::updateDbAccessPoints(odb::dbBlock* block, odb::dbTech* db_tech) { for (auto ap : block->getAccessPoints()) { diff --git a/src/drt/test/fixture.cpp b/src/drt/test/fixture.cpp index 15b71ecb17b..538f24dc741 100644 --- a/src/drt/test/fixture.cpp +++ b/src/drt/test/fixture.cpp @@ -555,6 +555,27 @@ void Fixture::makeLef58TwoWiresForbiddenSpc( design->getTech()->addUConstraint(std::move(con)); } +frLef58EnclosureConstraint* Fixture::makeLef58EnclosureConstrainut( + frLayerNum layer_num, + int cut_class_idx, + frCoord width, + frCoord firstOverhang, + frCoord secondOverhang) +{ + auto layer = design->getTech()->getLayer(layer_num); + auto dbRule = odb::dbTechLayerCutEnclosureRule::create(layer->getDbLayer()); + auto con = std::make_unique(dbRule); + auto rptr = con.get(); + rptr->setCutClassIdx(cut_class_idx); + dbRule->setMinWidth(width); + dbRule->setFirstOverhang(firstOverhang); + dbRule->setSecondOverhang(secondOverhang); + dbRule->setType(odb::dbTechLayerCutEnclosureRule::DEFAULT); + layer->addLef58EnclosureConstraint(rptr); + design->getTech()->addUConstraint(std::move(con)); + return rptr; +} + void Fixture::makeMetalWidthViaMap(frLayerNum layer_num, odb::dbMetalWidthViaMap* dbRule) { diff --git a/src/drt/test/fixture.h b/src/drt/test/fixture.h index 0fd3dd06a2b..0fe7b1f320a 100644 --- a/src/drt/test/fixture.h +++ b/src/drt/test/fixture.h @@ -155,6 +155,12 @@ class Fixture frLayerNum layer_num, odb::dbTechLayerTwoWiresForbiddenSpcRule* dbRule); + frLef58EnclosureConstraint* makeLef58EnclosureConstrainut( + frLayerNum layer_num, + int cut_class_idx, + frCoord width, + frCoord firstOverhang, + frCoord secondOverhang); void makeMinimumCut(frLayerNum layerNum, frCoord width, frCoord length, diff --git a/src/drt/test/gcTest.cpp b/src/drt/test/gcTest.cpp index 4f9cf7a1f81..1bc5a476048 100644 --- a/src/drt/test/gcTest.cpp +++ b/src/drt/test/gcTest.cpp @@ -1396,6 +1396,33 @@ BOOST_AUTO_TEST_CASE(twowires_forbidden_spc) BOOST_TEST(markers.size() == 1); } +BOOST_AUTO_TEST_CASE(lef58_enclosure) +{ + // Setup + addLayer(design->getTech(), "v2", dbTechLayerType::CUT); + addLayer(design->getTech(), "m2", dbTechLayerType::ROUTING); + makeCutClass(3, "Vx", 100, 200); + makeLef58EnclosureConstrainut(3, 0, 0, 0, 0); + makeLef58EnclosureConstrainut(3, 0, 200, 100, 50); + + frViaDef* vd = makeViaDef("v", 3, {0, 0}, {200, 100}); + + frNet* n1 = makeNet("n1"); + makeVia(vd, n1, {0, 0}); + makePathseg(n1, 4, {-50, 50}, {250, 50}, 200); + + runGC(); + // BELOW ENC VALID, ABOVE ENCLOSURE VIOLATING + auto& markers = worker.getMarkers(); + BOOST_TEST(markers.size() == 1); + if (!markers.empty()) { + testMarker(markers[0].get(), + 4, + frConstraintTypeEnum::frcLef58EnclosureConstraint, + Rect(0, 0, 200, 100)); + } +} + BOOST_AUTO_TEST_SUITE_END(); } // namespace drt From bc2a93b4e390481130c1de59738a7e84d10ebfb7 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Thu, 11 Apr 2024 20:19:12 +0200 Subject: [PATCH 2/6] drt: fixes enclosure rule Signed-off-by: osamahammad21 --- src/drt/src/db/tech/frConstraint.h | 4 +-- src/drt/src/db/tech/frLayer.h | 43 +++++++++++++++++++++--------- src/drt/src/gc/FlexGC_cut.cpp | 30 +++++++++++---------- src/drt/src/io/io.cpp | 8 ------ 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/drt/src/db/tech/frConstraint.h b/src/drt/src/db/tech/frConstraint.h index 43fe96e47ea..0419f0d3b0d 100644 --- a/src/drt/src/db/tech/frConstraint.h +++ b/src/drt/src/db/tech/frConstraint.h @@ -2196,8 +2196,8 @@ class frLef58EnclosureConstraint : public frConstraint } void setCutClassIdx(int in) { cut_class_idx_ = in; } int getCutClassIdx() const { return cut_class_idx_; } - bool isAbove() const { return db_rule_->isAbove(); } - bool isBelow() const { return db_rule_->isBelow(); } + bool isAboveOnly() const { return db_rule_->isAbove(); } + bool isBelowOnly() const { return db_rule_->isBelow(); } bool isValidOverhang(frCoord endOverhang, frCoord sideOverhang) const { if (db_rule_->getType() == odb::dbTechLayerCutEnclosureRule::ENDSIDE) { diff --git a/src/drt/src/db/tech/frLayer.h b/src/drt/src/db/tech/frLayer.h index a0f274d976b..44f17a5c95a 100644 --- a/src/drt/src/db/tech/frLayer.h +++ b/src/drt/src/db/tech/frLayer.h @@ -705,30 +705,45 @@ class frLayer void addLef58EnclosureConstraint(frLef58EnclosureConstraint* con) { - int cutClassIdx = con->getCutClassIdx(); - if (lef58EncConstraints_.size() <= cutClassIdx) { - lef58EncConstraints_.resize(cutClassIdx + 1); + auto addToLef58EncConstraints + = [](std::vector< + std::map>>& + lef58EncConstraints, + frLef58EnclosureConstraint* con) { + int cutClassIdx = con->getCutClassIdx(); + if (lef58EncConstraints.size() <= cutClassIdx) { + lef58EncConstraints.resize(cutClassIdx + 1); + } + lef58EncConstraints[cutClassIdx][con->getWidth()].push_back(con); + }; + if (!con->isAboveOnly()) { + addToLef58EncConstraints(belowLef58EncConstraints_, con); + } + if (!con->isBelowOnly()) { + addToLef58EncConstraints(aboveLef58EncConstraints_, con); } - lef58EncConstraints_[cutClassIdx][con->getWidth()].push_back(con); } - bool hasLef58EnclosureConstraint(int cutClassIdx) const + bool hasLef58EnclosureConstraint(int cutClassIdx, bool above) const { - if (cutClassIdx < 0 || lef58EncConstraints_.size() <= cutClassIdx) { + auto& lef58EncConstraints + = above ? aboveLef58EncConstraints_ : belowLef58EncConstraints_; + if (cutClassIdx < 0 || lef58EncConstraints.size() <= cutClassIdx) { return false; } - return !lef58EncConstraints_.at(cutClassIdx).empty(); + return !lef58EncConstraints.at(cutClassIdx).empty(); } - std::vector getLef58EnclosureConstraints( - int cutClassIdx, - frCoord width) const + std::vector + getLef58EnclosureConstraints(int cutClassIdx, frCoord width, bool above) const { // initialize with empty vector std::vector result; // check class and size match first - if (hasLef58EnclosureConstraint(cutClassIdx)) { - const auto& mmap = lef58EncConstraints_.at(cutClassIdx); + if (hasLef58EnclosureConstraint(cutClassIdx, above)) { + auto& lef58EncConstraints + = above ? aboveLef58EncConstraints_ : belowLef58EncConstraints_; + const auto& mmap = lef58EncConstraints.at(cutClassIdx); auto it = mmap.upper_bound(width); if (it != mmap.begin()) { it--; @@ -831,7 +846,9 @@ class frLayer std::vector twForbiddenSpcConstraints_; std::vector>> - lef58EncConstraints_; + aboveLef58EncConstraints_; + std::vector>> + belowLef58EncConstraints_; drEolSpacingConstraint drEolCon_; friend class io::Parser; diff --git a/src/drt/src/gc/FlexGC_cut.cpp b/src/drt/src/gc/FlexGC_cut.cpp index 8fa2b48b5e8..6106ddea63c 100644 --- a/src/drt/src/gc/FlexGC_cut.cpp +++ b/src/drt/src/gc/FlexGC_cut.cpp @@ -708,18 +708,12 @@ void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* viaRect, std::swap(sideOverhang, endOverhang); } frLef58EnclosureConstraint* lastCon = nullptr; - for (auto con : - layer->getLef58EnclosureConstraints(cutClassIdx, encRect->width())) { - if (con->isAbove() && !above) { - continue; - } - if (con->isBelow() && above) { - continue; - } + for (auto con : layer->getLef58EnclosureConstraints( + cutClassIdx, encRect->width(), above)) { + lastCon = con; if (con->isValidOverhang(endOverhang, sideOverhang)) { return; // valid overhangs } - lastCon = con; } Rect markerBox(gtl::xl(*viaRect), gtl::yl(*viaRect), @@ -758,7 +752,11 @@ void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* rect) } auto layer = getTech()->getLayer(rect->getLayerNum()); auto cutClassIdx = layer->getCutClassIdx(rect->width(), rect->length()); - if (!layer->hasLef58EnclosureConstraint(cutClassIdx)) { + bool hasAboveConstraints + = layer->hasLef58EnclosureConstraint(cutClassIdx, true); + bool hasBelowConstraints + = layer->hasLef58EnclosureConstraint(cutClassIdx, false); + if (!hasAboveConstraints && !hasBelowConstraints) { return; } auto getEnclosure = [this](gcRect* rect, frLayerNum layerNum) { @@ -781,10 +779,14 @@ void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* rect) } return encRect; }; - gcRect* belowEnc = getEnclosure(rect, layer->getLayerNum() - 1); - checkLef58Enclosure_main(rect, belowEnc); - gcRect* aboveEnc = getEnclosure(rect, layer->getLayerNum() + 1); - checkLef58Enclosure_main(rect, aboveEnc); + if (hasBelowConstraints) { + gcRect* belowEnc = getEnclosure(rect, layer->getLayerNum() - 1); + checkLef58Enclosure_main(rect, belowEnc); + } + if (hasAboveConstraints) { + gcRect* aboveEnc = getEnclosure(rect, layer->getLayerNum() + 1); + checkLef58Enclosure_main(rect, aboveEnc); + } } } // namespace drt diff --git a/src/drt/src/io/io.cpp b/src/drt/src/io/io.cpp index b75099a37a7..804552c21c2 100644 --- a/src/drt/src/io/io.cpp +++ b/src/drt/src/io/io.cpp @@ -1908,14 +1908,6 @@ void io::Parser::setCutLayerProperties(odb::dbTechLayer* layer, layer->getName()); continue; } - if (!rule->isWidthValid()) { - logger_->warn(DRT, - 350, - "LEF58_ENCLOSURE with no WIDTH is not supported. Skipping " - "for layer {}", - layer->getName()); - continue; - } std::unique_ptr uCon = std::make_unique(rule); auto rptr = static_cast(uCon.get()); From 70e2c44fc33984ff8403bbd06d7bc58501fcbb02 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 15 Apr 2024 19:56:39 +0200 Subject: [PATCH 3/6] update regression tests ok logs Signed-off-by: osamahammad21 --- src/drt/test/ndr_vias1.ok | 10 ++++++++++ src/drt/test/ndr_vias2.ok | 10 ++++++++++ src/drt/test/top_level_term.ok | 10 ++++++++++ src/drt/test/top_level_term2.ok | 10 ++++++++++ src/grt/test/pin_access1.ok | 10 ++++++++++ src/grt/test/pin_access2.ok | 10 ++++++++++ 6 files changed, 60 insertions(+) diff --git a/src/drt/test/ndr_vias1.ok b/src/drt/test/ndr_vias1.ok index bfa36782820..ad8ce8ad5b2 100644 --- a/src/drt/test/ndr_vias1.ok +++ b/src/drt/test/ndr_vias1.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 1 pins. [INFO ODB-0131] Created 66 components and 347 component-terminals. [INFO ODB-0133] Created 8 nets and 54 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR diff --git a/src/drt/test/ndr_vias2.ok b/src/drt/test/ndr_vias2.ok index 3e1961c1374..4336794a5d7 100644 --- a/src/drt/test/ndr_vias2.ok +++ b/src/drt/test/ndr_vias2.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 1 pins. [INFO ODB-0131] Created 66 components and 347 component-terminals. [INFO ODB-0133] Created 8 nets and 54 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR diff --git a/src/drt/test/top_level_term.ok b/src/drt/test/top_level_term.ok index 711adb06ebe..e247f20f16b 100644 --- a/src/drt/test/top_level_term.ok +++ b/src/drt/test/top_level_term.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 1 pins. [INFO ODB-0131] Created 4 components and 24 component-terminals. [INFO ODB-0133] Created 1 nets and 4 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR diff --git a/src/drt/test/top_level_term2.ok b/src/drt/test/top_level_term2.ok index f60a90da3ea..2bedc1b2d08 100644 --- a/src/drt/test/top_level_term2.ok +++ b/src/drt/test/top_level_term2.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 3 pins. [INFO ODB-0131] Created 4 components and 24 component-terminals. [INFO ODB-0133] Created 1 nets and 4 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR diff --git a/src/grt/test/pin_access1.ok b/src/grt/test/pin_access1.ok index de7dbdb3f30..806e34e67ed 100644 --- a/src/grt/test/pin_access1.ok +++ b/src/grt/test/pin_access1.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 1 pins. [INFO ODB-0131] Created 170 components and 1258 component-terminals. [INFO ODB-0133] Created 15 nets and 72 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR diff --git a/src/grt/test/pin_access2.ok b/src/grt/test/pin_access2.ok index dcf7bfc9b61..392b85af1f6 100644 --- a/src/grt/test/pin_access2.ok +++ b/src/grt/test/pin_access2.ok @@ -5,6 +5,16 @@ [INFO ODB-0131] Created 1360 components and 6650 component-terminals. [INFO ODB-0132] Created 2 special nets and 0 connections. [INFO ODB-0133] Created 411 nets and 1210 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR From 2a5820509c4c7ac12510244d21c72983582340ed Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Tue, 16 Apr 2024 16:04:51 +0200 Subject: [PATCH 4/6] drt: update obstruction ok Signed-off-by: osamahammad21 --- src/drt/test/obstruction.ok | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/drt/test/obstruction.ok b/src/drt/test/obstruction.ok index 66094adb514..bb050813f66 100644 --- a/src/drt/test/obstruction.ok +++ b/src/drt/test/obstruction.ok @@ -4,6 +4,16 @@ [INFO ODB-0130] Created 1 pins. [INFO ODB-0131] Created 4 components and 24 component-terminals. [INFO ODB-0133] Created 1 nets and 4 connections. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 [INFO DRT-0167] List of default vias: Layer via default via: M1M2_PR From 9f033ae806d94178f2cde75ae62698e6ecc6cbd5 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Tue, 16 Apr 2024 20:10:59 +0200 Subject: [PATCH 5/6] drt: fix missing << frcLef58EnclosureConstraint Signed-off-by: osamahammad21 --- src/drt/src/frBaseTypes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drt/src/frBaseTypes.cpp b/src/drt/src/frBaseTypes.cpp index 558e125e49b..ec9a8140ef7 100644 --- a/src/drt/src/frBaseTypes.cpp +++ b/src/drt/src/frBaseTypes.cpp @@ -297,6 +297,8 @@ std::ostream& operator<<(std::ostream& os, frConstraintTypeEnum type) return os << "frcLef58TwoWiresForbiddenSpcConstraint"; case frConstraintTypeEnum::frcLef58ForbiddenSpcConstraint: return os << "frcLef58ForbiddenSpcConstraint"; + case frConstraintTypeEnum::frcLef58EnclosureConstraint: + return os << "frcLef58EnclosureConstraint"; } return os << "Bad frConstraintTypeEnum"; } From ce3e573002dad4021b3ddcf19f35fa1423adc82a Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Tue, 16 Apr 2024 21:12:38 +0200 Subject: [PATCH 6/6] drt: clang-tidy suggestions Signed-off-by: osamahammad21 --- src/drt/src/db/tech/frConstraint.h | 9 ++++----- src/drt/src/gc/FlexGC_cut.cpp | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/drt/src/db/tech/frConstraint.h b/src/drt/src/db/tech/frConstraint.h index 0cd578b7635..082f554129c 100644 --- a/src/drt/src/db/tech/frConstraint.h +++ b/src/drt/src/db/tech/frConstraint.h @@ -2240,12 +2240,11 @@ class frLef58EnclosureConstraint : public frConstraint if (db_rule_->getType() == odb::dbTechLayerCutEnclosureRule::ENDSIDE) { return endOverhang >= db_rule_->getFirstOverhang() && sideOverhang >= db_rule_->getSecondOverhang(); - } else { - return (endOverhang >= db_rule_->getFirstOverhang() - && sideOverhang >= db_rule_->getSecondOverhang()) - || (endOverhang >= db_rule_->getSecondOverhang() - && sideOverhang >= db_rule_->getFirstOverhang()); } + return (endOverhang >= db_rule_->getFirstOverhang() + && sideOverhang >= db_rule_->getSecondOverhang()) + || (endOverhang >= db_rule_->getSecondOverhang() + && sideOverhang >= db_rule_->getFirstOverhang()); } frCoord getWidth() const { return db_rule_->getMinWidth(); } void report(utl::Logger* logger) const override diff --git a/src/drt/src/gc/FlexGC_cut.cpp b/src/drt/src/gc/FlexGC_cut.cpp index 6106ddea63c..e4222e539dc 100644 --- a/src/drt/src/gc/FlexGC_cut.cpp +++ b/src/drt/src/gc/FlexGC_cut.cpp @@ -743,7 +743,6 @@ void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* viaRect, viaRect->isFixed())); marker->addSrc(net->getOwner()); addMarker(std::move(marker)); - return; } void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* rect) {