00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "CommandLine.h"
00036 #include "FPcommon.h"
00037 #include "DB.h"
00038 #include "ClusterDB.h"
00039 using namespace parquetfp;
00040
00041 ClusterDB::ClusterDB(DB* db, Command_Line *params) :
00042 _nodesSeenBB(0),_numConnections(0,0)
00043 {
00044 _params = params;
00045 _db = db;
00046 _oldDB = new DB();
00047 *(_oldDB) = *(_db);
00048 }
00049
00050 void ClusterDB::clusterMulti(DB * newDB)
00051 {
00052 unsigned numNewNodes;
00053 unsigned numOldNodes;
00054 unsigned layerNum = 1;
00055
00056 if(_params->dontClusterMacros)
00057 {
00058 double avgNodeHeight = 5*_oldDB->getAvgHeight();
00059 _oldDB->markTallNodesAsMacros(avgNodeHeight);
00060 }
00061
00062 if(_params->verb.forMajStats > 0)
00063 cout<<"Num Nodes: "<<_oldDB->getNodes()->getNumNodes()<<" Num Nets: "
00064 <<_oldDB->getNets()->getNumNets()<<" Num Pins: "
00065 <<_oldDB->getNets()->getNumPins()<<endl;
00066
00067 unsigned maxTopLevelNodes;
00068 if(_params->maxTopLevelNodes == -9999)
00069 {
00070 maxTopLevelNodes = unsigned(2*sqrt(double(_db->getNumNodes())));
00071 if(maxTopLevelNodes < 50)
00072 maxTopLevelNodes = 50;
00073 }
00074 else
00075 {
00076 maxTopLevelNodes = _params->maxTopLevelNodes;
00077 if(maxTopLevelNodes <= 0)
00078 {
00079 cout<<"maxTopLevelNodes has to be > 0"<<endl;
00080 exit(0);
00081 }
00082 }
00083
00084 if(_db->getNumNodes() > maxTopLevelNodes)
00085 {
00086 unsigned maxConnId = 1;
00087 do
00088 {
00089 DB * tempDB = new DB();
00090 _newDB = tempDB;
00091 numOldNodes = _oldDB->getNodes()->getNumNodes();
00092 cluster1Layer(layerNum, maxConnId);
00093
00094 numNewNodes = _newDB->getNodes()->getNumNodes();
00095
00096 *(_oldDB) = *(_newDB);
00097
00098 if(_params->verb.forMajStats > 0)
00099 cout<<"Num Nodes: "<<_oldDB->getNodes()->getNumNodes()<<" Num Nets: "
00100 <<_oldDB->getNets()->getNumNets()<<" Num Pins: "
00101 <<_oldDB->getNets()->getNumPins()<<endl;
00102
00103 delete tempDB;
00104 ++layerNum;
00105 if(numOldNodes != numNewNodes && maxConnId > 1)
00106 {
00107 if(maxConnId > 10)
00108 maxConnId -= 4;
00109 else
00110 --maxConnId;
00111 }
00112 if(numOldNodes == numNewNodes)
00113 ++maxConnId;
00114 if(maxConnId >= unsigned(numOldNodes/4) || maxConnId > 100)
00115 break;
00116 }
00117 while(numNewNodes > maxTopLevelNodes);
00118 }
00119
00120 _newDB = _oldDB;
00121
00122 addWSPerNode();
00123
00124
00125 _newDB = new DB(*_oldDB, true);
00126
00127 *newDB = *_newDB;
00128 }
00129
00130 ClusterDB::~ClusterDB()
00131 {
00132 if(_oldDB) delete _oldDB;
00133 }
00134
00135 void ClusterDB::cluster1Layer(unsigned layerNum, unsigned maxConnId)
00136 {
00137 map<unsigned, unsigned> mapping;
00138
00139 char blockName[1024];
00140 unsigned blkCtr;
00141
00142 Nodes* nodes = _oldDB->getNodes();
00143 Nets* nets = _oldDB->getNets();
00144 Nodes* newNodes = _newDB->getNodes();
00145 Nets* newNets = _newDB->getNets();
00146
00147 double totalArea = _oldDB->getNodesArea();
00148 double threshold = 0.2*totalArea;
00149 unsigned numNodes = nodes->getNumNodes();
00150 unsigned currNodeIdx, nextNodeIdx;
00151
00152 itNode node, nodeBegin;
00153 static bool direction=false;
00154
00155 blkCtr = 0;
00156 vector<bool> seenNodes;
00157 seenNodes.resize(numNodes);
00158 fill(seenNodes.begin(), seenNodes.end(), false);
00159
00160 _nodesSeenBB.reset(numNodes);
00161 _numConnections.resize(numNodes,0);
00162 fill(_numConnections.begin(), _numConnections.end(), false);
00163
00164
00165 if(direction || numNodes == 1)
00166 nodeBegin = nodes->nodesBegin();
00167 else
00168 nodeBegin = nodes->nodesEnd()-1;
00169
00170 for(node = nodeBegin; ; )
00171 {
00172 Node& currNode = *node;
00173 currNodeIdx = currNode.getIndex();
00174
00175
00176
00177 if(!seenNodes[currNode.getIndex()] && !currNode.isMacro())
00178 {
00179
00180 double currNodeArea = currNode.getArea();
00181
00182 Node& nextNode = getClosestNode(currNode, nodes, nets, seenNodes,
00183 maxConnId, direction);
00184
00185 if(!seenNodes[nextNode.getIndex()] &&
00186 (currNodeIdx != (unsigned)nextNode.getIndex()))
00187 {
00188 double nextNodeArea = nextNode.getArea();
00189 double newNodeArea = currNodeArea+nextNodeArea;
00190 nextNodeIdx = nextNode.getIndex();
00191
00192 if(newNodeArea < threshold && !currNode.isMacro() &&
00193 !nextNode.isMacro())
00194 {
00195 seenNodes[nextNodeIdx] = true;
00196 seenNodes[currNodeIdx] = true;
00197
00198 sprintf(blockName, "Block_%d_%d",layerNum,blkCtr);
00199 Node tempNode(blockName, newNodeArea, 0.75, 1.5, blkCtr, false);
00200
00201
00202 for(vector<int>::iterator i = currNode.subBlocksBegin();
00203 i!= currNode.subBlocksEnd(); ++i)
00204 tempNode.addSubBlockIndex(*i);
00205
00206 for(vector<int>::iterator i = nextNode.subBlocksBegin();
00207 i!= nextNode.subBlocksEnd(); ++i)
00208 tempNode.addSubBlockIndex(*i);
00209
00210 mapping[currNodeIdx] = blkCtr;
00211 mapping[nextNodeIdx] = blkCtr;
00212 newNodes->putNewNode(tempNode);
00213 ++blkCtr;
00214 }
00215 else
00216 {
00217 seenNodes[currNodeIdx] = true;
00218 Node tempNode(currNode.getName(), currNode.getArea(),
00219 currNode.getminAR(), currNode.getmaxAR(),
00220 blkCtr, false);
00221 if(currNode.isMacro())
00222 tempNode.updateMacroInfo(true);
00223 if(currNode.isOrientFixed())
00224 tempNode.putIsOrientFixed(true);
00225
00226 for(vector<int>::iterator i = currNode.subBlocksBegin();
00227 i!= currNode.subBlocksEnd(); ++i)
00228 tempNode.addSubBlockIndex(*i);
00229
00230 mapping[currNodeIdx] = blkCtr;
00231 newNodes->putNewNode(tempNode);
00232 ++blkCtr;
00233 }
00234 }
00235 }
00236 else if(currNode.isMacro())
00237 {
00238 seenNodes[currNodeIdx] = true;
00239 Node tempNode(currNode.getName(), currNode.getArea(),
00240 currNode.getminAR(), currNode.getmaxAR(),
00241 blkCtr, false);
00242 if(currNode.isMacro())
00243 tempNode.updateMacroInfo(true);
00244 if(currNode.isOrientFixed())
00245 tempNode.putIsOrientFixed(true);
00246
00247 for(vector<int>::iterator i = currNode.subBlocksBegin();
00248 i!= currNode.subBlocksEnd(); ++i)
00249 tempNode.addSubBlockIndex(*i);
00250
00251 mapping[currNodeIdx] = blkCtr;
00252 newNodes->putNewNode(tempNode);
00253 ++blkCtr;
00254 }
00255
00256 if(direction)
00257 {
00258 ++node;
00259 if(node == nodes->nodesEnd())
00260 break;
00261 }
00262 else
00263 {
00264 if(node == nodes->nodesBegin())
00265 break;
00266 --node;
00267 }
00268 }
00269
00270 direction = !direction;
00271
00272
00273 for(node = nodes->nodesBegin(); node != nodes->nodesEnd(); ++node)
00274 {
00275 Node& currNode = *node;
00276 currNodeIdx = currNode.getIndex();
00277 if(!seenNodes[currNodeIdx])
00278 {
00279 seenNodes[currNodeIdx] = true;
00280 Node tempNode(currNode.getName(), currNode.getArea(),
00281 currNode.getminAR(), currNode.getmaxAR(),
00282 blkCtr, false);
00283 if(currNode.isMacro())
00284 tempNode.updateMacroInfo(true);
00285 if(currNode.isOrientFixed())
00286 tempNode.putIsOrientFixed(true);
00287
00288 for(vector<int>::iterator i = currNode.subBlocksBegin();
00289 i!= currNode.subBlocksEnd(); ++i)
00290 tempNode.addSubBlockIndex(*i);
00291 mapping[currNodeIdx] = blkCtr;
00292 newNodes->putNewNode(tempNode);
00293 ++blkCtr;
00294 }
00295 }
00296
00297 for(node = nodes->terminalsBegin(); node != nodes->terminalsEnd(); ++node)
00298 newNodes->putNewTerm(*node);
00299
00300
00301 addNetsToNewDB(nets, newNets, nodes, newNodes, mapping);
00302 }
00303
00304 Node& ClusterDB::getClosestNode(Node& currNode, Nodes* nodes, Nets* nets,
00305 vector<bool>& seenNodes, unsigned maxConnId,
00306 bool direction)
00307 {
00308 unsigned numNodes = nodes->getNumNodes();
00309 Point tempPoint;
00310 tempPoint.x = 0;
00311 tempPoint.y = 0;
00312 vector<Point> numConnections;
00313 bool iamDesperate=false;
00314
00315 unsigned currNodeIdx = currNode.getIndex();
00316 itNodePin nodePin;
00317
00318 for(nodePin = currNode.pinsBegin(); nodePin != currNode.pinsEnd(); ++nodePin)
00319 {
00320 Net& net = nets->getNet(nodePin->netIndex);
00321
00322 {
00323 itPin netPin;
00324 for(netPin = net.pinsBegin(); netPin != net.pinsEnd(); ++netPin)
00325 {
00326 if(!netPin->getType())
00327 {
00328 if(unsigned(netPin->getNodeIndex()) != currNodeIdx)
00329 {
00330 unsigned nodeId = netPin->getNodeIndex();
00331 _numConnections[nodeId] +=
00332 1.0/net.getDegree();
00333 _nodesSeenBB.setBit(nodeId);
00334 }
00335 }
00336 }
00337 }
00338 }
00339
00340 if(maxConnId < 11)
00341 {
00342 const vector<unsigned>& bitsSet = _nodesSeenBB.getIndicesOfSetBits();
00343 for(unsigned i=0; i<bitsSet.size(); ++i)
00344 {
00345 tempPoint.x = double(bitsSet[i]);
00346 tempPoint.y = _numConnections[bitsSet[i]];
00347 numConnections.push_back(tempPoint);
00348
00349 _numConnections[bitsSet[i]] = 0;
00350 }
00351 _nodesSeenBB.clear();
00352 }
00353 else
00354 {
00355 for(unsigned i=0; i<_numConnections.size(); ++i)
00356 {
00357 tempPoint.x = double(i);
00358 tempPoint.y = _numConnections[i];
00359 numConnections.push_back(tempPoint);
00360 }
00361 _nodesSeenBB.clear();
00362 fill(_numConnections.begin(), _numConnections.end(), 0);
00363 }
00364
00365
00366 std::sort(numConnections.begin(), numConnections.end(),
00367 sortNumConnections());
00368
00369 unsigned maxConnectionsIdx = 0;
00370 unsigned maxConnectedNodes = numConnections.size();
00371 int startingId=0;
00372 if(maxConnId > maxConnectedNodes)
00373 startingId = 0;
00374 else
00375 startingId = maxConnectedNodes-maxConnId;
00376
00377 if(maxConnectedNodes > 0)
00378 {
00379 for(int i=startingId; i>=0; --i)
00380 {
00381 maxConnectionsIdx = unsigned(numConnections[i].x);
00382 if(seenNodes[maxConnectionsIdx] != 1)
00383 {
00384 numConnections.clear();
00385 return nodes->getNode(maxConnectionsIdx);
00386 }
00387 }
00388
00389 if(maxConnId <= maxConnectedNodes)
00390 maxConnectionsIdx = unsigned(numConnections[maxConnectedNodes-maxConnId].x);
00391 else if(maxConnectedNodes > 0)
00392 maxConnectionsIdx = unsigned(numConnections[maxConnectedNodes-1].x);
00393 else
00394 {
00395 iamDesperate = true;
00396 if(direction)
00397 maxConnectionsIdx = 0;
00398 else
00399 maxConnectionsIdx = numNodes-1;
00400 }
00401 }
00402 else
00403 {
00404
00405 iamDesperate = true;
00406 if(direction)
00407 maxConnectionsIdx = 0;
00408 else
00409 maxConnectionsIdx = numNodes-1;
00410 }
00411 if(iamDesperate && maxConnId > 15)
00412 {
00413
00414
00415
00416
00417 maxConnectionsIdx = rand()%numNodes;
00418 }
00419 numConnections.clear();
00420 return nodes->getNode(maxConnectionsIdx);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 void ClusterDB::addWSPerNode(void)
00435 {
00436 itNode node;
00437 Nodes* newNodes = _newDB->getNodes();
00438
00439 double multFactor = 1+_params->maxWSHier/100;
00440 double currArea, newArea, newHeight, newWidth;
00441
00442 for(node = newNodes->nodesBegin(); node != newNodes->nodesEnd(); ++node)
00443 {
00444 if(node->numSubBlocks() > 1)
00445 {
00446 currArea = node->getArea();
00447 newArea = currArea*multFactor;
00448 newWidth = sqrt(newArea*node->getminAR());
00449 newHeight = newWidth/node->getminAR();
00450 node->putArea(newArea);
00451 node->putWidth(newWidth);
00452 node->putHeight(newHeight);
00453 }
00454 }
00455 }
00456
00457 void ClusterDB::addNetsToNewDB(Nets* nets, Nets* newNets, Nodes* nodes,
00458 Nodes* newNodes, map<unsigned, unsigned>& mapping)
00459 {
00460 int netCtr=0;
00461 itNet net;
00462
00463 vector<bool> seenNodes(newNodes->getNumNodes());
00464 for(net = nets->netsBegin(); net != nets->netsEnd(); ++net)
00465 {
00466 Net tempEdge;
00467 fill(seenNodes.begin(), seenNodes.end(), false);
00468 tempEdge.putName(net->getName());
00469 tempEdge.putIndex(netCtr);
00470 tempEdge.putWeight(net->getWeight());
00471 for(itPin netPin = net->pinsBegin(); netPin != net->pinsEnd(); ++netPin)
00472 {
00473 unsigned currNodeIdx = netPin->getNodeIndex();
00474
00475 if(!netPin->getType())
00476 {
00477 unsigned newNodeIdx = mapping[currNodeIdx];
00478 Node& newNode = newNodes->getNode(newNodeIdx);
00479 double poffsetX = 0, poffsetY = 0;
00480 if(newNode.numSubBlocks() == 1)
00481 {
00482 poffsetX = netPin->getXOffset();
00483 poffsetY = netPin->getYOffset();
00484 }
00485 else if(_params->clusterPhysical)
00486 {
00487 double xMin = newNode.getX();
00488 double yMin = newNode.getY();
00489 double xMax = xMin + sqrt(newNode.getArea());
00490 double yMax = yMin + sqrt(newNode.getArea());
00491 Node& oldNode = nodes->getNode(currNodeIdx);
00492 double xloc = oldNode.getX();
00493 double yloc = oldNode.getY();
00494 if(xloc >= xMax)
00495 poffsetX = 0.5;
00496 else if(xloc <= xMin)
00497 poffsetX = -0.5;
00498 else
00499 poffsetX = ((xloc-xMin)/(xMax-xMin)) - 0.5;
00500
00501 if(yloc >= yMax)
00502 poffsetY = 0.5;
00503 else if(yloc <= yMin)
00504 poffsetY = -0.5;
00505 else
00506 poffsetY = ((yloc-yMin)/(yMax-yMin)) - 0.5;
00507 }
00508
00509 pin tempPin(newNode.getName(), false, poffsetX, poffsetY,
00510 netCtr);
00511 tempPin.putNodeIndex(newNodeIdx);
00512
00513 if(!seenNodes[newNodeIdx])
00514 {
00515 tempEdge.addNode(tempPin);
00516 seenNodes[newNodeIdx] = 1;
00517 }
00518 }
00519 else
00520 {
00521 Node& newTerm = newNodes->getTerminal(currNodeIdx);
00522 double poffsetX = 0, poffsetY = 0;
00523
00524 pin tempPin(newTerm.getName(), true, poffsetX, poffsetY,
00525 netCtr);
00526 tempPin.putNodeIndex(currNodeIdx);
00527
00528 tempEdge.addNode(tempPin);
00529 }
00530 }
00531
00532 bool needNet = false;
00533 int firstNodeIdx = tempEdge.pinsBegin()->getNodeIndex();
00534 for(itPin netPin = tempEdge.pinsBegin(); netPin != tempEdge.pinsEnd();
00535 netPin++)
00536 {
00537 if(netPin->getType())
00538 {
00539 needNet = true;
00540 break;
00541 }
00542 else if(netPin->getNodeIndex() != firstNodeIdx)
00543 {
00544 needNet = true;
00545 break;
00546 }
00547 }
00548 if(needNet)
00549 {
00550 newNets->putNewNet(tempEdge);
00551 ++netCtr;
00552 }
00553 }
00554
00555
00556
00557
00558 newNodes->updatePinsInfo(*newNets);
00559 }
00560
00561 void ClusterDB::clusterMultiPhysical(DB * newDB)
00562 {
00563 const unsigned numNew = 6;
00564 unsigned numOldNodes = _oldDB->getNumNodes();
00565
00566 if(_params->dontClusterMacros)
00567 {
00568 double avgNodeHeight = _oldDB->getAvgHeight();
00569 _oldDB->markTallNodesAsMacros(avgNodeHeight);
00570 }
00571
00572 map<unsigned, unsigned> mapping;
00573
00574 _newDB = newDB;
00575
00576 Nodes* nodes = _oldDB->getNodes();
00577 Nets* nets = _oldDB->getNets();
00578 Nodes* newNodes = _newDB->getNodes();
00579 Nets* newNets = _newDB->getNets();
00580
00581 itNode node;
00582
00583 unsigned blkCtr = 0;
00584 if(numOldNodes <= 50)
00585 {
00586 *newDB = *_oldDB;
00587 return;
00588 }
00589
00590 double layOutXSize = _oldDB->getXSize();
00591 double layOutYSize = _oldDB->getYSize();
00592
00593
00594 for(node = nodes->nodesBegin(); node != nodes->nodesEnd(); ++node)
00595 {
00596 Node& currNode = *node;
00597 if(currNode.getX() > layOutXSize)
00598 currNode.putX(layOutXSize);
00599 if(currNode.getX() < 0.0)
00600 currNode.putX(0.0);
00601 if(currNode.getY() > layOutYSize)
00602 currNode.putY(layOutYSize);
00603 if(currNode.getY() < 0.0)
00604 currNode.putY(0.0);
00605 }
00606
00607 double xStep = layOutXSize/numNew;
00608 double yStep = layOutYSize/numNew;
00609 double xMax, yMax, xMin, yMin;
00610
00611 vector<bool> seenNodes(numOldNodes, false);
00612
00613 char blockName[1024];
00614
00615 for(unsigned i=0; i<numNew; ++i)
00616 {
00617 yMin = i*yStep;
00618 yMax = (i+1)*yStep;
00619 for(unsigned j=0; j<numNew; ++j)
00620 {
00621 xMin = j*xStep;
00622 xMax = (j+1)*xStep;
00623
00624 sprintf(blockName, "Block_%d_%d",i,j);
00625 double newNodeArea = 0;
00626 vector<int> newNodesIdxs;
00627
00628 for(node = nodes->nodesBegin(); node != nodes->nodesEnd(); ++node)
00629 {
00630 Node& currNode = *node;
00631 unsigned currNodeIdx = currNode.getIndex();
00632 if(!seenNodes[currNodeIdx])
00633 {
00634 if(currNode.getX() >= xMin && currNode.getX() <= xMax &&
00635 currNode.getY() >= yMin && currNode.getY() <= yMax)
00636 {
00637 if(!currNode.isMacro())
00638 {
00639 newNodeArea += currNode.getArea();
00640 newNodesIdxs.push_back(currNode.getIndex());
00641 seenNodes[currNode.getIndex()] = 1;
00642 }
00643 else
00644 {
00645 Node tempNode(currNode.getName(), currNode.getArea(),
00646 currNode.getminAR(),
00647 currNode.getmaxAR(), blkCtr, false);
00648 mapping[currNode.getIndex()] = blkCtr;
00649 tempNode.addSubBlockIndex(currNode.getIndex());
00650 tempNode.putX(currNode.getX());
00651 tempNode.putY(currNode.getY());
00652 tempNode.putOrient(currNode.getOrient());
00653 newNodes->putNewNode(tempNode);
00654 ++blkCtr;
00655 seenNodes[currNode.getIndex()] = 1;
00656 }
00657 }
00658 }
00659 }
00660 if(newNodesIdxs.size() != 0)
00661 {
00662 Node tempNode(blockName, newNodeArea, 0.5, 2.0, blkCtr, false);
00663 for(unsigned k=0; k<newNodesIdxs.size(); ++k)
00664 {
00665 tempNode.addSubBlockIndex(newNodesIdxs[k]);
00666 mapping[newNodesIdxs[k]] = blkCtr;
00667 }
00668 tempNode.putX(xMin);
00669 tempNode.putY(yMin);
00670 newNodes->putNewNode(tempNode);
00671 ++blkCtr;
00672 }
00673 }
00674 }
00675 for(unsigned i=0; i<seenNodes.size(); ++i)
00676 if(seenNodes[i] == 0)
00677 {
00678 Node& temp = nodes->getNode(i);
00679 Node tempNode(temp.getName(), temp.getArea(), temp.getminAR(),
00680 temp.getmaxAR(), blkCtr, false);
00681
00682 tempNode.addSubBlockIndex(temp.getIndex());
00683 double xLoc = temp.getX() > 0 ? temp.getX() : 0;
00684 double yLoc = temp.getY() > 0 ? temp.getY() : 0;
00685 tempNode.putX(xLoc);
00686 tempNode.putY(yLoc);
00687 tempNode.putOrient(temp.getOrient());
00688 newNodes->putNewNode(tempNode);
00689 ++blkCtr;
00690 cout<<"Warning in ClusterDB.cxx "<<temp.getName()<<"("<<temp.getX()
00691 <<", "<<temp.getY()<<") out of layout region "<<endl;
00692 }
00693
00694 for(node = nodes->terminalsBegin(); node != nodes->terminalsEnd(); ++node)
00695 newNodes->putNewTerm(*node);
00696
00697 addWSPerNode();
00698
00699 addNetsToNewDB(nets, newNets, nodes, newNodes, mapping);
00700 }
00701