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
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
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
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
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
00197 }
00198
00199
00200
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')
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() == ':')
00289 {
00290 input.get();
00291 input>>tempWord1;
00292 newOrient = toOrient(tempWord1);
00293 updateOrient(thisIndex, thisType, newOrient);
00294 }
00295
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
00317
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
00334
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
00352
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
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())
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
00465 for(node = nodesBegin(); node != nodesEnd(); ++node)
00466 {
00467 if(node->getOrient() != 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
00606 double AR;
00607 if(reqdAR == -9999)
00608 AR = 1;
00609 else
00610 AR = reqdAR;
00611
00612 double area = (1+reqdWS/100.0)*getNodesArea();
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 }