/**CFile**************************************************************** FileName [giaGig.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Scalable AIG package.] Synopsis [Parser for Gate-Inverter Graph by Niklas Een.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: giaGig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "gia.h" #include "misc/extra/extra.h" #include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// enum { GIG_NONE = 0, GIG_RESET = 1, GIG_PI = 2, GIG_PO = 3, GIG_SEQ = 4, GIG_LUT = 5, GIG_DELAY = 6, GIG_BOX = 7, GIG_SEL = 8, GIG_BAR = 9, GIG_UNUSED = 10 }; static char * s_GigNames[GIG_UNUSED] = { "NONE", // GIG_NONE = 0 "Reset", // GIG_RESET = 1 "PI", // GIG_PI = 2 "PO", // GIG_PO = 3 "Seq", // GIG_SEQ = 4 "Lut4", // GIG_LUT = 5 "Delay", // GIG_DELAY = 6 "Box", // GIG_BOX = 7 "Sel", // GIG_SEL = 8 "Bar" // GIG_BAR = 9 }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int * Gia_ManGigCount( Vec_Int_t * vObjs, Vec_Int_t * vStore ) { static int nObjs[GIG_UNUSED]; int i; for ( i = 0; i < GIG_UNUSED; i++ ) nObjs[i] = 0; for ( i = 0; i < Vec_IntSize(vObjs); i++ ) nObjs[Vec_IntEntry(vStore, Vec_IntEntry(vObjs,i) + 1)]++; return nObjs; } void Gia_ManGigPrint( int * nObjs ) { int i; printf( "Statistics: " ); for ( i = 1; i < GIG_UNUSED; i++ ) printf( "%s = %d ", s_GigNames[i], nObjs[i] ); printf( "\n" ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManPrintDelays( Vec_Int_t * vObjs, Vec_Int_t * vStore ) { Vec_Int_t * vFanCount = Vec_IntStart( Vec_IntSize(vObjs) + 100 ); int i, * pEntry;//, Counter = 0; for ( i = 0; i < Vec_IntSize(vObjs); i++ ) { pEntry = Vec_IntEntryP( vStore, Vec_IntEntry(vObjs,i) ); if ( pEntry[1] != GIG_SEL ) continue; assert( pEntry[2] == 1 ); Vec_IntAddToEntry( vFanCount, pEntry[3], 1 ); } for ( i = 0; i < Vec_IntSize(vObjs); i++ ) { pEntry = Vec_IntEntryP( vStore, Vec_IntEntry(vObjs,i) ); if ( pEntry[1] != GIG_DELAY ) continue; printf( "(%d,%d,%d) ", pEntry[2], Vec_IntEntry(vFanCount, pEntry[0]), pEntry[3+pEntry[2]] ); } printf( "\n" ); Vec_IntFree( vFanCount ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManBuildGig2( Vec_Int_t * vObjs, Vec_Int_t * vStore, char * pFileName ) { Gia_Man_t * pNew, * pTemp; //int * nObjs = Gia_ManGigCount( vObjs, vStore ); Vec_Int_t * vNets = Vec_IntAlloc( Vec_IntSize(vObjs) ); Vec_Int_t * vTypes = Vec_IntAlloc( Vec_IntSize(vObjs) ); Vec_Int_t * vMap; int i, Type; // connect net IDs for ( i = 0; i < Vec_IntSize(vObjs); i++ ) { Vec_IntPush( vNets, Vec_IntEntry(vStore, Vec_IntEntry(vObjs,i)) ); Vec_IntPush( vTypes, Vec_IntEntry(vStore, Vec_IntEntry(vObjs,i) + 1) ); } // create mapping for net IDs into GIA IDs vMap = Vec_IntStartFull( Vec_IntFindMax(vNets) + 1 ); Vec_IntWriteEntry( vMap, 0, 0 ); Vec_IntWriteEntry( vMap, 1, 1 ); // create new manager pNew = Gia_ManStart( Vec_IntSize(vObjs) ); pNew->pName = Abc_UtilStrsav( pFileName ); pNew->pSpec = Abc_UtilStrsav( pFileName ); // create primary inputs for ( i = 0; i < Vec_IntSize(vObjs); i++ ) if ( Vec_IntEntry(vTypes, i) == GIG_PI ) Vec_IntWriteEntry( vMap, Vec_IntEntry(vNets, i), Gia_ManAppendCi(pNew) ); // create box outputs for ( i = 0; i < Vec_IntSize(vObjs); i++ ) if ( Vec_IntEntry(vTypes, i) == GIG_BOX ) Vec_IntWriteEntry( vMap, Vec_IntEntry(vNets, i), Gia_ManAppendCi(pNew) ); // create internal nodes Gia_ManHashAlloc( pNew ); for ( i = 0; i < Vec_IntSize(vObjs); i++ ) { Type = Vec_IntEntry(vTypes, i); if ( Type != GIG_LUT && Type != GIG_DELAY && Type != GIG_BAR ) continue; } Vec_IntFree( vMap ); Vec_IntFree( vNets ); Vec_IntFree( vTypes ); // rehash pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } Gia_Man_t * Gia_ManBuildGig( Vec_Int_t * vObjs, Vec_Int_t * vStore, char * pFileName ) { printf( "Parsed %d objects and %d tokens.\n", Vec_IntSize(vObjs), Vec_IntSize(vStore) ); Gia_ManGigPrint( Gia_ManGigCount(vObjs, vStore) ); Gia_ManPrintDelays( vObjs, vStore ); return NULL; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManReadGig( char * pFileName ) { Gia_Man_t * pNew; int Type, Offset, fEndOfLine, Digit, nObjs; char * pChars = " w(-,)]\r\t"; char * pBuffer = Extra_FileReadContents( pFileName ); char * pStart = pBuffer, * pToken; Vec_Int_t * vObjs, * vStore; if ( pBuffer == NULL ) printf( "Cannot open input file %s\n", pFileName ); // count objects for ( nObjs = 0, pToken = pBuffer; *pToken; pToken++ ) nObjs += (int)(*pToken == '\n'); // read objects vObjs = Vec_IntAlloc( nObjs ); vStore = Vec_IntAlloc( 10*nObjs ); while ( 1 ) { // read net ID pToken = strtok( pStart, pChars ); pStart = NULL; if ( pToken == NULL ) break; // start new object Vec_IntPush( vObjs, Vec_IntSize(vStore) ); // save net ID assert( pToken[0] >= '0' && pToken[0] <= '9' ); Vec_IntPush( vStore, atoi(pToken) ); // read equal pToken = strtok( pStart, pChars ); assert( pToken[0] == '=' ); // read type pToken = strtok( pStart, pChars ); fEndOfLine = 0; if ( pToken[strlen(pToken)-1] == '\n' ) { pToken[strlen(pToken)-1] = 0; fEndOfLine = 1; } for ( Type = GIG_RESET; Type < GIG_UNUSED; Type++ ) if ( !strcmp(pToken, s_GigNames[Type]) ) break; assert( Type < GIG_UNUSED ); Vec_IntPush( vStore, Type ); if ( fEndOfLine ) continue; // read fanins Offset = Vec_IntSize(vStore); Vec_IntPush( vStore, 0 ); while ( 1 ) { pToken = strtok( pStart, pChars ); if ( pToken == NULL || pToken[0] == '\n' || pToken[0] == '[' ) break; assert( pToken[0] >= '0' && pToken[0] <= '9' ); Vec_IntPush( vStore, atoi(pToken) ); Vec_IntAddToEntry( vStore, Offset, 1 ); } assert( pToken != NULL ); if ( pToken[0] == '\n' ) continue; assert( pToken[0] == '[' ); // read attribute pToken++; if ( Type == GIG_LUT ) { assert( strlen(pToken) == 4 ); Digit = Abc_TtReadHexDigit(pToken[0]); Digit |= Abc_TtReadHexDigit(pToken[1]) << 4; Digit |= Abc_TtReadHexDigit(pToken[2]) << 8; Digit |= Abc_TtReadHexDigit(pToken[3]) << 12; Vec_IntPush( vStore, Digit ); } else { assert( Type == GIG_DELAY ); Vec_IntPush( vStore, atoi(pToken) ); } // read end of line pToken = strtok( pStart, pChars ); assert( pToken[0] == '\n' ); } ABC_FREE( pBuffer ); // create AIG pNew = Gia_ManBuildGig( vObjs, vStore, pFileName ); // cleanup Vec_IntFree( vObjs ); Vec_IntFree( vStore ); return pNew; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END