abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
amapLiberty.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileHead [amapLiberty.c]
4 
5  SystemHead [ABC: Logic synthesis and verification system.]
6 
7  PackageHead [Technology mapper for standard cells.]
8 
9  Synopsis [Liberty parser.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: amapLiberty.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "amapInt.h"
22 
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 #define ABC_MAX_LIB_STR_LEN 5000
31 
32 // entry types
33 typedef 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 
40 typedef struct Amap_Pair_t_ Amap_Pair_t;
42 {
43  int Beg; // item beginning
44  int End; // item end
45 };
46 
47 typedef struct Amap_Item_t_ Amap_Item_t;
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 
59 typedef struct Amap_Tree_t_ Amap_Tree_t;
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 
72 static inline Amap_Item_t * Amap_LibertyRoot( Amap_Tree_t * p ) { return p->pItems; }
73 static inline Amap_Item_t * Amap_LibertyItem( Amap_Tree_t * p, int v ) { assert( v < p->nItems ); return v < 0 ? NULL : p->pItems + v; }
74 static 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 ); }
75 static 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 ); }
76 static inline void Amap_PrintSpace( FILE * pFile, int nOffset ) { int i; for ( i = 0; i < nOffset; i++ ) fputc(' ', pFile); }
77 static 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 
82 ////////////////////////////////////////////////////////////////////////
83 /// FUNCTION DEFINITIONS ///
84 ////////////////////////////////////////////////////////////////////////
85 
86 /**Function*************************************************************
87 
88  Synopsis [Prints parse tree in Liberty format.]
89 
90  Description []
91 
92  SideEffects []
93 
94  SeeAlso []
95 
96 ***********************************************************************/
97 void 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 
132 /**Function*************************************************************
133 
134  Synopsis [Prints parse tree in Liberty format.]
135 
136  Description []
137 
138  SideEffects []
139 
140  SeeAlso []
141 
142 ***********************************************************************/
143 int 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  }
158  if ( pFile != stdout )
159  fclose( pFile );
160  return 1;
161 }
162 
163 
164 /**Function*************************************************************
165 
166  Synopsis [Returns the time stamp.]
167 
168  Description [The file should be closed.]
169 
170  SideEffects []
171 
172  SeeAlso []
173 
174 ***********************************************************************/
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 
189 /**Function*************************************************************
190 
191  Synopsis [Returns cell's function.]
192 
193  Description []
194 
195  SideEffects []
196 
197  SeeAlso []
198 
199 ***********************************************************************/
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 
210 /**Function*************************************************************
211 
212  Synopsis [Returns pin's function.]
213 
214  Description []
215 
216  SideEffects []
217 
218  SeeAlso []
219 
220 ***********************************************************************/
222 {
223  Amap_Item_t * pFunc;
224  Amap_ItemForEachChild( p, pPin, pFunc )
225  if ( !Amap_LibertyCompare(p, pFunc->Key, "function") )
226  return pFunc;
227  return NULL;
228 }
229 
230 /**Function*************************************************************
231 
232  Synopsis [Returns output pin(s).]
233 
234  Description []
235 
236  SideEffects []
237 
238  SeeAlso []
239 
240 ***********************************************************************/
242 {
243  Amap_Item_t * pPin;
244  Amap_ItemForEachChild( p, pCell, pPin )
245  {
246  if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
247  continue;
248  if ( Amap_LibertyPinFunction(p, pPin) )
249  return pPin;
250  }
251  return NULL;
252 }
254 {
255  Amap_Item_t * pPin;
256  Vec_Ptr_t * vOutPins;
257  vOutPins = Vec_PtrAlloc( 2 );
258  Amap_ItemForEachChild( p, pCell, pPin )
259  {
260  if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
261  continue;
262  if ( Amap_LibertyPinFunction(p, pPin) )
263  Vec_PtrPush( vOutPins, pPin );
264  }
265  return vOutPins;
266 }
267 
268 /**Function*************************************************************
269 
270  Synopsis [Returns cell's area.]
271 
272  Description []
273 
274  SideEffects []
275 
276  SeeAlso []
277 
278 ***********************************************************************/
280 {
281  Amap_Item_t * pArea;
282  Amap_ItemForEachChild( p, pCell, pArea )
283  {
284  if ( Amap_LibertyCompare(p, pArea->Key, "area") )
285  continue;
286  return pArea;
287  }
288  return NULL;
289 }
290 
291 /**Function*************************************************************
292 
293  Synopsis [Count cell's output pins (pins with a logic function).]
294 
295  Description []
296 
297  SideEffects []
298 
299  SeeAlso []
300 
301 ***********************************************************************/
303 {
304  Amap_Item_t * pPin;
305  int Counter = 0;
306  Amap_ItemForEachChild( p, pCell, pPin )
307  {
308  if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
309  continue;
310  if ( Amap_LibertyPinFunction(p, pPin) )
311  Counter++;
312  }
313  return Counter;
314 }
315 
316 /**Function*************************************************************
317 
318  Synopsis [Gets the name to write.]
319 
320  Description []
321 
322  SideEffects []
323 
324  SeeAlso []
325 
326 ***********************************************************************/
328 {
329  static char Buffer[ABC_MAX_LIB_STR_LEN];
330  assert( Pair.End-Pair.Beg < ABC_MAX_LIB_STR_LEN );
331  strncpy( Buffer, p->pContents+Pair.Beg, Pair.End-Pair.Beg );
332  Buffer[Pair.End-Pair.Beg] = 0;
333  return Buffer;
334 }
335 
336 /**Function*************************************************************
337 
338  Synopsis [Gets the name to write.]
339 
340  Description []
341 
342  SideEffects []
343 
344  SeeAlso []
345 
346 ***********************************************************************/
348 {
349  static char Buffer[ABC_MAX_LIB_STR_LEN];
350  assert( Pair.End-Pair.Beg-2 < ABC_MAX_LIB_STR_LEN );
351  strncpy( Buffer, p->pContents+Pair.Beg+1, Pair.End-Pair.Beg-2 );
352  Buffer[Pair.End-Pair.Beg-2] = 0;
353  return Buffer;
354 }
355 
356 /**Function*************************************************************
357 
358  Synopsis [Prints parse tree in Genlib format.]
359 
360  Description []
361 
362  SideEffects []
363 
364  SeeAlso []
365 
366 ***********************************************************************/
367 int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose )
368 {
369  FILE * pFile;
370  Vec_Ptr_t * vOutputs;
371  Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
372  char * pForm;
373  int i, Counter;
374  if ( pFileName == NULL )
375  pFile = stdout;
376  else
377  {
378  pFile = fopen( pFileName, "w" );
379  if ( pFile == NULL )
380  {
381  printf( "Amap_LibertyPrintGenlib(): The output file is unavailable (absent or open).\n" );
382  return 0;
383  }
384  }
385  fprintf( pFile, "# This Genlib file was generated by ABC on %s\n", Amap_LibertyTimeStamp() );
386  fprintf( pFile, "# The standard cell library \"%s\" is from Liberty file \"%s\"\n", Amap_LibertyGetString(p, Amap_LibertyRoot(p)->Head), p->pFileName );
387  fprintf( pFile, "# (To find out more about Genlib format, google for \"sis_paper.ps\")\n" );
388 
389  fprintf( pFile, "GATE " );
390  fprintf( pFile, "%16s ", "_const0_" );
391  fprintf( pFile, "%f ", 0.0 );
392  fprintf( pFile, "%s=", "z" );
393  fprintf( pFile, "%s;\n", "CONST0" );
394 
395  fprintf( pFile, "GATE " );
396  fprintf( pFile, "%16s ", "_const1_" );
397  fprintf( pFile, "%f ", 0.0 );
398  fprintf( pFile, "%s=", "z" );
399  fprintf( pFile, "%s;\n", "CONST1" );
400 
402  {
403 /*
404  if ( strcmp(Amap_LibertyGetString(p, pCell->Head), "HA1SVTX1") == 0 )
405  {
406  int s = 0;
407  }
408 */
409  if ( Amap_LibertyCompare(p, pCell->Key, "cell") )
410  continue;
411  if ( Amap_LibertyCellIsFlop(p, pCell) )
412  {
413  if ( fVerbose )
414  printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
415  continue;
416  }
417  Counter = Amap_LibertyCellCountOutputs( p, pCell );
418  if ( Counter == 0 )
419  {
420  if ( fVerbose )
421  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) );
422  continue;
423  }
424 /*
425  if ( Counter > 1 )
426  {
427  if ( fVerbose )
428  printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
429  continue;
430  }
431 */
432  pArea = Amap_LibertyCellArea( p, pCell );
433  if ( pArea == NULL )
434  {
435  if ( fVerbose )
436  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) );
437  continue;
438  }
439 // pOutput = Amap_LibertyCellOutput( p, pCell );
440  vOutputs = Amap_LibertyCellOutputs( p, pCell );
441  Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i )
442  {
443  pFunc = Amap_LibertyPinFunction( p, pOutput );
444  pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
445  if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
446  {
447  if ( fVerbose )
448  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
449  continue;
450  }
451  fprintf( pFile, "GATE " );
452  fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
453  fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
454  fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
455  fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
456  Amap_ItemForEachChild( p, pCell, pPin )
457  if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
458  fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
459  }
460  Vec_PtrFree( vOutputs );
461  }
462  if ( pFile != stdout )
463  fclose( pFile );
464  return 1;
465 }
466 
467 /**Function*************************************************************
468 
469  Synopsis [Prints parse tree in Genlib format.]
470 
471  Description []
472 
473  SideEffects []
474 
475  SeeAlso []
476 
477 ***********************************************************************/
479 {
480  Vec_Str_t * vStr;
481  char Buffer[100];
482  Vec_Ptr_t * vOutputs;
483  Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
484  int i, Counter;
485  char * pForm;
486 
487  vStr = Vec_StrAlloc( 1000 );
488 
489  Vec_StrPrintStr( vStr, "GATE _const0_ 0.000000 z=CONST0;\n" );
490  Vec_StrPrintStr( vStr, "GATE _const1_ 0.000000 z=CONST1;\n" );
492  {
493  if ( Amap_LibertyCompare(p, pCell->Key, "cell") )
494  continue;
495  if ( Amap_LibertyCellIsFlop(p, pCell) )
496  {
497  if ( fVerbose )
498  printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
499  continue;
500  }
501  Counter = Amap_LibertyCellCountOutputs( p, pCell );
502  if ( Counter == 0 )
503  {
504  if ( fVerbose )
505  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) );
506  continue;
507  }
508  pArea = Amap_LibertyCellArea( p, pCell );
509  if ( pArea == NULL )
510  {
511  if ( fVerbose )
512  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) );
513  continue;
514  }
515  vOutputs = Amap_LibertyCellOutputs( p, pCell );
516  Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i )
517  {
518  pFunc = Amap_LibertyPinFunction( p, pOutput );
519  pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
520  if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
521  {
522  if ( fVerbose )
523  printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
524  continue;
525  }
526 /*
527  fprintf( pFile, "GATE " );
528  fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
529  fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
530  fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
531  fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
532  Amap_ItemForEachChild( p, pCell, pPin )
533  if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
534  fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
535 */
536  Vec_StrPrintStr( vStr, "GATE " );
537  Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pCell->Head) );
538  Vec_StrPrintStr( vStr, " " );
539  sprintf( Buffer, "%f", atof(Amap_LibertyGetString(p, pArea->Head)) );
540  Vec_StrPrintStr( vStr, Buffer );
541  Vec_StrPrintStr( vStr, " " );
542  Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pOutput->Head) );
543  Vec_StrPrintStr( vStr, "=" );
545  Vec_StrPrintStr( vStr, ";\n" );
546  Amap_ItemForEachChild( p, pCell, pPin )
547  if ( Vec_PtrFind(vOutputs, pPin) == -1 && !Amap_LibertyCompare(p, pPin->Key, "pin") )
548  {
549  Vec_StrPrintStr( vStr, " PIN " );
550  Vec_StrPrintStr( vStr, Amap_LibertyGetString(p, pPin->Head) );
551  Vec_StrPrintStr( vStr, " UNKNOWN 1 999 1.00 0.00 1.00 0.00\n" );
552  }
553  }
554  Vec_PtrFree( vOutputs );
555  }
556  Vec_StrPrintStr( vStr, "\n.end\n" );
557  Vec_StrPush( vStr, '\0' );
558 // printf( "%s", Vec_StrArray(vStr) );
559  return vStr;
560 }
561 
562 
563 /**Function*************************************************************
564 
565  Synopsis [Returns the file size.]
566 
567  Description [The file should be closed.]
568 
569  SideEffects []
570 
571  SeeAlso []
572 
573 ***********************************************************************/
574 int Amap_LibertyFileSize( char * pFileName )
575 {
576  FILE * pFile;
577  int nFileSize;
578  pFile = fopen( pFileName, "rb" );
579  if ( pFile == NULL )
580  {
581  printf( "Amap_LibertyFileSize(): The input file is unavailable (absent or open).\n" );
582  return 0;
583  }
584  fseek( pFile, 0, SEEK_END );
585  nFileSize = ftell( pFile );
586  fclose( pFile );
587  return nFileSize;
588 }
589 
590 /**Function*************************************************************
591 
592  Synopsis []
593 
594  Description []
595 
596  SideEffects []
597 
598  SeeAlso []
599 
600 ***********************************************************************/
601 void Amap_LibertyFixFileHead( char * pFileName )
602 {
603  char * pHead;
604  for ( pHead = pFileName; *pHead; pHead++ )
605  if ( *pHead == '>' )
606  *pHead = '\\';
607 }
608 
609 /**Function*************************************************************
610 
611  Synopsis []
612 
613  Description []
614 
615  SideEffects []
616 
617  SeeAlso []
618 
619 ***********************************************************************/
620 int Amap_LibertyCountItems( char * pBeg, char * pEnd )
621 {
622  int Counter = 0;
623  for ( ; pBeg < pEnd; pBeg++ )
624  Counter += (*pBeg == '(' || *pBeg == ':');
625  return Counter;
626 }
627 
628 /**Function*************************************************************
629 
630  Synopsis [Removes C-style comments.]
631 
632  Description []
633 
634  SideEffects []
635 
636  SeeAlso []
637 
638 ***********************************************************************/
639 void Amap_LibertyWipeOutComments( char * pBeg, char * pEnd )
640 {
641  char * pCur, * pStart;
642  for ( pCur = pBeg; pCur < pEnd; pCur++ )
643  if ( pCur[0] == '/' && pCur[1] == '*' )
644  for ( pStart = pCur; pCur < pEnd; pCur++ )
645  if ( pCur[0] == '*' && pCur[1] == '/' )
646  {
647  for ( ; pStart < pCur + 2; pStart++ )
648  if ( *pStart != '\n' ) *pStart = ' ';
649  break;
650  }
651 }
652 
653 /**Function*************************************************************
654 
655  Synopsis [Returns 1 if the character is space.]
656 
657  Description []
658 
659  SideEffects []
660 
661  SeeAlso []
662 
663 ***********************************************************************/
664 static inline int Amap_LibertyCharIsSpace( char c )
665 {
666  return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\\';
667 }
668 
669 /**Function*************************************************************
670 
671  Synopsis [Skips spaces.]
672 
673  Description [Returns 1 if reached the end.]
674 
675  SideEffects []
676 
677  SeeAlso []
678 
679 ***********************************************************************/
680 static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd, int fStopAtNewLine )
681 {
682  char * pPos = *ppPos;
683  for ( ; pPos < pEnd; pPos++ )
684  {
685  if ( *pPos == '\n' )
686  {
687  p->nLines++;
688  if ( fStopAtNewLine )
689  break;
690  }
691  if ( !Amap_LibertyCharIsSpace(*pPos) )
692  break;
693  }
694  *ppPos = pPos;
695  return pPos == pEnd;
696 }
697 
698 /**Function*************************************************************
699 
700  Synopsis [Skips entry delimited by " :;(){}" ]
701 
702  Description [Returns 1 if reached the end.]
703 
704  SideEffects []
705 
706  SeeAlso []
707 
708 ***********************************************************************/
709 static inline int Amap_LibertySkipEntry( char ** ppPos, char * pEnd )
710 {
711  char * pPos = *ppPos;
712  if ( *pPos == '\"' )
713  {
714  for ( pPos++; pPos < pEnd; pPos++ )
715  if ( *pPos == '\"' )
716  {
717  pPos++;
718  break;
719  }
720  }
721  else
722  {
723  for ( ; pPos < pEnd; pPos++ )
724  if ( *pPos == ' ' || *pPos == '\r' || *pPos == '\n' || *pPos == '\t' ||
725  *pPos == ':' || *pPos == ';' ||
726  *pPos == '(' || *pPos == ')' ||
727  *pPos == '{' || *pPos == '}' )
728  break;
729  }
730  *ppPos = pPos;
731  return pPos == pEnd;
732 }
733 
734 /**Function*************************************************************
735 
736  Synopsis [Find the matching closing symbol.]
737 
738  Description []
739 
740  SideEffects []
741 
742  SeeAlso []
743 
744 ***********************************************************************/
745 static inline char * Amap_LibertyFindMatch( char * pPos, char * pEnd )
746 {
747  int Counter = 0;
748  assert( *pPos == '(' || *pPos == '{' );
749  if ( *pPos == '(' )
750  {
751  for ( ; pPos < pEnd; pPos++ )
752  {
753  if ( *pPos == '(' )
754  Counter++;
755  if ( *pPos == ')' )
756  Counter--;
757  if ( Counter == 0 )
758  break;
759  }
760  }
761  else
762  {
763  for ( ; pPos < pEnd; pPos++ )
764  {
765  if ( *pPos == '{' )
766  Counter++;
767  if ( *pPos == '}' )
768  Counter--;
769  if ( Counter == 0 )
770  break;
771  }
772  }
773  assert( *pPos == ')' || *pPos == '}' );
774  return pPos;
775 }
776 
777 /**Function*************************************************************
778 
779  Synopsis [Find the matching closing symbol.]
780 
781  Description []
782 
783  SideEffects []
784 
785  SeeAlso []
786 
787 ***********************************************************************/
789 {
790  Amap_Pair_t Res;
791  char * pBeg = p->pContents + Head.Beg;
792  char * pEnd = p->pContents + Head.End;
793  char * pFirstNonSpace = NULL;
794  char * pLastNonSpace = NULL;
795  char * pChar;
796  for ( pChar = pBeg; pChar < pEnd; pChar++ )
797  {
798  if ( *pChar == '\n' )
799  p->nLines++;
800  if ( Amap_LibertyCharIsSpace(*pChar) )
801  continue;
802  pLastNonSpace = pChar;
803  if ( pFirstNonSpace == NULL )
804  pFirstNonSpace = pChar;
805  }
806  if ( pFirstNonSpace == NULL || pLastNonSpace == NULL )
807  return Head;
808  assert( pFirstNonSpace && pLastNonSpace );
809  Res.Beg = pFirstNonSpace - p->pContents;
810  Res.End = pLastNonSpace - p->pContents + 1;
811  return Res;
812 }
813 
814 /**Function*************************************************************
815 
816  Synopsis [Returns free item.]
817 
818  Description []
819 
820  SideEffects []
821 
822  SeeAlso []
823 
824 ***********************************************************************/
825 static inline Amap_Item_t * Amap_LibertyNewItem( Amap_Tree_t * p, int Type )
826 {
827  p->pItems[p->nItems].iLine = p->nLines;
828  p->pItems[p->nItems].Type = Type;
829  p->pItems[p->nItems].Child = -1;
830  p->pItems[p->nItems].Next = -1;
831  return p->pItems + p->nItems++;
832 }
833 
834 /**Function*************************************************************
835 
836  Synopsis [Returns free item.]
837 
838  Description []
839 
840  SideEffects []
841 
842  SeeAlso []
843 
844 ***********************************************************************/
845 int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd )
846 {
847  Amap_Item_t * pItem;
848  Amap_Pair_t Key, Head, Body;
849  char * pNext, * pStop;
850  Key.End = 0;
851  if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
852  return -2;
853  Key.Beg = *ppPos - p->pContents;
854  if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
855  goto exit;
856  Key.End = *ppPos - p->pContents;
857  if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
858  goto exit;
859  pNext = *ppPos;
860  if ( *pNext == ':' )
861  {
862  *ppPos = pNext + 1;
863  if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
864  goto exit;
865  Head.Beg = *ppPos - p->pContents;
866  if ( Amap_LibertySkipEntry( ppPos, pEnd ) )
867  goto exit;
868  Head.End = *ppPos - p->pContents;
869  if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
870  goto exit;
871  pNext = *ppPos;
872  if ( *pNext != ';' && *pNext != '\n' )
873  goto exit;
874  *ppPos = pNext + 1;
875  // end of equation
877  pItem->Key = Key;
878  pItem->Head = Amap_LibertyUpdateHead( p, Head );
879  pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
880  if ( pItem->Next == -1 )
881  goto exit;
882  return Amap_LibertyItemId( p, pItem );
883  }
884  if ( *pNext == '(' )
885  {
886  pStop = Amap_LibertyFindMatch( pNext, pEnd );
887  Head.Beg = pNext - p->pContents + 1;
888  Head.End = pStop - p->pContents;
889  *ppPos = pStop + 1;
890  if ( Amap_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
891  {
892  // end of list
894  pItem->Key = Key;
895  pItem->Head = Amap_LibertyUpdateHead( p, Head );
896  return Amap_LibertyItemId( p, pItem );
897  }
898  pNext = *ppPos;
899  if ( *pNext == '{' ) // beginning of body
900  {
901  pStop = Amap_LibertyFindMatch( pNext, pEnd );
902  Body.Beg = pNext - p->pContents + 1;
903  Body.End = pStop - p->pContents;
904  // end of body
906  pItem->Key = Key;
907  pItem->Head = Amap_LibertyUpdateHead( p, Head );
908  pItem->Body = Body;
909  *ppPos = pNext + 1;
910  pItem->Child = Amap_LibertyBuildItem( p, ppPos, pStop );
911  if ( pItem->Child == -1 )
912  goto exit;
913  *ppPos = pStop + 1;
914  pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
915  if ( pItem->Next == -1 )
916  goto exit;
917  return Amap_LibertyItemId( p, pItem );
918  }
919  // end of list
920  if ( *pNext == ';' )
921  *ppPos = pNext + 1;
923  pItem->Key = Key;
924  pItem->Head = Amap_LibertyUpdateHead( p, Head );
925  pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd );
926  if ( pItem->Next == -1 )
927  goto exit;
928  return Amap_LibertyItemId( p, pItem );
929  }
930 exit:
931  if ( p->pError == NULL )
932  {
933  p->pError = ABC_ALLOC( char, 1000 );
934  sprintf( p->pError, "File \"%s\". Line %6d. Failed to parse entry \"%s\".\n",
935  p->pFileName, p->nLines, Amap_LibertyGetString(p, Key) );
936  }
937  return -1;
938 }
939 
940 /**Function*************************************************************
941 
942  Synopsis [Starts the parsing manager.]
943 
944  Description []
945 
946  SideEffects []
947 
948  SeeAlso []
949 
950 ***********************************************************************/
951 Amap_Tree_t * Amap_LibertyStart( char * pFileName )
952 {
953  FILE * pFile;
954  Amap_Tree_t * p;
955  int RetValue;
956  // start the manager
957  p = ABC_ALLOC( Amap_Tree_t, 1 );
958  memset( p, 0, sizeof(Amap_Tree_t) );
959  // read the file into the buffer
960  Amap_LibertyFixFileHead( pFileName );
961  p->nContents = Amap_LibertyFileSize( pFileName );
962  if ( p->nContents == 0 )
963  {
964  ABC_FREE( p );
965  return NULL;
966  }
967  pFile = fopen( pFileName, "rb" );
968  p->pContents = ABC_ALLOC( char, p->nContents+1 );
969  RetValue = fread( p->pContents, p->nContents, 1, pFile );
970  fclose( pFile );
971  p->pContents[p->nContents] = 0;
972  // other
973  p->pFileName = Abc_UtilStrsav( pFileName );
976  p->nItems = 0;
977  p->nLines = 1;
978  return p;
979 }
980 
981 /**Function*************************************************************
982 
983  Synopsis [Stops the parsing manager.]
984 
985  Description []
986 
987  SideEffects []
988 
989  SeeAlso []
990 
991 ***********************************************************************/
993 {
994  ABC_FREE( p->pFileName );
995  ABC_FREE( p->pContents );
996  ABC_FREE( p->pItems );
997  ABC_FREE( p->pError );
998  ABC_FREE( p );
999 }
1000 
1001 /**Function*************************************************************
1002 
1003  Synopsis [Parses the standard cell library in Liberty format.]
1004 
1005  Description [Writes the resulting file in Genlib format.]
1006 
1007  SideEffects []
1008 
1009  SeeAlso []
1010 
1011 ***********************************************************************/
1012 int Amap_LibertyParse( char * pFileName, int fVerbose )
1013 {
1014  Amap_Tree_t * p;
1015  char * pPos;
1016  abctime clk = Abc_Clock();
1017  int RetValue;
1018  p = Amap_LibertyStart( pFileName );
1019  if ( p == NULL )
1020  return 0;
1021  pPos = p->pContents;
1023  if ( Amap_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
1024  {
1025  if ( fVerbose )
1026  printf( "Parsing finished successfully.\n" );
1027 // Amap_LibertyPrintLiberty( p, "temp_.lib" );
1028  Amap_LibertyPrintGenlib( p, Extra_FileNameGenericAppend(pFileName, ".genlib"), fVerbose );
1029  RetValue = 1;
1030  }
1031  else
1032  {
1033  if ( p->pError )
1034  printf( "%s", p->pError );
1035  if ( fVerbose )
1036  printf( "Parsing failed.\n" );
1037  RetValue = 0;
1038  }
1039  if ( fVerbose )
1040  {
1041  printf( "Memory = %7.2f MB. ", 1.0*(p->nContents+p->nItermAlloc*sizeof(Amap_Item_t))/(1<<20) );
1042  ABC_PRT( "Time", Abc_Clock() - clk );
1043  }
1044  Amap_LibertyStop( p );
1045  return RetValue;
1046 }
1047 
1048 /**Function*************************************************************
1049 
1050  Synopsis [Parses the standard cell library in Liberty format.]
1051 
1052  Description [Writes the resulting file in Genlib format.]
1053 
1054  SideEffects []
1055 
1056  SeeAlso []
1057 
1058 ***********************************************************************/
1059 Vec_Str_t * Amap_LibertyParseStr( char * pFileName, int fVerbose )
1060 {
1061  Amap_Tree_t * p;
1062  Vec_Str_t * vStr = NULL;
1063  char * pPos;
1064  abctime clk = Abc_Clock();
1065  int RetValue;
1066  p = Amap_LibertyStart( pFileName );
1067  if ( p == NULL )
1068  return 0;
1069  pPos = p->pContents;
1071  if ( Amap_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
1072  {
1073  if ( fVerbose )
1074  printf( "Parsing finished successfully.\n" );
1075 // Amap_LibertyPrintLiberty( p, "temp_.lib" );
1076  vStr = Amap_LibertyPrintGenlibStr( p, fVerbose );
1077  RetValue = 1;
1078  }
1079  else
1080  {
1081  if ( p->pError )
1082  printf( "%s", p->pError );
1083  if ( fVerbose )
1084  printf( "Parsing failed.\n" );
1085  RetValue = 0;
1086  }
1087  if ( fVerbose )
1088  {
1089  printf( "Memory = %7.2f MB. ", 1.0*(p->nContents+p->nItermAlloc*sizeof(Amap_Item_t))/(1<<20) );
1090  ABC_PRT( "Time", Abc_Clock() - clk );
1091  }
1092  Amap_LibertyStop( p );
1093  return vStr;
1094 }
1095 
1096 
1097 ////////////////////////////////////////////////////////////////////////
1098 /// END OF FILE ///
1099 ////////////////////////////////////////////////////////////////////////
1100 
1101 
1103 
char * memset()
int Amap_LibertyPrintGenlib(Amap_Tree_t *p, char *pFileName, int fVerbose)
Definition: amapLiberty.c:367
int Amap_LibertyCountItems(char *pBeg, char *pEnd)
Definition: amapLiberty.c:620
VOID_HACK exit()
static int Amap_LibertyCompare(Amap_Tree_t *p, Amap_Pair_t Pair, char *pStr)
Definition: amapLiberty.c:74
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
Amap_Item_t * pItems
Definition: amapLiberty.c:68
int Amap_LibertyFileSize(char *pFileName)
Definition: amapLiberty.c:574
void Amap_LibertyStop(Amap_Tree_t *p)
Definition: amapLiberty.c:992
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int Amap_LibertyCellCountOutputs(Amap_Tree_t *p, Amap_Item_t *pCell)
Definition: amapLiberty.c:302
Amap_Pair_t Key
Definition: amapLiberty.c:52
static void Amap_PrintSpace(FILE *pFile, int nOffset)
Definition: amapLiberty.c:76
Amap_Item_t * Amap_LibertyPinFunction(Amap_Tree_t *p, Amap_Item_t *pPin)
Definition: amapLiberty.c:221
char * strncpy()
#define SEEK_END
Definition: zconf.h:392
Vec_Str_t * Amap_LibertyParseStr(char *pFileName, int fVerbose)
Definition: amapLiberty.c:1059
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 Vec_Str_t * Vec_StrAlloc(int nCap)
Definition: bblif.c:495
char * pContents
Definition: amapLiberty.c:63
static abctime Abc_Clock()
Definition: abc_global.h:279
static void Vec_StrPush(Vec_Str_t *p, char Entry)
Definition: vecStr.h:535
#define ABC_MAX_LIB_STR_LEN
DECLARATIONS ///.
Definition: amapLiberty.c:30
static char * Amap_LibertyFindMatch(char *pPos, char *pEnd)
Definition: amapLiberty.c:745
static int Vec_PtrFind(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:694
int strcmp()
Amap_Pair_t Body
Definition: amapLiberty.c:54
static int Amap_LibertySkipEntry(char **ppPos, char *pEnd)
Definition: amapLiberty.c:709
int Amap_LibertyPrintLiberty(Amap_Tree_t *p, char *pFileName)
Definition: amapLiberty.c:143
static Amap_Item_t * Amap_LibertyNewItem(Amap_Tree_t *p, int Type)
Definition: amapLiberty.c:825
void Amap_LibertyWipeOutComments(char *pBeg, char *pEnd)
Definition: amapLiberty.c:639
char * Amap_LibertyGetString(Amap_Tree_t *p, Amap_Pair_t Pair)
Definition: amapLiberty.c:327
char * pFileName
Definition: amapLiberty.c:62
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
void Amap_LibertyPrintLibertyItem(FILE *pFile, Amap_Tree_t *p, Amap_Item_t *pItem, int nOffset)
FUNCTION DEFINITIONS ///.
Definition: amapLiberty.c:97
Vec_Str_t * Amap_LibertyPrintGenlibStr(Amap_Tree_t *p, int fVerbose)
Definition: amapLiberty.c:478
#define Amap_ItemForEachChild(p, pItem, pChild)
Definition: amapLiberty.c:79
char * sprintf()
static int Counter
Amap_LibertyType_t
Definition: amapLiberty.c:33
int Amap_LibertyParse(char *pFileName, int fVerbose)
Definition: amapLiberty.c:1012
Amap_Pair_t Head
Definition: amapLiberty.c:53
Amap_Item_t * Amap_LibertyCellOutput(Amap_Tree_t *p, Amap_Item_t *pCell)
Definition: amapLiberty.c:241
char * strcpy()
double atof()
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
char * Amap_LibertyGetStringFormula(Amap_Tree_t *p, Amap_Pair_t Pair)
Definition: amapLiberty.c:347
int Amap_LibertyBuildItem(Amap_Tree_t *p, char **ppPos, char *pEnd)
Definition: amapLiberty.c:845
Vec_Ptr_t * Amap_LibertyCellOutputs(Amap_Tree_t *p, Amap_Item_t *pCell)
Definition: amapLiberty.c:253
static int Amap_LibertyCharIsSpace(char c)
Definition: amapLiberty.c:664
char * pError
Definition: amapLiberty.c:69
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
char * Amap_LibertyTimeStamp()
Definition: amapLiberty.c:175
Amap_Tree_t * Amap_LibertyStart(char *pFileName)
Definition: amapLiberty.c:951
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int Amap_LibertySkipSpaces(Amap_Tree_t *p, char **ppPos, char *pEnd, int fStopAtNewLine)
Definition: amapLiberty.c:680
#define ABC_PRT(a, t)
Definition: abc_global.h:220
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
static int Amap_LibertyItemId(Amap_Tree_t *p, Amap_Item_t *pItem)
Definition: amapLiberty.c:77
int strncmp()
int Amap_LibertyCellIsFlop(Amap_Tree_t *p, Amap_Item_t *pCell)
Definition: amapLiberty.c:200
void Amap_LibertyFixFileHead(char *pFileName)
Definition: amapLiberty.c:601
#define assert(ex)
Definition: util_old.h:213
char * Extra_FileNameGenericAppend(char *pBase, char *pSuffix)
int strlen()
static void Vec_StrPrintStr(Vec_Str_t *p, const char *pStr)
Definition: vecStr.h:627
static void Amap_PrintWord(FILE *pFile, Amap_Tree_t *p, Amap_Pair_t Pair)
Definition: amapLiberty.c:75
static Amap_Pair_t Amap_LibertyUpdateHead(Amap_Tree_t *p, Amap_Pair_t Head)
Definition: amapLiberty.c:788
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
ABC_INT64_T abctime
Definition: abc_global.h:278
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
Amap_Item_t * Amap_LibertyCellArea(Amap_Tree_t *p, Amap_Item_t *pCell)
Definition: amapLiberty.c:279
static Amap_Item_t * Amap_LibertyItem(Amap_Tree_t *p, int v)
Definition: amapLiberty.c:73
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
static Amap_Item_t * Amap_LibertyRoot(Amap_Tree_t *p)
Definition: amapLiberty.c:72