00001
00022 #include "io.h"
00023
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 static unsigned Io_ObjMakeLit( int Var, int fCompl ) { return (Var << 1) | fCompl; }
00129 static unsigned Io_ObjAigerNum( Abc_Obj_t * pObj ) { return (unsigned)pObj->pCopy; }
00130 static void Io_ObjSetAigerNum( Abc_Obj_t * pObj, unsigned Num ) { pObj->pCopy = (void *)Num; }
00131
00132 int Io_WriteAigerEncode( char * pBuffer, int Pos, unsigned x );
00133
00137
00149 void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols )
00150 {
00151 ProgressBar * pProgress;
00152 FILE * pFile;
00153 Abc_Obj_t * pObj, * pDriver;
00154 int i, nNodes, Pos, nBufferSize;
00155 unsigned char * pBuffer;
00156 unsigned uLit0, uLit1, uLit;
00157
00158 assert( Abc_NtkIsStrash(pNtk) );
00159
00160 pFile = fopen( pFileName, "wb" );
00161 if ( pFile == NULL )
00162 {
00163 fprintf( stdout, "Io_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
00164 return;
00165 }
00166 Abc_NtkForEachLatch( pNtk, pObj, i )
00167 if ( !Abc_LatchIsInit0(pObj) )
00168 {
00169 fprintf( stdout, "Io_WriteAiger(): Cannot write AIGER format with non-0 latch init values. Run \"zero\".\n" );
00170 return;
00171 }
00172
00173
00174 nNodes = 0;
00175 Io_ObjSetAigerNum( Abc_AigConst1(pNtk), nNodes++ );
00176 Abc_NtkForEachCi( pNtk, pObj, i )
00177 Io_ObjSetAigerNum( pObj, nNodes++ );
00178 Abc_AigForEachAnd( pNtk, pObj, i )
00179 Io_ObjSetAigerNum( pObj, nNodes++ );
00180
00181
00182 fprintf( pFile, "aig %u %u %u %u %u\n",
00183 Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) + Abc_NtkNodeNum(pNtk),
00184 Abc_NtkPiNum(pNtk),
00185 Abc_NtkLatchNum(pNtk),
00186 Abc_NtkPoNum(pNtk),
00187 Abc_NtkNodeNum(pNtk) );
00188
00189
00190
00191
00192
00193
00194 Abc_NtkForEachLatchInput( pNtk, pObj, i )
00195 {
00196 pDriver = Abc_ObjFanin0(pObj);
00197 fprintf( pFile, "%u\n", Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
00198 }
00199
00200
00201 Abc_NtkForEachPo( pNtk, pObj, i )
00202 {
00203 pDriver = Abc_ObjFanin0(pObj);
00204 fprintf( pFile, "%u\n", Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
00205 }
00206
00207
00208 Pos = 0;
00209 nBufferSize = 6 * Abc_NtkNodeNum(pNtk) + 100;
00210 pBuffer = ALLOC( char, nBufferSize );
00211 pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
00212 Abc_AigForEachAnd( pNtk, pObj, i )
00213 {
00214 Extra_ProgressBarUpdate( pProgress, i, NULL );
00215 uLit = Io_ObjMakeLit( Io_ObjAigerNum(pObj), 0 );
00216 uLit0 = Io_ObjMakeLit( Io_ObjAigerNum(Abc_ObjFanin0(pObj)), Abc_ObjFaninC0(pObj) );
00217 uLit1 = Io_ObjMakeLit( Io_ObjAigerNum(Abc_ObjFanin1(pObj)), Abc_ObjFaninC1(pObj) );
00218 assert( uLit0 < uLit1 );
00219 Pos = Io_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 );
00220 Pos = Io_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 );
00221 if ( Pos > nBufferSize - 10 )
00222 {
00223 printf( "Io_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" );
00224 fclose( pFile );
00225 return;
00226 }
00227 }
00228 assert( Pos < nBufferSize );
00229 Extra_ProgressBarStop( pProgress );
00230
00231
00232 fwrite( pBuffer, 1, Pos, pFile );
00233 free( pBuffer );
00234
00235
00236 if ( fWriteSymbols )
00237 {
00238
00239 Abc_NtkForEachPi( pNtk, pObj, i )
00240 fprintf( pFile, "i%d %s\n", i, Abc_ObjName(pObj) );
00241
00242 Abc_NtkForEachLatch( pNtk, pObj, i )
00243 fprintf( pFile, "l%d %s\n", i, Abc_ObjName(Abc_ObjFanout0(pObj)) );
00244
00245 Abc_NtkForEachPo( pNtk, pObj, i )
00246 fprintf( pFile, "o%d %s\n", i, Abc_ObjName(pObj) );
00247 }
00248
00249
00250 fprintf( pFile, "c\n" );
00251 if ( pNtk->pName && strlen(pNtk->pName) > 0 )
00252 fprintf( pFile, ".model %s\n", pNtk->pName );
00253 fprintf( pFile, "This file was produced by ABC on %s\n", Extra_TimeStamp() );
00254 fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
00255 fclose( pFile );
00256 }
00257
00270 int Io_WriteAigerEncode( char * pBuffer, int Pos, unsigned x )
00271 {
00272 unsigned char ch;
00273 while (x & ~0x7f)
00274 {
00275 ch = (x & 0x7f) | 0x80;
00276
00277 pBuffer[Pos++] = ch;
00278 x >>= 7;
00279 }
00280 ch = x;
00281
00282 pBuffer[Pos++] = ch;
00283 return Pos;
00284 }
00285
00286
00290
00291