92static char * Io_BlifLoadFile(
char * pFileName );
95static int Io_BlifParseModel(
Io_BlifMan_t *
p,
char * pLine );
96static int Io_BlifParseInputs(
Io_BlifMan_t *
p,
char * pLine );
97static int Io_BlifParseOutputs(
Io_BlifMan_t *
p,
char * pLine );
98static int Io_BlifParseLatch(
Io_BlifMan_t *
p,
char * pLine );
99static int Io_BlifParseNames(
Io_BlifMan_t *
p,
char * pLine );
101static int Io_BlifCharIsSpace(
char s ) {
return s ==
' ' || s ==
'\t' || s ==
'\r' || s ==
'\n'; }
125 pFile = fopen( pFileName,
"rb" );
128 printf(
"Io_Blif(): The file is unavailable (absent or open).\n" );
135 p->pFileName = pFileName;
136 p->pBuffer = Io_BlifLoadFile( pFileName );
137 if (
p->pBuffer == NULL )
143 Io_BlifReadPreparse(
p );
145 pAig = Io_BlifParse(
p );
147 fprintf( stdout,
"%s\n",
p->sError );
155 printf(
"Io_Blif: The network check has failed.\n" );
178 p->vLines = Vec_PtrAlloc( 512 );
179 p->vInputs = Vec_PtrAlloc( 512 );
180 p->vOutputs = Vec_PtrAlloc( 512 );
181 p->vLatches = Vec_PtrAlloc( 512 );
182 p->vNames = Vec_PtrAlloc( 512 );
183 p->vTokens = Vec_PtrAlloc( 512 );
184 p->vPis = Vec_PtrAlloc( 512 );
185 p->vPos = Vec_PtrAlloc( 512 );
186 p->vLis = Vec_PtrAlloc( 512 );
187 p->vLos = Vec_PtrAlloc( 512 );
209 Vec_PtrFree(
p->vLines );
210 Vec_PtrFree(
p->vInputs );
211 Vec_PtrFree(
p->vOutputs );
212 Vec_PtrFree(
p->vLatches );
213 Vec_PtrFree(
p->vNames );
214 Vec_PtrFree(
p->vTokens );
215 Vec_PtrFree(
p->vPis );
216 Vec_PtrFree(
p->vPos );
217 Vec_PtrFree(
p->vLis );
218 Vec_PtrFree(
p->vLos );
234static unsigned Io_BlifHashString(
char * pName,
int TableSize )
236 static int s_Primes[10] = {
237 1291, 1699, 2357, 4177, 5147,
238 5647, 6343, 7103, 7873, 8147
241 for ( i = 0; pName[i] !=
'\0'; i++ )
242 Key ^= s_Primes[i%10]*pName[i]*pName[i];
243 return Key % TableSize;
260 for ( ppEntry =
p->pTable + Io_BlifHashString(pName,
p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
261 if ( !
strcmp((*ppEntry)->pName, pName) )
280 ppEntry = Io_BlifHashLookup(
p, pName );
281 if ( *ppEntry == NULL )
283 assert(
p->iObjNext <
p->nObjects );
284 *ppEntry =
p->pObjects +
p->iObjNext++;
285 (*ppEntry)->pName = pName;
302static void Io_BlifCollectTokens(
Vec_Ptr_t * vTokens,
char * pInput,
char * pOutput )
305 Vec_PtrClear( vTokens );
306 for ( pCur = pInput; pCur < pOutput; pCur++ )
310 Vec_PtrPush( vTokens, pCur );
326static void Io_BlifSplitIntoTokens(
Vec_Ptr_t * vTokens,
char * pLine,
char Stop )
330 for ( pCur = pLine; *pCur != Stop; pCur++ )
331 if ( Io_BlifCharIsSpace(*pCur) )
334 Io_BlifCollectTokens( vTokens, pLine, pCur );
353 if ( pToken < pLine )
375 for ( fSpaces = 0; *pCur; pCur++ )
377 if ( Io_BlifCharIsSpace(*pCur) )
404 int i, CounterOne, Counter = 0;
405 for ( i = 0; i <
p->iObjNext; i++ )
407 pObj =
p->pObjects + i;
412 if ( *pCur ==
'0' || *pCur ==
'1' )
415 Counter += CounterOne - 1;
431static char * Io_BlifLoadFile(
char * pFileName )
437 pFile = fopen( pFileName,
"rb" );
440 printf(
"Io_BlifLoadFile(): The file is unavailable (absent or open).\n" );
444 nFileSize = ftell( pFile );
445 if ( nFileSize == 0 )
448 printf(
"Io_BlifLoadFile(): The file is empty.\n" );
451 pContents =
ABC_ALLOC(
char, nFileSize + 10 );
453 RetValue = fread( pContents, nFileSize, 1, pFile );
457 strcpy( pContents + nFileSize,
"\n.end\n" );
480 char * pCur, * pPrev;
483 Vec_PtrPush(
p->vLines,
p->pBuffer );
484 for ( pCur =
p->pBuffer; *pCur; pCur++ )
490 Vec_PtrPush(
p->vLines, pCur + 1 );
492 else if ( *pCur ==
'#' )
505 for ( pPrev = pCur - 2; pPrev >=
p->pBuffer; pPrev-- )
506 if ( !Io_BlifCharIsSpace(*pPrev) )
509 if ( *pPrev ==
'\\' )
511 for ( ; *pPrev; pPrev++ )
517 while ( Io_BlifCharIsSpace(*pCur++) );
519 if ( *(pCur-1) !=
'.' )
521 if ( !
strncmp(pCur,
"names", 5) )
522 Vec_PtrPush(
p->vNames, pCur );
523 else if ( !
strncmp(pCur,
"latch", 5) )
524 Vec_PtrPush(
p->vLatches, pCur );
525 else if ( !
strncmp(pCur,
"inputs", 6) )
526 Vec_PtrPush(
p->vInputs, pCur );
527 else if ( !
strncmp(pCur,
"outputs", 7) )
528 Vec_PtrPush(
p->vOutputs, pCur );
529 else if ( !
strncmp(pCur,
"model", 5) )
536 if ( pCur[
strlen(pCur)-1] ==
'\r' )
538 fprintf( stdout,
"Line %d: Skipping line \"%s\".\n", Io_BlifGetLine(
p, pCur), pCur );
543 p->nObjects = Io_BlifEstimatePiNum(
p) + Vec_PtrSize(
p->vLatches) + Vec_PtrSize(
p->vNames) + 512;
550 p->nTableSize =
p->nObjects/2 + 1;
573 if ( !Io_BlifParseModel(
p,
p->pModel ) )
577 if ( !Io_BlifParseInputs(
p, pLine ) )
581 if ( !Io_BlifParseOutputs(
p, pLine ) )
585 if ( !Io_BlifParseLatch(
p, pLine ) )
589 if ( !Io_BlifParseNames(
p, pLine ) )
592 if ( !Io_BlifParseConstruct(
p ) )
611static int Io_BlifParseModel(
Io_BlifMan_t *
p,
char * pLine )
614 Io_BlifSplitIntoTokens(
p->vTokens, pLine,
'\0' );
615 pToken = (
char *)Vec_PtrEntry(
p->vTokens, 0 );
617 if ( Vec_PtrSize(
p->vTokens) != 2 )
619 sprintf(
p->sError,
"Line %d: Model line has %d entries while it should have 2.", Io_BlifGetLine(
p, pToken), Vec_PtrSize(
p->vTokens) );
622 p->pModel = (
char *)Vec_PtrEntry(
p->vTokens, 1 );
637static int Io_BlifParseInputs(
Io_BlifMan_t *
p,
char * pLine )
642 Io_BlifSplitIntoTokens(
p->vTokens, pLine,
'\0' );
643 pToken = (
char *)Vec_PtrEntry(
p->vTokens, 0);
647 pObj = Io_BlifHashFindOrAdd(
p, pToken );
650 sprintf(
p->sError,
"Line %d: Primary input (%s) is defined more than once.", Io_BlifGetLine(
p, pToken), pToken );
654 Vec_PtrPush(
p->vPis, pObj );
670static int Io_BlifParseOutputs(
Io_BlifMan_t *
p,
char * pLine )
675 Io_BlifSplitIntoTokens(
p->vTokens, pLine,
'\0' );
676 pToken = (
char *)Vec_PtrEntry(
p->vTokens, 0);
680 pObj = Io_BlifHashFindOrAdd(
p, pToken );
682 fprintf( stdout,
"Line %d: Primary output (%s) is defined more than once (warning only).\n", Io_BlifGetLine(
p, pToken), pToken );
684 Vec_PtrPush(
p->vPos, pObj );
700static int Io_BlifParseLatch(
Io_BlifMan_t *
p,
char * pLine )
705 Io_BlifSplitIntoTokens(
p->vTokens, pLine,
'\0' );
706 pToken = (
char *)Vec_PtrEntry(
p->vTokens,0);
708 if ( Vec_PtrSize(
p->vTokens) < 3 )
710 sprintf(
p->sError,
"Line %d: Latch does not have input name and output name.", Io_BlifGetLine(
p, pToken) );
714 if ( Vec_PtrSize(
p->vTokens) > 3 )
715 Init = atoi( (
char *)Vec_PtrEntry(
p->vTokens,3) );
718 if ( Init < 0 || Init > 2 )
720 sprintf(
p->sError,
"Line %d: Initial state of the latch is incorrect (%s).", Io_BlifGetLine(
p, pToken), (
char*)Vec_PtrEntry(
p->vTokens,3) );
725 else if ( Init == 1 )
730 pObj = Io_BlifHashFindOrAdd(
p, (
char *)Vec_PtrEntry(
p->vTokens,1) );
732 Vec_PtrPush(
p->vLis, pObj );
735 pObj = Io_BlifHashFindOrAdd(
p, (
char *)Vec_PtrEntry(
p->vTokens,2) );
738 sprintf(
p->sError,
"Line %d: Primary input (%s) is also defined latch output.", Io_BlifGetLine(
p, pToken), (
char*)Vec_PtrEntry(
p->vTokens,2) );
743 sprintf(
p->sError,
"Line %d: Latch output (%s) is defined as the output of another latch.", Io_BlifGetLine(
p, pToken), (
char*)Vec_PtrEntry(
p->vTokens,2) );
747 Vec_PtrPush(
p->vLos, pObj );
763static int Io_BlifParseNames(
Io_BlifMan_t *
p,
char * pLine )
767 Io_BlifSplitIntoTokens(
p->vTokens, pLine,
'\0' );
768 assert( !
strcmp((
char *)Vec_PtrEntry(
p->vTokens,0),
"names") );
769 pName = (
char *)Vec_PtrEntryLast(
p->vTokens );
770 pObj = Io_BlifHashFindOrAdd(
p, pName );
773 sprintf(
p->sError,
"Line %d: Primary input (%s) has a table.", Io_BlifGetLine(
p, pName), pName );
778 sprintf(
p->sError,
"Line %d: Latch output (%s) has a table.", Io_BlifGetLine(
p, pName), pName );
783 sprintf(
p->sError,
"Line %d: Signal (%s) is defined more than once.", Io_BlifGetLine(
p, pName), pName );
789 pObj->
Offset = pObj->
pName - (
char *)Vec_PtrEntry(
p->vTokens,1);
807 char * pProduct, * pOutput;
809 int i, k, Polarity = -1;
813 Io_BlifSplitIntoTokens(
p->vTokens, pTable,
'.' );
814 if ( Vec_PtrSize(
p->vTokens) == 0 )
816 if ( Vec_PtrSize(
p->vTokens) == 1 )
818 pOutput = (
char *)Vec_PtrEntry(
p->vTokens, 0 );
819 if ( ((pOutput[0] -
'0') & 0x8E) || pOutput[1] )
821 sprintf(
p->sError,
"Line %d: Constant table has wrong output value (%s).", Io_BlifGetLine(
p, pOutput), pOutput );
824 return Abc_ObjNotCond(
Abc_AigConst1(
p->pAig), pOutput[0] ==
'0' );
826 pProduct = (
char *)Vec_PtrEntry(
p->vTokens, 0 );
827 if ( Vec_PtrSize(
p->vTokens) % 2 == 1 )
829 sprintf(
p->sError,
"Line %d: Table has odd number of tokens (%d).", Io_BlifGetLine(
p, pProduct), Vec_PtrSize(
p->vTokens) );
834 for ( i = 0; i < Vec_PtrSize(
p->vTokens)/2; i++ )
836 pProduct = (
char *)Vec_PtrEntry(
p->vTokens, 2*i + 0 );
837 pOutput = (
char *)Vec_PtrEntry(
p->vTokens, 2*i + 1 );
838 if (
strlen(pProduct) != (
unsigned)Vec_PtrSize(vFanins) )
840 sprintf(
p->sError,
"Line %d: Cube (%s) has size different from the fanin count (%d).", Io_BlifGetLine(
p, pProduct), pProduct, Vec_PtrSize(vFanins) );
843 if ( ((pOutput[0] -
'0') & 0x8E) || pOutput[1] )
845 sprintf(
p->sError,
"Line %d: Output value (%s) is incorrect.", Io_BlifGetLine(
p, pProduct), pOutput );
848 if ( Polarity == -1 )
849 Polarity = pOutput[0] -
'0';
850 else if ( Polarity != pOutput[0] -
'0' )
852 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 );
857 for ( k = 0; pProduct[k]; k++ )
859 if ( pProduct[k] ==
'0' )
861 else if ( pProduct[k] ==
'1' )
863 else if ( pProduct[k] !=
'-' )
865 sprintf(
p->sError,
"Line %d: Product term (%s) contains character (%c).", Io_BlifGetLine(
p, pProduct), pProduct, pProduct[k] );
871 pRes = Abc_ObjNotCond( pRes, Polarity == 0 );
894 pObjIo = *Io_BlifHashLookup(
p, pName );
895 if ( pObjIo == NULL )
897 sprintf(
p->sError,
"Line %d: Signal (%s) is not defined as a table.", Io_BlifGetLine(
p, pName), pName );
903 sprintf(
p->sError,
"Line %d: Signal (%s) appears twice on a combinational path.", Io_BlifGetLine(
p, pName), pName );
912 vFanins = Vec_PtrAlloc( 8 );
913 Io_BlifCollectTokens( vFanins, pObjIo->
pName - pObjIo->
Offset, pObjIo->
pName );
916 pFaninAbc = Io_BlifParseConstruct_rec(
p, pNameFanin );
917 if ( pFaninAbc == NULL )
919 Vec_PtrFree( vFanins );
922 Vec_PtrWriteEntry( vFanins, i, pFaninAbc );
926 Vec_PtrFree( vFanins );
957 pObj = Abc_NtkCreatePi( pAig );
964 pObj = Abc_NtkCreatePo( pAig );
971 pObj = Abc_NtkCreateBi( pAig );
976 pLatch = Abc_NtkCreateLatch( pAig );
977 pLatch->
pData = (
void *)(ABC_PTRUINT_T)pObjIo->
Init;
982 pObj = Abc_NtkCreateBo( pAig );
992 pObj = Io_BlifParseConstruct_rec(
p, pObjIo->
pName );
1000 pObj = Io_BlifParseConstruct_rec(
p, pObjIo->
pName );
1006 p->nTablesLeft = Vec_PtrSize(
p->vNames) -
p->nTablesRead;
1007 if (
p->nTablesLeft )
1008 printf(
"The number of dangling tables = %d.\n",
p->nTablesLeft );
1009 printf(
"AND nodes = %6d. Estimate = %6d.\n", Abc_NtkNodeNum(
p->pAig), Io_BlifEstimateAndNum(
p) );
struct Abc_Obj_t_ Abc_Obj_t
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
ABC_DLL int Abc_NtkCheckRead(Abc_Ntk_t *pNtk)
struct Abc_Aig_t_ Abc_Aig_t
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
ABC_DLL Abc_Obj_t * Abc_AigAnd(Abc_Aig_t *pMan, Abc_Obj_t *p0, Abc_Obj_t *p1)
ABC_DLL Abc_Obj_t * Abc_AigOr(Abc_Aig_t *pMan, Abc_Obj_t *p0, Abc_Obj_t *p1)
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
ABC_DLL Abc_Obj_t * Abc_AigConst1(Abc_Ntk_t *pNtk)
#define ABC_ALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Io_BlifMan_t_ Io_BlifMan_t
Io_BlifInit_t
DECLARATIONS ///.
Abc_Ntk_t * Io_ReadBlifAsAig(char *pFileName, int fCheck)
FUNCTION DEFINITIONS ///.
struct Io_BlifObj_t_ Io_BlifObj_t
#define Vec_PtrForEachEntryStart(Type, vVec, pEntry, i, Start)
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.