00001
00019 #include "mioInt.h"
00020
00024
00028
00029 static Mio_Library_t * Mio_LibraryReadOne( Abc_Frame_t * pAbc, char * FileName, bool fExtendedFormat, st_table * tExcludeGate, int fVerbose );
00030 static int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, bool fExtendedFormat, st_table * tExcludeGate, int fVerbose );
00031 static Mio_Gate_t * Mio_LibraryReadGate( char ** ppToken, bool fExtendedFormat );
00032 static Mio_Pin_t * Mio_LibraryReadPin( char ** ppToken, bool fExtendedFormat );
00033 static char * chomp( char *s );
00034 static void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib );
00035 static void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines );
00036
00037 #ifdef WIN32
00038 extern int isspace( int c );
00039 #endif
00040
00052 Mio_Library_t * Mio_LibraryRead( void * pAbc, char * FileName, char * ExcludeFile, int fVerbose )
00053 {
00054 Mio_Library_t * pLib;
00055 int num;
00056
00057 st_table * tExcludeGate = 0;
00058
00059 if ( ExcludeFile )
00060 {
00061 tExcludeGate = st_init_table(strcmp, st_strhash);
00062 if ( (num = Mio_LibraryReadExclude( pAbc, ExcludeFile, tExcludeGate )) == -1 )
00063 {
00064 st_free_table( tExcludeGate );
00065 tExcludeGate = 0;
00066 return 0;
00067 }
00068
00069 fprintf ( Abc_FrameReadOut( pAbc ), "Read %d gates from exclude file\n", num );
00070 }
00071
00072 pLib = Mio_LibraryReadOne( pAbc, FileName, 0, tExcludeGate, fVerbose );
00073 if ( pLib == NULL )
00074 {
00075 pLib = Mio_LibraryReadOne( pAbc, FileName, 1, tExcludeGate, fVerbose );
00076 if ( pLib != NULL )
00077 printf ( "Warning: Read extended GENLIB format but ignoring extensions\n" );
00078 }
00079
00080 return pLib;
00081 }
00082
00094 Mio_Library_t * Mio_LibraryReadOne( Abc_Frame_t * pAbc, char * FileName, bool fExtendedFormat, st_table * tExcludeGate, int fVerbose )
00095 {
00096 Mio_Library_t * pLib;
00097 char * pBuffer = 0;
00098
00099
00100 pLib = ALLOC( Mio_Library_t, 1 );
00101 memset( pLib, 0, sizeof(Mio_Library_t) );
00102 pLib->pName = Extra_UtilStrsav( FileName );
00103 pLib->tName2Gate = st_init_table(strcmp, st_strhash);
00104 pLib->pMmFlex = Extra_MmFlexStart();
00105 pLib->vCube = Vec_StrAlloc( 100 );
00106
00107
00108
00109
00110
00111
00112 {
00113 FILE * pFile;
00114 int nFileSize;
00115
00116
00117 pFile = Io_FileOpen( FileName, "open_path", "rb", 1 );
00118
00119
00120
00121 assert ( pFile != NULL );
00122
00123 fseek( pFile, 0, SEEK_END );
00124 nFileSize = ftell( pFile );
00125
00126 rewind( pFile );
00127
00128 pBuffer = ALLOC( char, nFileSize + 10 );
00129 fread( pBuffer, nFileSize, 1, pFile );
00130
00131 pBuffer[ nFileSize ] = '\0';
00132 strcat( pBuffer, "\n.end\n" );
00133
00134 fclose( pFile );
00135 }
00136
00137 Io_ReadFileRemoveComments( pBuffer, NULL, NULL );
00138
00139
00140 if ( Mio_LibraryReadInternal( pLib, pBuffer, fExtendedFormat, tExcludeGate, fVerbose ) )
00141 {
00142 Mio_LibraryDelete( pLib );
00143 free( pBuffer );
00144 return NULL;
00145 }
00146 free( pBuffer );
00147
00148
00149 if ( Mio_LibraryParseFormulas( pLib ) )
00150 {
00151 printf( "Mio_LibraryRead: Had problems parsing formulas.\n" );
00152 Mio_LibraryDelete( pLib );
00153 return NULL;
00154 }
00155
00156
00157 Mio_LibraryDetectSpecialGates( pLib );
00158
00159 return pLib;
00160 }
00161
00173 int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, bool fExtendedFormat, st_table * tExcludeGate, int fVerbose )
00174 {
00175 Mio_Gate_t * pGate, ** ppGate;
00176 char * pToken;
00177 int nGates = 0;
00178 int nDel = 0;
00179
00180
00181 pLib->pGates = NULL;
00182 ppGate = &pLib->pGates;
00183
00184
00185 pToken = strtok( pBuffer, " \t\r\n" );
00186 while ( pToken && strcmp( pToken, MIO_STRING_GATE ) == 0 )
00187 {
00188
00189 pGate = Mio_LibraryReadGate( &pToken, fExtendedFormat );
00190 if ( pGate == NULL )
00191 return 1;
00192
00193
00194 pGate->pLib = pLib;
00195
00196
00197
00198 if ( tExcludeGate && st_is_member( tExcludeGate, pGate->pName ) )
00199 {
00200
00201 Mio_GateDelete( pGate );
00202 nDel++;
00203 }
00204 else
00205 {
00206
00207 *ppGate = pGate;
00208 ppGate = &pGate->pNext;
00209 nGates++;
00210
00211
00212 if ( !st_is_member( pLib->tName2Gate, pGate->pName ) )
00213 st_insert( pLib->tName2Gate, pGate->pName, (char *)pGate );
00214 else
00215 printf( "The gate with name \"%s\" appears more than once.\n", pGate->pName );
00216 }
00217 }
00218 if ( fVerbose )
00219 printf( "The number of gates read = %d.\n", nGates );
00220
00221
00222 if ( pToken && strcmp( pToken, ".end" ) != 0 )
00223 return 1;
00224
00225 if ( nDel != 0 )
00226 printf( "Actually excluded %d cells\n", nDel );
00227
00228 return 0;
00229 }
00230
00242 Mio_Gate_t * Mio_LibraryReadGate( char ** ppToken, bool fExtendedFormat )
00243 {
00244 Mio_Gate_t * pGate;
00245 Mio_Pin_t * pPin, ** ppPin;
00246 char * pToken = *ppToken;
00247
00248
00249 pGate = ALLOC( Mio_Gate_t, 1 );
00250 memset( pGate, 0, sizeof(Mio_Gate_t) );
00251
00252
00253 pToken = strtok( NULL, " \t\r\n" );
00254 pGate->pName = Extra_UtilStrsav( pToken );
00255
00256
00257 pToken = strtok( NULL, " \t\r\n" );
00258 pGate->dArea = atof( pToken );
00259
00260
00261
00262
00263 pToken = strtok( NULL, "=" );
00264 pGate->pOutName = chomp( pToken );
00265
00266
00267 pToken = strtok( NULL, ";" );
00268 pGate->pForm = Extra_UtilStrsav( pToken );
00269
00270
00271
00272 pGate->pPins = NULL;
00273 ppPin = &pGate->pPins;
00274
00275
00276 pToken = strtok( NULL, " \t\r\n" );
00277 while ( pToken && strcmp( pToken, MIO_STRING_PIN ) == 0 )
00278 {
00279
00280 pPin = Mio_LibraryReadPin( &pToken, fExtendedFormat );
00281 if ( pPin == NULL )
00282 {
00283 Mio_GateDelete( pGate );
00284 *ppToken = pToken;
00285 return NULL;
00286 }
00287
00288 *ppPin = pPin;
00289 ppPin = &pPin->pNext;
00290
00291 pToken = strtok( NULL, " \t\r\n" );
00292 }
00293
00294 *ppToken = pToken;
00295 return pGate;
00296 }
00297
00298
00299
00311 Mio_Pin_t * Mio_LibraryReadPin( char ** ppToken, bool fExtendedFormat )
00312 {
00313 Mio_Pin_t * pPin;
00314 char * pToken = *ppToken;
00315
00316
00317 pPin = ALLOC( Mio_Pin_t, 1 );
00318 memset( pPin, 0, sizeof(Mio_Pin_t) );
00319
00320
00321 pToken = strtok( NULL, " \t\r\n" );
00322 pPin->pName = Extra_UtilStrsav( pToken );
00323
00324
00325 pToken = strtok( NULL, " \t\r\n" );
00326 if ( strcmp( pToken, MIO_STRING_UNKNOWN ) == 0 )
00327 pPin->Phase = MIO_PHASE_UNKNOWN;
00328 else if ( strcmp( pToken, MIO_STRING_INV ) == 0 )
00329 pPin->Phase = MIO_PHASE_INV;
00330 else if ( strcmp( pToken, MIO_STRING_NONINV ) == 0 )
00331 pPin->Phase = MIO_PHASE_NONINV;
00332 else
00333 {
00334 printf( "Cannot read pin phase specification\n" );
00335 Mio_PinDelete( pPin );
00336 *ppToken = pToken;
00337 return NULL;
00338 }
00339
00340 pToken = strtok( NULL, " \t\r\n" );
00341 pPin->dLoadInput = atof( pToken );
00342
00343 pToken = strtok( NULL, " \t\r\n" );
00344 pPin->dLoadMax = atof( pToken );
00345
00346 pToken = strtok( NULL, " \t\r\n" );
00347 pPin->dDelayBlockRise = atof( pToken );
00348
00349 pToken = strtok( NULL, " \t\r\n" );
00350 pPin->dDelayFanoutRise = atof( pToken );
00351
00352 pToken = strtok( NULL, " \t\r\n" );
00353 pPin->dDelayBlockFall = atof( pToken );
00354
00355 pToken = strtok( NULL, " \t\r\n" );
00356 pPin->dDelayFanoutFall = atof( pToken );
00357
00358 if ( fExtendedFormat )
00359 {
00360
00361
00362
00363
00364 pPin->dDelayBlockFall = pPin->dDelayFanoutFall;
00365
00366 pToken = strtok( NULL, " \t" );
00367 pPin->dDelayFanoutFall = atof( pToken );
00368
00369
00370 pToken = strtok( NULL, " \t\r\n" );
00371 }
00372
00373 if ( pPin->dDelayBlockRise > pPin->dDelayBlockFall )
00374 pPin->dDelayBlockMax = pPin->dDelayBlockRise;
00375 else
00376 pPin->dDelayBlockMax = pPin->dDelayBlockFall;
00377
00378 *ppToken = pToken;
00379 return pPin;
00380 }
00381
00382
00395 char *chomp( char *s )
00396 {
00397 char *b = ALLOC(char, strlen(s)+1), *c = b;
00398 while (*s && isspace(*s))
00399 ++s;
00400 while (*s && !isspace(*s))
00401 *c++ = *s++;
00402 *c = 0;
00403 return b;
00404 }
00405
00418 void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
00419 {
00420 Mio_Gate_t * pGate;
00421 DdNode * bFuncBuf, * bFuncInv, * bFuncNand2, * bFuncAnd2;
00422
00423 bFuncBuf = pLib->dd->vars[0]; Cudd_Ref( bFuncBuf );
00424 bFuncInv = Cudd_Not( pLib->dd->vars[0] ); Cudd_Ref( bFuncInv );
00425 bFuncNand2 = Cudd_bddNand( pLib->dd, pLib->dd->vars[0], pLib->dd->vars[1] ); Cudd_Ref( bFuncNand2 );
00426 bFuncAnd2 = Cudd_bddAnd( pLib->dd, pLib->dd->vars[0], pLib->dd->vars[1] ); Cudd_Ref( bFuncAnd2 );
00427
00428
00429 Mio_LibraryForEachGate( pLib, pGate )
00430 if ( pLib->pGateBuf == NULL && pGate->bFunc == bFuncBuf )
00431 {
00432 pLib->pGateBuf = pGate;
00433 break;
00434 }
00435 if ( pLib->pGateBuf == NULL )
00436 {
00437 printf( "Warnings: GENLIB library reader cannot detect the buffer gate.\n" );
00438 printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
00439 }
00440
00441
00442 Mio_LibraryForEachGate( pLib, pGate )
00443 if ( pLib->pGateInv == NULL && pGate->bFunc == bFuncInv )
00444 {
00445 pLib->pGateInv = pGate;
00446 break;
00447 }
00448 if ( pLib->pGateInv == NULL )
00449 {
00450 printf( "Warnings: GENLIB library reader cannot detect the invertor gate.\n" );
00451 printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
00452 }
00453
00454
00455 Mio_LibraryForEachGate( pLib, pGate )
00456 if ( pLib->pGateNand2 == NULL && pGate->bFunc == bFuncNand2 )
00457 {
00458 pLib->pGateNand2 = pGate;
00459 break;
00460 }
00461 Mio_LibraryForEachGate( pLib, pGate )
00462 if ( pLib->pGateAnd2 == NULL && pGate->bFunc == bFuncAnd2 )
00463 {
00464 pLib->pGateAnd2 = pGate;
00465 break;
00466 }
00467 if ( pLib->pGateAnd2 == NULL && pLib->pGateNand2 == NULL )
00468 {
00469 printf( "Warnings: GENLIB library reader cannot detect the AND2 or NAND2 gate.\n" );
00470 printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
00471 }
00472
00473 Cudd_RecursiveDeref( pLib->dd, bFuncInv );
00474 Cudd_RecursiveDeref( pLib->dd, bFuncNand2 );
00475 Cudd_RecursiveDeref( pLib->dd, bFuncAnd2 );
00476 }
00477
00489 int Mio_LibraryReadExclude( void * pAbc, char * ExcludeFile, st_table * tExcludeGate )
00490 {
00491 int nDel = 0;
00492 FILE *pEx;
00493 char buffer[128];
00494
00495 assert ( tExcludeGate );
00496
00497 if ( ExcludeFile )
00498 {
00499 pEx = fopen( ExcludeFile, "r" );
00500
00501 if ( pEx == NULL )
00502 {
00503 fprintf ( Abc_FrameReadErr( pAbc ), "Error: Could not open exclude file %s. Stop.\n", ExcludeFile );
00504 return -1;
00505 }
00506
00507 while (1 == fscanf( pEx, "%127s", buffer ))
00508 {
00509
00510 st_insert( tExcludeGate, Extra_UtilStrsav( buffer ), (char *)0 );
00511 nDel++;
00512 }
00513
00514 fclose( pEx );
00515 }
00516
00517 return nDel;
00518 }
00519
00533 void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines )
00534 {
00535 char * pCur;
00536 int nDots, nLines;
00537
00538
00539 nDots = nLines = 0;
00540 for ( pCur = pBuffer; *pCur; pCur++ )
00541 {
00542
00543
00544 if ( *pCur == '#' )
00545 while ( *pCur != '\n' )
00546 *pCur++ = ' ';
00547
00548
00549 if ( *pCur == '\n' ) {
00550 if (*(pCur-1)=='\r') {
00551
00552 if (*(pCur-2)!='\\') nLines++;
00553 else {
00554
00555 *(pCur-2) = ' ';
00556 *(pCur-1) = ' ';
00557 *pCur = ' ';
00558 }
00559 } else {
00560
00561 if (*(pCur-1)!='\\') nLines++;
00562 else {
00563
00564 *(pCur-1) = ' ';
00565 *pCur = ' ';
00566 }
00567 }
00568 }
00569 else if ( *pCur == '.' )
00570 nDots++;
00571 }
00572 if ( pnDots )
00573 *pnDots = nDots;
00574 if ( pnLines )
00575 *pnLines = nLines;
00576 }
00577
00581
00582