abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ioaReadAig.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [ioaReadAiger.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Command processing package.]
8 
9  Synopsis [Procedures to read binary AIGER format developed by
10  Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
11 
12  Author [Alan Mishchenko]
13 
14  Affiliation [UC Berkeley]
15 
16  Date [Ver. 1.0. Started - December 16, 2006.]
17 
18  Revision [$Id: ioaReadAiger.c,v 1.00 2006/12/16 00:00:00 alanmi Exp $]
19 
20 ***********************************************************************/
21 
22 #include "ioa.h"
23 
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 ////////////////////////////////////////////////////////////////////////
32 /// FUNCTION DEFINITIONS ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 /**Function*************************************************************
36 
37  Synopsis [Extracts one unsigned AIG edge from the input buffer.]
38 
39  Description [This procedure is a slightly modified version of Armin Biere's
40  procedure "unsigned decode (FILE * file)". ]
41 
42  SideEffects [Updates the current reading position.]
43 
44  SeeAlso []
45 
46 ***********************************************************************/
47 unsigned 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 
59 /**Function*************************************************************
60 
61  Synopsis [Decodes the encoded array of literals.]
62 
63  Description []
64 
65  SideEffects []
66 
67  SeeAlso []
68 
69 ***********************************************************************/
70 Vec_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 
92 /**Function*************************************************************
93 
94  Synopsis [Reads the AIG in from the memory buffer.]
95 
96  Description [The buffer constains the AIG in AIGER format. The size gives
97  the number of bytes in the buffer. The buffer is allocated by the user
98  and not deallocated by this procedure.]
99 
100  SideEffects []
101 
102  SeeAlso []
103 
104 ***********************************************************************/
105 Aig_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 )
408  Aig_ManInvertConstraints( pNew );
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 
420 /**Function*************************************************************
421 
422  Synopsis [Reads the AIG in the binary AIGER format.]
423 
424  Description []
425 
426  SideEffects []
427 
428  SeeAlso []
429 
430 ***********************************************************************/
431 Aig_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_ALLOC( char, nFileSize );
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 
459 ////////////////////////////////////////////////////////////////////////
460 /// END OF FILE ///
461 ////////////////////////////////////////////////////////////////////////
462 
463 
465 
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition: aigObj.c:66
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
ABC_DLL int Aig_ManCheck(Aig_Man_t *p)
FUNCTION DECLARATIONS ///.
Definition: aigCheck.c:45
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition: aig.h:50
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
void Aig_ManStop(Aig_Man_t *p)
Definition: aigMan.c:187
Aig_Man_t * Ioa_ReadAigerFromMemory(char *pContents, int nFileSize, int fCheck)
INCLUDES ///.
Definition: ioaReadAig.c:105
int Ioa_FileSize(char *pFileName)
DECLARATIONS ///.
Definition: ioaUtil.c:46
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition: aigMan.c:47
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition: aigObj.c:45
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
static Aig_Obj_t * Aig_ManConst0(Aig_Man_t *p)
Definition: aig.h:263
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
ABC_NAMESPACE_IMPL_START unsigned Ioa_ReadAigerDecode(char **ppPos)
DECLARATIONS ///.
Definition: ioaReadAig.c:47
Aig_Obj_t * Aig_And(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition: aigOper.c:104
Aig_Man_t * Ioa_ReadAiger(char *pFileName, int fCheck)
Definition: ioaReadAig.c:431
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
void Aig_ManSetRegNum(Aig_Man_t *p, int nRegs)
Definition: aigMan.c:438
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
Definition: aig.h:69
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
Vec_Int_t * Ioa_WriteDecodeLiterals(char **ppPos, int nEntries)
Definition: ioaReadAig.c:70
void Aig_ManInvertConstraints(Aig_Man_t *pAig)
Definition: aigUtil.c:1543
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
static int Aig_ManRegNum(Aig_Man_t *p)
Definition: aig.h:260
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
#define ABC_FREE(obj)
Definition: abc_global.h:232
int strncmp()
#define assert(ex)
Definition: util_old.h:213
static Aig_Obj_t * Aig_NotCond(Aig_Obj_t *p, int c)
Definition: aig.h:248
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
char * Ioa_FileNameGeneric(char *FileName)
Definition: ioaUtil.c:73
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
int Aig_ManCleanup(Aig_Man_t *p)
Definition: aigMan.c:265
int nTotal
DECLARATIONS ///.
Definition: cutTruth.c:37
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223