blob: 55f2cb3633225622b4c7baa40eb9a4a756ffc73d [file] [log] [blame]
/* Authors: Lutong Wang and Bangqi Xu */
/*
* Copyright (c) 2019, The Regents of the University of California
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "dr/FlexDR.h"
#include "io/io.h"
using namespace std;
using namespace fr;
// copied from FlexDRWorker::initNets_searchRepair_pin2epMap_helper
void FlexDR::checkConnectivity_pin2epMap_helper(frNet *net, const frPoint &bp, frLayerNum lNum,
map<frBlockObject*, set<pair<frPoint, frLayerNum> >, frBlockObjectComp> &pin2epMap) {
bool enableOutput = false;
//bool enableOutput = true;
auto regionQuery = getRegionQuery();
vector<rq_rptr_value_t<frBlockObject> > result;
//result.clear();
regionQuery->query(frBox(bp, bp), lNum, result);
for (auto &[bx, rqObj]: result) {
if (rqObj->typeId() == frcInstTerm) {
auto instTerm = static_cast<frInstTerm*>(rqObj);
if (instTerm->getNet() == net) {
if (enableOutput) {
cout <<" found " <<instTerm->getInst()->getName() <<"/" <<instTerm->getTerm()->getName() <<endl;
}
pin2epMap[rqObj].insert(make_pair(bp, lNum));
} else {
//if (enableOutput) {
// cout <<" found other instTerm" <<endl;
//}
}
} else if (rqObj->typeId() == frcTerm) {
auto term = static_cast<frTerm*>(rqObj);
if (term->getNet() == net) {
if (enableOutput) {
cout <<" found PIN/" <<term->getName() <<endl;
}
pin2epMap[rqObj].insert(make_pair(bp, lNum));
} else {
//if (enableOutput) {
// cout <<" found other term" <<endl;
//}
}
}
}
}
void FlexDR::checkConnectivity_pin2epMap(frNet* net, vector<frConnFig*> &netDRObjs,
map<frBlockObject*, set<pair<frPoint, frLayerNum> >, frBlockObjectComp> &pin2epMap) {
bool enableOutput = false;
//bool enableOutput = true;
frPoint bp, ep;
for (auto &connFig: netDRObjs) {
if (connFig->typeId() == frcPathSeg) {
auto obj = static_cast<frPathSeg*>(connFig);
obj->getPoints(bp, ep);
auto lNum = obj->getLayerNum();
if (enableOutput) {
cout <<"(bp, ep) (" <<bp.x() / 2000.0 <<" ," <<bp.y() / 2000.0 <<") ("
<<ep.x() / 2000.0 <<" ," <<ep.y() / 2000.0 <<") "
<<getTech()->getLayer(lNum)->getName() <<endl;
}
if (enableOutput) {
cout <<" query bp" <<endl;
}
checkConnectivity_pin2epMap_helper(net, bp, lNum, pin2epMap);
if (enableOutput) {
cout <<" query ep" <<endl;
}
checkConnectivity_pin2epMap_helper(net, ep, lNum, pin2epMap);
} else if (connFig->typeId() == frcVia) {
auto obj = static_cast<frVia*>(connFig);
obj->getOrigin(bp);
auto l1Num = obj->getViaDef()->getLayer1Num();
auto l2Num = obj->getViaDef()->getLayer2Num();
if (enableOutput) {
cout <<"pt (" <<bp.x() / 2000.0 <<" ," <<bp.y() / 2000.0 <<") "
<<obj->getViaDef()->getName() <<endl;
}
if (enableOutput) {
cout <<" query pt l1" <<endl;
}
checkConnectivity_pin2epMap_helper(net, bp, l1Num, pin2epMap);
if (enableOutput) {
cout <<" query pt l2" <<endl;
}
checkConnectivity_pin2epMap_helper(net, bp, l2Num, pin2epMap);
} else {
cout <<"Error: checkConnectivity_pin2epMap unsupported type" <<endl;
}
}
}
void FlexDR::checkConnectivity_initDRObjs(frNet* net, vector<frConnFig*> &netDRObjs) {
bool enableOutput = false;
//bool enableOutput = true;
for (auto &uPtr: net->getShapes()) {
auto connFig = uPtr.get();
if (connFig->typeId() == frcPathSeg) {
netDRObjs.push_back(connFig);
if (enableOutput) {
auto obj = static_cast<frPathSeg*>(connFig);
frPoint bp, ep;
auto lNum = obj->getLayerNum();
obj->getPoints(bp, ep);
cout <<" (" <<bp.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<bp.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") ("
<<ep.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<ep.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") "
<<getTech()->getLayer(lNum)->getName() <<endl;
}
} else {
cout <<"Error: checkConnectivity_initDRObjs unsupported type" <<endl;
}
}
for (auto &uPtr: net->getVias()) {
auto connFig = uPtr.get();
if (connFig->typeId() == frcVia) {
netDRObjs.push_back(connFig);
if (enableOutput) {
auto obj = static_cast<frVia*>(connFig);
frPoint bp;
obj->getOrigin(bp);
cout <<" (" <<bp.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<bp.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") "
<<obj->getViaDef()->getName() <<endl;
}
} else {
cout <<"Error: checkConnectivity_initDRObjs unsupported type" <<endl;
}
}
}
void FlexDR::checkConnectivity_nodeMap_routeObjEnd(frNet* net, vector<frConnFig*> &netRouteObjs,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
bool enableOutput = false;
frPoint bp, ep;
for (int i = 0; i < (int)netRouteObjs.size(); i++) {
auto &connFig = netRouteObjs[i];
if (connFig->typeId() == frcPathSeg) {
auto obj = static_cast<frPathSeg*>(connFig);
obj->getPoints(bp, ep);
auto lNum = obj->getLayerNum();
nodeMap[make_pair(bp, lNum)].insert(i);
nodeMap[make_pair(ep, lNum)].insert(i);
if (enableOutput) {
cout <<"node idx = " <<i <<", (" <<bp.x() / 2000.0 <<", " <<bp.y() / 2000.0 <<") ("
<<ep.x() / 2000.0 <<", " <<ep.y() / 2000.0 <<") "
<<getTech()->getLayer(lNum)->getName() <<endl;
}
} else if (connFig->typeId() == frcVia) {
auto obj = static_cast<frVia*>(connFig);
obj->getOrigin(bp);
auto l1Num = obj->getViaDef()->getLayer1Num();
auto l2Num = obj->getViaDef()->getLayer2Num();
nodeMap[make_pair(bp, l1Num)].insert(i);
nodeMap[make_pair(bp, l2Num)].insert(i);
if (enableOutput) {
cout <<"node idx = " <<i <<", (" <<bp.x() / 2000.0 <<", " <<bp.y() / 2000.0 <<") "
<<getTech()->getLayer(l1Num)->getName() <<" --> " <<getTech()->getLayer(l2Num)->getName() <<endl;
}
} else {
cout <<"Error: checkConnectivity_nodeMap_routeObjEnd unsupported type" <<endl;
}
}
}
void FlexDR::checkConnectivity_nodeMap_routeObjSplit_helper(const frPoint &crossPt,
frCoord trackCoord, frCoord splitCoord, frLayerNum lNum,
vector<map<frCoord, map<frCoord, pair<frCoord, int> > > > &mergeHelper,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
auto it1 = mergeHelper[lNum].find(trackCoord);
if (it1 != mergeHelper[lNum].end()) {
auto &mp = it1->second; // map<ep, pair<bp, objIdx> >
auto it2 = mp.lower_bound(splitCoord);
if (it2 != mp.end()) {
auto &endP = it2->first;
auto &[beginP, objIdx] = it2->second;
if (endP > splitCoord && beginP < splitCoord) {
nodeMap[make_pair(crossPt, lNum)].insert(objIdx);
}
}
}
}
void FlexDR::checkConnectivity_nodeMap_routeObjSplit(frNet* net, vector<frConnFig*> &netRouteObjs,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
frPoint bp, ep;
// vector<map<track, map<ep, pair<bp, objIdx> > > > interval_map
vector<map<frCoord, map<frCoord, pair<frCoord, int> > > > horzMergeHelper(getTech()->getLayers().size());
vector<map<frCoord, map<frCoord, pair<frCoord, int> > > > vertMergeHelper(getTech()->getLayers().size());
for (int i = 0; i < (int)netRouteObjs.size(); i++) {
auto &connFig = netRouteObjs[i];
if (connFig->typeId() == frcPathSeg) {
auto obj = static_cast<frPathSeg*>(connFig);
obj->getPoints(bp, ep);
auto lNum = obj->getLayerNum();
// vert seg
if (bp.x() == ep.x()) {
vertMergeHelper[lNum][bp.x()][ep.y()] = make_pair(bp.y(), i);
// horz seg
} else {
horzMergeHelper[lNum][bp.y()][ep.x()] = make_pair(bp.x(), i);
}
}
}
for (int i = 0; i < (int)netRouteObjs.size(); i++) {
auto &connFig = netRouteObjs[i];
// ep on pathseg
if (connFig->typeId() == frcPathSeg) {
auto obj = static_cast<frPathSeg*>(connFig);
obj->getPoints(bp, ep);
auto lNum = obj->getLayerNum();
// vert seg, find horz crossing seg
if (bp.x() == ep.x()) {
//find whether there is horz track at bp
auto crossPt = bp;
auto trackCoord = bp.y();
auto splitCoord = bp.x();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
//find whether there is horz track at ep
crossPt = ep;
trackCoord = ep.y();
splitCoord = ep.x();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
// horz seg
} else {
//find whether there is vert track at bp
auto crossPt = bp;
auto trackCoord = bp.x();
auto splitCoord = bp.y();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
//find whether there is vert track at ep
crossPt = ep;
trackCoord = ep.x();
splitCoord = ep.y();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
}
} else if (connFig->typeId() == frcVia) {
auto obj = static_cast<frVia*>(connFig);
obj->getOrigin(bp);
auto lNum = obj->getViaDef()->getLayer1Num();
//find whether there is horz track at bp on layer1
auto crossPt = bp;
auto trackCoord = bp.y();
auto splitCoord = bp.x();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
//find whether there is vert track at bp on layer1
crossPt = bp;
trackCoord = bp.x();
splitCoord = bp.y();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
lNum = obj->getViaDef()->getLayer2Num();
//find whether there is horz track at bp on layer2
crossPt = bp;
trackCoord = bp.y();
splitCoord = bp.x();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, horzMergeHelper, nodeMap);
//find whether there is vert track at bp on layer2
crossPt = bp;
trackCoord = bp.x();
splitCoord = bp.y();
checkConnectivity_nodeMap_routeObjSplit_helper(crossPt, trackCoord, splitCoord, lNum, vertMergeHelper, nodeMap);
}
}
}
void FlexDR::checkConnectivity_nodeMap_pin(frNet* net,
vector<frConnFig*> &netRouteObjs,
vector<frBlockObject*> &netPins,
map<frBlockObject*, set<pair<frPoint, frLayerNum> >, frBlockObjectComp> &pin2epMap,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
bool enableOutput = false;
int currCnt = (int)netRouteObjs.size();
for (auto &[obj, locS]: pin2epMap) {
netPins.push_back(obj);
for (auto &pr: locS) {
nodeMap[pr].insert(currCnt);
if (enableOutput) {
cout <<"pin idx = " <<currCnt <<", (" <<pr.first.x() <<", " <<pr.first.y() <<") "
<<getTech()->getLayer(pr.second)->getName() <<endl;
}
}
++currCnt;
}
}
void FlexDR::checkConnectivity_nodeMap(frNet* net,
vector<frConnFig*> &netRouteObjs,
vector<frBlockObject*> &netPins,
map<frBlockObject*, set<pair<frPoint, frLayerNum> >, frBlockObjectComp> &pin2epMap,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
bool enableOutput = false;
//bool enableOutput = true;
checkConnectivity_nodeMap_routeObjEnd(net, netRouteObjs, nodeMap);
checkConnectivity_nodeMap_routeObjSplit(net, netRouteObjs, nodeMap);
checkConnectivity_nodeMap_pin(net, netRouteObjs, netPins, pin2epMap, nodeMap);
if (enableOutput) {
int idx = 0;
for (auto connFig: netRouteObjs) {
if (connFig->typeId() == frcPathSeg) {
auto obj = static_cast<frPathSeg*>(connFig);
frPoint bp, ep;
auto lNum = obj->getLayerNum();
obj->getPoints(bp, ep);
cout <<"#" <<idx <<" ("
<<bp.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<bp.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") ("
<<ep.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<ep.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") "
<<getTech()->getLayer(lNum)->getName() <<endl;
} else if (connFig->typeId() == frcVia) {
auto obj = static_cast<frVia*>(connFig);
frPoint bp;
obj->getOrigin(bp);
cout <<"#" <<idx <<" ("
<<bp.x() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<", "
<<bp.y() * 1.0/ getDesign()->getTopBlock()->getDBUPerUU() <<") "
<<obj->getViaDef()->getName() <<endl;
} else {
cout <<"Error: checkConnectivity_nodeMap unsupported type" <<endl;
}
idx++;
}
for (auto obj: netPins) {
if (obj->typeId() == frcInstTerm) {
auto instTerm = static_cast<frInstTerm*>(obj);
cout <<"#" <<idx <<" " <<instTerm->getInst()->getName() <<"/" <<instTerm->getTerm()->getName() <<endl;
} else if (obj->typeId() == frcTerm) {
auto term = static_cast<frTerm*>(obj);
cout <<"#" <<idx <<" PIN/" <<term->getName() <<endl;
}
idx++;
}
}
}
bool FlexDR::checkConnectivity_astar(frNet* net, vector<bool> &adjVisited, vector<int> &adjPrevIdx,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap, int &gCnt, int &nCnt) {
//bool enableOutput = true;
bool enableOutput = false;
// a star search
// node index, node visited
vector<vector<int> > adjVec(nCnt, vector<int>());
vector<bool> onPathIdx(nCnt, false);
adjVisited.clear();
adjPrevIdx.clear();
adjVisited.resize(nCnt, false);
adjPrevIdx.resize(nCnt, -1);
for (auto &[pr, idxS]: nodeMap) {
//auto &[pt, lNum] = pr;
for (auto it1 = idxS.begin(); it1 != idxS.end(); it1++) {
auto it2 = it1;
it2++;
auto idx1 = *it1;
for (; it2 != idxS.end(); it2++) {
auto idx2 = *it2;
adjVec[idx1].push_back(idx2);
adjVec[idx2].push_back(idx1);
//cout <<"add edge #" <<idx1 <<" -- #" <<idx2 <<endl;
// one pin, one gcell
}
}
}
struct wf {
int nodeIdx;
int prevIdx;
int cost;
bool operator<(const wf &b) const {
if (cost == b.cost) {
return nodeIdx > b.nodeIdx;
} else {
return cost > b.cost;
}
}
};
for (int findNode = gCnt; findNode < nCnt - 1; findNode++) {
//adjVisited = onPathIdx;
//cout <<"finished " <<findNode <<" nodes" <<endl;
priority_queue<wf> pq;
if (enableOutput) {
//cout <<"visit";
}
if (findNode == gCnt) {
// push only first pin into pq
pq.push({gCnt, -1, 0});
} else {
// push every visited node into pq
for (int i = 0; i < nCnt; i++) {
//if (adjVisited[i]) {
if (onPathIdx[i]) {
// penalize feedthrough in normal mode
if (i >= gCnt) {
pq.push({i, adjPrevIdx[i], 0});
} else {
pq.push({i, adjPrevIdx[i], 0});
}
}
}
}
int lastNodeIdx = -1;
while (!pq.empty()) {
auto wfront = pq.top();
pq.pop();
if (!onPathIdx[wfront.nodeIdx] && adjVisited[wfront.nodeIdx]) {
continue;
}
if (wfront.nodeIdx > gCnt && wfront.nodeIdx < nCnt && adjVisited[wfront.nodeIdx] == false) {
adjVisited[wfront.nodeIdx] = true;
adjPrevIdx[wfront.nodeIdx] = wfront.prevIdx;
if (enableOutput) {
//cout <<" " <<wfront.nodeIdx <<" (" <<wfront.cost <<"," <<wfront.prevIdx <<")" <<" exit" <<endl;
cout <<"visit " <<wfront.nodeIdx <<" (" <<wfront.cost <<"," <<wfront.prevIdx <<")" <<" exit" <<endl;
}
lastNodeIdx = wfront.nodeIdx;
break;
}
adjVisited[wfront.nodeIdx] = true;
adjPrevIdx[wfront.nodeIdx] = wfront.prevIdx;
if (enableOutput) {
//cout <<" " <<wfront.nodeIdx <<" (" <<wfront.cost <<"," <<wfront.prevIdx <<")";
cout <<"visit " <<wfront.nodeIdx <<" (" <<wfront.cost <<"," <<wfront.prevIdx <<")" <<endl;
}
// visit other nodes
for (auto nbrIdx: adjVec[wfront.nodeIdx]) {
if (!adjVisited[nbrIdx]) {
pq.push({nbrIdx, wfront.nodeIdx, wfront.cost + 1});
if (enableOutput) {
cout <<"push " <<nbrIdx <<endl;
}
}
}
}
// trace back path
if (enableOutput) {
cout <<"trace back id";
}
while ((lastNodeIdx != -1) && (!onPathIdx[lastNodeIdx])) {
onPathIdx[lastNodeIdx] = true;
if (enableOutput) {
cout <<" " <<lastNodeIdx <<" (" <<adjPrevIdx[lastNodeIdx] <<")";
}
lastNodeIdx = adjPrevIdx[lastNodeIdx];
}
if (enableOutput) {
cout <<endl;
}
adjVisited = onPathIdx;
}
if (enableOutput) {
cout <<"stat: " <<net->getName() <<" #guide/#pin/#unused = " <<gCnt <<"/" <<nCnt - gCnt <<"/"
<<nCnt - count(adjVisited.begin(), adjVisited.end(), true) <<endl;
}
int pinVisited = count(adjVisited.begin() + gCnt, adjVisited.end(), true);
// true error when allowing feedthrough
if (pinVisited != nCnt - gCnt) {
cout <<"Error: " <<net->getName() <<" " <<nCnt - gCnt - pinVisited <<" pin not visited #guides = " <<gCnt <<endl;
if (enableOutput) {
for (int i = gCnt; i < nCnt; i++) {
if (!adjVisited[i]) {
cout <<" pin id = " <<i <<endl;
}
}
}
}
if (pinVisited == nCnt - gCnt) {
return true;
} else {
return false;
}
}
void FlexDR::checkConnectivity_final(frNet *net, vector<frConnFig*> &netRouteObjs, vector<frBlockObject*> &netPins,
vector<bool> &adjVisited, int gCnt, int nCnt,
map<pair<frPoint, frLayerNum>, set<int> > &nodeMap) {
//bool enableOutput = true;
bool enableOutput = false;
auto regionQuery = getRegionQuery();
// from obj to pt
map<int, set<pair<frPoint, frLayerNum> > > reverseNodeMap;
for (auto &[pr, idxS]: nodeMap) {
for (auto &idx: idxS) {
reverseNodeMap[idx].insert(pr);
}
}
// nodeMap delete redundant objs
for (int i = 0; i < (int)adjVisited.size(); i++) {
if (adjVisited[i]) {
continue;
}
for (auto &pr: reverseNodeMap[i]) {
nodeMap[pr].erase(i);
}
if (i < gCnt) {
if (netRouteObjs[i]->typeId() == frcPathSeg) {
regionQuery->removeDRObj(static_cast<frShape*>(netRouteObjs[i]));
net->removeShape(static_cast<frShape*>(netRouteObjs[i]));
if (enableOutput) {
cout <<"net " <<net->getName() <<" deleting pathseg" <<endl;
}
} else if (netRouteObjs[i]->typeId() == frcVia) {
regionQuery->removeDRObj(static_cast<frVia*>(netRouteObjs[i]));
net->removeVia(static_cast<frVia*>(netRouteObjs[i]));
if (enableOutput) {
cout <<"net " <<net->getName() <<" deleting via" <<endl;
}
} else {
cout <<"Error: checkConnectivity_final unsupporterd type" <<endl;
exit(1);
}
netRouteObjs[i] = nullptr;
} else {
cout <<"Error: checkConnectivity_final i >= gCnt" <<endl;
exit(1);
}
}
// rebuild reverseNodeMap
reverseNodeMap.clear();
for (auto &[pr, idxS]: nodeMap) {
if (idxS.size() == 1) {
continue;
}
for (auto &idx: idxS) {
reverseNodeMap[idx].insert(pr);
}
}
for (auto &[idx, ptS]: reverseNodeMap) {
if (idx < gCnt && netRouteObjs[idx]->typeId() == frcPathSeg) {
auto ps = static_cast<frPathSeg*>(netRouteObjs[idx]);
frPoint bp, ep;
ps->getPoints(bp, ep);
auto [minPr, maxPr] = minmax_element(ptS.begin(), ptS.end());
auto &minPt = minPr->first;
auto &maxPt = maxPr->first;
// shrink segment
if (bp < minPt || maxPt < ep) {
regionQuery->removeDRObj(ps);
ps->setPoints(minPt, maxPt);
regionQuery->addDRObj(ps);
if (enableOutput) {
cout <<"net " <<net->getName() <<" shrinking pathseg" <<endl;
}
}
}
}
}
// feedthrough and loop check
void FlexDR::checkConnectivity() {
//cout <<"checking connectivity " <<endl;
bool isWrong = false;
for (auto &uPtr: getDesign()->getTopBlock()->getNets()) {
auto net = uPtr.get();
//if (net->getName() != "net3097") {
// continue;
//}
vector<frConnFig*> netDRObjs;
checkConnectivity_initDRObjs(net, netDRObjs);
map<frBlockObject*, set<pair<frPoint, frLayerNum> >, frBlockObjectComp> pin2epMap;
checkConnectivity_pin2epMap(net, netDRObjs, pin2epMap);
vector<frBlockObject*> netPins;
map<pair<frPoint, frLayerNum>, set<int> > nodeMap;
checkConnectivity_nodeMap(net, netDRObjs, netPins, pin2epMap, nodeMap);
int gCnt = (int)netDRObjs.size();
int nCnt = (int)netDRObjs.size() + (int)netPins.size();
vector<bool> adjVisited;
vector<int> adjPrevIdx;
if (!checkConnectivity_astar(net, adjVisited, adjPrevIdx, nodeMap, gCnt, nCnt)) {
cout <<"Error: checkConnectivity break, net " <<net->getName() <<endl;
isWrong = true;
} else {
// get lock
// delete / shrink netRouteObjs,
checkConnectivity_final(net, netDRObjs, netPins, adjVisited, gCnt, nCnt, nodeMap);
// release lock
}
}
if (isWrong) {
io::Writer writer(getDesign());
writer.writeFromDR("_conn");
exit(1);
}
}