Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

DB.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 // 040608 hhchan modified how it plots:
00034 //                  plot terminals only when plotNets, "set size ratio -1"
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 //ctor
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    //_nodesBestCopy = new Nodes(baseName);
00069    //_nodesBestCopy->updatePinsInfo(*_nets);
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()) //not a terminal
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 //need terminal propagation
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                      //terminal propagation
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 //actual terminal
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                   //terminal propagation
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      if(_nodes) delete _nodes;
00297      if(_nets) delete _nets;
00298      if(_nodesBestCopy) delete _nodesBestCopy;
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          //any net connected to a macro or terminal is added as is
00319          //only nets between normal blocks are compressed
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                         /*&& ( node->isMacro() || origNet.getDegree() > 2)*/)
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          //now add the compressing code
00421          vector< vector< pair<unsigned,double> > > nodeConnections(oldNodes->getNumNodes());
00422 
00423          for(itNode node=oldNodes->nodesBegin(); 
00424              node != oldNodes->nodesEnd(); ++node)
00425            {
00426              //if(!node->isMacro())
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                              //following cond ensures that we go over each
00441                              //net only once
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                  //tempEdge.putWeight(numConn);
00494                  tempEdge.putWeight(sumOfWts);
00495                  _nets->putNewNet(tempEdge);
00496 
00497                  ++netCtr;
00498                  ++j;
00499                }
00500            }
00501          //_nets->updateNodeInfo(*_nodes);
00502          _nodes->updatePinsInfo(*_nets);
00503          _nodes->initNodesFastPOAccess(*_nets, false);
00504 
00505          /*
00506          cout<<"Initial #Nets "<<oldNets->getNumNets()<<" Initial #Pins "
00507              <<oldNets->getNumPins()<<" Compressed #Nets "<<_nets->getNumNets()
00508              <<" Compressed #Pins "<<_nets->getNumPins()<<endl;
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    // naive FP representation independent way of determining slacks
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             // have x-overlap 
00620             if ((xlocs[i] < xlocs[j] + widths[j])
00621                 && (xlocs[j] < xlocs[i] + widths[i]))
00622             {
00623                if (ylocs[j] > ylocs[i])
00624                {
00625                   // [j] is above [i]
00626                   yTopSlacks[i] = min(yTopSlacks[i],
00627                                       ylocs[j] - (ylocs[i]+heights[i]));
00628                }
00629                else
00630                {
00631                   // [j] is below [i]
00632                   yBottomSlacks[i] = min(yBottomSlacks[i],
00633                                          ylocs[i] - (ylocs[j]+heights[j]));
00634                }
00635             }
00636 
00637             // have y-overlap
00638             if ((ylocs[i] < ylocs[j] + heights[j])
00639                 && (ylocs[j] < ylocs[i] + heights[i]))
00640             {
00641                if (xlocs[j] > xlocs[i])
00642                {
00643                   // [j] is right of [i]
00644                   xRightSlacks[i] = min(xRightSlacks[i],
00645                                         xlocs[j] - (xlocs[i]+widths[i]));
00646                }
00647                else
00648                {
00649                   // [j] is left of [i]
00650                   xLeftSlacks[i] = min(xLeftSlacks[i],
00651                                        xlocs[i] - (xlocs[j]+widths[j]));
00652                }
00653             }
00654          }
00655       }
00656    }
00657 
00658    // set the locations
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    //BBox netBBox;
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)//special casing for 2 pin nets
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())        //if not terminal
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())        //if not terminal
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())        //if not terminal
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              //netBBox.put(tempPoint);
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      //if(netDegree > 1)
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      //if(netBBox.isValid())
00971      //HPWL += netBBox.getHPWL();
00972      //netBBox.clear();  
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())        //if not terminal
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          //cout<<net->getName()<<" "<<netBBox.getHPWL()<<" "<<HPWL<<endl;
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       // plot terminals only when Net is plotted
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())  //if not terminal
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    //save the aux file now
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())        //if not terminal
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 //   itPin pin;
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    //double xMin = DBL_MAX;
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          //value = node->getY();
01506          //if(value < xMin)
01507          //  xMin = value;
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    //double yMin = DBL_MAX;
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      //value = node->getY();
01557          //if(value < yMin)
01558          //  yMin = value;
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    // original bottomLeft corner of the floorplan
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       // the magnitude of shifting (not the final pos)
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        /* Saurabh: The below code is not general enough. only valid
01676           when relevant nodes are marked as macros. So I am connenting
01677           it out. only used for printing out a message anyway */
01678        /*
01679        double tempXSize = getXSizeWMacroOnly();
01680        double tempYSize = getYSizeWMacroOnly();
01681        if(tempXSize > 1e-5 && tempYSize > 1e-5)
01682          {
01683            designHeight = tempYSize;
01684            designWidth = tempXSize;
01685          }
01686        if (!(designWidth <= outlineWidth &&
01687              designHeight <= outlineHeight))
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          // find the net in which this pin lies
01712          unsigned currNetIndex = currNodePin->netIndex;
01713          Net& currNet = _nets->getNet(currNetIndex);
01714 
01715          // index number for the pin in its net
01716          unsigned currPinOffset = currNodePin->pinOffset;
01717 
01718          // pins offset from the center
01719          double pinOffset = (horizontal)
01720             ? currNet.getPin(currPinOffset).getXOffset()
01721             : currNet.getPin(currPinOffset).getYOffset();
01722 
01723          // absolute location of the pin
01724          double pinLocationAbs =
01725             currNodeLocAbs +
01726             currNodeLength/2 + (currNodeLength * pinOffset);
01727 
01728          // relative location wrt center of the FLOORPLAN
01729          double pinLocationWrtCenter = pinLocationAbs - center;
01730 
01731          // span of the net in this direction wrt this pin
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()) // true: pad/terminal
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          } // end for each pin in currNet
01752 
01753          if (spanStart <= spanEnd)
01754          {
01755             endPoints.push_back(spanStart);
01756             endPoints.push_back(spanEnd);
01757          }
01758       } // end for each pin in currNode
01759    } // end for each node
01760 
01761    sort(endPoints.begin(), endPoints.end());
01762 
01763    // return the median, assuming endPoints[] has even size
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                

Generated on Mon Apr 25 01:09:24 2005 for Parquete by doxygen 1.3.2