summaryrefslogtreecommitdiffstats
path: root/src/map/amap/amapRead.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2009-01-18 08:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2009-01-18 08:01:00 -0800
commitf936cc0680c98ffe51b3a1716c996072d5dbf76c (patch)
tree784a2a809fb6b972ec6a8e2758ab758ca590d01a /src/map/amap/amapRead.c
parentc9ad5880cc61787dec6d018111b63023407ce0e6 (diff)
downloadabc-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.c412
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 ///
+////////////////////////////////////////////////////////////////////////
+
+