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