diff options
Diffstat (limited to 'src/aig/gia')
49 files changed, 13546 insertions, 303 deletions
diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index 4cbb1731..4fb33a9b 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index f023366a..3358ca76 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -21,6 +21,7 @@ #ifndef __GIA_H__ #define __GIA_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,9 +38,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define GIA_NONE 0x1FFFFFFF #define GIA_VOID 0x0FFFFFFF @@ -48,6 +50,10 @@ extern "C" { /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Gia_MmFixed_t_ Gia_MmFixed_t; +typedef struct Gia_MmFlex_t_ Gia_MmFlex_t; +typedef struct Gia_MmStep_t_ Gia_MmStep_t; + typedef struct Gia_Rpr_t_ Gia_Rpr_t; struct Gia_Rpr_t_ { @@ -88,18 +94,6 @@ struct Gia_Obj_t_ // - traversal ID of the node during traversal // - reference counter of the node (will not be used in the future) -// sequential counter-example -typedef struct Gia_Cex_t_ Gia_Cex_t; -struct Gia_Cex_t_ -{ - int iPo; // the zero-based number of PO, for which verification failed - int iFrame; // the zero-based number of the time-frame, for which verificaiton failed - int nRegs; // the number of registers in the miter - int nPis; // the number of primary inputs in the miter - int nBits; // the number of words of bit data used - unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) -}; - // new AIG manager typedef struct Gia_Man_t_ Gia_Man_t; struct Gia_Man_t_ @@ -116,8 +110,10 @@ struct Gia_Man_t_ int nHTable; // hash table size int fAddStrash; // performs additional structural hashing int * pRefs; // the reference count - int * pLevels; // levels of the nodes + int * pNodeRefs; // node references + Vec_Int_t * vLevels; // levels of the nodes int nLevels; // the mamixum level + int nConstrs; // the number of constraints int nTravIds; // the current traversal ID int nFront; // frontier size int * pReprsOld; // representatives (for CIs and ANDs) @@ -129,9 +125,11 @@ struct Gia_Man_t_ int * pFanData; // the database to store fanout information int nFansAlloc; // the size of fanout representation int * pMapping; // mapping for each node - Gia_Cex_t * pCexComb; // combinational counter-example - Gia_Cex_t * pCexSeq; // sequential counter-example + Vec_Int_t * vLutConfigs; // LUT configurations + Abc_Cex_t * pCexComb; // combinational counter-example + Abc_Cex_t * pCexSeq; // sequential counter-example int * pCopies; // intermediate copies + Vec_Int_t * vTruths; // used for truth table computation Vec_Int_t * vFlopClasses; // classes of flops for retiming/merging/etc unsigned char* pSwitching; // switching activity for each object Gia_Plc_t * pPlacement; // placement of the objects @@ -139,6 +137,12 @@ struct Gia_Man_t_ int nTravIdsAlloc; // the number of trav IDs allocated Vec_Ptr_t * vNamesIn; // the input names Vec_Ptr_t * vNamesOut; // the output names + Vec_Int_t * vCiNumsOrig; // original names of the CIs + Vec_Int_t * vCoNumsOrig; // original names of the COs + Vec_Vec_t * vClockDoms; // clock domains + Vec_Flt_t * vTiming; // arrival/required/slack + void * pManTime; // the timing manager + void * pLutLib; // LUT library }; @@ -178,26 +182,31 @@ struct Gia_ParSim_t_ int TimeLimit; // time limit in seconds int fCheckMiter; // check if miter outputs are non-zero int fVerbose; // enables verbose output + int iOutFail; // index of the failed output }; extern void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p ); extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); -static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; } -static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); } -static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); } -static inline int Gia_Base2Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } -static inline int Gia_Base10Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } -static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; } -static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } -static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } -static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } -static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } -static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); } -static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); } -static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; } +static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; } +//static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); } +//static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); } +static inline int Gia_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } +static inline float Gia_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } +static inline int Gia_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } +static inline int Gia_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } +static inline int Gia_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ); return r; } +static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; } +static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } +static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } +static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } +static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } +static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); } +static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); } +static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; } +static inline int Gia_WordHasOnePair( unsigned uWord ) { return Gia_WordHasOneBit(uWord & (uWord>>1) & 0x55555555); } static inline int Gia_WordCountOnes( unsigned uWord ) { uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555); @@ -206,7 +215,7 @@ static inline int Gia_WordCountOnes( unsigned uWord ) uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF); return (uWord & 0x0000FFFF) + (uWord>>16); } -static inline int Gia_WordFindFirstBit( unsigned uWord ) +static inline int Gia_WordFindFirstBit( unsigned uWord ) { int i; for ( i = 0; i < 32; i++ ) @@ -215,6 +224,46 @@ static inline int Gia_WordFindFirstBit( unsigned uWord ) return -1; } +static inline int Gia_ManTruthIsConst0( unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + if ( pIn[w] ) + return 0; + return 1; +} +static inline int Gia_ManTruthIsConst1( unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + if ( pIn[w] != ~(unsigned)0 ) + return 0; + return 1; +} +static inline void Gia_ManTruthCopy( unsigned * pOut, unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = pIn[w]; +} +static inline void Gia_ManTruthClear( unsigned * pOut, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = 0; +} +static inline void Gia_ManTruthFill( unsigned * pOut, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~(unsigned)0; +} +static inline void Gia_ManTruthNot( unsigned * pOut, unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~pIn[w]; +} static inline int Gia_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } static inline int Gia_Lit2Var( int Lit ) { return Lit >> 1; } @@ -236,6 +285,7 @@ static inline int Gia_ManRegNum( Gia_Man_t * p ) { return p->nRegs static inline int Gia_ManObjNum( Gia_Man_t * p ) { return p->nObjs; } static inline int Gia_ManAndNum( Gia_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos) - 1; } static inline int Gia_ManCandNum( Gia_Man_t * p ) { return Gia_ManCiNum(p) + Gia_ManAndNum(p); } +static inline int Gia_ManConstrNum( Gia_Man_t * p ) { return p->nConstrs; } static inline Gia_Obj_t * Gia_ManConst0( Gia_Man_t * p ) { return p->pObjs; } static inline Gia_Obj_t * Gia_ManConst1( Gia_Man_t * p ) { return Gia_Not(Gia_ManConst0(p)); } @@ -259,6 +309,8 @@ static inline int Gia_ManObjIsConst0( Gia_Man_t * p, Gia_Obj_t * pObj){ static inline int Gia_ObjId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pObjs <= pObj && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } static inline int Gia_ObjCioId( Gia_Obj_t * pObj ) { assert( Gia_ObjIsTerm(pObj) ); return pObj->iDiff1; } static inline void Gia_ObjSetCioId( Gia_Obj_t * pObj, int v ) { assert( Gia_ObjIsTerm(pObj) ); pObj->iDiff1 = v; } +static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } +static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; } static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; } static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); } @@ -302,10 +354,14 @@ static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, Gia_Regular(pObj)), Gia_IsComplement(pObj) ); } static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } -static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } -static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntGetEntry(p->vLevels, Gia_ObjId(p,pObj)); } +static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); } +static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Vec_IntSetEntry(p->vLevels, Gia_ObjId(p,pObj), l); } +static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); } +static inline void Gia_ObjSetAndLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsAnd(pObj) ); Gia_ObjSetLevel( p, pObj, 1+ABC_MAX(Gia_ObjLevel(p,Gia_ObjFanin0(pObj)),Gia_ObjLevel(p,Gia_ObjFanin1(pObj))) ); } static inline int Gia_ObjRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjRefsId( Gia_Man_t * p, int Id ) { assert( p->pRefs); return p->pRefs[Id]; } static inline int Gia_ObjRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]++; } static inline int Gia_ObjRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return --p->pRefs[Gia_ObjId(p, pObj)]; } static inline void Gia_ObjRefFanin0Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefInc(p, Gia_ObjFanin0(pObj)); } @@ -313,37 +369,35 @@ static inline void Gia_ObjRefFanin1Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin0(pObj)); } static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); } -static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; } -static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } -static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } -static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } -static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } -static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } - -static inline void Gia_ManResetTravIdArray( Gia_Man_t * p ) -{ - ABC_FREE( p->pTravIds ); - p->nTravIdsAlloc = Gia_ManObjNum(p); - p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc ); - p->nTravIds = 1; -} -static inline void Gia_ManIncrementTravIdArray( Gia_Man_t * p ) -{ - while ( p->nTravIdsAlloc < Gia_ManObjNum(p) ) - { - p->nTravIdsAlloc *= 2; - p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc ); - memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 ); - } - p->nTravIds++; -} -static inline void Gia_ObjSetTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; } -static inline void Gia_ObjSetTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } -static inline int Gia_ObjIsTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } -static inline void Gia_ObjSetTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } -static inline int Gia_ObjIsTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } +static inline int Gia_ObjNodeRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjNodeRefsId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]; } +static inline int Gia_ObjNodeRefIncId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]++; } +static inline int Gia_ObjNodeRefDecId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return --p->pNodeRefs[Id]; } +static inline int Gia_ObjNodeRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]++; } +static inline int Gia_ObjNodeRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return --p->pNodeRefs[Gia_ObjId(p, pObj)]; } + +static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; } +static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } +static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } +static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } +static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } +static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } + +static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); } +static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); } +static inline void Gia_ManTimeStop( Gia_Man_t * p ) { assert( p->vTiming != NULL ); Vec_FltFreeP(&p->vTiming); } +static inline float Gia_ObjTimeArrival( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+0); } +static inline float Gia_ObjTimeRequired( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+1); } +static inline float Gia_ObjTimeSlack( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+2); } +static inline float Gia_ObjTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeArrival( p, Gia_ObjId(p, pObj) ); } +static inline float Gia_ObjTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeRequired( p, Gia_ObjId(p, pObj) ); } +static inline float Gia_ObjTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeSlack( p, Gia_ObjId(p, pObj) ); } +static inline void Gia_ObjSetTimeArrival( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+0, t ); } +static inline void Gia_ObjSetTimeRequired( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+1, t ); } +static inline void Gia_ObjSetTimeSlack( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+2, t ); } +static inline void Gia_ObjSetTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeArrival( p, Gia_ObjId(p, pObj), t ); } +static inline void Gia_ObjSetTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeRequired( p, Gia_ObjId(p, pObj), t ); } +static inline void Gia_ObjSetTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeSlack( p, Gia_ObjId(p, pObj), t ); } // AIG construction extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -405,6 +459,12 @@ static inline int Gia_ManAppendCo( Gia_Man_t * p, int iLit0 ) Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); return Gia_ObjId( p, pObj ) << 1; } +static inline int Gia_ManAppendMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Gia_ManAppendAnd( p, Gia_LitNot(iCtrl), iData0 ); + int iTemp1 = Gia_ManAppendAnd( p, iCtrl, iData1 ); + return Gia_LitNotCond( Gia_ManAppendAnd( p, Gia_LitNot(iTemp0), Gia_LitNot(iTemp1) ), 1 ); +} #define GIA_ZER 1 #define GIA_ONE 2 @@ -428,9 +488,10 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom } static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); } -static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } -static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; } -static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; } +static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } +static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { assert( Num == GIA_VOID || Num < Id ); p->pReprs[Id].iRepr = Num; } +static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; } +static inline int Gia_ObjHasRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr != GIA_VOID; } static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; } static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; } @@ -474,14 +535,17 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) -static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } -static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } -static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } +static inline int Gia_ObjIsLut( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } +static inline int Gia_ObjLutSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } +static inline int * Gia_ObjLutFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } +static inline int Gia_ObjLutFanin( Gia_Man_t * p, int Id, int i ) { return Gia_ObjLutFanins(p, Id)[i]; } -#define Gia_ManForEachGate( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else -#define Gia_GateForEachFanin( p, i, iFan, k ) \ - for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ ) +#define Gia_ManForEachLut( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsLut(p, i) ) {} else +#define Gia_LutForEachFanin( p, i, iFan, k ) \ + for ( k = 0; k < Gia_ObjLutSize(p,i) && ((iFan = Gia_ObjLutFanins(p,i)[k]),1); k++ ) +#define Gia_LutForEachFaninObj( p, i, pFanin, k ) \ + for ( k = 0; k < Gia_ObjLutSize(p,i) && ((pFanin = Gia_ManObj(p, Gia_ObjLutFanins(p,i)[k])),1); k++ ) //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -525,9 +589,13 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re //////////////////////////////////////////////////////////////////////// /*=== giaAiger.c ===========================================================*/ +extern int Gia_FileSize( char * pFileName ); extern Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ); extern void Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact ); extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ); +/*=== giaBidec.c ===========================================================*/ +extern unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ); +extern Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose ); /*=== giaCsatOld.c ============================================================*/ extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ); /*=== giaCsat.c ============================================================*/ @@ -542,14 +610,17 @@ extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVe /*=== giaDfs.c ============================================================*/ extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp ); extern void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vNodes ); +extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ); +extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p ); /*=== giaDup.c ============================================================*/ extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop ); extern Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p ); - extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState ); extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupSelf( Gia_Man_t * p ); @@ -562,32 +633,38 @@ extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj ); extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ); +extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fDualOut, int fSeq, int fVerbose ); extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); /*=== giaEnable.c ==========================================================*/ extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose ); extern Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose ); extern Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ); /*=== giaEquiv.c ==========================================================*/ +extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ); extern int Gia_ManCheckTopoOrder( Gia_Man_t * p ); extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); extern void Gia_ManDeriveReprs( Gia_Man_t * p ); extern int Gia_ManEquivCountLits( Gia_Man_t * p ); +extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p ); extern int Gia_ManEquivCountClasses( Gia_Man_t * p ); extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ); extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ); extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose ); extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ); extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ); -extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ); -extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut ); -extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ); +extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ); +extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut ); +extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ); extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ); extern void Gia_ManEquivImprove( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ); +extern int Gia_ManCountChoiceNodes( Gia_Man_t * p ); +extern int Gia_ManCountChoices( Gia_Man_t * p ); /*=== giaFanout.c =========================================================*/ extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -611,12 +688,16 @@ extern int Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 ); extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash ); extern void Gia_ManHashProfile( Gia_Man_t * p ); +extern int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ); +/*=== giaIf.c ===========================================================*/ +extern void Gia_ManPrintNpnClasses( Gia_Man_t * p ); /*=== giaLogic.c ===========================================================*/ extern void Gia_ManTestDistance( Gia_Man_t * p ); extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ); /*=== giaMan.c ===========================================================*/ extern Gia_Man_t * Gia_ManStart( int nObjsMax ); extern void Gia_ManStop( Gia_Man_t * p ); +extern void Gia_ManStopP( Gia_Man_t ** p ); extern void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ); extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); @@ -624,8 +705,32 @@ extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); /*=== giaMap.c ===========================================================*/ extern void Gia_ManPrintMappingStats( Gia_Man_t * p ); +extern int Gia_ManLutFaninCount( Gia_Man_t * p ); +extern int Gia_ManLutSizeMax( Gia_Man_t * p ); +extern int Gia_ManLutNum( Gia_Man_t * p ); +extern int Gia_ManLutLevel( Gia_Man_t * p ); +/*=== giaMem.c ===========================================================*/ +extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ); +extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ); +extern char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p ); +extern void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry ); +extern void Gia_MmFixedRestart( Gia_MmFixed_t * p ); +extern int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p ); +extern int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p ); +extern Gia_MmFlex_t * Gia_MmFlexStart(); +extern void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose ); +extern char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes ); +extern void Gia_MmFlexRestart( Gia_MmFlex_t * p ); +extern int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p ); +extern Gia_MmStep_t * Gia_MmStepStart( int nSteps ); +extern void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose ); +extern char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes ); +extern void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes ); +extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ); /*=== giaPat.c ===========================================================*/ extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); +/*=== giaReparam.c ===========================================================*/ +extern Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose ); /*=== giaRetime.c ===========================================================*/ extern Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose ); /*=== giaSat.c ============================================================*/ @@ -636,10 +741,16 @@ extern int Gia_ManCombMarkUsed( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +/*=== giaShrink.c ===========================================================*/ +extern Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose ); /*=== giaSort.c ============================================================*/ extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ); /*=== giaSim.c ============================================================*/ extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); +/*=== giaSpeedup.c ============================================================*/ +extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); +extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose ); /*=== giaSwitch.c ============================================================*/ extern float Gia_ManEvaluateSwitching( Gia_Man_t * p ); extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); @@ -649,7 +760,9 @@ extern Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ); extern unsigned Gia_ManRandom( int fReset ); extern void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop ); extern unsigned int Gia_PrimeCudd( unsigned int p ); +extern char * Gia_TimeStamp(); extern char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix ); +extern void Gia_ManIncrementTravId( Gia_Man_t * p ); extern void Gia_ManSetMark0( Gia_Man_t * p ); extern void Gia_ManCleanMark0( Gia_Man_t * p ); extern void Gia_ManCheckMark0( Gia_Man_t * p ); @@ -657,8 +770,12 @@ extern void Gia_ManSetMark1( Gia_Man_t * p ); extern void Gia_ManCleanMark1( Gia_Man_t * p ); extern void Gia_ManCheckMark1( Gia_Man_t * p ); extern void Gia_ManCleanValue( Gia_Man_t * p ); +extern void Gia_ManCleanLevels( Gia_Man_t * p, int Size ); +extern void Gia_ManCleanTruth( Gia_Man_t * p ); extern void Gia_ManFillValue( Gia_Man_t * p ); +extern void Gia_ObjSetPhase( Gia_Obj_t * pObj ); extern void Gia_ManSetPhase( Gia_Man_t * p ); +extern void Gia_ManSetPhase1( Gia_Man_t * p ); extern void Gia_ManCleanPhase( Gia_Man_t * p ); extern int Gia_ManLevelNum( Gia_Man_t * p ); extern void Gia_ManSetRefs( Gia_Man_t * p ); @@ -670,13 +787,18 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ); extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode ); extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ); extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); -extern Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); -extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ); -extern void Gia_ManPrintCounterExample( Gia_Cex_t * p ); +extern Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); +extern Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ); +extern Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ); +extern Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ); +extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ); +extern void Gia_ManPrintCounterExample( Abc_Cex_t * p ); extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_ManHasChoices( Gia_Man_t * p ); -extern int Gia_ManHasDandling( Gia_Man_t * p ); -/*=== giaUtil.c ===========================================================*/ +extern int Gia_ManHasDangling( Gia_Man_t * p ); +extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ); +extern void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ); +/*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit ); extern void Tas_ManStop( Tas_Man_t * p ); @@ -686,9 +808,11 @@ extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Ob extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/gia/giaAbs.c b/src/aig/gia/giaAbs.c new file mode 100644 index 00000000..38e010f1 --- /dev/null +++ b/src/aig/gia/giaAbs.c @@ -0,0 +1,553 @@ +/**CFile**************************************************************** + + FileName [giaAbs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Counter-example-guided abstraction refinement.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "giaAbs.h" +#include "saig.h" + +#ifndef _WIN32 +#include <unistd.h> +#endif + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +extern Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ) +{ + memset( p, 0, sizeof(Gia_ParAbs_t) ); + p->Algo = 0; // algorithm: CBA + p->nFramesMax = 10; // timeframes for PBA + p->nConfMax = 10000; // conflicts for PBA + p->fDynamic = 1; // dynamic unfolding for PBA + p->fConstr = 0; // use constraints + p->nFramesBmc = 250; // timeframes for BMC + p->nConfMaxBmc = 5000; // conflicts for BMC + p->nStableMax = 1000000; // the number of stable frames to quit + p->nRatio = 10; // ratio of flops to quit + p->nBobPar = 1000000; // the number of frames before trying to quit + p->fUseBdds = 0; // use BDDs to refine abstraction + p->fUseDprove = 0; // use 'dprove' to refine abstraction + p->fUseStart = 1; // use starting frame + p->fVerbose = 0; // verbose output + p->fVeryVerbose= 0; // printing additional information + p->Status = -1; // the problem status + p->nFramesDone = -1; // the number of rames covered +} + +/**Function************************************************************* + + Synopsis [Transform flop list into flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops ) +{ + Vec_Int_t * vFlopClasses; + int i, Entry; + vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) ); + Vec_IntForEachEntry( vFlops, Entry, i ) + Vec_IntWriteEntry( vFlopClasses, Entry, 1 ); + return vFlopClasses; +} + +/**Function************************************************************* + + Synopsis [Transform flop map into flop list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses ) +{ + Vec_Int_t * vFlops; + int i, Entry; + vFlops = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vFlopClasses, Entry, i ) + if ( Entry ) + Vec_IntPush( vFlops, i ); + return vFlops; +} + + +/**Function************************************************************* + + Synopsis [Performs abstraction on the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCexAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops ) +{ + Gia_Man_t * pGia; + Aig_Man_t * pNew, * pTemp; + pNew = Gia_ManToAig( p, 0 ); + pNew = Saig_ManDeriveAbstraction( pTemp = pNew, vFlops ); + Aig_ManStop( pTemp ); + pGia = Gia_ManFromAig( pNew ); + pGia->vCiNumsOrig = pNew->vCiNumsOrig; + pNew->vCiNumsOrig = NULL; + Aig_ManStop( pNew ); + return pGia; + +} + +/**Function************************************************************* + + Synopsis [Computes abstracted flops for the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCexAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + vFlops = Saig_ManCexAbstractionFlops( pNew, pPars ); + p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Aig_ManStop( pNew ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Computes abstracted flops for the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManProofAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + vFlops = Saig_ManProofAbstractionFlops( pNew, pPars ); + p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Aig_ManStop( pNew ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCexAbstractionStart( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + if ( p->vFlopClasses != NULL ) + { + printf( "Gia_ManCexAbstractionStart(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &p->vFlopClasses ); + } + vFlops = Gia_ManCexAbstractionFlops( p, pPars ); + if ( vFlops ) + { + p->vFlopClasses = Gia_ManFlops2Classes( p, vFlops ); + Vec_IntFree( vFlops ); + } +} + +/**Function************************************************************* + + Synopsis [Derives abstraction using the latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCexAbstractionDerive( Gia_Man_t * pGia ) +{ + Vec_Int_t * vFlops; + Gia_Man_t * pAbs = NULL; + if ( pGia->vFlopClasses == NULL ) + { + printf( "Gia_ManCexAbstractionDerive(): Abstraction latch map is missing.\n" ); + return NULL; + } + vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); + pAbs = Gia_ManCexAbstraction( pGia, vFlops ); + Vec_IntFree( vFlops ); + return pAbs; +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using the latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbose ) +{ + Aig_Man_t * pNew; + Vec_Int_t * vFlops; + if ( pGia->vFlopClasses == NULL ) + { + printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" ); + return -1; + } + pNew = Gia_ManToAig( pGia, 0 ); + vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); + if ( !Saig_ManCexRefineStep( pNew, vFlops, pCex, fVerbose ) ) + { + pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return 0; + } + Vec_IntFree( pGia->vFlopClasses ); + pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return -1; +} + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManProofAbstractionStart( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + if ( pGia->vFlopClasses != NULL ) + { + printf( "Gia_ManProofAbstractionStart(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &pGia->vFlopClasses ); + } + vFlops = Gia_ManProofAbstractionFlops( pGia, pPars ); + if ( vFlops ) + { + pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); + Vec_IntFree( vFlops ); + } +} + + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_ManReadFile( char * pFileName ) +{ + FILE * pFile; + Vec_Str_t * vStr; + int c; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\".\n", pFileName ); + return NULL; + } + vStr = Vec_StrAlloc( 100 ); + while ( (c = fgetc(pFile)) != EOF ) + Vec_StrPush( vStr, (char)c ); + Vec_StrPush( vStr, '\0' ); + fclose( pFile ); + return vStr; +} + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManReadBinary( char * pFileName, char * pToken ) +{ + Vec_Int_t * vMap = NULL; + Vec_Str_t * vStr; + char * pStr; + int i, Length; + vStr = Gia_ManReadFile( pFileName ); + if ( vStr == NULL ) + return NULL; + pStr = Vec_StrArray( vStr ); + pStr = strstr( pStr, pToken ); + if ( pStr != NULL ) + { + pStr += strlen( pToken ); + vMap = Vec_IntAlloc( 100 ); + Length = strlen( pStr ); + for ( i = 0; i < Length; i++ ) + { + if ( pStr[i] == '0' ) + Vec_IntPush( vMap, 0 ); + else if ( pStr[i] == '1' ) + Vec_IntPush( vMap, 1 ); + if ( ('a' <= pStr[i] && pStr[i] <= 'z') || + ('A' <= pStr[i] && pStr[i] <= 'Z') ) + break; + } + } + Vec_StrFree( vStr ); + return vMap; +} + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManReadInteger( char * pFileName, char * pToken ) +{ + int Result = -1; + Vec_Str_t * vStr; + char * pStr; + vStr = Gia_ManReadFile( pFileName ); + if ( vStr == NULL ) + return -1; + pStr = Vec_StrArray( vStr ); + pStr = strstr( pStr, pToken ); + if ( pStr != NULL ) + Result = atoi( pStr + strlen(pToken) ); + Vec_StrFree( vStr ); + return Result; +} + + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCexAbstractionStartNew( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) +{ + char BufTimeOut[100]; + char BufTimeOutVT[100]; + char Command[1000]; + char * pFileNameIn = "cex_abstr_in_.aig"; + char * pFileNameOut = "cex_abstr_out_.txt"; + FILE * pFile; + Vec_Int_t * vCex; + int RetValue, clk; + if ( pGia->vFlopClasses != NULL ) + { + printf( "Gia_ManCexAbstractionStartNew(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &pGia->vFlopClasses ); + } + Gia_WriteAiger( pGia, pFileNameIn, 0, 0 ); + sprintf( BufTimeOut, "-timeout=%d", pPars->TimeOut ); + sprintf( BufTimeOutVT, "-vt=%d", pPars->TimeOutVT ); +//ABC switch => cex_abstr switch +//-cba => <input> <output> +//-pba => ,bmc -pba-soft <input> <output> +//-cba-then-pba => -pba-soft <input> <output> +//-cba-with-pba => -pba <input> <output> + if ( pPars->Algo == 0 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 1 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -confl=%d -bob=%d ,bmc -pba-soft %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 2 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba-soft %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 3 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else + { + printf( "Unnknown option (algo=%d). CBA (algo=0) is assumed.\n", pPars->Algo ); + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + // run the command + printf( "Executing command line \"%s\"\n", Command ); + clk = clock(); + RetValue = system( Command ); + clk = clock() - clk; +#ifdef WIN32 + _unlink( pFileNameIn ); +#else + unlink( pFileNameIn ); +#endif + if ( RetValue == -1 ) + { + fprintf( stdout, "Command \"%s\" did not succeed.\n", Command ); + return; + } + // check that the input PostScript file is okay + if ( (pFile = fopen( pFileNameOut, "r" )) == NULL ) + { + fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileNameOut ); + return; + } + fclose( pFile ); + pPars->nFramesDone = Gia_ManReadInteger( pFileNameOut, "depth:" ); + if ( pPars->nFramesDone == -1 ) + printf( "Gia_ManCexAbstractionStartNew(): Cannot read the number of frames covered by BMC.\n" ); + pGia->vFlopClasses = Gia_ManReadBinary( pFileNameOut, "abstraction:" ); + vCex = Gia_ManReadBinary( pFileNameOut, "counter-example:" ); + if ( vCex ) + { + int nFrames = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) / Gia_ManPiNum(pGia); + int nRemain = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) % Gia_ManPiNum(pGia); + if ( nRemain != 0 ) + { + printf( "Counter example has a wrong length.\n" ); + } + else + { + printf( "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 ); + Abc_PrintTime( 1, "Time", clk ); + pGia->pCexSeq = Gia_ManDeriveCexFromArray( pGia, vCex, 0, nFrames-1 ); + if ( !Gia_ManVerifyCounterExample( pGia, pGia->pCexSeq, 0 ) ) + Abc_Print( 1, "Generated counter-example is INVALID.\n" ); + pPars->Status = 0; + } + Vec_IntFreeP( &vCex ); + } +#ifdef WIN32 + _unlink( pFileNameOut ); +#else + unlink( pFileNameOut ); +#endif +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAbs.h b/src/aig/gia/giaAbs.h new file mode 100644 index 00000000..090d5dca --- /dev/null +++ b/src/aig/gia/giaAbs.h @@ -0,0 +1,89 @@ +/**CFile**************************************************************** + + FileName [giaAbs.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAbs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __GIA_ABS_H__ +#define __GIA_ABS_H__ + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// abstraction parameters +typedef struct Gia_ParAbs_t_ Gia_ParAbs_t; +struct Gia_ParAbs_t_ +{ + int Algo; // the algorithm to be used + int nFramesMax; // timeframes for PBA + int nConfMax; // conflicts for PBA + int fDynamic; // dynamic unfolding for PBA + int fConstr; // use constraints + int nFramesBmc; // timeframes for BMC + int nConfMaxBmc; // conflicts for BMC + int nStableMax; // the number of stable frames to quit + int nRatio; // ratio of flops to quit + int TimeOut; // approximate timeout in seconds + int TimeOutVT; // approximate timeout in seconds + int nBobPar; // Bob's parameter + int fUseBdds; // use BDDs to refine abstraction + int fUseDprove; // use 'dprove' to refine abstraction + int fUseStart; // use starting frame + int fVerbose; // verbose output + int fVeryVerbose; // printing additional information + int Status; // the problem status + int nFramesDone; // the number of frames covered +}; + +extern void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index fa9030c5..0e004f87 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -19,6 +19,12 @@ ***********************************************************************/ #include "giaAig.h" +#include "fra.h" +#include "dch.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -84,6 +90,7 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create room to store equivalences if ( p->pEquivs ) pNew->pNexts = ABC_CALLOC( int, Aig_ManObjNum(p) ); @@ -122,6 +129,7 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); Aig_ManForEachObj( p, pObj, i ) @@ -138,8 +146,6 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ) assert( 0 ); } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); - if ( pNew->pNexts ) - Gia_ManDeriveReprs( pNew ); return pNew; } @@ -162,6 +168,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); Aig_ManConst1(p)->iData = 1; @@ -178,7 +185,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) Aig_ManForEachPo( p, pObj, i ) Gia_ManFromAig_rec( pNew, p, Aig_ObjFanin0(pObj) ); Aig_ManForEachPo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); + pObj->iData = Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } @@ -240,6 +247,7 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ) // create the new manager pNew = Aig_ManStart( Gia_ManAndNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // pNew->pSpec = Gia_UtilStrsav( p->pName ); // duplicate representation of choice nodes if ( fChoices ) @@ -249,6 +257,10 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ) ppNodes[0] = Aig_ManConst0(pNew); Gia_ManForEachCi( p, pObj, i ) ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePi( pNew ); + // transfer level + if ( p->vLevels ) + Gia_ManForEachCi( p, pObj, i ) + Aig_ObjSetLevel( ppNodes[Gia_ObjId(p, pObj)], Gia_ObjLevel(p, pObj) ); // add logic for the POs Gia_ManForEachCo( p, pObj, i ) { @@ -282,6 +294,7 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ) // create the new manager pNew = Aig_ManStart( Gia_ManAndNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // pNew->pSpec = Gia_UtilStrsav( p->pName ); // create the PIs ppNodes = ABC_CALLOC( Aig_Obj_t *, Gia_ManObjNum(p) ); @@ -312,6 +325,48 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ) SeeAlso [] ***********************************************************************/ +Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t ** ppNodes; + Gia_Obj_t * pObj; + int i; + ppNodes = ABC_ALLOC( Aig_Obj_t *, Gia_ManObjNum(p) ); + // create the new manager + pNew = Aig_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; + // create the PIs + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + ppNodes[i] = Aig_And( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)), Gia_ObjChild1Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); + else if ( Gia_ObjIsCi(pObj) ) + ppNodes[i] = Aig_ObjCreatePi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + ppNodes[i] = Aig_ObjCreatePo( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); + else if ( Gia_ObjIsConst0(pObj) ) + ppNodes[i] = Aig_ManConst0(pNew); + else + assert( 0 ); + pObj->Value = Gia_Var2Lit( Aig_ObjId(Aig_Regular(ppNodes[i])), Aig_IsComplement(ppNodes[i]) ); + } + Aig_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + ABC_FREE( ppNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ) { Aig_Man_t * pMan; @@ -329,41 +384,69 @@ Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ) Synopsis [Transfers representatives from pGia to pAig.] - Description [] + Description [Assumes that pGia was created from pAig.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ) +void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ) { Aig_Obj_t * pObj; Gia_Obj_t * pGiaObj, * pGiaRepr; int i; - assert( p->pReprs == NULL ); + assert( pAig->pReprs == NULL ); assert( pGia->pReprs != NULL ); // move pointers from AIG to GIA - Aig_ManForEachObj( p, pObj, i ) + Aig_ManForEachObj( pAig, pObj, i ) { assert( i == 0 || !Gia_LitIsCompl(pObj->iData) ); pGiaObj = Gia_ManObj( pGia, Gia_Lit2Var(pObj->iData) ); pGiaObj->Value = i; } // set the pointers to the nodes in AIG - Aig_ManReprStart( p, Aig_ManObjNumMax(p) ); + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); + Gia_ManForEachObj( pGia, pGiaObj, i ) + { + pGiaRepr = Gia_ObjReprObj( pGia, i ); + if ( pGiaRepr == NULL ) + continue; + Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, pGiaRepr->Value), Aig_ManObj(pAig, pGiaObj->Value) ); + } +} + +/**Function************************************************************* + + Synopsis [Transfers representatives from pGia to pAig.] + + Description [Assumes that pAig was created from pGia.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia ) +{ + Gia_Obj_t * pGiaObj, * pGiaRepr; + int i; + assert( pAig->pReprs == NULL ); + assert( pGia->pReprs != NULL ); + // set the pointers to the nodes in AIG + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); Gia_ManForEachObj( pGia, pGiaObj, i ) { pGiaRepr = Gia_ObjReprObj( pGia, i ); if ( pGiaRepr == NULL ) continue; - Aig_ObjCreateRepr( p, Aig_ManObj(p, pGiaRepr->Value), Aig_ManObj(p, pGiaObj->Value) ); + Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, Gia_Lit2Var(pGiaRepr->Value)), Aig_ManObj(pAig, Gia_Lit2Var(pGiaObj->Value)) ); } } /**Function************************************************************* - Synopsis [Applied DC2 to the GIA manager.] + Synopsis [Transfers representatives from pAig to pGia.] Description [] @@ -372,21 +455,159 @@ void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p ) +void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ) { - extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ); + Gia_Obj_t * pObjGia; + Aig_Obj_t * pObjAig, * pReprAig; + int i; + assert( pAig->pReprs != NULL ); + assert( pGia->pReprs == NULL ); + assert( Gia_ManObjNum(pGia) - Gia_ManCoNum(pGia) == Aig_ManObjNum(pAig) - Aig_ManPoNum(pAig) ); + pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pGia) ); + for ( i = 0; i < Gia_ManObjNum(pGia); i++ ) + Gia_ObjSetRepr( pGia, i, GIA_VOID ); + Gia_ManForEachObj( pGia, pObjGia, i ) + { +// Abc_Print( 1, "%d -> %d %d\n", i, Gia_ObjValue(pObjGia), Gia_ObjValue(pObjGia)/2 ); + if ( Gia_ObjIsCo(pObjGia) ) + continue; + assert( i == 0 || !Gia_LitIsCompl(Gia_ObjValue(pObjGia)) ); + pObjAig = Aig_ManObj( pAig, Gia_Lit2Var(Gia_ObjValue(pObjGia)) ); + pObjAig->iData = i; + } + Aig_ManForEachObj( pAig, pObjAig, i ) + { + if ( Aig_ObjIsPo(pObjAig) ) + continue; + if ( pAig->pReprs[i] == NULL ) + continue; + pReprAig = pAig->pReprs[i]; + Gia_ObjSetRepr( pGia, pObjAig->iData, pReprAig->iData ); + } + pGia->pNexts = Gia_ManDeriveNexts( pGia ); +} + +/**Function************************************************************* + + Synopsis [Applies DC2 to the GIA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) +{ +// extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ); Gia_Man_t * pGia; Aig_Man_t * pNew, * pTemp; pNew = Gia_ManToAig( p, 0 ); - pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0, 0 ); + pNew = Dar_ManCompress2( pTemp = pNew, 1, fUpdateLevel, 1, 0, fVerbose ); Aig_ManStop( pTemp ); pGia = Gia_ManFromAig( pNew ); Aig_ManStop( pNew ); return pGia; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) +{ + Gia_Man_t * pGia; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars ); + pGia = Gia_ManFromAig( pNew ); + Aig_ManStop( pNew ); + return pGia; +} + +/**Function************************************************************* + + Synopsis [Computes equivalences after structural sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ) +{ + Aig_Man_t * pNew, * pTemp; + pNew = Gia_ManToAigSimple( p ); + pTemp = Aig_ManScl( pNew, fConst, fEquiv, fVerbose ); + Gia_ManReprFromAigRepr( pNew, p ); + Aig_ManStop( pTemp ); + Aig_ManStop( pNew ); +} + +/**Function************************************************************* + + Synopsis [Solves SAT problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSolveSat( Gia_Man_t * p ) +{ +// extern int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fFlipBits, int fAndOuts, int fVerbose ); + Aig_Man_t * pNew; + int RetValue, clk = clock(); + pNew = Gia_ManToAig( p, 0 ); + RetValue = Fra_FraigSat( pNew, 10000000, 0, 1, 1, 0 ); + if ( RetValue == 0 ) + { + Gia_Obj_t * pObj; + int i, * pInit = (int *)pNew->pData; + Gia_ManConst0(p)->fMark0 = 0; + Gia_ManForEachPi( p, pObj, i ) + pObj->fMark0 = pInit[i]; + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachPo( p, pObj, i ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); + Gia_ManForEachPo( p, pObj, i ) + if ( pObj->fMark0 != 1 ) + break; + if ( i != Gia_ManPoNum(p) ) + Abc_Print( 1, "Counter-example verification has failed. " ); +// else +// Abc_Print( 1, "Counter-example verification succeeded. " ); + } +/* + else if ( RetValue == 1 ) + Abc_Print( 1, "The SAT problem is unsatisfiable. " ); + else if ( RetValue == -1 ) + Abc_Print( 1, "The SAT problem is undecided. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); +*/ + Aig_ManStop( pNew ); + return RetValue; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAig.h b/src/aig/gia/giaAig.h index 8cef5c7e..1c0a24d5 100644 --- a/src/aig/gia/giaAig.h +++ b/src/aig/gia/giaAig.h @@ -21,6 +21,7 @@ #ifndef __GIA_AIG_H__ #define __GIA_AIG_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -28,6 +29,9 @@ #include "aig.h" #include "gia.h" +ABC_NAMESPACE_HEADER_START + + //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// @@ -51,12 +55,18 @@ extern Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ); extern Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ); extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ); extern Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ); -extern void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ); -extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p ); - -#ifdef __cplusplus -} -#endif +extern Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p ); +extern void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ); +extern Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ); +extern Gia_Man_t * Gia_ManAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops ); +extern void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +extern int Gia_ManSolveSat( Gia_Man_t * p ); + + +ABC_NAMESPACE_HEADER_END #endif diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 6c8ace8a..e201cbb9 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -21,6 +21,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -41,7 +44,7 @@ SeeAlso [] ***********************************************************************/ -unsigned Gia_ReadAigerDecode( char ** ppPos ) +unsigned Gia_ReadAigerDecode( unsigned char ** ppPos ) { unsigned x = 0, i = 0; unsigned char ch; @@ -61,7 +64,7 @@ unsigned Gia_ReadAigerDecode( char ** ppPos ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +Vec_Int_t * Gia_WriteDecodeLiterals( unsigned char ** ppPos, int nEntries ) { Vec_Int_t * vLits; int Lit, LitPrev, Diff, i; @@ -151,30 +154,6 @@ char * Gia_FileNameGeneric( char * FileName ) /**Function************************************************************* - Synopsis [Returns the time stamp.] - - Description [The file should be closed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Gia_TimeStamp() -{ - 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 [Read integer from the string.] Description [] @@ -203,7 +182,7 @@ int Gia_ReadInt( unsigned char * pPos ) SeeAlso [] ***********************************************************************/ -unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +unsigned Gia_ReadDiffValue( unsigned char ** ppPos, int iPrev ) { int Item = Gia_ReadAigerDecode( ppPos ); if ( Item & 1 ) @@ -371,7 +350,8 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) Vec_Int_t * vNodes, * vDrivers;//, * vTerms; int iObj, iNode0, iNode1; int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; - char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned char * pDrivers, * pSymbols, * pCur;//, * pType; + char * pContents, * pName; unsigned uLit0, uLit1, uLit; // read the file into the buffer @@ -391,17 +371,17 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) } // read the file type - pCur = pContents; while ( *pCur++ != ' ' ); + pCur = (unsigned char *)pContents; while ( *pCur++ != ' ' ); // read the number of objects - nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + nTotal = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of inputs - nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + nInputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of latches - nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + nLatches = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of outputs - nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + nOutputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of nodes - nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + nAnds = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); // check the parameters if ( nTotal != nInputs + nLatches + nAnds ) { @@ -465,14 +445,14 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) pCur = pDrivers; for ( i = 0; i < nLatches; i++ ) { - uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); Vec_IntPush( vDrivers, iNode0 ); } // read the PO driver literals for ( i = 0; i < nOutputs; i++ ) { - uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); Vec_IntPush( vDrivers, iNode0 ); } @@ -509,7 +489,7 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) // check if there are other types of information to read pCur = pSymbols; - if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + if ( (char *)pCur + 1 < pContents + nFileSize && *pCur == 'c' ) { pCur++; if ( *pCur == 'e' ) @@ -539,17 +519,23 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); } if ( *pCur == 's' ) - { + { pCur++; // read switching activity pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } if ( *pCur == 'n' ) { pCur++; // read model name ABC_FREE( pNew->pName ); - pNew->pName = Gia_UtilStrsav( pCur ); + pNew->pName = Gia_UtilStrsav( (char *)pCur ); } } @@ -710,7 +696,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) Gia_ClassForEachObj( p, iRepr, iNode ) nItems++; } - pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) ); // write constant class iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); //printf( "\nRepr = %d ", 0 ); @@ -754,7 +740,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) SeeAlso [] ***********************************************************************/ -int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +int Gia_WriteDiffValue( unsigned char * pPos, int iPos, int iPrev, int iThis ) { if ( iPrev < iThis ) return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); @@ -779,16 +765,16 @@ unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) assert( p->pMapping ); // count the number of entries to be written nItems = 0; - Gia_ManForEachGate( p, i ) - nItems += 2 + Gia_ObjGateSize( p, i ); - pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) ); // write non-constant classes iPrev = 0; - Gia_ManForEachGate( p, i ) + Gia_ManForEachLut( p, i ) { -//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) ); - iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) ); - Gia_GateForEachFanin( p, i, iFan, k ) +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) { //printf( "Fan = %d ", iFan ); iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); @@ -915,8 +901,9 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write flop classes if ( p->vFlopClasses ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = 4*Gia_ManRegNum(p); + Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "f" ); fwrite( Buffer, 1, 4, pFile ); fwrite( Vec_IntArray(p->vFlopClasses), 1, nSize, pFile ); @@ -933,7 +920,7 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write placement if ( p->pPlacement ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = 4*Gia_ManObjNum(p); Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "p" ); @@ -943,13 +930,21 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write flop classes if ( p->pSwitching ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = Gia_ManObjNum(p); Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "s" ); fwrite( Buffer, 1, 4, pFile ); fwrite( p->pSwitching, 1, nSize, pFile ); } + // write constraints + if ( p->nConstrs ) + { + unsigned char Buffer[10]; + Gia_WriteInt( Buffer, p->nConstrs ); + fprintf( pFile, "c" ); + fwrite( Buffer, 1, 4, pFile ); + } // write name if ( p->pName ) fprintf( pFile, "n%s%c", p->pName, '\0' ); @@ -983,3 +978,5 @@ void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNu //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAiger_new.c b/src/aig/gia/giaAiger_new.c new file mode 100644 index 00000000..67981b26 --- /dev/null +++ b/src/aig/gia/giaAiger_new.c @@ -0,0 +1,1251 @@ +/**CFile**************************************************************** + + FileName [giaAiger.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Procedures to read/write binary AIGER format developed by + Armin Biere, Johannes Kepler University (http://fmv.jku.at/)] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef ABC_UINT64_T word; + +static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Extracts one unsigned AIG edge from the input buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "unsigned decode (FILE * file)". ] + + SideEffects [Updates the current reading position.] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadAigerDecode( char ** ppPos ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = *(*ppPos)++) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [Extracts one signed AIG edge from the input buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadAigerDecodeInt( char ** ppPos ) +{ + unsigned Res; + Res = Gia_ReadAigerDecode( ppPos ); + if ( Res & 1 ) + return -((int)(Res >> 1)); + return Res >> 1; +} + +/**Function************************************************************* + + Synopsis [Decodes the encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +{ + Vec_Int_t * vLits; + int Lit, LitPrev, Diff, i; + vLits = Vec_IntAlloc( nEntries ); + LitPrev = Gia_ReadAigerDecode( ppPos ); + Vec_IntPush( vLits, LitPrev ); + for ( i = 1; i < nEntries; i++ ) + { +// Diff = Lit - LitPrev; +// Diff = (Lit < LitPrev)? -Diff : Diff; +// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev); + Diff = Gia_ReadAigerDecode( ppPos ); + Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1; + Lit = Diff + LitPrev; + Vec_IntPush( vLits, Lit ); + LitPrev = Lit; + } + return vLits; +} + + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FixFileName( char * pFileName ) +{ + char * pName; + for ( pName = pFileName; *pName; pName++ ) + if ( *pName == '>' ) + *pName = '\\'; +} + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_FileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Gia_FileSize(): The 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 [] + +***********************************************************************/ +char * Gia_FileNameGeneric( char * FileName ) +{ + char * pDot, * pRes; + pRes = Gia_UtilStrsav( FileName ); + if ( (pDot = strrchr( pRes, '.' )) ) + *pDot = 0; + return pRes; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value |= ((unsigned)(*pPos++)) << (i << 3); + return Value; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; + assert( iRepr < iNode ); +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, k, iRepr, iNode, nMembers; + // find place to stop + pStop = *ppPos + nSize; + // prepare equivalence classes + pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc ); + for ( i = 0; i < nAlloc; i++ ) + pReprs[i].iRepr = GIA_VOID; + // skip the number of classes + Gia_ReadAigerDecode( ppPos ); + // read classes + iRepr = 0; + while ( *ppPos < pStop ) + { + nMembers = Gia_ReadAigerDecode( ppPos ); + iRepr += Gia_ReadAigerDecode( ppPos ); + iNode = iRepr; + for ( k = 1; k < nMembers; k++ ) + { + iNode += Gia_ReadAigerDecode( ppPos ); + pReprs[ Gia_Lit2Var(iNode) ].iRepr = Gia_Lit2Var(iRepr); + assert( Gia_Lit2Var(iRepr) < Gia_Lit2Var(iNode) ); +//if ( !iRepr ) +//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr ); + } + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read flop classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize ) +{ + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + assert( Vec_IntSize(vClasses) == nSize ); + memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); + *ppPos += 4 * nSize; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Read switching from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ + unsigned char * pSwitching; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc == nSize ); + pSwitching = ABC_ALLOC( unsigned char, nSize ); + memcpy( pSwitching, *ppPos, nSize ); + *ppPos += nSize; + return pSwitching; +} + +/**Function************************************************************* + + Synopsis [Read placement from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ + Gia_Plc_t * pPlacement; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); + memcpy( pPlacement, *ppPos, 4*nSize ); + *ppPos += 4 * nSize; + return pPlacement; +} + +/**Function************************************************************* + + Synopsis [Reads char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Gia_ReadBlockHeader( char ** ppCur, word * pWord ) +{ + int i; + char Char = *(*ppCur)++; + *pWord = 0; + for ( i = 0; i < 8; i++ ) + { +// printf( "%d\n", (unsigned char)(*(*ppCur)) ); + *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3); + } + return Char; +} + +/**Function************************************************************* + + Synopsis [Reads the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) +{ + FILE * pFile; + Gia_Man_t * pNew; + Vec_Int_t * vLits = NULL; + Vec_Int_t * vNodes, * vDrivers;//, * vTerms; + int iObj, iNode0, iNode1; + int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; + char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned uLit0, uLit1, uLit; + + // read the file into the buffer + Gia_FixFileName( pFileName ); + nFileSize = Gia_FileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = ABC_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + + // check if the input file format is correct + if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') ) + { + fprintf( stdout, "Wrong input file format.\n" ); + free( pContents ); + return NULL; + } + + // read the file type + pCur = pContents; while ( *pCur++ != ' ' ); + // read the number of objects + nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of inputs + nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of latches + nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of outputs + nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of nodes + nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + // check the parameters + if ( nTotal != nInputs + nLatches + nAnds ) + { + fprintf( stdout, "The paramters are wrong.\n" ); + return NULL; + } + + // allocate the empty AIG + pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 ); + pName = Gia_FileNameGeneric( pFileName ); + pNew->pName = Gia_UtilStrsav( pName ); +// pNew->pSpec = Gia_UtilStrsav( pFileName ); + ABC_FREE( pName ); + + // prepare the array of nodes + vNodes = Vec_IntAlloc( 1 + nTotal ); + Vec_IntPush( vNodes, 0 ); + + // create the PIs + for ( i = 0; i < nInputs + nLatches; i++ ) + { + iObj = Gia_ManAppendCi(pNew); + Vec_IntPush( vNodes, iObj ); + } + + // remember the beginning of latch/PO literals + pDrivers = pCur; + if ( pContents[3] == ' ' ) // standard AIGER + { + // scroll to the beginning of the binary data + for ( i = 0; i < nLatches + nOutputs; ) + if ( *pCur++ == '\n' ) + i++; + } + else // modified AIGER + { + vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs ); + } + + // create the AND gates + for ( i = 0; i < nAnds; i++ ) + { + uLit = ((i + 1 + nInputs + nLatches) << 1); + uLit1 = uLit - Gia_ReadAigerDecode( &pCur ); + uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur ); +// assert( uLit1 > uLit0 ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); + iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); + assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches ); +// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) ); + Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) ); + } + + // remember the place where symbols begin + pSymbols = pCur; + + // read the latch driver literals + vDrivers = Vec_IntAlloc( nLatches + nOutputs ); + if ( pContents[3] == ' ' ) // standard AIGER + { + pCur = pDrivers; + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + + } + else + { + // read the latch driver literals + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i+nLatches ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + Vec_IntFree( vLits ); + } + + // create the POs + for ( i = 0; i < nOutputs; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) ); + for ( i = 0; i < nLatches; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) ); + Vec_IntFree( vDrivers ); + + // create the latches + Gia_ManSetRegNum( pNew, nLatches ); + + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + char Char; + word Size; + pCur++; + + // read model name (old style) + if ( *pCur == 'n' ) + { + pCur++; + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + } + + Char = Gia_ReadBlockHeader( &pCur, &Size ); + if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE ) + { + while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) ) + { + switch (Char) + { + case 'N': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = ABC_ALLOC( char, (int)Size + 1 ); + strncpy( pNew->pName, pCur, (int)Size ); + pNew->pName[(int)Size] = '\0'; + pCur += (int)Size; + break; + case '=': + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + break; + case 'c': + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + break; + default: + printf( "Unrecognized data.\n" ); + break; + } + } + } + else + { + printf( "Extended AIGER reader: Internal signature does not match.\n" ); + } + +/* + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'f' ) + { + pCur++; + // read flop classes + pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); + Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 's' ) + { + pCur++; + // read switching activity + pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + } +*/ + } + + // skipping the comments + ABC_FREE( pContents ); + Vec_IntFree( vNodes ); +/* + // check the result + if ( fCheck && !Gia_ManCheck( pNew ) ) + { + printf( "Gia_ReadAiger: The network check has failed.\n" ); + Gia_ManStop( pNew ); + return NULL; + } +*/ + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Adds one unsigned AIG edge to the output buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "void encode (FILE * file, unsigned x)" ] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + pBuffer[Pos++] = ch; + x >>= 7; + } + ch = x; + pBuffer[Pos++] = ch; + return Pos; +} + +/**Function************************************************************* + + Synopsis [Adds one signed int to the output buffer.] + + Description [] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x ) +{ + if ( x >= 0 ) + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) ); + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 ); +} + +/**Function************************************************************* + + Synopsis [Create the array of literals to be written.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p ) +{ + Vec_Int_t * vLits; + Gia_Obj_t * pObj; + int i; + vLits = Vec_IntAlloc( Gia_ManPoNum(p) ); + Gia_ManForEachRi( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + return vLits; +} + +/**Function************************************************************* + + Synopsis [Creates the binary encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) +{ + Vec_Str_t * vBinary; + int Pos = 0, Lit, LitPrev, Diff, i; + vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) ); + LitPrev = Vec_IntEntry( vLits, 0 ); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev ); + Vec_IntForEachEntryStart( vLits, Lit, i, 1 ) + { + Diff = Lit - LitPrev; + Diff = (Lit < LitPrev)? -Diff : Diff; + Diff = (Diff << 1) | (int)(Lit < LitPrev); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff ); + LitPrev = Lit; + if ( Pos + 10 > vBinary->nCap ) + Vec_StrGrow( vBinary, vBinary->nCap+1 ); + } + vBinary->nSize = Pos; +/* + // verify + { + extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ); + char * pPos = Vec_StrArray( vBinary ); + Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) ); + for ( i = 0; i < Vec_IntSize(vLits); i++ ) + { + int Entry1 = Vec_IntEntry(vLits,i); + int Entry2 = Vec_IntEntry(vTemp,i); + assert( Entry1 == Entry2 ); + } + Vec_IntFree( vTemp ); + } +*/ + return vBinary; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( char * pBuffer, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + pBuffer[i] = (char)(0xff & (Value >> (i<<3))); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int k, iNode, iRepr, iPrevLit, iNodeLit, iPrevReprLit, iReprLit; + int nItems, iPos, nClasses, nMembers; + assert( p->pReprs && p->pNexts ); + Gia_ManSetPhase(p); + // count the number of entries to be written + nItems = 0; + nMembers = 0; + nClasses = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + nMembers += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + nClasses++; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + nClasses += (nMembers > 0); + // allocate place for data + pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 ); + // write the number of classes + iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses ); + // write constant class + if ( nMembers ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) ); + iPrevLit = Gia_Var2Lit(0,0); + k = 1; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit ); + iPrevLit = iNodeLit; +//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 ); + } + } + // write non-constant classes + iPrevReprLit = 0; + Gia_ManForEachClass( p, iRepr ) + { + // write number of members + nMembers = 0; + Gia_ClassForEachObj( p, iRepr, iNode ) + nMembers++; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers ); + // write representative + iReprLit = Gia_Var2Lit( iRepr, Gia_ObjPhase(Gia_ManObj(p, iRepr)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iReprLit - iPrevReprLit ); + iPrevReprLit = iReprLit; + // write members + iPrevLit = iReprLit; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit ); + iPrevLit = iNodeLit; +//printf( "Writing equiv %d -> %d\n", iNode, iRepr ); + } + } + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachLut( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Writes char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word ) +{ + int i; + fprintf( pFile, "%c", Char ); + for ( i = 0; i < 8; i++ ) + fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteIntF( FILE * pFile, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact ) +{ + FILE * pFile; + Gia_Man_t * p; + Gia_Obj_t * pObj; + int i, nBufferSize, Pos; + unsigned char * pBuffer; + unsigned uLit0, uLit1, uLit; + + if ( Gia_ManCoNum(pInit) == 0 ) + { + printf( "AIG cannot be written because it has no POs.\n" ); + return; + } + + // start the output stream + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + // create normalized AIG + if ( !Gia_ManIsNormalized(pInit) ) + { +// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); + p = Gia_ManDupNormalized( pInit ); + } + else + p = pInit; + + // write the header "M I L O A" where M = I + L + A + fprintf( pFile, "aig%s %u %u %u %u %u\n", + fCompact? "2" : "", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p), + Gia_ManRegNum(p), + Gia_ManPoNum(p), + Gia_ManAndNum(p) ); + + if ( !fCompact ) + { + // write latch drivers + Gia_ManForEachRi( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + // write PO drivers + Gia_ManForEachPo( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Vec_Int_t * vLits = Gia_WriteAigerLiterals( p ); + Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits ); + fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile ); + Vec_StrFree( vBinary ); + Vec_IntFree( vLits ); + } + + // write the nodes into the buffer + Pos = 0; + nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge + pBuffer = ABC_ALLOC( unsigned char, nBufferSize ); + Gia_ManForEachAnd( p, pObj, i ) + { + uLit = Gia_Var2Lit( i, 0 ); + uLit0 = Gia_ObjFaninLit0( pObj, i ); + uLit1 = Gia_ObjFaninLit1( pObj, i ); + assert( uLit0 < uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 ); + if ( Pos > nBufferSize - 10 ) + { + printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); + return; + } + } + assert( Pos < nBufferSize ); + + // write the buffer + fwrite( pBuffer, 1, Pos, pFile ); + ABC_FREE( pBuffer ); + + // write the comment + fprintf( pFile, "c" ); + // write signature + Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE ); + // write name + if ( p->pName ) + { + Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) ); + fwrite( pInit->pName, 1, strlen(pInit->pName), pFile ); + } + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } +/* + // write flop classes + if ( p->vFlopClasses ) + { + Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) ); + fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile ); + } + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement + if ( p->pPlacement ) + { + Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) ); + fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile ); + } + // write switching activity + if ( p->pSwitching ) + { + Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) ); + fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile ); + } + // write name + if ( p->pName ) + fprintf( pFile, "n%s%c", p->pName, '\0' ); +*/ + // write constraints + if ( p->nConstrs ) + { + Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs ); + Gia_WriteIntF( pFile, p->nConstrs ); + } + // write the closing statement + Gia_WriteBlockHeader( pFile, '\0', (word)0 ); + // write comment + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ + char Buffer[100]; + sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); + Gia_WriteAiger( p, Buffer, 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAiger_old.c b/src/aig/gia/giaAiger_old.c new file mode 100644 index 00000000..9a5ba5cd --- /dev/null +++ b/src/aig/gia/giaAiger_old.c @@ -0,0 +1,1255 @@ +/**CFile**************************************************************** + + FileName [giaAiger.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Procedures to read/write binary AIGER format developed by + Armin Biere, Johannes Kepler University (http://fmv.jku.at/)] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef ABC_UINT64_T word; + +static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Extracts one unsigned AIG edge from the input buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "unsigned decode (FILE * file)". ] + + SideEffects [Updates the current reading position.] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadAigerDecode( char ** ppPos ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = *(*ppPos)++) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [Extracts one signed AIG edge from the input buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadAigerDecodeInt( char ** ppPos ) +{ + unsigned Res; + Res = Gia_ReadAigerDecode( ppPos ); + if ( Res & 1 ) + return -((int)(Res >> 1)); + return Res >> 1; +} + +/**Function************************************************************* + + Synopsis [Decodes the encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +{ + Vec_Int_t * vLits; + int Lit, LitPrev, Diff, i; + vLits = Vec_IntAlloc( nEntries ); + LitPrev = Gia_ReadAigerDecode( ppPos ); + Vec_IntPush( vLits, LitPrev ); + for ( i = 1; i < nEntries; i++ ) + { +// Diff = Lit - LitPrev; +// Diff = (Lit < LitPrev)? -Diff : Diff; +// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev); + Diff = Gia_ReadAigerDecode( ppPos ); + Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1; + Lit = Diff + LitPrev; + Vec_IntPush( vLits, Lit ); + LitPrev = Lit; + } + return vLits; +} + + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FixFileName( char * pFileName ) +{ + char * pName; + for ( pName = pFileName; *pName; pName++ ) + if ( *pName == '>' ) + *pName = '\\'; +} + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_FileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Gia_FileSize(): The 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 [] + +***********************************************************************/ +char * Gia_FileNameGeneric( char * FileName ) +{ + char * pDot, * pRes; + pRes = Gia_UtilStrsav( FileName ); + if ( (pDot = strrchr( pRes, '.' )) ) + *pDot = 0; + return pRes; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value |= ((unsigned)(*pPos++)) << (i << 3); + return Value; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; + assert( iRepr < iNode ); +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, k, iRepr, iNode, nMembers; + // find place to stop + pStop = *ppPos + nSize; + // prepare equivalence classes + pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc ); + for ( i = 0; i < nAlloc; i++ ) + pReprs[i].iRepr = GIA_VOID; + // skip the number of classes + Gia_ReadAigerDecode( ppPos ); + // read classes + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + nMembers = Gia_ReadAigerDecode( ppPos ); + iRepr += Gia_ReadAigerDecode( ppPos ) >> 1; + iNode = iRepr; + for ( k = 1; k < nMembers; k++ ) + { + iNode += Gia_ReadAigerDecode( ppPos ) >> 1; + pReprs[ iNode ].iRepr = iRepr; + assert( iRepr < iNode ); +//if ( !iRepr ) +//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr ); + } + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read flop classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize ) +{ + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + assert( Vec_IntSize(vClasses) == nSize ); + memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); + *ppPos += 4 * nSize; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Read switching from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ + unsigned char * pSwitching; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc == nSize ); + pSwitching = ABC_ALLOC( unsigned char, nSize ); + memcpy( pSwitching, *ppPos, nSize ); + *ppPos += nSize; + return pSwitching; +} + +/**Function************************************************************* + + Synopsis [Read placement from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ + Gia_Plc_t * pPlacement; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); + memcpy( pPlacement, *ppPos, 4*nSize ); + *ppPos += 4 * nSize; + return pPlacement; +} + +/**Function************************************************************* + + Synopsis [Reads char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Gia_ReadBlockHeader( char ** ppCur, word * pWord ) +{ + int i; + char Char = *(*ppCur)++; + *pWord = 0; + for ( i = 0; i < 8; i++ ) + { +// printf( "%d\n", (unsigned char)(*(*ppCur)) ); + *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3); + } + return Char; +} + +/**Function************************************************************* + + Synopsis [Reads the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) +{ + FILE * pFile; + Gia_Man_t * pNew; + Vec_Int_t * vLits = NULL; + Vec_Int_t * vNodes, * vDrivers;//, * vTerms; + int iObj, iNode0, iNode1; + int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; + char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned uLit0, uLit1, uLit; + + // read the file into the buffer + Gia_FixFileName( pFileName ); + nFileSize = Gia_FileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = ABC_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + + // check if the input file format is correct + if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') ) + { + fprintf( stdout, "Wrong input file format.\n" ); + free( pContents ); + return NULL; + } + + // read the file type + pCur = pContents; while ( *pCur++ != ' ' ); + // read the number of objects + nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of inputs + nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of latches + nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of outputs + nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of nodes + nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + // check the parameters + if ( nTotal != nInputs + nLatches + nAnds ) + { + fprintf( stdout, "The paramters are wrong.\n" ); + return NULL; + } + + // allocate the empty AIG + pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 ); + pName = Gia_FileNameGeneric( pFileName ); + pNew->pName = Gia_UtilStrsav( pName ); +// pNew->pSpec = Gia_UtilStrsav( pFileName ); + ABC_FREE( pName ); + + // prepare the array of nodes + vNodes = Vec_IntAlloc( 1 + nTotal ); + Vec_IntPush( vNodes, 0 ); + + // create the PIs + for ( i = 0; i < nInputs + nLatches; i++ ) + { + iObj = Gia_ManAppendCi(pNew); + Vec_IntPush( vNodes, iObj ); + } + + // remember the beginning of latch/PO literals + pDrivers = pCur; + if ( pContents[3] == ' ' ) // standard AIGER + { + // scroll to the beginning of the binary data + for ( i = 0; i < nLatches + nOutputs; ) + if ( *pCur++ == '\n' ) + i++; + } + else // modified AIGER + { + vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs ); + } + + // create the AND gates + for ( i = 0; i < nAnds; i++ ) + { + uLit = ((i + 1 + nInputs + nLatches) << 1); + uLit1 = uLit - Gia_ReadAigerDecode( &pCur ); + uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur ); +// assert( uLit1 > uLit0 ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); + iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); + assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches ); +// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) ); + Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) ); + } + + // remember the place where symbols begin + pSymbols = pCur; + + // read the latch driver literals + vDrivers = Vec_IntAlloc( nLatches + nOutputs ); + if ( pContents[3] == ' ' ) // standard AIGER + { + pCur = pDrivers; + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + + } + else + { + // read the latch driver literals + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i+nLatches ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + Vec_IntFree( vLits ); + } + + // create the POs + for ( i = 0; i < nOutputs; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) ); + for ( i = 0; i < nLatches; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) ); + Vec_IntFree( vDrivers ); + + // create the latches + Gia_ManSetRegNum( pNew, nLatches ); + + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + char Char; + word Size; + pCur++; + + // read model name (old style) + if ( *pCur == 'n' ) + { + pCur++; + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + } + + Char = Gia_ReadBlockHeader( &pCur, &Size ); + if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE ) + { + while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) ) + { + switch (Char) + { + case 'N': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = ABC_ALLOC( char, (int)Size + 1 ); + strncpy( pNew->pName, pCur, (int)Size ); + pNew->pName[(int)Size] = '\0'; + pCur += (int)Size; + break; + case 'n': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + break; + case '=': + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + break; + case 'c': + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + break; + default: + printf( "Unrecognized data.\n" ); + break; + } + } + } + else + { + printf( "Extended AIGER reader: Internal signature does not match.\n" ); + } + +/* + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'f' ) + { + pCur++; + // read flop classes + pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); + Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 's' ) + { + pCur++; + // read switching activity + pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + } +*/ + } + + // skipping the comments + ABC_FREE( pContents ); + Vec_IntFree( vNodes ); +/* + // check the result + if ( fCheck && !Gia_ManCheck( pNew ) ) + { + printf( "Gia_ReadAiger: The network check has failed.\n" ); + Gia_ManStop( pNew ); + return NULL; + } +*/ + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Adds one unsigned AIG edge to the output buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "void encode (FILE * file, unsigned x)" ] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + pBuffer[Pos++] = ch; + x >>= 7; + } + ch = x; + pBuffer[Pos++] = ch; + return Pos; +} + +/**Function************************************************************* + + Synopsis [Adds one signed int to the output buffer.] + + Description [] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x ) +{ + if ( x >= 0 ) + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) ); + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 ); +} + +/**Function************************************************************* + + Synopsis [Create the array of literals to be written.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p ) +{ + Vec_Int_t * vLits; + Gia_Obj_t * pObj; + int i; + vLits = Vec_IntAlloc( Gia_ManPoNum(p) ); + Gia_ManForEachRi( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + return vLits; +} + +/**Function************************************************************* + + Synopsis [Creates the binary encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) +{ + Vec_Str_t * vBinary; + int Pos = 0, Lit, LitPrev, Diff, i; + vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) ); + LitPrev = Vec_IntEntry( vLits, 0 ); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev ); + Vec_IntForEachEntryStart( vLits, Lit, i, 1 ) + { + Diff = Lit - LitPrev; + Diff = (Lit < LitPrev)? -Diff : Diff; + Diff = (Diff << 1) | (int)(Lit < LitPrev); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff ); + LitPrev = Lit; + if ( Pos + 10 > vBinary->nCap ) + Vec_StrGrow( vBinary, vBinary->nCap+1 ); + } + vBinary->nSize = Pos; +/* + // verify + { + extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ); + char * pPos = Vec_StrArray( vBinary ); + Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) ); + for ( i = 0; i < Vec_IntSize(vLits); i++ ) + { + int Entry1 = Vec_IntEntry(vLits,i); + int Entry2 = Vec_IntEntry(vTemp,i); + assert( Entry1 == Entry2 ); + } + Vec_IntFree( vTemp ); + } +*/ + return vBinary; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( char * pBuffer, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + pBuffer[i] = (char)(0xff & (Value >> (i<<3))); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int k, iRepr, iNode, iPrevRepr, iPrevNode, iLit; + int nItems, iPos, nClasses, nMembers; + assert( p->pReprs && p->pNexts ); + Gia_ManSetPhase(p); + // count the number of entries to be written + nItems = 0; + nMembers = 0; + nClasses = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + nMembers += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + nClasses++; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + nClasses += (nMembers > 0); + // allocate place for data + pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 ); + // write the number of classes + iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses ); + // write constant class + if ( nMembers ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) ); + iPrevNode = 0; + k = 1; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, 0) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit ); + iPrevNode = iNode; +//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 ); + } + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + // write number of members + nMembers = 0; + Gia_ClassForEachObj( p, iRepr, iNode ) + nMembers++; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers ); + // write representatives + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 0) ); + // write members + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, iRepr) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit ); + iPrevNode = iNode; +//printf( "Writing equiv %d -> %d\n", iNode, iRepr ); + } + } + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachLut( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Writes char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word ) +{ + int i; + fprintf( pFile, "%c", Char ); + for ( i = 0; i < 8; i++ ) + fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteIntF( FILE * pFile, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact ) +{ + FILE * pFile; + Gia_Man_t * p; + Gia_Obj_t * pObj; + int i, nBufferSize, Pos; + unsigned char * pBuffer; + unsigned uLit0, uLit1, uLit; + + if ( Gia_ManCoNum(pInit) == 0 ) + { + printf( "AIG cannot be written because it has no POs.\n" ); + return; + } + + // start the output stream + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + // create normalized AIG + if ( !Gia_ManIsNormalized(pInit) ) + { +// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); + p = Gia_ManDupNormalized( pInit ); + } + else + p = pInit; + + // write the header "M I L O A" where M = I + L + A + fprintf( pFile, "aig%s %u %u %u %u %u\n", + fCompact? "2" : "", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p), + Gia_ManRegNum(p), + Gia_ManPoNum(p), + Gia_ManAndNum(p) ); + + if ( !fCompact ) + { + // write latch drivers + Gia_ManForEachRi( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + // write PO drivers + Gia_ManForEachPo( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Vec_Int_t * vLits = Gia_WriteAigerLiterals( p ); + Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits ); + fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile ); + Vec_StrFree( vBinary ); + Vec_IntFree( vLits ); + } + + // write the nodes into the buffer + Pos = 0; + nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge + pBuffer = ABC_ALLOC( unsigned char, nBufferSize ); + Gia_ManForEachAnd( p, pObj, i ) + { + uLit = Gia_Var2Lit( i, 0 ); + uLit0 = Gia_ObjFaninLit0( pObj, i ); + uLit1 = Gia_ObjFaninLit1( pObj, i ); + assert( uLit0 < uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 ); + if ( Pos > nBufferSize - 10 ) + { + printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); + return; + } + } + assert( Pos < nBufferSize ); + + // write the buffer + fwrite( pBuffer, 1, Pos, pFile ); + ABC_FREE( pBuffer ); + + // write the comment + fprintf( pFile, "c" ); + // write signature + Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE ); + // write name + if ( p->pName ) + { + Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) ); + fwrite( pInit->pName, 1, strlen(pInit->pName), pFile ); + } + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } + // write flop classes + if ( p->vFlopClasses ) + { + Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) ); + fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile ); + } +/* + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement + if ( p->pPlacement ) + { + Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) ); + fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile ); + } + // write switching activity + if ( p->pSwitching ) + { + Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) ); + fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile ); + } + // write name + if ( p->pName ) + fprintf( pFile, "n%s%c", p->pName, '\0' ); +*/ + // write constraints + if ( p->nConstrs ) + { + Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs ); + Gia_WriteIntF( pFile, p->nConstrs ); + } + // write the closing statement + Gia_WriteBlockHeader( pFile, '\0', (word)0 ); + // write comment + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ + char Buffer[100]; + sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); + Gia_WriteAiger( p, Buffer, 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaBidec.c b/src/aig/gia/giaBidec.c new file mode 100644 index 00000000..fc17b582 --- /dev/null +++ b/src/aig/gia/giaBidec.c @@ -0,0 +1,308 @@ +/**CFile**************************************************************** + + FileName [giaBidec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Application of bi-decomposition to AIG minimization.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "bdc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Bdc_FunObjCopy( Bdc_Fun_t * pObj ) { return Gia_LitNotCond( Bdc_FuncCopyInt(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } +static inline int Bdc_FunFanin0Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin0(pObj) ); } +static inline int Bdc_FunFanin1Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin1(pObj) ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManConvertAigToTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vTruth, int nWords, Vec_Int_t * vVisited ) +{ + unsigned * pTruth, * pTruth0, * pTruth1; + int i; + assert( !Gia_IsComplement(pObj) ); + if ( Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) != -1 ) + return (unsigned *)Vec_IntEntryP( vTruth, nWords * Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) ); + // compute the truth tables of the fanins + pTruth0 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin0(pObj), vTruth, nWords, vVisited ); + pTruth1 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin1(pObj), vTruth, nWords, vVisited ); + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + // create the truth table of the node + if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & pTruth1[i]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & ~pTruth1[i]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & pTruth1[i]; + else // if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; + // save the visited node + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) ); + Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); + return pTruth; +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the node.] + + Description [Assumes that the structural support is no more than 8 inputs. + Uses array vTruth to store temporary truth tables. The returned pointer should + be used immediately.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ) +{ + static unsigned uTruths[8][8] = { // elementary truth tables + { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, + { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, + { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, + { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, + { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, + { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, + { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, + { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } + }; + Gia_Obj_t * pObj; + Vec_Ptr_t * vTtElems = NULL; + unsigned * pTruth;//, * pTruth2; + int i, nWords, nVars; + // get the number of variables and words + nVars = Vec_IntSize( vLeaves ); + nWords = Gia_TruthWordNum( nVars ); + // check the case of a constant + if ( Gia_ObjIsConst0( Gia_Regular(pRoot) ) ) + { + Vec_IntClear( vTruth ); + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + if ( !Gia_IsComplement(pRoot) ) + Gia_ManTruthClear( pTruth, nVars ); + else + Gia_ManTruthFill( pTruth, nVars ); + return pTruth; + } + // if the number of variables is more than 8, allocate truth tables + if ( nVars > 8 ) + vTtElems = Vec_PtrAllocTruthTables( nVars ); + // assign elementary truth tables + Vec_IntClear( vTruth ); + Vec_IntClear( vVisited ); + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + { + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + // assign elementary variable + if ( vTtElems ) + Gia_ManTruthCopy( pTruth, (unsigned *)Vec_PtrEntry(vTtElems, i), nVars ); + else + Gia_ManTruthCopy( pTruth, uTruths[i], nVars ); + // save the visited node + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) ); + Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); + } + if ( vTtElems ) + Vec_PtrFree( vTtElems ); + // clear the marks and compute the truth table +// pTruth2 = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited ); + pTruth = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited ); + // copy the result +// Gia_ManTruthCopy( pTruth, pTruth2, nVars ); + if ( Gia_IsComplement(pRoot) ) + Gia_ManTruthNot( pTruth, pTruth, nVars ); + // clean truth tables + Gia_ManForEachObjVec( vVisited, p, pObj, i ) + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), -1 ); + return pTruth; +} + +/**Function************************************************************* + + Synopsis [Resynthesizes nodes using bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjPerformBidec( Bdc_Man_t * pManDec, + Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pRoot, + Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ) +{ + unsigned * pTruth; + Bdc_Fun_t * pFunc; + Gia_Obj_t * pFanin; + int i, iFan, nVars, nNodes; + // collect leaves of this gate + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i ) + Vec_IntPush( vLeaves, iFan ); + nVars = Vec_IntSize( vLeaves ); + assert( nVars < 16 ); + // derive truth table + pTruth = Gia_ManConvertAigToTruth( p, pRoot, vLeaves, vTruth, vVisited ); +//Extra_PrintBinary( stdout, pTruth, (1<<nVars) ); printf( "\n" ); + if ( Gia_ManTruthIsConst0(pTruth, nVars) ) + { +//printf( "Node %d is const0\n", Gia_ObjId(p, pRoot) ); + return 0; + } + if ( Gia_ManTruthIsConst1(pTruth, nVars) ) + { +//printf( "Node %d is const1\n", Gia_ObjId(p, pRoot) ); + return 1; + } + // decompose truth table + Bdc_ManDecompose( pManDec, pTruth, NULL, nVars, NULL, 1000 ); +/* +if ( Bdc_ManNodeNum(pManDec) == 0 ) + printf( "Node %d has 0 bidec nodes\n", Gia_ObjId(p, pRoot) ); +if ( Kit_TruthSupportSize(pTruth, nVars) != nVars ) +{ + printf( "Node %d has %d fanins and %d supp size\n", Gia_ObjId(p, pRoot), nVars, Kit_TruthSupportSize(pTruth, nVars) ); + Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i ) + { + printf( "%d ", Kit_TruthVarInSupport(pTruth, nVars, i) ); + Gia_ObjPrint( p, Gia_ManObj(p, iFan) ); + } +// Gia_ManPrintStats( p, 0 ); +} +*/ + // convert back into HOP + Bdc_FuncSetCopy( Bdc_ManFunc( pManDec, 0 ), Gia_ManConst1(pNew) ); + Gia_ManForEachObjVec( vLeaves, p, pFanin, i ) + Bdc_FuncSetCopyInt( Bdc_ManFunc( pManDec, i+1 ), Gia_ObjValue(pFanin) ); + nNodes = Bdc_ManNodeNum( pManDec ); + for ( i = nVars + 1; i < nNodes; i++ ) + { + pFunc = Bdc_ManFunc( pManDec, i ); + Bdc_FuncSetCopyInt( pFunc, Gia_ManHashAnd( pNew, Bdc_FunFanin0Copy(pFunc), Bdc_FunFanin1Copy(pFunc) ) ); + } + return Bdc_FunObjCopy( Bdc_ManRoot(pManDec) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose ) +{ + Bdc_Man_t * pManDec; + Bdc_Par_t Pars = {0}, * pPars = &Pars; + Vec_Int_t * vLeaves, * vTruth, * vVisited; + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, clk = clock(); + pPars->nVarsMax = Gia_ManLutSizeMax( p ); + pPars->fVerbose = fVerbose; + if ( pPars->nVarsMax < 2 ) + { + printf( "Resynthesis is not performed when nodes have less than 2 inputs.\n" ); + return NULL; + } + if ( pPars->nVarsMax > 15 ) + { + printf( "Resynthesis is not performed when nodes have more than 15 inputs.\n" ); + return NULL; + } + vLeaves = Vec_IntAlloc( 0 ); + vTruth = Vec_IntAlloc( (1<<16) ); + vVisited = Vec_IntAlloc( 0 ); + // clean the old manager + Gia_ManCleanTruth( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + // start the new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); +// Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); + pManDec = Bdc_ManAlloc( pPars ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) // transfer the CI level (is it needed?) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsLut(p, i) ) + pObj->Value = Gia_ObjPerformBidec( pManDec, pNew, p, pObj, vLeaves, vTruth, vVisited ); + } + Bdc_ManFree( pManDec ); + // cleanup the AIG + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + if ( Gia_ManHasDangling(pNew) ) + { + pNew = Gia_ManCleanup( pTemp = pNew ); + if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) ) + printf( "Gia_ManPerformBidec() node count before and after: %6d and %6d.\n", Gia_ManAndNum(pNew), Gia_ManAndNum(pTemp) ); + Gia_ManStop( pTemp ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + if ( fVerbose ) + { +// printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) ); +// ABC_PRT( "Total runtime", clock() - clk ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c index e3aca7df..1c5b05fe 100644 --- a/src/aig/gia/giaCSat.c +++ b/src/aig/gia/giaCSat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //#define gia_assert(exp) ((void)0) //#define gia_assert(exp) (assert(exp)) @@ -627,7 +630,7 @@ static inline void Cbs_ManDeriveReason( Cbs_Man_t * p, int Level ) assert( pQue->pData[pQue->iHead] != NULL ); pQue->iTail = k; // clear the marks - Vec_PtrForEachEntry( p->vTemp, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i ) pObj->fMark0 = 1; } @@ -1094,3 +1097,5 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCSatOld.c b/src/aig/gia/giaCSatOld.c index bd8f061b..983081f0 100644 --- a/src/aig/gia/giaCSatOld.c +++ b/src/aig/gia/giaCSatOld.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -796,3 +799,5 @@ Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStat //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCTas.c b/src/aig/gia/giaCTas.c new file mode 100644 index 00000000..c6aa3fec --- /dev/null +++ b/src/aig/gia/giaCTas.c @@ -0,0 +1,1788 @@ +/**CFile**************************************************************** + + FileName [giaCSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [A simple circuit-based solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//#define gia_assert(exp) ((void)0) +//#define gia_assert(exp) (assert(exp)) + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Tas_Par_t_ Tas_Par_t; +struct Tas_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + int nJustLimit; // limit on the size of justification queue + // current parameters + int nBTThis; // number of conflicts + int nBTThisNc; // number of conflicts + int nJustThis; // max size of the frontier + int nBTTotal; // total number of conflicts + int nJustTotal; // total size of the frontier + // activity + float VarDecay; // variable activity decay + int VarInc; // variable increment + // decision heuristics + int fUseActive; // use most active + int fUseHighest; // use node with the highest ID + int fUseLowest; // use node with the highest ID + int fUseMaxFF; // use node with the largest fanin fanout + // other + int fVerbose; +}; + +typedef struct Tas_Cls_t_ Tas_Cls_t; +struct Tas_Cls_t_ +{ + int iNext[2]; // beginning of the queue + int nLits; // the number of literals + int pLits[0]; // clause literals +}; + +typedef struct Tas_Sto_t_ Tas_Sto_t; +struct Tas_Sto_t_ +{ + int iCur; // current position + int nSize; // allocated size + int * pData; // clause information +}; + +typedef struct Tas_Que_t_ Tas_Que_t; +struct Tas_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + Gia_Obj_t ** pData; // nodes stored in the queue +}; + +struct Tas_Man_t_ +{ + Tas_Par_t Pars; // parameters + Gia_Man_t * pAig; // AIG manager + Tas_Que_t pProp; // propagation queue + Tas_Que_t pJust; // justification queue + Tas_Que_t pClauses; // clause queue + Gia_Obj_t ** pIter; // iterator through clause vars + Vec_Int_t * vLevReas; // levels and decisions + Vec_Int_t * vModel; // satisfying assignment + Vec_Ptr_t * vTemp; // temporary storage + // watched clauses + Tas_Sto_t pStore; // storage for watched clauses + int * pWatches; // watched lists for each literal + Vec_Int_t * vWatchLits; // lits whose watched are assigned + int nClauses; // the counter of clauses + // activity + float * pActivity; // variable activity + Vec_Int_t * vActiveVars; // variables with activity + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + // runtime stats + int timeSatUnsat; // unsat + int timeSatSat; // sat + int timeSatUndec; // undecided + int timeTotal; // total runtime +}; + +static inline int Tas_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } +static inline void Tas_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; } +static inline void Tas_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; pVar->fMark1 = 0; pVar->Value = ~0; } +static inline int Tas_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; } +static inline void Tas_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; } +static inline int Tas_VarIsJust( Gia_Obj_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); } +static inline int Tas_VarFanin0Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); } +static inline int Tas_VarFanin1Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); } +static inline int Tas_VarToLit( Tas_Man_t * p, Gia_Obj_t * pObj ) { assert( Tas_VarIsAssigned(pObj) ); return Gia_Var2Lit( Gia_ObjId(p->pAig, pObj), !Tas_VarValue(pObj) ); } +static inline int Tas_LitIsTrue( Gia_Obj_t * pObj, int Lit ) { assert( Tas_VarIsAssigned(pObj) ); return Tas_VarValue(pObj) != Gia_LitIsCompl(Lit); } + +static inline int Tas_ClsHandle( Tas_Man_t * p, Tas_Cls_t * pClause ) { return ((int *)pClause) - p->pStore.pData; } +static inline Tas_Cls_t * Tas_ClsFromHandle( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pStore.pData + h); } + +static inline int Tas_VarDecLevel( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); } +static inline Gia_Obj_t * Tas_VarReason0( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); } +static inline Gia_Obj_t * Tas_VarReason1( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); } +static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +static inline int Tas_VarHasReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value+1) == 0 && Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) != 0; } +static inline Tas_Cls_t * Tas_VarReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Tas_ClsFromHandle( p, Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) ); } + +#define Tas_QueForEachEntry( Que, pObj, i ) \ + for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ ) + +#define Tas_ClauseForEachVar( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData + hClause; (pObj = *pIter); (p)->pIter++ ) +#define Tas_ClauseForEachVar1( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData+hClause+1; (pObj = *pIter); (p)->pIter++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets default values of the parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_SetDefaultParams( Tas_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Tas_Par_t) ); + pPars->nBTLimit = 2000; // limit on the number of conflicts + pPars->nJustLimit = 2000; // limit on the size of justification queue + pPars->fUseActive = 0; // use node with the highest activity + pPars->fUseHighest = 1; // use node with the highest ID + pPars->fUseLowest = 0; // use node with the lowest ID + pPars->fUseMaxFF = 0; // use node with the largest fanin fanout + pPars->fVerbose = 1; // print detailed statistics + pPars->VarDecay = (float)0.95; // variable decay + pPars->VarInc = 1.0; // variable increment +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit ) +{ + Tas_Man_t * p; + p = ABC_CALLOC( Tas_Man_t, 1 ); + Tas_SetDefaultParams( &p->Pars ); + p->pAig = pAig; + p->Pars.nBTLimit = nBTLimit; + p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000; + p->pProp.pData = ABC_ALLOC( Gia_Obj_t *, p->pProp.nSize ); + p->pJust.pData = ABC_ALLOC( Gia_Obj_t *, p->pJust.nSize ); + p->pClauses.pData = ABC_ALLOC( Gia_Obj_t *, p->pClauses.nSize ); + p->pClauses.iHead = p->pClauses.iTail = 1; + p->vModel = Vec_IntAlloc( 1000 ); + p->vLevReas = Vec_IntAlloc( 1000 ); + p->vTemp = Vec_PtrAlloc( 1000 ); + p->pStore.iCur = 16; + p->pStore.nSize = 10000; + p->pStore.pData = ABC_ALLOC( int, p->pStore.nSize ); + p->pWatches = ABC_CALLOC( int, 2 * Gia_ManObjNum(pAig) ); + p->vWatchLits = Vec_IntAlloc( 100 ); + p->pActivity = ABC_CALLOC( float, Gia_ManObjNum(pAig) ); + p->vActiveVars = Vec_IntAlloc( 100 ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManStop( Tas_Man_t * p ) +{ + Vec_IntFree( p->vActiveVars ); + Vec_IntFree( p->vWatchLits ); + Vec_IntFree( p->vLevReas ); + Vec_IntFree( p->vModel ); + Vec_PtrFree( p->vTemp ); + ABC_FREE( p->pActivity ); + ABC_FREE( p->pWatches ); + ABC_FREE( p->pStore.pData ); + ABC_FREE( p->pClauses.pData ); + ABC_FREE( p->pProp.pData ); + ABC_FREE( p->pJust.pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Tas_ReadModel( Tas_Man_t * p ) +{ + return p->vModel; +} + + + + +/**Function************************************************************* + + Synopsis [Returns 1 if the solver is out of limits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManCheckLimits( Tas_Man_t * p ) +{ + return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit; +} + +/**Function************************************************************* + + Synopsis [Saves the satisfying assignment as an array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex ) +{ + Gia_Obj_t * pVar; + int i; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; +// printf( "\n" ); + Tas_QueForEachEntry( p->pProp, pVar, i ) + { + if ( Gia_ObjIsCi(pVar) ) +// Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Tas_VarValue(pVar)) ); + Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pVar), !Tas_VarValue(pVar)) ); +/* + printf( "%5d(%d) = ", Gia_ObjId(p->pAig, pVar), Tas_VarValue(pVar) ); + if ( Gia_ObjIsCi(pVar) ) + printf( "pi %d\n", Gia_ObjCioId(pVar) ); + else + { + printf( "%5d %d & ", Gia_ObjFaninId0p(p->pAig, pVar), Gia_ObjFaninC0(pVar) ); + printf( "%5d %d ", Gia_ObjFaninId1p(p->pAig, pVar), Gia_ObjFaninC1(pVar) ); + printf( "\n" ); + } +*/ + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueIsEmpty( Tas_Que_t * p ) +{ + return p->iHead == p->iTail; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QuePush( Tas_Que_t * p, Gia_Obj_t * pObj ) +{ + if ( p->iTail == p->nSize ) + { + p->nSize *= 2; + p->pData = ABC_REALLOC( Gia_Obj_t *, p->pData, p->nSize ); + } + p->pData[p->iTail++] = pObj; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the object in the queue.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueHasNode( Tas_Que_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pTemp; + int i; + Tas_QueForEachEntry( *p, pTemp, i ) + if ( pTemp == pObj ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QueStore( Tas_Que_t * p, int * piHeadOld, int * piTailOld ) +{ + int i; + *piHeadOld = p->iHead; + *piTailOld = p->iTail; + for ( i = *piHeadOld; i < *piTailOld; i++ ) + Tas_QuePush( p, p->pData[i] ); + p->iHead = *piTailOld; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QueRestore( Tas_Que_t * p, int iHeadOld, int iTailOld ) +{ + p->iHead = iHeadOld; + p->iTail = iTailOld; +} + +/**Function************************************************************* + + Synopsis [Finalized the clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueFinish( Tas_Que_t * p ) +{ + int iHeadOld = p->iHead; + assert( p->iHead < p->iTail ); + Tas_QuePush( p, NULL ); + p->iHead = p->iTail; + return iHeadOld; +} + + +/**Function************************************************************* + + Synopsis [Max number of fanins fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_VarFaninFanoutMax( Tas_Man_t * p, Gia_Obj_t * pObj ) +{ + int Count0, Count1; + assert( !Gia_IsComplement(pObj) ); + assert( Gia_ObjIsAnd(pObj) ); + Count0 = Gia_ObjRefs( p->pAig, Gia_ObjFanin0(pObj) ); + Count1 = Gia_ObjRefs( p->pAig, Gia_ObjFanin1(pObj) ); + return ABC_MAX( Count0, Count1 ); +} + + + +/**Function************************************************************* + + Synopsis [Find variable with the highest activity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManFindActive( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + float BestCost = 0.0; + int i, ObjId; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + ObjId = Gia_ObjId( p->pAig, pObj ); + if ( pObjMax == NULL || + p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] > BestCost || + (p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin0(pObj)) ) + { + pObjMax = Gia_ObjFanin0(pObj); + BestCost = p->pActivity[Gia_ObjFaninId0(pObj,ObjId)]; + } + if ( p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] > BestCost || + (p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin1(pObj)) ) + { + pObjMax = Gia_ObjFanin1(pObj); + BestCost = p->pActivity[Gia_ObjFaninId1(pObj,ObjId)]; + } + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest activity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighestFanin( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i, ObjId; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + ObjId = Gia_ObjId( p->pAig, pObj ); + if ( pObjMax == NULL || pObjMax < Gia_ObjFanin0(pObj) ) + pObjMax = Gia_ObjFanin0(pObj); + if ( pObjMax < Gia_ObjFanin1(pObj) ) + pObjMax = Gia_ObjFanin1(pObj); + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighest( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { +//printf( "%d %6.2f ", Gia_ObjId(p->pAig, pObj), p->pActivity[Gia_ObjId(p->pAig, pObj)] ); + if ( pObjMax == NULL || pObjMax < pObj ) + pObjMax = pObj; + } +//printf( "\n" ); + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighestA( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + if ( pObjMax == NULL || + p->pActivity[Gia_ObjId(p->pAig, pObjMax)] < p->pActivity[Gia_ObjId(p->pAig, pObj)] ) + pObjMax = pObj; + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the lowest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideLowest( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMin = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + if ( pObjMin == NULL || pObjMin > pObj ) + pObjMin = pObj; + return pObjMin; +} + +/**Function************************************************************* + + Synopsis [Find variable with the maximum number of fanin fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideMaxFF( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i, iMaxFF = 0, iCurFF; + assert( p->pAig->pRefs != NULL ); + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + iCurFF = Tas_VarFaninFanoutMax( p, pObj ); + assert( iCurFF > 0 ); + if ( iMaxFF < iCurFF ) + { + iMaxFF = iCurFF; + pObjMax = pObj; + } + } + return pObjMax; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManCancelUntil( Tas_Man_t * p, int iBound ) +{ + Gia_Obj_t * pVar; + int i; + assert( iBound <= p->pProp.iTail ); + p->pProp.iHead = iBound; + Tas_QueForEachEntry( p->pProp, pVar, i ) + Tas_VarUnassign( pVar ); + p->pProp.iTail = iBound; + Vec_IntShrink( p->vLevReas, 3*iBound ); +} + +int s_Counter2 = 0; +int s_Counter3 = 0; +int s_Counter4 = 0; + +/**Function************************************************************* + + Synopsis [Assigns the variables a value.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManAssign( Tas_Man_t * p, Gia_Obj_t * pObj, int Level, Gia_Obj_t * pRes0, Gia_Obj_t * pRes1 ) +{ + Gia_Obj_t * pObjR = Gia_Regular(pObj); + assert( Gia_ObjIsCand(pObjR) ); + assert( !Tas_VarIsAssigned(pObjR) ); + Tas_VarAssign( pObjR ); + Tas_VarSetValue( pObjR, !Gia_IsComplement(pObj) ); + assert( pObjR->Value == ~0 ); + pObjR->Value = p->pProp.iTail; + Tas_QuePush( &p->pProp, pObjR ); + Vec_IntPush( p->vLevReas, Level ); + if ( pRes0 == NULL && pRes1 != 0 ) // clause + { + Vec_IntPush( p->vLevReas, 0 ); + Vec_IntPush( p->vLevReas, Tas_ClsHandle( p, (Tas_Cls_t *)pRes1 ) ); + } + else + { + Vec_IntPush( p->vLevReas, pRes0 ? pRes0-pObjR : 0 ); + Vec_IntPush( p->vLevReas, pRes1 ? pRes1-pObjR : 0 ); + } + assert( Vec_IntSize(p->vLevReas) == 3 * p->pProp.iTail ); + s_Counter2++; +} + + +/**Function************************************************************* + + Synopsis [Returns clause size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManClauseSize( Tas_Man_t * p, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t ** pIter; + for ( pIter = pQue->pData + hClause; *pIter; pIter++ ); + return pIter - pQue->pData - hClause ; +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManPrintClause( Tas_Man_t * p, int Level, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%d=%d(%d) ", Gia_ObjId(p->pAig, pObj), Tas_VarValue(pObj), Tas_VarDecLevel(p, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManPrintClauseNew( Tas_Man_t * p, int Level, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%c%d ", Tas_VarValue(pObj)? '+':'-', Gia_ObjId(p->pAig, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManDeriveReason( Tas_Man_t * p, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj, * pReason; + int i, k, j, iLitLevel, iLitLevel2;//, Id; + assert( pQue->pData[pQue->iHead] == NULL ); + assert( pQue->iHead + 1 < pQue->iTail ); +/* + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + assert( pObj->fPhase == 0 ); + } +*/ + // compact literals + Vec_PtrClear( p->vTemp ); + for ( i = k = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Vec_PtrPush( p->vTemp, pObj ); + // bump activity +// Id = Gia_ObjId( p->pAig, pObj ); +// if ( p->pActivity[Id] == 0.0 ) +// Vec_IntPush( p->vActiveVars, Id ); +// p->pActivity[Id] += p->Pars.VarInc; + // check decision level + iLitLevel = Tas_VarDecLevel( p, pObj ); + if ( iLitLevel < Level ) + { + pQue->pData[k++] = pObj; + continue; + } + assert( iLitLevel == Level ); + if ( Tas_VarHasReasonCls( p, pObj ) ) + { + Tas_Cls_t * pCls = Tas_VarReasonCls( p, pObj ); + pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[0]) ); + assert( pReason == pObj ); + for ( j = 1; j < pCls->nLits; j++ ) + { + pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[j]) ); + iLitLevel2 = Tas_VarDecLevel( p, pReason ); + assert( Tas_VarIsAssigned( pReason ) ); + assert( !Tas_LitIsTrue( pReason, pCls->pLits[j] ) ); + Tas_QuePush( pQue, pReason ); + } + } + else + { + pReason = Tas_VarReason0( p, pObj ); + if ( pReason == pObj ) // no reason + { + assert( pQue->pData[pQue->iHead] == NULL || Level == 0 ); + if ( pQue->pData[pQue->iHead] == NULL ) + pQue->pData[pQue->iHead] = pObj; + else + Tas_QuePush( pQue, pObj ); + continue; + } + Tas_QuePush( pQue, pReason ); + pReason = Tas_VarReason1( p, pObj ); + if ( pReason != pObj ) // second reason + Tas_QuePush( pQue, pReason ); + } + } + assert( pQue->pData[pQue->iHead] != NULL ); + if ( pQue->pData[pQue->iHead] == NULL ) + printf( "Tas_ManDeriveReason(): Failed to derive the clause!!!\n" ); + pQue->iTail = k; + // clear the marks + Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i ) + pObj->fPhase = 0; +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManAnalyze( Tas_Man_t * p, int Level, Gia_Obj_t * pVar, Gia_Obj_t * pFan0, Gia_Obj_t * pFan1 ) +{ + Tas_Que_t * pQue = &(p->pClauses); + assert( Tas_VarIsAssigned(pVar) ); + assert( Tas_VarIsAssigned(pFan0) ); + assert( pFan1 == NULL || Tas_VarIsAssigned(pFan1) ); + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + Tas_QuePush( pQue, pVar ); + Tas_QuePush( pQue, pFan0 ); + if ( pFan1 ) + Tas_QuePush( pQue, pFan1 ); + Tas_ManDeriveReason( p, Level ); + return Tas_QueFinish( pQue ); +} + + +/**Function************************************************************* + + Synopsis [Performs resolution of two clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManResolve( Tas_Man_t * p, int Level, int hClause0, int hClause1 ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i, LevelMax = -1, LevelCur; + assert( pQue->pData[hClause0] != NULL ); + assert( pQue->pData[hClause0] == pQue->pData[hClause1] ); +/* + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fPhase == 0 ); + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fPhase == 0 ); +*/ + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Tas_QuePush( pQue, pObj ); + LevelCur = Tas_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Tas_QuePush( pQue, pObj ); + LevelCur = Tas_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + pQue->pData[i]->fPhase = 0; + Tas_ManDeriveReason( p, LevelMax ); + return Tas_QueFinish( pQue ); +} + + + +/**Function************************************************************* + + Synopsis [Allocates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Tas_Cls_t * Tas_ManAllocCls( Tas_Man_t * p, int nSize ) +{ + Tas_Cls_t * pCls; + if ( p->pStore.iCur + nSize > p->pStore.nSize ) + { + p->pStore.nSize *= 2; + p->pStore.pData = ABC_REALLOC( int, p->pStore.pData, p->pStore.nSize ); + } + pCls = Tas_ClsFromHandle( p, p->pStore.iCur ); p->pStore.iCur += nSize; + memset( pCls, 0, sizeof(int) * nSize ); + p->nClauses++; + return pCls; +} + +/**Function************************************************************* + + Synopsis [Adds one clause to the watcher list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManWatchClause( Tas_Man_t * p, Tas_Cls_t * pClause, int Lit ) +{ + assert( Gia_Lit2Var(Lit) < Gia_ManObjNum(p->pAig) ); + assert( pClause->nLits >= 2 ); + assert( pClause->pLits[0] == Lit || pClause->pLits[1] == Lit ); + if ( pClause->pLits[0] == Lit ) + pClause->iNext[0] = p->pWatches[Gia_LitNot(Lit)]; + else + pClause->iNext[1] = p->pWatches[Gia_LitNot(Lit)]; + if ( p->pWatches[Gia_LitNot(Lit)] == 0 ) + Vec_IntPush( p->vWatchLits, Gia_LitNot(Lit) ); + p->pWatches[Gia_LitNot(Lit)] = Tas_ClsHandle( p, pClause ); +} + +/**Function************************************************************* + + Synopsis [Creates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Tas_Cls_t * Tas_ManCreateCls( Tas_Man_t * p, int hClause ) +{ + Tas_Cls_t * pClause; + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i, nLits = 0; + assert( Tas_QueIsEmpty( pQue ) ); + assert( pQue->pData[hClause] != NULL ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + nLits++; + if ( nLits == 1 ) + return NULL; + // create this clause + pClause = Tas_ManAllocCls( p, nLits + 3 ); + pClause->nLits = nLits; + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + { + assert( Tas_VarIsAssigned( pObj ) ); + pClause->pLits[i-hClause] = Gia_LitNot( Tas_VarToLit(p, pObj) ); + } + // add the clause as watched one + if ( nLits >= 2 ) + { + Tas_ManWatchClause( p, pClause, pClause->pLits[0] ); + Tas_ManWatchClause( p, pClause, pClause->pLits[1] ); + } + // increment activity +// p->Pars.VarInc /= p->Pars.VarDecay; + return pClause; +} + +/**Function************************************************************* + + Synopsis [Creates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManCreateFromCls( Tas_Man_t * p, Tas_Cls_t * pCls, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + for ( i = 0; i < pCls->nLits; i++ ) + { + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[i]) ); + assert( Tas_VarIsAssigned(pObj) ); + assert( !Tas_LitIsTrue( pObj, pCls->pLits[i] ) ); + Tas_QuePush( pQue, pObj ); + } + Tas_ManDeriveReason( p, Level ); + return Tas_QueFinish( pQue ); +} + +/**Function************************************************************* + + Synopsis [Propagate one assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateWatch( Tas_Man_t * p, int Level, int Lit ) +{ + Gia_Obj_t * pObj; + Tas_Cls_t * pCur; + int * piPrev, iCur, iTemp; + int i, LitF = Gia_LitNot(Lit); + // iterate through the clauses + piPrev = p->pWatches + Lit; + for ( iCur = p->pWatches[Lit]; iCur; iCur = *piPrev ) + { + pCur = Tas_ClsFromHandle( p, iCur ); + // make sure the false literal is in the second literal of the clause + if ( pCur->pLits[0] == LitF ) + { + pCur->pLits[0] = pCur->pLits[1]; + pCur->pLits[1] = LitF; + iTemp = pCur->iNext[0]; + pCur->iNext[0] = pCur->iNext[1]; + pCur->iNext[1] = iTemp; + } + assert( pCur->pLits[1] == LitF ); + + // if the first literal is true, the clause is satisfied +// if ( pCur->pLits[0] == p->pAssigns[Gia_Lit2Var(pCur->pLits[0])] ) + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) ); + if ( Tas_VarIsAssigned(pObj) && Tas_LitIsTrue( pObj, pCur->pLits[0] ) ) + { + piPrev = &pCur->iNext[1]; + continue; + } + + // look for a new literal to watch + for ( i = 2; i < (int)pCur->nLits; i++ ) + { + // skip the case when the literal is false +// if ( Gia_LitNot(pCur->pLits[i]) == p->pAssigns[Gia_Lit2Var(pCur->pLits[i])] ) + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) ); + if ( Tas_VarIsAssigned(pObj) && !Tas_LitIsTrue( pObj, pCur->pLits[i] ) ) + continue; + // the literal is either true or unassigned - watch it + pCur->pLits[1] = pCur->pLits[i]; + pCur->pLits[i] = LitF; + // remove this clause from the watch list of Lit + *piPrev = pCur->iNext[1]; + // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1]) + Tas_ManWatchClause( p, pCur, pCur->pLits[1] ); + break; + } + if ( i < (int)pCur->nLits ) // found new watch + continue; + + // clause is unit - enqueue new implication + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) ); + if ( !Tas_VarIsAssigned(pObj) ) + { +/* + { + int iLitLevel, iPlace; + for ( i = 1; i < (int)pCur->nLits; i++ ) + { + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) ); + iLitLevel = Tas_VarDecLevel( p, pObj ); + iPlace = pObj->Value; + printf( "Lit = %d. Level = %d. Place = %d.\n", pCur->pLits[i], iLitLevel, iPlace ); + i = i; + } + } +*/ + Tas_ManAssign( p, Gia_ObjFromLit(p->pAig, pCur->pLits[0]), Level, NULL, (Gia_Obj_t *)pCur ); + piPrev = &pCur->iNext[1]; + continue; + } + // conflict detected - return the conflict clause + assert( !Tas_LitIsTrue( pObj, pCur->pLits[0] ) ); + return Tas_ManCreateFromCls( p, pCur, Level ); + } + return 0; +} + + + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns clause handle if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateOne( Tas_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1, hClause; + assert( !Gia_IsComplement(pVar) ); + assert( Tas_VarIsAssigned(pVar) ); + s_Counter3++; + if ( (hClause = Tas_ManPropagateWatch( p, Level, Tas_VarToLit(p, pVar) )) ) + return hClause; + if ( Gia_ObjIsCi(pVar) ) + return 0; +/* + if ( pVar->iDiff0 == 570869 && pVar->iDiff1 == 546821 && Level == 3 ) + { + Gia_Obj_t * pFan0 = Gia_ObjFanin0(pVar); + Gia_Obj_t * pFan1 = Gia_ObjFanin1(pVar); + int s = 0; + } +*/ + assert( Gia_ObjIsAnd(pVar) ); + Value0 = Tas_VarFanin0Value(pVar); + Value1 = Tas_VarFanin1Value(pVar); + if ( Tas_VarValue(pVar) ) + { // value is 1 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + { + if ( Value0 == 0 && Value1 != 0 ) + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), NULL ); + if ( Value0 != 0 && Value1 == 0 ) + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin1(pVar), NULL ); + assert( Value0 == 0 && Value1 == 0 ); + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + } + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_ObjChild0(pVar), Level, pVar, NULL ); + if ( Value1 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_ObjChild1(pVar), Level, pVar, NULL ); + return 0; + } + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + if ( Value0 == 1 || Value1 == 1 ) // one is 1 + { + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // second is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; + } + assert( Tas_VarIsJust(pVar) ); + assert( !Tas_QueHasNode( &p->pJust, pVar ) ); + Tas_QuePush( &p->pJust, pVar ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateTwo( Tas_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1; + s_Counter4++; + assert( !Gia_IsComplement(pVar) ); + assert( Gia_ObjIsAnd(pVar) ); + assert( Tas_VarIsAssigned(pVar) ); + assert( !Tas_VarValue(pVar) ); + Value0 = Tas_VarFanin0Value(pVar); + Value1 = Tas_VarFanin1Value(pVar); + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + assert( Value0 == 1 || Value1 == 1 ); + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates all variables.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManPropagate( Tas_Man_t * p, int Level ) +{ + int hClause; + Gia_Obj_t * pVar; + int i, k, nIter = 0; + while ( 1 ) + { +// nIter++; + Tas_QueForEachEntry( p->pProp, pVar, i ) + { + if ( (hClause = Tas_ManPropagateOne( p, pVar, Level )) ) + return hClause; + } + p->pProp.iHead = p->pProp.iTail; + k = p->pJust.iHead; + Tas_QueForEachEntry( p->pJust, pVar, i ) + { + if ( Tas_VarIsJust( pVar ) ) + p->pJust.pData[k++] = pVar; + else if ( (hClause = Tas_ManPropagateTwo( p, pVar, Level )) ) + return hClause; + } + if ( k == p->pJust.iTail ) + break; + p->pJust.iTail = k; + } +// printf( "%d ", nIter ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Solve the problem recursively.] + + Description [Returns learnt clause if unsat, NULL if sat or undecided.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolve_rec( Tas_Man_t * p, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pVar, * pDecVar; + int hClause, hLearn0, hLearn1; + int iPropHead, iJustHead, iJustTail; + // propagate assignments + assert( !Tas_QueIsEmpty(&p->pProp) ); + if ( (hClause = Tas_ManPropagate( p, Level )) ) + { + Tas_ManCreateCls( p, hClause ); + return hClause; + } + // check for satisfying assignment + assert( Tas_QueIsEmpty(&p->pProp) ); + if ( Tas_QueIsEmpty(&p->pJust) ) + return 0; + // quit using resource limits + p->Pars.nJustThis = ABC_MAX( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead ); + if ( Tas_ManCheckLimits( p ) ) + return 0; + // remember the state before branching + iPropHead = p->pProp.iHead; + Tas_QueStore( &p->pJust, &iJustHead, &iJustTail ); + // find the decision variable + if ( p->Pars.fUseActive ) + pVar = NULL, pDecVar = Tas_ManFindActive( p ); + else if ( p->Pars.fUseHighest ) +// pVar = NULL, pDecVar = Tas_ManDecideHighestFanin( p ); + pVar = Tas_ManDecideHighest( p ); + else if ( p->Pars.fUseLowest ) + pVar = Tas_ManDecideLowest( p ); + else if ( p->Pars.fUseMaxFF ) + pVar = Tas_ManDecideMaxFF( p ); + else assert( 0 ); + // chose decision variable using fanout count + if ( pVar != NULL ) + { + assert( Tas_VarIsJust( pVar ) ); + if ( Gia_ObjRefs(p->pAig, Gia_ObjFanin0(pVar)) > Gia_ObjRefs(p->pAig, Gia_ObjFanin1(pVar)) ) + pDecVar = Gia_Not(Gia_ObjChild0(pVar)); + else + pDecVar = Gia_Not(Gia_ObjChild1(pVar)); +// pDecVar = Gia_NotCond( pDecVar, Gia_Regular(pDecVar)->fMark1 ^ !Gia_IsComplement(pDecVar) ); + } + // decide on first fanin + Tas_ManAssign( p, pDecVar, Level+1, NULL, NULL ); + if ( !(hLearn0 = Tas_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn0] != Gia_Regular(pDecVar) ) + return hLearn0; + Tas_ManCancelUntil( p, iPropHead ); + Tas_QueRestore( &p->pJust, iJustHead, iJustTail ); + // decide on second fanin + Tas_ManAssign( p, Gia_Not(pDecVar), Level+1, NULL, NULL ); + if ( !(hLearn1 = Tas_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn1] != Gia_Regular(pDecVar) ) + return hLearn1; + hClause = Tas_ManResolve( p, Level, hLearn0, hLearn1 ); + Tas_ManCreateCls( p, hClause ); +// Tas_ManPrintClauseNew( p, Level, hClause ); +// if ( Level > Tas_ClauseDecLevel(p, hClause) ) +// p->Pars.nBTThisNc++; + p->Pars.nBTThis++; + return hClause; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [Assumes that each node has flag pObj->fMark0 set to 0. + Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided. + The node may be complemented. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ) +{ + int i, Entry, RetValue = 0; + s_Counter2 = 0; + Vec_IntClear( p->vModel ); + if ( pObj == Gia_ManConst0(p->pAig) || pObj2 == Gia_ManConst0(p->pAig) || pObj == Gia_Not(pObj2) ) + return 1; + if ( pObj == Gia_ManConst1(p->pAig) && (pObj2 == NULL || pObj2 == Gia_ManConst1(p->pAig)) ) + return 0; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + Tas_ManAssign( p, pObj, 0, NULL, NULL ); + if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) ) + Tas_ManAssign( p, pObj2, 0, NULL, NULL ); + if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) ) + Tas_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + Tas_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + // clauses + if ( p->nClauses > 0 ) + { + p->pStore.iCur = 16; + Vec_IntForEachEntry( p->vWatchLits, Entry, i ) + p->pWatches[Entry] = 0; + Vec_IntClear( p->vWatchLits ); + p->nClauses = 0; + } + // activity + Vec_IntForEachEntry( p->vActiveVars, Entry, i ) + p->pActivity[Entry] = 0.0; + Vec_IntClear( p->vActiveVars ); + // statistics + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( Tas_ManCheckLimits( p ) ) + RetValue = -1; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [Assumes that each node has flag pObj->fMark0 set to 0. + Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided. + The node may be complemented. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs ) +{ + Gia_Obj_t * pObj; + int i, Entry, RetValue = 0; + s_Counter2 = 0; + s_Counter3 = 0; + s_Counter4 = 0; + Vec_IntClear( p->vModel ); + Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i ) + if ( pObj == Gia_ManConst0(p->pAig) ) + return 1; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i ) + if ( pObj != Gia_ManConst1(p->pAig) && !Tas_VarIsAssigned(Gia_Regular(pObj)) ) + Tas_ManAssign( p, pObj, 0, NULL, NULL ); + if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) ) + Tas_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + Tas_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + // clauses + if ( p->nClauses > 0 ) + { + p->pStore.iCur = 16; + Vec_IntForEachEntry( p->vWatchLits, Entry, i ) + p->pWatches[Entry] = 0; + Vec_IntClear( p->vWatchLits ); + p->nClauses = 0; + } + // activity + Vec_IntForEachEntry( p->vActiveVars, Entry, i ) + p->pActivity[Entry] = 0.0; + Vec_IntClear( p->vActiveVars ); + // statistics + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( Tas_ManCheckLimits( p ) ) + RetValue = -1; + +// printf( "%d ", Gia_ManObjNum(p->pAig) ); +// printf( "%d ", p->Pars.nBTThis ); +// printf( "%d ", p->Pars.nJustThis ); +// printf( "%d ", s_Counter2 ); +// printf( "%d ", s_Counter3 ); +// printf( "%d ", s_Counter4 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManSatPrintStats( Tas_Man_t * p ) +{ + printf( "CO = %8d ", Gia_ManCoNum(p->pAig) ); + printf( "AND = %8d ", Gia_ManAndNum(p->pAig) ); + printf( "Conf = %6d ", p->Pars.nBTLimit ); + printf( "JustMax = %5d ", p->Pars.nJustLimit ); + printf( "\n" ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ) +{ + extern void Gia_ManCollectTest( Gia_Man_t * pAig ); + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Tas_Man_t * p; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot;//, * pRootCopy; +// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp; + + int i, status, clk, clkTotal = clock(); + assert( Gia_ManRegNum(pAig) == 0 ); +// Gia_ManCollectTest( pAig ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + Gia_ManFillValue( pAig ); // maps nodes into trail ids + Gia_ManCleanPhase( pAig ); // maps nodes into trail ids + // create logic network + p = Tas_ManAlloc( pAig, nConfs ); + p->pAig = pAig; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Tas_ReadModel( p ); + // solve for each output + Gia_ManForEachCo( pAig, pRoot, i ) + { +// printf( "%d=", i ); + + Vec_IntClear( vCex ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) + { + if ( Gia_ObjFaninC0(pRoot) ) + { +// printf( "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { +// printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + clk = clock(); +// p->Pars.fUseActive = 1; + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL ); +// printf( "\n" ); +/* + if ( status == -1 ) + { + p->Pars.fUseHighest = 0; + p->Pars.fUseLowest = 1; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot) ); + } +*/ + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { +// printf( "Unsolved %d.\n", i ); + + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += clock() - clk; + continue; + } + +// pRootCopy = Gia_ManCo( pAigCopy, i ); +// pRootCopy->iDiff0 = Gia_ObjId( pAigCopy, pRootCopy ); +// pRootCopy->fCompl0 = 0; + + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += clock() - clk; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); + p->timeSatSat += clock() - clk; + +// printf( "%d ", Vec_IntSize(vCex) ); + } +// pAigCopy = Gia_ManCleanup( pAigTemp = pAigCopy ); +// Gia_ManStop( pAigTemp ); +// Gia_DumpAiger( pAigCopy, "test", 0, 2 ); +// Gia_ManStop( pAigCopy ); + + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = clock() - clkTotal; + if ( fVerbose ) + Tas_ManSatPrintStats( p ); +// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro ); + Tas_ManStop( p ); + *pvStatus = vStatus; + +// printf( "Total number of cex literals = %d. (Ave = %d)\n", +// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat, +// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat ); + return vCexStore; +} + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Tas_StorePatternTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Gia_InfoHasBit( pPres, iBit ) && + Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_StorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex ) +{ + int k; + for ( k = 1; k < 32; k++ ) + if ( Tas_StorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) ) + break; + return (int)(k < 32); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Vec_Ptr_t * vOldRoots, Vec_Ptr_t * vSimInfo ) +{ + int nPatMax = 1000; + int fVerbose = 1; + extern void Gia_ManCollectTest( Gia_Man_t * pAig ); + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Tas_Man_t * p; + Vec_Ptr_t * vPres; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot, * pOldRoot; + int i, status, clk, clkTotal = clock(); + int Tried = 0, Stored = 0, Step = Gia_ManCoNum(pAig) / nPatMax; + assert( Gia_ManRegNum(pAig) == 0 ); +// Gia_ManCollectTest( pAig ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + Gia_ManFillValue( pAig ); // maps nodes into trail ids + Gia_ManCleanPhase( pAig ); // maps nodes into trail ids + // create logic network + p = Tas_ManAlloc( pAig, nConfs ); + p->pAig = pAig; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Tas_ReadModel( p ); + // solve for each output + vPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pAig), 1 ); + Vec_PtrCleanSimInfo( vPres, 0, 1 ); + + Gia_ManForEachCo( pAig, pRoot, i ) + { + assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); + Vec_IntClear( vCex ); + clk = clock(); + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL ); + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; +// Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += clock() - clk; + + i += Step; + continue; + } + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += clock() - clk; + // record proved + pOldRoot = (Gia_Obj_t *)Vec_PtrEntry( vOldRoots, i ); + assert( !Gia_ObjProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) ) ); + Gia_ObjSetProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) ); + + i += Step; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); +// Cec_ManSatAddToStore( vCexStore, vCex, i ); + + // save pattern + Tried++; + Stored += Tas_StorePattern( vSimInfo, vPres, vCex ); + p->timeSatSat += clock() - clk; + i += Step; + } + printf( "Tried = %d Stored = %d\n", Tried, Stored ); + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = clock() - clkTotal; + if ( fVerbose ) + Tas_ManSatPrintStats( p ); + Tas_ManStop( p ); + Vec_PtrFree( vPres ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCTas2.c b/src/aig/gia/giaCTas2.c new file mode 100644 index 00000000..855dcdd3 --- /dev/null +++ b/src/aig/gia/giaCTas2.c @@ -0,0 +1,208 @@ +/**CFile**************************************************************** + + FileName [giaCSat2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Circuit-based SAT solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Tas_Par_t_ Tas_Par_t; +struct Tas_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + // current parameters + int nBTThis; // number of conflicts + int nBTTotal; // total number of conflicts + // decision heuristics + int fUseHighest; // use node with the highest ID + // other parameters + int fVerbose; +}; + +typedef struct Tas_Sto_t_ Tas_Sto_t; +struct Tas_Sto_t_ +{ + int iCur; // currently used + int nSize; // allocated size + char * pBuffer; // handles of objects stored in the queue +}; + +typedef struct Tas_Que_t_ Tas_Que_t; +struct Tas_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + int * pData; // handles of objects stored in the queue +}; + +typedef struct Tas_Var_t_ Tas_Var_t; +struct Tas_Var_t_ +{ + unsigned fTerm : 1; // terminal node + unsigned fVal : 1; // current value + unsigned fValOld : 1; // previous value + unsigned fAssign : 1; // assigned status + unsigned fJQueue : 1; // part of J-frontier + unsigned fCompl0 : 1; // complemented attribute + unsigned fCompl1 : 1; // complemented attribute + unsigned fMark0 : 1; // multi-purpose mark + unsigned fMark1 : 1; // multi-purpose mark + unsigned fPhase : 1; // polarity + unsigned Level : 22; // decision level + int Id; // unique ID of this variable + int IdAig; // original ID of this variable + int Reason0; // reason of this variable + int Reason1; // reason of this variable + int Diff0; // difference for the first fanin + int Diff1; // difference for the second fanin + int Watch0; // handle of first watch + int Watch1; // handle of second watch +}; + +typedef struct Tas_Cls_t_ Tas_Cls_t; +struct Tas_Cls_t_ +{ + int Watch0; // next clause to watch + int Watch1; // next clause to watch + int pVars[0]; // variable handles +}; + +typedef struct Tas_Man_t_ Tas_Man_t; +struct Tas_Man_t_ +{ + // user data + Gia_Man_t * pAig; // AIG manager + Tas_Par_t Pars; // parameters + // solver data + Tas_Sto_t * pVars; // variables + Tas_Sto_t * pClauses; // clauses + // state representation + Tas_Que_t pProp; // propagation queue + Tas_Que_t pJust; // justification queue + Vec_Int_t * vModel; // satisfying assignment + Vec_Ptr_t * vTemp; // temporary storage + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + int nConfTotal; // total conflicts + // runtime stats + int timeSatUnsat; // unsat + int timeSatSat; // sat + int timeSatUndec; // undecided + int timeTotal; // total runtime +}; + +static inline int Tas_VarIsAssigned( Tas_Var_t * pVar ) { return pVar->fAssign; } +static inline void Tas_VarAssign( Tas_Var_t * pVar ) { assert(!pVar->fAssign); pVar->fAssign = 1; } +static inline void Tas_VarUnassign( Tas_Var_t * pVar ) { assert(pVar->fAssign); pVar->fAssign = 0; pVar->fVal = 0; } +static inline int Tas_VarValue( Tas_Var_t * pVar ) { assert(pVar->fAssign); return pVar->fVal; } +static inline void Tas_VarSetValue( Tas_Var_t * pVar, int v ) { assert(pVar->fAssign); pVar->fVal = v; } +static inline int Tas_VarIsJust( Tas_Var_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); } +static inline int Tas_VarFanin0Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); } +static inline int Tas_VarFanin1Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); } + +static inline int Tas_VarDecLevel( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); } +static inline Tas_Var_t * Tas_VarReason0( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); } +static inline Tas_Var_t * Tas_VarReason1( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); } +static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +static inline Tas_Var_t * Tas_ManVar( Tas_Man_t * p, int h ) { return (Tas_Var_t *)(p->pVars->pBuffer + h); } +static inline Tas_Cls_t * Tas_ManClause( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pClauses->pBuffer + h); } + +#define Tas_ClaForEachVar( p, pClause, pVar, i ) \ + for ( pVar = Tas_ManVar(p, pClause->pVars[(i=0)]); pClause->pVars[i]; pVar = (Tas_Var_t *)(((char *)pVar + pClause->pVars[++i])) ) + +#define Tas_QueForEachVar( p, pQue, pVar, i ) \ + for ( pVar = Tas_ManVar(p, pQue->pVars[(i=pQue->iHead)]); i < pQue->iTail; pVar = Tas_ManVar(p, pQue->pVars[i++]) ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Var_t * Tas_ManCreateVar( Tas_Man_t * p ) +{ + Tas_Var_t * pVar; + if ( p->pVars->iCur + sizeof(Tas_Var_t) > p->pVars->nSize ) + { + p->pVars->nSize *= 2; + p->pVars->pData = ABC_REALLOC( char, p->pVars->pData, p->pVars->nSize ); + } + pVar = p->pVars->pData + p->pVars->iCur; + p->pVars->iCur += sizeof(Tas_Var_t); + memset( pVar, 0, sizeof(Tas_Var_t) ); + pVar->Id = pVar - ((Tas_Var_t *)p->pVars->pData); + return pVar; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Var_t * Tas_ManObj2Var( Tas_Man_t * p, Gia_Obj_t * pObj ) +{ + Tas_Var_t * pVar; + assert( !Gia_ObjIsComplement(pObj) ); + if ( pObj->Value == 0 ) + { + pVar = Tas_ManCreateVar( p ); + pVar-> + + } + return Tas_ManVar( p, pObj->Value ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index da48c1b0..5a04d9d3 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -21,6 +21,9 @@ #include <math.h> #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -390,7 +393,7 @@ void Cof_ManInsertEntry_rec( Vec_Ptr_t * vNodes, Cof_Obj_t * pNode, int nNodeMax Vec_PtrPush(vNodes, pNode); return; } - pLast = Vec_PtrPop(vNodes); + pLast = (Cof_Obj_t *)Vec_PtrPop(vNodes); if ( Cof_ObjFanoutNum(pLast) < Cof_ObjFanoutNum(pNode) ) { Cof_ManInsertEntry_rec( vNodes, pNode, nNodeMax ); @@ -541,7 +544,7 @@ void Cof_ManPrintHighFanout( Cof_Man_t * p, int nNodes ) Cof_Obj_t * pObj; int i; vNodes = Cof_ManCollectHighFanout( p, nNodes ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Cof_Obj_t *, vNodes, pObj, i ) Cof_ManPrintHighFanoutOne( p, pObj ); Vec_PtrFree( vNodes ); } @@ -633,7 +636,7 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) printf( "%15d : ", k ); else { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 ); printf( "%15s : ", Buffer ); } if ( vFanins->pArray[k] == 0 ) @@ -916,3 +919,5 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaConstr.c b/src/aig/gia/giaConstr.c index 14768cc2..60432072 100644 --- a/src/aig/gia/giaConstr.c +++ b/src/aig/gia/giaConstr.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c index bcc1748f..3b591aee 100644 --- a/src/aig/gia/giaDfs.c +++ b/src/aig/gia/giaDfs.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -136,6 +139,63 @@ void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vN /**Function************************************************************* + Synopsis [Counts the support size of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectNodesCis_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes ); + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin1(pObj), vNodes ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes ) +{ + Vec_Int_t * vNodes; + Gia_Obj_t * pObj; + int i; + vNodes = Vec_IntAlloc( 10000 ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + for ( i = 0; i < nNodes; i++ ) + { + pObj = Gia_ManObj( p, pNodes[i] ); + if ( Gia_ObjIsCo(pObj) ) + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes ); + else + Gia_ManCollectNodesCis_rec( p, pObj, vNodes ); + } + return vNodes; +} + +/**Function************************************************************* + Synopsis [Collects support nodes.] Description [] @@ -151,7 +211,6 @@ void Gia_ManCollectTest( Gia_Man_t * p ) Gia_Obj_t * pObj; int i, iNode, clk = clock(); vNodes = Vec_IntAlloc( 100 ); - Gia_ManResetTravId( p ); Gia_ManIncrementTravId( p ); Gia_ManForEachCo( p, pObj, i ) { @@ -276,7 +335,7 @@ int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ) ***********************************************************************/ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ) -{ +{ Gia_Obj_t * pObj; Vec_Vec_t * vLevels; int nLevels, Level, i; @@ -291,8 +350,49 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ) return vLevels; } +/**Function************************************************************* + + Synopsis [Computes reverse topological order.] + + Description [Assumes that levels are already assigned. + The levels of CO nodes may not be assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Vec_t * vLevels; + Vec_Ptr_t * vLevel; + Vec_Int_t * vResult; + int i, k; + vLevels = Vec_VecStart( 100 ); + // make sure levels are assigned + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjLevel(p, pObj) > 0 ); + // add CO nodes based on the level of their fanin + Gia_ManForEachCo( p, pObj, i ) + Vec_VecPush( vLevels, Gia_ObjLevel(p, Gia_ObjFanin0(pObj)), pObj ); + // add other nodes based on their level + Gia_ManForEachObj( p, pObj, i ) + if ( !Gia_ObjIsCo(pObj) ) + Vec_VecPush( vLevels, Gia_ObjLevel(p, pObj), pObj ); + // put the nodes in the reverse topological order + vResult = Vec_IntAlloc( Gia_ManObjNum(p) ); + Vec_VecForEachLevelReverse( vLevels, vLevel, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vLevel, pObj, k ) + Vec_IntPush( vResult, Gia_ObjId(p, pObj) ); + Vec_VecFree( vLevels ); + return vResult; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cde19a22..4ded9a78 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -143,6 +146,8 @@ int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) return pObj->Value; if ( Gia_ObjIsCi(pObj) ) return pObj->Value = Gia_ManAppendCi(pNew); +// if ( p->pNexts && Gia_ObjNext(p, Gia_ObjId(p, pObj)) ) +// Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjNextObj(p, Gia_ObjId(p, pObj)) ); Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); if ( Gia_ObjIsCo(pObj) ) return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); @@ -193,6 +198,98 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + for ( i = iOutStart; i < iOutStop; i++ ) + { + pObj = Gia_ManCo( p, i ); + Gia_ManDupOrderDfs_rec( pNew, p, pObj ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupOrderDfsChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pNext; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + pNext = Gia_ObjNextObj( p, Gia_ObjId(p, pObj) ); + if ( pNext ) + Gia_ManDupOrderDfsChoices_rec( pNew, p, pNext ); + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( pNext ) + { + pNew->pNexts[Gia_Lit2Var(pObj->Value)] = Gia_Lit2Var( Gia_Lit2Var(pNext->Value) ); + assert( Gia_Lit2Var(pObj->Value) > Gia_Lit2Var(pNext->Value) ); + } +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +// Gia_ManDeriveReprs( pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ) { Gia_Man_t * pNew; @@ -274,13 +371,13 @@ Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState ) { pObj->Value = Gia_ManAppendCi( pNew ); if ( Gia_ObjCioId(pObj) >= Gia_ManPiNum(p) ) - pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) ); } else if ( Gia_ObjIsCo(pObj) ) { pObj->Value = Gia_ObjFanin0Copy(pObj); if ( Gia_ObjCioId(pObj) >= Gia_ManPoNum(p) ) - pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) ); pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); } } @@ -318,6 +415,8 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + if ( p->pCexSeq ) + pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } @@ -664,6 +763,8 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ) Gia_ManForEachCo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + if ( p->pCexSeq ) + pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } @@ -719,7 +820,8 @@ Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pRoot ) Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); - Gia_ManDupDfs_rec( pNew, p, pRoot ); + Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pRoot) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pRoot) ); Gia_ManSetRegNum( pNew, 0 ); return pNew; } @@ -820,6 +922,49 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ) /**Function************************************************************* + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ) +{ + Gia_Man_t * pTemp, * pNew; + Gia_Obj_t * pObj; + int i; + assert( Gia_ManPoNum(p) == Gia_ManPiNum(p2) ); + assert( Gia_ManRegNum(p) == 0 ); + assert( Gia_ManRegNum(p2) == 0 ); + pNew = Gia_ManStart( Gia_ManObjNum(p)+Gia_ManObjNum(p2) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + // dup first AIG + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + // dup second AIG + Gia_ManConst0(p2)->Value = 0; + Gia_ManForEachCo( p, pObj, i ) + Gia_ManPi(p2, i)->Value = Gia_ObjFanin0Copy(pObj); + Gia_ManForEachAnd( p2, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p2, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); +// Gia_ManPrintStats( pGiaNew, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + Synopsis [Print representatives.] Description [] @@ -1243,8 +1388,84 @@ Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derives the miter of several AIGs for choice computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ) +{ + Gia_Man_t * pNew, * pGia, * pGia0; + int i, k, iNode, nNodes; + // make sure they have equal parameters + assert( Vec_PtrSize(vGias) > 0 ); + pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + { + assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); + assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); + assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); + Gia_ManFillValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; + } + // start the new manager + pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); + pNew->pName = Gia_UtilStrsav( pGia0->pName ); + // create new CIs and assign them to the old manager CIs + for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) + { + iNode = Gia_ManAppendCi(pNew); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManCi( pGia, k )->Value = iNode; + } + // create internal nodes + Gia_ManHashAlloc( pNew ); + for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); + } + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + nNodes = Gia_ManHasDangling( pNew ); + assert( nNodes == 0 ); + // finalize + Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia0) ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index bd14eea9..5c7092a3 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -20,6 +20,10 @@ #include <math.h> #include "gia.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + /* The code is based on the paper by D. Harel and Y. Koren, @@ -743,7 +747,7 @@ void Emb_ManPrintFanio( Emb_Man_t * p ) printf( "%15d : ", k ); else { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 ); printf( "%15s : ", Buffer ); } if ( vFanins->pArray[k] == 0 ) @@ -1692,7 +1696,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowI extern void Gia_ManGnuplotShow( char * pPlotFileName ); // char * pDirectory = "place\\"; char * pDirectory = ""; - extern char * Ioa_TimeStamp(); +// extern char * Ioa_TimeStamp(); FILE * pFile; char Buffer[1000]; Emb_Obj_t * pThis, * pNext; @@ -1865,3 +1869,5 @@ ABC_PRT( "Image dump", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c index c768bb43..37f0c94f 100644 --- a/src/aig/gia/giaEnable.c +++ b/src/aig/gia/giaEnable.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -620,7 +623,7 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ) } Gia_ManForEachRi( p, pObj, i ) { - pData = Vec_PtrEntry(vDatas, i); + pData = (Gia_Obj_t *)Vec_PtrEntry(vDatas, i); if ( pData == NULL ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); else @@ -641,3 +644,5 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 0f680e31..668bc4a2 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -19,6 +19,9 @@ ***********************************************************************/ #include "gia.h" +#include "cec.h" + +ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -221,6 +224,8 @@ int Gia_ManEquivCountLitsAll( Gia_Man_t * p ) int Gia_ManEquivCountClasses( Gia_Man_t * p ) { int i, Counter = 0; + if ( p->pReprs == NULL ) + return 0; for ( i = 1; i < Gia_ManObjNum(p); i++ ) Counter += Gia_ObjIsHead(p, i); return Counter; @@ -448,14 +453,14 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fV { printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" ); return NULL; - } + } // check if there are any equivalences defined Gia_ManForEachObj( p, pObj, i ) if ( Gia_ObjReprObj(p, i) != NULL ) break; if ( i == Gia_ManObjNum(p) ) { - printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" ); +// printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" ); return NULL; } /* @@ -815,7 +820,7 @@ void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, V SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ) +Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; @@ -858,6 +863,11 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ) Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut ); Gia_ManForEachCo( p, pObj, i ) Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut ); + if ( !fSynthesis ) + { + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } Vec_IntForEachEntry( vXorLits, iLitNew, i ) Gia_ManAppendCo( pNew, iLitNew ); if ( Vec_IntSize(vXorLits) == 0 ) @@ -935,7 +945,7 @@ void Gia_ManSpecReduceInit_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut ) +Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRi, * pObjRo; @@ -1024,7 +1034,7 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ) +Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ) { Gia_Man_t * pFrames; int f, nLits; @@ -1225,7 +1235,7 @@ int Gia_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) assert( !Gia_IsComplement(pNode) ); vVisited = Vec_PtrAlloc( 100 ); RetValue = Gia_ObjCheckTfi_rec( p, pOld, pNode, vVisited ); - Vec_PtrForEachEntry( vVisited, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i ) pObj->fMark0 = 0; Vec_PtrFree( vVisited ); return RetValue; @@ -1293,7 +1303,9 @@ void Gia_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) ) { - assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); +// assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); + if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) != pReprNew ) + return; pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); return; } @@ -1373,9 +1385,11 @@ void Gia_ManRemoveBadChoices( Gia_Man_t * p ) ***********************************************************************/ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) { + Vec_Int_t * vNodes; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pRepr; int i; +//Gia_ManEquivPrintClasses( p, 0, 0 ); assert( (Gia_ManCoNum(p) % nSnapshots) == 0 ); Gia_ManSetPhase( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); @@ -1397,24 +1411,77 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) Gia_ManHashAlloc( pNew ); Gia_ManForEachCo( p, pObj, i ) Gia_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + vNodes = Gia_ManGetDangling( p ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Gia_ManEquivToChoices_rec( pNew, p, pObj ); + Vec_IntFree( vNodes ); Gia_ManForEachCo( p, pObj, i ) if ( i % nSnapshots == 0 ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManRemoveBadChoices( pNew ); -// Gia_ManEquivPrintClasses( pNew, 0, 0 ); +//Gia_ManEquivPrintClasses( pNew, 0, 0 ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); -// Gia_ManEquivPrintClasses( pNew, 0, 0 ); +//Gia_ManEquivPrintClasses( pNew, 0, 0 ); return pNew; } +/**Function************************************************************* + + Synopsis [Counts the number of choice nodes] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountChoiceNodes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( p->pReprs == NULL || p->pNexts == NULL ) + return 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += Gia_ObjIsHead( p, i ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of choices] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( p->pReprs == NULL || p->pNexts == NULL ) + return 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += (int)(Gia_ObjNext( p, i ) > 0); + return Counter; +} + +ABC_NAMESPACE_IMPL_END + #include "aig.h" #include "saig.h" #include "cec.h" #include "giaAig.h" +ABC_NAMESPACE_IMPL_START + + /**Function************************************************************* Synopsis [Implements iteration during speculation.] @@ -1428,7 +1495,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) ***********************************************************************/ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int fStart, int fCheckMiter, int fVerbose ) { - extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); +// extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); Aig_Man_t * pTemp; Gia_Man_t * pSrm, * pReduce, * pAux; int nIter, nStart = 0; @@ -1460,10 +1527,10 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f printf( "Gia_CommandSpecI: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); break; } - pSrm = Gia_ManSpecReduce( pGia, 0, 0 ); + pSrm = Gia_ManSpecReduce( pGia, 0, 0, 0 ); // bmc2 -F 100 -C 25000 { - Gia_Cex_t * pCex; + Abc_Cex_t * pCex; int nFrames = nFramesInit; // different from default int nNodeDelta = 2000; int nBTLimit = nBTLimitInit; // different from default @@ -1471,7 +1538,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f pTemp = Gia_ManToAig( pSrm, 0 ); // Aig_ManPrintStats( pTemp ); Gia_ManStop( pSrm ); - Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 20, nBTLimit, nBTLimitAll, fVerbose, 0 ); + Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVerbose, 0, NULL ); pCex = pTemp->pSeqModel; pTemp->pSeqModel = NULL; Aig_ManStop( pTemp ); if ( pCex == NULL ) @@ -1497,7 +1564,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f // write equivalence classes Gia_WriteAiger( pGia, "gore.aig", 0, 0 ); // reduce the model - pReduce = Gia_ManSpecReduce( pGia, 0, 0 ); + pReduce = Gia_ManSpecReduce( pGia, 0, 0, 0 ); if ( pReduce ) { pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); @@ -1516,3 +1583,5 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEra.c b/src/aig/gia/giaEra.c new file mode 100644 index 00000000..ec3e1b1b --- /dev/null +++ b/src/aig/gia/giaEra.c @@ -0,0 +1,561 @@ +/**CFile**************************************************************** + + FileName [giaEra.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Explicit reachability analysis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaEra.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "mem.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// explicit state representation +typedef struct Gia_ObjEra_t_ Gia_ObjEra_t; +struct Gia_ObjEra_t_ +{ + int Num; // ID of this state + int Cond; // input condition + int iPrev; // previous state + int iNext; // next state in the hash table + unsigned pData[0]; // state bits +}; + +// explicit state reachability +typedef struct Gia_ManEra_t_ Gia_ManEra_t; +struct Gia_ManEra_t_ +{ + Gia_Man_t * pAig; // user's AIG manager + int nWordsSim; // 2^(PInum) + int nWordsDat; // Gia_BitWordNum + unsigned * pDataSim; // simulation data + Mem_Fixed_t * pMemory; // memory manager + Vec_Ptr_t * vStates; // reached states + Gia_ObjEra_t * pStateNew; // temporary state + int iCurState; // the current state + Vec_Int_t * vBugTrace; // the sequence of transitions + // hash table for states + int nBins; + unsigned * pBins; +}; + +static inline unsigned * Gia_ManEraData( Gia_ManEra_t * p, int i ) { return p->pDataSim + i * p->nWordsSim; } +static inline Gia_ObjEra_t * Gia_ManEraState( Gia_ManEra_t * p, int i ) { return (Gia_ObjEra_t *)Vec_PtrEntry(p->vStates, i); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManEra_t * Gia_ManEraCreate( Gia_Man_t * pAig ) +{ + Vec_Ptr_t * vTruths; + Gia_ManEra_t * p; + unsigned * pTruth, * pSimInfo; + int i; + p = ABC_CALLOC( Gia_ManEra_t, 1 ); + p->pAig = pAig; + p->nWordsSim = Gia_TruthWordNum( Gia_ManPiNum(pAig) ); + p->nWordsDat = Gia_BitWordNum( Gia_ManRegNum(pAig) ); + p->pDataSim = ABC_ALLOC( unsigned, p->nWordsSim*Gia_ManObjNum(pAig) ); + p->pMemory = Mem_FixedStart( sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat ); + p->vStates = Vec_PtrAlloc( 100000 ); + p->nBins = Gia_PrimeCudd( 100000 ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + Vec_PtrPush( p->vStates, NULL ); + // assign primary input values + vTruths = Vec_PtrAllocTruthTables( Gia_ManPiNum(pAig) ); + Vec_PtrForEachEntry( unsigned *, vTruths, pTruth, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(pAig, Gia_ManPi(pAig, i)) ); + memcpy( pSimInfo, pTruth, sizeof(unsigned) * p->nWordsSim ); + } + Vec_PtrFree( vTruths ); + // assign constant zero node + pSimInfo = Gia_ManEraData( p, 0 ); + memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEraFree( Gia_ManEra_t * p ) +{ + Mem_FixedStop( p->pMemory, 0 ); + Vec_PtrFree( p->vStates ); + if ( p->vBugTrace ) Vec_IntFree( p->vBugTrace ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ObjEra_t * Gia_ManEraCreateState( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pNew; + pNew = (Gia_ObjEra_t *)Mem_FixedEntryFetch( p->pMemory ); + pNew->Num = Vec_PtrSize( p->vStates ); + pNew->iPrev = 0; + Vec_PtrPush( p->vStates, pNew ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEraStateHash( unsigned * pState, int nWordsSim, int nTableSize ) +{ + static int s_FPrimes[128] = { + 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, + 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, + 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, + 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, + 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, + 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, + 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, + 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, + 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, + 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, + 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, + 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, + 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 + }; + unsigned uHash; + int i; + uHash = 0; + for ( i = 0; i < nWordsSim; i++ ) + uHash ^= pState[i] * s_FPrimes[i & 0x7F]; + return uHash % nTableSize; +} + +/**Function************************************************************* + + Synopsis [Returns the place of this state in the table or NULL if it exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned * Gia_ManEraHashFind( Gia_ManEra_t * p, Gia_ObjEra_t * pState ) +{ + Gia_ObjEra_t * pThis; + unsigned * pPlace = p->pBins + Gia_ManEraStateHash( pState->pData, p->nWordsDat, p->nBins ); + for ( pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL; pThis; + pPlace = (unsigned *)&pThis->iNext, pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL ) + if ( !memcmp( pState->pData, pThis->pData, sizeof(unsigned) * p->nWordsDat ) ) + return NULL; + return pPlace; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEraHashResize( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pThis; + unsigned * pBinsOld, * piPlace; + int nBinsOld, iNext, Counter, i; + assert( p->pBins != NULL ); + // replace the table + pBinsOld = p->pBins; + nBinsOld = p->nBins; + p->nBins = Gia_PrimeCudd( 3 * p->nBins ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + // rehash the entries from the old table + Counter = 0; + for ( i = 0; i < nBinsOld; i++ ) + for ( pThis = (pBinsOld[i]? Gia_ManEraState(p, pBinsOld[i]) : NULL), + iNext = (pThis? pThis->iNext : 0); + pThis; pThis = (iNext? Gia_ManEraState(p, iNext) : NULL), + iNext = (pThis? pThis->iNext : 0) ) + { + assert( pThis->Num ); + pThis->iNext = 0; + piPlace = Gia_ManEraHashFind( p, pThis ); + assert( *piPlace == 0 ); // should not be there + *piPlace = pThis->Num; + Counter++; + } + assert( Counter == Vec_PtrSize( p->vStates ) - 1 ); + ABC_FREE( pBinsOld ); +} + +/**Function************************************************************* + + Synopsis [Initialize register output to the given state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManInsertState( Gia_ManEra_t * p, Gia_ObjEra_t * pState ) +{ + Gia_Obj_t * pObj; + unsigned * pSimInfo; + int i; + Gia_ManForEachRo( p->pAig, pObj, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + if ( Gia_InfoHasBit(pState->pData, i) ) + memset( pSimInfo, 0xff, sizeof(unsigned) * p->nWordsSim ); + else + memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim ); + } +} + +/**Function************************************************************* + + Synopsis [Returns -1 if outputs are not asserted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManOutputAsserted( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + int w; + for ( w = 0; w < p->nWordsSim; w++ ) + if ( pInfo[w] ) + return 32*w + Gia_WordFindFirstBit( pInfo[w] ); + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateCo( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + int Id = Gia_ObjId(p->pAig, pObj); + unsigned * pInfo = Gia_ManEraData( p, Id ); + unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w]; + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateNode( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + int Id = Gia_ObjId(p->pAig, pObj); + unsigned * pInfo = Gia_ManEraData( p, Id ); + unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) ); + unsigned * pInfo1 = Gia_ManEraData( p, Gia_ObjFaninId1(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Performs one iteration of reachability analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPerformOneIter( Gia_ManEra_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ManSimulateNode( p, pObj ); + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManSimulateCo( p, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Performs one iteration of reachability analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectBugTrace( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int iCond ) +{ + Vec_Int_t * vTrace; + vTrace = Vec_IntAlloc( 10 ); + Vec_IntPush( vTrace, iCond ); + for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL ) + Vec_IntPush( vTrace, pState->Cond ); + Vec_IntReverseOrder( vTrace ); + return vTrace; +} + +/**Function************************************************************* + + Synopsis [Counts the depth of state transitions leading ot this state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountDepth( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pState; + int Counter = 0; + pState = (Gia_ObjEra_t *)Vec_PtrEntryLast( p->vStates ); + if ( pState->iPrev == 0 && Vec_PtrSize(p->vStates) > 3 ) + pState = (Gia_ObjEra_t *)Vec_PtrEntry( p->vStates, Vec_PtrSize(p->vStates) - 2 ); + for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Analized reached states.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAnalyzeResult( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int fMiter ) +{ + Gia_Obj_t * pObj; + unsigned * pSimInfo, * piPlace; + int i, k, iCond, nMints; + // check if the miter is asserted + if ( fMiter ) + { + Gia_ManForEachPo( p->pAig, pObj, i ) + { + iCond = Gia_ManOutputAsserted( p, pObj ); + if ( iCond >= 0 ) + { + p->vBugTrace = Gia_ManCollectBugTrace( p, pState, iCond ); + return 1; + } + } + } + // collect reached states + nMints = (1 << Gia_ManPiNum(p->pAig)); + for ( k = 0; k < nMints; k++ ) + { + if ( p->pStateNew == NULL ) + p->pStateNew = Gia_ManEraCreateState( p ); + p->pStateNew->pData[p->nWordsDat-1] = 0; + Gia_ManForEachRi( p->pAig, pObj, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + if ( Gia_InfoHasBit(p->pStateNew->pData, i) != Gia_InfoHasBit(pSimInfo, k) ) + Gia_InfoXorBit( p->pStateNew->pData, i ); + } + piPlace = Gia_ManEraHashFind( p, p->pStateNew ); + if ( piPlace == NULL ) + continue; +//printf( "Inserting %d ", Vec_PtrSize(p->vStates) ); +//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" ); + assert( *piPlace == 0 ); + *piPlace = p->pStateNew->Num; + p->pStateNew->Cond = k; + p->pStateNew->iPrev = pState->Num; + p->pStateNew->iNext = 0; + p->pStateNew = NULL; + // expand hash table if needed + if ( Vec_PtrSize(p->vStates) > 2 * p->nBins ) + Gia_ManEraHashResize( p ); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCollectReachable( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose ) +{ + Gia_ManEra_t * p; + Gia_ObjEra_t * pState; + int Hash, clk = clock(); + int RetValue = 1; + assert( Gia_ManPiNum(pAig) <= 12 ); + assert( Gia_ManRegNum(pAig) > 0 ); + p = Gia_ManEraCreate( pAig ); + // create init state + pState = Gia_ManEraCreateState( p ); + pState->Cond = 0; + pState->iPrev = 0; + pState->iNext = 0; + memset( pState->pData, 0, sizeof(unsigned) * p->nWordsDat ); + Hash = Gia_ManEraStateHash(pState->pData, p->nWordsDat, p->nBins); + p->pBins[ Hash ] = pState->Num; + // process reachable states + while ( p->iCurState < Vec_PtrSize( p->vStates ) - 1 ) + { + if ( Vec_PtrSize(p->vStates) >= nStatesMax ) + { + printf( "Reached the limit on states traversed (%d). ", nStatesMax ); + RetValue = -1; + break; + } + pState = Gia_ManEraState( p, ++p->iCurState ); + if ( p->iCurState > 1 && pState->iPrev == 0 ) + continue; +//printf( "Extracting %d ", p->iCurState ); +//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" ); + Gia_ManInsertState( p, pState ); + Gia_ManPerformOneIter( p ); + if ( Gia_ManAnalyzeResult( p, pState, fMiter ) && fMiter ) + { + RetValue = 0; + printf( "Miter failed in state %d after %d transitions. ", + p->iCurState, Vec_IntSize(p->vBugTrace)-1 ); + break; + } + if ( fVerbose && p->iCurState % 5000 == 0 ) + { + printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ", + p->iCurState, Vec_PtrSize(p->vStates), 1.0*p->iCurState/Vec_PtrSize(p->vStates), Gia_ManCountDepth(p), + (1.0/(1<<20))*(1.0*Vec_PtrSize(p->vStates)*(sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat) + + 1.0*p->nBins*sizeof(unsigned) + 1.0*p->vStates->nCap * sizeof(void*)) ); + ABC_PRT( "Time", clock() - clk ); + } + } + printf( "Reachability analysis traversed %d states with depth %d. ", p->iCurState-1, Gia_ManCountDepth(p) ); + ABC_PRT( "Time", clock() - clk ); + Gia_ManEraFree( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEra2.c b/src/aig/gia/giaEra2.c new file mode 100644 index 00000000..64464832 --- /dev/null +++ b/src/aig/gia/giaEra2.c @@ -0,0 +1,1954 @@ +/**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 "giaAig.h" + +ABC_NAMESPACE_IMPL_START + +/* + Limitations of this package: + - no more than (1<<31)-1 state cubes and internal nodes + - no more than MAX_VARS_NUM state variables + - no more than MAX_CALL_NUM transitions from a state + - cube list rebalancing happens when cube count reaches MAX_CUBE_NUM +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_CALL_NUM (1000000) // the max number of recursive calls +#define MAX_ITEM_NUM (1<<20) // the number of items on a page +#define MAX_PAGE_NUM (1<<11) // the max number of memory pages +#define MAX_VARS_NUM (1<<14) // the max number of state vars allowed +#define MAX_CUBE_NUM 63 // the max number of cubes before rebalancing + +// pointer to the tree node or state cube +typedef struct Gia_PtrAre_t_ Gia_PtrAre_t; +struct Gia_PtrAre_t_ +{ + unsigned nItem : 20; // item number (related to MAX_ITEM_NUM) + unsigned nPage : 11; // page number (related to MAX_PAGE_NUM) + unsigned fMark : 1; // user mark +}; + +// tree nodes +typedef struct Gia_ObjAre_t_ Gia_ObjAre_t; +struct Gia_ObjAre_t_ +{ + unsigned iVar : 14; // variable (related to MAX_VARS_NUM) + unsigned nStas0 : 6; // cube counter (related to MAX_CUBE_NUM) + unsigned nStas1 : 6; // cube counter (related to MAX_CUBE_NUM) + unsigned nStas2 : 6; // cube counter (related to MAX_CUBE_NUM) + Gia_PtrAre_t F[3]; // branches +}; + +// state cube +typedef struct Gia_StaAre_t_ Gia_StaAre_t; +struct Gia_StaAre_t_ +{ + Gia_PtrAre_t iPrev; // previous state + Gia_PtrAre_t iNext; // next cube in the list + unsigned pData[0]; // state bits +}; + +// explicit state reachability manager +typedef struct Gia_ManAre_t_ Gia_ManAre_t; +struct Gia_ManAre_t_ +{ + Gia_Man_t * pAig; // user's AIG manager + Gia_Man_t * pNew; // temporary AIG manager + unsigned ** ppObjs; // storage for objects (MAX_PAGE_NUM pages) + unsigned ** ppStas; // storage for states (MAX_PAGE_NUM pages) +// unsigned * pfUseless; // to label useless cubes +// int nUselessAlloc; // the number of useless alloced + // internal flags + int fMiter; // stops when a bug is discovered + int fStopped; // set high when reachability is stopped + int fTree; // working in the tree mode + // internal parametesr + int nWords; // the size of bit info in words + int nSize; // the size of state structure in words + int nObjPages; // the number of pages used for objects + int nStaPages; // the number of pages used for states + int nObjs; // the number of objects + int nStas; // the number of states + int iStaCur; // the next state to be explored + Gia_PtrAre_t Root; // root of the tree + Vec_Vec_t * vCiTfos; // storage for nodes in the CI TFOs + Vec_Vec_t * vCiLits; // storage for literals of these nodes + Vec_Int_t * vCubesA; // checked cubes + Vec_Int_t * vCubesB; // unchecked cubes + // deriving counter-example + void * pSat; // SAT solver + Vec_Int_t * vSatNumCis; // SAT variables for CIs + Vec_Int_t * vSatNumCos; // SAT variables for COs + Vec_Int_t * vCofVars; // variables used to cofactor + Vec_Int_t * vAssumps; // temporary storage for assumptions + Gia_StaAre_t * pTarget; // state that needs to be reached + int iOutFail; // the number of the failed output + // statistics + int nChecks; // the number of timea cube was checked + int nEquals; // total number of equal + int nCompares; // the number of compares + int nRecCalls; // the number of rec calls + int nDisjs; // the number of disjoint cube pairs + int nDisjs2; // the number of disjoint cube pairs + int nDisjs3; // the number of disjoint cube pairs + // time + int timeAig; // AIG cofactoring time + int timeCube; // cube checking time +}; + +static inline Gia_PtrAre_t Gia_Int2Ptr( unsigned n ) { return *(Gia_PtrAre_t *)(&n); } +static inline unsigned Gia_Ptr2Int( Gia_PtrAre_t n ) { return (*(int *)(&n)) & 0x7fffffff; } + +static inline int Gia_ObjHasBranch0( Gia_ObjAre_t * q ) { return !q->nStas0 && (q->F[0].nPage || q->F[0].nItem); } +static inline int Gia_ObjHasBranch1( Gia_ObjAre_t * q ) { return !q->nStas1 && (q->F[1].nPage || q->F[1].nItem); } +static inline int Gia_ObjHasBranch2( Gia_ObjAre_t * q ) { return !q->nStas2 && (q->F[2].nPage || q->F[2].nItem); } + +static inline Gia_ObjAre_t * Gia_ManAreObj( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_ObjAre_t *)(p->ppObjs[n.nPage] + (n.nItem << 2)); } +static inline Gia_StaAre_t * Gia_ManAreSta( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_StaAre_t *)(p->ppStas[n.nPage] + n.nItem * p->nSize); } +static inline Gia_ObjAre_t * Gia_ManAreObjInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreObj( p, Gia_Int2Ptr(n) ); } +static inline Gia_StaAre_t * Gia_ManAreStaInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreSta( p, Gia_Int2Ptr(n) ); } +static inline Gia_ObjAre_t * Gia_ManAreObjLast( Gia_ManAre_t * p ) { return Gia_ManAreObjInt( p, p->nObjs-1 ); } +static inline Gia_StaAre_t * Gia_ManAreStaLast( Gia_ManAre_t * p ) { return Gia_ManAreStaInt( p, p->nStas-1 ); } + +static inline Gia_ObjAre_t * Gia_ObjNextObj0( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[0] ); } +static inline Gia_ObjAre_t * Gia_ObjNextObj1( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[1] ); } +static inline Gia_ObjAre_t * Gia_ObjNextObj2( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[2] ); } + +static inline int Gia_StaHasValue0( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, iReg << 1 ); } +static inline int Gia_StaHasValue1( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, (iReg << 1) + 1 ); } + +static inline void Gia_StaSetValue0( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, iReg << 1 ); } +static inline void Gia_StaSetValue1( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, (iReg << 1) + 1 ); } + +static inline Gia_StaAre_t * Gia_StaPrev( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iPrev); } +static inline Gia_StaAre_t * Gia_StaNext( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iNext); } +static inline int Gia_StaIsGood( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return ((unsigned *)pS) != p->ppStas[0]; } + +static inline void Gia_StaSetUnused( Gia_StaAre_t * pS ) { pS->iPrev.fMark = 1; } +static inline int Gia_StaIsUnused( Gia_StaAre_t * pS ) { return pS->iPrev.fMark; } +static inline int Gia_StaIsUsed( Gia_StaAre_t * pS ) { return !pS->iPrev.fMark; } + +#define Gia_ManAreForEachCubeList( p, pList, pCube ) \ + for ( pCube = pList; Gia_StaIsGood(p, pCube); pCube = Gia_StaNext(p, pCube) ) +#define Gia_ManAreForEachCubeList2( p, iList, pCube, iCube ) \ + for ( iCube = Gia_Ptr2Int(iList), pCube = Gia_ManAreSta(p, iList); \ + Gia_StaIsGood(p, pCube); \ + iCube = Gia_Ptr2Int(pCube->iNext), pCube = Gia_StaNext(p, pCube) ) +#define Gia_ManAreForEachCubeStore( p, pCube, i ) \ + for ( i = 1; i < p->nStas && (pCube = Gia_ManAreStaInt(p, i)); i++ ) +#define Gia_ManAreForEachCubeVec( vVec, p, pCube, i ) \ + for ( i = 0; i < Vec_IntSize(vVec) && (pCube = Gia_ManAreStaInt(p, Vec_IntEntry(vVec,i))); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Count state minterms contained in a cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCountMintermsInCube( Gia_StaAre_t * pCube, int nVars, unsigned * pStore ) +{ + unsigned Mint, Mask = 0; + int i, m, nMints, nDashes = 0, Dashes[32]; + // count the number of dashes + for ( i = 0; i < nVars; i++ ) + { + if ( Gia_StaHasValue0( pCube, i ) ) + continue; + if ( Gia_StaHasValue1( pCube, i ) ) + Mask |= (1 << i); + else + Dashes[nDashes++] = i; + } + // fill in the miterms + nMints = (1 << nDashes); + for ( m = 0; m < nMints; m++ ) + { + Mint = Mask; + for ( i = 0; i < nVars; i++ ) + if ( m & (1 << i) ) + Mint |= (1 << Dashes[i]); + Gia_InfoSetBit( pStore, Mint ); + } +} + +/**Function************************************************************* + + Synopsis [Count state minterms contains in the used cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountMinterms( Gia_ManAre_t * p ) +{ + Gia_StaAre_t * pCube; + unsigned * pMemory; + int i, nMemSize, Counter = 0; + if ( Gia_ManRegNum(p->pAig) > 30 ) + return -1; + nMemSize = Gia_BitWordNum( 1 << Gia_ManRegNum(p->pAig) ); + pMemory = ABC_CALLOC( unsigned, nMemSize ); + Gia_ManAreForEachCubeStore( p, pCube, i ) + if ( Gia_StaIsUsed(pCube) ) + Gia_ManCountMintermsInCube( pCube, Gia_ManRegNum(p->pAig), pMemory ); + for ( i = 0; i < nMemSize; i++ ) + Counter += Gia_WordCountOnes( pMemory[i] ); + ABC_FREE( pMemory ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Derives the TFO of one CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDeriveCiTfo_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRes ) +{ + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark0; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes ); + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin1(pObj), vRes ); + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 | Gia_ObjFanin1(pObj)->fMark0; + if ( pObj->fMark0 ) + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + return pObj->fMark0; +} + + +/**Function************************************************************* + + Synopsis [Derives the TFO of one CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManDeriveCiTfoOne( Gia_Man_t * p, Gia_Obj_t * pPivot ) +{ + Vec_Int_t * vRes; + Gia_Obj_t * pObj; + int i; + assert( pPivot->fMark0 == 0 ); + pPivot->fMark0 = 1; + vRes = Vec_IntAlloc( 100 ); + Vec_IntPush( vRes, Gia_ObjId(p, pPivot) ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes ); + if ( Gia_ObjFanin0(pObj)->fMark0 ) + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + } + pPivot->fMark0 = 0; + return vRes; +} + +/**Function************************************************************* + + Synopsis [Derives the TFO of each CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Gia_ManDeriveCiTfo( Gia_Man_t * p ) +{ + Vec_Ptr_t * vRes; + Gia_Obj_t * pPivot; + int i; + Gia_ManCleanMark0( p ); + Gia_ManIncrementTravId( p ); + vRes = Vec_PtrAlloc( Gia_ManCiNum(p) ); + Gia_ManForEachCi( p, pPivot, i ) + Vec_PtrPush( vRes, Gia_ManDeriveCiTfoOne(p, pPivot) ); + Gia_ManCleanMark0( p ); + return (Vec_Vec_t *)vRes; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if states are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreEqual( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( p1->pData[w] != p2->pData[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if states are disjoint.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDisjoint( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( ((p1->pData[w] ^ p2->pData[w]) >> 1) & (p1->pData[w] ^ p2->pData[w]) & 0x55555555 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if cube p1 contains cube p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreContain( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( (p1->pData[w] | p2->pData[w]) != p2->pData[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns the number of dashes in p1 that are non-dashes in p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDashNum( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w, Counter = 0; + for ( w = 0; w < nWords; w++ ) + Counter += Gia_WordCountOnes( (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555 ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Returns the number of a variable for sharping the cube.] + + Description [Counts the number of variables that have dash in p1 and + non-dash in p2. If there is exactly one such variable, returns its index. + Otherwise returns -1.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreSharpVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + unsigned Word; + int w, iVar = -1; + for ( w = 0; w < nWords; w++ ) + { + Word = (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555; + if ( Word == 0 ) + continue; + if ( !Gia_WordHasOneBit(Word) ) + return -1; + // has exactly one bit + if ( iVar >= 0 ) + return -1; + // the first variable of this type + iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2; + } + return iVar; +} + +/**Function************************************************************* + + Synopsis [Returns the number of a variable for merging the cubes.] + + Description [If there is exactly one such variable, returns its index. + Otherwise returns -1.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDisjointVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + unsigned Word; + int w, iVar = -1; + for ( w = 0; w < nWords; w++ ) + { + Word = (p1->pData[w] ^ p2->pData[w]) & ((p1->pData[w] ^ p2->pData[w]) >> 1) & 0x55555555; + if ( Word == 0 ) + continue; + if ( !Gia_WordHasOneBit(Word) ) + return -1; + // has exactly one bit + if ( iVar >= 0 ) + return -1; + // the first variable of this type + iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2; + } + return iVar; +} + +/**Function************************************************************* + + Synopsis [Creates reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManAre_t * Gia_ManAreCreate( Gia_Man_t * pAig ) +{ + Gia_ManAre_t * p; + assert( sizeof(Gia_ObjAre_t) == 16 ); + p = ABC_CALLOC( Gia_ManAre_t, 1 ); + p->pAig = pAig; + p->nWords = Gia_BitWordNum( 2 * Gia_ManRegNum(pAig) ); + p->nSize = sizeof(Gia_StaAre_t)/4 + p->nWords; + p->ppObjs = ABC_CALLOC( unsigned *, MAX_PAGE_NUM ); + p->ppStas = ABC_CALLOC( unsigned *, MAX_PAGE_NUM ); + p->vCiTfos = Gia_ManDeriveCiTfo( pAig ); + p->vCiLits = Vec_VecDupInt( p->vCiTfos ); + p->vCubesA = Vec_IntAlloc( 100 ); + p->vCubesB = Vec_IntAlloc( 100 ); + p->iOutFail = -1; + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreFree( Gia_ManAre_t * p ) +{ + int i; + Gia_ManStop( p->pAig ); + if ( p->pNew ) + Gia_ManStop( p->pNew ); + Vec_IntFree( p->vCubesA ); + Vec_IntFree( p->vCubesB ); + Vec_VecFree( p->vCiTfos ); + Vec_VecFree( p->vCiLits ); + for ( i = 0; i < p->nObjPages; i++ ) + ABC_FREE( p->ppObjs[i] ); + ABC_FREE( p->ppObjs ); + for ( i = 0; i < p->nStaPages; i++ ) + ABC_FREE( p->ppStas[i] ); + ABC_FREE( p->ppStas ); +// ABC_FREE( p->pfUseless ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns new object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_ObjAre_t * Gia_ManAreCreateObj( Gia_ManAre_t * p ) +{ + if ( p->nObjs == p->nObjPages * MAX_ITEM_NUM ) + { + if ( p->nObjPages == MAX_PAGE_NUM ) + { + printf( "ERA manager has run out of memory after allocating 2B internal nodes.\n" ); + return NULL; + } + p->ppObjs[p->nObjPages++] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * 4 ); + if ( p->nObjs == 0 ) + p->nObjs = 1; + } + return Gia_ManAreObjInt( p, p->nObjs++ ); +} + +/**Function************************************************************* + + Synopsis [Returns new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateSta( Gia_ManAre_t * p ) +{ + if ( p->nStas == p->nStaPages * MAX_ITEM_NUM ) + { + if ( p->nStaPages == MAX_PAGE_NUM ) + { + printf( "ERA manager has run out of memory after allocating 2B state cubes.\n" ); + return NULL; + } + if ( p->ppStas[p->nStaPages] == NULL ) + p->ppStas[p->nStaPages] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * p->nSize ); + p->nStaPages++; + if ( p->nStas == 0 ) + { + p->nStas = 1; +// p->nUselessAlloc = (1 << 18); +// p->pfUseless = ABC_CALLOC( unsigned, p->nUselessAlloc ); + } +// if ( p->nStas == p->nUselessAlloc * 32 ) +// { +// p->nUselessAlloc *= 2; +// p->pfUseless = ABC_REALLOC( unsigned, p->pfUseless, p->nUselessAlloc ); +// memset( p->pfUseless + p->nUselessAlloc/2, 0, sizeof(unsigned) * p->nUselessAlloc/2 ); +// } + } + return Gia_ManAreStaInt( p, p->nStas++ ); +} + +/**Function************************************************************* + + Synopsis [Recycles new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreRycycleSta( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + memset( pSta, 0, p->nSize << 2 ); + if ( pSta == Gia_ManAreStaLast(p) ) + { + p->nStas--; + if ( p->nStas == (p->nStaPages-1) * MAX_ITEM_NUM ) + p->nStaPages--; + } + else + { +// Gia_StaSetUnused( pSta ); + } +} + +/**Function************************************************************* + + Synopsis [Creates new state state from the latch values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateStaNew( Gia_ManAre_t * p ) +{ + Gia_StaAre_t * pSta; + Gia_Obj_t * pObj; + int i; + pSta = Gia_ManAreCreateSta( p ); + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( pObj->Value == 0 ) + Gia_StaSetValue0( pSta, i ); + else if ( pObj->Value == 1 ) + Gia_StaSetValue1( pSta, i ); + } + return pSta; +} + +/**Function************************************************************* + + Synopsis [Creates new state state with latch init values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateStaInit( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachRi( p->pAig, pObj, i ) + pObj->Value = 0; + return Gia_ManAreCreateStaNew( p ); +} + + +/**Function************************************************************* + + Synopsis [Prints the state cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManArePrintCube( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + Gia_Obj_t * pObj; + int i, Count0 = 0, Count1 = 0, Count2 = 0; + printf( "%4d %4d : ", p->iStaCur, p->nStas-1 ); + printf( "Prev %4d ", Gia_Ptr2Int(pSta->iPrev) ); + printf( "%p ", pSta ); + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( Gia_StaHasValue0(pSta, i) ) + printf( "0" ), Count0++; + else if ( Gia_StaHasValue1(pSta, i) ) + printf( "1" ), Count1++; + else + printf( "-" ), Count2++; + } + printf( " 0 =%3d", Count0 ); + printf( " 1 =%3d", Count1 ); + printf( " - =%3d", Count2 ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Counts the depth of state transitions leading ot this state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDepth( Gia_ManAre_t * p, int iState ) +{ + Gia_StaAre_t * pSta; + int Counter = 0; + for ( pSta = Gia_ManAreStaInt(p, iState); Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreListCountListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root ) +{ + Gia_StaAre_t * pCube; + int Counter = 0; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube ) + Counter += Gia_StaIsUsed(pCube); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreListCountUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree ) +{ + Gia_ObjAre_t * pObj; + if ( !fTree ) + return Gia_ManAreListCountListUsed( p, Root ); + pObj = Gia_ManAreObj(p, Root); + return Gia_ManAreListCountUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) + + Gia_ManAreListCountUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) + + Gia_ManAreListCountUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Counts the number of used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreListCountUsed( Gia_ManAre_t * p ) +{ + return Gia_ManAreListCountUsed_rec( p, p->Root, p->fTree ); +} + + +/**Function************************************************************* + + Synopsis [Prints used cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManArePrintListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root ) +{ + Gia_StaAre_t * pCube; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube ) + if ( Gia_StaIsUsed(pCube) ) + Gia_ManArePrintCube( p, pCube ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Prints used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManArePrintUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree ) +{ + Gia_ObjAre_t * pObj; + if ( !fTree ) + return Gia_ManArePrintListUsed( p, Root ); + pObj = Gia_ManAreObj(p, Root); + return Gia_ManArePrintUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) + + Gia_ManArePrintUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) + + Gia_ManArePrintUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Prints used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManArePrintUsed( Gia_ManAre_t * p ) +{ + return Gia_ManArePrintUsed_rec( p, p->Root, p->fTree ); +} + + +/**Function************************************************************* + + Synopsis [Best var has max weight.] + + Description [Weight is defined as the number of 0/1-lits minus the + absolute value of the diff between the number of 0-lits and 1-lits.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreFindBestVar( Gia_ManAre_t * p, Gia_PtrAre_t List ) +{ + Gia_StaAre_t * pCube; + int Count0, Count1, Count2; + int iVarThis, iVarBest = -1, WeightThis, WeightBest = -1; + for ( iVarThis = 0; iVarThis < Gia_ManRegNum(p->pAig); iVarThis++ ) + { + Count0 = Count1 = Count2 = 0; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, List), pCube ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + if ( Gia_StaHasValue0(pCube, iVarThis) ) + Count0++; + else if ( Gia_StaHasValue1(pCube, iVarThis) ) + Count1++; + else + Count2++; + } +// printf( "%4d : %5d %5d %5d Weight = %5d\n", iVarThis, Count0, Count1, Count2, +// Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0) ); + if ( (!Count0 && !Count1) || (!Count0 && !Count2) || (!Count1 && !Count2) ) + continue; + WeightThis = Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0); + if ( WeightBest < WeightThis ) + { + WeightBest = WeightThis; + iVarBest = iVarThis; + } + } + if ( iVarBest == -1 ) + { + Gia_ManArePrintListUsed( p, List ); + printf( "Error: Best variable not found!!!\n" ); + } + assert( iVarBest != -1 ); + return iVarBest; +} + +/**Function************************************************************* + + Synopsis [Rebalances the tree when cubes exceed the limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreRebalance( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot ) +{ + Gia_ObjAre_t * pNode; + Gia_StaAre_t * pCube; + Gia_PtrAre_t iCube, iNext; + assert( pRoot->nItem || pRoot->nPage ); + pNode = Gia_ManAreCreateObj( p ); + pNode->iVar = Gia_ManAreFindBestVar( p, *pRoot ); + for ( iCube = *pRoot, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext; + Gia_StaIsGood(p, pCube); + iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + if ( Gia_StaHasValue0(pCube, pNode->iVar) ) + pCube->iNext = pNode->F[0], pNode->F[0] = iCube, pNode->nStas0++; + else if ( Gia_StaHasValue1(pCube, pNode->iVar) ) + pCube->iNext = pNode->F[1], pNode->F[1] = iCube, pNode->nStas1++; + else + pCube->iNext = pNode->F[2], pNode->F[2] = iCube, pNode->nStas2++; + } + *pRoot = Gia_Int2Ptr(p->nObjs - 1); + assert( pNode == Gia_ManAreObj(p, *pRoot) ); + p->fTree = 1; +} + +/**Function************************************************************* + + Synopsis [Compresses the list by removing unused cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreCompress( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot ) +{ + Gia_StaAre_t * pCube; + Gia_PtrAre_t iList = *pRoot; + Gia_PtrAre_t iCube, iNext; + assert( pRoot->nItem || pRoot->nPage ); + pRoot->nItem = 0; + pRoot->nPage = 0; + for ( iCube = iList, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext; + Gia_StaIsGood(p, pCube); + iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + pCube->iNext = *pRoot; + *pRoot = iCube; + } +} + + +/**Function************************************************************* + + Synopsis [Checks if the state exists in the list.] + + Description [The state may be sharped.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeCheckList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + int fVerbose = 0; + Gia_StaAre_t * pCube; + int iVar; +if ( fVerbose ) +{ +printf( "Trying cube: " ); +Gia_ManArePrintCube( p, pSta ); +} + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, *pRoot), pCube ) + { + p->nChecks++; + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { +if ( fVerbose ) +{ +printf( "Contained in " ); +Gia_ManArePrintCube( p, pCube ); +} + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { +if ( fVerbose ) +{ +printf( "Contains " ); +Gia_ManArePrintCube( p, pCube ); +} + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; +if ( fVerbose ) +{ +printf( "Sharped by " ); +Gia_ManArePrintCube( p, pCube ); +Gia_ManArePrintCube( p, pSta ); +} +// printf( "%d %d\n", Gia_StaAreDashNum( pSta, pCube, p->nWords ), Gia_StaAreSharpVar( pSta, pCube, p->nWords ) ); + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); +// return Gia_ManAreCubeCheckList( p, pRoot, pSta ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds new state to the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreCubeAddToList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + int fVerbose = 0; + pSta->iNext = *pRoot; + *pRoot = Gia_Int2Ptr( p->nStas - 1 ); + assert( pSta == Gia_ManAreSta(p, *pRoot) ); +if ( fVerbose ) +{ +printf( "Adding cube: " ); +Gia_ManArePrintCube( p, pSta ); +//printf( "\n" ); +} +} + +/**Function************************************************************* + + Synopsis [Checks if the cube like this exists in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCheckTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + int RetValue; + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCheckList( p, pObj->F, pSta ); + if ( RetValue == 0 ) + return 0; + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCheckList( p, pObj->F + 1, pSta ); + if ( RetValue == 0 ) + return 0; + } + if ( Gia_ObjHasBranch2(pObj) ) + return Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + return Gia_ManAreCubeCheckList( p, pObj->F + 2, pSta ); +} + +/**Function************************************************************* + + Synopsis [Adds new cube to the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreCubeAddToTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F, pSta ); + if ( ++pObj->nStas0 == MAX_CUBE_NUM ) + { + pObj->nStas0 = Gia_ManAreListCountListUsed( p, pObj->F[0] ); + if ( pObj->nStas0 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F ); + else + { + Gia_ManAreRebalance( p, pObj->F ); + pObj->nStas0 = 0; + } + } + } + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F+1, pSta ); + if ( ++pObj->nStas1 == MAX_CUBE_NUM ) + { + pObj->nStas1 = Gia_ManAreListCountListUsed( p, pObj->F[1] ); + if ( pObj->nStas1 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F+1 ); + else + { + Gia_ManAreRebalance( p, pObj->F+1 ); + pObj->nStas1 = 0; + } + } + } + } + else + { + if ( Gia_ObjHasBranch2(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F+2, pSta ); + if ( ++pObj->nStas2 == MAX_CUBE_NUM ) + { + pObj->nStas2 = Gia_ManAreListCountListUsed( p, pObj->F[2] ); + if ( pObj->nStas2 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F+2 ); + else + { + Gia_ManAreRebalance( p, pObj->F+2 ); + pObj->nStas2 = 0; + } + } + } + } +} + + + +/**Function************************************************************* + + Synopsis [Collects overlapping cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeCollectList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + Gia_StaAre_t * pCube; + int iCube; + Gia_ManAreForEachCubeList2( p, *pRoot, pCube, iCube ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + { +/* + int iVar; + p->nDisjs++; + iVar = Gia_StaAreDisjointVar( pSta, pCube, p->nWords ); + if ( iVar >= 0 ) + { + p->nDisjs2++; + if ( iCube > p->iStaCur ) + p->nDisjs3++; + } +*/ + continue; + } +// p->nCompares++; +// p->nEquals += Gia_StaAreEqual( pSta, pCube, p->nWords ); + if ( iCube <= p->iStaCur ) + Vec_IntPush( p->vCubesA, iCube ); + else + Vec_IntPush( p->vCubesB, iCube ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collects overlapping cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCollectTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + int RetValue; + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCollectList( p, pObj->F, pSta ); + if ( RetValue == 0 ) + return 0; + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCollectList( p, pObj->F + 1, pSta ); + if ( RetValue == 0 ) + return 0; + } + if ( Gia_ObjHasBranch2(pObj) ) + return Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + return Gia_ManAreCubeCollectList( p, pObj->F + 2, pSta ); +} + +/**Function************************************************************* + + Synopsis [Checks if the cube like this exists in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCheckTree( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + Gia_StaAre_t * pCube; + int i, iVar; + assert( p->fTree ); + Vec_IntClear( p->vCubesA ); + Vec_IntClear( p->vCubesB ); + Gia_ManAreCubeCollectTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); +// if ( p->nStas > 3000 ) +// printf( "%d %d \n", Vec_IntSize(p->vCubesA), Vec_IntSize(p->vCubesB) ); +// Vec_IntSort( p->vCubesA, 0 ); +// Vec_IntSort( p->vCubesB, 0 ); + Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); + return Gia_ManAreCubeCheckTree( p, pSta ); + } + Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); + return Gia_ManAreCubeCheckTree( p, pSta ); + } +/* + if ( p->nStas > 3000 ) + { +printf( "Trying cube: " ); +Gia_ManArePrintCube( p, pSta ); + Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i ) + { +printf( "aaaaaaaaaaaa %5d ", Vec_IntEntry(p->vCubesA,i) ); +Gia_ManArePrintCube( p, pCube ); + } + Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i ) + { +printf( "bbbbbbbbbbbb %5d ", Vec_IntEntry(p->vCubesB,i) ); +Gia_ManArePrintCube( p, pCube ); + } + } +*/ + return 1; +} + +/**Function************************************************************* + + Synopsis [Processes the new cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeProcess( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + int RetValue; + p->nChecks = 0; + if ( !p->fTree && p->nStas == MAX_CUBE_NUM ) + Gia_ManAreRebalance( p, &p->Root ); + if ( p->fTree ) + { +// RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); + RetValue = Gia_ManAreCubeCheckTree( p, pSta ); + if ( RetValue ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); + } + else + { + RetValue = Gia_ManAreCubeCheckList( p, &p->Root, pSta ); + if ( RetValue ) + Gia_ManAreCubeAddToList( p, &p->Root, pSta ); + } +// printf( "%d ", p->nChecks ); + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Returns the most used CI, or NULL if condition is met.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreMostUsedPi_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value++; + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Returns the most used CI, or NULL if condition is met.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManAreMostUsedPi( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + // clean CI counters + Gia_ManForEachCi( p->pNew, pObj, i ) + pObj->Value = 0; + // traverse from each register output + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( pObj->Value <= 1 ) + continue; + Gia_ManIncrementTravId( p->pNew ); + Gia_ManAreMostUsedPi_rec( p->pNew, Gia_ManObj(p->pNew, Gia_Lit2Var(pObj->Value)) ); + } + // check the CI counters + Gia_ManForEachCi( p->pNew, pObj, i ) + if ( pObjMax == NULL || pObjMax->Value < pObj->Value ) + pObjMax = pObj; + // return the result + return pObjMax->Value > 1 ? pObjMax : NULL; +} + +/**Function************************************************************* + + Synopsis [Counts maximum support of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCheckPOs_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + return 1; + assert( Gia_ObjIsAnd(pObj) ); + return Gia_ManCheckPOs_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManCheckPOs_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Counts maximum support of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManCheckPOs( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i, CountCur, CountMax = 0; + Gia_ManForEachPo( p->pAig, pObj, i ) + { + pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjIsConst0(pObjNew) ) + CountCur = 0; + else + { + Gia_ManIncrementTravId( p->pNew ); + CountCur = Gia_ManCheckPOs_rec( p->pNew, pObjNew ); + } + CountMax = ABC_MAX( CountMax, CountCur ); + } + return CountMax; +} + +/**Function************************************************************* + + Synopsis [Returns the status of the primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManCheckPOstatus( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManForEachPo( p->pAig, pObj, i ) + { + pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjIsConst0(pObjNew) ) + { + if ( Gia_LitIsCompl(pObj->Value) ) + { + p->iOutFail = i; + return 1; + } + } + else + { + p->iOutFail = i; +// printf( "To fix later: PO may be assertable.\n" ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives next state cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDeriveNexts_rec( Gia_ManAre_t * p, Gia_PtrAre_t Sta ) +{ + Gia_Obj_t * pPivot; + Vec_Int_t * vLits, * vTfos; + Gia_Obj_t * pObj; + int i, clk; + if ( ++p->nRecCalls == MAX_CALL_NUM ) + return 0; + if ( (pPivot = Gia_ManAreMostUsedPi(p)) == NULL ) + { + Gia_StaAre_t * pNew; + clk = clock(); + pNew = Gia_ManAreCreateStaNew( p ); + pNew->iPrev = Sta; + p->fStopped = (p->fMiter && (Gia_ManCheckPOstatus(p) & 1)); + if ( p->fStopped ) + { + assert( p->pTarget == NULL ); + p->pTarget = pNew; + return 1; + } + Gia_ManAreCubeProcess( p, pNew ); + p->timeCube += clock() - clk; + return p->fStopped; + } + // remember values in the cone and perform update + vTfos = (Vec_Int_t *)Vec_VecEntry( p->vCiTfos, Gia_ObjCioId(pPivot) ); + vLits = (Vec_Int_t *)Vec_VecEntry( p->vCiLits, Gia_ObjCioId(pPivot) ); + assert( Vec_IntSize(vTfos) == Vec_IntSize(vLits) ); + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + { + Vec_IntWriteEntry( vLits, i, pObj->Value ); + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else + { + assert( Gia_ObjIsCi(pObj) ); + pObj->Value = 0; + } + } + if ( Gia_ManAreDeriveNexts_rec( p, Sta ) ) + return 1; + // compute different values + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else + { + assert( Gia_ObjIsCi(pObj) ); + pObj->Value = 1; + } + } + if ( Gia_ManAreDeriveNexts_rec( p, Sta ) ) + return 1; + // reset the original values + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + pObj->Value = Vec_IntEntry( vLits, i ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives next state cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDeriveNexts( Gia_ManAre_t * p, Gia_PtrAre_t Sta ) +{ + Gia_StaAre_t * pSta; + Gia_Obj_t * pObj; + int i, RetValue, clk = clock(); + pSta = Gia_ManAreSta( p, Sta ); + if ( Gia_StaIsUnused(pSta) ) + return 0; + // recycle the manager + if ( p->pNew && Gia_ManObjNum(p->pNew) > 1000000 ) + { + Gia_ManStop( p->pNew ); + p->pNew = NULL; + } + // allocate the manager + if ( p->pNew == NULL ) + { + p->pNew = Gia_ManStart( 10 * Gia_ManObjNum(p->pAig) ); + Gia_ManIncrementTravId( p->pNew ); + Gia_ManHashAlloc( p->pNew ); + Gia_ManConst0(p->pAig)->Value = 0; + Gia_ManForEachCi( p->pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi(p->pNew); + } + Gia_ManForEachRo( p->pAig, pObj, i ) + { + if ( Gia_StaHasValue0( pSta, i ) ) + pObj->Value = 0; + else if ( Gia_StaHasValue1( pSta, i ) ) + pObj->Value = 1; + else // don't-care literal + pObj->Value = Gia_Var2Lit( Gia_ObjId( p->pNew, Gia_ManCi(p->pNew, Gia_ObjCioId(pObj)) ), 0 ); + } + Gia_ManForEachAnd( p->pAig, pObj, i ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p->pAig, pObj, i ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + + // perform case-splitting + p->nRecCalls = 0; + RetValue = Gia_ManAreDeriveNexts_rec( p, Sta ); + if ( p->nRecCalls >= MAX_CALL_NUM ) + { + printf( "Exceeded the limit on the number of transitions from a state cube (%d).\n", MAX_CALL_NUM ); + p->fStopped = 1; + } +// printf( "%d ", p->nRecCalls ); +//printf( "%d ", Gia_ManObjNum(p->pNew) ); + p->timeAig += clock() - clk; + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Prints the report] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManArePrintReport( Gia_ManAre_t * p, int Time, int fFinal ) +{ + printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ", + p->iStaCur, p->nStas, 1.0*p->iStaCur/p->nStas, Gia_ManAreDepth(p, p->iStaCur), + (sizeof(Gia_ManAre_t) + 4.0*Gia_ManRegNum(p->pAig) + 8.0*MAX_PAGE_NUM + + 4.0*p->nStaPages*p->nSize*MAX_ITEM_NUM + 16.0*p->nObjPages*MAX_ITEM_NUM)/(1<<20) ); + if ( fFinal ) + { + ABC_PRT( "Time", clock() - Time ); + } + else + { + ABC_PRTr( "Time", clock() - Time ); + } +} + +/**Function************************************************************* + + Synopsis [Performs explicit reachability.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManArePerform( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose ) +{ +// extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ); + extern Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast ); + Gia_ManAre_t * p; + int clk = clock(); + int RetValue = 1; + if ( Gia_ManRegNum(pAig) > MAX_VARS_NUM ) + { + printf( "Currently can only handle circuit with up to %d registers.\n", MAX_VARS_NUM ); + return -1; + } + ABC_FREE( pAig->pCexSeq ); + p = Gia_ManAreCreate( Gia_ManCompress2(pAig, 0, 0) ); + p->fMiter = fMiter; + Gia_ManAreCubeProcess( p, Gia_ManAreCreateStaInit(p) ); + for ( p->iStaCur = 1; p->iStaCur < p->nStas; p->iStaCur++ ) + { +// printf( "Explored state %d. Total cubes %d.\n", p->iStaCur, p->nStas-1 ); + if ( Gia_ManAreDeriveNexts( p, Gia_Int2Ptr(p->iStaCur) ) || p->nStas > nStatesMax ) + pAig->pCexSeq = Gia_ManAreDeriveCex( p, p->pTarget ); + if ( p->fStopped ) + { + RetValue = -1; + break; + } + if ( fVerbose && p->iStaCur % 5000 == 0 ) + Gia_ManArePrintReport( p, clk, 0 ); + } + Gia_ManArePrintReport( p, clk, 1 ); + printf( "%s after finding %d state cubes (%d not contained) with depth %d. ", + p->fStopped ? "Stopped" : "Completed", + p->nStas, Gia_ManAreListCountUsed(p), + Gia_ManAreDepth(p, p->iStaCur-1) ); + ABC_PRT( "Time", clock() - clk ); + if ( pAig->pCexSeq != NULL ) +// printf( "Miter FAILED in state %d at frame %d (use \"&write_counter\" to dump a witness)\n", + printf( "Miter FAILED in state %d at frame %d (the cex is available for refinement)\n", + p->iStaCur, Gia_ManAreDepth(p, p->iStaCur)-1 ); + if ( fVerbose ) + { + ABC_PRTP( "Cofactoring", p->timeAig - p->timeCube, clock() - clk ); + ABC_PRTP( "Containment", p->timeCube, clock() - clk ); + ABC_PRTP( "Other ", clock() - clk - p->timeAig, clock() - clk ); + ABC_PRTP( "TOTAL ", clock() - clk, clock() - clk ); + } + if ( Gia_ManRegNum(pAig) <= 30 ) + { + clk = clock(); + printf( "The number of unique state minterms in computed state cubes is %d. ", Gia_ManCountMinterms(p) ); + ABC_PRT( "Time", clock() - clk ); + } +// printf( "Compares = %d. Equals = %d. Disj = %d. Disj2 = %d. Disj3 = %d.\n", +// p->nCompares, p->nEquals, p->nDisjs, p->nDisjs2, p->nDisjs3 ); +// Gia_ManAreFindBestVar( p, Gia_ManAreSta(p, p->Root) ); +// Gia_ManArePrintUsed( p ); + Gia_ManAreFree( p ); + // verify + if ( pAig->pCexSeq ) + { + if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) + printf( "Generated counter-example is INVALID. \n" ); + else + printf( "Generated counter-example verified correctly. \n" ); + return 0; + } + return RetValue; +} + +ABC_NAMESPACE_IMPL_END + +#include "giaAig.h" +#include "cnf.h" +#include "satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSatStart( Gia_ManAre_t * p ) +{ + Aig_Man_t * pAig2; + Cnf_Dat_t * pCnf; + assert( p->pSat == NULL ); + pAig2 = Gia_ManToAig( p->pAig, 0 ); + Aig_ManSetRegNum( pAig2, 0 ); + pCnf = Cnf_Derive( pAig2, Gia_ManCoNum(p->pAig) ); + p->pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + p->vSatNumCis = Cnf_DataCollectCiSatNums( pCnf, pAig2 ); + p->vSatNumCos = Cnf_DataCollectCoSatNums( pCnf, pAig2 ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pAig2 ); + p->vAssumps = Vec_IntAlloc( 100 ); + p->vCofVars = Vec_IntAlloc( 100 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSatStop( Gia_ManAre_t * p ) +{ + assert( p->pSat != NULL ); + assert( p->pTarget != NULL ); + sat_solver_delete( (sat_solver *)p->pSat ); + Vec_IntFree( p->vSatNumCis ); + Vec_IntFree( p->vSatNumCos ); + Vec_IntFree( p->vAssumps ); + Vec_IntFree( p->vCofVars ); + p->pTarget = NULL; + p->pSat = NULL; +} + +/**Function************************************************************* + + Synopsis [Computes satisfying assignment in one timeframe.] + + Description [Returns the vector of integers represeting PIO ids + of the primary inputs that should be 1 in the counter-example.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSat( Gia_ManAre_t * p, Gia_StaAre_t * pCur, Gia_StaAre_t * pNext, int iOutFailed ) +{ + int i, status; + // make assuptions + Vec_IntClear( p->vAssumps ); + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pCur, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 1 ) ); + else if ( Gia_StaHasValue1(pCur, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 0 ) ); + } + if ( pNext ) + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pNext, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 1 ) ); + else if ( Gia_StaHasValue1(pNext, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 0 ) ); + } + if ( iOutFailed >= 0 ) + { + assert( iOutFailed < Gia_ManPoNum(p->pAig) ); + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, iOutFailed), 0 ) ); + } + // solve SAT + status = sat_solver_solve( (sat_solver *)p->pSat, (int *)Vec_IntArray(p->vAssumps), (int *)Vec_IntArray(p->vAssumps) + Vec_IntSize(p->vAssumps), + (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( status != l_True ) + { + printf( "SAT problem is not satisfiable. Failure...\n" ); + return; + } + assert( status == l_True ); + // check the model + Vec_IntClear( p->vCofVars ); + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, i) ) ) + Vec_IntPush( p->vCofVars, i ); + } + // write the current state + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pCur, i) ) + assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 ); + else if ( Gia_StaHasValue1(pCur, i) ) + assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 1 ); + // set don't-care value + if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 ) + Gia_StaSetValue0( pCur, i ); + else + Gia_StaSetValue1( pCur, i ); + } +} + +/**Function************************************************************* + + Synopsis [Returns the status of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast ) +{ + Abc_Cex_t * pCex; + Vec_Ptr_t * vStates; + Gia_StaAre_t * pSta, * pPrev; + int Var, i, v; + assert( p->iOutFail >= 0 ); + Gia_ManAreDeriveCexSatStart( p ); + // compute the trace + vStates = Vec_PtrAlloc( 1000 ); + for ( pSta = pLast; Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) ) + if ( pSta != pLast ) + Vec_PtrPush( vStates, pSta ); + assert( Vec_PtrSize(vStates) >= 1 ); + // start the counter-example + pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(p->pAig), Gia_ManPiNum(p->pAig), Vec_PtrSize(vStates) ); + pCex->iFrame = Vec_PtrSize(vStates)-1; + pCex->iPo = p->iOutFail; + // compute states + pPrev = NULL; + Vec_PtrForEachEntry( Gia_StaAre_t *, vStates, pSta, i ) + { + Gia_ManAreDeriveCexSat( p, pSta, pPrev, (i == 0) ? p->iOutFail : -1 ); + pPrev = pSta; + // create the counter-example + Vec_IntForEachEntry( p->vCofVars, Var, v ) + { + assert( Var < Gia_ManPiNum(p->pAig) ); + Gia_InfoSetBit( pCex->pData, Gia_ManRegNum(p->pAig) + (Vec_PtrSize(vStates)-1-i) * Gia_ManPiNum(p->pAig) + Var ); + } + } + // free temporary things + Vec_PtrFree( vStates ); + Gia_ManAreDeriveCexSatStop( p ); + return pCex; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c index b32484af..c3e39405 100644 --- a/src/aig/gia/giaFanout.c +++ b/src/aig/gia/giaFanout.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -195,3 +198,5 @@ void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c index 04c8f2e7..b9135404 100644 --- a/src/aig/gia/giaForce.c +++ b/src/aig/gia/giaForce.c @@ -20,9 +20,12 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + /* The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah. - "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI�03. http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ @@ -1096,4 +1099,7 @@ Write = 1.81 sec //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -////////////////////////////////////////////////////////////////////////
\ No newline at end of file +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFrames.c b/src/aig/gia/giaFrames.c index c0ea6680..75b17361 100644 --- a/src/aig/gia/giaFrames.c +++ b/src/aig/gia/giaFrames.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -116,7 +119,7 @@ void Gia_ManFraSupports( Gia_ManFra_t * p ) p->vIns = Vec_PtrStart( p->pPars->nFrames ); p->vAnds = Vec_PtrStart( p->pPars->nFrames ); p->vOuts = Vec_PtrStart( p->pPars->nFrames ); - Gia_ManResetTravId( p->pAig ); + Gia_ManIncrementTravId( p->pAig ); for ( f = p->pPars->nFrames - 1; f >= 0; f-- ) { vOuts = Gia_ManCollectPoIds( p->pAig ); @@ -185,9 +188,9 @@ Gia_Man_t * Gia_ManFramesInit( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) Gia_ManConst0(pAig)->Value = 0; for ( f = 0; f < pPars->nFrames; f++ ) { - vIns = Vec_PtrEntry( p->vIns, f ); - vAnds = Vec_PtrEntry( p->vAnds, f ); - vOuts = Vec_PtrEntry( p->vOuts, f ); + vIns = (Vec_Int_t *)Vec_PtrEntry( p->vIns, f ); + vAnds = (Vec_Int_t *)Vec_PtrEntry( p->vAnds, f ); + vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vOuts, f ); if ( pPars->fVerbose ) printf( "Frame %3d : CI = %6d. AND = %6d. CO = %6d.\n", f, Vec_IntSize(vIns), Vec_IntSize(vAnds), Vec_IntSize(vOuts) ); @@ -344,3 +347,5 @@ Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFront.c b/src/aig/gia/giaFront.c index b3a3c2d0..6f1ce5a7 100644 --- a/src/aig/gia/giaFront.c +++ b/src/aig/gia/giaFront.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -193,7 +196,7 @@ Gia_Man_t * Gia_ManFront( Gia_Man_t * p ) pFront[iFront] = 0; } assert( pNew->nObjs == p->nObjs ); - assert( nCrossCut == 0 && nCrossCutMax == nCrossCutMaxInit ); + assert( nCrossCut == 0 || nCrossCutMax == nCrossCutMaxInit ); for ( i = 0; i < pNew->nFront; i++ ) assert( pFront[i] == 0 ); ABC_FREE( pFront ); @@ -246,3 +249,5 @@ void Gia_ManFrontTest( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaGiarf.c b/src/aig/gia/giaGiarf.c new file mode 100644 index 00000000..501f9bb3 --- /dev/null +++ b/src/aig/gia/giaGiarf.c @@ -0,0 +1,1077 @@ +/**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" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// combinational simulation manager +typedef struct Hcd_Man_t_ Hcd_Man_t; +struct Hcd_Man_t_ +{ + // parameters + Gia_Man_t * pGia; // the AIG to be used for simulation + int nBTLimit; // internal backtrack limit + int fVerbose; // internal verbose flag + // internal variables + unsigned * pSimInfo; // simulation info for each object + Vec_Ptr_t * vSimInfo; // pointers to the CI simulation info + Vec_Ptr_t * vSimPres; // pointers to the presense of simulation info + // temporaries + Vec_Int_t * vClassOld; // old class numbers + Vec_Int_t * vClassNew; // new class numbers + Vec_Int_t * vClassTemp; // temporary storage + Vec_Int_t * vRefinedC; // refined const reprs +}; + +static inline unsigned Hcd_ObjSim( Hcd_Man_t * p, int Id ) { return p->pSimInfo[Id]; } +static inline unsigned * Hcd_ObjSimP( Hcd_Man_t * p, int Id ) { return p->pSimInfo + Id; } +static inline unsigned Hcd_ObjSetSim( Hcd_Man_t * p, int Id, unsigned n ) { return p->pSimInfo[Id] = n; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hcd_Man_t * Gia_ManEquivStart( Gia_Man_t * pGia, int nBTLimit, int fVerbose ) +{ + Hcd_Man_t * p; + Gia_Obj_t * pObj; + int i; + p = ABC_CALLOC( Hcd_Man_t, 1 ); + p->pGia = pGia; + p->nBTLimit = nBTLimit; + p->fVerbose = fVerbose; + p->pSimInfo = ABC_ALLOC( unsigned, Gia_ManObjNum(pGia) ); + p->vClassOld = Vec_IntAlloc( 100 ); + p->vClassNew = Vec_IntAlloc( 100 ); + p->vClassTemp = Vec_IntAlloc( 100 ); + p->vRefinedC = Vec_IntAlloc( 100 ); + // collect simulation info + p->vSimInfo = Vec_PtrAlloc( 1000 ); + Gia_ManForEachCi( pGia, pObj, i ) + Vec_PtrPush( p->vSimInfo, Hcd_ObjSimP(p, Gia_ObjId(pGia,pObj)) ); + p->vSimPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pGia), 1 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivStop( Hcd_Man_t * p ) +{ + Vec_PtrFree( p->vSimInfo ); + Vec_PtrFree( p->vSimPres ); + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Compared two simulation infos.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareEqual( unsigned s0, unsigned s1 ) +{ + if ( (s0 & 1) == (s1 & 1) ) + return s0 == s1; + else + return s0 ==~s1; +} + +/**Function************************************************************* + + Synopsis [Compares one simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareConst( unsigned s ) +{ + if ( s & 1 ) + return s ==~0; + else + return s == 0; +} + +/**Function************************************************************* + + Synopsis [Creates one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassCreate( Gia_Man_t * pGia, Vec_Int_t * vClass ) +{ + int Repr = -1, EntPrev = -1, Ent, i; + assert( Vec_IntSize(vClass) > 0 ); + Vec_IntForEachEntry( vClass, Ent, i ) + { + if ( i == 0 ) + { + Repr = Ent; + Gia_ObjSetRepr( pGia, Ent, -1 ); + EntPrev = Ent; + } + else + { + Gia_ObjSetRepr( pGia, Ent, Repr ); + Gia_ObjSetNext( pGia, EntPrev, Ent ); + EntPrev = Ent; + } + } + Gia_ObjSetNext( pGia, EntPrev, 0 ); +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassClassRemoveOne( Hcd_Man_t * p, int i ) +{ + int iRepr, Ent; + if ( Gia_ObjIsConst(p->pGia, i) ) + { + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + return 1; + } + if ( !Gia_ObjIsClass(p->pGia, i) ) + return 0; + assert( Gia_ObjIsClass(p->pGia, i) ); + iRepr = Gia_ObjRepr( p->pGia, i ); + if ( iRepr == GIA_VOID ) + iRepr = i; + // collect nodes + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Gia_ClassForEachObj( p->pGia, iRepr, Ent ) + { + if ( Ent == i ) + Vec_IntPush( p->vClassNew, Ent ); + else + Vec_IntPush( p->vClassOld, Ent ); + } + assert( Vec_IntSize( p->vClassNew ) == 1 ); + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + assert( !Gia_ObjIsClass(p->pGia, i) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassRefineOne( Hcd_Man_t * p, int i ) +{ + unsigned Sim0, Sim1; + int Ent; + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Vec_IntPush( p->vClassOld, i ); + Sim0 = Hcd_ObjSim(p, i); + Gia_ClassForEachObj1( p->pGia, i, Ent ) + { + Sim1 = Hcd_ObjSim(p, Ent); + if ( Hcd_ManCompareEqual( Sim0, Sim1 ) ) + Vec_IntPush( p->vClassOld, Ent ); + else + Vec_IntPush( p->vClassNew, Ent ); + } + if ( Vec_IntSize( p->vClassNew ) == 0 ) + return 0; + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + if ( Vec_IntSize(p->vClassNew) > 1 ) + return 1 + Hcd_ManClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManHashKey( unsigned * pSim, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0; + int i; + if ( pSim[0] & 1 ) + for ( i = 0; i < nWords; i++ ) + uHash ^= ~pSim[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nWords; i++ ) + uHash ^= pSim[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Rehashes the refined classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRehash( Hcd_Man_t * p, Vec_Int_t * vRefined ) +{ + int * pTable, nTableSize, Key, i, k; + nTableSize = Gia_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 ); + pTable = ABC_CALLOC( int, nTableSize ); + Vec_IntForEachEntry( vRefined, i, k ) + { + assert( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ); + Key = Hcd_ManHashKey( Hcd_ObjSimP(p, i), 1, nTableSize ); + if ( pTable[Key] == 0 ) + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + else + { + Gia_ObjSetNext( p->pGia, pTable[Key], i ); + Gia_ObjSetRepr( p->pGia, i, Gia_ObjRepr(p->pGia, pTable[Key]) ); + if ( Gia_ObjRepr(p->pGia, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pGia, i, pTable[Key] ); + } + pTable[Key] = i; + } + ABC_FREE( pTable ); +// Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); + // refine classes in the table + Vec_IntForEachEntry( vRefined, i, k ) + { + if ( Gia_ObjIsHead( p->pGia, i ) ) + Hcd_ManClassRefineOne( p, i ); + } + Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); +} + +/**Function************************************************************* + + Synopsis [Refines equivalence classes after simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRefine( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Vec_IntClear( p->vRefinedC ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Gia_ObjIsTail(p->pGia, i) ) // add check for the class level + { + Hcd_ManClassRefineOne( p, Gia_ObjRepr(p->pGia, i) ); + } + else if ( Gia_ObjIsConst(p->pGia, i) ) + { + if ( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ) + Vec_IntPush( p->vRefinedC, i ); + } + } + Hcd_ManClassesRehash( p, p->vRefinedC ); +} + +/**Function************************************************************* + + Synopsis [Creates equivalence classes for the first time.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesCreate( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pGia->pReprs == NULL ); + p->pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pGia) ); + p->pGia->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( p->pGia, pObj, i ) + Gia_ObjSetRepr( p->pGia, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); +} + +/**Function************************************************************* + + Synopsis [Initializes simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulationInit( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachCi( p->pGia, pObj, i ) + Hcd_ObjSetSim( p, i, (Gia_ManRandom(0) << 1) ); +} + +/**Function************************************************************* + + Synopsis [Performs one round of simple combinational simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulateSimple( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + int i; + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + Res0 = Hcd_ObjSim( p, Gia_ObjFaninId0(pObj, i) ); + Res1 = Hcd_ObjSim( p, Gia_ObjFaninId1(pObj, i) ); + Hcd_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); + } +} + + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_Resimulate_rec( Hcd_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + if ( Gia_ObjIsTravIdCurrentId( p->pGia, iObj ) ) + return Hcd_ObjSim( p, iObj ); + Gia_ObjSetTravIdCurrentId( p->pGia, iObj ); + pObj = Gia_ManObj(p->pGia, iObj); + if ( Gia_ObjIsCi(pObj) ) + return Hcd_ObjSim( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Res0 = Gia_Resimulate_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + Res1 = Gia_Resimulate_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + return Hcd_ObjSetSim( p, iObj, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); +} + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [Assumes that the counter-example is assigned at the PIs. + The counter-example should have the first bit set to 0 at each PI.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ResimulateAndRefine( Hcd_Man_t * p, int i ) +{ + int RetValue, iObj; + Gia_ManIncrementTravId( p->pGia ); + Gia_ClassForEachObj( p->pGia, i, iObj ) + Gia_Resimulate_rec( p, iObj ); + RetValue = Hcd_ManClassRefineOne( p, i ); + if ( RetValue == 0 ) + printf( "!!! no refinement !!!\n" ); +// assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Returns temporary representative of the node.] + + Description [The temp repr is the first node among the nodes in the class that + (a) precedes the given node, and (b) whose level is lower than the given node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ObjTempRepr( Gia_Man_t * p, int i, int Level ) +{ + int iRepr, iMember; + iRepr = Gia_ObjRepr( p, i ); + if ( !Gia_ObjProved(p, i) ) + return NULL; + if ( Gia_ObjFailed(p, i) ) + return NULL; + if ( iRepr == GIA_VOID ) + return NULL; + if ( iRepr == 0 ) + return Gia_ManConst0( p ); +// if ( p->pLevels[iRepr] < Level ) +// return Gia_ManObj( p, iRepr ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjFailed(p, iMember) ) + continue; + if ( iMember >= i ) + return NULL; + if ( Gia_ObjLevelId(p, iMember) < Level ) + return Gia_ManObj( p, iMember ); + } + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Generates reduced AIG for the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_GenerateReducedLevel( Gia_Man_t * p, int Level, Vec_Ptr_t ** pvRoots ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRepr; + Vec_Ptr_t * vRoots; + int i; + vRoots = Vec_PtrAlloc( 100 ); + // copy unmarked nodes + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjLevelId(p, i) > Level ) + continue; + if ( Gia_ObjLevelId(p, i) == Level ) + Vec_PtrPush( vRoots, pObj ); + if ( Gia_ObjLevelId(p, i) < Level && (pRepr = Gia_ObjTempRepr(p, i, Level)) ) + { +// printf( "Substituting %d <--- %d\n", Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj) ); + assert( pRepr < pObj ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + continue; + } + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + *pvRoots = vRoots; + // required by SAT solving + Gia_ManCreateRefs( pNew ); + Gia_ManFillValue( pNew ); + Gia_ManIncrementTravId( pNew ); // needed for MiniSat to record cexes +// Gia_ManSetPhase( pNew ); // needed if MiniSat is using polarity -- should not be enabled for TAS because fPhase is used to label + return pNew; +} + +/**Function************************************************************* + + Synopsis [Collects relevant classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_CollectRelatedClasses( Gia_Man_t * pGia, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vClasses; + Gia_Obj_t * pRoot, * pRepr; + int i; + vClasses = Vec_PtrAlloc( 100 ); + Gia_ManConst0( pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pRoot, i ) + { + pRepr = Gia_ObjReprObj( pGia, Gia_ObjId(pGia, pRoot) ); + if ( pRepr == NULL || pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); + } + Gia_ManConst0( pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + return vClasses; +} + +/**Function************************************************************* + + Synopsis [Collects class members.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Obj_t * Gia_CollectClassMembers( Gia_Man_t * p, Gia_Obj_t * pRepr, Vec_Ptr_t * vMembers, int Level ) +{ + Gia_Obj_t * pTempRepr = NULL; + int iRepr, iMember; + iRepr = Gia_ObjId( p, pRepr ); + Vec_PtrClear( vMembers ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjLevelId(p, iMember) == Level ) + Vec_PtrPush( vMembers, Gia_ManObj( p, iMember ) ); + if ( pTempRepr == NULL && Gia_ObjLevelId(p, iMember) < Level ) + pTempRepr = Gia_ManObj( p, iMember ); + } + return pTempRepr; +} + + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Gia_GiarfStorePatternTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Gia_InfoHasBit( pPres, iBit ) && + Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_GiarfStorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex ) +{ + int k; + for ( k = 1; k < 32; k++ ) + if ( Gia_GiarfStorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) ) + break; + return (int)(k < 32); +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfInsertPattern( Hcd_Man_t * p, Vec_Int_t * vCex, int k ) +{ + Gia_Obj_t * pObj; + unsigned * pInfo; + int Lit, i; + Vec_IntForEachEntry( vCex, Lit, i ) + { + pObj = Gia_ManCi( p->pGia, Gia_Lit2Var(Lit) ); + pInfo = Hcd_ObjSimP( p, Gia_ObjId( p->pGia, pObj ) ); + if ( Gia_InfoHasBit( pInfo, k ) == Gia_LitIsCompl(Lit) ) + Gia_InfoXorBit( pInfo, k ); + } +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfPrintClasses( Gia_Man_t * pGia ) +{ + int nFails = 0; + int nProves = 0; + int nTotal = 0; + int nBoth = 0; + int i; + for ( i = 0; i < Gia_ManObjNum(pGia); i++ ) + { + nFails += Gia_ObjFailed(pGia, i); + nProves += Gia_ObjProved(pGia, i); + nTotal += Gia_ObjReprObj(pGia, i) != NULL; + nBoth += Gia_ObjFailed(pGia, i) && Gia_ObjProved(pGia, i); + } + printf( "nFails = %7d. nProves = %7d. nBoth = %7d. nTotal = %7d.\n", + nFails, nProves, nBoth, nTotal ); +} + +ABC_NAMESPACE_IMPL_END + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ComputeEquivalencesLevel( Hcd_Man_t * p, Gia_Man_t * pGiaLev, Vec_Ptr_t * vOldRoots, int Level, int fUseMiniSat ) +{ + int fUse2Solver = 0; + Cec_ManSat_t * pSat; + Cec_ParSat_t Pars; + Tas_Man_t * pTas; + Vec_Int_t * vCex; + Vec_Ptr_t * vClasses, * vMembers, * vOldRootsNew; + Gia_Obj_t * pRoot, * pMember, * pMemberPrev, * pRepr, * pTempRepr; + int i, k, nIter, iRoot, iRootNew, iMember, iMemberPrev, status, fOneFailed;//, iRepr;//, fTwoMember; + int nSaved = 0, nRecords = 0, nUndec = 0, nClassRefs = 0, nTsat = 0, nMiniSat = 0; + int clk, timeTsat = 0, timeMiniSat = 0, timeSim = 0, timeTotal = clock(); + if ( Vec_PtrSize(vOldRoots) == 0 ) + return 0; + // start SAT solvers + Cec_ManSatSetDefaultParams( &Pars ); + Pars.fPolarFlip = 0; + Pars.nBTLimit = p->nBTLimit; + pSat = Cec_ManSatCreate( pGiaLev, &Pars ); + pTas = Tas_ManAlloc( pGiaLev, p->nBTLimit ); + if ( fUseMiniSat ) + vCex = Cec_ManSatReadCex( pSat ); + else + vCex = Tas_ReadModel( pTas ); + vMembers = Vec_PtrAlloc( 100 ); + Vec_PtrCleanSimInfo( p->vSimPres, 0, 1 ); + // resolve constants + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( !Gia_ObjIsConst( p->pGia, iRoot ) ) + continue; + iRootNew = Gia_LitNotCond( pRoot->Value, pRoot->fPhase ); + assert( iRootNew != 1 ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; +// Hcd_ManClassClassRemoveOne( p, iRoot ); + Gia_ObjSetFailed( p->pGia, iRoot ); + } + else if ( status == 1 ) // unsat + { + Gia_ObjSetProved( p->pGia, iRoot ); +// printf( "proved constant %d\n", iRoot ); + } + else // sat + { +// printf( "Disproved constant %d\n", iRoot ); + Gia_ObjUnsetRepr( p->pGia, iRoot ); // do we need this? + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + } + } + + vClasses = Vec_PtrAlloc( 100 ); + vOldRootsNew = Vec_PtrAlloc( 100 ); + for ( nIter = 0; Vec_PtrSize(vOldRoots) > 0; nIter++ ) + { +// printf( "Iter = %d (Size = %d)\n", nIter, Vec_PtrSize(vOldRoots) ); + // resolve equivalences + Vec_PtrClear( vClasses ); + Vec_PtrClear( vOldRootsNew ); + Gia_ManConst0( p->pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( Gia_ObjIsHead( p->pGia, iRoot ) ) + pRepr = pRoot; + else if ( Gia_ObjIsClass( p->pGia, iRoot ) ) + pRepr = Gia_ObjReprObj( p->pGia, iRoot ); + else + continue; + if ( pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// fTwoMember = Gia_ClassIsPair(p->pGia, iRepr) + // derive temp repr and members on this level + pTempRepr = Gia_CollectClassMembers( p->pGia, pRepr, vMembers, Level ); + if ( pTempRepr ) + Vec_PtrPush( vMembers, pTempRepr ); + if ( Vec_PtrSize(vMembers) < 2 ) + continue; + // try proving the members + fOneFailed = 0; + pMemberPrev = (Gia_Obj_t *)Vec_PtrEntryLast( vMembers ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + { + iMemberPrev = Gia_LitNotCond( pMemberPrev->Value, pMemberPrev->fPhase ); + iMember = Gia_LitNotCond( pMember->Value, !pMember->fPhase ); + assert( iMemberPrev != iMember ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; + if ( Gia_ObjLevel(p->pGia, pMemberPrev) > Gia_ObjLevel(p->pGia, pMember) ) + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + else + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMember) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + } + else if ( status == 1 ) // unsat + { +// Gia_ObjSetProved( p->pGia, iRoot ); + } + else // sat + { +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// if ( Gia_ClassIsPair(p->pGia, iRepr) ) +// Gia_ClassUndoPair(p->pGia, iRepr); +// else + { + fOneFailed = 1; + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + Gia_GiarfInsertPattern( p, vCex, (k % 31) + 1 ); + } + } + pMemberPrev = pMember; +// if ( fOneFailed ) +// k += Vec_PtrSize(vMembers) / 4; + } + // if fail, quit this class + if ( fOneFailed ) + { + nClassRefs++; + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + if ( pMember != pTempRepr && !Gia_ObjFailed(p->pGia, Gia_ObjId(p->pGia, pMember)) ) + Vec_PtrPush( vOldRootsNew, pMember ); + clk = clock(); + Gia_ResimulateAndRefine( p, Gia_ObjId(p->pGia, pRepr) ); + timeSim += clock() - clk; + } + else + { + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + Gia_ObjSetProved( p->pGia, Gia_ObjId(p->pGia, pMember) ); +/* +// } +// else +// { + printf( "Proved equivalent: " ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + printf( "%d(L=%d) ", Gia_ObjId(p->pGia, pMember), p->pGia->pLevels[Gia_ObjId(p->pGia, pMember)] ); + printf( "\n" ); +*/ + } + + } + Vec_PtrClear( vOldRoots ); + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRootsNew, pMember, i ) + Vec_PtrPush( vOldRoots, pMember ); + // clean up + Gia_ManConst0( p->pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + } + Vec_PtrFree( vClasses ); + Vec_PtrFree( vOldRootsNew ); + printf( "nSaved = %d nRecords = %d nUndec = %d nClassRefs = %d nMiniSat = %d nTas = %d\n", + nSaved, nRecords, nUndec, nClassRefs, nMiniSat, nTsat ); + ABC_PRT( "Tas ", timeTsat ); + ABC_PRT( "MiniSat", timeMiniSat ); + ABC_PRT( "Sim ", timeSim ); + ABC_PRT( "Total ", clock() - timeTotal ); + + // resimulate +// clk = clock(); + Hcd_ManSimulateSimple( p ); + Hcd_ManClassesRefine( p ); +// ABC_PRT( "Simulate/refine", clock() - clk ); + + // verify the results + Vec_PtrFree( vMembers ); + Tas_ManStop( pTas ); + Cec_ManSatStop( pSat ); + return nIter; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ComputeEquivalences( Gia_Man_t * pGia, int nBTLimit, int fUseMiniSat, int fVerbose ) +{ + Hcd_Man_t * p; + Vec_Ptr_t * vRoots; + Gia_Man_t * pGiaLev; + int i, Lev, nLevels, nIters, clk; + Gia_ManRandom( 1 ); + Gia_ManSetPhase( pGia ); + nLevels = Gia_ManLevelNum( pGia ); + Gia_ManIncrementTravId( pGia ); + // start the manager + p = Gia_ManEquivStart( pGia, nBTLimit, fVerbose ); + // create trivial classes + Hcd_ManClassesCreate( p ); + // refine + for ( i = 0; i < 3; i++ ) + { + clk = clock(); + Hcd_ManSimulationInit( p ); + Hcd_ManSimulateSimple( p ); + ABC_PRT( "Sim", clock() - clk ); + clk = clock(); + Hcd_ManClassesRefine( p ); + ABC_PRT( "Ref", clock() - clk ); + } + // process in the levelized order + for ( Lev = 1; Lev < nLevels; Lev++ ) + { + clk = clock(); + printf( "LEVEL %3d (out of %3d) ", Lev, nLevels ); + pGiaLev = Gia_GenerateReducedLevel( pGia, Lev, &vRoots ); + nIters = Gia_ComputeEquivalencesLevel( p, pGiaLev, vRoots, Lev, fUseMiniSat ); + Gia_ManStop( pGiaLev ); + Vec_PtrFree( vRoots ); + printf( "Iters = %3d " ); + ABC_PRT( "Time", clock() - clk ); + } + Gia_GiarfPrintClasses( pGia ); + // clean up + Gia_ManEquivStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaGlitch.c b/src/aig/gia/giaGlitch.c index ed636540..a6e5315a 100644 --- a/src/aig/gia/giaGlitch.c +++ b/src/aig/gia/giaGlitch.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -779,3 +782,5 @@ void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c index 97326c92..6561ca13 100644 --- a/src/aig/gia/giaHash.c +++ b/src/aig/gia/giaHash.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,7 +69,7 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 ) Gia_Obj_t * pThis; int * pPlace = p->pHTable + Gia_ManHashOne( iLit0, iLit1, p->nHTable ); for ( pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL; pThis; - pPlace = &pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL ) + pPlace = (int *)&pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL ) if ( Gia_ObjFaninLit0p(p, pThis) == iLit0 && Gia_ObjFaninLit1p(p, pThis) == iLit1 ) break; return pPlace; @@ -74,6 +77,26 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 ) /**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ) +{ + int iLit0 = Gia_ObjToLit( p, p0 ); + int iLit1 = Gia_ObjToLit( p, p1 ); + if ( iLit0 > iLit1 ) + iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1; + return *Gia_ManHashFind( p, iLit0, iLit1 ); +} + +/**Function************************************************************* + Synopsis [Starts the hash table.] Description [] @@ -594,3 +617,5 @@ Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaHcd.c b/src/aig/gia/giaHcd.c new file mode 100644 index 00000000..454785b9 --- /dev/null +++ b/src/aig/gia/giaHcd.c @@ -0,0 +1,686 @@ +/**CFile**************************************************************** + + FileName [giaHcd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [New choice computation package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaHcd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "aig.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// choicing parameters +typedef struct Hcd_Pars_t_ Hcd_Pars_t; +struct Hcd_Pars_t_ +{ + int nWords; // the number of simulation words + int nBTLimit; // conflict limit at a node + int nSatVarMax; // the max number of SAT variables + int fSynthesis; // set to 1 to perform synthesis + int fPolarFlip; // uses polarity adjustment + int fSimulateTfo; // uses simulation of TFO classes + int fPower; // uses power-aware rewriting + int fUseGia; // uses GIA package + int fUseCSat; // uses circuit-based solver + int fVerbose; // verbose stats + int timeSynth; // synthesis runtime + int nNodesAhead; // the lookahead in terms of nodes + int nCallsRecycle; // calls to perform before recycling SAT solver +}; + +extern void Gia_ComputeEquivalences( Gia_Man_t * pMiter, int nBTLimit, int fUseMiniSat, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSetDefaultParams( Hcd_Pars_t * p ) +{ + memset( p, 0, sizeof(Hcd_Pars_t) ); + p->nWords = 8; // the number of simulation words + p->nBTLimit = 1000; // conflict limit at a node + p->nSatVarMax = 5000; // the max number of SAT variables + p->fSynthesis = 1; // derives three snapshots + p->fPolarFlip = 1; // uses polarity adjustment + p->fSimulateTfo = 1; // simulate TFO + p->fPower = 0; // power-aware rewriting + p->fVerbose = 0; // verbose stats + p->nNodesAhead = 1000; // the lookahead in terms of nodes + p->nCallsRecycle = 100; // calls to perform before recycling SAT solver +} + + +/**Function************************************************************* + + Synopsis [Reproduces script "compress".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_Compress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ) +//alias compress2 "b -l; rw -l; rwz -l; b -l; rwz -l; b -l" +{ + Aig_Man_t * pTemp; + + Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr; + Dar_RefPar_t ParsRef, * pParsRef = &ParsRef; + + Dar_ManDefaultRwrParams( pParsRwr ); + Dar_ManDefaultRefParams( pParsRef ); + + pParsRwr->fUpdateLevel = fUpdateLevel; + pParsRef->fUpdateLevel = fUpdateLevel; + + pParsRwr->fPower = fPower; + + pParsRwr->fVerbose = 0;//fVerbose; + pParsRef->fVerbose = 0;//fVerbose; + +// pAig = Aig_ManDupDfs( pAig ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + pParsRwr->fUseZeros = 1; + pParsRef->fUseZeros = 1; + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + return pAig; +} + +/**Function************************************************************* + + Synopsis [Reproduces script "compress2".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_Compress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ) +//alias compress2 "b -l; rw -l; rf -l; b -l; rw -l; rwz -l; b -l; rfz -l; rwz -l; b -l" +{ + Aig_Man_t * pTemp; + + Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr; + Dar_RefPar_t ParsRef, * pParsRef = &ParsRef; + + Dar_ManDefaultRwrParams( pParsRwr ); + Dar_ManDefaultRefParams( pParsRef ); + + pParsRwr->fUpdateLevel = fUpdateLevel; + pParsRef->fUpdateLevel = fUpdateLevel; + pParsRwr->fFanout = fFanout; + pParsRwr->fPower = fPower; + + pParsRwr->fVerbose = 0;//fVerbose; + pParsRef->fVerbose = 0;//fVerbose; + +// pAig = Aig_ManDupDfs( pAig ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance +// if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + pParsRwr->fUseZeros = 1; + pParsRef->fUseZeros = 1; + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + return pAig; +} + +/**Function************************************************************* + + Synopsis [Reproduces script "compress2".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Hcd_ChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ) +//alias resyn "b; rw; rwz; b; rwz; b" +//alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; rwz; b" +{ + Vec_Ptr_t * vGias; + Gia_Man_t * pGia; + + vGias = Vec_PtrAlloc( 3 ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); + + pAig = Hcd_Compress( pAig, fBalance, fUpdateLevel, fPower, fVerbose ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); +//Aig_ManPrintStats( pAig ); + + pAig = Hcd_Compress2( pAig, fBalance, fUpdateLevel, 1, fPower, fVerbose ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); +//Aig_ManPrintStats( pAig ); + + Aig_ManStop( pAig ); + return vGias; +} + + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derives the miter of several AIGs for choice computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Hcd_ManChoiceMiter( Vec_Ptr_t * vGias ) +{ + Gia_Man_t * pNew, * pGia, * pGia0; + int i, k, iNode, nNodes; + // make sure they have equal parameters + assert( Vec_PtrSize(vGias) > 0 ); + pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + { + assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); + assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); + assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); + Gia_ManFillValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; + } + // start the new manager + pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); + pNew->pName = Gia_UtilStrsav( pGia0->pName ); + // create new CIs and assign them to the old manager CIs + for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) + { + iNode = Gia_ManAppendCi(pNew); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManCi( pGia, k )->Value = iNode; + } + // create internal nodes + Gia_ManHashAlloc( pNew ); + for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Hcd_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); + } + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + nNodes = Gia_ManHasDangling( pNew ); + assert( nNodes == 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ObjCheckTfi_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode, Vec_Ptr_t * vVisited ) +{ + // check the trivial cases + if ( pNode == NULL ) + return 0; + if ( Gia_ObjIsCi(pNode) ) + return 0; +// if ( pNode->Id < pOld->Id ) // cannot use because of choices of pNode +// return 0; + if ( pNode == pOld ) + return 1; + // skip the visited node + if ( pNode->fMark0 ) + return 0; + pNode->fMark0 = 1; + Vec_PtrPush( vVisited, pNode ); + // check the children + if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin0(pNode), vVisited ) ) + return 1; + if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin1(pNode), vVisited ) ) + return 1; + // check equivalent nodes + return Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjNextObj(p, Gia_ObjId(p, pNode)), vVisited ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) +{ + Vec_Ptr_t * vVisited; + Gia_Obj_t * pObj; + int RetValue, i; + assert( !Gia_IsComplement(pOld) ); + assert( !Gia_IsComplement(pNode) ); + vVisited = Vec_PtrAlloc( 100 ); + RetValue = Hcd_ObjCheckTfi_rec( p, pOld, pNode, vVisited ); + Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i ) + pObj->fMark0 = 0; + Vec_PtrFree( vVisited ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Adds the next entry while making choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManAddNextEntry_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) +{ + if ( Gia_ObjNext(p, Gia_ObjId(p, pOld)) == 0 ) + { + Gia_ObjSetNext( p, Gia_ObjId(p, pOld), Gia_ObjId(p, pNode) ); + return; + } + Hcd_ManAddNextEntry_rec( p, Gia_ObjNextObj(p, Gia_ObjId(p, pOld)), pNode ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr, * pReprNew, * pObjNew; + if ( ~pObj->Value ) + return; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + if ( Gia_ObjIsConst0(pRepr) ) + { + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + Hcd_ManEquivToChoices_rec( pNew, p, pRepr ); + assert( Gia_ObjIsAnd(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( Gia_LitRegular(pObj->Value) == Gia_LitRegular(pRepr->Value) ) + { + assert( (int)pObj->Value == Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ) ); + return; + } + if ( pRepr->Value > pObj->Value ) // should never happen with high resource limit + return; + assert( pRepr->Value < pObj->Value ); + pReprNew = Gia_ManObj( pNew, Gia_Lit2Var(pRepr->Value) ); + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) ) + { + assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + if ( !Hcd_ObjCheckTfi( pNew, pReprNew, pObjNew ) ) + { + assert( Gia_ObjNext(pNew, Gia_ObjId(pNew, pObjNew)) == 0 ); + Gia_ObjSetRepr( pNew, Gia_ObjId(pNew, pObjNew), Gia_ObjId(pNew, pReprNew) ); + Hcd_ManAddNextEntry_rec( pNew, pReprNew, pObjNew ); + } + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Removes choices, which contain fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManRemoveBadChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, iObj, iPrev, Counter = 0; + // mark nodes with fanout + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fMark0 = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + // go through the classes and remove + Gia_ManForEachClass( p, i ) + { + for ( iPrev = i, iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iPrev) ) + { + if ( !Gia_ManObj(p, iObj)->fMark0 ) + { + iPrev = iObj; + continue; + } + Gia_ObjSetRepr( p, iObj, GIA_VOID ); + Gia_ObjSetNext( p, iPrev, Gia_ObjNext(p, iObj) ); + Gia_ObjSetNext( p, iObj, 0 ); + Counter++; + } + } + // remove the marks + Gia_ManCleanMark0( p ); +// printf( "Removed %d bad choices.\n", Counter ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Hcd_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + int i; + assert( (Gia_ManCoNum(p) % nSnapshots) == 0 ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachRo( p, pObj, i ) + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + assert( Gia_ObjIsConst0(pRepr) || Gia_ObjIsRo(p, pRepr) ); + pObj->Value = pRepr->Value; + } + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + if ( i % nSnapshots == 0 ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Hcd_ManRemoveBadChoices( pNew ); +// Gia_ManEquivPrintClasses( pNew, 0, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); +// Gia_ManEquivPrintClasses( pNew, 0, 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_ComputeChoices( Aig_Man_t * pAig, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose ) +{ + Vec_Ptr_t * vGias; + Gia_Man_t * pGia, * pMiter; + Aig_Man_t * pAigNew; + int i, clk = clock(); + // perform synthesis + if ( fSynthesis ) + { + vGias = Hcd_ChoiceSynthesis( Aig_ManDupDfs(pAig), 1, 1, 0, 0 ); + if ( fVerbose ) + ABC_PRT( "Synthesis time", clock() - clk ); + // create choices + clk = clock(); + pMiter = Hcd_ManChoiceMiter( vGias ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManStop( pGia ); + + Gia_WriteAiger( pMiter, "m3.aig", 0, 0 ); + } + else + { + vGias = Vec_PtrStart( 3 ); + pMiter = Gia_ManFromAig(pAig); + } + // perform choicing + Gia_ComputeEquivalences( pMiter, nBTLimit, fUseMiniSat, fVerbose ); + // derive AIG with choices + pGia = Hcd_ManEquivToChoices( pMiter, Vec_PtrSize(vGias) ); + Gia_ManSetRegNum( pGia, Aig_ManRegNum(pAig) ); + Gia_ManStop( pMiter ); + Vec_PtrFree( vGias ); + if ( fVerbose ) + ABC_PRT( "Choicing time", clock() - clk ); + Gia_ManHasChoices( pGia ); + // transform back + pAigNew = Gia_ManToAig( pGia, 1 ); + Gia_ManStop( pGia ); + + if ( fVerbose ) + { + extern int Dch_DeriveChoiceCountReprs( Aig_Man_t * pAig ); + extern int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig ); + printf( "Choices : Reprs = %5d. Equivs = %5d. Choices = %5d.\n", + Dch_DeriveChoiceCountReprs( pAigNew ), + Dch_DeriveChoiceCountEquivs( pAigNew ), + Aig_ManChoiceNum( pAigNew ) ); + } + + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ComputeChoicesTest( Gia_Man_t * pGia, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose ) +{ + Aig_Man_t * pAig, * pAigNew; + pAig = Gia_ManToAig( pGia, 0 ); + pAigNew = Hcd_ComputeChoices( pAig, nBTLimit, fSynthesis, fUseMiniSat, fVerbose ); + Aig_ManStop( pAigNew ); + Aig_ManStop( pAig ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaIf.c index 72bdb001..a06a6024 100644 --- a/src/aig/gia/giaMap.c +++ b/src/aig/gia/giaIf.c @@ -19,7 +19,12 @@ ***********************************************************************/ #include "gia.h" +#include "aig.h" #include "if.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -95,6 +100,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) Gia_Obj_t * pNode; int i, clk = clock(); Gia_ManLevelNum( p ); +// assert( p->pReprs == NULL ); /* // set the number of registers (switch activity will be combinational) Gia_ManSetRegNum( p, 0 ); @@ -114,24 +120,25 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) pIfMan = If_ManStart( pPars ); // pIfMan->vSwitching = vSwitching2; // load the AIG into the mapper + Gia_ManCreateRefs( p ); Gia_ManForEachObj( p, pNode, i ) { if ( Gia_ObjIsAnd(pNode) ) pIfObj = If_ManCreateAnd( pIfMan, - If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), - If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); else if ( Gia_ObjIsCi(pNode) ) { pIfObj = If_ManCreateCi( pIfMan ); If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) ); -// printf( "pi=%d ", pIfObj->Level ); +// Abc_Print( 1, "pi=%d ", pIfObj->Level ); if ( pIfMan->nLevelMax < (int)pIfObj->Level ) pIfMan->nLevelMax = (int)pIfObj->Level; } else if ( Gia_ObjIsCo(pNode) ) { - pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); -// printf( "po=%d ", pIfObj->Level ); + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); +// Abc_Print( 1, "po=%d ", pIfObj->Level ); } else if ( Gia_ObjIsConst0(pNode) ) pIfObj = If_Not(If_ManConst1( pIfMan )); @@ -142,6 +149,18 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); // if ( vSwitching2 ) // pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; + // set up the choice node +/* +// if ( p->pReprs && p->pNexts && Gia_ObjIsHead( p, i ) ) + if ( p->pNexts && Gia_ObjNext(p, i) && Gia_ObjRefsId(p, i) ) + { + int iPrev, iFanin; + pIfMan->nChoices++; + for ( iPrev = i, iFanin = Gia_ObjNext(p, i); iFanin; iPrev = iFanin, iFanin = Gia_ObjNext(p, iFanin) ) + If_ObjSetChoice( Vec_PtrEntry(vAigToIf,iPrev), Vec_PtrEntry(vAigToIf,iFanin) ); + If_ManCreateChoice( pIfMan, Vec_PtrEntry(vAigToIf,i) ); + } +*/ /* // set up the choice node if ( Gia_ObjIsChoice( p, pNode ) ) { @@ -186,7 +205,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); Gia_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) continue; @@ -197,7 +216,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) iOffset = Gia_ManObjNum(p); Gia_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) continue; pCutBest = If_ObjCutBest( pIfObj ); @@ -208,7 +227,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) pMapping[k++] = nLeaves; for ( j = 0; j < nLeaves; j++ ) { - pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] ); + pObjRepr = (Gia_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[j] ); pMapping[k++] = Gia_ObjId( p, pObjRepr ); } pMapping[k++] = i; @@ -279,23 +298,226 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p ) if ( !p->pMapping ) return; pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); - Gia_ManForEachGate( p, i ) + Gia_ManForEachLut( p, i ) { nLuts++; - nFanins += Gia_ObjGateSize(p, i); - nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) ); - Gia_GateForEachFanin( p, i, iFan, k ) + nFanins += Gia_ObjLutSize(p, i); + nLutSize = ABC_MAX( nLutSize, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] ); pLevels[i]++; LevelMax = ABC_MAX( LevelMax, pLevels[i] ); } ABC_FREE( pLevels ); - printf( "mapping : " ); - printf( "%d=lut =%7d ", nLutSize, nLuts ); - printf( "edge =%8d ", nFanins ); - printf( "lev =%5d ", LevelMax ); - printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); - printf( "\n" ); + Abc_Print( 1, "mapping (K=%d) : ", nLutSize ); + Abc_Print( 1, "lut =%7d ", nLuts ); + Abc_Print( 1, "edge =%8d ", nFanins ); + Abc_Print( 1, "lev =%5d ", LevelMax ); + Abc_Print( 1, "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutFaninCount( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter += Gia_ObjLutSize(p, i); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutSizeMax( Gia_Man_t * p ) +{ + int i, nSizeMax = -1; + Gia_ManForEachLut( p, i ) + nSizeMax = ABC_MAX( nSizeMax, Gia_ObjLutSize(p, i) ); + return nSizeMax; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutNum( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter ++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutLevel( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan, Level; + int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, i ) + { + Level = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + if ( Level < pLevels[iFan] ) + Level = pLevels[iFan]; + pLevels[i] = Level + 1; + } + Level = 0; + Gia_ManForEachCo( p, pObj, k ) + if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] ) + Level = pLevels[Gia_ObjFaninId0p(p, pObj)]; + ABC_FREE( pLevels ); + return Level; +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRefsMapped( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan; + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + Gia_ObjRefInc( p, Gia_ManObj(p, iFan) ); +} + +/**Function************************************************************* + + Synopsis [Prints NPN class statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintNpnClasses( Gia_Man_t * p ) +{ + extern char ** Kit_DsdNpn4ClassNames(); + char ** pNames = Kit_DsdNpn4ClassNames(); + Vec_Int_t * vLeaves, * vTruth, * vVisited; + int * pLutClass, ClassCounts[222] = {0}; + int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2; + unsigned * pTruth; + assert( p->pMapping != NULL ); + assert( Gia_ManLutSizeMax( p ) <= 4 ); + vLeaves = Vec_IntAlloc( 100 ); + vVisited = Vec_IntAlloc( 100 ); + vTruth = Vec_IntAlloc( (1<<16) ); + pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManCleanTruth( p ); + Gia_ManForEachLut( p, i ) + { + if ( Gia_ObjLutSize(p,i) > 4 ) + continue; + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, i, iFan, k ) + Vec_IntPush( vLeaves, iFan ); + for ( ; k < 4; k++ ) + Vec_IntPush( vLeaves, 0 ); + pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited ); + Class = Dar_LibReturnClass( *pTruth ); + ClassCounts[ Class ]++; + pLutClass[i] = Class; + } + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + Vec_IntFreeP( &p->vTruths ); + nTotal = 0; + for ( i = 0; i < 222; i++ ) + nTotal += ClassCounts[i]; + Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal ); + OtherClasses = 0; + for ( i = 0; i < 222; i++ ) + { + if ( ClassCounts[i] == 0 ) + continue; + if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent + continue; + OtherClasses += ClassCounts[i]; + Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n", + i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] ); + } + OtherClasses = nTotal - OtherClasses; + Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1) ); + // count the number of LUTs that have MUX function and two fanins with MUX functions + OtherClasses = OtherClasses2 = 0; + ABC_FREE( p->pRefs ); + Gia_ManSetRefsMapped( p ); + Gia_ManForEachLut( p, i ) + { + if ( pLutClass[i] != 109 ) + continue; + Counter = Counter2 = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + { + Counter += (pLutClass[iFan] == 109); + Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefsId(p, iFan) == 1); + } + OtherClasses += (Counter > 1); + OtherClasses2 += (Counter2 > 1); +// Abc_Print( 1, "%d -- ", pLutClass[i] ); +// Gia_LutForEachFanin( p, i, iFan, k ) +// Abc_Print( 1, "%d ", pLutClass[iFan] ); +// Abc_Print( 1, "\n" ); + } + ABC_FREE( p->pRefs ); + Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1), + OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) ); + ABC_FREE( pLutClass ); } //////////////////////////////////////////////////////////////////////// @@ -303,3 +525,5 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 4547e61c..ed6a5c95 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "gia.h" +#include "tim.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -66,10 +70,18 @@ Gia_Man_t * Gia_ManStart( int nObjsMax ) ***********************************************************************/ void Gia_ManStop( Gia_Man_t * p ) { + Tim_ManStopP( (Tim_Man_t **)&p->pManTime ); + assert( p->pManTime == NULL ); Vec_PtrFreeFree( p->vNamesIn ); Vec_PtrFreeFree( p->vNamesOut ); - if ( p->vFlopClasses ) - Vec_IntFree( p->vFlopClasses ); + Vec_FltFreeP( &p->vTiming ); + Vec_VecFreeP( &p->vClockDoms ); + Vec_IntFreeP( &p->vLutConfigs ); + Vec_IntFreeP( &p->vCiNumsOrig ); + Vec_IntFreeP( &p->vCoNumsOrig ); + Vec_IntFreeP( &p->vFlopClasses ); + Vec_IntFreeP( &p->vLevels ); + Vec_IntFreeP( &p->vTruths ); Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); ABC_FREE( p->pTravIds ); @@ -85,7 +97,7 @@ void Gia_ManStop( Gia_Man_t * p ) ABC_FREE( p->pNexts ); ABC_FREE( p->pName ); ABC_FREE( p->pRefs ); - ABC_FREE( p->pLevels ); + ABC_FREE( p->pNodeRefs ); ABC_FREE( p->pHTable ); ABC_FREE( p->pObjs ); ABC_FREE( p ); @@ -93,6 +105,25 @@ void Gia_ManStop( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStopP( Gia_Man_t ** p ) +{ + if ( *p == NULL ) + return; + Gia_ManStop( *p ); + *p = NULL; +} + +/**Function************************************************************* + Synopsis [Prints stats for the AIG.] Description [] @@ -102,7 +133,7 @@ void Gia_ManStop( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManPrintClasses( Gia_Man_t * p ) +void Gia_ManPrintClasses_old( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; @@ -134,6 +165,44 @@ void Gia_ManPrintClasses( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +void Gia_ManPrintClasses( Gia_Man_t * p ) +{ + int i, Class, Counter0, Counter1; + if ( p->vFlopClasses == NULL ) + return; + if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) ) + { + printf( "Gia_ManPrintClasses(): The number of flop map entries differs from the number of flops.\n" ); + return; + } + printf( "Register classes: " ); + // count zero entries + Counter0 = 0; + Vec_IntForEachEntry( p->vFlopClasses, Class, i ) + Counter0 += (Class == 0); + printf( "0=%d ", Counter0 ); + // count one entries + Counter1 = 0; + Vec_IntForEachEntry( p->vFlopClasses, Class, i ) + Counter1 += (Class == 1); + printf( "1=%d ", Counter1 ); + // add comment + if ( Counter0 + Counter1 < Gia_ManRegNum(p) ) + printf( "there are other classes..." ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Gia_ManPrintPlacement( Gia_Man_t * p ) { int i, nFixed = 0, nUndef = 0; @@ -163,13 +232,15 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ) if ( p->pName ) printf( "%-8s : ", p->pName ); printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) ); + if ( Gia_ManConstrNum(p) ) + printf( "(c=%d)", Gia_ManConstrNum(p) ); if ( Gia_ManRegNum(p) ) printf( " ff =%7d", Gia_ManRegNum(p) ); printf( " and =%8d", Gia_ManAndNum(p) ); printf( " lev =%5d", Gia_ManLevelNum(p) ); printf( " cut =%5d", Gia_ManCrossCut(p) ); printf( " mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); - if ( Gia_ManHasDandling(p) ) + if ( Gia_ManHasDangling(p) ) printf( " ch =%5d", Gia_ManEquivCountClasses(p) ); if ( fSwitch ) { @@ -189,7 +260,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ) if ( p->pPlacement ) Gia_ManPrintPlacement( p ); // print register classes -// Gia_ManPrintClasses( p ); + Gia_ManPrintClasses( p ); } /**Function************************************************************* @@ -309,3 +380,5 @@ void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMem.c b/src/aig/gia/giaMem.c new file mode 100644 index 00000000..d77ddfd5 --- /dev/null +++ b/src/aig/gia/giaMem.c @@ -0,0 +1,598 @@ +/**CFile**************************************************************** + + FileName [giaMem.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [AIG package.] + + Synopsis [Memory managers.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - April 28, 2007.] + + Revision [$Id: giaMem.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Gia_MmFixed_t_ +{ + // information about individual entries + int nEntrySize; // the size of one entry + int nEntriesAlloc; // the total number of entries allocated + int nEntriesUsed; // the number of entries in use + int nEntriesMax; // the max number of entries in use + char * pEntriesFree; // the linked list of free entries + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Gia_MmFlex_t_ +{ + // information about individual entries + int nEntriesUsed; // the number of entries allocated + char * pCurrent; // the current pointer to free memory + char * pEnd; // the first entry outside the free memory + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Gia_MmStep_t_ +{ + int nMems; // the number of fixed memory managers employed + Gia_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc + int nMapSize; // the size of the memory array + Gia_MmFixed_t ** pMap; // maps the number of bytes into its memory manager + // additional memory chunks + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates memory pieces of fixed size.] + + Description [The size of the chunk is computed as the minimum of + 1024 entries and 64K. Can only work with entry size at least 4 byte long.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ) +{ + Gia_MmFixed_t * p; + + p = ABC_ALLOC( Gia_MmFixed_t, 1 ); + memset( p, 0, sizeof(Gia_MmFixed_t) ); + + p->nEntrySize = nEntrySize; + p->nEntriesAlloc = 0; + p->nEntriesUsed = 0; + p->pEntriesFree = NULL; + + p->nChunkSize = nEntriesMax / 8; + if ( p->nChunkSize < 8 ) + p->nChunkSize = 8; + + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + + p->nMemoryUsed = 0; + p->nMemoryAlloc = 0; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ) +{ + int i; + if ( p == NULL ) + return; + if ( fVerbose ) + { + printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", + p->nEntrySize, p->nChunkSize, p->nChunks ); + printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", + p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); + } + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p ) +{ + char * pTemp; + int i; + + // check if there are still free entries + if ( p->nEntriesUsed == p->nEntriesAlloc ) + { // need to allocate more entries + assert( p->pEntriesFree == NULL ); + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize ); + p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; + // transform these entries into a linked list + pTemp = p->pEntriesFree; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // add the chunk to the chunk storage + p->pChunks[ p->nChunks++ ] = p->pEntriesFree; + // add to the number of entries allocated + p->nEntriesAlloc += p->nChunkSize; + } + // incrememt the counter of used entries + p->nEntriesUsed++; + if ( p->nEntriesMax < p->nEntriesUsed ) + p->nEntriesMax = p->nEntriesUsed; + // return the first entry in the free entry list + pTemp = p->pEntriesFree; + p->pEntriesFree = *((char **)pTemp); + return pTemp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry ) +{ + // decrement the counter of used entries + p->nEntriesUsed--; + // add the entry to the linked list of free entries + *((char **)pEntry) = p->pEntriesFree; + p->pEntriesFree = pEntry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedRestart( Gia_MmFixed_t * p ) +{ + int i; + char * pTemp; + if ( p->nChunks == 0 ) + return; + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + p->nChunks = 1; + // transform these entries into a linked list + pTemp = p->pChunks[0]; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // set the free entry list + p->pEntriesFree = p->pChunks[0]; + // set the correct statistics + p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; + p->nMemoryUsed = 0; + p->nEntriesAlloc = p->nChunkSize; + p->nEntriesUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p ) +{ + return p->nMemoryAlloc; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p ) +{ + return p->nEntriesMax; +} + + + +/**Function************************************************************* + + Synopsis [Allocates entries of flexible size.] + + Description [Can only work with entry size at least 4 byte long.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmFlex_t * Gia_MmFlexStart() +{ + Gia_MmFlex_t * p; + + p = ABC_ALLOC( Gia_MmFlex_t, 1 ); + memset( p, 0, sizeof(Gia_MmFlex_t) ); + + p->nEntriesUsed = 0; + p->pCurrent = NULL; + p->pEnd = NULL; + + p->nChunkSize = (1 << 18); + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + + p->nMemoryUsed = 0; + p->nMemoryAlloc = 0; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose ) +{ + int i; + if ( p == NULL ) + return; + if ( fVerbose ) + { + printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n", + p->nChunkSize, p->nChunks ); + printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n", + p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc ); + } + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes ) +{ + char * pTemp; + // check if there are still free entries + if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) + { // need to allocate more entries + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + if ( nBytes > p->nChunkSize ) + { + // resize the chunk size if more memory is requested than it can give + // (ideally, this should never happen) + p->nChunkSize = 2 * nBytes; + } + p->pCurrent = ABC_ALLOC( char, p->nChunkSize ); + p->pEnd = p->pCurrent + p->nChunkSize; + p->nMemoryAlloc += p->nChunkSize; + // add the chunk to the chunk storage + p->pChunks[ p->nChunks++ ] = p->pCurrent; + } + assert( p->pCurrent + nBytes <= p->pEnd ); + // increment the counter of used entries + p->nEntriesUsed++; + // keep track of the memory used + p->nMemoryUsed += nBytes; + // return the next entry + pTemp = p->pCurrent; + p->pCurrent += nBytes; + return pTemp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFlexRestart( Gia_MmFlex_t * p ) +{ + int i; + if ( p->nChunks == 0 ) + return; + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + p->nChunks = 1; + p->nMemoryAlloc = p->nChunkSize; + // transform these entries into a linked list + p->pCurrent = p->pChunks[0]; + p->pEnd = p->pCurrent + p->nChunkSize; + p->nEntriesUsed = 0; + p->nMemoryUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p ) +{ + return p->nMemoryUsed; +} + + + + + +/**Function************************************************************* + + Synopsis [Starts the hierarchical memory manager.] + + Description [This manager can allocate entries of any size. + Iternally they are mapped into the entries with the number of bytes + equal to the power of 2. The smallest entry size is 8 bytes. The + next one is 16 bytes etc. So, if the user requests 6 bytes, he gets + 8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc. + The input parameters "nSteps" says how many fixed memory managers + are employed internally. Calling this procedure with nSteps equal + to 10 results in 10 hierarchically arranged internal memory managers, + which can allocate up to 4096 (1Kb) entries. Requests for larger + entries are handed over to malloc() and then ABC_FREE()ed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmStep_t * Gia_MmStepStart( int nSteps ) +{ + Gia_MmStep_t * p; + int i, k; + p = ABC_ALLOC( Gia_MmStep_t, 1 ); + memset( p, 0, sizeof(Gia_MmStep_t) ); + p->nMems = nSteps; + // start the fixed memory managers + p->pMems = ABC_ALLOC( Gia_MmFixed_t *, p->nMems ); + for ( i = 0; i < p->nMems; i++ ) + p->pMems[i] = Gia_MmFixedStart( (8<<i), (1<<13) ); + // set up the mapping of the required memory size into the corresponding manager + p->nMapSize = (4<<p->nMems); + p->pMap = ABC_ALLOC( Gia_MmFixed_t *, p->nMapSize+1 ); + p->pMap[0] = NULL; + for ( k = 1; k <= 4; k++ ) + p->pMap[k] = p->pMems[0]; + for ( i = 0; i < p->nMems; i++ ) + for ( k = (4<<i)+1; k <= (8<<i); k++ ) + p->pMap[k] = p->pMems[i]; +//for ( i = 1; i < 100; i ++ ) +//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize ); + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the memory manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose ) +{ + int i; + for ( i = 0; i < p->nMems; i++ ) + Gia_MmFixedStop( p->pMems[i], fVerbose ); + if ( p->nChunksAlloc ) + { + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + } + ABC_FREE( p->pMems ); + ABC_FREE( p->pMap ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates the entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes ) +{ + if ( nBytes == 0 ) + return NULL; + if ( nBytes > p->nMapSize ) + { + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + p->pChunks[ p->nChunks++ ] = ABC_ALLOC( char, nBytes ); + return p->pChunks[p->nChunks-1]; + } + return Gia_MmFixedEntryFetch( p->pMap[nBytes] ); +} + + +/**Function************************************************************* + + Synopsis [Recycles the entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes ) +{ + if ( nBytes == 0 ) + return; + if ( nBytes > p->nMapSize ) + { +// ABC_FREE( pEntry ); + return; + } + Gia_MmFixedEntryRecycle( p->pMap[nBytes], pEntry ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ) +{ + int i, nMemTotal = 0; + for ( i = 0; i < p->nMems; i++ ) + nMemTotal += p->pMems[i]->nMemoryAlloc; + return nMemTotal; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaPat.c b/src/aig/gia/giaPat.c index 7968932c..bd43380f 100644 --- a/src/aig/gia/giaPat.c +++ b/src/aig/gia/giaPat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,3 +130,5 @@ void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, V //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaProp.c b/src/aig/gia/giaProp.c index 1d9ed8cf..fee9aa40 100644 --- a/src/aig/gia/giaProp.c +++ b/src/aig/gia/giaProp.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,3 +172,5 @@ int Gia_SatPathStart( Gia_Obj_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaReparam.c b/src/aig/gia/giaReparam.c new file mode 100644 index 00000000..e33c1b7e --- /dev/null +++ b/src/aig/gia/giaReparam.c @@ -0,0 +1,201 @@ +/**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 "giaAig.h" +#include "saig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Specialized duplication.] + + Description [Replaces registers by PIs/POs and PIs by registers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupIn2Ff( Gia_Man_t * p ) +{ + Vec_Int_t * vPiOuts; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + vPiOuts = Vec_IntAlloc( Gia_ManPiNum(p) ); + pNew = Gia_ManStart( Gia_ManObjNum(p) + 2 * Gia_ManPiNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachPi( p, pObj, i ) + Vec_IntPush( vPiOuts, Gia_ManAppendCi(pNew) ); + Gia_ManForEachRo( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManForEachRi( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vPiOuts, i) ); + Gia_ManSetRegNum( pNew, Gia_ManPiNum(p) ); + Vec_IntFree( vPiOuts ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reverses the above step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDupFf2In_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) +{ + if ( pObj->Value != ~0 ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reverses the above step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupFf2In( Gia_Man_t * p, int nFlopsOld ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachRo( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nFlopsOld; i < Gia_ManPiNum(p); i++ ) + Gia_ManPi(p, i)->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, nFlopsOld ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reparameterized to get rid of useless primary inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose ) +{ +// extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); + Aig_Man_t * pMan, * pTemp; + Gia_Man_t * pNew, * pTmp; + int nFlopsOld = Gia_ManRegNum(p); + if ( fVerbose ) + { + printf( "Original AIG:\n" ); + Gia_ManPrintStats( p, 0 ); + } + + // perform input trimming + pNew = Gia_ManDupTrimmed( p, 1, 0 ); + if ( fVerbose ) + { + printf( "After PI trimming:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + // transform GIA + pNew = Gia_ManDupIn2Ff( pTmp = pNew ); + Gia_ManStop( pTmp ); + if ( fVerbose ) + { + printf( "After PI-2-FF transformation:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + + // derive AIG + pMan = Gia_ManToAigSimple( pNew ); + Gia_ManStop( pNew ); + // perform min-reg retiming + pMan = Saig_ManRetimeMinArea( pTemp = pMan, 10, 0, 0, 1, 0 ); + Aig_ManStop( pTemp ); + // derive GIA + pNew = Gia_ManFromAigSimple( pMan ); + Aig_ManStop( pMan ); + if ( fVerbose ) + { + printf( "After min-area retiming:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + + // transform back + pNew = Gia_ManDupFf2In( pTmp = pNew, nFlopsOld ); + Gia_ManStop( pTmp ); + if ( fVerbose ) + { + printf( "After FF-2-PI tranformation:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaRetime.c b/src/aig/gia/giaRetime.c index 967b6d01..58029b66 100644 --- a/src/aig/gia/giaRetime.c +++ b/src/aig/gia/giaRetime.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -131,7 +134,7 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut ) Gia_ManForEachPi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) pObj->Value = Gia_LitNotCond( Gia_ManAppendCi(pNew), pObj->fPhase ); // duplicate logic above the cut Gia_ManForEachCo( p, pObj, i ) @@ -146,11 +149,11 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut ) Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRo->Value = pObjRi->Value; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) pObj->Value = ~0; // duplicate logic below the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) { Gia_ManRetimeDup_rec( pNew, pObj ); Gia_ManAppendCo( pNew, Gia_LitNotCond( pObj->Value, pObj->fPhase ) ); @@ -192,7 +195,7 @@ Gia_Man_t * Gia_ManRetimeForwardOne( Gia_Man_t * p, int * pnRegFixed, int * pnRe vFlopClasses = Vec_IntAlloc( Gia_ManRegNum(p) ); } // mark the retimable nodes - Gia_ManResetTravId( p ); + Gia_ManIncrementTravId( p ); Gia_ManMarkAutonomous( p ); // mark the retimable registers with the fresh trav ID Gia_ManIncrementTravId( p ); @@ -295,3 +298,5 @@ Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSat.c b/src/aig/gia/giaSat.c index 29ade5c6..c2d70795 100644 --- a/src/aig/gia/giaSat.c +++ b/src/aig/gia/giaSat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -419,3 +422,5 @@ void Gia_ManSatExperiment( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c index 5ac8e04a..a482d024 100644 --- a/src/aig/gia/giaScl.c +++ b/src/aig/gia/giaScl.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -187,7 +190,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) if ( Gia_ObjFanin0(pObjRi)->Value == 0 ) Gia_ObjFanin0(pObjRi)->Value = 2*nFanins++; pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p) ); - pMaps = ABC_FALLOC( unsigned, 2 * nFanins ); + pMaps = ABC_FALLOC( unsigned, 2 * nFanins ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) { iLit = Gia_ObjFanin0Copy( pObjRi ); @@ -215,7 +218,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) // printf( "ReduceEquiv detected %d constant regs and %d equivalent regs.\n", Counter0, Counter ); ABC_FREE( pMaps ); if ( Counter0 || Counter ) - pNew = Gia_ManDupDfsCiMap( p, pCi2Lit, NULL ); + pNew = Gia_ManDupDfsCiMap( p, (int *)pCi2Lit, NULL ); else pNew = p; ABC_FREE( pCi2Lit ); @@ -274,3 +277,5 @@ Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fV //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaShrink.c b/src/aig/gia/giaShrink.c new file mode 100644 index 00000000..fc9e80d6 --- /dev/null +++ b/src/aig/gia/giaShrink.c @@ -0,0 +1,151 @@ +/**CFile**************************************************************** + + FileName [giaShrink.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Implementation of mapShrink based on ideas of Niklas Een.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaShrink.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "aig.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern int Dar_LibEvalBuild( Gia_Man_t * p, Vec_Int_t * vCut, unsigned uTruth, int fKeepLevel, Vec_Int_t * vLeavesBest ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs AIG shrinking using the current mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose ) +{ + Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest; + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pFanin; + unsigned * pTruth; + int i, k, iFan, clk = clock(); + int ClassCounts[222] = {0}; + int * pLutClass, Counter = 0; + assert( p->pMapping != NULL ); + if ( Gia_ManLutSizeMax( p ) > 4 ) + { + printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" ); + return NULL; + } + pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); + vLeaves = Vec_IntAlloc( 0 ); + vTruth = Vec_IntAlloc( (1<<16) ); + vVisited = Vec_IntAlloc( 0 ); + vLeavesBest = Vec_IntAlloc( 4 ); + // prepare the library + Dar_LibPrepare( 5 ); + // clean the old manager + Gia_ManCleanTruth( p ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + // start the new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + else if ( Gia_ObjIsLut(p, i) ) + { + Counter++; + // collect leaves of this gate + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, i, iFan, k ) + Vec_IntPush( vLeaves, iFan ); + for ( ; k < 4; k++ ) + Vec_IntPush( vLeaves, 0 ); + //.compute the truth table + pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited ); + // change from node IDs to their literals + Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) + { + assert( Gia_ObjValue(pFanin) != ~0 ); + Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) ); + } + // derive new structre + if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) ) + pObj->Value = 0; + else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) ) + pObj->Value = 1; + else + { + pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase ); + } + } + } + // cleanup the AIG + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + if ( Gia_ManHasDangling(pNew) ) + { + pNew = Gia_ManCleanup( pTemp = pNew ); + if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) ) + printf( "Gia_ManPerformMapShrink() node reduction after sweep %6d -> %6d.\n", Gia_ManAndNum(pTemp), Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + Vec_IntFree( vLeavesBest ); + if ( fVerbose ) + { + printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) ); + ABC_PRT( "Total runtime", clock() - clk ); + } + ABC_FREE( pLutClass ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index ae9e304c..68b50fb6 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -65,6 +68,28 @@ void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p ) p->TimeLimit = 60; // time limit in seconds p->fCheckMiter = 0; // check if miter outputs are non-zero p->fVerbose = 0; // enables verbose output + p->iOutFail = -1; // index of the failed output +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimDelete( Gia_ManSim_t * p ) +{ + Vec_IntFreeP( &p->vCis2Ids ); + Gia_ManStopP( &p->pAig ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pDataSimCis ); + ABC_FREE( p->pDataSimCos ); + ABC_FREE( p ); } /**Function************************************************************* @@ -90,10 +115,18 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) p->pDataSim = ABC_ALLOC( unsigned, p->nWords * p->pAig->nFront ); p->pDataSimCis = ABC_ALLOC( unsigned, p->nWords * Gia_ManCiNum(p->pAig) ); p->pDataSimCos = ABC_ALLOC( unsigned, p->nWords * Gia_ManCoNum(p->pAig) ); + if ( !p->pDataSim || !p->pDataSimCis || !p->pDataSimCos ) + { + Abc_Print( 1, "Simulator could not allocate %.2f Gb for simulation info.\n", + 4.0 * p->nWords * (p->pAig->nFront + Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig)) / (1<<30) ); + Gia_ManSimDelete( p ); + return NULL; + } p->vCis2Ids = Vec_IntAlloc( Gia_ManCiNum(p->pAig) ); Vec_IntForEachEntry( pAig->vCis, Entry, i ) Vec_IntPush( p->vCis2Ids, i ); // do we need p->vCis2Ids? - printf( "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n", + if ( pPars->fVerbose ) + Abc_Print( 1, "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n", 12.0*Gia_ManObjNum(p->pAig)/(1<<20), 4.0*p->nWords*p->pAig->nFront/(1<<20), 4.0*p->nWords*(Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig))/(1<<20) ); @@ -111,27 +144,6 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) SeeAlso [] ***********************************************************************/ -void Gia_ManSimDelete( Gia_ManSim_t * p ) -{ - Vec_IntFree( p->vCis2Ids ); - Gia_ManStop( p->pAig ); - ABC_FREE( p->pDataSim ); - ABC_FREE( p->pDataSimCis ); - ABC_FREE( p->pDataSimCos ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ static inline void Gia_ManSimInfoRandom( Gia_ManSim_t * p, unsigned * pInfo ) { int w; @@ -171,9 +183,9 @@ static inline void Gia_ManSimInfoZero( Gia_ManSim_t * p, unsigned * pInfo ) static inline int Gia_ManSimInfoIsZero( Gia_ManSim_t * p, unsigned * pInfo ) { int w; - for ( w = p->nWords-1; w >= 0; w-- ) + for ( w = 0; w < p->nWords; w++ ) if ( pInfo[w] ) - return 32*(w-1) + Gia_WordFindFirstBit( pInfo[w] ); + return 32*w + Gia_WordFindFirstBit( pInfo[w] ); return -1; } @@ -418,9 +430,9 @@ static inline int Gia_ManCheckPos( Gia_ManSim_t * p, int * piPo, int * piPat ) SeeAlso [] ***********************************************************************/ -Gia_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) +Abc_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) { - Gia_Cex_t * p; + Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; p = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); @@ -468,43 +480,44 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) for ( i = 0; i < pPars->nIters; i++ ) { Gia_ManSimulateRound( p ); - if ( pPars->fVerbose ) { - printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit ); - printf( "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC ); + Abc_Print( 1, "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit ); + Abc_Print( 1, "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC ); } if ( pPars->fCheckMiter && Gia_ManCheckPos( p, &iOut, &iPat ) ) { + pPars->iOutFail = iOut; pAig->pCexSeq = Gia_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids ); - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", iOut, i ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d was asserted in frame %d. ", iOut, i ); if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) { - printf( "\n" ); - printf( "Generated counter-example is INVALID \n" ); - printf( "\n" ); +// Abc_Print( 1, "\n" ); + Abc_Print( 1, "\nGenerated counter-example is INVALID. " ); +// Abc_Print( 1, "\n" ); } else { - printf( "\n" ); - printf( "Generated counter-example is fine \n" ); - printf( "\n" ); +// Abc_Print( 1, "\n" ); +// if ( pPars->fVerbose ) +// Abc_Print( 1, "\nGenerated counter-example is verified correctly. " ); +// Abc_Print( 1, "\n" ); } RetValue = 1; break; } if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) { - printf( "No bug detected after %d frames with time limit %d seconds. \n", i+1, pPars->TimeLimit ); + i++; break; } - if ( i < pPars->nIters - 1 ) Gia_ManSimInfoTransfer( p ); } Gia_ManSimDelete( p ); - printf( "Simulated %d frames with %d words. ", i, pPars->nWords ); - ABC_PRT( "Time", clock() - clkTotal ); + if ( pAig->pCexSeq == NULL ) + Abc_Print( 1, "No bug detected after simulating %d frames with %d words. ", i, pPars->nWords ); + Abc_PrintTime( 1, "Time", clock() - clkTotal ); return RetValue; } @@ -513,3 +526,5 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c index 8574297d..f73e92bb 100644 --- a/src/aig/gia/giaSort.c +++ b/src/aig/gia/giaSort.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -266,3 +269,5 @@ int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c new file mode 100644 index 00000000..cce0b68d --- /dev/null +++ b/src/aig/gia/giaSpeedup.c @@ -0,0 +1,810 @@ +/**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 "if.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sorts the pins in the decreasing order of delays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_LutDelayTraceSortPins( Gia_Man_t * p, int iObj, int * pPinPerm, float * pPinDelays ) +{ + int iFanin, i, j, best_i, temp; + assert( Gia_ObjIsLut(p, iObj) ); + // start the trivial permutation and collect pin delays + Gia_LutForEachFanin( p, iObj, iFanin, i ) + { + pPinPerm[i] = i; + pPinDelays[i] = Gia_ObjTimeArrival(p, iFanin); + } + // selection sort the pins in the decreasible order of delays + // this order will match the increasing order of LUT input pins + for ( i = 0; i < Gia_ObjLutSize(p, iObj)-1; i++ ) + { + best_i = i; + for ( j = i+1; j < Gia_ObjLutSize(p, iObj); j++ ) + if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] ) + best_i = j; + if ( best_i == i ) + continue; + temp = pPinPerm[i]; + pPinPerm[i] = pPinPerm[best_i]; + pPinPerm[best_i] = temp; + } + // verify + assert( Gia_ObjLutSize(p, iObj) == 0 || pPinPerm[0] < Gia_ObjLutSize(p, iObj) ); + for ( i = 1; i < Gia_ObjLutSize(p, iObj); i++ ) + { + assert( pPinPerm[i] < Gia_ObjLutSize(p, iObj) ); + assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] ); + } +} + +/**Function************************************************************* + + Synopsis [Sorts the pins in the decreasing order of delays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm ) +{ + int i; + for ( i = 0; i < Gia_ObjLutSize(p, iFanout); i++ ) + if ( Gia_ObjLutFanin(p, iFanout, pPinPerm[i]) == iFanin ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Computes the arrival times for the given object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + int k, iFanin, pPinPerm[32]; + float pPinDelays[32]; + float tArrival, * pDelays; + if ( Gia_ObjIsCi(pObj) ) + return Gia_ObjTimeArrival(p, iObj); + if ( Gia_ObjIsCo(pObj) ) + return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) ); + assert( Gia_ObjIsLut(p, iObj) ); + tArrival = -TIM_ETERNITY; + if ( pLutLib == NULL ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0; + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[0]; + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + if ( fUseSorting ) + { + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k] ) + tArrival = Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k]; + } + else + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[k] ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[k]; + } + } + if ( Gia_ObjLutSize(p, iObj) == 0 ) + tArrival = 0.0; + return tArrival; +} + + +/**Function************************************************************* + + Synopsis [Propagates the required times through the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int k, iFanin, pPinPerm[32]; + float pPinDelays[32]; + float tRequired = 0.0; // Suppress "might be used uninitialized" + float * pDelays; + assert( Gia_ObjIsLut(p, iObj) ); + if ( pLutLib == NULL ) + { + tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[0]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + if ( fUseSorting ) + { + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + tRequired = Gia_ObjTimeRequired( p, iObj) - pDelays[k]; + if ( Gia_ObjTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) > tRequired ) + Gia_ObjSetTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k]), tRequired ); + } + } + else + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[k]; + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + } + } + return tRequired; +} + +/**Function************************************************************* + + Synopsis [Computes the delay trace of the given network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManDelayTraceLut( Gia_Man_t * p ) +{ + int fUseSorting = 1; + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + Vec_Int_t * vObjs; + Gia_Obj_t * pObj; + float tArrival, tArrivalCur, tRequired, tSlack; + int i, iObj; + + // get the library + if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) ) + { + printf( "The max LUT size (%d) is less than the max fanin count (%d).\n", + pLutLib->LutMax, Gia_ManLutSizeMax(p) ); + return -TIM_ETERNITY; + } + + // initialize the arrival times + Gia_ManTimeStart( p ); + + // propagate arrival times + if ( p->pManTime ) + Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( !Gia_ObjIsCi(pObj) && !Gia_ObjIsCo(pObj) && !Gia_ObjIsLut(p, i) ) + continue; + tArrival = Gia_ObjComputeArrival( p, i, fUseSorting ); + if ( Gia_ObjIsCi(pObj) && p->pManTime ) + { + tArrival = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); +//printf( "%.3f ", tArrival ); + } + if ( Gia_ObjIsCo(pObj) && p->pManTime ) + Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), tArrival ); + Gia_ObjSetTimeArrival( p, i, tArrival ); + } + + // get the latest arrival times + tArrival = -TIM_ETERNITY; + Gia_ManForEachCo( p, pObj, i ) + { + tArrivalCur = Gia_ObjTimeArrivalObj( p, Gia_ObjFanin0(pObj) ); + Gia_ObjSetTimeArrival( p, Gia_ObjId(p,pObj), tArrivalCur ); + if ( tArrival < tArrivalCur ) + tArrival = tArrivalCur; + } + + // initialize the required times + if ( p->pManTime ) + { + Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); + Tim_ManSetCoRequiredAll( (Tim_Man_t *)p->pManTime, tArrival ); + } + else + { + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjSetTimeRequiredObj( p, pObj, tArrival ); + } + + // propagate the required times + vObjs = Gia_ManOrderReverse( p ); + Vec_IntForEachEntry( vObjs, iObj, i ) + { + if ( i == 1137 ) + { + int s = 0; + } + pObj = Gia_ManObj(p, iObj); +//printf( "%d ", Gia_ObjLevel(p, pObj) ); + if ( Gia_ObjIsLut(p, iObj) ) + { + Gia_ObjPropagateRequired( p, iObj, fUseSorting ); + } + else if ( Gia_ObjIsCi(pObj) ) + { + if ( p->pManTime ) + Tim_ManSetCiRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), Gia_ObjTimeRequired(p, iObj) ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + if ( p->pManTime ) + { + tRequired = Tim_ManGetCoRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); + Gia_ObjSetTimeRequired( p, iObj, tRequired ); + } + if ( Gia_ObjTimeRequired(p, Gia_ObjFaninId0p(p, pObj)) > Gia_ObjTimeRequired(p, iObj) ) + Gia_ObjSetTimeRequired(p, Gia_ObjFaninId0p(p, pObj), Gia_ObjTimeRequired(p, iObj) ); + } + + // set slack for this object + tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj); + assert( tSlack + 0.01 > 0.0 ); + Gia_ObjSetTimeSlack( p, iObj, tSlack < 0.0 ? 0.0 : tSlack ); + } + Vec_IntFree( vObjs ); + return tArrival; +} + +#if 0 + +/**Function************************************************************* + + Synopsis [Computes the required times for the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjComputeRequired( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = p->pLutLib; + int pPinPerm[32]; + float pPinDelays[32]; + Gia_Obj_t * pFanout; + float tRequired, tDelay, * pDelays; + int k, iFanin; + if ( Gia_ObjIsCo(iObj) ) + return Gia_ObjTimeRequired( p, iObj); + tRequired = TIM_ETERNITY; + if ( pLutLib == NULL ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : 1.0; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else if ( !pLutLib->fVarPinDelays ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[0]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else + { + if ( fUseSorting ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + Gia_LutDelayTraceSortPins( p, pFanout, pPinPerm, pPinDelays ); + iFanin = Gia_LutWhereIsPin( p, pFanout, iObj, pPinPerm ); + assert( Gia_ObjLutFanin( p, pFanout, pPinPerm[iFanin]) == iObj ); + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + iFanin = Gia_ObjFindFanin( p, pFanout, iObj ); + assert( Gia_ObjLutFanin(p, pFanout, iFanin) == iObj ); + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + } + return tRequired; +} + +/**Function************************************************************* + + Synopsis [Computes the arrival times for the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_LutVerifyTiming( Gia_Man_t * p ) +{ + int iObj; + float tArrival, tRequired; + int i; + Gia_LutForEachObj( p, iObj, i ) + { + if ( Gia_ObjIsCi(iObj) && Gia_ObjFanoutNum(iObj) == 0 ) + continue; + tArrival = Gia_ObjComputeArrival( p, iObj, 1 ); + tRequired = Gia_ObjComputeRequired( p, iObj, 1 ); + if ( !Gia_LutTimeEqual( tArrival, Gia_ObjTimeArrival( p, iObj), (float)0.01 ) ) + printf( "Gia_LutVerifyTiming(): Object %d has different arrival time (%.2f) from computed (%.2f).\n", + iObj->Id, Gia_ObjTimeArrival( p, iObj), tArrival ); + if ( !Gia_LutTimeEqual( tRequired, Gia_ObjTimeRequired( p, iObj), (float)0.01 ) ) + printf( "Gia_LutVerifyTiming(): Object %d has different required time (%.2f) from computed (%.2f).\n", + iObj->Id, Gia_ObjTimeRequired( p, iObj), tRequired ); + } + return 1; +} + +#endif + +/**Function************************************************************* + + Synopsis [Prints the delay trace for the given network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int i, Nodes, * pCounters; + float tArrival, tDelta, nSteps, Num; + // get the library + if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) ) + { + printf( "The max LUT size (%d) is less than the max fanin count (%d).\n", + pLutLib->LutMax, Gia_ManLutSizeMax(p) ); + return -ABC_INFINITY; + } + // decide how many steps + nSteps = pLutLib ? 20 : Gia_ManLutLevel(p); + pCounters = ABC_ALLOC( int, nSteps + 1 ); + memset( pCounters, 0, sizeof(int)*(nSteps + 1) ); + // perform delay trace + tArrival = Gia_ManDelayTraceLut( p ); + tDelta = tArrival / nSteps; + // count how many nodes have slack in the corresponding intervals + Gia_ManForEachLut( p, i ) + { + if ( Gia_ObjLutSize(p, i) == 0 ) + continue; + Num = Gia_ObjTimeSlack(p, i) / tDelta; + if ( Num > nSteps ) + continue; + assert( Num >=0 && Num <= nSteps ); + pCounters[(int)Num]++; + } + // print the results + if ( fVerbose ) + { + printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" ); + Nodes = 0; + for ( i = 0; i < nSteps; i++ ) + { + Nodes += pCounters[i]; + printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1, + pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) ); + } + } + ABC_FREE( pCounters ); + Gia_ManTimeStop( p ); + return tArrival; +} + +/**Function************************************************************* + + Synopsis [Determines timing-critical edges of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_LutDelayTraceTCEdges( Gia_Man_t * p, int iObj, float tDelta ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int pPinPerm[32]; + float pPinDelays[32]; + float tRequired, * pDelays; + unsigned uResult = 0; + int k, iFanin; + tRequired = Gia_ObjTimeRequired( p, iObj ); + if ( pLutLib == NULL ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + 1.0 + tDelta ) + uResult |= (1 << k); + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] + tDelta ) + uResult |= (1 << k); + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) + pDelays[k] + tDelta ) + uResult |= (1 << pPinPerm[k]); + } + return uResult; +} + +/**Function************************************************************* + + Synopsis [Adds strashed nodes for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSpeedupObj_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 1; + Gia_ObjSetTravIdCurrent( p, pObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) + return 0; + if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin1(pObj), vNodes ) ) + return 0; + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds strashed nodes for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSpeedupObj( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vTimes ) +{ + Vec_Int_t * vNodes; + Gia_Obj_t * pTemp = NULL; + int pCofs[32], nCofs, nSkip, i, k, iResult, iObj; + // mark the leaves + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + Gia_ManForEachObjVec( vLeaves, p, pTemp, i ) + Gia_ObjSetTravIdCurrent( p, pTemp ); + // collect the AIG nodes + vNodes = Vec_IntAlloc( 100 ); + if ( !Gia_ManSpeedupObj_rec( p, pObj, vNodes ) ) + { + printf( "Bad node!!!\n" ); + Vec_IntFree( vNodes ); + return; + } + // derive cofactors + nCofs = (1 << Vec_IntSize(vTimes)); + for ( i = 0; i < nCofs; i++ ) + { + Gia_ManForEachObjVec( vLeaves, p, pTemp, k ) + pTemp->Value = Gia_Var2Lit( Gia_ObjId(p, pTemp), 0 ); + Gia_ManForEachObjVec( vTimes, p, pTemp, k ) + pTemp->Value = ((i & (1<<k)) != 0); + Gia_ManForEachObjVec( vNodes, p, pTemp, k ) + pTemp->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pTemp), Gia_ObjFanin1Copy(pTemp) ); + pCofs[i] = pTemp->Value; + } + Vec_IntFree( vNodes ); + // collect the resulting tree + Gia_ManForEachObjVec( vTimes, p, pTemp, k ) + for ( nSkip = (1<<k), i = 0; i < nCofs; i += 2*nSkip ) + pCofs[i] = Gia_ManHashMux( pNew, Gia_ObjToLit(p,pTemp), pCofs[i+nSkip], pCofs[i] ); + // create choice node (pObj is repr and ppCofs[0] is new) + iObj = Gia_ObjId( p, pObj ); + iResult = Gia_Lit2Var( pCofs[0] ); + if ( iResult <= iObj ) + return; + Gia_ObjSetRepr( pNew, iResult, iObj ); + Gia_ObjSetNext( pNew, iResult, Gia_ObjNext(pNew, iObj) ); + Gia_ObjSetNext( pNew, iObj, iResult ); +} + +/**Function************************************************************* + + Synopsis [Adds choices to speed up the network by the given percentage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Vec_Int_t * vTimeCries, * vTimeFanins; + int iObj, iFanin, iFanin2, nNodesNew; + float tDelta, tArrival; + int i, k, k2, Counter, CounterRes, nTimeCris; + int fUseLutLib = (p->pLutLib != NULL); + void * pTempTim = NULL; + unsigned * puTCEdges; + assert( p->pMapping != NULL ); + if ( !fUseLutLib && p->pManTime ) + { + pTempTim = p->pManTime; + p->pManTime = Tim_ManDup( (Tim_Man_t *)pTempTim, 1 ); + } + // perform delay trace + tArrival = Gia_ManDelayTraceLut( p ); + tDelta = fUseLutLib ? tArrival*Percentage/100.0 : 1.0; + if ( fVerbose ) + { + printf( "Max delay = %.2f. Delta = %.2f. ", tArrival, tDelta ); + printf( "Using %s model. ", fUseLutLib ? "LUT library" : "unit-delay" ); + if ( fUseLutLib ) + printf( "Percentage = %d. ", Percentage ); + printf( "\n" ); + } + // mark the timing critical nodes and edges + puTCEdges = ABC_CALLOC( unsigned, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, iObj ) + { + if ( Gia_ObjTimeSlack(p, iObj) >= tDelta ) + continue; + puTCEdges[iObj] = Gia_LutDelayTraceTCEdges( p, iObj, tDelta ); + } + if ( fVerbose ) + { + Counter = CounterRes = 0; + Gia_ManForEachLut( p, iObj ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && Gia_ObjTimeSlack(p, iFanin) < tDelta ) + Counter++; + CounterRes += Gia_WordCountOnes( puTCEdges[iObj] ); + } + printf( "Edges: Total = %7d. 0-slack = %7d. Critical = %7d. Ratio = %4.2f\n", + Gia_ManLutFaninCount(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 ); + } + + // start the resulting network + pNew = Gia_ManDup( p ); + Gia_ManHashStart( pNew ); + nNodesNew = 1000 + 3 * Gia_ManObjNum(pNew); + pNew->pNexts = ABC_CALLOC( int, nNodesNew ); + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, nNodesNew ); + for ( i = 0; i < nNodesNew; i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + + // collect nodes to be used for resynthesis + Counter = CounterRes = 0; + vTimeCries = Vec_IntAlloc( 16 ); + vTimeFanins = Vec_IntAlloc( 16 ); + Gia_ManForEachLut( p, iObj ) + { + if ( Gia_ObjTimeSlack(p, iObj) >= tDelta ) + continue; + // count the number of non-PI timing-critical nodes + nTimeCris = 0; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) ) + nTimeCris++; + if ( !fVeryVerbose && nTimeCris == 0 ) + continue; + Counter++; + // count the total number of timing critical second-generation nodes + Vec_IntClear( vTimeCries ); + if ( nTimeCris ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) ) + Gia_LutForEachFanin( p, iFanin, iFanin2, k2 ) + if ( puTCEdges[iFanin] & (1<<k2) ) + Vec_IntPushUnique( vTimeCries, iFanin2 ); + } +// if ( !fVeryVerbose && (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) ) + if ( (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) ) + continue; + CounterRes++; + // collect second generation nodes + Vec_IntClear( vTimeFanins ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + if ( Gia_ObjIsCi(Gia_ManObj(p, iFanin)) ) + Vec_IntPushUnique( vTimeFanins, iFanin ); + else + Gia_LutForEachFanin( p, iFanin, iFanin2, k2 ) + Vec_IntPushUnique( vTimeFanins, iFanin2 ); + } + // print the results + if ( fVeryVerbose ) + { + printf( "%5d Node %5d : %d %2d %2d ", Counter, iObj, + nTimeCris, Vec_IntSize(vTimeCries), Vec_IntSize(vTimeFanins) ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + printf( "%d(%.2f)%s ", iFanin, Gia_ObjTimeSlack(p, iFanin), (puTCEdges[iObj] & (1<<k))? "*":"" ); + printf( "\n" ); + } + // add the node to choices + if ( Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree ) + continue; + // order the fanins in the increasing order of criticalily + if ( Vec_IntSize(vTimeCries) > 1 ) + { + iFanin = Vec_IntEntry( vTimeCries, 0 ); + iFanin2 = Vec_IntEntry( vTimeCries, 1 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 0, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 1, iFanin ); + } + } + if ( Vec_IntSize(vTimeCries) > 2 ) + { + iFanin = Vec_IntEntry( vTimeCries, 1 ); + iFanin2 = Vec_IntEntry( vTimeCries, 2 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 1, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 2, iFanin ); + } + iFanin = Vec_IntEntry( vTimeCries, 0 ); + iFanin2 = Vec_IntEntry( vTimeCries, 1 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 0, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 1, iFanin ); + } + } + // add choice + Gia_ManSpeedupObj( pNew, p, Gia_ManObj(p,iObj), vTimeFanins, vTimeCries ); + // quit if the number of nodes is large + if ( Gia_ManObjNum(pNew) > nNodesNew - 100 ) + { + printf( "Speedup stopped adding choices because there was too many to add.\n" ); + break; + } + } + Gia_ManTimeStop( p ); + Vec_IntFree( vTimeCries ); + Vec_IntFree( vTimeFanins ); + ABC_FREE( puTCEdges ); + if ( fVerbose ) + printf( "Nodes: Total = %7d. 0-slack = %7d. Workable = %7d. Ratio = %4.2f\n", + Gia_ManLutNum(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 ); + if ( pTempTim ) + { + Tim_ManStop( (Tim_Man_t *)p->pManTime ); + p->pManTime = pTempTim; + } + // derive AIG with choices +//Gia_ManPrintStats( pNew, 0 ); + pTemp = Gia_ManEquivToChoices( pNew, 1 ); + Gia_ManStop( pNew ); +//Gia_ManPrintStats( pTemp, 0 ); +// pNew = Gia_ManDupOrderDfsChoices( pTemp ); +// Gia_ManStop( pTemp ); +//Gia_ManPrintStats( pNew, 0 ); +// return pNew; + return pTemp; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSupMin.c b/src/aig/gia/giaSupMin.c new file mode 100644 index 00000000..4abaab0f --- /dev/null +++ b/src/aig/gia/giaSupMin.c @@ -0,0 +1,165 @@ +/**CFile**************************************************************** + + FileName [giaSupMin.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Support minimization for AIGs with don't-cares.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSupMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "kit.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// decomposition manager +typedef struct Gia_ManSup_t_ Gia_ManSup_t; +struct Gia_ManSup_t_ +{ + int nVarsMax; // the max number of variables + int nWordsMax; // the max number of words + Vec_Ptr_t * vTruthVars; // elementary truth tables + Vec_Ptr_t * vTruthNodes; // internal truth tables + // current problem + Gia_Man_t * pGia; + int iData; + int iCare; + Vec_Int_t * vConeCare; + Vec_Int_t * vConeData; + unsigned * pTruthIn; + unsigned * pTruthOut; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManSup_t * Gia_ManSupStart( int nVarsMax ) +{ + Gia_ManSup_t * p; + assert( nVarsMax <= 20 ); + p = ABC_CALLOC( Gia_ManSup_t, 1 ); + p->nVarsMax = nVarsMax; + p->nWordsMax = Kit_TruthWordNum( p->nVarsMax ); + p->vTruthVars = Vec_PtrAllocTruthTables( p->nVarsMax ); + p->vTruthNodes = Vec_PtrAllocSimInfo( 512, p->nWordsMax ); + p->vConeCare = Vec_IntAlloc( 512 ); + p->vConeData = Vec_IntAlloc( 512 ); + p->pTruthIn = ABC_ALLOC( unsigned, p->nWordsMax ); + p->pTruthOut = ABC_ALLOC( unsigned, p->nWordsMax ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupStop( Gia_ManSup_t * p ) +{ + ABC_FREE( p->pTruthIn ); + ABC_FREE( p->pTruthOut ); + Vec_IntFreeP( &p->vConeCare ); + Vec_IntFreeP( &p->vConeData ); + Vec_PtrFreeP( &p->vTruthVars ); + Vec_PtrFreeP( &p->vTruthNodes ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupExperimentOne( Gia_ManSup_t * p, Gia_Obj_t * pData, Gia_Obj_t * pCare ) +{ + int iData = Gia_ObjId( p->pGia, Gia_Regular(pData) ); + int iCare = Gia_ObjId( p->pGia, Gia_Regular(pCare) ); + if ( !Gia_ObjIsAnd(Gia_Regular(pCare)) ) + { + Abc_Print( 1, "Enable is not an AND.\n" ); + return; + } + Abc_Print( 1, "DataSupp = %6d. DataCone = %6d. CareSupp = %6d. CareCone = %6d.", + Gia_ManSuppSize( p->pGia, &iData, 1 ), + Gia_ManConeSize( p->pGia, &iData, 1 ), + Gia_ManSuppSize( p->pGia, &iCare, 1 ), + Gia_ManConeSize( p->pGia, &iCare, 1 ) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupExperiment( Gia_Man_t * pGia, Vec_Int_t * vPairs ) +{ + Gia_ManSup_t * p; + Gia_Obj_t * pData, * pCare; + int i; + p = Gia_ManSupStart( 16 ); + p->pGia = pGia; + assert( Vec_IntSize(vPairs) % 2 == 0 ); + for ( i = 0; i < Vec_IntSize(vPairs)/2; i++ ) + { + Abc_Print( 1, "%6d : ", i ); + pData = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+0) ); + pCare = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+1) ); + Gia_ManSupExperimentOne( p, Gia_ObjChild0(pData), Gia_ObjChild0(pCare) ); + } + Gia_ManSupStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c index 5dac1fbc..bc2f0f67 100644 --- a/src/aig/gia/giaSwitch.c +++ b/src/aig/gia/giaSwitch.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "giaAig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -597,6 +601,13 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) { Gia_ManForEachObj( pAig, pObj, i ) pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); + Gia_ManForEachCo( pAig, pObj, i ) + { + if ( Gia_ObjFaninC0(pObj) ) + pSwitching[Gia_ObjId(pAig,pObj)] = (float)1.0-pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))]; + else + pSwitching[Gia_ObjId(pAig,pObj)] = pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))]; + } } else if ( pPars->fProbTrans ) { @@ -608,6 +619,27 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) Gia_ManForEachObj( pAig, pObj, i ) pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); } +/* + printf( "PI: " ); + Gia_ManForEachPi( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "LO: " ); + Gia_ManForEachRo( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "PO: " ); + Gia_ManForEachPo( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "LI: " ); + Gia_ManForEachRi( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); +*/ Gia_ManSwiDelete( p ); return vSwitching; @@ -625,7 +657,6 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); Gia_ParSwi_t Pars, * pPars = &Pars; Vec_Int_t * vSwitching, * vResult; Gia_Man_t * p; @@ -658,7 +689,11 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref // transfer the computed result to the original AIG vResult = Vec_IntStart( Aig_ManObjNumMax(pAig) ); Aig_ManForEachObj( pAig, pObj, i ) + { +// if ( Aig_ObjIsPo(pObj) ) +// printf( "%d=%f\n", i, Aig_Int2Float( Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ) ); Vec_IntWriteEntry( vResult, i, Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ); + } // delete intermediate results Vec_IntFree( vSwitching ); Gia_ManStop( p ); @@ -757,3 +792,5 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaTsim.c b/src/aig/gia/giaTsim.c index a4cdf88a..e829ff5b 100644 --- a/src/aig/gia/giaTsim.c +++ b/src/aig/gia/giaTsim.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -111,7 +114,7 @@ void Gia_ManTerStatesFree( Vec_Ptr_t * vStates ) { unsigned * pTemp; int i; - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) ABC_FREE( pTemp ); Vec_PtrFree( vStates ); } @@ -505,12 +508,12 @@ void Gia_ManTerStatePrint( unsigned * pState, int nRegs, int iNum ) ***********************************************************************/ void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs ) { - unsigned * pTemp, * pStates = Vec_PtrPop( vStates ); + unsigned * pTemp, * pStates = (unsigned *)Vec_PtrPop( vStates ); int i, w, nZeros, nConsts, nStateWords; // detect constant zero registers nStateWords = Gia_BitWordNum( 2*nRegs ); memset( pStates, 0, sizeof(int) * nStateWords ); - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) for ( w = 0; w < nStateWords; w++ ) pStates[w] |= pTemp[w]; // count the number of zeros @@ -521,7 +524,7 @@ void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs ) printf( "Found %d constant registers.\n", nZeros ); // detect non-ternary registers memset( pStates, 0, sizeof(int) * nStateWords ); - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) for ( w = 0; w < nStateWords; w++ ) pStates[w] |= (~(pTemp[w] ^ (pTemp[w] >> 1)) & 0x55555555); // count the nonternary registers @@ -585,7 +588,7 @@ Vec_Ptr_t * Gia_ManTerTranspose( Gia_ManTer_t * p ) continue; pFlop = Gia_ManTerStateAlloc( nFlopWords ); Vec_PtrPush( vFlops, pFlop ); - Vec_PtrForEachEntry( p->vStates, pState, k ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k ) Gia_ManTerSimInfoSet( pFlop, k, Gia_ManTerSimInfoGet(pState, i) ); //Gia_ManTerStatePrint( pFlop, Vec_PtrSize(p->vStates), i ); } @@ -607,8 +610,8 @@ int Gia_ManFindEqualFlop( Vec_Ptr_t * vFlops, int iFlop, int nFlopWords ) { unsigned * pFlop, * pTemp; int i; - pFlop = Vec_PtrEntry( vFlops, iFlop ); - Vec_PtrForEachEntryStop( vFlops, pTemp, i, iFlop ) + pFlop = (unsigned *)Vec_PtrEntry( vFlops, iFlop ); + Vec_PtrForEachEntryStop( unsigned *, vFlops, pTemp, i, iFlop ) if ( !memcmp( pTemp, pFlop, sizeof(unsigned) * nFlopWords ) ) return i; return -1; @@ -633,7 +636,7 @@ int * Gia_ManTerCreateMap( Gia_ManTer_t * p, int fVerbose ) int i, iRepr, nFlopWords, Counter0 = 0, CounterE = 0; nFlopWords = Gia_BitWordNum( 2*Vec_PtrSize(p->vStates) ); p->vFlops = Gia_ManTerTranspose( p ); - pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p->pAig) ); + pCi2Lit = ABC_FALLOC( int, Gia_ManCiNum(p->pAig) ); vMapKtoI = Vec_IntAlloc( 100 ); for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) if ( p->pCount0[i] == Vec_PtrSize(p->vStates) ) @@ -678,8 +681,7 @@ Gia_ManTer_t * Gia_ManTerSimulate( Gia_Man_t * pAig, int fVerbose ) if ( 0 ) { printf( "Obj = %8d (%8d). F = %6d. ", - pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront, - 4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20) ); + pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront ); printf( "AIG = %7.2f Mb. F-mem = %7.2f Mb. Other = %7.2f Mb. ", 12.0*Gia_ManObjNum(p->pAig)/(1<<20), 4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20), @@ -754,3 +756,5 @@ Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 938c6363..002e766d 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -72,7 +75,7 @@ void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int { unsigned * pInfo; int i, w; - Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart ) + Vec_PtrForEachEntryStart( unsigned *, vInfo, pInfo, i, iInputStart ) for ( w = iWordStart; w < iWordStop; w++ ) pInfo[w] = Gia_ManRandom(0); } @@ -116,6 +119,30 @@ unsigned int Gia_PrimeCudd( unsigned int p ) /**Function************************************************************* + Synopsis [Returns the time stamp.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_TimeStamp() +{ + 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 the composite name of the file.] Description [] @@ -140,6 +167,34 @@ char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix ) /**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManIncrementTravId( Gia_Man_t * p ) +{ + if ( p->pTravIds == NULL ) + { + p->nTravIdsAlloc = Gia_ManObjNum(p) + 100; + p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc ); + p->nTravIds = 0; + } + while ( p->nTravIdsAlloc < Gia_ManObjNum(p) ) + { + p->nTravIdsAlloc *= 2; + p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc ); + memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 ); + } + p->nTravIds++; +} + +/**Function************************************************************* + Synopsis [Sets phases of the internal nodes.] Description [] @@ -290,6 +345,28 @@ void Gia_ManFillValue( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Sets the phase of one object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjSetPhase( Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsAnd(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj)); + else if ( Gia_ObjIsCo(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)); + else + pObj->fPhase = 0; +} + +/**Function************************************************************* + Synopsis [Sets phases of the internal nodes.] Description [] @@ -304,15 +381,29 @@ void Gia_ManSetPhase( Gia_Man_t * p ) Gia_Obj_t * pObj; int i; Gia_ManForEachObj( p, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj)); - else if ( Gia_ObjIsCo(pObj) ) - pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)); - else - pObj->fPhase = 0; - } + Gia_ObjSetPhase( pObj ); +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetPhase1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachCi( p, pObj, i ) + pObj->fPhase = 1; + Gia_ManForEachObj( p, pObj, i ) + if ( !Gia_ObjIsCi(pObj) ) + Gia_ObjSetPhase( pObj ); } /**Function************************************************************* @@ -336,6 +427,41 @@ void Gia_ManCleanPhase( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Prepares copies for the model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanLevels( Gia_Man_t * p, int Size ) +{ + if ( p->vLevels == NULL ) + p->vLevels = Vec_IntAlloc( Size ); + Vec_IntFill( p->vLevels, Size, 0 ); +} +/**Function************************************************************* + + Synopsis [Prepares copies for the model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanTruth( Gia_Man_t * p ) +{ + if ( p->vTruths == NULL ) + p->vTruths = Vec_IntAlloc( Gia_ManObjNum(p) ); + Vec_IntFill( p->vTruths, Gia_ManObjNum(p), -1 ); +} + +/**Function************************************************************* + Synopsis [Assigns levels.] Description [] @@ -349,24 +475,18 @@ int Gia_ManLevelNum( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; - if ( p->pLevels ) - return p->nLevels; + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); p->nLevels = 0; - p->pLevels = ABC_ALLOC( int, p->nObjsAlloc ); Gia_ManForEachObj( p, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjSetAndLevel( p, pObj ); + else if ( Gia_ObjIsCo(pObj) ) { - if ( p->pLevels[Gia_ObjFaninId0(pObj, i)] > p->pLevels[Gia_ObjFaninId1(pObj, i)] ) - p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId0(pObj, i)]; - else - p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId1(pObj, i)]; - if ( p->nLevels < p->pLevels[i] ) - p->nLevels = p->pLevels[i]; + Gia_ObjSetCoLevel( p, pObj ); + p->nLevels = ABC_MAX( p->nLevels, Gia_ObjLevel(p, pObj) ); } - else if ( Gia_ObjIsCo(pObj) ) - p->pLevels[i] = p->pLevels[Gia_ObjFaninId0(pObj, i)]; else - p->pLevels[i] = 0; + Gia_ObjSetLevel( p, pObj, 0 ); return p->nLevels; } @@ -718,18 +838,93 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob SeeAlso [] ***********************************************************************/ -Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) +Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) { - Gia_Cex_t * pCex; + Abc_Cex_t * pCex; int nWords = Gia_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Gia_Cex_t *)ABC_ALLOC( char, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords ); + pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); pCex->nRegs = nRegs; pCex->nPis = nRealPis; pCex->nBits = nRegs + nRealPis * nFrames; return pCex; } + +/**Function************************************************************* + + Synopsis [Prints the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintCex( Abc_Cex_t * p ) +{ + int i, f, k; + for ( k = 0; k < p->nRegs; k++ ) + printf( "%d", Gia_InfoHasBit(p->pData, k) ); + printf( "\n" ); + for ( f = 0; f <= p->iFrame; f++ ) + { + for ( i = 0; i < p->nPis; i++ ) + printf( "%d", Gia_InfoHasBit(p->pData, k++) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Derives the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); + assert( Vec_IntSize(vValues) == nSkip + pCex->nBits ); + pCex->iPo = 0; + pCex->iFrame = iFrame; + for ( i = 0; i < pCex->nBits; i++ ) + if ( Vec_IntEntry(vValues, nSkip + i) ) + Gia_InfoSetBit( pCex->pData, i ); + return pCex; +} + +/**Function************************************************************* + + Synopsis [Allocates a counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( nRegs, nRealPis, 1 ); + pCex->iPo = iPo; + pCex->iFrame = 0; + for ( i = pCex->nRegs; i < pCex->nBits; i++ ) + if ( pModel[i-pCex->nRegs] ) + Gia_InfoSetBit( pCex->pData, i ); + return pCex; +} + /**Function************************************************************* Synopsis [Resimulates the counter-example.] @@ -741,10 +936,11 @@ Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) SeeAlso [] ***********************************************************************/ -int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) +int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ) { Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); for ( i = 0; i <= p->iFrame; i++ ) @@ -770,6 +966,73 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) /**Function************************************************************* + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManVerifyCounterExampleAllOuts( Gia_Man_t * pAig, Abc_Cex_t * p ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + // remember the number of failed output + RetValue = -1; + Gia_ManForEachPo( pAig, pObj, i ) + if ( Gia_ManPo(pAig, i)->fMark0 ) + { + RetValue = i; + break; + } + Gia_ManCleanMark0(pAig); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Make the trivial counter-example for the trivially asserted output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); + pCex->iPo = p->iPo; + pCex->iFrame = p->iFrame; + for ( i = p->nRegs; i < p->nBits; i++ ) + if ( Gia_InfoHasBit(p->pData, i) ) + Gia_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); + return pCex; +} + +/**Function************************************************************* + Synopsis [Prints out the counter-example.] Description [] @@ -779,7 +1042,7 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) SeeAlso [] ***********************************************************************/ -void Gia_ManPrintCounterExample( Gia_Cex_t * p ) +void Gia_ManPrintCounterExample( Abc_Cex_t * p ) { int i, f, k; printf( "Counter-example: iPo = %d iFrame = %d nRegs = %d nPis = %d nBits = %d\n", @@ -979,7 +1242,7 @@ int Gia_ManHasChoices( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Gia_ManHasDandling( Gia_Man_t * p ) +int Gia_ManHasDangling( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i, Counter = 0; @@ -1000,8 +1263,115 @@ int Gia_ManHasDandling( Gia_Man_t * p ) return Counter; } +/**Function************************************************************* + + Synopsis [Returns 1 if AIG has dangling nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ) +{ + Vec_Int_t * vDangles; + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fMark0 = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + vDangles = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( p, pObj, i ) + if ( !pObj->fMark0 ) + Vec_IntPush( vDangles, i ); + Gia_ManCleanMark0( p ); + return vDangles; +} +/**Function************************************************************* + + Synopsis [Verbose printing of the AIG node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( pObj == NULL ) + { + printf( "Object is NULL." ); + return; + } + if ( Gia_IsComplement(pObj) ) + { + printf( "Compl " ); + pObj = Gia_Not(pObj); + } + assert( !Gia_IsComplement(pObj) ); + printf( "Node %4d : ", Gia_ObjId(p, pObj) ); + if ( Gia_ObjIsConst0(pObj) ) + printf( "constant 0" ); + else if ( Gia_ObjIsPi(p, pObj) ) + printf( "PI" ); + else if ( Gia_ObjIsPo(p, pObj) ) + printf( "PO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); + else if ( Gia_ObjIsCi(pObj) ) + printf( "RI" ); + else if ( Gia_ObjIsCo(pObj) ) + printf( "RO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); +// else if ( Gia_ObjIsBuf(pObj) ) +// printf( "BUF( %d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); + else + printf( "AND( %4d%s, %4d%s )", + Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " "), + Gia_ObjFaninId1p(p, pObj), (Gia_ObjFaninC1(pObj)? "\'" : " ") ); + if ( p->pRefs ) + printf( " (refs = %3d)", Gia_ObjRefs(p, pObj) ); + printf( "\n" ); +/* + if ( p->pRefs ) + { + Gia_Obj_t * pFanout; + int i; + int iFan = -1; // Suppress "might be used uninitialized" + printf( "\nFanouts:\n" ); + Gia_ObjForEachFanout( p, pObj, pFanout, iFan, i ) + { + printf( " " ); + printf( "Node %4d : ", Gia_ObjId(pFanout) ); + if ( Gia_ObjIsPo(pFanout) ) + printf( "PO( %4d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") ); + else if ( Gia_ObjIsBuf(pFanout) ) + printf( "BUF( %d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") ); + else + printf( "AND( %4d%s, %4d%s )", + Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " "), + Gia_ObjFanin1(pFanout)->Id, (Gia_ObjFaninC1(pFanout)? "\'" : " ") ); + printf( "\n" ); + } + return; + } +*/ +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 0245b0f1..fc1c5c73 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -2,6 +2,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaAbs.c \ src/aig/gia/giaAig.c \ src/aig/gia/giaAiger.c \ + src/aig/gia/giaBidec.c \ src/aig/gia/giaCof.c \ src/aig/gia/giaCSatOld.c \ src/aig/gia/giaCSat.c \ @@ -19,13 +20,18 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaFront.c \ src/aig/gia/giaGlitch.c \ src/aig/gia/giaHash.c \ + src/aig/gia/giaIf.c \ src/aig/gia/giaMan.c \ - src/aig/gia/giaMap.c \ + src/aig/gia/giaMem.c \ src/aig/gia/giaPat.c \ + src/aig/gia/giaReparam.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaScl.c \ + src/aig/gia/giaShrink.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSort.c \ + src/aig/gia/giaSpeedup.c \ + src/aig/gia/giaSupMin.c \ src/aig/gia/giaSwitch.c \ src/aig/gia/giaTsim.c \ src/aig/gia/giaUtil.c |