| /**CFile**************************************************************** |
| |
| FileName [gia.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Scalable AIG package.] |
| |
| Synopsis [] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "gia.h" |
| #include "misc/extra/extra.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManPrintStateEncoding( Vec_Vec_t * vCodes, int nBits ) |
| { |
| char * pBuffer; |
| Vec_Int_t * vVec; |
| int i, k, Bit; |
| pBuffer = ABC_ALLOC( char, nBits + 1 ); |
| pBuffer[nBits] = 0; |
| Vec_VecForEachLevelInt( vCodes, vVec, i ) |
| { |
| printf( "%6d : ", i+1 ); |
| memset( pBuffer, '-', nBits ); |
| Vec_IntForEachEntry( vVec, Bit, k ) |
| { |
| assert( Bit < nBits ); |
| pBuffer[Bit] = '1'; |
| } |
| printf( "%s\n", pBuffer ); |
| } |
| ABC_FREE( pBuffer ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManCreateOrGate( Gia_Man_t * p, Vec_Int_t * vLits ) |
| { |
| if ( Vec_IntSize(vLits) == 0 ) |
| return 0; |
| while ( Vec_IntSize(vLits) > 1 ) |
| { |
| int i, k = 0, Lit1, Lit2, LitRes; |
| Vec_IntForEachEntryDouble( vLits, Lit1, Lit2, i ) |
| { |
| LitRes = Gia_ManHashOr( p, Lit1, Lit2 ); |
| Vec_IntWriteEntry( vLits, k++, LitRes ); |
| } |
| if ( Vec_IntSize(vLits) & 1 ) |
| Vec_IntWriteEntry( vLits, k++, Vec_IntEntryLast(vLits) ); |
| Vec_IntShrink( vLits, k ); |
| } |
| assert( Vec_IntSize(vLits) == 1 ); |
| return Vec_IntEntry(vLits, 0); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Vec_t * Gia_ManAssignCodes( int kHot, int nStates, int * pnBits ) |
| { |
| Vec_Vec_t * vCodes; |
| int s, i1, i2, i3, i4, i5, nBits; |
| assert( nStates > 0 ); |
| assert( kHot >= 1 && kHot <= 5 ); |
| vCodes = Vec_VecStart( nStates ); |
| *pnBits = -1; |
| if ( kHot == 1 ) |
| { |
| for ( i1 = 0; i1 < nStates; i1++ ) |
| Vec_VecPushInt( vCodes, i1, i1 ); |
| *pnBits = nStates; |
| return vCodes; |
| } |
| if ( kHot == 2 ) |
| { |
| for ( nBits = kHot; nBits < ABC_INFINITY; nBits++ ) |
| if ( nBits * (nBits-1) / 2 >= nStates ) |
| break; |
| *pnBits = nBits; |
| s = 0; |
| for ( i1 = 0; i1 < nBits; i1++ ) |
| for ( i2 = i1 + 1; i2 < nBits; i2++ ) |
| { |
| Vec_VecPushInt( vCodes, s, i1 ); |
| Vec_VecPushInt( vCodes, s, i2 ); |
| if ( ++s == nStates ) |
| return vCodes; |
| } |
| } |
| if ( kHot == 3 ) |
| { |
| for ( nBits = kHot; nBits < ABC_INFINITY; nBits++ ) |
| if ( nBits * (nBits-1) * (nBits-2) / 6 >= nStates ) |
| break; |
| *pnBits = nBits; |
| s = 0; |
| for ( i1 = 0; i1 < nBits; i1++ ) |
| for ( i2 = i1 + 1; i2 < nBits; i2++ ) |
| for ( i3 = i2 + 1; i3 < nBits; i3++ ) |
| { |
| Vec_VecPushInt( vCodes, s, i1 ); |
| Vec_VecPushInt( vCodes, s, i2 ); |
| Vec_VecPushInt( vCodes, s, i3 ); |
| if ( ++s == nStates ) |
| return vCodes; |
| } |
| } |
| if ( kHot == 4 ) |
| { |
| for ( nBits = kHot; nBits < ABC_INFINITY; nBits++ ) |
| if ( nBits * (nBits-1) * (nBits-2) * (nBits-3) / 24 >= nStates ) |
| break; |
| *pnBits = nBits; |
| s = 0; |
| for ( i1 = 0; i1 < nBits; i1++ ) |
| for ( i2 = i1 + 1; i2 < nBits; i2++ ) |
| for ( i3 = i2 + 1; i3 < nBits; i3++ ) |
| for ( i4 = i3 + 1; i4 < nBits; i4++ ) |
| { |
| Vec_VecPushInt( vCodes, s, i1 ); |
| Vec_VecPushInt( vCodes, s, i2 ); |
| Vec_VecPushInt( vCodes, s, i3 ); |
| Vec_VecPushInt( vCodes, s, i4 ); |
| if ( ++s == nStates ) |
| return vCodes; |
| } |
| } |
| if ( kHot == 5 ) |
| { |
| for ( nBits = kHot; nBits < ABC_INFINITY; nBits++ ) |
| if ( nBits * (nBits-1) * (nBits-2) * (nBits-3) * (nBits-4) / 120 >= nStates ) |
| break; |
| *pnBits = nBits; |
| s = 0; |
| for ( i1 = 0; i1 < nBits; i1++ ) |
| for ( i2 = i1 + 1; i2 < nBits; i2++ ) |
| for ( i3 = i2 + 1; i3 < nBits; i3++ ) |
| for ( i4 = i3 + 1; i4 < nBits; i4++ ) |
| for ( i5 = i4 + 1; i5 < nBits; i5++ ) |
| { |
| Vec_VecPushInt( vCodes, s, i1 ); |
| Vec_VecPushInt( vCodes, s, i2 ); |
| Vec_VecPushInt( vCodes, s, i3 ); |
| Vec_VecPushInt( vCodes, s, i4 ); |
| Vec_VecPushInt( vCodes, s, i5 ); |
| if ( ++s == nStates ) |
| return vCodes; |
| } |
| } |
| assert( 0 ); |
| return NULL; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManStgKHot( Vec_Int_t * vLines, int nIns, int nOuts, int nStates, int kHot, int fVerbose ) |
| { |
| Gia_Man_t * p, * pTemp; |
| Vec_Int_t * vInMints, * vCurs, * vVec; |
| Vec_Vec_t * vLitsNext, * vLitsOuts, * vCodes; |
| int i, b, k, nBits, LitC, Lit; |
| assert( Vec_IntSize(vLines) % 4 == 0 ); |
| |
| // produce state encoding |
| vCodes = Gia_ManAssignCodes( kHot, nStates, &nBits ); |
| assert( Vec_VecSize(vCodes) == nStates ); |
| if ( fVerbose ) |
| Gia_ManPrintStateEncoding( vCodes, nBits ); |
| |
| // start manager |
| p = Gia_ManStart( 10000 ); |
| p->pName = Abc_UtilStrsav( "stg" ); |
| for ( i = 0; i < nIns + nBits; i++ ) |
| Gia_ManAppendCi(p); |
| |
| // create input minterms |
| Gia_ManHashAlloc( p ); |
| vInMints = Vec_IntAlloc( 1 << nIns ); |
| for ( i = 0; i < (1 << nIns); i++ ) |
| { |
| for ( Lit = 1, b = 0; b < nIns; b++ ) |
| Lit = Gia_ManHashAnd( p, Lit, Abc_Var2Lit( b+1, !((i >> b) & 1) ) ); |
| Vec_IntPush( vInMints, Lit ); |
| } |
| |
| // create current states |
| vCurs = Vec_IntAlloc( nStates ); |
| Vec_VecForEachLevelInt( vCodes, vVec, i ) |
| { |
| Lit = 1; |
| Vec_IntForEachEntry( vVec, b, k ) |
| { |
| assert( b >= 0 && b < nBits ); |
| Lit = Gia_ManHashAnd( p, Lit, Abc_Var2Lit(1+nIns+b, (b<kHot)) ); |
| } |
| Vec_IntPush( vCurs, Lit ); |
| } |
| |
| // go through the lines |
| vLitsNext = Vec_VecStart( nBits ); |
| vLitsOuts = Vec_VecStart( nOuts ); |
| for ( i = 0; i < Vec_IntSize(vLines); ) |
| { |
| int iMint = Vec_IntEntry(vLines, i++); |
| int iCur = Vec_IntEntry(vLines, i++); |
| int iNext = Vec_IntEntry(vLines, i++); |
| int iOut = Vec_IntEntry(vLines, i++); |
| assert( iMint >= 0 && iMint < (1<<nIns) ); |
| assert( iCur >= 0 && iCur < nStates ); |
| assert( iNext >= 0 && iNext < nStates ); |
| assert( iOut >= 0 && iOut < (1<<nOuts) ); |
| // create condition |
| LitC = Gia_ManHashAnd( p, Vec_IntEntry(vInMints, iMint), Vec_IntEntry(vCurs, iCur) ); |
| // update next state |
| // Vec_VecPushInt( vLitsNext, iNext, LitC ); |
| vVec = (Vec_Int_t *)Vec_VecEntryInt( vCodes, iNext ); |
| Vec_IntForEachEntry( vVec, b, k ) |
| Vec_VecPushInt( vLitsNext, b, LitC ); |
| // update outputs |
| for ( b = 0; b < nOuts; b++ ) |
| if ( (iOut >> b) & 1 ) |
| Vec_VecPushInt( vLitsOuts, b, LitC ); |
| } |
| Vec_IntFree( vInMints ); |
| Vec_IntFree( vCurs ); |
| Vec_VecFree( vCodes ); |
| |
| // create POs |
| Vec_VecForEachLevelInt( vLitsOuts, vVec, b ) |
| Gia_ManAppendCo( p, Gia_ManCreateOrGate(p, vVec) ); |
| Vec_VecFree( vLitsOuts ); |
| |
| // create next states |
| Vec_VecForEachLevelInt( vLitsNext, vVec, b ) |
| Gia_ManAppendCo( p, Abc_LitNotCond( Gia_ManCreateOrGate(p, vVec), (b<kHot) ) ); |
| Vec_VecFree( vLitsNext ); |
| |
| Gia_ManSetRegNum( p, nBits ); |
| Gia_ManHashStop( p ); |
| |
| p = Gia_ManCleanup( pTemp = p ); |
| Gia_ManStop( pTemp ); |
| assert( !Gia_ManHasDangling(p) ); |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManStgOneHot( Vec_Int_t * vLines, int nIns, int nOuts, int nStates ) |
| { |
| Gia_Man_t * p, * pTemp; |
| Vec_Int_t * vInMints, * vCurs, * vVec; |
| Vec_Vec_t * vLitsNext, * vLitsOuts; |
| int i, b, LitC, Lit; |
| assert( Vec_IntSize(vLines) % 4 == 0 ); |
| |
| // start manager |
| p = Gia_ManStart( 10000 ); |
| p->pName = Abc_UtilStrsav( "stg" ); |
| for ( i = 0; i < nIns + nStates; i++ ) |
| Gia_ManAppendCi(p); |
| |
| // create input minterms |
| Gia_ManHashAlloc( p ); |
| vInMints = Vec_IntAlloc( 1 << nIns ); |
| for ( i = 0; i < (1 << nIns); i++ ) |
| { |
| for ( Lit = 1, b = 0; b < nIns; b++ ) |
| Lit = Gia_ManHashAnd( p, Lit, Abc_Var2Lit( b+1, !((i >> b) & 1) ) ); |
| Vec_IntPush( vInMints, Lit ); |
| } |
| |
| // create current states |
| vCurs = Vec_IntAlloc( nStates ); |
| for ( i = 0; i < nStates; i++ ) |
| Vec_IntPush( vCurs, Abc_Var2Lit( 1+nIns+i, !i ) ); |
| |
| // go through the lines |
| vLitsNext = Vec_VecStart( nStates ); |
| vLitsOuts = Vec_VecStart( nOuts ); |
| for ( i = 0; i < Vec_IntSize(vLines); ) |
| { |
| int iMint = Vec_IntEntry(vLines, i++); |
| int iCur = Vec_IntEntry(vLines, i++) - 1; |
| int iNext = Vec_IntEntry(vLines, i++) - 1; |
| int iOut = Vec_IntEntry(vLines, i++); |
| assert( iMint >= 0 && iMint < (1<<nIns) ); |
| assert( iCur >= 0 && iCur < nStates ); |
| assert( iNext >= 0 && iNext < nStates ); |
| assert( iOut >= 0 && iOut < (1<<nOuts) ); |
| // create condition |
| LitC = Gia_ManHashAnd( p, Vec_IntEntry(vInMints, iMint), Vec_IntEntry(vCurs, iCur) ); |
| // update next state |
| // Lit = Gia_ManHashOr( p, LitC, Vec_IntEntry(vNexts, iNext) ); |
| // Vec_IntWriteEntry( vNexts, iNext, Lit ); |
| Vec_VecPushInt( vLitsNext, iNext, LitC ); |
| // update outputs |
| for ( b = 0; b < nOuts; b++ ) |
| if ( (iOut >> b) & 1 ) |
| { |
| // Lit = Gia_ManHashOr( p, LitC, Vec_IntEntry(vOuts, b) ); |
| // Vec_IntWriteEntry( vOuts, b, Lit ); |
| Vec_VecPushInt( vLitsOuts, b, LitC ); |
| } |
| } |
| Vec_IntFree( vInMints ); |
| Vec_IntFree( vCurs ); |
| |
| // create POs |
| Vec_VecForEachLevelInt( vLitsOuts, vVec, i ) |
| Gia_ManAppendCo( p, Gia_ManCreateOrGate(p, vVec) ); |
| Vec_VecFree( vLitsOuts ); |
| |
| // create next states |
| Vec_VecForEachLevelInt( vLitsNext, vVec, i ) |
| Gia_ManAppendCo( p, Abc_LitNotCond( Gia_ManCreateOrGate(p, vVec), !i ) ); |
| Vec_VecFree( vLitsNext ); |
| |
| Gia_ManSetRegNum( p, nStates ); |
| Gia_ManHashStop( p ); |
| |
| p = Gia_ManCleanup( pTemp = p ); |
| Gia_ManStop( pTemp ); |
| assert( !Gia_ManHasDangling(p) ); |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManStgPrint( FILE * pFile, Vec_Int_t * vLines, int nIns, int nOuts, int nStates ) |
| { |
| int i, nDigits = Abc_Base10Log( nStates ); |
| assert( Vec_IntSize(vLines) % 4 == 0 ); |
| for ( i = 0; i < Vec_IntSize(vLines); i += 4 ) |
| { |
| int iMint = Vec_IntEntry(vLines, i ); |
| int iCur = Vec_IntEntry(vLines, i+1) - 1; |
| int iNext = Vec_IntEntry(vLines, i+2) - 1; |
| int iOut = Vec_IntEntry(vLines, i+3); |
| assert( iMint >= 0 && iMint < (1<<nIns) ); |
| assert( iCur >= 0 && iCur < nStates ); |
| assert( iNext >= 0 && iNext < nStates ); |
| assert( iOut >= 0 && iOut < (1<<nOuts) ); |
| Extra_PrintBinary( pFile, (unsigned *)Vec_IntEntryP(vLines, i), nIns ); |
| fprintf( pFile, " %*d", nDigits, Vec_IntEntry(vLines, i+1) ); |
| fprintf( pFile, " %*d ", nDigits, Vec_IntEntry(vLines, i+2) ); |
| Extra_PrintBinary( pFile, (unsigned *)Vec_IntEntryP(vLines, i+3), nOuts ); |
| fprintf( pFile, "\n" ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Gia_ManStgReadLines( char * pFileName, int * pnIns, int * pnOuts, int * pnStates ) |
| { |
| Vec_Int_t * vLines; |
| char pBuffer[1000]; |
| char * pToken; |
| int Number, nInputs = -1, nOutputs = -1, nStates = 1; |
| FILE * pFile; |
| if ( !strcmp(pFileName + strlen(pFileName) - 3, "aig") ) |
| { |
| printf( "Input file \"%s\" has extension \"%s\".\n", pFileName, "aig" ); |
| return NULL; |
| } |
| pFile = fopen( pFileName, "rb" ); |
| if ( pFile == NULL ) |
| { |
| printf( "Cannot open file \"%s\".\n", pFileName ); |
| return NULL; |
| } |
| vLines = Vec_IntAlloc( 1000 ); |
| while ( fgets( pBuffer, 1000, pFile ) != NULL ) |
| { |
| if ( pBuffer[0] == '.' || pBuffer[0] == '#' ) |
| continue; |
| // read condition |
| pToken = strtok( pBuffer, " \r\n" ); |
| if ( nInputs == -1 ) |
| nInputs = strlen(pToken); |
| else |
| assert( nInputs == (int)strlen(pToken) ); |
| Number = Extra_ReadBinary( pToken ); |
| Vec_IntPush( vLines, Number ); |
| // read current state |
| pToken = strtok( NULL, " \r\n" ); |
| Vec_IntPush( vLines, atoi(pToken) ); |
| nStates = Abc_MaxInt( nStates, Vec_IntEntryLast(vLines)+1 ); |
| // read next state |
| pToken = strtok( NULL, " \r\n" ); |
| Vec_IntPush( vLines, atoi(pToken) ); |
| // read output |
| pToken = strtok( NULL, " \r\n" ); |
| if ( nOutputs == -1 ) |
| nOutputs = strlen(pToken); |
| else |
| assert( nOutputs == (int)strlen(pToken) ); |
| Number = Extra_ReadBinary( pToken ); |
| Vec_IntPush( vLines, Number ); |
| } |
| fclose( pFile ); |
| if ( pnIns ) |
| *pnIns = nInputs; |
| if ( pnOuts ) |
| *pnOuts = nOutputs; |
| if ( pnStates ) |
| *pnStates = nStates; |
| return vLines; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManStgRead( char * pFileName, int kHot, int fVerbose ) |
| { |
| Gia_Man_t * p; |
| Vec_Int_t * vLines; |
| int nIns, nOuts, nStates; |
| vLines = Gia_ManStgReadLines( pFileName, &nIns, &nOuts, &nStates ); |
| if ( vLines == NULL ) |
| return NULL; |
| // p = Gia_ManStgOneHot( vLines, nIns, nOuts, nStates ); |
| p = Gia_ManStgKHot( vLines, nIns, nOuts, nStates, kHot, fVerbose ); |
| Vec_IntFree( vLines ); |
| return p; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |