From 0871bffae307e0553e0c5186336189e8b55cf6a6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Feb 2009 08:01:00 -0800 Subject: Version abc90215 --- src/map/amap/amapLiberty.c | 911 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 911 insertions(+) create mode 100644 src/map/amap/amapLiberty.c (limited to 'src/map/amap/amapLiberty.c') diff --git a/src/map/amap/amapLiberty.c b/src/map/amap/amapLiberty.c new file mode 100644 index 00000000..7f46ffdf --- /dev/null +++ b/src/map/amap/amapLiberty.c @@ -0,0 +1,911 @@ +/**CFile**************************************************************** + + FileHead [amapLiberty.c] + + SystemHead [ABC: Logic synthesis and verification system.] + + PackageHead [Technology mapper for standard cells.] + + Synopsis [Liberty parser.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: amapLiberty.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "amapInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// entry types +typedef enum { + AMAP_LIBERTY_NONE = 0, // 0: unknown + AMAP_LIBERTY_PROC, // 1: procedure : key(head){body} + AMAP_LIBERTY_EQUA, // 2: equation : key:head; + AMAP_LIBERTY_LIST // 3: list : key(head) +} Amap_LibertyType_t; + +typedef struct Amap_Pair_t_ Amap_Pair_t; +struct Amap_Pair_t_ +{ + int Beg; // item beginning + int End; // item end +}; + +typedef struct Amap_Item_t_ Amap_Item_t; +struct Amap_Item_t_ +{ + int Type; // Amap_LibertyType_t + int iLine; // file line where the item's spec begins + Amap_Pair_t Key; // key part + Amap_Pair_t Head; // head part + Amap_Pair_t Body; // body part + int Next; // next item in the list + int Child; // first child item +}; + +typedef struct Amap_Tree_t_ Amap_Tree_t; +struct Amap_Tree_t_ +{ + char * pFileName; // input Liberty file name + char * pContents; // file contents + int nContents; // file size + int nLines; // line counter + int nItems; // number of items + int nItermAlloc; // number of items allocated + Amap_Item_t * pItems; // the items + char * pError; // the error string +}; + +static inline Amap_Item_t * Amap_LibertyRoot( Amap_Tree_t * p ) { return p->pItems; } +static inline Amap_Item_t * Amap_LibertyItem( Amap_Tree_t * p, int v ) { assert( v < p->nItems ); return v < 0 ? NULL : p->pItems + v; } +static inline int Amap_LibertyCompare( Amap_Tree_t * p, Amap_Pair_t Pair, char * pStr ) { return strncmp( p->pContents+Pair.Beg, pStr, Pair.End-Pair.Beg ); } +static inline void Amap_PrintWord( FILE * pFile, Amap_Tree_t * p, Amap_Pair_t Pair ) { char * pBeg = p->pContents+Pair.Beg, * pEnd = p->pContents+Pair.End; while ( pBeg < pEnd ) fputc( *pBeg++, pFile ); } +static inline void Amap_PrintSpace( FILE * pFile, int nOffset ) { int i; for ( i = 0; i < nOffset; i++ ) fputc(' ', pFile); } +static inline int Amap_LibertyItemId( Amap_Tree_t * p, Amap_Item_t * pItem ) { return pItem - p->pItems; } + +#define Amap_ItemForEachChild( p, pItem, pChild ) \ + for ( pChild = Amap_LibertyItem(p, pItem->Child); pChild; pChild = Amap_LibertyItem(p, pChild->Next) ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Prints parse tree in Liberty format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Amap_LibertyPrintLibertyItem( FILE * pFile, Amap_Tree_t * p, Amap_Item_t * pItem, int nOffset ) +{ + if ( pItem->Type == AMAP_LIBERTY_PROC ) + { + Amap_PrintSpace( pFile, nOffset ); + Amap_PrintWord( pFile, p, pItem->Key ); + fprintf( pFile, "(" ); + Amap_PrintWord( pFile, p, pItem->Head ); + fprintf( pFile, ") {\n" ); + if ( Amap_LibertyItem(p, pItem->Child) ) + Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyItem(p, pItem->Child), nOffset + 1 ); + Amap_PrintSpace( pFile, nOffset ); + fprintf( pFile, "}\n" ); + } + else if ( pItem->Type == AMAP_LIBERTY_EQUA ) + { + Amap_PrintSpace( pFile, nOffset ); + Amap_PrintWord( pFile, p, pItem->Key ); + fprintf( pFile, " : " ); + Amap_PrintWord( pFile, p, pItem->Head ); + fprintf( pFile, ";\n" ); + } + else if ( pItem->Type == AMAP_LIBERTY_LIST ) + { + Amap_PrintSpace( pFile, nOffset ); + Amap_PrintWord( pFile, p, pItem->Key ); + fprintf( pFile, "(" ); + Amap_PrintWord( pFile, p, pItem->Head ); + fprintf( pFile, ");\n" ); + } + else assert( 0 ); + if ( Amap_LibertyItem(p, pItem->Next) ) + Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyItem(p, pItem->Next), nOffset ); +} + +/**Function************************************************************* + + Synopsis [Prints parse tree in Liberty format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyPrintLiberty( Amap_Tree_t * p, char * pFileName ) +{ + FILE * pFile; + if ( pFileName == NULL ) + pFile = stdout; + else + { + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + printf( "Amap_LibertyPrintLiberty(): The output file is unavailable (absent or open).\n" ); + return 0; + } + } + Amap_LibertyPrintLibertyItem( pFile, p, Amap_LibertyRoot(p), 0 ); + if ( pFile != stdout ) + fclose( pFile ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Returns the time stamp.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Amap_LibertyTimeStamp() +{ + static char Buffer[100]; + char * TimeStamp; + time_t ltime; + // get the current time + time( <ime ); + TimeStamp = asctime( localtime( <ime ) ); + TimeStamp[ strlen(TimeStamp) - 1 ] = 0; + strcpy( Buffer, TimeStamp ); + return Buffer; +} + +/**Function************************************************************* + + Synopsis [Returns cell's function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyCellIsFlop( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pAttr; + Amap_ItemForEachChild( p, pCell, pAttr ) + if ( !Amap_LibertyCompare(p, pAttr->Key, "ff") || + !Amap_LibertyCompare(p, pAttr->Key, "latch") ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns pin's function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Item_t * Amap_LibertyPinFunction( Amap_Tree_t * p, Amap_Item_t * pPin ) +{ + Amap_Item_t * pFunc; + Amap_ItemForEachChild( p, pPin, pFunc ) + if ( !Amap_LibertyCompare(p, pFunc->Key, "function") ) + return pFunc; + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns cell's function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Item_t * Amap_LibertyCellOutput( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pPin; + Amap_ItemForEachChild( p, pCell, pPin ) + { + if ( Amap_LibertyCompare(p, pPin->Key, "pin") ) + continue; + if ( Amap_LibertyPinFunction(p, pPin) ) + return pPin; + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns cell's area.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Item_t * Amap_LibertyCellArea( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pArea; + Amap_ItemForEachChild( p, pCell, pArea ) + { + if ( Amap_LibertyCompare(p, pArea->Key, "area") ) + continue; + return pArea; + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Count cell's output pins (pins with a logic function).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyCellCountOutputs( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pPin; + int Counter = 0; + Amap_ItemForEachChild( p, pCell, pPin ) + { + if ( Amap_LibertyCompare(p, pPin->Key, "pin") ) + continue; + if ( Amap_LibertyPinFunction(p, pPin) ) + Counter++; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Gets the name to write.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Amap_LibertyGetString( Amap_Tree_t * p, Amap_Pair_t Pair ) +{ + static char Buffer[256]; + strncpy( Buffer, p->pContents+Pair.Beg, Pair.End-Pair.Beg ); + Buffer[Pair.End-Pair.Beg] = 0; + return Buffer; +} + +/**Function************************************************************* + + Synopsis [Gets the name to write.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Amap_LibertyGetStringFormula( Amap_Tree_t * p, Amap_Pair_t Pair ) +{ + static char Buffer[256]; + strncpy( Buffer, p->pContents+Pair.Beg+1, Pair.End-Pair.Beg-2 ); + Buffer[Pair.End-Pair.Beg-2] = 0; + return Buffer; +} + +/**Function************************************************************* + + Synopsis [Prints parse tree in Genlib format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName ) +{ + FILE * pFile; + Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput; + int Counter; + if ( pFileName == NULL ) + pFile = stdout; + else + { + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + printf( "Amap_LibertyPrintGenlib(): The output file is unavailable (absent or open).\n" ); + return 0; + } + } + fprintf( pFile, "# This Genlib file was generated by ABC on %s\n", Amap_LibertyTimeStamp() ); + fprintf( pFile, "# The standard cell library \"%s\" is from Liberty file \"%s\"\n", Amap_LibertyGetString(p, Amap_LibertyRoot(p)->Head), p->pFileName ); + fprintf( pFile, "# (To find out more about Genlib format, google for \"sis_paper.ps\")\n" ); + + fprintf( pFile, "GATE " ); + fprintf( pFile, "%16s ", "_const0_" ); + fprintf( pFile, "%f ", 0.0 ); + fprintf( pFile, "%s=", "z" ); + fprintf( pFile, "%s;\n", "CONST0" ); + + fprintf( pFile, "GATE " ); + fprintf( pFile, "%16s ", "_const1_" ); + fprintf( pFile, "%f ", 0.0 ); + fprintf( pFile, "%s=", "z" ); + fprintf( pFile, "%s;\n", "CONST1" ); + + Amap_ItemForEachChild( p, Amap_LibertyRoot(p), pCell ) + { +/* + if ( strcmp(Amap_LibertyGetString(p, pCell->Head), "HA1SVTX1") == 0 ) + { + int s = 0; + } +*/ + if ( Amap_LibertyCompare(p, pCell->Key, "cell") ) + continue; + if ( Amap_LibertyCellIsFlop(p, pCell) ) + { + printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } + Counter = Amap_LibertyCellCountOutputs( p, pCell ); + if ( Counter == 0 ) + { + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } + if ( Counter > 1 ) + { + printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } + pArea = Amap_LibertyCellArea( p, pCell ); + if ( pArea == NULL ) + { + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } + pOutput = Amap_LibertyCellOutput( p, pCell ); + pFunc = Amap_LibertyPinFunction( p, pOutput ); + + fprintf( pFile, "GATE " ); + fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) ); + fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) ); + fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) ); + fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) ); + + Amap_ItemForEachChild( p, pCell, pPin ) + if ( pPin != pOutput && !Amap_LibertyCompare(p, pPin->Key, "pin") ) + fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) ); + } + if ( pFile != stdout ) + fclose( pFile ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyFileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Amap_LibertyFileSize(): The input file is unavailable (absent or open).\n" ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + fclose( pFile ); + return nFileSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Amap_LibertyFixFileHead( char * pFileName ) +{ + char * pHead; + for ( pHead = pFileName; *pHead; pHead++ ) + if ( *pHead == '>' ) + *pHead = '\\'; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyCountItems( char * pBeg, char * pEnd ) +{ + int Counter = 0; + for ( ; pBeg < pEnd; pBeg++ ) + Counter += (*pBeg == '(' || *pBeg == ':'); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Removes C-style comments.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Amap_LibertyWipeOutComments( char * pBeg, char * pEnd ) +{ + char * pCur, * pStart; + for ( pCur = pBeg; pCur < pEnd; pCur++ ) + if ( pCur[0] == '/' && pCur[1] == '*' ) + for ( pStart = pCur; pCur < pEnd; pCur++ ) + if ( pCur[0] == '*' && pCur[1] == '/' ) + { + for ( ; pStart < pCur + 2; pStart++ ) + if ( *pStart != '\n' ) *pStart = ' '; + break; + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the character is space.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Amap_LibertyCharIsSpace( char c ) +{ + return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\\'; +} + +/**Function************************************************************* + + Synopsis [Skips spaces.] + + Description [Returns 1 if reached the end.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Amap_LibertySkipSpaces( Amap_Tree_t * p, char ** ppPos, char * pEnd ) +{ + char * pPos = *ppPos; + for ( ; pPos < pEnd; pPos++ ) + { + if ( *pPos == '\n' ) + p->nLines++; + if ( !Amap_LibertyCharIsSpace(*pPos) ) + break; + } + *ppPos = pPos; + return pPos == pEnd; +} + +/**Function************************************************************* + + Synopsis [Skips entry delimited by " :;(){}" ] + + Description [Returns 1 if reached the end.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Amap_LibertySkipEntry( char ** ppPos, char * pEnd ) +{ + char * pPos = *ppPos; + if ( *pPos == '\"' ) + { + for ( pPos++; pPos < pEnd; pPos++ ) + if ( *pPos == '\"' ) + { + pPos++; + break; + } + } + else + { + for ( ; pPos < pEnd; pPos++ ) + if ( *pPos == ' ' || + *pPos == ':' || *pPos == ';' || + *pPos == '(' || *pPos == ')' || + *pPos == '{' || *pPos == '}' ) + break; + } + *ppPos = pPos; + return pPos == pEnd; +} + +/**Function************************************************************* + + Synopsis [Find the matching closing symbol.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char * Amap_LibertyFindMatch( char * pPos, char * pEnd ) +{ + int Counter = 0; + assert( *pPos == '(' || *pPos == '{' ); + if ( *pPos == '(' ) + { + for ( ; pPos < pEnd; pPos++ ) + { + if ( *pPos == '(' ) + Counter++; + if ( *pPos == ')' ) + Counter--; + if ( Counter == 0 ) + break; + } + } + else + { + for ( ; pPos < pEnd; pPos++ ) + { + if ( *pPos == '{' ) + Counter++; + if ( *pPos == '}' ) + Counter--; + if ( Counter == 0 ) + break; + } + } + assert( *pPos == ')' || *pPos == '}' ); + return pPos; +} + +/**Function************************************************************* + + Synopsis [Find the matching closing symbol.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Amap_Pair_t Amap_LibertyUpdateHead( Amap_Tree_t * p, Amap_Pair_t Head ) +{ + Amap_Pair_t Res; + char * pBeg = p->pContents + Head.Beg; + char * pEnd = p->pContents + Head.End; + char * pFirstNonSpace = NULL; + char * pLastNonSpace = NULL; + char * pChar; + for ( pChar = pBeg; pChar < pEnd; pChar++ ) + { + if ( *pChar == '\n' ) + p->nLines++; + if ( Amap_LibertyCharIsSpace(*pChar) ) + continue; + pLastNonSpace = pChar; + if ( pFirstNonSpace == NULL ) + pFirstNonSpace = pChar; + } + if ( pFirstNonSpace == NULL || pLastNonSpace == NULL ) + return Head; + assert( pFirstNonSpace && pLastNonSpace ); + Res.Beg = pFirstNonSpace - p->pContents; + Res.End = pLastNonSpace - p->pContents + 1; + return Res; +} + +/**Function************************************************************* + + Synopsis [Returns free item.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Amap_Item_t * Amap_LibertyNewItem( Amap_Tree_t * p, int Type ) +{ + p->pItems[p->nItems].iLine = p->nLines; + p->pItems[p->nItems].Type = Type; + p->pItems[p->nItems].Child = -1; + p->pItems[p->nItems].Next = -1; + return p->pItems + p->nItems++; +} + +/**Function************************************************************* + + Synopsis [Returns free item.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyBuildItem( Amap_Tree_t * p, char ** ppPos, char * pEnd ) +{ + Amap_Item_t * pItem; + Amap_Pair_t Key, Head, Body; + char * pNext, * pStop; + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + return -2; + Key.Beg = *ppPos - p->pContents; + if ( Amap_LibertySkipEntry( ppPos, pEnd ) ) + goto exit; + Key.End = *ppPos - p->pContents; + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + goto exit; + pNext = *ppPos; + if ( *pNext == ':' ) + { + *ppPos = pNext + 1; + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + goto exit; + Head.Beg = *ppPos - p->pContents; + if ( Amap_LibertySkipEntry( ppPos, pEnd ) ) + goto exit; + Head.End = *ppPos - p->pContents; + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + goto exit; + pNext = *ppPos; + if ( *pNext != ';' ) + goto exit; + *ppPos = pNext + 1; + // end of equation + pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_EQUA ); + pItem->Key = Key; + pItem->Head = Amap_LibertyUpdateHead( p, Head ); + pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd ); + if ( pItem->Next == -1 ) + goto exit; + return Amap_LibertyItemId( p, pItem ); + } + if ( *pNext == '(' ) + { + pStop = Amap_LibertyFindMatch( pNext, pEnd ); + Head.Beg = pNext - p->pContents + 1; + Head.End = pStop - p->pContents; + *ppPos = pStop + 1; + if ( Amap_LibertySkipSpaces( p, ppPos, pEnd ) ) + { + // end of list + pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST ); + pItem->Key = Key; + pItem->Head = Amap_LibertyUpdateHead( p, Head ); + return Amap_LibertyItemId( p, pItem ); + } + pNext = *ppPos; + if ( *pNext == '{' ) // beginning of body + { + pStop = Amap_LibertyFindMatch( pNext, pEnd ); + Body.Beg = pNext - p->pContents + 1; + Body.End = pStop - p->pContents; + // end of body + pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_PROC ); + pItem->Key = Key; + pItem->Head = Amap_LibertyUpdateHead( p, Head ); + pItem->Body = Body; + *ppPos = pNext + 1; + pItem->Child = Amap_LibertyBuildItem( p, ppPos, pStop ); + if ( pItem->Child == -1 ) + goto exit; + *ppPos = pStop + 1; + pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd ); + if ( pItem->Next == -1 ) + goto exit; + return Amap_LibertyItemId( p, pItem ); + } + // end of list + if ( *pNext == ';' ) + *ppPos = pNext + 1; + pItem = Amap_LibertyNewItem( p, AMAP_LIBERTY_LIST ); + pItem->Key = Key; + pItem->Head = Amap_LibertyUpdateHead( p, Head ); + pItem->Next = Amap_LibertyBuildItem( p, ppPos, pEnd ); + if ( pItem->Next == -1 ) + goto exit; + return Amap_LibertyItemId( p, pItem ); + } +exit: + if ( p->pError == NULL ) + { + p->pError = ABC_ALLOC( char, 1000 ); + sprintf( p->pError, "File \"%s\". Line %6d. Failed to parse entry \"%s\".\n", + p->pFileName, p->nLines, Amap_LibertyGetString(p, Key) ); + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Starts the parsing manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Tree_t * Amap_LibertyStart( char * pFileName ) +{ + FILE * pFile; + Amap_Tree_t * p; + // start the manager + p = ABC_ALLOC( Amap_Tree_t, 1 ); + memset( p, 0, sizeof(Amap_Tree_t) ); + // read the file into the buffer + Amap_LibertyFixFileHead( pFileName ); + p->nContents = Amap_LibertyFileSize( pFileName ); + if ( p->nContents == 0 ) + { + ABC_FREE( p ); + return NULL; + } + pFile = fopen( pFileName, "rb" ); + p->pContents = ABC_ALLOC( char, p->nContents+1 ); + fread( p->pContents, p->nContents, 1, pFile ); + fclose( pFile ); + p->pContents[p->nContents] = 0; + // other + p->pFileName = Aig_UtilStrsav( pFileName ); + p->nItermAlloc = 10 + Amap_LibertyCountItems( p->pContents, p->pContents+p->nContents ); + p->pItems = ABC_CALLOC( Amap_Item_t, p->nItermAlloc ); + p->nItems = 0; + p->nLines = 1; + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the parsing manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Amap_LibertyStop( Amap_Tree_t * p ) +{ + ABC_FREE( p->pFileName ); + ABC_FREE( p->pContents ); + ABC_FREE( p->pItems ); + ABC_FREE( p->pError ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Parses the standard cell library in Liberty format.] + + Description [Writes the resulting file in Genlib format.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyParse( char * pFileName, char * pFileGenlib, int fVerbose ) +{ + Amap_Tree_t * p; + char * pPos; + int clk = clock(); + int RetValue; + p = Amap_LibertyStart( pFileName ); + if ( p == NULL ) + return 0; + pPos = p->pContents; + Amap_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents ); + if ( Amap_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 ) + { + if ( fVerbose ) + printf( "Parsing finished successfully.\n" ); +// Amap_LibertyPrintLiberty( p, "temp.lib" ); + Amap_LibertyPrintGenlib( p, "temp.genlib" ); + RetValue = 1; + } + else + { + if ( p->pError ) + printf( "%s", p->pError ); + if ( fVerbose ) + printf( "Parsing failed.\n" ); + RetValue = 0; + } + if ( fVerbose ) + { + printf( "Memory = %7.2f Mb. ", 1.0*(p->nContents+p->nItermAlloc*sizeof(Amap_Item_t))/(1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + Amap_LibertyStop( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + -- cgit v1.2.3