ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ioaReadAig.c
Go to the documentation of this file.
1
21
22#include "ioa.h"
23
25
26
30
34
47unsigned Ioa_ReadAigerDecode( char ** ppPos )
48{
49 unsigned x = 0, i = 0;
50 unsigned char ch;
51
52// while ((ch = getnoneofch (file)) & 0x80)
53 while ((ch = *(*ppPos)++) & 0x80)
54 x |= (ch & 0x7f) << (7 * i++);
55
56 return x | (ch << (7 * i));
57}
58
70Vec_Int_t * Ioa_WriteDecodeLiterals( char ** ppPos, int nEntries )
71{
72 Vec_Int_t * vLits;
73 int Lit, LitPrev, Diff, i;
74 vLits = Vec_IntAlloc( nEntries );
75 LitPrev = Ioa_ReadAigerDecode( ppPos );
76 Vec_IntPush( vLits, LitPrev );
77 for ( i = 1; i < nEntries; i++ )
78 {
79// Diff = Lit - LitPrev;
80// Diff = (Lit < LitPrev)? -Diff : Diff;
81// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev);
82 Diff = Ioa_ReadAigerDecode( ppPos );
83 Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1;
84 Lit = Diff + LitPrev;
85 Vec_IntPush( vLits, Lit );
86 LitPrev = Lit;
87 }
88 return vLits;
89}
90
91
105Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck )
106{
107 Vec_Int_t * vLits = NULL;
108 Vec_Ptr_t * vNodes, * vDrivers;//, * vTerms;
109 Aig_Obj_t * pObj, * pNode0, * pNode1;
110 Aig_Man_t * pNew;
111 int nTotal, nInputs, nOutputs, nLatches, nAnds, i;//, iTerm, nDigits;
112 int nBad = 0, nConstr = 0, nJust = 0, nFair = 0;
113 char * pDrivers, * pSymbols, * pCur;//, * pType;
114 unsigned uLit0, uLit1, uLit;
115
116 // check if the input file format is correct
117 if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') )
118 {
119 fprintf( stdout, "Wrong input file format.\n" );
120 return NULL;
121 }
122
123 // read the parameters (M I L O A + B C J F)
124 pCur = pContents; while ( *pCur != ' ' ) pCur++; pCur++;
125 // read the number of objects
126 nTotal = atoi( pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
127 // read the number of inputs
128 nInputs = atoi( pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
129 // read the number of latches
130 nLatches = atoi( pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
131 // read the number of outputs
132 nOutputs = atoi( pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
133 // read the number of nodes
134 nAnds = atoi( pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
135 if ( *pCur == ' ' )
136 {
137 assert( nOutputs == 0 );
138 // read the number of properties
139 pCur++;
140 nBad = atoi( pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
141 nOutputs += nBad;
142 }
143 if ( *pCur == ' ' )
144 {
145 // read the number of properties
146 pCur++;
147 nConstr = atoi( pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
148 nOutputs += nConstr;
149 }
150 if ( *pCur == ' ' )
151 {
152 // read the number of properties
153 pCur++;
154 nJust = atoi( pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
155 nOutputs += nJust;
156 }
157 if ( *pCur == ' ' )
158 {
159 // read the number of properties
160 pCur++;
161 nFair = atoi( pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
162 nOutputs += nFair;
163 }
164 if ( *pCur != '\n' )
165 {
166 fprintf( stdout, "The parameter line is in a wrong format.\n" );
167 return NULL;
168 }
169 pCur++;
170
171 // check the parameters
172 if ( nTotal != nInputs + nLatches + nAnds )
173 {
174 fprintf( stdout, "The number of objects does not match.\n" );
175 return NULL;
176 }
177 if ( nJust || nFair )
178 {
179 fprintf( stdout, "Reading AIGER files with liveness properties are currently not supported.\n" );
180 return NULL;
181 }
182
183 if ( nConstr )
184 {
185 if ( nConstr == 1 )
186 fprintf( stdout, "Warning: The last output is interpreted as a constraint.\n" );
187 else
188 fprintf( stdout, "Warning: The last %d outputs are interpreted as constraints.\n", nConstr );
189 }
190
191 // allocate the empty AIG
192 pNew = Aig_ManStart( nAnds );
193 pNew->nConstrs = nConstr;
194
195 // prepare the array of nodes
196 vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
197 Vec_PtrPush( vNodes, Aig_ManConst0(pNew) );
198
199 // create the PIs
200 for ( i = 0; i < nInputs + nLatches; i++ )
201 {
202 pObj = Aig_ObjCreateCi(pNew);
203 Vec_PtrPush( vNodes, pObj );
204 }
205/*
206 // create the POs
207 for ( i = 0; i < nOutputs + nLatches; i++ )
208 {
209 pObj = Aig_ObjCreateCo(pNew);
210 }
211*/
212 // create the latches
213 pNew->nRegs = nLatches;
214/*
215 nDigits = Ioa_Base10Log( nLatches );
216 for ( i = 0; i < nLatches; i++ )
217 {
218 pObj = Aig_ObjCreateLatch(pNew);
219 Aig_LatchSetInit0( pObj );
220 pNode0 = Aig_ObjCreateBi(pNew);
221 pNode1 = Aig_ObjCreateBo(pNew);
222 Aig_ObjAddFanin( pObj, pNode0 );
223 Aig_ObjAddFanin( pNode1, pObj );
224 Vec_PtrPush( vNodes, pNode1 );
225 // assign names to latch and its input
226// Aig_ObjAssignName( pObj, Aig_ObjNameDummy("_L", i, nDigits), NULL );
227// printf( "Creating latch %s with input %d and output %d.\n", Aig_ObjName(pObj), pNode0->Id, pNode1->Id );
228 }
229*/
230
231 // remember the beginning of latch/PO literals
232 pDrivers = pCur;
233 if ( pContents[3] == ' ' ) // standard AIGER
234 {
235 // scroll to the beginning of the binary data
236 for ( i = 0; i < nLatches + nOutputs; )
237 if ( *pCur++ == '\n' )
238 i++;
239 }
240 else // modified AIGER
241 {
242 vLits = Ioa_WriteDecodeLiterals( &pCur, nLatches + nOutputs );
243 }
244
245 // create the AND gates
246// pProgress = Bar_ProgressStart( stdout, nAnds );
247 for ( i = 0; i < nAnds; i++ )
248 {
249// Bar_ProgressUpdate( pProgress, i, NULL );
250 uLit = ((i + 1 + nInputs + nLatches) << 1);
251 uLit1 = uLit - Ioa_ReadAigerDecode( &pCur );
252 uLit0 = uLit1 - Ioa_ReadAigerDecode( &pCur );
253// assert( uLit1 > uLit0 );
254 pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
255 pNode1 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
256 assert( Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches );
257 Vec_PtrPush( vNodes, Aig_And(pNew, pNode0, pNode1) );
258 }
259// Bar_ProgressStop( pProgress );
260
261 // remember the place where symbols begin
262 pSymbols = pCur;
263
264 // read the latch driver literals
265 vDrivers = Vec_PtrAlloc( nLatches + nOutputs );
266 if ( pContents[3] == ' ' ) // standard AIGER
267 {
268 pCur = pDrivers;
269 for ( i = 0; i < nLatches; i++ )
270 {
271 uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
272 pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
273 Vec_PtrPush( vDrivers, pNode0 );
274 }
275 // read the PO driver literals
276 for ( i = 0; i < nOutputs; i++ )
277 {
278 uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
279 pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
280 Vec_PtrPush( vDrivers, pNode0 );
281 }
282
283 }
284 else
285 {
286 // read the latch driver literals
287 for ( i = 0; i < nLatches; i++ )
288 {
289 uLit0 = Vec_IntEntry( vLits, i );
290 pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
291 Vec_PtrPush( vDrivers, pNode0 );
292 }
293 // read the PO driver literals
294 for ( i = 0; i < nOutputs; i++ )
295 {
296 uLit0 = Vec_IntEntry( vLits, i+nLatches );
297 pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
298 Vec_PtrPush( vDrivers, pNode0 );
299 }
300 Vec_IntFree( vLits );
301 }
302
303 // create the POs
304 for ( i = 0; i < nOutputs; i++ )
305 Aig_ObjCreateCo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vDrivers, nLatches + i) );
306 for ( i = 0; i < nLatches; i++ )
307 Aig_ObjCreateCo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vDrivers, i) );
308 Vec_PtrFree( vDrivers );
309
310/*
311 // read the names if present
312 pCur = pSymbols;
313 if ( *pCur != 'c' )
314 {
315 int Counter = 0;
316 while ( pCur < pContents + nFileSize && *pCur != 'c' )
317 {
318 // get the terminal type
319 pType = pCur;
320 if ( *pCur == 'i' )
321 vTerms = pNew->vPis;
322 else if ( *pCur == 'l' )
323 vTerms = pNew->vBoxes;
324 else if ( *pCur == 'o' )
325 vTerms = pNew->vPos;
326 else
327 {
328 fprintf( stdout, "Wrong terminal type.\n" );
329 return NULL;
330 }
331 // get the terminal number
332 iTerm = atoi( ++pCur ); while ( *pCur++ != ' ' );
333 // get the node
334 if ( iTerm >= Vec_PtrSize(vTerms) )
335 {
336 fprintf( stdout, "The number of terminal is out of bound.\n" );
337 return NULL;
338 }
339 pObj = Vec_PtrEntry( vTerms, iTerm );
340 if ( *pType == 'l' )
341 pObj = Aig_ObjFanout0(pObj);
342 // assign the name
343 pName = pCur; while ( *pCur++ != '\n' );
344 // assign this name
345 *(pCur-1) = 0;
346 Aig_ObjAssignName( pObj, pName, NULL );
347 if ( *pType == 'l' )
348 {
349 Aig_ObjAssignName( Aig_ObjFanin0(pObj), Aig_ObjName(pObj), "L" );
350 Aig_ObjAssignName( Aig_ObjFanin0(Aig_ObjFanin0(pObj)), Aig_ObjName(pObj), "_in" );
351 }
352 // mark the node as named
353 pObj->pCopy = (Aig_Obj_t *)Aig_ObjName(pObj);
354 }
355
356 // assign the remaining names
357 Aig_ManForEachCi( pNew, pObj, i )
358 {
359 if ( pObj->pCopy ) continue;
360 Aig_ObjAssignName( pObj, Aig_ObjName(pObj), NULL );
361 Counter++;
362 }
363 Aig_ManForEachLatchOutput( pNew, pObj, i )
364 {
365 if ( pObj->pCopy ) continue;
366 Aig_ObjAssignName( pObj, Aig_ObjName(pObj), NULL );
367 Aig_ObjAssignName( Aig_ObjFanin0(pObj), Aig_ObjName(pObj), "L" );
368 Aig_ObjAssignName( Aig_ObjFanin0(Aig_ObjFanin0(pObj)), Aig_ObjName(pObj), "_in" );
369 Counter++;
370 }
371 Aig_ManForEachCo( pNew, pObj, i )
372 {
373 if ( pObj->pCopy ) continue;
374 Aig_ObjAssignName( pObj, Aig_ObjName(pObj), NULL );
375 Counter++;
376 }
377 if ( Counter )
378 printf( "Ioa_ReadAiger(): Added %d default names for nameless I/O/register objects.\n", Counter );
379 }
380 else
381 {
382// printf( "Ioa_ReadAiger(): I/O/register names are not given. Generating short names.\n" );
383 Aig_ManShortNames( pNew );
384 }
385*/
386 pCur = pSymbols;
387 if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
388 {
389 pCur++;
390 if ( *pCur == 'n' )
391 {
392 pCur++;
393 // read model name
394 ABC_FREE( pNew->pName );
395 pNew->pName = Abc_UtilStrsav( pCur );
396 }
397 }
398
399 // skipping the comments
400 Vec_PtrFree( vNodes );
401
402 // remove the extra nodes
403 Aig_ManCleanup( pNew );
404 Aig_ManSetRegNum( pNew, Aig_ManRegNum(pNew) );
405
406 // update polarity of the additional outputs
407 if ( nBad || nConstr || nJust || nFair )
409
410 // check the result
411 if ( fCheck && !Aig_ManCheck( pNew ) )
412 {
413 printf( "Ioa_ReadAiger: The network check has failed.\n" );
414 Aig_ManStop( pNew );
415 return NULL;
416 }
417 return pNew;
418}
419
431Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck )
432{
433 FILE * pFile;
434 Aig_Man_t * pNew;
435 char * pName, * pContents;
436 int nFileSize, RetValue;
437
438 // read the file into the buffer
439 nFileSize = Ioa_FileSize( pFileName );
440 pFile = fopen( pFileName, "rb" );
441 pContents = ABC_CALLOC( char, nFileSize+1 );
442 RetValue = fread( pContents, nFileSize, 1, pFile );
443 fclose( pFile );
444
445 pNew = Ioa_ReadAigerFromMemory( pContents, nFileSize, fCheck );
446 ABC_FREE( pContents );
447 if ( pNew )
448 {
449 pName = Ioa_FileNameGeneric( pFileName );
450 ABC_FREE( pNew->pName );
451 pNew->pName = Abc_UtilStrsav( pName );
452 pNew->pSpec = Abc_UtilStrsav( pFileName );
453 ABC_FREE( pName );
454 }
455 return pNew;
456}
457
458
462
463
465
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void Aig_ManSetRegNum(Aig_Man_t *p, int nRegs)
Definition aigMan.c:438
void Aig_ManInvertConstraints(Aig_Man_t *pAig)
Definition aigUtil.c:1561
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
Aig_Obj_t * Aig_And(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition aigOper.c:104
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition aigObj.c:66
struct Aig_Obj_t_ Aig_Obj_t
Definition aig.h:51
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition aigMan.c:47
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
int Aig_ManCleanup(Aig_Man_t *p)
Definition aigMan.c:265
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigObj.c:45
ABC_DLL int Aig_ManCheck(Aig_Man_t *p)
FUNCTION DECLARATIONS ///.
Definition aigCheck.c:45
int nTotal
DECLARATIONS ///.
Definition cutTruth.c:37
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Vec_Int_t * Ioa_WriteDecodeLiterals(char **ppPos, int nEntries)
Definition ioaReadAig.c:70
ABC_NAMESPACE_IMPL_START unsigned Ioa_ReadAigerDecode(char **ppPos)
DECLARATIONS ///.
Definition ioaReadAig.c:47
Aig_Man_t * Ioa_ReadAiger(char *pFileName, int fCheck)
Definition ioaReadAig.c:431
Aig_Man_t * Ioa_ReadAigerFromMemory(char *pContents, int nFileSize, int fCheck)
INCLUDES ///.
Definition ioaReadAig.c:105
char * Ioa_FileNameGeneric(char *FileName)
Definition ioaUtil.c:73
int Ioa_FileSize(char *pFileName)
DECLARATIONS ///.
Definition ioaUtil.c:46
#define assert(ex)
Definition util_old.h:213
int strncmp()
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42