abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ioReadBlifAig.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [ioReadBlifAig.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Command processing package.]
8 
9  Synopsis [Procedures to read BLIF file into AIG.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - December 23, 2006.]
16 
17  Revision [$Id: ioReadBlifAig.c,v 1.00 2006/12/23 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "base/abc/abc.h"
22 #include "misc/vec/vecPtr.h"
23 
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 // latch initial values
32 typedef enum {
33  IO_BLIF_INIT_NONE = 0, // 0: unknown
34  IO_BLIF_INIT_ZERO, // 1: zero
35  IO_BLIF_INIT_ONE, // 2: one
36  IO_BLIF_INIT_DC // 3: don't-care
38 
39 typedef struct Io_BlifObj_t_ Io_BlifObj_t; // parsing object
41 {
42  unsigned fPi : 1; // the object is a primary input
43  unsigned fPo : 1; // the object is a primary output
44  unsigned fLi : 1; // the object is a latch input
45  unsigned fLo : 1; // the object is a latch output
46  unsigned fDef : 1; // the object is defined as a table (node, PO, LI)
47  unsigned fLoop : 1; // flag for loop detection
48  unsigned Init : 2; // the latch initial state
49  unsigned Offset : 24; // temporary number
50  char * pName; // the name of this object
51  void * pEquiv; // the AIG node representing this line
52  Io_BlifObj_t * pNext; // the next obj in the hash table
53 };
54 
55 typedef struct Io_BlifMan_t_ Io_BlifMan_t; // parsing manager
57 {
58  // general info about file
59  char * pFileName; // the name of the file
60  char * pBuffer; // the begining of the file buffer
61  Vec_Ptr_t * vLines; // the line beginnings
62  // temporary objects
63  Io_BlifObj_t * pObjects; // the storage for objects
64  int nObjects; // the number of objects allocated
65  int iObjNext; // the next free object
66  // file lines
67  char * pModel; // .model line
68  Vec_Ptr_t * vInputs; // .inputs lines
69  Vec_Ptr_t * vOutputs; // .outputs lines
70  Vec_Ptr_t * vLatches; // .latches lines
71  Vec_Ptr_t * vNames; // .names lines
72  // network objects
73  Vec_Ptr_t * vPis; // the PI structures
74  Vec_Ptr_t * vPos; // the PO structures
75  Vec_Ptr_t * vLis; // the LI structures
76  Vec_Ptr_t * vLos; // the LO structures
77  // mapping of names into objects
78  Io_BlifObj_t ** pTable; // the hash table
79  int nTableSize; // the hash table size
80  // current processing info
81  Abc_Ntk_t * pAig; // the network under construction
82  Vec_Ptr_t * vTokens; // the current tokens
83  char sError[512]; // the error string generated during parsing
84  // statistics
85  int nTablesRead; // the number of processed tables
86  int nTablesLeft; // the number of dangling tables
87 };
88 
89 // static functions
90 static Io_BlifMan_t * Io_BlifAlloc();
91 static void Io_BlifFree( Io_BlifMan_t * p );
92 static char * Io_BlifLoadFile( char * pFileName );
93 static void Io_BlifReadPreparse( Io_BlifMan_t * p );
94 static Abc_Ntk_t * Io_BlifParse( Io_BlifMan_t * p );
95 static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine );
96 static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine );
97 static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine );
98 static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine );
99 static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine );
100 static int Io_BlifParseConstruct( Io_BlifMan_t * p );
101 static int Io_BlifCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; }
102 
103 ////////////////////////////////////////////////////////////////////////
104 /// FUNCTION DEFINITIONS ///
105 ////////////////////////////////////////////////////////////////////////
106 
107 /**Function*************************************************************
108 
109  Synopsis [Reads the network from the BLIF file as an AIG.]
110 
111  Description []
112 
113  SideEffects []
114 
115  SeeAlso []
116 
117 ***********************************************************************/
118 Abc_Ntk_t * Io_ReadBlifAsAig( char * pFileName, int fCheck )
119 {
120  FILE * pFile;
121  Io_BlifMan_t * p;
122  Abc_Ntk_t * pAig;
123 
124  // check that the file is available
125  pFile = fopen( pFileName, "rb" );
126  if ( pFile == NULL )
127  {
128  printf( "Io_Blif(): The file is unavailable (absent or open).\n" );
129  return 0;
130  }
131  fclose( pFile );
132 
133  // start the file reader
134  p = Io_BlifAlloc();
135  p->pFileName = pFileName;
136  p->pBuffer = Io_BlifLoadFile( pFileName );
137  if ( p->pBuffer == NULL )
138  {
139  Io_BlifFree( p );
140  return NULL;
141  }
142  // prepare the file for parsing
143  Io_BlifReadPreparse( p );
144  // construct the network
145  pAig = Io_BlifParse( p );
146  if ( p->sError[0] )
147  fprintf( stdout, "%s\n", p->sError );
148  if ( pAig == NULL )
149  return NULL;
150  Io_BlifFree( p );
151 
152  // make sure that everything is okay with the network structure
153  if ( fCheck && !Abc_NtkCheckRead( pAig ) )
154  {
155  printf( "Io_Blif: The network check has failed.\n" );
156  Abc_NtkDelete( pAig );
157  return NULL;
158  }
159  return pAig;
160 }
161 
162 /**Function*************************************************************
163 
164  Synopsis [Allocates the BLIF parsing structure.]
165 
166  Description []
167 
168  SideEffects []
169 
170  SeeAlso []
171 
172 ***********************************************************************/
174 {
175  Io_BlifMan_t * p;
176  p = ABC_ALLOC( Io_BlifMan_t, 1 );
177  memset( p, 0, sizeof(Io_BlifMan_t) );
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 );
188  return p;
189 }
190 
191 /**Function*************************************************************
192 
193  Synopsis [Frees the BLIF parsing structure.]
194 
195  Description []
196 
197  SideEffects []
198 
199  SeeAlso []
200 
201 ***********************************************************************/
202 static void Io_BlifFree( Io_BlifMan_t * p )
203 {
204  if ( p->pAig )
205  Abc_NtkDelete( p->pAig );
206  if ( p->pBuffer ) ABC_FREE( p->pBuffer );
207  if ( p->pObjects ) ABC_FREE( p->pObjects );
208  if ( p->pTable ) ABC_FREE( p->pTable );
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 );
219  ABC_FREE( p );
220 }
221 
222 
223 /**Function*************************************************************
224 
225  Synopsis [Hashing for character strings.]
226 
227  Description []
228 
229  SideEffects []
230 
231  SeeAlso []
232 
233 ***********************************************************************/
234 static unsigned Io_BlifHashString( char * pName, int TableSize )
235 {
236  static int s_Primes[10] = {
237  1291, 1699, 2357, 4177, 5147,
238  5647, 6343, 7103, 7873, 8147
239  };
240  unsigned i, Key = 0;
241  for ( i = 0; pName[i] != '\0'; i++ )
242  Key ^= s_Primes[i%10]*pName[i]*pName[i];
243  return Key % TableSize;
244 }
245 
246 /**Function*************************************************************
247 
248  Synopsis [Checks if the given name exists in the table.]
249 
250  Description []
251 
252  SideEffects []
253 
254  SeeAlso []
255 
256 ***********************************************************************/
257 static Io_BlifObj_t ** Io_BlifHashLookup( Io_BlifMan_t * p, char * pName )
258 {
259  Io_BlifObj_t ** ppEntry;
260  for ( ppEntry = p->pTable + Io_BlifHashString(pName, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
261  if ( !strcmp((*ppEntry)->pName, pName) )
262  return ppEntry;
263  return ppEntry;
264 }
265 
266 /**Function*************************************************************
267 
268  Synopsis [Finds or add the given name to the table.]
269 
270  Description []
271 
272  SideEffects []
273 
274  SeeAlso []
275 
276 ***********************************************************************/
277 static Io_BlifObj_t * Io_BlifHashFindOrAdd( Io_BlifMan_t * p, char * pName )
278 {
279  Io_BlifObj_t ** ppEntry;
280  ppEntry = Io_BlifHashLookup( p, pName );
281  if ( *ppEntry == NULL )
282  {
283  assert( p->iObjNext < p->nObjects );
284  *ppEntry = p->pObjects + p->iObjNext++;
285  (*ppEntry)->pName = pName;
286  }
287  return *ppEntry;
288 }
289 
290 
291 /**Function*************************************************************
292 
293  Synopsis [Collects the already split tokens.]
294 
295  Description []
296 
297  SideEffects []
298 
299  SeeAlso []
300 
301 ***********************************************************************/
302 static void Io_BlifCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput )
303 {
304  char * pCur;
305  Vec_PtrClear( vTokens );
306  for ( pCur = pInput; pCur < pOutput; pCur++ )
307  {
308  if ( *pCur == 0 )
309  continue;
310  Vec_PtrPush( vTokens, pCur );
311  while ( *++pCur );
312  }
313 }
314 
315 /**Function*************************************************************
316 
317  Synopsis [Splits the line into tokens.]
318 
319  Description []
320 
321  SideEffects []
322 
323  SeeAlso []
324 
325 ***********************************************************************/
326 static void Io_BlifSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop )
327 {
328  char * pCur;
329  // clear spaces
330  for ( pCur = pLine; *pCur != Stop; pCur++ )
331  if ( Io_BlifCharIsSpace(*pCur) )
332  *pCur = 0;
333  // collect tokens
334  Io_BlifCollectTokens( vTokens, pLine, pCur );
335 }
336 
337 /**Function*************************************************************
338 
339  Synopsis [Returns the 1-based number of the line in which the token occurs.]
340 
341  Description []
342 
343  SideEffects []
344 
345  SeeAlso []
346 
347 ***********************************************************************/
348 static int Io_BlifGetLine( Io_BlifMan_t * p, char * pToken )
349 {
350  char * pLine;
351  int i;
352  Vec_PtrForEachEntry( char *, p->vLines, pLine, i )
353  if ( pToken < pLine )
354  return i;
355  return -1;
356 }
357 
358 /**Function*************************************************************
359 
360  Synopsis [Conservatively estimates the number of primary inputs.]
361 
362  Description []
363 
364  SideEffects []
365 
366  SeeAlso []
367 
368 ***********************************************************************/
370 {
371  char * pCur;
372  int i, fSpaces;
373  int Counter = 0;
374  Vec_PtrForEachEntry( char *, p->vInputs, pCur, i )
375  for ( fSpaces = 0; *pCur; pCur++ )
376  {
377  if ( Io_BlifCharIsSpace(*pCur) )
378  {
379  if ( !fSpaces )
380  Counter++;
381  fSpaces = 1;
382  }
383  else
384  fSpaces = 0;
385  }
386  return Counter;
387 }
388 
389 /**Function*************************************************************
390 
391  Synopsis [Conservatively estimates the number of AIG nodes.]
392 
393  Description []
394 
395  SideEffects []
396 
397  SeeAlso []
398 
399 ***********************************************************************/
401 {
402  Io_BlifObj_t * pObj;
403  char * pCur;
404  int i, CounterOne, Counter = 0;
405  for ( i = 0; i < p->iObjNext; i++ )
406  {
407  pObj = p->pObjects + i;
408  if ( !pObj->fDef )
409  continue;
410  CounterOne = 0;
411  for ( pCur = pObj->pName + strlen(pObj->pName); *pCur != '.'; pCur++ )
412  if ( *pCur == '0' || *pCur == '1' )
413  CounterOne++;
414  if ( CounterOne )
415  Counter += CounterOne - 1;
416  }
417  return Counter;
418 }
419 
420 /**Function*************************************************************
421 
422  Synopsis [Reads the file into a character buffer.]
423 
424  Description []
425 
426  SideEffects []
427 
428  SeeAlso []
429 
430 ***********************************************************************/
431 static char * Io_BlifLoadFile( char * pFileName )
432 {
433  FILE * pFile;
434  int nFileSize;
435  char * pContents;
436  int RetValue;
437  pFile = fopen( pFileName, "rb" );
438  if ( pFile == NULL )
439  {
440  printf( "Io_BlifLoadFile(): The file is unavailable (absent or open).\n" );
441  return NULL;
442  }
443  fseek( pFile, 0, SEEK_END );
444  nFileSize = ftell( pFile );
445  if ( nFileSize == 0 )
446  {
447  fclose( pFile );
448  printf( "Io_BlifLoadFile(): The file is empty.\n" );
449  return NULL;
450  }
451  pContents = ABC_ALLOC( char, nFileSize + 10 );
452  rewind( pFile );
453  RetValue = fread( pContents, nFileSize, 1, pFile );
454  fclose( pFile );
455  // finish off the file with the spare .end line
456  // some benchmarks suddenly break off without this line
457  strcpy( pContents + nFileSize, "\n.end\n" );
458  return pContents;
459 }
460 
461 /**Function*************************************************************
462 
463  Synopsis [Prepares the parsing.]
464 
465  Description [Performs several preliminary operations:
466  - Cuts the file buffer into separate lines.
467  - Removes comments and line extenders.
468  - Sorts lines by directives.
469  - Estimates the number of objects.
470  - Allocates room for the objects.
471  - Allocates room for the hash table.]
472 
473  SideEffects []
474 
475  SeeAlso []
476 
477 ***********************************************************************/
479 {
480  char * pCur, * pPrev;
481  int i, fComment = 0;
482  // parse the buffer into lines and remove comments
483  Vec_PtrPush( p->vLines, p->pBuffer );
484  for ( pCur = p->pBuffer; *pCur; pCur++ )
485  {
486  if ( *pCur == '\n' )
487  {
488  *pCur = 0;
489  fComment = 0;
490  Vec_PtrPush( p->vLines, pCur + 1 );
491  }
492  else if ( *pCur == '#' )
493  fComment = 1;
494  // remove comments
495  if ( fComment )
496  *pCur = 0;
497  }
498 
499  // unfold the line extensions and sort lines by directive
500  Vec_PtrForEachEntry( char *, p->vLines, pCur, i )
501  {
502  if ( *pCur == 0 )
503  continue;
504  // find previous non-space character
505  for ( pPrev = pCur - 2; pPrev >= p->pBuffer; pPrev-- )
506  if ( !Io_BlifCharIsSpace(*pPrev) )
507  break;
508  // if it is the line extender, overwrite it with spaces
509  if ( *pPrev == '\\' )
510  {
511  for ( ; *pPrev; pPrev++ )
512  *pPrev = ' ';
513  *pPrev = ' ';
514  continue;
515  }
516  // skip spaces at the beginning of the line
517  while ( Io_BlifCharIsSpace(*pCur++) );
518  // parse directives
519  if ( *(pCur-1) != '.' )
520  continue;
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) )
530  p->pModel = pCur;
531  else if ( !strncmp(pCur, "end", 3) || !strncmp(pCur, "exdc", 4) )
532  break;
533  else
534  {
535  pCur--;
536  if ( pCur[strlen(pCur)-1] == '\r' )
537  pCur[strlen(pCur)-1] = 0;
538  fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Io_BlifGetLine(p, pCur), pCur );
539  }
540  }
541 
542  // count the number of objects
544 
545  // allocate memory for objects
547  memset( p->pObjects, 0, p->nObjects * sizeof(Io_BlifObj_t) );
548 
549  // allocate memory for the hash table
550  p->nTableSize = p->nObjects/2 + 1;
551  p->pTable = ABC_ALLOC( Io_BlifObj_t *, p->nTableSize );
552  memset( p->pTable, 0, p->nTableSize * sizeof(Io_BlifObj_t *) );
553 }
554 
555 
556 /**Function*************************************************************
557 
558  Synopsis [Reads the AIG in the binary AIGER format.]
559 
560  Description []
561 
562  SideEffects []
563 
564  SeeAlso []
565 
566 ***********************************************************************/
568 {
569  Abc_Ntk_t * pAig;
570  char * pLine;
571  int i;
572  // parse the model
573  if ( !Io_BlifParseModel( p, p->pModel ) )
574  return NULL;
575  // parse the inputs
576  Vec_PtrForEachEntry( char *, p->vInputs, pLine, i )
577  if ( !Io_BlifParseInputs( p, pLine ) )
578  return NULL;
579  // parse the outputs
580  Vec_PtrForEachEntry( char *, p->vOutputs, pLine, i )
581  if ( !Io_BlifParseOutputs( p, pLine ) )
582  return NULL;
583  // parse the latches
584  Vec_PtrForEachEntry( char *, p->vLatches, pLine, i )
585  if ( !Io_BlifParseLatch( p, pLine ) )
586  return NULL;
587  // parse the nodes
588  Vec_PtrForEachEntry( char *, p->vNames, pLine, i )
589  if ( !Io_BlifParseNames( p, pLine ) )
590  return NULL;
591  // reconstruct the network from the parsed data
592  if ( !Io_BlifParseConstruct( p ) )
593  return NULL;
594  // return the network
595  pAig = p->pAig;
596  p->pAig = NULL;
597  return pAig;
598 }
599 
600 /**Function*************************************************************
601 
602  Synopsis [Parses the model line.]
603 
604  Description []
605 
606  SideEffects []
607 
608  SeeAlso []
609 
610 ***********************************************************************/
611 static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine )
612 {
613  char * pToken;
614  Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
615  pToken = (char *)Vec_PtrEntry( p->vTokens, 0 );
616  assert( !strcmp(pToken, "model") );
617  if ( Vec_PtrSize(p->vTokens) != 2 )
618  {
619  sprintf( p->sError, "Line %d: Model line has %d entries while it should have 2.", Io_BlifGetLine(p, pToken), Vec_PtrSize(p->vTokens) );
620  return 0;
621  }
622  p->pModel = (char *)Vec_PtrEntry( p->vTokens, 1 );
623  return 1;
624 }
625 
626 /**Function*************************************************************
627 
628  Synopsis [Parses the inputs line.]
629 
630  Description []
631 
632  SideEffects []
633 
634  SeeAlso []
635 
636 ***********************************************************************/
637 static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine )
638 {
639  Io_BlifObj_t * pObj;
640  char * pToken;
641  int i;
642  Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
643  pToken = (char *)Vec_PtrEntry(p->vTokens, 0);
644  assert( !strcmp(pToken, "inputs") );
645  Vec_PtrForEachEntryStart( char *, p->vTokens, pToken, i, 1 )
646  {
647  pObj = Io_BlifHashFindOrAdd( p, pToken );
648  if ( pObj->fPi )
649  {
650  sprintf( p->sError, "Line %d: Primary input (%s) is defined more than once.", Io_BlifGetLine(p, pToken), pToken );
651  return 0;
652  }
653  pObj->fPi = 1;
654  Vec_PtrPush( p->vPis, pObj );
655  }
656  return 1;
657 }
658 
659 /**Function*************************************************************
660 
661  Synopsis [Parses the outputs line.]
662 
663  Description []
664 
665  SideEffects []
666 
667  SeeAlso []
668 
669 ***********************************************************************/
670 static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine )
671 {
672  Io_BlifObj_t * pObj;
673  char * pToken;
674  int i;
675  Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
676  pToken = (char *)Vec_PtrEntry(p->vTokens, 0);
677  assert( !strcmp(pToken, "outputs") );
678  Vec_PtrForEachEntryStart( char *, p->vTokens, pToken, i, 1 )
679  {
680  pObj = Io_BlifHashFindOrAdd( p, pToken );
681  if ( pObj->fPo )
682  fprintf( stdout, "Line %d: Primary output (%s) is defined more than once (warning only).\n", Io_BlifGetLine(p, pToken), pToken );
683  pObj->fPo = 1;
684  Vec_PtrPush( p->vPos, pObj );
685  }
686  return 1;
687 }
688 
689 /**Function*************************************************************
690 
691  Synopsis [Parses the latches line.]
692 
693  Description []
694 
695  SideEffects []
696 
697  SeeAlso []
698 
699 ***********************************************************************/
700 static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine )
701 {
702  Io_BlifObj_t * pObj;
703  char * pToken;
704  int Init;
705  Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
706  pToken = (char *)Vec_PtrEntry(p->vTokens,0);
707  assert( !strcmp(pToken, "latch") );
708  if ( Vec_PtrSize(p->vTokens) < 3 )
709  {
710  sprintf( p->sError, "Line %d: Latch does not have input name and output name.", Io_BlifGetLine(p, pToken) );
711  return 0;
712  }
713  // get initial value
714  if ( Vec_PtrSize(p->vTokens) > 3 )
715  Init = atoi( (char *)Vec_PtrEntry(p->vTokens,3) );
716  else
717  Init = 2;
718  if ( Init < 0 || Init > 2 )
719  {
720  sprintf( p->sError, "Line %d: Initial state of the latch is incorrect (%s).", Io_BlifGetLine(p, pToken), (char*)Vec_PtrEntry(p->vTokens,3) );
721  return 0;
722  }
723  if ( Init == 0 )
724  Init = IO_BLIF_INIT_ZERO;
725  else if ( Init == 1 )
726  Init = IO_BLIF_INIT_ONE;
727  else // if ( Init == 2 )
728  Init = IO_BLIF_INIT_DC;
729  // get latch input
730  pObj = Io_BlifHashFindOrAdd( p, (char *)Vec_PtrEntry(p->vTokens,1) );
731  pObj->fLi = 1;
732  Vec_PtrPush( p->vLis, pObj );
733  pObj->Init = Init;
734  // get latch output
735  pObj = Io_BlifHashFindOrAdd( p, (char *)Vec_PtrEntry(p->vTokens,2) );
736  if ( pObj->fPi )
737  {
738  sprintf( p->sError, "Line %d: Primary input (%s) is also defined latch output.", Io_BlifGetLine(p, pToken), (char*)Vec_PtrEntry(p->vTokens,2) );
739  return 0;
740  }
741  if ( pObj->fLo )
742  {
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) );
744  return 0;
745  }
746  pObj->fLo = 1;
747  Vec_PtrPush( p->vLos, pObj );
748  pObj->Init = Init;
749  return 1;
750 }
751 
752 /**Function*************************************************************
753 
754  Synopsis [Parses the nodes line.]
755 
756  Description []
757 
758  SideEffects []
759 
760  SeeAlso []
761 
762 ***********************************************************************/
763 static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine )
764 {
765  Io_BlifObj_t * pObj;
766  char * pName;
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 );
771  if ( pObj->fPi )
772  {
773  sprintf( p->sError, "Line %d: Primary input (%s) has a table.", Io_BlifGetLine(p, pName), pName );
774  return 0;
775  }
776  if ( pObj->fLo )
777  {
778  sprintf( p->sError, "Line %d: Latch output (%s) has a table.", Io_BlifGetLine(p, pName), pName );
779  return 0;
780  }
781  if ( pObj->fDef )
782  {
783  sprintf( p->sError, "Line %d: Signal (%s) is defined more than once.", Io_BlifGetLine(p, pName), pName );
784  return 0;
785  }
786  pObj->fDef = 1;
787  // remember offset to the first fanin name
788  pObj->pName = pName;
789  pObj->Offset = pObj->pName - (char *)Vec_PtrEntry(p->vTokens,1);
790  return 1;
791 }
792 
793 
794 /**Function*************************************************************
795 
796  Synopsis [Constructs the AIG from the file parsing info.]
797 
798  Description []
799 
800  SideEffects []
801 
802  SeeAlso []
803 
804 ***********************************************************************/
805 static Abc_Obj_t * Io_BlifParseTable( Io_BlifMan_t * p, char * pTable, Vec_Ptr_t * vFanins )
806 {
807  char * pProduct, * pOutput;
808  Abc_Obj_t * pRes, * pCube;
809  int i, k, Polarity = -1;
810 
811  p->nTablesRead++;
812  // get the tokens
813  Io_BlifSplitIntoTokens( p->vTokens, pTable, '.' );
814  if ( Vec_PtrSize(p->vTokens) == 0 )
815  return Abc_ObjNot( Abc_AigConst1(p->pAig) );
816  if ( Vec_PtrSize(p->vTokens) == 1 )
817  {
818  pOutput = (char *)Vec_PtrEntry( p->vTokens, 0 );
819  if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
820  {
821  sprintf( p->sError, "Line %d: Constant table has wrong output value (%s).", Io_BlifGetLine(p, pOutput), pOutput );
822  return NULL;
823  }
824  return Abc_ObjNotCond( Abc_AigConst1(p->pAig), pOutput[0] == '0' );
825  }
826  pProduct = (char *)Vec_PtrEntry( p->vTokens, 0 );
827  if ( Vec_PtrSize(p->vTokens) % 2 == 1 )
828  {
829  sprintf( p->sError, "Line %d: Table has odd number of tokens (%d).", Io_BlifGetLine(p, pProduct), Vec_PtrSize(p->vTokens) );
830  return NULL;
831  }
832  // parse the table
833  pRes = Abc_ObjNot( Abc_AigConst1(p->pAig) );
834  for ( i = 0; i < Vec_PtrSize(p->vTokens)/2; i++ )
835  {
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) )
839  {
840  sprintf( p->sError, "Line %d: Cube (%s) has size different from the fanin count (%d).", Io_BlifGetLine(p, pProduct), pProduct, Vec_PtrSize(vFanins) );
841  return NULL;
842  }
843  if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
844  {
845  sprintf( p->sError, "Line %d: Output value (%s) is incorrect.", Io_BlifGetLine(p, pProduct), pOutput );
846  return NULL;
847  }
848  if ( Polarity == -1 )
849  Polarity = pOutput[0] - '0';
850  else if ( Polarity != pOutput[0] - '0' )
851  {
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 );
853  return NULL;
854  }
855  // parse one product product
856  pCube = Abc_AigConst1(p->pAig);
857  for ( k = 0; pProduct[k]; k++ )
858  {
859  if ( pProduct[k] == '0' )
860  pCube = Abc_AigAnd( (Abc_Aig_t *)p->pAig->pManFunc, pCube, Abc_ObjNot((Abc_Obj_t *)Vec_PtrEntry(vFanins,k)) );
861  else if ( pProduct[k] == '1' )
862  pCube = Abc_AigAnd( (Abc_Aig_t *)p->pAig->pManFunc, pCube, (Abc_Obj_t *)Vec_PtrEntry(vFanins,k) );
863  else if ( pProduct[k] != '-' )
864  {
865  sprintf( p->sError, "Line %d: Product term (%s) contains character (%c).", Io_BlifGetLine(p, pProduct), pProduct, pProduct[k] );
866  return NULL;
867  }
868  }
869  pRes = Abc_AigOr( (Abc_Aig_t *)p->pAig->pManFunc, pRes, pCube );
870  }
871  pRes = Abc_ObjNotCond( pRes, Polarity == 0 );
872  return pRes;
873 }
874 
875 /**Function*************************************************************
876 
877  Synopsis [Constructs the AIG from the file parsing info.]
878 
879  Description []
880 
881  SideEffects []
882 
883  SeeAlso []
884 
885 ***********************************************************************/
887 {
888  Vec_Ptr_t * vFanins;
889  Abc_Obj_t * pFaninAbc;
890  Io_BlifObj_t * pObjIo;
891  char * pNameFanin;
892  int i;
893  // get the IO object with this name
894  pObjIo = *Io_BlifHashLookup( p, pName );
895  if ( pObjIo == NULL )
896  {
897  sprintf( p->sError, "Line %d: Signal (%s) is not defined as a table.", Io_BlifGetLine(p, pName), pName );
898  return NULL;
899  }
900  // loop detection
901  if ( pObjIo->fLoop )
902  {
903  sprintf( p->sError, "Line %d: Signal (%s) appears twice on a combinational path.", Io_BlifGetLine(p, pName), pName );
904  return NULL;
905  }
906  // check if the AIG is already constructed
907  if ( pObjIo->pEquiv )
908  return (Abc_Obj_t *)pObjIo->pEquiv;
909  // mark this node on the path
910  pObjIo->fLoop = 1;
911  // construct the AIGs for the fanins
912  vFanins = Vec_PtrAlloc( 8 );
913  Io_BlifCollectTokens( vFanins, pObjIo->pName - pObjIo->Offset, pObjIo->pName );
914  Vec_PtrForEachEntry( char *, vFanins, pNameFanin, i )
915  {
916  pFaninAbc = Io_BlifParseConstruct_rec( p, pNameFanin );
917  if ( pFaninAbc == NULL )
918  {
919  Vec_PtrFree( vFanins );
920  return NULL;
921  }
922  Vec_PtrWriteEntry( vFanins, i, pFaninAbc );
923  }
924  // construct the node
925  pObjIo->pEquiv = Io_BlifParseTable( p, pObjIo->pName + strlen(pObjIo->pName), vFanins );
926  Vec_PtrFree( vFanins );
927  // unmark this node on the path
928  pObjIo->fLoop = 0;
929  // remember the new node
930  return (Abc_Obj_t *)pObjIo->pEquiv;
931 }
932 
933 /**Function*************************************************************
934 
935  Synopsis [Constructs the AIG from the file parsing info.]
936 
937  Description []
938 
939  SideEffects []
940 
941  SeeAlso []
942 
943 ***********************************************************************/
945 {
946  Abc_Ntk_t * pAig;
947  Io_BlifObj_t * pObjIo, * pObjIoInput;
948  Abc_Obj_t * pObj, * pLatch;
949  int i;
950  // allocate the empty AIG
951  pAig = p->pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
952  pAig->pName = Extra_UtilStrsav( p->pModel );
953  pAig->pSpec = Extra_UtilStrsav( p->pFileName );
954  // create PIs
955  Vec_PtrForEachEntry( Io_BlifObj_t *, p->vPis, pObjIo, i )
956  {
957  pObj = Abc_NtkCreatePi( pAig );
958  Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
959  pObjIo->pEquiv = pObj;
960  }
961  // create POs
962  Vec_PtrForEachEntry( Io_BlifObj_t *, p->vPos, pObjIo, i )
963  {
964  pObj = Abc_NtkCreatePo( pAig );
965  Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
966  }
967  // create latches
968  Vec_PtrForEachEntry( Io_BlifObj_t *, p->vLos, pObjIo, i )
969  {
970  // add the latch input terminal
971  pObj = Abc_NtkCreateBi( pAig );
972  pObjIoInput = (Io_BlifObj_t *)Vec_PtrEntry( p->vLis, i );
973  Abc_ObjAssignName( pObj, pObjIoInput->pName, NULL );
974 
975  // add the latch box
976  pLatch = Abc_NtkCreateLatch( pAig );
977  pLatch->pData = (void *)(ABC_PTRUINT_T)pObjIo->Init;
978  Abc_ObjAssignName( pLatch, pObjIo->pName, "L" );
979  Abc_ObjAddFanin( pLatch, pObj );
980 
981  // add the latch output terminal
982  pObj = Abc_NtkCreateBo( pAig );
983  Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
984  Abc_ObjAddFanin( pObj, pLatch );
985  // set the value of the latch output
986 // pObjIo->pEquiv = Abc_ObjNotCond( pObj, pObjIo->Init );
987  pObjIo->pEquiv = pObj;
988  }
989  // traverse the nodes from the POs
990  Vec_PtrForEachEntry( Io_BlifObj_t *, p->vPos, pObjIo, i )
991  {
992  pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
993  if ( pObj == NULL )
994  return 0;
995  Abc_ObjAddFanin( Abc_NtkPo(p->pAig, i), pObj );
996  }
997  // traverse the nodes from the latch inputs
998  Vec_PtrForEachEntry( Io_BlifObj_t *, p->vLis, pObjIo, i )
999  {
1000  pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
1001  if ( pObj == NULL )
1002  return 0;
1003 // pObj = Abc_ObjNotCond( pObj, pObjIo->Init );
1004  Abc_ObjAddFanin( Abc_ObjFanin0(Abc_NtkBox(p->pAig, i)), pObj );
1005  }
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) );
1010  return 1;
1011 }
1012 
1013 ////////////////////////////////////////////////////////////////////////
1014 /// END OF FILE ///
1015 ////////////////////////////////////////////////////////////////////////
1016 
1017 
1019 
char * memset()
Vec_Ptr_t * vLos
Definition: ioReadBlifAig.c:76
static Io_BlifObj_t * Io_BlifHashFindOrAdd(Io_BlifMan_t *p, char *pName)
static int Io_BlifParseLatch(Io_BlifMan_t *p, char *pLine)
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
Vec_Ptr_t * vOutputs
Definition: ioReadBlifAig.c:69
unsigned fPi
Definition: ioReadBlifAig.c:42
ABC_DLL Abc_Obj_t * Abc_AigOr(Abc_Aig_t *pMan, Abc_Obj_t *p0, Abc_Obj_t *p1)
Definition: abcAig.c:719
static Abc_Obj_t * Io_BlifParseConstruct_rec(Io_BlifMan_t *p, char *pName)
#define Vec_PtrForEachEntryStart(Type, vVec, pEntry, i, Start)
Definition: vecPtr.h:57
ABC_DLL Abc_Obj_t * Abc_AigConst1(Abc_Ntk_t *pNtk)
Definition: abcAig.c:683
Io_BlifInit_t
DECLARATIONS ///.
Definition: ioReadBlifAig.c:32
static Llb_Mgr_t * p
Definition: llb3Image.c:950
static void Io_BlifSplitIntoTokens(Vec_Ptr_t *vTokens, char *pLine, char Stop)
Vec_Ptr_t * vPis
Definition: ioReadBlifAig.c:73
static int Io_BlifParseModel(Io_BlifMan_t *p, char *pLine)
#define SEEK_END
Definition: zconf.h:392
static void Io_BlifCollectTokens(Vec_Ptr_t *vTokens, char *pInput, char *pOutput)
static int Io_BlifParseOutputs(Io_BlifMan_t *p, char *pLine)
char * pFileName
Definition: ioReadBlifAig.c:59
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static void Io_BlifFree(Io_BlifMan_t *p)
unsigned fLi
Definition: ioReadBlifAig.c:44
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition: abcNames.c:68
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
Vec_Ptr_t * vLines
Definition: ioReadBlifAig.c:61
DECLARATIONS ///.
Definition: abcAig.c:52
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition: abcNtk.c:1233
char * Extra_UtilStrsav(const char *s)
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition: abcFanio.c:84
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
Definition: abcNtk.c:50
int strcmp()
static Abc_Obj_t * Abc_NtkCreateBo(Abc_Ntk_t *pNtk)
Definition: abc.h:306
unsigned fDef
Definition: ioReadBlifAig.c:46
Abc_Ntk_t * pAig
Definition: ioReadBlifAig.c:81
char sError[512]
Definition: ioReadBlifAig.c:83
void * pManFunc
Definition: abc.h:191
static int Abc_NtkNodeNum(Abc_Ntk_t *pNtk)
Definition: abc.h:293
unsigned fPo
Definition: ioReadBlifAig.c:43
ABC_DLL Abc_Obj_t * Abc_AigAnd(Abc_Aig_t *pMan, Abc_Obj_t *p0, Abc_Obj_t *p1)
Definition: abcAig.c:700
static int s_Primes[MAX_PRIMES]
Definition: fxuPair.c:30
Vec_Ptr_t * vPos
Definition: ioReadBlifAig.c:74
static void * Vec_PtrEntryLast(Vec_Ptr_t *p)
Definition: vecPtr.h:413
ABC_DLL int Abc_NtkCheckRead(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:77
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static unsigned Io_BlifHashString(char *pName, int TableSize)
static Abc_Ntk_t * Io_BlifParse(Io_BlifMan_t *p)
static Abc_Obj_t * Abc_NtkCreateLatch(Abc_Ntk_t *pNtk)
Definition: abc.h:309
char * sprintf()
Io_BlifObj_t * pNext
Definition: ioReadBlifAig.c:52
static int Counter
static Abc_Obj_t * Abc_NtkCreatePi(Abc_Ntk_t *pNtk)
Definition: abc.h:303
static int Io_BlifParseNames(Io_BlifMan_t *p, char *pLine)
static int Io_BlifGetLine(Io_BlifMan_t *p, char *pToken)
static void Vec_PtrWriteEntry(Vec_Ptr_t *p, int i, void *Entry)
Definition: vecPtr.h:396
char * strcpy()
static Abc_Obj_t * Abc_NtkBox(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:319
unsigned fLoop
Definition: ioReadBlifAig.c:47
#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 Abc_Obj_t * Io_BlifParseTable(Io_BlifMan_t *p, char *pTable, Vec_Ptr_t *vFanins)
static int Io_BlifEstimateAndNum(Io_BlifMan_t *p)
static char * Io_BlifLoadFile(char *pFileName)
char * pSpec
Definition: abc.h:159
static int Io_BlifEstimatePiNum(Io_BlifMan_t *p)
static int Io_BlifParseConstruct(Io_BlifMan_t *p)
unsigned Offset
Definition: ioReadBlifAig.c:49
static Abc_Obj_t * Abc_NtkPo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:316
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
#define ABC_FREE(obj)
Definition: abc_global.h:232
static void Io_BlifReadPreparse(Io_BlifMan_t *p)
Vec_Ptr_t * vLatches
Definition: ioReadBlifAig.c:70
Vec_Ptr_t * vInputs
Definition: ioReadBlifAig.c:68
Abc_Ntk_t * Io_ReadBlifAsAig(char *pFileName, int fCheck)
FUNCTION DEFINITIONS ///.
int strncmp()
Io_BlifObj_t * pObjects
Definition: ioReadBlifAig.c:63
static Io_BlifMan_t * Io_BlifAlloc()
static Abc_Obj_t * Abc_ObjNotCond(Abc_Obj_t *p, int c)
Definition: abc.h:325
#define assert(ex)
Definition: util_old.h:213
static int Io_BlifCharIsSpace(char s)
static void Vec_PtrClear(Vec_Ptr_t *p)
Definition: vecPtr.h:545
int strlen()
static Abc_Obj_t * Abc_ObjNot(Abc_Obj_t *p)
Definition: abc.h:324
Vec_Ptr_t * vNames
Definition: ioReadBlifAig.c:71
void * pData
Definition: abc.h:145
Io_BlifObj_t ** pTable
Definition: ioReadBlifAig.c:78
static Abc_Obj_t * Abc_NtkCreateBi(Abc_Ntk_t *pNtk)
Definition: abc.h:305
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
unsigned fLo
Definition: ioReadBlifAig.c:45
static int Io_BlifParseInputs(Io_BlifMan_t *p, char *pLine)
static Io_BlifObj_t ** Io_BlifHashLookup(Io_BlifMan_t *p, char *pName)
static Abc_Obj_t * Abc_NtkCreatePo(Abc_Ntk_t *pNtk)
Definition: abc.h:304
VOID_HACK rewind()
char * pName
Definition: abc.h:158
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
unsigned Init
Definition: ioReadBlifAig.c:48
Vec_Ptr_t * vTokens
Definition: ioReadBlifAig.c:82
Vec_Ptr_t * vLis
Definition: ioReadBlifAig.c:75