00001
00021 #include "abc.h"
00022 #include "extra.h"
00023 #include "vecPtr.h"
00024
00028
00029
00030 typedef enum {
00031 IO_BLIF_INIT_NONE = 0,
00032 IO_BLIF_INIT_ZERO,
00033 IO_BLIF_INIT_ONE,
00034 IO_BLIF_INIT_DC
00035 } Io_BlifInit_t;
00036
00037 typedef struct Io_BlifObj_t_ Io_BlifObj_t;
00038 struct Io_BlifObj_t_
00039 {
00040 unsigned fPi : 1;
00041 unsigned fPo : 1;
00042 unsigned fLi : 1;
00043 unsigned fLo : 1;
00044 unsigned fDef : 1;
00045 unsigned fLoop : 1;
00046 unsigned Init : 2;
00047 unsigned Offset : 24;
00048 char * pName;
00049 void * pEquiv;
00050 Io_BlifObj_t * pNext;
00051 };
00052
00053 typedef struct Io_BlifMan_t_ Io_BlifMan_t;
00054 struct Io_BlifMan_t_
00055 {
00056
00057 char * pFileName;
00058 char * pBuffer;
00059 Vec_Ptr_t * vLines;
00060
00061 Io_BlifObj_t * pObjects;
00062 int nObjects;
00063 int iObjNext;
00064
00065 char * pModel;
00066 Vec_Ptr_t * vInputs;
00067 Vec_Ptr_t * vOutputs;
00068 Vec_Ptr_t * vLatches;
00069 Vec_Ptr_t * vNames;
00070
00071 Vec_Ptr_t * vPis;
00072 Vec_Ptr_t * vPos;
00073 Vec_Ptr_t * vLis;
00074 Vec_Ptr_t * vLos;
00075
00076 Io_BlifObj_t ** pTable;
00077 int nTableSize;
00078
00079 Abc_Ntk_t * pAig;
00080 Vec_Ptr_t * vTokens;
00081 char sError[512];
00082
00083 int nTablesRead;
00084 int nTablesLeft;
00085 };
00086
00087
00088 static Io_BlifMan_t * Io_BlifAlloc();
00089 static void Io_BlifFree( Io_BlifMan_t * p );
00090 static char * Io_BlifLoadFile( char * pFileName );
00091 static void Io_BlifReadPreparse( Io_BlifMan_t * p );
00092 static Abc_Ntk_t * Io_BlifParse( Io_BlifMan_t * p );
00093 static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine );
00094 static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine );
00095 static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine );
00096 static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine );
00097 static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine );
00098 static int Io_BlifParseConstruct( Io_BlifMan_t * p );
00099 static int Io_BlifCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; }
00100
00104
00116 Abc_Ntk_t * Io_ReadBlifAsAig( char * pFileName, int fCheck )
00117 {
00118 FILE * pFile;
00119 Io_BlifMan_t * p;
00120 Abc_Ntk_t * pAig;
00121
00122
00123 pFile = fopen( pFileName, "rb" );
00124 if ( pFile == NULL )
00125 {
00126 printf( "Io_Blif(): The file is unavailable (absent or open).\n" );
00127 return 0;
00128 }
00129 fclose( pFile );
00130
00131
00132 p = Io_BlifAlloc();
00133 p->pFileName = pFileName;
00134 p->pBuffer = Io_BlifLoadFile( pFileName );
00135 if ( p->pBuffer == NULL )
00136 {
00137 Io_BlifFree( p );
00138 return NULL;
00139 }
00140
00141 Io_BlifReadPreparse( p );
00142
00143 pAig = Io_BlifParse( p );
00144 if ( p->sError[0] )
00145 fprintf( stdout, "%s\n", p->sError );
00146 if ( pAig == NULL )
00147 return NULL;
00148 Io_BlifFree( p );
00149
00150
00151 if ( fCheck && !Abc_NtkCheckRead( pAig ) )
00152 {
00153 printf( "Io_Blif: The network check has failed.\n" );
00154 Abc_NtkDelete( pAig );
00155 return NULL;
00156 }
00157 return pAig;
00158 }
00159
00171 static Io_BlifMan_t * Io_BlifAlloc()
00172 {
00173 Io_BlifMan_t * p;
00174 p = ALLOC( Io_BlifMan_t, 1 );
00175 memset( p, 0, sizeof(Io_BlifMan_t) );
00176 p->vLines = Vec_PtrAlloc( 512 );
00177 p->vInputs = Vec_PtrAlloc( 512 );
00178 p->vOutputs = Vec_PtrAlloc( 512 );
00179 p->vLatches = Vec_PtrAlloc( 512 );
00180 p->vNames = Vec_PtrAlloc( 512 );
00181 p->vTokens = Vec_PtrAlloc( 512 );
00182 p->vPis = Vec_PtrAlloc( 512 );
00183 p->vPos = Vec_PtrAlloc( 512 );
00184 p->vLis = Vec_PtrAlloc( 512 );
00185 p->vLos = Vec_PtrAlloc( 512 );
00186 return p;
00187 }
00188
00200 static void Io_BlifFree( Io_BlifMan_t * p )
00201 {
00202 if ( p->pAig )
00203 Abc_NtkDelete( p->pAig );
00204 if ( p->pBuffer ) free( p->pBuffer );
00205 if ( p->pObjects ) free( p->pObjects );
00206 if ( p->pTable ) free( p->pTable );
00207 Vec_PtrFree( p->vLines );
00208 Vec_PtrFree( p->vInputs );
00209 Vec_PtrFree( p->vOutputs );
00210 Vec_PtrFree( p->vLatches );
00211 Vec_PtrFree( p->vNames );
00212 Vec_PtrFree( p->vTokens );
00213 Vec_PtrFree( p->vPis );
00214 Vec_PtrFree( p->vPos );
00215 Vec_PtrFree( p->vLis );
00216 Vec_PtrFree( p->vLos );
00217 free( p );
00218 }
00219
00220
00232 static unsigned Io_BlifHashString( char * pName, int TableSize )
00233 {
00234 static int s_Primes[10] = {
00235 1291, 1699, 2357, 4177, 5147,
00236 5647, 6343, 7103, 7873, 8147
00237 };
00238 unsigned i, Key = 0;
00239 for ( i = 0; pName[i] != '\0'; i++ )
00240 Key ^= s_Primes[i%10]*pName[i]*pName[i];
00241 return Key % TableSize;
00242 }
00243
00255 static Io_BlifObj_t ** Io_BlifHashLookup( Io_BlifMan_t * p, char * pName )
00256 {
00257 Io_BlifObj_t ** ppEntry;
00258 for ( ppEntry = p->pTable + Io_BlifHashString(pName, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
00259 if ( !strcmp((*ppEntry)->pName, pName) )
00260 return ppEntry;
00261 return ppEntry;
00262 }
00263
00275 static Io_BlifObj_t * Io_BlifHashFindOrAdd( Io_BlifMan_t * p, char * pName )
00276 {
00277 Io_BlifObj_t ** ppEntry;
00278 ppEntry = Io_BlifHashLookup( p, pName );
00279 if ( *ppEntry == NULL )
00280 {
00281 assert( p->iObjNext < p->nObjects );
00282 *ppEntry = p->pObjects + p->iObjNext++;
00283 (*ppEntry)->pName = pName;
00284 }
00285 return *ppEntry;
00286 }
00287
00288
00300 static void Io_BlifCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput )
00301 {
00302 char * pCur;
00303 Vec_PtrClear( vTokens );
00304 for ( pCur = pInput; pCur < pOutput; pCur++ )
00305 {
00306 if ( *pCur == 0 )
00307 continue;
00308 Vec_PtrPush( vTokens, pCur );
00309 while ( *++pCur );
00310 }
00311 }
00312
00324 static void Io_BlifSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop )
00325 {
00326 char * pCur;
00327
00328 for ( pCur = pLine; *pCur != Stop; pCur++ )
00329 if ( Io_BlifCharIsSpace(*pCur) )
00330 *pCur = 0;
00331
00332 Io_BlifCollectTokens( vTokens, pLine, pCur );
00333 }
00334
00346 static int Io_BlifGetLine( Io_BlifMan_t * p, char * pToken )
00347 {
00348 char * pLine;
00349 int i;
00350 Vec_PtrForEachEntry( p->vLines, pLine, i )
00351 if ( pToken < pLine )
00352 return i;
00353 return -1;
00354 }
00355
00367 static int Io_BlifEstimatePiNum( Io_BlifMan_t * p )
00368 {
00369 char * pCur;
00370 int i, fSpaces;
00371 int Counter = 0;
00372 Vec_PtrForEachEntry( p->vInputs, pCur, i )
00373 for ( fSpaces = 0; *pCur; pCur++ )
00374 {
00375 if ( Io_BlifCharIsSpace(*pCur) )
00376 {
00377 if ( !fSpaces )
00378 Counter++;
00379 fSpaces = 1;
00380 }
00381 else
00382 fSpaces = 0;
00383 }
00384 return Counter;
00385 }
00386
00398 static int Io_BlifEstimateAndNum( Io_BlifMan_t * p )
00399 {
00400 Io_BlifObj_t * pObj;
00401 char * pCur;
00402 int i, CounterOne, Counter = 0;
00403 for ( i = 0; i < p->iObjNext; i++ )
00404 {
00405 pObj = p->pObjects + i;
00406 if ( !pObj->fDef )
00407 continue;
00408 CounterOne = 0;
00409 for ( pCur = pObj->pName + strlen(pObj->pName); *pCur != '.'; pCur++ )
00410 if ( *pCur == '0' || *pCur == '1' )
00411 CounterOne++;
00412 if ( CounterOne )
00413 Counter += CounterOne - 1;
00414 }
00415 return Counter;
00416 }
00417
00429 static char * Io_BlifLoadFile( char * pFileName )
00430 {
00431 FILE * pFile;
00432 int nFileSize;
00433 char * pContents;
00434 pFile = fopen( pFileName, "rb" );
00435 if ( pFile == NULL )
00436 {
00437 printf( "Io_BlifLoadFile(): The file is unavailable (absent or open).\n" );
00438 return NULL;
00439 }
00440 fseek( pFile, 0, SEEK_END );
00441 nFileSize = ftell( pFile );
00442 if ( nFileSize == 0 )
00443 {
00444 printf( "Io_BlifLoadFile(): The file is empty.\n" );
00445 return NULL;
00446 }
00447 pContents = ALLOC( char, nFileSize + 10 );
00448 rewind( pFile );
00449 fread( pContents, nFileSize, 1, pFile );
00450 fclose( pFile );
00451
00452
00453 strcpy( pContents + nFileSize, "\n.end\n" );
00454 return pContents;
00455 }
00456
00474 static void Io_BlifReadPreparse( Io_BlifMan_t * p )
00475 {
00476 char * pCur, * pPrev;
00477 int i, fComment = 0;
00478
00479 Vec_PtrPush( p->vLines, p->pBuffer );
00480 for ( pCur = p->pBuffer; *pCur; pCur++ )
00481 {
00482 if ( *pCur == '\n' )
00483 {
00484 *pCur = 0;
00485 fComment = 0;
00486 Vec_PtrPush( p->vLines, pCur + 1 );
00487 }
00488 else if ( *pCur == '#' )
00489 fComment = 1;
00490
00491 if ( fComment )
00492 *pCur = 0;
00493 }
00494
00495
00496 Vec_PtrForEachEntry( p->vLines, pCur, i )
00497 {
00498 if ( *pCur == 0 )
00499 continue;
00500
00501 for ( pPrev = pCur - 2; pPrev >= p->pBuffer; pPrev-- )
00502 if ( !Io_BlifCharIsSpace(*pPrev) )
00503 break;
00504
00505 if ( *pPrev == '\\' )
00506 {
00507 for ( ; *pPrev; pPrev++ )
00508 *pPrev = ' ';
00509 *pPrev = ' ';
00510 continue;
00511 }
00512
00513 while ( Io_BlifCharIsSpace(*pCur++) );
00514
00515 if ( *(pCur-1) != '.' )
00516 continue;
00517 if ( !strncmp(pCur, "names", 5) )
00518 Vec_PtrPush( p->vNames, pCur );
00519 else if ( !strncmp(pCur, "latch", 5) )
00520 Vec_PtrPush( p->vLatches, pCur );
00521 else if ( !strncmp(pCur, "inputs", 6) )
00522 Vec_PtrPush( p->vInputs, pCur );
00523 else if ( !strncmp(pCur, "outputs", 7) )
00524 Vec_PtrPush( p->vOutputs, pCur );
00525 else if ( !strncmp(pCur, "model", 5) )
00526 p->pModel = pCur;
00527 else if ( !strncmp(pCur, "end", 3) || !strncmp(pCur, "exdc", 4) )
00528 break;
00529 else
00530 {
00531 pCur--;
00532 if ( pCur[strlen(pCur)-1] == '\r' )
00533 pCur[strlen(pCur)-1] = 0;
00534 fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Io_BlifGetLine(p, pCur), pCur );
00535 }
00536 }
00537
00538
00539 p->nObjects = Io_BlifEstimatePiNum(p) + Vec_PtrSize(p->vLatches) + Vec_PtrSize(p->vNames) + 512;
00540
00541
00542 p->pObjects = ALLOC( Io_BlifObj_t, p->nObjects );
00543 memset( p->pObjects, 0, p->nObjects * sizeof(Io_BlifObj_t) );
00544
00545
00546 p->nTableSize = p->nObjects/2 + 1;
00547 p->pTable = ALLOC( Io_BlifObj_t *, p->nTableSize );
00548 memset( p->pTable, 0, p->nTableSize * sizeof(Io_BlifObj_t *) );
00549 }
00550
00551
00563 static Abc_Ntk_t * Io_BlifParse( Io_BlifMan_t * p )
00564 {
00565 Abc_Ntk_t * pAig;
00566 char * pLine;
00567 int i;
00568
00569 if ( !Io_BlifParseModel( p, p->pModel ) )
00570 return NULL;
00571
00572 Vec_PtrForEachEntry( p->vInputs, pLine, i )
00573 if ( !Io_BlifParseInputs( p, pLine ) )
00574 return NULL;
00575
00576 Vec_PtrForEachEntry( p->vOutputs, pLine, i )
00577 if ( !Io_BlifParseOutputs( p, pLine ) )
00578 return NULL;
00579
00580 Vec_PtrForEachEntry( p->vLatches, pLine, i )
00581 if ( !Io_BlifParseLatch( p, pLine ) )
00582 return NULL;
00583
00584 Vec_PtrForEachEntry( p->vNames, pLine, i )
00585 if ( !Io_BlifParseNames( p, pLine ) )
00586 return NULL;
00587
00588 if ( !Io_BlifParseConstruct( p ) )
00589 return NULL;
00590
00591 pAig = p->pAig;
00592 p->pAig = NULL;
00593 return pAig;
00594 }
00595
00607 static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine )
00608 {
00609 char * pToken;
00610 Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
00611 pToken = Vec_PtrEntry( p->vTokens, 0 );
00612 assert( !strcmp(pToken, "model") );
00613 if ( Vec_PtrSize(p->vTokens) != 2 )
00614 {
00615 sprintf( p->sError, "Line %d: Model line has %d entries while it should have 2.", Io_BlifGetLine(p, pToken), Vec_PtrSize(p->vTokens) );
00616 return 0;
00617 }
00618 p->pModel = Vec_PtrEntry( p->vTokens, 1 );
00619 return 1;
00620 }
00621
00633 static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine )
00634 {
00635 Io_BlifObj_t * pObj;
00636 char * pToken;
00637 int i;
00638 Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
00639 pToken = Vec_PtrEntry(p->vTokens, 0);
00640 assert( !strcmp(pToken, "inputs") );
00641 Vec_PtrForEachEntryStart( p->vTokens, pToken, i, 1 )
00642 {
00643 pObj = Io_BlifHashFindOrAdd( p, pToken );
00644 if ( pObj->fPi )
00645 {
00646 sprintf( p->sError, "Line %d: Primary input (%s) is defined more than once.", Io_BlifGetLine(p, pToken), pToken );
00647 return 0;
00648 }
00649 pObj->fPi = 1;
00650 Vec_PtrPush( p->vPis, pObj );
00651 }
00652 return 1;
00653 }
00654
00666 static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine )
00667 {
00668 Io_BlifObj_t * pObj;
00669 char * pToken;
00670 int i;
00671 Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
00672 pToken = Vec_PtrEntry(p->vTokens, 0);
00673 assert( !strcmp(pToken, "outputs") );
00674 Vec_PtrForEachEntryStart( p->vTokens, pToken, i, 1 )
00675 {
00676 pObj = Io_BlifHashFindOrAdd( p, pToken );
00677 if ( pObj->fPo )
00678 fprintf( stdout, "Line %d: Primary output (%s) is defined more than once (warning only).\n", Io_BlifGetLine(p, pToken), pToken );
00679 pObj->fPo = 1;
00680 Vec_PtrPush( p->vPos, pObj );
00681 }
00682 return 1;
00683 }
00684
00696 static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine )
00697 {
00698 Io_BlifObj_t * pObj;
00699 char * pToken;
00700 int Init;
00701 Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
00702 pToken = Vec_PtrEntry(p->vTokens,0);
00703 assert( !strcmp(pToken, "latch") );
00704 if ( Vec_PtrSize(p->vTokens) < 3 )
00705 {
00706 sprintf( p->sError, "Line %d: Latch does not have input name and output name.", Io_BlifGetLine(p, pToken) );
00707 return 0;
00708 }
00709
00710 if ( Vec_PtrSize(p->vTokens) > 3 )
00711 Init = atoi( Vec_PtrEntry(p->vTokens,3) );
00712 else
00713 Init = 2;
00714 if ( Init < 0 || Init > 2 )
00715 {
00716 sprintf( p->sError, "Line %d: Initial state of the latch is incorrect (%s).", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,3) );
00717 return 0;
00718 }
00719 if ( Init == 0 )
00720 Init = IO_BLIF_INIT_ZERO;
00721 else if ( Init == 1 )
00722 Init = IO_BLIF_INIT_ONE;
00723 else
00724 Init = IO_BLIF_INIT_DC;
00725
00726 pObj = Io_BlifHashFindOrAdd( p, Vec_PtrEntry(p->vTokens,1) );
00727 pObj->fLi = 1;
00728 Vec_PtrPush( p->vLis, pObj );
00729 pObj->Init = Init;
00730
00731 pObj = Io_BlifHashFindOrAdd( p, Vec_PtrEntry(p->vTokens,2) );
00732 if ( pObj->fPi )
00733 {
00734 sprintf( p->sError, "Line %d: Primary input (%s) is also defined latch output.", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,2) );
00735 return 0;
00736 }
00737 if ( pObj->fLo )
00738 {
00739 sprintf( p->sError, "Line %d: Latch output (%s) is defined as the output of another latch.", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,2) );
00740 return 0;
00741 }
00742 pObj->fLo = 1;
00743 Vec_PtrPush( p->vLos, pObj );
00744 pObj->Init = Init;
00745 return 1;
00746 }
00747
00759 static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine )
00760 {
00761 Io_BlifObj_t * pObj;
00762 char * pName;
00763 Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
00764 assert( !strcmp(Vec_PtrEntry(p->vTokens,0), "names") );
00765 pName = Vec_PtrEntryLast( p->vTokens );
00766 pObj = Io_BlifHashFindOrAdd( p, pName );
00767 if ( pObj->fPi )
00768 {
00769 sprintf( p->sError, "Line %d: Primary input (%s) has a table.", Io_BlifGetLine(p, pName), pName );
00770 return 0;
00771 }
00772 if ( pObj->fLo )
00773 {
00774 sprintf( p->sError, "Line %d: Latch output (%s) has a table.", Io_BlifGetLine(p, pName), pName );
00775 return 0;
00776 }
00777 if ( pObj->fDef )
00778 {
00779 sprintf( p->sError, "Line %d: Signal (%s) is defined more than once.", Io_BlifGetLine(p, pName), pName );
00780 return 0;
00781 }
00782 pObj->fDef = 1;
00783
00784 pObj->pName = pName;
00785 pObj->Offset = pObj->pName - (char *)Vec_PtrEntry(p->vTokens,1);
00786 return 1;
00787 }
00788
00789
00801 static Abc_Obj_t * Io_BlifParseTable( Io_BlifMan_t * p, char * pTable, Vec_Ptr_t * vFanins )
00802 {
00803 char * pProduct, * pOutput;
00804 Abc_Obj_t * pRes, * pCube;
00805 int i, k, Polarity = -1;
00806
00807 p->nTablesRead++;
00808
00809 Io_BlifSplitIntoTokens( p->vTokens, pTable, '.' );
00810 if ( Vec_PtrSize(p->vTokens) == 0 )
00811 return Abc_ObjNot( Abc_AigConst1(p->pAig) );
00812 if ( Vec_PtrSize(p->vTokens) == 1 )
00813 {
00814 pOutput = Vec_PtrEntry( p->vTokens, 0 );
00815 if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
00816 {
00817 sprintf( p->sError, "Line %d: Constant table has wrong output value (%s).", Io_BlifGetLine(p, pOutput), pOutput );
00818 return NULL;
00819 }
00820 return Abc_ObjNotCond( Abc_AigConst1(p->pAig), pOutput[0] == '0' );
00821 }
00822 pProduct = Vec_PtrEntry( p->vTokens, 0 );
00823 if ( Vec_PtrSize(p->vTokens) % 2 == 1 )
00824 {
00825 sprintf( p->sError, "Line %d: Table has odd number of tokens (%d).", Io_BlifGetLine(p, pProduct), Vec_PtrSize(p->vTokens) );
00826 return NULL;
00827 }
00828
00829 pRes = Abc_ObjNot( Abc_AigConst1(p->pAig) );
00830 for ( i = 0; i < Vec_PtrSize(p->vTokens)/2; i++ )
00831 {
00832 pProduct = Vec_PtrEntry( p->vTokens, 2*i + 0 );
00833 pOutput = Vec_PtrEntry( p->vTokens, 2*i + 1 );
00834 if ( strlen(pProduct) != (unsigned)Vec_PtrSize(vFanins) )
00835 {
00836 sprintf( p->sError, "Line %d: Cube (%s) has size different from the fanin count (%d).", Io_BlifGetLine(p, pProduct), pProduct, Vec_PtrSize(vFanins) );
00837 return NULL;
00838 }
00839 if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
00840 {
00841 sprintf( p->sError, "Line %d: Output value (%s) is incorrect.", Io_BlifGetLine(p, pProduct), pOutput );
00842 return NULL;
00843 }
00844 if ( Polarity == -1 )
00845 Polarity = pOutput[0] - '0';
00846 else if ( Polarity != pOutput[0] - '0' )
00847 {
00848 sprintf( p->sError, "Line %d: Output value (%s) differs from the value in the first line of the table (%d).", Io_BlifGetLine(p, pProduct), pOutput, Polarity );
00849 return NULL;
00850 }
00851
00852 pCube = Abc_AigConst1(p->pAig);
00853 for ( k = 0; pProduct[k]; k++ )
00854 {
00855 if ( pProduct[k] == '0' )
00856 pCube = Abc_AigAnd( p->pAig->pManFunc, pCube, Abc_ObjNot(Vec_PtrEntry(vFanins,k)) );
00857 else if ( pProduct[k] == '1' )
00858 pCube = Abc_AigAnd( p->pAig->pManFunc, pCube, Vec_PtrEntry(vFanins,k) );
00859 else if ( pProduct[k] != '-' )
00860 {
00861 sprintf( p->sError, "Line %d: Product term (%s) contains character (%c).", Io_BlifGetLine(p, pProduct), pProduct, pProduct[k] );
00862 return NULL;
00863 }
00864 }
00865 pRes = Abc_AigOr( p->pAig->pManFunc, pRes, pCube );
00866 }
00867 pRes = Abc_ObjNotCond( pRes, Polarity == 0 );
00868 return pRes;
00869 }
00870
00882 static Abc_Obj_t * Io_BlifParseConstruct_rec( Io_BlifMan_t * p, char * pName )
00883 {
00884 Vec_Ptr_t * vFanins;
00885 Abc_Obj_t * pFaninAbc;
00886 Io_BlifObj_t * pObjIo;
00887 char * pNameFanin;
00888 int i;
00889
00890 pObjIo = *Io_BlifHashLookup( p, pName );
00891 if ( pObjIo == NULL )
00892 {
00893 sprintf( p->sError, "Line %d: Signal (%s) is not defined as a table.", Io_BlifGetLine(p, pName), pName );
00894 return NULL;
00895 }
00896
00897 if ( pObjIo->fLoop )
00898 {
00899 sprintf( p->sError, "Line %d: Signal (%s) appears twice on a combinational path.", Io_BlifGetLine(p, pName), pName );
00900 return NULL;
00901 }
00902
00903 if ( pObjIo->pEquiv )
00904 return pObjIo->pEquiv;
00905
00906 pObjIo->fLoop = 1;
00907
00908 vFanins = Vec_PtrAlloc( 8 );
00909 Io_BlifCollectTokens( vFanins, pObjIo->pName - pObjIo->Offset, pObjIo->pName );
00910 Vec_PtrForEachEntry( vFanins, pNameFanin, i )
00911 {
00912 pFaninAbc = Io_BlifParseConstruct_rec( p, pNameFanin );
00913 if ( pFaninAbc == NULL )
00914 {
00915 Vec_PtrFree( vFanins );
00916 return NULL;
00917 }
00918 Vec_PtrWriteEntry( vFanins, i, pFaninAbc );
00919 }
00920
00921 pObjIo->pEquiv = Io_BlifParseTable( p, pObjIo->pName + strlen(pObjIo->pName), vFanins );
00922 Vec_PtrFree( vFanins );
00923
00924 pObjIo->fLoop = 0;
00925
00926 return pObjIo->pEquiv;
00927 }
00928
00940 static int Io_BlifParseConstruct( Io_BlifMan_t * p )
00941 {
00942 Abc_Ntk_t * pAig;
00943 Io_BlifObj_t * pObjIo, * pObjIoInput;
00944 Abc_Obj_t * pObj, * pLatch;
00945 int i;
00946
00947 pAig = p->pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
00948 pAig->pName = Extra_UtilStrsav( p->pModel );
00949 pAig->pSpec = Extra_UtilStrsav( p->pFileName );
00950
00951 Vec_PtrForEachEntry( p->vPis, pObjIo, i )
00952 {
00953 pObj = Abc_NtkCreatePi( pAig );
00954 Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
00955 pObjIo->pEquiv = pObj;
00956 }
00957
00958 Vec_PtrForEachEntry( p->vPos, pObjIo, i )
00959 {
00960 pObj = Abc_NtkCreatePo( pAig );
00961 Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
00962 }
00963
00964 Vec_PtrForEachEntry( p->vLos, pObjIo, i )
00965 {
00966
00967 pObj = Abc_NtkCreateBi( pAig );
00968 pObjIoInput = Vec_PtrEntry( p->vLis, i );
00969 Abc_ObjAssignName( pObj, pObjIoInput->pName, NULL );
00970
00971
00972 pLatch = Abc_NtkCreateLatch( pAig );
00973 pLatch->pData = (void *)pObjIo->Init;
00974 Abc_ObjAssignName( pLatch, pObjIo->pName, "L" );
00975 Abc_ObjAddFanin( pLatch, pObj );
00976
00977
00978 pObj = Abc_NtkCreateBo( pAig );
00979 Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
00980 Abc_ObjAddFanin( pObj, pLatch );
00981
00982
00983 pObjIo->pEquiv = pObj;
00984 }
00985
00986 Vec_PtrForEachEntry( p->vPos, pObjIo, i )
00987 {
00988 pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
00989 if ( pObj == NULL )
00990 return 0;
00991 Abc_ObjAddFanin( Abc_NtkPo(p->pAig, i), pObj );
00992 }
00993
00994 Vec_PtrForEachEntry( p->vLis, pObjIo, i )
00995 {
00996 pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
00997 if ( pObj == NULL )
00998 return 0;
00999
01000 Abc_ObjAddFanin( Abc_ObjFanin0(Abc_NtkBox(p->pAig, i)), pObj );
01001 }
01002 p->nTablesLeft = Vec_PtrSize(p->vNames) - p->nTablesRead;
01003 if ( p->nTablesLeft )
01004 printf( "The number of dangling tables = %d.\n", p->nTablesLeft );
01005 printf( "AND nodes = %6d. Estimate = %6d.\n", Abc_NtkNodeNum(p->pAig), Io_BlifEstimateAndNum(p) );
01006 return 1;
01007 }
01008
01012
01013