1 /* Authors: Lutong Wang and Bangqi Xu */ 2 /* 3 * Copyright (c) 2019, The Regents of the University of California 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * * Neither the name of the University nor the 14 * names of its contributors may be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _FR_CONSTRAINT_H_ 30 #define _FR_CONSTRAINT_H_ 31 32 #include <algorithm> 33 #include <iterator> 34 #include <map> 35 #include <memory> 36 #include <utility> 37 38 #include "db/tech/frLookupTbl.h" 39 #include "frBaseTypes.h" 40 #include "frViaDef.h" 41 #include "frViaRuleGenerate.h" 42 #include "utl/Logger.h" 43 44 namespace fr { 45 namespace io { 46 class Parser; 47 } 48 49 enum class frLef58CornerSpacingExceptionEnum 50 { 51 NONE, 52 EXCEPTSAMENET, 53 EXCEPTSAMEMETAL 54 }; 55 56 // base type for design rule 57 class frConstraint 58 { 59 public: ~frConstraint()60 virtual ~frConstraint() {} 61 virtual frConstraintTypeEnum typeId() const = 0; 62 virtual void report(utl::Logger* logger) const = 0; 63 64 protected: frConstraint()65 frConstraint() {} 66 }; 67 68 class frLef58CutClassConstraint : public frConstraint 69 { 70 public: 71 friend class io::Parser; 72 // constructors; frLef58CutClassConstraint()73 frLef58CutClassConstraint() {} 74 // getters getCutClasses()75 frCollection<std::shared_ptr<frLef58CutClass>> getCutClasses() const 76 { 77 frCollection<std::shared_ptr<frLef58CutClass>> sol; 78 std::transform(cutClasses.begin(), 79 cutClasses.end(), 80 std::back_inserter(sol), 81 [](auto& kv) { return kv.second; }); 82 return sol; 83 } 84 // setters addToCutClass(const std::shared_ptr<frLef58CutClass> & in)85 void addToCutClass(const std::shared_ptr<frLef58CutClass>& in) 86 { 87 cutClasses[in->getName()] = in; 88 } 89 // others typeId()90 frConstraintTypeEnum typeId() const override 91 { 92 return frConstraintTypeEnum::frcLef58CutClassConstraint; 93 } report(utl::Logger * logger)94 void report(utl::Logger* logger) const override 95 { 96 logger->report("Cut class"); 97 } 98 99 protected: 100 std::map<frString, std::shared_ptr<frLef58CutClass>> cutClasses; 101 }; 102 103 // recheck constraint for negative rules 104 class frRecheckConstraint : public frConstraint 105 { 106 public: typeId()107 frConstraintTypeEnum typeId() const override 108 { 109 return frConstraintTypeEnum::frcRecheckConstraint; 110 } report(utl::Logger * logger)111 void report(utl::Logger* logger) const override { logger->report("Recheck"); } 112 }; 113 114 // short 115 116 class frShortConstraint : public frConstraint 117 { 118 public: typeId()119 frConstraintTypeEnum typeId() const override 120 { 121 return frConstraintTypeEnum::frcShortConstraint; 122 } report(utl::Logger * logger)123 void report(utl::Logger* logger) const override { logger->report("Short"); } 124 }; 125 126 // NSMetal 127 class frNonSufficientMetalConstraint : public frConstraint 128 { 129 public: typeId()130 frConstraintTypeEnum typeId() const override 131 { 132 return frConstraintTypeEnum::frcNonSufficientMetalConstraint; 133 } report(utl::Logger * logger)134 void report(utl::Logger* logger) const override { logger->report("NSMetal"); } 135 }; 136 137 // offGrid 138 class frOffGridConstraint : public frConstraint 139 { 140 public: typeId()141 frConstraintTypeEnum typeId() const override 142 { 143 return frConstraintTypeEnum::frcOffGridConstraint; 144 } report(utl::Logger * logger)145 void report(utl::Logger* logger) const override 146 { 147 logger->report("Off grid"); 148 } 149 }; 150 151 // minHole 152 class frMinEnclosedAreaConstraint : public frConstraint 153 { 154 public: 155 // constructor frMinEnclosedAreaConstraint(frCoord areaIn)156 frMinEnclosedAreaConstraint(frCoord areaIn) : area(areaIn), width(-1) {} 157 // getter getArea()158 frCoord getArea() const { return area; } hasWidth()159 bool hasWidth() const { return (width != -1); } getWidth()160 frCoord getWidth() const { return width; } 161 // setter setWidth(frCoord widthIn)162 void setWidth(frCoord widthIn) { width = widthIn; } 163 typeId()164 frConstraintTypeEnum typeId() const override 165 { 166 return frConstraintTypeEnum::frcMinEnclosedAreaConstraint; 167 } 168 report(utl::Logger * logger)169 void report(utl::Logger* logger) const override 170 { 171 logger->report("Min enclosed area {} width {}", area, width); 172 } 173 174 protected: 175 frCoord area, width; 176 }; 177 178 // LEF58_MINSTEP (currently only implement GF14 related API) 179 class frLef58MinStepConstraint : public frConstraint 180 { 181 public: 182 // constructor frLef58MinStepConstraint()183 frLef58MinStepConstraint() 184 : minStepLength(-1), 185 insideCorner(false), 186 outsideCorner(false), 187 step(false), 188 maxLength(-1), 189 maxEdges(-1), 190 minAdjLength(-1), 191 convexCorner(false), 192 exceptWithin(-1), 193 concaveCorner(false), 194 threeConcaveCorners(false), 195 width(-1), 196 minAdjLength2(-1), 197 minBetweenLength(-1), 198 exceptSameCorners(false), 199 eolWidth(-1), 200 concaveCorners(false) 201 { 202 } 203 // getter getMinStepLength()204 frCoord getMinStepLength() const { return minStepLength; } hasMaxEdges()205 bool hasMaxEdges() const { return (maxEdges != -1); } getMaxEdges()206 int getMaxEdges() const { return maxEdges; } hasMinAdjacentLength()207 bool hasMinAdjacentLength() const { return (minAdjLength != -1); } getMinAdjacentLength()208 frCoord getMinAdjacentLength() const { return minAdjLength; } hasEolWidth()209 bool hasEolWidth() const { return (eolWidth != -1); } getEolWidth()210 frCoord getEolWidth() const { return eolWidth; } 211 212 // setter setMinStepLength(frCoord in)213 void setMinStepLength(frCoord in) { minStepLength = in; } setMaxEdges(int in)214 void setMaxEdges(int in) { maxEdges = in; } setMinAdjacentLength(frCoord in)215 void setMinAdjacentLength(frCoord in) { minAdjLength = in; } setEolWidth(frCoord in)216 void setEolWidth(frCoord in) { eolWidth = in; } 217 typeId()218 frConstraintTypeEnum typeId() const override 219 { 220 return frConstraintTypeEnum::frcLef58MinStepConstraint; 221 } report(utl::Logger * logger)222 void report(utl::Logger* logger) const override 223 { 224 logger->report( 225 "MINSTEP minStepLength {} insideCorner {} outsideCorner {} step {} " 226 "maxLength {} maxEdges {} minAdjLength {} convexCorner {} exceptWithin " 227 "{} concaveCorner {} threeConcaveCorners {} width {} minAdjLength2 {} " 228 "minBetweenLength {} exceptSameCorners {} eolWidth {} concaveCorners " 229 "{} ", 230 minStepLength, 231 insideCorner, 232 outsideCorner, 233 step, 234 maxLength, 235 maxEdges, 236 minAdjLength, 237 convexCorner, 238 exceptWithin, 239 concaveCorner, 240 threeConcaveCorners, 241 width, 242 minAdjLength2, 243 minBetweenLength, 244 exceptSameCorners, 245 eolWidth, 246 concaveCorners); 247 } 248 249 protected: 250 frCoord minStepLength; 251 bool insideCorner; 252 bool outsideCorner; 253 bool step; 254 frCoord maxLength; 255 int maxEdges; 256 frCoord minAdjLength; 257 bool convexCorner; 258 frCoord exceptWithin; 259 bool concaveCorner; 260 bool threeConcaveCorners; 261 frCoord width; 262 frCoord minAdjLength2; 263 frCoord minBetweenLength; 264 bool exceptSameCorners; 265 frCoord eolWidth; 266 bool concaveCorners; 267 }; 268 269 // minStep 270 class frMinStepConstraint : public frConstraint 271 { 272 public: 273 // constructor frMinStepConstraint()274 frMinStepConstraint() 275 : minStepLength(-1), 276 minstepType(frMinstepTypeEnum::UNKNOWN), 277 maxLength(-1), 278 insideCorner(false), 279 outsideCorner(true), 280 step(false), 281 maxEdges(-1) 282 { 283 } 284 // getter getMinStepLength()285 frCoord getMinStepLength() const { return minStepLength; } hasMaxLength()286 bool hasMaxLength() const { return (maxLength != -1); } getMaxLength()287 frCoord getMaxLength() const { return maxLength; } hasMinstepType()288 bool hasMinstepType() const 289 { 290 return minstepType != frMinstepTypeEnum::UNKNOWN; 291 } getMinstepType()292 frMinstepTypeEnum getMinstepType() const { return minstepType; } hasInsideCorner()293 bool hasInsideCorner() const { return insideCorner; } hasOutsideCorner()294 bool hasOutsideCorner() const { return outsideCorner; } hasStep()295 bool hasStep() const { return step; } hasMaxEdges()296 bool hasMaxEdges() const { return (maxEdges != -1); } getMaxEdges()297 int getMaxEdges() const { return maxEdges; } 298 // setter setMinstepType(frMinstepTypeEnum in)299 void setMinstepType(frMinstepTypeEnum in) { minstepType = in; } setInsideCorner(bool in)300 void setInsideCorner(bool in) { insideCorner = in; } setOutsideCorner(bool in)301 void setOutsideCorner(bool in) { outsideCorner = in; } setStep(bool in)302 void setStep(bool in) { step = in; } setMinStepLength(frCoord in)303 void setMinStepLength(frCoord in) { minStepLength = in; } setMaxLength(frCoord in)304 void setMaxLength(frCoord in) { maxLength = in; } setMaxEdges(int in)305 void setMaxEdges(int in) { maxEdges = in; } 306 typeId()307 frConstraintTypeEnum typeId() const override 308 { 309 return frConstraintTypeEnum::frcMinStepConstraint; 310 } 311 report(utl::Logger * logger)312 void report(utl::Logger* logger) const override 313 { 314 logger->report( 315 "Min step length min {} type {} max {} " 316 "insideCorner {} outsideCorner {} step {} maxEdges {}", 317 minStepLength, 318 minstepType, 319 maxLength, 320 insideCorner, 321 outsideCorner, 322 step, 323 maxEdges); 324 } 325 326 protected: 327 frCoord minStepLength; 328 frMinstepTypeEnum minstepType; 329 frCoord maxLength; 330 bool insideCorner; 331 bool outsideCorner; 332 bool step; 333 int maxEdges; 334 }; 335 336 // minimumcut 337 class frMinimumcutConstraint : public frConstraint 338 { 339 public: frMinimumcutConstraint()340 frMinimumcutConstraint() 341 : numCuts(-1), 342 width(-1), 343 cutDistance(-1), 344 connection(frMinimumcutConnectionEnum::UNKNOWN), 345 length(-1), 346 distance(-1) 347 { 348 } 349 // getters getNumCuts()350 int getNumCuts() const { return numCuts; } getWidth()351 frCoord getWidth() const { return width; } hasWithin()352 bool hasWithin() const { return !(cutDistance == -1); } getCutDistance()353 frCoord getCutDistance() const { return cutDistance; } hasConnection()354 bool hasConnection() const 355 { 356 return !(connection == frMinimumcutConnectionEnum::UNKNOWN); 357 } getConnection()358 frMinimumcutConnectionEnum getConnection() const { return connection; } hasLength()359 bool hasLength() const { return !(length == -1); } getLength()360 frCoord getLength() const { return length; } getDistance()361 frCoord getDistance() const { return distance; } 362 // setters setNumCuts(int in)363 void setNumCuts(int in) { numCuts = in; } setWidth(frCoord in)364 void setWidth(frCoord in) { width = in; } setWithin(frCoord in)365 void setWithin(frCoord in) { cutDistance = in; } setConnection(frMinimumcutConnectionEnum in)366 void setConnection(frMinimumcutConnectionEnum in) { connection = in; } setLength(frCoord in1,frCoord in2)367 void setLength(frCoord in1, frCoord in2) 368 { 369 length = in1; 370 distance = in2; 371 } 372 // others typeId()373 frConstraintTypeEnum typeId() const override 374 { 375 return frConstraintTypeEnum::frcMinimumcutConstraint; 376 } report(utl::Logger * logger)377 void report(utl::Logger* logger) const override 378 { 379 logger->report( 380 "Min cut numCuts {} width {} cutDistance {} " 381 "connection {} length {} distance {}", 382 numCuts, 383 width, 384 cutDistance, 385 connection, 386 length, 387 distance); 388 } 389 390 protected: 391 int numCuts; 392 frCoord width; 393 frCoord cutDistance; 394 frMinimumcutConnectionEnum connection; 395 frCoord length; 396 frCoord distance; 397 }; 398 399 // minArea 400 401 class frAreaConstraint : public frConstraint 402 { 403 public: 404 // constructor frAreaConstraint(frCoord minAreaIn)405 frAreaConstraint(frCoord minAreaIn) { minArea = minAreaIn; } 406 // getter getMinArea()407 frCoord getMinArea() { return minArea; } 408 // setter setMinArea(frCoord minAreaIn)409 void setMinArea(frCoord minAreaIn) { minArea = minAreaIn; } 410 typeId()411 frConstraintTypeEnum typeId() const override 412 { 413 return frConstraintTypeEnum::frcAreaConstraint; 414 } report(utl::Logger * logger)415 void report(utl::Logger* logger) const override 416 { 417 logger->report("Area {}", minArea); 418 } 419 420 protected: 421 frCoord minArea; 422 }; 423 424 // minWidth 425 class frMinWidthConstraint : public frConstraint 426 { 427 public: 428 // constructor frMinWidthConstraint(frCoord minWidthIn)429 frMinWidthConstraint(frCoord minWidthIn) { minWidth = minWidthIn; } 430 // getter getMinWidth()431 frCoord getMinWidth() { return minWidth; } 432 // setter set(frCoord minWidthIn)433 void set(frCoord minWidthIn) { minWidth = minWidthIn; } 434 typeId()435 frConstraintTypeEnum typeId() const override 436 { 437 return frConstraintTypeEnum::frcMinWidthConstraint; 438 } report(utl::Logger * logger)439 void report(utl::Logger* logger) const override 440 { 441 logger->report("Width {}", minWidth); 442 } 443 444 protected: 445 frCoord minWidth; 446 }; 447 448 class frLef58SpacingEndOfLineWithinEncloseCutConstraint : public frConstraint 449 { 450 public: 451 // constructors frLef58SpacingEndOfLineWithinEncloseCutConstraint(frCoord encloseDistIn,frCoord cutToMetalSpaceIn)452 frLef58SpacingEndOfLineWithinEncloseCutConstraint(frCoord encloseDistIn, 453 frCoord cutToMetalSpaceIn) 454 : below(false), 455 above(false), 456 encloseDist(encloseDistIn), 457 cutToMetalSpace(cutToMetalSpaceIn), 458 allCuts(false) 459 { 460 } 461 // setters setBelow(bool value)462 void setBelow(bool value) { below = value; } setAbove(bool value)463 void setAbove(bool value) { above = value; } setAllCuts(bool value)464 void setAllCuts(bool value) { allCuts = value; } setEncloseDist(frCoord value)465 void setEncloseDist(frCoord value) { encloseDist = value; } setCutToMetalSpace(frCoord value)466 void setCutToMetalSpace(frCoord value) { cutToMetalSpace = value; } 467 // getters isAboveOnly()468 bool isAboveOnly() const { return above; } isBelowOnly()469 bool isBelowOnly() const { return below; } isAboveAndBelow()470 bool isAboveAndBelow() const { return !(above ^ below); } isAllCuts()471 bool isAllCuts() const { return allCuts; } getEncloseDist()472 frCoord getEncloseDist() const { return encloseDist; } getCutToMetalSpace()473 frCoord getCutToMetalSpace() const { return cutToMetalSpace; } 474 // others typeId()475 frConstraintTypeEnum typeId() const override 476 { 477 return frConstraintTypeEnum:: 478 frcLef58SpacingEndOfLineWithinEncloseCutConstraint; 479 } report(utl::Logger * logger)480 void report(utl::Logger* logger) const override 481 { 482 logger->report( 483 "\t\tSPACING_WITHIN_ENCLOSECUT below {} above {} encloseDist " 484 "{} cutToMetalSpace {} allCuts {}", 485 below, 486 above, 487 encloseDist, 488 cutToMetalSpace, 489 allCuts); 490 } 491 492 private: 493 bool below; 494 bool above; 495 frCoord encloseDist; 496 frCoord cutToMetalSpace; 497 bool allCuts; 498 }; 499 500 class frLef58SpacingEndOfLineWithinEndToEndConstraint : public frConstraint 501 { 502 public: 503 // constructors frLef58SpacingEndOfLineWithinEndToEndConstraint()504 frLef58SpacingEndOfLineWithinEndToEndConstraint() 505 : endToEndSpace(0), 506 cutSpace(false), 507 oneCutSpace(0), 508 twoCutSpace(0), 509 hExtension(false), 510 extension(0), 511 wrongDirExtension(false), 512 hOtherEndWidth(false), 513 otherEndWidth(0) 514 { 515 } 516 // getters getEndToEndSpace()517 frCoord getEndToEndSpace() const { return endToEndSpace; } getOneCutSpace()518 frCoord getOneCutSpace() const { return oneCutSpace; } getTwoCutSpace()519 frCoord getTwoCutSpace() const { return twoCutSpace; } hasExtension()520 bool hasExtension() const { return hExtension; } getExtension()521 frCoord getExtension() const { return extension; } getWrongDirExtension()522 frCoord getWrongDirExtension() const { return wrongDirExtension; } hasOtherEndWidth()523 bool hasOtherEndWidth() const { return hOtherEndWidth; } getOtherEndWidth()524 frCoord getOtherEndWidth() const { return otherEndWidth; } 525 526 // setters setEndToEndSpace(frCoord in)527 void setEndToEndSpace(frCoord in) { endToEndSpace = in; } setCutSpace(frCoord one,frCoord two)528 void setCutSpace(frCoord one, frCoord two) 529 { 530 oneCutSpace = one; 531 twoCutSpace = two; 532 } setExtension(frCoord extensionIn)533 void setExtension(frCoord extensionIn) 534 { 535 hExtension = true; 536 extension = extensionIn; 537 wrongDirExtension = extensionIn; 538 } setExtension(frCoord extensionIn,frCoord wrongDirExtensionIn)539 void setExtension(frCoord extensionIn, frCoord wrongDirExtensionIn) 540 { 541 hExtension = true; 542 extension = extensionIn; 543 wrongDirExtension = wrongDirExtensionIn; 544 } setOtherEndWidth(frCoord in)545 void setOtherEndWidth(frCoord in) 546 { 547 hOtherEndWidth = true; 548 otherEndWidth = in; 549 } 550 // others typeId()551 frConstraintTypeEnum typeId() const override 552 { 553 return frConstraintTypeEnum:: 554 frcLef58SpacingEndOfLineWithinEndToEndConstraint; 555 } report(utl::Logger * logger)556 void report(utl::Logger* logger) const override 557 { 558 logger->report( 559 "\t\tSPACING_WITHIN_ENDTOEND endToEndSpace {} cutSpace {} oneCutSpace " 560 "{} twoCutSpace {} hExtension {} extension {} wrongDirExtension {} " 561 "hOtherEndWidth {} otherEndWidth {} ", 562 endToEndSpace, 563 cutSpace, 564 oneCutSpace, 565 twoCutSpace, 566 hExtension, 567 extension, 568 wrongDirExtension, 569 hOtherEndWidth, 570 otherEndWidth); 571 } 572 573 protected: 574 frCoord endToEndSpace; 575 bool cutSpace; 576 frCoord oneCutSpace; 577 frCoord twoCutSpace; 578 bool hExtension; 579 frCoord extension; 580 frCoord wrongDirExtension; 581 bool hOtherEndWidth; 582 frCoord otherEndWidth; 583 }; 584 585 class frLef58SpacingEndOfLineWithinParallelEdgeConstraint : public frConstraint 586 { 587 public: 588 // constructors frLef58SpacingEndOfLineWithinParallelEdgeConstraint()589 frLef58SpacingEndOfLineWithinParallelEdgeConstraint() 590 : subtractEolWidth(false), 591 parSpace(0), 592 parWithin(0), 593 hPrl(false), 594 prl(0), 595 hMinLength(false), 596 minLength(0), 597 twoEdges(false), 598 sameMetal(false), 599 nonEolCornerOnly(false), 600 parallelSameMask(false) 601 { 602 } 603 // getters hasSubtractEolWidth()604 bool hasSubtractEolWidth() const { return subtractEolWidth; } getParSpace()605 frCoord getParSpace() const { return parSpace; } getParWithin()606 frCoord getParWithin() const { return parWithin; } hasPrl()607 bool hasPrl() const { return hPrl; } getPrl()608 frCoord getPrl() const { return prl; } hasMinLength()609 bool hasMinLength() const { return hMinLength; } getMinLength()610 frCoord getMinLength() const { return minLength; } hasTwoEdges()611 bool hasTwoEdges() const { return twoEdges; } hasSameMetal()612 bool hasSameMetal() const { return sameMetal; } hasNonEolCornerOnly()613 bool hasNonEolCornerOnly() const { return nonEolCornerOnly; } hasParallelSameMask()614 bool hasParallelSameMask() const { return parallelSameMask; } 615 // setters setSubtractEolWidth(bool in)616 void setSubtractEolWidth(bool in) { subtractEolWidth = in; } setPar(frCoord parSpaceIn,frCoord parWithinIn)617 void setPar(frCoord parSpaceIn, frCoord parWithinIn) 618 { 619 parSpace = parSpaceIn; 620 parWithin = parWithinIn; 621 } setPrl(frCoord in)622 void setPrl(frCoord in) 623 { 624 hPrl = true; 625 prl = in; 626 } setMinLength(frCoord in)627 void setMinLength(frCoord in) 628 { 629 hMinLength = true; 630 minLength = in; 631 } setTwoEdges(bool in)632 void setTwoEdges(bool in) { twoEdges = in; } setSameMetal(bool in)633 void setSameMetal(bool in) { sameMetal = in; } setNonEolCornerOnly(bool in)634 void setNonEolCornerOnly(bool in) { nonEolCornerOnly = in; } setParallelSameMask(bool in)635 void setParallelSameMask(bool in) { parallelSameMask = in; } 636 637 // others typeId()638 frConstraintTypeEnum typeId() const override 639 { 640 return frConstraintTypeEnum:: 641 frcLef58SpacingEndOfLineWithinParallelEdgeConstraint; 642 } report(utl::Logger * logger)643 void report(utl::Logger* logger) const override 644 { 645 logger->report( 646 "\t\tSPACING_WITHIN_PARALLELEDGE subtractEolWidth {} parSpace {} " 647 "parWithin {} hPrl {} prl {} hMinLength {} minLength {} twoEdges {} " 648 "sameMetal {} nonEolCornerOnly {} parallelSameMask {} ", 649 subtractEolWidth, 650 parSpace, 651 parWithin, 652 hPrl, 653 prl, 654 hMinLength, 655 minLength, 656 twoEdges, 657 sameMetal, 658 nonEolCornerOnly, 659 parallelSameMask); 660 } 661 662 protected: 663 bool subtractEolWidth; 664 frCoord parSpace; 665 frCoord parWithin; 666 bool hPrl; 667 frCoord prl; 668 bool hMinLength; 669 frCoord minLength; 670 bool twoEdges; 671 bool sameMetal; 672 bool nonEolCornerOnly; 673 bool parallelSameMask; 674 }; 675 676 class frLef58SpacingEndOfLineWithinMaxMinLengthConstraint : public frConstraint 677 { 678 public: 679 // constructors frLef58SpacingEndOfLineWithinMaxMinLengthConstraint()680 frLef58SpacingEndOfLineWithinMaxMinLengthConstraint() 681 : maxLength(false), length(0), twoSides(false) 682 { 683 } 684 685 // getters getLength()686 frCoord getLength() const { return length; } isMaxLength()687 bool isMaxLength() const { return maxLength; } isTwoSides()688 bool isTwoSides() const { return twoSides; } 689 690 // setters 691 void setLength(bool maxLengthIn, frCoord lengthIn, bool twoSidesIn = false) 692 { 693 maxLength = maxLengthIn; 694 length = lengthIn; 695 twoSides = twoSidesIn; 696 } 697 // others typeId()698 frConstraintTypeEnum typeId() const override 699 { 700 return frConstraintTypeEnum:: 701 frcLef58SpacingEndOfLineWithinMaxMinLengthConstraint; 702 } report(utl::Logger * logger)703 void report(utl::Logger* logger) const override 704 { 705 logger->report( 706 "\t\tSPACING_WITHIN_MAXMIN maxLength {} length {} twoSides {} ", 707 maxLength, 708 length, 709 twoSides); 710 } 711 712 protected: 713 bool maxLength; 714 frCoord length; 715 bool twoSides; 716 }; 717 718 class frLef58SpacingEndOfLineWithinConstraint : public frConstraint 719 { 720 public: 721 // constructors frLef58SpacingEndOfLineWithinConstraint()722 frLef58SpacingEndOfLineWithinConstraint() 723 : hOppositeWidth(false), 724 oppositeWidth(0), 725 eolWithin(0), 726 wrongDirWithin(false), 727 sameMask(false), 728 endToEndConstraint(nullptr), 729 parallelEdgeConstraint(nullptr) 730 { 731 } 732 733 // getters hasOppositeWidth()734 bool hasOppositeWidth() const { return hOppositeWidth; } getOppositeWidth()735 frCoord getOppositeWidth() const { return oppositeWidth; } getEolWithin()736 frCoord getEolWithin() const { return eolWithin; } getWrongDirWithin()737 frCoord getWrongDirWithin() const { return wrongDirWithin; } hasSameMask()738 bool hasSameMask() const { return sameMask; } hasExceptExactWidth()739 bool hasExceptExactWidth() const 740 { 741 return false; // skip for now 742 } hasFillConcaveCorner()743 bool hasFillConcaveCorner() const 744 { 745 return false; // skip for now 746 } hasWithCut()747 bool hasWithCut() const 748 { 749 return false; // skip for now 750 } hasEndPrlSpacing()751 bool hasEndPrlSpacing() const 752 { 753 return false; // skip for now 754 } hasEndToEndConstraint()755 bool hasEndToEndConstraint() const 756 { 757 return (endToEndConstraint) ? true : false; 758 } 759 std::shared_ptr<frLef58SpacingEndOfLineWithinEndToEndConstraint> getEndToEndConstraint()760 getEndToEndConstraint() const 761 { 762 return endToEndConstraint; 763 } hasMinMaxLength()764 bool hasMinMaxLength() const 765 { 766 return false; // skip for now 767 } hasEqualRectWidth()768 bool hasEqualRectWidth() const 769 { 770 return false; // skip for now 771 } hasParallelEdgeConstraint()772 bool hasParallelEdgeConstraint() const 773 { 774 return (parallelEdgeConstraint) ? true : false; 775 } 776 std::shared_ptr<frLef58SpacingEndOfLineWithinParallelEdgeConstraint> getParallelEdgeConstraint()777 getParallelEdgeConstraint() const 778 { 779 return parallelEdgeConstraint; 780 } hasMaxMinLengthConstraint()781 bool hasMaxMinLengthConstraint() const 782 { 783 return (maxMinLengthConstraint) ? true : false; 784 } 785 std::shared_ptr<frLef58SpacingEndOfLineWithinMaxMinLengthConstraint> getMaxMinLengthConstraint()786 getMaxMinLengthConstraint() const 787 { 788 return maxMinLengthConstraint; 789 } hasEncloseCutConstraint()790 bool hasEncloseCutConstraint() const 791 { 792 return (encloseCutConstraint) ? true : false; 793 } 794 std::shared_ptr<frLef58SpacingEndOfLineWithinEncloseCutConstraint> getEncloseCutConstraint()795 getEncloseCutConstraint() const 796 { 797 return encloseCutConstraint; 798 } 799 // setters setOppositeWidth(frCoord in)800 void setOppositeWidth(frCoord in) 801 { 802 hOppositeWidth = true; 803 oppositeWidth = in; 804 } setEolWithin(frCoord in)805 void setEolWithin(frCoord in) 806 { 807 eolWithin = in; 808 wrongDirWithin = in; 809 } setWrongDirWithin(frCoord in)810 void setWrongDirWithin(frCoord in) { wrongDirWithin = in; } setSameMask(bool in)811 void setSameMask(bool in) { sameMask = in; } setEndToEndConstraint(const std::shared_ptr<frLef58SpacingEndOfLineWithinEndToEndConstraint> & in)812 void setEndToEndConstraint( 813 const std::shared_ptr<frLef58SpacingEndOfLineWithinEndToEndConstraint>& 814 in) 815 { 816 endToEndConstraint = in; 817 } setParallelEdgeConstraint(const std::shared_ptr<frLef58SpacingEndOfLineWithinParallelEdgeConstraint> & in)818 void setParallelEdgeConstraint( 819 const std::shared_ptr< 820 frLef58SpacingEndOfLineWithinParallelEdgeConstraint>& in) 821 { 822 parallelEdgeConstraint = in; 823 } setMaxMinLengthConstraint(const std::shared_ptr<frLef58SpacingEndOfLineWithinMaxMinLengthConstraint> & in)824 void setMaxMinLengthConstraint( 825 const std::shared_ptr< 826 frLef58SpacingEndOfLineWithinMaxMinLengthConstraint>& in) 827 { 828 maxMinLengthConstraint = in; 829 } setEncloseCutConstraint(const std::shared_ptr<frLef58SpacingEndOfLineWithinEncloseCutConstraint> & in)830 void setEncloseCutConstraint( 831 const std::shared_ptr<frLef58SpacingEndOfLineWithinEncloseCutConstraint>& 832 in) 833 { 834 encloseCutConstraint = in; 835 } 836 // others typeId()837 frConstraintTypeEnum typeId() const override 838 { 839 return frConstraintTypeEnum::frcLef58SpacingEndOfLineWithinConstraint; 840 } report(utl::Logger * logger)841 void report(utl::Logger* logger) const override 842 { 843 logger->report( 844 "\tSPACING_WITHIN hOppositeWidth {} oppositeWidth {} eolWithin {} " 845 "wrongDirWithin {} sameMask {} ", 846 hOppositeWidth, 847 oppositeWidth, 848 eolWithin, 849 wrongDirWithin, 850 sameMask); 851 if (endToEndConstraint != nullptr) 852 endToEndConstraint->report(logger); 853 if (parallelEdgeConstraint != nullptr) 854 parallelEdgeConstraint->report(logger); 855 } 856 857 protected: 858 bool hOppositeWidth; 859 frCoord oppositeWidth; 860 frCoord eolWithin; 861 frCoord wrongDirWithin; 862 bool sameMask; 863 std::shared_ptr<frLef58SpacingEndOfLineWithinEndToEndConstraint> 864 endToEndConstraint; 865 std::shared_ptr<frLef58SpacingEndOfLineWithinParallelEdgeConstraint> 866 parallelEdgeConstraint; 867 std::shared_ptr<frLef58SpacingEndOfLineWithinMaxMinLengthConstraint> 868 maxMinLengthConstraint; 869 std::shared_ptr<frLef58SpacingEndOfLineWithinEncloseCutConstraint> 870 encloseCutConstraint; 871 }; 872 873 class frLef58SpacingEndOfLineConstraint : public frConstraint 874 { 875 public: 876 // constructors frLef58SpacingEndOfLineConstraint()877 frLef58SpacingEndOfLineConstraint() 878 : eolSpace(0), 879 eolWidth(0), 880 exactWidth(false), 881 wrongDirSpacing(false), 882 wrongDirSpace(0), 883 withinConstraint(nullptr) 884 { 885 } 886 // getters getEolSpace()887 frCoord getEolSpace() const { return eolSpace; } getEolWidth()888 frCoord getEolWidth() const { return eolWidth; } hasExactWidth()889 bool hasExactWidth() const { return exactWidth; } hasWrongDirSpacing()890 bool hasWrongDirSpacing() const { return wrongDirSpacing; } getWrongDirSpace()891 frCoord getWrongDirSpace() const { return wrongDirSpace; } hasWithinConstraint()892 bool hasWithinConstraint() const { return (withinConstraint) ? true : false; } getWithinConstraint()893 std::shared_ptr<frLef58SpacingEndOfLineWithinConstraint> getWithinConstraint() 894 const 895 { 896 return withinConstraint; 897 } hasToConcaveCornerConstraint()898 bool hasToConcaveCornerConstraint() const { return false; } hasToNotchLengthConstraint()899 bool hasToNotchLengthConstraint() const { return false; } 900 // setters 901 void setEol(frCoord eolSpaceIn, frCoord eolWidthIn, bool exactWidthIn = false) 902 { 903 eolSpace = eolSpaceIn; 904 eolWidth = eolWidthIn; 905 exactWidth = exactWidthIn; 906 } setWrongDirSpace(bool in)907 void setWrongDirSpace(bool in) 908 { 909 wrongDirSpacing = true; 910 wrongDirSpace = in; 911 } setWithinConstraint(const std::shared_ptr<frLef58SpacingEndOfLineWithinConstraint> & in)912 void setWithinConstraint( 913 const std::shared_ptr<frLef58SpacingEndOfLineWithinConstraint>& in) 914 { 915 withinConstraint = in; 916 } 917 // others typeId()918 frConstraintTypeEnum typeId() const override 919 { 920 return frConstraintTypeEnum::frcLef58SpacingEndOfLineConstraint; 921 } report(utl::Logger * logger)922 void report(utl::Logger* logger) const override 923 { 924 logger->report( 925 "SPACING eolSpace {} eolWidth {} exactWidth {} wrongDirSpacing {} " 926 "wrongDirSpace {} ", 927 eolSpace, 928 eolWidth, 929 exactWidth, 930 wrongDirSpacing, 931 wrongDirSpace); 932 if (withinConstraint != nullptr) 933 withinConstraint->report(logger); 934 } 935 936 protected: 937 frCoord eolSpace; 938 frCoord eolWidth; 939 bool exactWidth; 940 bool wrongDirSpacing; 941 frCoord wrongDirSpace; 942 std::shared_ptr<frLef58SpacingEndOfLineWithinConstraint> withinConstraint; 943 }; 944 945 class frLef58EolKeepOutConstraint : public frConstraint 946 { 947 public: 948 // constructors frLef58EolKeepOutConstraint()949 frLef58EolKeepOutConstraint() 950 : backwardExt(0), 951 sideExt(0), 952 forwardExt(0), 953 eolWidth(0), 954 cornerOnly(false), 955 exceptWithin(false), 956 withinLow(0), 957 withinHigh(0) 958 { 959 } 960 // getters getBackwardExt()961 frCoord getBackwardExt() const { return backwardExt; } getForwardExt()962 frCoord getForwardExt() const { return forwardExt; } getSideExt()963 frCoord getSideExt() const { return sideExt; } getEolWidth()964 frCoord getEolWidth() const { return eolWidth; } isCornerOnly()965 bool isCornerOnly() const { return cornerOnly; } isExceptWithin()966 bool isExceptWithin() const { return exceptWithin; } getWithinLow()967 frCoord getWithinLow() const { return withinLow; } getWithinHigh()968 frCoord getWithinHigh() const { return withinHigh; } 969 // setters setBackwardExt(frCoord value)970 void setBackwardExt(frCoord value) { backwardExt = value; } setForwardExt(frCoord value)971 void setForwardExt(frCoord value) { forwardExt = value; } setSideExt(frCoord value)972 void setSideExt(frCoord value) { sideExt = value; } setEolWidth(frCoord value)973 void setEolWidth(frCoord value) { eolWidth = value; } setCornerOnly(bool value)974 void setCornerOnly(bool value) { cornerOnly = value; } setExceptWithin(bool value)975 void setExceptWithin(bool value) { exceptWithin = value; } setWithinLow(frCoord value)976 void setWithinLow(frCoord value) { withinLow = value; } setWithinHigh(frCoord value)977 void setWithinHigh(frCoord value) { withinHigh = value; } 978 // others typeId()979 frConstraintTypeEnum typeId() const override 980 { 981 return frConstraintTypeEnum::frcLef58EolKeepOutConstraint; 982 } report(utl::Logger * logger)983 void report(utl::Logger* logger) const override 984 { 985 logger->report( 986 "EOLKEEPOUT backwardExt {} sideExt {} forwardExt {} eolWidth {} " 987 "cornerOnly {}", 988 "exceptWithin {} withinLow {} withinHigh {}", 989 backwardExt, 990 sideExt, 991 forwardExt, 992 eolWidth, 993 cornerOnly, 994 exceptWithin, 995 withinLow, 996 withinHigh); 997 } 998 999 private: 1000 frCoord backwardExt; 1001 frCoord sideExt; 1002 frCoord forwardExt; 1003 frCoord eolWidth; 1004 bool cornerOnly; 1005 bool exceptWithin; 1006 frCoord withinLow, withinHigh; 1007 }; 1008 1009 class frLef58CornerSpacingSpacingConstraint; 1010 1011 // SPACING Constraints 1012 class frSpacingConstraint : public frConstraint 1013 { 1014 public: frSpacingConstraint()1015 frSpacingConstraint() : minSpacing(0) {} frSpacingConstraint(frCoord minSpacingIn)1016 frSpacingConstraint(frCoord minSpacingIn) : minSpacing(minSpacingIn) {} 1017 1018 // getter getMinSpacing()1019 frCoord getMinSpacing() const { return minSpacing; } 1020 // setter setMinSpacing(frCoord minSpacingIn)1021 void setMinSpacing(frCoord minSpacingIn) { minSpacing = minSpacingIn; } 1022 // check typeId()1023 frConstraintTypeEnum typeId() const override 1024 { 1025 return frConstraintTypeEnum::frcSpacingConstraint; 1026 } report(utl::Logger * logger)1027 void report(utl::Logger* logger) const override 1028 { 1029 logger->report("Spacing {}", minSpacing); 1030 } 1031 1032 protected: 1033 frCoord minSpacing; 1034 }; 1035 1036 class frSpacingSamenetConstraint : public frSpacingConstraint 1037 { 1038 public: frSpacingSamenetConstraint()1039 frSpacingSamenetConstraint() : frSpacingConstraint(), pgonly(false) {} frSpacingSamenetConstraint(frCoord minSpacingIn,bool pgonlyIn)1040 frSpacingSamenetConstraint(frCoord minSpacingIn, bool pgonlyIn) 1041 : frSpacingConstraint(minSpacingIn), pgonly(pgonlyIn) 1042 { 1043 } 1044 // getter hasPGonly()1045 bool hasPGonly() const { return pgonly; } 1046 // setter setPGonly(bool in)1047 void setPGonly(bool in) { pgonly = in; } 1048 // check typeId()1049 frConstraintTypeEnum typeId() const override 1050 { 1051 return frConstraintTypeEnum::frcSpacingSamenetConstraint; 1052 } report(utl::Logger * logger)1053 void report(utl::Logger* logger) const override 1054 { 1055 logger->report("Spacing same net pgonly {}", pgonly); 1056 } 1057 1058 protected: 1059 bool pgonly; 1060 }; 1061 1062 class frSpacingTableInfluenceConstraint : public frConstraint 1063 { 1064 public: frSpacingTableInfluenceConstraint(const fr1DLookupTbl<frCoord,std::pair<frCoord,frCoord>> & in)1065 frSpacingTableInfluenceConstraint( 1066 const fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>& in) 1067 : tbl(in) 1068 { 1069 } 1070 // getter getLookupTbl()1071 const fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>& getLookupTbl() 1072 const 1073 { 1074 return tbl; 1075 } find(frCoord width)1076 std::pair<frCoord, frCoord> find(frCoord width) const 1077 { 1078 return tbl.find(width); 1079 } getMinWidth()1080 frCoord getMinWidth() const { return tbl.getMinRow(); } 1081 // setter setLookupTbl(const fr1DLookupTbl<frCoord,std::pair<frCoord,frCoord>> & in)1082 void setLookupTbl( 1083 const fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>& in) 1084 { 1085 tbl = in; 1086 } 1087 typeId()1088 frConstraintTypeEnum typeId() const override 1089 { 1090 return frConstraintTypeEnum::frcSpacingTableInfluenceConstraint; 1091 } report(utl::Logger * logger)1092 void report(utl::Logger* logger) const override 1093 { 1094 logger->report("Spacing table influence"); 1095 } 1096 1097 private: 1098 fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>> tbl; 1099 }; 1100 1101 // EOL spacing 1102 class frSpacingEndOfLineConstraint : public frSpacingConstraint 1103 { 1104 public: 1105 // constructor frSpacingEndOfLineConstraint()1106 frSpacingEndOfLineConstraint() 1107 : frSpacingConstraint(), 1108 eolWidth(-1), 1109 eolWithin(-1), 1110 parSpace(-1), 1111 parWithin(-1), 1112 isTwoEdges(false) 1113 { 1114 } 1115 // getter getEolWidth()1116 frCoord getEolWidth() const { return eolWidth; } getEolWithin()1117 frCoord getEolWithin() const { return eolWithin; } getParSpace()1118 frCoord getParSpace() const { return parSpace; } getParWithin()1119 frCoord getParWithin() const { return parWithin; } hasParallelEdge()1120 bool hasParallelEdge() const { return ((parSpace == -1) ? false : true); } hasTwoEdges()1121 bool hasTwoEdges() const { return isTwoEdges; } 1122 // setter setEolWithin(frCoord eolWithinIn)1123 void setEolWithin(frCoord eolWithinIn) { eolWithin = eolWithinIn; } setEolWidth(frCoord eolWidthIn)1124 void setEolWidth(frCoord eolWidthIn) { eolWidth = eolWidthIn; } setParSpace(frCoord parSpaceIn)1125 void setParSpace(frCoord parSpaceIn) { parSpace = parSpaceIn; } setParWithin(frCoord parWithinIn)1126 void setParWithin(frCoord parWithinIn) { parWithin = parWithinIn; } setTwoEdges(bool isTwoEdgesIn)1127 void setTwoEdges(bool isTwoEdgesIn) { isTwoEdges = isTwoEdgesIn; } typeId()1128 frConstraintTypeEnum typeId() const override 1129 { 1130 return frConstraintTypeEnum::frcSpacingEndOfLineConstraint; 1131 } report(utl::Logger * logger)1132 void report(utl::Logger* logger) const override 1133 { 1134 logger->report( 1135 "Spacing EOL eolWidth {} eolWithin {} " 1136 "parSpace {} parWithin {} isTwoEdges {}", 1137 eolWidth, 1138 eolWithin, 1139 parSpace, 1140 parWithin, 1141 isTwoEdges); 1142 } 1143 1144 protected: 1145 frCoord eolWidth, eolWithin; 1146 frCoord parSpace, parWithin; 1147 bool isTwoEdges; 1148 }; 1149 1150 class frLef58CutSpacingTableLayerConstraint : public frConstraint 1151 { 1152 public: 1153 // constructors frLef58CutSpacingTableLayerConstraint()1154 frLef58CutSpacingTableLayerConstraint() : secondLayerNum(0), nonZeroEnc(false) 1155 { 1156 } 1157 // getters getSecondLayerNum()1158 frLayerNum getSecondLayerNum() const { return secondLayerNum; } isNonZeroEnc()1159 bool isNonZeroEnc() const { return nonZeroEnc; } 1160 // setters setSecondLayerNum(frLayerNum in)1161 void setSecondLayerNum(frLayerNum in) { secondLayerNum = in; } setNonZeroEnc(bool in)1162 void setNonZeroEnc(bool in) { nonZeroEnc = in; } 1163 // others typeId()1164 frConstraintTypeEnum typeId() const override 1165 { 1166 return frConstraintTypeEnum::frcLef58CutSpacingTableLayerConstraint; 1167 } report(utl::Logger * logger)1168 void report(utl::Logger* logger) const override 1169 { 1170 logger->report("\tLAYERCONSTRAINT secondLayerNum {} nonZeroEnc {} ", 1171 secondLayerNum, 1172 nonZeroEnc); 1173 } 1174 1175 protected: 1176 frLayerNum secondLayerNum; 1177 bool nonZeroEnc; 1178 }; 1179 1180 class frLef58CutSpacingTablePrlConstraint : public frConstraint 1181 { 1182 public: 1183 // constructors frLef58CutSpacingTablePrlConstraint()1184 frLef58CutSpacingTablePrlConstraint() 1185 : prl(0), horizontal(false), vertical(false), maxXY(false) 1186 { 1187 } 1188 // getters getPrl()1189 frCoord getPrl() const { return prl; } isHorizontal()1190 bool isHorizontal() const { return horizontal; } isVertical()1191 bool isVertical() const { return vertical; } isMaxXY()1192 bool isMaxXY() const { return maxXY; } 1193 // setters setPrl(frCoord in)1194 void setPrl(frCoord in) { prl = in; } setHorizontal(bool in)1195 void setHorizontal(bool in) { horizontal = in; } setVertical(bool in)1196 void setVertical(bool in) { vertical = in; } setMaxXY(bool in)1197 void setMaxXY(bool in) { maxXY = in; } 1198 // others typeId()1199 frConstraintTypeEnum typeId() const override 1200 { 1201 return frConstraintTypeEnum::frcLef58CutSpacingTablePrlConstraint; 1202 } report(utl::Logger * logger)1203 void report(utl::Logger* logger) const override 1204 { 1205 logger->report("\tPRLCONSTRAINT prl {} horizontal {} vertical {} maxXY {} ", 1206 prl, 1207 horizontal, 1208 vertical, 1209 maxXY); 1210 } 1211 1212 protected: 1213 frCoord prl; 1214 bool horizontal; 1215 bool vertical; 1216 bool maxXY; 1217 }; 1218 1219 class frLef58EolExtensionConstraint : public frSpacingConstraint 1220 { 1221 public: 1222 // constructors frLef58EolExtensionConstraint(const fr1DLookupTbl<frCoord,frCoord> & tbl)1223 frLef58EolExtensionConstraint(const fr1DLookupTbl<frCoord, frCoord>& tbl) 1224 : frSpacingConstraint(), parallelOnly(false), extensionTbl(tbl) 1225 { 1226 } 1227 // setters 1228 setParallelOnly(bool value)1229 void setParallelOnly(bool value) { parallelOnly = value; } 1230 1231 // getters 1232 isParallelOnly()1233 bool isParallelOnly() const { return parallelOnly; } 1234 getExtensionTable()1235 fr1DLookupTbl<frCoord, frCoord> getExtensionTable() const 1236 { 1237 return extensionTbl; 1238 } 1239 1240 // others 1241 typeId()1242 frConstraintTypeEnum typeId() const override 1243 { 1244 return frConstraintTypeEnum::frcLef58EolExtensionConstraint; 1245 } 1246 report(utl::Logger * logger)1247 void report(utl::Logger* logger) const override 1248 { 1249 logger->report("EOLEXTENSIONSPACING spacing {} parallelonly {} ", 1250 minSpacing, 1251 parallelOnly); 1252 } 1253 1254 private: 1255 bool parallelOnly; 1256 fr1DLookupTbl<frCoord, frCoord> extensionTbl; 1257 }; 1258 1259 // LEF58 cut spacing table 1260 class frLef58CutSpacingTableConstraint : public frConstraint 1261 { 1262 public: 1263 // constructor frLef58CutSpacingTableConstraint()1264 frLef58CutSpacingTableConstraint() 1265 : cutClassHasAll(false), defaultCutSpacing(0) 1266 { 1267 } 1268 // getter 1269 std::shared_ptr< 1270 fr2DLookupTbl<frString, frString, std::pair<frCoord, frCoord>>> getCutClassTbl()1271 getCutClassTbl() const 1272 { 1273 return cutClassTbl; 1274 } hasPrlConstraint()1275 bool hasPrlConstraint() const { return (prlConstraint) ? true : false; } getPrlConstraint()1276 std::shared_ptr<frLef58CutSpacingTablePrlConstraint> getPrlConstraint() const 1277 { 1278 return prlConstraint; 1279 } hasLayerConstraint()1280 bool hasLayerConstraint() const { return (layerConstraint) ? true : false; } getLayerConstraint()1281 std::shared_ptr<frLef58CutSpacingTableLayerConstraint> getLayerConstraint() 1282 const 1283 { 1284 return layerConstraint; 1285 } hasAll()1286 bool hasAll() const { return cutClassHasAll; } getDefaultCutSpacing()1287 frCoord getDefaultCutSpacing() const { return defaultCutSpacing; } 1288 // setter setCutClassTbl(std::shared_ptr<fr2DLookupTbl<frString,frString,std::pair<frCoord,frCoord>>> & in)1289 void setCutClassTbl( 1290 std::shared_ptr< 1291 fr2DLookupTbl<frString, frString, std::pair<frCoord, frCoord>>>& in) 1292 { 1293 cutClassTbl = in; 1294 } setPrlConstraint(const std::shared_ptr<frLef58CutSpacingTablePrlConstraint> & in)1295 void setPrlConstraint( 1296 const std::shared_ptr<frLef58CutSpacingTablePrlConstraint>& in) 1297 { 1298 prlConstraint = in; 1299 } setLayerConstraint(const std::shared_ptr<frLef58CutSpacingTableLayerConstraint> & in)1300 void setLayerConstraint( 1301 const std::shared_ptr<frLef58CutSpacingTableLayerConstraint>& in) 1302 { 1303 layerConstraint = in; 1304 } setAll(bool in)1305 void setAll(bool in) { cutClassHasAll = in; } setDefaultCutSpacing(frCoord in)1306 void setDefaultCutSpacing(frCoord in) { defaultCutSpacing = in; } report(utl::Logger * logger)1307 void report(utl::Logger* logger) const override 1308 { 1309 logger->report("CUTSPACINGTABLE defaultCutSpacing {} cutClassHasAll {}"); 1310 if (prlConstraint != nullptr) 1311 prlConstraint->report(logger); 1312 if (layerConstraint != nullptr) 1313 layerConstraint->report(logger); 1314 if (cutClassTbl != nullptr) { 1315 std::string cols = ""; 1316 std::string rows = ""; 1317 for (auto row : cutClassTbl->getRows()) 1318 rows = rows + row + " "; 1319 for (auto col : cutClassTbl->getCols()) 1320 cols = cols + col + " "; 1321 logger->report("\trowName: {}", cutClassTbl->getRowName()); 1322 logger->report("\trows: {}", rows); 1323 logger->report("\trcolName: {}", cutClassTbl->getColName()); 1324 logger->report("\tcols: {}", cols); 1325 auto tbl = cutClassTbl->getValues(); 1326 for (auto row : tbl) { 1327 std::string vals = ""; 1328 for (auto col : row) 1329 vals = vals + "(" + std::to_string(col.first) + "," 1330 + std::to_string(col.second) + ") "; 1331 logger->report("\t{}", vals); 1332 } 1333 } 1334 } 1335 // others typeId()1336 frConstraintTypeEnum typeId() const override 1337 { 1338 return frConstraintTypeEnum::frcLef58CutSpacingTableConstraint; 1339 } 1340 1341 protected: 1342 std::shared_ptr< 1343 fr2DLookupTbl<frString, frString, std::pair<frCoord, frCoord>>> 1344 cutClassTbl; 1345 std::shared_ptr<frLef58CutSpacingTablePrlConstraint> prlConstraint; 1346 std::shared_ptr<frLef58CutSpacingTableLayerConstraint> layerConstraint; 1347 bool cutClassHasAll; 1348 frCoord defaultCutSpacing; 1349 }; 1350 1351 // new SPACINGTABLE Constraints 1352 class frSpacingTablePrlConstraint : public frConstraint 1353 { 1354 public: 1355 // constructor frSpacingTablePrlConstraint(const fr2DLookupTbl<frCoord,frCoord,frCoord> & in)1356 frSpacingTablePrlConstraint( 1357 const fr2DLookupTbl<frCoord, frCoord, frCoord>& in) 1358 : tbl(in) 1359 { 1360 } 1361 // getter getLookupTbl()1362 const fr2DLookupTbl<frCoord, frCoord, frCoord>& getLookupTbl() const 1363 { 1364 return tbl; 1365 } find(frCoord width,frCoord prl)1366 frCoord find(frCoord width, frCoord prl) const 1367 { 1368 return tbl.find(width, prl); 1369 } findMin()1370 frCoord findMin() const { return tbl.findMin(); } findMax()1371 frCoord findMax() const { return tbl.findMax(); } 1372 // setter setLookupTbl(const fr2DLookupTbl<frCoord,frCoord,frCoord> & in)1373 void setLookupTbl(const fr2DLookupTbl<frCoord, frCoord, frCoord>& in) 1374 { 1375 tbl = in; 1376 } typeId()1377 frConstraintTypeEnum typeId() const override 1378 { 1379 return frConstraintTypeEnum::frcSpacingTablePrlConstraint; 1380 } report(utl::Logger * logger)1381 void report(utl::Logger* logger) const override 1382 { 1383 logger->report("Spacing table PRL"); 1384 } 1385 1386 protected: 1387 fr2DLookupTbl<frCoord, frCoord, frCoord> tbl; 1388 }; 1389 1390 struct frSpacingTableTwRowType 1391 { frSpacingTableTwRowTypefrSpacingTableTwRowType1392 frSpacingTableTwRowType(frCoord in1, frCoord in2) : width(in1), prl(in2) {} 1393 frCoord width; 1394 frCoord prl; 1395 }; 1396 // new SPACINGTABLE Constraints 1397 class frSpacingTableTwConstraint : public frConstraint 1398 { 1399 public: 1400 // constructor frSpacingTableTwConstraint(const frCollection<frSpacingTableTwRowType> & rowsIn,const frCollection<frCollection<frCoord>> & spacingIn)1401 frSpacingTableTwConstraint( 1402 const frCollection<frSpacingTableTwRowType>& rowsIn, 1403 const frCollection<frCollection<frCoord>>& spacingIn) 1404 : rows(rowsIn), spacingTbl(spacingIn) 1405 { 1406 } 1407 // getter find(frCoord width1,frCoord width2,frCoord prl)1408 frCoord find(frCoord width1, frCoord width2, frCoord prl) const 1409 { 1410 if (rows.empty()) 1411 return 0; 1412 auto rowIdx = getIdx(width1, prl); 1413 auto colIdx = getIdx(width2, prl); 1414 return spacingTbl[rowIdx][colIdx]; 1415 } findMin()1416 frCoord findMin() const { return spacingTbl.front().front(); } findMax()1417 frCoord findMax() const { return spacingTbl.back().back(); } 1418 // setter setSpacingTable(const frCollection<frSpacingTableTwRowType> & rowsIn,const frCollection<frCollection<frCoord>> & spacingIn)1419 void setSpacingTable(const frCollection<frSpacingTableTwRowType>& rowsIn, 1420 const frCollection<frCollection<frCoord>>& spacingIn) 1421 { 1422 rows = rowsIn; 1423 spacingTbl = spacingIn; 1424 } 1425 typeId()1426 frConstraintTypeEnum typeId() const override 1427 { 1428 return frConstraintTypeEnum::frcSpacingTableTwConstraint; 1429 } report(utl::Logger * logger)1430 void report(utl::Logger* logger) const override 1431 { 1432 logger->report("Spacing table tw"); 1433 } 1434 1435 private: 1436 frCollection<frSpacingTableTwRowType> rows; 1437 frCollection<frCollection<frCoord>> spacingTbl; getIdx(frCoord width,frCoord prl)1438 frUInt4 getIdx(frCoord width, frCoord prl) const 1439 { 1440 int sz = rows.size(); 1441 for (int i = 0; i < sz; i++) { 1442 if (width <= rows[i].width) 1443 return std::max(0, i - 1); 1444 if (rows[i].prl != -1 && prl <= rows[i].prl) 1445 return std::max(0, i - 1); 1446 } 1447 return sz - 1; 1448 } 1449 }; 1450 1451 // original SPACINGTABLE Constraints 1452 class frSpacingTableConstraint : public frConstraint 1453 { 1454 public: 1455 // constructor frSpacingTableConstraint(std::shared_ptr<fr2DLookupTbl<frCoord,frCoord,frCoord>> parallelRunLengthConstraintIn)1456 frSpacingTableConstraint( 1457 std::shared_ptr<fr2DLookupTbl<frCoord, frCoord, frCoord>> 1458 parallelRunLengthConstraintIn) 1459 { 1460 parallelRunLengthConstraint = parallelRunLengthConstraintIn; 1461 } 1462 // getter 1463 std::shared_ptr<fr2DLookupTbl<frCoord, frCoord, frCoord>> getParallelRunLengthConstraint()1464 getParallelRunLengthConstraint() 1465 { 1466 return parallelRunLengthConstraint; 1467 } 1468 // setter setParallelRunLengthConstraint(std::shared_ptr<fr2DLookupTbl<frCoord,frCoord,frCoord>> & parallelRunLengthConstraintIn)1469 void setParallelRunLengthConstraint( 1470 std::shared_ptr<fr2DLookupTbl<frCoord, frCoord, frCoord>>& 1471 parallelRunLengthConstraintIn) 1472 { 1473 parallelRunLengthConstraint = parallelRunLengthConstraintIn; 1474 } 1475 typeId()1476 frConstraintTypeEnum typeId() const override 1477 { 1478 return frConstraintTypeEnum::frcSpacingTableConstraint; 1479 } report(utl::Logger * logger)1480 void report(utl::Logger* logger) const override 1481 { 1482 logger->report("Spacing table"); 1483 } 1484 1485 protected: 1486 std::shared_ptr<fr2DLookupTbl<frCoord, frCoord, frCoord>> 1487 parallelRunLengthConstraint; 1488 }; 1489 1490 class frLef58SpacingTableConstraint : public frSpacingTableConstraint 1491 { 1492 public: 1493 // constructor frLef58SpacingTableConstraint(const std::shared_ptr<fr2DLookupTbl<frCoord,frCoord,frCoord>> & parallelRunLengthConstraintIn,const std::map<int,std::pair<frCoord,frCoord>> & exceptWithinConstraintIn)1494 frLef58SpacingTableConstraint( 1495 const std::shared_ptr<fr2DLookupTbl<frCoord, frCoord, frCoord>>& 1496 parallelRunLengthConstraintIn, 1497 const std::map<int, std::pair<frCoord, frCoord>>& 1498 exceptWithinConstraintIn) 1499 : frSpacingTableConstraint(parallelRunLengthConstraintIn), 1500 exceptWithinConstraint(exceptWithinConstraintIn), 1501 wrongDirection(false), 1502 sameMask(false), 1503 exceptEol(false), 1504 eolWidth(0) 1505 { 1506 } 1507 // getter hasExceptWithin(frCoord val)1508 bool hasExceptWithin(frCoord val) const 1509 { 1510 auto rowIdx = parallelRunLengthConstraint->getRowIdx(val); 1511 return (exceptWithinConstraint.find(rowIdx) 1512 != exceptWithinConstraint.end()); 1513 } getExceptWithin(frCoord val)1514 std::pair<frCoord, frCoord> getExceptWithin(frCoord val) const 1515 { 1516 auto rowIdx = parallelRunLengthConstraint->getRowIdx(val); 1517 return exceptWithinConstraint.at(rowIdx); 1518 } isWrongDirection()1519 bool isWrongDirection() const { return wrongDirection; } isSameMask()1520 bool isSameMask() const { return sameMask; } hasExceptEol()1521 bool hasExceptEol() const { return exceptEol; } getEolWidth()1522 frUInt4 getEolWidth() const { return eolWidth; } 1523 // setters setExceptWithinConstraint(std::map<int,std::pair<frCoord,frCoord>> & exceptWithinConstraintIn)1524 void setExceptWithinConstraint( 1525 std::map<int, std::pair<frCoord, frCoord>>& exceptWithinConstraintIn) 1526 { 1527 exceptWithinConstraint = exceptWithinConstraintIn; 1528 } setWrongDirection(bool in)1529 void setWrongDirection(bool in) { wrongDirection = in; } setSameMask(bool in)1530 void setSameMask(bool in) { sameMask = in; } setEolWidth(frUInt4 in)1531 void setEolWidth(frUInt4 in) 1532 { 1533 exceptEol = true; 1534 eolWidth = in; 1535 } 1536 typeId()1537 frConstraintTypeEnum typeId() const override 1538 { 1539 return frConstraintTypeEnum::frcLef58SpacingTableConstraint; 1540 } 1541 report(utl::Logger * logger)1542 void report(utl::Logger* logger) const override 1543 { 1544 logger->report( 1545 "SPACINGTABLE wrongDirection {} sameMask {} exceptEol {} eolWidth {} ", 1546 wrongDirection, 1547 sameMask, 1548 exceptEol, 1549 eolWidth); 1550 logger->report("\texceptWithinConstraint"); 1551 for (auto& [key, val] : exceptWithinConstraint) 1552 logger->report("\t{} ({} {})", key, val.first, val.second); 1553 } 1554 1555 protected: 1556 std::map<frCoord, std::pair<frCoord, frCoord>> exceptWithinConstraint; 1557 bool wrongDirection; 1558 bool sameMask; 1559 bool exceptEol; 1560 frUInt4 eolWidth; 1561 }; 1562 1563 // ADJACENTCUTS 1564 class frCutSpacingConstraint : public frConstraint 1565 { 1566 public: 1567 // constructor frCutSpacingConstraint()1568 frCutSpacingConstraint() {} 1569 frCutSpacingConstraint(frCoord cutSpacingIn, 1570 bool centerToCenterIn, 1571 bool sameNetIn, 1572 frString secondLayerNameIn, 1573 bool stackIn, 1574 int adjacentCutsIn, 1575 frCoord cutWithinIn, 1576 bool isExceptSamePGNetIn, 1577 bool isParallelOverlapIn, 1578 frCoord cutAreaIn, 1579 int twoCutsIn = -1) 1580 { 1581 cutSpacing = cutSpacingIn; 1582 centerToCenter = centerToCenterIn; 1583 sameNet = sameNetIn; 1584 secondLayerName = secondLayerNameIn; 1585 stack = stackIn; 1586 adjacentCuts = adjacentCutsIn; 1587 cutWithin = cutWithinIn; 1588 exceptSamePGNet = isExceptSamePGNetIn; 1589 parallelOverlap = isParallelOverlapIn; 1590 cutArea = cutAreaIn; 1591 twoCuts = twoCutsIn; 1592 } 1593 // getter hasCenterToCenter()1594 bool hasCenterToCenter() const { return centerToCenter; } getCenterToCenter()1595 bool getCenterToCenter() const { return centerToCenter; } getSameNet()1596 bool getSameNet() const { return sameNet; } hasSameNet()1597 bool hasSameNet() const { return sameNet; } getSameNetConstraint()1598 frCutSpacingConstraint* getSameNetConstraint() { return sameNetConstraint; } getStack()1599 bool getStack() const { return stack; } hasStack()1600 bool hasStack() const { return stack; } isLayer()1601 bool isLayer() const { return !(secondLayerName.empty()); } getSecondLayerName()1602 const frString& getSecondLayerName() const { return secondLayerName; } hasSecondLayer()1603 bool hasSecondLayer() const { return (secondLayerNum != -1); } getSecondLayerNum()1604 frLayerNum getSecondLayerNum() const { return secondLayerNum; } isAdjacentCuts()1605 bool isAdjacentCuts() const { return (adjacentCuts != -1); } getAdjacentCuts()1606 int getAdjacentCuts() const { return adjacentCuts; } getCutWithin()1607 frCoord getCutWithin() const { return cutWithin; } hasExceptSamePGNet()1608 bool hasExceptSamePGNet() const { return exceptSamePGNet; } getExceptSamePGNet()1609 bool getExceptSamePGNet() const { return exceptSamePGNet; } isParallelOverlap()1610 bool isParallelOverlap() const { return parallelOverlap; } getParallelOverlap()1611 bool getParallelOverlap() const { return parallelOverlap; } isArea()1612 bool isArea() const { return !(cutArea == -1); } getCutArea()1613 bool getCutArea() const { return cutArea; } getCutSpacing()1614 frCoord getCutSpacing() const { return cutSpacing; } typeId()1615 frConstraintTypeEnum typeId() const override 1616 { 1617 return frConstraintTypeEnum::frcCutSpacingConstraint; 1618 } 1619 // LEF58 related isTwoCuts()1620 bool isTwoCuts() const { return (twoCuts == -1); } getTwoCuts()1621 int getTwoCuts() const { return twoCuts; } 1622 report(utl::Logger * logger)1623 void report(utl::Logger* logger) const override 1624 { 1625 logger->report("Cut Spacing"); 1626 } 1627 1628 // setter 1629 setSecondLayerNum(int secondLayerNumIn)1630 void setSecondLayerNum(int secondLayerNumIn) 1631 { 1632 secondLayerNum = secondLayerNumIn; 1633 } 1634 setSameNetConstraint(frCutSpacingConstraint * in)1635 void setSameNetConstraint(frCutSpacingConstraint* in) 1636 { 1637 sameNetConstraint = in; 1638 } 1639 1640 protected: 1641 frCoord cutSpacing = -1; 1642 bool centerToCenter = false; 1643 bool sameNet = false; 1644 frCutSpacingConstraint* sameNetConstraint = nullptr; 1645 bool stack = false; 1646 bool exceptSamePGNet = false; 1647 bool parallelOverlap = false; 1648 frString secondLayerName; 1649 frLayerNum secondLayerNum = -1; 1650 int adjacentCuts = -1; 1651 frCoord cutWithin = -1; 1652 frCoord cutArea = -1; 1653 // LEF58 related 1654 int twoCuts = -1; 1655 }; 1656 1657 // LEF58_SPACING for cut layer (new) 1658 class frLef58CutSpacingConstraint : public frConstraint 1659 { 1660 public: 1661 // constructor frLef58CutSpacingConstraint()1662 frLef58CutSpacingConstraint() 1663 : cutSpacing(-1), 1664 sameMask(false), 1665 maxXY(false), 1666 centerToCenter(false), 1667 sameNet(false), 1668 sameMetal(false), 1669 sameVia(false), 1670 secondLayerName(""), 1671 secondLayerNum(-1), 1672 stack(false), 1673 orthogonalSpacing(-1), 1674 cutClassName(""), 1675 cutClassIdx(-1), 1676 shortEdgeOnly(false), 1677 prl(-1), 1678 concaveCorner(false), 1679 width(-1), 1680 enclosure(-1), 1681 edgeLength(-1), 1682 parLength(-1), 1683 parWithin(-1), 1684 edgeEnclosure(-1), 1685 adjEnclosure(-1), 1686 extension(-1), 1687 eolWidth(-1), 1688 minLength(-1), 1689 maskOverlap(false), 1690 wrongDirection(false), 1691 adjacentCuts(-1), 1692 exactAlignedCut(-1), 1693 twoCuts(-1), 1694 twoCutsSpacing(-1), 1695 sameCut(false), 1696 cutWithin1(-1), 1697 cutWithin2(-1), 1698 exceptSamePGNet(false), 1699 exceptAllWithin(-1), 1700 above(false), 1701 below(false), 1702 toAll(false), 1703 noPrl(false), 1704 sideParallelOverlap(false), 1705 parallelOverlap(false), 1706 exceptSameNet(false), 1707 exceptSameMetal(false), 1708 exceptSameMetalOverlap(false), 1709 exceptSameVia(false), 1710 within(-1), 1711 longEdgeOnly(false), 1712 exceptTwoEdges(false), 1713 numCut(-1), 1714 cutArea(-1) 1715 { 1716 } 1717 // getters 1718 // is == what rules have; has == what derived from values getCutSpacing()1719 frCoord getCutSpacing() const { return cutSpacing; } isSameMask()1720 bool isSameMask() const { return sameMask; } isMaxXY()1721 bool isMaxXY() const { return maxXY; } isCenterToCenter()1722 bool isCenterToCenter() const { return centerToCenter; } isSameNet()1723 bool isSameNet() const { return sameNet; } isSameMetal()1724 bool isSameMetal() const { return sameMetal; } isSameVia()1725 bool isSameVia() const { return sameVia; } getSecondLayerName()1726 std::string getSecondLayerName() const { return secondLayerName; } hasSecondLayer()1727 bool hasSecondLayer() const 1728 { 1729 return (secondLayerNum != -1 || secondLayerName != std::string("")); 1730 } getSecondLayerNum()1731 frLayerNum getSecondLayerNum() const { return secondLayerNum; } isStack()1732 bool isStack() const { return stack; } hasOrthogonalSpacing()1733 bool hasOrthogonalSpacing() const { return (orthogonalSpacing != -1); } getCutClassName()1734 std::string getCutClassName() const { return cutClassName; } hasCutClass()1735 bool hasCutClass() const 1736 { 1737 return (cutClassIdx != -1 || cutClassName != std::string("")); 1738 } getCutClassIdx()1739 int getCutClassIdx() const { return cutClassIdx; } isShortEdgeOnly()1740 bool isShortEdgeOnly() const { return shortEdgeOnly; } hasPrl()1741 bool hasPrl() const { return (prl != -1); } getPrl()1742 frCoord getPrl() const { return prl; } isConcaveCorner()1743 bool isConcaveCorner() const { return concaveCorner; } hasWidth()1744 bool hasWidth() const { return (width != -1); } getWidth()1745 frCoord getWidth() const { return width; } hasEnclosure()1746 bool hasEnclosure() const { return (enclosure != -1); } getEnclosure()1747 frCoord getEnclosure() const { return enclosure; } hasEdgeLength()1748 bool hasEdgeLength() const { return (edgeLength != -1); } getEdgeLength()1749 frCoord getEdgeLength() const { return edgeLength; } hasParallel()1750 bool hasParallel() const { return (parLength != -1); } getParlength()1751 frCoord getParlength() const { return parLength; } getParWithin()1752 frCoord getParWithin() const { return parWithin; } getEdgeEnclosure()1753 frCoord getEdgeEnclosure() const { return edgeEnclosure; } getAdjEnclosure()1754 frCoord getAdjEnclosure() const { return adjEnclosure; } hasExtension()1755 bool hasExtension() const { return (extension != -1); } getExtension()1756 frCoord getExtension() const { return extension; } hasNonEolConvexCorner()1757 bool hasNonEolConvexCorner() const { return (eolWidth != -1); } getEolWidth()1758 frCoord getEolWidth() const { return eolWidth; } hasMinLength()1759