diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2009-01-18 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2009-01-18 08:01:00 -0800 |
commit | f936cc0680c98ffe51b3a1716c996072d5dbf76c (patch) | |
tree | 784a2a809fb6b972ec6a8e2758ab758ca590d01a /src/map/amap/amapRead.c | |
parent | c9ad5880cc61787dec6d018111b63023407ce0e6 (diff) | |
download | abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.gz abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.bz2 abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.zip |
Version abc90118
Diffstat (limited to 'src/map/amap/amapRead.c')
-rw-r--r-- | src/map/amap/amapRead.c | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/src/map/amap/amapRead.c b/src/map/amap/amapRead.c new file mode 100644 index 00000000..182de5d1 --- /dev/null +++ b/src/map/amap/amapRead.c @@ -0,0 +1,412 @@ +/**CFile**************************************************************** + + FileName [amapRead.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Technology mapper for standard cells.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: amapRead.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "amapInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define AMAP_STRING_GATE "GATE" +#define AMAP_STRING_PIN "PIN" +#define AMAP_STRING_NONINV "NONINV" +#define AMAP_STRING_INV "INV" +#define AMAP_STRING_UNKNOWN "UNKNOWN" + +// these symbols (and no other) can appear in the formulas +#define AMAP_SYMB_AND '*' +#define AMAP_SYMB_OR1 '+' +#define AMAP_SYMB_OR2 '|' +#define AMAP_SYMB_XOR '^' +#define AMAP_SYMB_NOT '!' +#define AMAP_SYMB_AFTNOT '\'' +#define AMAP_SYMB_OPEN '(' +#define AMAP_SYMB_CLOSE ')' + +typedef enum { + AMAP_PHASE_UNKNOWN, + AMAP_PHASE_INV, + AMAP_PHASE_NONINV +} Amap_PinPhase_t; + +static inline Amap_Gat_t * Amap_ParseGateAlloc( Aig_MmFlex_t * p, int nPins ) +{ return (Amap_Gat_t *)Aig_MmFlexEntryFetch( p, sizeof(Amap_Gat_t)+sizeof(Amap_Pin_t)*nPins ); } +static inline char * Amap_ParseStrsav( Aig_MmFlex_t * p, char * pStr ) +{ return pStr ? strcpy(Aig_MmFlexEntryFetch(p, strlen(pStr)+1), pStr) : NULL; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Loads the file into temporary buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Amap_LoadFile( char * pFileName ) +{ + extern FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mode, int fVerbose ); + FILE * pFile; + char * pBuffer; + int nFileSize; + // open the BLIF file for binary reading + pFile = Io_FileOpen( pFileName, "open_path", "rb", 1 ); +// pFile = fopen( FileName, "rb" ); + // if we got this far, file should be okay otherwise would + // have been detected by caller + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\".\n", pFileName ); + return NULL; + } + assert ( pFile != NULL ); + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + // move the file current reading position to the beginning + rewind( pFile ); + // load the contents of the file into memory + pBuffer = ALLOC( char, nFileSize + 10 ); + fread( pBuffer, nFileSize, 1, pFile ); + // terminate the string with '\0' + pBuffer[ nFileSize ] = '\0'; + strcat( pBuffer, "\n.end\n" ); + // close file + fclose( pFile ); + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Eliminates comments from the input file.] + + Description [As a byproduct, this procedure also counts the number + lines and dot-statements in the input file. This also joins non-comment + lines that are joined with a backspace '\'] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Amap_RemoveComments( char * pBuffer, int * pnDots, int * pnLines ) +{ + char * pCur; + int nDots, nLines; + // scan through the buffer and eliminate comments + // (in the BLIF file, comments are lines starting with "#") + nDots = nLines = 0; + for ( pCur = pBuffer; *pCur; pCur++ ) + { + // if this is the beginning of comment + // clean it with spaces until the new line statement + if ( *pCur == '#' ) + while ( *pCur != '\n' ) + *pCur++ = ' '; + + // count the number of new lines and dots + if ( *pCur == '\n' ) { + if (*(pCur-1)=='\r') { + // DOS(R) file support + if (*(pCur-2)!='\\') nLines++; + else { + // rewind to backslash and overwrite with a space + *(pCur-2) = ' '; + *(pCur-1) = ' '; + *pCur = ' '; + } + } else { + // UNIX(TM) file support + if (*(pCur-1)!='\\') nLines++; + else { + // rewind to backslash and overwrite with a space + *(pCur-1) = ' '; + *pCur = ' '; + } + } + } + else if ( *pCur == '.' ) + nDots++; + } + if ( pnDots ) + *pnDots = nDots; + if ( pnLines ) + *pnLines = nLines; +} + +/**Function************************************************************* + + Synopsis [Splits the stream into tokens.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Amap_DeriveTokens( char * pBuffer ) +{ + Vec_Ptr_t * vTokens; + char * pToken; + vTokens = Vec_PtrAlloc( 1000 ); + pToken = strtok( pBuffer, " ;=\t\r\n" ); + while ( pToken ) + { + Vec_PtrPush( vTokens, pToken ); + pToken = strtok( NULL, " ;=\t\r\n" ); + } + return vTokens; +} + +/**Function************************************************************* + + Synopsis [Finds the number of pins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_ParseCountPins( Vec_Ptr_t * vTokens, int iPos ) +{ + char * pToken; + int i, Counter = 0; + Vec_PtrForEachEntryStart( vTokens, pToken, i, iPos ) + if ( !strcmp( pToken, AMAP_STRING_PIN ) ) + Counter++; + else if ( !strcmp( pToken, AMAP_STRING_GATE ) ) + return Counter; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Collect the pin names used in the formula.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_GateCollectNames( Aig_MmFlex_t * pMem, char * pForm, char * pPinNames[] ) +{ + char Buffer[1000]; + char * pTemp; + int nPins, i; + // save the formula as it was + strcpy( Buffer, pForm ); + // remove the non-name symbols + for ( pTemp = Buffer; *pTemp; pTemp++ ) + if ( *pTemp == AMAP_SYMB_AND || *pTemp == AMAP_SYMB_OR1 || *pTemp == AMAP_SYMB_OR2 + || *pTemp == AMAP_SYMB_XOR || *pTemp == AMAP_SYMB_NOT || *pTemp == AMAP_SYMB_OPEN + || *pTemp == AMAP_SYMB_CLOSE || *pTemp == AMAP_SYMB_AFTNOT ) + *pTemp = ' '; + // save the names + nPins = 0; + pTemp = strtok( Buffer, " " ); + while ( pTemp ) + { + for ( i = 0; i < nPins; i++ ) + if ( strcmp( pTemp, pPinNames[i] ) == 0 ) + break; + if ( i == nPins ) + { // cannot find this name; save it + pPinNames[nPins++] = Amap_ParseStrsav( pMem, pTemp ); + } + // get the next name + pTemp = strtok( NULL, " " ); + } + return nPins; +} + +/**Function************************************************************* + + Synopsis [Creates a duplicate gate with pins specified.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Gat_t * Amap_ParseGateWithSamePins( Amap_Gat_t * p ) +{ + Amap_Gat_t * pGate; + Amap_Pin_t * pPin; + char * pPinNames[128]; + int nPinNames; + assert( p->nPins == 1 && !strcmp( p->Pins->pName, "*" ) ); + nPinNames = Amap_GateCollectNames( p->pLib->pMemGates, p->pForm, pPinNames ); + pGate = Amap_ParseGateAlloc( p->pLib->pMemGates, nPinNames ); + *pGate = *p; + pGate->nPins = nPinNames; + Amap_GateForEachPin( pGate, pPin ) + { + *pPin = *p->Pins; + pPin->pName = pPinNames[pPin - pGate->Pins]; + } + return pGate; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose ) +{ + Amap_Lib_t * p; + Amap_Gat_t * pGate; + Amap_Pin_t * pPin; + char * pToken; + int nPins, iPos = 0; + p = Amap_LibAlloc(); + pToken = Vec_PtrEntry(vTokens, iPos++); + do + { + if ( strcmp( pToken, AMAP_STRING_GATE ) ) + { + printf( "The first line should begin with %s.\n", AMAP_STRING_GATE ); + return NULL; + } + // start gate + nPins = Amap_ParseCountPins( vTokens, iPos ); + pGate = Amap_ParseGateAlloc( p->pMemGates, nPins ); + memset( pGate, 0, sizeof(Amap_Gat_t) ); + pGate->Id = Vec_PtrSize( p->vGates ); + Vec_PtrPush( p->vGates, pGate ); + pGate->pLib = p; + pGate->nPins = nPins; + // read gate + pToken = Vec_PtrEntry(vTokens, iPos++); + pGate->pName = Amap_ParseStrsav( p->pMemGates, pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pGate->dArea = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pGate->pOutName = Amap_ParseStrsav( p->pMemGates, pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pGate->pForm = Amap_ParseStrsav( p->pMemGates, pToken ); + // read pins + Amap_GateForEachPin( pGate, pPin ) + { + pToken = Vec_PtrEntry(vTokens, iPos++); + if ( strcmp( pToken, AMAP_STRING_PIN ) ) + { + printf( "Cannot parse gate %s.\n", pGate->pName ); + return NULL; + } + // read pin + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->pName = Amap_ParseStrsav( p->pMemGates, pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + if ( strcmp( pToken, AMAP_STRING_UNKNOWN ) == 0 ) + pPin->Phase = AMAP_PHASE_UNKNOWN; + else if ( strcmp( pToken, AMAP_STRING_INV ) == 0 ) + pPin->Phase = AMAP_PHASE_INV; + else if ( strcmp( pToken, AMAP_STRING_NONINV ) == 0 ) + pPin->Phase = AMAP_PHASE_NONINV; + else + { + printf( "Cannot read phase of pin %s of gate %s\n", pPin->pName, pGate->pName ); + return NULL; + } + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dLoadInput = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dLoadMax = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dDelayBlockRise = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dDelayFanoutRise = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dDelayBlockFall = atof( pToken ); + pToken = Vec_PtrEntry(vTokens, iPos++); + pPin->dDelayFanoutFall = atof( pToken ); + if ( pPin->dDelayBlockRise > pPin->dDelayBlockFall ) + pPin->dDelayBlockMax = pPin->dDelayBlockRise; + else + pPin->dDelayBlockMax = pPin->dDelayBlockFall; + } + // fix the situation when all pins are represented as one + if ( pGate->nPins == 1 && !strcmp( pGate->Pins->pName, "*" ) ) + { + pGate = Amap_ParseGateWithSamePins( pGate ); + Vec_PtrPop( p->vGates ); + Vec_PtrPush( p->vGates, pGate ); + } + pToken = Vec_PtrEntry(vTokens, iPos++); + } + while ( strcmp( pToken, ".end" ) ); + return p; +} + +/**Function************************************************************* + + Synopsis [Reads the library from the input file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Amap_Lib_t * Amap_LibReadFile( char * pFileName, int fVerbose ) +{ + Amap_Lib_t * pLib; + Vec_Ptr_t * vTokens; + char * pBuffer; + pBuffer = Amap_LoadFile( pFileName ); + if ( pBuffer == NULL ) + return NULL; + Amap_RemoveComments( pBuffer, NULL, NULL ); + vTokens = Amap_DeriveTokens( pBuffer ); + pLib = Amap_ParseTokens( vTokens, fVerbose ); + if ( pLib == NULL ) + return NULL; + pLib->pName = Amap_ParseStrsav( pLib->pMemGates, pFileName ); + Vec_PtrFree( vTokens ); + free( pBuffer ); + return pLib; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |