@@ -2101,87 +2101,48 @@ void FlexGCWorker::Impl::checkMetalShape_lef58Area(gcPin* pin)
21012101 }
21022102
21032103 auto poly = pin->getPolygon ();
2104- auto layer_idx = poly->getLayerNum ();
2104+ const auto layer_idx = poly->getLayerNum ();
21052105 auto layer = getTech ()->getLayer (layer_idx);
21062106
21072107 if (!layer->hasLef58AreaConstraint ()) {
21082108 return ;
21092109 }
21102110
2111- auto constraints = layer->getLef58AreaConstraints ();
2112-
2113- auto sort_cmp
2114- = [](const frLef58AreaConstraint* a, const frLef58AreaConstraint* b) {
2115- auto a_rule = a->getODBRule ();
2116- auto b_rule = b->getODBRule ();
2117-
2118- return a_rule->getRectWidth () < b_rule->getRectWidth ();
2119- };
2120-
2121- // sort constraints to ensure the smallest rect width will have
2122- // preference above other rect width statements
2123- std::ranges::sort (constraints, sort_cmp);
2124-
2125- bool check_rect_width = true ;
2126-
2127- for (auto con : constraints) {
2111+ gtl::rectangle_data<frCoord> bbox;
2112+ gtl::extents (bbox, *pin->getPolygon ());
2113+ const odb::Rect bbox2 (
2114+ gtl::xl (bbox), gtl::yl (bbox), gtl::xh (bbox), gtl::yh (bbox));
2115+ if (!drWorker_->getDrcBox ().contains (bbox2)) {
2116+ return ;
2117+ }
2118+ const frCoord width = bbox2.minDXDY ();
2119+ const auto curr_area = gtl::area (*poly);
2120+ // iterate through rectwidth constraints first
2121+ for (auto con : layer->getLef58AreaConstraintsRectWidth ()) {
2122+ odb::dbTechLayerAreaRule* db_rule = con->getODBRule ();
2123+ if (width < db_rule->getRectWidth ()) {
2124+ auto min_area = db_rule->getArea ();
2125+ if (curr_area < min_area
2126+ && checkMetalShape_lef58Area_rectWidth (poly, db_rule)) {
2127+ checkMetalShape_addPatch (pin, min_area);
2128+ }
2129+ // if any rectwidth constraint is satisfied, return
2130+ return ;
2131+ }
2132+ }
2133+ // Iterate through area constraints which are sorted by area in a descending
2134+ // order
2135+ for (auto con : layer->getLef58AreaConstraints ()) {
21282136 odb::dbTechLayerAreaRule* db_rule = con->getODBRule ();
21292137 auto min_area = db_rule->getArea ();
2130- auto curr_area = gtl::area (*poly);
21312138
21322139 if (curr_area >= min_area) {
2133- continue ;
2134- }
2135-
2136- gtl::rectangle_data<frCoord> bbox;
2137- gtl::extents (bbox, *pin->getPolygon ());
2138- odb::Rect bbox2 (gtl::xl (bbox), gtl::yl (bbox), gtl::xh (bbox), gtl::yh (bbox));
2139- if (!drWorker_->getDrcBox ().contains (bbox2)) {
2140- continue ;
2141- }
2142- for (auto & edges : pin->getPolygonEdges ()) {
2143- for (auto & edge : edges) {
2144- if (edge->isFixed ()) {
2145- continue ;
2146- }
2147- }
2140+ break ;
21482141 }
2149-
2150- if (checkMetalShape_lef58Area_exceptRectangle (poly, db_rule)) {
2151- // add patch only when the poly is not a rect
2152- checkMetalShape_addPatch (pin, min_area);
2153- } else if (check_rect_width
2154- && checkMetalShape_lef58Area_rectWidth (
2155- poly, db_rule, check_rect_width)) {
2156- // add patch only if poly is rect and its width is less than or equal to
2157- // rectWidth value on constraint
2158- checkMetalShape_addPatch (pin, min_area);
2159- } else if (db_rule->getExceptMinWidth () != 0 ) {
2160- logger_->warn (
2161- DRT ,
2162- 311 ,
2163- " Unsupported branch EXCEPTMINWIDTH in PROPERTY LEF58_AREA." );
2164- } else if (db_rule->getExceptEdgeLength () != 0
2165- || db_rule->getExceptEdgeLengths ()
2166- != std::pair<int , int >(0 , 0 )) {
2167- logger_->warn (
2168- DRT ,
2169- 312 ,
2170- " Unsupported branch EXCEPTEDGELENGTH in PROPERTY LEF58_AREA." );
2171- } else if (db_rule->getExceptMinSize () != std::pair<int , int >(0 , 0 )) {
2172- logger_->warn (
2173- DRT , 313 , " Unsupported branch EXCEPTMINSIZE in PROPERTY LEF58_AREA." );
2174- } else if (db_rule->getExceptStep () != std::pair<int , int >(0 , 0 )) {
2175- logger_->warn (
2176- DRT , 314 , " Unsupported branch EXCEPTSTEP in PROPERTY LEF58_AREA." );
2177- } else if (db_rule->getMask () != 0 ) {
2178- logger_->warn (
2179- DRT , 315 , " Unsupported branch MASK in PROPERTY LEF58_AREA." );
2180- } else if (db_rule->getTrimLayer () != nullptr ) {
2181- logger_->warn (
2182- DRT , 316 , " Unsupported branch LAYER in PROPERTY LEF58_AREA." );
2183- } else {
2142+ if (!db_rule->isExceptRectangle ()
2143+ || checkMetalShape_lef58Area_exceptRectangle (poly, db_rule)) {
21842144 checkMetalShape_addPatch (pin, min_area);
2145+ break ;
21852146 }
21862147 }
21872148}
@@ -2207,8 +2168,7 @@ bool FlexGCWorker::Impl::checkMetalShape_lef58Area_exceptRectangle(
22072168
22082169bool FlexGCWorker::Impl::checkMetalShape_lef58Area_rectWidth (
22092170 gcPolygon* poly,
2210- odb::dbTechLayerAreaRule* db_rule,
2211- bool & check_rect_width)
2171+ odb::dbTechLayerAreaRule* db_rule)
22122172{
22132173 if (db_rule->getRectWidth () > 0 ) {
22142174 std::vector<gtl::rectangle_data<frCoord>> rects;
@@ -2223,10 +2183,7 @@ bool FlexGCWorker::Impl::checkMetalShape_lef58Area_rectWidth(
22232183 const auto & rect = rects.back ();
22242184 auto xLen = gtl::delta (rect, gtl::HORIZONTAL );
22252185 auto yLen = gtl::delta (rect, gtl::VERTICAL );
2226- bool apply_rect_width_area = false ;
2227- apply_rect_width_area = std::min (xLen, yLen) <= min_width;
2228- check_rect_width = !apply_rect_width_area;
2229- return apply_rect_width_area;
2186+ return std::min (xLen, yLen) < min_width;
22302187 }
22312188 return false ;
22322189 }
@@ -2952,76 +2909,6 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_adjCut(
29522909 return ;
29532910 }
29542911
2955- if (con->hasExactAligned ()) {
2956- logger_->warn (
2957- DRT ,
2958- 45 ,
2959- " Unsupported branch EXACTALIGNED in checkLef58CutSpacing_spc_adjCut." );
2960- return ;
2961- }
2962- if (con->isExceptSamePGNet ()) {
2963- logger_->warn (DRT ,
2964- 46 ,
2965- " Unsupported branch EXCEPTSAMEPGNET in "
2966- " checkLef58CutSpacing_spc_adjCut." );
2967- return ;
2968- }
2969- if (con->hasExceptAllWithin ()) {
2970- logger_->warn (DRT ,
2971- 47 ,
2972- " Unsupported branch EXCEPTALLWITHIN in "
2973- " checkLef58CutSpacing_spc_adjCut." );
2974- return ;
2975- }
2976- if (con->isToAll ()) {
2977- logger_->warn (
2978- DRT ,
2979- 48 ,
2980- " Unsupported branch TO ALL in checkLef58CutSpacing_spc_adjCut." );
2981- return ;
2982- }
2983- if (con->hasEnclosure ()) {
2984- logger_->warn (
2985- DRT ,
2986- 50 ,
2987- " Unsupported branch ENCLOSURE in checkLef58CutSpacing_spc_adjCut." );
2988- return ;
2989- }
2990- if (con->isSideParallelOverlap ()) {
2991- logger_->warn (DRT ,
2992- 51 ,
2993- " Unsupported branch SIDEPARALLELOVERLAP in "
2994- " checkLef58CutSpacing_spc_adjCut." );
2995- return ;
2996- }
2997- if (con->isSameMask ()) {
2998- logger_->warn (
2999- DRT ,
3000- 52 ,
3001- " Unsupported branch SAMEMASK in checkLef58CutSpacing_spc_adjCut." );
3002- return ;
3003- }
3004-
3005- // start checking
3006- if (con->hasExactAligned ()) {
3007- ;
3008- }
3009- if (con->isExceptSamePGNet ()) {
3010- ;
3011- }
3012- if (con->hasExceptAllWithin ()) {
3013- ;
3014- }
3015- if (con->hasEnclosure ()) {
3016- ;
3017- }
3018- if (con->isNoPrl ()) {
3019- ;
3020- }
3021- if (con->isSameMask ()) {
3022- ;
3023- }
3024-
30252912 frSquaredDistance reqSpcValSquare = con->getCutSpacing ();
30262913 reqSpcValSquare *= reqSpcValSquare;
30272914
@@ -3083,85 +2970,16 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_layer(
30832970 auto reqSpcVal = con->getCutSpacing ();
30842971 frSquaredDistance reqSpcValSquare = (frSquaredDistance) reqSpcVal * reqSpcVal;
30852972
3086- // skip unsupported rule branch
3087- if (con->isStack ()) {
3088- logger_->warn (
3089- DRT , 54 , " Unsupported branch STACK in checkLef58CutSpacing_spc_layer." );
3090- return ;
3091- }
3092- if (con->hasOrthogonalSpacing ()) {
3093- logger_->warn (DRT ,
3094- 55 ,
3095- " Unsupported branch ORTHOGONALSPACING in "
3096- " checkLef58CutSpacing_spc_layer." );
3097- return ;
3098- }
3099- if (con->hasCutClass ()) {
3100- if (con->isShortEdgeOnly ()) {
3101- logger_->warn (DRT ,
3102- 56 ,
3103- " Unsupported branch SHORTEDGEONLY in "
3104- " checkLef58CutSpacing_spc_layer." );
3105- return ;
3106- }
3107- if (con->isConcaveCorner ()) {
3108- if (con->hasWidth ()) {
3109- logger_->warn (
3110- DRT ,
3111- 57 ,
3112- " Unsupported branch WIDTH in checkLef58CutSpacing_spc_layer." );
3113- } else if (con->hasParallel ()) {
3114- logger_->warn (
3115- DRT ,
3116- 58 ,
3117- " Unsupported branch PARALLEL in checkLef58CutSpacing_spc_layer." );
3118- } else if (con->hasEdgeLength ()) {
3119- logger_->warn (
3120- DRT ,
3121- 59 ,
3122- " Unsupported branch EDGELENGTH in checkLef58CutSpacing_spc_layer." );
3123- }
3124- } else if (con->hasExtension ()) {
3125- logger_->warn (
3126- DRT ,
3127- 60 ,
3128- " Unsupported branch EXTENSION in checkLef58CutSpacing_spc_layer." );
3129- } else if (con->hasNonEolConvexCorner ()) {
3130- ;
3131- } else if (con->hasAboveWidth ()) {
3132- logger_->warn (
3133- DRT ,
3134- 61 ,
3135- " Unsupported branch ABOVEWIDTH in checkLef58CutSpacing_spc_layer." );
3136- } else if (con->isMaskOverlap ()) {
3137- logger_->warn (
3138- DRT ,
3139- 62 ,
3140- " Unsupported branch MASKOVERLAP in checkLef58CutSpacing_spc_layer." );
3141- } else if (con->isWrongDirection ()) {
3142- logger_->warn (DRT ,
3143- 63 ,
3144- " Unsupported branch WRONGDIRECTION in "
3145- " checkLef58CutSpacing_spc_layer." );
3146- }
3147- }
3148-
31492973 // start checking
3150- if (con->isStack ()) {
3151- ;
3152- } else if (con->hasOrthogonalSpacing ()) {
3153- ;
3154- } else if (con->hasCutClass ()) {
2974+ if (con->hasCutClass ()) {
31552975 auto conCutClassIdx = con->getCutClassIdx ();
31562976 auto cutClassIdx = getTech ()->getLayer (layerNum)->getCutClassIdx (
31572977 rect1->width (), rect1->length ());
31582978 if (cutClassIdx != conCutClassIdx) {
31592979 return ;
31602980 }
31612981
3162- if (con->isShortEdgeOnly ()) {
3163- ;
3164- } else if (con->isConcaveCorner ()) {
2982+ if (con->isConcaveCorner ()) {
31652983 // skip if rect2 does not contains rect1
31662984 if (!gtl::contains (*rect2, *rect1)) {
31672985 return ;
@@ -3230,8 +3048,6 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_layer(
32303048 corner->isFixed ()));
32313049 addMarker (std::move (marker));
32323050 }
3233- } else if (con->hasExtension ()) {
3234- ;
32353051 } else if (con->hasNonEolConvexCorner ()) {
32363052 // skip if rect2 does not contains rect1
32373053 if (!gtl::contains (*rect2, *rect1)) {
@@ -3344,12 +3160,6 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_layer(
33443160 corner->isFixed ()));
33453161 addMarker (std::move (marker));
33463162 }
3347- } else if (con->hasAboveWidth ()) {
3348- ;
3349- } else if (con->isMaskOverlap ()) {
3350- ;
3351- } else if (con->isWrongDirection ()) {
3352- ;
33533163 }
33543164 }
33553165}
0 commit comments