ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
sclLiberty.c File Reference
#include <string.h>
#include <fnmatch.h>
#include "misc/zlib/zlib.h"
#include "sclLib.h"
#include "misc/st/st.h"
#include "map/mio/mio.h"
Include dependency graph for sclLiberty.c:

Go to the source code of this file.

Classes

struct  Scl_Pair_t_
 
struct  Scl_Item_t_
 
struct  Scl_Tree_t_
 

Macros

#define Scl_ItemForEachChild(p, pItem, pChild)
 
#define Scl_ItemForEachChildName(p, pItem, pChild, pName)
 

Typedefs

typedef struct Scl_Pair_t_ Scl_Pair_t
 
typedef struct Scl_Item_t_ Scl_Item_t
 
typedef struct Scl_Tree_t_ Scl_Tree_t
 

Enumerations

enum  Scl_LibertyType_t { SCL_LIBERTY_NONE = 0 , SCL_LIBERTY_PROC , SCL_LIBERTY_EQUA , SCL_LIBERTY_LIST }
 DECLARATIONS ///. More...
 

Functions

void Scl_LibertyParseDumpItem (FILE *pFile, Scl_Tree_t *p, Scl_Item_t *pItem, int nOffset)
 FUNCTION DEFINITIONS ///.
 
int Scl_LibertyParseDump (Scl_Tree_t *p, char *pFileName)
 
long Scl_LibertyCountItems (char *pBeg, char *pEnd)
 
void Scl_LibertyWipeOutComments (char *pBeg, char *pEnd)
 
char * Scl_LibertyReadString (Scl_Tree_t *p, Scl_Pair_t Pair)
 
long Scl_LibertyItemNum (Scl_Tree_t *p, Scl_Item_t *pRoot, char *pName)
 
long Scl_LibertyBuildItem (Scl_Tree_t *p, char **ppPos, char *pEnd)
 
void Scl_LibertyFixFileName (char *pFileName)
 
long Scl_LibertyFileSize (char *pFileName)
 
char * Scl_LibertyFileContents (char *pFileName, long *nContents)
 
void Scl_LibertyStringDump (char *pFileName, Vec_Str_t *vStr)
 
Scl_Tree_tScl_LibertyStart (char *pFileName)
 
void Scl_LibertyStop (Scl_Tree_t *p, int fVerbose)
 
Scl_Tree_tScl_LibertyParse (char *pFileName, int fVerbose)
 
int Scl_LibertyReadCellIsFlop (Scl_Tree_t *p, Scl_Item_t *pCell)
 
int Scl_LibertyReadCellIsDontUse (Scl_Tree_t *p, Scl_Item_t *pCell, SC_DontUse dont_use)
 
char * Scl_LibertyReadCellArea (Scl_Tree_t *p, Scl_Item_t *pCell)
 
char * Scl_LibertyReadCellLeakage (Scl_Tree_t *p, Scl_Item_t *pCell)
 
char * Scl_LibertyReadPinFormula (Scl_Tree_t *p, Scl_Item_t *pPin)
 
int Scl_LibertyReadCellIsThreeState (Scl_Tree_t *p, Scl_Item_t *pCell)
 
long Scl_LibertyReadCellOutputNum (Scl_Tree_t *p, Scl_Item_t *pCell)
 
Vec_Str_tScl_LibertyReadGenlibStr (Scl_Tree_t *p, int fVerbose, SC_DontUse dont_use)
 
char * Scl_LibertyReadDefaultWireLoad (Scl_Tree_t *p)
 
char * Scl_LibertyReadDefaultWireLoadSel (Scl_Tree_t *p)
 
float Scl_LibertyReadDefaultMaxTrans (Scl_Tree_t *p)
 
int Scl_LibertyReadTimeUnit (Scl_Tree_t *p)
 
void Scl_LibertyReadLoadUnit (Scl_Tree_t *p, Vec_Str_t *vOut)
 
void Scl_LibertyReadWireLoad (Scl_Tree_t *p, Vec_Str_t *vOut)
 
void Scl_LibertyReadWireLoadSelect (Scl_Tree_t *p, Vec_Str_t *vOut)
 
int Scl_LibertyReadDeriveStrength (Scl_Tree_t *p, Scl_Item_t *pCell)
 
int Scl_LibertyReadPinDirection (Scl_Tree_t *p, Scl_Item_t *pPin)
 
float Scl_LibertyReadPinCap (Scl_Tree_t *p, Scl_Item_t *pPin, char *pName)
 
Scl_Item_tScl_LibertyReadPinTiming (Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
 
Vec_Ptr_tScl_LibertyReadPinTimingAll (Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
 
int Scl_LibertyReadTimingSense (Scl_Tree_t *p, Scl_Item_t *pPin)
 
Vec_Flt_tScl_LibertyReadFloatVec (char *pName)
 
void Scl_LibertyDumpTables (Vec_Str_t *vOut, Vec_Flt_t *vInd1, Vec_Flt_t *vInd2, Vec_Flt_t *vValues)
 
int Scl_LibertyScanTable (Scl_Tree_t *p, Vec_Ptr_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
 
int Scl_LibertyComputeWorstCase (Vec_Ptr_t *vTables, Vec_Flt_t **pvInd0, Vec_Flt_t **pvInd1, Vec_Flt_t **pvValues)
 
int Scl_LibertyReadTable (Scl_Tree_t *p, Vec_Str_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
 
void Scl_LibertyPrintTemplates (Vec_Ptr_t *vRes)
 
Vec_Ptr_tScl_LibertyReadTemplates (Scl_Tree_t *p)
 
Vec_Str_tScl_LibertyReadSclStr (Scl_Tree_t *p, int fVerbose, int fVeryVerbose, SC_DontUse dont_use, int fSkipMultiOuts)
 
SC_LibAbc_SclReadLiberty (char *pFileName, int fVerbose, int fVeryVerbose, SC_DontUse dont_use, int fSkipMultiOuts)
 
void Scl_LibertyTest ()
 

Macro Definition Documentation

◆ Scl_ItemForEachChild

#define Scl_ItemForEachChild ( p,
pItem,
pChild )
Value:
for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) )
Cube * p
Definition exorList.c:222

Definition at line 99 of file sclLiberty.c.

99#define Scl_ItemForEachChild( p, pItem, pChild ) \
100 for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) )

◆ Scl_ItemForEachChildName

#define Scl_ItemForEachChildName ( p,
pItem,
pChild,
pName )
Value:
for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) ) if ( Scl_LibertyCompare(p, pChild->Key, pName) ) {} else

Definition at line 101 of file sclLiberty.c.

101#define Scl_ItemForEachChildName( p, pItem, pChild, pName ) \
102 for ( pChild = Scl_LibertyItem(p, pItem->Child); pChild; pChild = Scl_LibertyItem(p, pChild->Next) ) if ( Scl_LibertyCompare(p, pChild->Key, pName) ) {} else

Typedef Documentation

◆ Scl_Item_t

typedef struct Scl_Item_t_ Scl_Item_t

Definition at line 57 of file sclLiberty.c.

◆ Scl_Pair_t

typedef struct Scl_Pair_t_ Scl_Pair_t

Definition at line 50 of file sclLiberty.c.

◆ Scl_Tree_t

typedef struct Scl_Tree_t_ Scl_Tree_t

Definition at line 69 of file sclLiberty.c.

Enumeration Type Documentation

◆ Scl_LibertyType_t

DECLARATIONS ///.

CFile****************************************************************

FileName [sclLiberty.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Standard-cell library representation.]

Synopsis [Liberty parser.]

Author [Alan Mishchenko, Niklas Een]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - August 24, 2012.]

Revision [

Id
sclLiberty.c,v 1.0 2012/08/24 00:00:00 alanmi Exp

]

Enumerator
SCL_LIBERTY_NONE 
SCL_LIBERTY_PROC 
SCL_LIBERTY_EQUA 
SCL_LIBERTY_LIST 

Definition at line 43 of file sclLiberty.c.

43 {
44 SCL_LIBERTY_NONE = 0, // 0: unknown
45 SCL_LIBERTY_PROC, // 1: procedure : key(head){body}
46 SCL_LIBERTY_EQUA, // 2: equation : key:head;
47 SCL_LIBERTY_LIST // 3: list : key(head)
Scl_LibertyType_t
DECLARATIONS ///.
Definition sclLiberty.c:43
@ SCL_LIBERTY_LIST
Definition sclLiberty.c:47
@ SCL_LIBERTY_NONE
Definition sclLiberty.c:44
@ SCL_LIBERTY_EQUA
Definition sclLiberty.c:46
@ SCL_LIBERTY_PROC
Definition sclLiberty.c:45

Function Documentation

◆ Abc_SclReadLiberty()

SC_Lib * Abc_SclReadLiberty ( char * pFileName,
int fVerbose,
int fVeryVerbose,
SC_DontUse dont_use,
int fSkipMultiOuts )

Definition at line 1768 of file sclLiberty.c.

1769{
1770 SC_Lib * pLib;
1771 Scl_Tree_t * p;
1772 Vec_Str_t * vStr;
1773 p = Scl_LibertyParse( pFileName, fVeryVerbose );
1774 if ( p == NULL )
1775 return NULL;
1776// Scl_LibertyParseDump( p, "temp_.lib" );
1777 // collect relevant data
1778 vStr = Scl_LibertyReadSclStr( p, fVerbose, fVeryVerbose, dont_use, fSkipMultiOuts );
1779 Scl_LibertyStop( p, fVeryVerbose );
1780 if ( vStr == NULL )
1781 return NULL;
1782 // construct SCL data-structure
1783 pLib = Abc_SclReadFromStr( vStr );
1784 if ( pLib == NULL )
1785 return NULL;
1786 pLib->pFileName = Abc_UtilStrsav( pFileName );
1787 Abc_SclLibNormalize( pLib );
1788 Vec_StrFree( vStr );
1789// printf( "Average slew = %.2f ps\n", Abc_SclComputeAverageSlew(pLib) );
1790 return pLib;
1791}
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
struct SC_Lib_ SC_Lib
Definition sclLib.h:128
SC_Lib * Abc_SclReadFromStr(Vec_Str_t *vOut)
Definition sclLibScl.c:403
void Abc_SclLibNormalize(SC_Lib *p)
Definition sclLibUtil.c:750
void Scl_LibertyStop(Scl_Tree_t *p, int fVerbose)
Definition sclLiberty.c:659
Scl_Tree_t * Scl_LibertyParse(char *pFileName, int fVerbose)
Definition sclLiberty.c:673
struct Scl_Tree_t_ Scl_Tree_t
Definition sclLiberty.c:69
Vec_Str_t * Scl_LibertyReadSclStr(Scl_Tree_t *p, int fVerbose, int fVeryVerbose, SC_DontUse dont_use, int fSkipMultiOuts)
char * pFileName
Definition sclLib.h:226
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyBuildItem()

long Scl_LibertyBuildItem ( Scl_Tree_t * p,
char ** ppPos,
char * pEnd )

Function*************************************************************

Synopsis [Returns free item.]

Description []

SideEffects []

SeeAlso []

Definition at line 411 of file sclLiberty.c.

412{
413 Scl_Item_t * pItem;
414 Scl_Pair_t Key, Head, Body;
415 char * pNext, * pStop;
416 Key.End = 0;
417 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
418 return -2;
419 Key.Beg = *ppPos - p->pContents;
420 if ( Scl_LibertySkipEntry( ppPos, pEnd ) )
421 goto exit;
422 Key.End = *ppPos - p->pContents;
423 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
424 goto exit;
425 pNext = *ppPos;
426 if ( *pNext == ':' )
427 {
428 *ppPos = pNext + 1;
429 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
430 goto exit;
431 Head.Beg = *ppPos - p->pContents;
432 if ( Scl_LibertySkipEntry( ppPos, pEnd ) )
433 goto exit;
434 Head.End = *ppPos - p->pContents;
435 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
436 goto exit;
437 pNext = *ppPos;
438 while ( *pNext == '+' || *pNext == '-' || *pNext == '*' || *pNext == '/' )
439 {
440 (*ppPos) += 1;
441 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
442 goto exit;
443 if ( Scl_LibertySkipEntry( ppPos, pEnd ) )
444 goto exit;
445 Head.End = *ppPos - p->pContents;
446 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 1 ) )
447 goto exit;
448 pNext = *ppPos;
449 }
450 if ( *pNext != ';' && *pNext != '\n' )
451 goto exit;
452 *ppPos = pNext + 1;
453 // end of equation
454 pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_EQUA );
455 pItem->Key = Key;
456 pItem->Head = Scl_LibertyUpdateHead( p, Head );
457 pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
458 if ( pItem->Next == -1 )
459 goto exit;
460 return Scl_LibertyItemId( p, pItem );
461 }
462 if ( *pNext == '(' )
463 {
464 pStop = Scl_LibertyFindMatch( pNext, pEnd );
465 Head.Beg = pNext - p->pContents + 1;
466 Head.End = pStop - p->pContents;
467 *ppPos = pStop + 1;
468 if ( Scl_LibertySkipSpaces( p, ppPos, pEnd, 0 ) )
469 {
470 // end of list
471 pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_LIST );
472 pItem->Key = Key;
473 pItem->Head = Scl_LibertyUpdateHead( p, Head );
474 return Scl_LibertyItemId( p, pItem );
475 }
476 pNext = *ppPos;
477 if ( *pNext == '{' ) // beginning of body
478 {
479 pStop = Scl_LibertyFindMatch( pNext, pEnd );
480 Body.Beg = pNext - p->pContents + 1;
481 Body.End = pStop - p->pContents;
482 // end of body
483 pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_PROC );
484 pItem->Key = Key;
485 pItem->Head = Scl_LibertyUpdateHead( p, Head );
486 pItem->Body = Body;
487 *ppPos = pNext + 1;
488 pItem->Child = Scl_LibertyBuildItem( p, ppPos, pStop );
489 if ( pItem->Child == -1 )
490 goto exit;
491 *ppPos = pStop + 1;
492 pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
493 if ( pItem->Next == -1 )
494 goto exit;
495 return Scl_LibertyItemId( p, pItem );
496 }
497 // end of list
498 if ( *pNext == ';' )
499 *ppPos = pNext + 1;
500 pItem = Scl_LibertyNewItem( p, SCL_LIBERTY_LIST );
501 pItem->Key = Key;
502 pItem->Head = Scl_LibertyUpdateHead( p, Head );
503 pItem->Next = Scl_LibertyBuildItem( p, ppPos, pEnd );
504 if ( pItem->Next == -1 )
505 goto exit;
506 return Scl_LibertyItemId( p, pItem );
507 }
508 if ( *pNext == ';' )
509 {
510 *ppPos = pNext + 1;
511 return Scl_LibertyBuildItem(p, ppPos, pEnd);
512 }
513exit:
514 if ( p->pError == NULL )
515 {
516 p->pError = ABC_ALLOC( char, 1000 );
517 sprintf( p->pError, "File \"%s\". Line %6ld. Failed to parse entry \"%s\".\n",
518 p->pFileName, p->nLines, Scl_LibertyReadString(p, Key) );
519 }
520 return -1;
521}
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
char * Scl_LibertyReadString(Scl_Tree_t *p, Scl_Pair_t Pair)
Definition sclLiberty.c:374
long Scl_LibertyBuildItem(Scl_Tree_t *p, char **ppPos, char *pEnd)
Definition sclLiberty.c:411
struct Scl_Pair_t_ Scl_Pair_t
Definition sclLiberty.c:50
struct Scl_Item_t_ Scl_Item_t
Definition sclLiberty.c:57
Scl_Pair_t Head
Definition sclLiberty.c:63
Scl_Pair_t Body
Definition sclLiberty.c:64
Scl_Pair_t Key
Definition sclLiberty.c:62
char * sprintf()
VOID_HACK exit()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyComputeWorstCase()

int Scl_LibertyComputeWorstCase ( Vec_Ptr_t * vTables,
Vec_Flt_t ** pvInd0,
Vec_Flt_t ** pvInd1,
Vec_Flt_t ** pvValues )

Definition at line 1240 of file sclLiberty.c.

1241{
1242 Vec_Flt_t * vInd0, * vInd1, * vValues;
1243 Vec_Flt_t * vind0, * vind1, * vvalues;
1244 int i, k, nTriples = Vec_PtrSize(vTables) / 3;
1245 float Entry;
1246 assert( Vec_PtrSize(vTables) > 0 && Vec_PtrSize(vTables) % 3 == 0 );
1247 if ( nTriples == 1 )
1248 {
1249 *pvInd0 = (Vec_Flt_t *)Vec_PtrEntry(vTables, 0);
1250 *pvInd1 = (Vec_Flt_t *)Vec_PtrEntry(vTables, 1);
1251 *pvValues = (Vec_Flt_t *)Vec_PtrEntry(vTables, 2);
1252 Vec_PtrShrink( vTables, 0 );
1253 return 1;
1254 }
1255 vInd0 = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 0) );
1256 vInd1 = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 1) );
1257 vValues = Vec_FltDup( (Vec_Flt_t *)Vec_PtrEntry(vTables, 2) );
1258 for ( i = 1; i < nTriples; i++ )
1259 {
1260 vind0 = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+0);
1261 vind1 = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+1);
1262 vvalues = (Vec_Flt_t *)Vec_PtrEntry(vTables, i*3+2);
1263 // check equality of indexes
1264 if ( !Vec_FltEqual(vind0, vInd0) )
1265 continue;//return 0;
1266 if ( !Vec_FltEqual(vind1, vInd1) )
1267 continue;//return 0;
1268// Vec_FltForEachEntry( vvalues, Entry, k )
1269// Vec_FltAddToEntry( vValues, k, Entry );
1270 Vec_FltForEachEntry( vvalues, Entry, k )
1271 if ( Vec_FltEntry(vValues, k) < Entry )
1272 Vec_FltWriteEntry( vValues, k, Entry );
1273 }
1274// Vec_FltForEachEntry( vValues, Entry, k )
1275// Vec_FltWriteEntry( vValues, k, Entry/nTriples );
1276 // return the result
1277 *pvInd0 = vInd0;
1278 *pvInd1 = vInd1;
1279 *pvValues = vValues;
1280 return 1;
1281}
#define assert(ex)
Definition util_old.h:213
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecFlt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
Definition vecFlt.h:42
Here is the caller graph for this function:

◆ Scl_LibertyCountItems()

long Scl_LibertyCountItems ( char * pBeg,
char * pEnd )

Function*************************************************************

Synopsis [Gets the name to write.]

Description []

SideEffects []

SeeAlso []

Definition at line 185 of file sclLiberty.c.

186{
187 long Counter = 0;
188 for ( ; pBeg < pEnd; pBeg++ )
189 Counter += (*pBeg == '(' || *pBeg == ':');
190 return Counter;
191}
Here is the caller graph for this function:

◆ Scl_LibertyDumpTables()

void Scl_LibertyDumpTables ( Vec_Str_t * vOut,
Vec_Flt_t * vInd1,
Vec_Flt_t * vInd2,
Vec_Flt_t * vValues )

Definition at line 1087 of file sclLiberty.c.

1088{
1089 int i; float Entry;
1090 // write entries
1091 Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1092 Vec_FltForEachEntry( vInd1, Entry, i )
1093 Vec_StrPutF_( vOut, Entry );
1094 Vec_StrPut_( vOut );
1095 // write entries
1096 Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1097 Vec_FltForEachEntry( vInd2, Entry, i )
1098 Vec_StrPutF_( vOut, Entry );
1099 Vec_StrPut_( vOut );
1100 Vec_StrPut_( vOut );
1101 // write entries
1102 assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1103 Vec_FltForEachEntry( vValues, Entry, i )
1104 {
1105 Vec_StrPutF_( vOut, Entry );
1106 if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1107 Vec_StrPut_( vOut );
1108 }
1109 // dump approximations
1110 Vec_StrPut_( vOut );
1111 for ( i = 0; i < 3; i++ )
1112 Vec_StrPutF_( vOut, 0 );
1113 for ( i = 0; i < 4; i++ )
1114 Vec_StrPutF_( vOut, 0 );
1115 for ( i = 0; i < 6; i++ )
1116 Vec_StrPutF_( vOut, 0 );
1117 Vec_StrPut_( vOut );
1118 Vec_StrPut_( vOut );
1119}
Here is the caller graph for this function:

◆ Scl_LibertyFileContents()

char * Scl_LibertyFileContents ( char * pFileName,
long * nContents )

Definition at line 580 of file sclLiberty.c.

581{
582 char * pContents = NULL;
583 //if file ends in ".gz" then use gzopen
584 if ( !strncmp(pFileName+strlen(pFileName)-3,".gz", 3) )
585 {
586 FILE * pFile = fopen( pFileName, "rb" );
587 //char * pContents;
588 long RetValue = 0;
589 pContents = Io_LibLoadFileGz( pFileName, nContents );
590 if(pContents == NULL) {
591 printf( "Scl_LibertyFileContents(): The input file is unavailable (absent or open).\n" );
592 return NULL;
593 }
594 else {
595 RetValue = 1;
596 }
597 fclose( pFile );
598 }
599 // original .lib file
600 else
601 {
602 FILE * pFile = fopen( pFileName, "rb" );
603 pContents = ABC_ALLOC( char, *nContents+1 );
604 long RetValue = 0;
605 RetValue = fread( pContents, *nContents, 1, pFile );
606 fclose( pFile );
607 pContents[*nContents] = 0;
608 }
609 return pContents;
610}
int strncmp()
int strlen()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyFileSize()

long Scl_LibertyFileSize ( char * pFileName)

Definition at line 541 of file sclLiberty.c.

542{
543 FILE * pFile;
544 long nFileSize;
545 pFile = fopen( pFileName, "rb" );
546 if ( pFile == NULL )
547 {
548 printf( "Scl_LibertyFileSize(): The input file is unavailable (absent or open).\n" );
549 return 0;
550 }
551 fseek( pFile, 0, SEEK_END );
552 nFileSize = ftell( pFile );
553 fclose( pFile );
554 return nFileSize;
555}
#define SEEK_END
Definition zconf.h:392
Here is the caller graph for this function:

◆ Scl_LibertyFixFileName()

void Scl_LibertyFixFileName ( char * pFileName)

Function*************************************************************

Synopsis [File management.]

Description []

SideEffects []

SeeAlso []

Definition at line 534 of file sclLiberty.c.

535{
536 char * pHead;
537 for ( pHead = pFileName; *pHead; pHead++ )
538 if ( *pHead == '>' )
539 *pHead = '\\';
540}
Here is the caller graph for this function:

◆ Scl_LibertyItemNum()

long Scl_LibertyItemNum ( Scl_Tree_t * p,
Scl_Item_t * pRoot,
char * pName )

Definition at line 391 of file sclLiberty.c.

392{
393 Scl_Item_t * pItem;
394 long Counter = 0;
395 Scl_ItemForEachChildName( p, pRoot, pItem, pName )
396 Counter++;
397 return Counter;
398}
#define Scl_ItemForEachChildName(p, pItem, pChild, pName)
Definition sclLiberty.c:101
Here is the caller graph for this function:

◆ Scl_LibertyParse()

Scl_Tree_t * Scl_LibertyParse ( char * pFileName,
int fVerbose )

Definition at line 673 of file sclLiberty.c.

674{
675 Scl_Tree_t * p;
676 char * pPos;
677 if ( (p = Scl_LibertyStart(pFileName)) == NULL )
678 return NULL;
679 pPos = p->pContents;
680 Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents );
681 if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 )
682 {
683 if ( p->pError ) printf( "%s", p->pError );
684 printf( "Parsing failed. " );
685 Abc_PrintTime( 1, "Parsing time", Abc_Clock() - p->clkStart );
686 }
687 else if ( fVerbose )
688 {
689 printf( "Parsing finished successfully. " );
690 Abc_PrintTime( 1, "Parsing time", Abc_Clock() - p->clkStart );
691 }
692 return p;
693}
void Scl_LibertyWipeOutComments(char *pBeg, char *pEnd)
Definition sclLiberty.c:208
Scl_Tree_t * Scl_LibertyStart(char *pFileName)
Definition sclLiberty.c:635
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyParseDump()

int Scl_LibertyParseDump ( Scl_Tree_t * p,
char * pFileName )

Definition at line 153 of file sclLiberty.c.

154{
155 FILE * pFile;
156 if ( pFileName == NULL )
157 pFile = stdout;
158 else
159 {
160 pFile = fopen( pFileName, "w" );
161 if ( pFile == NULL )
162 {
163 printf( "Scl_LibertyParseDump(): The output file is unavailable (absent or open).\n" );
164 return 0;
165 }
166 }
167 Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyRoot(p), 0 );
168 if ( pFile != stdout )
169 fclose( pFile );
170 return 1;
171}
void Scl_LibertyParseDumpItem(FILE *pFile, Scl_Tree_t *p, Scl_Item_t *pItem, int nOffset)
FUNCTION DEFINITIONS ///.
Definition sclLiberty.c:119
Here is the call graph for this function:

◆ Scl_LibertyParseDumpItem()

void Scl_LibertyParseDumpItem ( FILE * pFile,
Scl_Tree_t * p,
Scl_Item_t * pItem,
int nOffset )

FUNCTION DEFINITIONS ///.

Function*************************************************************

Synopsis [Prints parse tree in Liberty format.]

Description []

SideEffects []

SeeAlso []

Definition at line 119 of file sclLiberty.c.

120{
121 if ( pItem->Type == SCL_LIBERTY_PROC )
122 {
123 Scl_PrintSpace( pFile, nOffset );
124 Scl_PrintWord( pFile, p, pItem->Key );
125 fprintf( pFile, "(" );
126 Scl_PrintWord( pFile, p, pItem->Head );
127 fprintf( pFile, ") {\n" );
128 if ( Scl_LibertyItem(p, pItem->Child) )
129 Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyItem(p, pItem->Child), nOffset + 2 );
130 Scl_PrintSpace( pFile, nOffset );
131 fprintf( pFile, "}\n" );
132 }
133 else if ( pItem->Type == SCL_LIBERTY_EQUA )
134 {
135 Scl_PrintSpace( pFile, nOffset );
136 Scl_PrintWord( pFile, p, pItem->Key );
137 fprintf( pFile, " : " );
138 Scl_PrintWord( pFile, p, pItem->Head );
139 fprintf( pFile, ";\n" );
140 }
141 else if ( pItem->Type == SCL_LIBERTY_LIST )
142 {
143 Scl_PrintSpace( pFile, nOffset );
144 Scl_PrintWord( pFile, p, pItem->Key );
145 fprintf( pFile, "(" );
146 Scl_PrintWord( pFile, p, pItem->Head );
147 fprintf( pFile, ");\n" );
148 }
149 else assert( 0 );
150 if ( Scl_LibertyItem(p, pItem->Next) )
151 Scl_LibertyParseDumpItem( pFile, p, Scl_LibertyItem(p, pItem->Next), nOffset );
152}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyPrintTemplates()

void Scl_LibertyPrintTemplates ( Vec_Ptr_t * vRes)

Definition at line 1432 of file sclLiberty.c.

1433{
1434 Vec_Flt_t * vArray; int i;
1435 assert( Vec_PtrSize(vRes) % 4 == 0 );
1436 printf( "There are %d slew/load templates\n", Vec_PtrSize(vRes) % 4 );
1437 Vec_PtrForEachEntry( Vec_Flt_t *, vRes, vArray, i )
1438 {
1439 if ( i % 4 == 0 )
1440 printf( "%s\n", (char *)vArray );
1441 else if ( i % 4 == 1 )
1442 printf( "%d\n", (int)(vArray != NULL) );
1443 else if ( i % 4 == 2 || i % 4 == 3 )
1444 Vec_FltPrint( vArray );
1445 if ( i % 4 == 3 )
1446 printf( "\n" );
1447 }
1448}
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55

◆ Scl_LibertyReadCellArea()

char * Scl_LibertyReadCellArea ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Definition at line 731 of file sclLiberty.c.

732{
733 Scl_Item_t * pArea;
734 Scl_ItemForEachChildName( p, pCell, pArea, "area" )
735 return Scl_LibertyReadString(p, pArea->Head);
736 return 0;
737}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadCellIsDontUse()

int Scl_LibertyReadCellIsDontUse ( Scl_Tree_t * p,
Scl_Item_t * pCell,
SC_DontUse dont_use )

Definition at line 715 of file sclLiberty.c.

716{
717 Scl_Item_t * pAttr;
718 Scl_ItemForEachChild( p, pCell, pAttr )
719 {
720 if ( !Scl_LibertyCompare(p, pAttr->Key, "dont_use") )
721 return 1;
722 const char * cell_name = Scl_LibertyReadString(p, pCell->Head);
723 for (int i = 0; i < dont_use.size; i++) {
724 if (Scl_LibertyGlobMatch(dont_use.dont_use_list[i], cell_name)) {
725 return 1;
726 }
727 }
728 }
729 return 0;
730}
#define Scl_ItemForEachChild(p, pItem, pChild)
Definition sclLiberty.c:99
int size
Definition sclLib.h:65
char ** dont_use_list
Definition sclLib.h:66
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadCellIsFlop()

int Scl_LibertyReadCellIsFlop ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Function*************************************************************

Synopsis [Fetching attributes.]

Description []

SideEffects []

SeeAlso []

Definition at line 706 of file sclLiberty.c.

707{
708 Scl_Item_t * pAttr;
709 Scl_ItemForEachChild( p, pCell, pAttr )
710 if ( !Scl_LibertyCompare(p, pAttr->Key, "ff") ||
711 !Scl_LibertyCompare(p, pAttr->Key, "latch") )
712 return 1;
713 return 0;
714}
Here is the caller graph for this function:

◆ Scl_LibertyReadCellIsThreeState()

int Scl_LibertyReadCellIsThreeState ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Definition at line 762 of file sclLiberty.c.

763{
764 Scl_Item_t * pPin, * pItem;
765 Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
766 Scl_ItemForEachChildName( p, pPin, pItem, "three_state" )
767 return 1;
768 return 0;
769}
Here is the caller graph for this function:

◆ Scl_LibertyReadCellLeakage()

char * Scl_LibertyReadCellLeakage ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Definition at line 738 of file sclLiberty.c.

739{
740 Scl_Item_t * pItem, * pChild;
741 Scl_ItemForEachChildName( p, pCell, pItem, "cell_leakage_power" )
742 return Scl_LibertyReadString(p, pItem->Head);
743 // look for another type
744 Scl_ItemForEachChildName( p, pCell, pItem, "leakage_power" )
745 {
746 Scl_ItemForEachChildName( p, pItem, pChild, "when" )
747 break;
748 if ( pChild && !Scl_LibertyCompare(p, pChild->Key, "when") )
749 continue;
750 Scl_ItemForEachChildName( p, pItem, pChild, "value" )
751 return Scl_LibertyReadString(p, pChild->Head);
752 }
753 return 0;
754}
if(last==0)
Definition sparse_int.h:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadCellOutputNum()

long Scl_LibertyReadCellOutputNum ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Definition at line 770 of file sclLiberty.c.

771{
772 Scl_Item_t * pPin;
773 long Counter = 0;
774 Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
776 Counter++;
777 return Counter;
778}
char * Scl_LibertyReadPinFormula(Scl_Tree_t *p, Scl_Item_t *pPin)
Definition sclLiberty.c:755
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadDefaultMaxTrans()

float Scl_LibertyReadDefaultMaxTrans ( Scl_Tree_t * p)

Definition at line 908 of file sclLiberty.c.

909{
910 Scl_Item_t * pItem;
911 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_max_transition" )
912 return atof(Scl_LibertyReadString(p, pItem->Head));
913 return 0;
914}
double atof()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadDefaultWireLoad()

char * Scl_LibertyReadDefaultWireLoad ( Scl_Tree_t * p)

Function*************************************************************

Synopsis [Parsing Liberty into internal data representation.]

Description []

SideEffects []

SeeAlso []

Definition at line 894 of file sclLiberty.c.

895{
896 Scl_Item_t * pItem;
897 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_wire_load" )
898 return Scl_LibertyReadString(p, pItem->Head);
899 return "";
900}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadDefaultWireLoadSel()

char * Scl_LibertyReadDefaultWireLoadSel ( Scl_Tree_t * p)

Definition at line 901 of file sclLiberty.c.

902{
903 Scl_Item_t * pItem;
904 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "default_wire_load_selection" )
905 return Scl_LibertyReadString(p, pItem->Head);
906 return "";
907}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadDeriveStrength()

int Scl_LibertyReadDeriveStrength ( Scl_Tree_t * p,
Scl_Item_t * pCell )

Definition at line 1012 of file sclLiberty.c.

1013{
1014 Scl_Item_t * pItem;
1015 Scl_ItemForEachChildName( p, pCell, pItem, "drive_strength" )
1016 return atoi(Scl_LibertyReadString(p, pItem->Head));
1017 return 0;
1018}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadFloatVec()

Vec_Flt_t * Scl_LibertyReadFloatVec ( char * pName)

Definition at line 1078 of file sclLiberty.c.

1079{
1080 char * pToken;
1081 Vec_Flt_t * vValues = Vec_FltAlloc( 100 );
1082 for ( pToken = strtok(pName, " \t\n\r\\\","); pToken; pToken = strtok(NULL, " \t\n\r\\\",") )
1083 Vec_FltPush( vValues, atof(pToken) );
1084 return vValues;
1085}
char * strtok()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadGenlibStr()

Vec_Str_t * Scl_LibertyReadGenlibStr ( Scl_Tree_t * p,
int fVerbose,
SC_DontUse dont_use )

Function*************************************************************

Synopsis [Parses the standard cell library in Liberty format.]

Description [Writes the resulting file in Genlib format.]

SideEffects []

SeeAlso []

Definition at line 791 of file sclLiberty.c.

792{
793 Vec_Str_t * vStr;
794 Scl_Item_t * pCell, * pOutput, * pInput;
795 char * pFormula;
796 vStr = Vec_StrAlloc( 1000 );
797 Vec_StrPrintStr( vStr, "GATE _const0_ 0.000000 z=CONST0;\n" );
798 Vec_StrPrintStr( vStr, "GATE _const1_ 0.000000 z=CONST1;\n" );
799 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
800 {
801 if ( Scl_LibertyReadCellIsFlop(p, pCell) )
802 {
803 if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped sequential cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
804 continue;
805 }
806 if ( Scl_LibertyReadCellIsDontUse(p, pCell, dont_use) )
807 {
808 if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Scl_LibertyReadString(p, pCell->Head) );
809 continue;
810 }
812 {
813 if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
814 continue;
815 }
816 if ( Scl_LibertyReadCellOutputNum(p, pCell) == 0 )
817 {
818 if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" without logic function.\n", Scl_LibertyReadString(p, pCell->Head) );
819 continue;
820 }
821 // iterate through output pins
822 Scl_ItemForEachChildName( p, pCell, pOutput, "pin" )
823 {
824 if ( !(pFormula = Scl_LibertyReadPinFormula(p, pOutput)) )
825 continue;
826 if ( !strcmp(pFormula, "0") || !strcmp(pFormula, "1") )
827 {
828 if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Scl_LibertyReadString(p, pCell->Head), pFormula );
829 break;
830 }
831 Vec_StrPrintStr( vStr, "GATE " );
832 Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pCell->Head) );
833 Vec_StrPrintStr( vStr, " " );
834 Vec_StrPrintStr( vStr, Scl_LibertyReadCellArea(p, pCell) );
835 Vec_StrPrintStr( vStr, " " );
836 Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pOutput->Head) );
837 Vec_StrPrintStr( vStr, "=" );
838 Vec_StrPrintStr( vStr, pFormula );
839 Vec_StrPrintStr( vStr, ";\n" );
840 // iterate through input pins
841 Scl_ItemForEachChildName( p, pCell, pInput, "pin" )
842 {
843 if ( Scl_LibertyReadPinFormula(p, pInput) == NULL )
844 continue;
845 Vec_StrPrintStr( vStr, " PIN " );
846 Vec_StrPrintStr( vStr, Scl_LibertyReadString(p, pInput->Head) );
847 Vec_StrPrintStr( vStr, " UNKNOWN 1 999 1.00 0.00 1.00 0.00\n" );
848 }
849 }
850 }
851 Vec_StrPrintStr( vStr, "\n.end\n" );
852 Vec_StrPush( vStr, '\0' );
853// printf( "%s", Vec_StrArray(vStr) );
854 return vStr;
855}
int Scl_LibertyReadCellIsThreeState(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition sclLiberty.c:762
long Scl_LibertyReadCellOutputNum(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition sclLiberty.c:770
char * Scl_LibertyReadCellArea(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition sclLiberty.c:731
int Scl_LibertyReadCellIsDontUse(Scl_Tree_t *p, Scl_Item_t *pCell, SC_DontUse dont_use)
Definition sclLiberty.c:715
int Scl_LibertyReadCellIsFlop(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition sclLiberty.c:706
int strcmp()
Here is the call graph for this function:

◆ Scl_LibertyReadLoadUnit()

void Scl_LibertyReadLoadUnit ( Scl_Tree_t * p,
Vec_Str_t * vOut )

Definition at line 935 of file sclLiberty.c.

936{
937 Scl_Item_t * pItem;
938 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "capacitive_load_unit" )
939 {
940 // expecting (1.00,ff) or (1, pf) ... 12 or 15 for 'pf' or 'ff'
941 char * pHead = Scl_LibertyReadString(p, pItem->Head);
942 float First = atof(strtok(pHead, " \t\n\r\\\","));
943 char * pSecond = strtok(NULL, " \t\n\r\\\",");
944 Vec_StrPutF_( vOut, First );
945 if ( pSecond && !strcmp(pSecond, "pf") )
946 Vec_StrPutI_( vOut, 12 );
947 else if ( pSecond && !strcmp(pSecond, "ff") )
948 Vec_StrPutI_( vOut, 15 );
949 else break;
950 return;
951 }
952 printf( "Liberty parser cannot read \"capacitive_load_unit\". Assuming capacitive_load_unit(1, pf).\n" );
953 Vec_StrPutF_( vOut, 1.0 );
954 Vec_StrPutI_( vOut, 12 );
955}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadPinCap()

float Scl_LibertyReadPinCap ( Scl_Tree_t * p,
Scl_Item_t * pPin,
char * pName )

Definition at line 1035 of file sclLiberty.c.

1036{
1037 Scl_Item_t * pItem;
1038 Scl_ItemForEachChildName( p, pPin, pItem, pName )
1039 return atof(Scl_LibertyReadString(p, pItem->Head));
1040 return 0;
1041}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadPinDirection()

int Scl_LibertyReadPinDirection ( Scl_Tree_t * p,
Scl_Item_t * pPin )

Definition at line 1019 of file sclLiberty.c.

1020{
1021 Scl_Item_t * pItem;
1022 Scl_ItemForEachChildName( p, pPin, pItem, "direction" )
1023 {
1024 char * pToken = Scl_LibertyReadString(p, pItem->Head);
1025 if ( !strcmp(pToken, "input") )
1026 return 0;
1027 if ( !strcmp(pToken, "output") )
1028 return 1;
1029 if ( !strcmp(pToken, "internal") )
1030 return 2;
1031 break;
1032 }
1033 return -1;
1034}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadPinFormula()

char * Scl_LibertyReadPinFormula ( Scl_Tree_t * p,
Scl_Item_t * pPin )

Definition at line 755 of file sclLiberty.c.

756{
757 Scl_Item_t * pFunc;
758 Scl_ItemForEachChildName( p, pPin, pFunc, "function" )
759 return Scl_LibertyReadString(p, pFunc->Head);
760 return NULL;
761}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadPinTiming()

Scl_Item_t * Scl_LibertyReadPinTiming ( Scl_Tree_t * p,
Scl_Item_t * pPinOut,
char * pNameIn )

Definition at line 1042 of file sclLiberty.c.

1043{
1044 Scl_Item_t * pTiming, * pPinIn;
1045 Scl_ItemForEachChildName( p, pPinOut, pTiming, "timing" )
1046 Scl_ItemForEachChildName( p, pTiming, pPinIn, "related_pin" )
1047 if ( !strcmp(Scl_LibertyReadString(p, pPinIn->Head), pNameIn) )
1048 return pTiming;
1049 return NULL;
1050}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadPinTimingAll()

Vec_Ptr_t * Scl_LibertyReadPinTimingAll ( Scl_Tree_t * p,
Scl_Item_t * pPinOut,
char * pNameIn )

Definition at line 1051 of file sclLiberty.c.

1052{
1053 Vec_Ptr_t * vTimings;
1054 Scl_Item_t * pTiming, * pPinIn;
1055 vTimings = Vec_PtrAlloc( 16 );
1056 Scl_ItemForEachChildName( p, pPinOut, pTiming, "timing" )
1057 Scl_ItemForEachChildName( p, pTiming, pPinIn, "related_pin" )
1058 if ( !strcmp(Scl_LibertyReadString(p, pPinIn->Head), pNameIn) )
1059 Vec_PtrPush( vTimings, pTiming );
1060 return vTimings;
1061}
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadSclStr()

Vec_Str_t * Scl_LibertyReadSclStr ( Scl_Tree_t * p,
int fVerbose,
int fVeryVerbose,
SC_DontUse dont_use,
int fSkipMultiOuts )

Definition at line 1503 of file sclLiberty.c.

1504{
1505 int fUseFirstTable = 0;
1506 Vec_Str_t * vOut;
1507 Vec_Ptr_t * vNameIns, * vTemples = NULL;
1508 Scl_Item_t * pCell, * pPin, * pTiming;
1509 Vec_Wrd_t * vTruth;
1510 char * pFormula, * pName;
1511 int i, k, Counter, nOutputs, nCells;
1512 int nSkipped[6] = {0};
1513
1514 // read delay-table templates
1515 vTemples = Scl_LibertyReadTemplates( p );
1516
1517 // start the library
1518 vOut = Vec_StrAlloc( 10000 );
1519 Vec_StrPutI_( vOut, ABC_SCL_CUR_VERSION );
1520
1521 // top level information
1522 Vec_StrPut_( vOut );
1523 Vec_StrPutS_( vOut, Scl_LibertyReadString(p, Scl_LibertyRoot(p)->Head) );
1524 Vec_StrPutS_( vOut, Scl_LibertyReadDefaultWireLoad(p) );
1525 Vec_StrPutS_( vOut, Scl_LibertyReadDefaultWireLoadSel(p) );
1526 Vec_StrPutF_( vOut, Scl_LibertyReadDefaultMaxTrans(p) );
1527 Vec_StrPutI_( vOut, Scl_LibertyReadTimeUnit(p) );
1528 Scl_LibertyReadLoadUnit( p, vOut );
1529 Vec_StrPut_( vOut );
1530 Vec_StrPut_( vOut );
1531
1532 // read wire loads
1533 Scl_LibertyReadWireLoad( p, vOut );
1535
1536 // count cells
1537 nCells = 0;
1538 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
1539 {
1540 if ( Scl_LibertyReadCellIsFlop(p, pCell) )
1541 {
1542 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped sequential cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
1543 nSkipped[0]++;
1544 continue;
1545 }
1546 if ( Scl_LibertyReadCellIsDontUse(p, pCell, dont_use) )
1547 {
1548 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Scl_LibertyReadString(p, pCell->Head) );
1549 nSkipped[3]++;
1550 continue;
1551 }
1552 if ( Scl_LibertyReadCellIsThreeState(p, pCell) )
1553 {
1554 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) );
1555 nSkipped[1]++;
1556 continue;
1557 }
1558 if ( (Counter = Scl_LibertyReadCellOutputNum(p, pCell)) == 0 )
1559 {
1560 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" without logic function.\n", Scl_LibertyReadString(p, pCell->Head) );
1561 nSkipped[2]++;
1562 continue;
1563 }
1564 if ( Counter > 2 )
1565 {
1566 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" with more than two outputs.\n", Scl_LibertyReadString(p, pCell->Head) );
1567 nSkipped[4]++;
1568 continue;
1569 }
1570 if ( fSkipMultiOuts && Counter > 1 )
1571 {
1572 if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" with two outputs.\n", Scl_LibertyReadString(p, pCell->Head) );
1573 nSkipped[5]++;
1574 continue;
1575 }
1576 nCells++;
1577 }
1578 // read cells
1579 Vec_StrPutI_( vOut, nCells );
1580 Vec_StrPut_( vOut );
1581 Vec_StrPut_( vOut );
1582 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pCell, "cell" )
1583 {
1584 if ( Scl_LibertyReadCellIsFlop(p, pCell) )
1585 continue;
1586 if ( Scl_LibertyReadCellIsDontUse(p, pCell, dont_use) )
1587 continue;
1588 if ( Scl_LibertyReadCellIsThreeState(p, pCell) )
1589 continue;
1590 if ( (Counter = Scl_LibertyReadCellOutputNum(p, pCell)) == 0 )
1591 continue;
1592 if ( Counter > 2 )
1593 continue;
1594 if ( fSkipMultiOuts && Counter > 1 )
1595 continue;
1596 // top level information
1597 Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pCell->Head) );
1598 pName = Scl_LibertyReadCellArea(p, pCell);
1599 Vec_StrPutF_( vOut, pName ? atof(pName) : 1 );
1600 pName = Scl_LibertyReadCellLeakage(p, pCell);
1601 Vec_StrPutF_( vOut, pName ? atof(pName) : 0 );
1602 Vec_StrPutI_( vOut, Scl_LibertyReadDeriveStrength(p, pCell) );
1603 // pin count
1604 nOutputs = Scl_LibertyReadCellOutputNum( p, pCell );
1605 Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pCell, "pin") - nOutputs );
1606 Vec_StrPutI_( vOut, nOutputs );
1607 Vec_StrPut_( vOut );
1608 Vec_StrPut_( vOut );
1609
1610 // input pins
1611 vNameIns = Vec_PtrAlloc( 16 );
1612 Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
1613 {
1614 float CapOne, CapRise, CapFall;
1615 if ( Scl_LibertyReadPinFormula(p, pPin) != NULL ) // skip output pin
1616 continue;
1618 pName = Scl_LibertyReadString(p, pPin->Head);
1619 Vec_PtrPush( vNameIns, Abc_UtilStrsav(pName) );
1620 Vec_StrPutS_( vOut, pName );
1621 CapOne = Scl_LibertyReadPinCap( p, pPin, "capacitance" );
1622 CapRise = Scl_LibertyReadPinCap( p, pPin, "rise_capacitance" );
1623 CapFall = Scl_LibertyReadPinCap( p, pPin, "fall_capacitance" );
1624 if ( CapRise == 0 )
1625 CapRise = CapOne;
1626 if ( CapFall == 0 )
1627 CapFall = CapOne;
1628 Vec_StrPutF_( vOut, CapRise );
1629 Vec_StrPutF_( vOut, CapFall );
1630 Vec_StrPut_( vOut );
1631 }
1632 Vec_StrPut_( vOut );
1633 // output pins
1634 Scl_ItemForEachChildName( p, pCell, pPin, "pin" )
1635 {
1636 if ( !Scl_LibertyReadPinFormula(p, pPin) ) // skip input pin
1637 continue;
1638 if (Scl_LibertyReadPinDirection(p, pPin) == 2) // skip internal pin
1639 continue;
1640 assert( Scl_LibertyReadPinDirection(p, pPin) == 1 );
1641 pName = Scl_LibertyReadString(p, pPin->Head);
1642 Vec_StrPutS_( vOut, pName );
1643 Vec_StrPutF_( vOut, Scl_LibertyReadPinCap( p, pPin, "max_capacitance" ) );
1644 Vec_StrPutF_( vOut, Scl_LibertyReadPinCap( p, pPin, "max_transition" ) );
1645 Vec_StrPutI_( vOut, Vec_PtrSize(vNameIns) );
1646 pFormula = Scl_LibertyReadPinFormula(p, pPin);
1647 Vec_StrPutS_( vOut, pFormula );
1648 // write truth table
1649 vTruth = Mio_ParseFormulaTruth( pFormula, (char **)Vec_PtrArray(vNameIns), Vec_PtrSize(vNameIns) );
1650 if ( vTruth == NULL )
1651 return NULL;
1652 for ( i = 0; i < Abc_Truth6WordNum(Vec_PtrSize(vNameIns)); i++ )
1653 Vec_StrPutW_( vOut, Vec_WrdEntry(vTruth, i) );
1654 Vec_WrdFree( vTruth );
1655 Vec_StrPut_( vOut );
1656 Vec_StrPut_( vOut );
1657
1658 // write the delay tables
1659 if ( fUseFirstTable )
1660 {
1661 Vec_PtrForEachEntry( char *, vNameIns, pName, i )
1662 {
1663 pTiming = Scl_LibertyReadPinTiming( p, pPin, pName );
1664 Vec_StrPutS_( vOut, pName );
1665 Vec_StrPutI_( vOut, (int)(pTiming != NULL) );
1666 if ( pTiming == NULL ) // output does not depend on input
1667 continue;
1668 Vec_StrPutI_( vOut, Scl_LibertyReadTimingSense(p, pTiming) );
1669 Vec_StrPut_( vOut );
1670 Vec_StrPut_( vOut );
1671 // some cells only have 'rise' or 'fall' but not both - here we work around this
1672 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_rise", vTemples ) )
1673 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_fall", vTemples ) )
1674 { printf( "Table cannot be found\n" ); return NULL; }
1675 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_fall", vTemples ) )
1676 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "cell_rise", vTemples ) )
1677 { printf( "Table cannot be found\n" ); return NULL; }
1678 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
1679 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
1680 { printf( "Table cannot be found\n" ); return NULL; }
1681 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "fall_transition", vTemples ) )
1682 if ( !Scl_LibertyReadTable( p, vOut, pTiming, "rise_transition", vTemples ) )
1683 { printf( "Table cannot be found\n" ); return NULL; }
1684 }
1685 continue;
1686 }
1687
1688 // write the timing tables
1689 Vec_PtrForEachEntry( char *, vNameIns, pName, i )
1690 {
1691 Vec_Ptr_t * vTables[4];
1692 Vec_Ptr_t * vTimings;
1693 vTimings = Scl_LibertyReadPinTimingAll( p, pPin, pName );
1694 Vec_StrPutS_( vOut, pName );
1695 Vec_StrPutI_( vOut, (int)(Vec_PtrSize(vTimings) != 0) );
1696 if ( Vec_PtrSize(vTimings) == 0 ) // output does not depend on input
1697 {
1698 Vec_PtrFree( vTimings );
1699 continue;
1700 }
1701 Vec_StrPutI_( vOut, Scl_LibertyReadTimingSense(p, (Scl_Item_t *)Vec_PtrEntry(vTimings, 0)) );
1702 Vec_StrPut_( vOut );
1703 Vec_StrPut_( vOut );
1704 // collect the timing tables
1705 for ( k = 0; k < 4; k++ )
1706 vTables[k] = Vec_PtrAlloc( 16 );
1707 Vec_PtrForEachEntry( Scl_Item_t *, vTimings, pTiming, k )
1708 {
1709 // some cells only have 'rise' or 'fall' but not both - here we work around this
1710 if ( !Scl_LibertyScanTable( p, vTables[0], pTiming, "cell_rise", vTemples ) )
1711 if ( !Scl_LibertyScanTable( p, vTables[0], pTiming, "cell_fall", vTemples ) )
1712 { printf( "Table cannot be found\n" ); return NULL; }
1713 if ( !Scl_LibertyScanTable( p, vTables[1], pTiming, "cell_fall", vTemples ) )
1714 if ( !Scl_LibertyScanTable( p, vTables[1], pTiming, "cell_rise", vTemples ) )
1715 { printf( "Table cannot be found\n" ); return NULL; }
1716 if ( !Scl_LibertyScanTable( p, vTables[2], pTiming, "rise_transition", vTemples ) )
1717 if ( !Scl_LibertyScanTable( p, vTables[2], pTiming, "fall_transition", vTemples ) )
1718 { printf( "Table cannot be found\n" ); return NULL; }
1719 if ( !Scl_LibertyScanTable( p, vTables[3], pTiming, "fall_transition", vTemples ) )
1720 if ( !Scl_LibertyScanTable( p, vTables[3], pTiming, "rise_transition", vTemples ) )
1721 { printf( "Table cannot be found\n" ); return NULL; }
1722 }
1723 Vec_PtrFree( vTimings );
1724 // compute worse case of the tables
1725 for ( k = 0; k < 4; k++ )
1726 {
1727 Vec_Flt_t * vInd0, * vInd1, * vValues;
1728 if ( !Scl_LibertyComputeWorstCase( vTables[k], &vInd0, &vInd1, &vValues ) )
1729 { printf( "Table indexes have different values\n" ); return NULL; }
1730 Vec_VecFree( (Vec_Vec_t *)vTables[k] );
1731 Scl_LibertyDumpTables( vOut, vInd0, vInd1, vValues );
1732 Vec_FltFree( vInd0 );
1733 Vec_FltFree( vInd1 );
1734 Vec_FltFree( vValues );
1735 }
1736 }
1737 }
1738 Vec_StrPut_( vOut );
1739 Vec_PtrFreeFree( vNameIns );
1740 }
1741 // free templates
1742 if ( vTemples )
1743 {
1744 Vec_Flt_t * vArray;
1745 assert( Vec_PtrSize(vTemples) % 4 == 0 );
1746 Vec_PtrForEachEntry( Vec_Flt_t *, vTemples, vArray, i )
1747 {
1748 if ( vArray == NULL )
1749 continue;
1750 if ( i % 4 == 0 )
1751 ABC_FREE( vArray );
1752 else if ( i % 4 == 2 || i % 4 == 3 )
1753 Vec_FltFree( vArray );
1754 }
1755 Vec_PtrFree( vTemples );
1756 }
1757 if ( fVerbose )
1758 {
1759 printf( "Library \"%s\" from \"%s\" has %d cells ",
1760 Scl_LibertyReadString(p, Scl_LibertyRoot(p)->Head), p->pFileName, nCells );
1761 printf( "(%d skipped: %d seq; %d tri-state; %d no func; %d dont_use; %d with 2 outputs; %d with 3+ outputs). ",
1762 nSkipped[0]+nSkipped[1]+nSkipped[2]+nSkipped[3]+nSkipped[4]+nSkipped[5],
1763 nSkipped[0],nSkipped[1],nSkipped[2],nSkipped[3],nSkipped[5],nSkipped[4] );
1764 Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
1765 }
1766 return vOut;
1767}
#define ABC_FREE(obj)
Definition abc_global.h:267
Vec_Wrd_t * Mio_ParseFormulaTruth(char *pFormInit, char **ppVarNames, int nVars)
Definition mioParse.c:396
#define ABC_SCL_CUR_VERSION
INCLUDES ///.
Definition sclLib.h:43
char * Scl_LibertyReadDefaultWireLoad(Scl_Tree_t *p)
Definition sclLiberty.c:894
void Scl_LibertyReadLoadUnit(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition sclLiberty.c:935
void Scl_LibertyReadWireLoad(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition sclLiberty.c:956
Vec_Ptr_t * Scl_LibertyReadTemplates(Scl_Tree_t *p)
int Scl_LibertyReadTable(Scl_Tree_t *p, Vec_Str_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
Scl_Item_t * Scl_LibertyReadPinTiming(Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
void Scl_LibertyDumpTables(Vec_Str_t *vOut, Vec_Flt_t *vInd1, Vec_Flt_t *vInd2, Vec_Flt_t *vValues)
int Scl_LibertyReadTimeUnit(Scl_Tree_t *p)
Definition sclLiberty.c:915
long Scl_LibertyItemNum(Scl_Tree_t *p, Scl_Item_t *pRoot, char *pName)
Definition sclLiberty.c:391
int Scl_LibertyScanTable(Scl_Tree_t *p, Vec_Ptr_t *vOut, Scl_Item_t *pTiming, char *pName, Vec_Ptr_t *vTemples)
void Scl_LibertyReadWireLoadSelect(Scl_Tree_t *p, Vec_Str_t *vOut)
Definition sclLiberty.c:984
char * Scl_LibertyReadDefaultWireLoadSel(Scl_Tree_t *p)
Definition sclLiberty.c:901
float Scl_LibertyReadPinCap(Scl_Tree_t *p, Scl_Item_t *pPin, char *pName)
int Scl_LibertyReadPinDirection(Scl_Tree_t *p, Scl_Item_t *pPin)
Vec_Ptr_t * Scl_LibertyReadPinTimingAll(Scl_Tree_t *p, Scl_Item_t *pPinOut, char *pNameIn)
int Scl_LibertyComputeWorstCase(Vec_Ptr_t *vTables, Vec_Flt_t **pvInd0, Vec_Flt_t **pvInd1, Vec_Flt_t **pvValues)
int Scl_LibertyReadDeriveStrength(Scl_Tree_t *p, Scl_Item_t *pCell)
int Scl_LibertyReadTimingSense(Scl_Tree_t *p, Scl_Item_t *pPin)
char * Scl_LibertyReadCellLeakage(Scl_Tree_t *p, Scl_Item_t *pCell)
Definition sclLiberty.c:738
float Scl_LibertyReadDefaultMaxTrans(Scl_Tree_t *p)
Definition sclLiberty.c:908
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadString()

char * Scl_LibertyReadString ( Scl_Tree_t * p,
Scl_Pair_t Pair )

Function*************************************************************

Synopsis [Gets the name to write.]

Description []

SideEffects []

SeeAlso []

Definition at line 374 of file sclLiberty.c.

375{
376 // static char Buffer[ABC_MAX_LIB_STR_LEN];
377 char * Buffer;
378 if ( Pair.End - Pair.Beg + 2 > Vec_StrSize(p->vBuffer) )
379 Vec_StrFill( p->vBuffer, Pair.End - Pair.Beg + 100, '\0' );
380 Buffer = Vec_StrArray( p->vBuffer );
381 strncpy( Buffer, p->pContents+Pair.Beg, Pair.End-Pair.Beg );
382 if ( Pair.Beg < Pair.End && Buffer[0] == '\"' )
383 {
384 assert( Buffer[Pair.End-Pair.Beg-1] == '\"' );
385 Buffer[Pair.End-Pair.Beg-1] = 0;
386 return Buffer + 1;
387 }
388 Buffer[Pair.End-Pair.Beg] = 0;
389 return Buffer;
390}
char * strncpy()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadTable()

int Scl_LibertyReadTable ( Scl_Tree_t * p,
Vec_Str_t * vOut,
Scl_Item_t * pTiming,
char * pName,
Vec_Ptr_t * vTemples )

Definition at line 1283 of file sclLiberty.c.

1284{
1285 Vec_Flt_t * vIndex1 = NULL;
1286 Vec_Flt_t * vIndex2 = NULL;
1287 Vec_Flt_t * vValues = NULL;
1288 Vec_Flt_t * vInd1, * vInd2;
1289 Scl_Item_t * pItem, * pTable = NULL;
1290 char * pThis, * pTempl = NULL;
1291 int iPlace, i;
1292 float Entry;
1293 // find the table
1294 Scl_ItemForEachChildName( p, pTiming, pTable, pName )
1295 break;
1296 if ( pTable == NULL )
1297 return 0;
1298 // find the template
1299 pTempl = Scl_LibertyReadString(p, pTable->Head);
1300 if ( pTempl == NULL || pTempl[0] == 0 )
1301 {
1302 // read the numbers
1303 Scl_ItemForEachChild( p, pTable, pItem )
1304 {
1305 if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1306 assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1307 else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1308 assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1309 else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1310 assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1311 }
1312 if ( vIndex1 == NULL || vIndex2 == NULL || vValues == NULL )
1313 { printf( "Incomplete table specification\n" ); return 0; }
1314 // dump the table
1315 vInd1 = vIndex1;
1316 vInd2 = vIndex2;
1317 // write entries
1318 Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1319 Vec_FltForEachEntry( vInd1, Entry, i )
1320 Vec_StrPutF_( vOut, Entry );
1321 Vec_StrPut_( vOut );
1322 // write entries
1323 Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1324 Vec_FltForEachEntry( vInd2, Entry, i )
1325 Vec_StrPutF_( vOut, Entry );
1326 Vec_StrPut_( vOut );
1327 Vec_StrPut_( vOut );
1328 // write entries
1329 assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1330 Vec_FltForEachEntry( vValues, Entry, i )
1331 {
1332 Vec_StrPutF_( vOut, Entry );
1333 if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1334 Vec_StrPut_( vOut );
1335 }
1336 }
1337 else
1338 {
1339 // fetch the template
1340 iPlace = -1;
1341 Vec_PtrForEachEntry( char *, vTemples, pThis, i )
1342 if ( i % 4 == 0 && !strcmp(pTempl, pThis) )
1343 {
1344 iPlace = i;
1345 break;
1346 }
1347 if ( iPlace == -1 )
1348 { printf( "Template cannot be found in the template library\n" ); return 0; }
1349 // read the numbers
1350 Scl_ItemForEachChild( p, pTable, pItem )
1351 {
1352 if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1353 assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1354 else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1355 assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1356 else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1357 assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1358 }
1359 // check the template style
1360 vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
1361 vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
1362 if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
1363 {
1364 assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
1365 assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd2) );
1366 vInd1 = vIndex1 ? vIndex1 : vInd1;
1367 vInd2 = vIndex2 ? vIndex2 : vInd2;
1368 // write entries
1369 Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1370 Vec_FltForEachEntry( vInd1, Entry, i )
1371 Vec_StrPutF_( vOut, Entry );
1372 Vec_StrPut_( vOut );
1373 // write entries
1374 Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1375 Vec_FltForEachEntry( vInd2, Entry, i )
1376 Vec_StrPutF_( vOut, Entry );
1377 Vec_StrPut_( vOut );
1378 Vec_StrPut_( vOut );
1379 // write entries
1380 assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1381 Vec_FltForEachEntry( vValues, Entry, i )
1382 {
1383 Vec_StrPutF_( vOut, Entry );
1384 if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1385 Vec_StrPut_( vOut );
1386 }
1387 }
1388 else // reverse order (vIndex2 is slew; vIndex1 is load)
1389 {
1390 assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd1) );
1391 assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd2) );
1392 vInd1 = vIndex2 ? vIndex2 : vInd1;
1393 vInd2 = vIndex1 ? vIndex1 : vInd2;
1394 // write entries
1395 Vec_StrPutI_( vOut, Vec_FltSize(vInd1) );
1396 Vec_FltForEachEntry( vInd1, Entry, i )
1397 Vec_StrPutF_( vOut, Entry );
1398 Vec_StrPut_( vOut );
1399 // write entries
1400 Vec_StrPutI_( vOut, Vec_FltSize(vInd2) );
1401 Vec_FltForEachEntry( vInd2, Entry, i )
1402 Vec_StrPutF_( vOut, Entry );
1403 Vec_StrPut_( vOut );
1404 Vec_StrPut_( vOut );
1405 // write entries -- transpose
1406 assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1407 Vec_FltForEachEntry( vValues, Entry, i )
1408 {
1409 int x = i % Vec_FltSize(vInd2);
1410 int y = i / Vec_FltSize(vInd2);
1411 Entry = Vec_FltEntry( vValues, x * Vec_FltSize(vInd1) + y );
1412 Vec_StrPutF_( vOut, Entry );
1413 if ( i % Vec_FltSize(vInd2) == Vec_FltSize(vInd2)-1 )
1414 Vec_StrPut_( vOut );
1415 }
1416 }
1417 }
1418 Vec_StrPut_( vOut );
1419 for ( i = 0; i < 3; i++ )
1420 Vec_StrPutF_( vOut, 0 );
1421 for ( i = 0; i < 4; i++ )
1422 Vec_StrPutF_( vOut, 0 );
1423 for ( i = 0; i < 6; i++ )
1424 Vec_StrPutF_( vOut, 0 );
1425 Vec_FltFreeP( &vIndex1 );
1426 Vec_FltFreeP( &vIndex2 );
1427 Vec_FltFreeP( &vValues );
1428 Vec_StrPut_( vOut );
1429 Vec_StrPut_( vOut );
1430 return 1;
1431}
Vec_Flt_t * Scl_LibertyReadFloatVec(char *pName)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadTemplates()

Vec_Ptr_t * Scl_LibertyReadTemplates ( Scl_Tree_t * p)

Definition at line 1449 of file sclLiberty.c.

1450{
1451 Vec_Ptr_t * vRes = NULL;
1452 Vec_Flt_t * vIndex1, * vIndex2;
1453 Scl_Item_t * pTempl, * pItem;
1454 char * pVar1, * pVar2;
1455 int fFlag0, fFlag1;
1456 vRes = Vec_PtrAlloc( 100 );
1457 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pTempl, "lu_table_template" )
1458 {
1459 pVar1 = pVar2 = NULL;
1460 vIndex1 = vIndex2 = NULL;
1461 Scl_ItemForEachChild( p, pTempl, pItem )
1462 {
1463 if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1464 assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1465 else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1466 assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1467 else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_1") )
1468 assert(pVar1 == NULL), pVar1 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
1469 else if ( !Scl_LibertyCompare(p, pItem->Key, "variable_2") )
1470 assert(pVar2 == NULL), pVar2 = Abc_UtilStrsav( Scl_LibertyReadString(p, pItem->Head) );
1471 }
1472 if ( pVar1 == NULL || pVar2 == NULL )
1473 {
1474 ABC_FREE( pVar1 );
1475 ABC_FREE( pVar2 );
1476 Vec_FltFreeP( &vIndex1 );
1477 Vec_FltFreeP( &vIndex2 );
1478 continue;
1479 }
1480 assert( pVar1 != NULL && pVar2 != NULL );
1481 fFlag0 = (!strcmp(pVar1, "input_net_transition") && !strcmp(pVar2, "total_output_net_capacitance"));
1482 fFlag1 = (!strcmp(pVar2, "input_net_transition") && !strcmp(pVar1, "total_output_net_capacitance"));
1483 ABC_FREE( pVar1 );
1484 ABC_FREE( pVar2 );
1485 if ( !fFlag0 && !fFlag1 )
1486 {
1487 Vec_FltFreeP( &vIndex1 );
1488 Vec_FltFreeP( &vIndex2 );
1489 continue;
1490 }
1491 Vec_PtrPush( vRes, Abc_UtilStrsav( Scl_LibertyReadString(p, pTempl->Head) ) );
1492 Vec_PtrPush( vRes, fFlag0 ? NULL : (void *)(ABC_PTRINT_T)1 );
1493 Vec_PtrPush( vRes, fFlag0 ? vIndex1 : vIndex2 );
1494 Vec_PtrPush( vRes, fFlag0 ? vIndex2 : vIndex1 );
1495 }
1496 if ( Vec_PtrSize(vRes) == 0 )
1497 Abc_Print( 0, "Templates are not defined.\n" );
1498 // print templates
1499// printf( "Found %d templates\n", Vec_PtrSize(vRes)/4 );
1500// Scl_LibertyPrintTemplates( vRes );
1501 return vRes;
1502}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadTimeUnit()

int Scl_LibertyReadTimeUnit ( Scl_Tree_t * p)

Definition at line 915 of file sclLiberty.c.

916{
917 Scl_Item_t * pItem;
918 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "time_unit" )
919 {
920 char * pUnit = Scl_LibertyReadString(p, pItem->Head);
921 // 9=1ns, 10=100ps, 11=10ps, 12=1ps
922 if ( !strcmp(pUnit, "1ns") )
923 return 9;
924 if ( !strcmp(pUnit, "100ps") )
925 return 10;
926 if ( !strcmp(pUnit, "10ps") )
927 return 11;
928 if ( !strcmp(pUnit, "1ps") )
929 return 12;
930 break;
931 }
932 printf( "Liberty parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" );
933 return 9;
934}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadTimingSense()

int Scl_LibertyReadTimingSense ( Scl_Tree_t * p,
Scl_Item_t * pPin )

Definition at line 1062 of file sclLiberty.c.

1063{
1064 Scl_Item_t * pItem;
1065 Scl_ItemForEachChildName( p, pPin, pItem, "timing_sense" )
1066 {
1067 char * pToken = Scl_LibertyReadString(p, pItem->Head);
1068 if ( !strcmp(pToken, "positive_unate") )
1069 return sc_ts_Pos;
1070 if ( !strcmp(pToken, "negative_unate") )
1071 return sc_ts_Neg;
1072 if ( !strcmp(pToken, "non_unate") )
1073 return sc_ts_Non;
1074 break;
1075 }
1076 return sc_ts_Non;
1077}
@ sc_ts_Neg
Definition sclLib.h:58
@ sc_ts_Non
Definition sclLib.h:59
@ sc_ts_Pos
Definition sclLib.h:57
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadWireLoad()

void Scl_LibertyReadWireLoad ( Scl_Tree_t * p,
Vec_Str_t * vOut )

Definition at line 956 of file sclLiberty.c.

957{
958 Scl_Item_t * pItem, * pChild;
959 Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, Scl_LibertyRoot(p), "wire_load") );
960 Vec_StrPut_( vOut );
961 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load" )
962 {
963 Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) );
964 Scl_ItemForEachChildName( p, pItem, pChild, "capacitance" )
965 Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) );
966 Scl_ItemForEachChildName( p, pItem, pChild, "slope" )
967 Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) );
968 Vec_StrPut_( vOut );
969 Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "fanout_length") );
970 Vec_StrPut_( vOut );
971 Scl_ItemForEachChildName( p, pItem, pChild, "fanout_length" )
972 {
973 char * pHead = Scl_LibertyReadString(p, pChild->Head);
974 int First = atoi( strtok(pHead, " ,") );
975 float Second = atof( strtok(NULL, " ") );
976 Vec_StrPutI_( vOut, First );
977 Vec_StrPutF_( vOut, Second );
978 Vec_StrPut_( vOut );
979 }
980 Vec_StrPut_( vOut );
981 }
982 Vec_StrPut_( vOut );
983}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyReadWireLoadSelect()

void Scl_LibertyReadWireLoadSelect ( Scl_Tree_t * p,
Vec_Str_t * vOut )

Definition at line 984 of file sclLiberty.c.

985{
986 Scl_Item_t * pItem, * pChild;
987 Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, Scl_LibertyRoot(p), "wire_load_selection") );
988 Vec_StrPut_( vOut );
989 Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load_selection" )
990 {
991 Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) );
992 Vec_StrPut_( vOut );
993 Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "wire_load_from_area") );
994 Vec_StrPut_( vOut );
995 Scl_ItemForEachChildName( p, pItem, pChild, "wire_load_from_area" )
996 {
997 char * pHead = Scl_LibertyReadString(p, pChild->Head);
998 float First = atof( strtok(pHead, " ,") );
999 float Second = atof( strtok(NULL, " ,") );
1000 char * pThird = strtok(NULL, " ");
1001 if ( pThird[0] == '\"' )
1002 assert(pThird[strlen(pThird)-1] == '\"'), pThird[strlen(pThird)-1] = 0, pThird++;
1003 Vec_StrPutF_( vOut, First );
1004 Vec_StrPutF_( vOut, Second );
1005 Vec_StrPutS_( vOut, pThird );
1006 Vec_StrPut_( vOut );
1007 }
1008 Vec_StrPut_( vOut );
1009 }
1010 Vec_StrPut_( vOut );
1011}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyScanTable()

int Scl_LibertyScanTable ( Scl_Tree_t * p,
Vec_Ptr_t * vOut,
Scl_Item_t * pTiming,
char * pName,
Vec_Ptr_t * vTemples )

Definition at line 1120 of file sclLiberty.c.

1121{
1122 Vec_Flt_t * vIndex1 = NULL;
1123 Vec_Flt_t * vIndex2 = NULL;
1124 Vec_Flt_t * vValues = NULL;
1125 Vec_Flt_t * vInd1, * vInd2;
1126 Scl_Item_t * pItem, * pTable = NULL;
1127 char * pThis, * pTempl = NULL;
1128 int iPlace, i;
1129 float Entry;
1130 // find the table
1131 Scl_ItemForEachChildName( p, pTiming, pTable, pName )
1132 break;
1133 if ( pTable == NULL )
1134 return 0;
1135 // find the template
1136 pTempl = Scl_LibertyReadString(p, pTable->Head);
1137 if ( pTempl == NULL || pTempl[0] == 0 )
1138 {
1139 // read the numbers
1140 Scl_ItemForEachChild( p, pTable, pItem )
1141 {
1142 if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1143 assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1144 else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1145 assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1146 else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1147 assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1148 }
1149 if ( vIndex1 == NULL || vIndex2 == NULL || vValues == NULL )
1150 { printf( "Incomplete table specification\n" ); return 0; }
1151 // dump the table
1152 vInd1 = vIndex1;
1153 vInd2 = vIndex2;
1154 // write entries
1155 Vec_PtrPush( vOut, vInd1 );
1156 Vec_PtrPush( vOut, vInd2 );
1157 Vec_PtrPush( vOut, vValues );
1158 }
1159 else if ( !strcmp(pTempl, "scalar") )
1160 {
1161 Scl_ItemForEachChild( p, pTable, pItem )
1162 if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1163 {
1164 assert(vValues == NULL);
1166 assert( Vec_FltSize(vValues) == 1 );
1167 // write entries
1168 Vec_PtrPush( vOut, Vec_IntStart(1) );
1169 Vec_PtrPush( vOut, Vec_IntStart(1) );
1170 Vec_PtrPush( vOut, vValues );
1171 break;
1172 }
1173 else
1174 { printf( "Cannot read \"scalar\" template\n" ); return 0; }
1175 }
1176 else
1177 {
1178 // fetch the template
1179 iPlace = -1;
1180 Vec_PtrForEachEntry( char *, vTemples, pThis, i )
1181 if ( i % 4 == 0 && !strcmp(pTempl, pThis) )
1182 {
1183 iPlace = i;
1184 break;
1185 }
1186 if ( iPlace == -1 )
1187 { printf( "Template cannot be found in the template library\n" ); return 0; }
1188 // read the numbers
1189 Scl_ItemForEachChild( p, pTable, pItem )
1190 {
1191 if ( !Scl_LibertyCompare(p, pItem->Key, "index_1") )
1192 assert(vIndex1 == NULL), vIndex1 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1193 else if ( !Scl_LibertyCompare(p, pItem->Key, "index_2") )
1194 assert(vIndex2 == NULL), vIndex2 = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1195 else if ( !Scl_LibertyCompare(p, pItem->Key, "values") )
1196 assert(vValues == NULL), vValues = Scl_LibertyReadFloatVec( Scl_LibertyReadString(p, pItem->Head) );
1197 }
1198 // check the template style
1199 vInd1 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 2 ); // slew
1200 vInd2 = (Vec_Flt_t *)Vec_PtrEntry( vTemples, iPlace + 3 ); // load
1201 if ( Vec_PtrEntry(vTemples, iPlace + 1) == NULL ) // normal order (vIndex1 is slew; vIndex2 is load)
1202 {
1203 assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd1) );
1204 assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd2) );
1205 vInd1 = vIndex1 ? vIndex1 : vInd1;
1206 vInd2 = vIndex2 ? vIndex2 : vInd2;
1207 // write entries
1208 Vec_PtrPush( vOut, Vec_FltDup(vInd1) );
1209 Vec_PtrPush( vOut, Vec_FltDup(vInd2) );
1210 Vec_PtrPush( vOut, Vec_FltDup(vValues) );
1211 }
1212 else // reverse order (vIndex2 is slew; vIndex1 is load)
1213 {
1214 Vec_Flt_t * vValues2 = Vec_FltAlloc( Vec_FltSize(vValues) );
1215 assert( !vIndex2 || Vec_FltSize(vIndex2) == Vec_FltSize(vInd1) );
1216 assert( !vIndex1 || Vec_FltSize(vIndex1) == Vec_FltSize(vInd2) );
1217 vInd1 = vIndex2 ? vIndex2 : vInd1;
1218 vInd2 = vIndex1 ? vIndex1 : vInd2;
1219 // write entries -- transpose
1220 assert( Vec_FltSize(vInd1) * Vec_FltSize(vInd2) == Vec_FltSize(vValues) );
1221 Vec_FltForEachEntry( vValues, Entry, i )
1222 {
1223 int x = i % Vec_FltSize(vInd2);
1224 int y = i / Vec_FltSize(vInd2);
1225 Entry = Vec_FltEntry( vValues, x * Vec_FltSize(vInd1) + y );
1226 Vec_FltPush( vValues2, Entry );
1227 }
1228 assert( Vec_FltSize(vValues) == Vec_FltSize(vValues2) );
1229 // write entries
1230 Vec_PtrPush( vOut, Vec_FltDup(vInd1) );
1231 Vec_PtrPush( vOut, Vec_FltDup(vInd2) );
1232 Vec_PtrPush( vOut, vValues2 );
1233 }
1234 Vec_FltFreeP( &vIndex1 );
1235 Vec_FltFreeP( &vIndex2 );
1236 Vec_FltFreeP( &vValues );
1237 }
1238 return 1;
1239}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyStart()

Scl_Tree_t * Scl_LibertyStart ( char * pFileName)

Function*************************************************************

Synopsis [Starts the parsing manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 635 of file sclLiberty.c.

636{
637 Scl_Tree_t * p;
638 long RetValue;
639 // read the file into the buffer
640 Scl_LibertyFixFileName( pFileName );
641 RetValue = Scl_LibertyFileSize( pFileName );
642 if ( RetValue == 0 )
643 return NULL;
644 // start the manager
645 p = ABC_ALLOC( Scl_Tree_t, 1 );
646 memset( p, 0, sizeof(Scl_Tree_t) );
647 p->clkStart = Abc_Clock();
648 p->nContents = RetValue;
649 p->pContents = Scl_LibertyFileContents( pFileName, &p->nContents );
650 // other
651 p->pFileName = Abc_UtilStrsav( pFileName );
652 p->nItermAlloc = 10 + Scl_LibertyCountItems( p->pContents, p->pContents+p->nContents );
653 p->pItems = ABC_CALLOC( Scl_Item_t, p->nItermAlloc );
654 p->nItems = 0;
655 p->nLines = 1;
656 p->vBuffer = Vec_StrStart( 10 );
657 return p;
658}
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
void Scl_LibertyFixFileName(char *pFileName)
Definition sclLiberty.c:534
char * Scl_LibertyFileContents(char *pFileName, long *nContents)
Definition sclLiberty.c:580
long Scl_LibertyFileSize(char *pFileName)
Definition sclLiberty.c:541
long Scl_LibertyCountItems(char *pBeg, char *pEnd)
Definition sclLiberty.c:185
char * memset()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Scl_LibertyStop()

void Scl_LibertyStop ( Scl_Tree_t * p,
int fVerbose )

Definition at line 659 of file sclLiberty.c.

660{
661 if ( fVerbose )
662 {
663 printf( "Memory = %7.2f MB. ", 1.0 * (p->nContents + p->nItermAlloc * sizeof(Scl_Item_t))/(1<<20) );
664 ABC_PRT( "Time", Abc_Clock() - p->clkStart );
665 }
666 Vec_StrFree( p->vBuffer );
667 ABC_FREE( p->pFileName );
668 ABC_FREE( p->pContents );
669 ABC_FREE( p->pItems );
670 ABC_FREE( p->pError );
671 ABC_FREE( p );
672}
#define ABC_PRT(a, t)
Definition abc_global.h:255
Here is the caller graph for this function:

◆ Scl_LibertyStringDump()

void Scl_LibertyStringDump ( char * pFileName,
Vec_Str_t * vStr )

Definition at line 611 of file sclLiberty.c.

612{
613 FILE * pFile = fopen( pFileName, "wb" );
614 long RetValue = 0;
615 if ( pFile == NULL )
616 {
617 printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" );
618 return;
619 }
620 RetValue = fwrite( Vec_StrArray(vStr), 1, Vec_StrSize(vStr), pFile );
621 fclose( pFile );
622}
Here is the caller graph for this function:

◆ Scl_LibertyTest()

void Scl_LibertyTest ( )

Function*************************************************************

Synopsis [Experiments with Liberty parsing.]

Description []

SideEffects []

SeeAlso []

Definition at line 1804 of file sclLiberty.c.

1805{
1806 char * pFileName = "bwrc.lib";
1807 int fVerbose = 1;
1808 int fVeryVerbose = 0;
1809 Scl_Tree_t * p;
1810 Vec_Str_t * vStr;
1811// return;
1812 p = Scl_LibertyParse( pFileName, fVeryVerbose );
1813 if ( p == NULL )
1814 return;
1815// Scl_LibertyParseDump( p, "temp_.lib" );
1816 SC_DontUse dont_use = {0};
1817 vStr = Scl_LibertyReadSclStr( p, fVerbose, fVeryVerbose, dont_use, 0);
1818 Scl_LibertyStringDump( "test_scl.lib", vStr );
1819 Vec_StrFree( vStr );
1820 Scl_LibertyStop( p, fVerbose );
1821}
struct SC_DontUse_ SC_DontUse
Definition sclLib.h:62
void Scl_LibertyStringDump(char *pFileName, Vec_Str_t *vStr)
Definition sclLiberty.c:611
Here is the call graph for this function:

◆ Scl_LibertyWipeOutComments()

void Scl_LibertyWipeOutComments ( char * pBeg,
char * pEnd )

Definition at line 208 of file sclLiberty.c.

209{
210 char * pCur, * pStart;
211 for ( pCur = pBeg; pCur < pEnd-1; pCur++ )
212 if ( pCur[0] == '/' && pCur[1] == '*' )
213 {
214 for ( pStart = pCur; pCur < pEnd-1; pCur++ )
215 if ( pCur[0] == '*' && pCur[1] == '/' )
216 {
217 for ( ; pStart < pCur + 2; pStart++ )
218 if ( *pStart != '\n' ) *pStart = ' ';
219 break;
220 }
221 }
222 else if ( pCur[0] == '/' && pCur[1] == '/' )
223 {
224 for ( pStart = pCur; pCur < pEnd; pCur++ )
225 if ( pCur[0] == '\n' || pCur == pEnd-1 )
226 {
227 for ( ; pStart < pCur; pStart++ ) *pStart = ' ';
228 break;
229 }
230 }
231}
Here is the caller graph for this function: