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