00001
00022 #include "io.h"
00023
00027
00028 unsigned Io_ReadAigerDecode( char ** ppPos );
00029
00033
00045 Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
00046 {
00047 ProgressBar * pProgress;
00048 FILE * pFile;
00049 Vec_Ptr_t * vNodes, * vTerms;
00050 Abc_Obj_t * pObj, * pNode0, * pNode1;
00051 Abc_Ntk_t * pNtkNew;
00052 int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, iTerm, nDigits, i;
00053 char * pContents, * pDrivers, * pSymbols, * pCur, * pName, * pType;
00054 unsigned uLit0, uLit1, uLit;
00055
00056
00057 nFileSize = Extra_FileSize( pFileName );
00058 pFile = fopen( pFileName, "rb" );
00059 pContents = ALLOC( char, nFileSize );
00060 fread( pContents, nFileSize, 1, pFile );
00061 fclose( pFile );
00062
00063
00064 if ( strncmp(pContents, "aig", 3) != 0 )
00065 {
00066 fprintf( stdout, "Wrong input file format.\n" );
00067 return NULL;
00068 }
00069
00070
00071 pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
00072 pName = Extra_FileNameGeneric( pFileName );
00073 pNtkNew->pName = Extra_UtilStrsav( pName );
00074 pNtkNew->pSpec = Extra_UtilStrsav( pFileName );
00075 free( pName );
00076
00077
00078
00079 pCur = pContents; while ( *pCur++ != ' ' );
00080
00081 nTotal = atoi( pCur ); while ( *pCur++ != ' ' );
00082
00083 nInputs = atoi( pCur ); while ( *pCur++ != ' ' );
00084
00085 nLatches = atoi( pCur ); while ( *pCur++ != ' ' );
00086
00087 nOutputs = atoi( pCur ); while ( *pCur++ != ' ' );
00088
00089 nAnds = atoi( pCur ); while ( *pCur++ != '\n' );
00090
00091 if ( nTotal != nInputs + nLatches + nAnds )
00092 {
00093 fprintf( stdout, "The paramters are wrong.\n" );
00094 return NULL;
00095 }
00096
00097
00098 vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
00099 Vec_PtrPush( vNodes, Abc_ObjNot( Abc_AigConst1(pNtkNew) ) );
00100
00101
00102 for ( i = 0; i < nInputs; i++ )
00103 {
00104 pObj = Abc_NtkCreatePi(pNtkNew);
00105 Vec_PtrPush( vNodes, pObj );
00106 }
00107
00108 for ( i = 0; i < nOutputs; i++ )
00109 {
00110 pObj = Abc_NtkCreatePo(pNtkNew);
00111 }
00112
00113 nDigits = Extra_Base10Log( nLatches );
00114 for ( i = 0; i < nLatches; i++ )
00115 {
00116 pObj = Abc_NtkCreateLatch(pNtkNew);
00117 Abc_LatchSetInit0( pObj );
00118 pNode0 = Abc_NtkCreateBi(pNtkNew);
00119 pNode1 = Abc_NtkCreateBo(pNtkNew);
00120 Abc_ObjAddFanin( pObj, pNode0 );
00121 Abc_ObjAddFanin( pNode1, pObj );
00122 Vec_PtrPush( vNodes, pNode1 );
00123
00124
00125
00126 }
00127
00128
00129 pDrivers = pCur;
00130
00131
00132 for ( i = 0; i < nLatches + nOutputs; )
00133 if ( *pCur++ == '\n' )
00134 i++;
00135
00136
00137 pProgress = Extra_ProgressBarStart( stdout, nAnds );
00138 for ( i = 0; i < nAnds; i++ )
00139 {
00140 Extra_ProgressBarUpdate( pProgress, i, NULL );
00141 uLit = ((i + 1 + nInputs + nLatches) << 1);
00142 uLit1 = uLit - Io_ReadAigerDecode( &pCur );
00143 uLit0 = uLit1 - Io_ReadAigerDecode( &pCur );
00144
00145 pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
00146 pNode1 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
00147 assert( Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches );
00148 Vec_PtrPush( vNodes, Abc_AigAnd(pNtkNew->pManFunc, pNode0, pNode1) );
00149 }
00150 Extra_ProgressBarStop( pProgress );
00151
00152
00153 pSymbols = pCur;
00154
00155
00156 pCur = pDrivers;
00157 Abc_NtkForEachLatchInput( pNtkNew, pObj, i )
00158 {
00159 uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
00160 pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
00161 Abc_ObjAddFanin( pObj, pNode0 );
00162
00163
00164
00165 }
00166
00167 Abc_NtkForEachPo( pNtkNew, pObj, i )
00168 {
00169 uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
00170 pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
00171 Abc_ObjAddFanin( pObj, pNode0 );
00172 }
00173
00174
00175 pCur = pSymbols;
00176 if ( *pCur != 'c' )
00177 {
00178 int Counter = 0;
00179 while ( pCur < pContents + nFileSize && *pCur != 'c' )
00180 {
00181
00182 pType = pCur;
00183 if ( *pCur == 'i' )
00184 vTerms = pNtkNew->vPis;
00185 else if ( *pCur == 'l' )
00186 vTerms = pNtkNew->vBoxes;
00187 else if ( *pCur == 'o' )
00188 vTerms = pNtkNew->vPos;
00189 else
00190 {
00191 fprintf( stdout, "Wrong terminal type.\n" );
00192 return NULL;
00193 }
00194
00195 iTerm = atoi( ++pCur ); while ( *pCur++ != ' ' );
00196
00197 if ( iTerm >= Vec_PtrSize(vTerms) )
00198 {
00199 fprintf( stdout, "The number of terminal is out of bound.\n" );
00200 return NULL;
00201 }
00202 pObj = Vec_PtrEntry( vTerms, iTerm );
00203 if ( *pType == 'l' )
00204 pObj = Abc_ObjFanout0(pObj);
00205
00206 pName = pCur; while ( *pCur++ != '\n' );
00207
00208 *(pCur-1) = 0;
00209 Abc_ObjAssignName( pObj, pName, NULL );
00210 if ( *pType == 'l' )
00211 {
00212 Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
00213 Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
00214 }
00215
00216 pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
00217 }
00218
00219
00220 Abc_NtkForEachPi( pNtkNew, pObj, i )
00221 {
00222 if ( pObj->pCopy ) continue;
00223 Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
00224 Counter++;
00225 }
00226 Abc_NtkForEachLatchOutput( pNtkNew, pObj, i )
00227 {
00228 if ( pObj->pCopy ) continue;
00229 Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
00230 Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
00231 Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
00232 Counter++;
00233 }
00234 Abc_NtkForEachPo( pNtkNew, pObj, i )
00235 {
00236 if ( pObj->pCopy ) continue;
00237 Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
00238 Counter++;
00239 }
00240 if ( Counter )
00241 printf( "Io_ReadAiger(): Added %d default names for nameless I/O/register objects.\n", Counter );
00242 }
00243 else
00244 {
00245
00246 Abc_NtkShortNames( pNtkNew );
00247 }
00248
00249
00250 if ( *pCur == 'c' )
00251 {
00252 if ( !strncmp( pCur + 2, ".model", 6 ) )
00253 {
00254 char * pTemp;
00255 for ( pTemp = pCur + 9; *pTemp && *pTemp != '\n'; pTemp++ );
00256 *pTemp = 0;
00257 free( pNtkNew->pName );
00258 pNtkNew->pName = Extra_UtilStrsav( pCur + 9 );
00259 }
00260 }
00261
00262
00263
00264 free( pContents );
00265 Vec_PtrFree( vNodes );
00266
00267
00268 Abc_AigCleanup( pNtkNew->pManFunc );
00269
00270
00271 if ( fCheck && !Abc_NtkCheckRead( pNtkNew ) )
00272 {
00273 printf( "Io_ReadAiger: The network check has failed.\n" );
00274 Abc_NtkDelete( pNtkNew );
00275 return NULL;
00276 }
00277 return pNtkNew;
00278 }
00279
00280
00293 unsigned Io_ReadAigerDecode( char ** ppPos )
00294 {
00295 unsigned x = 0, i = 0;
00296 unsigned char ch;
00297
00298
00299 while ((ch = *(*ppPos)++) & 0x80)
00300 x |= (ch & 0x7f) << (7 * i++);
00301
00302 return x | (ch << (7 * i));
00303 }
00304
00305
00309
00310