diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2009-02-15 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2009-02-15 08:01:00 -0800 |
commit | 0871bffae307e0553e0c5186336189e8b55cf6a6 (patch) | |
tree | 4571d1563fe33a53a57fea1c35fb668b9d33265f /src/aig/gia | |
parent | f936cc0680c98ffe51b3a1716c996072d5dbf76c (diff) | |
download | abc-0871bffae307e0553e0c5186336189e8b55cf6a6.tar.gz abc-0871bffae307e0553e0c5186336189e8b55cf6a6.tar.bz2 abc-0871bffae307e0553e0c5186336189e8b55cf6a6.zip |
Version abc90215
Diffstat (limited to 'src/aig/gia')
-rw-r--r-- | src/aig/gia/gia.c | 47 | ||||
-rw-r--r-- | src/aig/gia/gia.h | 423 | ||||
-rw-r--r-- | src/aig/gia/giaAig.c | 214 | ||||
-rw-r--r-- | src/aig/gia/giaAiger.c | 553 | ||||
-rw-r--r-- | src/aig/gia/giaCof.c | 688 | ||||
-rw-r--r-- | src/aig/gia/giaConstr.c | 47 | ||||
-rw-r--r-- | src/aig/gia/giaDfs.c | 243 | ||||
-rw-r--r-- | src/aig/gia/giaDup.c | 698 | ||||
-rw-r--r-- | src/aig/gia/giaFanout.c | 197 | ||||
-rw-r--r-- | src/aig/gia/giaForce.c | 164 | ||||
-rw-r--r-- | src/aig/gia/giaFrames.c | 346 | ||||
-rw-r--r-- | src/aig/gia/giaFront.c | 248 | ||||
-rw-r--r-- | src/aig/gia/giaGlitch.c | 743 | ||||
-rw-r--r-- | src/aig/gia/giaHash.c | 541 | ||||
-rw-r--r-- | src/aig/gia/giaLogic.c | 725 | ||||
-rw-r--r-- | src/aig/gia/giaMan.c | 203 | ||||
-rw-r--r-- | src/aig/gia/giaProp.c | 171 | ||||
-rw-r--r-- | src/aig/gia/giaSat.c | 421 | ||||
-rw-r--r-- | src/aig/gia/giaScl.c | 240 | ||||
-rw-r--r-- | src/aig/gia/giaSim.c | 437 | ||||
-rw-r--r-- | src/aig/gia/giaSolver.c | 490 | ||||
-rw-r--r-- | src/aig/gia/giaSolver_cnf.c | 103 | ||||
-rw-r--r-- | src/aig/gia/giaSwitch.c | 673 | ||||
-rw-r--r-- | src/aig/gia/giaTsim.c | 708 | ||||
-rw-r--r-- | src/aig/gia/giaUtil.c | 518 | ||||
-rw-r--r-- | src/aig/gia/module.make | 19 |
26 files changed, 9860 insertions, 0 deletions
diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c new file mode 100644 index 00000000..4cbb1731 --- /dev/null +++ b/src/aig/gia/gia.c @@ -0,0 +1,47 @@ +/**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" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h new file mode 100644 index 00000000..721056de --- /dev/null +++ b/src/aig/gia/gia.h @@ -0,0 +1,423 @@ +/**CFile**************************************************************** + + FileName [gia.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: gia.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __GIA_H__ +#define __GIA_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif + +#define GIA_NONE 0x1FFFFFFF + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_Obj_t_ Gia_Obj_t; +struct Gia_Obj_t_ +{ + unsigned iDiff0 : 29; // the diff of the first fanin + unsigned fCompl0: 1; // the complemented attribute + unsigned fMark0 : 1; // first user-controlled mark + unsigned fTerm : 1; // terminal node (CI/CO) + + unsigned iDiff1 : 29; // the diff of the second fanin + unsigned fCompl1: 1; // the complemented attribute + unsigned fMark1 : 1; // second user-controlled mark + unsigned fPhase : 1; // value under 000 pattern + + unsigned Value; // application-specific value +}; + +typedef struct Gia_Man_t_ Gia_Man_t; +struct Gia_Man_t_ +{ + char * pName; // name of the AIG + int nRegs; // number of registers + int nRegsAlloc; // number of allocated registers + int nObjs; // number of objects + int nObjsAlloc; // number of allocated objects + Gia_Obj_t * pObjs; // the array of objects + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) + int * pHTable; // hash table + int nHTable; // hash table size + int fAddStrash; // performs additional structural hashing + int * pRefs; // the reference count + int * pLevels; // levels of the nodes + int nLevels; // the mamixum level + int nTravIds; // the current traversal ID + int nFront; // frontier size + int * pReprs; // representatives (for CIs and ANDs) + int nTerLoop; // the state where loop begins + int nTerStates; // the total number of ternary states + int * pFanData; // the database to store fanout information + int nFansAlloc; // the size of fanout representation +}; + + + + +// frames parameters +typedef struct Gia_ParFra_t_ Gia_ParFra_t; +struct Gia_ParFra_t_ +{ + int nFrames; // the number of frames to unroll + int fInit; // initialize the timeframes + int fVerbose; // enables verbose output +}; + + + +// simulation parameters +typedef struct Gia_ParSim_t_ Gia_ParSim_t; +struct Gia_ParSim_t_ +{ + // user-controlled parameters + int nWords; // the number of machine words + int nIters; // the number of timeframes + int TimeLimit; // time limit in seconds + int fCheckMiter; // check if miter outputs are non-zero + int fVerbose; // enables verbose 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_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } +static inline int Gia_Lit2Var( int Lit ) { return Lit >> 1; } +static inline int Gia_LitIsCompl( int Lit ) { return Lit & 1; } +static inline int Gia_LitNot( int Lit ) { return Lit ^ 1; } +static inline int Gia_LitNotCond( int Lit, int c ) { return Lit ^ (int)(c > 0); } +static inline int Gia_LitRegular( int Lit ) { return Lit & ~01; } + +static inline Gia_Obj_t * Gia_Regular( Gia_Obj_t * p ) { return (Gia_Obj_t *)((ABC_PTRUINT_T)(p) & ~01); } +static inline Gia_Obj_t * Gia_Not( Gia_Obj_t * p ) { return (Gia_Obj_t *)((ABC_PTRUINT_T)(p) ^ 01); } +static inline Gia_Obj_t * Gia_NotCond( Gia_Obj_t * p, int c ) { return (Gia_Obj_t *)((ABC_PTRUINT_T)(p) ^ (c)); } +static inline int Gia_IsComplement( Gia_Obj_t * p ) { return (int)((ABC_PTRUINT_T)(p) & 01); } + +static inline int Gia_ManCiNum( Gia_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Gia_ManCoNum( Gia_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Gia_ManPiNum( Gia_Man_t * p ) { return Vec_IntSize(p->vCis) - p->nRegs; } +static inline int Gia_ManPoNum( Gia_Man_t * p ) { return Vec_IntSize(p->vCos) - p->nRegs; } +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 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)); } +static inline Gia_Obj_t * Gia_ManObj( Gia_Man_t * p, int v ) { assert( v < p->nObjs ); return p->pObjs + v; } +static inline Gia_Obj_t * Gia_ManCi( Gia_Man_t * p, int v ) { return Gia_ManObj( p, Vec_IntEntry(p->vCis,v) ); } +static inline Gia_Obj_t * Gia_ManCo( Gia_Man_t * p, int v ) { return Gia_ManObj( p, Vec_IntEntry(p->vCos,v) ); } +static inline Gia_Obj_t * Gia_ManPi( Gia_Man_t * p, int v ) { assert( v < Gia_ManPiNum(p) ); return Gia_ManCi( p, v ); } +static inline Gia_Obj_t * Gia_ManPo( Gia_Man_t * p, int v ) { assert( v < Gia_ManPoNum(p) ); return Gia_ManCo( p, v ); } +static inline Gia_Obj_t * Gia_ManRo( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCi( p, Gia_ManRegNum(p)+v ); } +static inline Gia_Obj_t * Gia_ManRi( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCo( p, Gia_ManRegNum(p)+v ); } + +static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; } +static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; } +static inline int Gia_ObjIsCi( Gia_Obj_t * pObj ) { return pObj->fTerm && pObj->iDiff0 == GIA_NONE; } +static inline int Gia_ObjIsCo( Gia_Obj_t * pObj ) { return pObj->fTerm && pObj->iDiff0 != GIA_NONE; } +static inline int Gia_ObjIsAnd( Gia_Obj_t * pObj ) { return!pObj->fTerm && pObj->iDiff0 != GIA_NONE; } +static inline int Gia_ObjIsConst0( Gia_Obj_t * pObj ) { return pObj->iDiff0 == GIA_NONE && pObj->iDiff1 == GIA_NONE; } +static inline int Gia_ManObjIsConst0( Gia_Man_t * p, Gia_Obj_t * pObj){ return pObj == p->pObjs; } + +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_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); } + +static inline int Gia_ObjIsPi( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCi(pObj) && Gia_ObjCioId(pObj) < Gia_ManPiNum(p); } +static inline int Gia_ObjIsPo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCo(pObj) && Gia_ObjCioId(pObj) < Gia_ManPoNum(p); } +static inline int Gia_ObjIsRo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCi(pObj) && Gia_ObjCioId(pObj) >= Gia_ManPiNum(p); } +static inline int Gia_ObjIsRi( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjIsCo(pObj) && Gia_ObjCioId(pObj) >= Gia_ManPoNum(p); } + +static inline Gia_Obj_t * Gia_ObjRoToRi( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsRo(p, pObj) ); return Gia_ManCo(p, Gia_ManCoNum(p) - Gia_ManCiNum(p) + Gia_ObjCioId(pObj)); } +static inline Gia_Obj_t * Gia_ObjRiToRo( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsRi(p, pObj) ); return Gia_ManCi(p, Gia_ManCiNum(p) - Gia_ManCoNum(p) + Gia_ObjCioId(pObj)); } + +static inline int Gia_ObjDiff0( Gia_Obj_t * pObj ) { return pObj->iDiff0; } +static inline int Gia_ObjDiff1( Gia_Obj_t * pObj ) { return pObj->iDiff1; } +static inline int Gia_ObjFaninC0( Gia_Obj_t * pObj ) { return pObj->fCompl0; } +static inline int Gia_ObjFaninC1( Gia_Obj_t * pObj ) { return pObj->fCompl1; } +static inline Gia_Obj_t * Gia_ObjFanin0( Gia_Obj_t * pObj ) { return pObj - pObj->iDiff0; } +static inline Gia_Obj_t * Gia_ObjFanin1( Gia_Obj_t * pObj ) { return pObj - pObj->iDiff1; } +static inline Gia_Obj_t * Gia_ObjChild0( Gia_Obj_t * pObj ) { return Gia_NotCond( Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj) ); } +static inline Gia_Obj_t * Gia_ObjChild1( Gia_Obj_t * pObj ) { return Gia_NotCond( Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFaninId0( Gia_Obj_t * pObj, int ObjId ) { return ObjId - pObj->iDiff0; } +static inline int Gia_ObjFaninId1( Gia_Obj_t * pObj, int ObjId ) { return ObjId - pObj->iDiff1; } +static inline int Gia_ObjFaninId0p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId0( pObj, Gia_ObjId(p, pObj) ); } +static inline int Gia_ObjFaninId1p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId1( pObj, Gia_ObjId(p, pObj) ); } +static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Gia_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); } +static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Gia_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); } +static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; } +static inline int Gia_ObjWhatFanin( Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { return Gia_ObjFanin0(pObj) == pFanin ? 0 : (Gia_ObjFanin1(pObj) == pFanin ? 1 : -1); } + +static inline int Gia_ObjFanin0Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } +static inline int Gia_ObjFanin1Copy( Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj) ); } + +static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) ); } +static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_LitNotCond( Gia_ObjId(p, 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_ObjRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]; } +static inline void Gia_ObjRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); p->pRefs[Gia_ObjId(p, pObj)]++; } +static inline void Gia_ObjRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); 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)); } +static inline void Gia_ObjRefFanin1Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefInc(p, Gia_ObjFanin1(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); } + +// AIG construction +extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); +static inline Gia_Obj_t * Gia_ManAppendObj( Gia_Man_t * p ) +{ + if ( p->nObjs == p->nObjsAlloc ) + { +// printf("Reallocing %d.\n", 2 * p->nObjsAlloc ); + assert( p->nObjsAlloc > 0 ); + p->pObjs = ABC_REALLOC( Gia_Obj_t, p->pObjs, 2 * p->nObjsAlloc ); + memset( p->pObjs + p->nObjsAlloc, 0, sizeof(Gia_Obj_t) * p->nObjsAlloc ); + p->nObjsAlloc *= 2; + } + return Gia_ManObj( p, p->nObjs++ ); +} +static inline int Gia_ManAppendCi( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj = Gia_ManAppendObj( p ); + pObj->fTerm = 1; + pObj->iDiff0 = GIA_NONE; + pObj->iDiff1 = Vec_IntSize( p->vCis ); + Vec_IntPush( p->vCis, Gia_ObjId(p, pObj) ); + return Gia_ObjId( p, pObj ) << 1; +} +static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + Gia_Obj_t * pObj = Gia_ManAppendObj( p ); + assert( iLit0 != iLit1 ); + if ( iLit0 < iLit1 ) + { + pObj->iDiff0 = Gia_ObjId(p, pObj) - Gia_Lit2Var(iLit0); + pObj->fCompl0 = Gia_LitIsCompl(iLit0); + pObj->iDiff1 = Gia_ObjId(p, pObj) - Gia_Lit2Var(iLit1); + pObj->fCompl1 = Gia_LitIsCompl(iLit1); + } + else + { + pObj->iDiff1 = Gia_ObjId(p, pObj) - Gia_Lit2Var(iLit0); + pObj->fCompl1 = Gia_LitIsCompl(iLit0); + pObj->iDiff0 = Gia_ObjId(p, pObj) - Gia_Lit2Var(iLit1); + pObj->fCompl0 = Gia_LitIsCompl(iLit1); + } + if ( p->pFanData ) + { + Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); + Gia_ObjAddFanout( p, Gia_ObjFanin1(pObj), pObj ); + } + return Gia_ObjId( p, pObj ) << 1; +} +static inline int Gia_ManAppendCo( Gia_Man_t * p, int iLit0 ) +{ + Gia_Obj_t * pObj = Gia_ManAppendObj( p ); + pObj->fTerm = 1; + pObj->iDiff0 = Gia_ObjId(p, pObj) - Gia_Lit2Var(iLit0); + pObj->fCompl0 = Gia_LitIsCompl(iLit0); + pObj->iDiff1 = Vec_IntSize( p->vCos ); + Vec_IntPush( p->vCos, Gia_ObjId(p, pObj) ); + if ( p->pFanData ) + Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); + return Gia_ObjId( p, pObj ) << 1; +} + +#define GIA_ZER 1 +#define GIA_ONE 2 +#define GIA_UND 3 + +static inline int Gia_XsimNotCond( int Value, int fCompl ) +{ + if ( Value == GIA_UND ) + return GIA_UND; + if ( Value == GIA_ZER + fCompl ) + return GIA_ZER; + return GIA_ONE; +} +static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCompl1 ) +{ + if ( Value0 == GIA_ZER + fCompl0 || Value1 == GIA_ZER + fCompl1 ) + return GIA_ZER; + if ( Value0 == GIA_UND || Value1 == GIA_UND ) + return GIA_UND; + return GIA_ONE; +} + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define Gia_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ ) +#define Gia_ManForEachObj1( p, pObj, i ) \ + for ( i = 1; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ ) +#define Gia_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Gia_ManForEachAnd( p, pObj, i ) \ + for ( i = 0; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ ) if ( !Gia_ObjIsAnd(pObj) ) {} else +#define Gia_ManForEachCi( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCis)) && ((pObj) = Gia_ManCi(p, i)); i++ ) +#define Gia_ManForEachCo( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ ) +#define Gia_ManForEachCoDriver( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ObjFanin0(Gia_ManCo(p, i))); i++ ) +#define Gia_ManForEachPi( p, pObj, i ) \ + for ( i = 0; (i < Gia_ManPiNum(p)) && ((pObj) = Gia_ManCi(p, i)); i++ ) +#define Gia_ManForEachPo( p, pObj, i ) \ + for ( i = 0; (i < Gia_ManPoNum(p)) && ((pObj) = Gia_ManCo(p, i)); i++ ) +#define Gia_ManForEachRo( p, pObj, i ) \ + for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObj) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ ) +#define Gia_ManForEachRi( p, pObj, i ) \ + for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObj) = Gia_ManCo(p, Gia_ManPoNum(p)+i)); i++ ) +#define Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) \ + for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObjRi) = Gia_ManCo(p, Gia_ManPoNum(p)+i)) && ((pObjRo) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== giaAig.c ============================================================*/ +extern Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ); +extern Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ); +extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p ); +/*=== giaAiger.c ==========================================================*/ +extern Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ); +extern void Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact ); +/*=== giaCof.c ============================================================*/ +extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes ); +/*=== 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 int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ); +extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ); +/*=== giaDup.c ============================================================*/ +extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes ); +extern Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p ); +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 ); +extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ); +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 ); +/*=== 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 ); +extern void Gia_ManFanoutStart( Gia_Man_t * p ); +extern void Gia_ManFanoutStop( Gia_Man_t * p ); +/*=== giaFrames.c =========================================================*/ +extern void Gia_ManFraSetDefaultParams( Gia_ParFra_t * p ); +extern Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ); +/*=== giaFront.c ==========================================================*/ +extern Gia_Man_t * Gia_ManFront( Gia_Man_t * p ); +extern void Gia_ManFrontTest( Gia_Man_t * p ); +/*=== giaHash.c ===========================================================*/ +extern void Gia_ManHashAlloc( Gia_Man_t * p ); +extern void Gia_ManHashStart( Gia_Man_t * p ); +extern void Gia_ManHashStop( Gia_Man_t * p ); +extern int Gia_ManHashAnd( Gia_Man_t * p, int iLit0, int iLit1 ); +extern int Gia_ManHashXor( Gia_Man_t * p, int iLit0, int iLit1 ); +extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 ); +extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p ); +/*=== giaLogic.c ===========================================================*/ +extern void Gia_ManTestDistance( Gia_Man_t * p ); + /*=== giaMan.c ===========================================================*/ +extern Gia_Man_t * Gia_ManStart( int nObjsMax ); +extern void Gia_ManStop( Gia_Man_t * p ); +extern void Gia_ManPrintStats( Gia_Man_t * p ); +extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); +extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); +extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); +/*=== giaSat.c ============================================================*/ +extern int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ); +/*=== giaScl.c ============================================================*/ +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 ); +/*=== giaSim.c ============================================================*/ +extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); +/*=== giaTsim.c ============================================================*/ +extern Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ); +/*=== giaUtil.c ===========================================================*/ +extern void Gia_ManSetMark0( Gia_Man_t * p ); +extern void Gia_ManCleanMark0( Gia_Man_t * p ); +extern void Gia_ManSetMark1( Gia_Man_t * p ); +extern void Gia_ManCleanMark1( Gia_Man_t * p ); +extern void Gia_ManCleanValue( Gia_Man_t * p ); +extern void Gia_ManFillValue( Gia_Man_t * p ); +extern void Gia_ManSetPhase( Gia_Man_t * p ); +extern int Gia_ManLevelNum( Gia_Man_t * p ); +extern void Gia_ManSetRefs( Gia_Man_t * p ); +extern void Gia_ManCreateRefs( Gia_Man_t * p ); +extern int Gia_ManCrossCut( Gia_Man_t * p ); +extern int Gia_ManIsNormalized( Gia_Man_t * p ); +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 ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c new file mode 100644 index 00000000..8b59341a --- /dev/null +++ b/src/aig/gia/giaAig.c @@ -0,0 +1,214 @@ +/**CFile**************************************************************** + + FileName [giaAig.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Transformation between AIG manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Gia_ObjChild0Copy( Aig_Obj_t * pObj ) { return Gia_LitNotCond( Aig_ObjFanin0(pObj)->iData, Aig_ObjFaninC0(pObj) ); } +static inline int Gia_ObjChild1Copy( Aig_Obj_t * pObj ) { return Gia_LitNotCond( Aig_ObjFanin1(pObj)->iData, Aig_ObjFaninC1(pObj) ); } + +static inline Aig_Obj_t * Gia_ObjChild0Copy2( Aig_Obj_t ** ppNodes, Gia_Obj_t * pObj, int Id ) { return Aig_NotCond( ppNodes[Gia_ObjFaninId0(pObj, Id)], Gia_ObjFaninC0(pObj) ); } +static inline Aig_Obj_t * Gia_ObjChild1Copy2( Aig_Obj_t ** ppNodes, Gia_Obj_t * pObj, int Id ) { return Aig_NotCond( ppNodes[Gia_ObjFaninId1(pObj, Id)], Gia_ObjFaninC1(pObj) ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derives combinational miter of the two AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFromAig_rec( Gia_Man_t * pNew, Aig_Obj_t * pObj ) +{ + if ( pObj->pData ) + return; + if ( Aig_ObjIsPi(pObj) ) + { + pObj->iData = Gia_ManAppendCi( pNew ); + return; + } + assert( Aig_ObjIsNode(pObj) ); + Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Gia_ManFromAig_rec( pNew, Aig_ObjFanin1(pObj) ); + pObj->iData = Gia_ManAppendAnd( pNew, Gia_ObjChild0Copy(pObj), Gia_ObjChild1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) +{ + Gia_Man_t * pNew; + Aig_Obj_t * pObj; + int i; + // add fake POs to all the dangling nodes (choices) + Aig_ManForEachNode( p, pObj, i ) + assert( Aig_ObjRefs(pObj) > 0 ); + // create the new manager + pNew = Gia_ManStart( Aig_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + // create the PIs + Aig_ManCleanData( p ); + Aig_ManConst1(p)->iData = 1; + Aig_ManForEachPi( p, pObj, i ) + { +// if ( Aig_ObjRefs(pObj) == 0 ) + pObj->iData = Gia_ManAppendCi( pNew ); + } + // add logic for the POs + Aig_ManForEachPo( p, pObj, i ) + { + Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Handles choices as additional combinational outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) +{ + Gia_Man_t * pNew; + Aig_Obj_t * pObj; + int i; + // create the new manager + pNew = Gia_ManStart( Aig_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + // create the PIs + Aig_ManCleanData( p ); + Aig_ManConst1(p)->iData = 1; + Aig_ManForEachPi( p, pObj, i ) + pObj->iData = Gia_ManAppendCi( pNew ); + // add POs corresponding to the nodes with choices + Aig_ManForEachNode( p, pObj, i ) + if ( Aig_ObjRefs(pObj) == 0 ) + { + Gia_ManFromAig_rec( pNew, pObj ); + Gia_ManAppendCo( pNew, pObj->iData ); + } + // add logic for the POs + Aig_ManForEachPo( p, pObj, i ) + { + Gia_ManFromAig_rec( pNew, Aig_ObjFanin0(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Derives combinational miter of the two AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManToAig_rec( Aig_Man_t * pNew, Aig_Obj_t ** ppNodes, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ppNodes[Gia_ObjId(p, pObj)] ) + return; + if ( Gia_ObjIsCi(pObj) ) + { + ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePi( pNew ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManToAig_rec( pNew, ppNodes, p, Gia_ObjFanin0(pObj) ); + Gia_ManToAig_rec( pNew, ppNodes, p, Gia_ObjFanin1(pObj) ); + ppNodes[Gia_ObjId(p, pObj)] = Aig_And( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)), Gia_ObjChild1Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Gia_ManToAig( Gia_Man_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t ** ppNodes; + Gia_Obj_t * pObj; + int i; + + // create the new manager + pNew = Aig_ManStart( Gia_ManAndNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + ppNodes = ABC_CALLOC( Aig_Obj_t *, Gia_ManObjNum(p) ); + // create the PIs + ppNodes[0] = Aig_ManConst0(pNew); + Gia_ManForEachCi( p, pObj, i ) + { +// if ( Aig_ObjRefs(pObj) == 0 ) + ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePi( pNew ); + } + // add logic for the POs + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManToAig_rec( pNew, ppNodes, p, Gia_ObjFanin0(pObj) ); + ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePo( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); + } + Aig_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + ABC_FREE( ppNodes ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c new file mode 100644 index 00000000..40c5329d --- /dev/null +++ b/src/aig/gia/giaAiger.c @@ -0,0 +1,553 @@ +/**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" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// 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 [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 = Aig_UtilStrsav( FileName ); + if ( (pDot = strrchr( pRes, '.' )) ) + *pDot = 0; + return pRes; +} + +/**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 [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 = Aig_UtilStrsav( pName ); +// pNew->pSpec = Aig_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 ); + + // 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 [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 [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) ) + 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\n" ); + if ( p->pName ) + fprintf( pFile, ".model %s\n", p->pName ); + fprintf( pFile, "This file was produced by the AIG package 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 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c new file mode 100644 index 00000000..d58429cd --- /dev/null +++ b/src/aig/gia/giaCof.c @@ -0,0 +1,688 @@ +/**CFile**************************************************************** + + FileName [giaCof.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Cofactor estimation procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCof.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <math.h> +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Cof_Fan_t_ Cof_Fan_t; +struct Cof_Fan_t_ +{ + unsigned iFan : 31; // ID of the fanin/fanout + unsigned fCompl : 1; // complemented attribute +}; + +typedef struct Cof_Obj_t_ Cof_Obj_t; +struct Cof_Obj_t_ +{ + unsigned fTerm : 1; // terminal node (CI/CO) + unsigned fPhase : 1; // value under 000 pattern + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanins : 4; // the number of fanins + unsigned nFanouts : 24; // total number of fanouts + unsigned Value; // application specific data + int Id; // ID of the node + int iNext; // next one in the linked list + int iLit; // literal of the node after rehashing + Cof_Fan_t Fanios[0]; // the array of fanins/fanouts +}; + +typedef struct Cof_Man_t_ Cof_Man_t; +struct Cof_Man_t_ +{ + Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) + int nObjs; // the number of objects + int nNodes; // the number of nodes + int nTravIds; // traversal ID of the network + int * pObjData; // the logic network defined for the AIG + int nObjData; // the size of array to store the logic network + int * pLevels; // the linked lists of levels + int nLevels; // the max number of logic levels +}; + +static inline unsigned Gia_ObjHandle( Gia_Obj_t * pObj ) { return pObj->Value; } + +static inline int Cof_ObjLevel( Cof_Man_t * p, Cof_Obj_t * pObj ) { return Gia_ObjLevel(p->pGia, Gia_ManObj(p->pGia,pObj->Id)); } + +static inline unsigned Cof_ObjHandle( Cof_Man_t * p, Cof_Obj_t * pObj ) { return (unsigned)(((int *)pObj) - p->pObjData); } +static inline unsigned Cof_ObjHandleDiff( Cof_Obj_t * pObj, Cof_Obj_t * pFanin ) { return (unsigned)(((int *)pObj) - ((int *)pFanin)); } + +static inline int Cof_ObjIsTerm( Cof_Obj_t * pObj ) { return pObj->fTerm; } +static inline int Cof_ObjIsCi( Cof_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 0; } +static inline int Cof_ObjIsCo( Cof_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 1; } +static inline int Cof_ObjIsNode( Cof_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins > 0; } +static inline int Cof_ObjIsConst0( Cof_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins == 0; } + +static inline int Cof_ObjFaninNum( Cof_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Cof_ObjFanoutNum( Cof_Obj_t * pObj ) { return pObj->nFanouts; } +static inline int Cof_ObjSize( Cof_Obj_t * pObj ) { return sizeof(Cof_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } + +static inline Cof_Obj_t * Cof_ManObj( Cof_Man_t * p, unsigned iHandle ) { return (Cof_Obj_t *)(p->pObjData + iHandle); } +static inline Cof_Obj_t * Cof_ObjFanin( Cof_Obj_t * pObj, int i ) { return (Cof_Obj_t *)(((int *)pObj) - pObj->Fanios[i].iFan); } +static inline Cof_Obj_t * Cof_ObjFanout( Cof_Obj_t * pObj, int i ) { return (Cof_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i].iFan); } + +static inline int Cof_ManObjNum( Cof_Man_t * p ) { return p->nObjs; } +static inline int Cof_ManNodeNum( Cof_Man_t * p ) { return p->nNodes; } + +static inline void Cof_ManResetTravId( Cof_Man_t * p ) { extern void Cof_ManCleanValue( Cof_Man_t * p ); Cof_ManCleanValue( p ); p->nTravIds = 1; } +static inline void Cof_ManIncrementTravId( Cof_Man_t * p ) { p->nTravIds++; } +static inline void Cof_ObjSetTravId( Cof_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } +static inline void Cof_ObjSetTravIdCurrent( Cof_Man_t * p, Cof_Obj_t * pObj ) { pObj->Value = p->nTravIds; } +static inline void Cof_ObjSetTravIdPrevious( Cof_Man_t * p, Cof_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } +static inline int Cof_ObjIsTravIdCurrent( Cof_Man_t * p, Cof_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } +static inline int Cof_ObjIsTravIdPrevious( Cof_Man_t * p, Cof_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } + +#define Cof_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Cof_ManObj(p,i)); i += Cof_ObjSize(pObj) ) +#define Cof_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Cof_ManObj(p,i)); i += Cof_ObjSize(pObj) ) if ( Cof_ObjIsTerm(pObj) ) {} else +#define Cof_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Cof_ObjFanin(pObj,i)); i++ ) +#define Cof_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Cof_ObjFanout(pObj,i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) +{ + Cof_Man_t * p; + Cof_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj; + int i, iHandle = 0; + p = ABC_CALLOC( Cof_Man_t, 1 ); + p->pGia = pGia; + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Cof_Obj_t) / 4) * Gia_ManObjNum(pGia) + 4 * Gia_ManAndNum(pGia) + 2 * Gia_ManCoNum(pGia); + p->pObjData = ABC_CALLOC( int, p->nObjData ); + ABC_FREE( pGia->pRefs ); + Gia_ManCreateRefs( pGia ); + Gia_ManForEachObj( pGia, pObj, i ) + { + pObj->Value = iHandle; + pObjLog = Cof_ManObj( p, iHandle ); + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->Id = i; + pObjLog->Value = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); + pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = + pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); + pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); + + pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin1(pObj)) ); + pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = + pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); + pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC1(pObj); + p->nNodes++; + } + else if ( Gia_ObjIsCo(pObj) ) + { + pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); + pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = + pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); + pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); + + pObjLog->fTerm = 1; + Vec_IntPush( p->vCos, iHandle ); + } + else if ( Gia_ObjIsCi(pObj) ) + { + pObjLog->fTerm = 1; + Vec_IntPush( p->vCis, iHandle ); + } + iHandle += Cof_ObjSize( pObjLog ); + p->nObjs++; + } + assert( iHandle == p->nObjData ); + Gia_ManForEachObj( pGia, pObj, i ) + { + pObjLog = Cof_ManObj( p, Gia_ObjHandle(pObj) ); + assert( pObjLog->nFanouts == pObjLog->Value ); + } + return p; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManStop( Cof_Man_t * p ) +{ + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pObjData ); + ABC_FREE( p->pLevels ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManTfoSize_rec( Cof_Man_t * p, Cof_Obj_t * pObj ) +{ + Cof_Obj_t * pNext; + unsigned i, Counter = 0; + if ( Cof_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Cof_ObjSetTravIdCurrent(p, pObj); + if ( Cof_ObjIsCo(pObj) ) + return 0; + assert( Cof_ObjIsCi(pObj) || Cof_ObjIsNode(pObj) ); + Cof_ObjForEachFanout( pObj, pNext, i ) + Counter += Cof_ManTfoSize_rec( p, pNext ); + return 1 + Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManTfoSize( Cof_Man_t * p, Cof_Obj_t ** ppObjs, int nObjs ) +{ + int i, Counter = 0; + Cof_ManIncrementTravId( p ); + for ( i = 0; i < nObjs; i++ ) + Counter += Cof_ManTfoSize_rec( p, ppObjs[i] ) - 1; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManTfiSize_rec( Cof_Man_t * p, Cof_Obj_t * pObj ) +{ + Cof_Obj_t * pNext; + unsigned i, Counter = 0; + if ( Cof_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Cof_ObjSetTravIdCurrent(p, pObj); + if ( Cof_ObjIsCi(pObj) ) + return 0; + assert( Cof_ObjIsNode(pObj) ); + Cof_ObjForEachFanin( pObj, pNext, i ) + Counter += Cof_ManTfiSize_rec( p, pNext ); + return 1 + Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManTfiSize( Cof_Man_t * p, Cof_Obj_t ** ppObjs, int nObjs ) +{ + int i, Counter = 0; + Cof_ManIncrementTravId( p ); + for ( i = 0; i < nObjs; i++ ) + if ( Cof_ObjIsCo(ppObjs[i]) ) + Counter += Cof_ManTfiSize_rec( p, Cof_ObjFanin(ppObjs[i],0) ); + else + Counter += Cof_ManTfiSize_rec( p, ppObjs[i] ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManSuppSize_rec( Cof_Man_t * p, Cof_Obj_t * pObj ) +{ + Cof_Obj_t * pNext; + unsigned i, Counter = 0; + if ( Cof_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Cof_ObjSetTravIdCurrent(p, pObj); + if ( Cof_ObjIsCi(pObj) ) + return 1; + assert( Cof_ObjIsNode(pObj) ); + Cof_ObjForEachFanin( pObj, pNext, i ) + Counter += Cof_ManSuppSize_rec( p, pNext ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManSuppSize( Cof_Man_t * p, Cof_Obj_t ** ppObjs, int nObjs ) +{ + int i, Counter = 0; + Cof_ManIncrementTravId( p ); + for ( i = 0; i < nObjs; i++ ) + if ( Cof_ObjIsCo(ppObjs[i]) ) + Counter += Cof_ManSuppSize_rec( p, Cof_ObjFanin(ppObjs[i],0) ); + else + Counter += Cof_ManSuppSize_rec( p, ppObjs[i] ); + return Counter; +} + + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManCleanValue( Cof_Man_t * p ) +{ + Cof_Obj_t * pObj; + int i; + Cof_ManForEachObj( p, pObj, i ) + pObj->Value = 0; +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManInsertEntry_rec( Vec_Ptr_t * vNodes, Cof_Obj_t * pNode, int nNodeMax ) +{ + Cof_Obj_t * pLast; + if ( Vec_PtrSize(vNodes) == 0 ) + { + Vec_PtrPush(vNodes, pNode); + return; + } + pLast = Vec_PtrPop(vNodes); + if ( Cof_ObjFanoutNum(pLast) < Cof_ObjFanoutNum(pNode) ) + { + Cof_ManInsertEntry_rec( vNodes, pNode, nNodeMax ); + if ( Vec_PtrSize(vNodes) < nNodeMax ) + Vec_PtrPush( vNodes, pLast ); + } + else + { + Vec_PtrPush( vNodes, pLast ); + if ( Vec_PtrSize(vNodes) < nNodeMax ) + Vec_PtrPush( vNodes, pNode ); + } +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Cof_ManCollectHighFanout( Cof_Man_t * p, int nNodes ) +{ + Vec_Ptr_t * vNodes; + Cof_Obj_t * pObj; + int i; + vNodes = Vec_PtrAlloc( nNodes ); + Cof_ManForEachObj( p, pObj, i ) + if ( Cof_ObjIsCi(pObj) || Cof_ObjIsNode(pObj) ) + Cof_ManInsertEntry_rec( vNodes, pObj, nNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_ManCountRemoved( Cof_Man_t * p, Cof_Obj_t * pRoot, int fConst1 ) +{ + Gia_Obj_t * pNextGia; + Cof_Obj_t * pTemp, * pNext, * pFanin0, * pFanin1; + int Counter = 0, LevelStart, LevelNext; + int i, k, iHandle, iLit0, iLit1, iNextNew; + // restart the trav ids + Cof_ManIncrementTravId( p ); + Cof_ObjSetTravIdCurrent( p, pRoot ); + // add the node to the queue + LevelStart = Cof_ObjLevel(p, pRoot); + assert( p->pLevels[LevelStart] == 0 ); + pRoot->iNext = 0; + p->pLevels[LevelStart] = Cof_ObjHandle( p, pRoot ); + // set the new literal + pRoot->iLit = Gia_Var2Lit( 0, fConst1 ); + // process nodes in the levelized order + for ( i = LevelStart; i < p->nLevels; i++ ) + { + for ( iHandle = p->pLevels[i]; + iHandle && (pTemp = Cof_ManObj(p, iHandle)); + iHandle = pTemp->iNext ) + { + assert( pTemp->Id != Gia_Lit2Var(pTemp->iLit) ); + Cof_ObjForEachFanout( pTemp, pNext, k ) + { + if ( Cof_ObjIsCo(pNext) ) + continue; + if ( Cof_ObjIsTravIdCurrent(p, pNext) ) + continue; + pFanin0 = Cof_ObjFanin( pNext, 0 ); + pFanin1 = Cof_ObjFanin( pNext, 1 ); + assert( pFanin0 == pTemp || pFanin1 == pTemp ); + pNextGia = Gia_ManObj( p->pGia, pNext->Id ); + if ( Cof_ObjIsTravIdCurrent(p, pFanin0) ) + iLit0 = Gia_LitNotCond( pFanin0->iLit, Gia_ObjFaninC0(pNextGia) ); + else + iLit0 = Gia_ObjFaninLit0( pNextGia, pNext->Id ); + if ( Cof_ObjIsTravIdCurrent(p, pFanin1) ) + iLit1 = Gia_LitNotCond( pFanin1->iLit, Gia_ObjFaninC1(pNextGia) ); + else + iLit1 = Gia_ObjFaninLit1( pNextGia, pNext->Id ); + iNextNew = Gia_ManHashAndTry( p->pGia, iLit0, iLit1 ); + if ( iNextNew == -1 ) + continue; + Cof_ObjSetTravIdCurrent(p, pNext); + // set the new literal + pNext->iLit = iNextNew; + // add it to be processed + LevelNext = Cof_ObjLevel( p, pNext ); + assert( LevelNext > i && LevelNext < p->nLevels ); + pNext->iNext = p->pLevels[LevelNext]; + p->pLevels[LevelNext] = Cof_ObjHandle( p, pNext ); + Counter++; + } + } + p->pLevels[i] = 0; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManPrintHighFanoutOne( Cof_Man_t * p, Cof_Obj_t * pObj ) +{ + printf( "%7d : ", pObj->Id ); + printf( "fi =%2d ", Cof_ObjFaninNum(pObj) ); + printf( "fo =%5d ", Cof_ObjFanoutNum(pObj) ); + printf( "l =%4d ", Cof_ObjLevel(p, pObj) ); + printf( "s =%5d ", Cof_ManSuppSize(p, &pObj, 1) ); + printf( "TFI =%7d ", Cof_ManTfiSize(p, &pObj, 1) ); + printf( "TFO =%7d ", Cof_ManTfoSize(p, &pObj, 1) ); + printf( "C0 =%6d ", Cof_ManCountRemoved(p, pObj, 0) ); + printf( "C1 =%6d", Cof_ManCountRemoved(p, pObj, 1) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManPrintHighFanout( Cof_Man_t * p, int nNodes ) +{ + Vec_Ptr_t * vNodes; + Cof_Obj_t * pObj; + int i; + vNodes = Cof_ManCollectHighFanout( p, nNodes ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + Cof_ManPrintHighFanoutOne( p, pObj ); + Vec_PtrFree( vNodes ); +} + +/**Function************************************************************* + + Synopsis [Prints the distribution of fanins/fanouts in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cof_ManPrintFanio( Cof_Man_t * p ) +{ + char Buffer[100]; + Cof_Obj_t * pNode; + Vec_Int_t * vFanins, * vFanouts; + int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll; + int i, k, nSizeMax; + + // determine the largest fanin and fanout + nFaninsMax = nFanoutsMax = 0; + nFaninsAll = nFanoutsAll = 0; + Cof_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; + nFanins = Cof_ObjFaninNum(pNode); + nFanouts = Cof_ObjFanoutNum(pNode); + nFaninsAll += nFanins; + nFanoutsAll += nFanouts; + nFaninsMax = ABC_MAX( nFaninsMax, nFanins ); + nFanoutsMax = ABC_MAX( nFanoutsMax, nFanouts ); + } + + // allocate storage for fanin/fanout numbers + nSizeMax = AIG_MAX( 10 * (Aig_Base10Log(nFaninsMax) + 1), 10 * (Aig_Base10Log(nFanoutsMax) + 1) ); + vFanins = Vec_IntStart( nSizeMax ); + vFanouts = Vec_IntStart( nSizeMax ); + + // count the number of fanins and fanouts + Cof_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; + nFanins = Cof_ObjFaninNum(pNode); + nFanouts = Cof_ObjFanoutNum(pNode); +// nFanouts = Cof_NodeMffcSize(pNode); + + if ( nFanins < 10 ) + Vec_IntAddToEntry( vFanins, nFanins, 1 ); + else if ( nFanins < 100 ) + Vec_IntAddToEntry( vFanins, 10 + nFanins/10, 1 ); + else if ( nFanins < 1000 ) + Vec_IntAddToEntry( vFanins, 20 + nFanins/100, 1 ); + else if ( nFanins < 10000 ) + Vec_IntAddToEntry( vFanins, 30 + nFanins/1000, 1 ); + else if ( nFanins < 100000 ) + Vec_IntAddToEntry( vFanins, 40 + nFanins/10000, 1 ); + else if ( nFanins < 1000000 ) + Vec_IntAddToEntry( vFanins, 50 + nFanins/100000, 1 ); + else if ( nFanins < 10000000 ) + Vec_IntAddToEntry( vFanins, 60 + nFanins/1000000, 1 ); + + if ( nFanouts < 10 ) + Vec_IntAddToEntry( vFanouts, nFanouts, 1 ); + else if ( nFanouts < 100 ) + Vec_IntAddToEntry( vFanouts, 10 + nFanouts/10, 1 ); + else if ( nFanouts < 1000 ) + Vec_IntAddToEntry( vFanouts, 20 + nFanouts/100, 1 ); + else if ( nFanouts < 10000 ) + Vec_IntAddToEntry( vFanouts, 30 + nFanouts/1000, 1 ); + else if ( nFanouts < 100000 ) + Vec_IntAddToEntry( vFanouts, 40 + nFanouts/10000, 1 ); + else if ( nFanouts < 1000000 ) + Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 ); + else if ( nFanouts < 10000000 ) + Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 ); + } + + printf( "The distribution of fanins and fanouts in the network:\n" ); + printf( " Number Nodes with fanin Nodes with fanout\n" ); + for ( k = 0; k < nSizeMax; k++ ) + { + if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) + continue; + if ( k < 10 ) + printf( "%15d : ", k ); + else + { + sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + printf( "%15s : ", Buffer ); + } + if ( vFanins->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanins->pArray[k] ); + printf( " " ); + if ( vFanouts->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanouts->pArray[k] ); + printf( "\n" ); + } + Vec_IntFree( vFanins ); + Vec_IntFree( vFanouts ); + + printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f.\n", + nFaninsMax, 1.0*nFaninsAll/Cof_ManNodeNum(p), + nFanoutsMax, 1.0*nFanoutsAll/Cof_ManNodeNum(p) ); +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes ) +{ + Cof_Man_t * p; + int clk = clock(); + p = Cof_ManCreateLogicSimple( pGia ); + p->nLevels = 1 + Gia_ManLevelNum( pGia ); + p->pLevels = ABC_CALLOC( int, p->nLevels ); + Cof_ManPrintFanio( p ); + + Cof_ManResetTravId( p ); + Gia_ManHashStart( pGia ); + Cof_ManPrintHighFanout( p, nNodes ); + Gia_ManHashStop( pGia ); +ABC_PRM( "Memory for logic network", 4*p->nObjData ); +ABC_PRT( "Time", clock() - clk ); + Cof_ManStop( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaConstr.c b/src/aig/gia/giaConstr.c new file mode 100644 index 00000000..14768cc2 --- /dev/null +++ b/src/aig/gia/giaConstr.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [giaConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Constraint propagation in CNF-based solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaConstr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c new file mode 100644 index 00000000..a978dcc3 --- /dev/null +++ b/src/aig/gia/giaDfs.c @@ -0,0 +1,243 @@ +/**CFile**************************************************************** + + FileName [giaDfs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [DFS procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Counts the support size of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectCis_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectCis_rec( p, Gia_ObjFanin0(pObj), vSupp ); + Gia_ManCollectCis_rec( p, Gia_ObjFanin1(pObj), vSupp ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj; + int i; + Vec_IntClear( vSupp ); + 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_ManCollectCis_rec( p, Gia_ObjFanin0(pObj), vSupp ); + else + Gia_ManCollectCis_rec( p, pObj, vSupp ); + } +} + +/**Function************************************************************* + + Synopsis [Counts the support size of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectAnds_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) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectAnds_rec( p, Gia_ObjFanin0(pObj), vNodes ); + Gia_ManCollectAnds_rec( p, Gia_ObjFanin1(pObj), vNodes ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vNodes ) +{ + Gia_Obj_t * pObj; + int i; + Vec_IntClear( vNodes ); + 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_ManCollectAnds_rec( p, Gia_ObjFanin0(pObj), vNodes ); + else + Gia_ManCollectAnds_rec( p, pObj, vNodes ); + } +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSuppSize_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_ManSuppSize_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManSuppSize_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + 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) ) + Counter += Gia_ManSuppSize_rec( p, Gia_ObjFanin0(pObj) ); + else + Counter += Gia_ManSuppSize_rec( p, pObj ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManConeSize_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 0; + assert( Gia_ObjIsAnd(pObj) ); + return 1 + Gia_ManConeSize_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManConeSize_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + 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) ) + Counter += Gia_ManConeSize_rec( p, Gia_ObjFanin0(pObj) ); + else + Counter += Gia_ManConeSize_rec( p, pObj ); + } + return Counter; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c new file mode 100644 index 00000000..f8d759be --- /dev/null +++ b/src/aig/gia/giaDup.c @@ -0,0 +1,698 @@ +/**CFile**************************************************************** + + FileName [giaDup.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Duplication procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaDup.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Duplicates AIG without any changes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDup( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG without any changes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, nRos = 0, nRis = 0; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( pObj->fMark0 ) + continue; + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + nRos += Gia_ObjIsRo(p, pObj); + } + else if ( Gia_ObjIsCo(pObj) ) + { + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + nRis += Gia_ObjIsRi(p, pObj); + } + } + assert( nRos == nRis ); + Gia_ManSetRegNum( pNew, nRos ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while creating "parallel" copies.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vPis, * vPos, * vRis, * vRos; + int i, t, Entry; + assert( nTimes > 0 ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + vPis = Vec_IntAlloc( Gia_ManPiNum(p) * nTimes ); + vPos = Vec_IntAlloc( Gia_ManPoNum(p) * nTimes ); + vRis = Vec_IntAlloc( Gia_ManRegNum(p) * nTimes ); + vRos = Vec_IntAlloc( Gia_ManRegNum(p) * nTimes ); + for ( t = 0; t < nTimes; t++ ) + { + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + if ( Gia_ObjIsPi(p, pObj) ) + Vec_IntPush( vPis, Gia_Lit2Var(pObj->Value) ); + else + Vec_IntPush( vRos, Gia_Lit2Var(pObj->Value) ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + if ( Gia_ObjIsPo(p, pObj) ) + Vec_IntPush( vPos, Gia_Lit2Var(pObj->Value) ); + else + Vec_IntPush( vRis, Gia_Lit2Var(pObj->Value) ); + } + } + } + Vec_IntClear( pNew->vCis ); + Vec_IntForEachEntry( vPis, Entry, i ) + { + Gia_ObjSetCioId( Gia_ManObj(pNew, Entry), Vec_IntSize(pNew->vCis) ); + Vec_IntPush( pNew->vCis, Entry ); + } + Vec_IntForEachEntry( vRos, Entry, i ) + { + Gia_ObjSetCioId( Gia_ManObj(pNew, Entry), Vec_IntSize(pNew->vCis) ); + Vec_IntPush( pNew->vCis, Entry ); + } + Vec_IntClear( pNew->vCos ); + Vec_IntForEachEntry( vPos, Entry, i ) + { + Gia_ObjSetCioId( Gia_ManObj(pNew, Entry), Vec_IntSize(pNew->vCos) ); + Vec_IntPush( pNew->vCos, Entry ); + } + Vec_IntForEachEntry( vRis, Entry, i ) + { + Gia_ObjSetCioId( Gia_ManObj(pNew, Entry), Vec_IntSize(pNew->vCos) ); + Vec_IntPush( pNew->vCos, Entry ); + } + Vec_IntFree( vPis ); + Vec_IntFree( vPos ); + Vec_IntFree( vRis ); + Vec_IntFree( vRos ); + Gia_ManSetRegNum( pNew, nTimes * Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + if ( p->pReprs && ~p->pReprs[Gia_ObjId(p, pObj)] ) + { + Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprs[Gia_ObjId(p, pObj)] ); + pObj->Value = Gia_ManDupDfs_rec( pNew, p, pRepr ); + return pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + } + if ( Gia_ObjIsCi(pObj) ) + return pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin1(pObj) ); + if ( pNew->pHTable ) + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupDfs_rec( pNew, p, pObj ); + Gia_ManForEachCi( p, pObj, i ) + if ( ~pObj->Value == 0 ) + pObj->Value = Gia_ManAppendCi(pNew); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + // remap combinational inputs + Gia_ManForEachCi( p, pObj, i ) + { + pObjNew = Gia_ObjFromLit( pNew, pObj->Value ); + assert( !Gia_IsComplement(pObjNew) ); + Vec_IntWriteEntry( pNew->vCis, Gia_ObjCioId(pObj), Gia_ObjId(pNew, pObjNew) ); + Gia_ObjSetCioId( pObjNew, Gia_ObjCioId(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachCo( p, pObj, i ) + if ( pObj->fMark1 == 0 ) + Gia_ManDupDfs_rec( pNew, p, pObj ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pRoot ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + assert( Gia_ObjIsCo(pRoot) ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManDupDfs_rec( pNew, p, pRoot ); + Gia_ManSetRegNum( pNew, 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, iLit, iLitRes; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Vec_IntForEachEntry( vLits, iLit, i ) + { + iLitRes = Gia_ManDupDfs_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) ); + Gia_ManAppendCo( pNew, Gia_LitNotCond( iLitRes, Gia_LitIsCompl(iLit)) ); + } + Gia_ManSetRegNum( pNew, 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + 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) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + assert( Gia_ManIsNormalized(pNew) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManSetRefs( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + if ( pObj->Value > 0 || Gia_ObjIsRo(p, pObj) ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) || Gia_ObjIsRi(p, pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pPivot; + int i; + assert( Gia_ManRegNum(p) == 0 ); + assert( iVar < Gia_ManObjNum(p) ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // find the cofactoring variable + pPivot = Gia_ManObj(p, iVar); + // compute the negative cofactor + if ( Gia_ObjIsCi(pPivot) ) + pPivot->Value = Gia_Var2Lit( 0, 0 ); + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( pObj == pPivot ) + pPivot->Value = Gia_Var2Lit( 0, 0 ); + } + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + // compute the positive cofactor + if ( Gia_ObjIsCi(pPivot) ) + pPivot->Value = Gia_Var2Lit( 0, 1 ); + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( pObj == pPivot ) + pPivot->Value = Gia_Var2Lit( 0, 1 ); + } + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + // rehash the result + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Print representatives.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintRepr( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + if ( ~p->pReprs[i] ) + printf( "%d->%d ", i, p->pReprs[i] ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi(pNew); + if ( ~pCi2Lit[i] ) + pObj->Value = Gia_LitNotCond( Gia_ManObj(p, Gia_Lit2Var(pCi2Lit[i]))->Value, Gia_LitIsCompl(pCi2Lit[i]) ); + } + Gia_ManHashAlloc( pNew ); + if ( vLits ) + { + int iLit, iLitRes; + Vec_IntForEachEntry( vLits, iLit, i ) + { + iLitRes = Gia_ManDupDfs_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) ); + Gia_ManAppendCo( pNew, Gia_LitNotCond( iLitRes, Gia_LitIsCompl(iLit)) ); + } + } + else + { + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupDfs_rec( pNew, p, pObj ); + } + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i; + assert( p->pReprs != NULL ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupDfs_rec( pNew, p, pObj ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Detect topmost gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTopAnd_iter( Gia_Man_t * p, int fVerbose ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vFront, * vLeaves; + int i, iLit, iObjId, nCiLits, * pCi2Lit; + char * pVar2Val; + // collect the frontier + vFront = Vec_IntAlloc( 1000 ); + vLeaves = Vec_IntAlloc( 1000 ); + Gia_ManForEachCo( p, pObj, i ) + { + if ( Gia_ObjIsConst0( Gia_ObjFanin0(pObj) ) ) + continue; + if ( Gia_ObjFaninC0(pObj) ) + Vec_IntPush( vLeaves, Gia_ObjFaninLit0p(p, pObj) ); + else + Vec_IntPush( vFront, Gia_ObjFaninId0p(p, pObj) ); + } + if ( Vec_IntSize(vFront) == 0 ) + { + if ( fVerbose ) + printf( "The AIG cannot be decomposed using AND-decomposition.\n" ); + Vec_IntFree( vFront ); + Vec_IntFree( vLeaves ); + return Gia_ManDupNormalized( p ); + } + // expand the frontier + Gia_ManForEachObjVec( vFront, p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vLeaves, Gia_Var2Lit( Gia_ObjId(p, pObj), 0 ) ); + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + if ( Gia_ObjFaninC0(pObj) ) + Vec_IntPush( vLeaves, Gia_ObjFaninLit0p(p, pObj) ); + else + Vec_IntPush( vFront, Gia_ObjFaninId0p(p, pObj) ); + if ( Gia_ObjFaninC1(pObj) ) + Vec_IntPush( vLeaves, Gia_ObjFaninLit1p(p, pObj) ); + else + Vec_IntPush( vFront, Gia_ObjFaninId1p(p, pObj) ); + } + Vec_IntFree( vFront ); + // sort the literals + nCiLits = 0; + pCi2Lit = ABC_FALLOC( int, Gia_ManObjNum(p) ); + pVar2Val = ABC_FALLOC( char, Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vLeaves, iLit, i ) + { + iObjId = Gia_Lit2Var(iLit); + pObj = Gia_ManObj(p, iObjId); + if ( Gia_ObjIsCi(pObj) ) + { + pCi2Lit[Gia_ObjCioId(pObj)] = !Gia_LitIsCompl(iLit); + nCiLits++; + } + if ( pVar2Val[iObjId] != 0 && pVar2Val[iObjId] != 1 ) + pVar2Val[iObjId] = Gia_LitIsCompl(iLit); + else if ( pVar2Val[iObjId] != Gia_LitIsCompl(iLit) ) + break; + } + if ( i < Vec_IntSize(vLeaves) ) + { + printf( "Problem is trivially UNSAT.\n" ); + ABC_FREE( pCi2Lit ); + ABC_FREE( pVar2Val ); + Vec_IntFree( vLeaves ); + return Gia_ManDupNormalized( p ); + } + // create array of input literals + Vec_IntClear( vLeaves ); + Gia_ManForEachObj( p, pObj, i ) + if ( !Gia_ObjIsCi(pObj) && (pVar2Val[i] == 0 || pVar2Val[i] == 1) ) + Vec_IntPush( vLeaves, Gia_Var2Lit(i, pVar2Val[i]) ); + if ( fVerbose ) + printf( "Detected %6d AND leaves and %6d CI leaves.\n", Vec_IntSize(vLeaves), nCiLits ); + // create the input map + if ( nCiLits == 0 ) + pNew = Gia_ManDupDfsLitArray( p, vLeaves ); + else + pNew = Gia_ManDupDfsCiMap( p, pCi2Lit, vLeaves ); + ABC_FREE( pCi2Lit ); + ABC_FREE( pVar2Val ); + Vec_IntFree( vLeaves ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Detect topmost gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + int fContinue, iIter = 0; + pNew = Gia_ManDupNormalized( p ); + for ( fContinue = 1; fContinue; ) + { + pNew = Gia_ManDupTopAnd_iter( pTemp = pNew, fVerbose ); + if ( Gia_ManCoNum(pNew) == Gia_ManCoNum(pTemp) && Gia_ManAndNum(pNew) == Gia_ManAndNum(pTemp) ) + fContinue = 0; + Gia_ManStop( pTemp ); + if ( fVerbose ) + { + printf( "Iter %2d : ", ++iIter ); + Gia_ManPrintStatsShort( pNew ); + } + } + return pNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c new file mode 100644 index 00000000..42ccd7e7 --- /dev/null +++ b/src/aig/gia/giaFanout.c @@ -0,0 +1,197 @@ +/**CFile**************************************************************** + + FileName [giaFanout.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: giaFanout.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// 0: first iFan +// 1: prev iFan0 +// 2: prev iFan1 +// 3: next iFan0 +// 4: next iFan1 + +static inline int Gia_FanoutCreate( int FanId, int Num ) { assert( Num < 2 ); return (FanId << 1) | Num; } +static inline int * Gia_FanoutObj( int * pData, int ObjId ) { return pData + 5*ObjId; } +static inline int * Gia_FanoutPrev( int * pData, int iFan ) { return pData + 5*(iFan >> 1) + 1 + (iFan & 1); } +static inline int * Gia_FanoutNext( int * pData, int iFan ) { return pData + 5*(iFan >> 1) + 3 + (iFan & 1); } + +// these two procedures are only here for the use inside the iterator +static inline int Gia_ObjFanout0Int( Gia_Man_t * p, int ObjId ) { assert(ObjId < p->nFansAlloc); return p->pFanData[5*ObjId]; } +static inline int Gia_ObjFanoutNext( Gia_Man_t * p, int iFan ) { assert(iFan/2 < p->nFansAlloc); return p->pFanData[5*(iFan >> 1) + 3 + (iFan & 1)]; } +// iterator over the fanouts +#define Gia_ObjForEachFanout( p, pObj, pFanout, iFan, i ) \ + for ( assert(p->pFanData), i = 0; (i < (int)(pObj)->nRefs) && \ + (((iFan) = i? Gia_ObjFanoutNext(p, iFan) : Gia_ObjFanout0Int(p, Gia_ObjId(p, pObj))), 1) && \ + (((pFanout) = Gia_ManObj(p, iFan>>1)), 1); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Create fanout for all objects in the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFanoutStart( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + // allocate fanout datastructure + assert( p->pFanData == NULL ); + p->nFansAlloc = 2 * Gia_ManObjNum(p); + if ( p->nFansAlloc < (1<<12) ) + p->nFansAlloc = (1<<12); + p->pFanData = ABC_ALLOC( int, 5 * p->nFansAlloc ); + memset( p->pFanData, 0, sizeof(int) * 5 * p->nFansAlloc ); + // add fanouts for all objects + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjChild0(pObj) ) + Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); + if ( Gia_ObjChild1(pObj) ) + Gia_ObjAddFanout( p, Gia_ObjFanin1(pObj), pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Deletes fanout for all objects in the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFanoutStop( Gia_Man_t * p ) +{ + assert( p->pFanData != NULL ); + ABC_FREE( p->pFanData ); + p->nFansAlloc = 0; +} + +/**Function************************************************************* + + Synopsis [Adds fanout (pFanout) of node (pObj).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) +{ + int iFan, * pFirst, * pPrevC, * pNextC, * pPrev, * pNext; + assert( p->pFanData ); + assert( !Gia_IsComplement(pObj) && !Gia_IsComplement(pFanout) ); + assert( Gia_ObjId(p, pFanout) > 0 ); + if ( Gia_ObjId(p, pObj) >= p->nFansAlloc || Gia_ObjId(p, pFanout) >= p->nFansAlloc ) + { + int nFansAlloc = 2 * AIG_MAX( Gia_ObjId(p, pObj), Gia_ObjId(p, pFanout) ); + p->pFanData = ABC_REALLOC( int, p->pFanData, 5 * nFansAlloc ); + memset( p->pFanData + 5 * p->nFansAlloc, 0, sizeof(int) * 5 * (nFansAlloc - p->nFansAlloc) ); + p->nFansAlloc = nFansAlloc; + } + assert( Gia_ObjId(p, pObj) < p->nFansAlloc && Gia_ObjId(p, pFanout) < p->nFansAlloc ); + iFan = Gia_FanoutCreate( Gia_ObjId(p, pFanout), Gia_ObjWhatFanin(pFanout, pObj) ); + pPrevC = Gia_FanoutPrev( p->pFanData, iFan ); + pNextC = Gia_FanoutNext( p->pFanData, iFan ); + pFirst = Gia_FanoutObj( p->pFanData, Gia_ObjId(p, pObj) ); + if ( *pFirst == 0 ) + { + *pFirst = iFan; + *pPrevC = iFan; + *pNextC = iFan; + } + else + { + pPrev = Gia_FanoutPrev( p->pFanData, *pFirst ); + pNext = Gia_FanoutNext( p->pFanData, *pPrev ); + assert( *pNext == *pFirst ); + *pPrevC = *pPrev; + *pNextC = *pFirst; + *pPrev = iFan; + *pNext = iFan; + } +} + +/**Function************************************************************* + + Synopsis [Removes fanout (pFanout) of node (pObj).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) +{ + int iFan, * pFirst, * pPrevC, * pNextC, * pPrev, * pNext; + assert( p->pFanData && Gia_ObjId(p, pObj) < p->nFansAlloc && Gia_ObjId(p, pFanout) < p->nFansAlloc ); + assert( !Gia_IsComplement(pObj) && !Gia_IsComplement(pFanout) ); + assert( Gia_ObjId(p, pFanout) > 0 ); + iFan = Gia_FanoutCreate( Gia_ObjId(p, pFanout), Gia_ObjWhatFanin(pFanout, pObj) ); + pPrevC = Gia_FanoutPrev( p->pFanData, iFan ); + pNextC = Gia_FanoutNext( p->pFanData, iFan ); + pPrev = Gia_FanoutPrev( p->pFanData, *pNextC ); + pNext = Gia_FanoutNext( p->pFanData, *pPrevC ); + assert( *pPrev == iFan ); + assert( *pNext == iFan ); + pFirst = Gia_FanoutObj( p->pFanData, Gia_ObjId(p, pObj) ); + assert( *pFirst > 0 ); + if ( *pFirst == iFan ) + { + if ( *pNextC == iFan ) + { + *pFirst = 0; + *pPrev = 0; + *pNext = 0; + *pPrevC = 0; + *pNextC = 0; + return; + } + *pFirst = *pNextC; + } + *pPrev = *pPrevC; + *pNext = *pNextC; + *pPrevC = 0; + *pNextC = 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c new file mode 100644 index 00000000..eae0a1cc --- /dev/null +++ b/src/aig/gia/giaForce.c @@ -0,0 +1,164 @@ +/**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" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This is implementation of qsort in MiniSat.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int num_cmp ( int * x, int * y) { return ((*x) < (*y)) ? -1 : 1; } +// Returns a random float 0 <= x < 1. Seed must never be 0. +static inline double drand(double* seed) { + int q; + *seed *= 1389796; + q = (int)(*seed / 2147483647); + *seed -= (double)q * 2147483647; + return *seed / 2147483647; } +// Returns a random integer 0 <= x < size. Seed must never be 0. +static inline int irand(double* seed, int size) { + return (int)(drand(seed) * size); } +static inline void selectionsort(int* array, int size, int(*comp)(const void *, const void *)) +{ + int i, j, best_i; + int tmp; + for (i = 0; i < size-1; i++){ + best_i = i; + for (j = i+1; j < size; j++){ + if (comp(array + j, array + best_i) < 0) + best_i = j; + } + tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; + } +} +static void sortrnd(int* array, int size, int(*comp)(const void *, const void *), double* seed) +{ + if (size <= 15) + selectionsort(array, size, comp); + else{ + int * pivot = array + irand(seed, size); + int tmp; + int i = -1; + int j = size; + for(;;){ + do i++; while(comp(array + i, pivot)<0); + do j--; while(comp(pivot, array + j)<0); + if (i >= j) break; + tmp = array[i]; array[i] = array[j]; array[j] = tmp; + } + sortrnd(array , i , comp, seed); + sortrnd(&array[i], size-i, comp, seed); + } +} +void minisat_sort(int* array, int size, int(*comp)(const void *, const void *)) +{ + double seed = 91648253; + sortrnd(array,size,comp,&seed); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_SortGetTest( int nSize ) +{ + int i, * pArray; + Aig_ManRandom( 1 ); + pArray = ABC_ALLOC( int, nSize ); + for ( i = 0; i < nSize; i++ ) + pArray[i] = (Aig_ManRandom( 0 ) >> 2); + return pArray; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SortVerifySorted( int * pArray, int nSize ) +{ + int i; + for ( i = 1; i < nSize; i++ ) + assert( pArray[i-1] <= pArray[i] ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SortTest() +{ + int nSize = 1000000; + int * pArray; + int clk = clock(); + pArray = Gia_SortGetTest( nSize ); +clk = clock(); + qsort( pArray, nSize, 4, (int (*)(const void *, const void *)) num_cmp ); +ABC_PRT( "qsort ", clock() - clk ); + Gia_SortVerifySorted( pArray, nSize ); + ABC_FREE( pArray ); + pArray = Gia_SortGetTest( nSize ); +clk = clock(); + minisat_sort( pArray, nSize, (int (*)(const void *, const void *)) num_cmp ); +ABC_PRT( "minisat", clock() - clk ); + Gia_SortVerifySorted( pArray, nSize ); + ABC_FREE( pArray ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaFrames.c b/src/aig/gia/giaFrames.c new file mode 100644 index 00000000..e99ef514 --- /dev/null +++ b/src/aig/gia/giaFrames.c @@ -0,0 +1,346 @@ +/**CFile**************************************************************** + + FileName [giaFrames.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Timeframe unrolling.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaFrames.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_ManFra_t_ Gia_ManFra_t; +struct Gia_ManFra_t_ +{ + Gia_ParFra_t * pPars; // parameters + Gia_Man_t * pAig; // AIG to unroll + Vec_Ptr_t * vIns; // inputs of each timeframe + Vec_Ptr_t * vAnds; // nodes of each timeframe + Vec_Ptr_t * vOuts; // outputs of each timeframe +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFraSetDefaultParams( Gia_ParFra_t * p ) +{ + memset( p, 0, sizeof(Gia_ParFra_t) ); + p->nFrames = 32; // the number of frames to unroll + p->fInit = 0; // initialize the timeframes + p->fVerbose = 0; // enables verbose output +} + +/**Function************************************************************* + + Synopsis [Creates manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManFra_t * Gia_ManFraStart( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) +{ + Gia_ManFra_t * p; + p = ABC_ALLOC( Gia_ManFra_t, 1 ); + memset( p, 0, sizeof(Gia_ManFra_t) ); + p->pAig = pAig; + p->pPars = pPars; + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFraStop( Gia_ManFra_t * p ) +{ + Vec_VecFree( (Vec_Vec_t *)p->vIns ); + Vec_VecFree( (Vec_Vec_t *)p->vAnds ); + Vec_VecFree( (Vec_Vec_t *)p->vOuts ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Computes supports of all timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFraSupports( Gia_ManFra_t * p ) +{ + Vec_Int_t * vIns = NULL, * vAnds, * vOuts; + Gia_Obj_t * pObj; + int f, i; + 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 ); + for ( f = p->pPars->nFrames - 1; f >= 0; f-- ) + { + vOuts = Gia_ManCollectPoIds( p->pAig ); + if ( vIns ) + Gia_ManForEachObjVec( vIns, p->pAig, pObj, i ) + if ( Gia_ObjIsRo(p->pAig, pObj) ) + Vec_IntPush( vOuts, Gia_ObjId( p->pAig, Gia_ObjRoToRi(p->pAig, pObj) ) ); + vIns = Vec_IntAlloc( 100 ); + Gia_ManCollectCis( p->pAig, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vIns ); + vAnds = Vec_IntAlloc( 100 ); + Gia_ManCollectAnds( p->pAig, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vAnds ); + Vec_PtrWriteEntry( p->vIns, f, vIns ); + Vec_PtrWriteEntry( p->vAnds, f, vAnds ); + Vec_PtrWriteEntry( p->vOuts, f, vOuts ); + } +} + +/**Function************************************************************* + + Synopsis [Moves the first nRegs entries to the end.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFraTransformCis( Gia_Man_t * pAig, Vec_Int_t * vCis ) +{ + int i, k = 0, Entry; + Vec_IntForEachEntryStop( vCis, Entry, i, Gia_ManRegNum(pAig) ) + assert( Entry == i+1 ); + Vec_IntForEachEntryStart( vCis, Entry, i, Gia_ManRegNum(pAig) ) + Vec_IntWriteEntry( vCis, k++, Entry ); + for ( i = 0; i < Gia_ManRegNum(pAig); i++ ) + Vec_IntWriteEntry( vCis, k++, i+1 ); + assert( k == Vec_IntSize(vCis) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFramesInit( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) +{ + int fUseAllPis = 1; + Gia_Man_t * pFrames, * pTemp; + Gia_ManFra_t * p; + Gia_Obj_t * pObj; + Vec_Int_t * vIns, * vAnds, * vOuts; + int i, f; + p = Gia_ManFraStart( pAig, pPars ); + Gia_ManFraSupports( p ); + pFrames = Gia_ManStart( Vec_VecSizeSize((Vec_Vec_t*)p->vIns)+ + Vec_VecSizeSize((Vec_Vec_t*)p->vAnds)+Vec_VecSizeSize((Vec_Vec_t*)p->vOuts) ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + Gia_ManHashAlloc( pFrames ); + 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 ); + if ( pPars->fVerbose ) + printf( "Frame %3d : CI = %6d. AND = %6d. CO = %6d.\n", + f, Vec_IntSize(vIns), Vec_IntSize(vAnds), Vec_IntSize(vOuts) ); + if ( fUseAllPis ) + { + Gia_ManForEachPi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( pFrames ); + if ( f == 0 ) + { + Gia_ManForEachObjVec( vIns, pAig, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) ); + if ( !Gia_ObjIsPi(pAig, pObj) ) + pObj->Value = 0; + } + } + else + { + Gia_ManForEachObjVec( vIns, pAig, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) ); + if ( !Gia_ObjIsPi(pAig, pObj) ) + pObj->Value = Gia_ObjRoToRi(pAig, pObj)->Value; + } + } + } + else + { + if ( f == 0 ) + { + Gia_ManForEachObjVec( vIns, pAig, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) ); + if ( Gia_ObjIsPi(pAig, pObj) ) + pObj->Value = Gia_ManAppendCi( pFrames ); + else + pObj->Value = 0; + } + } + else + { + Gia_ManForEachObjVec( vIns, pAig, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) ); + if ( Gia_ObjIsPi(pAig, pObj) ) + pObj->Value = Gia_ManAppendCi( pFrames ); + else + pObj->Value = Gia_ObjRoToRi(pAig, pObj)->Value; + } + } + } + Gia_ManForEachObjVec( vAnds, pAig, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + pObj->Value = Gia_ManHashAnd( pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + Gia_ManForEachObjVec( vOuts, pAig, pObj, i ) + { + assert( Gia_ObjIsCo(pObj) ); + if ( Gia_ObjIsPo(pAig, pObj) ) + pObj->Value = Gia_ManAppendCo( pFrames, Gia_ObjFanin0Copy(pObj) ); + else + pObj->Value = Gia_ObjFanin0Copy(pObj); + } + } + Gia_ManFraStop( p ); + Gia_ManHashStop( pFrames ); + if ( Gia_ManCombMarkUsed(pFrames) < Gia_ManAndNum(pFrames) ) + { + pFrames = Gia_ManDupMarked( pTemp = pFrames ); + if ( pPars->fVerbose ) + printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", + Gia_ManAndNum(pTemp), Gia_ManAndNum(pFrames) ); + Gia_ManStop( pTemp ); + } + else if ( pPars->fVerbose ) + printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", + Gia_ManAndNum(pFrames), Gia_ManAndNum(pFrames) ); + return pFrames; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) +{ + Gia_Man_t * pFrames, * pTemp; + Gia_Obj_t * pObj; + int i, f; + assert( Gia_ManRegNum(pAig) > 0 ); + assert( pPars->nFrames > 0 ); + if ( pPars->fInit ) + return Gia_ManFramesInit( pAig, pPars ); + pFrames = Gia_ManStart( pPars->nFrames * Gia_ManObjNum(pAig) ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + Gia_ManHashAlloc( pFrames ); + Gia_ManConst0(pAig)->Value = 0; + for ( f = 0; f < pPars->nFrames; f++ ) + { + if ( f == 0 ) + { + Gia_ManForEachRo( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( pFrames ); + } + else + { + Gia_ManForEachRo( pAig, pObj, i ) + pObj->Value = Gia_ObjRoToRi( pAig, pObj )->Value; + } + Gia_ManForEachPi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( pFrames ); + Gia_ManForEachAnd( pAig, pObj, i ) + pObj->Value = Gia_ManHashAnd( pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCo( pFrames, Gia_ObjFanin0Copy(pObj) ); + if ( f == pPars->nFrames - 1 ) + { + Gia_ManForEachRi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCo( pFrames, Gia_ObjFanin0Copy(pObj) ); + } + else + { + Gia_ManForEachRi( pAig, pObj, i ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + } + } + Gia_ManHashStop( pFrames ); + Gia_ManFraTransformCis( pAig, pFrames->vCis ); + Gia_ManSetRegNum( pFrames, Gia_ManRegNum(pAig) ); + if ( Gia_ManCombMarkUsed(pFrames) < Gia_ManAndNum(pFrames) ) + { + pFrames = Gia_ManDupMarked( pTemp = pFrames ); + if ( pPars->fVerbose ) + printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", + Gia_ManAndNum(pTemp), Gia_ManAndNum(pFrames) ); + Gia_ManStop( pTemp ); + } + else if ( pPars->fVerbose ) + printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", + Gia_ManAndNum(pFrames), Gia_ManAndNum(pFrames) ); + return pFrames; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaFront.c b/src/aig/gia/giaFront.c new file mode 100644 index 00000000..ee9e5b5f --- /dev/null +++ b/src/aig/gia/giaFront.c @@ -0,0 +1,248 @@ +/**CFile**************************************************************** + + FileName [giaFront.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Frontier representation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaFront.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Find the next place on the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManFrontFindNext( char * pFront, int nFront, int iFront ) +{ + assert( iFront < nFront ); + for ( ; pFront[iFront]; iFront = (iFront + 1) % nFront ); + assert( pFront[iFront] == 0 ); + pFront[iFront] = 1; + return iFront; +} + +/**Function************************************************************* + + Synopsis [Transforms the frontier manager to its initial state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFrontTransform( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, * pFrontToId; // mapping of nodes into frontier variables + assert( p->nFront > 0 ); + pFrontToId = ABC_ALLOC( int, p->nFront ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + { + assert( pObj->Value == GIA_NONE ); + pObj->iDiff0 = i - pFrontToId[Gia_ObjDiff0(pObj)]; + } + else if ( Gia_ObjIsAnd(pObj) ) + { + assert( (int)pObj->Value < p->nFront ); + pObj->iDiff0 = i - pFrontToId[Gia_ObjDiff0(pObj)]; + pObj->iDiff1 = i - pFrontToId[Gia_ObjDiff1(pObj)]; + pFrontToId[pObj->Value] = i; + } + else + { + assert( (int)pObj->Value < p->nFront ); + pFrontToId[pObj->Value] = i; + } + pObj->Value = 0; + } + ABC_FREE( pFrontToId ); +} + +/**Function************************************************************* + + Synopsis [Determine the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFront( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pFanin0New, * pFanin1New, * pObjNew; + char * pFront; // places used for the frontier + int i, iLit, nCrossCut = 0, nCrossCutMax = 0; + int nCrossCutMaxInit = Gia_ManCrossCut( p ); + int iFront = 0, clk = clock(); + // set references for all objects + Gia_ManSetRefs( p ); + // start the new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + pNew->nFront = 1 + (int)((float)1.1 * nCrossCutMaxInit); + // start the frontier + pFront = ABC_CALLOC( char, pNew->nFront ); + // add constant node + Gia_ManConst0(pNew)->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); + if ( Gia_ObjValue(Gia_ManConst0(p)) == 0 ) + pFront[iFront] = 0; + else + nCrossCut = 1; + // iterate through the objects + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + if ( Gia_ObjValue(pObj) && nCrossCutMax < ++nCrossCut ) + nCrossCutMax = nCrossCut; + // create new node + iLit = Gia_ManAppendCi( pNew ); + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(iLit) ); + assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); + pObjNew->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); + // handle CIs without fanout + if ( Gia_ObjValue(pObj) == 0 ) + pFront[iFront] = 0; + continue; + } + if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjValue(pObj) == 0 ); + // create new node + iLit = Gia_ManAppendCo( pNew, 0 ); + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(iLit) ); + assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); + // get the fanin + pFanin0New = Gia_ManObj( pNew, Gia_ObjFaninId0(pObj, i) ); + assert( pFanin0New->Value != GIA_NONE ); + pObjNew->Value = GIA_NONE; + pObjNew->iDiff0 = pFanin0New->Value; + pObjNew->fCompl0 = Gia_ObjFaninC0(pObj); + // deref the fanin + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + { + pFront[pFanin0New->Value] = 0; + nCrossCut--; + } + continue; + } + if ( Gia_ObjValue(pObj) && nCrossCutMax < ++nCrossCut ) + nCrossCutMax = nCrossCut; + // create new node + pObjNew = Gia_ManAppendObj( pNew ); + assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); + // assign the first fanin + pFanin0New = Gia_ManObj( pNew, Gia_ObjFaninId0(pObj, i) ); + assert( pFanin0New->Value != GIA_NONE ); + pObjNew->iDiff0 = pFanin0New->Value; + pObjNew->fCompl0 = Gia_ObjFaninC0(pObj); + // assign the second fanin + pFanin1New = Gia_ManObj( pNew, Gia_ObjFaninId1(pObj, i) ); + assert( pFanin1New->Value != GIA_NONE ); + pObjNew->iDiff1 = pFanin1New->Value; + pObjNew->fCompl1 = Gia_ObjFaninC1(pObj); + // assign the frontier number + pObjNew->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); + // deref the fanins + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + { + pFront[pFanin0New->Value] = 0; + nCrossCut--; + } + if ( --Gia_ObjFanin1(pObj)->Value == 0 ) + { + pFront[pFanin1New->Value] = 0; + nCrossCut--; + } + // handle nodes without fanout (choice nodes) + if ( Gia_ObjValue(pObj) == 0 ) + pFront[iFront] = 0; + } + assert( pNew->nObjs == p->nObjs ); + assert( nCrossCut == 0 && nCrossCutMax == nCrossCutMaxInit ); + for ( i = 0; i < pNew->nFront; i++ ) + assert( pFront[i] == 0 ); + ABC_FREE( pFront ); +//printf( "Crosscut = %6d. Frontier = %6d. ", nCrossCutMaxInit, pNew->nFront ); +//ABC_PRT( "Time", clock() - clk ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFrontTest( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + pNew = Gia_ManFront( p ); + Gia_ManFrontTransform( pNew ); +// Gia_ManCleanValue( p ); +// Gia_ManCleanValue( pNew ); + if ( memcmp( pNew->pObjs, p->pObjs, sizeof(Gia_Obj_t) * p->nObjs ) ) + { +/* + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + pObjNew = Gia_ManObj( pNew, i ); + printf( "%5d %5d %5d %5d\n", + pObj->iDiff0, pObjNew->iDiff0, + pObj->iDiff1, pObjNew->iDiff1 ); + } +*/ + printf( "Verification failed.\n" ); + } + else + printf( "Verification successful.\n" ); + Gia_ManStop( pNew ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaGlitch.c b/src/aig/gia/giaGlitch.c new file mode 100644 index 00000000..bbc509c4 --- /dev/null +++ b/src/aig/gia/giaGlitch.c @@ -0,0 +1,743 @@ +/**CFile**************************************************************** + + FileName [giaGlitch.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Glitch simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaGlitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gli_Obj_t_ Gli_Obj_t; +struct Gli_Obj_t_ +{ + unsigned fTerm : 1; // terminal node + unsigned fPhase : 1; // value under 000 pattern + unsigned fPhase2 : 1; // value under 000 pattern + unsigned fMark : 1; // user-controlled mark + unsigned nFanins : 3; // the number of fanins + unsigned nFanouts : 25; // total number of fanouts + unsigned Handle; // ID of the node + unsigned uTruth[2]; // truth table of the node + unsigned uSimInfo; // simulation info of the node + union + { + int iFanin; // the number of fanins added + int nSwitches; // the number of switches + }; + union + { + int iFanout; // the number of fanouts added + int nGlitches; // the number of glitches ( nGlitches >= nSwitches ) + }; + int Fanios[0]; // the array of fanins/fanouts +}; + +typedef struct Gli_Man_t_ Gli_Man_t; +struct Gli_Man_t_ +{ + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) + Vec_Int_t * vCisChanged; // the changed CIs + Vec_Int_t * vAffected; // the affected nodes + Vec_Int_t * vFrontier; // the fanouts of these nodes + int nObjs; // the number of objects + int nRegs; // the number of registers + int nTravIds; // traversal ID of the network + int iObjData; // pointer to the current data + int nObjData; // the size of array to store the logic network + int * pObjData; // the internal nodes + unsigned * pSimInfoPrev; // previous values of the CIs +}; + + +static inline int Gli_ManCiNum( Gli_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Gli_ManCoNum( Gli_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Gli_ManPiNum( Gli_Man_t * p ) { return Vec_IntSize(p->vCis) - p->nRegs; } +static inline int Gli_ManPoNum( Gli_Man_t * p ) { return Vec_IntSize(p->vCos) - p->nRegs; } +static inline int Gli_ManRegNum( Gli_Man_t * p ) { return p->nRegs; } +static inline int Gli_ManObjNum( Gli_Man_t * p ) { return p->nObjs; } +static inline int Gli_ManNodeNum( Gli_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos); } + +static inline Gli_Obj_t * Gli_ManObj( Gli_Man_t * p, int v ) { return (Gli_Obj_t *)(p->pObjData + v); } +static inline Gli_Obj_t * Gli_ManCi( Gli_Man_t * p, int v ) { return Gli_ManObj( p, Vec_IntEntry(p->vCis,v) ); } +static inline Gli_Obj_t * Gli_ManCo( Gli_Man_t * p, int v ) { return Gli_ManObj( p, Vec_IntEntry(p->vCos,v) ); } +static inline Gli_Obj_t * Gli_ManPi( Gli_Man_t * p, int v ) { assert( v < Gli_ManPiNum(p) ); return Gli_ManCi( p, v ); } +static inline Gli_Obj_t * Gli_ManPo( Gli_Man_t * p, int v ) { assert( v < Gli_ManPoNum(p) ); return Gli_ManCo( p, v ); } +static inline Gli_Obj_t * Gli_ManRo( Gli_Man_t * p, int v ) { assert( v < Gli_ManRegNum(p) ); return Gli_ManCi( p, Gli_ManRegNum(p)+v ); } +static inline Gli_Obj_t * Gli_ManRi( Gli_Man_t * p, int v ) { assert( v < Gli_ManRegNum(p) ); return Gli_ManCo( p, Gli_ManRegNum(p)+v ); } + +static inline int Gli_ObjIsTerm( Gli_Obj_t * pObj ) { return pObj->fTerm; } +static inline int Gli_ObjIsCi( Gli_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 0; } +static inline int Gli_ObjIsCo( Gli_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 1; } +static inline int Gli_ObjIsNode( Gli_Obj_t * pObj ) { return!pObj->fTerm; } + +static inline int Gli_ObjFaninNum( Gli_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Gli_ObjFanoutNum( Gli_Obj_t * pObj ) { return pObj->nFanouts; } +static inline int Gli_ObjSize( Gli_Obj_t * pObj ) { return sizeof(Gli_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } + +static inline Gli_Obj_t * Gli_ObjFanin( Gli_Obj_t * pObj, int i ) { return (Gli_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); } +static inline Gli_Obj_t * Gli_ObjFanout( Gli_Obj_t * pObj, int i ) { return (Gli_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); } + +#define Gli_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Gli_ManObj(p,i)); i += Gli_ObjSize(pObj) ) +#define Gli_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Gli_ManObj(p,i)); i += Gli_ObjSize(pObj) ) if ( Gli_ObjIsTerm(pObj) ) {} else + +#define Gli_ManForEachEntry( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && (pObj = Gli_ManObj(p,Vec_IntEntry(vVec,i))); i++ ) +#define Gli_ManForEachCi( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCis)) && (pObj = Gli_ManObj(p,Vec_IntEntry(p->vCis,i))); i++ ) +#define Gli_ManForEachCo( p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(p->vCos)) && (pObj = Gli_ManObj(p,Vec_IntEntry(p->vCos,i))); i++ ) + +#define Gli_ManForEachPi( p, pObj, i ) \ + for ( i = 0; (i < Gli_ManPiNum(p)) && ((pObj) = Gli_ManCi(p, i)); i++ ) +#define Gli_ManForEachPo( p, pObj, i ) \ + for ( i = 0; (i < Gli_ManPoNum(p)) && ((pObj) = Gli_ManCo(p, i)); i++ ) +#define Gli_ManForEachRo( p, pObj, i ) \ + for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObj) = Gli_ManCi(p, Gli_ManPiNum(p)+i)); i++ ) +#define Gli_ManForEachRi( p, pObj, i ) \ + for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObj) = Gli_ManCo(p, Gli_ManPoNum(p)+i)); i++ ) +#define Gli_ManForEachRiRo( p, pObjRi, pObjRo, i ) \ + for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObjRi) = Gli_ManCo(p, Gli_ManPoNum(p)+i)) && ((pObjRo) = Gli_ManCi(p, Gli_ManPiNum(p)+i)); i++ ) + +#define Gli_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Gli_ObjFanin(pObj,i)); i++ ) +#define Gli_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Gli_ObjFanout(pObj,i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates logic network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gli_Man_t * Gli_ManAlloc( int nObjs, int nRegs, int nFanioPairs ) +{ + Gli_Man_t * p; + p = (Gli_Man_t *)ABC_CALLOC( int, (sizeof(Gli_Man_t) / 4) + (sizeof(Gli_Obj_t) / 4) * nObjs + 2 * nFanioPairs ); + p->nRegs = nRegs; + p->vCis = Vec_IntAlloc( 1000 ); + p->vCos = Vec_IntAlloc( 1000 ); + p->vCisChanged = Vec_IntAlloc( 1000 ); + p->vAffected = Vec_IntAlloc( 1000 ); + p->vFrontier = Vec_IntAlloc( 1000 ); + p->nObjData = (sizeof(Gli_Obj_t) / 4) * nObjs + 2 * nFanioPairs; + p->pObjData = (int *)(p + 1); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes logic network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManStop( Gli_Man_t * p ) +{ + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + Vec_IntFree( p->vCisChanged ); + Vec_IntFree( p->vAffected ); + Vec_IntFree( p->vFrontier ); + ABC_FREE( p->pSimInfoPrev ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Checks logic network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManPrintObjects( Gli_Man_t * p ) +{ + Gli_Obj_t * pObj, * pNext; + int i, k; + Gli_ManForEachObj( p, pObj, i ) + { + printf( "Node %d \n", pObj->Handle ); + printf( "Fanins: " ); + Gli_ObjForEachFanin( pObj, pNext, k ) + printf( "%d ", pNext->Handle ); + printf( "\n" ); + printf( "Fanouts: " ); + Gli_ObjForEachFanout( pObj, pNext, k ) + printf( "%d ", pNext->Handle ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Checks logic network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManFinalize( Gli_Man_t * p ) +{ + Gli_Obj_t * pObj; + int i; + assert( p->iObjData == p->nObjData ); + Gli_ManForEachObj( p, pObj, i ) + { + assert( pObj->iFanin == (int)pObj->nFanins ); + assert( pObj->iFanout == (int)pObj->nFanouts ); + pObj->iFanin = 0; + pObj->iFanout = 0; + } +} + +/**Function************************************************************* + + Synopsis [Creates fanin/fanout pair.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ObjAddFanin( Gli_Obj_t * pObj, Gli_Obj_t * pFanin ) +{ + assert( pObj->iFanin < (int)pObj->nFanins ); + assert( pFanin->iFanout < (int)pFanin->nFanouts ); + pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] = + pObj->Fanios[pObj->iFanin++] = pObj->Handle - pFanin->Handle; +} + +/**Function************************************************************* + + Synopsis [Allocates object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gli_Obj_t * Gli_ObjAlloc( Gli_Man_t * p, int nFanins, int nFanouts ) +{ + Gli_Obj_t * pObj; + pObj = Gli_ManObj( p, p->iObjData ); + pObj->Handle = p->iObjData; + pObj->nFanins = nFanins; + pObj->nFanouts = nFanouts; + p->iObjData += Gli_ObjSize( pObj ); + p->nObjs++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gli_ManCreateCi( Gli_Man_t * p, int nFanouts ) +{ + Gli_Obj_t * pObj; + pObj = Gli_ObjAlloc( p, 0, nFanouts ); + pObj->fTerm = 1; + Vec_IntPush( p->vCis, pObj->Handle ); + return pObj->Handle; +} + +/**Function************************************************************* + + Synopsis [Creates CO.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gli_ManCreateCo( Gli_Man_t * p, int iFanin ) +{ + Gli_Obj_t * pObj, * pFanin; + pObj = Gli_ObjAlloc( p, 1, 0 ); + pObj->fTerm = 1; + pFanin = Gli_ManObj( p, iFanin ); + Gli_ObjAddFanin( pObj, pFanin ); + pObj->fPhase = pObj->fPhase2 = pFanin->fPhase; + Vec_IntPush( p->vCos, pObj->Handle ); + return pObj->Handle; +} + +/**Function************************************************************* + + Synopsis [Creates node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gli_NodeComputeValue( Gli_Obj_t * pNode ) +{ + int i, Phase = 0; + for ( i = 0; i < (int)pNode->nFanins; i++ ) + Phase |= (Gli_ObjFanin(pNode, i)->fPhase << i); + return Aig_InfoHasBit( pNode->uTruth, Phase ); +} + +/**Function************************************************************* + + Synopsis [Creates node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gli_NodeComputeValue2( Gli_Obj_t * pNode ) +{ + int i, Phase = 0; + for ( i = 0; i < (int)pNode->nFanins; i++ ) + Phase |= (Gli_ObjFanin(pNode, i)->fPhase2 << i); + return Aig_InfoHasBit( pNode->uTruth, Phase ); +} + +/**Function************************************************************* + + Synopsis [Creates node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, unsigned * puTruth ) +{ + Gli_Obj_t * pObj, * pFanin; + int i; + assert( Vec_IntSize(vFanins) <= 6 ); + pObj = Gli_ObjAlloc( p, Vec_IntSize(vFanins), nFanouts ); + Gli_ManForEachEntry( vFanins, p, pFanin, i ) + Gli_ObjAddFanin( pObj, pFanin ); + pObj->uTruth[0] = puTruth[0]; + pObj->uTruth[1] = puTruth[Vec_IntSize(vFanins) == 6]; + pObj->fPhase = pObj->fPhase2 = Gli_NodeComputeValue( pObj ); + return pObj->Handle; +} + +/**Function************************************************************* + + Synopsis [Returns the number of switches of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gli_ObjNumSwitches( Gli_Man_t * p, int iNode ) +{ + return Gli_ManObj( p, iNode )->nSwitches; +} + +/**Function************************************************************* + + Synopsis [Returns the number of glitches of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gli_ObjNumGlitches( Gli_Man_t * p, int iNode ) +{ + return Gli_ManObj( p, iNode )->nGlitches; +} + + +/**Function************************************************************* + + Synopsis [Sets random info at the PIs and collects changed PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManSetPiRandom( Gli_Man_t * p, float PiTransProb ) +{ + Gli_Obj_t * pObj; + float Multi = 1.0 / (1 << 16); + int i; + assert( 0.0 < PiTransProb && PiTransProb < 1.0 ); + Vec_IntClear( p->vCisChanged ); + Gli_ManForEachCi( p, pObj, i ) + if ( Multi * (Aig_ManRandom(0) & 0xffff) < PiTransProb ) + { + Vec_IntPush( p->vCisChanged, pObj->Handle ); + pObj->fPhase ^= 1; + pObj->fPhase2 ^= 1; + pObj->nSwitches++; + pObj->nGlitches++; + } +} + +/**Function************************************************************* + + Synopsis [Sets random info at the PIs and collects changed PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManSetPiFromSaved( Gli_Man_t * p, int iBit ) +{ + Gli_Obj_t * pObj; + int i; + Vec_IntClear( p->vCisChanged ); + Gli_ManForEachCi( p, pObj, i ) + if ( (p->pSimInfoPrev[i] ^ pObj->uSimInfo) & (1 << iBit) ) + { + Vec_IntPush( p->vCisChanged, pObj->Handle ); + pObj->fPhase ^= 1; + pObj->fPhase2 ^= 1; + pObj->nSwitches++; + pObj->nGlitches++; + } +} + +/**Function************************************************************* + + Synopsis [Computes switching activity of each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManSwitching( Gli_Man_t * p ) +{ + Gli_Obj_t * pThis; + int i; + Gli_ManForEachNode( p, pThis, i ) + { + if ( ((int)pThis->fPhase) == Gli_NodeComputeValue(pThis) ) + continue; + pThis->fPhase ^= 1; + pThis->nSwitches++; + } +} + +/**Function************************************************************* + + Synopsis [Computes glitching activity of each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManGlitching( Gli_Man_t * p ) +{ + Gli_Obj_t * pThis, * pFanout, * pOther = Gli_ManObj(p, 41); + int i, k, Handle; +// Gli_ManForEachObj( p, pThis, i ) +// assert( pThis->fMark == 0 ); + // start the array of affected nodes + Vec_IntClear( p->vAffected ); + Vec_IntForEachEntry( p->vCisChanged, Handle, i ) + Vec_IntPush( p->vAffected, Handle ); + // iteration propagation + while ( Vec_IntSize(p->vAffected) > 0 ) + { + // compute the frontier + Vec_IntClear( p->vFrontier ); + Gli_ManForEachEntry( p->vAffected, p, pThis, i ) + { + Gli_ObjForEachFanout( pThis, pFanout, k ) + { + if ( Gli_ObjIsCo(pFanout) ) + continue; + if ( pFanout->fMark ) + continue; + pFanout->fMark = 1; + Vec_IntPush( p->vFrontier, pFanout->Handle ); + } + } + // compute the next set of affected nodes + Vec_IntClear( p->vAffected ); + Gli_ManForEachEntry( p->vFrontier, p, pThis, i ) + { + pThis->fMark = 0; + if ( ((int)pThis->fPhase2) == Gli_NodeComputeValue2(pThis) ) + continue; + pThis->fPhase2 ^= 1; + pThis->nGlitches++; + Vec_IntPush( p->vAffected, pThis->Handle ); + } + } +} + +/**Function************************************************************* + + Synopsis [Checks that the resulting values are the same.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManVerify( Gli_Man_t * p ) +{ + Gli_Obj_t * pObj; + int i; + Gli_ManForEachObj( p, pObj, i ) + { + assert( pObj->fPhase == pObj->fPhase2 ); + assert( pObj->nGlitches >= pObj->nSwitches ); + } +} + +/**Function************************************************************* + + Synopsis [Simulates one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gli_ManSimulateSeqNode( Gli_Man_t * p, Gli_Obj_t * pNode ) +{ + unsigned pSimInfos[6], Result = 0; + int nFanins = Gli_ObjFaninNum(pNode); + int i, k, Phase; + Gli_Obj_t * pFanin; + assert( nFanins <= 6 ); + Gli_ObjForEachFanin( pNode, pFanin, i ) + pSimInfos[i] = pFanin->uSimInfo; + for ( i = 0; i < 32; i++ ) + { + Phase = 0; + for ( k = 0; k < nFanins; k++ ) + if ( (pSimInfos[k] >> i) & 1 ) + Phase |= (1 << k); + if ( Aig_InfoHasBit( pNode->uTruth, Phase ) ) + Result |= (1 << i); + } + return Result; +} + +/**Function************************************************************* + + Synopsis [Simulates one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Gli_ManUpdateRandomInput( unsigned uInfo, float PiTransProb ) +{ + float Multi = 1.0 / (1 << 16); + int i; + if ( PiTransProb == 0.5 ) + return Aig_ManRandom(0); + for ( i = 0; i < 32; i++ ) + if ( Multi * (Aig_ManRandom(0) & 0xffff) < PiTransProb ) + uInfo ^= 1; + return uInfo; +} + +/**Function************************************************************* + + Synopsis [Simulates sequential network randomly for the given number of frames.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gli_ManSimulateSeqOne( Gli_Man_t * p, float PiTransProb ) +{ + Gli_Obj_t * pObj, * pObjRi, * pObjRo; + int i; + Gli_ManForEachPi( p, pObj, i ) + pObj->uSimInfo = Gli_ManUpdateRandomInput( pObj->uSimInfo, PiTransProb ); + Gli_ManForEachNode( p, pObj, i ) + pObj->uSimInfo = Gli_ManSimulateSeqNode( p, pObj ); + Gli_ManForEachRi( p, pObj, i ) + pObj->uSimInfo = Gli_ObjFanin(pObj, 0)->uSimInfo; + Gli_ManForEachRiRo( p, pObjRi, pObjRo, i ) + pObjRo->uSimInfo = pObjRi->uSimInfo; +} + +/**Function************************************************************* + + Synopsis [Simulates sequential network randomly for the given number of frames.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gli_ManSaveCiInfo( Gli_Man_t * p ) +{ + Gli_Obj_t * pObj; + int i; + if ( p->pSimInfoPrev == NULL ) + p->pSimInfoPrev = ABC_ALLOC( unsigned, Gli_ManCiNum(p) ); + Gli_ManForEachCi( p, pObj, i ) + p->pSimInfoPrev[i] = pObj->uSimInfo; +} + +/**Function************************************************************* + + Synopsis [Simulates sequential network randomly for the given number of frames.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManSimulateSeqPref( Gli_Man_t * p, int nPref ) +{ + Gli_Obj_t * pObj; + int i, f; + Gli_ManForEachRo( p, pObj, i ) + pObj->uSimInfo = 0; + for ( f = 0; f < nPref; f++ ) + Gli_ManSimulateSeqOne( p, 0.5 ); +} + +/**Function************************************************************* + + Synopsis [Computes glitching activity of each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb, int fVerbose ) +{ + int i, k, clk = clock(); + Aig_ManRandom( 1 ); + Gli_ManFinalize( p ); + if ( p->nRegs == 0 ) + { + for ( i = 0; i < nPatterns; i++ ) + { + Gli_ManSetPiRandom( p, PiTransProb ); + Gli_ManSwitching( p ); + Gli_ManGlitching( p ); +// Gli_ManVerify( p ); + } + } + else + { + Gli_ManSimulateSeqPref( p, 16 ); + for ( k = Aig_BitWordNum(nPatterns) - 1; k >= 0; k-- ) + { + Gli_ManSaveCiInfo( p ); + Gli_ManSimulateSeqOne( p, PiTransProb ); + for ( i = 0; i < 32; i++ ) + { + Gli_ManSetPiFromSaved( p, i ); + Gli_ManSwitching( p ); + Gli_ManGlitching( p ); +// Gli_ManVerify( p ); + } + } + } + if ( fVerbose ) + { + printf( "\nSimulated %d patterns. ", nPatterns ); + ABC_PRM( "Memory", 4*p->nObjData ); + ABC_PRT( "Time", clock() - clk ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c new file mode 100644 index 00000000..c2bde6ba --- /dev/null +++ b/src/aig/gia/giaHash.c @@ -0,0 +1,541 @@ +/**CFile**************************************************************** + + FileName [giaHash.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Structural hashing.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaHash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Hashing the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManHashOne( int iLit0, int iLit1, int TableSize ) +{ + unsigned Key = 0; + assert( iLit0 < iLit1 ); + Key ^= Gia_Lit2Var(iLit0) * 7937; + Key ^= Gia_Lit2Var(iLit1) * 2971; + Key ^= Gia_LitIsCompl(iLit0) * 911; + Key ^= Gia_LitIsCompl(iLit1) * 353; + return (int)(Key % TableSize); +} + +/**Function************************************************************* + + Synopsis [Returns the place where this node is stored (or should be stored).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ) + if ( Gia_ObjFaninLit0p(p, pThis) == iLit0 && Gia_ObjFaninLit1p(p, pThis) == iLit1 ) + break; + return pPlace; +} + +/**Function************************************************************* + + Synopsis [Starts the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManHashAlloc( Gia_Man_t * p ) +{ + assert( p->pHTable == NULL ); + p->nHTable = Aig_PrimeCudd( p->nObjsAlloc / 3 ); + p->pHTable = ABC_CALLOC( int, p->nHTable ); +} + +/**Function************************************************************* + + Synopsis [Starts the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManHashStart( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int * pPlace, i; + Gia_ManHashAlloc( p ); + Gia_ManCleanValue( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + pPlace = Gia_ManHashFind( p, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) ); + assert( *pPlace == 0 ); + *pPlace = Gia_Var2Lit( i, 0 ); + } +} + +/**Function************************************************************* + + Synopsis [Stops the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManHashStop( Gia_Man_t * p ) +{ + ABC_FREE( p->pHTable ); + p->nHTable = 0; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManHashResize( Gia_Man_t * p ) +{ + Gia_Obj_t * pThis; + int * pHTableOld, * pPlace; + int nHTableOld, iNext, Counter, Counter2, i; + assert( p->pHTable != NULL ); + // replace the table + pHTableOld = p->pHTable; + nHTableOld = p->nHTable; + p->nHTable = Aig_PrimeCudd( 2 * Gia_ManAndNum(p) ); + p->pHTable = ABC_CALLOC( int, p->nHTable ); + // rehash the entries from the old table + Counter = 0; + for ( i = 0; i < nHTableOld; i++ ) + for ( pThis = (pHTableOld[i]? Gia_ManObj(p, Gia_Lit2Var(pHTableOld[i])) : NULL), + iNext = (pThis? pThis->Value : 0); + pThis; pThis = (iNext? Gia_ManObj(p, Gia_Lit2Var(iNext)) : NULL), + iNext = (pThis? pThis->Value : 0) ) + { + pThis->Value = 0; + pPlace = Gia_ManHashFind( p, Gia_ObjFaninLit0p(p, pThis), Gia_ObjFaninLit1p(p, pThis) ); + assert( *pPlace == 0 ); // should not be there + *pPlace = Gia_Var2Lit( Gia_ObjId(p, pThis), 0 ); + assert( *pPlace != 0 ); + Counter++; + } + Counter2 = Gia_ManAndNum(p); + assert( Counter == Counter2 ); + ABC_FREE( pHTableOld ); +} + + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are control and data inputs of a MUX.] + + Description [If the node is a MUX, returns the control variable C. + Assigns nodes T and E to be the then and else variables of the MUX. + Node C is never complemented. Nodes T and E can be complemented. + This function also recognizes EXOR/NEXOR gates as MUXes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ObjRecognizeMuxTwo( Gia_Obj_t * pNode0, Gia_Obj_t * pNode1, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ) +{ + assert( !Gia_IsComplement(pNode0) ); + assert( !Gia_IsComplement(pNode1) ); + // find the control variable + if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + assert( 0 ); // this is not MUX + return NULL; +} + + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManHashAndP( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ) +{ + return Gia_ObjFromLit( p, Gia_ManHashAnd( p, Gia_ObjToLit(p, p0), Gia_ObjToLit(p, p1) ) ); +} + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [http://fmv.jku.at/papers/BrummayerBiere-MEMICS06.pdf] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManAddStrash( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ) +{ + Gia_Obj_t * pNode0, * pNode1, * pFanA, * pFanB, * pFanC, * pFanD; + assert( p->fAddStrash ); + if ( !Gia_ObjIsAnd(Gia_Regular(p0)) && !Gia_ObjIsAnd(Gia_Regular(p1)) ) + return NULL; + pNode0 = Gia_Regular(p0); + pNode1 = Gia_Regular(p1); + pFanA = Gia_ObjChild0(pNode0); + pFanB = Gia_ObjChild1(pNode0); + pFanC = Gia_ObjChild0(pNode1); + pFanD = Gia_ObjChild1(pNode1); + if ( Gia_IsComplement(p0) ) + { + if ( pFanA == Gia_Not(p1) || pFanB == Gia_Not(p1) ) + return p1; + if ( pFanB == p1 ) + return Gia_ManHashAndP( p, Gia_Not(pFanA), pFanB ); + if ( pFanA == p1 ) + return Gia_ManHashAndP( p, Gia_Not(pFanB), pFanA ); + } + else + { + if ( pFanA == Gia_Not(p1) || pFanB == Gia_Not(p1) ) + return Gia_ManConst0(p); + if ( pFanA == p1 || pFanB == p1 ) + return p0; + } + if ( Gia_IsComplement(p1) ) + { + if ( pFanC == Gia_Not(p0) || pFanD == Gia_Not(p0) ) + return p0; + if ( pFanD == p0 ) + return Gia_ManHashAndP( p, Gia_Not(pFanC), pFanD ); + if ( pFanC == p0 ) + return Gia_ManHashAndP( p, Gia_Not(pFanD), pFanC ); + } + else + { + if ( pFanC == Gia_Not(p0) || pFanD == Gia_Not(p0) ) + return Gia_ManConst0(p); + if ( pFanC == p0 || pFanD == p0 ) + return p1; + } + if ( !Gia_IsComplement(p0) && !Gia_IsComplement(p1) ) + { + if ( pFanA == Gia_Not(pFanC) || pFanA == Gia_Not(pFanD) || pFanB == Gia_Not(pFanC) || pFanB == Gia_Not(pFanD) ) + return Gia_ManConst0(p); + if ( pFanA == pFanC || pFanB == pFanC ) + return Gia_ManHashAndP( p, p0, pFanD ); + if ( pFanB == pFanC || pFanB == pFanD ) + return Gia_ManHashAndP( p, pFanA, p1 ); + if ( pFanA == pFanD || pFanB == pFanD ) + return Gia_ManHashAndP( p, p0, pFanC ); + if ( pFanA == pFanC || pFanA == pFanD ) + return Gia_ManHashAndP( p, pFanB, p1 ); + } + else if ( Gia_IsComplement(p0) && !Gia_IsComplement(p1) ) + { + if ( pFanA == Gia_Not(pFanC) || pFanA == Gia_Not(pFanD) || pFanB == Gia_Not(pFanC) || pFanB == Gia_Not(pFanD) ) + return p1; + if ( pFanB == pFanC || pFanB == pFanD ) + return Gia_ManHashAndP( p, Gia_Not(pFanA), p1 ); + if ( pFanA == pFanC || pFanA == pFanD ) + return Gia_ManHashAndP( p, Gia_Not(pFanB), p1 ); + } + else if ( !Gia_IsComplement(p0) && Gia_IsComplement(p1) ) + { + if ( pFanC == Gia_Not(pFanA) || pFanC == Gia_Not(pFanB) || pFanD == Gia_Not(pFanA) || pFanD == Gia_Not(pFanB) ) + return p0; + if ( pFanD == pFanA || pFanD == pFanB ) + return Gia_ManHashAndP( p, Gia_Not(pFanC), p0 ); + if ( pFanC == pFanA || pFanC == pFanB ) + return Gia_ManHashAndP( p, Gia_Not(pFanD), p0 ); + } + else // if ( Gia_IsComplement(p0) && Gia_IsComplement(p1) ) + { + if ( pFanA == pFanD && pFanB == Gia_Not(pFanC) ) + return Gia_Not(pFanA); + if ( pFanB == pFanC && pFanA == Gia_Not(pFanD) ) + return Gia_Not(pFanB); + if ( pFanA == pFanC && pFanB == Gia_Not(pFanD) ) + return Gia_Not(pFanA); + if ( pFanB == pFanD && pFanA == Gia_Not(pFanC) ) + return Gia_Not(pFanB); + } + if ( !Gia_IsComplement(p0) || !Gia_IsComplement(p1) ) + return NULL; + if ( !Gia_ObjIsAnd(pNode0) || !Gia_ObjIsAnd(pNode1) ) + return NULL; + if ( (Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1))) ) + { + Gia_Obj_t * pNodeC, * pNodeT, * pNodeE; + int fCompl; + pNodeC = Gia_ObjRecognizeMuxTwo( pNode0, pNode1, &pNodeT, &pNodeE ); + // using non-standard canonical rule for MUX (d0 is not compl; d1 may be compl) + if ( (fCompl = Gia_IsComplement(pNodeE)) ) + { + pNodeE = Gia_Not(pNodeE); + pNodeT = Gia_Not(pNodeT); + } + pNode0 = Gia_ManHashAndP( p, Gia_Not(pNodeC), pNodeE ); + pNode1 = Gia_ManHashAndP( p, pNodeC, pNodeT ); + return Gia_NotCond( Gia_ManHashAndP( p, pNode0, pNode1 ), !fCompl ); + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManHashAnd( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Gia_LitNot(iLit1) ) + return 0; + if ( (p->nObjs & 0xFF) == 0 && 2 * p->nHTable < Gia_ManAndNum(p) ) + Gia_ManHashResize( p ); + if ( p->fAddStrash ) + { + Gia_Obj_t * pObj = Gia_ManAddStrash( p, Gia_ObjFromLit(p, iLit0), Gia_ObjFromLit(p, iLit1) ); + if ( pObj != NULL ) + return Gia_ObjToLit( p, pObj ); + } + if ( iLit0 > iLit1 ) + iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1; + { + int * pPlace = Gia_ManHashFind( p, iLit0, iLit1 ); + if ( *pPlace ) + return *pPlace; + if ( p->nObjs < p->nObjsAlloc ) + return *pPlace = Gia_ManAppendAnd( p, iLit0, iLit1 ); + else + { + int iNode = Gia_ManAppendAnd( p, iLit0, iLit1 ); + pPlace = Gia_ManHashFind( p, iLit0, iLit1 ); + assert( *pPlace == 0 ); + return *pPlace = iNode; + } + } +} + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Gia_LitNot(iLit1) ) + return 0; + if ( iLit0 > iLit1 ) + iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1; + { + int * pPlace = Gia_ManHashFind( p, iLit0, iLit1 ); + if ( *pPlace ) + return *pPlace; + return -1; + } +} + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManHashXor( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + int fCompl = Gia_LitIsCompl(iLit0) ^ Gia_LitIsCompl(iLit1); + int iTemp0 = Gia_ManHashAnd( p, Gia_LitRegular(iLit0), Gia_LitNot(Gia_LitRegular(iLit1)) ); + int iTemp1 = Gia_ManHashAnd( p, Gia_LitRegular(iLit1), Gia_LitNot(Gia_LitRegular(iLit0)) ); + return Gia_LitNotCond( Gia_ManHashAnd( p, Gia_LitNot(iTemp0), Gia_LitNot(iTemp1) ), !fCompl ); +} + +/**Function************************************************************* + + Synopsis [Rehashes AIG with mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManRehash( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +// printf( "Top gate is %s\n", Gia_ObjFaninC0(Gia_ManCo(pNew, 0))? "OR" : "AND" ); + return pNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaLogic.c b/src/aig/gia/giaLogic.c new file mode 100644 index 00000000..825cec02 --- /dev/null +++ b/src/aig/gia/giaLogic.c @@ -0,0 +1,725 @@ +/**CFile**************************************************************** + + FileName [giaLogic.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Logic network derived from AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaLogic.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <math.h> +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Log_Obj_t_ Log_Obj_t; +struct Log_Obj_t_ +{ + unsigned fTerm : 1; // terminal node (CI/CO) + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanins : 28; // the number of fanins + unsigned nFanouts; // the number of fanouts + unsigned hHandle; // the handle of the node + union { + unsigned TravId; // user-specified value + unsigned iFanin; + }; + union { + unsigned Value; // user-specified value + unsigned iFanout; + }; + int Fanios[0]; // the array of fanins/fanouts +}; + +typedef struct Log_Man_t_ Log_Man_t; +struct Log_Man_t_ +{ + Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) + int nObjs; // the number of objects + int nNodes; // the number of nodes + int nTravIds; // traversal ID of the network + int * pObjData; // the array containing data for objects + int nObjData; // the size of array to store the logic network +}; + +static inline int Log_ManCiNum( Log_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Log_ManCoNum( Log_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Log_ManObjNum( Log_Man_t * p ) { return p->nObjs; } +static inline int Log_ManNodeNum( Log_Man_t * p ) { return p->nNodes; } + +static inline Log_Obj_t * Log_ManObj( Log_Man_t * p, unsigned hHandle ) { return (Log_Obj_t *)(p->pObjData + hHandle); } +static inline Log_Obj_t * Log_ManCi( Log_Man_t * p, int i ) { return Log_ManObj( p, Vec_IntEntry(p->vCis,i) ); } +static inline Log_Obj_t * Log_ManCo( Log_Man_t * p, int i ) { return Log_ManObj( p, Vec_IntEntry(p->vCos,i) ); } + +static inline int Log_ObjIsTerm( Log_Obj_t * pObj ) { return pObj->fTerm; } +static inline int Log_ObjIsCi( Log_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 0; } +static inline int Log_ObjIsCo( Log_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 1; } +static inline int Log_ObjIsNode( Log_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins > 0; } +static inline int Log_ObjIsConst0( Log_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins == 0; } + +static inline int Log_ObjFaninNum( Log_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Log_ObjFanoutNum( Log_Obj_t * pObj ) { return pObj->nFanouts; } +static inline int Log_ObjSize( Log_Obj_t * pObj ) { return sizeof(Log_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } +static inline Log_Obj_t * Log_ObjFanin( Log_Obj_t * pObj, int i ) { return (Log_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); } +static inline Log_Obj_t * Log_ObjFanout( Log_Obj_t * pObj, int i ) { return (Log_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); } + +static inline void Log_ManResetTravId( Log_Man_t * p ) { extern void Log_ManCleanTravId( Log_Man_t * p ); Log_ManCleanTravId( p ); p->nTravIds = 1; } +static inline void Log_ManIncrementTravId( Log_Man_t * p ) { p->nTravIds++; } +static inline void Log_ObjSetTravId( Log_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; } +static inline void Log_ObjSetTravIdCurrent( Log_Man_t * p, Log_Obj_t * pObj ) { pObj->TravId = p->nTravIds; } +static inline void Log_ObjSetTravIdPrevious( Log_Man_t * p, Log_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1; } +static inline int Log_ObjIsTravIdCurrent( Log_Man_t * p, Log_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); } +static inline int Log_ObjIsTravIdPrevious( Log_Man_t * p, Log_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); } + +#define Log_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Log_ManObj(p,i)); i += Log_ObjSize(pObj) ) +#define Log_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Log_ManObj(p,i)); i += Log_ObjSize(pObj) ) if ( Log_ObjIsTerm(pObj) ) {} else +#define Log_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Log_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Log_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Log_ObjFanin(pObj,i)); i++ ) +#define Log_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Log_ObjFanout(pObj,i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collect the fanin IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + if ( pObj->fMark0 ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Log_ManCollectSuper( p, Gia_ObjFanin0(pObj), vSuper ); + Log_ManCollectSuper( p, Gia_ObjFanin1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCreateRefsSpecial( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + Gia_Obj_t * pObjC, * pObjD0, * pObjD1; + int i; + assert( p->pRefs == NULL ); + Gia_ManCleanMark0( p ); + Gia_ManCreateRefs( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + assert( pObj->fMark0 == 0 ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + // skip nodes whose fanins are PIs or are already marked + if ( Gia_ObjIsCi(pFan0) || pFan0->fMark0 || + Gia_ObjIsCi(pFan1) || pFan1->fMark0 ) + continue; + // skip nodes that are not MUX type + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + // the node is MUX type, mark it and its fanins + pObj->fMark0 = 1; + pFan0->fMark0 = 1; + pFan1->fMark0 = 1; + // deref the control + pObjC = Gia_ObjRecognizeMux( pObj, &pObjD1, &pObjD0 ); + Gia_ObjRefDec( p, Gia_Regular(pObjC) ); + if ( Gia_Regular(pObjD0) == Gia_Regular(pObjD1) ) + Gia_ObjRefDec( p, Gia_Regular(pObjD0) ); + } + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjRefs(p, pObj) > 0 ); + Gia_ManCleanMark0( p ); +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManTransformRefs( Gia_Man_t * p, int * pnObjs, int * pnFanios ) +{ + Vec_Int_t * vSuper; + Gia_Obj_t * pObj, * pFanin; + int i, k, Counter; + assert( p->pRefs != NULL ); + + // mark nodes to be used in the logic network + Gia_ManCleanMark0( p ); + Gia_ManConst0(p)->fMark0 = 1; + // mark the inputs + Gia_ManForEachCi( p, pObj, i ) + pObj->fMark0 = 1; + // mark those nodes that have ref count more than 1 + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjRefs(p, pObj) > 1); + // mark the output drivers + Gia_ManForEachCoDriver( p, pObj, i ) + pObj->fMark0 = 1; + + // count the number of nodes + Counter = 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += pObj->fMark0; + *pnObjs = Counter + Gia_ManCoNum(p); + + // reset the references + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + // reference from internal nodes + Counter = 0; + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( pObj->fMark0 == 0 ) + continue; + Vec_IntClear( vSuper ); + pObj->fMark0 = 0; + Log_ManCollectSuper( p, pObj, vSuper ); + pObj->fMark0 = 1; + Gia_ManForEachObjVec( vSuper, p, pFanin, k ) + { + assert( pFanin->fMark0 ); + Gia_ObjRefInc( p, pFanin ); + } + Counter += Vec_IntSize( vSuper ); + } + Vec_IntFree( vSuper ); + // reference from outputs + Gia_ManForEachCoDriver( p, pObj, i ) + { + assert( pObj->fMark0 ); + Gia_ObjRefInc( p, pObj ); + } + *pnFanios = Counter + Gia_ManCoNum(p); +} + +/**Function************************************************************* + + Synopsis [Creates fanin/fanout pair.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ObjAddFanin( Log_Obj_t * pObj, Log_Obj_t * pFanin ) +{ + assert( pObj->iFanin < pObj->nFanins ); + assert( pFanin->iFanout < pFanin->nFanouts ); + pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] = + pObj->Fanios[pObj->iFanin++] = pObj->hHandle - pFanin->hHandle; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Log_Man_t * Log_ManStart( Gia_Man_t * pGia ) +{ + Log_Man_t * p; + Log_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj, * pFanin; + Vec_Int_t * vSuper; + int nObjs, nFanios; + int i, k, hHandle = 0; + // prepare the AIG +// Gia_ManCreateRefs( pGia ); + Log_ManCreateRefsSpecial( pGia ); + Log_ManTransformRefs( pGia, &nObjs, &nFanios ); + Gia_ManFillValue( pGia ); + // create logic network + p = ABC_CALLOC( Log_Man_t, 1 ); + p->pGia = pGia; + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Log_Obj_t) / 4) * nObjs + 2 * nFanios; + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nNodes++; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) + { + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fTerm = 1; + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nObjs++; + } + // create internal nodes + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( pGia, pObj, i ) + { + if ( pObj->fMark0 == 0 ) + { + assert( Gia_ObjRefs( pGia, pObj ) == 0 ); + continue; + } + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + // collect fanins + Vec_IntClear( vSuper ); + pObj->fMark0 = 0; + Log_ManCollectSuper( pGia, pObj, vSuper ); + pObj->fMark0 = 1; + // create node object + pObj->Value = hHandle; + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = Vec_IntSize( vSuper ); + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + Gia_ManForEachObjVec( vSuper, pGia, pFanin, k ) + { + pFanLog = Log_ManObj( p, Gia_ObjValue(pFanin) ); + Log_ObjAddFanin( pObjLog, pFanLog ); + } + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nNodes++; + p->nObjs++; + } + Vec_IntFree( vSuper ); + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fTerm = 1; + // add fanins + pFanLog = Log_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Log_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nObjs++; + } + Gia_ManCleanMark0( pGia ); + assert( nObjs == p->nObjs ); + assert( hHandle == p->nObjData ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Log_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManPrintStats( Log_Man_t * p ) +{ +// if ( p->pName ) +// printf( "%8s : ", p->pName ); + printf( "i/o =%7d/%7d ", Log_ManCiNum(p), Log_ManCoNum(p) ); +// if ( Log_ManRegNum(p) ) +// printf( "ff =%7d ", Log_ManRegNum(p) ); + printf( "node =%8d ", Log_ManNodeNum(p) ); +// printf( "lev =%5d ", Log_ManLevelNum(p) ); +// printf( "cut =%5d ", Log_ManCrossCut(p) ); + printf( "mem =%5.2f Mb", 4.0*p->nObjData/(1<<20) ); +// printf( "obj =%5d ", Log_ManObjNum(p) ); + printf( "\n" ); + +// Log_ManSatExperiment( p ); +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManStop( Log_Man_t * p ) +{ + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pObjData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCleanTravId( Log_Man_t * p ) +{ + Log_Obj_t * pObj; + int i; + Log_ManForEachObj( p, pObj, i ) + pObj->TravId = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCleanValue( Log_Man_t * p ) +{ + Log_Obj_t * pObj; + int i; + Log_ManForEachObj( p, pObj, i ) + pObj->Value = 0; +} + +/**Function************************************************************* + + Synopsis [Prints the distribution of fanins/fanouts in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManPrintFanio( Log_Man_t * p ) +{ + char Buffer[100]; + Log_Obj_t * pNode; + Vec_Int_t * vFanins, * vFanouts; + int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll; + int i, k, nSizeMax; + + // determine the largest fanin and fanout + nFaninsMax = nFanoutsMax = 0; + nFaninsAll = nFanoutsAll = 0; + Log_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; // skip const 0 obj + nFanins = Log_ObjFaninNum(pNode); + nFanouts = Log_ObjFanoutNum(pNode); + nFaninsAll += nFanins; + nFanoutsAll += nFanouts; + nFaninsMax = ABC_MAX( nFaninsMax, nFanins ); + nFanoutsMax = ABC_MAX( nFanoutsMax, nFanouts ); + } + + // allocate storage for fanin/fanout numbers + nSizeMax = AIG_MAX( 10 * (Aig_Base10Log(nFaninsMax) + 1), 10 * (Aig_Base10Log(nFanoutsMax) + 1) ); + vFanins = Vec_IntStart( nSizeMax ); + vFanouts = Vec_IntStart( nSizeMax ); + + // count the number of fanins and fanouts + Log_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; // skip const 0 obj + nFanins = Log_ObjFaninNum(pNode); + nFanouts = Log_ObjFanoutNum(pNode); + + if ( nFanins < 10 ) + Vec_IntAddToEntry( vFanins, nFanins, 1 ); + else if ( nFanins < 100 ) + Vec_IntAddToEntry( vFanins, 10 + nFanins/10, 1 ); + else if ( nFanins < 1000 ) + Vec_IntAddToEntry( vFanins, 20 + nFanins/100, 1 ); + else if ( nFanins < 10000 ) + Vec_IntAddToEntry( vFanins, 30 + nFanins/1000, 1 ); + else if ( nFanins < 100000 ) + Vec_IntAddToEntry( vFanins, 40 + nFanins/10000, 1 ); + else if ( nFanins < 1000000 ) + Vec_IntAddToEntry( vFanins, 50 + nFanins/100000, 1 ); + else if ( nFanins < 10000000 ) + Vec_IntAddToEntry( vFanins, 60 + nFanins/1000000, 1 ); + + if ( nFanouts < 10 ) + Vec_IntAddToEntry( vFanouts, nFanouts, 1 ); + else if ( nFanouts < 100 ) + Vec_IntAddToEntry( vFanouts, 10 + nFanouts/10, 1 ); + else if ( nFanouts < 1000 ) + Vec_IntAddToEntry( vFanouts, 20 + nFanouts/100, 1 ); + else if ( nFanouts < 10000 ) + Vec_IntAddToEntry( vFanouts, 30 + nFanouts/1000, 1 ); + else if ( nFanouts < 100000 ) + Vec_IntAddToEntry( vFanouts, 40 + nFanouts/10000, 1 ); + else if ( nFanouts < 1000000 ) + Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 ); + else if ( nFanouts < 10000000 ) + Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 ); + } + + printf( "The distribution of fanins and fanouts in the network:\n" ); + printf( " Number Nodes with fanin Nodes with fanout\n" ); + for ( k = 0; k < nSizeMax; k++ ) + { + if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) + continue; + if ( k < 10 ) + printf( "%15d : ", k ); + else + { + sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + printf( "%15s : ", Buffer ); + } + if ( vFanins->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanins->pArray[k] ); + printf( " " ); + if ( vFanouts->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanouts->pArray[k] ); + printf( "\n" ); + } + Vec_IntFree( vFanins ); + Vec_IntFree( vFanouts ); + + printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f.\n", + nFaninsMax, 1.0*nFaninsAll/Log_ManNodeNum(p), + nFanoutsMax, 1.0*nFanoutsAll/Log_ManNodeNum(p) ); +} + +/**Function************************************************************* + + Synopsis [Computes the distance from the given object] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Log_ManComputeDistance( Log_Man_t * p, Log_Obj_t * pPivot ) +{ + Vec_Int_t * vThis, * vNext, * vTemp; + Log_Obj_t * pThis, * pNext; + int i, k, d, nVisited = 0; +// assert( Log_ObjIsTerm(pPivot) ); + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + Log_ManIncrementTravId( p ); + Log_ObjSetTravIdCurrent( p, pPivot ); + Vec_IntPush( vThis, pPivot->hHandle ); + for ( d = 0; Vec_IntSize(vThis) > 0; d++ ) + { + nVisited += Vec_IntSize(vThis); + Vec_IntClear( vNext ); + Log_ManForEachObjVec( vThis, p, pThis, i ) + { + Log_ObjForEachFanin( pThis, pNext, k ) + { + if ( Log_ObjIsTravIdCurrent(p, pNext) ) + continue; + Log_ObjSetTravIdCurrent(p, pNext); + Vec_IntPush( vNext, pNext->hHandle ); + nVisited += !Log_ObjIsTerm(pNext); + } + Log_ObjForEachFanout( pThis, pNext, k ) + { + if ( Log_ObjIsTravIdCurrent(p, pNext) ) + continue; + Log_ObjSetTravIdCurrent(p, pNext); + Vec_IntPush( vNext, pNext->hHandle ); + nVisited += !Log_ObjIsTerm(pNext); + } + } + vTemp = vThis; vThis = vNext; vNext = vTemp; + } + Vec_IntFree( vThis ); + Vec_IntFree( vNext ); + // check if there are several strongly connected components +// if ( nVisited < Log_ManNodeNum(p) ) +// printf( "Visited less nodes (%d) than present (%d).\n", nVisited, Log_ManNodeNum(p) ); + return d; +} + +/**Function************************************************************* + + Synopsis [Traverses from the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestDistanceInternal( Log_Man_t * p ) +{ + int nAttempts = 20; + int i, iNode, Dist, clk; + Log_Obj_t * pPivot, * pNext; + Aig_ManRandom( 1 ); + Log_ManResetTravId( p ); + // compute distances from several randomly selected PIs + clk = clock(); + printf( "From inputs: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Log_ManCiNum(p); + pPivot = Log_ManCi( p, iNode ); + if ( Log_ObjFanoutNum(pPivot) == 0 ) + { i--; continue; } + pNext = Log_ObjFanout( pPivot, 0 ); + if ( !Log_ObjIsNode(pNext) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); + // compute distances from several randomly selected POs + clk = clock(); + printf( "From outputs: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Log_ManCoNum(p); + pPivot = Log_ManCo( p, iNode ); + pNext = Log_ObjFanin( pPivot, 0 ); + if ( !Log_ObjIsNode(pNext) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); + // compute distances from several randomly selected nodes + clk = clock(); + printf( "From nodes: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Gia_ManObjNum(p->pGia); + if ( !~Gia_ManObj(p->pGia, iNode)->Value ) + { i--; continue; } + pPivot = Log_ManObj( p, Gia_ManObj(p->pGia, iNode)->Value ); + if ( !Log_ObjIsNode(pPivot) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestDistance( Gia_Man_t * pGia ) +{ + Log_Man_t * p; + int clk = clock(); + p = Log_ManStart( pGia ); +// Log_ManPrintFanio( p ); + Log_ManPrintStats( p ); +ABC_PRT( "Time", clock() - clk ); + Gia_ManTestDistanceInternal( p ); + Log_ManStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c new file mode 100644 index 00000000..e6e45cb5 --- /dev/null +++ b/src/aig/gia/giaMan.c @@ -0,0 +1,203 @@ +/**CFile**************************************************************** + + FileName [giaMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Package manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManStart( int nObjsMax ) +{ + Gia_Man_t * p; + assert( nObjsMax > 0 ); + p = ABC_CALLOC( Gia_Man_t, 1 ); + p->nObjsAlloc = nObjsMax; + p->pObjs = ABC_CALLOC( Gia_Obj_t, nObjsMax ); + p->pObjs->iDiff0 = p->pObjs->iDiff1 = GIA_NONE; + p->nObjs = 1; + p->vCis = Vec_IntAlloc( nObjsMax / 10 ); + p->vCos = Vec_IntAlloc( nObjsMax / 10 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStop( Gia_Man_t * p ) +{ + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pFanData ); + ABC_FREE( p->pReprs ); + ABC_FREE( p->pName ); + ABC_FREE( p->pRefs ); + ABC_FREE( p->pLevels ); + ABC_FREE( p->pHTable ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintStats( Gia_Man_t * p ) +{ + if ( p->pName ) + printf( "%8s : ", p->pName ); + printf( "i/o =%7d/%7d ", Gia_ManPiNum(p), Gia_ManPoNum(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) ); +// printf( "obj =%5d ", Gia_ManObjNum(p) ); + printf( "\n" ); + +// Gia_ManSatExperiment( p ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintStatsShort( Gia_Man_t * p ) +{ + printf( "i/o =%7d/%7d ", Gia_ManPiNum(p), Gia_ManPoNum(p) ); +// printf( "ff =%7d ", Gia_ManRegNum(p) ); + printf( "and =%8d ", Gia_ManAndNum(p) ); + printf( "lev =%5d ", Gia_ManLevelNum(p) ); + printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintMiterStatus( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pChild; + int i, nSat = 0, nUnsat = 0, nUndec = 0, iOut = -1; + Gia_ManForEachPo( p, pObj, i ) + { + pChild = Gia_ObjChild0(pObj); + // check if the output is constant 0 + if ( pChild == Gia_ManConst0(p) ) + nUnsat++; + // check if the output is constant 1 + else if ( pChild == Gia_ManConst1(p) ) + { + nSat++; + if ( iOut == -1 ) + iOut = i; + } + // check if the output is a primary input + else if ( Gia_ObjIsPi(p, Gia_Regular(pChild)) ) + { + nSat++; + if ( iOut == -1 ) + iOut = i; + } +/* + // check if the output is 1 for the 0000 pattern + else if ( Gia_Regular(pChild)->fPhase != (unsigned)Gia_IsComplement(pChild) ) + { + nSat++; + if ( iOut == -1 ) + iOut = i; + } +*/ + else + nUndec++; + } + printf( "Outputs = %7d. Unsat = %7d. Sat = %7d. Undec = %7d.\n", + Gia_ManPoNum(p), nUnsat, nSat, nUndec ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ) +{ + assert( p->nRegs == 0 ); + p->nRegs = nRegs; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaProp.c b/src/aig/gia/giaProp.c new file mode 100644 index 00000000..1d9ed8cf --- /dev/null +++ b/src/aig/gia/giaProp.c @@ -0,0 +1,171 @@ +/**CFile**************************************************************** + + FileName [giaProp.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Constraint propagation on the AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaProp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define GIA_SAT_SHIFT 12 +#define GIA_ROOT_MASK +#define GIA_PATH00_MASK +#define GIA_PATH10_MASK +#define GIA_PATH20_MASK +#define GIA_PATH30_MASK +#define GIA_PATH00_MASK +#define GIA_PATH10_MASK +#define GIA_PATH20_MASK +#define GIA_PATH30_MASK + +static inline int Gia_SatObjIsRoot( Gia_Obj_t * p ) { return 0; } +static inline int Gia_SatObjXorRoot( Gia_Obj_t * p ) { return 0; } + + +static inline int Gia_SatObjIsAssigned( Gia_Obj_t * p ) { return 0; } +static inline int Gia_SatObjIsHeld( Gia_Obj_t * p ) { return 0; } +static inline int Gia_SatObjValue( Gia_Obj_t * p ) { return 0; } + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks if the give cut is satisfied.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_SatPathCheckCutSat_rec( Gia_Obj_t * p, int fCompl ) +{ + if ( Gia_SatObjIsRoot(p) ) + return Gia_ObjIsAssigned(p) && Gia_SatObjValue(p) == fCompl; + if ( Gia_SatObjPath0(p) && !Gia_SatPathCheckCutSat_rec( Gia_ObjFanin0(p), fCompl ^ Gia_ObjFaninC0(p) ) ) + return 0; + if ( Gia_SatObjPath1(p) && !Gia_SatPathCheckCutSat_rec( Gia_ObjFanin1(p), fCompl ^ Gia_ObjFaninC1(p) ) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Checks if the give cut is satisfied.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_SatPathCheckCutSat( Gia_Obj_t * p ) +{ + int RetValue; + assert( Gia_SatObjIsRoot(p) ); + Gia_SatObjXorRoot(p); + RetValue = Gia_SatPathCheckCutSat_rec( p ); + Gia_SatObjXorRoot(p); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Unbinds literals on the path.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_SatPathUnbind_rec( Gia_Obj_t * p ) +{ +} + +/**Function************************************************************* + + Synopsis [Creates a feasible path from the node to a terminal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_SatPathStart_rec( Gia_Obj_t * p, int fDiffs, int fCompl ) +{ + if ( Gia_SatObjIsRoot(p) ) + return fDiffs && (!Gia_ObjIsAssigned(p) || Gia_SatObjValue(p) != fCompl); + if ( fCompl == 0 ) + { + if ( Gia_SatPathStart_rec( Gia_ObjFanin0(p), fDiffs + !Gia_SatObjPath0(p), fCompl ^ Gia_ObjFaninC0(p) ) && + Gia_SatPathStart_rec( Gia_ObjFanin1(p), fDiffs + !Gia_SatObjPath1(p), fCompl ^ Gia_ObjFaninC1(p) ) ) + return Gia_ObjSetDraftPath0(p) + Gia_ObjSetDraftPath1(p); + } + else + { + if ( Gia_SatPathStart_rec( Gia_ObjFanin0(p), fDiffs + !Gia_SatObjPath0(p), fCompl ^ Gia_ObjFaninC0(p) ) ) + { + Gia_ObjUnsetDraftPath1(p); + return Gia_ObjSetDraftPath0(p); + } + if ( Gia_SatPathStart_rec( Gia_ObjFanin1(p), fDiffs + !Gia_SatObjPath1(p), fCompl ^ Gia_ObjFaninC1(p) ) ) + { + Gia_ObjUnsetDraftPath0(p); + return Gia_ObjSetDraftPath1(p); + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Creates a feasible path from the node to a terminal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_SatPathStart( Gia_Obj_t * p ) +{ + int RetValue; + assert( Gia_SatObjIsRoot(p) ); + Gia_SatObjXorRoot(p); + RetValue = Gia_SatPathStart_rec( p, 0, 0 ); + Gia_SatObjXorRoot(p); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSat.c b/src/aig/gia/giaSat.c new file mode 100644 index 00000000..6d127223 --- /dev/null +++ b/src/aig/gia/giaSat.c @@ -0,0 +1,421 @@ +/**CFile**************************************************************** + + FileName [giaSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [New constraint-propagation procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define GIA_LIMIT 10 + + +typedef struct Gia_ManSat_t_ Gia_ManSat_t; +struct Gia_ManSat_t_ +{ + Aig_MmFlex_t * pMem; +}; + +typedef struct Gia_ObjSat1_t_ Gia_ObjSat1_t; +struct Gia_ObjSat1_t_ +{ + char nFans; + char nOffset; + char PathsH; + char PathsV; +}; + +typedef struct Gia_ObjSat2_t_ Gia_ObjSat2_t; +struct Gia_ObjSat2_t_ +{ + unsigned fTerm : 1; + unsigned iLit : 31; +}; + +typedef struct Gia_ObjSat_t_ Gia_ObjSat_t; +struct Gia_ObjSat_t_ +{ + union { + Gia_ObjSat1_t Obj1; + Gia_ObjSat2_t Obj2; + }; +}; + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManSat_t * Gia_ManSatStart() +{ + Gia_ManSat_t * p; + p = ABC_CALLOC( Gia_ManSat_t, 1 ); + p->pMem = Aig_MmFlexStart(); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSatStop( Gia_ManSat_t * p ) +{ + Aig_MmFlexStop( p->pMem, 0 ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Collects the supergate rooted at this ] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSatPartCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, int * pLits, int * pnLits ) +{ + Gia_Obj_t * pFanin; + assert( Gia_ObjIsAnd(pObj) ); + assert( pObj->fMark0 == 0 ); + pFanin = Gia_ObjFanin0(pObj); + if ( pFanin->fMark0 || Gia_ObjFaninC0(pObj) ) + pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC0(pObj)); + else + Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits); + pFanin = Gia_ObjFanin1(pObj); + if ( pFanin->fMark0 || Gia_ObjFaninC1(pObj) ) + pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC1(pObj)); + else + Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits); +} + +/**Function************************************************************* + + Synopsis [Returns the number of words used.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSatPartCreate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int * pObjPlace, int * pStore ) +{ + Gia_Obj_t * pFanin; + int i, nWordsUsed, nSuperSize = 0, Super[2*GIA_LIMIT]; + // make sure this is a valid node + assert( Gia_ObjIsAnd(pObj) ); + assert( pObj->fMark0 == 0 ); + // collect inputs to the supergate + Gia_ManSatPartCollectSuper( p, pObj, Super, &nSuperSize ); + assert( nSuperSize <= 2*GIA_LIMIT ); + // create the root entry + *pObjPlace = 0; + ((Gia_ObjSat1_t *)pObjPlace)->nFans = Gia_Var2Lit( nSuperSize, 0 ); + ((Gia_ObjSat1_t *)pObjPlace)->nOffset = pStore - pObjPlace; + nWordsUsed = nSuperSize; + for ( i = 0; i < nSuperSize; i++ ) + { + pFanin = Gia_ManObj( p, Gia_Lit2Var(Super[i]) ); + if ( pFanin->fMark0 ) + { + ((Gia_ObjSat2_t *)(pStore + i))->fTerm = 1; + ((Gia_ObjSat2_t *)(pStore + i))->iLit = Super[i]; + } + else + { + assert( Gia_LitIsCompl(Super[i]) ); + nWordsUsed += Gia_ManSatPartCreate_rec( p, pFanin, pStore + i, pStore + nWordsUsed ); + } + } + return nWordsUsed; +} + +/**Function************************************************************* + + Synopsis [Creates part and returns the number of words used.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSatPartCreate( Gia_Man_t * p, Gia_Obj_t * pObj, int * pStore ) +{ + return 1 + Gia_ManSatPartCreate_rec( p, pObj, pStore, pStore + 1 ); +} + + +/**Function************************************************************* + + Synopsis [Count the number of internal nodes in the leaf-DAG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSatPartCountClauses( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnOnset, int * pnOffset ) +{ + Gia_Obj_t * pFanin; + int nOnset0, nOnset1, nOffset0, nOffset1; + assert( Gia_ObjIsAnd(pObj) ); + pFanin = Gia_ObjFanin0(pObj); + if ( pFanin->fMark0 ) + nOnset0 = 1, nOffset0 = 1; + else + { + Gia_ManSatPartCountClauses(p, pFanin, &nOnset0, &nOffset0); + if ( Gia_ObjFaninC0(pObj) ) + { + int Temp = nOnset0; + nOnset0 = nOffset0; + nOffset0 = Temp; + } + } + pFanin = Gia_ObjFanin1(pObj); + if ( pFanin->fMark0 ) + nOnset1 = 1, nOffset1 = 1; + else + { + Gia_ManSatPartCountClauses(p, pFanin, &nOnset1, &nOffset1); + if ( Gia_ObjFaninC1(pObj) ) + { + int Temp = nOnset1; + nOnset1 = nOffset1; + nOffset1 = Temp; + } + } + *pnOnset = nOnset0 * nOnset1; + *pnOffset = nOffset0 + nOffset1; +} + +/**Function************************************************************* + + Synopsis [Count the number of internal nodes in the leaf-DAG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSatPartCount( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnLeaves, int * pnNodes ) +{ + Gia_Obj_t * pFanin; + int Level0 = 0, Level1 = 0; + assert( Gia_ObjIsAnd(pObj) ); + assert( pObj->fMark0 == 0 ); + (*pnNodes)++; + pFanin = Gia_ObjFanin0(pObj); + if ( pFanin->fMark0 ) + (*pnLeaves)++; + else + Level0 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC0(pObj); + pFanin = Gia_ObjFanin1(pObj); + if ( pFanin->fMark0 ) + (*pnLeaves)++; + else + Level1 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC1(pObj); + return AIG_MAX( Level0, Level1 ); +} + +/**Function************************************************************* + + Synopsis [Count the number of internal nodes in the leaf-DAG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSatPartCountNodes( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pFanin; + int nNodes0 = 0, nNodes1 = 0; + assert( Gia_ObjIsAnd(pObj) ); + assert( pObj->fMark0 == 0 ); + pFanin = Gia_ObjFanin0(pObj); + if ( !(pFanin->fMark0) ) + nNodes0 = Gia_ManSatPartCountNodes(p, pFanin); + pFanin = Gia_ObjFanin1(pObj); + if ( !(pFanin->fMark0) ) + nNodes1 = Gia_ManSatPartCountNodes(p, pFanin); + return nNodes0 + nNodes1 + 1; +} + +/**Function************************************************************* + + Synopsis [Count the number of internal nodes in the leaf-DAG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSatPartPrint( Gia_Man_t * p, Gia_Obj_t * pObj, int Step ) +{ + Gia_Obj_t * pFanin; + assert( Gia_ObjIsAnd(pObj) ); + assert( pObj->fMark0 == 0 ); + pFanin = Gia_ObjFanin0(pObj); + if ( pFanin->fMark0 ) + printf( "%s%d", Gia_ObjFaninC0(pObj)?"!":"", Gia_ObjId(p,pFanin) ); + else + { + if ( Gia_ObjFaninC0(pObj) ) + printf( "(" ); + Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC0(pObj)); + if ( Gia_ObjFaninC0(pObj) ) + printf( ")" ); + } + printf( "%s", (Step & 1)? " + " : "*" ); + pFanin = Gia_ObjFanin1(pObj); + if ( pFanin->fMark0 ) + printf( "%s%d", Gia_ObjFaninC1(pObj)?"!":"", Gia_ObjId(p,pFanin) ); + else + { + if ( Gia_ObjFaninC1(pObj) ) + printf( "(" ); + Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC1(pObj)); + if ( Gia_ObjFaninC1(pObj) ) + printf( ")" ); + } +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSatExperiment( Gia_Man_t * p ) +{ + int nStored, Storage[1000], * pStart; + Gia_ManSat_t * pMan; + Gia_Obj_t * pObj; + int i, nLevels, nLeaves, nNodes, nCount[2*GIA_LIMIT+2] = {0}, nCountAll = 0; + int Num0 = 0, Num1 = 0; + int clk = clock(), nWords = 0, nWords2 = 0; + pMan = Gia_ManSatStart(); + // mark the nodes to become roots of leaf-DAGs + Gia_ManSetRefs( p ); + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fMark0 = 0; + if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + else if ( Gia_ObjIsCi(pObj) ) + pObj->fMark0 = 1; + else if ( Gia_ObjIsAnd(pObj) ) + { + if ( pObj->Value > 1 || Gia_ManSatPartCountNodes(p,pObj) >= GIA_LIMIT ) + pObj->fMark0 = 1; + } + pObj->Value = 0; + } + // compute the sizes of leaf-DAGs + Gia_ManForEachAnd( p, pObj, i ) + { + if ( pObj->fMark0 == 0 ) + continue; + pObj->fMark0 = 0; + + nCountAll++; + nStored = Gia_ManSatPartCreate( p, pObj, Storage ); + nWords2 += nStored; + assert( nStored < 500 ); + pStart = (int *)Aig_MmFlexEntryFetch( pMan->pMem, sizeof(int) * nStored ); + memcpy( pStart, Storage, sizeof(int) * nStored ); + + nLeaves = nNodes = 0; + nLevels = 1+Gia_ManSatPartCount( p, pObj, &nLeaves, &nNodes ); + nWords += nLeaves + nNodes; + if ( nNodes <= 2*GIA_LIMIT ) + nCount[nNodes]++; + else + nCount[2*GIA_LIMIT+1]++; +// if ( nNodes > 10 && i % 100 == 0 ) +// if ( nNodes > 5 ) + if ( 0 ) + { + Gia_ManSatPartCountClauses( p, pObj, &Num0, &Num1 ); + printf( "%8d : And = %3d. Lev = %2d. Clauses = %3d. (%3d + %3d).\n", i, nNodes, nLevels, Num0+Num1, Num0, Num1 ); + Gia_ManSatPartPrint( p, pObj, 0 ); + printf( "\n" ); + } + + pObj->fMark0 = 1; + } + printf( "\n" ); + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 0; + Gia_ManSatStop( pMan ); + for ( i = 0; i < 2*GIA_LIMIT+2; i++ ) + printf( "%2d=%6d %7.2f %% %7.2f %%\n", i, nCount[i], 100.0*nCount[i]/nCountAll, 100.0*i*nCount[i]/Gia_ManAndNum(p) ); + ABC_PRM( "MemoryEst", 4*nWords ); + ABC_PRM( "MemoryReal", 4*nWords2 ); + printf( "%5.2f bpn ", 4.0*nWords2/Gia_ManObjNum(p) ); + ABC_PRT( "Time", clock() - clk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c new file mode 100644 index 00000000..3f72b0b9 --- /dev/null +++ b/src/aig/gia/giaScl.c @@ -0,0 +1,240 @@ +/**CFile**************************************************************** + + FileName [giaScl.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Sequential cleanup.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaScl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the number of unmarked nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCombMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( !pObj->fMark0 ) + return 0; + pObj->fMark0 = 0; + assert( Gia_ObjIsAnd(pObj) ); + return Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ) + 1; +} + +/**Function************************************************************* + + Synopsis [Returns the number of unused nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCombMarkUsed( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, nNodes = 0; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = Gia_ObjIsAnd(pObj); + Gia_ManForEachCo( p, pObj, i ) + nNodes += Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs combinational cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) +{ + Gia_ManCombMarkUsed( p ); + return Gia_ManDupMarked( p ); +} + +/**Function************************************************************* + + Synopsis [Marks CIs/COs reachable from POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) +{ + if ( !pObj->fMark0 ) + return; + pObj->fMark0 = 0; + if ( Gia_ObjIsCo(pObj) ) + { + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); + return; + } + if ( Gia_ObjIsRo(p, pObj) ) + { + Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ObjRoToRi(p, pObj)) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); +} + +/**Function************************************************************* + + Synopsis [Performs sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) +{ + Vec_Int_t * vRoots; + Gia_Obj_t * pObj; + int i; + Gia_ManSetMark0( p ); + Gia_ManConst0(p)->fMark0 = 0; + Gia_ManForEachPi( p, pObj, i ) + pObj->fMark0 = 0; + vRoots = Gia_ManCollectPoIds( p ); + Gia_ManForEachObjVec( vRoots, p, pObj, i ) + Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); + Vec_IntFree( vRoots ); + return Gia_ManDupMarked( p ); +} + +/**Function************************************************************* + + Synopsis [Find representatives due to identical fanins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObjRi, * pObjRo; + unsigned * pCi2Lit, * pMaps; + int i, iLit, nFanins = 1, Counter0 = 0, Counter = 0; + Gia_ManForEachRi( p, pObjRi, i ) + Gia_ObjFanin0(pObjRi)->Value = 0; + Gia_ManForEachRi( p, pObjRi, i ) + 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 ); + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) + { + iLit = Gia_ObjFanin0Copy( pObjRi ); + if ( Gia_ObjFaninId0p(p, pObjRi) == 0 ) + pCi2Lit[Gia_ManPiNum(p)+i] = 0, Counter0++; + else if ( ~pMaps[iLit] ) // in this case, ID(pObj) > ID(pRepr) + pCi2Lit[Gia_ManPiNum(p)+i] = pMaps[iLit], Counter++; + else + pMaps[iLit] = Gia_Var2Lit( Gia_ObjId(p, pObjRo), 0 ); + } +/* + Gia_ManForEachCi( p, pObjRo, i ) + { + if ( ~pCi2Lit[i] ) + { + Gia_Obj_t * pObj0 = Gia_ObjRoToRi(p, pObjRo); + Gia_Obj_t * pObj1 = Gia_ObjRoToRi(p, Gia_ManObj(p, pCi2Lit[i])); + Gia_Obj_t * pFan0 = Gia_ObjChild0( p, Gia_ObjRoToRi(p, pObjRo) ); + Gia_Obj_t * pFan1 = Gia_ObjChild0( p, Gia_ObjRoToRi(p, Gia_ManObj(p, pCi2Lit[i])) ); + assert( pFan0 == pFan1 ); + } + } +*/ + if ( fVerbose ) + printf( "ReduceEquiv detected %d constant regs and %d equivalent regs.\n", Counter0, Counter ); + ABC_FREE( pMaps ); + pNew = Gia_ManDupDfsCiMap( p, pCi2Lit, NULL ); + ABC_FREE( pCi2Lit ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Performs sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ) +{ + Gia_Man_t * pTemp; + if ( Gia_ManRegNum(p) == 0 ) + return Gia_ManDup( p ); + p = Gia_ManSeqCleanup( p ); + if ( fConst && Gia_ManRegNum(p) ) + { + p = Gia_ManReduceConst( pTemp = p, fVerbose ); + Gia_ManStop( pTemp ); + } + if ( fEquiv && Gia_ManRegNum(p) ) + { + p = Gia_ManReduceEquiv( pTemp = p, fVerbose ); + Gia_ManStop( pTemp ); + } + p = Gia_ManSeqCleanup( pTemp = p ); + Gia_ManStop( pTemp ); + return p; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c new file mode 100644 index 00000000..7ee0ddc4 --- /dev/null +++ b/src/aig/gia/giaSim.c @@ -0,0 +1,437 @@ +/**CFile**************************************************************** + + FileName [giaSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Fast sequential simulator.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_ManSim_t_ Gia_ManSim_t; +struct Gia_ManSim_t_ +{ + Gia_Man_t * pAig; + Gia_ParSim_t * pPars; + int nWords; + Vec_Int_t * vCis2Ids; + // simulation information + unsigned * pDataSim; // simulation data + unsigned * pDataSimCis; // simulation data for CIs + unsigned * pDataSimCos; // simulation data for COs +}; + +static inline unsigned * Gia_SimData( Gia_ManSim_t * p, int i ) { return p->pDataSim + i * p->nWords; } +static inline unsigned * Gia_SimDataCi( Gia_ManSim_t * p, int i ) { return p->pDataSimCis + i * p->nWords; } +static inline unsigned * Gia_SimDataCo( Gia_ManSim_t * p, int i ) { return p->pDataSimCos + i * p->nWords; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p ) +{ + memset( p, 0, sizeof(Gia_ParSim_t) ); + // user-controlled parameters + p->nWords = 8; // the number of machine words + p->nIters = 32; // the number of timeframes + p->TimeLimit = 60; // time limit in seconds + p->fCheckMiter = 0; // check if miter outputs are non-zero + p->fVerbose = 1; // enables verbose output +} + +/**Function************************************************************* + + Synopsis [Creates fast simulation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) +{ + Gia_ManSim_t * p; + int Entry, i; + p = ABC_ALLOC( Gia_ManSim_t, 1 ); + memset( p, 0, sizeof(Gia_ManSim_t) ); + p->pAig = Gia_ManFront( pAig ); + p->pPars = pPars; + p->nWords = pPars->nWords; + 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) ); + p->vCis2Ids = Vec_IntAlloc( Gia_ManCiNum(p->pAig) ); + Vec_IntForEachEntry( pAig->vCis, Entry, i ) + Vec_IntPush( p->vCis2Ids, Entry ); + printf( "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) ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + 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; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = Aig_ManRandom( 0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimInfoZero( Gia_ManSim_t * p, unsigned * pInfo ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = 0; +} + +/**Function************************************************************* + + Synopsis [Returns index of the first pattern that failed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManSimInfoIsZero( Gia_ManSim_t * p, unsigned * pInfo ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + if ( pInfo[w] ) + return 32*(w-1) + Aig_WordFindFirstBit( pInfo[w] ); + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimInfoOne( Gia_ManSim_t * p, unsigned * pInfo ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimInfoCopy( Gia_ManSim_t * p, unsigned * pInfo, unsigned * pInfo0 ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateCi( Gia_ManSim_t * p, Gia_Obj_t * pObj, int iCi ) +{ + unsigned * pInfo = Gia_SimData( p, Gia_ObjValue(pObj) ); + unsigned * pInfo0 = Gia_SimDataCi( p, iCi ); + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateCo( Gia_ManSim_t * p, int iCo, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_SimDataCo( p, iCo ); + unsigned * pInfo0 = Gia_SimData( p, Gia_ObjDiff0(pObj) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w]; + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateNode( Gia_ManSim_t * p, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_SimData( p, Gia_ObjValue(pObj) ); + unsigned * pInfo0 = Gia_SimData( p, Gia_ObjDiff0(pObj) ); + unsigned * pInfo1 = Gia_SimData( p, Gia_ObjDiff1(pObj) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimInfoInit( Gia_ManSim_t * p ) +{ + int iPioNum, i; + Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i ) + { + if ( iPioNum < Gia_ManPiNum(p->pAig) ) + Gia_ManSimInfoRandom( p, Gia_SimDataCi(p, i) ); + else + Gia_ManSimInfoZero( p, Gia_SimDataCi(p, i) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimInfoTransfer( Gia_ManSim_t * p ) +{ + int iPioNum, i; + Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i ) + { + if ( iPioNum < Gia_ManPiNum(p->pAig) ) + Gia_ManSimInfoRandom( p, Gia_SimDataCi(p, i) ); + else + Gia_ManSimInfoCopy( p, Gia_SimDataCi(p, i), Gia_SimDataCo(p, Gia_ManPoNum(p->pAig)+iPioNum-Gia_ManPiNum(p->pAig)) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateRound( Gia_ManSim_t * p ) +{ + Gia_Obj_t * pObj; + int i, iCis = 0, iCos = 0; + assert( p->pAig->nFront > 0 ); + assert( Gia_ManConst0(p->pAig)->Value == 0 ); + Gia_ManSimInfoZero( p, Gia_SimData(p, 0) ); + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsAndOrConst0(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManSimulateNode( p, pObj ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjValue(pObj) == GIA_NONE ); + Gia_ManSimulateCo( p, iCos++, pObj ); + } + else // if ( Gia_ObjIsCi(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManSimulateCi( p, pObj, iCis++ ); + } + } + assert( Gia_ManCiNum(p->pAig) == iCis ); + assert( Gia_ManCoNum(p->pAig) == iCos ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) +{ + Gia_ManSim_t * p; + int i, clk = clock(); + p = Gia_ManSimCreate( pAig, pPars ); + Aig_ManRandom( 1 ); + Gia_ManSimInfoInit( p ); + 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 ); + } + if ( pPars->fCheckMiter && Gia_ManCheckPos( p, &iOut, &iPat ) ) + { + assert( pAig->pSeqModel == NULL ); + pAig->pSeqModel = Gia_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids ); + if ( pPars->fVerbose ) + printf( "Miter is satisfiable after simulation (output %d).\n", iOut ); + 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 ); + break; + } +*/ + if ( i < pPars->nIters - 1 ) + Gia_ManSimInfoTransfer( p ); + } + Gia_ManSimDelete( p ); + printf( "Simulated %d frames with %d words. ", pPars->nIters, pPars->nWords ); + ABC_PRT( "Time", clock() - clk ); + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSolver.c b/src/aig/gia/giaSolver.c new file mode 100644 index 00000000..e1f68c6f --- /dev/null +++ b/src/aig/gia/giaSolver.c @@ -0,0 +1,490 @@ +/**CFile**************************************************************** + + FileName [giaSolver.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: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Sat_Man_t_ Sat_Man_t; +struct Sat_Man_t_ +{ + Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vModel; // satisfying PI assignment + int nConfs; // cur number of conflicts + int nConfsMax; // max number of conflicts + int iHead; // variable queue + int iTail; // variable queue + int iJust; // head of justification + int nTrail; // variable queue size + int pTrail[0]; // variable queue data +}; + +static inline int Sat_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } +static inline void Sat_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; } +static inline void Sat_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; } +static inline int Sat_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; } +static inline void Sat_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; } + +extern void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ); +extern void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sat_Man_t * Sat_ManCreate( Gia_Man_t * pGia ) +{ + Sat_Man_t * p; + p = (Sat_Man_t *)ABC_ALLOC( char, sizeof(Sat_Man_t) + sizeof(int)*Gia_ManObjNum(pGia) ); + memset( p, 0, sizeof(Sat_Man_t) ); + p->pGia = pGia; + p->nTrail = Gia_ManObjNum(pGia); + p->vModel = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sat_ManDelete( Sat_Man_t * p ) +{ + Vec_IntFree( p->vModel ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Sat_ManCancelUntil( Sat_Man_t * p, int iBound ) +{ + Gia_Obj_t * pVar; + int i; + for ( i = p->iTail-1; i >= iBound; i-- ) + { + pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); + Sat_VarUnassign( pVar ); + } + p->iTail = p->iTail = iBound; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Sat_ManDeriveModel( Sat_Man_t * p ) +{ + Gia_Obj_t * pVar; + int i; + Vec_IntClear( p->vModel ); + for ( i = 0; i < p->iTail; i++ ) + { + pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); + if ( Gia_ObjIsCi(pVar) ) + Vec_IntPush( p->vModel, Gia_ObjCioId(pVar) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Sat_ManEnqueue( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) +{ + assert( p->iTail < p->nTrail ); + Sat_VarAssign( pVar ); + Sat_VarSetValue( pVar, Value ); + p->pTrail[p->iTail++] = Gia_ObjId(p->pGia, pVar); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Sat_ManAssume( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) +{ + assert( p->iHead == p->iTail ); + Sat_ManEnqueue( p, pVar, Value ); +} + +/**Function************************************************************* + + Synopsis [Propagates one assignment.] + + Description [Returns 1 if there is no conflict, 0 otherwise.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sat_ManPropagateOne( Sat_Man_t * p, int iPos ) +{ + Gia_Obj_t * pVar, * pFan0, * pFan1; + pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); + if ( Gia_ObjIsCi(pVar) ) + return 1; + pFan0 = Gia_ObjFanin0(pVar); + pFan1 = Gia_ObjFanin1(pVar); + if ( Sat_VarValue(pVar) ) // positive + { + if ( Sat_VarIsAssigned(pFan0) ) + { + if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> conflict + return 0; + // check second var + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict + return 0; + // positive + positive -> nothing to do + return 1; + } + } + else + { + // pFan0 unassigned -> enqueue first var + Sat_ManEnqueue( p, pFan0, !Gia_ObjFaninC0(pVar) ); + // check second var + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict + return 0; + // positive + positive -> nothing to do + return 1; + } + } + // unassigned -> enqueue second var + Sat_ManEnqueue( p, pFan1, !Gia_ObjFaninC1(pVar) ); + } + else // negative + { + if ( Sat_VarIsAssigned(pFan0) ) + { + if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> nothing to do + return 1; + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do + return 1; + // positive + positive -> conflict + return 0; + } + // positive + unassigned -> enqueue second var + Sat_ManEnqueue( p, pFan1, Gia_ObjFaninC1(pVar) ); + } + else + { + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do + return 1; + // unassigned + positive -> enqueue first var + Sat_ManEnqueue( p, pFan0, Gia_ObjFaninC0(pVar) ); + } + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Propagates assignments.] + + Description [Returns 1 if there is no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sat_ManPropagate( Sat_Man_t * p ) +{ + assert( p->iHead <= p->iTail ); + for ( ; p->iHead < p->iTail; p->iHead++ ) + if ( !Sat_ManPropagateOne( p, p->pTrail[p->iHead] ) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Propagates one assignment.] + + Description [Returns 1 if justified, 0 if conflict, -1 if needs justification.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sat_ManJustifyNextOne( Sat_Man_t * p, int iPos ) +{ + Gia_Obj_t * pVar, * pFan0, * pFan1; + pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); + if ( Gia_ObjIsCi(pVar) ) + return 1; + pFan0 = Gia_ObjFanin0(pVar); + pFan1 = Gia_ObjFanin1(pVar); + if ( Sat_VarValue(pVar) ) // positive + return 1; + // nevative + if ( Sat_VarIsAssigned(pFan0) ) + { + if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> already justified + return 1; + // positive + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified + return 1; + // positive -> conflict + return 0; + } + // unasigned -> propagate + Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); + return Sat_ManPropagate(p); + } + if ( Sat_VarIsAssigned(pFan1) ) + { + if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified + return 1; + // positive + assert( !Sat_VarIsAssigned(pFan0) ); + // unasigned -> propagate + Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); + return Sat_ManPropagate(p); + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Justifies assignments.] + + Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sat_ManJustify( Sat_Man_t * p ) +{ + Gia_Obj_t * pVar, * pFan0, * pFan1; + int RetValue, iState, iJustState; + if ( p->nConfs && p->nConfs >= p->nConfsMax ) + return -1; + // get the next variable to justify + assert( p->iJust <= p->iTail ); + iJustState = p->iJust; + for ( ; p->iJust < p->iTail; p->iJust++ ) + { + RetValue = Sat_ManJustifyNextOne( p, p->pTrail[p->iJust] ); + if ( RetValue == 0 ) + return 1; + if ( RetValue == -1 ) + break; + } + if ( p->iJust == p->iTail ) // could not find + return 0; + // found variable to justify + pVar = Gia_ManObj( p->pGia, p->pTrail[p->iJust] ); + pFan0 = Gia_ObjFanin0(pVar); + pFan1 = Gia_ObjFanin1(pVar); + assert( !Sat_VarValue(pVar) && !Sat_VarIsAssigned(pFan0) && !Sat_VarIsAssigned(pFan1) ); + // remember the state of the stack + iState = p->iHead; + // try to justify by setting first fanin to 0 + Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); + if ( Sat_ManPropagate(p) ) + { + RetValue = Sat_ManJustify(p); + if ( RetValue != 1 ) + return RetValue; + } + Sat_ManCancelUntil( p, iState ); + // try to justify by setting second fanin to 0 + Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); + if ( Sat_ManPropagate(p) ) + { + RetValue = Sat_ManJustify(p); + if ( RetValue != 1 ) + return RetValue; + } + Sat_ManCancelUntil( p, iState ); + p->iJust = iJustState; + p->nConfs++; + return 1; +} + +/**Function************************************************************* + + Synopsis [Runs one call to the SAT solver.] + + Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sat_ManPrepare( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) +{ + Gia_Obj_t * pVar; + int i; + // double check that vars are unassigned + Gia_ManForEachObj( p->pGia, pVar, i ) + assert( !Sat_VarIsAssigned(pVar) ); + // prepare + p->iHead = p->iTail = p->iJust = 0; + p->nConfsMax = nConfsMax; + // assign literals + for ( i = 0; i < nLits; i++ ) + { + pVar = Gia_ManObj( p->pGia, Gia_Lit2Var(pLits[i]) ); + if ( Sat_VarIsAssigned(pVar) ) // assigned + { + if ( Sat_VarValue(pVar) != Gia_LitIsCompl(pLits[i]) ) // compatible assignment + continue; + } + else // unassigned + { + Sat_ManAssume( p, pVar, !Gia_LitIsCompl(pLits[i]) ); + if ( Sat_ManPropagate(p) ) + continue; + } + // conflict + Sat_ManCancelUntil( p, 0 ); + return 1; + } + assert( p->iHead == p->iTail ); + return 0; +} + + +/**Function************************************************************* + + Synopsis [Runs one call to the SAT solver.] + + Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sat_ManSolve( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) +{ + int RetValue; + // propagate the assignments + if ( Sat_ManPrepare( p, pLits, nLits, nConfsMax ) ) + return 1; + // justify the assignments + RetValue = Sat_ManJustify( p ); + if ( RetValue == 0 ) // SAT + Sat_ManDeriveModel( p ); + // return the solver to the initial state + Sat_ManCancelUntil( p, 0 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Testing the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ) +{ + Sat_Man_t * p; + int RetValue, iLit; + assert( Gia_ObjIsCo(pObj) ); + p = Sat_ManCreate( pGia ); + iLit = Gia_LitNot( Gia_ObjFaninLit0p(pGia, pObj) ); + RetValue = Sat_ManSolve( p, &iLit, 1, nConfsMax ); + if ( RetValue == 0 ) + { + Cec_ManPatVerifyPattern( pGia, pObj, p->vModel ); + Cec_ManPatCleanMark0( pGia, pObj ); + } + Sat_ManDelete( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSolver_cnf.c b/src/aig/gia/giaSolver_cnf.c new file mode 100644 index 00000000..12f6895a --- /dev/null +++ b/src/aig/gia/giaSolver_cnf.c @@ -0,0 +1,103 @@ +/**CFile**************************************************************** + + FileName [giaSolver.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: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Sat_Cla_t_ Sat_Cla_t; +struct Sat_Cla_t_ +{ + unsigned hWatch0; // watched list for 0 literal + unsigned hWatch1; // watched list for 1 literal + int Activity; // activity of the clause + int nLits; // the number of literals + int pLits[0]; // the array of literals +}; + +typedef struct Sat_Fan_t_ Sat_Fan_t; +struct Sat_Fan_t_ +{ + unsigned iFan : 31; // ID of the fanin/fanout + unsigned fCompl : 1; // complemented attribute +}; + +typedef struct Sat_Obj_t_ Sat_Obj_t; +struct Sat_Obj_t_ +{ + unsigned hHandle; // node handle + unsigned fAssign : 1; // terminal node (CI/CO) + unsigned fValue : 1; // value under 000 pattern + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanouuts : 28; // the number of fanouts + unsigned nFanins : 8; // the number of fanins + unsigned Level : 24; // logic level + unsigned hNext; // next one on this level + unsigned hWatch0; // watched list for 0 literal + unsigned hWatch1; // watched list for 1 literal + unsigned hReason; // reason for this variable + unsigned Depth; // decision depth + Sat_Fan_t Fanios[0]; // the array of fanins/fanouts +}; + +typedef struct Sat_Man_t_ Sat_Man_t; +struct Sat_Man_t_ +{ + Gia_Man_t * pGia; // the original AIG manager + // circuit + Vec_Int_t vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t vObjs; // the vector of objects + // learned clauses + Vec_Int_t vClauses; // the vector of clauses + // solver data + Vec_Int_t vTrail; // variable queue + Vec_Int_t vTrailLim; // pointer into the trail + int iHead; // variable queue + int iTail; // variable queue + int iRootLevel; // first decision + // levelized order + int iLevelTop; // the largest unassigned level + Vec_Int_t vLevels; // the linked lists of levels +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c new file mode 100644 index 00000000..71aefec3 --- /dev/null +++ b/src/aig/gia/giaSwitch.c @@ -0,0 +1,673 @@ +/**CFile**************************************************************** + + FileName [giaSwitch.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Computing switching activity.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// switching estimation parameters +typedef struct Gia_ParSwi_t_ Gia_ParSwi_t; +struct Gia_ParSwi_t_ +{ + // user-controlled parameters + int nWords; // the number of machine words + int nIters; // the number of timeframes + int nPref; // the number of first timeframes to skip + int nRandPiFactor; // PI trans prob (-1=3/8; 0=1/2; 1=1/4; 2=1/8, etc) + int fProbOne; // collect probability of one + int fProbTrans; // collect probatility of Swiing + int fVerbose; // enables verbose output +}; + +typedef struct Gia_ManSwi_t_ Gia_ManSwi_t; +struct Gia_ManSwi_t_ +{ + Gia_Man_t * pAig; + Gia_ParSwi_t * pPars; + int nWords; + // simulation information + unsigned * pDataSim; // simulation data + unsigned * pDataSimCis; // simulation data for CIs + unsigned * pDataSimCos; // simulation data for COs + int * pData1; // switching data +}; + +static inline unsigned * Gia_SwiData( Gia_ManSwi_t * p, int i ) { return p->pDataSim + i * p->nWords; } +static inline unsigned * Gia_SwiDataCi( Gia_ManSwi_t * p, int i ) { return p->pDataSimCis + i * p->nWords; } +static inline unsigned * Gia_SwiDataCo( Gia_ManSwi_t * p, int i ) { return p->pDataSimCos + i * p->nWords; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetDefaultParamsSwi( Gia_ParSwi_t * p ) +{ + memset( p, 0, sizeof(Gia_ParSwi_t) ); + p->nWords = 1; // the number of machine words of simulatation data + p->nIters = 48; // the number of all timeframes to simulate + p->nPref = 16; // the number of first timeframes to skip when computing switching + p->nRandPiFactor = 2; // primary input transition probability (-1=3/8; 0=1/2; 1=1/4; 2=1/8, etc) + p->fProbOne = 0; // compute probability of signal being one (if 0, compute probability of switching) + p->fProbTrans = 1; // compute signal transition probability (if 0, compute transition probability using probability of being one) + p->fVerbose = 1; // enables verbose output +} + +/**Function************************************************************* + + Synopsis [Creates fast simulation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManSwi_t * Gia_ManSwiCreate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) +{ + Gia_ManSwi_t * p; + p = ABC_ALLOC( Gia_ManSwi_t, 1 ); + memset( p, 0, sizeof(Gia_ManSwi_t) ); + p->pAig = Gia_ManFront( pAig ); + p->pPars = pPars; + p->nWords = pPars->nWords; + 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) ); + p->pData1 = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSwiDelete( Gia_ManSwi_t * p ) +{ + Gia_ManStop( p->pAig ); + ABC_FREE( p->pData1 ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pDataSimCis ); + ABC_FREE( p->pDataSimCos ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoRandom( Gia_ManSwi_t * p, unsigned * pInfo, int nProbNum ) +{ + unsigned Mask; + int w, i; + if ( nProbNum == -1 ) + { // 3/8 = 1/4 + 1/8 + Mask = (Aig_ManRandom( 0 ) & Aig_ManRandom( 0 )) | + (Aig_ManRandom( 0 ) & Aig_ManRandom( 0 ) & Aig_ManRandom( 0 )); + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] ^= Mask; + } + else if ( nProbNum > 0 ) + { + Mask = Aig_ManRandom( 0 ); + for ( i = 0; i < nProbNum; i++ ) + Mask &= Aig_ManRandom( 0 ); + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] ^= Mask; + } + else if ( nProbNum == 0 ) + { + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = Aig_ManRandom( 0 ); + } + else + assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoRandomShift( Gia_ManSwi_t * p, unsigned * pInfo, int nProbNum ) +{ + unsigned Mask; + int w, i; + if ( nProbNum == -1 ) + { // 3/8 = 1/4 + 1/8 + Mask = (Aig_ManRandom( 0 ) & Aig_ManRandom( 0 )) | + (Aig_ManRandom( 0 ) & Aig_ManRandom( 0 ) & Aig_ManRandom( 0 )); + } + else if ( nProbNum >= 0 ) + { + Mask = Aig_ManRandom( 0 ); + for ( i = 0; i < nProbNum; i++ ) + Mask &= Aig_ManRandom( 0 ); + } + else + assert( 0 ); + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = (pInfo[w] << 16) | ((pInfo[w] ^ Mask) & 0xffff); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoZero( Gia_ManSwi_t * p, unsigned * pInfo ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoOne( Gia_ManSwi_t * p, unsigned * pInfo ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoCopy( Gia_ManSwi_t * p, unsigned * pInfo, unsigned * pInfo0 ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoCopyShift( Gia_ManSwi_t * p, unsigned * pInfo, unsigned * pInfo0 ) +{ + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = (pInfo[w] << 16) | (pInfo0[w] & 0xffff); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimulateCi( Gia_ManSwi_t * p, Gia_Obj_t * pObj, int iCi ) +{ + unsigned * pInfo = Gia_SwiData( p, Gia_ObjValue(pObj) ); + unsigned * pInfo0 = Gia_SwiDataCi( p, iCi ); + int w; + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimulateCo( Gia_ManSwi_t * p, int iCo, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_SwiDataCo( p, iCo ); + unsigned * pInfo0 = Gia_SwiData( p, Gia_ObjDiff0(pObj) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w]; + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimulateNode( Gia_ManSwi_t * p, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_SwiData( p, Gia_ObjValue(pObj) ); + unsigned * pInfo0 = Gia_SwiData( p, Gia_ObjDiff0(pObj) ); + unsigned * pInfo1 = Gia_SwiData( p, Gia_ObjDiff1(pObj) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = p->nWords-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoInit( Gia_ManSwi_t * p ) +{ + int i = 0; + for ( ; i < Gia_ManPiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoRandom( p, Gia_SwiDataCi(p, i), 0 ); + for ( ; i < Gia_ManCiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoZero( p, Gia_SwiDataCi(p, i) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoTransfer( Gia_ManSwi_t * p, int nProbNum ) +{ + int i = 0, nShift = Gia_ManPoNum(p->pAig)-Gia_ManPiNum(p->pAig); + for ( ; i < Gia_ManPiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoRandom( p, Gia_SwiDataCi(p, i), nProbNum ); + for ( ; i < Gia_ManCiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoCopy( p, Gia_SwiDataCi(p, i), Gia_SwiDataCo(p, nShift+i) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimInfoTransferShift( Gia_ManSwi_t * p, int nProbNum ) +{ + int i = 0, nShift = Gia_ManPoNum(p->pAig)-Gia_ManPiNum(p->pAig); + for ( ; i < Gia_ManPiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoRandomShift( p, Gia_SwiDataCi(p, i), nProbNum ); + for ( ; i < Gia_ManCiNum(p->pAig); i++ ) + Gia_ManSwiSimInfoCopyShift( p, Gia_SwiDataCi(p, i), Gia_SwiDataCo(p, nShift+i) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManSwiSimInfoCountOnes( Gia_ManSwi_t * p, int iPlace ) +{ + unsigned * pInfo; + int w, Counter = 0; + pInfo = Gia_SwiData( p, iPlace ); + for ( w = p->nWords-1; w >= 0; w-- ) + Counter += Aig_WordCountOnes( pInfo[w] ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManSwiSimInfoCountTrans( Gia_ManSwi_t * p, int iPlace ) +{ + unsigned * pInfo; + int w, Counter = 0; + pInfo = Gia_SwiData( p, iPlace ); + for ( w = p->nWords-1; w >= 0; w-- ) + Counter += 2*Aig_WordCountOnes( (pInfo[w] ^ (pInfo[w] >> 16)) & 0xffff ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSwiSimulateRound( Gia_ManSwi_t * p, int fCount ) +{ + Gia_Obj_t * pObj; + int i, iCis = 0, iCos = 0; + assert( p->pAig->nFront > 0 ); + assert( Gia_ManConst0(p->pAig)->Value == 0 ); + Gia_ManSwiSimInfoZero( p, Gia_SwiData(p, 0) ); + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsAndOrConst0(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManSwiSimulateNode( p, pObj ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjValue(pObj) == GIA_NONE ); + Gia_ManSwiSimulateCo( p, iCos++, pObj ); + } + else // if ( Gia_ObjIsCi(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManSwiSimulateCi( p, pObj, iCis++ ); + } + if ( fCount && !Gia_ObjIsCo(pObj) ) + { + if ( p->pPars->fProbTrans ) + p->pData1[i] += Gia_ManSwiSimInfoCountTrans( p, Gia_ObjValue(pObj) ); + else + p->pData1[i] += Gia_ManSwiSimInfoCountOnes( p, Gia_ObjValue(pObj) ); + } + } + assert( Gia_ManCiNum(p->pAig) == iCis ); + assert( Gia_ManCoNum(p->pAig) == iCos ); +} + +/**Function************************************************************* + + Synopsis [Computes switching activity of one node.] + + Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManSwiComputeSwitching( int nOnes, int nSimWords ) +{ + int nTotal = 32 * nSimWords; + return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal; +} + +/**Function************************************************************* + + Synopsis [Computes switching activity of one node.] + + Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManSwiComputeProbOne( int nOnes, int nSimWords ) +{ + int nTotal = 32 * nSimWords; + return (float)nOnes / nTotal; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) +{ + Gia_ManSwi_t * p; + Gia_Obj_t * pObj; + Vec_Int_t * vSwitching; + float * pSwitching; + int i, clk, clkTotal = clock(); + if ( pPars->fProbOne && pPars->fProbTrans ) + printf( "Conflict of options: Can either compute probability of 1, or probability of switching by observing transitions.\n" ); + // create manager + clk = clock(); + p = Gia_ManSwiCreate( pAig, pPars ); + if ( pPars->fVerbose ) + { + printf( "Obj = %8d (%8d). F = %6d. ", + pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront, + 4.0*Aig_BitWordNum(2 * p->pAig->nFront)/(1<<20) ); + printf( "AIG = %7.2f Mb. F-mem = %7.2f Mb. Other = %7.2f Mb. ", + 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) ); + ABC_PRT( "Time", clock() - clk ); + } + // perform simulation + Aig_ManRandom( 1 ); + Gia_ManSwiSimInfoInit( p ); + for ( i = 0; i < pPars->nIters; i++ ) + { + Gia_ManSwiSimulateRound( p, i >= pPars->nPref ); + if ( i == pPars->nIters - 1 ) + break; + if ( pPars->fProbTrans ) + Gia_ManSwiSimInfoTransferShift( p, pPars->nRandPiFactor ); + else + Gia_ManSwiSimInfoTransfer( p, pPars->nRandPiFactor ); + } + if ( pPars->fVerbose ) + { + printf( "Simulated %d frames with %d words. ", pPars->nIters, pPars->nWords ); + ABC_PRT( "Simulation time", clock() - clkTotal ); + } + // derive the result + vSwitching = Vec_IntStart( Gia_ManObjNum(pAig) ); + pSwitching = (float *)vSwitching->pArray; + if ( pPars->fProbOne ) + { + Gia_ManForEachObj( pAig, pObj, i ) + pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); + } + else if ( pPars->fProbTrans ) + { + Gia_ManForEachObj( pAig, pObj, i ) + pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); + } + else + { + Gia_ManForEachObj( pAig, pObj, i ) + pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); + } + Gia_ManSwiDelete( p ); + return vSwitching; + +} + +/**Function************************************************************* + + Synopsis [Computes probability of switching (or of being 1).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + Aig_Obj_t * pObj; + int i; + // set the default parameters + Gia_ManSetDefaultParamsSwi( pPars ); + // override some of the defaults + pPars->nWords = 10; // set number machine words to simulate + pPars->nIters = nFrames; // set number of total timeframes + if ( Abc_FrameReadFlag("seqsimframes") ) + pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") ); + pPars->nPref = nPref; // set number of first timeframes to skip + pPars->fVerbose = 0; // disable verbose output + // decide what should be computed + if ( fProbOne ) + { + // if the user asked to compute propability of 1, we do not need transition information + pPars->fProbOne = 1; // enable computing probabiblity of being one + pPars->fProbTrans = 0; // disable computing transition probability + } + else + { + // if the user asked for transition propabability, we do not need to compute probability of 1 + pPars->fProbOne = 0; // disable computing probabiblity of being one + pPars->fProbTrans = 1; // enable computing transition probability + } + // translate AIG into the intermediate form (takes care of choices if present!) + p = Gia_ManFromAigSwitch( pAig ); + // perform the computation of switching activity + vSwitching = Gia_ManSwiSimulate( p, pPars ); + // transfer the computed result to the original AIG + vResult = Vec_IntStart( Aig_ManObjNumMax(pAig) ); + Aig_ManForEachObj( pAig, pObj, i ) + Vec_IntWriteEntry( vResult, i, Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ); + // delete intermediate results + Vec_IntFree( vSwitching ); + Gia_ManStop( p ); + return vResult; +} + + //////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaTsim.c b/src/aig/gia/giaTsim.c new file mode 100644 index 00000000..c7aac864 --- /dev/null +++ b/src/aig/gia/giaTsim.c @@ -0,0 +1,708 @@ +/**CFile**************************************************************** + + FileName [giaTsim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Ternary simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaTsim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Gia_ManTerSimInfoGet( unsigned * pInfo, int i ) +{ + return 3 & (pInfo[i >> 4] >> ((i & 15) << 1)); +} +static inline void Gia_ManTerSimInfoSet( unsigned * pInfo, int i, int Value ) +{ + assert( Value >= GIA_ZER && Value <= GIA_UND ); + Value ^= Gia_ManTerSimInfoGet( pInfo, i ); + pInfo[i >> 4] ^= (Value << ((i & 15) << 1)); +} + +static inline unsigned * Gia_ManTerStateNext( unsigned * pState, int nWords ) { return *((unsigned **)(pState + nWords)); } +static inline void Gia_ManTerStateSetNext( unsigned * pState, int nWords, unsigned * pNext ) { *((unsigned **)(pState + nWords)) = pNext; } + +// ternary simulation manager +typedef struct Gia_ManTer_t_ Gia_ManTer_t; +struct Gia_ManTer_t_ +{ + Gia_Man_t * pAig; + int nIters; + int nStateWords; + Vec_Ptr_t * vStates; + Vec_Ptr_t * vFlops; + int * pCount0; + int * pCountX; + // hash table for states + int nBins; + unsigned ** pBins; + // simulation information + unsigned * pDataSim; // simulation data + unsigned * pDataSimCis; // simulation data for CIs + unsigned * pDataSimCos; // simulation data for COs +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates fast simulation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManTer_t * Gia_ManTerCreate( Gia_Man_t * pAig ) +{ + Gia_ManTer_t * p; + p = ABC_CALLOC( Gia_ManTer_t, 1 ); + p->pAig = Gia_ManFront( pAig ); + p->nIters = 300; + p->pDataSim = ABC_ALLOC( unsigned, Aig_BitWordNum(2*p->pAig->nFront) ); + p->pDataSimCis = ABC_ALLOC( unsigned, Aig_BitWordNum(2*Gia_ManCiNum(p->pAig)) ); + p->pDataSimCos = ABC_ALLOC( unsigned, Aig_BitWordNum(2*Gia_ManCoNum(p->pAig)) ); + // allocate storage for terminary states + p->nStateWords = Aig_BitWordNum( 2*Gia_ManRegNum(pAig) ); + p->vStates = Vec_PtrAlloc( 1000 ); + p->pCount0 = ABC_CALLOC( int, Gia_ManRegNum(pAig) ); + p->pCountX = ABC_CALLOC( int, Gia_ManRegNum(pAig) ); + p->nBins = Aig_PrimeCudd( 500 ); + p->pBins = ABC_CALLOC( unsigned *, p->nBins ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerStatesFree( Vec_Ptr_t * vStates ) +{ + unsigned * pTemp; + int i; + Vec_PtrForEachEntry( vStates, pTemp, i ) + ABC_FREE( pTemp ); + Vec_PtrFree( vStates ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerDelete( Gia_ManTer_t * p ) +{ + if ( p->vStates ) + Gia_ManTerStatesFree( p->vStates ); + if ( p->vFlops ) + Gia_ManTerStatesFree( p->vFlops ); + Gia_ManStop( p->pAig ); + ABC_FREE( p->pCount0 ); + ABC_FREE( p->pCountX ); + ABC_FREE( p->pBins ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pDataSimCis ); + ABC_FREE( p->pDataSimCos ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimulateCi( Gia_ManTer_t * p, Gia_Obj_t * pObj, int iCi ) +{ + Gia_ManTerSimInfoSet( p->pDataSim, Gia_ObjValue(pObj), Gia_ManTerSimInfoGet(p->pDataSimCis, iCi) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimulateCo( Gia_ManTer_t * p, int iCo, Gia_Obj_t * pObj ) +{ + int Value = Gia_ManTerSimInfoGet( p->pDataSim, Gia_ObjDiff0(pObj) ); + Gia_ManTerSimInfoSet( p->pDataSimCos, iCo, Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimulateNode( Gia_ManTer_t * p, Gia_Obj_t * pObj ) +{ + int Value0 = Gia_ManTerSimInfoGet( p->pDataSim, Gia_ObjDiff0(pObj) ); + int Value1 = Gia_ManTerSimInfoGet( p->pDataSim, Gia_ObjDiff1(pObj) ); + Gia_ManTerSimInfoSet( p->pDataSim, Gia_ObjValue(pObj), Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimInfoInit( Gia_ManTer_t * p ) +{ + int i = 0; + for ( ; i < Gia_ManPiNum(p->pAig); i++ ) + Gia_ManTerSimInfoSet( p->pDataSimCis, i, GIA_UND ); + for ( ; i < Gia_ManCiNum(p->pAig); i++ ) + Gia_ManTerSimInfoSet( p->pDataSimCis, i, GIA_ZER ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimInfoTransfer( Gia_ManTer_t * p ) +{ + int i = 0; + for ( ; i < Gia_ManPiNum(p->pAig); i++ ) + Gia_ManTerSimInfoSet( p->pDataSimCis, i, GIA_UND ); + for ( ; i < Gia_ManCiNum(p->pAig); i++ ) + Gia_ManTerSimInfoSet( p->pDataSimCis, i, Gia_ManTerSimInfoGet( p->pDataSimCos, Gia_ManCoNum(p->pAig)-Gia_ManCiNum(p->pAig)+i ) ); +} + + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManTerStateHash( unsigned * pState, int nWords, 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 < nWords; i++ ) + uHash ^= pState[i] * s_FPrimes[i & 0x7F]; + return uHash % nTableSize; +} + +/**Function************************************************************* + + Synopsis [Inserts value into the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManTerStateLookup( unsigned * pState, int nWords, unsigned ** pBins, int nBins ) +{ + unsigned * pEntry; + int Hash = Gia_ManTerStateHash( pState, nWords, nBins ); + for ( pEntry = pBins[Hash]; pEntry; pEntry = Gia_ManTerStateNext(pEntry, nWords) ) + if ( !memcmp( pEntry, pState, sizeof(unsigned) * nWords ) ) + return pEntry; + return NULL; +} + +/**Function************************************************************* + + Synopsis [Inserts value into the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerStateInsert( unsigned * pState, int nWords, unsigned ** pBins, int nBins ) +{ + int Hash = Gia_ManTerStateHash( pState, nWords, nBins ); + assert( !Gia_ManTerStateLookup( pState, nWords, pBins, nBins ) ); + Gia_ManTerStateSetNext( pState, nWords, pBins[Hash] ); + pBins[Hash] = pState; +} + +/**Function************************************************************* + + Synopsis [Allocs new ternary state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManTerStateAlloc( int nWords ) +{ + return (unsigned *)ABC_CALLOC( char, sizeof(unsigned) * nWords + sizeof(unsigned *) ); +} + +/**Function************************************************************* + + Synopsis [Creates new ternary state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManTerStateCreate( Gia_ManTer_t * p ) +{ + int i, Value, nPis = Gia_ManPiNum(p->pAig); + unsigned * pRes = Gia_ManTerStateAlloc( p->nStateWords ); + for ( i = nPis; i < Gia_ManCiNum(p->pAig); i++ ) + { + Value = Gia_ManTerSimInfoGet( p->pDataSimCis, i ); + Gia_ManTerSimInfoSet( pRes, i-nPis, Value ); + if ( Value == GIA_ZER ) + p->pCount0[i-nPis]++; + if ( Value == GIA_UND ) + p->pCountX[i-nPis]++; + } + Vec_PtrPush( p->vStates, pRes ); + return pRes; +} + +/**Function************************************************************* + + Synopsis [Performs one round of ternary simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManTerSimulateRound( Gia_ManTer_t * p ) +{ + Gia_Obj_t * pObj; + int i, iCis = 0, iCos = 0; + assert( p->pAig->nFront > 0 ); + assert( Gia_ManConst0(p->pAig)->Value == 0 ); + Gia_ManTerSimInfoSet( p->pDataSim, 0, GIA_ONE ); + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsAndOrConst0(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManTerSimulateNode( p, pObj ); + } + else if ( Gia_ObjIsCi(pObj) ) + { + assert( Gia_ObjValue(pObj) < p->pAig->nFront ); + Gia_ManTerSimulateCi( p, pObj, iCis++ ); + } + else // if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjValue(pObj) == GIA_NONE ); + Gia_ManTerSimulateCo( p, iCos++, pObj ); + } + } + assert( Gia_ManCiNum(p->pAig) == iCis ); + assert( Gia_ManCoNum(p->pAig) == iCos ); +} + +/**Function************************************************************* + + Synopsis [Retires a set of registers to speed up convergence.] + + Description [Retire all non-ternary registers which has max number + of ternary values so far.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManTerRetire( Gia_ManTer_t * p, unsigned * pState ) +{ + int i, iMaxTerValue = 0, Counter = 0; + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + if ( Gia_ManTerSimInfoGet( pState, i ) != GIA_UND && iMaxTerValue < p->pCountX[i] ) + iMaxTerValue = p->pCountX[i]; + // retire all registers with this value + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + if ( Gia_ManTerSimInfoGet( pState, i ) != GIA_UND && iMaxTerValue == p->pCountX[i] ) + { + Gia_ManTerSimInfoSet( p->pDataSimCis, Gia_ManPiNum(p->pAig)+i, GIA_UND ); + Counter++; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Inserts value into the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerStatePrint( unsigned * pState, int nRegs, int iNum ) +{ + int i, nZeros = 0, nOnes = 0, nDcs = 0; + printf( " %4d : ", iNum ); + for ( i = 0; i < nRegs; i++ ) + { + if ( Gia_ManTerSimInfoGet(pState, i) == GIA_ZER ) + printf( "0" ), nZeros++; + else if ( Gia_ManTerSimInfoGet(pState, i) == GIA_ONE ) + printf( "1" ), nOnes++; + else if ( Gia_ManTerSimInfoGet(pState, i) == GIA_UND ) + printf( "x" ), nDcs++; + else + assert( 0 ); + } + printf( " (0=%4d, 1=%4d, x=%4d)\n", nZeros, nOnes, nDcs ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs ) +{ + unsigned * pTemp, * pStates = Vec_PtrPop( vStates ); + int i, w, nZeros, nConsts, nStateWords; + // detect constant zero registers + nStateWords = Aig_BitWordNum( 2*nRegs ); + memset( pStates, 0, sizeof(int) * nStateWords ); + Vec_PtrForEachEntry( vStates, pTemp, i ) + for ( w = 0; w < nStateWords; w++ ) + pStates[w] |= pTemp[w]; + // count the number of zeros + nZeros = 0; + for ( i = 0; i < nRegs; i++ ) + if ( Gia_ManTerSimInfoGet(pStates, i) == GIA_ZER ) + nZeros++; + printf( "Found %d constant registers.\n", nZeros ); + // detect non-ternary registers + memset( pStates, 0, sizeof(int) * nStateWords ); + Vec_PtrForEachEntry( vStates, pTemp, i ) + for ( w = 0; w < nStateWords; w++ ) + pStates[w] |= (~(pTemp[w] ^ (pTemp[w] >> 1)) & 0x55555555); + // count the nonternary registers + nConsts = 0; + for ( i = 0; i < nRegs; i++ ) + if ( Gia_ManTerSimInfoGet(pStates, i) == 0 ) + nConsts++; + printf( "Found %d non-ternary registers.\n", nConsts ); + // return the state back + Vec_PtrPush( vStates, pStates ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTerAnalyze( Gia_ManTer_t * p ) +{ + int i, nZeros = 0, nConsts = 0; + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + if ( p->pCount0[i] == Vec_PtrSize(p->vStates) ) + nZeros++; + else if ( p->pCountX[i] == 0 ) + nConsts++; + printf( "Found %d constant registers.\n", nZeros ); + printf( "Found %d non-ternary registers.\n", nConsts ); +} + + + +/**Function************************************************************* + + Synopsis [Transposes state vector for non-ternary registers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_ManTerTranspose( Gia_ManTer_t * p ) +{ + Vec_Ptr_t * vFlops; + unsigned * pState, * pFlop; + int i, k, nFlopWords; + vFlops = Vec_PtrAlloc( 100 ); + nFlopWords = Aig_BitWordNum( 2*Vec_PtrSize(p->vStates) ); + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( p->pCount0[i] == Vec_PtrSize(p->vStates) ) + continue; + if ( p->pCountX[i] > 0 ) + continue; + pFlop = Gia_ManTerStateAlloc( nFlopWords ); + Vec_PtrPush( vFlops, pFlop ); + Vec_PtrForEachEntry( p->vStates, pState, k ) + Gia_ManTerSimInfoSet( pFlop, k, Gia_ManTerSimInfoGet(pState, i) ); +//Gia_ManTerStatePrint( pFlop, Vec_PtrSize(p->vStates), i ); + } + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Transposes state vector for non-ternary registers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ) + if ( !memcmp( pTemp, pFlop, sizeof(unsigned) * nFlopWords ) ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Creates map of registers to replace.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManTerCreateMap( Gia_ManTer_t * p ) +{ + int * pCi2Lit; + Gia_Obj_t * pObj; + Vec_Int_t * vMapKtoI; + int i, iRepr, nFlopWords, Counter0 = 0, CounterE = 0; + nFlopWords = Aig_BitWordNum( 2*Vec_PtrSize(p->vStates) ); + p->vFlops = Gia_ManTerTranspose( p ); + pCi2Lit = ABC_FALLOC( unsigned, 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) ) + pCi2Lit[Gia_ManPiNum(p->pAig)+i] = 0, Counter0++; + else if ( p->pCountX[i] == 0 ) + { + iRepr = Gia_ManFindEqualFlop( p->vFlops, Vec_IntSize(vMapKtoI), nFlopWords ); + Vec_IntPush( vMapKtoI, i ); + if ( iRepr < 0 ) + continue; + pObj = Gia_ManCi( p->pAig, Gia_ManPiNum(p->pAig)+Vec_IntEntry(vMapKtoI, iRepr) ); + pCi2Lit[Gia_ManPiNum(p->pAig)+i] = Gia_Var2Lit( Gia_ObjId( p->pAig, pObj ), 0 ); + CounterE++; + } + Vec_IntFree( vMapKtoI ); + printf( "Transformed %d const registers and %d equiv registers.\n", Counter0, CounterE ); + return pCi2Lit; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManTer_t * Gia_ManTerSimulate( Gia_Man_t * pAig, int fVerbose ) +{ + Gia_ManTer_t * p; + unsigned * pState, * pLoop; + int i, Counter, clk, clkTotal = clock(); + assert( Gia_ManRegNum(pAig) > 0 ); + // create manager + clk = clock(); + p = Gia_ManTerCreate( pAig ); + if ( fVerbose ) + { + printf( "Obj = %8d (%8d). F = %6d. ", + pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront, + 4.0*Aig_BitWordNum(2 * p->pAig->nFront)/(1<<20) ); + printf( "AIG = %7.2f Mb. F-mem = %7.2f Mb. Other = %7.2f Mb. ", + 12.0*Gia_ManObjNum(p->pAig)/(1<<20), + 4.0*Aig_BitWordNum(2 * p->pAig->nFront)/(1<<20), + 4.0*Aig_BitWordNum(2 * (Gia_ManCiNum(pAig) + Gia_ManCoNum(pAig)))/(1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + // perform simulation + Gia_ManTerSimInfoInit( p ); + // hash the first state + pState = Gia_ManTerStateCreate( p ); + Gia_ManTerStateInsert( pState, p->nStateWords, p->pBins, p->nBins ); +//Gia_ManTerStatePrint( pState, Gia_ManRegNum(pAig), 0 ); + // perform simuluation till convergence + for ( i = 0; ; i++ ) + { + Gia_ManTerSimulateRound( p ); + Gia_ManTerSimInfoTransfer( p ); + pState = Gia_ManTerStateCreate( p ); +//Gia_ManTerStatePrint( pState, Gia_ManRegNum(pAig), i+1 ); + if ( (pLoop = Gia_ManTerStateLookup(pState, p->nStateWords, p->pBins, p->nBins)) ) + { + pAig->nTerStates = Vec_PtrSize( p->vStates ); + pAig->nTerLoop = Vec_PtrFind( p->vStates, pLoop ); + break; + } + Gia_ManTerStateInsert( pState, p->nStateWords, p->pBins, p->nBins ); + if ( i >= p->nIters && i % 10 == 0 ) + { + Counter = Gia_ManTerRetire( p, pState ); + if ( fVerbose ) + printf( "Retired %d registers.\n", Counter ); + } + } + if ( fVerbose ) + { + printf( "Saturated after %d iterations. ", i+1 ); + ABC_PRT( "Total time", clock() - clkTotal ); + } + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ) +{ + Gia_ManTer_t * p; + Gia_Man_t * pNew = NULL; + int * pCi2Lit; + p = Gia_ManTerSimulate( pAig, fVerbose ); + Gia_ManTerAnalyze( p ); + pCi2Lit = Gia_ManTerCreateMap( p ); + Gia_ManTerDelete( p ); + pNew = Gia_ManDupDfsCiMap( pAig, pCi2Lit, NULL ); + ABC_FREE( pCi2Lit ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c new file mode 100644 index 00000000..ef433159 --- /dev/null +++ b/src/aig/gia/giaUtil.c @@ -0,0 +1,518 @@ +/**CFile**************************************************************** + + FileName [giaUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Various utilities.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetMark0( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 1; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanMark0( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 0; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetMark1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark1 = 1; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanMark1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark1 = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanValue( Gia_Man_t * p ) +{ + int i; + for ( i = 0; i < p->nObjs; i++ ) + p->pObjs[i].Value = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFillValue( Gia_Man_t * p ) +{ + int i; + for ( i = 0; i < p->nObjs; i++ ) + p->pObjs[i].Value = ~0; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + } +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLevelNum( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + if ( p->pLevels ) + return p->nLevels; + p->nLevels = 0; + p->pLevels = ABC_ALLOC( int, p->nObjsAlloc ); + Gia_ManForEachObj( p, pObj, i ) + if ( Gia_ObjIsAnd(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]; + } + else if ( Gia_ObjIsCo(pObj) ) + p->pLevels[i] = p->pLevels[Gia_ObjFaninId0(pObj, i)]; + else + p->pLevels[i] = 0; + return p->nLevels; +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + pObj->Value = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->Value++; + Gia_ObjFanin1(pObj)->Value++; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->Value++; + } +} + +/**Function************************************************************* + + Synopsis [Assigns references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCreateRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pRefs == NULL ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjRefFanin0Inc( p, pObj ); + Gia_ObjRefFanin1Inc( p, pObj ); + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjRefFanin0Inc( p, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Computes the maximum frontier size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCrossCut( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, nCutCur = 0, nCutMax = 0; + Gia_ManSetRefs( p ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( pObj->Value ) + nCutCur++; + if ( nCutMax < nCutCur ) + nCutMax = nCutCur; + if ( Gia_ObjIsAnd(pObj) ) + { + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + nCutCur--; + if ( --Gia_ObjFanin1(pObj)->Value == 0 ) + nCutCur--; + } + else if ( Gia_ObjIsCo(pObj) ) + { + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + nCutCur--; + } + } +// Gia_ManForEachObj( p, pObj, i ) +// assert( pObj->Value == 0 ); + return nCutMax; +} + +/**Function************************************************************* + + Synopsis [Makes sure the manager is normalized.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManIsNormalized( Gia_Man_t * p ) +{ + int i, nOffset; + nOffset = 1; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + if ( !Gia_ObjIsCi( Gia_ManObj(p, nOffset+i) ) ) + return 0; + nOffset = 1 + Gia_ManCiNum(p) + Gia_ManAndNum(p); + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + if ( !Gia_ObjIsCo( Gia_ManObj(p, nOffset+i) ) ) + return 0; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Collects PO Ids into one array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ) +{ + Vec_Int_t * vStart; + int Entry, i; + vStart = Vec_IntAlloc( Gia_ManPoNum(p) ); + Vec_IntForEachEntryStop( p->vCos, Entry, i, Gia_ManPoNum(p) ) + Vec_IntPush( vStart, Entry ); + return vStart; +} + + +/**Function************************************************************* + + Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjIsMuxType( Gia_Obj_t * pNode ) +{ + Gia_Obj_t * pNode0, * pNode1; + // check that the node is regular + assert( !Gia_IsComplement(pNode) ); + // if the node is not AND, this is not MUX + if ( !Gia_ObjIsAnd(pNode) ) + return 0; + // if the children are not complemented, this is not MUX + if ( !Gia_ObjFaninC0(pNode) || !Gia_ObjFaninC1(pNode) ) + return 0; + // get children + pNode0 = Gia_ObjFanin0(pNode); + pNode1 = Gia_ObjFanin1(pNode); + // if the children are not ANDs, this is not MUX + if ( !Gia_ObjIsAnd(pNode0) || !Gia_ObjIsAnd(pNode1) ) + return 0; + // otherwise the node is MUX iff it has a pair of equal grandchildren + return (Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1))); +} + + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are inputs of the EXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ) +{ + Gia_Obj_t * p0, * p1; + assert( !Gia_IsComplement(pObj) ); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + p0 = Gia_ObjChild0(pObj); + p1 = Gia_ObjChild1(pObj); + if ( !Gia_IsComplement(p0) || !Gia_IsComplement(p1) ) + return 0; + p0 = Gia_Regular(p0); + p1 = Gia_Regular(p1); + if ( !Gia_ObjIsAnd(p0) || !Gia_ObjIsAnd(p1) ) + return 0; + if ( Gia_ObjFanin0(p0) != Gia_ObjFanin0(p1) || Gia_ObjFanin1(p0) != Gia_ObjFanin1(p1) ) + return 0; + if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) ) + return 0; + *ppFan0 = Gia_ObjChild0(p0); + *ppFan1 = Gia_ObjChild1(p0); + return 1; +} + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are control and data inputs of a MUX.] + + Description [If the node is a MUX, returns the control variable C. + Assigns nodes T and E to be the then and else variables of the MUX. + Node C is never complemented. Nodes T and E can be complemented. + This function also recognizes EXOR/NEXOR gates as MUXes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ) +{ + Gia_Obj_t * pNode0, * pNode1; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsMuxType(pNode) ); + // get children + pNode0 = Gia_ObjFanin0(pNode); + pNode1 = Gia_ObjFanin1(pNode); + + // find the control variable + if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + assert( 0 ); // this is not MUX + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make new file mode 100644 index 00000000..67798476 --- /dev/null +++ b/src/aig/gia/module.make @@ -0,0 +1,19 @@ +SRC += src/aig/gia/gia.c \ + src/aig/gia/giaAig.c \ + src/aig/gia/giaAiger.c \ + src/aig/gia/giaCof.c \ + src/aig/gia/giaDfs.c \ + src/aig/gia/giaDup.c \ + src/aig/gia/giaFanout.c \ + src/aig/gia/giaForce.c \ + src/aig/gia/giaFrames.c \ + src/aig/gia/giaFront.c \ + src/aig/gia/giaGlitch.c \ + src/aig/gia/giaHash.c \ + src/aig/gia/giaLogic.c \ + src/aig/gia/giaMan.c \ + src/aig/gia/giaScl.c \ + src/aig/gia/giaSim.c \ + src/aig/gia/giaSwitch.c \ + src/aig/gia/giaTsim.c \ + src/aig/gia/giaUtil.c |