Skip to content

Commit 0d1370f

Browse files
committed
drt: filter unsupported rules at io and fix minarea in FlexGC
Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
1 parent 7bc6374 commit 0d1370f

4 files changed

Lines changed: 261 additions & 265 deletions

File tree

src/drt/src/db/tech/frLayer.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,15 +621,46 @@ class frLayer
621621
}
622622
void addLef58AreaConstraint(frLef58AreaConstraint* in)
623623
{
624-
lef58AreaConstraints_.push_back(in);
624+
// This vector should be sorted by area in a descending order
625+
auto area = in->getODBRule()->getArea();
626+
auto it = std::lower_bound(lef58AreaConstraints_.begin(),
627+
lef58AreaConstraints_.end(),
628+
area,
629+
[](const frLef58AreaConstraint* a, frCoord b) {
630+
return a->getODBRule()->getArea() > b;
631+
});
632+
lef58AreaConstraints_.insert(it, in);
625633
}
626634

627635
const std::vector<frLef58AreaConstraint*>& getLef58AreaConstraints() const
628636
{
629637
return lef58AreaConstraints_;
630638
}
631639

632-
bool hasLef58AreaConstraint() const { return !lef58AreaConstraints_.empty(); }
640+
bool hasLef58AreaConstraint() const
641+
{
642+
return !lef58AreaConstraints_.empty()
643+
|| !lef58AreaConstraintsRectWidth_.empty();
644+
}
645+
646+
void addLef58AreaConstraintRectWidth(frLef58AreaConstraint* in)
647+
{
648+
// This vector should be sorted by rectwidth in an ascending order
649+
auto rectwidth = in->getODBRule()->getRectWidth();
650+
auto it = std::lower_bound(lef58AreaConstraintsRectWidth_.begin(),
651+
lef58AreaConstraintsRectWidth_.end(),
652+
rectwidth,
653+
[](const frLef58AreaConstraint* a, frCoord b) {
654+
return a->getODBRule()->getRectWidth() < b;
655+
});
656+
lef58AreaConstraintsRectWidth_.insert(it, in);
657+
}
658+
659+
const std::vector<frLef58AreaConstraint*>& getLef58AreaConstraintsRectWidth()
660+
const
661+
{
662+
return lef58AreaConstraintsRectWidth_;
663+
}
633664

634665
void addKeepOutZoneConstraint(frLef58KeepOutZoneConstraint* in)
635666
{
@@ -929,6 +960,7 @@ class frLayer
929960
std::vector<frLef58EolKeepOutConstraint*> lef58EolKeepOutConstraints_;
930961
std::vector<frMetalWidthViaConstraint*> metalWidthViaConstraints_;
931962
std::vector<frLef58AreaConstraint*> lef58AreaConstraints_;
963+
std::vector<frLef58AreaConstraint*> lef58AreaConstraintsRectWidth_;
932964
std::vector<frLef58KeepOutZoneConstraint*> keepOutZoneConstraints_;
933965
std::vector<frSpacingRangeConstraint*> spacingRangeConstraints_;
934966
std::vector<frLef58TwoWiresForbiddenSpcConstraint*>

src/drt/src/gc/FlexGC_impl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,7 @@ class FlexGCWorker::Impl
539539
gcPolygon* poly,
540540
odb::dbTechLayerAreaRule* db_rule);
541541
bool checkMetalShape_lef58Area_rectWidth(gcPolygon* poly,
542-
odb::dbTechLayerAreaRule* db_rule,
543-
bool& check_rect_width);
542+
odb::dbTechLayerAreaRule* db_rule);
544543
void checkMetalShape_addPatch(gcPin* pin, int min_area);
545544
void checkMetalShape_patchOwner_helper(drPatchWire* patch,
546545
const std::vector<drNet*>* dr_nets);

src/drt/src/gc/FlexGC_main.cpp

Lines changed: 34 additions & 224 deletions
Original file line numberDiff line numberDiff line change
@@ -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

22082169
bool 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

Comments
 (0)