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

Nodes.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 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #include <map>
00049 #include "FPcommon.h"
00050 #include "Nets.h"
00051 #include "Nodes.h"
00052 using namespace parquetfp;
00053 
00054 //ctor
00055 
00056 Nodes::Nodes(char* baseName)
00057 {
00058   char fname[1024];
00059   strcpy(fname,baseName);
00060   strcat(fname,".blocks");
00061   parseNodes(fname);
00062   strcpy(fname,baseName);
00063   strcat(fname,".pl");
00064   parsePl(fname);
00065 }
00066 
00067 void Nodes::parseNodes(char* fnameBl)
00068 {
00069     char block_name[1024];
00070     char block_type[1024];
00071     char tempWord1[1024];
00072     
00073     vector<Point> vertices;
00074     int numVertices;
00075     bool success; 
00076     double width, height;
00077 
00078     int voltage;
00079     
00080     double area,minAr,maxAr;
00081     int numSoftBl=0;
00082     int numHardBl=0;
00083     int numTerm=0;
00084     
00085     int indexBlock=0;
00086     int indexTerm=0;
00087     
00088     ifstream input(fnameBl);
00089     if(!input)
00090      {
00091       cout<<"ERROR: .blocks file could not be opened successfully"<<endl;
00092       exit(0);
00093      }
00094     skiptoeol(input);
00095     while(!input.eof())
00096       {
00097         input>>tempWord1;
00098         if(!(strcmp(tempWord1,"NumSoftRectangularBlocks")))
00099           break;
00100       }
00101     input>>tempWord1;
00102     input>>numSoftBl;
00103     while(!input.eof())
00104       {
00105         input>>tempWord1;
00106         if(!(strcmp(tempWord1,"NumHardRectilinearBlocks")))
00107           break;
00108       }
00109     input>>tempWord1;
00110     input>>numHardBl;
00111     
00112     while(!input.eof())
00113       {
00114         input>>tempWord1;
00115         if(!(strcmp(tempWord1,"NumTerminals")))
00116           break;
00117       }
00118     input>>tempWord1;
00119     input>>numTerm;
00120     
00121     while(!input.eof())
00122       {
00123         block_type[0] = '\0';
00124         eatblank(input);
00125         if(input.eof())
00126           break;
00127         if(input.peek()=='#')
00128           eathash(input);
00129         else
00130         {
00131           eatblank(input);
00132           if(input.peek() == '\n' || input.peek() == '\r' 
00133              || input.peek() == EOF)
00134             {
00135               input.get();
00136               continue;
00137             }
00138 
00139           input >> block_name;
00140           input >> block_type ;
00141         
00142    
00143           if(!strcmp(block_type,"softrectangular")) 
00144            {
00145             input >> voltage;
00146             input >> area;
00147             input >> minAr;
00148             input >> maxAr;
00149             Node temp(block_name,area,minAr,maxAr,indexBlock,false);
00150             temp.addSubBlockIndex(indexBlock);
00151             temp.addVoltage(voltage);
00152             _nodes.push_back(temp);
00153             
00154             ++indexBlock;
00155             //cout<<block_name<<" "<<area<<endl;
00156            }
00157           else if(!strcmp(block_type,"hardrectilinear"))
00158           {
00159             input >> voltage;
00160             input >> numVertices;
00161             Point tempPoint;
00162             success = 1;
00163             if(numVertices > 4)
00164               cout<<"ERROR in parsing .blocks file. rectilinear blocks (" << block_name << ", " << numVertices << ") can be only rectangles for now\n";
00165             for(int i=0; i<numVertices; ++i)
00166              {
00167                success &= needCaseChar(input, '(');  input.get();
00168                input >> tempPoint.x;
00169                success &= needCaseChar(input, ',');  input.get();
00170                input >> tempPoint.y;
00171                success &= needCaseChar(input, ')');  input.get();
00172                vertices.push_back(tempPoint);
00173              }
00174             if(!success)
00175               cout<<"ERROR in parsing .blocks file while processing hardrectilinear blocks"<<endl;
00176             
00177             width = vertices[2].x - vertices[0].x;
00178             height = vertices[2].y - vertices[0].y;
00179             area = width*height;
00180             minAr = width/height;
00181             maxAr = minAr;
00182             Node temp(block_name,area,minAr,maxAr,indexBlock,false);
00183             temp.addSubBlockIndex(indexBlock);
00184             temp.addVoltage(voltage);
00185             _nodes.push_back(temp);
00186             ++indexBlock;
00187             vertices.clear();
00188             //cout<<block_name<<" "<<area<<endl;
00189           }
00190           else if(!strcmp(block_type,"terminal"))
00191            {
00192             Node temp(block_name,0,1,1,indexTerm,true);
00193             temp.addSubBlockIndex(indexTerm);
00194             _terminals.push_back(temp);
00195             ++indexTerm;
00196             //cout<<indexTerm<<"  "<<block_name<<endl;
00197            }
00198           /*
00199           else
00200            cout<<"ERROR in parsing .blocks file"<<endl;
00201           */
00202          }  
00203       }
00204     input.close();
00205 
00206     if(numSoftBl+numHardBl+numTerm != indexBlock+indexTerm)
00207       cout<<"ERROR in parsing .blocks file. No: of blocks do not tally "<<(indexBlock+indexTerm)<<" vs "<<(numSoftBl+numHardBl+numTerm)<<endl;
00208      
00209 }
00210 
00211 void Nodes::parsePl(char* fnamePl)
00212 {
00213    char block_name[1024];
00214    char tempWord[1024];
00215    char tempWord1[1024];
00216    double xloc;
00217    double yloc;
00218    double width;
00219    double height;
00220    bool success;
00221    ORIENT newOrient;
00222    itNode node;
00223 
00224    map<const char*, int, ltstr> index;
00225    map<const char*, bool, ltstr> type;
00226    for(node = nodesBegin(); node != nodesEnd(); node++)
00227      {
00228        index[node->getName()] = node->getIndex();
00229        type[node->getName()] = 0;
00230      }
00231    for(node = terminalsBegin(); node != terminalsEnd(); node++)
00232      {
00233        index[node->getName()] = node->getIndex();
00234        type[node->getName()] = 1;
00235      }
00236    
00237    ifstream input(fnamePl);
00238    if(!input)
00239      {
00240        cout<<"ERROR: .pl file could not be opened successfully"<<endl;
00241        return;
00242      }
00243      
00244    skiptoeol(input);
00245    while(!input.eof())
00246      {
00247        eatblank(input);
00248        if(input.eof())
00249          break;
00250        if(input.peek()=='#')
00251          eathash(input);
00252        else
00253        {
00254          eatblank(input);
00255          if(input.peek() == '\n' || input.peek() == '\r' 
00256             || input.peek() == EOF)
00257            {
00258              input.get();
00259              continue;
00260            }
00261          input>>block_name;
00262          input>>xloc;
00263          input>>yloc;
00264          int thisIndex = index[block_name];
00265          int thisType = type[block_name];
00266 
00267          updatePlacement(thisIndex, thisType, xloc, yloc);
00268          
00269          eatblank(input);
00270          success = 1;
00271          if(input.peek() == 'D')   //block with width and height
00272           {
00273            input>>tempWord;  
00274            success &= needCaseChar(input,'('); input.get();
00275            input>>width;
00276            success &= needCaseChar(input,','); input.get();
00277            input>>height;
00278            success &= needCaseChar(input,')'); input.get();
00279            
00280            if(!success || strcmp(tempWord,"DIMS"))
00281              cout<<"ERROR in parsing .pl file while reading in DIMS\n";
00282            updateHW(thisIndex, thisType, width, height);
00283            getNode(thisIndex).needSyncOrient = false;
00284           }
00285           
00286          success = 1;
00287          eatblank(input);
00288          if(input.peek() == ':') //initial orientation given
00289           {
00290             input.get();
00291             input>>tempWord1;    //the orientation in words;
00292             newOrient = toOrient(tempWord1);
00293             updateOrient(thisIndex, thisType, newOrient);
00294           }
00295          //cout<<block_name<<" "<<xloc<<" "<<yloc<<endl;  
00296        }
00297      }
00298    input.close();
00299 }
00300 
00301   
00302 void Nodes::updatePlacement(int index, bool type, double xloc, double yloc)
00303 {
00304   if(!type)
00305     {
00306       Node& node = getNode(index);
00307       node.putX(xloc);
00308       node.putY(yloc);
00309     }
00310   else
00311     {
00312       Node& node = getTerm(index);
00313       node.putX(xloc);
00314       node.putY(yloc);
00315     }
00316   // cout<<"ERROR: could not find node to update placement for. Name: "<<
00317   //block_name<<endl;
00318   return;
00319 }
00320 
00321 void Nodes::updateOrient(int index, bool type, ORIENT newOrient)
00322 {
00323   if(!type)
00324     {
00325       Node& node = getNode(index);
00326       node.putOrient(newOrient);
00327     }
00328   else
00329     {
00330       Node& node = getTerm(index);
00331       node.putOrient(newOrient);
00332     }
00333   //cout<<"ERROR: could not find node to update Orient for. Name: "<<block_name
00334   //    <<endl;
00335 }
00336 
00337 void Nodes::updateHW(int index, bool type, double width, double height)
00338 {
00339   if(!type)
00340     {
00341       Node& node = getNode(index);
00342       node.putWidth(width);
00343       node.putHeight(height);
00344     }
00345   else
00346     {
00347       Node& node = getTerm(index);
00348       node.putWidth(width);
00349       node.putHeight(height);
00350     }
00351   //cout<<"ERROR: could not find node to update Height/Width for. Name: "<<
00352   //  block_name<<endl;
00353 }
00354 
00355 unsigned Nodes::getNumNodes(void)
00356 { return _nodes.size(); }
00357 
00358 double Nodes::getNodeWidth(unsigned index)
00359 {
00360   return _nodes[index].getWidth();
00361 }
00362 
00363 double Nodes::getNodeHeight(unsigned index)
00364 {
00365   return _nodes[index].getHeight();
00366 }
00367 
00368 void Nodes::putNodeWidth(unsigned index, double width)
00369 {
00370   _nodes[index].putWidth(width);
00371 }
00372 
00373 void Nodes::putNodeHeight(unsigned index, double height)
00374 {
00375   _nodes[index].putHeight(height);
00376 }
00377 
00378 vector<double> Nodes::getNodeWidths(void)
00379 {
00380   vector<double> widths;
00381   for(itNode iNodes=nodesBegin(); iNodes!=nodesEnd(); iNodes++)
00382     widths.push_back(iNodes->getWidth());
00383   return widths;
00384 }
00385 
00386 vector<double> Nodes::getNodeHeights(void)
00387 {
00388   vector<double> heights;
00389   for(itNode iNodes=nodesBegin(); iNodes!=nodesEnd(); iNodes++)
00390     heights.push_back(iNodes->getHeight());
00391   return heights;
00392 }
00393 
00394 
00395 vector<double> Nodes::getXLocs(void)
00396 {
00397   vector<double> xloc;
00398   for(itNode iNodes=nodesBegin(); iNodes!=nodesEnd(); iNodes++)
00399     xloc.push_back(iNodes->getX());
00400   return xloc;
00401 }
00402 
00403 vector<double> Nodes::getYLocs(void)
00404 {
00405   vector<double> yloc;
00406   for(itNode iNodes=nodesBegin(); iNodes!=nodesEnd(); iNodes++)
00407     yloc.push_back(iNodes->getY());
00408   return yloc;
00409 }
00410 
00411 double Nodes::getNodesArea()
00412 {
00413   itNode iNode;
00414   double area = 0;
00415   for(iNode = nodesBegin(); iNode != nodesEnd(); ++iNode)
00416     {
00417       area += iNode->getHeight()*iNode->getWidth();
00418     }
00419   return area;
00420 }
00421 
00422 void Nodes::changeOrient(unsigned index, ORIENT newOrient, Nets& nets)
00423 {
00424   Node& node = _nodes[index];
00425   node.changeOrient(newOrient, nets);
00426 }
00427 
00428 /*following function assumes that pin info about node index is correct.*/
00429 void Nodes::updatePinsInfo(Nets& nets)
00430 {
00431   itNet net;
00432   itPin pin;
00433   itNode node;
00434   NodePin tempNodePin;
00435   unsigned pinOffset;
00436   
00437   for(node=nodesBegin(); node != nodesEnd(); ++node)
00438     node->clearPins();
00439   for(node=terminalsBegin(); node != terminalsEnd(); ++node)
00440     node->clearPins();
00441 
00442   for(net = nets.netsBegin(); net != nets.netsEnd(); net++)
00443     {
00444       pinOffset = 0;
00445       for(pin = net->pinsBegin(); pin != net->pinsEnd(); pin++)
00446         {
00447           tempNodePin.netIndex = net->getIndex();
00448           tempNodePin.pinOffset = pinOffset;
00449           unsigned nodeIndex = pin->getNodeIndex();
00450           if(!pin->getType())     //if not pad
00451           {
00452            Node& node = getNode(nodeIndex);
00453            node.addPin(tempNodePin);
00454           }
00455           else
00456           {
00457            Node& node = getTerminal(nodeIndex);
00458            node.addPin(tempNodePin);
00459           }
00460           pinOffset++;
00461         }
00462     }
00463 
00464   //now sync the orientations of the pins with that of the nodes
00465   for(node = nodesBegin(); node != nodesEnd(); ++node)
00466     { 
00467       if(node->getOrient() != N)   //synchronize orientation only if not N
00468         node->syncOrient(nets);
00469     }
00470 }
00471 
00472 
00473 void Nodes::savePl(char* baseFileName)
00474 {
00475   char fileName[1024];
00476   strcpy(fileName, baseFileName);
00477   strcat(fileName, ".pl");
00478   ofstream outPl(fileName);
00479   if(!outPl)
00480     {
00481       cout<<"ERROR in saving .pl file"<<endl;
00482       return;
00483     }
00484   cout<<"Saving "<<fileName<<" as output .pl file"<<endl;
00485   outPl<<"UMICH blocks 1.0"<<endl<<endl<<endl<<endl;
00486   
00487   itNode node;
00488   
00489   for(node = nodesBegin(); node != nodesEnd(); node++)
00490     {
00491       outPl<<node->getName()<<"\t"<<node->getX()<<"\t"<<node->getY();
00492       outPl<<"\tDIMS = ("<<node->getWidth()<<", "<<node->getHeight()<<")";
00493       outPl<<"\t: "<<toChar(node->getOrient())<<endl;
00494     }
00495   outPl<<endl;
00496 
00497   for(node = terminalsBegin(); node != terminalsEnd(); node++)
00498     {
00499       outPl<<node->getName()<<"\t"<<node->getX()<<"\t"<<node->getY()
00500            <<"\t: "<<toChar(node->getOrient())<<endl;
00501     }
00502   outPl<<endl;
00503   outPl.close();
00504 }
00505 
00506 void Nodes::saveCapoNodes(char* baseFileName)
00507 {
00508   
00509   char fileName[1024];
00510   strcpy(fileName, baseFileName);
00511   strcat(fileName, ".nodes");
00512   ofstream file(fileName);
00513   file<<"UCLA nodes  1.0"<<endl<<endl<<endl;
00514   
00515   file<<"NumNodes : \t"<<_nodes.size()+_terminals.size()<<endl;
00516   file<<"NumTerminals : \t"<<_terminals.size()<<endl;
00517 
00518   itNode node;
00519 
00520   double width, height, temp;
00521   for(node = nodesBegin(); node != nodesEnd(); ++node)
00522     {
00523       width = node->getWidth();
00524       height = node->getHeight();
00525       if(int(node->getOrient())%2 == 1)
00526         {
00527           temp = width;
00528           width = height;
00529           height = temp;
00530         }
00531       file<<"\t"<<node->getName()<<"\t"<<width<<"\t"<<height<<endl;      
00532     }
00533 
00534   for(node = terminalsBegin(); node != terminalsEnd(); ++node)
00535     {
00536       width = node->getWidth();
00537       height = node->getHeight();
00538       if(int(node->getOrient())%2 == 1)
00539         {
00540           temp = width;
00541           width = height;
00542           height = temp;
00543         }
00544       file<<"\t"<<node->getName()<<"\t"<<width<<"\t"<<height<<"\tterminal "
00545           <<endl;      
00546     }
00547   file.close();
00548 }
00549 
00550 void Nodes::saveNodes(char* baseFileName)
00551 {
00552   char fileName[1024];
00553   strcpy(fileName, baseFileName);
00554   strcat(fileName, ".blocks");
00555   ofstream file(fileName);
00556   file<<"UCSC blocks  1.0"<<endl<<endl<<endl;
00557   
00558   file<<"NumSoftRectangularBlocks : \t"<<_nodes.size()<<endl;
00559   file<<"NumHardRectilinearBlocks : \t0"<<endl;
00560   file<<"NumTerminals : \t"<<_terminals.size()<<endl<<endl;
00561 
00562   itNode node;
00563      
00564   for(node = nodesBegin(); node != nodesEnd(); ++node)
00565     {
00566       file<<node->getName()<<" softrectangular "<<node->getArea()<<"\t"
00567           <<node->getminAR()<<"\t"<<node->getmaxAR()<<endl;      
00568     }
00569   file<<endl;
00570   for(node = terminalsBegin(); node != terminalsEnd(); ++node)
00571     file<<node->getName()<<" terminal"<<endl;
00572 
00573   file.close();
00574 }
00575 
00576 void Nodes::saveCapoPl(char* baseFileName)
00577 {
00578   char fileName[1024];
00579   strcpy(fileName, baseFileName);
00580   strcat(fileName, ".pl");
00581   ofstream file(fileName);
00582 
00583   file<<"UCLA pl   1.0"<<endl<<endl<<endl;
00584   
00585   itNode node;
00586      
00587   for(node = nodesBegin(); node != nodesEnd(); ++node)
00588     {
00589       file<<"\t"<<node->getName()<<"\t"<<node->getX()<<"\t"
00590           <<node->getY()<<" : \t"<<toChar(node->getOrient())<<endl;      
00591     }
00592 
00593     
00594   for(node = terminalsBegin(); node != terminalsEnd(); ++node)
00595     {
00596       file<<"\t"<<node->getName()<<"\t"<<node->getX()<<"\t"
00597           <<node->getY()<<" : \t"<<toChar(node->getOrient())<<endl;
00598     }
00599     
00600   file.close();
00601 }
00602 
00603 void Nodes::saveCapoScl(char* baseFileName, double reqdAR, double reqdWS)
00604 {
00605   //default required aspect ratio of 1
00606   double AR;
00607   if(reqdAR == -9999)
00608     AR = 1;
00609   else
00610     AR = reqdAR;
00611     
00612   double area = (1+reqdWS/100.0)*getNodesArea();  //add WS
00613   double height = sqrt(area/AR);
00614   double width = AR*height;
00615   int siteWidth = 1;
00616   int numSites = int(width/siteWidth) + 1;
00617   int rowHeight;
00618   int minHeight = int(getMinHeight());
00619   int minWidth = int(getMinWidth());
00620   if(minHeight < minWidth)
00621     rowHeight = minHeight;
00622   else
00623     rowHeight = minWidth;
00624   
00625   rowHeight = int(rowHeight/10);
00626   if(rowHeight < 1)
00627     rowHeight = 1;
00628 
00629   int numRows = int(height/rowHeight) + 1;  
00630   int rowCoord = 1;
00631   
00632   char fileName[1024];
00633   strcpy(fileName, baseFileName);
00634   strcat(fileName, ".scl");
00635   ofstream file(fileName);
00636 
00637   file<<"UCLA scl   1.0"<<endl<<endl<<endl;
00638   file<<"Numrows : "<<numRows<<endl;
00639   
00640   for(int i=0; i<numRows; ++i)
00641    {
00642      file<<"CoreRow Horizontal"<<endl;
00643      file<<" Coordinate\t: "<<rowCoord<<endl;
00644      file<<" Height\t: "<<rowHeight<<endl;
00645      file<<" SiteWidth\t: "<<siteWidth<<endl;
00646      file<<" Sitespacing\t: "<<siteWidth<<endl;
00647      file<<" Siteorient\t: N"<<endl;
00648      file<<" Sitesymmetry\t: Y"<<endl;
00649      file<<" SubrowOrigin\t: 0 Numsites\t: "<<numSites<<endl;
00650      file<<"End"<<endl;
00651 
00652      rowCoord += rowHeight;
00653    }
00654 
00655   file.close();
00656 }
00657 
00658 double Nodes::getMinHeight()
00659 {
00660   itNode node;
00661   double minHeight = 1e100;
00662   for(node = nodesBegin(); node != nodesEnd(); ++node)
00663    {
00664      if(minHeight > node->getHeight())
00665        minHeight = node->getHeight();
00666    }
00667   return minHeight;
00668 }
00669 
00670 double Nodes::getMinWidth()
00671 {
00672   itNode node;
00673   double minWidth = 1e100;
00674   for(node = nodesBegin(); node != nodesEnd(); ++node)
00675    {
00676      if(minWidth > node->getWidth())
00677        minWidth = node->getWidth();
00678    }
00679   return minWidth;
00680 }
00681 
00682 void Nodes::initNodesFastPOAccess(Nets& nets, bool reset)
00683 {
00684   itNode node;
00685   if (reset)
00686     for(node = nodesBegin(); node != nodesEnd(); ++node)
00687       node->allPinsAtCenter = false;
00688   else
00689     {
00690       for(node = nodesBegin(); node != nodesEnd(); ++node)
00691         node->allPinsAtCenter =  node->calcAllPinsAtCenter(nets);
00692     }
00693 }

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