1 /**CFile****************************************************************
2 
3   FileName    [giaGig.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Scalable AIG package.]
8 
9   Synopsis    [Parser for Gate-Inverter Graph by Niklas Een.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: giaGig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "gia.h"
22 #include "misc/extra/extra.h"
23 #include "misc/util/utilTruth.h"
24 
25 ABC_NAMESPACE_IMPL_START
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 ///                        DECLARATIONS                              ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 #define MAX_LINE 1000000
33 
34 // network types
35 enum {
36     GLS_NONE = -1,  // not used
37     GLS_ZERO =  0,  // zero
38     GLS_ONE  =  1,  // one
39     GLS_PI   =  2,  // primary input
40     GLS_PO   =  3,  // primary output
41     GLS_BAR  =  4,  // barrier
42     GLS_SEQ  =  5,  // sequential
43     GLS_SEL  =  6,  // fan
44     GLS_LUT4 =  7,  // LUT4
45     GLS_LUT6 =  8,  // LUT6
46     GLS_BOX  =  9,  // sequential box
47     GLS_DEL  = 10,  // delay box
48     GLS_FINAL
49 };
50 
51 static char * s_Strs[GLS_FINAL] =
52 {
53     "0",     // GLS_ZERO =  0,  // zero
54     "1",     // GLS_ONE  =  1,  // one
55     "PI",    // GLS_PI   =  2,  // primary input
56     "PO",    // GLS_PO   =  3,  // primary output
57     "Bar",   // GLS_BAR  =  4,  // barrier
58     "Seq",   // GLS_SEQ  =  5,  // sequential
59     "Sel",   // GLS_SEL  =  6,  // fan
60     "Lut4",  // GLS_LUT4 =  7,  // LUT4
61     "Lut6",  // GLS_LUT6 =  8,  // LUT6
62     "Box",   // GLS_BOX  =  9,  // sequential box
63     "Del"    // GLS_DEL  = 10,  // delay box
64 };
65 
66 typedef struct Gls_Man_t_ Gls_Man_t;
67 struct Gls_Man_t_
68 {
69     // general
70     Vec_Str_t *    vLines;       // line types
71     Vec_Str_t *    vTypes;       // gate types
72     Vec_Int_t *    vIndexes;     // gate indexes
73     // specific types
74     Vec_Int_t *    vLut4s;       // 4-LUTs (4-tuples)
75     Vec_Int_t *    vLut4TTs;     // truth tables
76     Vec_Int_t *    vLut6s;       // 6-LUTs (6-tuples)
77     Vec_Wrd_t *    vLut6TTs;     // truth tables
78     Vec_Int_t *    vBoxes;       // boxes (5-tuples)
79     Vec_Wec_t *    vDelayIns;    // delay fanins
80     Vec_Wec_t *    vDelayOuts;   // delay fanouts
81     Vec_Int_t *    vDelays;      // delay values
82     // ordering
83     Vec_Int_t *    vOrderPis;
84     Vec_Int_t *    vOrderPos;
85     Vec_Int_t *    vOrderBoxes;
86     Vec_Int_t *    vOrderDelays;
87     Vec_Int_t *    vOrderLuts;
88     Vec_Int_t *    vOrderSeqs;
89 };
90 
91 ////////////////////////////////////////////////////////////////////////
92 ///                     FUNCTION DEFINITIONS                         ///
93 ////////////////////////////////////////////////////////////////////////
94 
95 /**Function*************************************************************
96 
97   Synopsis    []
98 
99   Description []
100 
101   SideEffects []
102 
103   SeeAlso     []
104 
105 ***********************************************************************/
Gls_ManAlloc(Vec_Str_t * vLines,int * pCounts)106 Gls_Man_t * Gls_ManAlloc( Vec_Str_t * vLines, int * pCounts )
107 {
108     Gls_Man_t * p = ABC_CALLOC( Gls_Man_t, 1 );
109     p->vLines     = vLines;
110     p->vTypes     = Vec_StrStart( Vec_StrSize(vLines)+100 );
111     p->vIndexes   = Vec_IntStart( Vec_StrSize(vLines)+100 );
112     p->vLut4s     = Vec_IntAlloc( 4 * pCounts[GLS_LUT4] );
113     p->vLut4TTs   = Vec_IntAlloc( pCounts[GLS_LUT4] );
114     p->vLut6s     = Vec_IntAlloc( 6 * pCounts[GLS_LUT6] );
115     p->vLut6TTs   = Vec_WrdAlloc( pCounts[GLS_LUT6] );
116     p->vBoxes     = Vec_IntAlloc( 5 * pCounts[GLS_BOX] );
117     p->vDelays    = Vec_IntAlloc( pCounts[GLS_DEL] );
118     p->vDelayIns  = Vec_WecAlloc( pCounts[GLS_DEL] );
119     p->vDelayOuts = Vec_WecAlloc( pCounts[GLS_DEL] );
120     // ordering
121     p->vOrderPis    = Vec_IntAlloc( pCounts[GLS_PI] );
122     p->vOrderPos    = Vec_IntAlloc( pCounts[GLS_PO] );
123     p->vOrderBoxes  = Vec_IntAlloc( pCounts[GLS_BOX] );
124     p->vOrderDelays = Vec_IntAlloc( pCounts[GLS_DEL] );
125     p->vOrderLuts   = Vec_IntAlloc( pCounts[GLS_LUT4] + pCounts[GLS_LUT6] + 2*pCounts[GLS_BAR] );
126     p->vOrderSeqs   = Vec_IntAlloc( pCounts[GLS_SEQ] );
127     return p;
128 }
Gls_ManStop(Gls_Man_t * p)129 void Gls_ManStop( Gls_Man_t * p )
130 {
131     Vec_StrFree( p->vLines );
132     Vec_StrFree( p->vTypes );
133     Vec_IntFree( p->vIndexes );
134     Vec_IntFree( p->vLut4s );
135     Vec_IntFree( p->vLut4TTs );
136     Vec_IntFree( p->vLut6s );
137     Vec_WrdFree( p->vLut6TTs );
138     Vec_IntFree( p->vBoxes );
139     Vec_IntFree( p->vDelays );
140     Vec_WecFree( p->vDelayIns );
141     Vec_WecFree( p->vDelayOuts );
142     // ordering
143     Vec_IntFree( p->vOrderPis );
144     Vec_IntFree( p->vOrderPos );
145     Vec_IntFree( p->vOrderBoxes );
146     Vec_IntFree( p->vOrderDelays );
147     Vec_IntFree( p->vOrderLuts );
148     Vec_IntFree( p->vOrderSeqs );
149     ABC_FREE( p );
150 }
151 
152 /**Function*************************************************************
153 
154   Synopsis    []
155 
156   Description []
157 
158   SideEffects []
159 
160   SeeAlso     []
161 
162 ***********************************************************************/
Gls_ManCount(FILE * pFile,int pCounts[GLS_FINAL])163 Vec_Str_t * Gls_ManCount( FILE * pFile, int pCounts[GLS_FINAL] )
164 {
165     char * pLine, * pBuffer = ABC_ALLOC(char, MAX_LINE); int Type;
166     Vec_Str_t * vLines = Vec_StrAlloc( 10000 );
167     memset( pCounts, 0, sizeof(int)*GLS_FINAL );
168     while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
169     {
170         pLine = pBuffer;
171         while ( *pLine )
172             if ( *pLine++ == '=' )
173                 break;
174         while ( *pLine == ' ' )
175             pLine++;
176         if ( *pLine == 'L' )
177         {
178             if ( pLine[3] == '4' )
179                 Type = GLS_LUT4;
180             else if ( pLine[3] == '6' )
181                 Type = GLS_LUT6;
182             else assert( 0 );
183         }
184         else if ( *pLine == 'P' )
185         {
186             if ( pLine[1] == 'I' )
187                 Type = GLS_PI;
188             else if ( pLine[1] == 'O' )
189                 Type = GLS_PO;
190             else assert( 0 );
191         }
192         else if ( *pLine == 'B' )
193         {
194             if ( pLine[1] == 'o' )
195                 Type = GLS_BOX;
196             else if ( pLine[1] == 'a' )
197                 Type = GLS_BAR;
198             else assert( 0 );
199         }
200         else if ( *pLine == 'S' )
201         {
202             if ( pLine[2] == 'l' )
203                 Type = GLS_SEL;
204             else if ( pLine[2] == 'q' )
205                 Type = GLS_SEQ;
206             else assert( 0 );
207         }
208         else if ( *pLine == 'D' )
209             Type = GLS_DEL;
210         else assert( 0 );
211         Vec_StrPush( vLines, (char)Type );
212         pCounts[Type]++;
213     }
214     ABC_FREE( pBuffer );
215     return vLines;
216 }
Gls_ManParseOne(char ** ppLine)217 int Gls_ManParseOne( char ** ppLine )
218 {
219     int Entry;
220     char * pLine = *ppLine;
221     while ( *pLine == ' ' )   pLine++;
222     if ( *pLine == '-' )
223         Entry = GLS_NONE;
224     else if ( *pLine == '0' )
225         Entry = 0;
226     else if ( *pLine == '1' )
227         Entry = 1;
228     else if ( *pLine == 'w' )
229         Entry = atoi(++pLine);
230     else assert( 0 );
231     while ( *pLine == '-' || (*pLine >= '0' && *pLine <= '9') )   pLine++;
232     while ( *pLine == ' ' )   pLine++;
233     *ppLine = pLine;
234     return Entry;
235 }
Gls_ManParse(FILE * pFile,Gls_Man_t * p)236 int Gls_ManParse( FILE * pFile, Gls_Man_t * p )
237 {
238     char * pLine, * pBuffer = ABC_ALLOC(char, MAX_LINE);
239     int i, k, Type, iObj, Entry, iItem;  word Truth;
240     for ( i = 0; fgets( pBuffer, MAX_LINE, pFile ) != NULL; i++ )
241     {
242         pLine = pBuffer;
243         Type = Vec_StrEntry( p->vLines, i );
244         iObj = Gls_ManParseOne( &pLine );
245         Vec_StrWriteEntry( p->vTypes, iObj, (char)Type );
246         if ( Type == GLS_PI )
247         {
248             Vec_IntPush( p->vOrderPis, iObj );
249             Vec_IntWriteEntry( p->vIndexes, iObj, -1 );
250             continue;
251         }
252         while ( *pLine )
253             if ( *pLine++ == '(' )
254                 break;
255         Entry = Gls_ManParseOne( &pLine );
256         if ( Type == GLS_PO || Type == GLS_BAR || Type == GLS_SEQ || Type == GLS_SEL )
257         {
258             if ( Type == GLS_PO )
259                 Vec_IntPush( p->vOrderPos, iObj );
260             else if ( Type == GLS_BAR )
261                 Vec_IntPush( p->vOrderLuts, iObj );
262             else if ( Type == GLS_SEQ )
263                 Vec_IntPush( p->vOrderSeqs, iObj );
264             else if ( Type == GLS_SEL )
265             {
266                 if ( (int)Vec_StrEntry(p->vTypes, Entry) == GLS_DEL )
267                 {
268                     Vec_Int_t * vOuts = Vec_WecEntry( p->vDelayOuts, Vec_IntEntry(p->vIndexes, Entry) );
269                     Vec_IntPush( vOuts, iObj );
270                 }
271                 else if ( (int)Vec_StrEntry(p->vTypes, Entry) == GLS_BAR )
272                     Vec_IntPush( p->vOrderLuts, iObj );
273                 else assert( 0 );
274             }
275             Vec_IntWriteEntry( p->vIndexes, iObj, Entry );
276             continue;
277         }
278         if ( Type == GLS_LUT4 )
279         {
280             Vec_IntWriteEntry( p->vIndexes, iObj, Vec_IntSize(p->vLut4TTs) );
281             Vec_IntPush( p->vLut4s, Entry );
282             for ( k = 1; ; k++ )
283             {
284                 if ( *pLine != ',' )     break;
285                 pLine++;
286                 Entry = Gls_ManParseOne( &pLine );
287                 Vec_IntPush( p->vLut4s, Entry );
288             }
289             assert( *pLine == ')' );
290             assert( k == 4 );
291             pLine++;
292             while ( *pLine )
293                 if ( *pLine++ == '[' )
294                     break;
295             Abc_TtReadHex( &Truth, pLine );
296             Vec_IntPush( p->vLut4TTs, (unsigned)Truth );
297             Vec_IntPush( p->vOrderLuts, iObj );
298         }
299         else if ( Type == GLS_LUT6 )
300         {
301             Vec_IntWriteEntry( p->vIndexes, iObj, Vec_WrdSize(p->vLut6TTs) );
302             Vec_IntPush( p->vLut6s, Entry );
303             for ( k = 1; ; k++ )
304             {
305                 if ( *pLine != ',' )     break;
306                 pLine++;
307                 Entry = Gls_ManParseOne( &pLine );
308                 Vec_IntPush( p->vLut6s, Entry );
309             }
310             assert( *pLine == ')' );
311             assert( k == 4 );
312             pLine++;
313             while ( *pLine )
314                 if ( *pLine++ == '[' )
315                     break;
316             Abc_TtReadHex( &Truth, pLine );
317             Vec_WrdPush( p->vLut6TTs, Truth );
318             Vec_IntPush( p->vOrderLuts, iObj );
319         }
320         else if ( Type == GLS_BOX )
321         {
322             Vec_IntWriteEntry( p->vIndexes, iObj, Vec_IntSize(p->vBoxes)/5 );
323             Vec_IntPush( p->vBoxes, Entry );
324             for ( k = 1; ; k++ )
325             {
326                 if ( *pLine != ',' )     break;
327                 pLine++;
328                 Entry = Gls_ManParseOne( &pLine );
329                 Vec_IntPush( p->vBoxes, Entry );
330             }
331             assert( *pLine == ')' );
332             assert( k == 4 || k == 5 );
333             if ( k == 4 )
334                 Vec_IntPush( p->vBoxes, GLS_NONE );
335             Vec_IntPush( p->vOrderBoxes, iObj );
336         }
337         else if ( Type == GLS_DEL )
338         {
339             Vec_Int_t * vIns  = Vec_WecPushLevel( p->vDelayIns );
340             Vec_Int_t * vOuts = Vec_WecPushLevel( p->vDelayOuts );
341             Vec_IntWriteEntry( p->vIndexes, iObj, Vec_IntSize(p->vDelays) );
342             Vec_IntPush( vIns, Entry );
343             if ( *pLine != ')' )
344             {
345                 for ( k = 1; ; k++ )
346                 {
347                     if ( *pLine != ',' )     break;
348                     pLine++;
349                     Entry = Gls_ManParseOne( &pLine );
350                     Vec_IntPush( vIns, Entry );
351                 }
352             }
353             assert( *pLine == ')' );
354             pLine++;
355             while ( *pLine )
356                 if ( *pLine++ == '[' )
357                     break;
358             iItem = atoi(pLine);
359             Vec_IntPush( p->vDelays, iItem );
360             Vec_IntPush( p->vOrderDelays, iObj );
361             vOuts = vIns; // harmless use to prevent a compiler warning
362         }
363         else assert( 0 );
364     }
365     ABC_FREE( pBuffer );
366     return 1;
367 }
368 
369 /**Function*************************************************************
370 
371   Synopsis    []
372 
373   Description []
374 
375   SideEffects []
376 
377   SeeAlso     []
378 
379 ***********************************************************************/
Gls_ManConstruct(Gls_Man_t * p,char * pFileName)380 Gia_Man_t * Gls_ManConstruct( Gls_Man_t * p, char * pFileName )
381 {
382     extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
383     Gia_Man_t * pGia = NULL;
384     Vec_Int_t * vMap, * vArray;
385     Vec_Int_t * vCover = Vec_IntAlloc(0);
386     Vec_Int_t * vLeaves = Vec_IntAlloc(6);
387     int  k, iObj, iLit, Index;  char Type;
388     // create new manager
389     pGia = Gia_ManStart( Vec_StrSize(p->vTypes) );
390     pGia->pName = Abc_UtilStrsav( pFileName );
391     pGia->pSpec = Abc_UtilStrsav( pFileName );
392     // create constants
393     vMap = Vec_IntStartFull( Vec_StrSize(p->vTypes) );
394     Vec_IntWriteEntry( vMap, 0, 0 );
395     Vec_IntWriteEntry( vMap, 1, 1 );
396     // create primary inputs
397     Vec_IntForEachEntry( p->vOrderPis, iObj, k )
398         Vec_IntWriteEntry( vMap, iObj, Gia_ManAppendCi(pGia) );
399     // create box outputs
400     Vec_IntForEachEntry( p->vOrderBoxes, iObj, k )
401         Vec_IntWriteEntry( vMap, iObj, Gia_ManAppendCi(pGia) );
402     // create delay outputs
403     Vec_IntForEachEntry( p->vOrderDelays, iObj, Index )
404     {
405         assert( Index == Vec_IntEntry(p->vIndexes, iObj) );
406         vArray = Vec_WecEntry(p->vDelayOuts, Index);
407         if ( Vec_IntSize(vArray) == 0 )
408             Vec_IntWriteEntry( vMap, iObj, Gia_ManAppendCi(pGia) );
409         else
410             Vec_IntForEachEntry( vArray, iObj, k )
411                 Vec_IntWriteEntry( vMap, iObj, Gia_ManAppendCi(pGia) );
412     }
413     // construct LUTs
414     Vec_IntForEachEntry( p->vOrderLuts, iObj, Index )
415     {
416         Type = Vec_StrEntry( p->vTypes, iObj );
417         if ( Type == GLS_LUT4 || Type == GLS_LUT6 )
418         {
419             int Limit = Type == GLS_LUT4 ? 4 : 6;
420             int Index = Vec_IntEntry(p->vIndexes, iObj);
421             int * pFanins = Type == GLS_LUT4 ? Vec_IntEntryP(p->vLut4s, 4*Index) : Vec_IntEntryP(p->vLut6s, 6*Index);
422             word Truth = Type == GLS_LUT4 ? (word)Vec_IntEntry(p->vLut4TTs, Index) : Vec_WrdEntry(p->vLut6TTs, Index);
423             Vec_IntClear( vLeaves );
424             for ( k = 0; k < Limit; k++ )
425                 Vec_IntPush( vLeaves, pFanins[k] == GLS_NONE ? 0 : Vec_IntEntry(vMap, pFanins[k]) );
426             iLit = Kit_TruthToGia( pGia, (unsigned *)&Truth, Vec_IntSize(vLeaves), vCover, vLeaves, 0 );
427             Vec_IntWriteEntry( vMap, iObj, iLit );
428         }
429         else if ( Type == GLS_BAR || Type == GLS_SEL )
430         {
431             iLit = Vec_IntEntry( vMap, Vec_IntEntry(p->vIndexes, iObj) );
432             Vec_IntWriteEntry( vMap, iObj, iLit );
433         }
434     }
435     // delay inputs
436     Vec_IntForEachEntry( p->vOrderDelays, iObj, Index )
437     {
438         vArray = Vec_WecEntry(p->vDelayIns, Index);
439         assert( Vec_IntSize(vArray) > 0 );
440         Vec_IntForEachEntry( vArray, iObj, k )
441             Gia_ManAppendCo( pGia, Vec_IntEntry(vMap, iObj) );
442     }
443     // create primary outputs
444     Vec_IntForEachEntry( p->vOrderPos, iObj, k )
445         Gia_ManAppendCo( pGia, Vec_IntEntry(vMap, Vec_IntEntry(p->vIndexes, iObj)) );
446     // create sequential nodes
447     Vec_IntForEachEntry( p->vOrderSeqs, iObj, k )
448         Gia_ManAppendCo( pGia, Vec_IntEntry(vMap, Vec_IntEntry(p->vIndexes, iObj)) );
449     Vec_IntFree( vMap );
450     Vec_IntFree( vCover );
451     Vec_IntFree( vLeaves );
452     // print delay boxes
453 //    for ( k = 0; k < Vec_IntSize(p->vDelays); k++ )
454 //        printf( "%d:%d  ", Vec_IntSize(Vec_WecEntry(p->vDelayIns, k)), Vec_IntSize(Vec_WecEntry(p->vDelayOuts, k)) );
455 //    printf( "\n" );
456     return pGia;
457 }
458 
459 /**Function*************************************************************
460 
461   Synopsis    []
462 
463   Description []
464 
465   SideEffects []
466 
467   SeeAlso     []
468 
469 ***********************************************************************/
Gia_ManReadGig(char * pFileName)470 Gia_Man_t * Gia_ManReadGig( char * pFileName )
471 {
472     abctime clk = Abc_Clock();
473     Gls_Man_t * p = NULL;
474     Gia_Man_t * pGia = NULL;
475     Vec_Str_t * vLines;
476     int i, pCounts[GLS_FINAL];
477     FILE * pFile = fopen( pFileName, "rb" );
478     if ( pFile == NULL )
479     {
480         printf( "Cannot read file \"%s\".\n", pFileName );
481         return NULL;
482     }
483     vLines = Gls_ManCount( pFile, pCounts );
484     rewind( pFile );
485     // statistics
486     for ( i = 0; i < GLS_FINAL; i++ )
487         if ( pCounts[i] )
488             printf( "%s=%d  ", s_Strs[i], pCounts[i] );
489     Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
490     // collect data and derive AIG
491     p = Gls_ManAlloc( vLines, pCounts );
492     if ( Gls_ManParse( pFile, p ) )
493         pGia = Gls_ManConstruct( p, pFileName );
494     Gls_ManStop( p );
495     fclose( pFile );
496     //printf( "\n" );
497     return pGia;
498 }
499 
500 ////////////////////////////////////////////////////////////////////////
501 ///                       END OF FILE                                ///
502 ////////////////////////////////////////////////////////////////////////
503 
504 
505 ABC_NAMESPACE_IMPL_END
506 
507