00001
00021 #include "io.h"
00022 #include "main.h"
00023 #include "mio.h"
00024
00028
00029 typedef struct Io_ReadBlif_t_ Io_ReadBlif_t;
00030 struct Io_ReadBlif_t_
00031 {
00032
00033 char * pFileName;
00034 Extra_FileReader_t * pReader;
00035
00036 Abc_Ntk_t * pNtkMaster;
00037 Abc_Ntk_t * pNtkCur;
00038 int LineCur;
00039
00040 Vec_Ptr_t * vTokens;
00041 Vec_Ptr_t * vNewTokens;
00042 Vec_Str_t * vCubes;
00043
00044 FILE * Output;
00045 char sError[1000];
00046 int fError;
00047 };
00048
00049 static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
00050 static void Io_ReadBlifFree( Io_ReadBlif_t * p );
00051 static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p );
00052 static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p );
00053 static char * Io_ReadBlifCleanName( char * pName );
00054
00055 static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
00056 static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p );
00057 static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00058 static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00059 static int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00060 static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00061 static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
00062 static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00063 static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00064 static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00065 static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
00066 static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
00067
00071
00083 Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
00084 {
00085 Io_ReadBlif_t * p;
00086 Abc_Ntk_t * pNtk;
00087
00088
00089 p = Io_ReadBlifFile( pFileName );
00090 if ( p == NULL )
00091 return NULL;
00092
00093
00094 pNtk = Io_ReadBlifNetwork( p );
00095 if ( pNtk == NULL )
00096 {
00097 Io_ReadBlifFree( p );
00098 return NULL;
00099 }
00100 pNtk->pSpec = Extra_UtilStrsav( pFileName );
00101 Abc_NtkTimeInitialize( pNtk );
00102 Io_ReadBlifFree( p );
00103
00104
00105 if ( fCheck && !Abc_NtkCheckRead( pNtk ) )
00106 {
00107 printf( "Io_ReadBlif: The network check has failed.\n" );
00108 Abc_NtkDelete( pNtk );
00109 return NULL;
00110 }
00111 return pNtk;
00112 }
00113
00125 Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
00126 {
00127 Abc_Ntk_t * pNtk, * pNtkMaster;
00128
00129
00130 p->vTokens = Io_ReadBlifGetTokens(p);
00131 if ( p->vTokens == NULL || strcmp( p->vTokens->pArray[0], ".model" ) )
00132 {
00133 p->LineCur = 0;
00134 sprintf( p->sError, "Wrong input file format." );
00135 Io_ReadBlifPrintErrorMessage( p );
00136 return NULL;
00137 }
00138
00139
00140 pNtkMaster = NULL;
00141 while ( p->vTokens )
00142 {
00143
00144 pNtk = Io_ReadBlifNetworkOne( p );
00145 if ( pNtk == NULL )
00146 break;
00147 if ( p->vTokens && strcmp(p->vTokens->pArray[0], ".exdc") == 0 )
00148 {
00149 pNtk->pExdc = Io_ReadBlifNetworkOne( p );
00150 Abc_NtkFinalizeRead( pNtk->pExdc );
00151 if ( pNtk->pExdc == NULL )
00152 break;
00153 }
00154
00155 if ( pNtkMaster == NULL )
00156 {
00157 p->pNtkMaster = pNtkMaster = pNtk;
00158 continue;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 if ( !p->fError )
00191 Abc_NtkFinalizeRead( pNtkMaster );
00192
00193 return pNtkMaster;
00194 }
00195
00207 Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
00208 {
00209 ProgressBar * pProgress;
00210 Abc_Ntk_t * pNtk;
00211 char * pDirective;
00212 int iLine, fTokensReady, fStatus;
00213
00214
00215 assert( p->vTokens != NULL );
00216
00217
00218 p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
00219
00220 if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
00221 pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
00222 else if ( strcmp( p->vTokens->pArray[0], ".exdc" ) != 0 )
00223 {
00224 printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName,
00225 Extra_FileReaderGetLineNumber(p->pReader, 0), p->vTokens->pArray[0] );
00226 Abc_NtkDelete(pNtk);
00227 p->pNtkCur = NULL;
00228 return NULL;
00229 }
00230
00231
00232 if ( p->pNtkMaster == NULL )
00233 pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
00234 fTokensReady = fStatus = 0;
00235 for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
00236 {
00237 if ( p->pNtkMaster == NULL && iLine % 1000 == 0 )
00238 Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
00239
00240
00241 fTokensReady = 0;
00242 pDirective = p->vTokens->pArray[0];
00243 if ( !strcmp( pDirective, ".names" ) )
00244 { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; }
00245 else if ( !strcmp( pDirective, ".gate" ) )
00246 fStatus = Io_ReadBlifNetworkGate( p, p->vTokens );
00247 else if ( !strcmp( pDirective, ".latch" ) )
00248 fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens );
00249 else if ( !strcmp( pDirective, ".inputs" ) )
00250 fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
00251 else if ( !strcmp( pDirective, ".outputs" ) )
00252 fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
00253 else if ( !strcmp( pDirective, ".asserts" ) )
00254 fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens );
00255 else if ( !strcmp( pDirective, ".input_arrival" ) )
00256 fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
00257 else if ( !strcmp( pDirective, ".default_input_arrival" ) )
00258 fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
00259
00260
00261 else if ( !strcmp( pDirective, ".exdc" ) )
00262 break;
00263 else if ( !strcmp( pDirective, ".end" ) )
00264 {
00265 p->vTokens = Io_ReadBlifGetTokens(p);
00266 break;
00267 }
00268 else if ( !strcmp( pDirective, ".blackbox" ) )
00269 {
00270 pNtk->ntkType = ABC_NTK_NETLIST;
00271 pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
00272 Extra_MmFlexStop( pNtk->pManFunc );
00273 pNtk->pManFunc = NULL;
00274 }
00275 else
00276 printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
00277 Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
00278 if ( p->vTokens == NULL )
00279 break;
00280 if ( fStatus == 1 )
00281 {
00282 Extra_ProgressBarStop( pProgress );
00283 Abc_NtkDelete( pNtk );
00284 return NULL;
00285 }
00286 }
00287 if ( p->pNtkMaster == NULL )
00288 Extra_ProgressBarStop( pProgress );
00289 return pNtk;
00290 }
00291
00303 int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00304 {
00305 int i;
00306 for ( i = 1; i < vTokens->nSize; i++ )
00307 Io_ReadCreatePi( p->pNtkCur, vTokens->pArray[i] );
00308 return 0;
00309 }
00310
00322 int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00323 {
00324 int i;
00325 for ( i = 1; i < vTokens->nSize; i++ )
00326 Io_ReadCreatePo( p->pNtkCur, vTokens->pArray[i] );
00327 return 0;
00328 }
00329
00341 int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00342 {
00343 int i;
00344 for ( i = 1; i < vTokens->nSize; i++ )
00345 Io_ReadCreateAssert( p->pNtkCur, vTokens->pArray[i] );
00346 return 0;
00347 }
00348
00360 int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00361 {
00362 Abc_Ntk_t * pNtk = p->pNtkCur;
00363 Abc_Obj_t * pLatch;
00364 int ResetValue;
00365 if ( vTokens->nSize < 3 )
00366 {
00367 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00368 sprintf( p->sError, "The .latch line does not have enough tokens." );
00369 Io_ReadBlifPrintErrorMessage( p );
00370 return 1;
00371 }
00372
00373 pLatch = Io_ReadCreateLatch( pNtk, vTokens->pArray[1], vTokens->pArray[2] );
00374
00375 if ( vTokens->nSize == 3 )
00376 Abc_LatchSetInitDc( pLatch );
00377 else
00378 {
00379 ResetValue = atoi(vTokens->pArray[vTokens->nSize-1]);
00380 if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 )
00381 {
00382 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00383 sprintf( p->sError, "The .latch line has an unknown reset value (%s).", vTokens->pArray[3] );
00384 Io_ReadBlifPrintErrorMessage( p );
00385 return 1;
00386 }
00387 if ( ResetValue == 0 )
00388 Abc_LatchSetInit0( pLatch );
00389 else if ( ResetValue == 1 )
00390 Abc_LatchSetInit1( pLatch );
00391 else if ( ResetValue == 2 )
00392 Abc_LatchSetInitDc( pLatch );
00393 }
00394 return 0;
00395 }
00396
00408 int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
00409 {
00410 Vec_Ptr_t * vTokens = *pvTokens;
00411 Abc_Ntk_t * pNtk = p->pNtkCur;
00412 Abc_Obj_t * pNode;
00413 char * pToken, Char, ** ppNames;
00414 int nFanins, nNames;
00415
00416
00417 if ( vTokens->nSize < 2 )
00418 {
00419 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00420 sprintf( p->sError, "The .names line has less than two tokens." );
00421 Io_ReadBlifPrintErrorMessage( p );
00422 return 1;
00423 }
00424
00425
00426 ppNames = (char **)vTokens->pArray + 1;
00427 nNames = vTokens->nSize - 2;
00428 pNode = Io_ReadCreateNode( pNtk, ppNames[nNames], ppNames, nNames );
00429
00430
00431 p->vCubes->nSize = 0;
00432 nFanins = vTokens->nSize - 2;
00433 if ( nFanins == 0 )
00434 {
00435 while ( vTokens = Io_ReadBlifGetTokens(p) )
00436 {
00437 pToken = vTokens->pArray[0];
00438 if ( pToken[0] == '.' )
00439 break;
00440
00441 if ( vTokens->nSize != 1 )
00442 {
00443 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00444 sprintf( p->sError, "The number of tokens in the constant cube is wrong." );
00445 Io_ReadBlifPrintErrorMessage( p );
00446 return 1;
00447 }
00448
00449 Char = ((char *)vTokens->pArray[0])[0];
00450 Vec_StrPush( p->vCubes, ' ' );
00451 Vec_StrPush( p->vCubes, Char );
00452 Vec_StrPush( p->vCubes, '\n' );
00453 }
00454 }
00455 else
00456 {
00457 while ( vTokens = Io_ReadBlifGetTokens(p) )
00458 {
00459 pToken = vTokens->pArray[0];
00460 if ( pToken[0] == '.' )
00461 break;
00462
00463 if ( vTokens->nSize != 2 )
00464 {
00465 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00466 sprintf( p->sError, "The number of tokens in the cube is wrong." );
00467 Io_ReadBlifPrintErrorMessage( p );
00468 return 1;
00469 }
00470
00471 Vec_StrAppend( p->vCubes, vTokens->pArray[0] );
00472
00473 Char = ((char *)vTokens->pArray[1])[0];
00474 if ( Char != '0' && Char != '1' && Char != 'x' && Char != 'n' )
00475 {
00476 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00477 sprintf( p->sError, "The output character in the constant cube is wrong." );
00478 Io_ReadBlifPrintErrorMessage( p );
00479 return 1;
00480 }
00481 Vec_StrPush( p->vCubes, ' ' );
00482 Vec_StrPush( p->vCubes, Char );
00483 Vec_StrPush( p->vCubes, '\n' );
00484 }
00485 }
00486
00487 if ( p->vCubes->nSize == 0 )
00488 {
00489
00490 Vec_StrPush( p->vCubes, ' ' );
00491 Vec_StrPush( p->vCubes, '0' );
00492 Vec_StrPush( p->vCubes, '\n' );
00493 }
00494 Vec_StrPush( p->vCubes, 0 );
00495
00496
00497 Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, p->vCubes->pArray) );
00498
00499
00500 if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum(Abc_ObjData(pNode)) )
00501 {
00502 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00503 sprintf( p->sError, "The number of fanins (%d) of node %s is different from SOP size (%d).",
00504 Abc_ObjFaninNum(pNode), Abc_ObjName(Abc_ObjFanout(pNode,0)), Abc_SopGetVarNum(Abc_ObjData(pNode)) );
00505 Io_ReadBlifPrintErrorMessage( p );
00506 return 1;
00507 }
00508
00509
00510 *pvTokens = vTokens;
00511 return 0;
00512 }
00513
00525 int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00526 {
00527 Mio_Library_t * pGenlib;
00528 Mio_Gate_t * pGate;
00529 Abc_Obj_t * pNode;
00530 char ** ppNames;
00531 int i, nNames;
00532
00533
00534 pGenlib = Abc_FrameReadLibGen();
00535 if ( pGenlib == NULL )
00536 {
00537 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00538 sprintf( p->sError, "The current library is not available." );
00539 Io_ReadBlifPrintErrorMessage( p );
00540 return 1;
00541 }
00542
00543
00544 if ( vTokens->nSize < 2 )
00545 {
00546 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00547 sprintf( p->sError, "The .gate line has less than two tokens." );
00548 Io_ReadBlifPrintErrorMessage( p );
00549 return 1;
00550 }
00551
00552
00553 pGate = Mio_LibraryReadGateByName( pGenlib, vTokens->pArray[1] );
00554 if ( pGate == NULL )
00555 {
00556 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00557 sprintf( p->sError, "Cannot find gate \"%s\" in the library.", vTokens->pArray[1] );
00558 Io_ReadBlifPrintErrorMessage( p );
00559 return 1;
00560 }
00561
00562
00563 if ( Abc_NtkNodeNum(p->pNtkCur) == 0 )
00564 {
00565 assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP );
00566 p->pNtkCur->ntkFunc = ABC_FUNC_MAP;
00567 Extra_MmFlexStop( p->pNtkCur->pManFunc );
00568 p->pNtkCur->pManFunc = pGenlib;
00569 }
00570
00571
00572 for ( i = 2; i < vTokens->nSize; i++ )
00573 {
00574 vTokens->pArray[i] = Io_ReadBlifCleanName( vTokens->pArray[i] );
00575 if ( vTokens->pArray[i] == NULL )
00576 {
00577 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00578 sprintf( p->sError, "Invalid gate input assignment." );
00579 Io_ReadBlifPrintErrorMessage( p );
00580 return 1;
00581 }
00582 }
00583
00584
00585 ppNames = (char **)vTokens->pArray + 2;
00586 nNames = vTokens->nSize - 3;
00587 pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
00588
00589
00590 Abc_ObjSetData( pNode, pGate );
00591 return 0;
00592 }
00593
00605 int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00606 {
00607 Abc_Obj_t * pBox;
00608 Vec_Ptr_t * vNames;
00609 char * pName;
00610 int i;
00611
00612
00613 if ( vTokens->nSize < 3 )
00614 {
00615 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00616 sprintf( p->sError, "The .subcircuit line has less than three tokens." );
00617 Io_ReadBlifPrintErrorMessage( p );
00618 return 1;
00619 }
00620
00621
00622 vNames = Vec_PtrAlloc( 10 );
00623 Vec_PtrForEachEntryStart( vTokens, pName, i, 1 )
00624
00625 Vec_PtrPush( vNames, Extra_UtilStrsav(pName) );
00626
00627
00628 pBox = Abc_NtkCreateBlackbox( p->pNtkCur );
00629
00630 Abc_ObjSetData( pBox, vNames );
00631
00632 pBox->pCopy = (void *)Extra_FileReaderGetLineNumber(p->pReader, 0);
00633 return 0;
00634 }
00635
00647 char * Io_ReadBlifCleanName( char * pName )
00648 {
00649 int i, Length;
00650 Length = strlen(pName);
00651 for ( i = 0; i < Length; i++ )
00652 if ( pName[i] == '=' )
00653 return pName + i + 1;
00654 return NULL;
00655 }
00656
00668 int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00669 {
00670 Abc_Obj_t * pNet;
00671 char * pFoo1, * pFoo2;
00672 double TimeRise, TimeFall;
00673
00674
00675 assert( strncmp( vTokens->pArray[0], ".input_arrival", 14 ) == 0 );
00676 if ( vTokens->nSize != 4 )
00677 {
00678 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00679 sprintf( p->sError, "Wrong number of arguments on .input_arrival line." );
00680 Io_ReadBlifPrintErrorMessage( p );
00681 return 1;
00682 }
00683 pNet = Abc_NtkFindNet( p->pNtkCur, vTokens->pArray[1] );
00684 if ( pNet == NULL )
00685 {
00686 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00687 sprintf( p->sError, "Cannot find object corresponding to %s on .input_arrival line.", vTokens->pArray[1] );
00688 Io_ReadBlifPrintErrorMessage( p );
00689 return 1;
00690 }
00691 TimeRise = strtod( vTokens->pArray[2], &pFoo1 );
00692 TimeFall = strtod( vTokens->pArray[3], &pFoo2 );
00693 if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
00694 {
00695 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00696 sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_arrival line.", vTokens->pArray[2], vTokens->pArray[3] );
00697 Io_ReadBlifPrintErrorMessage( p );
00698 return 1;
00699 }
00700
00701 Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
00702 return 0;
00703 }
00704
00716 int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
00717 {
00718 char * pFoo1, * pFoo2;
00719 double TimeRise, TimeFall;
00720
00721
00722 assert( strncmp( vTokens->pArray[0], ".default_input_arrival", 23 ) == 0 );
00723 if ( vTokens->nSize != 3 )
00724 {
00725 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00726 sprintf( p->sError, "Wrong number of arguments on .default_input_arrival line." );
00727 Io_ReadBlifPrintErrorMessage( p );
00728 return 1;
00729 }
00730 TimeRise = strtod( vTokens->pArray[1], &pFoo1 );
00731 TimeFall = strtod( vTokens->pArray[2], &pFoo2 );
00732 if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
00733 {
00734 p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
00735 sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_arrival line.", vTokens->pArray[1], vTokens->pArray[2] );
00736 Io_ReadBlifPrintErrorMessage( p );
00737 return 1;
00738 }
00739
00740 Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall );
00741 return 0;
00742 }
00743
00755 void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
00756 {
00757 p->fError = 1;
00758 if ( p->LineCur == 0 )
00759 fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
00760 else
00761 fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
00762 }
00763
00775 Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
00776 {
00777 Vec_Ptr_t * vTokens;
00778 char * pLastToken;
00779 int i;
00780
00781
00782 if ( p->vNewTokens->nSize > 0 )
00783 {
00784 for ( i = 0; i < p->vNewTokens->nSize; i++ )
00785 free( p->vNewTokens->pArray[i] );
00786 p->vNewTokens->nSize = 0;
00787 }
00788
00789
00790 vTokens = Extra_FileReaderGetTokens(p->pReader);
00791 if ( vTokens == NULL )
00792 return vTokens;
00793
00794
00795 pLastToken = vTokens->pArray[vTokens->nSize - 1];
00796 if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
00797 return vTokens;
00798
00799
00800 pLastToken[ strlen(pLastToken)-1 ] = 0;
00801 if ( pLastToken[0] == 0 )
00802 vTokens->nSize--;
00803
00804 for ( i = 0; i < vTokens->nSize; i++ )
00805 Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
00806
00807
00808 while ( 1 )
00809 {
00810
00811 vTokens = Extra_FileReaderGetTokens(p->pReader);
00812 if ( vTokens->nSize == 0 )
00813 return p->vNewTokens;
00814
00815 pLastToken = vTokens->pArray[vTokens->nSize - 1];
00816 if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
00817 {
00818
00819 pLastToken[ strlen(pLastToken)-1 ] = 0;
00820 if ( pLastToken[0] == 0 )
00821 vTokens->nSize--;
00822
00823 for ( i = 0; i < vTokens->nSize; i++ )
00824 Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
00825 continue;
00826 }
00827
00828 for ( i = 0; i < vTokens->nSize; i++ )
00829 Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
00830 break;
00831 }
00832 return p->vNewTokens;
00833 }
00834
00846 Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
00847 {
00848 Extra_FileReader_t * pReader;
00849 Io_ReadBlif_t * p;
00850
00851
00852 pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );
00853
00854 if ( pReader == NULL )
00855 return NULL;
00856
00857
00858 p = ALLOC( Io_ReadBlif_t, 1 );
00859 memset( p, 0, sizeof(Io_ReadBlif_t) );
00860 p->pFileName = pFileName;
00861 p->pReader = pReader;
00862 p->Output = stdout;
00863 p->vNewTokens = Vec_PtrAlloc( 100 );
00864 p->vCubes = Vec_StrAlloc( 100 );
00865 return p;
00866 }
00867
00879 void Io_ReadBlifFree( Io_ReadBlif_t * p )
00880 {
00881 Extra_FileReaderFree( p->pReader );
00882 Vec_PtrFree( p->vNewTokens );
00883 Vec_StrFree( p->vCubes );
00884 free( p );
00885 }
00886
00887
00899 int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model )
00900 {
00901 Vec_Ptr_t * pNames;
00902 Abc_Ntk_t * pNtkModel;
00903 Abc_Obj_t * pObj, * pNet;
00904 char * pName, * pActual;
00905 int i, Length, Start;
00906
00907
00908 pNames = pBox->pData;
00909 if ( !stmm_lookup( tName2Model, Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) )
00910 {
00911 p->LineCur = (int)pBox->pCopy;
00912 sprintf( p->sError, "Cannot find the model for subcircuit %s.", Vec_PtrEntry(pNames, 0) );
00913 Io_ReadBlifPrintErrorMessage( p );
00914 return 1;
00915 }
00916
00917
00918 Abc_NtkForEachPi( pNtkModel, pObj, i )
00919 pObj->pCopy = NULL;
00920 if ( Abc_NtkPiNum(pNtkModel) == 0 )
00921 Start = 1;
00922 else
00923 {
00924 Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
00925 {
00926 pActual = Io_ReadBlifCleanName(pName);
00927 if ( pActual == NULL )
00928 {
00929 p->LineCur = (int)pBox->pCopy;
00930 sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
00931 Io_ReadBlifPrintErrorMessage( p );
00932 return 1;
00933 }
00934 Length = pActual - pName - 1;
00935 pName[Length] = 0;
00936
00937 pObj = Abc_NtkFindNet( pNtkModel, pName );
00938 if ( pObj == NULL )
00939 {
00940 p->LineCur = (int)pBox->pCopy;
00941 sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
00942 Io_ReadBlifPrintErrorMessage( p );
00943 return 1;
00944 }
00945
00946 pObj = Abc_ObjFanin0(pObj);
00947
00948 if ( !Abc_ObjIsPi(pObj) )
00949 {
00950 pName[Length] = '=';
00951 Start = i;
00952 break;
00953 }
00954
00955 if ( pObj->pCopy != NULL )
00956 {
00957 p->LineCur = (int)pBox->pCopy;
00958 sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
00959 Io_ReadBlifPrintErrorMessage( p );
00960 return 1;
00961 }
00962 pObj->pCopy = (void *)pActual;
00963
00964 if ( i == Abc_NtkPiNum(pNtkModel) )
00965 {
00966 Start = i+1;
00967 break;
00968 }
00969 }
00970 }
00971
00972 Abc_NtkForEachPi( pNtkModel, pObj, i )
00973 {
00974 pActual = (void *)pObj->pCopy;
00975 if ( pActual == NULL )
00976 {
00977 p->LineCur = (int)pBox->pCopy;
00978 sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
00979 Io_ReadBlifPrintErrorMessage( p );
00980 return 1;
00981 }
00982 pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
00983 Abc_ObjAddFanin( pBox, pNet );
00984 }
00985 Abc_NtkForEachPi( pNtkModel, pObj, i )
00986 pObj->pCopy = NULL;
00987
00988
00989 Abc_NtkForEachPo( pNtkModel, pObj, i )
00990 pObj->pCopy = NULL;
00991 Vec_PtrForEachEntryStart( pNames, pName, i, Start )
00992 {
00993 pActual = Io_ReadBlifCleanName(pName);
00994 if ( pActual == NULL )
00995 {
00996 p->LineCur = (int)pBox->pCopy;
00997 sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
00998 Io_ReadBlifPrintErrorMessage( p );
00999 return 1;
01000 }
01001 Length = pActual - pName - 1;
01002 pName[Length] = 0;
01003
01004 pObj = Abc_NtkFindNet( pNtkModel, pName );
01005 if ( pObj == NULL )
01006 {
01007 p->LineCur = (int)pBox->pCopy;
01008 sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
01009 Io_ReadBlifPrintErrorMessage( p );
01010 return 1;
01011 }
01012
01013 pObj = Abc_ObjFanout0(pObj);
01014 if ( pObj->pCopy != NULL )
01015 {
01016 p->LineCur = (int)pBox->pCopy;
01017 sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName );
01018 Io_ReadBlifPrintErrorMessage( p );
01019 return 1;
01020 }
01021 pObj->pCopy = (void *)pActual;
01022 }
01023
01024 Abc_NtkForEachPo( pNtkModel, pObj, i )
01025 {
01026 pActual = (void *)pObj->pCopy;
01027 if ( pActual == NULL )
01028 {
01029 p->LineCur = (int)pBox->pCopy;
01030 sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
01031 Io_ReadBlifPrintErrorMessage( p );
01032 return 1;
01033 }
01034 pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
01035 Abc_ObjAddFanin( pNet, pBox );
01036 }
01037 Abc_NtkForEachPo( pNtkModel, pObj, i )
01038 pObj->pCopy = NULL;
01039
01040
01041 Vec_PtrForEachEntry( pBox->pData, pName, i )
01042 free( pName );
01043 Vec_PtrFree( pBox->pData );
01044 pBox->pData = pNtkModel;
01045 return 0;
01046 }
01047
01059 int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model )
01060 {
01061 Abc_Obj_t * pBox;
01062 int i;
01063
01064 Abc_NtkForEachBlackbox( pNtk, pBox, i )
01065 if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
01066 return 1;
01067 Abc_NtkFinalizeRead( pNtk );
01068 return 0;
01069 }
01070
01071 #if 0
01072
01084 int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
01085 {
01086 stmm_generator * gen;
01087 Abc_Ntk_t * pNtk;
01088 char * pName;
01089
01090 if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) )
01091 return 1;
01092
01093 stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk )
01094 if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) )
01095 return 1;
01096 return 0;
01097 }
01098
01099 #endif
01100
01104
01105