summaryrefslogtreecommitdiffstats
path: root/src/aig/gia
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia')
-rw-r--r--src/aig/gia/gia.c47
-rw-r--r--src/aig/gia/gia.h423
-rw-r--r--src/aig/gia/giaAig.c214
-rw-r--r--src/aig/gia/giaAiger.c553
-rw-r--r--src/aig/gia/giaCof.c688
-rw-r--r--src/aig/gia/giaConstr.c47
-rw-r--r--src/aig/gia/giaDfs.c243
-rw-r--r--src/aig/gia/giaDup.c698
-rw-r--r--src/aig/gia/giaFanout.c197
-rw-r--r--src/aig/gia/giaForce.c164
-rw-r--r--src/aig/gia/giaFrames.c346
-rw-r--r--src/aig/gia/giaFront.c248
-rw-r--r--src/aig/gia/giaGlitch.c743
-rw-r--r--src/aig/gia/giaHash.c541
-rw-r--r--src/aig/gia/giaLogic.c725
-rw-r--r--src/aig/gia/giaMan.c203
-rw-r--r--src/aig/gia/giaProp.c171
-rw-r--r--src/aig/gia/giaSat.c421
-rw-r--r--src/aig/gia/giaScl.c240
-rw-r--r--src/aig/gia/giaSim.c437
-rw-r--r--src/aig/gia/giaSolver.c490
-rw-r--r--src/aig/gia/giaSolver_cnf.c103
-rw-r--r--src/aig/gia/giaSwitch.c673
-rw-r--r--src/aig/gia/giaTsim.c708
-rw-r--r--src/aig/gia/giaUtil.c518
-rw-r--r--src/aig/gia/module.make19
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( &ltime );
+ TimeStamp = asctime( localtime( &ltime ) );
+ 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