abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sclLiberty.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [sclLiberty.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Standard-cell library representation.]
8 
9  Synopsis [Liberty parser.]
10 
11  Author [Alan Mishchenko, Niklas Een]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - August 24, 2012.]
16 
17  Revision [$Id: sclLiberty.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "sclLib.h"
22 #include "misc/st/st.h"
23 #include "map/mio/mio.h"
24 
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 #define ABC_MAX_LIB_STR_LEN 5000
33 
34 // entry types
35 typedef enum {
36  SCL_LIBERTY_NONE = 0, // 0: unknown
37  SCL_LIBERTY_PROC, // 1: procedure : key(head){body}
38  SCL_LIBERTY_EQUA, // 2: equation : key:head;
39  SCL_LIBERTY_LIST // 3: list : key(head)
41 
42 typedef struct Scl_Pair_t_ Scl_Pair_t;
44 {
45  int Beg; // item beginning
46  int End; // item end
47 };
48 
49 typedef struct Scl_Item_t_ Scl_Item_t;
51 {
52  int Type; // Scl_LibertyType_t
53  int iLine; // file line where the item's spec begins
54  Scl_Pair_t Key; // key part
55  Scl_Pair_t Head; // head part
56  Scl_Pair_t Body; // body part
57  int Next; // next item in the list
58  int Child; // first child item
59 };
60 
61 typedef struct Scl_Tree_t_ Scl_Tree_t;
63 {
64  char * pFileName; // input Liberty file name
65  char * pContents; // file contents
66  int nContents; // file size
67  int nLines; // line counter
68  int nItems; // number of items
69  int nItermAlloc; // number of items allocated
70  Scl_Item_t * pItems; // the items
71  char * pError; // the error string
72  abctime clkStart; // beginning time
73 };
74 
75 static inline Scl_Item_t * Scl_LibertyRoot( Scl_Tree_t * p ) { return p->pItems; }
76 static inline Scl_Item_t * Scl_LibertyItem( Scl_Tree_t * p, int v ) { assert( v < p->nItems ); return v < 0 ? NULL : p->pItems + v; }
77 static inline int Scl_LibertyCompare( Scl_Tree_t * p, Scl_Pair_t Pair, char * pStr ) { return strncmp( p->pContents+Pair.Beg, pStr, Pair.End-Pair.Beg ) || ((int)strlen(pStr) != Pair.End-Pair.Beg); }
78 static inline void Scl_PrintWord( FILE * pFile, Scl_Tree_t * p, Scl_Pair_t Pair ) { char * pBeg = p->pContents+Pair.Beg, * pEnd = p->pContents+Pair.End; while ( pBeg < pEnd ) fputc( *pBeg++, pFile ); }
79 static inline void Scl_PrintSpace( FILE * pFile, int nOffset ) { int i; for ( i = 0; i < nOffset; i++ ) fputc(' ', pFile); }
80 static inline int Scl_LibertyItemId( Scl_Tree_t * p, Scl_Item_t * pItem ) { return pItem - p->pItems; }
81 
82 #define Scl_ItemForEachChild( p, pItem, pChild ) \
83  for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) )
84 #define Scl_ItemForEachChildName( p, pItem, pChild, pName ) \
85  for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) ) if ( Scl_LibertyCompare(p, pChild->Key, pName) ) {} else
86 
87 ////////////////////////////////////////////////////////////////////////
88 /// FUNCTION DEFINITIONS ///
89 ////////////////////////////////////////////////////////////////////////
90 
91 /**Function*************************************************************
92 
93  Synopsis [Prints parse tree in Liberty format.]
94 
95  Description []
96 
97  SideEffects []
98 
99  SeeAlso []
100 
101 ***********************************************************************/
102 void Scl_LibertyParseDumpItem( FILE * pFile, Scl_Tree_t * p, Scl_Item_t * pItem, int nOffset )
103 {
104  if ( pItem->Type == SCL_LIBERTY_PROC )
105  {
106  Scl_PrintSpace( pFile, nOffset );
107  Scl_PrintWord( pFile, p, pItem->Key );
108  fprintf( pFile, "(" );
109  Scl_PrintWord( pFile, p, pItem->Head );
110  fprintf( pFile, ") {\n" );
111  if ( Scl_LibertyItem(p, pItem->Child) )
112  Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyItem(p, pItem->Child), nOffset + 2 );
113  Scl_PrintSpace( pFile, nOffset );
114  fprintf( pFile, "}\n" );
115  }
116  else if ( pItem->Type == SCL_LIBERTY_EQUA )
117  {
118  Scl_PrintSpace( pFile, nOffset );
119  Scl_PrintWord( pFile, p, pItem->Key );
120  fprintf( pFile, " : " );
121  Scl_PrintWord( pFile, p, pItem->Head );
122  fprintf( pFile, ";\n" );
123  }
124  else if ( pItem->Type == SCL_LIBERTY_LIST )
125  {
126  Scl_PrintSpace( pFile, nOffset );
127  Scl_PrintWord( pFile, p, pItem->Key );
128  fprintf( pFile, "(" );
129  Scl_PrintWord( pFile, p, pItem->Head );
130  fprintf( pFile, ");\n" );
131  }
132  else assert( 0 );
133  if ( Scl_LibertyItem(p, pItem->Next) )
134  Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyItem(p, pItem->Next), nOffset );
135 }
136 int Scl_LibertyParseDump( Scl_Tree_t * p, char * pFileName )
137 {
138  FILE * pFile;
139  if ( pFileName == NULL )
140  pFile = stdout;
141  else
142  {
143  pFile = fopen( pFileName, "w" );
144  if ( pFile == NULL )
145  {
146  printf( "Scl_LibertyParseDump(): The output file is unavailable (absent or open).\n" );
147  return 0;
148  }
149  }
150  Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyRoot(p), 0 );
151  if ( pFile != stdout )
152  fclose( pFile );
153  return 1;
154 }
155 
156 
157 /**Function*************************************************************
158 
159  Synopsis [Gets the name to write.]
160 
161  Description []
162 
163  SideEffects []
164 
165  SeeAlso []
166 
167 ***********************************************************************/
168 int Scl_LibertyCountItems( char * pBeg, char * pEnd )
169 {
170  int Counter = 0;
171  for ( ; pBeg < pEnd; pBeg++ )
172  Counter += (*pBeg == '(' || *pBeg == ':');
173  return Counter;
174 }
175 // removes C-style comments
176 /*
177 void Scl_LibertyWipeOutComments( char * pBeg, char * pEnd )
178 {
179  char * pCur, * pStart;
180  for ( pCur = pBeg; pCur < pEnd; pCur++ )
181  if ( pCur[0] == '/' && pCur[1] == '*' )
182  for ( pStart = pCur; pCur < pEnd; pCur++ )
183  if ( pCur[0] == '*' && pCur[1] == '/' )
184  {
185  for ( ; pStart < pCur + 2; pStart++ )
186  if ( *pStart != '\n' ) *pStart = ' ';
187  break;
188  }
189 }
190 */
191 void Scl_LibertyWipeOutComments( char * pBeg, char * pEnd )
192 {
193  char * pCur, * pStart;
194  for ( pCur = pBeg; pCur < pEnd-1; pCur++ )
195  if ( pCur[0] == '/' && pCur[1] == '*' )
196  {
197  for ( pStart = pCur; pCur < pEnd-1; pCur++ )
198  if ( pCur[0] == '*' && pCur[1] == '/' )
199  {
200  for ( ; pStart < pCur + 2; pStart++ )
201  if ( *pStart != '\n' ) *pStart = ' ';
202  break;
203  }
204  }
205  else if ( pCur[0] == '/' && pCur[1] == '/' )
206  {
207  for ( pStart = pCur; pCur < pEnd; pCur++ )
208  if ( pCur[0] == '\n' || pCur == pEnd-1 )
209  {
210  for ( ; pStart < pCur; pStart++ ) *pStart = ' ';
211  break;
212  }
213  }
214 }
215 static inline int Scl_LibertyCharIsSpace( char c )
216 {
217  return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\\';
218 }
219 static inline int Scl_LibertySkipSpaces( Scl_Tree_t * p, char ** ppPos, char * pEnd, int fStopAtNewLine )
220 {
221  char * pPos = *ppPos;
222  for ( ; pPos < pEnd; pPos++ )
223  {
224  if ( *pPos == '\n' )
225  {
226  p->nLines++;
227  if ( fStopAtNewLine )
228  break;
229  }
230  if ( !Scl_LibertyCharIsSpace(*pPos) )
231  break;
232  }
233  *ppPos = pPos;
234  return pPos == pEnd;
235 }
236 // skips entry delimited by " :;(){}" and returns 1 if reached the end
237 static inline int Scl_LibertySkipEntry( char ** ppPos, char * pEnd )
238 {
239  char * pPos = *ppPos;
240  if ( *pPos == '\"' )
241  {
242  for ( pPos++; pPos < pEnd; pPos++ )
243  if ( *pPos == '\"' )
244  {
245  pPos++;
246  break;
247  }
248  }
249  else
250  {
251  for ( ; pPos < pEnd; pPos++ )
252  if ( *pPos == ' ' || *pPos == '\r' || *pPos == '\n' || *pPos == '\t' ||
253  *pPos == ':' || *pPos == ';' ||
254  *pPos == '(' || *pPos == ')' ||
255  *pPos == '{' || *pPos == '}' )
256  break;
257  }
258  *ppPos = pPos;
259  return pPos == pEnd;
260 }
261 // finds the matching closing symbol
262 static inline char * Scl_LibertyFindMatch( char * pPos, char * pEnd )
263 {
264  int Counter = 0;
265  assert( *pPos == '(' || *pPos == '{' );
266  if ( *pPos == '(' )
267  {
268  for ( ; pPos < pEnd; pPos++ )
269  {
270  if ( *pPos == '(' )
271  Counter++;
272  if ( *pPos == ')' )
273  Counter--;
274  if ( Counter == 0 )
275  break;
276  }
277  }
278  else
279  {
280  for ( ; pPos < pEnd; pPos++ )
281  {
282  if ( *pPos == '{' )
283  Counter++;
284  if ( *pPos == '}' )
285  Counter--;
286  if ( Counter == 0 )
287  break;
288  }
289  }
290  assert( *pPos == ')' || *pPos == '}' );
291  return pPos;
292 }
293 // trims spaces around the head
295 {
296  Scl_Pair_t Res;
297  char * pBeg = p->pContents + Head.Beg;
298  char * pEnd = p->pContents + Head.End;
299  char * pFirstNonSpace = NULL;
300  char * pLastNonSpace = NULL;
301  char * pChar;
302  for ( pChar = pBeg; pChar < pEnd; pChar++ )
303  {
304  if ( *pChar == '\n' )
305  p->nLines++;
306  if ( Scl_LibertyCharIsSpace(*pChar) )
307  continue;
308  pLastNonSpace = pChar;
309  if ( pFirstNonSpace == NULL )
310  pFirstNonSpace = pChar;
311  }
312  if ( pFirstNonSpace == NULL || pLastNonSpace == NULL )
313  return Head;
314  assert( pFirstNonSpace && pLastNonSpace );
315  Res.Beg = pFirstNonSpace - p->pContents;
316  Res.End = pLastNonSpace - p->pContents + 1;
317  return Res;
318 }
319 // returns new item
320 static inline Scl_Item_t * Scl_LibertyNewItem( Scl_Tree_t * p, int Type )
321 {
322  p->pItems[p->nItems].iLine = p->nLines;
323  p->pItems[p->nItems].Type = Type;
324  p->pItems[p->nItems].Child = -1;
325  p->pItems[p->nItems].Next = -1;
326  return p->pItems + p->nItems++;
327 }
328 
329 
330 /**Function*************************************************************
331 
332  Synopsis [Gets the name to write.]
333 
334  Description []
335 
336  SideEffects []
337 
338  SeeAlso []
339 
340 ***********************************************************************/
342 {
343  static char Buffer[ABC_MAX_LIB_STR_LEN];
344  assert( Pair.End-Pair.Beg < ABC_MAX_LIB_STR_LEN );
345  strncpy( Buffer, p->pContents+Pair.Beg, Pair.End-Pair.Beg );
346  if ( Pair.Beg < Pair.End && Buffer[0] == '\"' )
347  {
348  assert( Buffer[Pair.End-Pair.Beg-1] == '\"' );
349  Buffer[Pair.End-Pair.Beg-1] = 0;
350  return Buffer + 1;
351  }
352  Buffer[Pair.End-Pair.Beg] = 0;
353  return Buffer;
354 }
355 int Scl_LibertyItemNum( Scl_Tree_t * p, Scl_Item_t * pRoot, char * pName )
356 {
357  Scl_Item_t * pItem;
358  int Counter = 0;
359  Scl_ItemForEachChildName( p, pRoot, pItem, pName )
360  Counter++;
361  return Counter;
362 }
363 
364 /**Function*************************************************************
365 
366  Synopsis [Returns free item.]
367 
368  Description []
369 
370  SideEffects []
371 
372  SeeAlso []
373 
374 ***********************************************************************/
375 int Scl_LibertyBuildItem( Scl_Tree_t * p, char ** ppPos, char * pEnd )
376 {
377  Scl_Item_t * pItem;
378  Scl_Pair_t Key, Head, Body;
379  char * pNext, * pStop;
380  Key.End = 0;
381  if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
382  return -2;
383  Key.Beg = *ppPos - p->pContents;
384  if ( Scl_LibertySkipEntry( ppPos, pEnd ) )
385  goto exit;
386  Key.End = *ppPos - p->pContents;
387  if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
388  goto exit;
389  pNext = *ppPos;
390  if ( *pNext == ':' )
391  {
392  *ppPos = pNext + 1;
393  if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
394  goto exit;
395  Head.Beg = *ppPos - p->pContents;
396  if ( Scl_LibertySkipEntry( ppPos, pEnd ) )
397  goto exit;
398  Head.End = *ppPos - p->pContents;
399  if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
400  goto exit;
401  pNext = *ppPos;
402  if ( *pNext != ';' && *pNext != '\n' )
403  goto exit;
404  *ppPos = pNext + 1;
405  // end of equation
406  pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_EQUA );
407  pItem->Key = Key;
408  pItem->Head = Scl_LibertyUpdateHead( p, Head );
409  pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
410  if ( pItem->Next == -1 )
411  goto exit;
412  return Scl_LibertyItemId( p, pItem );
413  }
414  if ( *pNext == '(' )
415  {
416  pStop = Scl_LibertyFindMatch( pNext, pEnd );
417  Head.Beg = pNext - p->pContents + 1;
418  Head.End = pStop - p->pContents;
419  *ppPos = pStop + 1;
420  if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
421  {
422  // end of list
423  pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_LIST );
424  pItem->Key = Key;
425  pItem->Head = Scl_LibertyUpdateHead( p, Head );
426  return Scl_LibertyItemId( p, pItem );
427  }
428  pNext = *ppPos;
429  if ( *pNext == '{' ) // beginning of body
430  {
431  pStop = Scl_LibertyFindMatch( pNext, pEnd );
432  Body.Beg = pNext - p->pContents + 1;
433  Body.End = pStop - p->pContents;
434  // end of body
435  pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_PROC );
436  pItem->Key = Key;
437  pItem->Head = Scl_LibertyUpdateHead( p, Head );
438  pItem->Body = Body;
439  *ppPos = pNext + 1;
440  pItem->Child = Scl_LibertyBuildItem( p, ppPos, pStop );
441  if ( pItem->Child == -1 )
442  goto exit;
443  *ppPos = pStop + 1;
444  pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
445  if ( pItem->Next == -1 )
446  goto exit;
447  return Scl_LibertyItemId( p, pItem );
448  }
449  // end of list
450  if ( *pNext == ';' )
451  *ppPos = pNext + 1;
452  pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_LIST );
453  pItem->Key = Key;
454  pItem->Head = Scl_LibertyUpdateHead( p, Head );
455  pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
456  if ( pItem->Next == -1 )
457  goto exit;
458  return Scl_LibertyItemId( p, pItem );
459  }
460 exit:
461  if ( p->pError == NULL )
462  {
463  p->pError = ABC_ALLOC( char, 1000 );
464  sprintf( p->pError, "File \"%s\". Line %6d. Failed to parse entry \"%s\".\n",
465  p->pFileName, p->nLines, Scl_LibertyReadString(p, Key) );
466  }
467  return -1;
468 }
469 
470 /**Function*************************************************************
471 
472  Synopsis [File management.]
473 
474  Description []
475 
476  SideEffects []
477 
478  SeeAlso []
479 
480 ***********************************************************************/
481 void Scl_LibertyFixFileName( char * pFileName )
482 {
483  char * pHead;
484  for ( pHead = pFileName; *pHead; pHead++ )
485  if ( *pHead == '>' )
486  *pHead = '\\';
487 }
488 int Scl_LibertyFileSize( char * pFileName )
489 {
490  FILE * pFile;
491  int nFileSize;
492  pFile = fopen( pFileName, "rb" );
493  if ( pFile == NULL )
494  {
495  printf( "Scl_LibertyFileSize(): The input file is unavailable (absent or open).\n" );
496  return 0;
497  }
498  fseek( pFile, 0, SEEK_END );
499  nFileSize = ftell( pFile );
500  fclose( pFile );
501  return nFileSize;
502 }
503 char * Scl_LibertyFileContents( char * pFileName, int nContents )
504 {
505  FILE * pFile = fopen( pFileName, "rb" );
506  char * pContents = ABC_ALLOC( char, nContents+1 );
507  int RetValue;
508  RetValue = fread( pContents, nContents, 1, pFile );
509  fclose( pFile );
510  pContents[nContents] = 0;
511  return pContents;
512 }
513 void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr )
514 {
515  FILE * pFile = fopen( pFileName, "wb" );
516  int RetValue;
517  if ( pFile == NULL )
518  {
519  printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" );
520  return;
521  }
522  RetValue = fwrite( Vec_StrArray(vStr), 1, Vec_StrSize(vStr), pFile );
523  fclose( pFile );
524 }
525 
526 /**Function*************************************************************
527 
528  Synopsis [Starts the parsing manager.]
529 
530  Description []
531 
532  SideEffects []
533 
534  SeeAlso []
535 
536 ***********************************************************************/
537 Scl_Tree_t * Scl_LibertyStart( char * pFileName )
538 {
539  Scl_Tree_t * p;
540  int RetValue;
541  // read the file into the buffer
542  Scl_LibertyFixFileName( pFileName );
543  RetValue = Scl_LibertyFileSize( pFileName );
544  if ( RetValue == 0 )
545  return NULL;
546  // start the manager
547  p = ABC_ALLOC( Scl_Tree_t, 1 );
548  memset( p, 0, sizeof(Scl_Tree_t) );
549  p->clkStart = Abc_Clock();
550  p->nContents = RetValue;
551  p->pContents = Scl_LibertyFileContents( pFileName, p->nContents );
552  // other
553  p->pFileName = Abc_UtilStrsav( pFileName );
556  p->nItems = 0;
557  p->nLines = 1;
558  return p;
559 }
560 void Scl_LibertyStop( Scl_Tree_t * p, int fVerbose )
561 {
562  if ( fVerbose )
563  {
564  printf( "Memory = %7.2f MB. ", 1.0 * (p->nContents + p->nItermAlloc * sizeof(Scl_Item_t))/(1<<20) );
565  ABC_PRT( "Time", Abc_Clock() - p->clkStart );
566  }
567  ABC_FREE( p->pFileName );
568  ABC_FREE( p->pContents );
569  ABC_FREE( p->pItems );
570  ABC_FREE( p->pError );
571  ABC_FREE( p );
572 }
573 Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose )
574 {
575  Scl_Tree_t * p;
576  char * pPos;
577  if ( (p = Scl_LibertyStart(pFileName)) == NULL )
578  return NULL;
579  pPos = p->pContents;
581  if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
582  {
583  if ( p->pError ) printf( "%s", p->pError );
584  printf( "Parsing failed. " );
585  Abc_PrintTime( 1, "Parsing time", Abc_Clock() - p->clkStart );
586  }
587  else if ( fVerbose )
588  {
589  printf( "Parsing finished successfully. " );
590  Abc_PrintTime( 1, "Parsing time", Abc_Clock() - p->clkStart );
591  }
592  return p;
593 }
594 
595 /**Function*************************************************************
596 
597  Synopsis [Fetching attributes.]
598 
599  Description []
600 
601  SideEffects []
602 
603  SeeAlso []
604 
605 ***********************************************************************/
607 {
608  Scl_Item_t * pAttr;
609  Scl_ItemForEachChild( p, pCell, pAttr )
610  if ( !Scl_LibertyCompare(p, pAttr->Key, "ff") ||
611  !Scl_LibertyCompare(p, pAttr->Key, "latch") )
612  return 1;
613  return 0;
614 }
616 {
617  Scl_Item_t * pArea;
618  Scl_ItemForEachChildName( p, pCell, pArea, "area" )
619  return Scl_LibertyReadString(p, pArea->Head);
620  return 0;
621 }
623 {
624  Scl_Item_t * pItem, * pChild;
625  Scl_ItemForEachChildName( p, pCell, pItem, "cell_leakage_power" )
626  return Scl_LibertyReadString(p, pItem->Head);
627  // look for another type
628  Scl_ItemForEachChildName( p, pCell, pItem, "leakage_power" )
629  {
630  Scl_ItemForEachChildName( p, pItem, pChild, "when" )
631  break;
632  if ( pChild && !Scl_LibertyCompare(p, pChild->Key, "when") )
633  continue;
634  Scl_ItemForEachChildName( p, pItem, pChild, "value" )
635  return Scl_LibertyReadString(p, pChild->Head);
636  }
637  return 0;
638 }
640 {
641  Scl_Item_t * pFunc;
642  Scl_ItemForEachChildName( p, pPin, pFunc, "function" )
643  return Scl_LibertyReadString(p, pFunc->Head);
644  return NULL;
645 }
647 {
648  Scl_Item_t * pPin, * pItem;
649  Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
650  Scl_ItemForEachChildName( p, pPin, pItem, "three_state" )
651  return 1;
652  return 0;
653 }
655 {
656  Scl_Item_t * pPin;
657  int Counter = 0;
658  Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
659  if ( Scl_LibertyReadPinFormula(p, pPin) )
660  Counter++;
661  return Counter;
662 }
663 
664 /**Function*************************************************************
665 
666  Synopsis [Parses the standard cell library in Liberty format.]
667 
668  Description [Writes the resulting file in Genlib format.]
669 
670  SideEffects []
671 
672  SeeAlso []
673 
674 ***********************************************************************/
676 {
677  Vec_Str_t * vStr;
678  Scl_Item_t * pCell, * pOutput, * pInput;
679  char * pFormula;
680  vStr = Vec_StrAlloc( 1000 );
681  Vec_StrPrintStr( vStr, "GATE _const0_ 0.000000 z=CONST0;\n" );
682  Vec_StrPrintStr( vStr, "GATE _const1_ 0.000000 z=CONST1;\n" );
683  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
684  {
685  if ( Scl_LibertyReadCellIsFlop(p, pCell) )
686  {
687  if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped sequential cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
688  continue;
689  }
690  if ( Scl_LibertyReadCellIsThreeState(p, pCell) )
691  {
692  if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
693  continue;
694  }
695  if ( Scl_LibertyReadCellOutputNum(p, pCell) == 0 )
696  {
697  if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" without logic function.\n", Scl_LibertyReadString(p, pCell->Head) );
698  continue;
699  }
700  // iterate through output pins
701  Scl_ItemForEachChildName( p, pCell, pOutput, "pin" )
702  {
703  if ( (pFormula = Scl_LibertyReadPinFormula(p, pOutput)) )
704  continue;
705  if ( !strcmp(pFormula, "0") || !strcmp(pFormula, "1") )
706  {
707  if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Scl_LibertyReadString(p, pCell->Head), pFormula );
708  break;
709  }
710  Vec_StrPrintStr( vStr, "GATE " );
711  Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pCell->Head) );
712  Vec_StrPrintStr( vStr, " " );
713  Vec_StrPrintStr( vStr, Scl_LibertyReadCellArea(p, pCell) );
714  Vec_StrPrintStr( vStr, " " );
715  Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pOutput->Head) );
716  Vec_StrPrintStr( vStr, "=" );
717  Vec_StrPrintStr( vStr, pFormula );
718  Vec_StrPrintStr( vStr, ";\n" );
719  // iterate through input pins
720  Scl_ItemForEachChildName( p, pCell, pInput, "pin" )
721  {
722  if ( Scl_LibertyReadPinFormula(p, pInput) == NULL )
723  continue;
724  Vec_StrPrintStr( vStr, " PIN " );
725  Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pInput->Head) );
726  Vec_StrPrintStr( vStr, " UNKNOWN 1 999 1.00 0.00 1.00 0.00\n" );
727  }
728  }
729  }
730  Vec_StrPrintStr( vStr, "\n.end\n" );
731  Vec_StrPush( vStr, '\0' );
732 // printf( "%s", Vec_StrArray(vStr) );
733  return vStr;
734 }
735 Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose )
736 {
737  Scl_Tree_t * p;
738  Vec_Str_t * vStr;
739  p = Scl_LibertyParse( pFileName, fVerbose );
740  if ( p == NULL )
741  return NULL;
742 // Scl_LibertyRead( p, "temp_.lib" );
743  vStr = Scl_LibertyReadGenlibStr( p, fVerbose );
744  Scl_LibertyStop( p, fVerbose );
745 // Scl_LibertyStringDump( "test_genlib.lib", vStr );
746  return vStr;
747 }
748 
749 
750 /**Function*************************************************************
751 
752  Synopsis [Enabling debug output.]
753 
754  Description []
755 
756  SideEffects []
757 
758  SeeAlso []
759 
760 ***********************************************************************/
761 //#define SCL_DEBUG
762 #ifdef SCL_DEBUG
763 static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); }
764 static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); }
765 static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); }
766 static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); }
767 static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); }
768 #else
769 static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); }
770 static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { Vec_StrPutW( vOut, Val ); }
771 static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { Vec_StrPutF( vOut, Val ); }
772 static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { Vec_StrPutS( vOut, Val ); }
773 static inline void Vec_StrPut_( Vec_Str_t * vOut ) { }
774 #endif
775 
776 /**Function*************************************************************
777 
778  Synopsis [Parsing Liberty into internal data representation.]
779 
780  Description []
781 
782  SideEffects []
783 
784  SeeAlso []
785 
786 ***********************************************************************/
788 {
789  Scl_Item_t * pItem;
790  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_wire_load" )
791  return Scl_LibertyReadString(p, pItem->Head);
792  return "";
793 }
795 {
796  Scl_Item_t * pItem;
797  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_wire_load_selection" )
798  return Scl_LibertyReadString(p, pItem->Head);
799  return "";
800 }
802 {
803  Scl_Item_t * pItem;
804  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_max_transition" )
805  return atof(Scl_LibertyReadString(p, pItem->Head));
806  return 0;
807 }
809 {
810  Scl_Item_t * pItem;
811  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "time_unit" )
812  {
813  char * pUnit = Scl_LibertyReadString(p, pItem->Head);
814  // 9=1ns, 10=100ps, 11=10ps, 12=1ps
815  if ( !strcmp(pUnit, "1ns") )
816  return 9;
817  if ( !strcmp(pUnit, "100ps") )
818  return 10;
819  if ( !strcmp(pUnit, "10ps") )
820  return 11;
821  if ( !strcmp(pUnit, "1ps") )
822  return 12;
823  break;
824  }
825  printf( "Libery parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" );
826  return 9;
827 }
829 {
830  Scl_Item_t * pItem;
831  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "capacitive_load_unit" )
832  {
833  // expecting (1.00,ff) or (1, pf) ... 12 or 15 for 'pf' or 'ff'
834  char * pHead = Scl_LibertyReadString(p, pItem->Head);
835  float First = atof(strtok(pHead, " \t\n\r\\\","));
836  char * pSecond = strtok(NULL, " \t\n\r\\\",");
837  Vec_StrPutF_( vOut, First );
838  if ( pSecond && !strcmp(pSecond, "pf") )
839  Vec_StrPutI_( vOut, 12 );
840  else if ( pSecond && !strcmp(pSecond, "ff") )
841  Vec_StrPutI_( vOut, 15 );
842  else break;
843  return;
844  }
845  printf( "Libery parser cannot read \"capacitive_load_unit\". Assuming capacitive_load_unit(1, pf).\n" );
846  Vec_StrPutF_( vOut, 1.0 );
847  Vec_StrPutI_( vOut, 12 );
848 }
850 {
851  Scl_Item_t * pItem, * pChild;
852  Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, Scl_LibertyRoot(p), "wire_load") );
853  Vec_StrPut_( vOut );
854  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load" )
855  {
856  Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) );
857  Scl_ItemForEachChildName( p, pItem, pChild, "capacitance" )
858  Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) );
859  Scl_ItemForEachChildName( p, pItem, pChild, "slope" )
860  Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) );
861  Vec_StrPut_( vOut );
862  Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "fanout_length") );
863  Vec_StrPut_( vOut );
864  Scl_ItemForEachChildName( p, pItem, pChild, "fanout_length" )
865  {
866  char * pHead = Scl_LibertyReadString(p, pChild->Head);
867  int First = atoi( strtok(pHead, " ,") );
868  float Second = atof( strtok(NULL, " ") );
869  Vec_StrPutI_( vOut, First );
870  Vec_StrPutF_( vOut, Second );
871  Vec_StrPut_( vOut );
872  }
873  Vec_StrPut_( vOut );
874  }
875  Vec_StrPut_( vOut );
876 }
878 {
879  Scl_Item_t * pItem, * pChild;
880  Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, Scl_LibertyRoot(p), "wire_load_selection") );
881  Vec_StrPut_( vOut );
882  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load_selection" )
883  {
884  Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) );
885  Vec_StrPut_( vOut );
886  Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "wire_load_from_area") );
887  Vec_StrPut_( vOut );
888  Scl_ItemForEachChildName( p, pItem, pChild, "wire_load_from_area" )
889  {
890  char * pHead = Scl_LibertyReadString(p, pChild->Head);
891  float First = atof( strtok(pHead, " ,") );
892  float Second = atof( strtok(NULL, " ,") );
893  char * pThird = strtok(NULL, " ");
894  if ( pThird[0] == '\"' )
895  assert(pThird[strlen(pThird)-1] == '\"'), pThird[strlen(pThird)-1] = 0, pThird++;
896  Vec_StrPutF_( vOut, First );
897  Vec_StrPutF_( vOut, Second );
898  Vec_StrPutS_( vOut, pThird );
899  Vec_StrPut_( vOut );
900  }
901  Vec_StrPut_( vOut );
902  }
903  Vec_StrPut_( vOut );
904 }
906 {
907  Scl_Item_t * pItem;
908  Scl_ItemForEachChildName( p, pCell, pItem, "drive_strength" )
909  return atoi(Scl_LibertyReadString(p, pItem->Head));
910  return 0;
911 }
913 {
914  Scl_Item_t * pItem;
915  Scl_ItemForEachChildName( p, pPin, pItem, "direction" )
916  {
917  char * pToken = Scl_LibertyReadString(p, pItem->Head);
918  if ( !strcmp(pToken, "input") )
919  return 0;
920  if ( !strcmp(pToken, "output") )
921  return 1;
922  break;
923  }
924  return -1;
925 }
926 float Scl_LibertyReadPinCap( Scl_Tree_t * p, Scl_Item_t * pPin, char * pName )
927 {
928  Scl_Item_t * pItem;
929  Scl_ItemForEachChildName( p, pPin, pItem, pName )
930  return atof(Scl_LibertyReadString(p, pItem->Head));
931  return 0;
932 }
933 Scl_Item_t * Scl_LibertyReadPinTiming( Scl_Tree_t * p, Scl_Item_t * pPinOut, char * pNameIn )
934 {
935  Scl_Item_t * pTiming, * pPinIn;
936  Scl_ItemForEachChildName( p, pPinOut, pTiming, "timing" )
937  Scl_ItemForEachChildName( p, pTiming, pPinIn, "related_pin" )
938  if ( !strcmp(Scl_LibertyReadString(p, pPinIn->Head), pNameIn) )
939  return pTiming;
940  return NULL;
941 }
943 {
944  Vec_Ptr_t * vTimings;
945  Scl_Item_t * pTiming, * pPinIn;
946  vTimings = Vec_PtrAlloc( 16 );
947  Scl_ItemForEachChildName( p, pPinOut, pTiming, "timing" )
948  Scl_ItemForEachChildName( p, pTiming, pPinIn, "related_pin" )
949  if ( !strcmp(Scl_LibertyReadString(p, pPinIn->Head), pNameIn) )
950  Vec_PtrPush( vTimings, pTiming );
951  return vTimings;
952 }
954 {
955  Scl_Item_t * pItem;
956  Scl_ItemForEachChildName( p, pPin, pItem, "timing_sense" )
957  {
958  char * pToken = Scl_LibertyReadString(p, pItem->Head);
959  if ( !strcmp(pToken, "positive_unate") )
960  return sc_ts_Pos;
961  if ( !strcmp(pToken, "negative_unate") )
962  return sc_ts_Neg;
963  if ( !strcmp(pToken, "non_unate") )
964  return sc_ts_Non;
965  break;
966  }
967  return sc_ts_Non;
968 }
970 {
971  char * pToken;
972  Vec_Flt_t * vValues = Vec_FltAlloc( 100 );
973  for ( pToken = strtok(pName, " \t\n\r\\\","); pToken; pToken = strtok(NULL, " \t\n\r\\\",") )
974  Vec_FltPush( vValues, atof(pToken) );
975  return vValues;
976 }
977 
978 void Scl_LibertyDumpTables( Vec_Str_t * vOut, Vec_Flt_t * vInd1, Vec_Flt_t * vInd2, Vec_Flt_t * vValues )
979 {
980  int i; float Entry;
981  // write entries
982  Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
983  Vec_FltForEachEntry( vInd1, Entry, i )
984  Vec_StrPutF_( vOut, Entry );
985  Vec_StrPut_( vOut );
986  // write entries
987  Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
988  Vec_FltForEachEntry( vInd2, Entry, i )
989  Vec_StrPutF_( vOut, Entry );
990  Vec_StrPut_( vOut );
991  Vec_StrPut_( vOut );
992  // write entries
993  assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
994  Vec_FltForEachEntry( vValues, Entry, i )
995  {
996  Vec_StrPutF_( vOut, Entry );
997  if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
998  Vec_StrPut_( vOut );
999  }
1000  // dump approximations
1001  Vec_StrPut_( vOut );
1002  for ( i = 0; i < 3; i++ )
1003  Vec_StrPutF_( vOut, 0 );
1004  for ( i = 0; i < 4; i++ )
1005  Vec_StrPutF_( vOut, 0 );
1006  for ( i = 0; i < 6; i++ )
1007  Vec_StrPutF_( vOut, 0 );
1008  Vec_StrPut_( vOut );
1009  Vec_StrPut_( vOut );
1010 }
1011 int Scl_LibertyScanTable( Scl_Tree_t * p, Vec_Ptr_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
1012 {
1013  Vec_Flt_t * vIndex1 = NULL;
1014  Vec_Flt_t * vIndex2 = NULL;
1015  Vec_Flt_t * vValues = NULL;
1016  Vec_Flt_t * vInd1, * vInd2;
1017  Scl_Item_t * pItem, * pTable = NULL;
1018  char * pThis, * pTempl = NULL;
1019  int iPlace, i;
1020  float Entry;
1021  // find the table
1022  Scl_ItemForEachChildName( p, pTiming, pTable, pName )
1023  break;
1024  if ( pTable == NULL )
1025  return 0;
1026  // find the template
1027  pTempl = Scl_LibertyReadString(p, pTable->Head);
1028  if ( pTempl == NULL || pTempl[0] == 0 )
1029  {
1030  // read the numbers
1031  Scl_ItemForEachChild( p, pTable, pItem )
1032  {
1033  if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1034  assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1035  else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1036  assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1037  else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1038  assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1039  }
1040  if ( vIndex1 == NULL || vIndex2 == NULL || vValues == NULL )
1041  { printf( "Incomplete table specification\n" ); return 0; }
1042  // dump the table
1043  vInd1 = vIndex1;
1044  vInd2 = vIndex2;
1045  // write entries
1046  Vec_PtrPush( vOut, vInd1 );
1047  Vec_PtrPush( vOut, vInd2 );
1048  Vec_PtrPush( vOut, vValues );
1049  }
1050  else if ( !strcmp(pTempl, "scalar") )
1051  {
1052  Scl_ItemForEachChild( p, pTable, pItem )
1053  if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1054  {
1055  assert(vValues == NULL);
1056  vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1057  assert( Vec_FltSize(vValues) == 1 );
1058  // write entries
1059  Vec_PtrPush( vOut, Vec_IntStart(1) );
1060  Vec_PtrPush( vOut, Vec_IntStart(1) );
1061  Vec_PtrPush( vOut, vValues );
1062  break;
1063  }
1064  else
1065  { printf( "Cannot read \"scalar\" template\n" ); return 0; }
1066  }
1067  else
1068  {
1069  // fetch the template
1070  iPlace = -1;
1071  Vec_PtrForEachEntry( char *, vTemples, pThis, i )
1072  if ( i % 4 == 0 && !strcmp(pTempl, pThis) )
1073  {
1074  iPlace = i;
1075  break;
1076  }
1077  if ( iPlace == -1 )
1078  { printf( "Template cannot be found in the template library\n" ); return 0; }
1079  // read the numbers
1080  Scl_ItemForEachChild( p, pTable, pItem )
1081  {
1082  if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1083  assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1084  else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1085  assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1086  else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1087  assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1088  }
1089  // check the template style
1090  vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
1091  vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
1092  if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
1093  {
1094  assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
1095  assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd2) );
1096  vInd1 = vIndex1 ? vIndex1 : vInd1;
1097  vInd2 = vIndex2 ? vIndex2 : vInd2;
1098  // write entries
1099  Vec_PtrPush( vOut, Vec_FltDup(vInd1) );
1100  Vec_PtrPush( vOut, Vec_FltDup(vInd2) );
1101  Vec_PtrPush( vOut, Vec_FltDup(vValues) );
1102  }
1103  else // reverse order (vIndex2 is slew; vIndex1 is load)
1104  {
1105  Vec_Flt_t * vValues2 = Vec_FltAlloc( Vec_FltSize(vValues) );
1106  assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd1) );
1107  assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd2) );
1108  vInd1 = vIndex2 ? vIndex2 : vInd1;
1109  vInd2 = vIndex1 ? vIndex1 : vInd2;
1110  // write entries -- transpose
1111  assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1112  Vec_FltForEachEntry( vValues, Entry, i )
1113  {
1114  int x = i % Vec_FltSize(vInd2);
1115  int y = i / Vec_FltSize(vInd2);
1116  Entry = Vec_FltEntry( vValues, x * Vec_FltSize(vInd1) + y );
1117  Vec_FltPush( vValues2, Entry );
1118  }
1119  assert( Vec_FltSize(vValues) == Vec_FltSize(vValues2) );
1120  // write entries
1121  Vec_PtrPush( vOut, Vec_FltDup(vInd1) );
1122  Vec_PtrPush( vOut, Vec_FltDup(vInd2) );
1123  Vec_PtrPush( vOut, vValues2 );
1124  }
1125  Vec_FltFreeP( &vIndex1 );
1126  Vec_FltFreeP( &vIndex2 );
1127  Vec_FltFreeP( &vValues );
1128  }
1129  return 1;
1130 }
1131 int Scl_LibertyComputeWorstCase( Vec_Ptr_t * vTables, Vec_Flt_t ** pvInd0, Vec_Flt_t ** pvInd1, Vec_Flt_t ** pvValues )
1132 {
1133  Vec_Flt_t * vInd0, * vInd1, * vValues;
1134  Vec_Flt_t * vind0, * vind1, * vvalues;
1135  int i, k, nTriples = Vec_PtrSize(vTables) / 3;
1136  float Entry;
1137  assert( Vec_PtrSize(vTables) > 0 && Vec_PtrSize(vTables) % 3 == 0 );
1138  if ( nTriples == 1 )
1139  {
1140  *pvInd0 = (Vec_Flt_t *)Vec_PtrEntry(vTables, 0);
1141  *pvInd1 = (Vec_Flt_t *)Vec_PtrEntry(vTables, 1);
1142  *pvValues = (Vec_Flt_t *)Vec_PtrEntry(vTables, 2);
1143  Vec_PtrShrink( vTables, 0 );
1144  return 1;
1145  }
1146  vInd0 = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 0) );
1147  vInd1 = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 1) );
1148  vValues = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 2) );
1149  for ( i = 1; i < nTriples; i++ )
1150  {
1151  vind0 = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+0);
1152  vind1 = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+1);
1153  vvalues = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+2);
1154  // check equality of indexes
1155  if ( !Vec_FltEqual(vind0, vInd0) )
1156  continue;//return 0;
1157  if ( !Vec_FltEqual(vind1, vInd1) )
1158  continue;//return 0;
1159 // Vec_FltForEachEntry( vvalues, Entry, k )
1160 // Vec_FltAddToEntry( vValues, k, Entry );
1161  Vec_FltForEachEntry( vvalues, Entry, k )
1162  if ( Vec_FltEntry(vValues, k) < Entry )
1163  Vec_FltWriteEntry( vValues, k, Entry );
1164  }
1165 // Vec_FltForEachEntry( vValues, Entry, k )
1166 // Vec_FltWriteEntry( vValues, k, Entry/nTriples );
1167  // return the result
1168  *pvInd0 = vInd0;
1169  *pvInd1 = vInd1;
1170  *pvValues = vValues;
1171  return 1;
1172 }
1173 
1174 int Scl_LibertyReadTable( Scl_Tree_t * p, Vec_Str_t * vOut, Scl_Item_t * pTiming, char * pName, Vec_Ptr_t * vTemples )
1175 {
1176  Vec_Flt_t * vIndex1 = NULL;
1177  Vec_Flt_t * vIndex2 = NULL;
1178  Vec_Flt_t * vValues = NULL;
1179  Vec_Flt_t * vInd1, * vInd2;
1180  Scl_Item_t * pItem, * pTable = NULL;
1181  char * pThis, * pTempl = NULL;
1182  int iPlace, i;
1183  float Entry;
1184  // find the table
1185  Scl_ItemForEachChildName( p, pTiming, pTable, pName )
1186  break;
1187  if ( pTable == NULL )
1188  return 0;
1189  // find the template
1190  pTempl = Scl_LibertyReadString(p, pTable->Head);
1191  if ( pTempl == NULL || pTempl[0] == 0 )
1192  {
1193  // read the numbers
1194  Scl_ItemForEachChild( p, pTable, pItem )
1195  {
1196  if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1197  assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1198  else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1199  assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1200  else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1201  assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1202  }
1203  if ( vIndex1 == NULL || vIndex2 == NULL || vValues == NULL )
1204  { printf( "Incomplete table specification\n" ); return 0; }
1205  // dump the table
1206  vInd1 = vIndex1;
1207  vInd2 = vIndex2;
1208  // write entries
1209  Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1210  Vec_FltForEachEntry( vInd1, Entry, i )
1211  Vec_StrPutF_( vOut, Entry );
1212  Vec_StrPut_( vOut );
1213  // write entries
1214  Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1215  Vec_FltForEachEntry( vInd2, Entry, i )
1216  Vec_StrPutF_( vOut, Entry );
1217  Vec_StrPut_( vOut );
1218  Vec_StrPut_( vOut );
1219  // write entries
1220  assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1221  Vec_FltForEachEntry( vValues, Entry, i )
1222  {
1223  Vec_StrPutF_( vOut, Entry );
1224  if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1225  Vec_StrPut_( vOut );
1226  }
1227  }
1228  else
1229  {
1230  // fetch the template
1231  iPlace = -1;
1232  Vec_PtrForEachEntry( char *, vTemples, pThis, i )
1233  if ( i % 4 == 0 && !strcmp(pTempl, pThis) )
1234  {
1235  iPlace = i;
1236  break;
1237  }
1238  if ( iPlace == -1 )
1239  { printf( "Template cannot be found in the template library\n" ); return 0; }
1240  // read the numbers
1241  Scl_ItemForEachChild( p, pTable, pItem )
1242  {
1243  if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1244  assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1245  else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1246  assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1247  else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1248  assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1249  }
1250  // check the template style
1251  vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
1252  vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
1253  if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
1254  {
1255  assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
1256  assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd2) );
1257  vInd1 = vIndex1 ? vIndex1 : vInd1;
1258  vInd2 = vIndex2 ? vIndex2 : vInd2;
1259  // write entries
1260  Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1261  Vec_FltForEachEntry( vInd1, Entry, i )
1262  Vec_StrPutF_( vOut, Entry );
1263  Vec_StrPut_( vOut );
1264  // write entries
1265  Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1266  Vec_FltForEachEntry( vInd2, Entry, i )
1267  Vec_StrPutF_( vOut, Entry );
1268  Vec_StrPut_( vOut );
1269  Vec_StrPut_( vOut );
1270  // write entries
1271  assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1272  Vec_FltForEachEntry( vValues, Entry, i )
1273  {
1274  Vec_StrPutF_( vOut, Entry );
1275  if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1276  Vec_StrPut_( vOut );
1277  }
1278  }
1279  else // reverse order (vIndex2 is slew; vIndex1 is load)
1280  {
1281  assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd1) );
1282  assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd2) );
1283  vInd1 = vIndex2 ? vIndex2 : vInd1;
1284  vInd2 = vIndex1 ? vIndex1 : vInd2;
1285  // write entries
1286  Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1287  Vec_FltForEachEntry( vInd1, Entry, i )
1288  Vec_StrPutF_( vOut, Entry );
1289  Vec_StrPut_( vOut );
1290  // write entries
1291  Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1292  Vec_FltForEachEntry( vInd2, Entry, i )
1293  Vec_StrPutF_( vOut, Entry );
1294  Vec_StrPut_( vOut );
1295  Vec_StrPut_( vOut );
1296  // write entries -- transpose
1297  assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1298  Vec_FltForEachEntry( vValues, Entry, i )
1299  {
1300  int x = i % Vec_FltSize(vInd2);
1301  int y = i / Vec_FltSize(vInd2);
1302  Entry = Vec_FltEntry( vValues, x * Vec_FltSize(vInd1) + y );
1303  Vec_StrPutF_( vOut, Entry );
1304  if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1305  Vec_StrPut_( vOut );
1306  }
1307  }
1308  }
1309  Vec_StrPut_( vOut );
1310  for ( i = 0; i < 3; i++ )
1311  Vec_StrPutF_( vOut, 0 );
1312  for ( i = 0; i < 4; i++ )
1313  Vec_StrPutF_( vOut, 0 );
1314  for ( i = 0; i < 6; i++ )
1315  Vec_StrPutF_( vOut, 0 );
1316  Vec_FltFreeP( &vIndex1 );
1317  Vec_FltFreeP( &vIndex2 );
1318  Vec_FltFreeP( &vValues );
1319  Vec_StrPut_( vOut );
1320  Vec_StrPut_( vOut );
1321  return 1;
1322 }
1324 {
1325  Vec_Flt_t * vArray; int i;
1326  assert( Vec_PtrSize(vRes) % 4 == 0 );
1327  printf( "There are %d slew/load templates\n", Vec_PtrSize(vRes) % 4 );
1328  Vec_PtrForEachEntry( Vec_Flt_t *, vRes, vArray, i )
1329  {
1330  if ( i % 4 == 0 )
1331  printf( "%s\n", (char *)vArray );
1332  else if ( i % 4 == 1 )
1333  printf( "%d\n", (int)(vArray != NULL) );
1334  else if ( i % 4 == 2 || i % 4 == 3 )
1335  Vec_FltPrint( vArray );
1336  if ( i % 4 == 3 )
1337  printf( "\n" );
1338  }
1339 }
1341 {
1342  Vec_Ptr_t * vRes = NULL;
1343  Vec_Flt_t * vIndex1, * vIndex2;
1344  Scl_Item_t * pTempl, * pItem;
1345  char * pVar1, * pVar2;
1346  int fFlag0, fFlag1;
1347  vRes = Vec_PtrAlloc( 100 );
1348  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pTempl, "lu_table_template" )
1349  {
1350  pVar1 = pVar2 = NULL;
1351  vIndex1 = vIndex2 = NULL;
1352  Scl_ItemForEachChild( p, pTempl, pItem )
1353  {
1354  if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1355  assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1356  else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1357  assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1358  else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_1") )
1359  assert(pVar1 == NULL), pVar1 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
1360  else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_2") )
1361  assert(pVar2 == NULL), pVar2 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
1362  }
1363  if ( pVar1 == NULL || pVar2 == NULL )
1364  {
1365  ABC_FREE( pVar1 );
1366  ABC_FREE( pVar2 );
1367  Vec_FltFreeP( &vIndex1 );
1368  Vec_FltFreeP( &vIndex2 );
1369  continue;
1370  }
1371  assert( pVar1 != NULL && pVar2 != NULL );
1372  fFlag0 = (!strcmp(pVar1, "input_net_transition") && !strcmp(pVar2, "total_output_net_capacitance"));
1373  fFlag1 = (!strcmp(pVar2, "input_net_transition") && !strcmp(pVar1, "total_output_net_capacitance"));
1374  ABC_FREE( pVar1 );
1375  ABC_FREE( pVar2 );
1376  if ( !fFlag0 && !fFlag1 )
1377  {
1378  Vec_FltFreeP( &vIndex1 );
1379  Vec_FltFreeP( &vIndex2 );
1380  continue;
1381  }
1382  Vec_PtrPush( vRes, Abc_UtilStrsav( Scl_LibertyReadString(p, pTempl->Head) ) );
1383  Vec_PtrPush( vRes, fFlag0 ? NULL : (void *)(ABC_PTRINT_T)1 );
1384  Vec_PtrPush( vRes, fFlag0 ? vIndex1 : vIndex2 );
1385  Vec_PtrPush( vRes, fFlag0 ? vIndex2 : vIndex1 );
1386  }
1387  if ( Vec_PtrSize(vRes) == 0 )
1388  Abc_Print( 0, "Templates are not defined.\n" );
1389  // print templates
1390 // printf( "Found %d templates\n", Vec_PtrSize(vRes)/4 );
1391 // Scl_LibertyPrintTemplates( vRes );
1392  return vRes;
1393 }
1394 Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbose )
1395 {
1396  int fUseFirstTable = 0;
1397  Vec_Str_t * vOut;
1398  Vec_Ptr_t * vNameIns, * vTemples = NULL;
1399  Scl_Item_t * pCell, * pPin, * pTiming;
1400  Vec_Wrd_t * vTruth;
1401  char * pFormula, * pName;
1402  int i, k, Counter, nOutputs, nCells;
1403  int nSkipped[3] = {0};
1404 
1405  // read delay-table templates
1406  vTemples = Scl_LibertyReadTemplates( p );
1407 
1408  // start the library
1409  vOut = Vec_StrAlloc( 10000 );
1411 
1412  // top level information
1413  Vec_StrPut_( vOut );
1414  Vec_StrPutS_( vOut, Scl_LibertyReadString(p, Scl_LibertyRoot(p)->Head) );
1419  Scl_LibertyReadLoadUnit( p, vOut );
1420  Vec_StrPut_( vOut );
1421  Vec_StrPut_( vOut );
1422 
1423  // read wire loads
1424  Scl_LibertyReadWireLoad( p, vOut );
1425  Scl_LibertyReadWireLoadSelect( p, vOut );
1426 
1427  // count cells
1428  nCells = 0;
1429  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
1430  {
1431  if ( Scl_LibertyReadCellIsFlop(p, pCell) )
1432  {
1433  if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped sequential cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
1434  nSkipped[0]++;
1435  continue;
1436  }
1437  if ( Scl_LibertyReadCellIsThreeState(p, pCell) )
1438  {
1439  if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
1440  nSkipped[1]++;
1441  continue;
1442  }
1443  if ( (Counter = Scl_LibertyReadCellOutputNum(p, pCell)) == 0 )
1444  {
1445  if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" without logic function.\n", Scl_LibertyReadString(p, pCell->Head) );
1446  nSkipped[2]++;
1447  continue;
1448  }
1449  nCells++;
1450  }
1451  // read cells
1452  Vec_StrPutI_( vOut, nCells );
1453  Vec_StrPut_( vOut );
1454  Vec_StrPut_( vOut );
1455  Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
1456  {
1457  if ( Scl_LibertyReadCellIsFlop(p, pCell) )
1458  continue;
1459  if ( Scl_LibertyReadCellIsThreeState(p, pCell) )
1460  continue;
1461  if ( (Counter = Scl_LibertyReadCellOutputNum(p, pCell)) == 0 )
1462  continue;
1463  // top level information
1464  Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pCell->Head) );
1465  pName = Scl_LibertyReadCellArea(p, pCell);
1466  Vec_StrPutF_( vOut, pName ? atof(pName) : 1 );
1467  pName = Scl_LibertyReadCellLeakage(p, pCell);
1468  Vec_StrPutF_( vOut, pName ? atof(pName) : 0 );
1469  Vec_StrPutI_( vOut, Scl_LibertyReadDeriveStrength(p, pCell) );
1470  // pin count
1471  nOutputs = Scl_LibertyReadCellOutputNum( p, pCell );
1472  Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pCell, "pin") - nOutputs );
1473  Vec_StrPutI_( vOut, nOutputs );
1474  Vec_StrPut_( vOut );
1475  Vec_StrPut_( vOut );
1476 
1477  // input pins
1478  vNameIns = Vec_PtrAlloc( 16 );
1479  Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
1480  {
1481  float CapOne, CapRise, CapFall;
1482  if ( Scl_LibertyReadPinFormula(p, pPin) != NULL ) // skip output pin
1483  continue;
1484  assert( Scl_LibertyReadPinDirection(p, pPin) == 0 );
1485  pName = Scl_LibertyReadString(p, pPin->Head);
1486  Vec_PtrPush( vNameIns, Abc_UtilStrsav(pName) );
1487  Vec_StrPutS_( vOut, pName );
1488  CapOne = Scl_LibertyReadPinCap( p, pPin, "capacitance" );
1489  CapRise = Scl_LibertyReadPinCap( p, pPin, "rise_capacitance" );
1490  CapFall = Scl_LibertyReadPinCap( p, pPin, "fall_capacitance" );
1491  if ( CapRise == 0 )
1492  CapRise = CapOne;
1493  if ( CapFall == 0 )
1494  CapFall = CapOne;
1495  Vec_StrPutF_( vOut, CapRise );
1496  Vec_StrPutF_( vOut, CapFall );
1497  Vec_StrPut_( vOut );
1498  }
1499  Vec_StrPut_( vOut );
1500  // output pins
1501  Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
1502  {
1503  if ( !Scl_LibertyReadPinFormula(p, pPin) ) // skip input pin
1504  continue;
1505  assert( Scl_LibertyReadPinDirection(p, pPin) == 1 );
1506  pName = Scl_LibertyReadString(p, pPin->Head);
1507  Vec_StrPutS_( vOut, pName );
1508  Vec_StrPutF_( vOut, Scl_LibertyReadPinCap( p, pPin, "max_capacitance" ) );
1509  Vec_StrPutF_( vOut, Scl_LibertyReadPinCap( p, pPin, "max_transition" ) );
1510  Vec_StrPutI_( vOut, Vec_PtrSize(vNameIns) );
1511  pFormula = Scl_LibertyReadPinFormula(p, pPin);
1512  Vec_StrPutS_( vOut, pFormula );
1513  // write truth table
1514  vTruth = Mio_ParseFormulaTruth( pFormula, (char **)Vec_PtrArray(vNameIns), Vec_PtrSize(vNameIns) );
1515  for ( i = 0; i < Abc_Truth6WordNum(Vec_PtrSize(vNameIns)); i++ )
1516  Vec_StrPutW_( vOut, Vec_WrdEntry(vTruth, i) );
1517  Vec_WrdFree( vTruth );
1518  Vec_StrPut_( vOut );
1519  Vec_StrPut_( vOut );
1520 
1521  // write the delay tables
1522  if ( fUseFirstTable )
1523  {
1524  Vec_PtrForEachEntry( char *, vNameIns, pName, i )
1525  {
1526  pTiming = Scl_LibertyReadPinTiming( p, pPin, pName );
1527  Vec_StrPutS_( vOut, pName );
1528  Vec_StrPutI_( vOut, (int)(pTiming != NULL) );
1529  if ( pTiming == NULL ) // output does not depend on input
1530  continue;
1531  Vec_StrPutI_( vOut, Scl_LibertyReadTimingSense(p, pTiming) );
1532  Vec_StrPut_( vOut );
1533  Vec_StrPut_( vOut );
1534  // some cells only have 'rise' or 'fall' but not both - here we work around this
1535  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_rise", vTemples ) )
1536  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_fall", vTemples ) )
1537  { printf( "Table cannot be found\n" ); return NULL; }
1538  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_fall", vTemples ) )
1539  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_rise", vTemples ) )
1540  { printf( "Table cannot be found\n" ); return NULL; }
1541  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
1542  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
1543  { printf( "Table cannot be found\n" ); return NULL; }
1544  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
1545  if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
1546  { printf( "Table cannot be found\n" ); return NULL; }
1547  }
1548  continue;
1549  }
1550 
1551  // write the timing tables
1552  Vec_PtrForEachEntry( char *, vNameIns, pName, i )
1553  {
1554  Vec_Ptr_t * vTables[4];
1555  Vec_Ptr_t * vTimings;
1556  vTimings = Scl_LibertyReadPinTimingAll( p, pPin, pName );
1557  Vec_StrPutS_( vOut, pName );
1558  Vec_StrPutI_( vOut, (int)(Vec_PtrSize(vTimings) != 0) );
1559  if ( Vec_PtrSize(vTimings) == 0 ) // output does not depend on input
1560  {
1561  Vec_PtrFree( vTimings );
1562  continue;
1563  }
1564  Vec_StrPutI_( vOut, Scl_LibertyReadTimingSense(p, (Scl_Item_t *)Vec_PtrEntry(vTimings, 0)) );
1565  Vec_StrPut_( vOut );
1566  Vec_StrPut_( vOut );
1567  // collect the timing tables
1568  for ( k = 0; k < 4; k++ )
1569  vTables[k] = Vec_PtrAlloc( 16 );
1570  Vec_PtrForEachEntry( Scl_Item_t *, vTimings, pTiming, k )
1571  {
1572  // some cells only have 'rise' or 'fall' but not both - here we work around this
1573  if ( !Scl_LibertyScanTable( p, vTables[0], pTiming, "cell_rise", vTemples ) )
1574  if ( !Scl_LibertyScanTable( p, vTables[0], pTiming, "cell_fall", vTemples ) )
1575  { printf( "Table cannot be found\n" ); return NULL; }
1576  if ( !Scl_LibertyScanTable( p, vTables[1], pTiming, "cell_fall", vTemples ) )
1577  if ( !Scl_LibertyScanTable( p, vTables[1], pTiming, "cell_rise", vTemples ) )
1578  { printf( "Table cannot be found\n" ); return NULL; }
1579  if ( !Scl_LibertyScanTable( p, vTables[2], pTiming, "rise_transition", vTemples ) )
1580  if ( !Scl_LibertyScanTable( p, vTables[2], pTiming, "fall_transition", vTemples ) )
1581  { printf( "Table cannot be found\n" ); return NULL; }
1582  if ( !Scl_LibertyScanTable( p, vTables[3], pTiming, "fall_transition", vTemples ) )
1583  if ( !Scl_LibertyScanTable( p, vTables[3], pTiming, "rise_transition", vTemples ) )
1584  { printf( "Table cannot be found\n" ); return NULL; }
1585  }
1586  Vec_PtrFree( vTimings );
1587  // compute worse case of the tables
1588  for ( k = 0; k < 4; k++ )
1589  {
1590  Vec_Flt_t * vInd0, * vInd1, * vValues;
1591  if ( !Scl_LibertyComputeWorstCase( vTables[k], &vInd0, &vInd1, &vValues ) )
1592  { printf( "Table indexes have different values\n" ); return NULL; }
1593  Vec_VecFree( (Vec_Vec_t *)vTables[k] );
1594  Scl_LibertyDumpTables( vOut, vInd0, vInd1, vValues );
1595  Vec_FltFree( vInd0 );
1596  Vec_FltFree( vInd1 );
1597  Vec_FltFree( vValues );
1598  }
1599  }
1600  }
1601  Vec_StrPut_( vOut );
1602  Vec_PtrFreeFree( vNameIns );
1603  }
1604  // free templates
1605  if ( vTemples )
1606  {
1607  Vec_Flt_t * vArray;
1608  assert( Vec_PtrSize(vTemples) % 4 == 0 );
1609  Vec_PtrForEachEntry( Vec_Flt_t *, vTemples, vArray, i )
1610  if ( i % 4 == 0 )
1611  ABC_FREE( vArray );
1612  else if ( i % 4 == 2 || i % 4 == 3 )
1613  Vec_FltFree( vArray );
1614  Vec_PtrFree( vTemples );
1615  }
1616  if ( fVerbose )
1617  {
1618  printf( "Library \"%s\" from \"%s\" has %d cells ",
1619  Scl_LibertyReadString(p, Scl_LibertyRoot(p)->Head), p->pFileName, nCells );
1620  printf( "(%d skipped: %d seq; %d tri-state; %d no func). ",
1621  nSkipped[0]+nSkipped[1]+nSkipped[2], nSkipped[0], nSkipped[1], nSkipped[2] );
1622  Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
1623  }
1624  return vOut;
1625 }
1626 SC_Lib * Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose )
1627 {
1628  SC_Lib * pLib;
1629  Scl_Tree_t * p;
1630  Vec_Str_t * vStr;
1631  p = Scl_LibertyParse( pFileName, fVeryVerbose );
1632  if ( p == NULL )
1633  return NULL;
1634 // Scl_LibertyParseDump( p, "temp_.lib" );
1635  // collect relevant data
1636  vStr = Scl_LibertyReadSclStr( p, fVerbose, fVeryVerbose );
1637  Scl_LibertyStop( p, fVeryVerbose );
1638  if ( vStr == NULL )
1639  return NULL;
1640  // construct SCL data-structure
1641  pLib = Abc_SclReadFromStr( vStr );
1642  if ( pLib == NULL )
1643  return NULL;
1644  pLib->pFileName = Abc_UtilStrsav( pFileName );
1645  Abc_SclLibNormalize( pLib );
1646  Vec_StrFree( vStr );
1647 // printf( "Average slew = %.2f ps\n", Abc_SclComputeAverageSlew(pLib) );
1648  return pLib;
1649 }
1650 
1651 /**Function*************************************************************
1652 
1653  Synopsis [Experiments with Liberty parsing.]
1654 
1655  Description []
1656 
1657  SideEffects []
1658 
1659  SeeAlso []
1660 
1661 ***********************************************************************/
1663 {
1664  char * pFileName = "bwrc.lib";
1665  int fVerbose = 1;
1666  int fVeryVerbose = 0;
1667  Scl_Tree_t * p;
1668  Vec_Str_t * vStr;
1669 // return;
1670  p = Scl_LibertyParse( pFileName, fVeryVerbose );
1671  if ( p == NULL )
1672  return;
1673 // Scl_LibertyParseDump( p, "temp_.lib" );
1674  vStr = Scl_LibertyReadSclStr( p, fVerbose, fVeryVerbose );
1675  Scl_LibertyStringDump( "test_scl.lib", vStr );
1676  Vec_StrFree( vStr );
1677  Scl_LibertyStop( p, fVerbose );
1678 }
1679 
1680 ////////////////////////////////////////////////////////////////////////
1681 /// END OF FILE ///
1682 ////////////////////////////////////////////////////////////////////////
1683 
1684 
1686 
char * memset()
static Scl_Item_t * Scl_LibertyRoot(Scl_Tree_t *p)
Definition: sclLiberty.c:75
void Scl_LibertyReadWireLoadSelect(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition: sclLiberty.c:877
int Scl_LibertyCountItems(char *pBeg, char *pEnd)
Definition: sclLiberty.c:168
VOID_HACK exit()
int nItermAlloc
Definition: sclLiberty.c:69
int Scl_LibertyReadTable(Scl_Tree_t *p, Vec_Str_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
Definition: sclLiberty.c:1174
static int Scl_LibertyCompare(Scl_Tree_t *p, Scl_Pair_t Pair, char *pStr)
Definition: sclLiberty.c:77
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecFlt.h:54
static void Vec_StrPutI_(Vec_Str_t *vOut, int Val)
Definition: sclLiberty.c:769
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
static void Vec_StrPutW_(Vec_Str_t *vOut, word Val)
Definition: sclLiberty.c:770
abctime clkStart
Definition: sclLiberty.c:72
void Scl_LibertyFixFileName(char *pFileName)
Definition: sclLiberty.c:481
int Scl_LibertyReadDeriveStrength(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:905
static void Vec_FltWriteEntry(Vec_Flt_t *p, int i, float Entry)
Definition: vecFlt.h:364
static Vec_Flt_t * Vec_FltDup(Vec_Flt_t *pVec)
Definition: vecFlt.h:172
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition: vecVec.h:42
char * pFileName
Definition: sclLib.h:205
static int Scl_LibertyItemId(Scl_Tree_t *p, Scl_Item_t *pItem)
Definition: sclLiberty.c:80
static Llb_Mgr_t * p
Definition: llb3Image.c:950
static void Vec_StrPutW(Vec_Str_t *vOut, word Val)
Definition: vecStr.h:846
void Scl_LibertyTest()
Definition: sclLiberty.c:1662
static char * Vec_StrArray(Vec_Str_t *p)
Definition: vecStr.h:272
void Scl_LibertyPrintTemplates(Vec_Ptr_t *vRes)
Definition: sclLiberty.c:1323
char * Scl_LibertyReadCellArea(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:615
char * pFileName
Definition: sclLiberty.c:64
char * strncpy()
static int Abc_Truth6WordNum(int nVars)
Definition: abc_global.h:257
#define SEEK_END
Definition: zconf.h:392
static void Vec_FltFree(Vec_Flt_t *p)
Definition: vecFlt.h:218
static void Vec_PtrFreeFree(Vec_Ptr_t *p)
Definition: vecPtr.h:569
Vec_Str_t * Scl_LibertyReadSclStr(Scl_Tree_t *p, int fVerbose, int fVeryVerbose)
Definition: sclLiberty.c:1394
Vec_Wrd_t * Mio_ParseFormulaTruth(char *pFormInit, char **ppVarNames, int nVars)
Definition: mioParse.c:396
char * strtok()
Scl_Tree_t * Scl_LibertyStart(char *pFileName)
Definition: sclLiberty.c:537
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
static Vec_Flt_t * Vec_FltAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecFlt.h:78
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
float Scl_LibertyReadPinCap(Scl_Tree_t *p, Scl_Item_t *pPin, char *pName)
Definition: sclLiberty.c:926
char * Scl_LibertyReadDefaultWireLoadSel(Scl_Tree_t *p)
Definition: sclLiberty.c:794
static Vec_Str_t * Vec_StrAlloc(int nCap)
Definition: bblif.c:495
Vec_Flt_t * Scl_LibertyReadFloatVec(char *pName)
Definition: sclLiberty.c:969
static abctime Abc_Clock()
Definition: abc_global.h:279
static void Vec_StrPush(Vec_Str_t *p, char Entry)
Definition: vecStr.h:535
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
static void Vec_VecFree(Vec_Vec_t *p)
Definition: vecVec.h:347
static void Vec_FltFreeP(Vec_Flt_t **p)
Definition: vecFlt.h:235
static void Vec_FltPush(Vec_Flt_t *p, float Entry)
Definition: vecFlt.h:528
Scl_Pair_t Body
Definition: sclLiberty.c:56
static int Vec_FltEqual(Vec_Flt_t *p1, Vec_Flt_t *p2)
Definition: vecFlt.h:701
int Scl_LibertyParseDump(Scl_Tree_t *p, char *pFileName)
Definition: sclLiberty.c:136
Scl_LibertyType_t
Definition: sclLiberty.c:35
int Scl_LibertyReadTimingSense(Scl_Tree_t *p, Scl_Item_t *pPin)
Definition: sclLiberty.c:953
int strcmp()
#define ABC_MAX_LIB_STR_LEN
DECLARATIONS ///.
Definition: sclLiberty.c:32
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
static void Vec_StrPutF_(Vec_Str_t *vOut, float Val)
Definition: sclLiberty.c:771
static void Vec_FltPrint(Vec_Flt_t *vVec)
Definition: vecFlt.h:723
static Vec_Int_t * Vec_IntStart(int nSize)
Definition: bblif.c:172
int Scl_LibertyReadCellIsThreeState(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:646
static void Scl_PrintWord(FILE *pFile, Scl_Tree_t *p, Scl_Pair_t Pair)
Definition: sclLiberty.c:78
int Scl_LibertyReadCellOutputNum(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:654
Vec_Str_t * Scl_LibertyParseGenlibStr(char *pFileName, int fVerbose)
Definition: sclLiberty.c:735
static void Vec_StrFree(Vec_Str_t *p)
Definition: bblif.c:616
SC_Lib * Abc_SclReadFromStr(Vec_Str_t *vOut)
Definition: sclLibScl.c:234
char * pContents
Definition: sclLiberty.c:65
void Scl_LibertyReadLoadUnit(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition: sclLiberty.c:828
Scl_Item_t * pItems
Definition: sclLiberty.c:70
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
void Scl_LibertyReadWireLoad(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition: sclLiberty.c:849
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static void Vec_WrdFree(Vec_Wrd_t *p)
Definition: vecWrd.h:260
static Scl_Pair_t Scl_LibertyUpdateHead(Scl_Tree_t *p, Scl_Pair_t Head)
Definition: sclLiberty.c:294
static void Vec_StrPutS_(Vec_Str_t *vOut, char *Val)
Definition: sclLiberty.c:772
static void Vec_StrPutS(Vec_Str_t *vOut, char *pStr)
Definition: vecStr.h:897
void Scl_LibertyWipeOutComments(char *pBeg, char *pEnd)
Definition: sclLiberty.c:191
int Scl_LibertyReadCellIsFlop(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:606
char * sprintf()
static int Counter
float Scl_LibertyReadDefaultMaxTrans(Scl_Tree_t *p)
Definition: sclLiberty.c:801
Vec_Ptr_t * Scl_LibertyReadTemplates(Scl_Tree_t *p)
Definition: sclLiberty.c:1340
#define Scl_ItemForEachChild(p, pItem, pChild)
Definition: sclLiberty.c:82
int nContents
Definition: sclLiberty.c:66
static void Abc_Print(int level, const char *format,...)
Definition: abc_global.h:313
void Scl_LibertyParseDumpItem(FILE *pFile, Scl_Tree_t *p, Scl_Item_t *pItem, int nOffset)
FUNCTION DEFINITIONS ///.
Definition: sclLiberty.c:102
static void Vec_StrPutF(Vec_Str_t *vOut, float Val)
Definition: vecStr.h:861
Scl_Item_t * Scl_LibertyReadPinTiming(Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
Definition: sclLiberty.c:933
double atof()
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define ABC_SCL_CUR_VERSION
INCLUDES ///.
Definition: sclLib.h:43
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
static int Vec_StrSize(Vec_Str_t *p)
Definition: bblif.c:600
int Scl_LibertyReadTimeUnit(Scl_Tree_t *p)
Definition: sclLiberty.c:808
char * pError
Definition: sclLiberty.c:71
int Scl_LibertyComputeWorstCase(Vec_Ptr_t *vTables, Vec_Flt_t **pvInd0, Vec_Flt_t **pvInd1, Vec_Flt_t **pvValues)
Definition: sclLiberty.c:1131
char * Scl_LibertyReadPinFormula(Scl_Tree_t *p, Scl_Item_t *pPin)
Definition: sclLiberty.c:639
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
int Scl_LibertyReadPinDirection(Scl_Tree_t *p, Scl_Item_t *pPin)
Definition: sclLiberty.c:912
Scl_Tree_t * Scl_LibertyParse(char *pFileName, int fVerbose)
Definition: sclLiberty.c:573
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ABC_PRT(a, t)
Definition: abc_global.h:220
void Scl_LibertyStringDump(char *pFileName, Vec_Str_t *vStr)
Definition: sclLiberty.c:513
int Scl_LibertyFileSize(char *pFileName)
Definition: sclLiberty.c:488
char * Scl_LibertyReadCellLeakage(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition: sclLiberty.c:622
static word Vec_WrdEntry(Vec_Wrd_t *p, int i)
Definition: vecWrd.h:384
static void Vec_StrPutI(Vec_Str_t *vOut, int Val)
Definition: vecStr.h:831
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
static void Vec_StrPut_(Vec_Str_t *vOut)
Definition: sclLiberty.c:773
char * Scl_LibertyFileContents(char *pFileName, int nContents)
Definition: sclLiberty.c:503
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
Definition: vecFlt.h:42
int strncmp()
char * Scl_LibertyReadDefaultWireLoad(Scl_Tree_t *p)
Definition: sclLiberty.c:787
Scl_Pair_t Head
Definition: sclLiberty.c:55
#define Scl_ItemForEachChildName(p, pItem, pChild, pName)
Definition: sclLiberty.c:84
int Scl_LibertyItemNum(Scl_Tree_t *p, Scl_Item_t *pRoot, char *pName)
Definition: sclLiberty.c:355
int Scl_LibertyScanTable(Scl_Tree_t *p, Vec_Ptr_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
Definition: sclLiberty.c:1011
static int Scl_LibertyCharIsSpace(char c)
Definition: sclLiberty.c:215
#define assert(ex)
Definition: util_old.h:213
int strlen()
static void Vec_StrPrintStr(Vec_Str_t *p, const char *pStr)
Definition: vecStr.h:627
static float Vec_FltEntry(Vec_Flt_t *p, int i)
Definition: vecFlt.h:342
void Scl_LibertyStop(Scl_Tree_t *p, int fVerbose)
Definition: sclLiberty.c:560
static void Scl_PrintSpace(FILE *pFile, int nOffset)
Definition: sclLiberty.c:79
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
char * Scl_LibertyReadString(Scl_Tree_t *p, Scl_Pair_t Pair)
Definition: sclLiberty.c:341
ABC_INT64_T abctime
Definition: abc_global.h:278
void Abc_SclLibNormalize(SC_Lib *p)
Definition: sclLibUtil.c:615
static int Vec_FltSize(Vec_Flt_t *p)
Definition: vecFlt.h:294
static void Vec_PtrShrink(Vec_Ptr_t *p, int nSizeNew)
Definition: vecPtr.h:528
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
Scl_Pair_t Key
Definition: sclLiberty.c:54
SC_Lib * Abc_SclReadLiberty(char *pFileName, int fVerbose, int fVeryVerbose)
Definition: sclLiberty.c:1626
static Scl_Item_t * Scl_LibertyItem(Scl_Tree_t *p, int v)
Definition: sclLiberty.c:76
static void ** Vec_PtrArray(Vec_Ptr_t *p)
Definition: vecPtr.h:279
static int Scl_LibertySkipEntry(char **ppPos, char *pEnd)
Definition: sclLiberty.c:237
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition: vecWrd.h:42
static int Scl_LibertySkipSpaces(Scl_Tree_t *p, char **ppPos, char *pEnd, int fStopAtNewLine)
Definition: sclLiberty.c:219
static char * Scl_LibertyFindMatch(char *pPos, char *pEnd)
Definition: sclLiberty.c:262
Vec_Str_t * Scl_LibertyReadGenlibStr(Scl_Tree_t *p, int fVerbose)
Definition: sclLiberty.c:675
static Scl_Item_t * Scl_LibertyNewItem(Scl_Tree_t *p, int Type)
Definition: sclLiberty.c:320
int Scl_LibertyBuildItem(Scl_Tree_t *p, char **ppPos, char *pEnd)
Definition: sclLiberty.c:375
Vec_Ptr_t * Scl_LibertyReadPinTimingAll(Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
Definition: sclLiberty.c:942
void Scl_LibertyDumpTables(Vec_Str_t *vOut, Vec_Flt_t *vInd1, Vec_Flt_t *vInd2, Vec_Flt_t *vValues)
Definition: sclLiberty.c:978
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223