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
00036 #include <map>
00037 #include <algorithm>
00038 #include <climits>
00039 #include <cfloat>
00040
00041 #include "FPcommon.h"
00042 #include "DB.h"
00043 #include "PlToSP.h"
00044 #include "SPeval.h"
00045 #include "ABKCommon/abkassert.h"
00046
00047 using namespace parquetfp;
00048 using std::min;
00049
00050
00051 DB::DB(char* baseName)
00052 {
00053 cout << "Reading Nodes (files " << baseName << ".blocks and "
00054 << baseName << ".pl)" << endl;
00055 _nodes = new Nodes(baseName);
00056
00057 cout << "Reading Nets (file " << baseName << ".nets)"
00058 << endl;
00059 _nets = new Nets(baseName);
00060
00061 _nets->updateNodeInfo(*_nodes);
00062 _nodes->updatePinsInfo(*_nets);
00063 _nodes->initNodesFastPOAccess(*_nets, false);
00064
00065 cout << "Done creating DB " << endl;
00066
00067 _nodesBestCopy = new Nodes();
00068
00069
00070
00071 _initArea = 0;
00072 successAR = 0;
00073 _rowHeight = 0;
00074 _siteSpacing = 0;
00075 }
00076
00077 DB::DB()
00078 {
00079 _nodes = new Nodes();
00080 _nets = new Nets();
00081 _nodesBestCopy = new Nodes();
00082
00083 _initArea = 0;
00084 successAR = 0;
00085 _rowHeight = 0;
00086 _siteSpacing = 0;
00087 }
00088
00089 DB::DB(DB * db, vector<int>& subBlocksIndices, Point& dbLoc, double reqdAR)
00090 {
00091 _nodes = new Nodes();
00092 _nets = new Nets();
00093 _nodesBestCopy = new Nodes();
00094 _initArea = 0;
00095 successAR = 0;
00096 _rowHeight = 0;
00097 _siteSpacing = 0;
00098
00099 Nodes* origNodes = db->getNodes();
00100 Nets* origNets = db->getNets();
00101
00102 map<unsigned, unsigned> mapping;
00103 unsigned numOrigNodes = origNodes->getNumNodes();
00104 vector<bool> seenNodes(numOrigNodes, false);
00105
00106 double nodesArea = 0;
00107 for(unsigned i=0; i<subBlocksIndices.size(); ++i)
00108 {
00109 Node& origNode = origNodes->getNode(subBlocksIndices[i]);
00110 nodesArea += origNode.getArea();
00111 Node tempNode(origNode.getName(), origNode.getArea() ,
00112 origNode.getminAR(), origNode.getmaxAR(), i, false);
00113 tempNode.addSubBlockIndex(subBlocksIndices[i]);
00114 tempNode.putX(origNode.getX());
00115 tempNode.putY(origNode.getY());
00116 _nodes->putNewNode(tempNode);
00117 seenNodes[subBlocksIndices[i]] = true;
00118 mapping[subBlocksIndices[i]] = i;
00119 }
00120
00121 double reqdHeight = sqrt(nodesArea/reqdAR);
00122 double reqdWidth = reqdHeight*reqdAR;
00123 double termXLoc, termYLoc;
00124 double minXLoc = dbLoc.x;
00125 double maxXLoc = minXLoc + reqdWidth;
00126 double minYLoc = dbLoc.y;
00127 double maxYLoc = minYLoc + reqdHeight;
00128
00129 unsigned numOrigNets = origNets->getNumNets();
00130 vector<bool> seenNets(numOrigNets, false);
00131
00132 unsigned newNetCtr=0;
00133 unsigned newTermCtr = 0;
00134
00135 itNodePin origNodePin;
00136 Net tempEdge;
00137
00138 for(unsigned i=0; i<subBlocksIndices.size(); ++i)
00139 {
00140 Node& origNode = origNodes->getNode(subBlocksIndices[i]);
00141 for(origNodePin = origNode.pinsBegin();
00142 origNodePin != origNode.pinsEnd(); ++origNodePin)
00143 {
00144 Net& origNet = origNets->getNet(origNodePin->netIndex);
00145 if(!seenNets[origNet.getIndex()])
00146 {
00147 seenNets[origNet.getIndex()] = true;
00148 tempEdge.putName(origNet.getName());
00149 tempEdge.putIndex(newNetCtr);
00150 for(itPin netPin = origNet.pinsBegin();
00151 netPin != origNet.pinsEnd(); ++netPin)
00152 {
00153 double poffsetX, poffsetY;
00154 unsigned origNodeIdx = netPin->getNodeIndex();
00155 if(!netPin->getType())
00156 {
00157 if(seenNodes[origNodeIdx])
00158 {
00159 unsigned newNodeIdx = mapping[origNodeIdx];
00160 poffsetX = netPin->getXOffset();
00161 poffsetY = netPin->getYOffset();
00162
00163 Node& newNode = _nodes->getNode(newNodeIdx);
00164 pin tempPin(newNode.getName(), false, poffsetX,
00165 poffsetY, newNetCtr);
00166 tempPin.putNodeIndex(newNodeIdx);
00167 tempEdge.addNode(tempPin);
00168 }
00169 else
00170 {
00171 Node& origTerm =
00172 origNodes->getNode(netPin->getNodeIndex());
00173
00174 Node tempTerm(origTerm.getName(), 0, 1, 1,
00175 newTermCtr, true);
00176 tempTerm.addSubBlockIndex(origTerm.getIndex());
00177
00178
00179 if(origTerm.getX() < minXLoc)
00180 termXLoc = 0;
00181 else if(origTerm.getX() > maxXLoc)
00182 termXLoc = reqdWidth;
00183 else
00184 termXLoc = origTerm.getX() - minXLoc;
00185
00186 if(origTerm.getY() < minYLoc)
00187 termYLoc = 0;
00188 else if(origTerm.getY() > maxYLoc)
00189 termYLoc = reqdHeight;
00190 else
00191 termYLoc = origTerm.getY() - minYLoc;
00192
00193 tempTerm.putX(termXLoc);
00194 tempTerm.putY(termYLoc);
00195
00196 _nodes->putNewTerm(tempTerm);
00197
00198 pin tempPin(origTerm.getName(), true, 0, 0, newNetCtr);
00199 tempPin.putNodeIndex(newTermCtr);
00200 tempEdge.addNode(tempPin);
00201 newTermCtr++;
00202 }
00203 }
00204 else
00205 {
00206 Node& origTerm =
00207 origNodes->getTerminal(netPin->getNodeIndex());
00208
00209 Node tempTerm(origTerm.getName(), 0, 1, 1, newTermCtr,
00210 true);
00211 tempTerm.addSubBlockIndex(origTerm.getIndex());
00212
00213
00214
00215 if(origTerm.getX() < minXLoc)
00216 termXLoc = 0;
00217 else if(origTerm.getX() > maxXLoc)
00218 termXLoc = reqdWidth;
00219 else
00220 termXLoc = origTerm.getX() - minXLoc;
00221
00222 if(origTerm.getY() < minYLoc)
00223 termYLoc = 0;
00224 else if(origTerm.getY() > maxYLoc)
00225 termYLoc = reqdHeight;
00226 else
00227 termYLoc = origTerm.getY() - minYLoc;
00228
00229 tempTerm.putX(termXLoc);
00230 tempTerm.putY(termYLoc);
00231
00232 _nodes->putNewTerm(tempTerm);
00233
00234 pin tempPin(origTerm.getName(), true, 0, 0, newNetCtr);
00235 tempPin.putNodeIndex(newTermCtr);
00236 tempEdge.addNode(tempPin);
00237 newTermCtr++;
00238 }
00239 }
00240 _nets->putNewNet(tempEdge);
00241 ++newNetCtr;
00242 tempEdge.clean();
00243 }
00244 }
00245 }
00246 _nodes->updatePinsInfo(*_nets);
00247 _nodes->initNodesFastPOAccess(*_nets, false);
00248 *_nodesBestCopy = *_nodes;
00249 }
00250
00251 DB::~DB()
00252 {
00253 if(_nodes) delete _nodes;
00254 if(_nets) delete _nets;
00255 if(_nodesBestCopy) delete _nodesBestCopy;
00256 }
00257
00258 DB& DB::operator=(DB& db2)
00259 {
00260 if(this != &db2)
00261 {
00262 if(_nodes) delete _nodes;
00263 if(_nets) delete _nets;
00264 if(_nodesBestCopy) delete _nodesBestCopy;
00265
00266 _nodes = new Nodes();
00267 _nets = new Nets();
00268 _nodesBestCopy = new Nodes();
00269
00270 *(_nodes) = *(db2.getNodes());
00271 *(_nets) = *(db2.getNets());
00272 *(_nodesBestCopy) = *(db2._nodesBestCopy);
00273
00274 _area = db2._area;
00275 _initArea = db2._initArea;
00276 _rowHeight = db2._rowHeight;
00277 _siteSpacing = db2._siteSpacing;
00278 }
00279 return *this;
00280 }
00281
00282
00283 struct sortFnPairFirst
00284 {
00285 bool operator()(const pair<unsigned, double> &elem1,
00286 const pair<unsigned, double> &elem2)
00287 { return(elem1.first < elem2.first); }
00288 };
00289
00290
00291 DB::DB(DB& db2, bool compressDB)
00292 {
00293 if(this != &db2)
00294 {
00295
00296
00297
00298
00299
00300 _nodes = new Nodes();
00301 _nets = new Nets();
00302 _nodesBestCopy = new Nodes();
00303
00304 *(_nodes) = *(db2.getNodes());
00305 *(_nodesBestCopy) = *(db2._nodesBestCopy);
00306
00307 _area = db2._area;
00308 _initArea = db2._initArea;
00309 _rowHeight = db2._rowHeight;
00310 _siteSpacing = db2._siteSpacing;
00311
00312 if(!compressDB)
00313 {
00314 *(_nets) = *(db2.getNets());
00315 }
00316 else
00317 {
00318
00319
00320 int netCtr=0;
00321 Nets* oldNets = db2.getNets();
00322 Nodes* oldNodes = db2.getNodes();
00323 vector<bool> seenNets(oldNets->getNumNets(), false);
00324 for(itNode term=oldNodes->terminalsBegin();
00325 term != oldNodes->terminalsEnd(); ++term)
00326 {
00327 for(itNodePin pin=term->pinsBegin(); pin!=term->pinsEnd(); ++pin)
00328 {
00329 unsigned netId = pin->netIndex;
00330 if(!seenNets[netId])
00331 {
00332 Net& origNet = oldNets->getNet(netId);
00333 Net tempEdge;
00334 tempEdge.putName(origNet.getName());
00335 tempEdge.putIndex(netCtr);
00336 tempEdge.putWeight(origNet.getWeight());
00337 for(itPin netPin = origNet.pinsBegin();
00338 netPin != origNet.pinsEnd(); ++netPin)
00339 {
00340 unsigned currNodeIdx = netPin->getNodeIndex();
00341 double poffsetX = 0, poffsetY = 0;
00342 poffsetX = netPin->getXOffset();
00343 poffsetY = netPin->getYOffset();
00344 if(!netPin->getType())
00345 {
00346 Node& oldNode = oldNodes->getNode(currNodeIdx);
00347 parquetfp::pin tempPin(oldNode.getName(), false, poffsetX,
00348 poffsetY, netCtr);
00349 tempPin.putNodeIndex(currNodeIdx);
00350 tempEdge.addNode(tempPin);
00351 }
00352 else
00353 {
00354 Node& oldTerm = oldNodes->getTerminal(currNodeIdx);
00355 parquetfp::pin tempPin(oldTerm.getName(), true, poffsetX,
00356 poffsetY, netCtr);
00357 tempPin.putNodeIndex(currNodeIdx);
00358 tempEdge.addNode(tempPin);
00359 }
00360 }
00361 seenNets[netId] = true;
00362 _nets->putNewNet(tempEdge);
00363 ++netCtr;
00364 }
00365 }
00366 }
00367
00368 for(itNode node=oldNodes->nodesBegin();
00369 node != oldNodes->nodesEnd(); ++node)
00370 {
00371 for(itNodePin pin=node->pinsBegin(); pin!=node->pinsEnd(); ++pin)
00372 {
00373 unsigned netId = pin->netIndex;
00374 Net& origNet = oldNets->getNet(netId);
00375 if(!seenNets[netId]
00376 )
00377 {
00378 Net tempEdge;
00379 bool atleast1PinOffsetNotZero=false;
00380 tempEdge.putName(origNet.getName());
00381 tempEdge.putIndex(netCtr);
00382 tempEdge.putWeight(origNet.getWeight());
00383 for(itPin netPin = origNet.pinsBegin();
00384 netPin != origNet.pinsEnd(); ++netPin)
00385 {
00386 unsigned currNodeIdx = netPin->getNodeIndex();
00387 double poffsetX = 0, poffsetY = 0;
00388 poffsetX = netPin->getXOffset();
00389 poffsetY = netPin->getYOffset();
00390 if(!(fabs(poffsetX-0) < 1e-5 && fabs(poffsetY-0) < 1e-5))
00391 atleast1PinOffsetNotZero = true;
00392
00393 if(!netPin->getType())
00394 {
00395 Node& oldNode = oldNodes->getNode(currNodeIdx);
00396 parquetfp::pin tempPin(oldNode.getName(), false, poffsetX,
00397 poffsetY, netCtr);
00398 tempPin.putNodeIndex(currNodeIdx);
00399 tempEdge.addNode(tempPin);
00400 }
00401 else
00402 {
00403 Node& oldTerm = oldNodes->getTerminal(currNodeIdx);
00404 parquetfp::pin tempPin(oldTerm.getName(), true, poffsetX,
00405 poffsetY, netCtr);
00406 tempPin.putNodeIndex(currNodeIdx);
00407 tempEdge.addNode(tempPin);
00408 }
00409 }
00410 if(atleast1PinOffsetNotZero || origNet.getDegree()>2)
00411 {
00412 seenNets[netId] = true;
00413 _nets->putNewNet(tempEdge);
00414 ++netCtr;
00415 }
00416 }
00417 }
00418 }
00419
00420
00421 vector< vector< pair<unsigned,double> > > nodeConnections(oldNodes->getNumNodes());
00422
00423 for(itNode node=oldNodes->nodesBegin();
00424 node != oldNodes->nodesEnd(); ++node)
00425 {
00426
00427 {
00428 unsigned currNodeIdx = node->getIndex();
00429
00430 for(itNodePin pin=node->pinsBegin(); pin!=node->pinsEnd(); ++pin)
00431 {
00432 unsigned netId = pin->netIndex;
00433 Net& origNet = oldNets->getNet(netId);
00434 if(!seenNets[netId] && origNet.getDegree() == 2)
00435 {
00436 for(itPin netPin = origNet.pinsBegin();
00437 netPin != origNet.pinsEnd(); ++netPin)
00438 {
00439 unsigned nextNodeIdx = netPin->getNodeIndex();
00440
00441
00442 if(nextNodeIdx > currNodeIdx)
00443 {
00444 pair<unsigned, double> elem(nextNodeIdx, origNet.getWeight());
00445 nodeConnections[currNodeIdx].push_back(elem);
00446 }
00447 }
00448 }
00449 }
00450 }
00451 }
00452
00453 for(unsigned i=0; i<nodeConnections.size(); ++i)
00454 std::sort(nodeConnections[i].begin(), nodeConnections[i].end(), sortFnPairFirst());
00455
00456 char netName [100];
00457 for(int i=0; i<int(nodeConnections.size()); ++i)
00458 {
00459 int j=0;
00460 while(j<int(nodeConnections[i].size()))
00461 {
00462 unsigned numConn=1;
00463 double sumOfWts=nodeConnections[i][j].second;
00464 if(j != (int(nodeConnections[i].size())-1))
00465 {
00466 while(j<(int(nodeConnections[i].size())-1) &&
00467 nodeConnections[i][j].first == nodeConnections[i][j+1].first)
00468 {
00469 ++numConn;
00470 ++j;
00471 sumOfWts+=nodeConnections[i][j].second;
00472 }
00473 }
00474
00475 Net tempEdge;
00476 sprintf(netName, "clusteredNet_%d",netCtr);
00477 tempEdge.putName(netName);
00478 tempEdge.putIndex(netCtr);
00479 double poffsetX = 0, poffsetY = 0;
00480 Node& node1 = _nodes->getNode(i);
00481 Node& node2 = _nodes->getNode(nodeConnections[i][j].first);
00482
00483 pin tempPin1(node1.getName(), false, poffsetX,
00484 poffsetY, netCtr);
00485 tempPin1.putNodeIndex(i);
00486 tempEdge.addNode(tempPin1);
00487
00488 pin tempPin2(node2.getName(), false, poffsetX,
00489 poffsetY, netCtr);
00490 tempPin2.putNodeIndex(nodeConnections[i][j].first);
00491 tempEdge.addNode(tempPin2);
00492
00493
00494 tempEdge.putWeight(sumOfWts);
00495 _nets->putNewNet(tempEdge);
00496
00497 ++netCtr;
00498 ++j;
00499 }
00500 }
00501
00502 _nodes->updatePinsInfo(*_nets);
00503 _nodes->initNodesFastPOAccess(*_nets, false);
00504
00505
00506
00507
00508
00509
00510 }
00511 }
00512 }
00513
00514
00515 void DB::clean(void)
00516 {
00517 if(_nodes) _nodes->clean();
00518 if(_nets) _nets->clean();
00519 if(_nodesBestCopy) _nodesBestCopy->clean();
00520 }
00521
00522 Nodes* DB::getNodes(void)
00523 { return _nodes; }
00524
00525 Nets* DB::getNets(void)
00526 { return _nets; }
00527
00528 unsigned DB::getNumNodes(void) const
00529 {
00530 return _nodes->getNumNodes();
00531 }
00532
00533 vector<double> DB::getNodeWidths(void) const
00534 {
00535 return _nodes->getNodeWidths();
00536 }
00537
00538 vector<double> DB::getNodeHeights(void) const
00539 {
00540 return _nodes->getNodeHeights();
00541 }
00542
00543 vector<double> DB::getXLocs(void) const
00544 {
00545 return _nodes->getXLocs();
00546 }
00547
00548 vector<double> DB::getYLocs(void) const
00549 {
00550 return _nodes->getYLocs();
00551 }
00552
00553 Point DB::getBottomLeftCorner() const
00554 {
00555 vector<double> nodesXLocs(_nodes->getXLocs());
00556 vector<double> nodesYLocs(_nodes->getYLocs());
00557
00558 vector<double>::iterator xMin = min_element(nodesXLocs.begin(),
00559 nodesXLocs.end());
00560 vector<double>::iterator yMin = min_element(nodesYLocs.begin(),
00561 nodesYLocs.end());
00562
00563 Point bottomLeft;
00564 bottomLeft.x = *xMin;
00565 bottomLeft.y = *yMin;
00566 return bottomLeft;
00567 }
00568
00569 Point DB::getTopRightCorner() const
00570 {
00571 vector<double> nodesXLocs(_nodes->getXLocs());
00572 vector<double> nodesYLocs(_nodes->getYLocs());
00573 for (unsigned int i = 0; i < _nodes->getNumNodes(); i++)
00574 {
00575 nodesXLocs[i] += _nodes->getNodeWidth(i);
00576 nodesYLocs[i] += _nodes->getNodeHeight(i);
00577 }
00578
00579 vector<double>::iterator xMax = max_element(nodesXLocs.begin(),
00580 nodesXLocs.end());
00581 vector<double>::iterator yMax = max_element(nodesYLocs.begin(),
00582 nodesYLocs.end());
00583
00584 Point topRight;
00585 topRight.x = *xMax;
00586 topRight.y = *yMax;
00587 return topRight;
00588 }
00589
00590 void DB::packToCorner(vector< vector<double> >& xlocsAt,
00591 vector< vector<double> >& ylocsAt) const
00592 {
00593 const Point topRightCorner(getTopRightCorner());
00594 const Point bottomLeftCorner(getBottomLeftCorner());
00595
00596 const vector<double> xlocs(getXLocs());
00597 const vector<double> ylocs(getYLocs());
00598 const vector<double> widths(getNodeWidths());
00599 const vector<double> heights(getNodeHeights());
00600
00601
00602 vector<double> xRightSlacks(getNumNodes());
00603 vector<double> xLeftSlacks(getNumNodes());
00604
00605 vector<double> yTopSlacks(getNumNodes());
00606 vector<double> yBottomSlacks(getNumNodes());
00607 for (unsigned i = 0; i < getNumNodes(); i++)
00608 {
00609 xRightSlacks[i] = topRightCorner.x - xlocs[i] - widths[i];
00610 xLeftSlacks[i] = xlocs[i] - bottomLeftCorner.x;
00611
00612 yTopSlacks[i] = topRightCorner.y - ylocs[i] - heights[i];
00613 yBottomSlacks[i] = ylocs[i] - bottomLeftCorner.y;
00614
00615 for (unsigned j = 0; j < getNumNodes(); j++)
00616 {
00617 if (i != j)
00618 {
00619
00620 if ((xlocs[i] < xlocs[j] + widths[j])
00621 && (xlocs[j] < xlocs[i] + widths[i]))
00622 {
00623 if (ylocs[j] > ylocs[i])
00624 {
00625
00626 yTopSlacks[i] = min(yTopSlacks[i],
00627 ylocs[j] - (ylocs[i]+heights[i]));
00628 }
00629 else
00630 {
00631
00632 yBottomSlacks[i] = min(yBottomSlacks[i],
00633 ylocs[i] - (ylocs[j]+heights[j]));
00634 }
00635 }
00636
00637
00638 if ((ylocs[i] < ylocs[j] + heights[j])
00639 && (ylocs[j] < ylocs[i] + heights[i]))
00640 {
00641 if (xlocs[j] > xlocs[i])
00642 {
00643
00644 xRightSlacks[i] = min(xRightSlacks[i],
00645 xlocs[j] - (xlocs[i]+widths[i]));
00646 }
00647 else
00648 {
00649
00650 xLeftSlacks[i] = min(xLeftSlacks[i],
00651 xlocs[i] - (xlocs[j]+widths[j]));
00652 }
00653 }
00654 }
00655 }
00656 }
00657
00658
00659 for (unsigned i = 0; i < getNumNodes(); i++)
00660 {
00661 xlocsAt[BOTTOM_LEFT][i] = xlocs[i] - xLeftSlacks[i];
00662 ylocsAt[BOTTOM_LEFT][i] = ylocs[i] - yBottomSlacks[i];
00663
00664 xlocsAt[BOTTOM_RIGHT][i] = xlocs[i] + xRightSlacks[i];
00665 ylocsAt[BOTTOM_RIGHT][i] = ylocs[i] - yBottomSlacks[i];
00666
00667 xlocsAt[TOP_LEFT][i] = xlocs[i] - xLeftSlacks[i];
00668 ylocsAt[TOP_LEFT][i] = ylocs[i] + yTopSlacks[i];
00669
00670 xlocsAt[TOP_RIGHT][i] = xlocs[i] + xRightSlacks[i];
00671 ylocsAt[TOP_RIGHT][i] = ylocs[i] + yTopSlacks[i];
00672 }
00673 }
00674
00675 void DB::cornerOptimizeDesign()
00676 {
00677 const vector<double> origXLocs(getXLocs());
00678 const vector<double> origYLocs(getYLocs());
00679
00680 vector< vector<double> > xlocsAt(NUM_CORNERS,
00681 vector<double>(getNumNodes()));
00682 vector< vector<double> > ylocsAt(NUM_CORNERS,
00683 vector<double>(getNumNodes()));
00684 packToCorner(xlocsAt, ylocsAt);
00685
00686 static int ORIGINAL = -1;
00687 int minCorner = ORIGINAL;
00688 double minHPWL = evalHPWL();
00689 cout << "Original HPWL: " << minHPWL << endl;
00690
00691 for (unsigned i = 0; i < NUM_CORNERS; i++)
00692 {
00693 updatePlacement(xlocsAt[i], ylocsAt[i]);
00694
00695 double currHPWL = evalHPWL();
00696 if (currHPWL < minHPWL)
00697 {
00698 minHPWL = currHPWL;
00699 minCorner = i;
00700 }
00701 cout << toString(Corner(i)) << " HPWL: " << currHPWL << endl;
00702 }
00703 cout << "minimum HPWL: " << minHPWL;
00704 if (minCorner == ORIGINAL)
00705 cout << " in the original position." << endl;
00706 else
00707 cout << " at " << toString(Corner(minCorner)) << endl;
00708
00709 cout << "packing design towards "
00710 << ((minCorner==ORIGINAL)
00711 ? string("the original position")
00712 : toString(Corner(minCorner))) << endl;
00713 if (minCorner == ORIGINAL)
00714 updatePlacement(origXLocs, origYLocs);
00715 else
00716 updatePlacement(xlocsAt[minCorner], ylocsAt[minCorner]);
00717 cout << "final HPWL: " << evalHPWL() << endl;
00718 }
00719
00720 double DB::getNodesArea(void) const
00721 {
00722 if(_initArea)
00723 return _area;
00724 else
00725 {
00726 _area=_nodes->getNodesArea();
00727 _initArea = 1;
00728 return _area;
00729 }
00730 }
00731
00732 double DB::getRowHeight(void) const
00733 {
00734 return _rowHeight;
00735 }
00736
00737 double DB::getSiteSpacing(void) const
00738 {
00739 return _siteSpacing;
00740 }
00741
00742 void DB::setRowHeight(double rowHeight)
00743 {
00744 _rowHeight = rowHeight;
00745 }
00746
00747 void DB::setSiteSpacing(double siteSpacing)
00748 {
00749 _siteSpacing = siteSpacing;
00750 }
00751
00752 double DB::getAvgHeight(void) const
00753 {
00754 itNode node;
00755 double avgHeight = 0;
00756 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
00757 avgHeight += node->getHeight();
00758 avgHeight /= getNumNodes();
00759 return(avgHeight);
00760 }
00761
00762 void DB::updatePlacement(const vector<double>& xloc,
00763 const vector<double>& yloc)
00764 {
00765 unsigned int numNodes = _nodes->getNumNodes();
00766 unsigned int size = min(unsigned(xloc.size()), numNodes);
00767 abkwarn(size >= numNodes, "Too few locations specified.");
00768
00769 for(unsigned i = 0; i < size; i++)
00770 {
00771 _nodes->getNode(i).putX(xloc[i]);
00772 _nodes->getNode(i).putY(yloc[i]);
00773 }
00774 }
00775
00776 void DB::initPlacement(const Point& loc)
00777 {
00778 itNode node;
00779 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
00780 {
00781 node->putX(loc.x);
00782 node->putY(loc.y);
00783 }
00784 }
00785
00786 void DB::updateSlacks(const vector<double>& xSlack,
00787 const vector<double>& ySlack)
00788 {
00789 for(unsigned i=0; i<xSlack.size(); ++i)
00790 {
00791 _nodes->getNode(i).putslackX(xSlack[i]);
00792 _nodes->getNode(i).putslackY(ySlack[i]);
00793 }
00794 }
00795
00796 double DB::evalHPWL(bool useWts) const
00797 {
00798 itNet net;
00799 itPin pin;
00800 unsigned nodeIndex;
00801
00802 Point tempPoint;
00803 double HPWL=0;
00804 double width;
00805 double height;
00806 double absOffsetX;
00807 double absOffsetY;
00808 double xloc;
00809 double yloc;
00810 Point llc;
00811 Point trc;
00812
00813 for(net = _nets->netsBegin(); net != _nets->netsEnd(); ++net)
00814 {
00815 llc.x=llc.y=1e306;
00816 trc.x=trc.y=-1e306;
00817 unsigned netDegree = net->getDegree();
00818 if(netDegree <= 1)
00819 continue;
00820 else if(netDegree == 2)
00821 {
00822 itPin pin1 = net->pinsBegin();
00823 itPin pin2 = pin1+1;
00824
00825 unsigned nodeIndex1 = pin1->getNodeIndex();
00826 unsigned nodeIndex2 = pin2->getNodeIndex();
00827
00828 if(!pin1->getType())
00829 {
00830 Node& node = _nodes->getNode(nodeIndex1);
00831 width = node.getWidth();
00832 height = node.getHeight();
00833 xloc = node.getX();
00834 yloc = node.getY();
00835
00836 if(!node.allPinsAtCenter)
00837 {
00838 absOffsetX = 0.5*width + (pin1->getXOffset()*width);
00839 absOffsetY = 0.5*height + (pin1->getYOffset()*height);
00840 llc.x = xloc + absOffsetX;
00841 llc.y = yloc + absOffsetY;
00842 }
00843 else
00844 {
00845 llc.x = xloc + 0.5*width;
00846 llc.y = yloc + 0.5*height;
00847 }
00848 }
00849 else
00850 {
00851 Node& node = _nodes->getTerminal(nodeIndex1);
00852 width = node.getWidth();
00853 height = node.getHeight();
00854 xloc = node.getX();
00855 yloc = node.getY();
00856
00857 absOffsetX = 0.5*width + (pin1->getXOffset()*width);
00858 absOffsetY = 0.5*height + (pin1->getYOffset()*height);
00859 llc.x = xloc + absOffsetX;
00860 llc.y = yloc + absOffsetY;
00861 }
00862
00863 if(!pin2->getType())
00864 {
00865 Node& node = _nodes->getNode(nodeIndex2);
00866 width = node.getWidth();
00867 height = node.getHeight();
00868 xloc = node.getX();
00869 yloc = node.getY();
00870
00871 if(!node.allPinsAtCenter)
00872 {
00873 absOffsetX = 0.5*width + (pin2->getXOffset()*width);
00874 absOffsetY = 0.5*height + (pin2->getYOffset()*height);
00875 trc.x = xloc + absOffsetX;
00876 trc.y = yloc + absOffsetY;
00877 }
00878 else
00879 {
00880 trc.x = xloc + 0.5*width;
00881 trc.y = yloc + 0.5*height;
00882 }
00883 }
00884 else
00885 {
00886 Node& node = _nodes->getTerminal(nodeIndex2);
00887 width = node.getWidth();
00888 height = node.getHeight();
00889 xloc = node.getX();
00890 yloc = node.getY();
00891
00892 absOffsetX = 0.5*width + (pin2->getXOffset()*width);
00893 absOffsetY = 0.5*height + (pin2->getYOffset()*height);
00894 trc.x = xloc + absOffsetX;
00895 trc.y = yloc + absOffsetY;
00896 }
00897
00898 double swapVar;
00899 if(trc.x < llc.x )
00900 {
00901 swapVar = llc.x;
00902 llc.x = trc.x;
00903 trc.x = swapVar;
00904 }
00905 if(trc.y < llc.y )
00906 {
00907 swapVar = llc.y;
00908 llc.y = trc.y;
00909 trc.y = swapVar;
00910 }
00911 }
00912 else
00913 {
00914 for(pin = net->pinsBegin(); pin != net->pinsEnd(); ++pin)
00915 {
00916 nodeIndex = pin->getNodeIndex();
00917 if(!pin->getType())
00918 {
00919 Node& node = _nodes->getNode(nodeIndex);
00920 width = node.getWidth();
00921 height = node.getHeight();
00922 xloc = node.getX();
00923 yloc = node.getY();
00924
00925 if(!node.allPinsAtCenter)
00926 {
00927 absOffsetX = 0.5*width + (pin->getXOffset()*width);
00928 absOffsetY = 0.5*height + (pin->getYOffset()*height);
00929 tempPoint.x = xloc + absOffsetX;
00930 tempPoint.y = yloc + absOffsetY;
00931 }
00932 else
00933 {
00934 tempPoint.x = xloc + 0.5*width;
00935 tempPoint.y = yloc + 0.5*height;
00936 }
00937 }
00938 else
00939 {
00940 Node& node = _nodes->getTerminal(nodeIndex);
00941 width = node.getWidth();
00942 height = node.getHeight();
00943 xloc = node.getX();
00944 yloc = node.getY();
00945
00946 absOffsetX = 0.5*width + (pin->getXOffset()*width);
00947 absOffsetY = 0.5*height + (pin->getYOffset()*height);
00948 tempPoint.x = xloc + absOffsetX;
00949 tempPoint.y = yloc + absOffsetY;
00950 }
00951
00952
00953 if(tempPoint.x < llc.x)
00954 llc.x = tempPoint.x;
00955 if(tempPoint.x > trc.x)
00956 trc.x = tempPoint.x;
00957 if(tempPoint.y < llc.y)
00958 llc.y = tempPoint.y;
00959 if(tempPoint.y > trc.y)
00960 trc.y = tempPoint.y;
00961 }
00962 }
00963
00964
00965 if(useWts)
00966 HPWL += net->getWeight()*(trc.x-llc.x + trc.y-llc.y);
00967 else
00968 HPWL += (trc.x-llc.x + trc.y-llc.y);
00969
00970
00971
00972
00973 }
00974 return HPWL;
00975 }
00976
00977 double DB::evalHPWL(double xSize, double ySize, bool useWts) const
00978 {
00979 itNet net;
00980 itPin pin;
00981 unsigned nodeIndex;
00982 BBox netBBox;
00983 Point tempPoint;
00984 double HPWL=0;
00985 double width;
00986 double height;
00987 double absOffsetX;
00988 double absOffsetY;
00989 double xloc;
00990 double yloc;
00991
00992 for(net = _nets->netsBegin(); net != _nets->netsEnd(); ++net)
00993 {
00994 for(pin = net->pinsBegin(); pin != net->pinsEnd(); ++pin)
00995 {
00996 nodeIndex = pin->getNodeIndex();
00997 if(!pin->getType())
00998 {
00999 Node& node = _nodes->getNode(nodeIndex);
01000 width = node.getWidth();
01001 height = node.getHeight();
01002 xloc = node.getX();
01003 yloc = node.getY();
01004 }
01005 else
01006 {
01007 Node& node = _nodes->getTerminal(nodeIndex);
01008 width = node.getWidth();
01009 height = node.getHeight();
01010 xloc = node.getX();
01011 yloc = node.getY();
01012 if(xloc > xSize)
01013 xloc = xSize;
01014 if(yloc > ySize)
01015 yloc = ySize;
01016 }
01017 absOffsetX = 0.5*width + (pin->getXOffset()*width);
01018 absOffsetY = 0.5*height + (pin->getYOffset()*height);
01019
01020 tempPoint.x = xloc + absOffsetX;
01021 tempPoint.y = yloc + absOffsetY;
01022 netBBox.put(tempPoint);
01023 }
01024 if(netBBox.isValid())
01025 {
01026
01027 if(useWts)
01028 HPWL += net->getWeight()*netBBox.getHPWL();
01029 else
01030 HPWL += netBBox.getHPWL();
01031 }
01032 netBBox.clear();
01033 }
01034 return HPWL;
01035 }
01036
01037 double DB::evalArea(void) const
01038 {
01039 BBox area;
01040 itNode node;
01041 Point P;
01042 for(node = const_cast<DB*>(this)->getNodes()->nodesBegin();
01043 node != const_cast<DB*>(this)->getNodes()->nodesEnd(); ++node)
01044 {
01045 P.x = node->getX();
01046 P.y = node->getY();
01047 area.put(P);
01048 P.x = node->getX()+node->getWidth();
01049 P.y = node->getY()+node->getHeight();
01050 area.put(P);
01051 }
01052 return(area.getXSize()*area.getYSize());
01053 }
01054
01055 double DB::getXSize(void) const
01056 {
01057 BBox xSize;
01058 itNode node;
01059 Point P;
01060 for(node = const_cast<DB*>(this)->getNodes()->nodesBegin();
01061 node != const_cast<DB*>(this)->getNodes()->nodesEnd(); ++node)
01062 {
01063 P.x = node->getX();
01064 P.y = 0;
01065 xSize.put(P);
01066 P.x = node->getX()+node->getWidth();
01067 P.y = 0;
01068 xSize.put(P);
01069 }
01070 return(xSize.getXSize());
01071 }
01072
01073 double DB::getYSize(void) const
01074 {
01075 BBox ySize;
01076 itNode node;
01077 Point P;
01078 for(node = const_cast<DB*>(this)->getNodes()->nodesBegin();
01079 node != const_cast<DB*>(this)->getNodes()->nodesEnd(); ++node)
01080 {
01081 P.y = node->getY();
01082 P.x = 0;
01083 ySize.put(P);
01084 P.y = node->getY()+node->getHeight();
01085 P.x = 0;
01086 ySize.put(P);
01087 }
01088 return(ySize.getYSize());
01089 }
01090
01091 void DB::plot(char* fileName, double area, double whitespace,
01092 double aspectRatio, double time, double HPWL, bool plotSlacks,
01093 bool plotNets, bool plotNames) const
01094 {
01095 double x=0;
01096 double y=0;
01097 double w=0;
01098 double h=0;
01099 double nodesArea = getNodesArea();
01100 double starDelta = sqrt(nodesArea) / 200;
01101 itNode it;
01102
01103 cout<<"OutPut Plot file is "<<fileName<<endl;
01104 ofstream gpOut(fileName);
01105 if (!gpOut.good())
01106 {
01107 cout << "Warning: output file " << fileName
01108 << " can't be opened" << endl;
01109 }
01110
01111 gpOut<<"#Use this file as a script for gnuplot"<<endl;
01112 gpOut<<"#(See http://www.gnuplot.info/ for details)"<<endl;
01113 gpOut << "set nokey"<<endl;
01114
01115 gpOut << "set size ratio -1" << endl;
01116 gpOut << "set title ' " << fileName
01117 << " area= " << area << " WS= " << whitespace << "%" << " AR= " << aspectRatio
01118 << " time= " << time << "s" << " HPWL= " << HPWL << endl << endl;
01119
01120 gpOut<<"# Uncomment these two lines starting with \"set\""<<endl ;
01121 gpOut<<"# to save an EPS file for inclusion into a latex document"<<endl;
01122 gpOut << "# set terminal postscript eps color solid 10"<<endl;
01123 gpOut << "# set output \"out.eps\""<<endl<<endl<<endl;
01124
01125 gpOut<<"# Uncomment these two lines starting with \"set\""<<endl ;
01126 gpOut<<"# to save a PS file for printing"<<endl;
01127 gpOut<<"# set terminal postscript portrait color solid 8"<<endl;
01128 gpOut << "# set output \"out.ps\""<<endl<<endl<<endl;
01129
01130 if(plotNames)
01131 {
01132 for(it=_nodes->nodesBegin();it!=_nodes->nodesEnd();++it)
01133 {
01134 gpOut<<"set label \""<<it->getName()<<"("<<(it-_nodes->nodesBegin())<<"),vdd=" << it->getVoltage()
01135 <<"\" at "<<it->getX()+it->getWidth()/4<<" , "<<it->getY()+it->getHeight()/4<<endl;
01136 }
01137
01138
01139 if (plotNets)
01140 {
01141 for(it=_nodes->terminalsBegin();it!=_nodes->terminalsEnd();++it)
01142 {
01143 gpOut<<"set label \""<<it->getName()<<"\" at "<<it->getX()+it->getWidth()/4<<" , "<<it->getY()+it->getHeight()/4<<endl;
01144 }
01145 }
01146 }
01147
01148
01149 if(plotSlacks)
01150 {
01151 for(it=_nodes->nodesBegin();it!=_nodes->nodesEnd();++it)
01152 {
01153 double xSlack = it->getslackX();
01154 double ySlack = it->getslackY();
01155 if(xSlack < 1e-5)
01156 xSlack = 0;
01157 if(ySlack < 1e-5)
01158 ySlack = 0;
01159
01160 gpOut.precision(4);
01161 gpOut<<"set label \"x "<<xSlack<<"\" at "<<it->getX()+it->getWidth()/6<<" , "<<it->getY()+it->getHeight()/2<<endl;
01162 gpOut<<"set label \"y "<<ySlack<<"\" at "<<it->getX()+it->getWidth()/6<<" , "<<it->getY()+it->getHeight()*3/4<<endl;
01163 }
01164 }
01165
01166 gpOut.precision(6);
01167 gpOut << "plot '-' w l";
01168 if (plotNets)
01169 gpOut << ", '-' w l 3";
01170 gpOut << endl;
01171
01172 for(it=_nodes->nodesBegin();it!=_nodes->nodesEnd();++it)
01173 {
01174 x=it->getX();
01175 y=it->getY();
01176 w=it->getWidth();
01177 h=it->getHeight();
01178
01179 gpOut<<x<<" "<<y<<endl;
01180 gpOut<<x+w<<" "<<y<<endl;
01181 gpOut<<x+w<<" "<<y+h<<endl;
01182 gpOut<<x<<" "<<y+h<<endl;
01183 gpOut<<x<<" "<<y<<endl<<endl;
01184 }
01185 gpOut << "EOF"<<endl;
01186
01187 if(plotNets)
01188 {
01189 double width;
01190 double height;
01191 double absOffsetX;
01192 double absOffsetY;
01193
01194 itNet net;
01195 itPin netPin;
01196 for(net = _nets->netsBegin(); net != _nets->netsEnd(); ++net)
01197 {
01198 Point starPoint;
01199 starPoint.x = 0;
01200 starPoint.y = 0;
01201 unsigned netDegree = 0;
01202 for(netPin = net->pinsBegin(); netPin != net->pinsEnd(); netPin++)
01203 {
01204 Node node;
01205 if(!netPin->getType())
01206 node = _nodes->getNode(netPin->getNodeIndex());
01207 else
01208 node = _nodes->getTerminal(netPin->getNodeIndex());
01209
01210 width = node.getWidth();
01211 height = node.getHeight();
01212 absOffsetX = width/2 + (netPin->getXOffset()*width);
01213 absOffsetY = height/2 + (netPin->getYOffset()*height);
01214 starPoint.x += node.getX() + absOffsetX;
01215 starPoint.y += node.getY() + absOffsetY;
01216 ++netDegree;
01217 }
01218
01219 if(netDegree != 0)
01220 {
01221 starPoint.x /= netDegree;
01222 starPoint.y /= netDegree;
01223 for(netPin = net->pinsBegin(); netPin != net->pinsEnd(); netPin++)
01224 {
01225 Node node;
01226 if(!netPin->getType())
01227 node = _nodes->getNode(netPin->getNodeIndex());
01228 else
01229 node = _nodes->getTerminal(netPin->getNodeIndex());
01230 width = node.getWidth();
01231 height = node.getHeight();
01232 absOffsetX = width/2 + (netPin->getXOffset()*width);
01233 absOffsetY = height/2 + (netPin->getYOffset()*height);
01234 gpOut<<starPoint.x<<" "<<starPoint.y<<endl;
01235 gpOut<<node.getX()+absOffsetX<<" "<<node.getY()+absOffsetY<<endl;
01236 gpOut<<starPoint.x<<" "<<starPoint.y<<endl<<endl;
01237
01238 gpOut<<starPoint.x-starDelta<<" "<<starPoint.y<<endl;
01239 gpOut<<starPoint.x<<" "<<starPoint.y+starDelta<<endl;
01240 gpOut<<starPoint.x+starDelta<<" "<<starPoint.y<<endl;
01241 gpOut<<starPoint.x<<" "<<starPoint.y-starDelta<<endl;
01242 gpOut<<starPoint.x-starDelta<<" "<<starPoint.y<<endl<<endl;
01243
01244 }
01245 }
01246 else
01247 {
01248 cout << "Warning: net with zero degree detected." << endl;
01249 }
01250 }
01251 gpOut << "EOF"<<endl<<endl;
01252 }
01253 gpOut << "pause -1 'Press any key' "<<endl;
01254 gpOut.close();
01255 }
01256
01257
01258 void DB::saveCapo(char* baseFileName,
01259 double reqdAR, double reqdWS) const
01260 {
01261 cout<<"Saving in Capo Format "<<baseFileName<<endl;
01262 _nodes->saveCapoNodes(baseFileName);
01263 _nodes->saveCapoPl(baseFileName);
01264 saveCapoNets(baseFileName);
01265 _nodes->saveCapoScl(baseFileName, reqdAR, reqdWS);
01266
01267
01268 char fileName[1024];
01269 strcpy(fileName, baseFileName);
01270 strcat(fileName, ".aux");
01271 ofstream aux(fileName);
01272 aux<<"RowBasedPlacement : "<<baseFileName<<".nodes "<<baseFileName<<".nets "<<
01273 baseFileName<<".scl "<<baseFileName<<".pl "<<endl;
01274 aux.close();
01275 }
01276
01277 void DB::save(char* baseFileName) const
01278 {
01279 cout<<"Saving in Floorplan Format "<<baseFileName<<endl;
01280 _nodes->saveNodes(baseFileName);
01281 _nodes->savePl(baseFileName);
01282 saveNets(baseFileName);
01283 saveWts(baseFileName);
01284 }
01285
01286 void DB::saveCapoNets(char* baseFileName) const
01287 {
01288 Nets* nets;
01289 nets = const_cast<DB*>(this)->getNets();
01290 double absOffsetX;
01291 double absOffsetY;
01292 double width;
01293 double height;
01294 double temp;
01295 int nodeIndex;
01296
01297 char fileName[1024];
01298 strcpy(fileName, baseFileName);
01299 strcat(fileName, ".nets");
01300 ofstream file(fileName);
01301
01302 file<<"UCLA nets 1.0"<<endl<<endl<<endl;
01303 file<<"NumPins : "<<nets->getNumPins()<<endl<<endl;
01304
01305 itNet net;
01306 itPin pin;
01307 for(net = nets->netsBegin(); net != nets->netsEnd(); ++net)
01308 {
01309 file<<"NetDegree : "<<net->_pins.size()<<"\t"<<net->getName()<<endl;
01310 for(pin = net->pinsBegin(); pin != net->pinsEnd(); ++pin)
01311 {
01312 nodeIndex = pin->getNodeIndex();
01313 if(!pin->getType())
01314 {
01315 Node& node = _nodes->getNode(nodeIndex);
01316 width = node.getWidth();
01317 height = node.getHeight();
01318 }
01319 else
01320 {
01321 Node& node = _nodes->getTerminal(nodeIndex);
01322 width = node.getWidth();
01323 height = node.getHeight();
01324 }
01325 if(int(pin->getOrient())%2 == 1)
01326 {
01327 temp = width;
01328 width = height;
01329 height = temp;
01330 }
01331 absOffsetX = (pin->getOrigXOffset()*width);
01332 absOffsetY = (pin->getOrigYOffset()*height);
01333
01334 file<<"\t"<<pin->getName()<<" B : \t"<<absOffsetX<<"\t "<<absOffsetY<<endl;
01335 }
01336 }
01337 file.close();
01338 }
01339
01340 void DB::saveNets(char* baseFileName) const
01341 {
01342 Nets* nets;
01343 nets = const_cast<DB*>(this)->getNets();
01344
01345 char fileName[1024];
01346 strcpy(fileName, baseFileName);
01347 strcat(fileName, ".nets");
01348 ofstream file(fileName);
01349
01350 file<<"UCLA nets 1.0"<<endl<<endl<<endl;
01351 file<<"NumNets : "<<nets->getNumNets()<<endl;
01352 file<<"NumPins : "<<nets->getNumPins()<<endl<<endl;
01353
01354 itNet net;
01355 itPin pin;
01356 for(net = nets->netsBegin(); net != nets->netsEnd(); ++net)
01357 {
01358 file<<"NetDegree : "<<net->_pins.size()<<" "<<net->getName()<<endl;
01359 for(pin = net->pinsBegin(); pin != net->pinsEnd(); ++pin)
01360 {
01361 file<<pin->getName()<<" B : \t%"<<pin->getOrigXOffset()*100<<
01362 "\t %"<<pin->getOrigYOffset()*100<<endl;
01363 }
01364 }
01365 file.close();
01366 }
01367
01368 void DB::saveWts(char* baseFileName) const
01369 {
01370 Nets* nets;
01371 nets = const_cast<DB*>(this)->getNets();
01372
01373 char fileName[1024];
01374 strcpy(fileName, baseFileName);
01375 strcat(fileName, ".wts");
01376 ofstream file(fileName);
01377
01378 file<<"UCLA wts 1.0"<<endl<<endl<<endl;
01379
01380 itNet net;
01381
01382 for(net = nets->netsBegin(); net != nets->netsEnd(); ++net)
01383 {
01384 file<<net->getName()<<"\t"<<net->getWeight()<<endl;
01385 }
01386 file.close();
01387 }
01388
01389 void DB::shiftDesign(Point& offset)
01390 {
01391 itNode node;
01392 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01393 {
01394 node->putX(node->getX() + offset.x);
01395 node->putY(node->getY() + offset.y);
01396 }
01397 }
01398
01399 void DB::expandDesign(double maxWidth, double maxHeight)
01400 {
01401 double currWidth = getXSize();
01402 double currHeight = getYSize();
01403 if(currWidth > maxWidth && currHeight > maxHeight)
01404 return;
01405
01406 double xExpRatio=1;
01407 double yExpRatio=1;
01408
01409 if(currWidth < maxWidth)
01410 xExpRatio = maxWidth/currWidth;
01411 if(currHeight < maxHeight)
01412 yExpRatio = maxHeight/currHeight;
01413
01414 itNode node;
01415 double newLoc;
01416 for(node = getNodes()->nodesBegin(); node != getNodes()->nodesEnd(); ++node)
01417 {
01418 newLoc = node->getX()*xExpRatio;
01419 node->putX(newLoc);
01420 newLoc = node->getY()*yExpRatio;
01421 node->putY(newLoc);
01422 }
01423 }
01424
01425
01426 void DB::saveInBestCopy(void)
01427 {
01428 successAR = 1;
01429 itNode node;
01430 itNode nodeBest;
01431 nodeBest = _nodesBestCopy->nodesBegin();
01432 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); node++)
01433 {
01434 nodeBest->putX(node->getX());
01435 nodeBest->putY(node->getY());
01436 nodeBest->putWidth(node->getWidth());
01437 nodeBest->putHeight(node->getHeight());
01438 nodeBest->putOrient(node->getOrient());
01439 nodeBest++;
01440 }
01441 }
01442
01443 void DB::saveBestCopyPl(char* fileName) const
01444 {
01445 _nodesBestCopy->savePl(fileName);
01446 }
01447
01448 void DB::markTallNodesAsMacros(double maxHeight)
01449 {
01450 itNode node;
01451 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01452 {
01453 if(node->getHeight() > maxHeight)
01454 node->updateMacroInfo(true);
01455 }
01456 }
01457
01458 void DB::reduceCoreCellsArea(double layoutArea, double maxWS)
01459 {
01460 double currNodesArea = getNodesArea();
01461 double currWS = (layoutArea - currNodesArea)/currNodesArea;
01462
01463 if(currWS > maxWS)
01464 return;
01465
01466 double macroArea = 0;
01467 itNode node;
01468 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01469 {
01470 if(node->isMacro())
01471 macroArea += node->getHeight()*node->getWidth();
01472 }
01473
01474 double newCtoOldCRatio = ((layoutArea - (1+maxWS)*macroArea)*(1+currWS))/
01475 ((layoutArea - (1+currWS)*macroArea)*(1+maxWS));
01476
01477 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01478 {
01479 if(!node->isMacro())
01480 {
01481 double nodeWidth = node->getWidth();
01482 double newNodeWidth = nodeWidth*newCtoOldCRatio;
01483 node->putWidth(newNodeWidth);
01484 }
01485 }
01486
01487 _initArea = false;
01488 double newNodesArea = getNodesArea();
01489
01490 currWS = (layoutArea - newNodesArea)/newNodesArea;
01491 }
01492
01493 double DB::getXMaxWMacroOnly(void)
01494 {
01495
01496 double xMax = -1e20;
01497 itNode node;
01498 double value;
01499 bool valid=false;
01500 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01501 {
01502 if(node->isMacro())
01503 {
01504 valid = true;
01505
01506
01507
01508
01509 value = node->getX()+node->getWidth();
01510 if(value > xMax)
01511 xMax = value;
01512 }
01513 }
01514 if(valid)
01515 return (xMax);
01516 else
01517 return 0;
01518 }
01519
01520 double DB::getXSizeWMacroOnly(void)
01521 {
01522
01523 BBox xSize;
01524 itNode node;
01525 Point P;
01526 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01527 {
01528 if(node->isMacro())
01529 {
01530 P.x = node->getX();
01531 P.y = 0;
01532 xSize.put(P);
01533 P.x = node->getX()+node->getWidth();
01534 P.y = 0;
01535 xSize.put(P);
01536 }
01537 }
01538 if(xSize.isValid())
01539 return (xSize.getXSize());
01540 else
01541 return 0;
01542 }
01543
01544 double DB::getYMaxWMacroOnly(void)
01545 {
01546
01547 double yMax = -1e20;
01548 itNode node;
01549 double value;
01550 bool valid=false;
01551 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01552 {
01553 if(node->isMacro())
01554 {
01555 valid = true;
01556
01557
01558
01559
01560 value = node->getY()+node->getHeight();
01561 if(value > yMax)
01562 yMax = value;
01563 }
01564 }
01565 if(valid)
01566 return (yMax);
01567 else
01568 return 0;
01569 }
01570
01571 double DB::getYSizeWMacroOnly(void)
01572 {
01573 BBox ySize;
01574 itNode node;
01575 Point P;
01576 for(node = _nodes->nodesBegin(); node != _nodes->nodesEnd(); ++node)
01577 {
01578 if(node->isMacro())
01579 {
01580 P.y = node->getY();
01581 P.x = 0;
01582 ySize.put(P);
01583 P.y = node->getY()+node->getHeight();
01584 P.x = 0;
01585 ySize.put(P);
01586 }
01587 }
01588 if(ySize.isValid())
01589 return (ySize.getYSize());
01590 else
01591 return 0;
01592 }
01593
01594
01595 void DB::shiftOptimizeDesign(double outlineWidth,
01596 double outlineHeight)
01597 {
01598 if (_nodes->getNumTerminals() == 0)
01599 return;
01600
01601
01602 Point outlineBottomLeft(getBottomLeftCorner());
01603 Point outlineTopRight;
01604 outlineTopRight.x = outlineBottomLeft.x + outlineWidth;
01605 outlineTopRight.y = outlineBottomLeft.y + outlineHeight;
01606
01607 shiftOptimizeDesign(outlineBottomLeft, outlineTopRight);
01608 }
01609
01610 void DB::shiftOptimizeDesign(const Point& outlineBottomLeft,
01611 const Point& outlineTopRight)
01612 {
01613 double designWidth = getXSize();
01614 double designHeight = getYSize();
01615
01616 double outlineWidth = outlineTopRight.x - outlineBottomLeft.x;
01617 double outlineHeight = outlineTopRight.y - outlineBottomLeft.y;
01618
01619 if (designWidth < outlineWidth &&
01620 designHeight < outlineHeight)
01621 {
01622 Point currBottomLeft(getBottomLeftCorner());
01623 Point minOffset;
01624 minOffset.x = outlineBottomLeft.x - currBottomLeft.x;
01625 minOffset.y = outlineBottomLeft.y - currBottomLeft.y;
01626
01627 Point currTopRight(getTopRightCorner());
01628 Point maxOffset;
01629 maxOffset.x = outlineTopRight.x - currTopRight.x;
01630 maxOffset.y = outlineTopRight.y - currTopRight.y;
01631
01632 double xRangeStart = getOptimalRangeStart(true);
01633 xRangeStart = max(xRangeStart, minOffset.x);
01634 xRangeStart = min(xRangeStart, maxOffset.x);
01635
01636 double yRangeStart = getOptimalRangeStart(false);
01637 yRangeStart = max(yRangeStart, minOffset.y);
01638 yRangeStart = min(yRangeStart, maxOffset.y);
01639
01640
01641 Point offset;
01642 offset.x = xRangeStart;
01643 offset.y = yRangeStart;
01644
01645 printf("currBBox: %.2f %.2f %.2f %.2f\n",
01646 currBottomLeft.x, currBottomLeft.y,
01647 currTopRight.x, currTopRight.y);
01648 printf("outBBox: %.2f %.2f %.2f %.2f\n",
01649 outlineBottomLeft.x, outlineBottomLeft.y,
01650 outlineTopRight.x, outlineTopRight.y);
01651 cout << "offset.x: " << offset.x
01652 << " offset.y: " << offset.y << endl;
01653
01654 double origHPWL = evalHPWL();
01655 cout << "HPWL before shifting: " << origHPWL << endl;
01656
01657 shiftDesign(offset);
01658
01659 double newHPWL = evalHPWL();
01660 cout << "HPWL after shifting: " << newHPWL << endl;
01661
01662 if (origHPWL < newHPWL)
01663 {
01664 cout << "Undo-ing the shift..." << endl;
01665 offset.x = -offset.x;
01666 offset.y = -offset.y;
01667 shiftDesign(offset);
01668 }
01669
01670 double finalHPWL = evalHPWL();
01671 cout << "Final HPWL: " << finalHPWL << endl;
01672 }
01673 else
01674 {
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 cout << "No shifting for HPWL minimization is performed. " << endl;
01690 }
01691 }
01692
01693 double DB::getOptimalRangeStart(bool horizontal)
01694 {
01695 double center = (horizontal)
01696 ? getXSize() / 2 : getYSize() / 2;
01697
01698 vector<double> endPoints;
01699 for (itNode currBlk = _nodes->nodesBegin();
01700 currBlk != _nodes->nodesEnd(); currBlk++)
01701 {
01702 double currNodeLength = (horizontal)
01703 ? currBlk->getWidth() : currBlk->getHeight();
01704
01705 double currNodeLocAbs = (horizontal)
01706 ? currBlk->getX() : currBlk->getY();
01707
01708 for (itNodePin currNodePin = currBlk->pinsBegin();
01709 currNodePin != currBlk->pinsEnd(); currNodePin++)
01710 {
01711
01712 unsigned currNetIndex = currNodePin->netIndex;
01713 Net& currNet = _nets->getNet(currNetIndex);
01714
01715
01716 unsigned currPinOffset = currNodePin->pinOffset;
01717
01718
01719 double pinOffset = (horizontal)
01720 ? currNet.getPin(currPinOffset).getXOffset()
01721 : currNet.getPin(currPinOffset).getYOffset();
01722
01723
01724 double pinLocationAbs =
01725 currNodeLocAbs +
01726 currNodeLength/2 + (currNodeLength * pinOffset);
01727
01728
01729 double pinLocationWrtCenter = pinLocationAbs - center;
01730
01731
01732 double spanStart = 1e90;
01733 double spanEnd = -1e90;
01734
01735 for (itPin currPad = currNet.pinsBegin();
01736 currPad != currNet.pinsEnd(); currPad++)
01737 {
01738 if (currPad->getType())
01739 {
01740 int padIndex = currPad->getNodeIndex();
01741 Node& currTerm = _nodes->getTerm(padIndex);
01742
01743 double padLoc = (horizontal)
01744 ? currTerm.getX() : currTerm.getY();
01745
01746 double padAdjusted = padLoc - pinLocationWrtCenter;
01747
01748 spanStart = min(spanStart, padAdjusted);
01749 spanEnd = max(spanEnd, padAdjusted);
01750 }
01751 }
01752
01753 if (spanStart <= spanEnd)
01754 {
01755 endPoints.push_back(spanStart);
01756 endPoints.push_back(spanEnd);
01757 }
01758 }
01759 }
01760
01761 sort(endPoints.begin(), endPoints.end());
01762
01763
01764 int endPointNum = endPoints.size();
01765 if(endPointNum < 2)
01766 {
01767 abkwarn(0,"Could not find optimal ranges.");
01768 return 0;
01769 }
01770 abkwarn(endPointNum % 2 == 0, "size of endPoints is not even.");
01771 return (endPoints[(endPointNum/2) - 1] + endPoints[endPointNum/2]) / 2;
01772 }
01773
01774