summaryrefslogtreecommitdiffstats
path: root/src/aig/gia
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2009-03-13 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2009-03-13 08:01:00 -0700
commit81b51657f5c502e45418630614fd56e5e1506230 (patch)
tree4fcda87840fb9cca09ac3b31b13aa73abce29a08 /src/aig/gia
parent243cb29e561d9ae4808f9ba27f980ea64a466881 (diff)
downloadabc-81b51657f5c502e45418630614fd56e5e1506230.tar.gz
abc-81b51657f5c502e45418630614fd56e5e1506230.tar.bz2
abc-81b51657f5c502e45418630614fd56e5e1506230.zip
Version abc90313
Diffstat (limited to 'src/aig/gia')
-rw-r--r--src/aig/gia/gia.h28
-rw-r--r--src/aig/gia/giaAig.c23
-rw-r--r--src/aig/gia/giaAiger.c1
-rw-r--r--src/aig/gia/giaCof.c226
-rw-r--r--src/aig/gia/giaDup.c195
-rw-r--r--src/aig/gia/giaEnable.c229
-rw-r--r--src/aig/gia/giaEquiv.c239
7 files changed, 783 insertions, 158 deletions
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index c5d55565..1c3529ba 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -67,6 +67,11 @@ struct Gia_Obj_t_
unsigned Value; // application-specific value
};
+// Value is currently use to store several types of information
+// - pointer to the next node in the hash table during structural hashing
+// - pointer to the node copy during duplication
+// - traversal ID of the node during traversal
+// - reference counter of the node (will not be used in the future)
// sequential counter-example
typedef struct Gia_Cex_t_ Gia_Cex_t;
@@ -177,6 +182,7 @@ static inline int Gia_ManPoNum( Gia_Man_t * p ) { return Vec_IntS
static inline int Gia_ManRegNum( Gia_Man_t * p ) { return p->nRegs; }
static inline int Gia_ManObjNum( Gia_Man_t * p ) { return p->nObjs; }
static inline int Gia_ManAndNum( Gia_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos) - 1; }
+static inline int Gia_ManCandNum( Gia_Man_t * p ) { return Gia_ManCiNum(p) + Gia_ManAndNum(p); }
static inline 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)); }
@@ -193,6 +199,7 @@ static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) {
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_ObjIsCand( Gia_Obj_t * pObj ) { return Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj); }
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; }
@@ -232,6 +239,12 @@ static inline int Gia_ObjWhatFanin( Gia_Obj_t * pObj, Gia_Obj_t * pFani
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 int Gia_ObjCopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return p->pCopies[Gia_ManObjNum(p) * f + Gia_ObjId(p,pObj)]; }
+static inline void Gia_ObjSetCopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj, int iLit ) { p->pCopies[Gia_ManObjNum(p) * f + Gia_ObjId(p,pObj)] = iLit; }
+
+static inline int Gia_ObjFanin0CopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjCopyF(p, f, Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj)); }
+static inline int Gia_ObjFanin1CopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjCopyF(p, f, Gia_ObjFanin1(pObj)), 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_Var2Lit( 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) ); }
@@ -397,6 +410,8 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
#define Gia_ManForEachObjVecLit( vVec, p, pObj, fCompl, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Gia_Lit2Var(Vec_IntEntry(vVec,i)))) && (((fCompl) = Gia_LitIsCompl(Vec_IntEntry(vVec,i))),1); i++ )
+#define Gia_ManForEachObjReverse( p, pObj, i ) \
+ for ( i = p->nObjs - 1; (i > 0) && ((pObj) = Gia_ManObj(p, 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 ) \
@@ -429,6 +444,9 @@ 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 );
+extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar );
+extern Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose );
+extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose );
/*=== 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 );
@@ -436,6 +454,7 @@ extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNo
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_ManDupSelf( 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 );
@@ -444,22 +463,23 @@ extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj );
extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos );
-extern Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan );
extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fDualOut, int fSeq, int fVerbose );
extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p );
/*=== giaEnable.c ==========================================================*/
-extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset );
+extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose );
+extern Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose );
/*=== giaEquiv.c ==========================================================*/
+extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter );
extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem );
-extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll );
+extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose );
extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs );
extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose );
-extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut );
+extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose );
extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut );
extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose );
/*=== giaFanout.c =========================================================*/
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index 544cfe0d..3f707e1c 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -205,6 +205,29 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit )
+{
+ Aig_Man_t * pMan;
+ Gia_Man_t * pGia, * pTemp;
+ pGia = Gia_ManFromAig( p );
+ pGia = Gia_ManUnrollAndCofactor( pTemp = pGia, nFrames, nCofFanLit, 1 );
+ Gia_ManStop( pTemp );
+ pMan = Gia_ManToAig( pGia );
+ Gia_ManStop( pGia );
+ return pMan;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c
index cfd2dc73..da1a8c9f 100644
--- a/src/aig/gia/giaAiger.c
+++ b/src/aig/gia/giaAiger.c
@@ -230,6 +230,7 @@ Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize )
iNode += Item;
pReprs[iNode].fProved = fProved;
pReprs[iNode].iRepr = iRepr;
+ assert( iRepr < iNode );
//printf( "Node = %d ", iNode );
}
return pReprs;
diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c
index 735aca72..c5efa839 100644
--- a/src/aig/gia/giaCof.c
+++ b/src/aig/gia/giaCof.c
@@ -685,6 +685,232 @@ ABC_PRT( "Time", clock() - clk );
}
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG in the DFS order while putting CIs first.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupCofInt( Gia_Man_t * p, int iVar )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pPivot;
+ int i, iCofVar = -1;
+ if ( !(iVar > 0 && iVar < Gia_ManObjNum(p)) )
+ {
+ printf( "Gia_ManDupCof(): Variable %d is out of range (%d; %d).\n", iVar, 0, Gia_ManObjNum(p) );
+ return NULL;
+ }
+ // find the cofactoring variable
+ pPivot = Gia_ManObj( p, iVar );
+ if ( !Gia_ObjIsCand(pPivot) )
+ {
+ printf( "Gia_ManDupCof(): Variable %d should be a CI or an AND node.\n", iVar );
+ return NULL;
+ }
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ // compute negative cofactor
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ if ( pObj == pPivot )
+ {
+ iCofVar = pObj->Value;
+ pObj->Value = Gia_Var2Lit( 0, 0 );
+ }
+ }
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( pObj == pPivot )
+ {
+ iCofVar = pObj->Value;
+ pObj->Value = Gia_Var2Lit( 0, 0 );
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ // compute the positive cofactor
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_Var2Lit( Gia_ObjId(pNew, Gia_ManCi(pNew, i)), 0 );
+ if ( pObj == pPivot )
+ pObj->Value = Gia_Var2Lit( 0, 1 );
+ }
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( pObj == pPivot )
+ pObj->Value = Gia_Var2Lit( 0, 1 );
+ }
+ // create MUXes
+ assert( iCofVar > 0 );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ if ( pObj->Value == (unsigned)Gia_ObjFanin0Copy(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ else
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ManHashMux(pNew, iCofVar, Gia_ObjFanin0Copy(pObj), pObj->Value) );
+ }
+ Gia_ManHashStop( pNew );
+ 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_ManDupCof( Gia_Man_t * p, int iVar )
+{
+ Gia_Man_t * pNew, * pTemp;
+ pNew = Gia_ManDupCofInt( p, iVar );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Determines variables whose fanout count is higher than this.]
+
+ Description [Variables are returned in a reverse topological order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCofVars( Gia_Man_t * p, int nFanLim )
+{
+ Vec_Int_t * vVars;
+ Gia_Obj_t * pObj;
+ int i;
+ ABC_FREE( p->pRefs );
+ Gia_ManCreateRefs( p );
+ vVars = Vec_IntAlloc( 100 );
+ Gia_ManForEachObj( p, pObj, i )
+ if ( Gia_ObjIsCand(pObj) && Gia_ObjRefs(p, pObj) >= nFanLim )
+ Vec_IntPush( vVars, i );
+ ABC_FREE( p->pRefs );
+ return vVars;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers attributes from the original one to the final one.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManTransfer( Gia_Man_t * pAig, Gia_Man_t * pCof, Gia_Man_t * pNew, Vec_Int_t * vSigs )
+{
+ Vec_Int_t * vSigsNew;
+ Gia_Obj_t * pObj, * pObjF;
+ int i;
+ vSigsNew = Vec_IntAlloc( 100 );
+ Gia_ManForEachObjVec( vSigs, pAig, pObj, i )
+ {
+ assert( Gia_ObjIsCand(pObj) );
+ pObjF = Gia_ManObj( pCof, Gia_Lit2Var(pObj->Value) );
+ if ( pObjF->Value && ~pObjF->Value )
+ Vec_IntPushUnique( vSigsNew, Gia_Lit2Var(pObjF->Value) );
+ }
+ return vSigsNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cofactors selected variables (should be in reverse topo order).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose )
+{
+ Vec_Int_t * vSigsNew, * vTemp;
+ Gia_Man_t * pAig, * pCof, * pNew;
+ int iVar;
+ if ( fVerbose )
+ {
+ printf( "Cofactoring %d signals.\n", Vec_IntSize(vSigs) );
+ Gia_ManPrintStats( p );
+ }
+ if ( Vec_IntSize( vSigs ) > 200 )
+ {
+ printf( "Too many signals to cofactor.\n" );
+ return NULL;
+ }
+ pAig = Gia_ManDup( p );
+ vSigsNew = Vec_IntDup( vSigs );
+ while ( Vec_IntSize(vSigsNew) > 0 )
+ {
+ Vec_IntSort( vSigsNew, 0 );
+ iVar = Vec_IntPop( vSigsNew );
+// Gia_ManCreateRefs( pAig );
+// printf( "ref count = %d\n", Gia_ObjRefs( pAig, Gia_ManObj(pAig, iVar) ) );
+// ABC_FREE( pAig->pRefs );
+ pCof = Gia_ManDupCofInt( pAig, iVar );
+ pNew = Gia_ManCleanup( pCof );
+ vSigsNew = Gia_ManTransfer( pAig, pCof, pNew, vTemp = vSigsNew );
+ Vec_IntFree( vTemp );
+ Gia_ManStop( pAig );
+ Gia_ManStop( pCof );
+ pAig = pNew;
+ if ( fVerbose )
+ printf( "Cofactored variable %d.\n", iVar );
+ if ( fVerbose )
+ Gia_ManPrintStats( pAig );
+ }
+ Vec_IntFree( vSigsNew );
+ return pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cofactors all variables whose fanout is higher than this.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vSigs = Gia_ManCofVars( p, nFanLim );
+ pNew = Gia_ManDupCofAllInt( p, vSigs, fVerbose );
+ Vec_IntFree( vSigs );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index 1d940b78..5fb801a7 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -62,6 +62,45 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Duplicates while adding self-loops to the registers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupSelf( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, iCtrl;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ iCtrl = Gia_ManAppendCi( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ Gia_ManForEachRi( p, pObj, i )
+ pObj->Value = Gia_ManHashMux( pNew, iCtrl, Gia_ObjFanin0Copy(pObj), Gia_ObjRiToRo(p, pObj)->Value );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates AIG without any changes.]
Description []
@@ -192,22 +231,22 @@ Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes )
SeeAlso []
***********************************************************************/
-int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+int Gia_ManDupDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( ~pObj->Value )
return pObj->Value;
if ( p->pReprsOld && ~p->pReprsOld[Gia_ObjId(p, pObj)] )
{
Gia_Obj_t * pRepr = Gia_ManObj( p, p->pReprsOld[Gia_ObjId(p, pObj)] );
- pRepr->Value = Gia_ManDupDfs_rec( pNew, p, pRepr );
+ pRepr->Value = Gia_ManDupDfs2_rec( pNew, p, pRepr );
return pObj->Value = Gia_LitNotCond( pRepr->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) );
+ Gia_ManDupDfs2_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) );
+ Gia_ManDupDfs2_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) );
@@ -224,7 +263,7 @@ int Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p )
+Gia_Man_t * Gia_ManDupDfs2( Gia_Man_t * p )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj, * pObjNew;
@@ -234,7 +273,7 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p )
pNew->pName = Aig_UtilStrsav( p->pName );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCo( p, pObj, i )
- Gia_ManDupDfs_rec( pNew, p, pObj );
+ Gia_ManDupDfs2_rec( pNew, p, pObj );
Gia_ManForEachCi( p, pObj, i )
if ( ~pObj->Value == 0 )
pObj->Value = Gia_ManAppendCi(pNew);
@@ -253,6 +292,57 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ 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;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ 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 []
@@ -332,7 +422,7 @@ Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits )
pObj->Value = Gia_ManAppendCi(pNew);
Vec_IntForEachEntry( vLits, iLit, i )
{
- iLitRes = Gia_ManDupDfs_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) );
+ iLitRes = Gia_ManDupDfs2_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) );
Gia_ManAppendCo( pNew, Gia_LitNotCond( iLitRes, Gia_LitIsCompl(iLit)) );
}
Gia_ManSetRegNum( pNew, 0 );
@@ -404,95 +494,6 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos )
/**Function*************************************************************
- Synopsis [Duplicates AIG in the DFS order while putting CIs first.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Gia_Man_t * Gia_ManDupCofactored( Gia_Man_t * p, int iVar, int nLimFan )
-{
- Gia_Man_t * pNew, * pTemp;
- Gia_Obj_t * pObj, * pPivot;
- int i, iCofVar = -1;
- if ( nLimFan > 0 )
- {
- printf( "This feature is not implemented.\n" );
- return NULL;
- }
- if ( !(iVar > 0 && iVar < Gia_ManObjNum(p)) )
- {
- printf( "Gia_ManDupCofactored(): Variable %d is out of range (%d; %d).\n", iVar, 0, Gia_ManObjNum(p) );
- return NULL;
- }
- // find the cofactoring variable
- pPivot = Gia_ManObj( p, iVar );
- if ( !(Gia_ObjIsCi(pPivot) || Gia_ObjIsAnd(pPivot)) )
- {
- printf( "Gia_ManDupCofactored(): Variable %d should be a CI or an AND node.\n", iVar );
- return NULL;
- }
-// assert( Gia_ManRegNum(p) == 0 );
- pNew = Gia_ManStart( Gia_ManObjNum(p) );
- pNew->pName = Aig_UtilStrsav( p->pName );
- Gia_ManHashAlloc( pNew );
- Gia_ManConst0(p)->Value = 0;
- // compute negative cofactor
- Gia_ManForEachCi( p, pObj, i )
- {
- pObj->Value = Gia_ManAppendCi(pNew);
- if ( pObj == pPivot )
- {
- iCofVar = pObj->Value;
- pObj->Value = Gia_Var2Lit( 0, 0 );
- }
- }
- Gia_ManForEachAnd( p, pObj, i )
- {
- pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
- if ( pObj == pPivot )
- {
- iCofVar = pObj->Value;
- pObj->Value = Gia_Var2Lit( 0, 0 );
- }
- }
- Gia_ManForEachCo( p, pObj, i )
- pObj->Value = Gia_ObjFanin0Copy(pObj);
- // compute the positive cofactor
- Gia_ManForEachCi( p, pObj, i )
- {
- pObj->Value = Gia_Var2Lit( Gia_ObjId(pNew, Gia_ManCi(pNew, i)), 0 );
- if ( pObj == pPivot )
- pObj->Value = Gia_Var2Lit( 0, 1 );
- }
- Gia_ManForEachAnd( p, pObj, i )
- {
- pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
- if ( pObj == pPivot )
- pObj->Value = Gia_Var2Lit( 0, 1 );
- }
- // create MUXes
- assert( iCofVar > 0 );
- Gia_ManForEachCo( p, pObj, i )
- {
- if ( pObj->Value == (unsigned)Gia_ObjFanin0Copy(pObj) )
- pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
- else
- pObj->Value = Gia_ManAppendCo( pNew, Gia_ManHashMux(pNew, iCofVar, Gia_ObjFanin0Copy(pObj), pObj->Value) );
- }
- 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 []
@@ -544,7 +545,7 @@ Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits
int iLit, iLitRes;
Vec_IntForEachEntry( vLits, iLit, i )
{
- iLitRes = Gia_ManDupDfs_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) );
+ iLitRes = Gia_ManDupDfs2_rec( pNew, p, Gia_ManObj(p, Gia_Lit2Var(iLit)) );
Gia_ManAppendCo( pNew, Gia_LitNotCond( iLitRes, Gia_LitIsCompl(iLit)) );
}
}
diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c
index d05dc5a9..f80bc885 100644
--- a/src/aig/gia/giaEnable.c
+++ b/src/aig/gia/giaEnable.c
@@ -104,7 +104,7 @@ void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr )
printf( "%s (total = %d driven = %d)\n", pStr, Counter, nTotal );
Counter = 0;
for ( i = 0; i < Gia_ManObjNum(p); i++ )
- if ( pFreq[i] > 1 )
+ if ( pFreq[i] > 10 )
{
printf( "%3d : Obj = %6d Refs = %6d Freq = %6d\n",
++Counter, i, Gia_ObjRefs(p, Gia_ManObj(p,i)), pFreq[i] );
@@ -124,7 +124,7 @@ void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr )
SeeAlso []
***********************************************************************/
-void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset )
+void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose )
{
Vec_Int_t * vSuper;
Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp;
@@ -189,20 +189,235 @@ void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset )
}
}
Vec_IntFree( vSuper );
+ ABC_FREE( p->pRefs );
Gia_ManCreateRefs( p );
- printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable );
- if ( fSetReset )
+ if ( fVerbose )
{
- Gia_ManPrintSignals( p, pSets, "Set signals" );
- Gia_ManPrintSignals( p, pResets, "Reset signals" );
+ printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable );
+ if ( fSetReset )
+ {
+ Gia_ManPrintSignals( p, pSets, "Set signals" );
+ Gia_ManPrintSignals( p, pResets, "Reset signals" );
+ }
+ Gia_ManPrintSignals( p, pEnables, "Enable signals" );
}
- Gia_ManPrintSignals( p, pEnables, "Enable signals" );
ABC_FREE( p->pRefs );
ABC_FREE( pSets );
ABC_FREE( pResets );
ABC_FREE( pEnables );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManDetectSeqSignalsWithFanout( Gia_Man_t * p, int nFanMax, int fVerbose )
+{
+ Vec_Int_t * vResult;
+ Vec_Int_t * vSuper;
+ Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp;
+ int i, k, Ent, * pSets, * pResets, * pEnables;
+ int nHaveSetReset = 0, nHaveEnable = 0;
+ assert( Gia_ManRegNum(p) > 0 );
+ pSets = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ pResets = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ vSuper = Vec_IntAlloc( 100 );
+ Gia_ManForEachRi( p, pFlop, i )
+ {
+ pNode = Gia_ObjFanin0(pFlop);
+ if ( !Gia_ObjIsAnd(pNode) )
+ continue;
+ // detect sets/resets
+ Gia_CollectSuper( p, pNode, vSuper );
+ if ( Gia_ObjFaninC0(pFlop) )
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ pSets[Ent]++;
+ else
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ pResets[Ent]++;
+ // detect enables
+ if ( !Gia_ObjIsMuxType(pNode) )
+ continue;
+ pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 );
+ pTemp = Gia_ObjRiToRo( p, pFlop );
+ if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp )
+ continue;
+ if ( !Gia_ObjFaninC0(pFlop) )
+ {
+ pObj0 = Gia_Not(pObj0);
+ pObj1 = Gia_Not(pObj1);
+ }
+ if ( Gia_IsComplement(pObjC) )
+ {
+ pObjC = Gia_Not(pObjC);
+ pTemp = pObj0;
+ pObj0 = pObj1;
+ pObj1 = pTemp;
+ }
+ // detect controls
+// Gia_CollectSuper( p, pObjC, vSuper );
+// Vec_IntForEachEntry( vSuper, Ent, k )
+// pEnables[Ent]++;
+ pEnables[Gia_ObjId(p, pObjC)]++;
+ nHaveEnable++;
+ }
+ Gia_ManForEachRi( p, pFlop, i )
+ {
+ pNode = Gia_ObjFanin0(pFlop);
+ if ( !Gia_ObjIsAnd(pNode) )
+ continue;
+ // detect sets/resets
+ Gia_CollectSuper( p, pNode, vSuper );
+ Vec_IntForEachEntry( vSuper, Ent, k )
+ if ( pSets[Ent] > 1 || pResets[Ent] > 1 )
+ {
+ nHaveSetReset++;
+ break;
+ }
+ }
+ Vec_IntFree( vSuper );
+ vResult = Vec_IntAlloc( 100 );
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ if ( pSets[i] > nFanMax )
+ {
+ if ( fVerbose )
+ printf( "Adding set signal %d related to %d flops.\n", i, pSets[i] );
+ Vec_IntPushUnique( vResult, i );
+ }
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ if ( pResets[i] > nFanMax )
+ {
+ if ( fVerbose )
+ printf( "Adding reset signal %d related to %d flops.\n", i, pResets[i] );
+ Vec_IntPushUnique( vResult, i );
+ }
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ if ( pEnables[i] > nFanMax )
+ {
+ if ( fVerbose )
+ printf( "Adding enable signal %d related to %d flops.\n", i, pEnables[i] );
+ Vec_IntPushUnique( vResult, i );
+ }
+ ABC_FREE( pSets );
+ ABC_FREE( pResets );
+ ABC_FREE( pEnables );
+ return vResult;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transfers attributes from the original one to the final one.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManTransferFrames( Gia_Man_t * pAig, Gia_Man_t * pFrames, int nFrames, Gia_Man_t * pNew, Vec_Int_t * vSigs )
+{
+ Vec_Int_t * vSigsNew;
+ Gia_Obj_t * pObj, * pObjF;
+ int k, f;
+ vSigsNew = Vec_IntAlloc( 100 );
+ Gia_ManForEachObjVec( vSigs, pAig, pObj, k )
+ {
+ assert( Gia_ObjIsCand(pObj) );
+ for ( f = 0; f < nFrames; f++ )
+ {
+ pObjF = Gia_ManObj( pFrames, Gia_Lit2Var(Gia_ObjCopyF( pAig, f, pObj )) );
+ if ( pObjF->Value && ~pObjF->Value )
+ Vec_IntPushUnique( vSigsNew, Gia_Lit2Var(pObjF->Value) );
+ }
+ }
+ return vSigsNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManUnrollInit( Gia_Man_t * p, int nFrames )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ int f, i;
+ ABC_FREE( p->pCopies );
+ p->pCopies = ABC_FALLOC( int, nFrames * Gia_ManObjNum(p) );
+ pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRo( p, pObj, i )
+ Gia_ObjSetCopyF( p, 0, pObj, 0 );
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManHashAnd(pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj)) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ObjFanin0CopyF(p, f, pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjCopyF(p, f, pObj) );
+ if ( f == nFrames - 1 )
+ break;
+ Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
+ Gia_ObjSetCopyF( p, f+1, pObjRo, Gia_ObjCopyF(p, f, pObjRi) );
+ }
+ Gia_ManHashStop( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Unrolls initialized timeframes while cofactoring some vars.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose )
+{
+ Vec_Int_t * vCofSigs, * vTemp;
+ Gia_Man_t * pAig, * pFrames, * pNew;
+ // compute initialized timeframes
+ pFrames = Gia_ManUnrollInit( p, nFrames );
+ pAig = Gia_ManCleanup( pFrames );
+ // compute and remap set/reset/enable signals
+ vCofSigs = Gia_ManDetectSeqSignalsWithFanout( p, nFanMax, fVerbose );
+ vCofSigs = Gia_ManTransferFrames( p, pFrames, nFrames, pAig, vTemp = vCofSigs );
+ Vec_IntFree( vTemp );
+ Gia_ManStop( pFrames );
+ ABC_FREE( p->pCopies );
+ // cofactor all these variables
+ pNew = Gia_ManDupCofAllInt( pAig, vCofSigs, fVerbose );
+ Vec_IntFree( vCofSigs );
+ Gia_ManStop( pAig );
+ return pNew;
+
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index acdd3c13..b87c77e5 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -30,6 +30,57 @@
/**Function*************************************************************
+ Synopsis [Returns 1 if AIG is not in the required topo order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCheckTopoOrder_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr;
+ if ( pObj->Value == 0 )
+ return 1;
+ pObj->Value = 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( !Gia_ManCheckTopoOrder_rec( p, Gia_ObjFanin0(pObj) ) )
+ return 0;
+ if ( !Gia_ManCheckTopoOrder_rec( p, Gia_ObjFanin1(pObj) ) )
+ return 0;
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ return pRepr == NULL || pRepr->Value == 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 0 if AIG is not in the required topo order.]
+
+ Description [AIG should be in such an order that the representative
+ is always traversed before the node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCheckTopoOrder( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, RetValue = 1;
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = 0;
+ Gia_ManForEachCo( p, pObj, i )
+ RetValue &= Gia_ManCheckTopoOrder_rec( p, Gia_ObjFanin0(pObj) );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
Synopsis [Given representatives, derives pointers to the next objects.]
Description []
@@ -192,18 +243,21 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
SeeAlso []
***********************************************************************/
-static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll )
+static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll, int fDualOut )
{
if ( fUseAll )
{
if ( Gia_ObjRepr(p, Gia_ObjId(p,pObj)) == GIA_VOID )
return NULL;
- }
+ }
else
{
if ( !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
return NULL;
}
+// if ( fDualOut && !Gia_ObjDiffColors( p, Gia_ObjId(p, pObj), Gia_ObjRepr(p, Gia_ObjId(p,pObj)) ) )
+ if ( fDualOut && !Gia_ObjDiffColors2( p, Gia_ObjId(p, pObj), Gia_ObjRepr(p, Gia_ObjId(p,pObj)) ) )
+ return NULL;
return Gia_ManObj( p, Gia_ObjRepr(p, Gia_ObjId(p,pObj)) );
}
@@ -218,20 +272,20 @@ static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int
SeeAlso []
***********************************************************************/
-void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll )
+void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll, int fDualOut )
{
Gia_Obj_t * pRepr;
if ( ~pObj->Value )
return;
assert( Gia_ObjIsAnd(pObj) );
- if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll)) )
+ if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) )
{
- Gia_ManEquivReduce_rec( pNew, p, pRepr, fUseAll );
+ Gia_ManEquivReduce_rec( pNew, p, pRepr, fUseAll, fDualOut );
pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
return;
}
- Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll );
- Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj), fUseAll );
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut );
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj), fUseAll, fDualOut );
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
}
@@ -246,12 +300,24 @@ void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll )
+Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj, * pRepr;
int i;
+ if ( fDualOut && (Gia_ManPoNum(p) & 1) )
+ {
+ printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" );
+ return NULL;
+ }
+ if ( !Gia_ManCheckTopoOrder( p ) )
+ {
+ printf( "Gia_ManEquivReduce(): AIG is not in a correct topological order.\n" );
+ return NULL;
+ }
Gia_ManSetPhase( p );
+ if ( fDualOut )
+ Gia_ManEquivSetColors( p, fVerbose );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
Gia_ManFillValue( p );
@@ -259,12 +325,12 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll )
Gia_ManForEachCi( p, pObj, i )
{
pObj->Value = Gia_ManAppendCi(pNew);
- if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll)) )
+ if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) )
pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
}
Gia_ManHashAlloc( pNew );
Gia_ManForEachCo( p, pObj, i )
- Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll );
+ Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut );
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManHashStop( pNew );
@@ -386,6 +452,52 @@ void Gia_ManEquivDeriveReprs( Gia_Man_t * p, Gia_Man_t * pNew, Gia_Man_t * pFina
/**Function*************************************************************
+ Synopsis [Removes pointers to the unmarked nodes..]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManEquivRemapDfs( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vClass;
+ int i, k, iNode, iRepr, iPrev;
+ pNew = Gia_ManDupDfs( p );
+ // start representatives
+ pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) );
+ for ( i = 0; i < Gia_ManObjNum(pNew); i++ )
+ Gia_ObjSetRepr( pNew, i, GIA_VOID );
+ // iterate over constant candidates
+ Gia_ManForEachConst( p, i )
+ Gia_ObjSetRepr( pNew, Gia_Lit2Var(Gia_ManObj(p, i)->Value), 0 );
+ // iterate over class candidates
+ vClass = Vec_IntAlloc( 100 );
+ Gia_ManForEachClass( p, i )
+ {
+ Vec_IntClear( vClass );
+ Gia_ClassForEachObj( p, i, k )
+ Vec_IntPushUnique( vClass, Gia_Lit2Var(Gia_ManObj(p, k)->Value) );
+ assert( Vec_IntSize( vClass ) > 1 );
+ Vec_IntSort( vClass, 0 );
+ iRepr = iPrev = Vec_IntEntry( vClass, 0 );
+ Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
+ {
+ Gia_ObjSetRepr( pNew, iNode, iRepr );
+ assert( iPrev < iNode );
+ iPrev = iNode;
+ }
+ }
+ Vec_IntFree( vClass );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Reduces AIG while remapping equivalence classes.]
Description [Drops the pairs of outputs if they are proved equivalent.]
@@ -398,7 +510,9 @@ void Gia_ManEquivDeriveReprs( Gia_Man_t * p, Gia_Man_t * pNew, Gia_Man_t * pFina
Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs )
{
Gia_Man_t * pNew, * pFinal;
- pNew = Gia_ManEquivReduce( p, 0 );
+ pNew = Gia_ManEquivReduce( p, 0, 0, 0 );
+ if ( pNew == NULL )
+ return NULL;
if ( fMiterPairs )
Gia_ManEquivFixOutputPairs( pNew );
if ( fSeq )
@@ -409,6 +523,8 @@ Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs
pFinal = Gia_ManDupMarked( pNew );
Gia_ManEquivDeriveReprs( p, pNew, pFinal );
Gia_ManStop( pNew );
+ pFinal = Gia_ManEquivRemapDfs( pNew = pFinal );
+ Gia_ManStop( pNew );
return pFinal;
}
@@ -448,25 +564,24 @@ int Gia_ManEquivSetColor_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fOdds )
int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose )
{
Gia_Obj_t * pObj;
- int i, nNodes[2] = {0,0}, nDiffs[2];
+ int i, nNodes[2], nDiffs[2];
assert( (Gia_ManPoNum(p) & 1) == 0 );
Gia_ObjSetColors( p, 0 );
Gia_ManForEachPi( p, pObj, i )
Gia_ObjSetColors( p, Gia_ObjId(p,pObj) );
+ nNodes[0] = nNodes[1] = Gia_ManPiNum(p);
Gia_ManForEachPo( p, pObj, i )
nNodes[i&1] += Gia_ManEquivSetColor_rec( p, Gia_ObjFanin0(pObj), i&1 );
// Gia_ManForEachObj( p, pObj, i )
// if ( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) )
// assert( Gia_ObjColors(p, i) );
- nDiffs[0] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[0]);
- nDiffs[1] = Gia_ManCiNum(p) + Gia_ManAndNum(p) - (Gia_ManPiNum(p) + nNodes[1]);
+ nDiffs[0] = Gia_ManCandNum(p) - nNodes[0];
+ nDiffs[1] = Gia_ManCandNum(p) - nNodes[1];
if ( fVerbose )
{
printf( "CI+AND = %7d A = %7d B = %7d Ad = %7d Bd = %7d AB = %7d.\n",
- Gia_ManCiNum(p) + Gia_ManAndNum(p),
- Gia_ManPiNum(p) + nNodes[0], Gia_ManPiNum(p) + nNodes[1],
- nDiffs[0], nDiffs[1],
- Gia_ManCiNum(p) + Gia_ManAndNum(p) - nDiffs[0] - nDiffs[1] );
+ Gia_ManCandNum(p), nNodes[0], nNodes[1], nDiffs[0], nDiffs[1],
+ Gia_ManCandNum(p) - nDiffs[0] - nDiffs[1] );
}
return (nDiffs[0] + nDiffs[1]) / 2;
}
@@ -482,13 +597,16 @@ int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
-static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits )
+static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut )
{
Gia_Obj_t * pRepr;
unsigned iLitNew;
pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
if ( pRepr == NULL )
return;
+// if ( fDualOut && !Gia_ObjDiffColors( p, Gia_ObjId(p, pObj), Gia_ObjId(p, pRepr) ) )
+ if ( fDualOut && !Gia_ObjDiffColors2( p, Gia_ObjId(p, pObj), Gia_ObjId(p, pRepr) ) )
+ return;
iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
if ( pObj->Value != iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) );
@@ -506,15 +624,15 @@ static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t
SeeAlso []
***********************************************************************/
-void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits )
+void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut )
{
if ( ~pObj->Value )
return;
assert( Gia_ObjIsAnd(pObj) );
- Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits );
- Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits );
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut );
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits, fDualOut );
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
- Gia_ManSpecBuild( pNew, p, pObj, vXorLits );
+ Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut );
}
/**Function*************************************************************
@@ -528,7 +646,7 @@ void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, V
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut )
+Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose )
{
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj;
@@ -539,9 +657,21 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut )
printf( "Gia_ManSpecReduce(): Equivalence classes are not available.\n" );
return NULL;
}
+ if ( fDualOut && (Gia_ManPoNum(p) & 1) )
+ {
+ printf( "Gia_ManSpecReduce(): Dual-output miter should have even number of POs.\n" );
+ return NULL;
+ }
+ if ( !Gia_ManCheckTopoOrder( p ) )
+ {
+ printf( "Gia_ManSpecReduce(): AIG is not in a correct topological order.\n" );
+ return NULL;
+ }
vXorLits = Vec_IntAlloc( 1000 );
Gia_ManSetPhase( p );
Gia_ManFillValue( p );
+ if ( fDualOut )
+ Gia_ManEquivSetColors( p, fVerbose );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
Gia_ManHashAlloc( pNew );
@@ -549,9 +679,9 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut )
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachRo( p, pObj, i )
- Gia_ManSpecBuild( pNew, p, pObj, vXorLits );
+ Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut );
Gia_ManForEachCo( p, pObj, i )
- Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits );
+ Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut );
Vec_IntForEachEntry( vXorLits, iLitNew, i )
Gia_ManAppendCo( pNew, iLitNew );
if ( Vec_IntSize(vXorLits) == 0 )
@@ -570,12 +700,6 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut )
}
-static inline int Gia_ObjSpec( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return p->pCopies[Gia_ManObjNum(p) * f + Gia_ObjId(p,pObj)]; }
-static inline void Gia_ObjSetSpec( Gia_Man_t * p, int f, Gia_Obj_t * pObj, int iLit ) { p->pCopies[Gia_ManObjNum(p) * f + Gia_ObjId(p,pObj)] = iLit; }
-
-static inline int Gia_ObjChild0Spec( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjSpec(p, f, Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj)); }
-static inline int Gia_ObjChild1Spec( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjSpec(p, f, Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj)); }
-
/**Function*************************************************************
Synopsis [Duplicates the AIG in the DFS order.]
@@ -587,17 +711,20 @@ static inline int Gia_ObjChild1Spec( Gia_Man_t * p, int f, Gia_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-void Gia_ManSpecBuildInit( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int f )
+void Gia_ManSpecBuildInit( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int f, int fDualOut )
{
Gia_Obj_t * pRepr;
int iLitNew;
pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
if ( pRepr == NULL )
return;
- iLitNew = Gia_LitNotCond( Gia_ObjSpec(p, f, pRepr), Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
- if ( Gia_ObjSpec(p, f, pObj) != iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
- Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, Gia_ObjSpec(p, f, pObj), iLitNew) );
- Gia_ObjSetSpec( p, f, pObj, iLitNew );
+// if ( fDualOut && !Gia_ObjDiffColors( p, Gia_ObjId(p, pObj), Gia_ObjId(p, pRepr) ) )
+ if ( fDualOut && !Gia_ObjDiffColors2( p, Gia_ObjId(p, pObj), Gia_ObjId(p, pRepr) ) )
+ return;
+ iLitNew = Gia_LitNotCond( Gia_ObjCopyF(p, f, pRepr), Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ if ( Gia_ObjCopyF(p, f, pObj) != iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) )
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, Gia_ObjCopyF(p, f, pObj), iLitNew) );
+ Gia_ObjSetCopyF( p, f, pObj, iLitNew );
}
/**Function*************************************************************
@@ -611,15 +738,15 @@ void Gia_ManSpecBuildInit( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Ve
SeeAlso []
***********************************************************************/
-void Gia_ManSpecReduceInit_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int f )
+void Gia_ManSpecReduceInit_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int f, int fDualOut )
{
- if ( ~Gia_ObjSpec(p, f, pObj) )
+ if ( ~Gia_ObjCopyF(p, f, pObj) )
return;
assert( Gia_ObjIsAnd(pObj) );
- Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, f );
- Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits, f );
- Gia_ObjSetSpec( p, f, pObj, Gia_ManHashAnd(pNew, Gia_ObjChild0Spec(p, f, pObj), Gia_ObjChild1Spec(p, f, pObj)) );
- Gia_ManSpecBuildInit( pNew, p, pObj, vXorLits, f );
+ Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, f, fDualOut );
+ Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits, f, fDualOut );
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManHashAnd(pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj)) );
+ Gia_ManSpecBuildInit( pNew, p, pObj, vXorLits, f, fDualOut );
}
/**Function*************************************************************
@@ -654,31 +781,43 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames
printf( "Gia_ManSpecReduceInit(): Mismatch in the number of registers.\n" );
return NULL;
}
+ if ( fDualOut && (Gia_ManPoNum(p) & 1) )
+ {
+ printf( "Gia_ManSpecReduceInit(): Dual-output miter should have even number of POs.\n" );
+ return NULL;
+ }
+ if ( !Gia_ManCheckTopoOrder( p ) )
+ {
+ printf( "Gia_ManSpecReduceInit(): AIG is not in a correct topological order.\n" );
+ return NULL;
+ }
assert( pInit->nRegs == Gia_ManRegNum(p) && pInit->nPis == 0 );
p->pCopies = ABC_FALLOC( int, nFrames * Gia_ManObjNum(p) );
vXorLits = Vec_IntAlloc( 1000 );
Gia_ManSetPhase( p );
+ if ( fDualOut )
+ Gia_ManEquivSetColors( p, 0 );
pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
Gia_ManHashAlloc( pNew );
Gia_ManForEachRo( p, pObj, i )
- Gia_ObjSetSpec( p, 0, pObj, Aig_InfoHasBit(pInit->pData, i) );
+ Gia_ObjSetCopyF( p, 0, pObj, Aig_InfoHasBit(pInit->pData, i) );
for ( f = 0; f < nFrames; f++ )
{
- Gia_ObjSetSpec( p, f, Gia_ManConst0(p), 0 );
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
Gia_ManForEachPi( p, pObj, i )
- Gia_ObjSetSpec( p, f, pObj, Gia_ManAppendCi(pNew) );
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
Gia_ManForEachRo( p, pObj, i )
- Gia_ManSpecBuildInit( pNew, p, pObj, vXorLits, f );
+ Gia_ManSpecBuildInit( pNew, p, pObj, vXorLits, f, fDualOut );
Gia_ManForEachCo( p, pObj, i )
{
- Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, f );
- Gia_ObjSetSpec( p, f, pObj, Gia_ObjChild0Spec(p, f, pObj) );
+ Gia_ManSpecReduceInit_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, f, fDualOut );
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ObjFanin0CopyF(p, f, pObj) );
}
if ( f == nFrames - 1 )
break;
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
- Gia_ObjSetSpec( p, f+1, pObjRo, Gia_ObjSpec(p, f, pObjRi) );
+ Gia_ObjSetCopyF( p, f+1, pObjRo, Gia_ObjCopyF(p, f, pObjRi) );
}
Vec_IntForEachEntry( vXorLits, iLitNew, i )
Gia_ManAppendCo( pNew, iLitNew );