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   bool hasMinLength() const { return (minLength != -1); }
getMinLength()1760   frCoord getMinLength() const { return minLength; }
hasAboveWidth()1761   bool hasAboveWidth() const { return (width != -1); }
isMaskOverlap()1762   bool isMaskOverlap() const { return maskOverlap; }
isWrongDirection()1763   bool isWrongDirection() const { return wrongDirection; }
hasAdjacentCuts()1764   bool hasAdjacentCuts() const { return (adjacentCuts != -1); }
getAdjacentCuts()1765   int getAdjacentCuts() const { return adjacentCuts; }
hasExactAligned()1766   bool hasExactAligned() const { return (exactAlignedCut != -1); }
getExactAligned()1767   int getExactAligned() const { return exactAlignedCut; }
hasTwoCuts()1768   bool hasTwoCuts() const { return (twoCuts != -1); }
getTwoCuts()1769   int getTwoCuts() const { return twoCuts; }
hasTwoCutsSpacing()1770   bool hasTwoCutsSpacing() const { return (twoCutsSpacing != -1); }
getTwoCutsSpacing()1771   frCoord getTwoCutsSpacing() const { return twoCutsSpacing; }
isSameCut()1772   bool isSameCut() const { return sameCut; }
1773   // cutWithin2 is always used as upper bound
hasTwoCutWithin()1774   bool hasTwoCutWithin() const { return (cutWithin1 != -1); }
getCutWithin()1775   frCoord getCutWithin() const { return cutWithin2; }
getCutWithin1()1776   frCoord getCutWithin1() const { return cutWithin1; }
getCutWithin2()1777   frCoord getCutWithin2() const { return cutWithin2; }
isExceptSamePGNet()1778   bool isExceptSamePGNet() const { return exceptSamePGNet; }
hasExceptAllWithin()1779   bool hasExceptAllWithin() const { return (exceptAllWithin != -1); }
getExceptAllWithin()1780   frCoord getExceptAllWithin() const { return exceptAllWithin; }
isAbove()1781   bool isAbove() const { return above; }
isBelow()1782   bool isBelow() const { return below; }
isToAll()1783   bool isToAll() const { return toAll; }
isNoPrl()1784   bool isNoPrl() const { return noPrl; }
isSideParallelOverlap()1785   bool isSideParallelOverlap() const { return sideParallelOverlap; }
isParallelOverlap()1786   bool isParallelOverlap() const { return parallelOverlap; }
isExceptSameNet()1787   bool isExceptSameNet() const { return exceptSameNet; }
isExceptSameMetal()1788   bool isExceptSameMetal() const { return exceptSameMetal; }
isExceptSameMetalOverlap()1789   bool isExceptSameMetalOverlap() const { return exceptSameMetalOverlap; }
isExceptSameVia()1790   bool isExceptSameVia() const { return exceptSameVia; }
hasParallelWithin()1791   bool hasParallelWithin() const { return (within != -1); }
getWithin()1792   frCoord getWithin() const { return within; }
isLongEdgeOnly()1793   bool isLongEdgeOnly() const { return longEdgeOnly; }
hasSameMetalSharedEdge()1794   bool hasSameMetalSharedEdge() const { return (parWithin != -1); }
isExceptTwoEdges()1795   bool isExceptTwoEdges() const { return exceptTwoEdges; }
hasExceptSameVia()1796   bool hasExceptSameVia() const { return (numCut != -1); }
hasArea()1797   bool hasArea() const { return (cutArea != -1); }
getCutArea()1798   frCoord getCutArea() const { return cutArea; }
1799   // setters
setCutSpacing(frCoord in)1800   void setCutSpacing(frCoord in) { cutSpacing = in; }
setSameMask(bool in)1801   void setSameMask(bool in) { sameMask = in; }
setMaxXY(bool in)1802   void setMaxXY(bool in) { maxXY = in; }
setCenterToCenter(bool in)1803   void setCenterToCenter(bool in) { centerToCenter = in; }
setSameNet(bool in)1804   void setSameNet(bool in) { sameNet = in; }
setSameMetal(bool in)1805   void setSameMetal(bool in) { sameMetal = in; }
setSameVia(bool in)1806   void setSameVia(bool in) { sameVia = in; }
setSecondLayerName(const std::string & in)1807   void setSecondLayerName(const std::string& in) { secondLayerName = in; }
setSecondLayerNum(frLayerNum in)1808   void setSecondLayerNum(frLayerNum in) { secondLayerNum = in; }
setStack(bool in)1809   void setStack(bool in) { stack = in; }
setOrthogonalSpacing(frCoord in)1810   void setOrthogonalSpacing(frCoord in) { orthogonalSpacing = in; }
setCutClassName(const std::string & in)1811   void setCutClassName(const std::string& in) { cutClassName = in; }
setCutClassIdx(int in)1812   void setCutClassIdx(int in) { cutClassIdx = in; }
setShortEdgeOnly(bool in)1813   void setShortEdgeOnly(bool in) { shortEdgeOnly = in; }
setPrl(frCoord in)1814   void setPrl(frCoord in) { prl = in; }
setConcaveCorner(bool in)1815   void setConcaveCorner(bool in) { concaveCorner = in; }
setWidth(frCoord in)1816   void setWidth(frCoord in) { width = in; }
setEnclosure(frCoord in)1817   void setEnclosure(frCoord in) { enclosure = in; }
setEdgeLength(frCoord in)1818   void setEdgeLength(frCoord in) { edgeLength = in; }
setParLength(frCoord in)1819   void setParLength(frCoord in) { parLength = in; }
setParWithin(frCoord in)1820   void setParWithin(frCoord in) { parWithin = in; }
setEdgeEnclosure(frCoord in)1821   void setEdgeEnclosure(frCoord in) { edgeEnclosure = in; }
setAdjEnclosure(frCoord in)1822   void setAdjEnclosure(frCoord in) { adjEnclosure = in; }
setExtension(frCoord in)1823   void setExtension(frCoord in) { extension = in; }
setEolWidth(frCoord in)1824   void setEolWidth(frCoord in) { eolWidth = in; }
setMinLength(frCoord in)1825   void setMinLength(frCoord in) { minLength = in; }
setMaskOverlap(bool in)1826   void setMaskOverlap(bool in) { maskOverlap = in; }
setWrongDirection(bool in)1827   void setWrongDirection(bool in) { wrongDirection = in; }
setAdjacentCuts(int in)1828   void setAdjacentCuts(int in) { adjacentCuts = in; }
setExactAlignedCut(int in)1829   void setExactAlignedCut(int in) { exactAlignedCut = in; }
setTwoCuts(int in)1830   void setTwoCuts(int in) { twoCuts = in; }
setTwoCutsSpacing(frCoord in)1831   void setTwoCutsSpacing(frCoord in) { twoCutsSpacing = in; }
setSameCut(bool in)1832   void setSameCut(bool in) { sameCut = in; }
setCutWithin(frCoord in)1833   void setCutWithin(frCoord in) { cutWithin2 = in; }
setCutWithin1(frCoord in)1834   void setCutWithin1(frCoord in) { cutWithin1 = in; }
setCutWithin2(frCoord in)1835   void setCutWithin2(frCoord in) { cutWithin2 = in; }
setExceptSamePGNet(bool in)1836   void setExceptSamePGNet(bool in) { exceptSamePGNet = in; }
setExceptAllWithin(frCoord in)1837   void setExceptAllWithin(frCoord in) { exceptAllWithin = in; }
setAbove(bool in)1838   void setAbove(bool in) { above = in; }
setBelow(bool in)1839   void setBelow(bool in) { below = in; }
setToAll(bool in)1840   void setToAll(bool in) { toAll = in; }
setNoPrl(bool in)1841   void setNoPrl(bool in) { noPrl = in; }
setSideParallelOverlap(bool in)1842   void setSideParallelOverlap(bool in) { sideParallelOverlap = in; }
setExceptSameNet(bool in)1843   void setExceptSameNet(bool in) { exceptSameNet = in; }
setExceptSameMetal(bool in)1844   void setExceptSameMetal(bool in) { exceptSameMetal = in; }
setExceptSameMetalOverlap(bool in)1845   void setExceptSameMetalOverlap(bool in) { exceptSameMetalOverlap = in; }
setExceptSameVia(bool in)1846   void setExceptSameVia(bool in) { exceptSameVia = in; }
setWithin(frCoord in)1847   void setWithin(frCoord in) { within = in; }
setLongEdgeOnly(bool in)1848   void setLongEdgeOnly(bool in) { longEdgeOnly = in; }
setExceptTwoEdges(bool in)1849   void setExceptTwoEdges(bool in) { exceptTwoEdges = in; }
setNumCut(int in)1850   void setNumCut(int in) { numCut = in; }
setCutArea(frCoord in)1851   void setCutArea(frCoord in) { cutArea = in; }
1852 
1853   // others
typeId()1854   frConstraintTypeEnum typeId() const override
1855   {
1856     return frConstraintTypeEnum::frcLef58CutSpacingConstraint;
1857   }
1858 
report(utl::Logger * logger)1859   void report(utl::Logger* logger) const override
1860   {
1861     logger->report(
1862         "CUTSPACING cutSpacing {} sameMask {} maxXY {} centerToCenter {} "
1863         "sameNet {} sameMetal {} sameVia {} secondLayerName {} secondLayerNum "
1864         "{} stack {} orthogonalSpacing {} cutClassName {} cutClassIdx {} "
1865         "shortEdgeOnly {} prl {} concaveCorner {} width {} enclosure {} "
1866         "edgeLength {} parLength {} parWithin {} edgeEnclosure {} adjEnclosure "
1867         "{} extension {} eolWidth {} minLength {} maskOverlap {} "
1868         "wrongDirection {} adjacentCuts {} exactAlignedCut {} twoCuts {} "
1869         "twoCutsSpacing {} sameCut {} cutWithin1 {} cutWithin2 {} "
1870         "exceptSamePGNet {} exceptAllWithin {} above {} below {} toAll {} "
1871         "noPrl {} sideParallelOverlap {} parallelOverlap {} exceptSameNet {} "
1872         "exceptSameMetal {} exceptSameMetalOverlap {} exceptSameVia {} within "
1873         "{} longEdgeOnly {} exceptTwoEdges {} numCut {} cutArea {} ",
1874         cutSpacing,
1875         sameMask,
1876         maxXY,
1877         centerToCenter,
1878         sameNet,
1879         sameMetal,
1880         sameVia,
1881         secondLayerName,
1882         secondLayerNum,
1883         stack,
1884         orthogonalSpacing,
1885         cutClassName,
1886         cutClassIdx,
1887         shortEdgeOnly,
1888         prl,
1889         concaveCorner,
1890         width,
1891         enclosure,
1892         edgeLength,
1893         parLength,
1894         parWithin,
1895         edgeEnclosure,
1896         adjEnclosure,
1897         extension,
1898         eolWidth,
1899         minLength,
1900         maskOverlap,
1901         wrongDirection,
1902         adjacentCuts,
1903         exactAlignedCut,
1904         twoCuts,
1905         twoCutsSpacing,
1906         sameCut,
1907         cutWithin1,
1908         cutWithin2,
1909         exceptSamePGNet,
1910         exceptAllWithin,
1911         above,
1912         below,
1913         toAll,
1914         noPrl,
1915         sideParallelOverlap,
1916         parallelOverlap,
1917         exceptSameNet,
1918         exceptSameMetal,
1919         exceptSameMetalOverlap,
1920         exceptSameVia,
1921         within,
1922         longEdgeOnly,
1923         exceptTwoEdges,
1924         numCut,
1925         cutArea);
1926   }
1927 
1928  protected:
1929   frCoord cutSpacing;
1930   bool sameMask;
1931   bool maxXY;
1932   bool centerToCenter;
1933   bool sameNet;
1934   bool sameMetal;
1935   bool sameVia;
1936   std::string secondLayerName;
1937   frLayerNum secondLayerNum;
1938   bool stack;
1939   frCoord orthogonalSpacing;
1940   std::string cutClassName;
1941   int cutClassIdx;
1942   bool shortEdgeOnly;
1943   frCoord prl;
1944   bool concaveCorner;
1945   frCoord width;
1946   frCoord enclosure;
1947   frCoord edgeLength;
1948   frCoord parLength;
1949   frCoord parWithin;
1950   frCoord edgeEnclosure;
1951   frCoord adjEnclosure;
1952   frCoord extension;
1953   frCoord eolWidth;
1954   frCoord minLength;
1955   bool maskOverlap;
1956   bool wrongDirection;
1957   int adjacentCuts;
1958   int exactAlignedCut;
1959   int twoCuts;
1960   frCoord twoCutsSpacing;
1961   bool sameCut;
1962   frCoord cutWithin1;
1963   frCoord cutWithin2;
1964   bool exceptSamePGNet;
1965   frCoord exceptAllWithin;
1966   bool above;
1967   bool below;
1968   bool toAll;
1969   bool noPrl;
1970   bool sideParallelOverlap;
1971   bool parallelOverlap;
1972   bool exceptSameNet;
1973   bool exceptSameMetal;
1974   bool exceptSameMetalOverlap;
1975   bool exceptSameVia;
1976   frCoord within;
1977   bool longEdgeOnly;
1978   bool exceptTwoEdges;
1979   int numCut;
1980   frCoord cutArea;
1981 };
1982 
1983 // LEF58_CORNERSPACING (new)
1984 class frLef58CornerSpacingConstraint : public frConstraint
1985 {
1986  public:
1987   // constructor
frLef58CornerSpacingConstraint(const fr1DLookupTbl<frCoord,std::pair<frCoord,frCoord>> & tblIn)1988   frLef58CornerSpacingConstraint(
1989       const fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>& tblIn)
1990       : cornerType(frCornerTypeEnum::UNKNOWN),
1991         sameMask(false),
1992         within(-1),
1993         eolWidth(-1),
1994         length(-1),
1995         edgeLength(false),
1996         includeLShape(false),
1997         minLength(-1),
1998         exceptNotch(false),
1999         notchLength(-1),
2000         exceptSameNet(false),
2001         exceptSameMetal(false),
2002         tbl(tblIn),
2003         sameXY(false)
2004   {
2005   }
2006 
2007   // getters
typeId()2008   frConstraintTypeEnum typeId() const override
2009   {
2010     return frConstraintTypeEnum::frcLef58CornerSpacingConstraint;
2011   }
getCornerType()2012   frCornerTypeEnum getCornerType() const { return cornerType; }
getSameMask()2013   bool getSameMask() const { return sameMask; }
hasCornerOnly()2014   bool hasCornerOnly() const { return (within != -1); }
getWithin()2015   frCoord getWithin() const { return within; }
hasExceptEol()2016   bool hasExceptEol() const { return (eolWidth != -1); }
getEolWidth()2017   frCoord getEolWidth() const { return eolWidth; }
hasExceptJogLength()2018   bool hasExceptJogLength() const { return (minLength != -1); }
getLength()2019   frCoord getLength() const { return length; }
hasEdgeLength()2020   bool hasEdgeLength() const { return edgeLength; }
getEdgeLength()2021   bool getEdgeLength() const { return edgeLength; }
hasIncludeLShape()2022   bool hasIncludeLShape() const { return includeLShape; }
getIncludeLShape()2023   bool getIncludeLShape() const { return includeLShape; }
getMinLength()2024   frCoord getMinLength() const { return minLength; }
hasExceptNotch()2025   bool hasExceptNotch() const { return exceptNotch; }
getExceptNotch()2026   bool getExceptNotch() const { return exceptNotch; }
getNotchLength()2027   frCoord getNotchLength() const { return notchLength; }
hasExceptSameNet()2028   bool hasExceptSameNet() const { return exceptSameNet; }
getExceptSameNet()2029   bool getExceptSameNet() const { return exceptSameNet; }
hasExceptSameMetal()2030   bool hasExceptSameMetal() const { return exceptSameMetal; }
getExceptSameMetal()2031   bool getExceptSameMetal() const { return exceptSameMetal; }
2032   frCoord find(frCoord width, bool isHorizontal = true) const
2033   {
2034     return (isHorizontal ? tbl.find(width).first : tbl.find(width).second);
2035   }
findMin()2036   frCoord findMin() const
2037   {
2038     return std::min(tbl.findMin().first, tbl.findMin().second);
2039   }
findMax()2040   frCoord findMax() const
2041   {
2042     return std::max(tbl.findMax().first, tbl.findMax().second);
2043   }
findMax(bool isHorz)2044   frCoord findMax(bool isHorz) const
2045   {
2046     return (isHorz ? tbl.findMax().first : tbl.findMax().second);
2047   }
hasSameXY()2048   bool hasSameXY() const { return sameXY; }
getSameXY()2049   bool getSameXY() const { return sameXY; }
2050 
2051   // setters
setCornerType(frCornerTypeEnum in)2052   void setCornerType(frCornerTypeEnum in) { cornerType = in; }
setSameMask(bool in)2053   void setSameMask(bool in) { sameMask = in; }
setWithin(frCoord in)2054   void setWithin(frCoord in) { within = in; }
setEolWidth(frCoord in)2055   void setEolWidth(frCoord in) { eolWidth = in; }
setLength(frCoord in)2056   void setLength(frCoord in) { length = in; }
setEdgeLength(bool in)2057   void setEdgeLength(bool in) { edgeLength = in; }
setIncludeLShape(bool in)2058   void setIncludeLShape(bool in) { includeLShape = in; }
setMinLength(frCoord in)2059   void setMinLength(frCoord in) { minLength = in; }
setExceptNotch(bool in)2060   void setExceptNotch(bool in) { exceptNotch = in; }
setExceptNotchLength(frCoord in)2061   void setExceptNotchLength(frCoord in) { notchLength = in; }
setExceptSameNet(bool in)2062   void setExceptSameNet(bool in) { exceptSameNet = in; }
setExceptSameMetal(bool in)2063   void setExceptSameMetal(bool in) { exceptSameMetal = in; }
setLookupTbl(const fr1DLookupTbl<frCoord,std::pair<frCoord,frCoord>> & in)2064   void setLookupTbl(
2065       const fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>& in)
2066   {
2067     tbl = in;
2068   }
setSameXY(bool in)2069   void setSameXY(bool in) { sameXY = in; }
report(utl::Logger * logger)2070   void report(utl::Logger* logger) const override
2071   {
2072     logger->report(
2073         "CORNERSPACING cornerType {} sameMask {} within {} eolWidth {} length "
2074         "{} edgeLength {} includeLShape {} minLength {} exceptNotch {} "
2075         "notchLength {} exceptSameNet {} exceptSameMetal {} sameXY {} ",
2076         cornerType,
2077         sameMask,
2078         within,
2079         eolWidth,
2080         length,
2081         edgeLength,
2082         includeLShape,
2083         minLength,
2084         exceptNotch,
2085         notchLength,
2086         exceptSameNet,
2087         exceptSameMetal,
2088         sameXY);
2089 
2090     std::string vals = "";
2091     std::string rows = "";
2092     for (auto row : tbl.getRows())
2093       rows = rows + std::to_string(row) + " ";
2094     for (auto val : tbl.getValues())
2095       vals = vals + "(" + std::to_string(val.first) + ","
2096              + std::to_string(val.second) + ") ";
2097     logger->report("\trowName: {}", tbl.getRowName());
2098     logger->report("\trows: {}", rows);
2099     logger->report("\tvals: {}", vals);
2100   }
2101 
2102  protected:
2103   frCornerTypeEnum cornerType;
2104   bool sameMask;
2105   frCoord within;
2106   frCoord eolWidth;
2107   frCoord length;
2108   bool edgeLength;
2109   bool includeLShape;
2110   frCoord minLength;
2111   bool exceptNotch;
2112   frCoord notchLength;
2113   bool exceptSameNet;
2114   bool exceptSameMetal;
2115   fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>>
2116       tbl;      // horz / vert spacing
2117   bool sameXY;  // indicate whether horz spacing == vert spacing // for write
2118                 // LEF some day
2119 };
2120 
2121 class frLef58CornerSpacingSpacingConstraint : public frConstraint
2122 {
2123  public:
2124   // constructor
frLef58CornerSpacingSpacingConstraint(frCoord widthIn)2125   frLef58CornerSpacingSpacingConstraint(frCoord widthIn) : width(widthIn) {}
2126   // getter
getWidth()2127   frCoord getWidth() { return width; }
2128   // setter
setWidth(frCoord widthIn)2129   void setWidth(frCoord widthIn) { width = widthIn; }
2130 
typeId()2131   frConstraintTypeEnum typeId() const override
2132   {
2133     return frConstraintTypeEnum::frcLef58CornerSpacingSpacingConstraint;
2134   }
report(utl::Logger * logger)2135   void report(utl::Logger* logger) const override
2136   {
2137     logger->report("58 Corner spacing spacing {}", width);
2138   }
2139 
2140  protected:
2141   frCoord width;
2142 };
2143 
2144 class frLef58CornerSpacingSpacing1DConstraint
2145     : public frLef58CornerSpacingSpacingConstraint
2146 {
2147  public:
2148   // constructor
frLef58CornerSpacingSpacing1DConstraint(frCoord widthIn,frCoord spacingIn)2149   frLef58CornerSpacingSpacing1DConstraint(frCoord widthIn, frCoord spacingIn)
2150       : frLef58CornerSpacingSpacingConstraint(widthIn), spacing(spacingIn)
2151   {
2152   }
2153   // getter
getSpacing()2154   frCoord getSpacing() { return spacing; }
2155   // setter
setSpacing(frCoord spacingIn)2156   void setSpacing(frCoord spacingIn) { spacing = spacingIn; }
2157 
typeId()2158   frConstraintTypeEnum typeId() const override
2159   {
2160     return frConstraintTypeEnum::frcLef58CornerSpacingSpacing1DConstraint;
2161   }
2162 
report(utl::Logger * logger)2163   void report(utl::Logger* logger) const override
2164   {
2165     logger->report("58 Corner spacing 1D {}", spacing);
2166   }
2167 
2168  protected:
2169   frCoord spacing = -1;
2170 };
2171 
2172 class frLef58CornerSpacingSpacing2DConstraint
2173     : public frLef58CornerSpacingSpacingConstraint
2174 {
2175  public:
2176   // constructor
frLef58CornerSpacingSpacing2DConstraint(frCoord widthIn,frCoord horizontalSpacingIn,frCoord verticalSpacingIn)2177   frLef58CornerSpacingSpacing2DConstraint(frCoord widthIn,
2178                                           frCoord horizontalSpacingIn,
2179                                           frCoord verticalSpacingIn)
2180       : frLef58CornerSpacingSpacingConstraint(widthIn),
2181         horizontalSpacing(horizontalSpacingIn),
2182         verticalSpacing(verticalSpacingIn)
2183   {
2184   }
2185   // getter
getHorizontalSpacing()2186   frCoord getHorizontalSpacing() { return horizontalSpacing; }
getVerticalSpacing()2187   frCoord getVerticalSpacing() { return verticalSpacing; }
2188   // setter
setHorizontalSpacing(frCoord horizontalSpacingIn)2189   void setHorizontalSpacing(frCoord horizontalSpacingIn)
2190   {
2191     horizontalSpacing = horizontalSpacingIn;
2192   }
setVerticalSpacing(frCoord verticalSpacingIn)2193   void setVerticalSpacing(frCoord verticalSpacingIn)
2194   {
2195     verticalSpacing = verticalSpacingIn;
2196   }
2197 
typeId()2198   frConstraintTypeEnum typeId() const override
2199   {
2200     return frConstraintTypeEnum::frcLef58CornerSpacingSpacing2DConstraint;
2201   }
report(utl::Logger * logger)2202   void report(utl::Logger* logger) const override
2203   {
2204     logger->report("58 Corner spacing spacing 2D h {} v {}",
2205                    horizontalSpacing,
2206                    verticalSpacing);
2207   }
2208 
2209  protected:
2210   frCoord horizontalSpacing = -1, verticalSpacing = -1;
2211 };
2212 
2213 class frLef58RectOnlyConstraint : public frConstraint
2214 {
2215  public:
2216   // constructor
2217   frLef58RectOnlyConstraint(bool exceptNonCorePinsIn = false)
exceptNonCorePins(exceptNonCorePinsIn)2218       : exceptNonCorePins(exceptNonCorePinsIn)
2219   {
2220   }
2221   // getter
isExceptNonCorePinsIn()2222   bool isExceptNonCorePinsIn() { return exceptNonCorePins; }
2223   // setter
setExceptNonCorePins(bool exceptNonCorePinsIn)2224   void setExceptNonCorePins(bool exceptNonCorePinsIn)
2225   {
2226     exceptNonCorePins = exceptNonCorePinsIn;
2227   }
2228 
typeId()2229   frConstraintTypeEnum typeId() const override
2230   {
2231     return frConstraintTypeEnum::frcLef58RectOnlyConstraint;
2232   }
report(utl::Logger * logger)2233   void report(utl::Logger* logger) const override
2234   {
2235     logger->report("RECTONLY exceptNonCorePins {}", exceptNonCorePins);
2236   }
2237 
2238  protected:
2239   bool exceptNonCorePins;
2240 };
2241 
2242 class frLef58RightWayOnGridOnlyConstraint : public frConstraint
2243 {
2244  public:
2245   // constructor
2246   frLef58RightWayOnGridOnlyConstraint(bool checkMaskIn = false)
checkMask(checkMaskIn)2247       : checkMask(checkMaskIn)
2248   {
2249   }
2250   // getter
isCheckMask()2251   bool isCheckMask() { return checkMask; }
2252   // setter
setCheckMask(bool checkMaskIn)2253   void setCheckMask(bool checkMaskIn) { checkMask = checkMaskIn; }
2254 
typeId()2255   frConstraintTypeEnum typeId() const override
2256   {
2257     return frConstraintTypeEnum::frcLef58RightWayOnGridOnlyConstraint;
2258   }
report(utl::Logger * logger)2259   void report(utl::Logger* logger) const override
2260   {
2261     logger->report("RIGHTWAYONGRIDONLY checkMask {}", checkMask);
2262   }
2263 
2264  protected:
2265   bool checkMask;
2266 };
2267 
2268 using namespace std;
2269 class frNonDefaultRule
2270 {
2271   friend class FlexRP;
2272   friend class frTechObject;
2273 
2274  private:
2275   string name_;
2276   // each vector position is a metal layer
2277   vector<frCoord> widths_;
2278   vector<frCoord> spacings_;
2279   vector<frCoord> wireExtensions_;
2280   vector<int> minCuts_;  // min cuts per cut layer
2281 
2282   // vias for each layer
2283   vector<vector<frViaDef*>> vias_;
2284   vector<vector<frViaRuleGenerate*>> viasRules_;
2285 
2286   bool hardSpacing_ = false;
2287 
2288   std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>>
2289       via2ViaForbiddenLen;
2290   std::vector<std::vector<std::vector<std::pair<frCoord, frCoord>>>>
2291       viaForbiddenTurnLen;
2292 
2293  public:
getPrefVia(int z)2294   frViaDef* getPrefVia(int z)
2295   {
2296     if (z >= (int) vias_.size() || vias_[z].empty()) {
2297       return nullptr;
2298     }
2299     return vias_[z][0];
2300   }
2301 
setWidth(frCoord w,int z)2302   void setWidth(frCoord w, int z)
2303   {
2304     if (z >= (int) widths_.size()) {
2305       widths_.resize(z + 1, 0);
2306     }
2307     widths_[z] = w;
2308   }
2309 
setSpacing(frCoord s,int z)2310   void setSpacing(frCoord s, int z)
2311   {
2312     if (z >= (int) spacings_.size()) {
2313       spacings_.resize(z + 1, 0);
2314     }
2315     spacings_[z] = s;
2316   }
2317 
setMinCuts(int ncuts,int z)2318   void setMinCuts(int ncuts, int z)
2319   {
2320     if (z >= (int) minCuts_.size()) {
2321       minCuts_.resize(z + 1, 1);
2322     }
2323     minCuts_[z] = ncuts;
2324   }
2325 
setWireExtension(frCoord we,int z)2326   void setWireExtension(frCoord we, int z)
2327   {
2328     if (z >= (int) wireExtensions_.size()) {
2329       wireExtensions_.resize(z + 1, 0);
2330     }
2331     wireExtensions_[z] = we;
2332   }
2333 
addVia(frViaDef * via,int z)2334   void addVia(frViaDef* via, int z)
2335   {
2336     if (z >= (int) vias_.size()) {
2337       vias_.resize(z + 1, vector<frViaDef*>());
2338     }
2339     vias_[z].push_back(via);
2340   }
2341 
addViaRule(frViaRuleGenerate * via,int z)2342   void addViaRule(frViaRuleGenerate* via, int z)
2343   {
2344     if (z >= (int) viasRules_.size()) {
2345       viasRules_.resize(z + 1, vector<frViaRuleGenerate*>());
2346     }
2347     viasRules_[z].push_back(via);
2348   }
2349 
setHardSpacing(bool isHard)2350   void setHardSpacing(bool isHard) { hardSpacing_ = isHard; }
2351 
setName(const char * n)2352   void setName(const char* n) { name_ = string(n); }
2353 
getName()2354   string getName() const { return name_; }
2355 
getWidth(int z)2356   frCoord getWidth(int z) const
2357   {
2358     if (z >= (int) widths_.size()) {
2359       return 0;
2360     }
2361     return widths_[z];
2362   }
2363 
getSpacing(int z)2364   frCoord getSpacing(int z) const
2365   {
2366     if (z >= (int) spacings_.size()) {
2367       return 0;
2368     }
2369     return spacings_[z];
2370   }
2371 
getWireExtension(int z)2372   frCoord getWireExtension(int z) const
2373   {
2374     if (z >= (int) wireExtensions_.size()) {
2375       return 0;
2376     }
2377     return wireExtensions_[z];
2378   }
2379 
getMinCuts(int z)2380   int getMinCuts(int z) const
2381   {
2382     if (z >= (int) minCuts_.size()) {
2383       return 1;
2384     }
2385     return minCuts_[z];
2386   }
2387 
getVias(int z)2388   const vector<frViaDef*>& getVias(int z) const { return vias_[z]; }
2389 
getViaRules(int z)2390   const vector<frViaRuleGenerate*>& getViaRules(int z) const
2391   {
2392     return viasRules_[z];
2393   }
2394 
isHardSpacing()2395   bool isHardSpacing() const { return hardSpacing_; }
2396 };
2397 }  // namespace fr
2398 
2399 #endif
2400