1 /**CFile****************************************************************
2 
3   FileName    [mioRead.c]
4 
5   PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
6 
7   Synopsis    [File reading/writing for technology mapping.]
8 
9   Author      [MVSIS Group]
10 
11   Affiliation [UC Berkeley]
12 
13   Date        [Ver. 1.0. Started - September 8, 2003.]
14 
15   Revision    [$Id: mioRead.c,v 1.9 2004/10/19 06:40:16 satrajit Exp $]
16 
17 ***********************************************************************/
18 
19 #include <ctype.h>
20 #include "mioInt.h"
21 #include "base/io/ioAbc.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 static Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
35        Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
36 static int             Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
37 static Mio_Gate_t *    Mio_LibraryReadGate( char ** ppToken, int fExtendedFormat );
38 static Mio_Pin_t *     Mio_LibraryReadPin( char ** ppToken, int fExtendedFormat );
39 static char *          chomp( char *s );
40 static void            Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib );
41 static void            Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines );
42 
43 /**Function*************************************************************
44 
45   Synopsis    [Read the genlib type of library.]
46 
47   Description []
48 
49   SideEffects []
50 
51   SeeAlso     []
52 
53 ***********************************************************************/
Mio_LibraryRead(char * FileName,char * pBuffer,char * ExcludeFile,int fVerbose)54 Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * ExcludeFile, int fVerbose )
55 {
56     Mio_Library_t * pLib;
57     int num;
58     char * pBufferCopy;
59 
60     st__table * tExcludeGate = 0;
61 
62     if ( ExcludeFile )
63     {
64         tExcludeGate = st__init_table(strcmp, st__strhash);
65         if ( (num = Mio_LibraryReadExclude( ExcludeFile, tExcludeGate )) == -1 )
66         {
67             st__free_table( tExcludeGate );
68             tExcludeGate = 0;
69             return 0;
70         }
71         fprintf ( stdout, "Read %d gates from exclude file\n", num );
72     }
73 
74     pBufferCopy = Abc_UtilStrsav(pBuffer);
75     if ( pBuffer == NULL )
76         pLib = Mio_LibraryReadOne( FileName, 0, tExcludeGate, fVerbose );       // try normal format first ..
77     else
78     {
79         pLib = Mio_LibraryReadBuffer( pBuffer, 0, tExcludeGate, fVerbose );       // try normal format first ..
80         if ( pLib )
81             pLib->pName = Abc_UtilStrsav( Extra_FileNameGenericAppend(FileName, ".genlib") );
82     }
83     if ( pLib == NULL )
84     {
85         if ( pBuffer == NULL )
86             pLib = Mio_LibraryReadOne( FileName, 1, tExcludeGate, fVerbose );       // try normal format first ..
87         else
88         {
89             pLib = Mio_LibraryReadBuffer( pBufferCopy, 1, tExcludeGate, fVerbose );       // try normal format first ..
90             if ( pLib )
91                 pLib->pName = Abc_UtilStrsav( Extra_FileNameGenericAppend(FileName, ".genlib") );
92         }
93         if ( pLib != NULL )
94             printf ( "Warning: Read extended genlib format but ignoring extensions\n" );
95     }
96     ABC_FREE( pBufferCopy );
97     if ( tExcludeGate )
98         st__free_table( tExcludeGate );
99 
100     return pLib;
101 }
102 
103 /**Function*************************************************************
104 
105   Synopsis    [Read contents of the file.]
106 
107   Description []
108 
109   SideEffects []
110 
111   SeeAlso     []
112 
113 ***********************************************************************/
Mio_ReadFile(char * FileName,int fAddEnd)114 char * Mio_ReadFile( char * FileName, int fAddEnd )
115 {
116     char * pBuffer;
117     FILE * pFile;
118     int nFileSize;
119     int RetValue;
120 
121     // open the BLIF file for binary reading
122     pFile = Io_FileOpen( FileName, "open_path", "rb", 1 );
123 //    pFile = fopen( FileName, "rb" );
124     // if we got this far, file should be okay otherwise would
125     // have been detected by caller
126     assert ( pFile != NULL );
127     // get the file size, in bytes
128     fseek( pFile, 0, SEEK_END );
129     nFileSize = ftell( pFile );
130     // move the file current reading position to the beginning
131     rewind( pFile );
132     // load the contents of the file into memory
133     pBuffer   = ABC_ALLOC( char, nFileSize + 10 );
134     RetValue = fread( pBuffer, nFileSize, 1, pFile );
135     // terminate the string with '\0'
136     pBuffer[ nFileSize ] = '\0';
137     if ( fAddEnd )
138         strcat( pBuffer, "\n.end\n" );
139     // close file
140     fclose( pFile );
141     return pBuffer;
142 }
143 
144 /**Function*************************************************************
145 
146   Synopsis    [Read the genlib type of library.]
147 
148   Description []
149 
150   SideEffects []
151 
152   SeeAlso     []
153 
154 ***********************************************************************/
Mio_LibraryReadBuffer(char * pBuffer,int fExtendedFormat,st__table * tExcludeGate,int fVerbose)155 Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
156 {
157     Mio_Library_t * pLib;
158 
159     // allocate the genlib structure
160     pLib = ABC_CALLOC( Mio_Library_t, 1 );
161     pLib->tName2Gate = st__init_table(strcmp, st__strhash);
162     pLib->pMmFlex = Mem_FlexStart();
163     pLib->vCube = Vec_StrAlloc( 100 );
164 
165     Io_ReadFileRemoveComments( pBuffer, NULL, NULL );
166 
167     // parse the contents of the file
168     if ( Mio_LibraryReadInternal( pLib, pBuffer, fExtendedFormat, tExcludeGate, fVerbose ) )
169     {
170         Mio_LibraryDelete( pLib );
171         return NULL;
172     }
173 
174     // derive the functinality of gates
175     if ( Mio_LibraryParseFormulas( pLib ) )
176     {
177         printf( "Mio_LibraryRead: Had problems parsing formulas.\n" );
178         Mio_LibraryDelete( pLib );
179         return NULL;
180     }
181 
182     // detect INV and NAND2
183     Mio_LibraryDetectSpecialGates( pLib );
184 //Mio_WriteLibrary( stdout, pLib );
185     return pLib;
186 }
187 
188 /**Function*************************************************************
189 
190   Synopsis    [Read the genlib type of library.]
191 
192   Description []
193 
194   SideEffects []
195 
196   SeeAlso     []
197 
198 ***********************************************************************/
Mio_LibraryReadOne(char * FileName,int fExtendedFormat,st__table * tExcludeGate,int fVerbose)199 Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
200 {
201     Mio_Library_t * pLib;
202     char * pBuffer;
203     // read the file and clean comments
204     // pBuffer = Io_ReadFileFileContents( FileName, NULL );
205     // we don't use above function but actually do the same thing explicitly
206     // to handle open_path expansion correctly
207     pBuffer = Mio_ReadFile( FileName, 1 );
208     if ( pBuffer == NULL )
209         return NULL;
210     pLib = Mio_LibraryReadBuffer( pBuffer, fExtendedFormat, tExcludeGate, fVerbose );
211     ABC_FREE( pBuffer );
212     if ( pLib )
213         pLib->pName = Abc_UtilStrsav( FileName );
214     return pLib;
215 }
216 
217 /**Function*************************************************************
218 
219   Synopsis    [Read the genlib type of library.]
220 
221   Description []
222 
223   SideEffects []
224 
225   SeeAlso     []
226 
227 ***********************************************************************/
Mio_LibraryReadInternal(Mio_Library_t * pLib,char * pBuffer,int fExtendedFormat,st__table * tExcludeGate,int fVerbose)228 int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
229 {
230     Mio_Gate_t * pGate, ** ppGate;
231     char * pToken;
232     int nGates = 0;
233     int nDel = 0;
234 
235     // start the linked list of gates
236     pLib->pGates = NULL;
237     ppGate = &pLib->pGates;
238 
239     // read gates one by one
240     pToken = strtok( pBuffer, " \t\r\n" );
241     while ( pToken && (strcmp( pToken, MIO_STRING_GATE ) == 0 || strcmp( pToken, MIO_STRING_LATCH ) == 0) )
242     {
243         // skip latches
244         if ( strcmp( pToken, MIO_STRING_LATCH ) == 0 )
245         {
246             while ( pToken && strcmp( pToken, MIO_STRING_GATE ) != 0 && strcmp( pToken, ".end" ) != 0 )
247             {
248                 if ( strcmp( pToken, MIO_STRING_LATCH ) == 0 )
249                 {
250                     pToken = strtok( NULL, " \t\r\n" );
251                     printf( "Skipping latch \"%s\"...\n", pToken );
252                     continue;
253                 }
254                 pToken = strtok( NULL, " \t\r\n" );
255             }
256             if ( !(pToken && strcmp( pToken, MIO_STRING_GATE ) == 0) )
257                 break;
258         }
259 
260         // derive the next gate
261         pGate = Mio_LibraryReadGate( &pToken, fExtendedFormat );
262         if ( pGate == NULL )
263             return 1;
264 
265         // skip the gate if its formula has problems
266         if ( !Mio_ParseCheckFormula(pGate, pGate->pForm) )
267         {
268             Mio_GateDelete( pGate );
269             continue;
270         }
271 
272         // set the library
273         pGate->pLib = pLib;
274 
275         // printf ("Processing: '%s'\n", pGate->pName);
276 
277         if ( tExcludeGate && st__is_member( tExcludeGate, pGate->pName ) )
278         {
279             //printf ("Excluding: '%s'\n", pGate->pName);
280             Mio_GateDelete( pGate );
281             nDel++;
282         }
283         else
284         {
285             // add this gate to the list
286             *ppGate = pGate;
287             ppGate  = &pGate->pNext;
288             nGates++;
289 
290             // remember this gate by name
291             if ( ! st__is_member( pLib->tName2Gate, pGate->pName ) )
292                 st__insert( pLib->tName2Gate, pGate->pName, (char *)pGate );
293             else
294             {
295                 Mio_Gate_t * pBase = Mio_LibraryReadGateByName( pLib, pGate->pName, NULL );
296                 if ( pBase->pTwin != NULL )
297                 {
298                     printf( "Gates with more than 2 outputs are not supported.\n" );
299                     continue;
300                 }
301                 pBase->pTwin = pGate;
302                 pGate->pTwin = pBase;
303 //                printf( "Gate \"%s\" appears two times. Creating a 2-output gate.\n", pGate->pName );
304             }
305         }
306     }
307 
308     if ( nGates == 0 )
309     {
310         printf( "The library contains no gates.\n" );
311         return 1;
312     }
313 
314     // check what is the last word read
315     if ( pToken && strcmp( pToken, ".end" ) != 0 )
316         return 1;
317 
318     if ( nDel != 0 )
319         printf( "Actually excluded %d cells\n", nDel );
320 
321     return 0;
322 }
323 
324 /**Function*************************************************************
325 
326   Synopsis    [Read the genlib type of gate.]
327 
328   Description []
329 
330   SideEffects []
331 
332   SeeAlso     []
333 
334 ***********************************************************************/
Mio_LibraryCleanStr(char * p)335 char * Mio_LibraryCleanStr( char * p )
336 {
337     int i, k;
338     int whitespace_state = 0;
339     char * pRes = Abc_UtilStrsav( p );
340     for ( i = k = 0; pRes[i]; i++ )
341         if ( pRes[i] != ' ' && pRes[i] != '\t' && pRes[i] != '\r' && pRes[i] != '\n' )
342         {
343             if ( pRes[i] != '(' && pRes[i] != ')' && pRes[i] != '+' && pRes[i] != '*' && pRes[i] != '|' && pRes[i] != '&' && pRes[i] != '^' && pRes[i] != '\'' && pRes[i] != '!' )
344             {
345                 if (whitespace_state == 2)
346                     pRes[k++] = ' ';
347                 whitespace_state = 1;
348             }
349             else
350                 whitespace_state = 0;
351             pRes[k++] = pRes[i];
352         }
353         else
354             whitespace_state = whitespace_state ? 2 : 0;
355     pRes[k] = 0;
356     return pRes;
357 }
358 
Mio_LibraryReadGate(char ** ppToken,int fExtendedFormat)359 Mio_Gate_t * Mio_LibraryReadGate( char ** ppToken, int fExtendedFormat )
360 {
361     Mio_Gate_t * pGate;
362     Mio_Pin_t * pPin, ** ppPin;
363     char * pToken = *ppToken;
364 
365     // allocate the gate structure
366     pGate = ABC_CALLOC( Mio_Gate_t, 1 );
367     pGate->Cell = -1;
368 
369     // read the name
370     pToken = strtok( NULL, " \t\r\n" );
371     pGate->pName = Abc_UtilStrsav( pToken );
372 
373     // read the area
374     pToken = strtok( NULL, " \t\r\n" );
375     pGate->dArea = atof( pToken );
376 
377     // read the formula
378 
379     // first the output name
380     pToken = strtok( NULL, "=" );
381     pGate->pOutName = chomp( pToken );
382 
383     // then rest of the expression
384     pToken = strtok( NULL, ";" );
385 //    pGate->pForm = Mio_LibraryCleanStr( pToken );
386     pGate->pForm = Abc_UtilStrsav( pToken );
387 
388     // read the pin info
389     // start the linked list of pins
390     pGate->pPins = NULL;
391     ppPin = &pGate->pPins;
392 
393     // read gates one by one
394     pToken = strtok( NULL, " \t\r\n" );
395     while ( pToken && strcmp( pToken, MIO_STRING_PIN ) == 0 )
396     {
397         // derive the next gate
398         pPin = Mio_LibraryReadPin( &pToken, fExtendedFormat );
399         if ( pPin == NULL )
400         {
401             Mio_GateDelete( pGate );
402             *ppToken = pToken;
403             return NULL;
404         }
405         // add this pin to the list
406         *ppPin = pPin;
407         ppPin  = &pPin->pNext;
408         // get the next token
409         pToken = strtok( NULL, " \t\r\n" );
410     }
411 
412     *ppToken = pToken;
413     return pGate;
414 }
415 
416 
417 
418 /**Function*************************************************************
419 
420   Synopsis    [Read the genlib type of pin.]
421 
422   Description []
423 
424   SideEffects []
425 
426   SeeAlso     []
427 
428 ***********************************************************************/
Mio_LibraryReadPin(char ** ppToken,int fExtendedFormat)429 Mio_Pin_t * Mio_LibraryReadPin( char ** ppToken, int fExtendedFormat )
430 {
431     Mio_Pin_t * pPin;
432     char * pToken = *ppToken;
433 
434     // allocate the gate structure
435     pPin = ABC_CALLOC( Mio_Pin_t, 1 );
436 
437     // read the name
438     pToken = strtok( NULL, " \t\r\n" );
439     pPin->pName = Abc_UtilStrsav( pToken );
440 
441     // read the pin phase
442     pToken = strtok( NULL, " \t\r\n" );
443     if ( strcmp( pToken, MIO_STRING_UNKNOWN ) == 0 )
444         pPin->Phase = MIO_PHASE_UNKNOWN;
445     else if ( strcmp( pToken, MIO_STRING_INV ) == 0 )
446         pPin->Phase = MIO_PHASE_INV;
447     else if ( strcmp( pToken, MIO_STRING_NONINV ) == 0 )
448         pPin->Phase = MIO_PHASE_NONINV;
449     else
450     {
451         printf( "Cannot read pin phase specification\n" );
452         Mio_PinDelete( pPin );
453         *ppToken = pToken;
454         return NULL;
455     }
456 
457     pToken = strtok( NULL, " \t\r\n" );
458     pPin->dLoadInput = atof( pToken );
459 
460     pToken = strtok( NULL, " \t\r\n" );
461     pPin->dLoadMax = atof( pToken );
462 
463     pToken = strtok( NULL, " \t\r\n" );
464     pPin->dDelayBlockRise = atof( pToken );
465 
466     pToken = strtok( NULL, " \t\r\n" );
467     pPin->dDelayFanoutRise = atof( pToken );
468 
469     pToken = strtok( NULL, " \t\r\n" );
470     pPin->dDelayBlockFall = atof( pToken );
471 
472     pToken = strtok( NULL, " \t\r\n" );
473     pPin->dDelayFanoutFall = atof( pToken );
474 
475     if ( fExtendedFormat )
476     {
477         /* In extended format, the field after dDelayFanoutRise
478          * is to be ignored
479          **/
480 
481         pPin->dDelayBlockFall  = pPin->dDelayFanoutFall;
482 
483         pToken = strtok( NULL, " \t" );
484         pPin->dDelayFanoutFall = atof( pToken );
485 
486         /* last field is ignored */
487         pToken = strtok( NULL, " \t\r\n" );
488     }
489 
490     if ( pPin->dDelayBlockRise > pPin->dDelayBlockFall )
491         pPin->dDelayBlockMax = pPin->dDelayBlockRise;
492     else
493         pPin->dDelayBlockMax = pPin->dDelayBlockFall;
494 
495     *ppToken = pToken;
496     return pPin;
497 }
498 
499 
500 /**Function*************************************************************
501 
502   Synopsis    [Duplicates string and returns it with leading and
503                trailing spaces removed.]
504 
505   Description []
506 
507   SideEffects []
508 
509   SeeAlso     []
510 
511 ***********************************************************************/
chomp(char * s)512 char * chomp( char *s )
513 {
514     char *a, *b, *c;
515     // remove leading spaces
516     for ( b = s; *b; b++ )
517         if ( !isspace(*b) )
518             break;
519     // strsav the string
520     a = strcpy( ABC_ALLOC(char, strlen(b)+1), b );
521     // remove trailing spaces
522     for ( c = a+strlen(a); c > a; c-- )
523         if ( *c == 0 || isspace(*c) )
524             *c = 0;
525         else
526             break;
527     return a;
528 }
529 
530 /**Function*************************************************************
531 
532   Synopsis    []
533 
534   Description []
535 
536   SideEffects []
537 
538   SeeAlso     []
539 
540 ***********************************************************************/
Mio_LibraryCompareGatesByArea(Mio_Gate_t ** pp1,Mio_Gate_t ** pp2)541 int Mio_LibraryCompareGatesByArea( Mio_Gate_t ** pp1, Mio_Gate_t ** pp2 )
542 {
543     double Diff = (*pp1)->dArea - (*pp2)->dArea;
544     if ( Diff < 0.0 )
545         return -1;
546     if ( Diff > 0.0 )
547         return 1;
548     return 0;
549 }
550 
551 /**Function*************************************************************
552 
553   Synopsis    []
554 
555   Description []
556 
557   SideEffects []
558 
559   SeeAlso     []
560 
561 ***********************************************************************/
Mio_LibraryCompareGatesByName(Mio_Gate_t ** pp1,Mio_Gate_t ** pp2)562 int Mio_LibraryCompareGatesByName( Mio_Gate_t ** pp1, Mio_Gate_t ** pp2 )
563 {
564     int Diff = strcmp( (*pp1)->pName, (*pp2)->pName );
565     if ( Diff < 0 )
566         return -1;
567     if ( Diff > 0 )
568         return 1;
569     return 0;
570 }
571 
572 /**Function*************************************************************
573 
574   Synopsis    []
575 
576   Description []
577 
578   SideEffects []
579 
580   SeeAlso     []
581 
582 ***********************************************************************/
Mio_LibrarySortGates(Mio_Library_t * pLib)583 void Mio_LibrarySortGates( Mio_Library_t * pLib )
584 {
585     Mio_Gate_t ** ppGates, * pGate;
586     int i = 0;
587     ppGates = ABC_ALLOC( Mio_Gate_t *, pLib->nGates );
588     Mio_LibraryForEachGate( pLib, pGate )
589     {
590         pGate->Cell = i;
591         ppGates[i++] = pGate;
592     }
593     assert( i == pLib->nGates );
594     // sort gates by name
595     pLib->ppGates0 = ABC_ALLOC( Mio_Gate_t *, pLib->nGates );
596     for ( i = 0; i < pLib->nGates; i++ )
597         pLib->ppGates0[i] = ppGates[i];
598     qsort( (void *)ppGates, (size_t)pLib->nGates, sizeof(void *),
599             (int (*)(const void *, const void *)) Mio_LibraryCompareGatesByName );
600     for ( i = 0; i < pLib->nGates; i++ )
601         ppGates[i]->pNext = (i < pLib->nGates-1)? ppGates[i+1] : NULL;
602     pLib->pGates = ppGates[0];
603     pLib->ppGatesName = ppGates;
604 }
605 
606 /**Function*************************************************************
607 
608   Synopsis    []
609 
610   Description []
611 
612   SideEffects []
613 
614   SeeAlso     []
615 
616 ***********************************************************************/
Mio_GateCompare(Mio_Gate_t * pThis,Mio_Gate_t * pNew,word uTruth)617 static inline Mio_Gate_t * Mio_GateCompare( Mio_Gate_t * pThis, Mio_Gate_t * pNew, word uTruth )
618 {
619     if ( pNew->uTruth != uTruth )
620         return pThis;
621     if ( pThis == NULL )
622         return pNew;
623     if ( pThis->dArea > pNew->dArea || (pThis->dArea == pNew->dArea && strcmp(pThis->pName, pNew->pName) > 0) )
624         return pNew;
625     return pThis;
626 }
Mio_LibraryDetectSpecialGates(Mio_Library_t * pLib)627 void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
628 {
629     Mio_Gate_t * pGate;
630     word uFuncBuf, uFuncInv, uFuncNand2, uFuncAnd2, uFuncNor2, uFuncOr2;
631 
632     Mio_LibrarySortGates( pLib );
633 
634     uFuncBuf   = ABC_CONST(0xAAAAAAAAAAAAAAAA);
635     uFuncAnd2  = ABC_CONST(0xAAAAAAAAAAAAAAAA) & ABC_CONST(0xCCCCCCCCCCCCCCCC);
636     uFuncOr2   = ABC_CONST(0xAAAAAAAAAAAAAAAA) | ABC_CONST(0xCCCCCCCCCCCCCCCC);
637     uFuncInv   = ~uFuncBuf;
638     uFuncNand2 = ~uFuncAnd2;
639     uFuncNor2  = ~uFuncOr2;
640 
641     // get smallest-area buffer
642     Mio_LibraryForEachGate( pLib, pGate )
643         pLib->pGateBuf = Mio_GateCompare( pLib->pGateBuf, pGate, uFuncBuf );
644     if ( pLib->pGateBuf == NULL )
645     {
646         printf( "Warnings: genlib library reader cannot detect the buffer gate.\n" );
647         printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
648     }
649 
650     // get smallest-area inverter
651     Mio_LibraryForEachGate( pLib, pGate )
652         pLib->pGateInv = Mio_GateCompare( pLib->pGateInv, pGate, uFuncInv );
653     if ( pLib->pGateInv == NULL )
654     {
655         printf( "Warnings: genlib library reader cannot detect the invertor gate.\n" );
656         printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
657     }
658 
659     // get smallest-area NAND2/AND2 gates
660     Mio_LibraryForEachGate( pLib, pGate )
661     {
662         pLib->pGateNand2 = Mio_GateCompare( pLib->pGateNand2, pGate, uFuncNand2 );
663         pLib->pGateAnd2 = Mio_GateCompare( pLib->pGateAnd2, pGate, uFuncAnd2 );
664         pLib->pGateNor2 = Mio_GateCompare( pLib->pGateNor2, pGate, uFuncNor2 );
665         pLib->pGateOr2 = Mio_GateCompare( pLib->pGateOr2, pGate, uFuncOr2 );
666     }
667     if ( pLib->pGateAnd2 == NULL && pLib->pGateNand2 == NULL && pLib->pGateNor2 == NULL && pLib->pGateOr2 == NULL )
668     {
669         printf( "Warnings: genlib library reader cannot detect the AND2, NAND2, OR2, and NOR2 gate.\n" );
670         printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
671     }
672 }
673 
674 /**Function*************************************************************
675 
676   Synopsis    [populate hash table of gates to be exlcuded from genlib]
677 
678   Description []
679 
680   SideEffects []
681 
682   SeeAlso     []
683 
684 ***********************************************************************/
Mio_LibraryReadExclude(char * ExcludeFile,st__table * tExcludeGate)685 int Mio_LibraryReadExclude( char * ExcludeFile, st__table * tExcludeGate )
686 {
687     int nDel = 0;
688     FILE *pEx;
689     char buffer[128];
690 
691     assert ( tExcludeGate );
692 
693     if ( ExcludeFile )
694     {
695         pEx = fopen( ExcludeFile, "r" );
696 
697         if ( pEx == NULL )
698         {
699             fprintf ( stdout, "Error: Could not open exclude file %s. Stop.\n", ExcludeFile );
700             return -1;
701         }
702 
703         while (1 == fscanf( pEx, "%127s", buffer ))
704         {
705             //printf ("Read: '%s'\n", buffer );
706             st__insert( tExcludeGate, Abc_UtilStrsav( buffer ), (char *)0 );
707             nDel++;
708         }
709 
710         fclose( pEx );
711     }
712 
713     return nDel;
714 }
715 
716 /**Function*************************************************************
717 
718   Synopsis    [Eliminates comments from the input file.]
719 
720   Description [As a byproduct, this procedure also counts the number
721   lines and dot-statements in the input file. This also joins non-comment
722   lines that are joined with a backspace '\']
723 
724   SideEffects []
725 
726   SeeAlso     []
727 
728 ***********************************************************************/
Io_ReadFileRemoveComments(char * pBuffer,int * pnDots,int * pnLines)729 void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines )
730 {
731     char * pCur;
732     int nDots, nLines;
733     // scan through the buffer and eliminate comments
734     // (in the BLIF file, comments are lines starting with "#")
735     nDots = nLines = 0;
736     for ( pCur = pBuffer; *pCur; pCur++ )
737     {
738         // if this is the beginning of comment
739         // clean it with spaces until the new line statement
740         if ( *pCur == '#' )
741             while ( *pCur != '\n' )
742                 *pCur++ = ' ';
743 
744         // count the number of new lines and dots
745         if ( *pCur == '\n' ) {
746         if (*(pCur-1)=='\r') {
747         // DOS(R) file support
748         if (*(pCur-2)!='\\') nLines++;
749         else {
750             // rewind to backslash and overwrite with a space
751             *(pCur-2) = ' ';
752             *(pCur-1) = ' ';
753             *pCur = ' ';
754         }
755         } else {
756         // UNIX(TM) file support
757         if (*(pCur-1)!='\\') nLines++;
758         else {
759             // rewind to backslash and overwrite with a space
760             *(pCur-1) = ' ';
761             *pCur = ' ';
762         }
763         }
764     }
765         else if ( *pCur == '.' )
766             nDots++;
767     }
768     if ( pnDots )
769         *pnDots = nDots;
770     if ( pnLines )
771         *pnLines = nLines;
772 }
773 
774 ////////////////////////////////////////////////////////////////////////
775 ///                       END OF FILE                                ///
776 ////////////////////////////////////////////////////////////////////////
777 
778 
779 ABC_NAMESPACE_IMPL_END
780 
781