1 /* Author: Matt Liberty */
2 /*
3  * Copyright (c) 2020, 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 #include "fixture.h"
30 
31 #include <stdexcept>
32 
33 using namespace fr;
34 
Fixture()35 Fixture::Fixture()
36     : logger(std::make_unique<Logger>()),
37       design(std::make_unique<frDesign>(logger.get())),
38       numBlockages(0),
39       numTerms(0),
40       numRefBlocks(0),
41       numInsts(0)
42 {
43   makeDesign();
44 }
45 
addLayer(frTechObject * tech,const char * name,frLayerTypeEnum type,frPrefRoutingDirEnum dir)46 void Fixture::addLayer(frTechObject* tech,
47                        const char* name,
48                        frLayerTypeEnum type,
49                        frPrefRoutingDirEnum dir)
50 {
51   auto layer = std::make_unique<frLayer>();
52   layer->setLayerNum(tech->getTopLayerNum() + 1);
53   layer->setName(name);
54   layer->setType(type);
55   layer->setDir(dir);
56 
57   layer->setWidth(100);
58   layer->setMinWidth(100);
59   layer->setPitch(200);
60 
61   // These constraints are mandatory
62   if (type == frLayerTypeEnum::ROUTING) {
63     auto minWidthConstraint
64         = std::make_unique<frMinWidthConstraint>(layer->getMinWidth());
65     layer->setMinWidthConstraint(minWidthConstraint.get());
66     tech->addUConstraint(std::move(minWidthConstraint));
67 
68     auto offGridConstraint = std::make_unique<frOffGridConstraint>();
69     layer->setOffGridConstraint(offGridConstraint.get());
70     tech->addUConstraint(std::move(offGridConstraint));
71 
72     auto nsmetalConstraint = std::make_unique<frNonSufficientMetalConstraint>();
73     layer->setNonSufficientMetalConstraint(nsmetalConstraint.get());
74     tech->addUConstraint(std::move(nsmetalConstraint));
75   }
76 
77   auto shortConstraint = std::make_unique<frShortConstraint>();
78   layer->setShortConstraint(shortConstraint.get());
79   tech->addUConstraint(std::move(shortConstraint));
80 
81   tech->addLayer(std::move(layer));
82 }
83 
setupTech(frTechObject * tech)84 void Fixture::setupTech(frTechObject* tech)
85 {
86   tech->setManufacturingGrid(10);
87   tech->setDBUPerUU(1000);
88 
89   // TR assumes that masterslice always exists
90   addLayer(tech, "masterslice", frLayerTypeEnum::MASTERSLICE);
91   addLayer(tech, "v0", frLayerTypeEnum::CUT);
92   addLayer(tech, "m1", frLayerTypeEnum::ROUTING);
93 }
94 
makeMacro(const char * name,frCoord originX,frCoord originY,frCoord sizeX,frCoord sizeY)95 frBlock* Fixture::makeMacro(const char* name,
96                             frCoord originX,
97                             frCoord originY,
98                             frCoord sizeX,
99                             frCoord sizeY)
100 {
101   auto block = make_unique<frBlock>(name);
102   vector<frBoundary> bounds;
103   frBoundary bound;
104   vector<frPoint> points;
105   points.push_back(frPoint(originX, originY));
106   points.push_back(frPoint(sizeX, originY));
107   points.push_back(frPoint(sizeX, sizeY));
108   points.push_back(frPoint(originX, sizeY));
109   bound.setPoints(points);
110   bounds.push_back(bound);
111   block->setBoundaries(bounds);
112   block->setMacroClass(MacroClassEnum::CORE);
113   block->setId(++numRefBlocks);
114   auto blkPtr = block.get();
115   design->addRefBlock(std::move(block));
116   return blkPtr;
117 }
118 
makeMacroObs(frBlock * refBlock,frCoord xl,frCoord yl,frCoord xh,frCoord yh,frLayerNum lNum,frCoord designRuleWidth)119 frBlockage* Fixture::makeMacroObs(frBlock* refBlock,
120                                   frCoord xl,
121                                   frCoord yl,
122                                   frCoord xh,
123                                   frCoord yh,
124                                   frLayerNum lNum,
125                                   frCoord designRuleWidth)
126 {
127   int id = refBlock->getBlockages().size();
128   auto blkIn = make_unique<frBlockage>();
129   blkIn->setId(id);
130   blkIn->setDesignRuleWidth(designRuleWidth);
131   auto pinIn = make_unique<frPin>();
132   pinIn->setId(0);
133   // pinFig
134   unique_ptr<frRect> pinFig = make_unique<frRect>();
135   pinFig->setBBox(frBox(xl, yl, xh, yh));
136   pinFig->addToPin(pinIn.get());
137   pinFig->setLayerNum(lNum);
138   unique_ptr<frPinFig> uptr(std::move(pinFig));
139   pinIn->addPinFig(std::move(uptr));
140   blkIn->setPin(std::move(pinIn));
141   auto blk = blkIn.get();
142   refBlock->addBlockage(std::move(blkIn));
143   return blk;
144 }
145 
makeMacroPin(frBlock * refBlock,std::string name,frCoord xl,frCoord yl,frCoord xh,frCoord yh,frLayerNum lNum)146 frTerm* Fixture::makeMacroPin(frBlock* refBlock,
147                               std::string name,
148                               frCoord xl,
149                               frCoord yl,
150                               frCoord xh,
151                               frCoord yh,
152                               frLayerNum lNum)
153 {
154   int id = refBlock->getTerms().size();
155   unique_ptr<frTerm> uTerm = make_unique<frTerm>(name);
156   auto term = uTerm.get();
157   term->setId(id);
158   refBlock->addTerm(std::move(uTerm));
159   frTermEnum termType = frTermEnum::frcNormalTerm;
160   term->setType(termType);
161   frTermDirectionEnum termDirection = frTermDirectionEnum::INPUT;
162   term->setDirection(termDirection);
163   auto pinIn = make_unique<frPin>();
164   pinIn->setId(0);
165   unique_ptr<frRect> pinFig = make_unique<frRect>();
166   pinFig->setBBox(frBox(xl, yl, xh, yh));
167   pinFig->addToPin(pinIn.get());
168   pinFig->setLayerNum(lNum);
169   unique_ptr<frPinFig> uptr(std::move(pinFig));
170   pinIn->addPinFig(std::move(uptr));
171   term->addPin(std::move(pinIn));
172   return term;
173 }
174 
makeInst(const char * name,frBlock * refBlock,frCoord x,frCoord y)175 frInst* Fixture::makeInst(const char* name,
176                           frBlock* refBlock,
177                           frCoord x,
178                           frCoord y)
179 {
180   auto uInst = make_unique<frInst>(name, refBlock);
181   auto tmpInst = uInst.get();
182   tmpInst->setId(numInsts++);
183   tmpInst->setOrigin(frPoint(x, y));
184   tmpInst->setOrient(frOrientEnum::frcR0);
185   for (auto& uTerm : tmpInst->getRefBlock()->getTerms()) {
186     auto term = uTerm.get();
187     unique_ptr<frInstTerm> instTerm = make_unique<frInstTerm>(tmpInst, term);
188     instTerm->setId(numTerms++);
189     int pinCnt = term->getPins().size();
190     instTerm->setAPSize(pinCnt);
191     tmpInst->addInstTerm(std::move(instTerm));
192   }
193   for (auto& uBlk : tmpInst->getRefBlock()->getBlockages()) {
194     auto blk = uBlk.get();
195     unique_ptr<frInstBlockage> instBlk
196         = make_unique<frInstBlockage>(tmpInst, blk);
197     instBlk->setId(numBlockages);
198     numBlockages++;
199     tmpInst->addInstBlockage(std::move(instBlk));
200   }
201   design->getTopBlock()->addInst(std::move(uInst));
202   return tmpInst;
203 }
204 
makeDesign()205 void Fixture::makeDesign()
206 {
207   setupTech(design->getTech());
208 
209   auto block = std::make_unique<frBlock>("test");
210 
211   // GC assumes these fake nets exist
212   auto vssFakeNet = std::make_unique<frNet>("frFakeVSS");
213   vssFakeNet->setType(frNetEnum::frcGroundNet);
214   vssFakeNet->setIsFake(true);
215   block->addFakeSNet(std::move(vssFakeNet));
216 
217   auto vddFakeNet = std::make_unique<frNet>("frFakeVDD");
218   vddFakeNet->setType(frNetEnum::frcPowerNet);
219   vddFakeNet->setIsFake(true);
220   block->addFakeSNet(std::move(vddFakeNet));
221 
222   design->setTopBlock(std::move(block));
223   USEMINSPACING_OBS = false;
224 }
225 
makeCornerConstraint(frLayerNum layer_num,frCoord eolWidth,frCornerTypeEnum type)226 void Fixture::makeCornerConstraint(frLayerNum layer_num,
227                                    frCoord eolWidth,
228                                    frCornerTypeEnum type)
229 {
230   fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>> cornerSpacingTbl(
231       "WIDTH", {0}, {{200, 200}});
232   auto con = std::make_unique<frLef58CornerSpacingConstraint>(cornerSpacingTbl);
233 
234   con->setCornerType(type);
235   con->setSameXY(true);
236   if (eolWidth >= 0) {
237     con->setEolWidth(eolWidth);
238   }
239 
240   frTechObject* tech = design->getTech();
241   frLayer* layer = tech->getLayer(layer_num);
242   layer->addLef58CornerSpacingConstraint(con.get());
243   tech->addUConstraint(std::move(con));
244 }
245 
makeSpacingConstraint(frLayerNum layer_num)246 void Fixture::makeSpacingConstraint(frLayerNum layer_num)
247 {
248   fr2DLookupTbl<frCoord, frCoord, frCoord> tbl("WIDTH",
249                                                {0, 200},
250                                                "PARALLELRUNLENGTH",
251                                                {0, 400},
252                                                {{100, 200}, {300, 400}});
253   auto con = std::make_unique<frSpacingTablePrlConstraint>(tbl);
254 
255   frTechObject* tech = design->getTech();
256   frLayer* layer = tech->getLayer(layer_num);
257   layer->setMinSpacing(con.get());
258   tech->addUConstraint(std::move(con));
259 }
260 
makeMinStepConstraint(frLayerNum layer_num)261 void Fixture::makeMinStepConstraint(frLayerNum layer_num)
262 {
263   auto con = std::make_unique<frMinStepConstraint>();
264 
265   con->setMinstepType(frMinstepTypeEnum::STEP);
266   con->setMinStepLength(50);
267 
268   frTechObject* tech = design->getTech();
269   frLayer* layer = tech->getLayer(layer_num);
270   layer->setMinStepConstraint(con.get());
271   tech->addUConstraint(std::move(con));
272 }
273 
makeMinStep58Constraint(frLayerNum layer_num)274 void Fixture::makeMinStep58Constraint(frLayerNum layer_num)
275 {
276   auto con = std::make_unique<frLef58MinStepConstraint>();
277 
278   con->setMinStepLength(50);
279   con->setMaxEdges(1);
280   con->setEolWidth(200);
281 
282   frTechObject* tech = design->getTech();
283   frLayer* layer = tech->getLayer(layer_num);
284   layer->addLef58MinStepConstraint(con.get());
285   tech->addUConstraint(std::move(con));
286 }
287 
makeRectOnlyConstraint(frLayerNum layer_num)288 void Fixture::makeRectOnlyConstraint(frLayerNum layer_num)
289 {
290   auto con = std::make_unique<frLef58RectOnlyConstraint>();
291 
292   frTechObject* tech = design->getTech();
293   frLayer* layer = tech->getLayer(layer_num);
294   layer->setLef58RectOnlyConstraint(con.get());
295   tech->addUConstraint(std::move(con));
296 }
297 
makeMinEnclosedAreaConstraint(frLayerNum layer_num)298 void Fixture::makeMinEnclosedAreaConstraint(frLayerNum layer_num)
299 {
300   auto con = std::make_unique<frMinEnclosedAreaConstraint>(200 * 200);
301 
302   frTechObject* tech = design->getTech();
303   frLayer* layer = tech->getLayer(layer_num);
304   layer->addMinEnclosedAreaConstraint(con.get());
305   tech->addUConstraint(std::move(con));
306 }
307 
makeSpacingEndOfLineConstraint(frLayerNum layer_num,frCoord par_space,frCoord par_within,bool two_edges)308 void Fixture::makeSpacingEndOfLineConstraint(frLayerNum layer_num,
309                                              frCoord par_space,
310                                              frCoord par_within,
311                                              bool two_edges)
312 {
313   auto con = std::make_unique<frSpacingEndOfLineConstraint>();
314 
315   con->setMinSpacing(200);
316   con->setEolWidth(200);
317   con->setEolWithin(50);
318 
319   if (par_space != -1) {
320     if (par_within == -1) {
321       throw std::invalid_argument("Must give par_within with par_space");
322     }
323     con->setParSpace(par_space);
324     con->setParWithin(par_within);
325     con->setTwoEdges(two_edges);
326   }
327 
328   frTechObject* tech = design->getTech();
329   frLayer* layer = tech->getLayer(layer_num);
330   layer->addEolSpacing(con.get());
331   tech->addUConstraint(std::move(con));
332 }
333 
makeSpacingTableInfluenceConstraint(frLayerNum layer_num,std::vector<frCoord> widthTbl,std::vector<std::pair<frCoord,frCoord>> valTbl)334 frSpacingTableInfluenceConstraint* Fixture::makeSpacingTableInfluenceConstraint(
335     frLayerNum layer_num,
336     std::vector<frCoord> widthTbl,
337     std::vector<std::pair<frCoord, frCoord>> valTbl)
338 {
339   frTechObject* tech = design->getTech();
340   frLayer* layer = tech->getLayer(layer_num);
341   fr1DLookupTbl<frCoord, std::pair<frCoord, frCoord>> tbl(
342       "WIDTH", widthTbl, valTbl);
343   unique_ptr<frConstraint> uCon
344       = make_unique<frSpacingTableInfluenceConstraint>(tbl);
345   auto rptr = static_cast<frSpacingTableInfluenceConstraint*>(uCon.get());
346   tech->addUConstraint(std::move(uCon));
347   layer->setSpacingTableInfluence(rptr);
348   return rptr;
349 }
350 
makeEolExtensionConstraint(frLayerNum layer_num,frCoord spacing,std::vector<frCoord> eol,std::vector<frCoord> ext,bool parallelOnly)351 frLef58EolExtensionConstraint* Fixture::makeEolExtensionConstraint(
352     frLayerNum layer_num,
353     frCoord spacing,
354     std::vector<frCoord> eol,
355     std::vector<frCoord> ext,
356     bool parallelOnly)
357 {
358   frTechObject* tech = design->getTech();
359   frLayer* layer = tech->getLayer(layer_num);
360   fr1DLookupTbl<frCoord, frCoord> tbl("WIDTH", eol, ext, false);
361   unique_ptr<frLef58EolExtensionConstraint> uCon
362       = make_unique<frLef58EolExtensionConstraint>(tbl);
363   uCon->setMinSpacing(spacing);
364   uCon->setParallelOnly(parallelOnly);
365   auto rptr = uCon.get();
366   tech->addUConstraint(std::move(uCon));
367   layer->addLef58EolExtConstraint(rptr);
368   return rptr;
369 }
370 
makeSpacingTableTwConstraint(frLayerNum layer_num,std::vector<frCoord> widthTbl,std::vector<frCoord> prlTbl,std::vector<std::vector<frCoord>> spacingTbl)371 frSpacingTableTwConstraint* Fixture::makeSpacingTableTwConstraint(
372     frLayerNum layer_num,
373     std::vector<frCoord> widthTbl,
374     std::vector<frCoord> prlTbl,
375     std::vector<std::vector<frCoord>> spacingTbl)
376 {
377   frTechObject* tech = design->getTech();
378   frLayer* layer = tech->getLayer(layer_num);
379   frCollection<frSpacingTableTwRowType> rows;
380   for (size_t i = 0; i < widthTbl.size(); i++) {
381     rows.push_back(frSpacingTableTwRowType(widthTbl[i], prlTbl[i]));
382   }
383   unique_ptr<frConstraint> uCon
384       = make_unique<frSpacingTableTwConstraint>(rows, spacingTbl);
385   auto rptr = static_cast<frSpacingTableTwConstraint*>(uCon.get());
386   tech->addUConstraint(std::move(uCon));
387   layer->setMinSpacing(rptr);
388   return rptr;
389 }
390 
makeLef58EolKeepOutConstraint(frLayerNum layer_num,bool cornerOnly,bool exceptWithin,frCoord withinLow,frCoord withinHigh,frCoord forward,frCoord side,frCoord backward,frCoord width)391 void Fixture::makeLef58EolKeepOutConstraint(frLayerNum layer_num,
392                                             bool cornerOnly,
393                                             bool exceptWithin,
394                                             frCoord withinLow,
395                                             frCoord withinHigh,
396                                             frCoord forward,
397                                             frCoord side,
398                                             frCoord backward,
399                                             frCoord width)
400 {
401   frTechObject* tech = design->getTech();
402   frLayer* layer = tech->getLayer(layer_num);
403   auto con = std::make_unique<frLef58EolKeepOutConstraint>();
404   auto rptr = con.get();
405   rptr->setEolWidth(width);
406   rptr->setForwardExt(forward);
407   rptr->setBackwardExt(backward);
408   rptr->setSideExt(side);
409   rptr->setCornerOnly(cornerOnly);
410   rptr->setExceptWithin(exceptWithin);
411   rptr->setWithinLow(withinLow);
412   rptr->setWithinHigh(withinHigh);
413   layer->addLef58EolKeepOutConstraint(rptr);
414   tech->addUConstraint(std::move(con));
415 }
416 
417 std::shared_ptr<frLef58SpacingEndOfLineConstraint>
makeLef58SpacingEolConstraint(frLayerNum layer_num,frCoord space,frCoord width,frCoord within)418 Fixture::makeLef58SpacingEolConstraint(frLayerNum layer_num,
419                                        frCoord space,
420                                        frCoord width,
421                                        frCoord within)
422 {
423   auto con = std::make_shared<frLef58SpacingEndOfLineConstraint>();
424   con->setEol(space, width);
425   auto withinCon = std::make_shared<frLef58SpacingEndOfLineWithinConstraint>();
426   con->setWithinConstraint(withinCon);
427   withinCon->setEolWithin(within);
428   frTechObject* tech = design->getTech();
429   frLayer* layer = tech->getLayer(layer_num);
430   layer->addLef58SpacingEndOfLineConstraint(con);
431   tech->addConstraint(con);
432   return con;
433 }
434 
435 std::shared_ptr<frLef58SpacingEndOfLineWithinParallelEdgeConstraint>
makeLef58SpacingEolParEdgeConstraint(std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,fr::frCoord par_space,fr::frCoord par_within,bool two_edges)436 Fixture::makeLef58SpacingEolParEdgeConstraint(
437     std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,
438     fr::frCoord par_space,
439     fr::frCoord par_within,
440     bool two_edges)
441 {
442   auto parallelEdge
443       = std::make_shared<frLef58SpacingEndOfLineWithinParallelEdgeConstraint>();
444   con->getWithinConstraint()->setParallelEdgeConstraint(parallelEdge);
445   parallelEdge->setPar(par_space, par_within);
446   parallelEdge->setTwoEdges(two_edges);
447   return parallelEdge;
448 }
449 
450 std::shared_ptr<frLef58SpacingEndOfLineWithinMaxMinLengthConstraint>
makeLef58SpacingEolMinMaxLenConstraint(std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,fr::frCoord min_max_length,bool max,bool two_sides)451 Fixture::makeLef58SpacingEolMinMaxLenConstraint(
452     std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,
453     fr::frCoord min_max_length,
454     bool max,
455     bool two_sides)
456 {
457   auto minMax
458       = std::make_shared<frLef58SpacingEndOfLineWithinMaxMinLengthConstraint>();
459   con->getWithinConstraint()->setMaxMinLengthConstraint(minMax);
460   minMax->setLength(max, min_max_length, two_sides);
461   return minMax;
462 }
463 
464 std::shared_ptr<frLef58SpacingEndOfLineWithinEncloseCutConstraint>
makeLef58SpacingEolCutEncloseConstraint(std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,frCoord encloseDist,frCoord cutToMetalSpacing,bool above,bool below,bool allCuts)465 Fixture::makeLef58SpacingEolCutEncloseConstraint(
466     std::shared_ptr<frLef58SpacingEndOfLineConstraint> con,
467     frCoord encloseDist,
468     frCoord cutToMetalSpacing,
469     bool above,
470     bool below,
471     bool allCuts)
472 {
473   auto cutEnc
474       = std::make_shared<frLef58SpacingEndOfLineWithinEncloseCutConstraint>(
475           encloseDist, cutToMetalSpacing);
476   con->getWithinConstraint()->setEncloseCutConstraint(cutEnc);
477   cutEnc->setAbove(above);
478   cutEnc->setBelow(below);
479   cutEnc->setAllCuts(allCuts);
480   return cutEnc;
481 }
482 
makeNet(const char * name)483 frNet* Fixture::makeNet(const char* name)
484 {
485   frBlock* block = design->getTopBlock();
486   auto net_p = std::make_unique<frNet>(name);
487   frNet* net = net_p.get();
488   block->addNet(std::move(net_p));
489   return net;
490 }
491 
makeViaDef(const char * name,frLayerNum layer_num,const frPoint & ll,const frPoint & ur)492 frViaDef* Fixture::makeViaDef(const char* name,
493                               frLayerNum layer_num,
494                               const frPoint& ll,
495                               const frPoint& ur)
496 {
497   auto tech = design->getTech();
498   auto via_p = std::make_unique<frViaDef>(name);
499   for (frLayerNum l = layer_num - 1; l <= layer_num + 1; l++) {
500     unique_ptr<frRect> pinFig = make_unique<frRect>();
501     pinFig->setBBox(frBox(ll, ur));
502     pinFig->setLayerNum(l);
503     switch (l - layer_num) {
504       case -1:
505         via_p->addLayer1Fig(std::move(pinFig));
506         break;
507       case 0:
508         via_p->addCutFig(std::move(pinFig));
509         break;
510       case 1:
511         via_p->addLayer2Fig(std::move(pinFig));
512         break;
513     }
514   }
515 
516   frViaDef* via = via_p.get();
517   tech->addVia(std::move(via_p));
518   return via;
519 }
520 
makeVia(frViaDef * viaDef,frNet * net,const frPoint & origin)521 frVia* Fixture::makeVia(frViaDef* viaDef, frNet* net, const frPoint& origin)
522 {
523   auto via_p = make_unique<frVia>(viaDef);
524   via_p->setOrigin(origin);
525   via_p->addToNet(net);
526   frVia* via = via_p.get();
527   net->addVia(std::move(via_p));
528   return via;
529 }
530 
makePathseg(frNet * net,frLayerNum layer_num,const frPoint & begin,const frPoint & end,frUInt4 width,frEndStyleEnum begin_style,frEndStyleEnum end_style)531 void Fixture::makePathseg(frNet* net,
532                           frLayerNum layer_num,
533                           const frPoint& begin,
534                           const frPoint& end,
535                           frUInt4 width,
536                           frEndStyleEnum begin_style,
537                           frEndStyleEnum end_style)
538 {
539   auto ps = std::make_unique<frPathSeg>();
540   ps->setPoints(begin, end);
541   ps->setLayerNum(layer_num);
542 
543   if (begin_style == frcVariableEndStyle || end_style == frcVariableEndStyle) {
544     throw std::invalid_argument("frcVariableEndStyle not supported");
545   }
546 
547   frCoord begin_ext = begin_style == frcExtendEndStyle ? width / 2 : 0;
548   frCoord end_ext = begin_style == frcExtendEndStyle ? width / 2 : 0;
549 
550   frSegStyle style;
551   style.setWidth(width);
552   style.setBeginStyle(begin_style, begin_ext);
553   style.setEndStyle(end_style, end_ext);
554 
555   ps->setStyle(style);
556   net->addShape(std::move(ps));
557 }
558 
initRegionQuery()559 void Fixture::initRegionQuery()
560 {
561   frRegionQuery* query = design->getRegionQuery();
562   query->init();
563   query->initDRObj();
564 }
565