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 #include <omp.h>
30
31 #include "dr/FlexDR.h"
32 #include "frProfileTask.h"
33 #include "io/io.h"
34
35 using namespace std;
36 using namespace fr;
37
38 string netToDebug = "";
39 // copied from FlexDRWorker::initNets_searchRepair_pin2epMap_helper
checkConnectivity_pin2epMap_helper(const frNet * net,const frPoint & bp,frLayerNum lNum,map<frBlockObject *,set<pair<frPoint,frLayerNum>>,frBlockObjectComp> & pin2epMap,bool isPathSeg)40 void FlexDR::checkConnectivity_pin2epMap_helper(
41 const frNet* net,
42 const frPoint& bp,
43 frLayerNum lNum,
44 map<frBlockObject*, set<pair<frPoint, frLayerNum>>, frBlockObjectComp>&
45 pin2epMap,
46 bool isPathSeg)
47 {
48 bool enableOutput = false;
49 // bool enableOutput = true;
50 auto regionQuery = getRegionQuery();
51 frRegionQuery::Objects<frBlockObject> result;
52 // result.clear();
53 // In PA we may have used NearbyGrid which puts a via outside the pin
54 // but still overlapping. So we expand bp to a min-width square when
55 // searching for the pin shape.
56 auto half_min_width = getTech()->getLayer(lNum)->getMinWidth() / 2;
57 frBox query_box(bp.x() - half_min_width,
58 bp.y() - half_min_width,
59 bp.x() + half_min_width,
60 bp.y() + half_min_width);
61 regionQuery->query(query_box, lNum, result);
62 for (auto& [bx, rqObj] : result) {
63 if (isPathSeg && !bx.contains(bp))
64 continue;
65 if (rqObj->typeId() == frcInstTerm) {
66 auto instTerm = static_cast<frInstTerm*>(rqObj);
67 if (instTerm->getNet() == net) {
68 if (!isPathSeg && !bx.contains(bp) &&
69 !instTerm->hasAccessPoint(bp.x(), bp.y(), lNum))
70 continue;
71 if (enableOutput) {
72 cout << " found " << instTerm->getName() << "\n";
73 }
74 pin2epMap[rqObj].insert(make_pair(bp, lNum));
75 }
76 } else if (rqObj->typeId() == frcTerm) {
77 if (!isPathSeg && !bx.contains(bp))
78 continue;
79 auto term = static_cast<frTerm*>(rqObj);
80 if (term->getNet() == net) {
81 if (enableOutput) {
82 cout << " found PIN/" << term->getName() << endl;
83 }
84 pin2epMap[rqObj].insert(make_pair(bp, lNum));
85 }
86 }
87 }
88 }
89
checkConnectivity_pin2epMap(const frNet * net,const vector<frConnFig * > & netDRObjs,map<frBlockObject *,set<pair<frPoint,frLayerNum>>,frBlockObjectComp> & pin2epMap)90 void FlexDR::checkConnectivity_pin2epMap(
91 const frNet* net,
92 const vector<frConnFig*>& netDRObjs,
93 map<frBlockObject*, set<pair<frPoint, frLayerNum>>, frBlockObjectComp>&
94 pin2epMap)
95 {
96 bool enableOutput = net->getName() == netToDebug;
97 // bool enableOutput = true;
98 if (enableOutput)
99 cout << "pin2epMap\n\n";
100 frPoint bp, ep;
101 set<pair<frPoint, frLayerNum>>
102 extEndPoints; // to avoid delooping fake planar ep in pin
103 for (auto& connFig : netDRObjs) {
104 if (connFig->typeId() == frcPathSeg) {
105 auto obj = static_cast<frPathSeg*>(connFig);
106 obj->getPoints(bp, ep);
107 frSegStyle style;
108 obj->getStyle(style);
109 auto lNum = obj->getLayerNum();
110 if (enableOutput) {
111 cout << *obj << " layer " << getTech()->getLayer(lNum)->getName()
112 << endl;
113 cout << " query bp" << endl;
114 }
115 if (style.getBeginStyle() == frEndStyle(frcTruncateEndStyle)) {
116 checkConnectivity_pin2epMap_helper(net, bp, lNum, pin2epMap, true);
117 }
118 if (enableOutput) {
119 cout << " query ep" << endl;
120 }
121 if (style.getEndStyle() == frEndStyle(frcTruncateEndStyle)) {
122 checkConnectivity_pin2epMap_helper(net, ep, lNum, pin2epMap, true);
123 }
124 }
125 }
126 for (auto& connFig : netDRObjs) {
127 if (connFig->typeId() == frcVia) {
128 auto obj = static_cast<frVia*>(connFig);
129 obj->getOrigin(bp);
130 auto l1Num = obj->getViaDef()->getLayer1Num();
131 auto l2Num = obj->getViaDef()->getLayer2Num();
132 if (enableOutput) {
133 cout << *obj;
134 }
135 if (enableOutput) {
136 cout << " query pt l1" << endl;
137 }
138 if (obj->isBottomConnected())
139 checkConnectivity_pin2epMap_helper(net, bp, l1Num, pin2epMap, false);
140 if (enableOutput) {
141 cout << " query pt l2" << endl;
142 }
143 if (obj->isTopConnected())
144 checkConnectivity_pin2epMap_helper(net, bp, l2Num, pin2epMap, false);
145 //} else if (connFig->typeId() == frcPatchWire) {
146 // ;
147 }
148 }
149 }
150
checkConnectivity_initDRObjs(const frNet * net,vector<frConnFig * > & netDRObjs)151 void FlexDR::checkConnectivity_initDRObjs(const frNet* net,
152 vector<frConnFig*>& netDRObjs)
153 {
154 bool enableOutput = false;
155 // bool enableOutput = true;
156 if (enableOutput)
157 cout << "initDRObjs\n\n";
158 for (auto& uPtr : net->getShapes()) {
159 auto connFig = uPtr.get();
160 if (connFig->typeId() == frcPathSeg) {
161 netDRObjs.push_back(connFig);
162 if (enableOutput) {
163 auto obj = static_cast<frPathSeg*>(connFig);
164 frPoint bp, ep;
165 auto lNum = obj->getLayerNum();
166 obj->getPoints(bp, ep);
167 cout << *obj << " layer " << getTech()->getLayer(lNum)->getName()
168 << endl;
169 }
170 } else {
171 cout << "Error: checkConnectivity_initDRObjs unsupported type" << endl;
172 }
173 }
174 for (auto& uPtr : net->getVias()) {
175 auto connFig = uPtr.get();
176 if (connFig->typeId() == frcVia) {
177 netDRObjs.push_back(connFig);
178 if (enableOutput) {
179 auto obj = static_cast<frVia*>(connFig);
180 frPoint bp;
181 obj->getOrigin(bp);
182 cout << *obj << " layer " << obj->getViaDef()->getName() << endl;
183 }
184 } else {
185 cout << "Error: checkConnectivity_initDRObjs unsupported type" << endl;
186 }
187 }
188 }
189
checkConnectivity_nodeMap_routeObjEnd(const frNet * net,const vector<frConnFig * > & netRouteObjs,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)190 void FlexDR::checkConnectivity_nodeMap_routeObjEnd(
191 const frNet* net,
192 const vector<frConnFig*>& netRouteObjs,
193 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
194 {
195 bool enableOutput = false;
196 frPoint bp, ep;
197 for (int i = 0; i < (int) netRouteObjs.size(); i++) {
198 auto& connFig = netRouteObjs[i];
199 if (connFig->typeId() == frcPathSeg) {
200 auto obj = static_cast<frPathSeg*>(connFig);
201 obj->getPoints(bp, ep);
202 auto lNum = obj->getLayerNum();
203 nodeMap[make_pair(bp, lNum)].insert(i);
204 nodeMap[make_pair(ep, lNum)].insert(i);
205 if (enableOutput) {
206 cout << "node idx = " << i << ", (" << bp.x() / 2000.0 << ", "
207 << bp.y() / 2000.0 << ") (" << ep.x() / 2000.0 << ", "
208 << ep.y() / 2000.0 << ") " << getTech()->getLayer(lNum)->getName()
209 << endl;
210 }
211 } else if (connFig->typeId() == frcVia) {
212 auto obj = static_cast<frVia*>(connFig);
213 obj->getOrigin(bp);
214 auto l1Num = obj->getViaDef()->getLayer1Num();
215 auto l2Num = obj->getViaDef()->getLayer2Num();
216 nodeMap[make_pair(bp, l1Num)].insert(i);
217 nodeMap[make_pair(bp, l2Num)].insert(i);
218 if (enableOutput) {
219 cout << "node idx = " << i << ", (" << bp.x() / 2000.0 << ", "
220 << bp.y() / 2000.0 << ") " << getTech()->getLayer(l1Num)->getName()
221 << " --> " << getTech()->getLayer(l2Num)->getName() << endl;
222 }
223 } else {
224 cout << "Error: checkConnectivity_nodeMap_routeObjEnd unsupported type"
225 << endl;
226 }
227 }
228 }
229
checkConnectivity_nodeMap_routeObjSplit_helper(const frPoint & crossPt,frCoord trackCoord,frCoord splitCoord,frLayerNum lNum,const vector<map<frCoord,map<frCoord,pair<frCoord,int>>>> & mergeHelper,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)230 void FlexDR::checkConnectivity_nodeMap_routeObjSplit_helper(
231 const frPoint& crossPt,
232 frCoord trackCoord,
233 frCoord splitCoord,
234 frLayerNum lNum,
235 const vector<map<frCoord, map<frCoord, pair<frCoord, int>>>>& mergeHelper,
236 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
237 {
238 auto it1 = mergeHelper[lNum].find(trackCoord);
239 if (it1 != mergeHelper[lNum].end()) {
240 auto& mp = it1->second; // map<ep, pair<bp, objIdx>>
241 auto it2 = mp.lower_bound(splitCoord);
242 if (it2 != mp.end()) {
243 auto& endP = it2->first;
244 auto& [beginP, objIdx] = it2->second;
245 if (endP > splitCoord && beginP < splitCoord) {
246 nodeMap[make_pair(crossPt, lNum)].insert(objIdx);
247 }
248 }
249 }
250 }
251
checkConnectivity_nodeMap_routeObjSplit(const frNet * net,const vector<frConnFig * > & netRouteObjs,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)252 void FlexDR::checkConnectivity_nodeMap_routeObjSplit(
253 const frNet* net,
254 const vector<frConnFig*>& netRouteObjs,
255 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
256 {
257 frPoint bp, ep;
258 // vector<map<track, map<ep, pair<bp, objIdx>>>> interval_map
259 vector<map<frCoord, map<frCoord, pair<frCoord, int>>>> horzMergeHelper(
260 getTech()->getLayers().size());
261 vector<map<frCoord, map<frCoord, pair<frCoord, int>>>> vertMergeHelper(
262 getTech()->getLayers().size());
263 for (int i = 0; i < (int) netRouteObjs.size(); i++) {
264 auto& connFig = netRouteObjs[i];
265 if (connFig->typeId() == frcPathSeg) {
266 auto obj = static_cast<frPathSeg*>(connFig);
267 obj->getPoints(bp, ep);
268 auto lNum = obj->getLayerNum();
269 // vert seg
270 if (bp.x() == ep.x()) {
271 vertMergeHelper[lNum][bp.x()][ep.y()] = make_pair(bp.y(), i);
272 // horz seg
273 } else {
274 horzMergeHelper[lNum][bp.y()][ep.x()] = make_pair(bp.x(), i);
275 }
276 }
277 }
278 for (int i = 0; i < (int) netRouteObjs.size(); i++) {
279 auto& connFig = netRouteObjs[i];
280 // ep on pathseg
281 if (connFig->typeId() == frcPathSeg) {
282 auto obj = static_cast<frPathSeg*>(connFig);
283 obj->getPoints(bp, ep);
284 auto lNum = obj->getLayerNum();
285 // vert seg, find horz crossing seg
286 if (bp.x() == ep.x()) {
287 // find whether there is horz track at bp
288 auto crossPt = bp;
289 auto trackCoord = bp.y();
290 auto splitCoord = bp.x();
291 checkConnectivity_nodeMap_routeObjSplit_helper(
292 crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
293 // find whether there is horz track at ep
294 crossPt = ep;
295 trackCoord = ep.y();
296 splitCoord = ep.x();
297 checkConnectivity_nodeMap_routeObjSplit_helper(
298 crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
299 // horz seg
300 } else {
301 // find whether there is vert track at bp
302 auto crossPt = bp;
303 auto trackCoord = bp.x();
304 auto splitCoord = bp.y();
305 checkConnectivity_nodeMap_routeObjSplit_helper(
306 crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
307 // find whether there is vert track at ep
308 crossPt = ep;
309 trackCoord = ep.x();
310 splitCoord = ep.y();
311 checkConnectivity_nodeMap_routeObjSplit_helper(
312 crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
313 }
314 } else if (connFig->typeId() == frcVia) {
315 auto obj = static_cast<frVia*>(connFig);
316 obj->getOrigin(bp);
317 auto lNum = obj->getViaDef()->getLayer1Num();
318 // find whether there is horz track at bp on layer1
319 auto crossPt = bp;
320 auto trackCoord = bp.y();
321 auto splitCoord = bp.x();
322 checkConnectivity_nodeMap_routeObjSplit_helper(
323 crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
324 // find whether there is vert track at bp on layer1
325 crossPt = bp;
326 trackCoord = bp.x();
327 splitCoord = bp.y();
328 checkConnectivity_nodeMap_routeObjSplit_helper(
329 crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
330
331 lNum = obj->getViaDef()->getLayer2Num();
332 // find whether there is horz track at bp on layer2
333 crossPt = bp;
334 trackCoord = bp.y();
335 splitCoord = bp.x();
336 checkConnectivity_nodeMap_routeObjSplit_helper(
337 crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
338 // find whether there is vert track at bp on layer2
339 crossPt = bp;
340 trackCoord = bp.x();
341 splitCoord = bp.y();
342 checkConnectivity_nodeMap_routeObjSplit_helper(
343 crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
344 }
345 }
346 }
347
checkConnectivity_nodeMap_pin(const vector<frConnFig * > & netRouteObjs,vector<frBlockObject * > & netPins,const map<frBlockObject *,set<pair<frPoint,frLayerNum>>,frBlockObjectComp> & pin2epMap,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)348 void FlexDR::checkConnectivity_nodeMap_pin(
349 const vector<frConnFig*>& netRouteObjs,
350 vector<frBlockObject*>& netPins,
351 const map<frBlockObject*,
352 set<pair<frPoint, frLayerNum>>,
353 frBlockObjectComp>& pin2epMap,
354 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
355 {
356 bool enableOutput = false;
357 int currCnt = (int) netRouteObjs.size();
358 for (auto& [obj, locS] : pin2epMap) {
359 netPins.push_back(obj);
360 for (auto& pr : locS) {
361 nodeMap[pr].insert(currCnt);
362 if (enableOutput) {
363 cout << "pin idx = " << currCnt << ", (" << pr.first.x() << ", "
364 << pr.first.y() << ") "
365 << getTech()->getLayer(pr.second)->getName() << endl;
366 }
367 }
368 ++currCnt;
369 }
370 }
371
checkConnectivity_nodeMap(const frNet * net,const vector<frConnFig * > & netRouteObjs,vector<frBlockObject * > & netPins,const map<frBlockObject *,set<pair<frPoint,frLayerNum>>,frBlockObjectComp> & pin2epMap,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)372 void FlexDR::checkConnectivity_nodeMap(
373 const frNet* net,
374 const vector<frConnFig*>& netRouteObjs,
375 vector<frBlockObject*>& netPins,
376 const map<frBlockObject*,
377 set<pair<frPoint, frLayerNum>>,
378 frBlockObjectComp>& pin2epMap,
379 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
380 {
381 bool enableOutput = false;
382 // bool enableOutput = true;
383 checkConnectivity_nodeMap_routeObjEnd(net, netRouteObjs, nodeMap);
384 checkConnectivity_nodeMap_routeObjSplit(net, netRouteObjs, nodeMap);
385 checkConnectivity_nodeMap_pin(netRouteObjs, netPins, pin2epMap, nodeMap);
386 if (enableOutput) {
387 int idx = 0;
388 for (auto connFig : netRouteObjs) {
389 if (connFig->typeId() == frcPathSeg) {
390 auto obj = static_cast<frPathSeg*>(connFig);
391 frPoint bp, ep;
392 auto lNum = obj->getLayerNum();
393 obj->getPoints(bp, ep);
394 cout << "#" << idx << *obj << getTech()->getLayer(lNum)->getName()
395 << endl;
396 } else if (connFig->typeId() == frcVia) {
397 auto obj = static_cast<frVia*>(connFig);
398 frPoint bp;
399 obj->getOrigin(bp);
400 cout << "#" << idx << *obj << obj->getViaDef()->getName() << endl;
401 } else {
402 cout << "Error: checkConnectivity_nodeMap unsupported type" << endl;
403 }
404 idx++;
405 }
406 for (auto obj : netPins) {
407 if (obj->typeId() == frcInstTerm) {
408 auto instTerm = static_cast<frInstTerm*>(obj);
409 cout << "#" << idx << " " << instTerm->getName() << "\n";
410 } else if (obj->typeId() == frcTerm) {
411 auto term = static_cast<frTerm*>(obj);
412 cout << "#" << idx << " PIN/" << term->getName() << endl;
413 }
414 idx++;
415 }
416 }
417 }
418
checkConnectivity_astar(frNet * net,vector<bool> & adjVisited,vector<int> & adjPrevIdx,const map<pair<frPoint,frLayerNum>,set<int>> & nodeMap,const vector<frConnFig * > & netDRObjs,const int & nNetRouteObjs,const int & nNetObjs)419 bool FlexDR::checkConnectivity_astar(
420 frNet* net,
421 vector<bool>& adjVisited,
422 vector<int>& adjPrevIdx,
423 const map<pair<frPoint, frLayerNum>, set<int>>& nodeMap,
424 const vector<frConnFig*>& netDRObjs,
425 const int& nNetRouteObjs,
426 const int& nNetObjs)
427 {
428 // bool enableOutput = true;
429 bool enableOutput = net->getName() == netToDebug;
430 // a star search
431 if (enableOutput)
432 cout << "checkConnectivity_astar\n\n";
433 // node index, node visited
434 vector<vector<int>> adjVec(nNetObjs, vector<int>());
435 vector<bool> onPathIdx(nNetObjs, false);
436 adjVisited.clear();
437 adjPrevIdx.clear();
438 adjVisited.resize(nNetObjs, false);
439 adjPrevIdx.resize(nNetObjs, -1);
440 for (auto& [pr, idxS] : nodeMap) {
441 // auto &[pt, lNum] = pr;
442 for (auto it1 = idxS.begin(); it1 != idxS.end(); it1++) {
443 auto it2 = it1;
444 it2++;
445 auto idx1 = *it1;
446 for (; it2 != idxS.end(); it2++) {
447 auto idx2 = *it2;
448 adjVec[idx1].push_back(idx2);
449 adjVec[idx2].push_back(idx1);
450 if (enableOutput)
451 cout << "add edge #" << idx1 << " -- #" << idx2 << endl;
452 // one pin, one gcell
453 }
454 }
455 }
456
457 struct wf
458 {
459 int nodeIdx;
460 int prevIdx;
461 int cost;
462 bool operator<(const wf& b) const
463 {
464 if (cost == b.cost) {
465 return nodeIdx > b.nodeIdx;
466 } else {
467 return cost > b.cost;
468 }
469 }
470 };
471 for (int findNode = nNetRouteObjs; findNode < nNetObjs - 1; findNode++) {
472 // adjVisited = onPathIdx;
473 // cout <<"finished " <<findNode <<" nodes" <<endl;
474 priority_queue<wf> pq;
475 if (enableOutput) {
476 // cout <<"visit";
477 }
478 if (findNode == nNetRouteObjs) {
479 // push only first pin into pq
480 pq.push({nNetRouteObjs, -1, 0});
481 } else {
482 // push every visited node into pq
483 for (int i = 0; i < nNetObjs; i++) {
484 // if (adjVisited[i]) {
485 if (onPathIdx[i]) {
486 // penalize feedthrough in normal mode
487 if (i >= nNetRouteObjs) {
488 pq.push({i, adjPrevIdx[i], 5});
489 } else {
490 pq.push({i, adjPrevIdx[i], 0});
491 }
492 }
493 }
494 }
495 int lastNodeIdx = -1;
496 while (!pq.empty()) {
497 auto wfront = pq.top();
498 pq.pop();
499 if (!onPathIdx[wfront.nodeIdx] && adjVisited[wfront.nodeIdx]) {
500 continue;
501 }
502 if (wfront.nodeIdx > nNetRouteObjs && wfront.nodeIdx < nNetObjs
503 && adjVisited[wfront.nodeIdx] == false) {
504 adjVisited[wfront.nodeIdx] = true;
505 adjPrevIdx[wfront.nodeIdx] = wfront.prevIdx;
506 if (enableOutput) {
507 cout << "visit pin " << wfront.nodeIdx << " (" << wfront.cost << ","
508 << wfront.prevIdx << ")"
509 << " exit" << endl;
510 }
511 lastNodeIdx = wfront.nodeIdx;
512 break;
513 }
514 adjVisited[wfront.nodeIdx] = true;
515 adjPrevIdx[wfront.nodeIdx] = wfront.prevIdx;
516 if (enableOutput) {
517 cout << "visit ";
518 if (wfront.nodeIdx < (int)netDRObjs.size())
519 cout << *netDRObjs[wfront.nodeIdx];
520 cout << "idx " << wfront.nodeIdx << " (" << wfront.cost << ","
521 << wfront.prevIdx << ")" << endl;
522 }
523 // visit other nodes
524 for (auto nbrIdx : adjVec[wfront.nodeIdx]) {
525 if (!adjVisited[nbrIdx]) {
526 pq.push({nbrIdx, wfront.nodeIdx, wfront.cost + 1});
527 if (enableOutput) {
528 cout << "push " << nbrIdx << endl;
529 }
530 }
531 }
532 }
533 // trace back path
534 if (enableOutput) {
535 cout << "trace back id";
536 }
537 while ((lastNodeIdx != -1) && (!onPathIdx[lastNodeIdx])) {
538 onPathIdx[lastNodeIdx] = true;
539 if (enableOutput) {
540 cout << " " << lastNodeIdx << " (" << adjPrevIdx[lastNodeIdx] << ")";
541 }
542 lastNodeIdx = adjPrevIdx[lastNodeIdx];
543 }
544 if (enableOutput) {
545 cout << endl;
546 }
547 adjVisited = onPathIdx;
548 }
549 if (enableOutput) {
550 cout << "stat: " << net->getName()
551 << " #guide/#pin/#unused = " << nNetRouteObjs << "/"
552 << nNetObjs - nNetRouteObjs << "/"
553 << nNetObjs - count(adjVisited.begin(), adjVisited.end(), true)
554 << endl;
555 }
556 int pinVisited
557 = count(adjVisited.begin() + nNetRouteObjs, adjVisited.end(), true);
558 // true error when allowing feedthrough
559 if (pinVisited != nNetObjs - nNetRouteObjs) {
560 cout << "Error: " << net->getName() << " "
561 << nNetObjs - nNetRouteObjs - pinVisited
562 << " pin not visited #guides = " << nNetRouteObjs << endl;
563 if (enableOutput) {
564 for (int i = nNetRouteObjs; i < nNetObjs; i++) {
565 if (!adjVisited[i]) {
566 cout << " pin id = " << i << endl;
567 }
568 }
569 }
570 }
571 if (pinVisited == nNetObjs - nNetRouteObjs) {
572 return true;
573 } else {
574 return false;
575 }
576 }
577
checkConnectivity_final(frNet * net,vector<frConnFig * > & netRouteObjs,vector<frBlockObject * > & netPins,const vector<bool> & adjVisited,int gCnt,int nCnt,map<pair<frPoint,frLayerNum>,set<int>> & nodeMap)578 void FlexDR::checkConnectivity_final(
579 frNet* net,
580 vector<frConnFig*>& netRouteObjs,
581 vector<frBlockObject*>& netPins,
582 const vector<bool>& adjVisited,
583 int gCnt,
584 int nCnt,
585 map<pair<frPoint, frLayerNum>, set<int>>& nodeMap)
586 {
587 // bool enableOutput = true;
588 bool enableOutput = net->getName() == netToDebug;
589
590 auto regionQuery = getRegionQuery();
591
592 // from obj to pt
593 map<int, set<pair<frPoint, frLayerNum>>> reverseNodeMap;
594 for (auto& [pr, idxS] : nodeMap) {
595 for (auto& idx : idxS) {
596 reverseNodeMap[idx].insert(pr);
597 }
598 }
599
600 // nodeMap delete redundant objs
601 for (int i = 0; i < (int) adjVisited.size(); i++) {
602 if (adjVisited[i]) {
603 continue;
604 }
605 for (auto& pr : reverseNodeMap[i]) {
606 nodeMap[pr].erase(i);
607 }
608 if (i < gCnt) {
609 if (netRouteObjs[i]->typeId() == frcPathSeg) {
610 auto victimPathSeg = static_cast<frPathSeg*>(netRouteObjs[i]);
611 // negative rule
612 frBox bbox;
613 victimPathSeg->getBBox(bbox);
614 checkConnectivity_addMarker(net, victimPathSeg->getLayerNum(), bbox);
615
616 if (enableOutput) {
617 cout << "net " << net->getName() << " deleting pathseg " <<
618 *static_cast<frPathSeg*>(netRouteObjs[i]) << endl;
619 }
620 regionQuery->removeDRObj(static_cast<frShape*>(netRouteObjs[i]));
621 net->removeShape(static_cast<frShape*>(netRouteObjs[i]));
622 } else if (netRouteObjs[i]->typeId() == frcVia) {
623 auto victimVia = static_cast<frVia*>(netRouteObjs[i]);
624 // negative rule
625 frBox bbox;
626 victimVia->getLayer1BBox(bbox);
627 checkConnectivity_addMarker(
628 net, victimVia->getViaDef()->getLayer1Num(), bbox);
629
630 frVia* via = static_cast<frVia*>(netRouteObjs[i]);
631 if (enableOutput) {
632 cout << "net " << net->getName() << " deleting via " << *via << endl;
633 }
634 regionQuery->removeDRObj(via);
635 net->removeVia(via);
636 //} else if (netRouteObjs[i]->typeId() == frcPatchWire) {
637 // regionQuery->removeDRObj(static_cast<frPatchWire*>(netRouteObjs[i]));
638 // net->removePatchWire(static_cast<frPatchWire*>(netRouteObjs[i]));
639 // if (enableOutput) {
640 // cout <<"net " <<net->getName() <<" deleting pwire" <<endl;
641 // }
642 } else {
643 cout << "Error: checkConnectivity_final unsupporterd type" << endl;
644 exit(1);
645 }
646 netRouteObjs[i] = nullptr;
647 } else {
648 cout << "Error: checkConnectivity_final i >= gCnt" << endl;
649 exit(1);
650 }
651 }
652
653 // rebuild reverseNodeMap
654 reverseNodeMap.clear();
655 for (auto& [pr, idxS] : nodeMap) {
656 if (idxS.size() == 1) {
657 continue;
658 }
659 for (auto& idx : idxS) {
660 reverseNodeMap[idx].insert(pr);
661 }
662 }
663
664 // must use map because split has to start from right
665 map<pair<frPoint, frLayerNum>, int> psSplits;
666 for (auto& [pr, idxS] : nodeMap) {
667 bool hasPin = false;
668 for (auto idx : idxS) {
669 // skip for non-pin idx
670 if (idx >= gCnt) {
671 hasPin = true;
672 break;
673 }
674 }
675
676 if (!hasPin) {
677 continue;
678 }
679
680 bool hasPinEP = false;
681 int psIdx = -1;
682 for (auto idx : idxS) {
683 if (idx >= gCnt) {
684 continue;
685 }
686 if (netRouteObjs[idx]->typeId() == frcPathSeg) {
687 auto ps = static_cast<frPathSeg*>(netRouteObjs[idx]);
688 frPoint bp, ep;
689 ps->getPoints(bp, ep);
690 if (bp == pr.first || ep == pr.first) {
691 hasPinEP = true;
692 break;
693 } else {
694 psIdx = idx;
695 }
696 } else if (netRouteObjs[idx]->typeId() == frcVia) {
697 hasPinEP = true;
698 break;
699 }
700 }
701
702 // need to split for pin feedthrough for connectivity
703 // psIdx might be -1 because empty nodeMap
704 // 1. two segments of a corner deleted, corner does not exist anymore
705 // 2. to a feedthrough pin, if the feedthrough is in a loop, one end does
706 // not exist anymore
707 if (!hasPinEP && psIdx != -1) {
708 psSplits[pr] = psIdx;
709 }
710 }
711
712 vector<frPathSeg*> addedPS;
713 for (auto it = psSplits.rbegin(); it != psSplits.rend(); it++) {
714 auto& [pr, idx1] = *it;
715 int idx2 = nCnt + addedPS.size();
716 auto& [splitPt, lNum] = pr;
717 frPoint bp1, ep1;
718 auto ps1 = static_cast<frPathSeg*>(netRouteObjs[idx1]);
719 ps1->getPoints(bp1, ep1);
720 bool isHorz = (bp1.y() == ep1.y());
721 set<pair<frPoint, frLayerNum>> newPr1;
722 set<pair<frPoint, frLayerNum>> newPr2;
723 for (auto& [prPt, prLNum] : reverseNodeMap[idx1]) {
724 if (isHorz) {
725 if (prPt.x() <= splitPt.x()) {
726 newPr1.insert(make_pair(prPt, prLNum));
727 } else {
728 nodeMap[make_pair(prPt, prLNum)].erase(idx1);
729 }
730 if (prPt.x() >= splitPt.x()) {
731 newPr2.insert(make_pair(prPt, prLNum));
732 nodeMap[make_pair(prPt, prLNum)].insert(idx2);
733 }
734 } else {
735 if (prPt.y() <= splitPt.y()) {
736 newPr1.insert(make_pair(prPt, prLNum));
737 } else {
738 nodeMap[make_pair(prPt, prLNum)].erase(idx1);
739 }
740 if (prPt.y() >= splitPt.y()) {
741 newPr2.insert(make_pair(prPt, prLNum));
742 nodeMap[make_pair(prPt, prLNum)].insert(idx2);
743 }
744 }
745 }
746
747 reverseNodeMap[idx1].clear();
748 reverseNodeMap[idx1] = newPr1;
749 reverseNodeMap[idx2] = newPr2;
750
751 auto uPs2 = make_unique<frPathSeg>(*ps1);
752 auto ps2 = uPs2.get();
753 addedPS.push_back(ps2);
754 unique_ptr<frShape> uShape(std::move(uPs2));
755 net->addShape(std::move(uShape));
756 // manipulate ps1
757 regionQuery->removeDRObj(ps1);
758 frSegStyle ps1Style;
759 ps1->getStyle(ps1Style);
760 ps1Style.setEndStyle(frEndStyle(frcTruncateEndStyle), 0);
761 ps1->setStyle(ps1Style);
762 ps1->setPoints(bp1, splitPt);
763 regionQuery->addDRObj(ps1);
764
765 // manipulate ps2
766 frSegStyle ps2Style;
767 ps2->getStyle(ps2Style);
768 ps2Style.setBeginStyle(frEndStyle(frcTruncateEndStyle), 0);
769 ps2->setStyle(ps2Style);
770 ps2->setPoints(splitPt, ep1);
771 regionQuery->addDRObj(ps2);
772 }
773
774 for (auto& [idx, ptS] : reverseNodeMap) {
775 frPathSeg* ps = nullptr;
776 if (idx < gCnt) {
777 if (netRouteObjs[idx]->typeId() == frcPathSeg) {
778 ps = static_cast<frPathSeg*>(netRouteObjs[idx]);
779 }
780 } else if (idx >= nCnt) {
781 ps = addedPS[idx - nCnt];
782 }
783 if (!ps) {
784 continue;
785 }
786
787 frPoint bp, ep;
788 ps->getPoints(bp, ep);
789 auto [minPr, maxPr] = minmax_element(ptS.begin(), ptS.end());
790 auto& minPt = minPr->first;
791 auto& maxPt = maxPr->first;
792 // shrink segment
793 if (bp < minPt || maxPt < ep) {
794 // negative rule
795 frBox bbox;
796 ps->getBBox(bbox);
797 checkConnectivity_addMarker(net, ps->getLayerNum(), bbox);
798
799 regionQuery->removeDRObj(ps);
800 ps->setPoints(minPt, maxPt);
801 regionQuery->addDRObj(ps);
802 if (enableOutput) {
803 cout << "net " << net->getName() << " shrinking pathseg" << endl;
804 }
805 }
806 }
807
808 // delete redundant pwires
809 set<pair<frPoint, frLayerNum>> validPoints;
810 frPoint bp, ep;
811 frLayerNum lNum;
812 for (auto& connFig : net->getShapes()) {
813 if (connFig->typeId() == frcPathSeg) {
814 auto obj = static_cast<frPathSeg*>(connFig.get());
815 obj->getPoints(bp, ep);
816 lNum = obj->getLayerNum();
817 validPoints.insert(make_pair(bp, lNum));
818 validPoints.insert(make_pair(ep, lNum));
819 } else {
820 cout << "Error: checkConnectivity_final unsupporterd type" << endl;
821 exit(1);
822 }
823 }
824 for (auto& connFig : net->getVias()) {
825 if (connFig->typeId() == frcVia) {
826 auto obj = static_cast<frVia*>(connFig.get());
827 obj->getOrigin(bp);
828 lNum = obj->getViaDef()->getLayer1Num();
829 validPoints.insert(make_pair(bp, lNum));
830 lNum = obj->getViaDef()->getLayer2Num();
831 validPoints.insert(make_pair(bp, lNum));
832 } else {
833 cout << "Error: checkConnectivity_final unsupporterd type" << endl;
834 exit(1);
835 }
836 }
837 for (auto it = net->getPatchWires().begin();
838 it != net->getPatchWires().end();) {
839 auto obj = static_cast<frPatchWire*>(it->get());
840 it++;
841 obj->getOrigin(bp);
842 lNum = obj->getLayerNum();
843 if (validPoints.find(make_pair(bp, lNum)) == validPoints.end()) {
844 // negative rule
845 frBox bbox;
846 obj->getBBox(bbox);
847 checkConnectivity_addMarker(net, obj->getLayerNum(), bbox);
848
849 regionQuery->removeDRObj(obj);
850 net->removePatchWire(obj);
851 if (enableOutput) {
852 cout << "net " << net->getName() << " deleting pwire" << endl;
853 }
854 }
855 }
856 }
857
checkConnectivity_merge1(const frNet * net,const vector<frConnFig * > & netRouteObjs,vector<map<frCoord,vector<int>>> & horzPathSegs,vector<map<frCoord,vector<int>>> & vertPathSegs)858 void FlexDR::checkConnectivity_merge1(
859 const frNet* net,
860 const vector<frConnFig*>& netRouteObjs,
861 vector<map<frCoord, vector<int>>>& horzPathSegs,
862 vector<map<frCoord, vector<int>>>& vertPathSegs)
863 {
864 // bool enableOutput = false;
865 frPoint bp, ep;
866 if (netRouteObjs.empty()) {
867 return;
868 }
869
870 for (int i = 0; i < (int) netRouteObjs.size(); i++) {
871 auto& connFig = netRouteObjs[i];
872 if (connFig->typeId() == frcPathSeg) {
873 auto obj = static_cast<frPathSeg*>(connFig);
874 obj->getPoints(bp, ep);
875 auto lNum = obj->getLayerNum();
876 // vert
877 if (bp.x() == ep.x()) {
878 vertPathSegs[lNum][bp.x()].push_back(i);
879 } else if (bp.y() == ep.y()) {
880 horzPathSegs[lNum][bp.y()].push_back(i);
881 } else {
882 cout << "Error: non-orthogonal wires in checkConnectivity_merge\n";
883 }
884 // vert
885 } else if (connFig->typeId() == frcVia) {
886 ;
887 } else if (connFig->typeId() == frcPatchWire) {
888 ;
889 } else {
890 cout << "Warning: unsupporterd obj type in checkConnectivity_merge"
891 << endl;
892 }
893 }
894 }
895
checkConnectivity_merge2(frNet * net,const vector<frConnFig * > & netRouteObjs,const vector<map<frCoord,vector<int>>> & horzPathSegs,const vector<map<frCoord,vector<int>>> & vertPathSegs,vector<vector<vector<int>>> & horzVictims,vector<vector<vector<int>>> & vertVictims,vector<vector<vector<pair<frCoord,frCoord>>>> & horzNewSegSpans,vector<vector<vector<pair<frCoord,frCoord>>>> & vertNewSegSpans)896 void FlexDR::checkConnectivity_merge2(
897 frNet* net,
898 const vector<frConnFig*>& netRouteObjs,
899 const vector<map<frCoord, vector<int>>>& horzPathSegs,
900 const vector<map<frCoord, vector<int>>>& vertPathSegs,
901 vector<vector<vector<int>>>& horzVictims,
902 vector<vector<vector<int>>>& vertVictims,
903 vector<vector<vector<pair<frCoord, frCoord>>>>& horzNewSegSpans,
904 vector<vector<vector<pair<frCoord, frCoord>>>>& vertNewSegSpans)
905 {
906 for (auto lNum = 0; lNum < (int) horzPathSegs.size(); lNum++) {
907 auto& track2Segs = horzPathSegs[lNum];
908 horzVictims[lNum].resize(track2Segs.size());
909 horzNewSegSpans[lNum].resize(track2Segs.size());
910 int i = 0;
911 for (auto& [trackCoord, indices] : track2Segs) {
912 auto& victims = horzVictims[lNum][i];
913 auto& newSegSpans = horzNewSegSpans[lNum][i];
914 checkConnectivity_merge_perform(
915 netRouteObjs, indices, victims, newSegSpans, true /*isHorz*/);
916 i++;
917 }
918 }
919
920 for (auto lNum = 0; lNum < (int) vertPathSegs.size(); lNum++) {
921 auto& track2Segs = vertPathSegs[lNum];
922 vertVictims[lNum].resize(track2Segs.size());
923 vertNewSegSpans[lNum].resize(track2Segs.size());
924 int i = 0;
925 for (auto& [trackCoord, indices] : track2Segs) {
926 auto& victims = vertVictims[lNum][i];
927 auto& newSegSpans = vertNewSegSpans[lNum][i];
928 checkConnectivity_merge_perform(
929 netRouteObjs, indices, victims, newSegSpans, false /*isHorz*/);
930 i++;
931 }
932 }
933 }
934
checkConnectivity_merge3(frNet * net,vector<frConnFig * > & netRouteObjs,const vector<map<frCoord,vector<int>>> & horzPathSegs,const vector<map<frCoord,vector<int>>> & vertPathSegs,const vector<vector<vector<int>>> & horzVictims,const vector<vector<vector<int>>> & vertVictims,const vector<vector<vector<pair<frCoord,frCoord>>>> & horzNewSegSpans,const vector<vector<vector<pair<frCoord,frCoord>>>> & vertNewSegSpans)935 void FlexDR::checkConnectivity_merge3(
936 frNet* net,
937 vector<frConnFig*>& netRouteObjs,
938 const vector<map<frCoord, vector<int>>>& horzPathSegs,
939 const vector<map<frCoord, vector<int>>>& vertPathSegs,
940 const vector<vector<vector<int>>>& horzVictims,
941 const vector<vector<vector<int>>>& vertVictims,
942 const vector<vector<vector<pair<frCoord, frCoord>>>>& horzNewSegSpans,
943 const vector<vector<vector<pair<frCoord, frCoord>>>>& vertNewSegSpans)
944 {
945 for (auto lNum = 0; lNum < (int) horzPathSegs.size(); lNum++) {
946 auto& track2Segs = horzPathSegs[lNum];
947 int i = 0;
948 for (auto& [trackCoord, indices] : track2Segs) {
949 auto& victims = horzVictims[lNum][i];
950 auto& newSegSpans = horzNewSegSpans[lNum][i];
951 checkConnectivity_merge_commit(net,
952 netRouteObjs,
953 victims,
954 lNum,
955 trackCoord,
956 newSegSpans,
957 true /*isHorz*/);
958 i++;
959 }
960 }
961
962 for (auto lNum = 0; lNum < (int) vertPathSegs.size(); lNum++) {
963 auto& track2Segs = vertPathSegs[lNum];
964 int i = 0;
965 for (auto& [trackCoord, indices] : track2Segs) {
966 auto& victims = vertVictims[lNum][i];
967 auto& newSegSpans = vertNewSegSpans[lNum][i];
968 checkConnectivity_merge_commit(net,
969 netRouteObjs,
970 victims,
971 lNum,
972 trackCoord,
973 newSegSpans,
974 false /*isHorz*/);
975 i++;
976 }
977 }
978 }
979
checkConnectivity_merge_perform(const vector<frConnFig * > & netRouteObjs,const vector<int> & indices,vector<int> & victims,vector<pair<frCoord,frCoord>> & newSegSpans,bool isHorz)980 void FlexDR::checkConnectivity_merge_perform(
981 const vector<frConnFig*>& netRouteObjs,
982 const vector<int>& indices,
983 vector<int>& victims,
984 vector<pair<frCoord, frCoord>>& newSegSpans,
985 bool isHorz)
986 {
987 vector<pair<pair<frCoord, frCoord>, int>> segSpans;
988 frPoint bp, ep;
989 for (auto& idx : indices) {
990 auto obj = static_cast<frPathSeg*>(netRouteObjs[idx]);
991 obj->getPoints(bp, ep);
992 if (isHorz) {
993 segSpans.push_back(make_pair(make_pair(bp.x(), ep.x()), idx));
994 if (bp.x() >= ep.x()) {
995 cout << "Error: bp >= ep\n";
996 }
997 } else {
998 segSpans.push_back(make_pair(make_pair(bp.y(), ep.y()), idx));
999 if (bp.y() >= ep.y()) {
1000 cout << "Error: bp >= ep\n";
1001 }
1002 }
1003 }
1004 sort(segSpans.begin(), segSpans.end());
1005
1006 // get victim segments and merged segments
1007 checkConnectivity_merge_perform_helper(segSpans, victims, newSegSpans);
1008 }
1009
checkConnectivity_merge_perform_helper(const vector<pair<pair<frCoord,frCoord>,int>> & segSpans,vector<int> & victims,vector<pair<frCoord,frCoord>> & newSegSpans)1010 void FlexDR::checkConnectivity_merge_perform_helper(
1011 const vector<pair<pair<frCoord, frCoord>, int>>& segSpans,
1012 vector<int>& victims,
1013 vector<pair<frCoord, frCoord>>& newSegSpans)
1014 {
1015 // bool enableOutput = true;
1016 map<int, int> victimIdx2SegSpanIdx;
1017 int ovlpCnt = 0;
1018 frCoord currStart = INT_MAX, currEnd = INT_MIN;
1019 vector<int> localVictims;
1020 for (auto& segSpan : segSpans) {
1021 if (segSpan.first.first >= currEnd) {
1022 ovlpCnt++;
1023 if (ovlpCnt >= 2) {
1024 // commit prev merged segs
1025 newSegSpans.push_back(make_pair(currStart, currEnd));
1026 // commit victims in merged segs
1027 victims.insert(victims.end(), localVictims.begin(), localVictims.end());
1028 // if (enableOutput) {
1029 // cout << "intervals ";
1030 // for (auto &victimIdx: localVictims) {
1031 // auto &intv = segSpans[victimIdx2SegSpanIdx[victimIdx]].first;
1032 // cout << "[" << intv.first << "," << intv.second << "] ";
1033 // }
1034 // cout << "merged to [" << currStart << "," << currEnd << "]\n";
1035 // }
1036 }
1037 // cleanup
1038 localVictims.clear();
1039 ovlpCnt = 0;
1040 // update local variables
1041 currStart = segSpan.first.first;
1042 currEnd = segSpan.first.second;
1043 localVictims.push_back(segSpan.second);
1044 } else {
1045 ovlpCnt++;
1046 // update local variables
1047 currEnd = max(currEnd, segSpan.first.second);
1048 localVictims.push_back(segSpan.second);
1049 }
1050 }
1051 if (ovlpCnt >= 1) {
1052 newSegSpans.push_back(make_pair(currStart, currEnd));
1053 victims.insert(victims.end(), localVictims.begin(), localVictims.end());
1054 }
1055 }
1056
checkConnectivity_merge_commit(frNet * net,vector<frConnFig * > & netRouteObjs,const vector<int> & victims,frLayerNum lNum,frCoord trackCoord,const vector<pair<frCoord,frCoord>> & newSegSpans,bool isHorz)1057 void FlexDR::checkConnectivity_merge_commit(
1058 frNet* net,
1059 vector<frConnFig*>& netRouteObjs,
1060 const vector<int>& victims,
1061 frLayerNum lNum,
1062 frCoord trackCoord,
1063 const vector<pair<frCoord, frCoord>>& newSegSpans,
1064 bool isHorz)
1065 {
1066 if (victims.empty()) {
1067 return;
1068 }
1069 auto regionQuery = getRegionQuery();
1070 // add segments from overlapped segments
1071 int cnt = 0;
1072 frPathSeg *last, *curr;
1073 for (auto& newSegSpan : newSegSpans) {
1074 auto victimPathSeg = static_cast<frPathSeg*>(netRouteObjs[victims[cnt]]);
1075 regionQuery->removeDRObj(static_cast<frShape*>(victimPathSeg));
1076
1077 frPoint bp, ep;
1078 if (isHorz) {
1079 bp.set(newSegSpan.first, trackCoord);
1080 ep.set(newSegSpan.second, trackCoord);
1081 } else {
1082 bp.set(trackCoord, newSegSpan.first);
1083 ep.set(trackCoord, newSegSpan.second);
1084 }
1085 victimPathSeg->setPoints(bp, ep);
1086 cnt++;
1087 last = nullptr;
1088 for (; cnt < (int) victims.size(); cnt++) {
1089 curr = static_cast<frPathSeg*>(netRouteObjs[victims[cnt]]);
1090 if (curr->high() <= newSegSpan.second) {
1091 last = curr;
1092 regionQuery->removeDRObj(
1093 static_cast<frShape*>(netRouteObjs[victims[cnt]]));
1094 net->removeShape(static_cast<frShape*>(netRouteObjs[victims[cnt]]));
1095 netRouteObjs[victims[cnt]] = nullptr;
1096 } else
1097 break;
1098 }
1099 if (last) {
1100 victimPathSeg->setEndStyle(last->getEndStyle(), last->getEndExt());
1101 }
1102 regionQuery->addDRObj(victimPathSeg);
1103 }
1104 }
1105
checkConnectivity_addMarker(frNet * net,frLayerNum lNum,const frBox & bbox)1106 void FlexDR::checkConnectivity_addMarker(frNet* net,
1107 frLayerNum lNum,
1108 const frBox& bbox)
1109 {
1110 auto regionQuery = getRegionQuery();
1111 auto marker = make_unique<frMarker>();
1112 marker->setBBox(bbox);
1113 marker->setLayerNum(lNum);
1114 marker->setConstraint(
1115 getDesign()->getTech()->getLayer(lNum)->getRecheckConstraint());
1116 marker->addSrc(net);
1117 marker->addVictim(net, make_tuple(lNum, bbox, false));
1118 marker->addAggressor(net, make_tuple(lNum, bbox, false));
1119 regionQuery->addMarker(marker.get());
1120 getDesign()->getTopBlock()->addMarker(std::move(marker));
1121 }
1122
1123 // feedthrough and loop check
checkConnectivity(int iter)1124 void FlexDR::checkConnectivity(int iter)
1125 {
1126 ProfileTask profile("DR:checkConnectivity");
1127 bool isWrong = false;
1128
1129 int batchSize = 131072;
1130 vector<vector<frNet*>> batches(1);
1131 for (auto& uPtr : getDesign()->getTopBlock()->getNets()) {
1132 auto net = uPtr.get();
1133 if (!net->isModified()) {
1134 continue;
1135 } else {
1136 net->setModified(false);
1137 if ((int) batches.back().size() < batchSize) {
1138 batches.back().push_back(net);
1139 } else {
1140 batches.push_back(vector<frNet*>());
1141 batches.back().push_back(net);
1142 }
1143 }
1144 }
1145 if (batches.size() && batches[0].empty()) {
1146 batches.clear();
1147 }
1148
1149 // omp_set_num_threads(MAX_THREADS);
1150 omp_set_num_threads(1);
1151 for (auto& batch : batches) {
1152 // only for init batch vectors, prefix t = temporary
1153 vector<map<frCoord, vector<int>>> tHorzPathSegs(
1154 getTech()->getLayers().size());
1155 vector<map<frCoord, vector<int>>> tVertPathSegs(
1156 getTech()->getLayers().size());
1157 vector<vector<vector<int>>> tHorzVictims(getTech()->getLayers().size());
1158 vector<vector<vector<int>>> tVertVictims(getTech()->getLayers().size());
1159 vector<vector<vector<pair<frCoord, frCoord>>>> tHorzNewSegSpans(
1160 getTech()->getLayers().size());
1161 vector<vector<vector<pair<frCoord, frCoord>>>> tVertNewSegSpans(
1162 getTech()->getLayers().size());
1163
1164 // prefix a = all batch
1165 // net->figs
1166 vector<vector<frConnFig*>> aNetDRObjs(batchSize);
1167 // net->layer->track->indices of DRObj
1168 vector<vector<map<frCoord, vector<int>>>> aHorzPathSegs(batchSize,
1169 tHorzPathSegs);
1170 vector<vector<map<frCoord, vector<int>>>> aVertPathSegs(batchSize,
1171 tVertPathSegs);
1172 // net->lnum->trackIdx->objIdxs
1173 vector<vector<vector<vector<int>>>> aHorzVictims(batchSize, tHorzVictims);
1174 vector<vector<vector<vector<int>>>> aVertVictims(batchSize, tVertVictims);
1175 // net->lnum->trackIdx->seg_start_end_pairs
1176 vector<vector<vector<vector<pair<frCoord, frCoord>>>>> aHorzNewSegSpans(
1177 batchSize, tHorzNewSegSpans);
1178 vector<vector<vector<vector<pair<frCoord, frCoord>>>>> aVertNewSegSpans(
1179 batchSize, tVertNewSegSpans);
1180 // net->term/instTerm->pt_layer
1181 vector<
1182 map<frBlockObject*, set<pair<frPoint, frLayerNum>>, frBlockObjectComp>>
1183 aPin2epMap(batchSize);
1184 vector<vector<frBlockObject*>> aNetPins(batchSize);
1185 vector<map<pair<frPoint, frLayerNum>, set<int>>> aNodeMap(batchSize);
1186 vector<vector<bool>> aAdjVisited(batchSize);
1187 vector<vector<int>> aAdjPrevIdx(batchSize);
1188 vector<bool> status(batchSize, false);
1189
1190 // parallel
1191 #pragma omp parallel for schedule(static)
1192 for (int i = 0; i < (int) batch.size(); i++) {
1193 auto& net = batch[i];
1194 auto& initNetDRObjs = aNetDRObjs[i];
1195 auto& horzPathSegs = aHorzPathSegs[i];
1196 auto& vertPathSegs = aVertPathSegs[i];
1197 auto& horzVictims = aHorzVictims[i];
1198 auto& vertVictims = aVertVictims[i];
1199 auto& horzNewSegSpans = aHorzNewSegSpans[i];
1200 auto& vertNewSegSpans = aVertNewSegSpans[i];
1201
1202 checkConnectivity_initDRObjs(net, initNetDRObjs);
1203 checkConnectivity_merge1(net, initNetDRObjs, horzPathSegs, vertPathSegs);
1204 checkConnectivity_merge2(net,
1205 initNetDRObjs,
1206 horzPathSegs,
1207 vertPathSegs,
1208 horzVictims,
1209 vertVictims,
1210 horzNewSegSpans,
1211 vertNewSegSpans);
1212 }
1213
1214 // sequential
1215 for (int i = 0; i < (int) batch.size(); i++) {
1216 auto& net = batch[i];
1217 auto& initNetDRObjs = aNetDRObjs[i];
1218 auto& horzPathSegs = aHorzPathSegs[i];
1219 auto& vertPathSegs = aVertPathSegs[i];
1220 auto& horzVictims = aHorzVictims[i];
1221 auto& vertVictims = aVertVictims[i];
1222 auto& horzNewSegSpans = aHorzNewSegSpans[i];
1223 auto& vertNewSegSpans = aVertNewSegSpans[i];
1224 checkConnectivity_merge3(net,
1225 initNetDRObjs,
1226 horzPathSegs,
1227 vertPathSegs,
1228 horzVictims,
1229 vertVictims,
1230 horzNewSegSpans,
1231 vertNewSegSpans);
1232 }
1233
1234 // parallel
1235 #pragma omp parallel for schedule(static)
1236 for (int i = 0; i < (int) batch.size(); i++) {
1237 auto& net = batch[i];
1238 auto& netDRObjs = aNetDRObjs[i];
1239 auto& pin2epMap = aPin2epMap[i];
1240 auto& netPins = aNetPins[i];
1241 auto& nodeMap = aNodeMap[i];
1242 auto& adjVisited = aAdjVisited[i];
1243 auto& adjPrevIdx = aAdjPrevIdx[i];
1244 netDRObjs.clear();
1245 checkConnectivity_initDRObjs(net, netDRObjs);
1246 checkConnectivity_pin2epMap(net, netDRObjs, pin2epMap);
1247 checkConnectivity_nodeMap(net, netDRObjs, netPins, pin2epMap, nodeMap);
1248
1249 int nNetRouteObjs = (int) netDRObjs.size();
1250 int nNetObjs = (int) netDRObjs.size() + (int) netPins.size();
1251 status[i] = checkConnectivity_astar(
1252 net, adjVisited, adjPrevIdx, nodeMap, netDRObjs, nNetRouteObjs, nNetObjs);
1253 }
1254
1255 // sequential
1256 for (int i = 0; i < (int) batch.size(); i++) {
1257 auto& net = batch[i];
1258 auto& netDRObjs = aNetDRObjs[i];
1259 auto& netPins = aNetPins[i];
1260 auto& nodeMap = aNodeMap[i];
1261 auto& adjVisited = aAdjVisited[i];
1262
1263 int gCnt = (int) netDRObjs.size();
1264 int nCnt = (int) netDRObjs.size() + (int) netPins.size();
1265
1266 if (!status[i]) {
1267 cout << "Error: checkConnectivity break, net " << net->getName() << endl
1268 << "Objs not visited:\n";
1269 for (int idx = 0; idx < (int)adjVisited.size(); idx++) {
1270 if (!adjVisited[idx]) {
1271 if (idx < (int)netDRObjs.size())
1272 cout << *(netDRObjs[idx]) << "\n";
1273 else
1274 cout << *(netPins[idx - netDRObjs.size()]) << "\n";
1275 }
1276 }
1277 isWrong = true;
1278 } else {
1279 // get lock
1280 // delete / shrink netRouteObjs,
1281 checkConnectivity_final(
1282 net, netDRObjs, netPins, adjVisited, gCnt, nCnt, nodeMap);
1283 // release lock
1284 }
1285 }
1286 }
1287
1288 if (isWrong) {
1289 if (graphics_) {
1290 graphics_->debugWholeDesign();
1291 }
1292 auto writer = io::Writer(getDesign(), logger_);
1293 writer.updateDb(db_);
1294 logger_->error(utl::DRT, 206, "checkConnectivity error");
1295 }
1296 }
1297