ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
amapLiberty.c
Go to the documentation of this file.
1
20
21#include "amapInt.h"
22
24
25
29
30#define ABC_MAX_LIB_STR_LEN 5000
31
32// entry types
33typedef enum {
34 AMAP_LIBERTY_NONE = 0, // 0: unknown
35 AMAP_LIBERTY_PROC, // 1: procedure : key(head){body}
36 AMAP_LIBERTY_EQUA, // 2: equation : key:head;
37 AMAP_LIBERTY_LIST // 3: list : key(head)
39
42{
43 int Beg; // item beginning
44 int End; // item end
45};
46
49{
50 int Type; // Amap_LibertyType_t
51 int iLine; // file line where the item's spec begins
52 Amap_Pair_t Key; // key part
53 Amap_Pair_t Head; // head part
54 Amap_Pair_t Body; // body part
55 int Next; // next item in the list
56 int Child; // first child item
57};
58
61{
62 char * pFileName; // input Liberty file name
63 char * pContents; // file contents
64 int nContents; // file size
65 int nLines; // line counter
66 int nItems; // number of items
67 int nItermAlloc; // number of items allocated
68 Amap_Item_t * pItems; // the items
69 char * pError; // the error string
70};
71
72static inline Amap_Item_t * Amap_LibertyRoot( Amap_Tree_t * p ) { return p->pItems; }
73static inline Amap_Item_t * Amap_LibertyItem( Amap_Tree_t * p, int v ) { assert( v < p->nItems ); return v < 0 ? NULL : p->pItems + v; }
74static inline int Amap_LibertyCompare( Amap_Tree_t * p, Amap_Pair_t Pair, char * pStr ) { return strncmp( p->pContents+Pair.Beg, pStr, Pair.End-Pair.Beg ); }
75static inline void Amap_PrintWord( FILE * pFile, Amap_Tree_t * p, Amap_Pair_t Pair ) { char * pBeg = p->pContents+Pair.Beg, * pEnd = p->pContents+Pair.End; while ( pBeg < pEnd ) fputc( *pBeg++, pFile ); }
76static inline void Amap_PrintSpace( FILE * pFile, int nOffset ) { int i; for ( i = 0; i < nOffset; i++ ) fputc(' ', pFile); }
77static inline int Amap_LibertyItemId( Amap_Tree_t * p, Amap_Item_t * pItem ) { return pItem - p->pItems; }
78
79#define Amap_ItemForEachChild( p, pItem, pChild ) \
80 for ( pChild = Amap_LibertyItem(p, pItem->Child); pChild; pChild = Amap_LibertyItem(p, pChild->Next) )
81
85
97void Amap_LibertyPrintLibertyItem( FILE * pFile, Amap_Tree_t * p, Amap_Item_t * pItem, int nOffset )
98{
99 if ( pItem->Type == AMAP_LIBERTY_PROC )
100 {
101 Amap_PrintSpace( pFile, nOffset );
102 Amap_PrintWord( pFile, p, pItem->Key );
103 fprintf( pFile, "(" );
104 Amap_PrintWord( pFile, p, pItem->Head );
105 fprintf( pFile, ") {\n" );
106 if ( Amap_LibertyItem(p, pItem->Child) )
107 Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyItem(p, pItem->Child), nOffset + 1 );
108 Amap_PrintSpace( pFile, nOffset );
109 fprintf( pFile, "}\n" );
110 }
111 else if ( pItem->Type == AMAP_LIBERTY_EQUA )
112 {
113 Amap_PrintSpace( pFile, nOffset );
114 Amap_PrintWord( pFile, p, pItem->Key );
115 fprintf( pFile, " : " );
116 Amap_PrintWord( pFile, p, pItem->Head );
117 fprintf( pFile, ";\n" );
118 }
119 else if ( pItem->Type == AMAP_LIBERTY_LIST )
120 {
121 Amap_PrintSpace( pFile, nOffset );
122 Amap_PrintWord( pFile, p, pItem->Key );
123 fprintf( pFile, "(" );
124 Amap_PrintWord( pFile, p, pItem->Head );
125 fprintf( pFile, ");\n" );
126 }
127 else assert( 0 );
128 if ( Amap_LibertyItem(p, pItem->Next) )
129 Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyItem(p, pItem->Next), nOffset );
130}
131
143int Amap_LibertyPrintLiberty( Amap_Tree_t * p, char * pFileName )
144{
145 FILE * pFile;
146 if ( pFileName == NULL )
147 pFile = stdout;
148 else
149 {
150 pFile = fopen( pFileName, "w" );
151 if ( pFile == NULL )
152 {
153 printf( "Amap_LibertyPrintLiberty(): The output file is unavailable (absent or open).\n" );
154 return 0;
155 }
156 }
157 Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyRoot(p), 0 );
158 if ( pFile != stdout )
159 fclose( pFile );
160 return 1;
161}
162
163
176{
177 static char Buffer[100];
178 char * TimeStamp;
179 time_t ltime;
180 // get the current time
181 time( &ltime );
182 TimeStamp = asctime( localtime( &ltime ) );
183 TimeStamp[ strlen(TimeStamp) - 1 ] = 0;
184 assert( strlen(TimeStamp) < 100 );
185 strcpy( Buffer, TimeStamp );
186 return Buffer;
187}
188
201{
202 Amap_Item_t * pAttr;
203 Amap_ItemForEachChild( p, pCell, pAttr )
204 if ( !Amap_LibertyCompare(p, pAttr->Key, "ff") ||
205 !Amap_LibertyCompare(p, pAttr->Key, "latch") )
206 return 1;
207 return 0;
208}
209
222{
223 Amap_Item_t * pAttr;
224 Amap_ItemForEachChild( p, pCell, pAttr )
225 if ( !Amap_LibertyCompare(p, pAttr->Key, "dont_use") )
226 return 1;
227 return 0;
228}
229
242{
243 Amap_Item_t * pFunc;
244 Amap_ItemForEachChild( p, pPin, pFunc )
245 if ( !Amap_LibertyCompare(p, pFunc->Key, "function") )
246 return pFunc;
247 return NULL;
248}
249
262{
263 Amap_Item_t * pPin;
264 Amap_ItemForEachChild( p, pCell, pPin )
265 {
266 if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
267 continue;
268 if ( Amap_LibertyPinFunction(p, pPin) )
269 return pPin;
270 }
271 return NULL;
272}
274{
275 Amap_Item_t * pPin;
276 Vec_Ptr_t * vOutPins;
277 vOutPins = Vec_PtrAlloc( 2 );
278 Amap_ItemForEachChild( p, pCell, pPin )
279 {
280 if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
281 continue;
282 if ( Amap_LibertyPinFunction(p, pPin) )
283 Vec_PtrPush( vOutPins, pPin );
284 }
285 return vOutPins;
286}
287
300{
301 Amap_Item_t * pArea;
302 Amap_ItemForEachChild( p, pCell, pArea )
303 {
304 if ( Amap_LibertyCompare(p, pArea->Key, "area") )
305 continue;
306 return pArea;
307 }
308 return NULL;
309}
310
323{
324 Amap_Item_t * pPin;
325 int Counter = 0;
326 Amap_ItemForEachChild( p, pCell, pPin )
327 {
328 if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
329 continue;
330 if ( Amap_LibertyPinFunction(p, pPin) )
331 Counter++;
332 }
333 return Counter;
334}
335
348{
349 static char Buffer[ABC_MAX_LIB_STR_LEN];
350 assert( Pair.End-Pair.Beg < ABC_MAX_LIB_STR_LEN );
351 strncpy( Buffer, p->pContents+Pair.Beg, Pair.End-Pair.Beg );
352 Buffer[Pair.End-Pair.Beg] = 0;
353 return Buffer;
354}
355
368{
369 static char Buffer[ABC_MAX_LIB_STR_LEN];
370 assert( Pair.End-Pair.Beg-2 < ABC_MAX_LIB_STR_LEN );
371 strncpy( Buffer, p->pContents+Pair.Beg+1, Pair.End-Pair.Beg-2 );
372 Buffer[Pair.End-Pair.Beg-2] = 0;
373 return Buffer;
374}
375
387int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose )
388{
389 FILE * pFile;
390 Vec_Ptr_t * vOutputs;
391 Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
392 char * pForm;
393 int i, Counter;
394 if ( pFileName == NULL )
395 pFile = stdout;
396 else
397 {
398 pFile = fopen( pFileName, "w" );
399 if ( pFile == NULL )
400 {
401 printf( "Amap_LibertyPrintGenlib(): The output file is unavailable (absent or open).\n" );
402 return 0;
403 }
404 }
405 fprintf( pFile, "# This Genlib file was generated by ABC on %s\n", Amap_LibertyTimeStamp() );
406 fprintf( pFile, "# The standard cell library \"%s\" is from Liberty file \"%s\"\n", Amap_LibertyGetString(p, Amap_LibertyRoot(p)->Head), p->pFileName );
407 fprintf( pFile, "# (To find out more about Genlib format, google for \"sis_paper.ps\")\n" );
408
409 fprintf( pFile, "GATE " );
410 fprintf( pFile, "%16s ", "_const0_" );
411 fprintf( pFile, "%f ", 0.0 );
412 fprintf( pFile, "%s=", "z" );
413 fprintf( pFile, "%s;\n", "CONST0" );
414
415 fprintf( pFile, "GATE " );
416 fprintf( pFile, "%16s ", "_const1_" );
417 fprintf( pFile, "%f ", 0.0 );
418 fprintf( pFile, "%s=", "z" );
419 fprintf( pFile, "%s;\n", "CONST1" );
420
421 Amap_ItemForEachChild( p, Amap_LibertyRoot(p), pCell )
422 {
423/*
424 if ( strcmp(Amap_LibertyGetString(p, pCell->Head), "HA1SVTX1") == 0 )
425 {
426 int s = 0;
427 }
428*/
429 if ( Amap_LibertyCompare(p, pCell->Key, "cell") )
430 continue;
431 if ( Amap_LibertyCellIsFlop(p, pCell) )
432 {
433 if ( fVerbose )
434 printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
435 continue;
436 }
437 if ( Amap_LibertyCellIsDontUse(p, pCell) )
438 {
439 if ( fVerbose )
440 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Amap_LibertyGetString(p, pCell->Head) );
441 continue;
442 }
443 Counter = Amap_LibertyCellCountOutputs( p, pCell );
444 if ( Counter == 0 )
445 {
446 if ( fVerbose )
447 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) );
448 continue;
449 }
450/*
451 if ( Counter > 1 )
452 {
453 if ( fVerbose )
454 printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
455 continue;
456 }
457*/
458 pArea = Amap_LibertyCellArea( p, pCell );
459 if ( pArea == NULL )
460 {
461 if ( fVerbose )
462 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) );
463 continue;
464 }
465// pOutput = Amap_LibertyCellOutput( p, pCell );
466 vOutputs = Amap_LibertyCellOutputs( p, pCell );
467 Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i )
468 {
469 pFunc = Amap_LibertyPinFunction( p, pOutput );
470 pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
471 if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
472 {
473 if ( fVerbose )
474 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
475 continue;
476 }
477 fprintf( pFile, "GATE " );
478 fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
479 fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
480 fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
481 fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
482 Amap_ItemForEachChild( p, pCell, pPin )
483 if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
484 fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
485 }
486 Vec_PtrFree( vOutputs );
487 }
488 if ( pFile != stdout )
489 fclose( pFile );
490 return 1;
491}
492
505{
506 Vec_Str_t * vStr;
507 char Buffer[100];
508 Vec_Ptr_t * vOutputs;
509 Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
510 int i, Counter;
511 char * pForm;
512
513 vStr = Vec_StrAlloc( 1000 );
514
515 Vec_StrPrintStr( vStr, "GATE _const0_ 0.000000 z=CONST0;\n" );
516 Vec_StrPrintStr( vStr, "GATE _const1_ 0.000000 z=CONST1;\n" );
517 Amap_ItemForEachChild( p, Amap_LibertyRoot(p), pCell )
518 {
519 if ( Amap_LibertyCompare(p, pCell->Key, "cell") )
520 continue;
521 if ( Amap_LibertyCellIsFlop(p, pCell) )
522 {
523 if ( fVerbose )
524 printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
525 continue;
526 }
527 if ( Amap_LibertyCellIsDontUse(p, pCell) )
528 {
529 if ( fVerbose )
530 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Amap_LibertyGetString(p, pCell->Head) );
531 continue;
532 }
533 Counter = Amap_LibertyCellCountOutputs( p, pCell );
534 if ( Counter == 0 )
535 {
536 if ( fVerbose )
537 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) );
538 continue;
539 }
540 pArea = Amap_LibertyCellArea( p, pCell );
541 if ( pArea == NULL )
542 {
543 if ( fVerbose )
544 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) );
545 continue;
546 }
547 vOutputs = Amap_LibertyCellOutputs( p, pCell );
548 Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i )
549 {
550 pFunc = Amap_LibertyPinFunction( p, pOutput );
551 pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
552 if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
553 {
554 if ( fVerbose )
555 printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
556 continue;
557 }
558/*
559 fprintf( pFile, "GATE " );
560 fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
561 fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
562 fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
563 fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
564 Amap_ItemForEachChild( p, pCell, pPin )
565 if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
566 fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
567*/
568 Vec_StrPrintStr( vStr, "GATE " );
569 Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pCell->Head) );
570 Vec_StrPrintStr( vStr, " " );
571 sprintf( Buffer, "%f", atof(Amap_LibertyGetString(p, pArea->Head)) );
572 Vec_StrPrintStr( vStr, Buffer );
573 Vec_StrPrintStr( vStr, " " );
574 Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pOutput->Head) );
575 Vec_StrPrintStr( vStr, "=" );
576 Vec_StrPrintStr( vStr, Amap_LibertyGetStringFormula(p, pFunc->Head) );
577 Vec_StrPrintStr( vStr, ";\n" );
578 Amap_ItemForEachChild( p, pCell, pPin )
579 if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
580 {
581 Vec_StrPrintStr( vStr, " PIN " );
582 Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pPin->Head) );
583 Vec_StrPrintStr( vStr, " UNKNOWN 1 999 1.00 0.00 1.00 0.00\n" );
584 }
585 }
586 Vec_PtrFree( vOutputs );
587 }
588 Vec_StrPrintStr( vStr, "\n.end\n" );
589 Vec_StrPush( vStr, '\0' );
590// printf( "%s", Vec_StrArray(vStr) );
591 return vStr;
592}
593
594
606int Amap_LibertyFileSize( char * pFileName )
607{
608 FILE * pFile;
609 int nFileSize;
610 pFile = fopen( pFileName, "rb" );
611 if ( pFile == NULL )
612 {
613 printf( "Amap_LibertyFileSize(): The input file is unavailable (absent or open).\n" );
614 return 0;
615 }
616 fseek( pFile, 0, SEEK_END );
617 nFileSize = ftell( pFile );
618 fclose( pFile );
619 return nFileSize;
620}
621
633void Amap_LibertyFixFileHead( char * pFileName )
634{
635 char * pHead;
636 for ( pHead = pFileName; *pHead; pHead++ )
637 if ( *pHead == '>' )
638 *pHead = '\\';
639}
640
652int Amap_LibertyCountItems( char * pBeg, char * pEnd )
653{
654 int Counter = 0;
655 for ( ; pBeg < pEnd; pBeg++ )
656 Counter += (*pBeg == '(' || *pBeg == ':');
657 return Counter;
658}
659
671void Amap_LibertyWipeOutComments( char * pBeg, char * pEnd )
672{
673 char * pCur, * pStart;
674 for ( pCur = pBeg; pCur < pEnd; pCur++ )
675 if ( pCur[0] == '/' && pCur[1] == '*' )
676 for ( pStart = pCur; pCur < pEnd; pCur++ )
677 if ( pCur[0] == '*' && pCur[1] == '/' )
678 {
679 for ( ; pStart < pCur + 2; pStart++ )
680 if ( *pStart != '\n' ) *pStart = ' ';
681 break;
682 }
683}
684
696static inline int Amap_LibertyCharIsSpace( char c )
697{
698 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\\';
699}
700
712static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd, int fStopAtNewLine )
713{
714 char * pPos = *ppPos;
715 for ( ; pPos < pEnd; pPos++ )
716 {
717 if ( *pPos == '\n' )
718 {
719 p->nLines++;
720 if ( fStopAtNewLine )
721 break;
722 }
723 if ( !Amap_LibertyCharIsSpace(*pPos) )
724 break;
725 }
726 *ppPos = pPos;
727 return pPos == pEnd;
728}
729
741static inline int Amap_LibertySkipEntry( char ** ppPos, char * pEnd )
742{
743 char * pPos = *ppPos;
744 if ( *pPos == '\"' )
745 {
746 for ( pPos++; pPos < pEnd; pPos++ )
747 if ( *pPos == '\"' )
748 {
749 pPos++;
750 break;
751 }
752 }
753 else
754 {
755 for ( ; pPos < pEnd; pPos++ )
756 if ( *pPos == ' ' || *pPos == '\r' || *pPos == '\n' || *pPos == '\t' ||
757 *pPos == ':' || *pPos == ';' ||
758 *pPos == '(' || *pPos == ')' ||
759 *pPos == '{' || *pPos == '}' )
760 break;
761 }
762 *ppPos = pPos;
763 return pPos == pEnd;
764}
765
777static inline char * Amap_LibertyFindMatch( char * pPos, char * pEnd )
778{
779 int Counter = 0;
780 assert( *pPos == '(' || *pPos == '{' );
781 if ( *pPos == '(' )
782 {
783 for ( ; pPos < pEnd; pPos++ )
784 {
785 if ( *pPos == '(' )
786 Counter++;
787 if ( *pPos == ')' )
788 Counter--;
789 if ( Counter == 0 )
790 break;
791 }
792 }
793 else
794 {
795 for ( ; pPos < pEnd; pPos++ )
796 {
797 if ( *pPos == '{' )
798 Counter++;
799 if ( *pPos == '}' )
800 Counter--;
801 if ( Counter == 0 )
802 break;
803 }
804 }
805 assert( *pPos == ')' || *pPos == '}' );
806 return pPos;
807}
808
820static inline Amap_Pair_t Amap_LibertyUpdateHead( Amap_Tree_t * p, Amap_Pair_t Head )
821{
822 Amap_Pair_t Res;
823 char * pBeg = p->pContents + Head.Beg;
824 char * pEnd = p->pContents + Head.End;
825 char * pFirstNonSpace = NULL;
826 char * pLastNonSpace = NULL;
827 char * pChar;
828 for ( pChar = pBeg; pChar < pEnd; pChar++ )
829 {
830 if ( *pChar == '\n' )
831 p->nLines++;
832 if ( Amap_LibertyCharIsSpace(*pChar) )
833 continue;
834 pLastNonSpace = pChar;
835 if ( pFirstNonSpace == NULL )
836 pFirstNonSpace = pChar;
837 }
838 if ( pFirstNonSpace == NULL || pLastNonSpace == NULL )
839 return Head;
840 assert( pFirstNonSpace && pLastNonSpace );
841 Res.Beg = pFirstNonSpace - p->pContents;
842 Res.End = pLastNonSpace - p->pContents + 1;
843 return Res;
844}
845
857static inline Amap_Item_t * Amap_LibertyNewItem( Amap_Tree_t * p, int Type )
858{
859 p->pItems[p->nItems].iLine = p->nLines;
860 p->pItems[p->nItems].Type = Type;
861 p->pItems[p->nItems].Child = -1;
862 p->pItems[p->nItems].Next = -1;
863 return p->pItems + p->nItems++;
864}
865
877int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd )
878{
879 Amap_Item_t * pItem;
880 Amap_Pair_t Key, Head, Body;
881 char * pNext, * pStop;
882 Key.End = 0;
883 if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
884 return -2;
885 Key.Beg = *ppPos - p->pContents;
886 if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
887 goto exit;
888 Key.End = *ppPos - p->pContents;
889 if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
890 goto exit;
891 pNext = *ppPos;
892 if ( *pNext == ':' )
893 {
894 *ppPos = pNext + 1;
895 if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
896 goto exit;
897 Head.Beg = *ppPos - p->pContents;
898 if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
899 goto exit;
900 Head.End = *ppPos - p->pContents;
901 if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
902 goto exit;
903 pNext = *ppPos;
904 if ( *pNext != ';' && *pNext != '\n' )
905 goto exit;
906 *ppPos = pNext + 1;
907 // end of equation
908 pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_EQUA );
909 pItem->Key = Key;
910 pItem->Head = Amap_LibertyUpdateHead( p, Head );
911 pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
912 if ( pItem->Next == -1 )
913 goto exit;
914 return Amap_LibertyItemId( p, pItem );
915 }
916 if ( *pNext == '(' )
917 {
918 pStop = Amap_LibertyFindMatch( pNext, pEnd );
919 Head.Beg = pNext - p->pContents + 1;
920 Head.End = pStop - p->pContents;
921 *ppPos = pStop + 1;
922 if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
923 {
924 // end of list
925 pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST );
926 pItem->Key = Key;
927 pItem->Head = Amap_LibertyUpdateHead( p, Head );
928 return Amap_LibertyItemId( p, pItem );
929 }
930 pNext = *ppPos;
931 if ( *pNext == '{' ) // beginning of body
932 {
933 pStop = Amap_LibertyFindMatch( pNext, pEnd );
934 Body.Beg = pNext - p->pContents + 1;
935 Body.End = pStop - p->pContents;
936 // end of body
937 pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_PROC );
938 pItem->Key = Key;
939 pItem->Head = Amap_LibertyUpdateHead( p, Head );
940 pItem->Body = Body;
941 *ppPos = pNext + 1;
942 pItem->Child = Amap_LibertyBuildItem( p, ppPos, pStop );
943 if ( pItem->Child == -1 )
944 goto exit;
945 *ppPos = pStop + 1;
946 pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
947 if ( pItem->Next == -1 )
948 goto exit;
949 return Amap_LibertyItemId( p, pItem );
950 }
951 // end of list
952 if ( *pNext == ';' )
953 *ppPos = pNext + 1;
954 pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST );
955 pItem->Key = Key;
956 pItem->Head = Amap_LibertyUpdateHead( p, Head );
957 pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
958 if ( pItem->Next == -1 )
959 goto exit;
960 return Amap_LibertyItemId( p, pItem );
961 }
962exit:
963 if ( p->pError == NULL )
964 {
965 p->pError = ABC_ALLOC( char, 1000 );
966 sprintf( p->pError, "File \"%s\". Line %6d. Failed to parse entry \"%s\".\n",
967 p->pFileName, p->nLines, Amap_LibertyGetString(p, Key) );
968 }
969 return -1;
970}
971
983Amap_Tree_t * Amap_LibertyStart( char * pFileName )
984{
985 FILE * pFile;
986 Amap_Tree_t * p;
987 int RetValue;
988 // start the manager
989 p = ABC_ALLOC( Amap_Tree_t, 1 );
990 memset( p, 0, sizeof(Amap_Tree_t) );
991 // read the file into the buffer
992 Amap_LibertyFixFileHead( pFileName );
993 p->nContents = Amap_LibertyFileSize( pFileName );
994 if ( p->nContents == 0 )
995 {
996 ABC_FREE( p );
997 return NULL;
998 }
999 pFile = fopen( pFileName, "rb" );
1000 p->pContents = ABC_ALLOC( char, p->nContents+1 );
1001 RetValue = fread( p->pContents, p->nContents, 1, pFile );
1002 fclose( pFile );
1003 p->pContents[p->nContents] = 0;
1004 // other
1005 p->pFileName = Abc_UtilStrsav( pFileName );
1006 p->nItermAlloc = 10 + Amap_LibertyCountItems( p->pContents, p->pContents+p->nContents );
1007 p->pItems = ABC_CALLOC( Amap_Item_t, p->nItermAlloc );
1008 p->nItems = 0;
1009 p->nLines = 1;
1010 return p;
1011}
1012
1025{
1026 ABC_FREE( p->pFileName );
1027 ABC_FREE( p->pContents );
1028 ABC_FREE( p->pItems );
1029 ABC_FREE( p->pError );
1030 ABC_FREE( p );
1031}
1032
1044int Amap_LibertyParse( char * pFileName, int fVerbose )
1045{
1046 Amap_Tree_t * p;
1047 char * pPos;
1048 abctime clk = Abc_Clock();
1049 int RetValue;
1050 p = Amap_LibertyStart( pFileName );
1051 if ( p == NULL )
1052 return 0;
1053 pPos = p->pContents;
1054 Amap_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents );
1055 if ( Amap_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
1056 {
1057 if ( fVerbose )
1058 printf( "Parsing finished successfully.\n" );
1059// Amap_LibertyPrintLiberty( p, "temp_.lib" );
1060 Amap_LibertyPrintGenlib( p, Extra_FileNameGenericAppend(pFileName, ".genlib"), fVerbose );
1061 RetValue = 1;
1062 }
1063 else
1064 {
1065 if ( p->pError )
1066 printf( "%s", p->pError );
1067 if ( fVerbose )
1068 printf( "Parsing failed.\n" );
1069 RetValue = 0;
1070 }
1071 if ( fVerbose )
1072 {
1073 printf( "Memory = %7.2f MB. ", 1.0*(p->nContents+p->nItermAlloc*sizeof(Amap_Item_t))/(1<<20) );
1074 ABC_PRT( "Time", Abc_Clock() - clk );
1075 }
1077 return RetValue;
1078}
1079
1091Vec_Str_t * Amap_LibertyParseStr( char * pFileName, int fVerbose )
1092{
1093 Amap_Tree_t * p;
1094 Vec_Str_t * vStr = NULL;
1095 char * pPos;
1096 abctime clk = Abc_Clock();
1097 int RetValue;
1098 p = Amap_LibertyStart( pFileName );
1099 if ( p == NULL )
1100 return 0;
1101 pPos = p->pContents;
1102 Amap_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents );
1103 if ( Amap_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
1104 {
1105 if ( fVerbose )
1106 printf( "Parsing finished successfully.\n" );
1107// Amap_LibertyPrintLiberty( p, "temp_.lib" );
1108 vStr = Amap_LibertyPrintGenlibStr( p, fVerbose );
1109 RetValue = 1;
1110 }
1111 else
1112 {
1113 if ( p->pError )
1114 printf( "%s", p->pError );
1115 if ( fVerbose )
1116 printf( "Parsing failed.\n" );
1117 RetValue = 0;
1118 }
1119 if ( fVerbose )
1120 {
1121 printf( "Memory = %7.2f MB. ", 1.0*(p->nContents+p->nItermAlloc*sizeof(Amap_Item_t))/(1<<20) );
1122 ABC_PRT( "Time", Abc_Clock() - clk );
1123 }
1125 return vStr;
1126}
1127
1128
1132
1133
1135
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
char * Amap_LibertyGetStringFormula(Amap_Tree_t *p, Amap_Pair_t Pair)
void Amap_LibertyWipeOutComments(char *pBeg, char *pEnd)
int Amap_LibertyCellCountOutputs(Amap_Tree_t *p, Amap_Item_t *pCell)
int Amap_LibertyPrintLiberty(Amap_Tree_t *p, char *pFileName)
Amap_LibertyType_t
Definition amapLiberty.c:33
@ AMAP_LIBERTY_LIST
Definition amapLiberty.c:37
@ AMAP_LIBERTY_EQUA
Definition amapLiberty.c:36
@ AMAP_LIBERTY_PROC
Definition amapLiberty.c:35
@ AMAP_LIBERTY_NONE
Definition amapLiberty.c:34
void Amap_LibertyStop(Amap_Tree_t *p)
Amap_Item_t * Amap_LibertyCellArea(Amap_Tree_t *p, Amap_Item_t *pCell)
struct Amap_Pair_t_ Amap_Pair_t
Definition amapLiberty.c:40
struct Amap_Tree_t_ Amap_Tree_t
Definition amapLiberty.c:59
struct Amap_Item_t_ Amap_Item_t
Definition amapLiberty.c:47
char * Amap_LibertyTimeStamp()
Amap_Item_t * Amap_LibertyPinFunction(Amap_Tree_t *p, Amap_Item_t *pPin)
int Amap_LibertyCellIsFlop(Amap_Tree_t *p, Amap_Item_t *pCell)
int Amap_LibertyFileSize(char *pFileName)
void Amap_LibertyPrintLibertyItem(FILE *pFile, Amap_Tree_t *p, Amap_Item_t *pItem, int nOffset)
FUNCTION DEFINITIONS ///.
Definition amapLiberty.c:97
void Amap_LibertyFixFileHead(char *pFileName)
int Amap_LibertyBuildItem(Amap_Tree_t *p, char **ppPos, char *pEnd)
#define ABC_MAX_LIB_STR_LEN
DECLARATIONS ///.
Definition amapLiberty.c:30
Amap_Item_t * Amap_LibertyCellOutput(Amap_Tree_t *p, Amap_Item_t *pCell)
char * Amap_LibertyGetString(Amap_Tree_t *p, Amap_Pair_t Pair)
Vec_Str_t * Amap_LibertyParseStr(char *pFileName, int fVerbose)
Vec_Str_t * Amap_LibertyPrintGenlibStr(Amap_Tree_t *p, int fVerbose)
int Amap_LibertyCellIsDontUse(Amap_Tree_t *p, Amap_Item_t *pCell)
int Amap_LibertyCountItems(char *pBeg, char *pEnd)
Amap_Tree_t * Amap_LibertyStart(char *pFileName)
int Amap_LibertyParse(char *pFileName, int fVerbose)
#define Amap_ItemForEachChild(p, pItem, pChild)
Definition amapLiberty.c:79
int Amap_LibertyPrintGenlib(Amap_Tree_t *p, char *pFileName, int fVerbose)
Vec_Ptr_t * Amap_LibertyCellOutputs(Amap_Tree_t *p, Amap_Item_t *pCell)
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
Cube * p
Definition exorList.c:222
char * Extra_FileNameGenericAppend(char *pBase, char *pSuffix)
Amap_Pair_t Head
Definition amapLiberty.c:53
Amap_Pair_t Body
Definition amapLiberty.c:54
Amap_Pair_t Key
Definition amapLiberty.c:52
char * pError
Definition amapLiberty.c:69
char * pFileName
Definition amapLiberty.c:62
Amap_Item_t * pItems
Definition amapLiberty.c:68
char * pContents
Definition amapLiberty.c:63
#define assert(ex)
Definition util_old.h:213
int strncmp()
char * memset()
int strlen()
char * strncpy()
int strcmp()
char * sprintf()
char * strcpy()
VOID_HACK exit()
double atof()
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
#define SEEK_END
Definition zconf.h:392