summaryrefslogtreecommitdiffstats
path: root/src/aig
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2021-11-12 12:31:29 +0100
committerMiodrag Milanovic <mmicko@gmail.com>2021-11-12 12:31:29 +0100
commitd2d6bbd9f86f61fc9b5cc7d703e1386bbd6ad6a2 (patch)
tree071fb2118c158c748ff9969ef250affe7b9a3561 /src/aig
parent4f5f73d18b137930fb3048c0b385c82fa078db38 (diff)
parent9b245d9f6910c048e9bbcf95ee5dee46f2f24f2c (diff)
downloadabc-d2d6bbd9f86f61fc9b5cc7d703e1386bbd6ad6a2.tar.gz
abc-d2d6bbd9f86f61fc9b5cc7d703e1386bbd6ad6a2.tar.bz2
abc-d2d6bbd9f86f61fc9b5cc7d703e1386bbd6ad6a2.zip
Merge remote-tracking branch 'upstream/master' into yosys-experimental
Diffstat (limited to 'src/aig')
-rw-r--r--src/aig/gia/gia.c96
-rw-r--r--src/aig/gia/gia.h58
-rw-r--r--src/aig/gia/giaAig.c36
-rw-r--r--src/aig/gia/giaAiger.c281
-rw-r--r--src/aig/gia/giaCSat.c4
-rw-r--r--src/aig/gia/giaCSat3.c1365
-rw-r--r--src/aig/gia/giaCut.c149
-rw-r--r--src/aig/gia/giaDecs.c350
-rw-r--r--src/aig/gia/giaDeep.c120
-rw-r--r--src/aig/gia/giaDfs.c28
-rw-r--r--src/aig/gia/giaDup.c188
-rw-r--r--src/aig/gia/giaEmbed.c2
-rw-r--r--src/aig/gia/giaEquiv.c297
-rw-r--r--src/aig/gia/giaFanout.c83
-rw-r--r--src/aig/gia/giaFx.c6
-rw-r--r--src/aig/gia/giaGen.c461
-rw-r--r--src/aig/gia/giaHash.c322
-rw-r--r--src/aig/gia/giaIf.c82
-rw-r--r--src/aig/gia/giaIso.c6
-rw-r--r--src/aig/gia/giaIso2.c2
-rw-r--r--src/aig/gia/giaIso3.c91
-rw-r--r--src/aig/gia/giaMan.c99
-rw-r--r--src/aig/gia/giaMf.c238
-rw-r--r--src/aig/gia/giaMinLut.c1058
-rw-r--r--src/aig/gia/giaMinLut2.c1372
-rw-r--r--src/aig/gia/giaMini.c396
-rw-r--r--src/aig/gia/giaPat2.c1329
-rw-r--r--src/aig/gia/giaReshape1.c (renamed from src/aig/gia/giaSim5.c)18
-rw-r--r--src/aig/gia/giaReshape2.c (renamed from src/aig/gia/giaSim4.c)12
-rw-r--r--src/aig/gia/giaResub.c1767
-rw-r--r--src/aig/gia/giaResub2.c1558
-rw-r--r--src/aig/gia/giaResub3.c54
-rw-r--r--src/aig/gia/giaScript.c21
-rw-r--r--src/aig/gia/giaSim.c166
-rw-r--r--src/aig/gia/giaSimBase.c837
-rw-r--r--src/aig/gia/giaStoch.c448
-rw-r--r--src/aig/gia/giaStr.c26
-rw-r--r--src/aig/gia/giaSupps.c817
-rw-r--r--src/aig/gia/giaSweep.c25
-rw-r--r--src/aig/gia/giaTruth.c32
-rw-r--r--src/aig/gia/giaUtil.c803
-rw-r--r--src/aig/gia/module.make13
-rw-r--r--src/aig/hop/hopBalance.c2
-rw-r--r--src/aig/ivy/ivyBalance.c2
-rw-r--r--src/aig/ivy/ivyCutTrav.c2
-rw-r--r--src/aig/ivy/ivyRwrAlg.c2
-rw-r--r--src/aig/miniaig/abcOper.h26
-rw-r--r--src/aig/miniaig/minilut.h32
-rw-r--r--src/aig/miniaig/ndr.h85
-rw-r--r--src/aig/saig/saigConstr.c4
-rw-r--r--src/aig/saig/saigIso.c4
-rw-r--r--src/aig/saig/saigIsoFast.c2
-rw-r--r--src/aig/saig/saigIsoSlow.c8
-rw-r--r--src/aig/saig/saigWnd.c2
54 files changed, 14986 insertions, 301 deletions
diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c
index 7947a60e..ed6e276a 100644
--- a/src/aig/gia/gia.c
+++ b/src/aig/gia/gia.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "gia.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -297,6 +298,101 @@ void Gia_ManStructExperiment( Gia_Man_t * p )
Vec_PtrFree( vGias );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_EnumFirstUnused( int * pUsed, int nVars )
+{
+ int i;
+ for ( i = 0; i < nVars; i++ )
+ if ( pUsed[i] == 0 )
+ return i;
+ return -1;
+}
+void Gia_EnumPerms_rec( int * pUsed, int nVars, int * pPerm, int nPerm, int * pCount, FILE * pFile, int nLogVars )
+{
+ int i, k, New;
+ if ( nPerm == nVars )
+ {
+ if ( pFile )
+ {
+ for ( i = 0; i < nLogVars; i++ )
+ fprintf( pFile, "%c", '0' + ((*pCount) >> (nLogVars-1-i) & 1) );
+ fprintf( pFile, " " );
+ for ( i = 0; i < nVars; i++ )
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, "%c", '0' + (pPerm[i] == k) );
+ fprintf( pFile, "\n" );
+ }
+ else
+ {
+ if ( *pCount < 20 )
+ {
+ printf( "%5d : ", (*pCount) );
+ for ( i = 0; i < nVars; i += 2 )
+ printf( "%d %d ", pPerm[i], pPerm[i+1] );
+ printf( "\n" );
+ }
+ }
+ (*pCount)++;
+ return;
+ }
+ New = Gia_EnumFirstUnused( pUsed, nVars );
+ assert( New >= 0 );
+ pPerm[nPerm] = New;
+ assert( pUsed[New] == 0 );
+ pUsed[New] = 1;
+ // try remaining ones
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( pUsed[i] == 1 )
+ continue;
+ pPerm[nPerm+1] = i;
+ assert( pUsed[i] == 0 );
+ pUsed[i] = 1;
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, nPerm+2, pCount, pFile, nLogVars );
+ assert( pUsed[i] == 1 );
+ pUsed[i] = 0;
+ }
+ assert( pUsed[New] == 1 );
+ pUsed[New] = 0;
+}
+void Gia_EnumPerms( int nVars )
+{
+ int nLogVars = 0, Count = 0;
+ int * pUsed = ABC_CALLOC( int, nVars );
+ int * pPerm = ABC_CALLOC( int, nVars );
+ FILE * pFile = fopen( "pairset.pla", "wb" );
+ assert( nVars % 2 == 0 );
+
+ printf( "Printing sets of pairs for %d objects:\n", nVars );
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, NULL, -1 );
+ if ( Count > 20 )
+ printf( "...\n" );
+ printf( "Finished enumerating %d sets of pairs.\n", Count );
+
+ nLogVars = Abc_Base2Log( Count );
+ printf( "Need %d variables to encode %d sets.\n", nLogVars, Count );
+ Count = 0;
+ fprintf( pFile, ".i %d\n", nLogVars );
+ fprintf( pFile, ".o %d\n", nVars*nVars );
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, pFile, nLogVars );
+ fprintf( pFile, ".e\n" );
+ fclose( pFile );
+ printf( "Finished dumping file \"%s\".\n", "pairset.pla" );
+
+ ABC_FREE( pUsed );
+ ABC_FREE( pPerm );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index ae9835ee..5548def6 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -171,6 +171,7 @@ struct Gia_Man_t_
Vec_Int_t * vCoReqs; // CO required times
Vec_Int_t * vCoArrs; // CO arrival times
Vec_Int_t * vCoAttrs; // CO attributes
+ Vec_Int_t * vWeights; // object attributes
int And2Delay; // delay of the AND gate
float DefInArrs; // default PI arrival times
float DefOutReqs; // default PO required times
@@ -179,6 +180,7 @@ struct Gia_Man_t_
int nTravIdsAlloc; // the number of trav IDs allocated
Vec_Ptr_t * vNamesIn; // the input names
Vec_Ptr_t * vNamesOut; // the output names
+ Vec_Ptr_t * vNamesNode; // the node names
Vec_Int_t * vUserPiIds; // numbers assigned to PIs by the user
Vec_Int_t * vUserPoIds; // numbers assigned to POs by the user
Vec_Int_t * vUserFfIds; // numbers assigned to FFs by the user
@@ -214,6 +216,8 @@ struct Gia_Man_t_
Vec_Wrd_t * vSimsPo;
Vec_Int_t * vClassOld;
Vec_Int_t * vClassNew;
+ Vec_Int_t * vPats;
+ Vec_Bit_t * vPolars;
// incremental simulation
int fIncrSim;
int iNextPi;
@@ -235,6 +239,7 @@ struct Gia_Man_t_
Vec_Wrd_t * vSuppWords; // support information
Vec_Int_t vCopiesTwo; // intermediate copies
Vec_Int_t vSuppVars; // used variables
+ Vec_Int_t vVarMap; // used variables
Gia_Dat_t * pUData;
};
@@ -339,6 +344,7 @@ struct Jf_Par_t_
int fCutMin;
int fFuncDsd;
int fGenCnf;
+ int fGenLit;
int fCnfObjIds;
int fAddOrCla;
int fCnfMapping;
@@ -477,6 +483,11 @@ static inline int Gia_ObjValue( Gia_Obj_t * pObj ) {
static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; }
static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; }
static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); }
+static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; }
+static inline char * Gia_ObjCiName( Gia_Man_t * p, int i ) { return p->vNamesIn ? (char*)Vec_PtrEntry(p->vNamesIn, i) : NULL; }
+static inline char * Gia_ObjCoName( Gia_Man_t * p, int i ) { return p->vNamesOut ? (char*)Vec_PtrEntry(p->vNamesOut, i) : NULL; }
+static inline char * Gia_ObjName( Gia_Man_t * p, int i ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, i) : NULL; }
+static inline char * Gia_ObjNameObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, Gia_ObjId(p, pObj)) : NULL; }
static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; }
static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; }
@@ -538,6 +549,7 @@ static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) {
static inline int Gia_ObjFaninNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsMux(p, pObj) ) return 3; if ( Gia_ObjIsAnd(pObj) ) return 2; if ( Gia_ObjIsCo(pObj) ) return 1; return 0; }
static inline int Gia_ObjWhatFanin( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { if ( Gia_ObjFanin0(pObj) == pFanin ) return 0; if ( Gia_ObjFanin1(pObj) == pFanin ) return 1; if ( Gia_ObjFanin2(p, pObj) == pFanin ) return 2; assert(0); return -1; }
+static inline int Gia_ManCoDriverId( Gia_Man_t * p, int iCoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManCo(p, iCoIndex)); }
static inline int Gia_ManPoIsConst( Gia_Man_t * p, int iPoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManPo(p, iPoIndex)) == 0; }
static inline int Gia_ManPoIsConst0( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst0Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
static inline int Gia_ManPoIsConst1( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst1Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
@@ -570,6 +582,7 @@ static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) {
static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); }
static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjLevelId( p, Gia_ObjId(p,pObj) ); }
+static inline void Gia_ObjUpdateLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, Abc_MaxInt(Vec_IntEntry(p->vLevels, Id), l)); }
static inline void Gia_ObjSetLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, l); }
static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Gia_ObjSetLevelId( p, Gia_ObjId(p,pObj), l ); }
static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); }
@@ -610,10 +623,14 @@ static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * p
static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; }
static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); }
static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
+static inline int Gia_ObjUpdateTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 1; Gia_ObjSetTravIdCurrent(p, pObj); return 0; }
+static inline int Gia_ObjUpdateTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdPrevious(p, pObj) ) return 1; Gia_ObjSetTravIdPrevious(p, pObj); return 0; }
static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; }
static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); }
+static inline int Gia_ObjUpdateTravIdCurrentId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdCurrentId(p, Id) ) return 1; Gia_ObjSetTravIdCurrentId(p, Id); return 0; }
+static inline int Gia_ObjUpdateTravIdPreviousId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdPreviousId(p, Id) ) return 1; Gia_ObjSetTravIdPreviousId(p, Id); return 0; }
static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); }
static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); }
@@ -1067,9 +1084,11 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a
#define Gia_ManForEachClassReverse( p, i ) \
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ClassForEachObj( p, i, iObj ) \
- for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
+ for ( assert(Gia_ObjIsHead(p, i) && i), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
#define Gia_ClassForEachObj1( p, i, iObj ) \
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
+#define Gia_ClassForEachObjStart( p, i, iObj, Start ) \
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, Start); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); }
@@ -1149,7 +1168,13 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
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_ManForEachObjVecReverse( vVec, p, pObj, i ) \
+#define Gia_ManForEachObjVecStart( vVec, p, pObj, i, Start ) \
+ for ( i = Start; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecStop( vVec, p, pObj, i, Stop ) \
+ for ( i = 0; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecStartStop( vVec, p, pObj, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((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, Abc_Lit2Var(Vec_IntEntry(vVec,i)))) && (((fCompl) = Abc_LitIsCompl(Vec_IntEntry(vVec,i))),1); i++ )
@@ -1245,7 +1270,7 @@ extern Cbs_Man_t * Cbs_ManAlloc( Gia_Man_t * pGia );
extern void Cbs_ManStop( Cbs_Man_t * p );
extern int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj );
extern int Cbs_ManSolve2( Cbs_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
-extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
+extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose );
extern void Cbs_ManSetConflictNum( Cbs_Man_t * p, int Num );
extern Vec_Int_t * Cbs_ReadModel( Cbs_Man_t * p );
/*=== giaCTas.c ============================================================*/
@@ -1255,6 +1280,11 @@ 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 );
+/*=== giaDecs.c ============================================================*/
+extern int Gia_ResubVarNum( Vec_Int_t * vResub );
+extern word Gia_ResubToTruth6( Vec_Int_t * vResub );
+extern int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose );
+extern Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type );
/*=== giaDfs.c ============================================================*/
extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp );
extern void Gia_ManCollectAnds_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes );
@@ -1264,6 +1294,7 @@ extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes,
extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p );
+extern Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p );
extern void Gia_ManCollectTfi( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
extern void Gia_ManCollectTfo( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
@@ -1272,7 +1303,7 @@ extern void Gia_ManDupRemapLiterals( Vec_Int_t * vLits, Gia_Man_t
extern void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p );
-extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts );
extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop );
extern Gia_Man_t * Gia_ManDupOutputVec( Gia_Man_t * p, Vec_Int_t * vOutPres );
extern Gia_Man_t * Gia_ManDupSelectedOutputs( Gia_Man_t * p, Vec_Int_t * vOutsLeft );
@@ -1298,6 +1329,7 @@ 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_ManDupDfsOnePo( Gia_Man_t * p, int iPo );
+extern Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupCofactorVar( Gia_Man_t * p, int iVar, int Value );
extern Gia_Man_t * Gia_ManDupCofactorObj( Gia_Man_t * p, int iObj, int Value );
extern Gia_Man_t * Gia_ManDupMux( int iVar, Gia_Man_t * pCof1, Gia_Man_t * pCof0 );
@@ -1397,6 +1429,7 @@ extern void Gia_ManFanoutStart( Gia_Man_t * p );
extern void Gia_ManFanoutStop( Gia_Man_t * p );
extern void Gia_ManStaticFanoutStart( Gia_Man_t * p );
extern void Gia_ManStaticFanoutStop( Gia_Man_t * p );
+extern void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p );
/*=== giaForce.c =========================================================*/
extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose );
/*=== giaFrames.c =========================================================*/
@@ -1480,7 +1513,7 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
-extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs );
+extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs );
/*=== giaMem.c ===========================================================*/
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
@@ -1504,7 +1537,7 @@ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars );
extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars );
extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose );
/*=== giaMini.c ===========================================================*/
-extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName );
+extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple );
extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
extern Gia_Man_t * Gia_ManReadMiniLut( char * pFileName );
extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName );
@@ -1557,6 +1590,15 @@ extern void Gia_ManIncrSimStart( Gia_Man_t * p, int nWords, int n
extern void Gia_ManIncrSimSet( Gia_Man_t * p, Vec_Int_t * vObjLits );
extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, int iLit1 );
extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 );
+/*=== giaSimBase.c ============================================================*/
+extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p );
+extern Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts );
+extern void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes );
+extern Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims );
+extern Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes );
+extern Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes );
+extern void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose );
+extern Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose );
/*=== giaSpeedup.c ============================================================*/
extern float Gia_ManDelayTraceLut( Gia_Man_t * p );
extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose );
@@ -1668,6 +1710,7 @@ extern void Gia_ManSetPhase1( Gia_Man_t * p );
extern void Gia_ManCleanPhase( Gia_Man_t * p );
extern int Gia_ManCheckCoPhase( Gia_Man_t * p );
extern int Gia_ManLevelNum( Gia_Man_t * p );
+extern int Gia_ManLevelRNum( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManGetCiLevels( Gia_Man_t * p );
extern int Gia_ManSetLevels( Gia_Man_t * p, Vec_Int_t * vCiLevels );
extern Vec_Int_t * Gia_ManReverseLevel( Gia_Man_t * p );
@@ -1682,7 +1725,9 @@ extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t **
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
extern int Gia_ObjRecognizeMuxLits( Gia_Man_t * p, Gia_Obj_t * pNode, int * iLitT, int * iLitE );
extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode );
+extern int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode );
extern int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp );
+extern int Gia_NodeMffcMapping( Gia_Man_t * p );
extern int Gia_ManHasDangling( Gia_Man_t * p );
extern int Gia_ManMarkDangling( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p );
@@ -1704,6 +1749,7 @@ extern int Gia_ManCheckSuppOverlap( Gia_Man_t * p, int iNode1, i
extern int Gia_ManCountPisWithFanout( Gia_Man_t * p );
extern int Gia_ManCountPosWithNonZeroDrivers( Gia_Man_t * p );
extern void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p );
+extern Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose );
/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index dfd4a467..91a9c600 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -102,6 +102,41 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
/**Function*************************************************************
+ Synopsis [Checks integrity of choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCheckChoices_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !pObj || !Gia_ObjIsAnd(pObj) || pObj->fPhase )
+ return;
+ pObj->fPhase = 1;
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin1(pObj) );
+ Gia_ManCheckChoices_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) );
+}
+void Gia_ManCheckChoices( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, fFound = 0;
+ Gia_ManCleanPhase( p );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( !pObj->fPhase )
+ printf( "Object %d is dangling.\n", i ), fFound = 1;
+ if ( !fFound )
+ printf( "There are no dangling objects.\n" );
+ Gia_ManCleanPhase( p );
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates AIG in the DFS order.]
Description []
@@ -155,6 +190,7 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
+ //Gia_ManCheckChoices( pNew );
return pNew;
}
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c
index c9ad28db..aafe311b 100644
--- a/src/aig/gia/giaAiger.c
+++ b/src/aig/gia/giaAiger.c
@@ -176,6 +176,7 @@ Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits )
Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck )
{
Gia_Man_t * pNew, * pTemp;
+ Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL, * vNamesNode = NULL;
Vec_Int_t * vLits = NULL, * vPoTypes = NULL;
Vec_Int_t * vNodes, * vDrivers, * vInits = NULL;
int iObj, iNode0, iNode1, fHieOnly = 0;
@@ -377,6 +378,101 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
pCur = pSymbols;
if ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
{
+ int fReadNames = 1;
+ if ( fReadNames )
+ {
+ int fError = 0;
+ while ( !fError && pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
+ {
+ int iTerm;
+ char * pType = (char *)pCur;
+ char * pName = NULL;
+ // check terminal type
+ if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' && *pCur != 'n' )
+ {
+ fError = 1;
+ break;
+ }
+ // get terminal number
+ iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' );
+ // skip spaces
+ while ( *pCur == ' ' )
+ pCur++;
+ // skip till the end of line
+ for ( pName = (char *)pCur; *pCur && *pCur != '\n'; pCur++ );
+ if ( *pCur == '\n' )
+ *pCur = 0;
+ // save the name
+ if ( *pType == 'i' )
+ {
+ if ( vNamesIn == NULL )
+ vNamesIn = Vec_PtrAlloc( nInputs + nLatches );
+ if ( Vec_PtrSize(vNamesIn) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesIn, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'o' )
+ {
+ if ( vNamesOut == NULL )
+ vNamesOut = Vec_PtrAlloc( nOutputs + nLatches );
+ if ( Vec_PtrSize(vNamesOut) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesOut, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'l' )
+ {
+ char Buffer[1000];
+ assert( strlen(pName) < 995 );
+ sprintf( Buffer, "%s_in", pName );
+ if ( vNamesRegIn == NULL )
+ vNamesRegIn = Vec_PtrAlloc( nLatches );
+ if ( vNamesRegOut == NULL )
+ vNamesRegOut = Vec_PtrAlloc( nLatches );
+ if ( Vec_PtrSize(vNamesRegIn) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) );
+ Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'n' )
+ {
+ if ( Vec_IntSize(&pNew->vHTable) != 0 )
+ {
+ printf( "Structural hashing should be disabled to read internal nodes names.\n" );
+ fError = 1;
+ break;
+ }
+ if ( vNamesNode == NULL )
+ vNamesNode = Vec_PtrStart( Gia_ManObjNum(pNew) );
+ Vec_PtrWriteEntry( vNamesNode, iTerm, Abc_UtilStrsav(pName) );
+ }
+ else
+ {
+ fError = 1;
+ break;
+ }
+ pCur++;
+ }
+ if ( fError )
+ {
+ printf( "Error occurred when reading signal names. Signal names ignored.\n" );
+ if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ), vNamesIn = NULL;
+ if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ), vNamesOut = NULL;
+ if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ), vNamesRegIn = NULL;
+ if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ), vNamesRegOut = NULL;
+ if ( vNamesNode ) Vec_PtrFreeFree( vNamesNode ), vNamesNode = NULL;
+ }
+ }
+ else
+ {
int fBreakUsed = 0;
unsigned char * pCurOld = pCur;
pNew->vUserPiIds = Vec_IntStartFull( nInputs );
@@ -505,6 +601,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
}
Vec_IntFree( vPoNames );
}
+ }
}
@@ -636,6 +733,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
pCur++;
if ( (*pCur >= 'a' && *pCur <= 'z') || (*pCur >= 'A' && *pCur <= 'Z') || (*pCur >= '0' && *pCur <= '9') )
{
+ ABC_FREE( pNew->pName );
pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1;
}
else
@@ -866,6 +964,39 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
Abc_Print( 0, "Structural hashing enabled while reading AIGER invalidated the mapping. Consider using \"&r -s\".\n" );
Vec_IntFreeP( &pNew->vMapping );
}
+ if ( vNamesIn && Gia_ManPiNum(pNew) != Vec_PtrSize(vNamesIn) )
+ Abc_Print( 0, "The number of inputs does not match the number of input names.\n" );
+ else if ( vNamesOut && Gia_ManPoNum(pNew) != Vec_PtrSize(vNamesOut) )
+ Abc_Print( 0, "The number of output does not match the number of output names.\n" );
+ else if ( vNamesRegOut && Gia_ManRegNum(pNew) != Vec_PtrSize(vNamesRegOut) )
+ Abc_Print( 0, "The number of inputs does not match the number of flop names.\n" );
+ else if ( vNamesIn && vNamesOut )
+ {
+ pNew->vNamesIn = vNamesIn; vNamesIn = NULL;
+ pNew->vNamesOut = vNamesOut; vNamesOut = NULL;
+ if ( vNamesRegOut )
+ {
+ Vec_PtrAppend( pNew->vNamesIn, vNamesRegOut );
+ Vec_PtrClear( vNamesRegOut );
+ Vec_PtrFree( vNamesRegOut );
+ vNamesRegOut = NULL;
+ }
+ if ( vNamesRegIn )
+ {
+ Vec_PtrAppend( pNew->vNamesOut, vNamesRegIn );
+ Vec_PtrClear( vNamesRegIn );
+ Vec_PtrFree( vNamesRegIn );
+ vNamesRegIn = NULL;
+ }
+ }
+ if ( vNamesNode && Gia_ManObjNum(pNew) != Vec_PtrSize(vNamesNode) )
+ Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not entered.\n" );
+ else if ( vNamesNode )
+ pNew->vNamesNode = vNamesNode, vNamesNode = NULL;
+ if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn );
+ if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut );
+ if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn );
+ if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut );
return pNew;
}
@@ -1197,6 +1328,14 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
Gia_ManForEachPo( p, pObj, i )
fprintf( pFile, "o%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesOut, i) );
}
+ if ( p->vNamesNode && Vec_PtrSize(p->vNamesNode) != Gia_ManObjNum(p) )
+ Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not written.\n" );
+ else if ( p->vNamesNode )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_PtrEntry(p->vNamesNode, i) )
+ fprintf( pFile, "n%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesNode, i) );
+ }
// write the comment
if ( fWriteNewLine )
@@ -1477,6 +1616,148 @@ void Gia_AigerWriteSimple( Gia_Man_t * pInit, char * pFileName )
fclose( pFile );
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Simple AIGER reader/writer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned Aiger_ReadUnsigned( FILE * pFile )
+{
+ unsigned x = 0, i = 0;
+ unsigned char ch;
+ while ((ch = fgetc(pFile)) & 0x80)
+ x |= (ch & 0x7f) << (7 * i++);
+ return x | (ch << (7 * i));
+}
+static inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+ fputc( ch, pFile );
+ x >>= 7;
+ }
+ ch = x;
+ fputc( ch, pFile );
+}
+int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds )
+{
+ int i, Temp, Value = 0, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Aiger_Read(): Cannot open the output file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' )
+ {
+ fprintf( stdout, "Aiger_Read(): Can only read binary AIGER.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLats, &nOuts, &nAnds) != 5 )
+ {
+ fprintf( stdout, "Aiger_Read(): Cannot read the header line.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nTotal != nIns + nLats + nAnds )
+ {
+ fprintf( stdout, "The number of objects does not match.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ nObjs = 1 + nIns + 2*nLats + nOuts + nAnds;
+ pObjs = ABC_CALLOC( int, nObjs * 2 );
+ // read flop input literals
+ for ( i = 0; i < nLats; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ Value += fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nLats+i)+0] = Temp;
+ pObjs[2*(nObjs-nLats+i)+1] = Temp;
+ }
+ // read output literals
+ for ( i = 0; i < nOuts; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ Value += fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp;
+ pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp;
+ }
+ assert( Value == nLats + nOuts );
+ // read the binary part
+ while ( fgetc(pFile) != '\n' );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1 + nIns + nLats + i);
+ int uLit1 = uLit - Aiger_ReadUnsigned( pFile );
+ int uLit0 = uLit1 - Aiger_ReadUnsigned( pFile );
+ pObjs[2*(1+nIns+nLats+i)+0] = uLit0;
+ pObjs[2*(1+nIns+nLats+i)+1] = uLit1;
+ }
+ fclose( pFile );
+ if ( pnObjs ) *pnObjs = nObjs;
+ if ( pnIns ) *pnIns = nIns;
+ if ( pnLats ) *pnLats = nLats;
+ if ( pnOuts ) *pnOuts = nOuts;
+ if ( pnAnds ) *pnAnds = nAnds;
+ return pObjs;
+}
+void Aiger_Write( char * pFileName, int * pObjs, int nObjs, int nIns, int nLats, int nOuts, int nAnds )
+{
+ FILE * pFile = fopen( pFileName, "wb" ); int i;
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Aiger_Write(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+ fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLats + nAnds, nIns, nLats, nOuts, nAnds );
+ for ( i = 0; i < nLats; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLats+i)+0] );
+ for ( i = 0; i < nOuts; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLats+i)+0] );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1 + nIns + nLats + i);
+ int uLit0 = pObjs[2*(1+nIns+nLats+i)+0];
+ int uLit1 = pObjs[2*(1+nIns+nLats+i)+1];
+ Aiger_WriteUnsigned( pFile, uLit - uLit1 );
+ Aiger_WriteUnsigned( pFile, uLit1 - uLit0 );
+ }
+ fprintf( pFile, "c\n" );
+ fclose( pFile );
+}
+void Aiger_Test( char * pFileNameIn, char * pFileNameOut )
+{
+ int nObjs, nIns, nLats, nOuts, nAnds, * pObjs = Aiger_Read( pFileNameIn, &nObjs, &nIns, &nLats, &nOuts, &nAnds );
+ if ( pObjs == NULL )
+ return;
+ printf( "Read input file \"%s\".\n", pFileNameIn );
+ Aiger_Write( pFileNameOut, pObjs, nObjs, nIns, nLats, nOuts, nAnds );
+ printf( "Written output file \"%s\".\n", pFileNameOut );
+ ABC_FREE( pObjs );
+}
+
+/*
+int main( int argc, char ** argv )
+{
+ if ( argc != 3 )
+ return 0;
+ Aiger_Test( argv[1], argv[2] );
+ return 1;
+}
+*/
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c
index 503961d4..67b62655 100644
--- a/src/aig/gia/giaCSat.c
+++ b/src/aig/gia/giaCSat.c
@@ -1034,7 +1034,7 @@ void Cbs_ManSatPrintStats( Cbs_Man_t * p )
SeeAlso []
***********************************************************************/
-Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
+Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
{
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
@@ -1105,6 +1105,8 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
}
if ( status == 1 )
{
+ if ( f0Proved )
+ Gia_ManPatchCoDriver( pAig, i, 0 );
p->nSatUnsat++;
p->nConfUnsat += p->Pars.nBTThis;
p->timeSatUnsat += Abc_Clock() - clk;
diff --git a/src/aig/gia/giaCSat3.c b/src/aig/gia/giaCSat3.c
new file mode 100644
index 00000000..c34c84ca
--- /dev/null
+++ b/src/aig/gia/giaCSat3.c
@@ -0,0 +1,1365 @@
+/**CFile****************************************************************
+
+ FileName [giaCSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [A simple circuit-based solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Cbs3_Par_t_ Cbs3_Par_t;
+struct Cbs3_Par_t_
+{
+ // conflict limits
+ int nBTLimit; // limit on the number of conflicts
+ int nJustLimit; // limit on the size of justification queue
+ int nRestLimit; // limit on the number of restarts
+ // current parameters
+ int nBTThis; // number of conflicts
+ int nJustThis; // max size of the frontier
+ int nBTTotal; // total number of conflicts
+ int nJustTotal; // total size of the frontier
+ // other
+ int fVerbose;
+};
+
+typedef struct Cbs3_Que_t_ Cbs3_Que_t;
+struct Cbs3_Que_t_
+{
+ int iHead; // beginning of the queue
+ int iTail; // end of the queue
+ int nSize; // allocated size
+ int * pData; // nodes stored in the queue
+};
+
+typedef struct Cbs3_Man_t_ Cbs3_Man_t;
+struct Cbs3_Man_t_
+{
+ Cbs3_Par_t Pars; // parameters
+ Gia_Man_t * pAig; // AIG manager
+ Cbs3_Que_t pProp; // propagation queue
+ Cbs3_Que_t pJust; // justification queue
+ Cbs3_Que_t pClauses; // clause queue
+ Vec_Int_t * vModel; // satisfying assignment
+ Vec_Int_t * vTemp; // temporary storage
+ // circuit structure
+ int nVars;
+ int nVarsAlloc;
+ int var_inc;
+ Vec_Int_t vMap;
+ Vec_Int_t vRef;
+ Vec_Int_t vFans;
+ Vec_Wec_t vImps;
+ // internal data
+ Vec_Str_t vAssign;
+ Vec_Str_t vMark;
+ Vec_Int_t vLevReason;
+ Vec_Int_t vActs;
+ Vec_Int_t vWatches;
+ Vec_Int_t vWatchUpds;
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ // runtime stats
+ abctime timeJFront;
+ abctime timeSatLoad; // SAT solver loading time
+ abctime timeSatUnsat; // unsat
+ abctime timeSatSat; // sat
+ abctime timeSatUndec; // undecided
+ abctime timeTotal; // total runtime
+ // other statistics
+ int nPropCalls[3];
+ int nFails[2];
+ int nClauseConf;
+ int nDecs;
+};
+
+static inline int Cbs3_VarUnused( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry(&p->vLevReason, 3*iVar) == -1; }
+static inline void Cbs3_VarSetUnused( Cbs3_Man_t * p, int iVar ) { Vec_IntWriteEntry(&p->vLevReason, 3*iVar, -1); }
+
+static inline int Cbs3_VarMark0( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vMark, iVar); }
+static inline void Cbs3_VarSetMark0( Cbs3_Man_t * p, int iVar, int Value ) { Vec_StrWriteEntry(&p->vMark, iVar, (char)Value); }
+
+static inline int Cbs3_VarIsAssigned( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar) < 2; }
+static inline void Cbs3_VarUnassign( Cbs3_Man_t * p, int iVar ) { assert( Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)(2+Vec_StrEntry(&p->vAssign, iVar))); Cbs3_VarSetUnused(p, iVar); }
+
+static inline int Cbs3_VarValue( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar); }
+static inline void Cbs3_VarSetValue( Cbs3_Man_t * p, int iVar, int v ) { assert( !Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)v); }
+
+static inline int Cbs3_VarLit0( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ); }
+static inline int Cbs3_VarLit1( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 1) ); }
+static inline int Cbs3_VarIsPi( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ) == 0; }
+static inline int Cbs3_VarIsJust( Cbs3_Man_t * p, int iVar ) { int * pLits = Vec_IntEntryP(&p->vFans, Abc_Var2Lit(iVar, 0)); return pLits[0] > 0 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) >= 2 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[1])) >= 2; }
+
+static inline int Cbs3_VarDecLevel( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar); }
+static inline int Cbs3_VarReason0( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+1); }
+static inline int Cbs3_VarReason1( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+2); }
+static inline int * Cbs3_VarReasonP( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntryP(&p->vLevReason, 3*iVar+1); }
+static inline int Cbs3_ClauseDecLevel( Cbs3_Man_t * p, int hClause ) { return Cbs3_VarDecLevel( p, p->pClauses.pData[hClause] ); }
+
+static inline int Cbs3_ClauseSize( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData[hClause]; }
+static inline int * Cbs3_ClauseLits( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+1; }
+static inline int Cbs3_ClauseLit( Cbs3_Man_t * p, int hClause, int i ) { return p->pClauses.pData[hClause+1+i]; }
+static inline int * Cbs3_ClauseNext1p( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+Cbs3_ClauseSize(p, hClause)+2; }
+
+static inline void Cbs3_ClauseSetSize( Cbs3_Man_t * p, int hClause, int x ) { p->pClauses.pData[hClause] = x; }
+static inline void Cbs3_ClauseSetLit( Cbs3_Man_t * p, int hClause, int i, int x ) { p->pClauses.pData[hClause+i+1] = x; }
+static inline void Cbs3_ClauseSetNext( Cbs3_Man_t * p, int hClause, int n, int x ){ p->pClauses.pData[hClause+Cbs3_ClauseSize(p, hClause)+1+n] = x; }
+
+
+#define Cbs3_QueForEachEntry( Que, iObj, i ) \
+ for ( i = (Que).iHead; (i < (Que).iTail) && ((iObj) = (Que).pData[i]); i++ )
+
+#define Cbs3_ClauseForEachEntry( p, hClause, iObj, i ) \
+ for ( i = 1; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ )
+#define Cbs3_ClauseForEachEntry1( p, hClause, iObj, i ) \
+ for ( i = 2; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets default values of the parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_SetDefaultParams( Cbs3_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(Cbs3_Par_t) );
+ pPars->nBTLimit = 1000; // limit on the number of conflicts
+ pPars->nJustLimit = 500; // limit on the size of justification queue
+ pPars->nRestLimit = 10; // limit on the number of restarts
+ pPars->fVerbose = 1; // print detailed statistics
+}
+void Cbs3_ManSetConflictNum( Cbs3_Man_t * p, int Num )
+{
+ p->Pars.nBTLimit = Num;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cbs3_Man_t * Cbs3_ManAlloc( Gia_Man_t * pGia )
+{
+ Cbs3_Man_t * p;
+ p = ABC_CALLOC( Cbs3_Man_t, 1 );
+ p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000;
+ p->pProp.pData = ABC_ALLOC( int, p->pProp.nSize );
+ p->pJust.pData = ABC_ALLOC( int, p->pJust.nSize );
+ p->pClauses.pData = ABC_ALLOC( int, p->pClauses.nSize );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->vModel = Vec_IntAlloc( 1000 );
+ p->vTemp = Vec_IntAlloc( 1000 );
+ p->pAig = pGia;
+ Cbs3_SetDefaultParams( &p->Pars );
+ // circuit structure
+ Vec_IntPush( &p->vMap, -1 );
+ Vec_IntPush( &p->vRef, -1 );
+ Vec_IntPushTwo( &p->vFans, -1, -1 );
+ Vec_WecPushLevel( &p->vImps );
+ Vec_WecPushLevel( &p->vImps );
+ p->nVars = 1;
+ // internal data
+ p->nVarsAlloc = 1000;
+ Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 );
+ Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 );
+ Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 );
+ Vec_IntGrow( &p->vWatchUpds, 1000 );
+ return p;
+}
+static inline void Cbs3_ManReset( Cbs3_Man_t * p )
+{
+ assert( p->nVars == Vec_IntSize(&p->vMap) );
+ Vec_IntShrink( &p->vMap, 1 );
+ Vec_IntShrink( &p->vRef, 1 );
+ Vec_IntShrink( &p->vFans, 2 );
+ Vec_WecShrink( &p->vImps, 2 );
+ p->nVars = 1;
+}
+static inline void Cbs3_ManGrow( Cbs3_Man_t * p )
+{
+ if ( p->nVarsAlloc < p->nVars )
+ {
+ p->nVarsAlloc = 2*p->nVars;
+ Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 );
+ Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 );
+ Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManStop( Cbs3_Man_t * p )
+{
+ // circuit structure
+ Vec_IntErase( &p->vMap );
+ Vec_IntErase( &p->vRef );
+ Vec_IntErase( &p->vFans );
+ Vec_WecErase( &p->vImps );
+ // internal data
+ Vec_StrErase( &p->vAssign );
+ Vec_StrErase( &p->vMark );
+ Vec_IntErase( &p->vLevReason );
+ Vec_IntErase( &p->vActs );
+ Vec_IntErase( &p->vWatches );
+ Vec_IntErase( &p->vWatchUpds );
+ Vec_IntFree( p->vModel );
+ Vec_IntFree( p->vTemp );
+ ABC_FREE( p->pClauses.pData );
+ ABC_FREE( p->pProp.pData );
+ ABC_FREE( p->pJust.pData );
+ ABC_FREE( p );
+}
+int Cbs3_ManMemory( Cbs3_Man_t * p )
+{
+ int nMem = sizeof(Cbs3_Man_t);
+ nMem += (int)Vec_IntMemory( &p->vMap );
+ nMem += (int)Vec_IntMemory( &p->vRef );
+ nMem += (int)Vec_IntMemory( &p->vFans );
+ nMem += (int)Vec_WecMemory( &p->vImps );
+ nMem += (int)Vec_StrMemory( &p->vAssign );
+ nMem += (int)Vec_StrMemory( &p->vMark );
+ nMem += (int)Vec_IntMemory( &p->vActs );
+ nMem += (int)Vec_IntMemory( &p->vWatches );
+ nMem += (int)Vec_IntMemory( &p->vWatchUpds );
+ nMem += (int)Vec_IntMemory( p->vModel );
+ nMem += (int)Vec_IntMemory( p->vTemp );
+ nMem += 4*p->pClauses.nSize;
+ nMem += 4*p->pProp.nSize;
+ nMem += 4*p->pJust.nSize;
+ return nMem;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cbs3_ReadModel( Cbs3_Man_t * p )
+{
+ return p->vModel;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Activity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+//#define USE_ACTIVITY
+
+#ifdef USE_ACTIVITY
+static inline void Cbs3_ActReset( Cbs3_Man_t * p )
+{
+ int i, * pAct = Vec_IntArray(&p->vActs);
+ for ( i = 0; i < p->nVars; i++ )
+ pAct[i] = (1 << 10);
+ p->var_inc = (1 << 5);
+}
+static inline void Cbs3_ActRescale( Cbs3_Man_t * p )
+{
+ int i, * pAct = Vec_IntArray(&p->vActs);
+ for ( i = 0; i < p->nVars; i++ )
+ pAct[i] >>= 19;
+ p->var_inc >>= 19;
+ p->var_inc = Abc_MaxInt( (unsigned)p->var_inc, (1<<5) );
+}
+static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar )
+{
+ int * pAct = Vec_IntArray(&p->vActs);
+ pAct[iVar] += p->var_inc;
+ if ((unsigned)pAct[iVar] & 0x80000000)
+ Cbs3_ActRescale(p);
+}
+static inline void Cbs3_ActDecay( Cbs3_Man_t * p )
+{
+ p->var_inc += (p->var_inc >> 4);
+}
+#else
+static inline void Cbs3_ActReset( Cbs3_Man_t * p ) {}
+static inline void Cbs3_ActRescale( Cbs3_Man_t * p ) {}
+static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar ) {}
+static inline void Cbs3_ActDecay( Cbs3_Man_t * p ) {}
+#endif
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the solver is out of limits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManCheckLimits( Cbs3_Man_t * p )
+{
+ p->nFails[0] += p->Pars.nJustThis > p->Pars.nJustLimit;
+ p->nFails[1] += p->Pars.nBTThis > p->Pars.nBTLimit;
+ return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves the satisfying assignment as an array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManSaveModel( Cbs3_Man_t * p, Vec_Int_t * vCex )
+{
+ int i, iLit;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ if ( Cbs3_VarIsPi(p, Abc_Lit2Var(iLit)) )
+ Vec_IntPush( vCex, Abc_Lit2LitV(Vec_IntArray(&p->vMap), iLit)-2 );
+}
+static inline void Cbs3_ManSaveModelAll( Cbs3_Man_t * p, Vec_Int_t * vCex )
+{
+ int i, iLit;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ Vec_IntPush( vCex, Abc_Var2Lit(iVar, !Cbs3_VarValue(p, iVar)) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_QueIsEmpty( Cbs3_Que_t * p )
+{
+ return p->iHead == p->iTail;
+}
+static inline int Cbs3_QueSize( Cbs3_Que_t * p )
+{
+ return p->iTail - p->iHead;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QuePush( Cbs3_Que_t * p, int iObj )
+{
+ if ( p->iTail == p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( int, p->pData, p->nSize );
+ }
+ p->pData[p->iTail++] = iObj;
+}
+static inline void Cbs3_QueGrow( Cbs3_Que_t * p, int Plus )
+{
+ if ( p->iTail + Plus > p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( int, p->pData, p->nSize );
+ }
+ assert( p->iTail + Plus <= p->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the object in the queue.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_QueHasNode( Cbs3_Que_t * p, int iObj )
+{
+ int i, iTemp;
+ Cbs3_QueForEachEntry( *p, iTemp, i )
+ if ( iTemp == iObj )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QueStore( Cbs3_Que_t * p, int * piHeadOld, int * piTailOld )
+{
+ int i;
+ *piHeadOld = p->iHead;
+ *piTailOld = p->iTail;
+ for ( i = *piHeadOld; i < *piTailOld; i++ )
+ Cbs3_QuePush( p, p->pData[i] );
+ p->iHead = *piTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QueRestore( Cbs3_Que_t * p, int iHeadOld, int iTailOld )
+{
+ p->iHead = iHeadOld;
+ p->iTail = iTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManDecide( Cbs3_Man_t * p )
+{
+ int i, iObj, iObjMax = 0;
+#ifdef USE_ACTIVITY
+ Cbs3_QueForEachEntry( p->pJust, iObj, i )
+ if ( iObjMax == 0 ||
+ Vec_IntEntry(&p->vActs, iObjMax) < Vec_IntEntry(&p->vActs, iObj) ||
+ (Vec_IntEntry(&p->vActs, iObjMax) == Vec_IntEntry(&p->vActs, iObj) && Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj)) )
+ iObjMax = iObj;
+#else
+ Cbs3_QueForEachEntry( p->pJust, iObj, i )
+// if ( iObjMax == 0 || iObjMax < iObj )
+ if ( iObjMax == 0 || Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj) )
+ iObjMax = iObj;
+#endif
+ return iObjMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManCancelUntil( Cbs3_Man_t * p, int iBound )
+{
+ int i, iLit;
+ assert( iBound <= p->pProp.iTail );
+ p->pProp.iHead = iBound;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ Cbs3_VarUnassign( p, Abc_Lit2Var(iLit) );
+ p->pProp.iTail = iBound;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns the variables a value.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManAssign( Cbs3_Man_t * p, int iLit, int Level, int iRes0, int iRes1 )
+{
+ int iObj = Abc_Lit2Var(iLit);
+ assert( Cbs3_VarUnused(p, iObj) );
+ assert( !Cbs3_VarIsAssigned(p, iObj) );
+ Cbs3_VarSetValue( p, iObj, !Abc_LitIsCompl(iLit) );
+ Cbs3_QuePush( &p->pProp, iLit );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj, Level );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj+1, iRes0 );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj+2, iRes1 );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManPrintClause( Cbs3_Man_t * p, int Level, int hClause )
+{
+ int i, iLit;
+ assert( Cbs3_QueIsEmpty( &p->pClauses ) );
+ printf( "Level %2d : ", Level );
+ Cbs3_ClauseForEachEntry( p, hClause, iLit, i )
+ printf( "%c%d ", Abc_LitIsCompl(iLit) ? '-':'+', Abc_Lit2Var(iLit) );
+// printf( "%d=%d(%d) ", iObj, Cbs3_VarValue(p, Abc_Lit2Var(iLit)), Cbs3_VarDecLevel(p, Abc_Lit2Var(iLit)) );
+ printf( "\n" );
+}
+static inline void Cbs3_ManPrintCube( Cbs3_Man_t * p, int Level, int hClause )
+{
+ int i, iObj;
+ assert( Cbs3_QueIsEmpty( &p->pClauses ) );
+ printf( "Level %2d : ", Level );
+ Cbs3_ClauseForEachEntry( p, hClause, iObj, i )
+ printf( "%c%d ", Cbs3_VarValue(p, iObj)? '+':'-', iObj );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalized the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManCleanWatch( Cbs3_Man_t * p )
+{
+ int i, iLit;
+ Vec_IntForEachEntry( &p->vWatchUpds, iLit, i )
+ Vec_IntWriteEntry( &p->vWatches, iLit, 0 );
+ Vec_IntClear( &p->vWatchUpds );
+ //Vec_IntForEachEntry( &p->vWatches, iLit, i )
+ // assert( iLit == 0 );
+}
+static inline void Cbs3_ManWatchClause( Cbs3_Man_t * p, int hClause, int Lit )
+{
+ int * pLits = Cbs3_ClauseLits( p, hClause );
+ int * pPlace = Vec_IntEntryP( &p->vWatches, Abc_LitNot(Lit) );
+ if ( *pPlace == 0 )
+ Vec_IntPush( &p->vWatchUpds, Abc_LitNot(Lit) );
+/*
+ if ( pClause->pLits[0] == Lit )
+ pClause->pNext0 = p->pWatches[lit_neg(Lit)];
+ else
+ {
+ assert( pClause->pLits[1] == Lit );
+ pClause->pNext1 = p->pWatches[lit_neg(Lit)];
+ }
+ p->pWatches[lit_neg(Lit)] = pClause;
+*/
+ assert( Lit == pLits[0] || Lit == pLits[1] );
+ Cbs3_ClauseSetNext( p, hClause, Lit == pLits[1], *pPlace );
+ *pPlace = hClause;
+}
+static inline int Cbs3_QueFinish( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, iObj, hClauseC, hClause = pQue->iHead, Size = pQue->iTail - pQue->iHead - 1;
+ assert( pQue->iHead+1 < pQue->iTail );
+ Cbs3_ClauseSetSize( p, pQue->iHead, Size );
+ hClauseC = pQue->iHead = pQue->iTail;
+ //printf( "Adding cube: " ); Cbs3_ManPrintCube(p, Level, hClause);
+ if ( Size == 1 )
+ return hClause;
+ // create watched clause
+ pQue->iHead = hClause;
+ Cbs3_QueForEachEntry( p->pClauses, iObj, i )
+ {
+ if ( i == hClauseC )
+ break;
+ else if ( i == hClause ) // nlits
+ Cbs3_QuePush( pQue, iObj );
+ else // literals
+ Cbs3_QuePush( pQue, Abc_Var2Lit(iObj, Cbs3_VarValue(p, iObj)) ); // complement
+ }
+ Cbs3_QuePush( pQue, 0 ); // next0
+ Cbs3_QuePush( pQue, 0 ); // next1
+ pQue->iHead = pQue->iTail;
+ Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 0) );
+ Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 1) );
+ //printf( "Adding clause %d: ", hClauseC ); Cbs3_ManPrintClause(p, Level, hClauseC);
+ Cbs3_ActDecay( p );
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManDeriveReason( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, k, iObj, iLitLevel, * pReason;
+ assert( pQue->pData[pQue->iHead] == 0 );
+ assert( pQue->pData[pQue->iHead+1] == 0 );
+ assert( pQue->iHead + 2 < pQue->iTail );
+ //for ( i = pQue->iHead + 2; i < pQue->iTail; i++ )
+ // assert( !Cbs3_VarMark0(p, pQue->pData[i]) );
+ // compact literals
+ Vec_IntClear( p->vTemp );
+ for ( i = k = pQue->iHead + 2; i < pQue->iTail; i++ )
+ {
+ iObj = pQue->pData[i];
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Vec_IntPush( p->vTemp, iObj );
+ // check decision level
+ iLitLevel = Cbs3_VarDecLevel( p, iObj );
+ if ( iLitLevel < Level )
+ {
+ pQue->pData[k++] = iObj;
+ continue;
+ }
+ assert( iLitLevel == Level );
+ pReason = Cbs3_VarReasonP( p, iObj );
+ if ( pReason[0] == 0 && pReason[1] == 0 ) // no reason
+ {
+ assert( pQue->pData[pQue->iHead+1] == 0 );
+ pQue->pData[pQue->iHead+1] = iObj;
+ }
+ else if ( pReason[0] != 0 ) // circuit reason
+ {
+ Cbs3_QuePush( pQue, pReason[0] );
+ if ( pReason[1] )
+ Cbs3_QuePush( pQue, pReason[1] );
+ }
+ else // clause reason
+ {
+ int i, * pLits, nLits = Cbs3_ClauseSize( p, pReason[1] );
+ assert( pReason[1] );
+ Cbs3_QueGrow( pQue, nLits );
+ pLits = Cbs3_ClauseLits( p, pReason[1] );
+ assert( iObj == Abc_Lit2Var(pLits[0]) );
+ for ( i = 1; i < nLits; i++ )
+ Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) );
+ }
+ }
+ assert( pQue->pData[pQue->iHead] == 0 );
+ assert( pQue->pData[pQue->iHead+1] != 0 );
+ pQue->iTail = k;
+ // clear the marks
+ Vec_IntForEachEntry( p->vTemp, iObj, i )
+ Cbs3_VarSetMark0(p, iObj, 0);
+ return Cbs3_QueFinish( p, Level );
+}
+static inline int Cbs3_ManAnalyze( Cbs3_Man_t * p, int Level, int iVar, int iFan0, int iFan1 )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ assert( Cbs3_VarIsAssigned(p, iVar) );
+ assert( Cbs3_QueIsEmpty( pQue ) );
+ Cbs3_QuePush( pQue, 0 );
+ Cbs3_QuePush( pQue, 0 );
+ if ( iFan0 ) // circuit conflict
+ {
+ assert( Cbs3_VarIsAssigned(p, iFan0) );
+ assert( iFan1 == 0 || Cbs3_VarIsAssigned(p, iFan1) );
+ Cbs3_QuePush( pQue, iVar );
+ Cbs3_QuePush( pQue, iFan0 );
+ if ( iFan1 )
+ Cbs3_QuePush( pQue, iFan1 );
+ }
+ else // clause conflict
+ {
+ int i, * pLits, nLits = Cbs3_ClauseSize( p, iFan1 );
+ assert( iFan1 );
+ Cbs3_QueGrow( pQue, nLits );
+ pLits = Cbs3_ClauseLits( p, iFan1 );
+ assert( iVar == Abc_Lit2Var(pLits[0]) );
+ assert( Cbs3_VarValue(p, iVar) == Abc_LitIsCompl(pLits[0]) );
+ for ( i = 0; i < nLits; i++ )
+ Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) );
+ }
+ return Cbs3_ManDeriveReason( p, Level );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description [Returns handle of the conflict clause, if conflict occurs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManPropagateClauses( Cbs3_Man_t * p, int Level, int Lit )
+{
+ int i, Value, Cur, LitF = Abc_LitNot(Lit);
+ int * pPrev = Vec_IntEntryP( &p->vWatches, Lit );
+ //for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
+ for ( Cur = *pPrev; Cur; Cur = *pPrev )
+ {
+ int nLits = Cbs3_ClauseSize( p, Cur );
+ int * pLits = Cbs3_ClauseLits( p, Cur );
+ p->nPropCalls[1]++;
+//printf( " Watching literal %c%d on level %d.\n", Abc_LitIsCompl(Lit) ? '-':'+', Abc_Lit2Var(Lit), Level );
+ // make sure the false literal is in the second literal of the clause
+ //if ( pCur->pLits[0] == LitF )
+ if ( pLits[0] == LitF )
+ {
+ //pCur->pLits[0] = pCur->pLits[1];
+ pLits[0] = pLits[1];
+ //pCur->pLits[1] = LitF;
+ pLits[1] = LitF;
+ //pTemp = pCur->pNext0;
+ //pCur->pNext0 = pCur->pNext1;
+ //pCur->pNext1 = pTemp;
+ ABC_SWAP( int, pLits[nLits], pLits[nLits+1] );
+ }
+ //assert( pCur->pLits[1] == LitF );
+ assert( pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+ //if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
+ if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) == !Abc_LitIsCompl(pLits[0]) )
+ {
+ //ppPrev = &pCur->pNext1;
+ pPrev = Cbs3_ClauseNext1p(p, Cur);
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < nLits; i++ )
+ {
+ // skip the case when the literal is false
+ //if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
+ if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[i])) == Abc_LitIsCompl(pLits[i]) )
+ continue;
+ // the literal is either true or unassigned - watch it
+ //pCur->pLits[1] = pCur->pLits[i];
+ //pCur->pLits[i] = LitF;
+ pLits[1] = pLits[i];
+ pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ //*ppPrev = pCur->pNext1;
+ *pPrev = *Cbs3_ClauseNext1p(p, Cur);
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ //Intb_ManWatchClause( p, pCur, pCur->pLits[1] );
+ Cbs3_ManWatchClause( p, Cur, Cbs3_ClauseLit(p, Cur, 1) );
+ break;
+ }
+ if ( i < nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ //if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) )
+ //{
+ // ppPrev = &pCur->pNext1;
+ // continue;
+ //}
+
+ // clause is unit - enqueue new implication
+ Value = Cbs3_VarValue(p, Abc_Lit2Var(pLits[0]));
+ if ( Value >= 2 ) // unassigned
+ {
+ Cbs3_ManAssign( p, pLits[0], Level, 0, Cur );
+ pPrev = Cbs3_ClauseNext1p(p, Cur);
+ continue;
+ }
+
+ // conflict detected - return the conflict clause
+ //return pCur;
+ if ( Value == Abc_LitIsCompl(pLits[0]) )
+ {
+ p->nClauseConf++;
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(pLits[0]), 0, Cur );
+ }
+ }
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs resolution of two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManResolve( Cbs3_Man_t * p, int Level, int hClause0, int hClause1 )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, iObj, LevelMax = -1, LevelCur;
+ assert( pQue->pData[hClause0+1] != 0 );
+ assert( pQue->pData[hClause0+1] == pQue->pData[hClause1+1] );
+ //Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i )
+ // assert( !Cbs3_VarMark0(p, iObj) );
+ //Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i )
+ // assert( !Cbs3_VarMark0(p, iObj) );
+ assert( Cbs3_QueIsEmpty( pQue ) );
+ Cbs3_QuePush( pQue, 0 );
+ Cbs3_QuePush( pQue, 0 );
+// for ( i = hClause0 + 1; (iObj = pQue->pData[i]); i++ )
+ Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i )
+ {
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Cbs3_QuePush( pQue, iObj );
+ LevelCur = Cbs3_VarDecLevel( p, iObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+// for ( i = hClause1 + 1; (iObj = pQue->pData[i]); i++ )
+ Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i )
+ {
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Cbs3_QuePush( pQue, iObj );
+ LevelCur = Cbs3_VarDecLevel( p, iObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = pQue->iHead + 2; i < pQue->iTail; i++ )
+ Cbs3_VarSetMark0(p, pQue->pData[i], 0);
+ return Cbs3_ManDeriveReason( p, LevelMax );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns clause handle if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManUpdateJFrontier( Cbs3_Man_t * p )
+{
+ //abctime clk = Abc_Clock();
+ int iVar, iLit, i, k = p->pJust.iTail;
+ Cbs3_QueGrow( &p->pJust, Cbs3_QueSize(&p->pJust) + Cbs3_QueSize(&p->pProp) );
+ Cbs3_QueForEachEntry( p->pJust, iVar, i )
+ if ( Cbs3_VarIsJust(p, iVar) )
+ p->pJust.pData[k++] = iVar;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ if ( Cbs3_VarIsJust(p, Abc_Lit2Var(iLit)) )
+ p->pJust.pData[k++] = Abc_Lit2Var(iLit);
+ p->pJust.iHead = p->pJust.iTail;
+ p->pJust.iTail = k;
+ //p->timeJFront += Abc_Clock() - clk;
+}
+int Cbs3_ManPropagateNew( Cbs3_Man_t * p, int Level )
+{
+ int i, k, iLit, hClause, nLits, * pLits;
+ p->nPropCalls[0]++;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ {
+ if ( (hClause = Cbs3_ManPropagateClauses(p, Level, iLit)) )
+ return hClause;
+ p->nPropCalls[2]++;
+ nLits = Vec_IntSize(Vec_WecEntry(&p->vImps, iLit));
+ pLits = Vec_IntArray(Vec_WecEntry(&p->vImps, iLit));
+ for ( k = 0; k < nLits; k += 2 )
+ {
+ int Value0 = Cbs3_VarValue(p, Abc_Lit2Var(pLits[k]));
+ int Value1 = pLits[k+1] ? Cbs3_VarValue(p, Abc_Lit2Var(pLits[k+1])) : -1;
+ if ( Value1 == -1 || Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false
+ {
+ if ( Value0 >= 2 ) // pLits[k] is unassigned
+ Cbs3_ManAssign( p, pLits[k], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k+1]) );
+ else if ( Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) );
+ }
+ if ( Value1 != -1 && Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false
+ {
+ if ( Value1 >= 2 ) // pLits[k+1] is unassigned
+ Cbs3_ManAssign( p, pLits[k+1], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]) );
+ else if ( Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) );
+ }
+ }
+ }
+ Cbs3_ManUpdateJFrontier( p );
+ // finalize propagation queue
+ p->pProp.iHead = p->pProp.iTail;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solve the problem recursively.]
+
+ Description [Returns learnt clause if unsat, NULL if sat or undecided.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cbs3_ManSolve2_rec( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int iPropHead, iJustHead, iJustTail;
+ int hClause, hLearn0, hLearn1, iVar, iDecLit;
+ int nRef0, nRef1;
+ // propagate assignments
+ assert( !Cbs3_QueIsEmpty(&p->pProp) );
+ //if ( (hClause = Cbs3_ManPropagate( p, Level )) )
+ if ( (hClause = Cbs3_ManPropagateNew( p, Level )) )
+ return hClause;
+ // check for satisfying assignment
+ assert( Cbs3_QueIsEmpty(&p->pProp) );
+ if ( Cbs3_QueIsEmpty(&p->pJust) )
+ return 0;
+ // quit using resource limits
+ p->Pars.nJustThis = Abc_MaxInt( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead );
+ if ( Cbs3_ManCheckLimits( p ) )
+ return 0;
+ // remember the state before branching
+ iPropHead = p->pProp.iHead;
+ iJustHead = p->pJust.iHead;
+ iJustTail = p->pJust.iTail;
+ // find the decision variable
+ p->nDecs++;
+ iVar = Cbs3_ManDecide( p );
+ assert( !Cbs3_VarIsPi(p, iVar) );
+ assert( Cbs3_VarIsJust(p, iVar) );
+ // chose decision variable using fanout count
+ nRef0 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit0(p, iVar)));
+ nRef1 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit1(p, iVar)));
+// if ( nRef0 >= nRef1 || (nRef0 == nRef1) && (Abc_Random(0) & 1) )
+ if ( nRef0 >= nRef1 )
+ iDecLit = Abc_LitNot(Cbs3_VarLit0(p, iVar));
+ else
+ iDecLit = Abc_LitNot(Cbs3_VarLit1(p, iVar));
+ // decide on first fanin
+ Cbs3_ManAssign( p, iDecLit, Level+1, 0, 0 );
+ if ( !(hLearn0 = Cbs3_ManSolve2_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn0+1] != Abc_Lit2Var(iDecLit) )
+ return hLearn0;
+ Cbs3_ManCancelUntil( p, iPropHead );
+ Cbs3_QueRestore( &p->pJust, iJustHead, iJustTail );
+ // decide on second fanin
+ Cbs3_ManAssign( p, Abc_LitNot(iDecLit), Level+1, 0, 0 );
+ if ( !(hLearn1 = Cbs3_ManSolve2_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn1+1] != Abc_Lit2Var(iDecLit) )
+ return hLearn1;
+ hClause = Cbs3_ManResolve( p, Level, hLearn0, hLearn1 );
+ p->Pars.nBTThis++;
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Looking for a satisfying assignment of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManSolveInt( Cbs3_Man_t * p, int iLit )
+{
+ int RetValue = 0;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ p->Pars.nBTThis = p->Pars.nJustThis = 0;
+ Cbs3_ManAssign( p, iLit, 0, 0, 0 );
+ if ( !Cbs3_ManSolve2_rec(p, 0) && !Cbs3_ManCheckLimits(p) )
+ Cbs3_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ Cbs3_ManCancelUntil( p, 0 );
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( Cbs3_ManCheckLimits( p ) )
+ RetValue = -1;
+ return RetValue;
+}
+int Cbs3_ManSolve( Cbs3_Man_t * p, int iLit, int nRestarts )
+{
+ int i, RetValue = -1;
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ for ( i = 0; i < nRestarts; i++ )
+ if ( (RetValue = Cbs3_ManSolveInt(p, iLit)) != -1 )
+ break;
+ Cbs3_ManCleanWatch( p );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManSatPrintStats( Cbs3_Man_t * p )
+{
+ printf( "CO = %8d ", Gia_ManCoNum(p->pAig) );
+ printf( "AND = %8d ", Gia_ManAndNum(p->pAig) );
+ printf( "Conf = %6d ", p->Pars.nBTLimit );
+ printf( "Restart = %2d ", p->Pars.nRestLimit );
+ printf( "JustMax = %5d ", p->Pars.nJustLimit );
+ printf( "\n" );
+ printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
+ printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
+ printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+ ABC_PRT( "Total time", p->timeTotal );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManAddVar( Cbs3_Man_t * p, int iGiaObj )
+{
+ assert( Vec_IntSize(&p->vMap) == p->nVars );
+ Vec_IntPush( &p->vMap, iGiaObj );
+ Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) );
+ Vec_IntPushTwo( &p->vFans, 0, 0 );
+ Vec_WecPushLevel(&p->vImps);
+ Vec_WecPushLevel(&p->vImps);
+ return Abc_Var2Lit( p->nVars++, 0 );
+}
+static inline void Cbs3_ManAddConstr( Cbs3_Man_t * p, int x, int x0, int x1 )
+{
+ Vec_WecPushTwo( &p->vImps, x , x0, 0 ); // ~x + x0
+ Vec_WecPushTwo( &p->vImps, x , x1, 0 ); // ~x + x1
+ Vec_WecPushTwo( &p->vImps, 1^x0, 1^x , 0 ); // ~x + x0
+ Vec_WecPushTwo( &p->vImps, 1^x1, 1^x , 0 ); // ~x + x1
+ Vec_WecPushTwo( &p->vImps, 1^x , 1^x0, 1^x1 ); // x + ~x0 + ~x1
+ Vec_WecPushTwo( &p->vImps, x0, x , 1^x1 ); // x + ~x0 + ~x1
+ Vec_WecPushTwo( &p->vImps, x1, x , 1^x0 ); // x + ~x0 + ~x1
+}
+static inline void Cbs3_ManAddAnd( Cbs3_Man_t * p, int x, int x0, int x1 )
+{
+ assert( x > 0 && x0 > 0 && x1 > 0 );
+ Vec_IntWriteEntry( &p->vFans, x, x0 );
+ Vec_IntWriteEntry( &p->vFans, x+1, x1 );
+ Cbs3_ManAddConstr( p, x, x0, x1 );
+}
+static inline int Cbs3_ManToSolver1_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return pObj->Value;
+ pObj->Value = Cbs3_ManAddVar( pSol, iObj );
+ if ( Gia_ObjIsCi(pObj) || Depth == 0 )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) );
+ Lit1 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) );
+ Cbs3_ManAddAnd( pSol, pObj->Value, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj) );
+ return pObj->Value;
+}
+static inline int Cbs3_ManToSolver1( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth )
+{
+ //abctime clk = Abc_Clock();
+ assert( Gia_ObjIsCo(pRoot) );
+ Cbs3_ManReset( pSol );
+ Gia_ManIncrementTravId( p );
+ Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth );
+ Cbs3_ManGrow( pSol );
+ Cbs3_ActReset( pSol );
+ //pSol->timeSatLoad += Abc_Clock() - clk;
+ return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManPrepare( Cbs3_Man_t * p )
+{
+ int x, x0, x1;
+ Vec_WecInit( &p->vImps, Abc_Var2Lit(p->nVars, 0) );
+ Vec_IntForEachEntryDoubleStart( &p->vFans, x0, x1, x, 2 )
+ if ( x0 ) Cbs3_ManAddConstr( p, x, x0, x1 );
+}
+static inline int Cbs3_ManAddNode( Cbs3_Man_t * p, int iGiaObj, int iLit0, int iLit1 )
+{
+ assert( Vec_IntSize(&p->vMap) == p->nVars );
+ Vec_IntPush( &p->vMap, iGiaObj );
+ Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) );
+ Vec_IntPushTwo( &p->vFans, iLit0, iLit1 );
+ return Abc_Var2Lit( p->nVars++, 0 );
+}
+static inline int Cbs3_ManToSolver2_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return pObj->Value;
+ if ( Gia_ObjIsCi(pObj) || Depth == 0 )
+ return pObj->Value = Cbs3_ManAddNode(pSol, iObj, 0, 0);
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) );
+ Lit1 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) );
+ return pObj->Value = Cbs3_ManAddNode(pSol, iObj, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj));
+}
+static inline int Cbs3_ManToSolver2( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth )
+{
+ //abctime clk = Abc_Clock();
+ assert( Gia_ObjIsCo(pRoot) );
+ Cbs3_ManReset( pSol );
+ Gia_ManIncrementTravId( p );
+ Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth );
+ Cbs3_ManGrow( pSol );
+ Cbs3_ManPrepare( pSol );
+ Cbs3_ActReset( pSol );
+ //pSol->timeSatLoad += Abc_Clock() - clk;
+ return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Procedure to test the new SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cbs3_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, int nRestarts, Vec_Str_t ** pvStatus, int fVerbose )
+{
+ extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
+ Cbs3_Man_t * p;
+ Vec_Int_t * vCex, * vVisit, * vCexStore;
+ Vec_Str_t * vStatus;
+ Gia_Obj_t * pRoot;
+ int i, status; // 1 = unsat, 0 = sat, -1 = undec
+ abctime clk, clkTotal = Abc_Clock();
+ //assert( Gia_ManRegNum(pAig) == 0 );
+ Gia_ManCreateRefs( pAig );
+ //Gia_ManLevelNum( pAig );
+ // create logic network
+ p = Cbs3_ManAlloc( pAig );
+ p->Pars.nBTLimit = nConfs;
+ p->Pars.nRestLimit = nRestarts;
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ vVisit = Vec_IntAlloc( 100 );
+ vCex = Cbs3_ReadModel( p );
+ // solve for each output
+ Gia_ManForEachCo( pAig, pRoot, i )
+ {
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) )
+ {
+ Vec_IntClear( vCex );
+ Vec_StrPush( vStatus, (char)(!Gia_ObjFaninC0(pRoot)) );
+ if ( Gia_ObjFaninC0(pRoot) ) // const1
+ Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example
+ continue;
+ }
+ clk = Abc_Clock();
+ status = Cbs3_ManToSolver2( p, pAig, pRoot, p->Pars.nRestLimit, 10000 );
+ Vec_StrPush( vStatus, (char)status );
+ if ( status == -1 )
+ {
+ p->nSatUndec++;
+ p->nConfUndec += p->Pars.nBTThis;
+ Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
+ p->timeSatUndec += Abc_Clock() - clk;
+ continue;
+ }
+ if ( status == 1 )
+ {
+ p->nSatUnsat++;
+ p->nConfUnsat += p->Pars.nBTThis;
+ p->timeSatUnsat += Abc_Clock() - clk;
+ continue;
+ }
+ p->nSatSat++;
+ p->nConfSat += p->Pars.nBTThis;
+ //Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit );
+ Cec_ManSatAddToStore( vCexStore, vCex, i );
+ p->timeSatSat += Abc_Clock() - clk;
+ }
+ Vec_IntFree( vVisit );
+ p->nSatTotal = Gia_ManPoNum(pAig);
+ p->timeTotal = Abc_Clock() - clkTotal;
+ if ( fVerbose )
+ Cbs3_ManSatPrintStats( p );
+ if ( fVerbose )
+ {
+ printf( "Prop1 = %d. Prop2 = %d. Prop3 = %d. ClaConf = %d. FailJ = %d. FailC = %d. ", p->nPropCalls[0], p->nPropCalls[1], p->nPropCalls[2], p->nClauseConf, p->nFails[0], p->nFails[1] );
+ printf( "Mem usage %.2f MB.\n", 1.0*Cbs3_ManMemory(p)/(1<<20) );
+ //Abc_PrintTime( 1, "JFront", p->timeJFront );
+ //Abc_PrintTime( 1, "Loading", p->timeSatLoad );
+ //printf( "Decisions = %d.\n", p->nDecs );
+ }
+ Cbs3_ManStop( p );
+ *pvStatus = vStatus;
+ return vCexStore;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCut.c b/src/aig/gia/giaCut.c
index f70f0fc0..7ee795b6 100644
--- a/src/aig/gia/giaCut.c
+++ b/src/aig/gia/giaCut.c
@@ -602,10 +602,10 @@ void Gia_StoRefObj( Gia_Sto_t * p, int iObj )
}
void Gia_StoComputeCuts( Gia_Man_t * pGia )
{
- int nCutSize = 6;
- int nCutNum = 25;
- int fCutMin = 1;
- int fTruthMin = 1;
+ int nCutSize = 8;
+ int nCutNum = 6;
+ int fCutMin = 0;
+ int fTruthMin = 0;
int fVerbose = 1;
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
Gia_Obj_t * pObj; int i, iObj;
@@ -637,6 +637,147 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia )
Gia_StoFree( p );
}
+
+/**Function*************************************************************
+
+ Synopsis [Extract a given number of cuts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_StoSelectOneCut( Vec_Wec_t * vCuts, int iObj, Vec_Int_t * vCut, int nCutSizeMin )
+{
+ Vec_Int_t * vThis = Vec_WecEntry( vCuts, iObj );
+ int i, v, * pCut, * pList = Vec_IntArray( vThis );
+ if ( pList == NULL )
+ return 0;
+ Vec_IntClear( vCut );
+ Sdb_ForEachCut( pList, pCut, i )
+ {
+ if ( pCut[0] < nCutSizeMin )
+ continue;
+ for ( v = 0; v <= pCut[0]; v++ )
+ Vec_IntPush( vCut, pCut[v] );
+ return 1;
+ }
+ return 0;
+}
+Vec_Wec_t * Gia_ManSelectCuts( Vec_Wec_t * vCuts, int nCuts, int nCutSizeMin )
+{
+ Vec_Wec_t * vCutsSel = Vec_WecStart( nCuts );
+ int i; srand( time(NULL) );
+ for ( i = 0; i < nCuts; i++ )
+ while ( !Gia_StoSelectOneCut(vCuts, (rand() | (rand() << 15)) % Vec_WecSize(vCuts), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
+ return vCutsSel;
+}
+Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
+{
+ int nCutSize = nCutSize0;
+ int nCutNum = 6;
+ int fCutMin = 0;
+ int fTruthMin = 0;
+ int fVerbose = fVerbose0;
+ Vec_Wec_t * vCutsSel;
+ Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
+ Gia_Obj_t * pObj; int i, iObj;
+ assert( nCutSize <= GIA_MAX_CUTSIZE );
+ assert( nCutNum < GIA_MAX_CUTNUM );
+ // prepare references
+ Gia_ManForEachObj( p->pGia, pObj, iObj )
+ Gia_StoRefObj( p, iObj );
+ // compute cuts
+ Gia_StoComputeCutsConst0( p, 0 );
+ Gia_ManForEachCiId( p->pGia, iObj, i )
+ Gia_StoComputeCutsCi( p, iObj );
+ Gia_ManForEachAnd( p->pGia, pObj, iObj )
+ Gia_StoComputeCutsNode( p, iObj );
+ if ( p->fVerbose )
+ {
+ printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
+ p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
+ printf( "CutPair = %.0f ", p->CutCount[0] );
+ printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
+ printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
+ printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
+ printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
+ printf( "\n" );
+ printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
+ p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
+ Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
+ }
+ vCutsSel = Gia_ManSelectCuts( p->vCuts, nCuts0, nCutSize0-1 );
+ Gia_StoFree( p );
+ return vCutsSel;
+}
+void Gia_ManCreateWins( Gia_Man_t * pGia, Vec_Wec_t * vCuts )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vWins = Vec_WecStart( Gia_ManObjNum(pGia) );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCut; int i, k, Obj, Cut;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ Vec_IntForEachEntryStart( vCut, Obj, k, 1 )
+ Vec_IntPush( Vec_WecEntry(vWins, Obj), i );
+ Gia_ManForEachAnd( pGia, pObj, Obj )
+ {
+ Vec_Int_t * vWin = Vec_WecEntry(vWins, Obj);
+ Vec_Int_t * vWin0 = Vec_WecEntry(vWins, Gia_ObjFaninId0(pObj, Obj));
+ Vec_Int_t * vWin1 = Vec_WecEntry(vWins, Gia_ObjFaninId1(pObj, Obj));
+ Vec_IntTwoFindCommon( vWin0, vWin1, vTemp );
+ Vec_IntForEachEntry( vTemp, Cut, k )
+ {
+ Vec_IntPushUniqueOrder( vWin, Cut );
+ Vec_IntPush( Vec_WecEntry(vCuts, Cut), Obj );
+ }
+ }
+ Vec_WecFree( vWins );
+ Vec_IntFree( vTemp );
+}
+void Gia_ManPrintWins( Vec_Wec_t * vCuts )
+{
+ Vec_Int_t * vCut; int i, k, Obj;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ {
+ int nInputs = Vec_IntEntry(vCut, 0);
+ printf( "Cut %5d : ", i );
+ printf( "Supp = %d ", nInputs );
+ printf( "Nodes = %d ", Vec_IntSize(vCut) - 1 - nInputs );
+ Vec_IntForEachEntryStartStop( vCut, Obj, k, 1, nInputs+1 )
+ printf( "%d ", Obj );
+ printf( " " );
+ Vec_IntForEachEntryStart( vCut, Obj, k, nInputs+1 )
+ printf( "%d ", Obj );
+ printf( "\n" );
+ }
+}
+void Gia_ManPrintWinStats( Vec_Wec_t * vCuts )
+{
+ Vec_Int_t * vCut; int i, nInputs = 0, nNodes = 0;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ {
+ nInputs += Vec_IntEntry(vCut, 0);
+ nNodes += Vec_IntSize(vCut) - 1 - Vec_IntEntry(vCut, 0);
+ }
+ printf( "Computed %d windows with average support %.3f and average volume %.3f.\n",
+ Vec_WecSize(vCuts), 1.0*nInputs/Vec_WecSize(vCuts), 1.0*nNodes/Vec_WecSize(vCuts) );
+}
+void Gia_ManExtractTest( Gia_Man_t * pGia )
+{
+ extern Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose );
+ Vec_Wec_t * vCutsSel = Gia_ManExtractCuts2( pGia, 8, 10000, 1 );
+ //Vec_Wec_t * vCutsSel = Gia_ManExtractCuts( pGia, 8, 10000, 1 );
+ abctime clk = Abc_Clock();
+ Gia_ManCreateWins( pGia, vCutsSel );
+ //Gia_ManPrintWins( vCutsSel );
+ Gia_ManPrintWinStats( vCutsSel );
+ Vec_WecFree( vCutsSel );
+ Abc_PrintTime( 0, "Creating windows", Abc_Clock() - clk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaDecs.c b/src/aig/gia/giaDecs.c
new file mode 100644
index 00000000..343891d5
--- /dev/null
+++ b/src/aig/gia/giaDecs.c
@@ -0,0 +1,350 @@
+/**CFile****************************************************************
+
+ FileName [giaDecs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Calling various decomposition engines.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaDecs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
+#include "bool/bdc/bdc.h"
+#include "bool/kit/kit.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+extern Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ResubVarNum( Vec_Int_t * vResub )
+{
+ if ( Vec_IntSize(vResub) == 1 )
+ return Vec_IntEntryLast(vResub) >= 2;
+ return Vec_IntEntryLast(vResub)/2 - Vec_IntSize(vResub)/2 - 1;
+}
+word Gia_ResubToTruth6_rec( Vec_Int_t * vResub, int iNode, int nVars )
+{
+ assert( iNode >= 0 && nVars <= 6 );
+ if ( iNode < nVars )
+ return s_Truths6[iNode];
+ else
+ {
+ int iLit0 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 0) );
+ int iLit1 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 1) );
+ word Res0 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit0)-2, nVars );
+ word Res1 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit1)-2, nVars );
+ Res0 = Abc_LitIsCompl(iLit0) ? ~Res0 : Res0;
+ Res1 = Abc_LitIsCompl(iLit1) ? ~Res1 : Res1;
+ return iLit0 > iLit1 ? Res0 ^ Res1 : Res0 & Res1;
+ }
+}
+word Gia_ResubToTruth6( Vec_Int_t * vResub )
+{
+ word Res;
+ int iRoot = Vec_IntEntryLast(vResub);
+ if ( iRoot < 2 )
+ return iRoot ? ~(word)0 : 0;
+ assert( iRoot != 2 && iRoot != 3 );
+ Res = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iRoot)-2, Gia_ResubVarNum(vResub) );
+ return Abc_LitIsCompl(iRoot) ? ~Res : Res;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Gia_ManDeriveTruths( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords )
+{
+ int nTtWords = Abc_Truth6WordNum(Vec_IntSize(vSet));
+ int nFuncs = Vec_WrdSize(vIsfs) / 2 / nWords;
+ Vec_Wrd_t * vRes = Vec_WrdStart( 2 * nFuncs * nTtWords );
+ Vec_Wrd_t * vIn = Vec_WrdStart( 64*nWords ), * vOut;
+ int i, f, m, iObj; word Func;
+ assert( Vec_IntSize(vSet) <= 64 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Abc_TtCopy( Vec_WrdEntryP(vIn, i*nWords), Vec_WrdEntryP(vSims, Vec_IntEntry(vCands, iObj)*nWords), nWords, 0 );
+ vOut = Vec_WrdStart( Vec_WrdSize(vIn) );
+ Extra_BitMatrixTransposeP( vIn, nWords, vOut, 1 );
+ for ( f = 0; f < nFuncs; f++ )
+ {
+ word * pIsf[2] = { Vec_WrdEntryP(vIsfs, (2*f+0)*nWords),
+ Vec_WrdEntryP(vIsfs, (2*f+1)*nWords) };
+ word * pTruth[2] = { Vec_WrdEntryP(vRes, (2*f+0)*nTtWords),
+ Vec_WrdEntryP(vRes, (2*f+1)*nTtWords) };
+ for ( m = 0; m < 64*nWords; m++ )
+ {
+ int iMint = (int)Vec_WrdEntry(vOut, m);
+ int Value0 = Abc_TtGetBit( pIsf[0], m );
+ int Value1 = Abc_TtGetBit( pIsf[1], m );
+ if ( !Value0 && !Value1 )
+ continue;
+ if ( Value0 && Value1 )
+ printf( "Internal error: Onset and Offset overlap.\n" );
+ assert( !Value0 || !Value1 );
+ Abc_TtSetBit( pTruth[Value1], iMint );
+ }
+ if ( Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) )
+ printf( "Verification for function %d failed for %d minterm pairs.\n", f,
+ Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) );
+ }
+ if ( Vec_IntSize(vSet) < 6 )
+ Vec_WrdForEachEntry( vRes, Func, i )
+ Vec_WrdWriteEntry( vRes, i, Abc_Tt6Stretch(Func, Vec_IntSize(vSet)) );
+ Vec_WrdFree( vIn );
+ Vec_WrdFree( vOut );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountResub( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ Vec_Int_t * vResub; int nNodes;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
+ Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
+ assert( Vec_WrdSize(vElems) == nTtWords * nVars );
+ assert( nFuncs == 1 );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
+ for ( v = 0; v < nVars; v++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
+ vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, fVerbose, NULL, 0 );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vElems );
+ nNodes = Vec_IntSize(vResub) ? Vec_IntSize(vResub)/2 : 999;
+ Vec_IntFree( vResub );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveResub( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vResub;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
+ Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
+ assert( Vec_WrdSize(vElems) == nTtWords * nVars );
+ assert( nFuncs == 1 );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
+ for ( v = 0; v < nVars; v++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
+ vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, 0, NULL, 0 );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vElems );
+ return vResub;
+}
+
+int Gia_ManCountBidec( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ int nNodes, nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ nNodes = Bdc_ManBidecNodeNum( pTruth[1], pTruth[0], nVars, fVerbose );
+ Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveBidec( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vRes = NULL;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ vRes = Bdc_ManBidecResub( pTruth[1], pTruth[0], nVars );
+ Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ return vRes;
+}
+
+int Gia_ManCountIsop( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ int nNodes = Kit_IsopNodeNum( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveIsop( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vRes = NULL;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ vRes = Kit_IsopResub( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
+ return vRes;
+}
+
+int Gia_ManCountBdd( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Gia_Man_t * pGia; int nNodes;
+
+ Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+ Abc_TtNot( pTruth[0], nTtWords );
+ pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
+ Abc_TtNot( pTruth[0], nTtWords );
+ Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+
+ nNodes = Gia_ManAndNum(pGia);
+ Gia_ManStop( pGia );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveBdd( Vec_Wrd_t * vTruths, int nVars )
+{
+ extern Vec_Int_t * Gia_ManToGates( Gia_Man_t * p );
+ Vec_Int_t * vRes = NULL;
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Gia_Man_t * pGia;
+
+ Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+ Abc_TtNot( pTruth[0], nTtWords );
+ pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
+ Abc_TtNot( pTruth[0], nTtWords );
+ Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+
+ vRes = Gia_ManToGates( pGia );
+ Gia_ManStop( pGia );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose )
+{
+ Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
+ int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ int nNodesResub = Gia_ManCountResub( vTruths, nVars, 0 );
+ int nNodesBidec = nVars > 2 ? Gia_ManCountBidec( vTruths, nVars, 0 ) : 999;
+ int nNodesIsop = nVars > 2 ? Gia_ManCountIsop( vTruths, nVars, 0 ) : 999;
+ int nNodesBdd = nVars > 2 ? Gia_ManCountBdd( vTruths, nVars, 0 ) : 999;
+ int nNodesMin = Abc_MinInt( Abc_MinInt(nNodesResub, nNodesBidec), Abc_MinInt(nNodesIsop, nNodesBdd) );
+ if ( fVerbose )
+ {
+ printf( "Size = %2d ", nVars );
+ printf( "Resub =%3d ", nNodesResub );
+ printf( "Bidec =%3d ", nNodesBidec );
+ printf( "Isop =%3d ", nNodesIsop );
+ printf( "Bdd =%3d ", nNodesBdd );
+ Abc_TtIsfPrint( pTruth[0], pTruth[1], nTtWords );
+ if ( nVars <= 6 )
+ {
+ printf( " " );
+ Extra_PrintHex( stdout, (unsigned*)pTruth[0], nVars );
+ printf( " " );
+ Extra_PrintHex( stdout, (unsigned*)pTruth[1], nVars );
+ }
+ printf( "\n" );
+ }
+ Vec_WrdFree( vTruths );
+ if ( nNodesMin > 500 )
+ return -1;
+ if ( nNodesMin == nNodesResub )
+ return (nNodesMin << 2) | 0;
+ if ( nNodesMin == nNodesBidec )
+ return (nNodesMin << 2) | 1;
+ if ( nNodesMin == nNodesIsop )
+ return (nNodesMin << 2) | 2;
+ if ( nNodesMin == nNodesBdd )
+ return (nNodesMin << 2) | 3;
+ return -1;
+}
+Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type )
+{
+ Vec_Int_t * vRes = NULL;
+ Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
+ int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ if ( Type == 0 )
+ vRes = Gia_ManDeriveResub( vTruths, nVars );
+ else if ( Type == 1 )
+ vRes = Gia_ManDeriveBidec( vTruths, nVars );
+ else if ( Type == 2 )
+ vRes = Gia_ManDeriveIsop( vTruths, nVars );
+ else if ( Type == 3 )
+ vRes = Gia_ManDeriveBdd( vTruths, nVars );
+ if ( vRes && Gia_ResubVarNum(vRes) <= 6 )
+ {
+ word Func = Gia_ResubToTruth6( vRes );
+ assert( !(Func & pTruth[0][0]) );
+ assert( !(pTruth[1][0] & ~Func) );
+ }
+ Vec_WrdFree( vTruths );
+ return vRes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c
index f8b2930e..815a546e 100644
--- a/src/aig/gia/giaDeep.c
+++ b/src/aig/gia/giaDeep.c
@@ -19,14 +19,14 @@
***********************************************************************/
#include "gia.h"
+#include "base/main/main.h"
+#include "base/cmd/cmd.h"
ABC_NAMESPACE_IMPL_START
-
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -43,9 +43,121 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed, int fVerbose )
+Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
+{
+ abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
+ abctime clkStart = Abc_Clock();
+ int s, i, IterMax = 100000, nAndsMin = -1, iIterLast = -1;
+ Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ Gia_Man_t * pNew = Gia_ManDup( pTemp );
+ Abc_Random(1);
+ for ( s = 0; s < 10+Seed; s++ )
+ Abc_Random(0);
+ for ( i = 0; i < IterMax; i++ )
+ {
+ unsigned Rand = Abc_Random(0);
+ int fDch = Rand & 1;
+ //int fCom = (Rand >> 1) & 3;
+ int fCom = (Rand >> 1) & 1;
+ int fFx = (Rand >> 2) & 1;
+ int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4);
+ int fChange = 0;
+ char Command[1000];
+ char * pComp = NULL;
+ if ( fCom == 3 )
+ pComp = "; &put; compress2rs; compress2rs; compress2rs; &get";
+ else if ( fCom == 2 )
+ pComp = "; &put; compress2rs; compress2rs; &get";
+ else if ( fCom == 1 )
+ pComp = "; &put; compress2rs; &get";
+ else if ( fCom == 0 )
+ pComp = "; &dc2";
+ sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
+ fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
+ if ( Abc_FrameIsBatchMode() )
+ {
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
+ return NULL;
+ }
+ }
+ else
+ {
+ Abc_FrameSetBatchMode( 1 );
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
+ return NULL;
+ }
+ Abc_FrameSetBatchMode( 0 );
+ }
+ pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
+ {
+ Gia_ManStop( pNew );
+ pNew = Gia_ManDup( pTemp );
+ fChange = 1;
+ iIterLast = i;
+ }
+ else if ( Gia_ManAndNum(pNew) + Gia_ManAndNum(pNew)/10 < Gia_ManAndNum(pTemp) )
+ {
+ //printf( "Updating\n" );
+ //Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pNew) );
+ }
+ if ( fChange && fVerbose )
+ {
+ printf( "Iter %6d : ", i );
+ printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ printf( "And = %6d ", Gia_ManAndNum(pNew) );
+ printf( "Lev = %3d ", Gia_ManLevelNum(pNew) );
+ if ( fChange )
+ printf( "<== best : " );
+ else if ( fVerbose )
+ printf( " " );
+ printf( "%s", Command );
+ printf( "\n" );
+ }
+ if ( nTimeToStop && Abc_Clock() > nTimeToStop )
+ {
+ printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
+ break;
+ }
+ if ( i - iIterLast > nNoImpr )
+ {
+ printf( "Completed %d iterations without improvement in %.2f seconds.\n",
+ nNoImpr, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ break;
+ }
+ }
+ if ( i == IterMax )
+ printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ else if ( nAnds && nAndsMin <= nAnds )
+ printf( "Quality goal (%d nodes <= %d nodes) is achieved after %d iterations and %.2f seconds.\n",
+ nAndsMin, nAnds, i, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ return pNew;
+}
+Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
{
- return NULL;
+ Gia_Man_t * pInit = Gia_ManDup(pGia);
+ Gia_Man_t * pBest = Gia_ManDup(pGia);
+ Gia_Man_t * pThis;
+ int i;
+ for ( i = 0; i < nIters; i++ )
+ {
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
+ pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose );
+ if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) )
+ {
+ Gia_ManStop( pBest );
+ pBest = pThis;
+ }
+ else
+ Gia_ManStop( pThis );
+
+ }
+ Gia_ManStop( pInit );
+ return pBest;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c
index 5cfe3b44..7ed59b9a 100644
--- a/src/aig/gia/giaDfs.c
+++ b/src/aig/gia/giaDfs.c
@@ -418,6 +418,34 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Levelizes the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vLevels;
+ int nLevels, Level, i;
+ nLevels = Gia_ManLevelRNum( p );
+ vLevels = Vec_WecStart( nLevels + 1 );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( i == 0 || (!Gia_ObjIsCo(pObj) && !Gia_ObjLevel(p, pObj)) )
+ continue;
+ Level = Gia_ObjLevel( p, pObj );
+ assert( Level <= nLevels );
+ Vec_WecPush( vLevels, Level, i );
+ }
+ return vLevels;
+}
+/**Function*************************************************************
+
Synopsis [Computes reverse topological order.]
Description [Assumes that levels are already assigned.
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index 4f448c40..b3fcd295 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -466,7 +466,16 @@ Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p )
+int Gia_ManDupOrderDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
@@ -476,12 +485,28 @@ Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p )
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
- Gia_ManForEachCoReverse( p, pObj, i )
- Gia_ManDupOrderDfs_rec( pNew, p, pObj );
Gia_ManForEachCi( p, pObj, i )
- if ( !~pObj->Value )
- pObj->Value = Gia_ManAppendCi(pNew);
- assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
+ pObj->Value = Gia_ManAppendCi(pNew);
+ if ( fRevOuts )
+ {
+ if ( fRevFans )
+ Gia_ManForEachCoReverse( p, pObj, i )
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ else
+ Gia_ManForEachCoReverse( p, pObj, i )
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ }
+ else
+ {
+ if ( fRevFans )
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ else
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManDupRemapCis( pNew, p );
Gia_ManDupRemapCos( pNew, p );
Gia_ManDupRemapEquiv( pNew, p );
@@ -1327,7 +1352,7 @@ Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p )
{
Gia_Obj_t * pRepr;
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) );
- for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ for ( i = 0; i < Gia_ManObjNum(pNew); i++ )
Gia_ObjSetRepr( pNew, i, GIA_VOID );
Gia_ManForEachObj1( p, pObj, i )
{
@@ -1585,6 +1610,52 @@ Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo )
/**Function*************************************************************
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupDfsRehash_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew->nConstrs = p->nConstrs;
+ if ( p->pCexSeq )
+ pNew->pCexSeq = Abc_CexDup( p->pCexSeq, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Cofactors w.r.t. a primary input variable.]
Description []
@@ -2295,6 +2366,31 @@ Gia_Man_t * Gia_ManDupTrimmed2( Gia_Man_t * p )
assert( !Gia_ManHasDangling( pNew ) );
return pNew;
}
+Gia_Man_t * Gia_ManDupTrimmed3( Gia_Man_t * p )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ 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) );
+ // mark duplicated POs
+ Gia_ManForEachPo( p, pObj, i )
+ Vec_IntWriteEntry( vMap, Gia_ObjFaninId0p(p, pObj), i );
+ Gia_ManForEachPo( p, pObj, i )
+ if ( Vec_IntEntry(vMap, Gia_ObjFaninId0p(p, pObj)) == i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntFree( vMap );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
/**Function*************************************************************
@@ -2916,6 +3012,44 @@ Vec_Ptr_t * Gia_ManMiterNames( Vec_Ptr_t * p, int nOuts )
/**Function*************************************************************
+ Synopsis [Pair-wise miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPairWiseMiter( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pObj2;
+ int i, k, iLit;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManHashAlloc( 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 )
+ Gia_ManForEachPo( p, pObj2, k )
+ {
+ if ( i >= k )
+ continue;
+ iLit = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Transforms the circuit into a regular miter.]
Description []
@@ -3448,7 +3582,7 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis )
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots );
- Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId );
+ Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId );
// start the new manager
// Gia_ManFillValue( p );
@@ -3460,6 +3594,8 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis )
// create PIs
if ( fTrimPis )
{
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = ~0;
Vec_PtrForEachEntry( Gia_Obj_t *, vLeaves, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
}
@@ -3508,7 +3644,7 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots );
- Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId );
+ Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId );
// start the new manager
// Gia_ManFillValue( p );
@@ -4245,7 +4381,7 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
vSuperPtr = Vec_PtrAlloc( Vec_IntSize(vSuper) );
Vec_IntForEachEntry( vSuper, iLit, i )
Vec_PtrPush( vSuperPtr, Gia_Lit2Obj(p, iLit) );
- Vec_PtrSort( vSuperPtr, (int (*)(void))Gia_ManSortByValue );
+ Vec_PtrSort( vSuperPtr, (int (*)(const void *, const void *))Gia_ManSortByValue );
// create new manager
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
@@ -4899,6 +5035,38 @@ Gia_Man_t * Gia_ManDupReplaceCut( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Duplicate AIG by creating a cut between logic fed by PIs]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti )
+{
+ Gia_Man_t * pNew; int i, k;
+ Gia_Obj_t * pObj;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCiNum(p) * nMulti );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ for ( k = 1; k < nMulti; k++ )
+ 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) );
+ assert( Gia_ManCiNum(pNew) == nMulti * Gia_ManCiNum(p) );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c
index b646a311..28d28483 100644
--- a/src/aig/gia/giaEmbed.c
+++ b/src/aig/gia/giaEmbed.c
@@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START
http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf
Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah.
- "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
+ "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI 03.
http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
*/
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index 03b9b819..5c82b260 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -269,6 +269,7 @@ int * Gia_ManDeriveNexts( Gia_Man_t * p )
pTails[i] = i;
for ( i = 0; i < Gia_ManObjNum(p); i++ )
{
+ //if ( p->pReprs[i].iRepr == GIA_VOID )
if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID )
continue;
pNexts[ pTails[p->pReprs[i].iRepr] ] = i;
@@ -480,8 +481,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
}
CounterX -= Gia_ManCoNum(p);
nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
- Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
- Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
+// Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
+// Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
+ Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d\n",
+ Counter0, Counter, nLits, CounterX, Proved );
assert( Gia_ManEquivCheckLits( p, nLits ) );
if ( fVerbose )
{
@@ -1985,7 +1988,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) );
for ( i = 0; i < Gia_ManObjNum(p); i++ )
- Gia_ObjSetRepr( pNew, i, GIA_VOID );
+ pNew->pReprs[i].iRepr = GIA_VOID;
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
@@ -2587,6 +2590,294 @@ void Gia_ManFilterEquivsUsingLatches( Gia_Man_t * pGia, int fFlopsOnly, int fFlo
Abc_Print( 1, "The number of literals: Before = %d. After = %d.\n", iLitsOld, iLitsNew );
}
+/**Function*************************************************************
+
+ Synopsis [Changing node order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManChangeOrder_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ if ( Gia_ObjIsCo(pObj) )
+ return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManChangeOrder( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i, k;
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachClass( p, i )
+ Gia_ClassForEachObj( p, i, k )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
+ Gia_ManForEachConst( p, k )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ assert( Gia_ManObjNum(pNew) == Gia_ManObjNum(p) );
+ return pNew;
+}
+void Gia_ManTransferEquivs( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ Vec_Int_t * vClass;
+ int i, k, iNode, iRepr;
+ assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
+ assert( p->pReprs != NULL );
+ assert( p->pNexts != NULL );
+ assert( pNew->pReprs == NULL );
+ assert( pNew->pNexts == NULL );
+ // 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, Abc_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, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
+ assert( Vec_IntSize( vClass ) > 1 );
+ Vec_IntSort( vClass, 0 );
+ iRepr = Vec_IntEntry( vClass, 0 );
+ Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
+ Gia_ObjSetRepr( pNew, iNode, iRepr );
+ }
+ Vec_IntFree( vClass );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+}
+void Gia_ManTransferTest( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_Rpr_t * pReprs = p->pReprs; // representatives (for CIs and ANDs)
+ int * pNexts = p->pNexts; // next nodes in the equivalence classes
+ Gia_Man_t * pNew = Gia_ManChangeOrder(p);
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
+ Gia_ManTransferEquivs( p, pNew );
+ p->pReprs = NULL;
+ p->pNexts = NULL;
+ // make new point to old
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ assert( !Abc_LitIsCompl(pObj->Value) );
+ Gia_ManObj(pNew, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0);
+ }
+ Gia_ManTransferEquivs( pNew, p );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ pReprs[i].fProved = 0;
+ //printf( "%5d : %5d %5d %5d %5d\n", i, *(int*)&p->pReprs[i], *(int*)&pReprs[i], (int)p->pNexts[i], (int)pNexts[i] );
+ if ( memcmp(p->pReprs, pReprs, sizeof(int)*Gia_ManObjNum(p)) )
+ printf( "Verification of reprs failed.\n" );
+ else
+ printf( "Verification of reprs succeeded.\n" );
+ if ( memcmp(p->pNexts, pNexts, sizeof(int)*Gia_ManObjNum(p)) )
+ printf( "Verification of nexts failed.\n" );
+ else
+ printf( "Verification of nexts succeeded.\n" );
+ ABC_FREE( pNew->pReprs );
+ ABC_FREE( pNew->pNexts );
+ ABC_FREE( pReprs );
+ ABC_FREE( pNexts );
+ Gia_ManStop( pNew );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec4_ManMarkIndependentClasses_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ assert( iObj > 0 );
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) // failed
+ return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) // passed
+ return 1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 1;
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId0(pObj, iObj) ) &&
+ Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId1(pObj, iObj) ) )
+ return 1;
+ Gia_ObjSetTravIdPreviousId(p, iObj);
+ return 0;
+}
+int Cec4_ManMarkIndependentClasses( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ int iObjNew, iRepr, iObj, Res, fHaveChoices = 0;
+ Gia_ManCleanMark01(p);
+ Gia_ManForEachClass( p, iRepr )
+ {
+ Gia_ManIncrementTravId( pNew );
+ Gia_ManIncrementTravId( pNew );
+ iObjNew = Abc_Lit2Var( Gia_ManObj(p, iRepr)->Value );
+ Res = Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew );
+ assert( Res == 1 );
+ Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
+ p->pReprs[iRepr].fColorA = 1;
+ Gia_ClassForEachObj1( p, iRepr, iObj )
+ {
+ assert( p->pReprs[iObj].iRepr == (unsigned)iRepr );
+ iObjNew = Abc_Lit2Var( Gia_ManObj(p, iObj)->Value );
+ if ( Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew ) )
+ {
+ p->pReprs[iObj].fColorA = 1;
+ fHaveChoices = 1;
+ }
+ Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
+ }
+ }
+ return fHaveChoices;
+}
+int Cec4_ManSatSolverAnd_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
+{
+ return 0;
+}
+int Cec4_ManSatSolverChoices_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
+{
+ if ( !Gia_ObjIsClass(p, iObj) )
+ return Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj );
+ else
+ {
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ int i, iHead, iNext, iRepr = Gia_ObjIsHead(p, iObj) ? iObj : Gia_ObjRepr(p, iObj);
+ Gia_ClassForEachObj( p, iRepr, iObj )
+ if ( p->pReprs[iObj].fColorA )
+ Vec_IntPush( vLits, Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj ) );
+ Vec_IntSort( vLits, 1 );
+ iHead = Abc_Lit2Var( Vec_IntEntry(vLits, 0) );
+ if ( Vec_IntSize(vLits) > 1 )
+ {
+ Vec_IntForEachEntryStart( vLits, iNext, i, 1 )
+ {
+ pCho->pSibls[iHead] = Abc_Lit2Var(iNext);
+ iHead = Abc_Lit2Var(iNext);
+ }
+ }
+ return Abc_LitNotCond( Vec_IntEntry(vLits, 0), Gia_ManObj(p, iHead)->fPhase );
+ }
+}
+Gia_Man_t * Cec4_ManSatSolverChoices( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ Gia_Man_t * pCho;
+ Gia_Obj_t * pObj;
+ int i, DriverId;
+ // mark topologically dependent equivalent nodes
+ if ( !Cec4_ManMarkIndependentClasses( p, pNew ) )
+ return Gia_ManDup( pNew );
+ // rebuild AIG in a different order with choices
+ pCho = Gia_ManStart( Gia_ManObjNum(pNew) );
+ pCho->pName = Abc_UtilStrsav( p->pName );
+ pCho->pSpec = Abc_UtilStrsav( p->pSpec );
+ pCho->pSibls = ABC_CALLOC( int, Gia_ManObjNum(pNew) );
+ Gia_ManFillValue(pNew);
+ Gia_ManConst0(pNew)->Value = 0;
+ for ( i = 0; i < Gia_ManCiNum(pNew); i++ )
+ Gia_ManCi(pNew, i)->Value = Gia_ManAppendCi( pCho );
+ Gia_ManForEachCoDriverId( p, DriverId, i )
+ Cec4_ManSatSolverChoices_rec( pCho, p, pNew, DriverId );
+ Gia_ManForEachCo( pNew, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pCho, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pCho, Gia_ManRegNum(p) );
+ return pCho;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCombSpecReduce( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pRepr; int i, iLit;
+ Vec_Int_t * vXors = Vec_IntAlloc( 100 );
+ Gia_Man_t * pTemp, * pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ assert( p->pReprs && p->pNexts );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManLevelNum(p);
+ Gia_ManSetPhase(p);
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pRepr = Gia_ObjReprObj( p, i );
+ if ( pRepr && Abc_Lit2Var(pObj->Value) != Abc_Lit2Var(pRepr->Value) )
+ {
+ //if ( Gia_ObjLevel(p, pRepr) > Gia_ObjLevel(p, pObj) + 50 )
+ //printf( "%d %d ", Gia_ObjLevel(p, pRepr), Gia_ObjLevel(p, pObj) );
+ iLit = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
+ Vec_IntPush( vXors, Gia_ManHashXor( pNew, pObj->Value, iLit ) );
+ pObj->Value = iLit;
+ }
+ }
+ Gia_ManHashStop( pNew );
+ if ( Vec_IntSize(vXors) == 0 )
+ Vec_IntPush( vXors, 0 );
+ Vec_IntForEachEntry( vXors, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vXors );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+void Gia_ManCombSpecReduceTest( Gia_Man_t * p, char * pFileName )
+{
+ Gia_Man_t * pSrm = Gia_ManCombSpecReduce( p );
+ if ( pFileName == NULL )
+ pFileName = "test.aig";
+ Gia_AigerWrite( pSrm, pFileName, 0, 0, 0 );
+ Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", pFileName );
+ Gia_ManStop( pSrm );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c
index 44e79ba2..8b104e9b 100644
--- a/src/aig/gia/giaFanout.c
+++ b/src/aig/gia/giaFanout.c
@@ -283,6 +283,89 @@ void Gia_ManStaticFanoutStart( Gia_Man_t * p )
Vec_IntFree( vCounts );
}
+
+/**Function*************************************************************
+
+ Synopsis [Compute the map of all edges.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManStartMappingFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums )
+{
+ Gia_Obj_t * pObj;
+ int i, iOffset = Gia_ManObjNum(p);
+ Vec_Int_t * vEdgeMap = Vec_IntAlloc( 2 * iOffset );
+ Vec_IntFill( vEdgeMap, iOffset, 0 );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Vec_IntEntry(vFanoutNums, i) == 0 )
+ continue;
+ Vec_IntWriteEntry( vEdgeMap, i, iOffset );
+ iOffset += Vec_IntEntry( vFanoutNums, i );
+ Vec_IntFillExtra( vEdgeMap, iOffset, 0 );
+ }
+ //printf( "Fanout map is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vEdgeMap)/Gia_ManObjNum(p) );
+ return vEdgeMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates static fanout.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p )
+{
+ Vec_Int_t * vCounts;
+ int * pRefsOld;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, iFan, iFanout;
+ assert( p->vFanoutNums == NULL );
+ assert( p->vFanout == NULL );
+ // recompute reference counters
+ pRefsOld = p->pLutRefs; p->pLutRefs = NULL;
+ Gia_ManSetLutRefs(p);
+ p->vFanoutNums = Vec_IntAllocArray( p->pLutRefs, Gia_ManObjNum(p) );
+ p->pLutRefs = pRefsOld;
+ // start the fanout maps
+ p->vFanout = Gia_ManStartMappingFanoutMap( p, p->vFanoutNums );
+ // incrementally add fanouts
+ vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManForEachLut( p, i )
+ {
+ pObj = Gia_ManObj( p, i );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ pFanin = Gia_ManObj( p, iFan );
+ iFanout = Vec_IntEntry( vCounts, iFan );
+ Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
+ Vec_IntAddToEntry( vCounts, iFan, 1 );
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ iFan = Gia_ObjFaninId0p(p, pObj);
+ pFanin = Gia_ManObj( p, iFan );
+ iFanout = Vec_IntEntry( vCounts, iFan );
+ Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
+ Vec_IntAddToEntry( vCounts, iFan, 1 );
+ }
+ // double-check the current number of fanouts added
+ Gia_ManForEachObj( p, pObj, i )
+ assert( Vec_IntEntry(vCounts, i) == Gia_ObjFanoutNum(p, pObj) );
+ Vec_IntFree( vCounts );
+}
+
/**Function*************************************************************
Synopsis [Deallocates static fanout.]
diff --git a/src/aig/gia/giaFx.c b/src/aig/gia/giaFx.c
index c6eae6c7..032ae5fc 100644
--- a/src/aig/gia/giaFx.c
+++ b/src/aig/gia/giaFx.c
@@ -460,7 +460,11 @@ Gia_Man_t * Gia_ManPerformFx( Gia_Man_t * p, int nNewNodesMax, int LitCountMax,
Vec_Wec_t * vCubes;
Vec_Str_t * vCompl;
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ return pNew;
+ }
// abctime clk;
assert( Gia_ManHasMapping(p) );
// collect information
diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c
index 94d561cc..cb56ef64 100644
--- a/src/aig/gia/giaGen.c
+++ b/src/aig/gia/giaGen.c
@@ -20,6 +20,7 @@
#include "gia.h"
#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -35,6 +36,64 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_DeriveAig( Vec_Wrd_t * vSims, Vec_Str_t * vSimsOut )
+{
+ int nInputs = 32*32*24;
+ int nWords = nInputs/64;
+ int nExamps = 64;
+ int i, e, iLitOut[10] = {0};
+ Gia_Man_t * pNew;
+ assert( Vec_WrdSize(vSims) % nInputs == 0 );
+ pNew = Gia_ManStart( nInputs * nExamps + 10000 );
+ for ( i = 0; i < nInputs; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashStart( pNew );
+ for ( e = 0; e < nExamps; e++ )
+ {
+ int Class = Vec_StrEntry( vSimsOut, e );
+ int This = 1;
+ word * pSim = Vec_WrdEntryP( vSims, e*nWords );
+ for ( i = 0; i < nInputs; i++ )
+ This = Gia_ManHashAnd( pNew, This, Abc_Var2Lit(i+1, !Abc_TtGetBit(pSim, i)) );
+ assert( Class >= 0 && Class <= 9 );
+ iLitOut[Class] = Gia_ManHashOr( pNew, iLitOut[Class], This );
+ //printf( "Finished example %d\n", e );
+ }
+ for ( i = 0; i < 10; i++ )
+ Gia_ManAppendCo( pNew, iLitOut[i] );
+ //pNew = Gia_ManCleanup( pTemp = pNew );
+ //Gia_ManStop( pTemp );
+ return pNew;
+}
+void Gia_DeriveAigTest()
+{
+ extern int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples );
+ char pFileName[100] = "test";
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int nExamples = 0;
+ int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples );
+ Gia_Man_t * pThis = Gia_DeriveAig( vSimsIn, vSimsOut );
+ Gia_AigerWrite( pThis, "examples64.aig", 0, 0, 0 );
+ printf( "Dumped file \"%s\".\n", "examples64.aig" );
+ Gia_ManStop( pThis );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+ nInputs = 0;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Populate internal simulation info.]
Description []
@@ -136,6 +195,38 @@ int Gia_ManSimulateWordsInit( Gia_Man_t * p, Vec_Wrd_t * vSimsIn )
return 1;
}
+Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn )
+{
+ Gia_Obj_t * pObj; int i, Id;
+ int nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p);
+ Vec_Wrd_t * vSimsOut = Vec_WrdStart( nWords * Gia_ManCoNum(p) );
+ assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) );
+ // allocate simulation info for one timeframe
+ Vec_WrdFreeP( &p->vSims );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
+ p->nSimWords = nWords;
+ // set input sim info
+ Gia_ManForEachCiId( p, Id, i )
+ memcpy( Vec_WrdEntryP(p->vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords );
+ // perform simulation
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManObjSimAnd( p, i );
+ else if ( Gia_ObjIsCi(pObj) )
+ continue;
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ManObjSimPo( p, i );
+ else assert( 0 );
+ }
+ // set output sim info
+ Gia_ManForEachCoId( p, Id, i )
+ memcpy( Vec_WrdEntryP(vSimsOut, i*nWords), Vec_WrdEntryP(p->vSims, Id*nWords), sizeof(word)*nWords );
+ Vec_WrdFreeP( &p->vSims );
+ p->nSimWords = -1;
+ return vSimsOut;
+}
+
/**Function*************************************************************
Synopsis [Dump data files.]
@@ -443,6 +534,224 @@ void Gia_ManCompareValues( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Int_t * vValu
SeeAlso []
***********************************************************************/
+void Gia_ManReadSimFile( char * pFileName, int * pnIns, int * pnOuts, int * pnPats, Vec_Wrd_t ** pvSimsIn, Vec_Wrd_t ** pvSimsOut )
+{
+ char * pTemp, pBuffer[1000];
+ Vec_Wrd_t * vSimsIn = NULL, * vSimsOut = NULL;
+ int i, iPat = 0, nWordsI, nWordsO, nIns = -1, nOuts = -1, nPats = -1;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ while ( fgets( pBuffer, 1000, pFile ) != NULL )
+ {
+ pTemp = pBuffer;
+ if ( pTemp[0] == '\0' || pTemp[0] == '#' || pTemp[0] == ' ' )
+ continue;
+ if ( pTemp[0] != '.' )
+ break;
+ if ( pTemp[1] == 'i' )
+ nIns = atoi(pTemp+2);
+ else if ( pTemp[1] == 'o' )
+ nOuts = atoi(pTemp+2);
+ else if ( pTemp[1] == 'p' )
+ {
+ if ( atoi(pTemp+2) % 64 == 0 )
+ printf( "Expecting the number of patterns divisible by 64.\n" );
+ nPats = atoi(pTemp+2) / 64;
+ }
+ }
+ if ( nIns == -1 || nOuts == -1 || nPats == -1 )
+ {
+ printf( "Some of the parameters (inputs, outputs, patterns) is not specified.\n" );
+ fclose( pFile );
+ return;
+ }
+ nWordsI = (nIns + 63) / 64;
+ nWordsO = (nOuts + 63) / 64;
+
+ vSimsIn = Vec_WrdStart( nPats * nWordsI );
+ vSimsOut = Vec_WrdStart( nPats * nWordsO );
+ rewind(pFile);
+ while ( fgets( pBuffer, 1000, pFile ) != NULL )
+ {
+ if ( pTemp[0] == '\0' || pTemp[0] == '.' )
+ continue;
+ for ( i = 0, pTemp = pBuffer; *pTemp != '\n'; pTemp++ )
+ if ( *pTemp == '0' || *pTemp == '1' )
+ {
+ if ( *pTemp == '1' )
+ {
+ if ( i < nIns )
+ Abc_TtSetBit( Vec_WrdEntryP(vSimsIn, nWordsI*iPat), i );
+ else
+ Abc_TtSetBit( Vec_WrdEntryP(vSimsOut, nWordsO*iPat), i-nIns );
+ }
+ i++;
+ }
+ iPat++;
+ }
+ if ( iPat != nPats )
+ printf( "The number of patterns does not match.\n" );
+ fclose( pFile );
+ *pnIns = nIns;
+ *pnOuts = nOuts;
+ *pnPats = nPats;
+ *pvSimsIn = vSimsIn;
+ *pvSimsOut = vSimsOut;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManReadBinaryFile( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ int nFileSize = Extra_FileSize( pFileName );
+ int nExamples = 1 << 16;
+ int nInputs = nFileSize / nExamples - 1;
+ int nWords = (8*nInputs + 63)/64, i;
+ char * pContents = Extra_FileReadContents( pFileName );
+ Vec_Wrd_t * vSimsIn = Vec_WrdStart( nExamples * nWords );
+ Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nExamples * nWords );
+ Vec_Str_t * vSimsOut = Vec_StrAlloc( nExamples );
+ assert( nFileSize % nExamples == 0 );
+ for ( i = 0; i < nExamples; i++ )
+ {
+ memcpy( (void *)Vec_WrdEntryP(vSimsIn, i*nWords), (void *)(pContents + i*(nInputs+1)), nInputs );
+ Vec_StrPush( vSimsOut, pContents[i*(nInputs+1) + nInputs] );
+ }
+ Extra_BitMatrixTransposeP( vSimsIn, nWords, vSimsIn2, nExamples/64 );
+ Vec_WrdShrink( vSimsIn2, 8*nInputs * nExamples/64 );
+ Vec_WrdFree( vSimsIn );
+ *pvSimsIn = vSimsIn2;
+ *pvSimsOut = vSimsOut;
+ ABC_FREE( pContents );
+ return nInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimLogStats2( Gia_Man_t * p, char * pDumpFile, int Total, int nPositives, float ErrorTotal, float GuessTotal )
+{
+ FILE * pTable = fopen( pDumpFile, "wb" );
+ fprintf( pTable, "{\n" );
+ fprintf( pTable, " \"name\" : \"%s\",\n", p->pName );
+ fprintf( pTable, " \"input\" : %d,\n", Gia_ManCiNum(p) );
+ fprintf( pTable, " \"output\" : %d,\n", Gia_ManCoNum(p) );
+ fprintf( pTable, " \"and\" : %d,\n", Gia_ManAndNum(p) );
+ fprintf( pTable, " \"level\" : %d,\n", Gia_ManLevelNum(p) );
+ fprintf( pTable, " \"total\" : %d,\n", Total );
+ fprintf( pTable, " \"positive\" : %d,\n", nPositives );
+ fprintf( pTable, " \"error\" : %e,\n", ErrorTotal );
+ fprintf( pTable, " \"guess\" : %e\n", GuessTotal );
+ fprintf( pTable, "}\n" );
+ fclose( pTable );
+}
+int Gia_ManGetExampleValue( word ** ppSims, int nSims, int iExample )
+{
+ int o, Sign = 0, ValueSim = 0;
+ for ( o = 0; o < nSims; o++ )
+ if ( (Sign = Abc_TtGetBit(ppSims[o], iExample)) )
+ ValueSim |= (1 << o);
+ if ( Sign )
+ ValueSim |= ~0 << nSims;
+ return ValueSim;
+}
+void Gia_ManCompareValues2( int nInputs, Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vValues, char * pDumpFile )
+{
+ float Error1, ErrorTotal = 0, Guess1, GuessTotal = 0;
+ int i, o, nPositives = 0, nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p);
+ word ** ppSims = ABC_CALLOC( word *, Gia_ManCoNum(p) );
+ Gia_Obj_t * pObj;
+ assert( nWords == (1<<10) );
+ assert( Vec_WrdSize(vSimsIn) % Gia_ManCiNum(p) == 0 );
+ assert( Vec_StrSize(vValues) == (1 << 16) );
+ assert( nWords*64 == (1 << 16) );
+ // simulate examples given in vSimsIn
+ Gia_ManSimulateWordsInit( p, vSimsIn );
+ // collect simulation info for the outputs
+ assert( p->nSimWords == nWords );
+ Gia_ManForEachCo( p, pObj, o )
+ ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) );
+ // compare the output for each example
+ for ( i = 0; i < nWords*64; i++ )
+ {
+ int ValueGold = (int)Vec_StrEntry( vValues, i );
+ int ValueImpl = Gia_ManGetExampleValue( ppSims, Gia_ManCoNum(p), i );
+ // compute error for this example
+ Error1 = (float)(ValueGold - ValueImpl)/256;
+ ErrorTotal += Error1 * Error1;
+ // compute error of zero-output
+ Guess1 = ValueGold > 0 ? Abc_AbsInt(ValueImpl) : 0;
+ GuessTotal += Guess1 * Guess1;
+ // count positive values (disregard negative values due to Leaky ReLU)
+ nPositives += (int)(ValueGold > 0);
+ }
+ ABC_FREE( ppSims );
+ printf( "Total = %6d. Positive = %6d. (%6.2f %%) Errors = %e. Guess = %e. (%6.2f %%)\n",
+ Vec_StrSize(vValues), nPositives, 100.0*nPositives/Vec_StrSize(vValues),
+ ErrorTotal, GuessTotal, 100.0*ErrorTotal/GuessTotal );
+ if ( pDumpFile == NULL )
+ return;
+ Gia_ManSimLogStats2( p, pDumpFile, Vec_StrSize(vValues), nPositives, ErrorTotal, GuessTotal );
+ printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManTestWordFileUnused( Gia_Man_t * p, char * pFileName, char * pDumpFile )
+{
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int nInputs = Gia_ManReadBinaryFile( pFileName, &vSimsIn, &vSimsOut );
+ if ( Gia_ManCiNum(p) == 8*nInputs )
+ Gia_ManCompareValues2( nInputs, p, vSimsIn, vSimsOut, pDumpFile );
+ else
+ printf( "The number of inputs in the AIG (%d) and in the file (%d) does not match.\n", Gia_ManCiNum(p), 8*nInputs );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile )
{
Vec_Wrd_t * vSimsIn;
@@ -463,6 +772,158 @@ void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile )
Vec_IntFree( vValues );
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples )
+{
+ int nPixels = 32*32*3;
+ int nFileSize = Extra_FileSize( pFileName );
+ int nExamples = nFileSize / (nPixels + 1);
+ int nWordsIn = nPixels / 8;
+ int nWordsOut = (nExamples + 63) / 64; int e;
+ if ( nFileSize % (nPixels + 1) )
+ {
+ printf( "The input file \"%s\" with image data does not appear to be in CIFAR10 format.\n", pFileName );
+ return 0;
+ }
+ else
+ {
+ Vec_Wrd_t * vSimsIn = Vec_WrdStart( 64 * nWordsOut * nWordsIn );
+ Vec_Str_t * vSimsOut = Vec_StrAlloc( 64 * nWordsOut );
+ unsigned char * pBuffer = ABC_ALLOC( unsigned char, nFileSize );
+ FILE * pFile = fopen( pFileName, "rb" );
+ int Value = fread( pBuffer, 1, nFileSize, pFile );
+ fclose( pFile );
+ assert( Value == nFileSize );
+ printf( "Successfully read %5.2f MB (%d images) from file \"%s\".\n", (float)nFileSize/(1<<20), nExamples, pFileName );
+ for ( e = 0; e < nExamples; e++ )
+ {
+ Vec_StrPush( vSimsOut, (char)pBuffer[e*(nPixels + 1)] );
+ memcpy( Vec_WrdEntryP(vSimsIn, e*nWordsIn), pBuffer + e*(nPixels + 1) + 1, nPixels );
+ }
+ ABC_FREE( pBuffer );
+ for ( ; e < 64 * nWordsOut; e++ )
+ Vec_StrPush( vSimsOut, (char)0 );
+ memset( Vec_WrdEntryP(vSimsIn, nExamples*nWordsIn), 0, (64*nWordsOut - nExamples)*nWordsIn );
+ *pvSimsIn = vSimsIn;
+ *pvSimsOut = vSimsOut;
+ *pnExamples = nExamples;
+ return 8*nPixels;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSimulateBatch( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, Vec_Str_t * vSimsOut2, int b, int Limit )
+{
+ Gia_Obj_t * pObj;
+ word * ppSims[10];
+ int i, o, Count = 0;
+ assert( Gia_ManCiNum(p) == Vec_WrdSize(vSimsIn) );
+ assert( Gia_ManCoNum(p) == 10 );
+ Gia_ManSimulateWordsInit( p, vSimsIn );
+ Gia_ManForEachCo( p, pObj, o )
+ ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) );
+ for ( i = 0; i < Limit; i++ )
+ {
+ int Value = 0;
+ for ( o = 0; o < 10; o++ )
+ if ( Abc_TtGetBit(ppSims[o], i) )
+ {
+ Value = o;
+ break;
+ }
+ Vec_StrPush( vSimsOut, (char)Value );
+ Count += Value == (int)Vec_StrEntry( vSimsOut2, 64*b+i );
+ }
+ return Count;
+}
+Vec_Str_t * Gia_ManSimulateAll( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, int nExamples, int fVerbose )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ Vec_Str_t * vRes = Vec_StrAlloc( 100 ); int b, Count;
+ int nWordsIn = 32*32*24/64; // one image
+ int nWordsOut = Vec_WrdSize(vSimsIn)/(nWordsIn*64);
+ assert( Vec_WrdSize(vSimsIn) % nWordsIn == 0 );
+ for ( b = 0; b < nWordsOut; b++ )
+ {
+ int Limit = b == nWordsOut-1 ? nExamples-b*64 : 64;
+ Vec_Wrd_t * vSimsIn1 = Vec_WrdStart( nWordsIn*64 );
+ Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nWordsIn*64 );
+ memcpy( Vec_WrdArray(vSimsIn1), Vec_WrdEntryP(vSimsIn, b*nWordsIn*64), sizeof(word)*nWordsIn*64 );
+ Extra_BitMatrixTransposeP( vSimsIn1, nWordsIn, vSimsIn2, 1 );
+ Vec_WrdFree( vSimsIn1 );
+ Count = Gia_ManSimulateBatch( p, vSimsIn2, vRes, vSimsOut, b, Limit );
+ Vec_WrdFree( vSimsIn2 );
+ if ( fVerbose )
+ printf( "Finished simulating word %4d (out of %4d). Correct = %2d. (Limit = %2d.)\n", b, nWordsOut, Count, Limit );
+ }
+ assert( Vec_StrSize(vRes) == nExamples );
+ return vRes;
+}
+void Gia_ManCompareCifar10Values( Gia_Man_t * p, Vec_Str_t * vRes, Vec_Str_t * vSimsOut, char * pDumpFile, int nExamples )
+{
+ int i, Guess = (nExamples+9)/10, Count = 0;
+ for ( i = 0; i < nExamples; i++ )
+ {
+ char ValueReal = Vec_StrEntry(vRes, i);
+ char ValueGold = Vec_StrEntry(vSimsOut, i);
+ if ( ValueReal == ValueGold )
+ Count++;
+ }
+ printf( "Summary: Total = %6d. Errors = %6d. Correct = %6d. (%6.2f %%) Naive guess = %6d. (%6.2f %%)\n",
+ nExamples, nExamples - Count,
+ Count, 100.0*Count/nExamples,
+ Guess, 100.0*Guess/nExamples);
+ if ( pDumpFile == NULL )
+ return;
+ Gia_ManSimLogStats( p, pDumpFile, nExamples, Count, Guess );
+ printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile );
+}
+void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int i, nExamples = 0;
+ int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples );
+ char * pKnownFileNames[3] = {"small.aig", "medium.aig", "large.aig"};
+ int pLimitFileSizes[3] = {10000, 100000, 1000000};
+ for ( i = 0; i < 3; i++ )
+ if ( p->pSpec && !strncmp(p->pSpec, pKnownFileNames[i], 5) && Gia_ManAndNum(p) > pLimitFileSizes[i] )
+ printf( "Warning: The input file \"%s\" contains more than %d internal and-nodes.\n", pKnownFileNames[i], pLimitFileSizes[i] );
+ if ( nInputs == Gia_ManCiNum(p) )
+ {
+ Vec_Str_t * vRes = Gia_ManSimulateAll( p, vSimsIn, vSimsOut, nExamples, fVerbose );
+ Gia_ManCompareCifar10Values( p, vRes, vSimsOut, pDumpFile, nExamples );
+ Vec_StrFree( vRes );
+ }
+ else
+ printf( "The primary input counts in the AIG (%d) and in the image data (%d) do not match.\n", Gia_ManCiNum(p), nInputs );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+ Abc_PrintTime( 1, "Total checking time", Abc_Clock() - clk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c
index 64e39613..063cfd31 100644
--- a/src/aig/gia/giaHash.c
+++ b/src/aig/gia/giaHash.c
@@ -814,6 +814,328 @@ int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts )
return iRes;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create multi-input tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManCollectLiterals( int nVars )
+{
+ int i, * pRes = ABC_CALLOC( int, nVars );
+ for ( i = 0; i < nVars; i++ )
+ pRes[i] = Abc_Var2Lit( i+1, 0 );
+ return pRes;
+}
+int * Gia_ManGenZero( int nBits )
+{
+ return ABC_CALLOC( int, nBits );
+}
+int * Gia_ManGenPerm( int nBits )
+{
+ int i, * pRes = ABC_CALLOC( int, nBits );
+ srand( time(NULL) );
+ for ( i = 0; i < nBits; i++ )
+ pRes[i] = i;
+ for ( i = 0; i < nBits; i++ )
+ {
+ int iPerm = rand() % nBits;
+ ABC_SWAP( int, pRes[i], pRes[iPerm] );
+ }
+ return pRes;
+}
+int * Gia_ManGenPerm2( int nBits )
+{
+ int i, * pRes = ABC_CALLOC( int, nBits );
+ srand( time(NULL) );
+ for ( i = 0; i < nBits; i++ )
+ pRes[i] = rand() % nBits;
+ return pRes;
+}
+int Gia_ManMultiCheck( int * pPerm, int nPerm )
+{
+ int i;
+ for ( i = 1; i < nPerm; i++ )
+ if ( pPerm[i-1] <= pPerm[i] )
+ return 0;
+ return 1;
+}
+int Gia_ManMultiInputPerm( Gia_Man_t * pNew, int * pVars, int nVars, int * pPerm, int fOr, int fXor )
+{
+ int fPrint = 1;
+ int i, iLit;
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ while ( 1 )
+ {
+ for ( i = 1; i < nVars; i++ )
+ if ( pPerm[i-1] >= pPerm[i] )
+ break;
+ if ( i == nVars )
+ break;
+ assert( pPerm[i-1] >= pPerm[i] );
+ if ( pPerm[i-1] > pPerm[i] )
+ {
+ ABC_SWAP( int, pPerm[i-1], pPerm[i] );
+ ABC_SWAP( int, pVars[i-1], pVars[i] );
+ }
+ else
+ {
+ assert( pPerm[i-1] == pPerm[i] );
+ pPerm[i-1]++;
+ if ( fXor )
+ pVars[i-1] = Gia_ManHashXor( pNew, pVars[i-1], pVars[i] );
+ else if ( fOr )
+ pVars[i-1] = Gia_ManHashOr( pNew, pVars[i-1], pVars[i] );
+ else
+ pVars[i-1] = Gia_ManHashAnd( pNew, pVars[i-1], pVars[i] );
+ for ( i = i+1; i < nVars; i++ )
+ {
+ pPerm[i-1] = pPerm[i];
+ pVars[i-1] = pVars[i];
+ }
+ nVars--;
+ }
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ }
+ iLit = pVars[0];
+ for ( i = 1; i < nVars; i++ )
+ if ( fXor )
+ iLit = Gia_ManHashXor( pNew, iLit, pVars[i] );
+ else if ( fOr )
+ iLit = Gia_ManHashOr( pNew, iLit, pVars[i] );
+ else
+ iLit = Gia_ManHashAnd( pNew, iLit, pVars[i] );
+ return iLit;
+}
+Gia_Man_t * Gia_ManMultiInputTest( int nBits )
+{
+ Gia_Man_t * pNew;
+ int i, iRes, * pPerm;
+ int * pMulti = Gia_ManCollectLiterals( nBits );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "multi" );
+ for ( i = 0; i < nBits; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ pPerm = Gia_ManGenPerm2( nBits );
+ //pPerm = Gia_ManGenZero( nBits );
+ iRes = Gia_ManMultiInputPerm( pNew, pMulti, nBits, pPerm, 0, 0 );
+ Gia_ManAppendCo( pNew, iRes );
+ ABC_FREE( pPerm );
+ ABC_FREE( pMulti );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create MUX tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCube( Gia_Man_t * pNew, int Vars, int nVars, int * pLits )
+{
+ int i, iLit = 1;
+ for ( i = 0; i < nVars; i++ )
+ iLit = Gia_ManHashAnd( pNew, iLit, Abc_LitNotCond(pLits[i], !((Vars >> i) & 1)) );
+ return iLit;
+}
+int Gia_ManMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, int * pData )
+{
+ int iLit0, iLit1;
+ if ( nCtrl == 0 )
+ return pData[0];
+ iLit0 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData );
+ iLit1 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData + (1<<(nCtrl-1)) );
+ return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 );
+}
+void Gia_ManUsePerm( int * pTree, int nBits, int * pPerm )
+{
+ int fPrint = 0;
+ int i, k, m, nVars = nBits + (1 << nBits);
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ for ( i = 0; i < nBits; i++ )
+ {
+ for ( k = i+1; k < nBits; k++ )
+ if ( pPerm[i] > pPerm[k] )
+ break;
+ if ( k == nBits )
+ break;
+ assert( pPerm[i] > pPerm[k] );
+ ABC_SWAP( int, pPerm[i], pPerm[k] );
+ ABC_SWAP( int, pTree[i], pTree[k] );
+ for ( m = 0; m < (1 << nBits); m++ )
+ if ( ((m >> i) & 1) && !((m >> k) & 1) )
+ {
+ ABC_SWAP( int, pTree[nBits+m], pTree[nBits+(m^(1<<i)^(1<<k))] );
+ ABC_SWAP( int, pPerm[nBits+m], pPerm[nBits+(m^(1<<i)^(1<<k))] );
+ }
+ }
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+}
+int Gia_ManFindCond( int * pLits, int nBits, int iLate1, int iLate2 )
+{
+ int i;
+ assert( iLate1 != iLate2 );
+ for ( i = 0; i < nBits; i++ )
+ if ( (((iLate1 ^ iLate2) >> i) & 1) )
+ return Abc_LitNotCond( pLits[i], (iLate1 >> i) & 1 );
+ return -1;
+}
+int Gia_ManLatest( int * pPerm, int nVars, int iPrev1, int iPrev2, int iPrev3 )
+{
+ int i, Value = -1, iLate = -1;
+ for ( i = 0; i < nVars; i++ )
+ if ( Value < pPerm[i] && i != iPrev1 && i != iPrev2 && i != iPrev3 )
+ {
+ Value = pPerm[i];
+ iLate = i;
+ }
+ return iLate;
+}
+int Gia_ManEarliest( int * pPerm, int nVars )
+{
+ int i, Value = ABC_INFINITY, iLate = -1;
+ for ( i = 0; i < nVars; i++ )
+ if ( Value > pPerm[i] )
+ {
+ Value = pPerm[i];
+ iLate = i;
+ }
+ return iLate;
+}
+int Gia_ManDecompOne( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate )
+{
+ int iRes, iData;
+ assert( iLate >= 0 && iLate < (1<<nBits) );
+ iData = pTree[nBits+iLate];
+ pTree[nBits+iLate] = pTree[nBits+(iLate^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ return Gia_ManHashMux( pNew, Gia_ManCube(pNew, iLate, nBits, pTree), iData, iRes );
+}
+int Gia_ManDecompTwo( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2 )
+{
+ int iRes, iData1, iData2, iData, iCond, iCond2;
+ assert( iLate1 != iLate2 );
+ assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
+ assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
+ iData1 = pTree[nBits+iLate1];
+ iData2 = pTree[nBits+iLate2];
+ pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
+ pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ iCond = Gia_ManHashOr( pNew, Gia_ManCube(pNew, iLate1, nBits, pTree), Gia_ManCube(pNew, iLate2, nBits, pTree) );
+ iCond2 = Gia_ManFindCond( pTree, nBits, iLate1, iLate2 );
+ iData = Gia_ManHashMux( pNew, iCond2, iData2, iData1 );
+ return Gia_ManHashMux( pNew, iCond, iData, iRes );
+}
+int Gia_ManDecompThree( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2, int iLate3 )
+{
+ int iRes, iData1, iData2, iData3, iCube1, iCube2, iCube3, iCtrl0, iCtrl1, iMux10, iMux11;
+ assert( iLate1 != iLate2 );
+ assert( iLate1 != iLate3 );
+ assert( iLate2 != iLate3 );
+ assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
+ assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
+ assert( iLate3 >= 0 && iLate3 < (1<<nBits) );
+ iData1 = pTree[nBits+iLate1];
+ iData2 = pTree[nBits+iLate2];
+ iData3 = pTree[nBits+iLate3];
+ pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
+ pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
+ pTree[nBits+iLate3] = pTree[nBits+(iLate3^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ iCube1 = Gia_ManCube( pNew, iLate1, nBits, pTree );
+ iCube2 = Gia_ManCube( pNew, iLate2, nBits, pTree );
+ iCube3 = Gia_ManCube( pNew, iLate3, nBits, pTree );
+ iCtrl0 = Gia_ManHashOr( pNew, iCube1, iCube3 );
+ iCtrl1 = Gia_ManHashOr( pNew, iCube2, iCube3 );
+ iMux10 = Gia_ManHashMux( pNew, iCtrl0, iData1, iRes );
+ iMux11 = Gia_ManHashMux( pNew, iCtrl0, iData3, iData2 );
+ return Gia_ManHashMux( pNew, iCtrl1, iMux11, iMux10 );
+}
+int Gia_ManDecomp( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm )
+{
+ if ( nBits == 2 )
+ return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ else
+ {
+ int iBase = Gia_ManEarliest( pPerm+nBits, 1<<nBits ), BaseValue = pPerm[nBits+iBase];
+ int iLate1 = Gia_ManLatest( pPerm+nBits, 1<<nBits, -1, -1, -1 );
+ int iLate2 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, -1, -1 );
+ int iLate3 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, -1 );
+ int iLate4 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, iLate3 );
+ if ( 0 )
+ {
+ int i;
+ for ( i = 0; i < (1<<nBits); i++ )
+ printf( "%d ", pPerm[nBits+i] );
+ printf( "\n" );
+ }
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] > BaseValue && pPerm[nBits+iLate4] == BaseValue )
+ return Gia_ManDecompThree( pNew, pTree, nBits, pPerm, iLate1, iLate2, iLate3 );
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] == BaseValue )
+ return Gia_ManDecompTwo( pNew, pTree, nBits, pPerm, iLate1, iLate2 );
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] == BaseValue )
+ return Gia_ManDecompOne( pNew, pTree, nBits, pPerm, iLate1 );
+ return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ }
+}
+Gia_Man_t * Gia_ManMuxTreeTest( int nBits )
+{
+ Gia_Man_t * pNew;
+ int i, iLit, nVars = nBits + (1 << nBits);
+ int * pPerm, * pTree = Gia_ManCollectLiterals( nVars );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "mux_tree" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ pPerm = Gia_ManGenPerm( nVars );
+ //pPerm = Gia_ManGenZero( nVars );
+ pPerm[nBits+1] = 100;
+ pPerm[nBits+5] = 100;
+ pPerm[nBits+4] = 100;
+ Gia_ManUsePerm( pTree, nBits, pPerm );
+ iLit = Gia_ManDecomp( pNew, pTree, nBits, pPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ ABC_FREE( pPerm );
+ ABC_FREE( pTree );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 37ca6d4b..ae87277a 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -39,6 +39,8 @@ ABC_NAMESPACE_IMPL_START
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
extern int Abc_RecToGia3( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, Vec_Int_t * vLeaves, int fHash );
+extern void Gia_ManPrintGetMuxFanins( Gia_Man_t * p, Gia_Obj_t * pObj, int * pFanins );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -200,6 +202,7 @@ int Gia_ManLutLevel( Gia_Man_t * p, int ** ppLevels )
***********************************************************************/
void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * pnCurLevels )
{
+ int fDisable2Lut = 1;
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t *)p->pManTime) )
{
int i;
@@ -219,20 +222,37 @@ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * p
int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
*pnCurLuts = 0;
*pnCurEdges = 0;
+ *pnCurLevels = 0;
Gia_ManForEachLut( p, i )
{
- int Level = 0;
+ if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) )
+ {
+ int pFanins[3];
+ if ( Gia_ObjLutSize(p, i) == 3 )
+ {
+ Gia_ManPrintGetMuxFanins( p, Gia_ManObj(p, i), pFanins );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[0]]+1 );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[1]] );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[2]] );
+ }
+ else if ( Gia_ObjLutSize(p, i) == 2 )
+ {
+ pObj = Gia_ManObj( p, i );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId0(pObj, i)] );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId1(pObj, i)] );
+ }
+ *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] );
+ (*pnCurEdges)++;
+ //nMuxF++;
+ continue;
+ }
(*pnCurLuts)++;
(*pnCurEdges) += Gia_ObjLutSize(p, i);
Gia_LutForEachFanin( p, i, iFan, k )
- if ( Level < pLevels[iFan] )
- Level = pLevels[iFan];
- pLevels[i] = Level + 1;
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] );
+ pLevels[i]++;
+ *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] );
}
- *pnCurLevels = 0;
- Gia_ManForEachCo( p, pObj, k )
- if ( *pnCurLevels < pLevels[Gia_ObjFaninId0p(p, pObj)] )
- *pnCurLevels = pLevels[Gia_ObjFaninId0p(p, pObj)];
ABC_FREE( pLevels );
}
}
@@ -452,6 +472,7 @@ int Gia_ManCountDupLut( Gia_Man_t * p )
void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
{
+ int fDisable2Lut = 1;
Gia_Obj_t * pObj;
int * pLevels;
int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0, Ave = 0, nMuxF = 0;
@@ -460,7 +481,7 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
Gia_ManForEachLut( p, i )
{
- if ( Gia_ObjLutIsMux(p, i) )
+ if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) )
{
int pFanins[3];
if ( Gia_ObjLutSize(p, i) == 3 )
@@ -756,6 +777,43 @@ int Gia_ManChoiceLevel( Gia_Man_t * p )
}
+/**Function*************************************************************
+
+ Synopsis [Checks integrity of choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManCheckChoices_rec( If_Man_t * pIfMan, If_Obj_t * pIfObj )
+{
+ if ( !pIfObj || pIfObj->Type != IF_AND || pIfObj->fDriver )
+ return;
+ pIfObj->fDriver = 1;
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) );
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin1(pIfObj) );
+ If_ManCheckChoices_rec( pIfMan, pIfObj->pEquiv );
+}
+void If_ManCheckChoices( If_Man_t * pIfMan )
+{
+ If_Obj_t * pIfObj;
+ int i, fFound = 0;
+ If_ManForEachObj( pIfMan, pIfObj, i )
+ pIfObj->fDriver = 0;
+ If_ManForEachCo( pIfMan, pIfObj, i )
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) );
+ If_ManForEachNode( pIfMan, pIfObj, i )
+ if ( !pIfObj->fDriver )
+ printf( "Object %d is dangling.\n", i ), fFound = 1;
+ if ( !fFound )
+ printf( "There are no dangling objects.\n" );
+ If_ManForEachObj( pIfMan, pIfObj, i )
+ pIfObj->fDriver = 0;
+}
+
/**Function*************************************************************
@@ -824,6 +882,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars )
}
if ( Gia_ManHasChoices(p) )
Gia_ManCleanMark0( p );
+ //If_ManCheckChoices( pIfMan );
return pIfMan;
}
@@ -1987,6 +2046,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
pFile = fopen( Buffer, "wb" );
if ( pFile == NULL )
{
+ Vec_StrFree( vConfigsStr );
printf( "Cannot open file \"%s\".\n", Buffer );
return pNew;
}
@@ -2162,10 +2222,11 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
p->DefOutReqs = pGia->DefOutReqs;
p->And2Delay = pGia->And2Delay;
}
- if ( pGia->vNamesIn || pGia->vNamesOut )
+ if ( pGia->vNamesIn || pGia->vNamesOut || pGia->vNamesNode )
{
p->vNamesIn = pGia->vNamesIn; pGia->vNamesIn = NULL;
p->vNamesOut = pGia->vNamesOut; pGia->vNamesOut = NULL;
+ p->vNamesNode = pGia->vNamesNode; pGia->vNamesNode = NULL;
}
if ( pGia->vConfigs || pGia->pCellStr )
{
@@ -2357,6 +2418,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
// transfer name
assert( pNew->pName == NULL );
pNew->pName = Abc_UtilStrsav( p->pName );
+ ABC_FREE( pNew->pSpec );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
// print delay trace
diff --git a/src/aig/gia/giaIso.c b/src/aig/gia/giaIso.c
index 76419e93..fcfa3448 100644
--- a/src/aig/gia/giaIso.c
+++ b/src/aig/gia/giaIso.c
@@ -894,7 +894,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
Vec_PtrClear( vTemp );
Gia_ManForEachPi( p, pObj, i )
Vec_PtrPush( vTemp, pObj );
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
// create the result
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
Vec_IntPush( vCis, Gia_ObjId(p, pObj) );
@@ -917,7 +917,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
pObj->Value = Abc_Var2Lit( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) );
Vec_PtrPush( vTemp, pObj );
}
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
Vec_IntPush( vCos, Gia_ObjId(p, pObj) );
}
@@ -926,7 +926,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
Vec_PtrClear( vTemp );
Gia_ManForEachRo( p, pObj, i )
Vec_PtrPush( vTemp, pObj );
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
// create the result
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
{
diff --git a/src/aig/gia/giaIso2.c b/src/aig/gia/giaIso2.c
index 576b118f..22b1d09e 100644
--- a/src/aig/gia/giaIso2.c
+++ b/src/aig/gia/giaIso2.c
@@ -328,7 +328,7 @@ int Gia_Iso2ManUniqify( Gia_Iso2Man_t * p )
}
Vec_IntShrink( p->vTied, k );
// sort singletons
- Vec_PtrSort( p->vSingles, (int (*)(void))Gia_ObjCompareByValue2 );
+ Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Gia_ObjCompareByValue2 );
// add them to unique and increment signature
Vec_PtrForEachEntry( Gia_Obj_t *, p->vSingles, pObj, i )
{
diff --git a/src/aig/gia/giaIso3.c b/src/aig/gia/giaIso3.c
index a88a0569..8bea4bbf 100644
--- a/src/aig/gia/giaIso3.c
+++ b/src/aig/gia/giaIso3.c
@@ -158,6 +158,97 @@ void Gia_Iso3Test( Gia_Man_t * p )
Vec_IntFreeP( &vSign );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
+{
+ Vec_Wec_t * vLevs = Gia_ManLevelizeR( p );
+ Vec_Int_t * vLevel; int l;
+ Abc_Random( 1 );
+ Vec_WecForEachLevel( vLevs, vLevel, l )
+ {
+ Gia_Obj_t * pObj; int i;
+ int RandC[2] = { Abc_Random(0), Abc_Random(0) };
+ if ( l == 0 )
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ {
+ assert( Gia_ObjIsCo(pObj) );
+ pObj->Value = Abc_Random(0);
+ Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
+ }
+ }
+ else
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i ) if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
+ Gia_ObjFanin1(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC1(pObj)];
+ }
+ }
+ }
+ return vLevs;
+}
+void Gia_Iso4Test( Gia_Man_t * p )
+{
+ Vec_Wec_t * vLevs = Gia_Iso4Gia( p );
+ Vec_Int_t * vLevel; int l;
+ Vec_WecForEachLevel( vLevs, vLevel, l )
+ {
+ Gia_Obj_t * pObj; int i;
+ printf( "Level %d\n", l );
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ printf( "Obj = %5d. Value = %08x.\n", Gia_ObjId(p, pObj), pObj->Value );
+ }
+ Vec_WecFree( vLevs );
+}
+Vec_Int_t * Gia_IsoCollectData( Gia_Man_t * p, Vec_Int_t * vObjs )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vData = Vec_IntAlloc( Vec_IntSize(vObjs) );
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ Vec_IntPush( vData, pObj->Value );
+ return vData;
+}
+void Gia_IsoCompareVecs( Gia_Man_t * pGia0, Vec_Wec_t * vLevs0, Gia_Man_t * pGia1, Vec_Wec_t * vLevs1 )
+{
+ int i, Common, nLevels = Abc_MinInt( Vec_WecSize(vLevs0), Vec_WecSize(vLevs1) );
+ Gia_ManPrintStats( pGia0, NULL );
+ Gia_ManPrintStats( pGia1, NULL );
+ printf( "Printing %d shared levels:\n", nLevels );
+ for ( i = 0; i < nLevels; i++ )
+ {
+ Vec_Int_t * vLev0 = Vec_WecEntry(vLevs0, i);
+ Vec_Int_t * vLev1 = Vec_WecEntry(vLevs1, i);
+ Vec_Int_t * vData0 = Gia_IsoCollectData( pGia0, vLev0 );
+ Vec_Int_t * vData1 = Gia_IsoCollectData( pGia1, vLev1 );
+ Vec_IntSort( vData0, 0 );
+ Vec_IntSort( vData1, 0 );
+ Common = Vec_IntTwoCountCommon( vData0, vData1 );
+ printf( "Level = %3d. One = %6d. Two = %6d. Common = %6d.\n",
+ i, Vec_IntSize(vData0)-Common, Vec_IntSize(vData1)-Common, Common );
+ Vec_IntFree( vData0 );
+ Vec_IntFree( vData1 );
+ }
+}
+void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 )
+{
+ Vec_Wec_t * vLevs0 = Gia_Iso4Gia( pGia0 );
+ Vec_Wec_t * vLevs1 = Gia_Iso4Gia( pGia1 );
+ Gia_IsoCompareVecs( pGia0, vLevs0, pGia1, vLevs1 );
+ Vec_WecFree( vLevs0 );
+ Vec_WecFree( vLevs1 );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index 4ca9bfa4..a40673a7 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -81,8 +81,6 @@ Gia_Man_t * Gia_ManStart( int nObjsMax )
***********************************************************************/
void Gia_ManStop( Gia_Man_t * p )
{
- extern void Gia_DatFree( Gia_Dat_t * p );
- Gia_DatFree( p->pUData );
if ( p->vSeqModelVec )
Vec_PtrFreeFree( p->vSeqModelVec );
Gia_ManStaticFanoutStop( p );
@@ -90,11 +88,14 @@ void Gia_ManStop( Gia_Man_t * p )
assert( p->pManTime == NULL );
Vec_PtrFreeFree( p->vNamesIn );
Vec_PtrFreeFree( p->vNamesOut );
+ Vec_PtrFreeFree( p->vNamesNode );
Vec_IntFreeP( &p->vSwitching );
Vec_IntFreeP( &p->vSuper );
Vec_IntFreeP( &p->vStore );
Vec_IntFreeP( &p->vClassNew );
Vec_IntFreeP( &p->vClassOld );
+ Vec_IntFreeP( &p->vPats );
+ Vec_BitFreeP( &p->vPolars );
Vec_WrdFreeP( &p->vSims );
Vec_WrdFreeP( &p->vSimsT );
Vec_WrdFreeP( &p->vSimsPi );
@@ -129,6 +130,7 @@ void Gia_ManStop( Gia_Man_t * p )
Vec_IntFreeP( &p->vVar2Obj );
Vec_IntErase( &p->vCopiesTwo );
Vec_IntErase( &p->vSuppVars );
+ Vec_IntErase( &p->vVarMap );
Vec_WrdFreeP( &p->vSuppWords );
Vec_IntFreeP( &p->vTtNums );
Vec_IntFreeP( &p->vTtNodes );
@@ -147,6 +149,7 @@ void Gia_ManStop( Gia_Man_t * p )
Vec_IntFreeP( &p->vCoReqs );
Vec_IntFreeP( &p->vCoArrs );
Vec_IntFreeP( &p->vCoAttrs );
+ Vec_IntFreeP( &p->vWeights );
Gia_ManStopP( &p->pAigExtra );
Vec_IntFree( p->vCis );
Vec_IntFree( p->vCos );
@@ -201,6 +204,7 @@ double Gia_ManMemory( Gia_Man_t * p )
Memory += Vec_FltMemory( p->vOutReqs );
Memory += Vec_PtrMemory( p->vNamesIn );
Memory += Vec_PtrMemory( p->vNamesOut );
+ Memory += Vec_PtrMemory( p->vNamesNode );
return Memory;
}
@@ -582,7 +586,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars )
Gia_ManPrintMappingStats( p, pPars ? pPars->pDumpFile : NULL );
else if ( pPars && pPars->pDumpFile )
Gia_ManLogAigStats( p, pPars->pDumpFile );
- if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) && Gia_ManLutSizeMax(p) <= 4 )
+ if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) )
Gia_ManPrintNpnClasses( p );
if ( p->vPacking )
Gia_ManPrintPackingStats( p );
@@ -1269,13 +1273,14 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta
fFirst = 0;
}
}
-void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
+void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs )
{
FILE * pFile;
Gia_Obj_t * pObj;
Vec_Bit_t * vInvs, * vUsed;
- int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
- int nDigits2 = Abc_Base10Log( Gia_ManPiNum(p) );
+ int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
+ int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
+ int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
int i, k, iObj;
if ( Gia_ManRegNum(p) )
{
@@ -1300,20 +1305,63 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
fprintf( pFile, "%c", p->pName[i] );
else
fprintf( pFile, "_" );
- fprintf( pFile, " (\n " );
- Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
- fprintf( pFile, ",\n " );
- Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
- fprintf( pFile, "\n );\n\n" );
+ if ( fVerBufs )
+ {
+ fprintf( pFile, " (\n " );
+ Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL );
+ fprintf( pFile, ",\n " );
+
+ Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL );
+ fprintf( pFile, "\n );\n\n" );
+
+ fprintf( pFile, " input " );
+ Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " output " );
+ Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " wire " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
- fprintf( pFile, " input " );
- Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
- fprintf( pFile, ";\n\n" );
+ fprintf( pFile, " wire " );
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
- fprintf( pFile, " output " );
- Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
- fprintf( pFile, ";\n\n" );
+ Gia_ManForEachPi( p, pObj, i )
+ {
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'a', i, nDigitsI) );
+ }
+ fprintf( pFile, "\n" );
+
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'y', i, nDigitsO) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
+ }
+ fprintf( pFile, "\n" );
+ }
+ else
+ {
+ fprintf( pFile, " (\n " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
+ fprintf( pFile, ",\n " );
+
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
+ fprintf( pFile, "\n );\n\n" );
+
+ fprintf( pFile, " input " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " output " );
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+ }
if ( Vec_BitCount(vUsed) )
{
@@ -1337,7 +1385,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
fprintf( pFile, ";\n\n" );
Vec_IntForEachEntry( vObjs, iObj, i )
{
- fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
fprintf( pFile, " t_%d );\n", i );
}
fprintf( pFile, "\n" );
@@ -1348,13 +1396,13 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
{
if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
{
- fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
- fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
}
if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
{
- fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
- fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
+ fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
}
}
@@ -1373,20 +1421,19 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
}
if ( !fSkip )
{
- fprintf( pFile, " and( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
+ fprintf( pFile, " and ( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
fprintf( pFile, " %s,", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
}
if ( Vec_BitEntry(vInvs, i) )
{
- fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
+ fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
}
}
// output drivers
fprintf( pFile, "\n" );
- nDigits2 = Abc_Base10Log( Gia_ManPoNum(p) );
Gia_ManForEachPo( p, pObj, i )
{
/*
@@ -1396,7 +1443,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
else
fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
*/
- fprintf( pFile, " buf( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigits2) );
+ fprintf( pFile, " buf ( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) );
else
diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c
index 7e699d9b..e732f25e 100644
--- a/src/aig/gia/giaMf.c
+++ b/src/aig/gia/giaMf.c
@@ -24,6 +24,7 @@
#include "misc/extra/extra.h"
#include "sat/cnf/cnf.h"
#include "opt/dau/dau.h"
+#include "bool/kit/kit.h"
ABC_NAMESPACE_IMPL_START
@@ -557,8 +558,8 @@ static inline int Mf_CutComputeTruth6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t
assert( (int)(t & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, &t);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
// p->nCutMux += Mf_ManTtIsMux( t );
assert( (int)pCutR->nLeaves <= nOldSupp );
// Mf_ManTruthCanonicize( &t, pCutR->nLeaves );
@@ -588,8 +589,8 @@ static inline int Mf_CutComputeTruth( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t *
//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -612,8 +613,8 @@ static inline int Mf_CutComputeTruthMux6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut
assert( (int)(t & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, &t);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -642,8 +643,8 @@ static inline int Mf_CutComputeTruthMux( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_
assert( (uTruth[0] & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -699,6 +700,8 @@ static inline void Mf_CutPrint( Mf_Man_t * p, Mf_Cut_t * pCut )
{
if ( p->pPars->fGenCnf )
printf( "CNF = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
+ if ( p->pPars->fGenLit )
+ printf( "Lit = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
Dau_DsdPrintFromTruth( Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)), pCut->nLeaves );
}
else
@@ -998,7 +1001,7 @@ static inline int Mf_CutArea( Mf_Man_t * p, int nLeaves, int iFunc )
{
if ( nLeaves < 2 )
return 0;
- if ( p->pPars->fGenCnf )
+ if ( p->pPars->fGenCnf || p->pPars->fGenLit )
return Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(iFunc));
if ( p->pPars->fOptEdge )
return nLeaves + p->pPars->nAreaTuner;
@@ -1202,7 +1205,7 @@ int Mf_ManSetMapRefs( Mf_Man_t * p )
Mf_ObjMapRefInc( p, pCut[k] );
p->pPars->Edge += Mf_CutSize(pCut);
p->pPars->Area++;
- if ( p->pPars->fGenCnf )
+ if ( p->pPars->fGenCnf || p->pPars->fGenLit )
p->pPars->Clause += Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
}
// blend references
@@ -1394,7 +1397,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
p->pLfObjs = ABC_CALLOC( Mf_Obj_t, Gia_ManObjNum(pGia) );
p->iCur = 2;
Vec_PtrGrow( &p->vPages, 256 );
- if ( pPars->fGenCnf )
+ if ( pPars->fGenCnf || pPars->fGenLit )
{
Vec_IntGrow( &p->vCnfSizes, 10000 );
Vec_IntPush( &p->vCnfSizes, 1 );
@@ -1410,7 +1413,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
}
void Mf_ManFree( Mf_Man_t * p )
{
- assert( !p->pPars->fGenCnf || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
+ assert( !p->pPars->fGenCnf || !p->pPars->fGenLit || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
if ( p->pPars->fCutMin )
Vec_MemHashFree( p->vTtMem );
if ( p->pPars->fCutMin )
@@ -1453,6 +1456,7 @@ void Mf_ManSetDefaultPars( Jf_Par_t * pPars )
pPars->fCoarsen = 1;
pPars->fCutMin = 0;
pPars->fGenCnf = 0;
+ pPars->fGenLit = 0;
pPars->fPureAig = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
@@ -1469,6 +1473,8 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle )
printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
printf( "CNF =%9lu ", (long)p->pPars->Clause );
+ if ( p->pPars->fGenLit )
+ printf( "FFL =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@@ -1483,6 +1489,7 @@ void Mf_ManPrintInit( Mf_Man_t * p )
printf( "CutMin = %d ", p->pPars->fCutMin );
printf( "Coarse = %d ", p->pPars->fCoarsen );
printf( "CNF = %d ", p->pPars->fGenCnf );
+ printf( "FFL = %d ", p->pPars->fGenLit );
printf( "\n" );
printf( "Computing cuts...\r" );
fflush( stdout );
@@ -1541,51 +1548,97 @@ void Mf_ManComputeCuts( Mf_Man_t * p )
SeeAlso []
***********************************************************************/
-int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
+int Mf_CutRef_rec( Mf_Man_t * p, int * pCut )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
- if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
- {
- Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
- }
+ Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) );
return Count;
}
-static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
+int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut )
{
- int Ela1, iObj, i;
- Vec_IntClear( &p->vTemp );
- Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
- Vec_IntForEachEntry( &p->vTemp, iObj, i )
- Mf_ObjMapRefDec( p, iObj );
+ int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
+ Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ return Count;
+}
+static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut )
+{
+ int Ela1 = Mf_CutDeref_rec( p, pCut );
+ int Ela2 = Mf_CutRef_rec( p, pCut );
+ assert( Ela1 == Ela2 );
+ return Ela1;
+}
+static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
+{
+ int Ela1 = Mf_CutRef_rec( p, pCut );
+ int Ela2 = Mf_CutDeref_rec( p, pCut );
+ assert( Ela1 == Ela2 );
return Ela1;
}
+static inline int Mf_CutAreaMffc( Mf_Man_t * p, int iObj )
+{
+ return Mf_ObjMapRefNum(p, iObj) ?
+ Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) :
+ Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj));
+}
-int Mf_CutRef_rec( Mf_Man_t * p, int * pCut )
+int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ {
+ Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
+ }
return Count;
}
-int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut )
+int Mf_CutDeref2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ {
+ Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ Count += Mf_CutDeref2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
+ }
return Count;
}
-static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
+static inline int Mf_CutAreaRefed2( Mf_Man_t * p, int * pCut )
{
- int Ela1 = Mf_CutRef_rec( p, pCut );
- int Ela2 = Mf_CutDeref_rec( p, pCut );
- assert( Ela1 == Ela2 );
+ int Ela1, iObj, i;
+ Vec_IntClear( &p->vTemp );
+ Ela1 = Mf_CutDeref2_rec( p, pCut, &p->vTemp, 8 );
+ Vec_IntForEachEntry( &p->vTemp, iObj, i )
+ Mf_ObjMapRefInc( p, iObj );
return Ela1;
}
+static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
+{
+ int Ela1, iObj, i;
+ Vec_IntClear( &p->vTemp );
+ Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
+ Vec_IntForEachEntry( &p->vTemp, iObj, i )
+ Mf_ObjMapRefDec( p, iObj );
+ return Ela1;
+}
+static inline int Mf_CutAreaRefed2Multi( Mf_Man_t * p, int iObj, int ** ppCuts, int nCuts )
+{
+ int Ela1 = 0, iTemp, i;
+ Vec_IntClear( &p->vTemp );
+ for ( i = 0; i < nCuts; i++ )
+ Ela1 += Mf_CutDeref2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY );
+ assert( Mf_ObjMapRefNum(p, iObj) == 0 );
+ Vec_IntForEachEntry( &p->vTemp, iTemp, i )
+ Mf_ObjMapRefInc( p, iTemp );
+ return Ela1;
+}
+
static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime )
{
Mf_Obj_t * pObj;
@@ -1635,6 +1688,120 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Mf_ManMappingFromMapping( Mf_Man_t * p )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ Gia_Obj_t * pObj;
+ int i, iObj, Count = 0;
+ Vec_Int_t * vMapping = Vec_IntAlloc( 3 * Gia_ManObjNum(pGia) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pGia), 0 );
+ Gia_ManForEachAnd( pGia, pObj, iObj )
+ if ( Mf_ObjMapRefNum(p, iObj) )
+ {
+ int * pCut = Mf_ObjCutBest(p, iObj);
+ Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Mf_CutSize(pCut) );
+ for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ Vec_IntPush( vMapping, pCut[i] );
+ Vec_IntPush( vMapping, iObj );
+ Count++;
+ }
+ assert( pGia->vMapping == NULL );
+ pGia->vMapping = vMapping;
+ printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(pGia) );
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Mf_ManPrintFanoutProfile( Mf_Man_t * p, Vec_Int_t * vFanCounts )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int i, Count, nMax = Vec_IntFindMax( vFanCounts );
+ Vec_Int_t * vCounts = Vec_IntStart( nMax + 1 );
+ Vec_IntForEachEntry( vFanCounts, Count, i )
+ if ( Count && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
+ Vec_IntAddToEntry( vCounts, Count, 1 );
+ printf( "\nFanout distribution for internal nodes:\n" );
+ Vec_IntForEachEntry( vCounts, Count, i )
+ if ( Count ) printf( "Fanout = %5d : Nodes = %5d.\n", i, Count );
+ printf( "Total nodes with fanout = %d. Max fanout = %d.\n\n", Vec_IntCountPositive(vCounts), nMax );
+ Vec_IntFree( vCounts );
+}
+int Mf_ManPrintMfccStats( Mf_Man_t * p, int iObj )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int Area;
+ printf( "%5d : Level = %5d Refs = %5d Mffc = %5d\n",
+ iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), (Area = Mf_CutAreaMffc(p, iObj)) );
+ return Area;
+}
+void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int * ppCuts[32], nCuts = 0;
+ int iFanout, i, nAreaSum = 0, nAreaBest = 0;
+ // skip pivots whose MFFC fanouts are pointed to by COs
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ if ( Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) )
+ return;
+ // the pivot is used in the mapping as well as all of its fanouts
+ assert( Mf_ObjMapRefNum(p, iObj) > 1 );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ assert( Mf_ObjMapRefNum(p, iFanout) > 0 );
+ // print this pivot and its fanouts
+ printf( "\nPivot node = %d\n", iObj );
+ printf( "Pivot " ), Mf_ManPrintMfccStats( p, iObj );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ printf( "Node " ), nAreaSum += Mf_ManPrintMfccStats( p, iFanout );
+ // calculate the shared MFFC
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ Mf_ObjMapRefInc( p, iFanout );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ ppCuts[nCuts++] = Mf_ObjCutBest( p, iFanout );
+ nAreaBest = Mf_CutAreaRefed2Multi( p, iObj, ppCuts, nCuts );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ Mf_ObjMapRefDec( p, iFanout );
+ printf( "Sum of MFFC sizes = %d\n", nAreaSum );
+ printf( "Shared MFFC size = %d\n", nAreaBest );
+}
+void Mf_ManOptimization( Mf_Man_t * p )
+{
+ int nOutMax = 3;
+ Gia_Man_t * pGia = p->pGia0;
+ int i, Count, nNodes = Mf_ManMappingFromMapping( p );
+ Gia_ManLevelNum( pGia );
+ Gia_ManStaticMappingFanoutStart( pGia );
+ Mf_ManPrintFanoutProfile( p, pGia->vFanoutNums );
+ printf( "\nIndividual logic cones for mapping with %d nodes:\n", nNodes );
+ Vec_IntForEachEntry( pGia->vFanoutNums, Count, i )
+ if ( Count >= 2 && Count <= nOutMax && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
+ Mf_ManOptimizationOne( p, i );
+ printf( "\nFinished printing individual logic cones.\n" );
+ Gia_ManStaticFanoutStop( pGia );
+ Vec_IntFreeP( &pGia->vMapping );
+}
+
+/**Function*************************************************************
+
Synopsis [Technology mappping.]
Description []
@@ -1656,7 +1823,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
{
Mf_Man_t * p;
Gia_Man_t * pNew, * pCls;
- if ( pPars->fGenCnf )
+ if ( pPars->fGenCnf || pPars->fGenLit )
pPars->fCutMin = 1;
if ( Gia_ManHasChoices(pGia) )
pPars->fCutMin = 1, pPars->fCoarsen = 0;
@@ -1675,6 +1842,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
p->fUseEla = 1;
for ( ; p->Iter < p->pPars->nRounds + pPars->nRoundsEla; p->Iter++ )
Mf_ManComputeMapping( p );
+ //Mf_ManOptimization( p );
if ( pPars->fVeryVerbose && pPars->fCutMin )
Vec_MemDumpTruthTables( p->vTtMem, Gia_ManName(p->pGia), pPars->nLutSize );
if ( pPars->fCutMin )
@@ -1685,8 +1853,8 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
pNew = Mf_ManDeriveMapping( p );
if ( p->pPars->fGenCnf )
pGia->pData = Mf_ManDeriveCnf( p, p->pPars->fCnfObjIds, p->pPars->fAddOrCla );
-// if ( p->pPars->fGenCnf )
-// Mf_ManProfileTruths( p );
+ //if ( p->pPars->fGenCnf || p->pPars->fGenLit )
+ // Mf_ManProfileTruths( p );
Gia_ManMappingVerify( pNew );
Mf_ManPrintQuit( p, pNew );
Mf_ManFree( p );
diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c
new file mode 100644
index 00000000..5304486d
--- /dev/null
+++ b/src/aig/gia/giaMinLut.c
@@ -0,0 +1,1058 @@
+/**CFile****************************************************************
+
+ FileName [giaMinLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Collapsing AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "base/main/mainInt.h"
+#include "opt/sfm/sfm.h"
+
+#ifdef ABC_USE_CUDD
+#include "bdd/extrab/extraBdd.h"
+#include "bdd/dsd/dsd.h"
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Vec_WrdReadLayerText( char * pFileName, int * pnIns, int * pnOuts )
+{
+ char * pThis, pLine[1000];
+ Vec_Wec_t * vRes; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vRes = Vec_WecAlloc(100);
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ if ( iLine == 0 )
+ {
+ pThis = strstr( pLine, "[" );
+ *pnIns = atoi( pThis+1 ) + 1;
+ pThis = strstr( pThis+1, "[" );
+ *pnOuts = atoi( pThis+1 ) + 1;
+ }
+ else
+ {
+ Vec_Int_t * vLevel = NULL;
+ for ( pThis = pLine; (pThis = strstr(pThis, "M0[")); pThis++ )
+ {
+ if ( vLevel == NULL )
+ vLevel = Vec_WecPushLevel( vRes );
+ Vec_IntPush( vLevel, atoi( pThis+3 ) );
+ }
+ if ( vLevel )
+ Vec_IntReverseOrder( vLevel );
+ }
+ }
+ fclose( pFile );
+ //Vec_WecPrint( vRes, 0 );
+ return vRes;
+}
+int Vec_WrdReadTruthTextOne( char * pFileName, int nIns, int nOuts, word * pRes )
+{
+ int i, nWords = Abc_TtWordNum( nIns );
+ char * pStart, * pBuffer = Extra_FileReadContents( pFileName );
+ if ( pBuffer == NULL )
+ {
+ printf( "Cannot read file \"%s\".\n", pFileName );
+ return 0;
+ }
+ pStart = pBuffer;
+ for ( i = 0; i < nOuts; i++ )
+ {
+ pStart = strstr( pStart + 1, "0x" );
+ if ( !Extra_ReadHex( (unsigned *)(pRes + i*nWords), pStart + 2, nWords*16 ) )
+ {
+ printf( "Cannot read truth table %d (out of %d) in file \"%s\".\n", i, nOuts, pFileName );
+ ABC_FREE( pBuffer );
+ return 0;
+ }
+ }
+ ABC_FREE( pBuffer );
+ return 1;
+}
+word * Vec_WrdReadTruthText( char * pFileName, int nIns, int nOuts, int nFiles )
+{
+ char FileName[1000];
+ int i, nWords = Abc_TtWordNum( nIns );
+ word * pRes = ABC_CALLOC( word, nOuts*nFiles*nWords );
+ for ( i = 0; i < nFiles; i++ )
+ {
+ assert( strlen(pFileName) < 900 );
+ strcpy( FileName, pFileName );
+ sprintf( FileName + strlen(FileName) - 2, "_N%d.bench", i );
+ if ( !Vec_WrdReadTruthTextOne( FileName, nIns, nOuts, pRes + i*nOuts*nWords ) )
+ {
+ ABC_FREE( pRes );
+ return NULL;
+ }
+ }
+ return pRes;
+}
+Gia_Man_t * Vec_WrdReadTest( char * pFileName )
+{
+ extern int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ Gia_Man_t * pPart, * pNew = NULL; Gia_Obj_t * pObj;
+ int i, k, nIns, nOuts, iLit;
+ Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts );
+ int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0;
+ int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0;
+ int nWords = Abc_TtWordNum(nBitsI);
+ word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL;
+ Vec_Int_t * vPart, * vLits = Vec_IntAlloc( nOuts );
+ if ( vRes == NULL || pFuncs == NULL )
+ {
+ Vec_WecFreeP( &vRes );
+ Vec_IntFreeP( &vLits );
+ ABC_FREE( pFuncs );
+ return NULL;
+ }
+ assert( nOuts % Vec_WecSize(vRes) == 0 );
+ pNew = Gia_ManStart( 10000 );
+ pNew->pName = Abc_UtilStrsav( pFileName );
+ pNew->pSpec = NULL;
+ for ( i = 0; i < nIns; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashStart( pNew );
+ Vec_WecForEachLevel( vRes, vPart, i )
+ {
+ assert( Vec_IntSize(vPart) <= nBitsI );
+ pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 20, 0 );
+ Gia_ManFillValue( pPart );
+ Gia_ManConst0(pPart)->Value = 0;
+ Gia_ManForEachCi( pPart, pObj, k )
+ pObj->Value = Abc_Var2Lit( 1+Vec_IntEntry(vPart, k), 0 );
+ Gia_ManForEachCo( pPart, pObj, k )
+ {
+ Gia_ManPerformLNetOpt_rec( pNew, pPart, Gia_ObjFanin0(pObj) );
+ Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManStop( pPart );
+ }
+ Gia_ManHashStop( pNew );
+ Vec_IntForEachEntry( vLits, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ ABC_FREE( pFuncs );
+ Vec_WecFree( vRes );
+ Vec_IntFree( vLits );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts )
+{
+ int i, nSize, iLine, nLines, nWords;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI, * vSimO;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + nOuts + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + nOuts + 1) );
+ fclose( pFile );
+ return;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + nOuts + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ for ( i = 0; i < nOuts; i++ )
+ if ( pLine[nIns+nOuts-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ else assert( pLine[nIns+nOuts-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ *pvSimO = vSimO;
+ printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines );
+}
+int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
+{
+ int i, nSize, iLine, nLines, nWords, nIns;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return 0;
+ }
+ if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 )
+ {
+ printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName );
+ fclose( pFile );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + 1) );
+ fclose( pFile );
+ return 0;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ printf( "Read %d words of simulation data for %d inputs (padded to 64-bit boundary with %d zero-patterns).\n", nWords, nIns, nWords*64-nLines );
+ return nIns;
+}
+Vec_Int_t * Vec_WrdReadNumsOut( char * pFileName, int fVerbose )
+{
+ char pLine[1000];
+ Vec_Int_t * vNums; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vNums = Vec_IntAlloc( 1000 );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ Vec_IntPush( vNums, atoi(pLine) );
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Finished reading %d output values from file \"%s\".\n", Vec_IntSize(vNums), pFileName );
+ return vNums;
+}
+Vec_Wrd_t * Vec_WrdReadTextOut( char * pFileName, int nOuts )
+{
+ int i, iLine, nLines, nWords;
+ Vec_Wrd_t * vSimO;
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName, 1 );
+ if ( vNums == NULL )
+ return NULL;
+ nLines = Vec_IntSize(vNums);
+ nWords = (nLines + 63)/64;
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ Vec_IntForEachEntry( vNums, i, iLine )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ Vec_IntFree( vNums );
+ printf( "Read %d words of simulation data for %d outputs (padded %d zero-patterns).\n", nWords, nOuts, nWords*64-nLines );
+ return vSimO;
+}
+void Gia_ManReadSimInfoInputs( char * pFileName, char * pFileOut1, int fVerbose )
+{
+ Vec_Wrd_t * vSimI;
+ Vec_WrdReadText2( pFileName, &vSimI );
+ Vec_WrdDumpBin( pFileOut1, vSimI, fVerbose );
+ Vec_WrdFree( vSimI );
+}
+void Gia_ManReadSimInfoOutputs( char * pFileName, char * pFileOut, int nOuts )
+{
+ Vec_Wrd_t * vSimO = Vec_WrdReadTextOut( pFileName, nOuts );
+ Vec_WrdDumpBin( pFileOut, vSimO, 1 );
+ Vec_WrdFree( vSimO );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Vec_WrdZoneExtract( int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(p)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ Vec_Wrd_t * pNew = Vec_WrdStart( nZones*nWords );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*nWords + w, Vec_WrdEntry(p, z*ZoneSize + iWord + w) );
+ return pNew;
+}
+void Vec_WrdZoneInsert( Vec_Wrd_t * pNew, int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(pNew)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*ZoneSize + iWord + w, Vec_WrdEntry(p, z*nWords + w) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimInfoPrintOne( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nWords, int nPats )
+{
+ int Id, i, k;
+ for ( k = 0; k < nPats; k++ )
+ {
+ Gia_ManForEachCiId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 );
+ printf( " " );
+ Gia_ManForEachCoId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 );
+ printf( "\n" );
+ }
+}
+Vec_Wrd_t * Gia_ManSimInfoTryOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int fPrint )
+{
+ extern Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn );
+ Vec_Wrd_t * vSimsOut = Gia_ManSimulateWordsOut( p, vSimI );
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ assert( Vec_WrdSize(vSimI) % Gia_ManCiNum(p) == 0 );
+ if ( fPrint )
+ Gia_ManSimInfoPrintOne( p, vSimI, vSimsOut, nWords, 6 );
+ return vSimsOut;
+}
+int Gia_ManSimEvalOne( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords );
+ }
+ Count = Abc_TtCountOnesVec( pSim0, nWords );
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords), 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalOne2( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtXor( pSim0, pSimImpl, pSimGold, nWords, 0 );
+ Count += Abc_TtCountOnesVec( pSim0, nWords );
+ }
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords*Gia_ManCoNum(p)), 64*nWords*Gia_ManCoNum(p), Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalMaxValue( Vec_Wrd_t * vSimO, int nWords, int nOuts, int nBits, int iPat )
+{
+ int o, ValueMax = -1, OutMax = -1;
+ for ( o = 0; o < nOuts; o++ )
+ {
+ int i, Value = 0;
+ for ( i = 0; i < nBits; i++ )
+ {
+ word * pSim = Vec_WrdEntryP( vSimO, (o*nBits+i) * nWords );
+ if ( Abc_TtGetBit(pSim, iPat) )
+ Value |= 1 << i;
+ }
+ if ( ValueMax <= Value )
+ {
+ ValueMax = Value;
+ OutMax = o;
+ }
+ }
+ return OutMax;
+}
+int Gia_ManSimEvalOne3( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Int_t * vValues, int nBits )
+{
+ int i, Value, nOuts = Gia_ManCoNum(p) / nBits;
+ int First = -1, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ assert( Gia_ManCoNum(p) % nBits == 0 );
+ assert( 64*(nWords-1) < Vec_IntSize(vValues) && Vec_IntSize(vValues) <= 64*nWords );
+ Vec_IntForEachEntry( vValues, Value, i )
+ if ( Value == Gia_ManSimEvalMaxValue(vSimO, nWords, nOuts, nBits, i) )
+ {
+ Count++;
+ if ( First == -1 )
+ First = i;
+ }
+ printf( "The accuracy is %8.4f %% (%d out of %d output are correct, for example, output number %d).\n",
+ 100.0*Count/Vec_IntSize(vValues), Count, Vec_IntSize(vValues), First );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f \n", 100.0*Count/Vec_IntSize(vValues) );
+ fclose( pTable );
+ }
+ return Count;
+}
+Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI )
+{
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int w, nWordsOne = 200, nWordBatches = (nWords + nWordsOne - 1)/nWordsOne;
+ Vec_Wrd_t * vSimO_new = Vec_WrdStart( nWords * Gia_ManCoNum(p) );
+ for ( w = 0; w < nWordBatches; w++ )
+ {
+ //int Value = printf( "%3d / %3d : ", w, nWordBatches );
+ Vec_Wrd_t * vSimI_ = Vec_WrdZoneExtract( nWords, vSimI, w*nWordsOne, nWordsOne );
+ Vec_Wrd_t * vSimO_ = Gia_ManSimInfoTryOne( p, vSimI_, 0 );
+ Vec_WrdZoneInsert( vSimO_new, nWords, vSimO_, w*nWordsOne, nWordsOne );
+ Vec_WrdFree( vSimI_ );
+ Vec_WrdFree( vSimO_ );
+ //Value = 0;
+ }
+ return vSimO_new;
+}
+int Gia_ManSimInfoEval_old( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int nResult = Gia_ManSimEvalOne2(p, vSimO, vSimO_new);
+ //Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 );
+ printf( "Total errors = %d. ", nResult );
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) );
+ return nResult;
+}
+void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ if ( fVerbose )
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) );
+ Vec_WrdDumpBin( pFileName2, vSimO, fVerbose );
+ Vec_WrdFree( vSimI );
+ Vec_WrdFree( vSimO );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Gia_ManSimInfoEval( Gia_Man_t * p, char * pFileName, char * pFileName2, int nOuts, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName2, fVerbose );
+ assert( nOuts > 0 );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) );
+ Gia_ManSimEvalOne3( p, vSim1, vNums, nOuts );
+ Vec_WrdFree( vSim1 );
+ Vec_IntFree( vNums );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose, int * pCare )
+{
+ Gia_Obj_t * pObj;
+ int i, k, nUsed = 0, nGood = 0;
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int nMints = 1 << Vec_IntSize(vSupp);
+ word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) );
+ word * pRes = ABC_CALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int * pCounts = ABC_CALLOC( int, nMints );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pSims[i] = Vec_WrdEntryP( vSimI, Gia_ObjCioId(pObj) * nWords );
+ for ( k = 0; k < 64*nWords; k++ )
+ {
+ int iMint = 0;
+ for ( i = 0; i < Vec_IntSize(vSupp); i++ )
+ if ( Abc_TtGetBit(pSims[i], k) )
+ iMint |= 1 << i;
+ assert( iMint < nMints );
+ pCounts[iMint]++;
+ }
+ for ( k = 0; k < nMints; k++ )
+ {
+ nUsed += (pCounts[k] > 0);
+ nGood += (pCounts[k] >= Thresh);
+ if ( pCounts[k] >= Thresh )
+ Abc_TtXorBit( pRes, k );
+ //printf( "%d ", pCounts[k] );
+ }
+ if ( Vec_IntSize(vSupp) < 6 )
+ pRes[0] = Abc_Tt6Stretch( pRes[0], Vec_IntSize(vSupp) );
+ //printf( "\n" );
+ if ( fVerbose )
+ printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints );
+ ABC_FREE( pSims );
+ ABC_FREE( pCounts );
+ *pCare = nGood;
+ return pRes;
+}
+void Gia_ManPermuteSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLevels, Vec_Int_t * vCounts )
+{
+ Gia_Obj_t * pObj; int n;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vLevels, vCounts );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vLevels, vCounts );
+ for ( n = 0; n < 2; n++ )
+ {
+ Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj);
+ if ( !Gia_ObjIsCi(pFanin) )
+ continue;
+ Vec_IntAddToEntry( vLevels, Gia_ObjCioId(pFanin), Gia_ObjLevel(p, pObj) );
+ Vec_IntAddToEntry( vCounts, Gia_ObjCioId(pFanin), 1 );
+ }
+}
+void Gia_ManPermuteSupp( Gia_Man_t * p, int iOut, int nOuts, Vec_Int_t * vSupp )
+{
+ Vec_Int_t * vLevels = Vec_IntStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManCiNum(p) );
+ int i, * pCost = ABC_CALLOC( int, Gia_ManCiNum(p) );
+ Gia_Obj_t * pObj;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vLevels, vCounts );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Abc_MaxInt(1, Vec_IntEntry(vCounts, Gia_ObjCioId(pObj)));
+ Vec_IntFree( vCounts );
+ Vec_IntFree( vLevels );
+ Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), pCost );
+ assert( Vec_IntSize(vSupp) < 2 || pCost[0] <= pCost[1] );
+ ABC_FREE( pCost );
+}
+void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ //Vec_IntPush( vSupp, Gia_ObjCioId(pObj) );
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vSupp );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vSupp );
+}
+Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vSupp = Vec_IntAlloc( 16 ); int i;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp );
+ return vSupp;
+}
+Vec_Int_t * Gia_ManCollectSuppNew( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vRes = Gia_ManCollectSupp( p, iOut, nOuts );
+ Gia_ManPermuteSupp( p, iOut, nOuts, vRes );
+ return vRes;
+}
+int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew; Gia_Obj_t * pObj;
+ Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) );
+ word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0;
+ word * pTruthsTry = ABC_CALLOC( word, 2*nOuts*Abc_Truth6WordNum(nIns) );
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ObjComputeTruthTableStart( p, nIns );
+ Gia_ManHashStart( pNew );
+ for ( g = 0; g < Gia_ManCoNum(p); g += nOuts )
+ {
+ Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0;
+ word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp));
+ assert( Vec_IntSize(vSupp) <= nIns );
+ Vec_IntClear( vLeaves );
+ Gia_ManForEachObjVec( vSupp, p, pObj, k )
+ Vec_IntPush( vLeaves, pObj->Value );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtSharp( pTruth0, pCare, pTruth, nWords );
+ Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 );
+ if ( vSimI )
+ {
+ Abc_TtCopy( pTruthsTry + (2*k+0)*nWords, pTruth1, nWords, 0 );
+ Abc_TtCopy( pTruthsTry + (2*k+1)*nWords, pTruth0, nWords, 0 );
+ }
+ else
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth1, nWords, 0 );
+ if ( !fTryNew )
+ {
+ pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 );
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ }
+ if ( fTryNew )
+ {
+ Gia_Man_t * pMin;
+ if ( vSimI )
+ pMin = Gia_TryPermOpt( pTruthsTry, Vec_IntSize(vSupp), 2*nOuts, nWords, nRounds, fVerbose );
+ else
+ pMin = Gia_TryPermOptCare( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ Gia_Obj_t * pObj2 = Gia_ManCo( pMin, k );
+ pObj->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj2) );
+ pObj->Value ^= Gia_ObjFaninC0(pObj2);
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ }
+ ABC_FREE( pCare );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ Gia_ManHashStop( pNew );
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjComputeTruthTableStop( p );
+ ABC_FREE( pTruth0 );
+ ABC_FREE( pTruth1 );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vMemory );
+ Vec_WrdFreeP( &vSimI );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pMin; Gia_Obj_t * pObj;
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruthsTry = ABC_CALLOC( word, (nOuts+1)*Abc_Truth6WordNum(nIns) );
+ int k, g; float CareAve = 0;
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ObjComputeTruthTableStart( p, nIns );
+ Gia_ManHashStart( pNew );
+ for ( g = 0; g < Gia_ManCoNum(p); g += nOuts )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(Gia_ManCo( p, g+k ))) )
+ break;
+ if ( k == nOuts )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ }
+ continue;
+ }
+ else
+ {
+
+ Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0;
+ word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp));
+ assert( Vec_IntSize(vSupp) <= nIns );
+ Vec_IntClear( vLeaves );
+ Gia_ManForEachObjVec( vSupp, p, pObj, k )
+ Vec_IntPush( vLeaves, pObj->Value );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth, nWords, Gia_ObjFaninC0(pObj) );
+ }
+ Abc_TtCopy( pTruthsTry + nOuts*nWords, pCare, nWords, 0 );
+ ABC_FREE( pCare );
+ pMin = Gia_TryPermOptNew( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ Gia_ManForEachCo( pMin, pObj, k )
+ {
+ Gia_Obj_t * pObj0 = Gia_ManCo( p, g+k );
+ pObj0->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj) );
+ pObj0->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+
+ }
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ Gia_ManHashStop( pNew );
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjComputeTruthTableStop( p );
+ Vec_IntFree( vLeaves );
+ Vec_WrdFreeP( &vSimI );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+
+#ifdef ABC_USE_CUDD
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDoMuxMapping( Gia_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars );
+ Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
+ Jf_Par_t Pars, * pPars = &Pars; int c, nIters = 2;
+ Sfm_Par_t Pars2, * pPars2 = &Pars2;
+ Lf_ManSetDefaultPars( pPars );
+ Sfm_ParSetDefault( pPars2 );
+ pPars2->nTfoLevMax = 5;
+ pPars2->nDepthMax = 100;
+ pPars2->nWinSizeMax = 2000;
+ for ( c = 0; c < nIters; c++ )
+ {
+ pNew = Lf_ManPerformMapping( pTemp = pNew, pPars );
+ Gia_ManStop( pTemp );
+ pNew = Gia_ManPerformMfs( pTemp = pNew, pPars2 );
+ Gia_ManStop( pTemp );
+ if ( c == nIters-1 )
+ break;
+ pNew = (Gia_Man_t *)Dsm_ManDeriveGia( pTemp = pNew, 0 );
+ Gia_ManStop( pTemp );
+ }
+ return pNew;
+}
+Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder )
+{
+ extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
+ extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd );
+ Gia_Man_t * pRes = NULL;
+ Aig_Man_t * pMan = Gia_ManToAig( p, 0 );
+ Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan );
+ Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ pNtk->pName = Extra_UtilStrsav( pMan->pName );
+ Aig_ManStop( pMan );
+ //pNtkNew = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder, 0 ) )
+ {
+ Abc_Ntk_t * pStrash = Abc_NtkStrash( pNtkNew, 1, 1, 0 );
+ pRes = Abc_NtkStrashToGia( pStrash );
+ Abc_NtkDelete( pStrash );
+ }
+ Abc_NtkDelete( pNtkNew );
+ Abc_NtkDelete( pNtk );
+ return pRes;
+}
+int Gia_ManDoTest1( Gia_Man_t * p, int fReorder )
+{
+ Gia_Man_t * pTemp, * pNew; int Res;
+ pNew = Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Res = Gia_ManLutNum( pNew );
+ Gia_ManStop( pNew );
+ return Res;
+}
+Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder, int fTryNew )
+{
+ extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs );
+ Abc_Ntk_t * pNtkNew;
+ Gia_Man_t * pTemp, * pNew;
+ pNew = fTryNew ? Gia_ManDup(p) : Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ pNtkNew = Abc_NtkFromMappedGia( pNew, 0, 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ Gia_ManStop( pNew );
+ Abc_NtkToSop( pNtkNew, 1, ABC_INFINITY );
+ return pNtkNew;
+}
+Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fTryNew, int fVerbose )
+{
+ extern Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose );
+ int i, k, g, nGroups = Gia_ManCoNum(p) / nOuts, CountsAll[3] = {0};
+ Abc_Obj_t * pObjNew, * pFaninNew; Gia_Obj_t * pObj;
+ Abc_Ntk_t * pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ assert( Gia_ManCoNum(p) % nOuts == 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec);
+ Gia_ManFillValue( p );
+ Gia_ManForEachPi( p, pObj, i )
+ Abc_NtkCreatePi( pNtkNew );
+ Gia_ManForEachPo( p, pObj, i )
+ Abc_NtkCreatePo( pNtkNew );
+ assert( nOuts <= 64 );
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew; Aig_Man_t * pMan;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkMap;
+ int pPos[64], Counter = 0, Counts[3] = {0};
+ for ( i = 0; i < nOuts; i++ )
+ pPos[i] = g*nOuts+i;
+ pNew = Gia_ManDupCones( p, pPos, nOuts, 1 );
+ if ( !fUseFixed )
+ pNtkMap = Gia_ManDoTest2( pNew, 1, fTryNew );
+ else
+ {
+ pMan = Gia_ManToAig( pNew, 0 );
+ pNtk = Abc_NtkFromAigPhase( pMan );
+ Aig_ManStop( pMan );
+ pNtkRes = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ Abc_NtkDelete( pNtk );
+ pNtkMap = Abc_NtkSpecialMapping( pNtkRes, 0 );
+ Abc_NtkDelete( pNtkRes );
+ }
+ Gia_ManStop( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ if ( ~pObj->Value )
+ Abc_NtkCi(pNtkMap, Counter++)->pCopy = Abc_NtkCi(pNtkNew, i);
+ assert( Counter == Abc_NtkCiNum(pNtkMap) );
+ Abc_NtkForEachNode( pNtkMap, pObjNew, i )
+ {
+ pObjNew->pCopy = Abc_NtkDupObj( pNtkNew, pObjNew, 0 );
+ pObjNew->pCopy->fPersist = pObjNew->fPersist;
+ if ( pObjNew->fPersist )
+ Counts[1]++;
+ else
+ Counts[0]++;
+ Abc_ObjForEachFanin( pObjNew, pFaninNew, k )
+ Abc_ObjAddFanin( pObjNew->pCopy, pFaninNew->pCopy );
+ }
+ Abc_NtkForEachCo( pNtkMap, pObjNew, i )
+ Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, g*nOuts+i), Abc_ObjFanin0(pObjNew)->pCopy );
+ Abc_NtkDelete( pNtkMap );
+
+ if ( fVerbose )
+ {
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test = %4d ", Counts[0] );
+ printf( "MarkA = %4d ", Counts[1] );
+ printf( "MarkB = %4d ", Counts[2] );
+ printf( "\n" );
+ }
+
+ CountsAll[0] += Counts[0];
+ CountsAll[1] += Counts[1];
+ CountsAll[2] += Counts[2];
+ }
+ if ( fVerbose )
+ printf( "Total LUT count = %5d. MarkA = %5d. MarkB = %5d.\n", CountsAll[0], CountsAll[1], CountsAll[2] );
+ // create names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ Abc_NtkAddDummyBoxNames( pNtkNew );
+ // check the resulting AIG
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ int fPrintOnly = 0;
+ int Res1, Res2, Result = 0;
+ int g, nGroups = Gia_ManCoNum(p) / GroupSize;
+ assert( Gia_ManCoNum(p) % GroupSize == 0 );
+ assert( GroupSize <= 64 );
+ if ( fPrintOnly )
+ {
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew;
+ int o, pPos[64];
+ for ( o = 0; o < GroupSize; o++ )
+ pPos[o] = g*GroupSize+o;
+ pNew = Gia_ManDupCones( p, pPos, GroupSize, 0 );
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) );
+ printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) );
+ printf( "Test = %4d ", Abc_MinInt(Res1, Res2) );
+ printf( "\n" );
+ Result += Abc_MinInt(Res1, Res2);
+ //Gia_ManPrintStats( pNew, NULL );
+ Gia_ManStop( pNew );
+ }
+ printf( "Total LUT count = %d.\n", Result );
+ return NULL;
+
+ }
+ return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fTryNew, fVerbose );
+}
+
+#else
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ return NULL;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c
new file mode 100644
index 00000000..85cae0d2
--- /dev/null
+++ b/src/aig/gia/giaMinLut2.c
@@ -0,0 +1,1372 @@
+/**CFile****************************************************************
+
+ FileName [giaMinLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Collapsing AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "base/main/mainInt.h"
+#include "opt/sfm/sfm.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define TREE_MAX_VARS 16
+
+typedef struct Tree_Sto_t_ Tree_Sto_t;
+struct Tree_Sto_t_
+{
+ int nIns;
+ int nOuts;
+ int pTried[TREE_MAX_VARS];
+ int pPerm[TREE_MAX_VARS];
+ int pIPerm[TREE_MAX_VARS];
+ int nNodes[TREE_MAX_VARS];
+ Vec_Int_t vCofs[TREE_MAX_VARS];
+ word * pMem;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Tree_Sto_t * Gia_ManTreeDup( Tree_Sto_t * p )
+{
+ Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 );
+ int i, k, Obj;
+ *pSto = *p;
+ pSto->pMem = Abc_TtDup( pSto->pMem, p->nOuts*Abc_TtWordNum(p->nIns), 0 );
+ memset( pSto->vCofs, 0, sizeof(Vec_Int_t)*TREE_MAX_VARS );
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ Vec_IntForEachEntry( p->vCofs+i, Obj, k )
+ Vec_IntPush( pSto->vCofs+i, Obj );
+ return pSto;
+}
+void Gia_ManTreeFree( Tree_Sto_t * p )
+{
+ int i;
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ ABC_FREE( p->vCofs[i].pArray );
+ ABC_FREE( p->pMem );
+ ABC_FREE( p );
+}
+int Gia_ManTreeCountNodes( Tree_Sto_t * p )
+{
+ int i, nNodes = 0;
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ nNodes += p->nNodes[i];
+ return nNodes;
+}
+void Gia_ManTreePrint( Tree_Sto_t * p )
+{
+ int i;
+ printf( "Tree with %d nodes:\n", Gia_ManTreeCountNodes(p) );
+ for ( i = p->nIns-1; i >= 0; i-- )
+ printf( "Level %2d Var %2d : %s Nodes = %3d Cofs = %3d\n",
+ i, p->pIPerm[i], p->pTried[i]?"*":" ", p->nNodes[i], Vec_IntSize(p->vCofs+i) );
+// for ( i = p->nIns-1; i >= 0; i-- )
+// printf( "Var %2d Level %2d\n", i, p->pPerm[i] );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManFindOrAddNode( Tree_Sto_t * pSto, int iVar, int Truth, word * pCof )
+{
+ int k, Obj;
+ if ( iVar > 5 )
+ {
+ int nWords = Abc_TtWordNum(iVar);
+ Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k )
+ if ( Abc_TtEqual( pSto->pMem + Obj, pCof, nWords ) )
+ return 1;
+ Vec_IntPush( pSto->vCofs+iVar, pCof - pSto->pMem );
+ }
+ else
+ {
+ Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k )
+ if ( Obj == Truth )
+ return 1;
+ Vec_IntPush( pSto->vCofs+iVar, Truth );
+ }
+ return 0;
+}
+int Gia_ManProcessLevel( Tree_Sto_t * pSto, int iVar )
+{
+ int k, Obj, nNodes = 0;
+ //Vec_IntPrint( pSto->vCofs+iVar );
+ Vec_IntClear( pSto->vCofs+iVar );
+ if ( iVar > 5 )
+ {
+ int nWords = Abc_TtWordNum(iVar);
+ Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k )
+ {
+ word * pCof0 = pSto->pMem + Obj;
+ word * pCof1 = pCof0 + nWords;
+ Gia_ManFindOrAddNode( pSto, iVar, -1, pCof0 );
+ if ( Abc_TtEqual( pCof0, pCof1, nWords ) )
+ continue;
+ Gia_ManFindOrAddNode( pSto, iVar, -1, pCof1 );
+ nNodes++;
+ }
+ }
+ else
+ {
+ Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k )
+ {
+ unsigned Cof0 = iVar < 5 ? Abc_Tt5Cofactor0( Obj, iVar ) : (unsigned) pSto->pMem[Obj];
+ unsigned Cof1 = iVar < 5 ? Abc_Tt5Cofactor1( Obj, iVar ) : (unsigned)(pSto->pMem[Obj] >> 32);
+ Gia_ManFindOrAddNode( pSto, iVar, Cof0, NULL );
+ if ( Cof0 == Cof1 )
+ continue;
+ Gia_ManFindOrAddNode( pSto, iVar, Cof1, NULL );
+ nNodes++;
+ }
+ }
+ //printf( "Level %2d : Nodes = %3d Cofs = %3d\n", iVar, nNodes, Vec_IntSize(pSto->vCofs+iVar) );
+ //Vec_IntPrint( pSto->vCofs+iVar );
+ //printf( "\n" );
+ return nNodes;
+}
+Tree_Sto_t * Gia_ManContructTree( word * pTruths, int nIns, int nOuts, int nWords )
+{
+ Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 ); int i;
+ assert( Abc_TtWordNum(nIns) == nWords );
+ assert( nIns+1 <= TREE_MAX_VARS );
+ pSto->pMem = Abc_TtDup(pTruths, nOuts*nWords, 0);
+ pSto->nIns = nIns;
+ pSto->nOuts = nOuts;
+ for ( i = 0; i < nIns; i++ )
+ pSto->pPerm[i] = pSto->pIPerm[i] = i;
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManFindOrAddNode( pSto, nIns, (unsigned)pSto->pMem[i], pSto->pMem + i*nWords );
+ for ( i = nIns-1; i >= 0; i-- )
+ pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i );
+ return pSto;
+}
+void Gia_ManContructTreeTest( word * pTruths, int nIns, int nOuts, int nWords )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ printf( "Total nodes = %d.\n", Gia_ManTreeCountNodes(pSto) );
+ Gia_ManTreeFree( pSto );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSwapTree( Tree_Sto_t * pSto, int i )
+{
+ int nNodes = pSto->nNodes[i+1] + pSto->nNodes[i];
+ int v, o, nWords = Abc_TtWordNum(pSto->nIns);
+ //printf( "Swapping %2d and %2d ", i, i+1 );
+ assert( i >= 0 && i < pSto->nIns-1 );
+ for ( o = 0; o < pSto->nOuts; o++ )
+ Abc_TtSwapAdjacent( pSto->pMem + o*nWords, nWords, i );
+ for ( v = 5; v > i+1; v-- )
+ pSto->nNodes[v] = Gia_ManProcessLevel( pSto, v );
+ pSto->nNodes[i+1] = Gia_ManProcessLevel( pSto, i+1 );
+ pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i );
+ ABC_SWAP( int, pSto->pTried[i], pSto->pTried[i+1] );
+ ABC_SWAP( int, pSto->pIPerm[i], pSto->pIPerm[i+1] );
+ pSto->pPerm[pSto->pIPerm[i+1]] = i+1;
+ pSto->pPerm[pSto->pIPerm[i]] = i;
+ return pSto->nNodes[i+1] + pSto->nNodes[i] - nNodes;
+}
+int Gia_ManFindBestPosition( word * pTruths, int nIns, int nOuts, int nWords, word * pStore, int fMoveMore, int * pnNodesMin, int fVerbose )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ //int v, vBest = nIns-1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = nNodesCur;
+ int v, vBest = -1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = ABC_INFINITY;
+ if ( fVerbose )
+ Gia_ManTreePrint( pSto );
+ Abc_TtCopy( pStore+(nIns-1)*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 );
+ for ( v = nIns-2; v >= 0; v-- )
+ {
+ nNodesCur += Gia_ManSwapTree( pSto, v );
+ if ( fMoveMore ? nNodesMin >= nNodesCur : nNodesMin > nNodesCur )
+ {
+ nNodesMin = nNodesCur;
+ vBest = v;
+ }
+ if ( fVerbose )
+ printf( "Level %2d -> %2d : Nodes = %4d. ", v+1, v, nNodesCur );
+ Abc_TtCopy( pStore+v*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 );
+ if ( fVerbose )
+ Gia_ManContructTreeTest( pSto->pMem, nIns, nOuts, nWords );
+ }
+ assert( vBest != nIns-1 );
+ Gia_ManTreeFree( pSto );
+ if ( fVerbose )
+ printf( "Best level = %d. Best nodes = %d.\n", vBest, nNodesMin );
+ if ( pnNodesMin )
+ *pnNodesMin = nNodesMin;
+ return vBest;
+}
+void Gia_ManPermStats( int nIns, int * pIPerm, int * pTried )
+{
+ int v;
+ for ( v = nIns-1; v >= 0; v-- )
+ printf( "Level = %2d : Var = %2d Tried = %2d\n", v, pIPerm[v], pTried[v] );
+ printf( "\n" );
+}
+int Gia_ManPermuteTreeOne( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int * pIPermOut, int fVeryVerbose, int fVerbose )
+{
+ extern void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm );
+ word * pStore = ABC_ALLOC( word, nIns*nOuts*nWords );
+ int pTried[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int v, r, Pos, nNodesPrev = -1, nNodesMin = 0, nNoChange = 0;
+ int nNodesBeg, nNodesEnd;
+ Tree_Sto_t * pSto;
+ for ( v = 0; v < nIns; v++ )
+ pIPerm[v] = v;
+ pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ nNodesBeg = Gia_ManTreeCountNodes(pSto);
+ //Gia_ManDumpMuxes( pSto, "from_tt1.aig", pIPerm );
+ Gia_ManTreeFree( pSto );
+ if ( fRandom )
+ for ( v = 0; v < nIns; v++ )
+ {
+ //int o, vRand = rand() % nIns;
+ int o, vRand = Gia_ManRandom(0) % nIns;
+ for ( o = 0; o < nOuts; o++ )
+ Abc_TtSwapVars( pTruths + o*nWords, nIns, v, vRand );
+ ABC_SWAP( int, pIPerm[vRand], pIPerm[v] );
+ }
+ for ( r = 0; r < 10*nIns; r++ )
+ {
+ nNodesPrev = nNodesMin;
+ if ( fVeryVerbose )
+ printf( "\nRound %d:\n", r );
+ Pos = Gia_ManFindBestPosition( pTruths, nIns, nOuts, nWords, pStore, r&1, &nNodesMin, fVeryVerbose );
+ Abc_TtCopy( pTruths, pStore+Pos*nOuts*nWords, nOuts*nWords, 0 );
+ pTried[nIns-1]++;
+ for ( v = nIns-2; v >= Pos; v-- )
+ {
+ ABC_SWAP( int, pTried[v+1], pTried[v] );
+ ABC_SWAP( int, pIPerm[v+1], pIPerm[v] );
+ }
+ if ( fVeryVerbose )
+ Gia_ManPermStats( nIns, pIPerm, pTried );
+ nNoChange = nNodesPrev == nNodesMin ? nNoChange + 1 : 0;
+ if ( nNoChange == 4 )
+ break;
+ }
+ pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ nNodesEnd = Gia_ManTreeCountNodes(pSto);
+ //Gia_ManDumpMuxes( pSto, "from_tt2.aig", pIPerm );
+ if ( fVerbose )
+ printf( "Nodes %5d -> %5d. ", nNodesBeg, nNodesEnd );
+ Gia_ManTreeFree( pSto );
+ ABC_FREE( pStore );
+ if ( pIPermOut )
+ memcpy( pIPermOut, pIPerm, sizeof(int)*nIns );
+ return nNodesEnd;
+}
+void Gia_ManPermuteTree( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ int r;
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < 100; r++ )
+ {
+ Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, fRandom, NULL, 0, fVerbose );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ }
+ ABC_FREE( pTruthDup );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define TT_UNDEF ABC_CONST(0x1234567887654321)
+
+static inline word Abc_Tt6Min_rec( word uF, word uR, int nVars, Vec_Wrd_t * vNodes )
+{
+ word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var;
+ assert( nVars <= 6 );
+ assert( (uF & uR) == 0 );
+ if ( !uF && !uR )
+ return TT_UNDEF;
+ if ( !uF && !~uR )
+ return 0;
+ if ( !~uF && !uR )
+ return ~(word)0;
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( 1 && vNodes )
+ Vec_WrdForEachEntry( vNodes, uRes2, i )
+ if ( !(uF & ~uRes2) && !(uRes2 & uR) )
+ return uRes2;
+// else if ( !(uF & uRes2) && !(~uRes2 & uR) )
+// return ~uRes2;
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uR0 = Abc_Tt6Cofactor0( uR, Var );
+ uR1 = Abc_Tt6Cofactor1( uR, Var );
+ uRes0 = Abc_Tt6Min_rec( uF0, uR0, Var, vNodes );
+ uRes1 = Abc_Tt6Min_rec( uF1, uR1, Var, vNodes );
+ if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF )
+ return TT_UNDEF;
+ if ( uRes0 == TT_UNDEF )
+ return uRes1;
+ if ( uRes1 == TT_UNDEF )
+ return uRes0;
+ if ( uRes0 == uRes1 )
+ return uRes0;
+// if ( (uRes0 & ~uRes1) == 0 )
+// printf( "0" );
+// else if ( (~uRes0 & uRes1) == 0 )
+// printf( "1" );
+// else
+// printf( "*" );
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ assert( !(uF & ~uRes2) );
+ assert( !(uRes2 & uR) );
+ if ( vNodes )
+ Vec_WrdPush( vNodes, uRes2 );
+ return uRes2;
+}
+word * Abc_TtMin_rec( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 )
+{
+ int i, Entry, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_Tt6Min_rec( pF[0], pR[0], nVars, vNodes );
+ return pRes2;
+ }
+ assert( !Abc_TtIntersect(pF, pR, nWords, 0) );
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ return NULL;
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) )
+ {
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ {
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) )
+ {
+ pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntForEachEntry( vLayer, Entry, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ return pTemp;
+/*
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+*/
+ }
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 );
+ pRes1 = Abc_TtMin_rec( pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2 );
+ if ( pRes0 == NULL && pRes1 == NULL )
+ return NULL;
+ if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) );
+ assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) );
+ if ( vNodes2 )
+ Vec_WecPush( vNodes2, nVars, pRes2 - Vec_WrdArray(vMemory) );
+ return pRes2;
+}
+word * Abc_TtMin( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 )
+{
+ word * pResult;
+ int i, nWords = Abc_TtWordNum(nVars);
+ assert( nVars >= 0 && nVars <= 16 );
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ Vec_WrdClear( vMemory );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pResult = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 );
+ if ( pResult == NULL )
+ {
+ Vec_WrdFill( vMemory, nWords, 0 );
+ return Vec_WrdArray( vMemory );
+ }
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ Abc_TtCopy( Vec_WrdArray(vMemory), pResult, nWords, 0 );
+ Vec_WrdShrink( vMemory, nWords );
+ return Vec_WrdArray(vMemory);
+}
+word * Abc_TtMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbose )
+{
+ int o, i, nWords = Abc_TtWordNum(nVars);
+ word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ for ( o = 0; o < nOuts/2; o++ )
+ {
+ word * pF = p + (2*o+0)*nWords;
+ word * pR = p + (2*o+1)*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ pRes = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 );
+ if ( pResult == NULL )
+ Abc_TtClear( pResult + o*nWords, nWords );
+ else
+ Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Abc_TtSimple6Min_rec( Gia_Man_t * p, word uF, word uC, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm )
+{
+ word uF0, uF1, uC0, uC1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1;
+ word uFC = uF & uC;
+ word uRC = ~uF & uC;
+ assert( nVars <= 6 );
+ *piLit = 0;
+ if ( !uFC )
+ {
+ *piLit = 0;
+ return 0;
+ }
+ if ( !uRC )
+ {
+ *piLit = 1;
+ return ~(word)0;
+ }
+ assert( nVars > 0 );
+ if ( 1 && vNodes )
+ {
+ int iLit;
+ Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i )
+ if ( !((uF ^ uRes2) & uC) )
+ {
+ *piLit = (unsigned)iLit;
+ return uRes2;
+ }
+ else if ( !((uF ^ ~uRes2) & uC) )
+ {
+ *piLit = Abc_LitNot( (unsigned)iLit );
+ return ~uRes2;
+ }
+ }
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) )
+ break;
+ else
+ uC = Abc_Tt6Cofactor0(uC, Var) | Abc_Tt6Cofactor1(uC, Var);
+ assert( Var >= 0 );
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uC0 = Abc_Tt6Cofactor0( uC, Var );
+ uC1 = Abc_Tt6Cofactor1( uC, Var );
+ uRes0 = Abc_TtSimple6Min_rec( p, uF0, uC0, Var, vNodes, &iLit0, pPerm );
+ uRes1 = Abc_TtSimple6Min_rec( p, uF1, uC1, Var, vNodes, &iLit1, pPerm );
+ if ( uRes0 == uRes1 )
+ {
+ *piLit = iLit0;
+ return uRes0;
+ }
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ Var = pPerm ? pPerm[Var] : Var;
+ //if ( !(uRes0 & ~uRes1 & uC1) )
+ if ( !(uRes0 & ~uRes1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ //else if ( !(uRes1 & ~uRes0 & uC0) )
+ else if ( !(uRes1 & ~uRes0) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !(uFC & ~uRes2) );
+ assert( !(uRes2 & uRC) );
+ if ( vNodes )
+ Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit );
+ return uRes2;
+}
+word * Abc_TtSimpleMin_rec( Gia_Man_t * p, word * pF, word * pC, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm )
+{
+ int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ *piLit = 0;
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_TtSimple6Min_rec( p, pF[0], pC[0], nVars, vNodes, piLit, pPerm );
+ return pRes2;
+ }
+ if ( !Abc_TtIntersect(pF, pC, nWords, 0) )
+ {
+ *piLit = 0;
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( !Abc_TtIntersect(pF, pC, nWords, 1) )
+ {
+ *piLit = 1;
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) )
+ {
+ word * pCn = Vec_WrdFetch( vMemory, nWords );
+ Abc_TtOr( pCn, pC, pC + nWords, nWords );
+ pRes0 = Abc_TtSimpleMin_rec( p, pF, pCn, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit;
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( Abc_TtEqualCare(pTemp, pF, pC, 0, 2*nWords) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( Abc_TtEqualCare(pTemp, pF, pC, 1, 2*nWords) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtSimpleMin_rec( p, pF, pC, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm );
+ pRes1 = Abc_TtSimpleMin_rec( p, pF + nWords, pC + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm );
+ if ( Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ *piLit = iLit0;
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ Var = pPerm ? pPerm[nVars-1] : nVars-1;
+ //if ( !Abc_TtIntersectCare(pRes1, pRes0, pC + nWords, nWords, 1) )
+ if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ //else if ( !Abc_TtIntersectCare(pRes0, pRes1, pC, nWords, 1) )
+ else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( Abc_TtEqualCare(pRes2, pF, pC, 0, 2*nWords) );
+ if ( vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit );
+ }
+ return pRes2;
+}
+Gia_Man_t * Abc_TtSimpleMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pF = ABC_ALLOC( word, nWords );
+ word * pR = ABC_ALLOC( word, nWords );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts; o++ )
+ {
+ word * pCare = p + nOuts*nWords;
+ word * pTruth = p + o*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pTruth[0], i) && !Abc_Tt6HasVar(pCare[0], i) );
+ Abc_TtSimpleMin_rec( pNew, pTruth, pCare, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pF );
+ ABC_FREE( pR );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Abc_TtGia6Min_rec( Gia_Man_t * p, word uF, word uR, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm )
+{
+ word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1;
+ assert( nVars <= 6 );
+ assert( (uF & uR) == 0 );
+ *piLit = 0;
+ if ( !uF && !uR )
+ return TT_UNDEF;
+ if ( !uF && !~uR )
+ {
+ *piLit = 0;
+ return 0;
+ }
+ if ( !~uF && !uR )
+ {
+ *piLit = 1;
+ return ~(word)0;
+ }
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( 1 && vNodes )
+ {
+ int iLit;
+ Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i )
+ if ( !(uF & ~uRes2) && !(uRes2 & uR) )
+ {
+ *piLit = (unsigned)iLit;
+ return uRes2;
+ }
+ else if ( !(uF & uRes2) && !(~uRes2 & uR) )
+ {
+ *piLit = Abc_LitNot( (unsigned)iLit );
+ return ~uRes2;
+ }
+ }
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uR0 = Abc_Tt6Cofactor0( uR, Var );
+ uR1 = Abc_Tt6Cofactor1( uR, Var );
+ uRes0 = Abc_TtGia6Min_rec( p, uF0, uR0, Var, vNodes, &iLit0, pPerm );
+ uRes1 = Abc_TtGia6Min_rec( p, uF1, uR1, Var, vNodes, &iLit1, pPerm );
+ if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF )
+ return TT_UNDEF;
+ if ( uRes0 == TT_UNDEF )
+ {
+ *piLit = iLit1;
+ return uRes1;
+ }
+ if ( uRes1 == TT_UNDEF || uRes0 == uRes1 )
+ {
+ *piLit = iLit0;
+ return uRes0;
+ }
+// if ( (uRes0 & ~uRes1) == 0 )
+// printf( "0" );
+// else if ( (~uRes0 & uRes1) == 0 )
+// printf( "1" );
+// else
+// printf( "*" );
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ Var = pPerm ? pPerm[Var] : Var;
+ if ( !(uRes0 & ~uRes1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ else if ( !(uRes1 & ~uRes0) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !(uF & ~uRes2) );
+ assert( !(uRes2 & uR) );
+ if ( vNodes )
+ Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit );
+ return uRes2;
+}
+word * Abc_TtGiaMin_rec( Gia_Man_t * p, word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm )
+{
+ int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ *piLit = 0;
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_TtGia6Min_rec( p, pF[0], pR[0], nVars, vNodes, piLit, pPerm );
+ return pRes2;
+ }
+ assert( !Abc_TtIntersect(pF, pR, nWords, 0) );
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ return NULL;
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) )
+ {
+ *piLit = 0;
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ {
+ *piLit = 1;
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) )
+ {
+ pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit;
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+/*
+ if ( nVars > 7 )
+ {
+ vLayer = Vec_WecEntry( vNodes2, nVars-1 );
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+ }
+*/
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm );
+ pRes1 = Abc_TtGiaMin_rec( p, pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm );
+ if ( pRes0 == NULL && pRes1 == NULL )
+ return NULL;
+ if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ *piLit = pRes0 ? iLit0 : iLit1;
+ Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ Var = pPerm ? pPerm[nVars-1] : nVars-1;
+ if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) );
+ assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) );
+ if ( vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit );
+ }
+ return pRes2;
+}
+Gia_Man_t * Abc_TtGiaMinArray( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts/2; o++ )
+ {
+ word * pF = p + (2*o+0)*nWords;
+ word * pR = p + (2*o+1)*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ pRes = Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ if ( pResult == NULL )
+ {
+ Abc_TtClear( pResult + o*nWords, nWords );
+ Gia_ManAppendCo( pNew, 0 );
+ }
+ else
+ {
+ Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pResult );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Abc_TtGiaMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pF = ABC_ALLOC( word, nWords );
+ word * pR = ABC_ALLOC( word, nWords );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts; o++ )
+ {
+ word * pCare = p + nOuts*nWords;
+ word * pTruth = p + o*nWords;
+ Abc_TtAnd( pF, pCare, pTruth, nWords, 0 );
+ Abc_TtSharp( pR, pCare, pTruth, nWords );
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pF );
+ ABC_FREE( pR );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManBuildMuxes6_rec( Gia_Man_t * p, word t, int nVars, int * pPerm )
+{
+ int iLit0, iLit1, Var;
+ assert( nVars <= 6 );
+ if ( t == 0 )
+ return 0;
+ if ( ~t == 0 )
+ return 1;
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( t, Var ) )
+ break;
+ assert( Var >= 0 );
+ iLit0 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor0(t, Var), Var, pPerm );
+ iLit1 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor1(t, Var), Var, pPerm );
+ Var = pPerm ? pPerm[Var] : Var;
+ return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+}
+int Gia_ManBuildMuxes_rec( Gia_Man_t * p, word * pTruth, int nVars, int * pPerm )
+{
+ int iLit0, iLit1, Var, nWords = Abc_TtWordNum(nVars);
+ if ( nVars <= 6 )
+ return Gia_ManBuildMuxes6_rec( p, pTruth[0], nVars, pPerm );
+ if ( Abc_TtIsConst0(pTruth, nWords) )
+ return 0;
+ if ( Abc_TtIsConst1(pTruth, nWords) )
+ return 1;
+/*
+ assert( nVars > 0 );
+ if ( !Abc_TtHasVar( pTruth, nVars, nVars-1 ) )
+ return Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 );
+ assert( nVars > 6 );
+ iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 );
+ iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+nWords/2, nVars-1 );
+*/
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_TtHasVar( pTruth, nVars, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( Var < 6 )
+ return Gia_ManBuildMuxes6_rec( p, pTruth[0], Var+1, pPerm );
+ iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, Var, pPerm );
+ iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+Abc_TtWordNum(Var), Var, pPerm );
+ Var = pPerm ? pPerm[Var] : Var;
+ return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+}
+Gia_Man_t * Gia_ManBuildMuxesTest( word * pTruth, int nIns, int nOuts, int * pPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int i, nWords = Abc_TtWordNum(nIns);
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nIns; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManAppendCo( pNew, Gia_ManBuildMuxes_rec( pNew, pTruth+i*nWords, nIns, pPerm ) );
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Gia_ManBuildMuxes( Tree_Sto_t * p, int * pIPerm )
+{
+ return Gia_ManBuildMuxesTest( p->pMem, p->nIns, p->nOuts, pIPerm ? pIPerm : p->pIPerm );
+}
+void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm )
+{
+ Gia_Man_t * pNew = Gia_ManBuildMuxes( p, pIPerm );
+ Gia_AigerWrite( pNew, pFileName, 0, 0, 0 );
+ Gia_ManStop( pNew );
+ printf( "Finished dumping tree into AIG file \"%s\".\n", pFileName );
+}
+Gia_Man_t * Gia_ManCreateMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ Gia_Man_t * pNew = Gia_ManBuildMuxes( pSto, pIPerm );
+ //printf( "Internal nodes = %5d.\n", Gia_ManTreeCountNodes(pSto) );
+ Gia_ManTreeFree( pSto );
+ return pNew;
+}
+void Gia_ManDumpMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm, char * pFileName )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ Gia_ManDumpMuxes( pSto, pFileName, pIPerm );
+ Gia_ManTreeFree( pSto );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ word * pTruthBest = ABC_FALLOC( word, (nOuts+1)*nWords );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY;
+ //Gia_ManDumpMuxGia( pTruths, nIns, nOuts, nWords, NULL, "tt_beg.aig" );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ nNodes = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ if ( nNodesBest > nNodes )
+ {
+ nNodesBest = nNodes;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ Abc_TtCopy( pTruthBest, pTruthDup, nOuts*nWords, 0 );
+ rBest = r;
+ }
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "\n" );
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ //pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest );
+ pNew = Abc_TtSimpleMinArrayNew( pTruthBest, nIns, nOuts, NULL, 0, pIPermBest );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest, "tt_end.aig" );
+ ABC_FREE( pTruthBest );
+ return pNew;
+}
+Gia_Man_t * Gia_TryPermOpt2( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ word * pRes, * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ word * pTruthBest = ABC_ALLOC( word, nOuts*nWords/2 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY;
+ assert( nOuts % 2 == 0 );
+ // collect onsets
+ //for ( r = 0; r < nOuts/2; r++ )
+ // Abc_TtCopy( pTruthBest+r*nWords, pTruths+2*r*nWords, nWords, 0 );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, NULL, "tt_beg.aig" );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ pRes = Abc_TtMinArray( pTruthDup, nOuts, nIns, &nNodes, fVerbose );
+ if ( nNodesBest > nNodes )
+ {
+ nNodesBest = nNodes;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ Abc_TtCopy( pTruthBest, pRes, nOuts*nWords/2, 0 );
+ rBest = r;
+ }
+ ABC_FREE( pRes );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "\n" );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest, "tt_end.aig" );
+ ABC_FREE( pTruthBest );
+ return pNew;
+}
+Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pBest = NULL;
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY;
+ assert( nOuts % 2 == 0 );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ Gia_Man_t * pTemp = Abc_TtGiaMinArray( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ nNodes2 = Gia_ManAndNum(pTemp);
+ if ( nNodesBest > nNodes2 )
+ {
+ nNodesBest = nNodes2;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ rBest = r;
+
+ Gia_ManStopP( &pBest );
+ pBest = pTemp;
+ pTemp = NULL;
+ }
+ Gia_ManStopP( &pTemp );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pBest;
+}
+Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pTemp, * pBest = NULL;
+ word * pTruthDup = Abc_TtDup( pTruths, (nOuts+1)*nWords, 0 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY;
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ Abc_TtPermute( pTruthDup + nOuts*nWords, pIPerm, nIns );
+ //pTemp = Abc_TtGiaMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ pTemp = Abc_TtSimpleMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ nNodes2 = Gia_ManAndNum(pTemp);
+ if ( nNodesBest > nNodes2 )
+ {
+ nNodesBest = nNodes2;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ rBest = r;
+
+ Gia_ManStopP( &pBest );
+ pBest = pTemp;
+ pTemp = NULL;
+ }
+ Gia_ManStopP( &pTemp );
+/*
+ for ( i = 0; i <= nOuts; i++ )
+ {
+ Abc_TtUnpermute( pTruthDup + i*nWords, pIPerm, nIns );
+ if ( !Abc_TtEqual(pTruthDup + i*nWords, pTruths + i*nWords, nWords) )
+ printf( "Verification failed for output %d (out of %d).\n", i, nOuts );
+ }
+*/
+ Abc_TtCopy( pTruthDup, pTruths, (nOuts+1)*nWords, 0 );
+ if ( fVerbose )
+ printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pBest;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_Tt6MinTest3( Gia_Man_t * p )
+{
+ word f = ABC_CONST(0x513B00000819050F);
+ //word r = ABC_CONST(0xA000571507200000);
+ word r = ~f;
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ word Res = Abc_Tt6Min_rec( f, r, 6, vNodes );
+ printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) );
+ if ( Res == f )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification FAILED.\n" );
+ Vec_WrdFree( vNodes );
+}
+void Abc_Tt6MinTest2( Gia_Man_t * p )
+{
+ int fVerbose = 0;
+ int i, nWords = Abc_TtWordNum(Gia_ManCiNum(p));
+ word * pTruth = ABC_ALLOC( word, 3*nWords );
+ word * pRes = NULL, * pTruths[3] = { pTruth, pTruth+nWords, pTruth+2*nWords };
+
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecAlloc( 100 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 0 );
+
+ Gia_Obj_t * pObj;
+ Gia_ManForEachCi( p, pObj, i )
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+
+ Gia_ObjComputeTruthTableStart( p, Gia_ManCiNum(p) );
+ assert( Gia_ManCoNum(p) == 3 );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtCopy( pTruths[i], pTruth, nWords, Gia_ObjFaninC0(pObj) );
+ }
+ Gia_ObjComputeTruthTableStop( p );
+
+
+ //Abc_TtSharp( pTruths[0], pTruths[0], pTruths[1], nWords );
+ Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) );
+ Abc_TtCopy( pTruths[1], pTruths[0], nWords, 1 );
+
+ pRes = Abc_TtMin( pTruths[0], pTruths[1], Gia_ManCiNum(p), vMemory, vNodes, vNodes2 );
+ printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) );
+ printf( "Nodes2 = %d.\n", Vec_WecSizeSize(vNodes2) );
+ if ( Abc_TtEqual(pRes, pTruths[0], nWords) )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification FAILED.\n" );
+
+ //printf( "Printing the tree:\n" );
+// Gia_ManPermuteTree( pTruths[0], Gia_ManCiNum(p), 1, nWords, fVerbose );
+ Gia_ManPermuteTree( pTruth, Gia_ManCiNum(p), 3, nWords, 0, fVerbose );
+
+
+/*
+ Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) );
+ Abc_TtReverseVars( pTruths[1], Gia_ManCiNum(p) );
+ Abc_TtReverseVars( pTruths[2], Gia_ManCiNum(p) );
+ printf( "Printing the tree:\n" );
+ Gia_ManContructTree( pTruth, Gia_ManCiNum(p), 3, nWords );
+*/
+
+/*
+ pNew = Gia_ManBuildMuxesTest( pTruth, Gia_ManCiNum(p), Gia_ManCoNum(p), NULL );
+ Gia_AigerWrite( pNew, "from_tt.aig", 0, 0, 0 );
+ printf( "Dumping file \"%s\".\n", "from_tt.aig" );
+ Gia_ManStop( pNew );
+*/
+
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ Vec_IntFree( vSupp );
+ ABC_FREE( pTruth );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c
index ce42f73c..6cc528f2 100644
--- a/src/aig/gia/giaMini.c
+++ b/src/aig/gia/giaMini.c
@@ -32,6 +32,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -57,7 +59,7 @@ int Gia_ObjFromMiniFanin1Copy( Gia_Man_t * pGia, Vec_Int_t * vCopies, Mini_Aig_t
int Lit = Mini_AigNodeFanin1( p, Id );
return Abc_LitNotCond( Vec_IntEntry(vCopies, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit) );
}
-Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
+Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies, int fGiaSimple )
{
Gia_Man_t * pGia, * pTemp;
Vec_Int_t * vCopies;
@@ -71,7 +73,10 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
vCopies = Vec_IntAlloc( nNodes );
Vec_IntPush( vCopies, 0 );
// iterate through the objects
- Gia_ManHashAlloc( pGia );
+ if ( fGiaSimple )
+ pGia->fGiaSimple = fGiaSimple;
+ else
+ Gia_ManHashAlloc( pGia );
for ( i = 1; i < nNodes; i++ )
{
if ( Mini_AigNodeIsPi( p, i ) )
@@ -83,17 +88,19 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
else assert( 0 );
Vec_IntPush( vCopies, iGiaLit );
}
- Gia_ManHashStop( pGia );
assert( Vec_IntSize(vCopies) == nNodes );
if ( pvCopies )
*pvCopies = vCopies;
else
Vec_IntFree( vCopies );
Gia_ManSetRegNum( pGia, Mini_AigRegNum(p) );
- pGia = Gia_ManCleanup( pTemp = pGia );
- if ( pvCopies )
- Gia_ManDupRemapLiterals( *pvCopies, pTemp );
- Gia_ManStop( pTemp );
+ if ( !fGiaSimple )
+ {
+ pGia = Gia_ManCleanup( pTemp = pGia );
+ if ( pvCopies )
+ Gia_ManDupRemapLiterals( *pvCopies, pTemp );
+ Gia_ManStop( pTemp );
+ }
return pGia;
}
@@ -148,7 +155,7 @@ void Abc_FrameGiaInputMiniAig( Abc_Frame_t * pAbc, void * p )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
Gia_ManStopP( &pAbc->pGiaMiniAig );
Vec_IntFreeP( &pAbc->vCopyMiniAig );
- pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig );
+ pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig, 0 );
Abc_FrameUpdateGia( pAbc, pGia );
pAbc->pGiaMiniAig = Gia_ManDup( pGia );
// Gia_ManDelete( pGia );
@@ -175,10 +182,10 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManReadMiniAig( char * pFileName )
+Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple )
{
Mini_Aig_t * p = Mini_AigLoad( pFileName );
- Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL );
+ Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
ABC_FREE( pGia->pName );
pGia->pName = Extra_FileNameGeneric( pFileName );
Mini_AigStop( p );
@@ -260,6 +267,65 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
return pGia;
}
+
+/**Function*************************************************************
+
+ Synopsis [Converts MiniLUT into GIA.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManFromMiniLut2( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
+{
+ Gia_Man_t * pGia;
+ Vec_Int_t * vCopies;
+ Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ int i, k, Fan, iGiaLit, nNodes;
+ // get the number of nodes
+ nNodes = Mini_LutNodeNum(p);
+ // create ABC network
+ pGia = Gia_ManStart( 3 * nNodes );
+ pGia->pName = Abc_UtilStrsav( "MiniLut" );
+ // create mapping from MiniLUT objects into ABC objects
+ vCopies = Vec_IntAlloc( nNodes );
+ Vec_IntPush( vCopies, 0 );
+ Vec_IntPush( vCopies, 1 );
+ // iterate through the objects
+ pGia->fGiaSimple = 1;
+ for ( i = 2; i < nNodes; i++ )
+ {
+ if ( Mini_LutNodeIsPi( p, i ) )
+ iGiaLit = Gia_ManAppendCi(pGia);
+ else if ( Mini_LutNodeIsPo( p, i ) )
+ iGiaLit = Gia_ManAppendCo(pGia, Vec_IntEntry(vCopies, Mini_LutNodeFanin(p, i, 0)));
+ else if ( Mini_LutNodeIsNode( p, i ) )
+ {
+ unsigned * puTruth = Mini_LutNodeTruth( p, i );
+ Vec_IntClear( vLits );
+ Mini_LutForEachFanin( p, i, Fan, k )
+ Vec_IntPush( vLits, Vec_IntEntry(vCopies, Fan) );
+ iGiaLit = Kit_TruthToGia( pGia, puTruth, Vec_IntSize(vLits), vCover, vLits, 0 );
+ }
+ else assert( 0 );
+ Vec_IntPush( vCopies, iGiaLit );
+ }
+ Vec_IntFree( vCover );
+ Vec_IntFree( vLits );
+ assert( Vec_IntSize(vCopies) == nNodes );
+ if ( pvCopies )
+ *pvCopies = vCopies;
+ else
+ Vec_IntFree( vCopies );
+ Gia_ManSetRegNum( pGia, Mini_LutRegNum(p) );
+ return pGia;
+}
+
+
/**Function*************************************************************
Synopsis [Marks LUTs that should be complemented.]
@@ -412,6 +478,15 @@ void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * p )
Abc_FrameUpdateGia( pAbc, pGia );
// Gia_ManDelete( pGia );
}
+void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * p )
+{
+ if ( pAbc == NULL )
+ printf( "ABC framework is not initialized by calling Abc_Start()\n" );
+ Vec_IntFreeP( &pAbc->vCopyMiniLut );
+ Gia_ManStopP( &pAbc->pGiaMiniLut );
+ pAbc->pGiaMiniLut = Gia_ManFromMiniLut2( (Mini_Lut_t *)p, &pAbc->vCopyMiniLut );
+// Abc_FrameUpdateGia( pAbc, pGia );
+}
void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc )
{
Mini_Lut_t * pRes = NULL;
@@ -589,6 +664,39 @@ int * Abc_FrameReadMiniLutNameMapping( Abc_Frame_t * pAbc )
Gia_ManStop( pGia );
return pRes;
}
+int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
+{
+ Vec_Int_t * vSwitching;
+ int i, iObj, * pRes = NULL;
+ if ( pAbc->pGiaMiniLut == NULL )
+ {
+ printf( "GIA derived from MiniLut is not available.\n" );
+ return NULL;
+ }
+ vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniLut, 48, 16, 0 );
+ pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) );
+ Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i )
+ if ( iObj >= 0 )
+ pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) ));
+ Vec_IntFree( vSwitching );
+ return pRes;
+}
+int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc )
+{
+ Vec_Int_t * vSwitching;
+ int i, iObj, * pRes = NULL;
+ if ( pAbc->pGiaMiniAig == NULL )
+ {
+ printf( "GIA derived from MiniAIG is not available.\n" );
+ return NULL;
+ }
+ vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniAig, 48, 16, 0 );
+ pRes = ABC_CALLOC( int, Gia_ManCoNum(pAbc->pGiaMiniAig) );
+ Gia_ManForEachCoDriverId( pAbc->pGiaMiniAig, iObj, i )
+ pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, iObj ));
+ Vec_IntFree( vSwitching );
+ return pRes;
+}
/**Function*************************************************************
@@ -797,6 +905,274 @@ void Gia_MiniAigVerify( Abc_Frame_t * pAbc, char * pFileName )
Mini_AigStop( p );
}
+/**Function*************************************************************
+
+ Synopsis [Collects supergate for the outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MiniAigSuperGates_rec( Mini_Aig_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vMap )
+{
+ int iFan0, iFan1;
+ if ( Mini_AigNodeIsPi(p, iObj) )
+ {
+ assert( Vec_IntEntry(vMap, iObj) >= 0 );
+ Vec_IntPush( vRes, Vec_IntEntry(vMap, iObj) );
+ return;
+ }
+ iFan0 = Mini_AigNodeFanin0( p, iObj );
+ iFan1 = Mini_AigNodeFanin1( p, iObj );
+ assert( !Abc_LitIsCompl(iFan0) );
+ assert( !Abc_LitIsCompl(iFan1) );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), vRes, vMap );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan1), vRes, vMap );
+}
+Vec_Wec_t * Gia_MiniAigSuperGates( Mini_Aig_t * p )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Mini_AigPoNum(p) );
+ Vec_Int_t * vMap = Vec_IntStartFull( Mini_AigNodeNum(p) );
+ int i, Index = 0;
+ Mini_AigForEachPi( p, i )
+ Vec_IntWriteEntry( vMap, i, Index++ );
+ assert( Index == Mini_AigPiNum(p) );
+ Index = 0;
+ Mini_AigForEachPo( p, i )
+ {
+ int iFan0 = Mini_AigNodeFanin0( p, i );
+ assert( !Abc_LitIsCompl(iFan0) );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), Vec_WecEntry(vRes, Index++), vMap );
+ }
+ assert( Index == Mini_AigPoNum(p) );
+ Vec_IntFree( vMap );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MiniAigSuperPrintDouble( Vec_Int_t * p, int nPis )
+{
+ int i, Entry;
+ printf( "\n" );
+ Vec_IntForEachEntry( p, Entry, i )
+ printf( "%d(%d) ", Entry%nPis, Entry/nPis );
+ printf( " Total = %d\n", Vec_IntSize(p) );
+}
+int Gia_MiniAigSuperMerge( Vec_Int_t * p, int nPis )
+{
+ int i, k = 0, This, Prev = -1, fChange = 0;
+ Vec_IntForEachEntry( p, This, i )
+ {
+ if ( Prev == This )
+ {
+ Vec_IntWriteEntry( p, k++, (This/nPis+1)*nPis + This%nPis );
+ Prev = -1;
+ fChange = 1;
+ }
+ else
+ {
+ if ( Prev != -1 )
+ Vec_IntWriteEntry( p, k++, Prev );
+ Prev = This;
+ }
+ }
+ if ( Prev != -1 )
+ Vec_IntWriteEntry( p, k++, Prev );
+ Vec_IntShrink( p, k );
+ return fChange;
+}
+int Gia_MiniAigSuperPreprocess( Mini_Aig_t * p, Vec_Wec_t * vSuper, int nPis, int fVerbose )
+{
+ Vec_Int_t * vRes;
+ int i, nIters, Multi = 1;
+ Vec_WecForEachLevel( vSuper, vRes, i )
+ {
+ Vec_IntSort( vRes, 0 );
+ if ( fVerbose )
+ printf( "\nOutput %d\n", i );
+ if ( fVerbose )
+ Gia_MiniAigSuperPrintDouble( vRes, nPis );
+ for ( nIters = 1; Gia_MiniAigSuperMerge(vRes, nPis); nIters++ )
+ {
+ if ( fVerbose )
+ Gia_MiniAigSuperPrintDouble( vRes, nPis );
+ }
+ Multi = Abc_MaxInt( Multi, nIters );
+ }
+ if ( fVerbose )
+ printf( "Multi = %d.\n", Multi );
+ return Multi;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_MiniAigSuperDeriveGia( Vec_Wec_t * p, int nPis, int Multi )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vTemp, * vLits = Vec_IntAlloc( 100 );
+ Vec_Int_t * vDrivers = Vec_IntAlloc(100);
+ int i, k, iObj, iLit, nInputs = nPis*Multi;
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "tree" );
+ for ( i = 0; i < nInputs; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Vec_WecForEachLevel( p, vTemp, i )
+ {
+ Vec_IntClear( vLits );
+ Vec_IntForEachEntry( vTemp, iObj, k )
+ {
+ assert( iObj < nInputs );
+ Vec_IntPush( vLits, 2+2*((iObj%nPis)*Multi+iObj/nPis) );
+ }
+ Vec_IntPush( vDrivers, Gia_ManHashAndMulti2(pNew, vLits) );
+ }
+ Gia_ManHashStop( pNew );
+ Vec_IntFree( vLits );
+ Vec_IntForEachEntry( vDrivers, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vDrivers );
+ return pNew;
+}
+Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose )
+{
+ Mini_Aig_t * p = Mini_AigLoad( pFileName );
+ Vec_Wec_t * vSuper = Gia_MiniAigSuperGates( p );
+ int Multi = Gia_MiniAigSuperPreprocess( p, vSuper, Mini_AigPiNum(p), fVerbose );
+ Gia_Man_t * pNew = Gia_MiniAigSuperDeriveGia( vSuper, Mini_AigPiNum(p), Multi );
+ Vec_WecFree( vSuper );
+ Mini_AigStop( p );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Process file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_MiniAigProcessFile()
+{
+ Vec_Int_t * vTriples = Vec_IntAlloc( 100 );
+ char * pFileName = "test.txt";
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ printf( "Cannot open the file.\n" );
+ else
+ {
+ int nLines = 0, nLinesAll = 0;
+ char * pToken;
+ char Buffer[1000];
+ while ( fgets( Buffer, 1000, pFile ) != NULL )
+ {
+ nLinesAll++;
+ if ( Buffer[0] != '#' )
+ continue;
+ //printf( "%s", Buffer );
+ nLines++;
+ pToken = strtok( Buffer+3, " \r\n\r+=" );
+ while ( pToken )
+ {
+ Vec_IntPush( vTriples, atoi(pToken) );
+ pToken = strtok( NULL, " \r\n\r+=" );
+ }
+ }
+ fclose( pFile );
+ printf( "Collected %d (out of %d) lines.\n", nLines, nLinesAll );
+ printf( "Entries = %d\n", Vec_IntSize(vTriples) );
+ }
+ return vTriples;
+}
+void Gia_MiniAigGenerate_rec( Mini_Aig_t * p, Vec_Int_t * vTriples, int iObj, Vec_Int_t * vDefs, Vec_Int_t * vMap )
+{
+ int Index, Entry0, Entry1, Entry2, Value;
+ if ( Vec_IntEntry(vMap, iObj) >= 0 )
+ return;
+ Index = Vec_IntEntry( vDefs, iObj );
+ Entry0 = Vec_IntEntry( vTriples, 3*Index+0 );
+ Entry1 = Vec_IntEntry( vTriples, 3*Index+1 );
+ Entry2 = Vec_IntEntry( vTriples, 3*Index+2 );
+ Gia_MiniAigGenerate_rec( p, vTriples, Entry1, vDefs, vMap );
+ Gia_MiniAigGenerate_rec( p, vTriples, Entry2, vDefs, vMap );
+ assert( Vec_IntEntry(vMap, Entry1) >= 0 );
+ assert( Vec_IntEntry(vMap, Entry2) >= 0 );
+ Value = Mini_AigAnd( p, Vec_IntEntry(vMap, Entry1), Vec_IntEntry(vMap, Entry2) );
+ Vec_IntWriteEntry( vMap, Entry0, Value );
+}
+void Gia_MiniAigGenerateFromFile()
+{
+ Mini_Aig_t * p = Mini_AigStart();
+ Vec_Int_t * vTriples = Gia_MiniAigProcessFile();
+ Vec_Int_t * vDefs = Vec_IntStartFull( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMap = Vec_IntStartFull( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMapIn = Vec_IntStart( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMapOut = Vec_IntStart( Vec_IntSize(vTriples) );
+ Vec_Int_t * vPis = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPos = Vec_IntAlloc( 100 );
+ int i, ObjOut, ObjIn;
+ assert( Vec_IntSize(vTriples) % 3 == 0 );
+ for ( i = 0; i < Vec_IntSize(vTriples)/3; i++ )
+ {
+ int Entry0 = Vec_IntEntry(vTriples, 3*i+0);
+ int Entry1 = Vec_IntEntry(vTriples, 3*i+1);
+ int Entry2 = Vec_IntEntry(vTriples, 3*i+2);
+ Vec_IntWriteEntry( vDefs, Entry0, i );
+ Vec_IntAddToEntry( vMapOut, Entry0, 1 );
+ Vec_IntAddToEntry( vMapIn, Entry1, 1 );
+ Vec_IntAddToEntry( vMapIn, Entry2, 1 );
+ }
+ Vec_IntForEachEntryTwo( vMapOut, vMapIn, ObjOut, ObjIn, i )
+ if ( !ObjOut && ObjIn )
+ Vec_IntPush( vPis, i );
+ else if ( ObjOut && !ObjIn )
+ Vec_IntPush( vPos, i );
+ Vec_IntForEachEntry( vPis, ObjIn, i )
+ Vec_IntWriteEntry( vMap, ObjIn, Mini_AigCreatePi(p) );
+ Vec_IntForEachEntry( vPos, ObjOut, i )
+ Gia_MiniAigGenerate_rec( p, vTriples, ObjOut, vDefs, vMap );
+ Vec_IntForEachEntry( vPos, ObjOut, i )
+ {
+ assert( Vec_IntEntry(vMap, ObjOut) >= 0 );
+ Mini_AigCreatePo( p, Vec_IntEntry(vMap, ObjOut) );
+ }
+ Vec_IntFree( vTriples );
+ Vec_IntFree( vDefs );
+ Vec_IntFree( vMap );
+ Vec_IntFree( vMapIn );
+ Vec_IntFree( vMapOut );
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPos );
+ Mini_AigDump( p, "test.miniaig" );
+ Mini_AigStop( p );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c
new file mode 100644
index 00000000..f14ce34a
--- /dev/null
+++ b/src/aig/gia/giaPat2.c
@@ -0,0 +1,1329 @@
+/**CFile****************************************************************
+
+ FileName [giaPat2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Pattern generation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaPat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/vec/vecHsh.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satStore.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Min_Man_t_ Min_Man_t;
+struct Min_Man_t_
+{
+ int nCis;
+ int nCos;
+ int FirstAndLit;
+ int FirstCoLit;
+ Vec_Int_t vFans;
+ Vec_Str_t vValsN;
+ Vec_Str_t vValsL;
+ Vec_Int_t vVis;
+ Vec_Int_t vPat;
+};
+
+static inline int Min_ManCiNum( Min_Man_t * p ) { return p->nCis; }
+static inline int Min_ManCoNum( Min_Man_t * p ) { return p->nCos; }
+static inline int Min_ManObjNum( Min_Man_t * p ) { return Vec_IntSize(&p->vFans) >> 1; }
+static inline int Min_ManAndNum( Min_Man_t * p ) { return Min_ManObjNum(p) - p->nCis - p->nCos - 1; }
+
+static inline int Min_ManCi( Min_Man_t * p, int i ) { return 1 + i; }
+static inline int Min_ManCo( Min_Man_t * p, int i ) { return Min_ManObjNum(p) - Min_ManCoNum(p) + i; }
+
+static inline int Min_ObjIsCi( Min_Man_t * p, int i ) { return i > 0 && i <= Min_ManCiNum(p); }
+static inline int Min_ObjIsNode( Min_Man_t * p, int i ) { return i > Min_ManCiNum(p) && i < Min_ManObjNum(p) - Min_ManCoNum(p); }
+static inline int Min_ObjIsAnd( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) < Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsXor( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) > Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsBuf( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) ==Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsCo( Min_Man_t * p, int i ) { return i >= Min_ManObjNum(p) - Min_ManCoNum(p) && i < Min_ManObjNum(p); }
+
+static inline int Min_ObjLit( Min_Man_t * p, int i, int n ) { return Vec_IntEntry(&p->vFans, i + i + n); }
+static inline int Min_ObjLit0( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 0); }
+static inline int Min_ObjLit1( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 1); }
+static inline int Min_ObjCioId( Min_Man_t * p, int i ) { assert( i && !Min_ObjIsNode(p, i) ); return Min_ObjLit1(p, i); }
+
+static inline int Min_ObjFan0( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit0(p, i) ); }
+static inline int Min_ObjFan1( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit1(p, i) ); }
+
+static inline int Min_ObjFanC0( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit0(p, i) ); }
+static inline int Min_ObjFanC1( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit1(p, i) ); }
+
+static inline char Min_ObjValN( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsN, i); }
+static inline void Min_ObjSetValN( Min_Man_t * p, int i, char v ){ Vec_StrWriteEntry(&p->vValsN, i, v); }
+
+static inline char Min_LitValL( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsL, i); }
+static inline void Min_LitSetValL( Min_Man_t * p, int i, char v ){ assert(v==0 || v==1); Vec_StrWriteEntry(&p->vValsL, i, v); Vec_StrWriteEntry(&p->vValsL, i^1, (char)!v); Vec_IntPush(&p->vVis, Abc_Lit2Var(i)); }
+static inline void Min_ObjCleanValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] = 0x0202; }
+static inline void Min_ObjMarkValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0404; }
+static inline void Min_ObjMark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0808; }
+static inline void Min_ObjUnmark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] &= 0xF7F7; }
+
+static inline int Min_LitIsCi( Min_Man_t * p, int v ) { return v > 1 && v < p->FirstAndLit; }
+static inline int Min_LitIsNode( Min_Man_t * p, int v ) { return v >= p->FirstAndLit && v < p->FirstCoLit; }
+static inline int Min_LitIsCo( Min_Man_t * p, int v ) { return v >= p->FirstCoLit; }
+
+static inline int Min_LitIsAnd( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 < v1); }
+static inline int Min_LitIsXor( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 > v1); }
+static inline int Min_LitIsBuf( int v, int v0, int v1 ) { return v0 == v1; }
+
+static inline int Min_LitFan( Min_Man_t * p, int v ) { return Vec_IntEntry(&p->vFans, v); }
+static inline int Min_LitFanC( Min_Man_t * p, int v ) { return Abc_LitIsCompl( Min_LitFan(p, v) ); }
+
+static inline void Min_ManStartValsN( Min_Man_t * p ) { Vec_StrGrow(&p->vValsN, Vec_IntCap(&p->vFans)/2); Vec_StrFill(&p->vValsN, Min_ManObjNum(p), 2); }
+static inline void Min_ManStartValsL( Min_Man_t * p ) { Vec_StrGrow(&p->vValsL, Vec_IntCap(&p->vFans)); Vec_StrFill(&p->vValsL, Vec_IntSize(&p->vFans), 2); }
+static inline int Min_ManCheckCleanValsL( Min_Man_t * p ) { int i; char c; Vec_StrForEachEntry( &p->vValsL, c, i ) if ( c != 2 ) return 0; return 1; }
+static inline void Min_ManCleanVisitedValL( Min_Man_t * p ) { int i, iObj; Vec_IntForEachEntry(&p->vVis, iObj, i) Min_ObjCleanValL(p, iObj); Vec_IntClear(&p->vVis); }
+
+
+#define Min_ManForEachObj( p, i ) \
+ for ( i = 0; i < Min_ManObjNum(p); i++ )
+#define Min_ManForEachCi( p, i ) \
+ for ( i = 1; i <= Min_ManCiNum(p); i++ )
+#define Min_ManForEachCo( p, i ) \
+ for ( i = Min_ManObjNum(p) - Min_ManCoNum(p); i < Min_ManObjNum(p); i++ )
+#define Min_ManForEachAnd( p, i ) \
+ for ( i = 1 + Min_ManCiNum(p); i < Min_ManObjNum(p) - Min_ManCoNum(p); i++ )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Min_Man_t * Min_ManStart( int nObjMax )
+{
+ Min_Man_t * p = ABC_CALLOC( Min_Man_t, 1 );
+ Vec_IntGrow( &p->vFans, nObjMax );
+ Vec_IntPushTwo( &p->vFans, -1, -1 );
+ return p;
+}
+static inline void Min_ManStop( Min_Man_t * p )
+{
+ Vec_IntErase( &p->vFans );
+ Vec_StrErase( &p->vValsN );
+ Vec_StrErase( &p->vValsL );
+ Vec_IntErase( &p->vVis );
+ Vec_IntErase( &p->vPat );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Min_ManAppendObj( Min_Man_t * p, int iLit0, int iLit1 )
+{
+ int iLit = Vec_IntSize(&p->vFans);
+ Vec_IntPushTwo( &p->vFans, iLit0, iLit1 );
+ return iLit;
+}
+static inline int Min_ManAppendCi( Min_Man_t * p )
+{
+ p->nCis++;
+ p->FirstAndLit = Vec_IntSize(&p->vFans) + 2;
+ return Min_ManAppendObj( p, 0, p->nCis-1 );
+}
+static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 )
+{
+ p->nCos++;
+ if ( p->FirstCoLit == 0 )
+ p->FirstCoLit = Vec_IntSize(&p->vFans);
+ return Min_ManAppendObj( p, iLit0, p->nCos-1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) );
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) );
+ pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
+{
+ Gia_Obj_t * pObj; int i;
+ Min_Man_t * pNew = Min_ManStart( Gia_ManObjNum(p) );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Min_ManAppendCi( pNew );
+ if ( vOuts == NULL )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) );
+ }
+ else
+ {
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Min_XsimNot( char Val )
+{
+ if ( Val < 2 )
+ return Val ^ 1;
+ return 2;
+}
+static inline char Min_XsimXor( char Val0, char Val1 )
+{
+ if ( Val0 < 2 && Val1 < 2 )
+ return Val0 ^ Val1;
+ return 2;
+}
+static inline char Min_XsimAnd( char Val0, char Val1 )
+{
+ if ( Val0 == 0 || Val1 == 0 )
+ return 0;
+ if ( Val0 == 1 && Val1 == 1 )
+ return 1;
+ return 2;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char Min_LitVerify_rec( Min_Man_t * p, int iLit )
+{
+ char Val = Min_LitValL(p, iLit);
+ if ( Val == 2 && Min_LitIsNode(p, iLit) ) // unassigned
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitVerify_rec( p, iLit0 );
+ char Val1 = Min_LitVerify_rec( p, iLit1 );
+ assert( Val0 < 3 && Val1 < 3 );
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ else
+ Vec_IntPush( &p->vVis, Abc_Lit2Var(iLit) );
+ Min_ObjMark2ValL( p, Abc_Lit2Var(iLit) );
+ }
+ return Val&3;
+}
+char Min_LitVerify( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
+{
+ int i, Entry; char Res;
+ if ( iLit < 2 ) return 1;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ Vec_IntForEachEntry( vLits, Entry, i )
+ Min_LitSetValL( p, Entry, 1 ); // ms notation
+ Res = Min_LitVerify_rec( p, iLit );
+ Min_ManCleanVisitedValL( p );
+ return Res;
+}
+
+void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
+{
+ int i, iObj, iTemp; char Res;
+ Vec_IntClear( &p->vPat );
+ if ( iLit < 2 ) return;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ Vec_IntForEachEntry( vLits, iTemp, i )
+ Min_LitSetValL( p, iTemp, 1 ); // ms notation
+ Res = Min_LitVerify_rec( p, iLit );
+ assert( Res == 1 );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit) );
+ Vec_IntForEachEntryReverse( &p->vVis, iObj, i )
+ {
+ int iLit = Abc_Var2Lit( iObj, 0 );
+ int Value = 7 & Min_LitValL(p, iLit);
+ if ( Value >= 4 )
+ {
+ if ( Min_LitIsCi(p, iLit) )
+ Vec_IntPush( &p->vPat, Abc_LitNotCond(iLit, !(Value&1)) );
+ else
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL( p, iLit0 );
+ char Val1 = Min_LitValL( p, iLit1 );
+ if ( Value&1 ) // value == 1
+ {
+ assert( (Val0&1) && (Val1&1) );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ }
+ else // value == 0
+ {
+ int Zero0 = !(Val0&3);
+ int Zero1 = !(Val1&3);
+ assert( Zero0 || Zero1 );
+ if ( Zero0 && !Zero1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else if ( !Zero0 && Zero1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ else if ( Val0 == 4 && Val1 != 4 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else if ( Val1 == 4 && Val1 != 4 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ else if ( Abc_Random(0) & 1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ }
+ }
+ }
+ Min_ObjCleanValL( p, Abc_Lit2Var(iLit) );
+ }
+ Vec_IntClear( &p->vVis );
+ //Min_ManCleanVisitedValL( p );
+ //assert( Min_LitVerify(p, iLit, &p->vPat) == 1 );
+ assert( Vec_IntSize(&p->vPat) <= Vec_IntSize(vLits) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Min_LitIsImplied1( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied1(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied1(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied2(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied2(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied3(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied3(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied4(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied4(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+
+// this recursive procedure is about 10% slower
+char Min_LitIsImplied_rec( Min_Man_t * p, int iLit, int Depth )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Depth > 0 );
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Depth > 1 && Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied_rec(p, iLit0, Depth-1);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Depth > 1 && Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied_rec(p, iLit1, Depth-1);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+int Min_LitJustify_rec( Min_Man_t * p, int iLit )
+{
+ int Res = 1, LitValue = !Abc_LitIsCompl(iLit);
+ int Val = (int)Min_LitValL(p, iLit);
+ if ( Val < 2 ) // assigned
+ return Val == LitValue;
+ // unassigned
+ if ( Min_LitIsCi(p, iLit) )
+ Vec_IntPush( &p->vPat, iLit ); // ms notation
+ else
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ {
+ if ( Val0 < 2 && Val1 < 2 )
+ Res = LitValue == (Val0 ^ Val1);
+ else if ( Val0 < 2 )
+ Res = Min_LitJustify_rec(p, iLit1^Val0^!LitValue);
+ else if ( Val1 < 2 )
+ Res = Min_LitJustify_rec(p, iLit0^Val1^!LitValue);
+ else if ( Abc_Random(0) & 1 )
+ Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1^ LitValue);
+ else
+ Res = Min_LitJustify_rec(p, iLit0^1) && Min_LitJustify_rec(p, iLit1^!LitValue);
+ assert( !Res || LitValue == Min_XsimXor(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ else if ( LitValue ) // value 1
+ {
+ if ( Val0 == 0 || Val1 == 0 )
+ Res = 0;
+ else if ( Val0 == 1 && Val1 == 1 )
+ Res = 1;
+ else if ( Val0 == 1 )
+ Res = Min_LitJustify_rec(p, iLit1);
+ else if ( Val1 == 1 )
+ Res = Min_LitJustify_rec(p, iLit0);
+ else
+ Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1);
+ assert( !Res || 1 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ else // value 0
+ {
+/*
+ int Depth = 3;
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied_rec(p, iLit0, Depth);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied_rec(p, iLit1, Depth);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+*/
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied3(p, iLit0);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied3(p, iLit1);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+ if ( Val0 == 0 || Val1 == 0 )
+ Res = 1;
+ else if ( Val0 == 1 && Val1 == 1 )
+ Res = 0;
+ else if ( Val0 == 1 )
+ Res = Min_LitJustify_rec(p, iLit1^1);
+ else if ( Val1 == 1 )
+ Res = Min_LitJustify_rec(p, iLit0^1);
+ else if ( Abc_Random(0) & 1 )
+ //else if ( (p->Random >> (iLit & 0x1F)) & 1 )
+ Res = Min_LitJustify_rec(p, iLit0^1);
+ else
+ Res = Min_LitJustify_rec(p, iLit1^1);
+ //Val0 = Min_LitValL(p, iLit0);
+ //Val1 = Min_LitValL(p, iLit1);
+ assert( !Res || 0 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ }
+ if ( Res )
+ Min_LitSetValL( p, iLit, 1 );
+ return Res;
+}
+int Min_LitJustify( Min_Man_t * p, int iLit )
+{
+ int Res, fCheck = 0;
+ Vec_IntClear( &p->vPat );
+ if ( iLit < 2 ) return 1;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ //p->Random = Abc_Random(0);
+ Res = Min_LitJustify_rec( p, iLit );
+ Min_ManCleanVisitedValL( p );
+ if ( Res )
+ {
+ if ( fCheck && Min_LitVerify(p, iLit, &p->vPat) != 1 )
+ printf( "Verification FAILED for literal %d.\n", iLit );
+ //else
+ // printf( "Verification succeeded for literal %d.\n", iLit );
+ }
+ //else
+ // printf( "Could not justify literal %d.\n", iLit );
+ return Res;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Min_TargGenerateCexes( Min_Man_t * p, Vec_Int_t * vCoErrs, int nCexes, int nCexesStop, int * pnComputed, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ int t, iObj, Count = 0, CountPos = 0, CountPosSat = 0, nRuns[2] = {0}, nCountCexes[2] = {0};
+ Vec_Int_t * vPats = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vPatBest = Vec_IntAlloc( Min_ManCiNum(p) );
+ Hsh_VecMan_t * pHash = Hsh_VecManStart( 10000 );
+ Min_ManForEachCo( p, iObj ) if ( Min_ObjLit0(p, iObj) > 1 )
+ {
+ int nCexesGenSim0 = 0;
+ int nCexesGenSim = 0;
+ int nCexesGenSat = 0;
+ if ( vCoErrs && Vec_IntEntry(vCoErrs, Min_ObjCioId(p, iObj)) >= nCexesStop )
+ continue;
+ //printf( "%d ", i );
+ for ( t = 0; t < nCexes; t++ )
+ {
+ nRuns[0]++;
+ if ( Min_LitJustify( p, Min_ObjLit0(p, iObj) ) )
+ {
+ int Before, After;
+ assert( Vec_IntSize(&p->vPat) > 0 );
+ //printf( "%d ", Vec_IntSize(vPat) );
+ Vec_IntClear( vPatBest );
+ if ( 1 ) // no minimization
+ Vec_IntAppend( vPatBest, &p->vPat );
+ else
+ {
+/*
+ for ( k = 0; k < 10; k++ )
+ {
+ Vec_IntClear( vPat2 );
+ Gia_ManIncrementTravId( p );
+ Cexes_MinimizePattern_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat2 );
+ assert( Vec_IntSize(vPat2) <= Vec_IntSize(vPat) );
+ if ( Vec_IntSize(vPatBest) == 0 || Vec_IntSize(vPatBest) > Vec_IntSize(vPat2) )
+ {
+ Vec_IntClear( vPatBest );
+ Vec_IntAppend( vPatBest, vPat2 );
+ }
+ //printf( "%d ", Vec_IntSize(vPat2) );
+ }
+*/
+ }
+
+ //Gia_CexVerify( p, Gia_ObjFaninId0p(p, pObj), !Gia_ObjFaninC0(pObj), vPatBest );
+ //printf( "\n" );
+ Before = Hsh_VecSize( pHash );
+ Vec_IntSort( vPatBest, 0 );
+ Hsh_VecManAdd( pHash, vPatBest );
+ After = Hsh_VecSize( pHash );
+ if ( Before != After )
+ {
+ Vec_IntPush( vPats, Min_ObjCioId(p, iObj) );
+ Vec_IntPush( vPats, Vec_IntSize(vPatBest) );
+ Vec_IntAppend( vPats, vPatBest );
+ nCexesGenSim++;
+ }
+ nCexesGenSim0++;
+ if ( nCexesGenSim0 > nCexesGenSim*10 )
+ {
+ printf( "**** Skipping output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) );
+ break;
+ }
+ }
+ if ( nCexesGenSim == nCexesStop )
+ break;
+ }
+ //printf( "(%d %d) ", nCexesGenSim0, nCexesGenSim );
+ //printf( "%d ", t/nCexesGenSim );
+
+ //printf( "The number of CEXes = %d\n", nCexesGen );
+ //if ( fVerbose )
+ // printf( "%d ", nCexesGen );
+ nCountCexes[0] += nCexesGenSim;
+ nCountCexes[1] += nCexesGenSat;
+ Count += nCexesGenSim + nCexesGenSat;
+ CountPos++;
+
+ if ( nCexesGenSim0 == 0 && t == nCexes )
+ printf( "#### Output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) );
+ }
+ //printf( "\n" );
+ if ( fVerbose )
+ printf( "\n" );
+ if ( fVerbose )
+ printf( "Got %d unique CEXes using %d sim (%d) and %d SAT (%d) runs (ave size %.1f). PO = %d ErrPO = %d SatPO = %d ",
+ Count, nRuns[0], nCountCexes[0], nRuns[1], nCountCexes[1],
+ 1.0*Vec_IntSize(vPats)/Abc_MaxInt(1, Count)-2, Min_ManCoNum(p), CountPos, CountPosSat );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ Hsh_VecManStop( pHash );
+ Vec_IntFree( vPatBest );
+ *pnComputed = Count;
+ return vPats;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Min_ManTest3( Gia_Man_t * p, Vec_Int_t * vCoErrs )
+{
+ int fXor = 0;
+ int nComputed;
+ Vec_Int_t * vPats;
+ Gia_Man_t * pXor = fXor ? Gia_ManDupMuxes(p, 1) : NULL;
+ Min_Man_t * pNew = Min_ManFromGia( fXor ? pXor : p, NULL );
+ Gia_ManStopP( &pXor );
+ Min_ManStartValsL( pNew );
+ //Vec_IntFill( vCoErrs, Vec_IntSize(vCoErrs), 0 );
+ //vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 );
+ vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 );
+ Vec_IntFree( vPats );
+ Min_ManStop( pNew );
+}
+void Min_ManTest4( Gia_Man_t * p )
+{
+ Vec_Int_t * vCoErrs = Vec_IntStartNatural( Gia_ManCoNum(p) );
+ Min_ManTest3(p, vCoErrs);
+ Vec_IntFree( vCoErrs );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupCones2CollectPis_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMap )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId0(pObj, iObj), vMap );
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId1(pObj, iObj), vMap );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ Vec_IntPush( vMap, iObj );
+ else assert( 0 );
+}
+void Gia_ManDupCones2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsCi(pObj) || Gia_ObjUpdateTravIdCurrent(p, pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupCones2( Gia_Man_t * p, int * pOuts, int nOuts, Vec_Int_t * vMap )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj; int i;
+ Vec_IntClear( vMap );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ManCoDriverId(p, pOuts[i]), vMap );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(Gia_ManCo(p, pOuts[i])) );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p, pOuts[i])) );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Min_ManRemoveItem( Vec_Wec_t * vCexes, int iItem, int iFirst, int iLimit )
+{
+ Vec_Int_t * vLevel, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i;
+ assert( iFirst <= iItem && iItem < iLimit );
+ Vec_WecForEachLevelReverseStartStop( vCexes, vLevel, i, iLimit, iFirst )
+ if ( Vec_IntSize(vLevel) > 0 )
+ break;
+ assert( iFirst <= i && iItem <= i );
+ Vec_IntClear( vLevel0 );
+ if ( iItem < i )
+ ABC_SWAP( Vec_Int_t, *vLevel0, *vLevel );
+ return -1;
+}
+int Min_ManAccumulate( Vec_Wec_t * vCexes, int iFirst, int iLimit, Vec_Int_t * vCex )
+{
+ Vec_Int_t * vLevel; int i, nCommon, nDiff = 0;
+ Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ {
+ Vec_IntAppend(vLevel, vCex);
+ return nDiff+1;
+ }
+ nCommon = Vec_IntTwoCountCommon( vLevel, vCex );
+ if ( nCommon == Vec_IntSize(vLevel) ) // ignore vCex
+ return nDiff;
+ if ( nCommon == Vec_IntSize(vCex) ) // remove vLevel
+ nDiff += Min_ManRemoveItem( vCexes, i, iFirst, iLimit );
+ }
+ assert( 0 );
+ return ABC_INFINITY;
+}
+int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit )
+{
+ Vec_Int_t * vLevel; int i, nTotal = 0;
+ Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit )
+ nTotal += Vec_IntSize(vLevel) > 0;
+ return nTotal;
+}
+Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose )
+{
+ Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) );
+ Min_Man_t * pNew = Min_ManFromGia( p, vOuts );
+ Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes );
+ Vec_Int_t * vPatBest = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj; int i, iObj, nOuts = 0, nSimOuts = 0, nSatOuts = 0;
+ vStats[0] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // total calls
+ vStats[1] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // successful calls + SAT runs
+ vStats[2] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // results
+ Min_ManStartValsL( pNew );
+ Min_ManForEachCo( pNew, iObj )
+ {
+ int nAllCalls = 0;
+ int nGoodCalls = 0;
+ int nCurrCexes = 0;
+ if ( fUseSim && Min_ObjLit0(pNew, iObj) >= 2 )
+ {
+ while ( nAllCalls++ < nMaxTries )
+ {
+ if ( Min_LitJustify( pNew, Min_ObjLit0(pNew, iObj) ) )
+ {
+ Vec_IntClearAppend( vLits, &pNew->vPat );
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ if ( 1 ) // minimization
+ {
+ //printf( "%d -> ", Vec_IntSize(vPatBest) );
+ for ( i = 0; i < 20; i++ )
+ {
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) )
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ }
+ //printf( "%d ", Vec_IntSize(vPatBest) );
+ }
+ assert( Vec_IntSize(vPatBest) > 0 );
+ Vec_IntSort( vPatBest, 0 );
+ nCurrCexes += Min_ManAccumulate( vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes, vPatBest );
+ nGoodCalls++;
+ }
+ if ( nCurrCexes == nMinCexes || nGoodCalls > 10*nCurrCexes )
+ break;
+ }
+ nSimOuts++;
+ }
+ assert( nCurrCexes <= nMinCexes );
+ assert( nCurrCexes == Min_ManCountSize(vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes) );
+ Vec_IntPush( vStats[0], nAllCalls );
+ Vec_IntPush( vStats[1], nGoodCalls );
+ Vec_IntPush( vStats[2], nCurrCexes );
+ nOuts++;
+ }
+ assert( Vec_IntSize(vOuts) == nOuts );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) );
+
+ if ( fUseSat )
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ {
+ if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
+ continue;
+ {
+ int iObj = Min_ManCo(pNew, i);
+ int Index = Gia_ObjCioId(pObj);
+ Vec_Int_t * vMap = Vec_IntAlloc( 100 );
+ Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 );
+ sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ int Lit = Abc_Var2Lit( 1, 0 );
+ int status = sat_solver_addclause( pSat, &Lit, &Lit+1 );
+ int nAllCalls = 0;
+ int nCurrCexes = Vec_IntEntry(vStats[2], i);
+ //Gia_AigerWrite( pCon, "temp_miter.aig", 0, 0, 0 );
+ if ( status == l_True )
+ {
+ nSatOuts++;
+ //printf( "Running SAT for output %d\n", i );
+ if ( Min_ObjLit0(pNew, iObj) >= 2 )
+ {
+ while ( nAllCalls++ < 100 )
+ {
+ int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon);
+ sat_solver_randomize( pSat, iVar, nVars );
+ status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
+ assert( status == l_True );
+ Vec_IntClear( vLits );
+ for ( v = 0; v < nVars; v++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(Vec_IntEntry(vMap, v), !sat_solver_var_value(pSat, iVar + v)) );
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ if ( 1 ) // minimization
+ {
+ //printf( "%d -> ", Vec_IntSize(vPatBest) );
+ for ( v = 0; v < 20; v++ )
+ {
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) )
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ }
+ //printf( "%d ", Vec_IntSize(vPatBest) );
+ }
+ Vec_IntSort( vPatBest, 0 );
+ nCurrCexes += Min_ManAccumulate( vCexes, i*nMinCexes, (i+1)*nMinCexes, vPatBest );
+ if ( nCurrCexes == nMinCexes || nAllCalls > 10*nCurrCexes )
+ break;
+ }
+ }
+ }
+ Vec_IntWriteEntry( vStats[0], i, nAllCalls*nMaxTries );
+ Vec_IntWriteEntry( vStats[1], i, nAllCalls*nMaxTries );
+ Vec_IntWriteEntry( vStats[2], i, nCurrCexes );
+ sat_solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ Gia_ManStop( pCon );
+ Vec_IntFree( vMap );
+ }
+ }
+ if ( fVerbose )
+ printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );
+ //Vec_WecPrint( vCexes, 0 );
+ if ( vOuts != vOuts0 )
+ Vec_IntFreeP( &vOuts );
+ Min_ManStop( pNew );
+ Vec_IntFree( vPatBest );
+ Vec_IntFree( vLits );
+ return vCexes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Bit-packing for selected patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Min_ManBitPackTry( Vec_Wrd_t * vSimsPi, int nWords, int iPat, Vec_Int_t * vLits )
+{
+ int i, Lit;
+ assert( iPat >= 0 && iPat < 64 * nWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ if ( Abc_InfoHasBit( (unsigned *)pCare, iPat ) &&
+ Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation
+ return 0;
+ }
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ Abc_InfoSetBit( (unsigned *)pCare, iPat );
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation
+ Abc_InfoXorBit( (unsigned *)pInfo, iPat );
+ }
+ return 1;
+}
+int Min_ManBitPackOne( Vec_Wrd_t * vSimsPi, int iPat0, int nWords, Vec_Int_t * vLits )
+{
+ int iPat, nTotal = 64*nWords;
+ for ( iPat = iPat0 + 1; iPat != iPat0; iPat = (iPat + 1) % nTotal )
+ if ( Min_ManBitPackTry( vSimsPi, nWords, iPat, vLits ) )
+ break;
+ return iPat;
+}
+Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_WecSize(vCexes) );
+ int i, c, nOuts = Vec_WecSize(vCexes)/nMinCexes;
+ for ( i = 0; i < nMinCexes; i++ )
+ for ( c = 0; c < nOuts; c++ )
+ {
+ Vec_Int_t * vLevel = Vec_WecEntry( vCexes, c*nMinCexes+i );
+ if ( Vec_IntSize(vLevel) )
+ Vec_PtrPush( vRes, vLevel );
+ }
+ return vRes;
+}
+
+Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ int fVeryVerbose = 0;
+ Vec_Wrd_t * vSimsPi = NULL;
+ Vec_Int_t * vLevel;
+ int w, nBits, nTotal = 0, fFailed = ABC_INFINITY;
+ Vec_Int_t * vOrder = NULL;
+ Vec_Ptr_t * vReload = NULL;
+ if ( 0 )
+ {
+ vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes );
+ assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) );
+ assert( Vec_WecSize(vCexes)%nMinCexes == 0 );
+ Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) );
+ }
+ else
+ vReload = Min_ReloadCexes( vCexes, nMinCexes );
+ if ( fVerbose )
+ printf( "Packing: " );
+ for ( w = nWords0 ? nWords0 : 1; nWords0 ? w <= nWords0 : fFailed > 0; w++ )
+ {
+ int i, iPatUsed, iPat = 0;
+ //int k, iOut;
+ Vec_WrdFreeP( &vSimsPi );
+ vSimsPi = fRandom ? Vec_WrdStartRandom(2 * Gia_ManCiNum(p) * w) : Vec_WrdStart(2 * Gia_ManCiNum(p) * w);
+ Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 );
+ Abc_TtClear( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) );
+ fFailed = nTotal = 0;
+ //Vec_IntForEachEntry( vOrder, iOut, k )
+ //Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes )
+ Vec_PtrForEachEntry( Vec_Int_t *, vReload, vLevel, i )
+ {
+ //if ( fVeryVerbose && i%nMinCexes == 0 )
+ // printf( "\n" );
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ iPatUsed = Min_ManBitPackOne( vSimsPi, iPat, w, vLevel );
+ fFailed += iPatUsed == iPat;
+ iPat = (iPatUsed + 1) % (64*(w-1) - 1);
+ //if ( fVeryVerbose )
+ //printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed );
+ //if ( fVeryVerbose )
+ //Vec_IntPrint( vLevel );
+ nTotal++;
+ }
+ if ( fVerbose )
+ printf( "W = %d (F = %d) ", w, fFailed );
+// printf( "Failed patterns = %d\n", fFailed );
+ }
+ if ( fVerbose )
+ printf( "Total = %d\n", nTotal );
+ if ( fVerbose )
+ {
+ nBits = Abc_TtCountOnesVec( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) );
+ printf( "Bit-packing is using %d words and %d bits. Density =%8.4f %%. ",
+ Vec_WrdSize(vSimsPi)/Gia_ManCiNum(p), nBits, 100.0*nBits/64/Vec_WrdSize(vSimsPi) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+ Vec_IntFreeP( &vOrder );
+ Vec_PtrFreeP( &vReload );
+ return vSimsPi;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Patt_ManOutputErrorCoverage( Vec_Wrd_t * vErrors, int nOuts )
+{
+ Vec_Int_t * vCounts = Vec_IntAlloc( nOuts );
+ int i, nWords = Vec_WrdSize(vErrors)/nOuts;
+ assert( Vec_WrdSize(vErrors) == nOuts * nWords );
+ for ( i = 0; i < nOuts; i++ )
+ Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vErrors, nWords * i), nWords) );
+ return vCounts;
+}
+Vec_Wrd_t * Patt_ManTransposeErrors( Vec_Wrd_t * vErrors, int nOuts )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ int nWordsIn = Vec_WrdSize(vErrors) / nOuts;
+ int nWordsOut = Abc_Bit6WordNum(nOuts);
+ Vec_Wrd_t * vSims1 = Vec_WrdStart( 64*nWordsIn*nWordsOut );
+ Vec_Wrd_t * vSims2 = Vec_WrdStart( 64*nWordsIn*nWordsOut );
+ assert( Vec_WrdSize(vErrors) == nWordsIn * nOuts );
+ Abc_TtCopy( Vec_WrdArray(vSims1), Vec_WrdArray(vErrors), Vec_WrdSize(vErrors), 0 );
+ Extra_BitMatrixTransposeP( vSims1, nWordsIn, vSims2, nWordsOut );
+ Vec_WrdFree( vSims1 );
+ return vSims2;
+}
+Vec_Int_t * Patt_ManPatternErrorCoverage( Vec_Wrd_t * vErrors, int nOuts )
+{
+ int nWords = Vec_WrdSize(vErrors)/nOuts;
+ Vec_Wrd_t * vErrors2 = Patt_ManTransposeErrors( vErrors, nOuts );
+ Vec_Int_t * vPatErrs = Patt_ManOutputErrorCoverage( vErrors2, 64*nWords );
+ Vec_WrdFree( vErrors2 );
+ return vPatErrs;
+}
+
+#define ERR_REPT_SIZE 32
+void Patt_ManProfileErrors( Vec_Int_t * vOutErrs, Vec_Int_t * vPatErrs )
+{
+ int nOuts = Vec_IntSize(vOutErrs);
+ int nPats = Vec_IntSize(vPatErrs);
+ int ErrOuts[ERR_REPT_SIZE+1] = {0};
+ int ErrPats[ERR_REPT_SIZE+1] = {0};
+ int i, Errs, nErrors1 = 0, nErrors2 = 0;
+ Vec_IntForEachEntry( vOutErrs, Errs, i )
+ {
+ nErrors1 += Errs;
+ ErrOuts[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++;
+ }
+ Vec_IntForEachEntry( vPatErrs, Errs, i )
+ {
+ nErrors2 += Errs;
+ ErrPats[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++;
+ }
+ assert( nErrors1 == nErrors2 );
+ // errors/error_outputs/error_patterns
+ //printf( "\nError statistics:\n" );
+ printf( "Errors =%6d ", nErrors1 );
+ printf( "ErrPOs =%5d (Ave = %5.2f) ", nOuts-ErrOuts[0], 1.0*nErrors1/Abc_MaxInt(1, nOuts-ErrOuts[0]) );
+ printf( "Patterns =%5d (Ave = %5.2f) ", nPats, 1.0*nErrors1/nPats );
+ printf( "Density =%8.4f %%\n", 100.0*nErrors1/nPats/Abc_MaxInt(1, nOuts-ErrOuts[0]) );
+ // how many times each output fails
+ printf( "Outputs: " );
+ for ( i = 0; i <= ERR_REPT_SIZE; i++ )
+ if ( ErrOuts[i] )
+ printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrOuts[i] );
+ printf( "\n" );
+ // how many times each patterns fails an output
+ printf( "Patterns: " );
+ for ( i = 0; i <= ERR_REPT_SIZE; i++ )
+ if ( ErrPats[i] )
+ printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrPats[i] );
+ printf( "\n" );
+}
+int Patt_ManProfileErrorsOne( Vec_Wrd_t * vErrors, int nOuts )
+{
+ Vec_Int_t * vCoErrs = Patt_ManOutputErrorCoverage( vErrors, nOuts );
+ Vec_Int_t * vPatErrs = Patt_ManPatternErrorCoverage( vErrors, nOuts );
+ Patt_ManProfileErrors( vCoErrs, vPatErrs );
+ Vec_IntFree( vPatErrs );
+ Vec_IntFree( vCoErrs );
+ return 1;
+}
+
+Vec_Int_t * Min_ManGetUnsolved( Gia_Man_t * p )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i, Driver;
+ Gia_ManForEachCoDriverId( p, Driver, i )
+ if ( Driver > 0 )
+ Vec_IntPush( vRes, i );
+ if ( Vec_IntSize(vRes) == 0 )
+ Vec_IntFreeP( &vRes );
+ return vRes;
+}
+Vec_Wrd_t * Min_ManRemapSims( int nInputs, Vec_Int_t * vMap, Vec_Wrd_t * vSimsPi )
+{
+ int i, iObj, nWords = Vec_WrdSize(vSimsPi)/Vec_IntSize(vMap);
+ Vec_Wrd_t * vSimsNew = Vec_WrdStart( 2 * nInputs * nWords );
+ //Vec_Wrd_t * vSimsNew = Vec_WrdStartRandom( nInputs * nWords );
+ //Vec_WrdFillExtra( vSimsNew, 2 * nInputs * nWords, 0 );
+ assert( Vec_WrdSize(vSimsPi)%Vec_IntSize(vMap) == 0 );
+ Vec_WrdShrink( vSimsNew, Vec_WrdSize(vSimsNew)/2 );
+ Vec_IntForEachEntry( vMap, iObj, i )
+ {
+ Abc_TtCopy( Vec_WrdArray(vSimsNew) + (iObj-1)*nWords, Vec_WrdArray(vSimsPi) + i*nWords, nWords, 0 );
+ Abc_TtCopy( Vec_WrdLimit(vSimsNew) + (iObj-1)*nWords, Vec_WrdLimit(vSimsPi) + i*nWords, nWords, 0 );
+ }
+ return vSimsNew;
+}
+Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
+{
+ Vec_Int_t * vStats[3] = {0}; int i, iObj;
+ Vec_Int_t * vMap = Vec_IntAlloc( 100 );
+ Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap );
+ Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
+ Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
+ Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVerbose )
+ Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVeryVerbose )
+ {
+ printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
+ Gia_ManPrintStats( pSwp2, NULL );
+ Vec_IntForEachEntry( vOuts, iObj, i )
+ {
+ printf( "%4d : ", i );
+ printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
+ printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
+ printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
+ printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
+ printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
+ printf( "\n" );
+ if ( i == 20 )
+ break;
+ }
+ }
+ for ( i = 0; i < 3; i++ )
+ Vec_IntFree( vStats[i] );
+ Vec_IntFree( vCounts );
+ Vec_WrdFree( vSimsPo );
+ Vec_WecFree( vCexes );
+ Gia_ManStop( pSwp2 );
+ //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
+ vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
+ Vec_WrdFree( vSimsPo );
+ Vec_IntFree( vMap );
+ return vSimsPi;
+}
+Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
+{
+ abctime clk = Abc_Clock();
+ extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 );
+ abctime clkSweep = Abc_Clock() - clk;
+ int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n",
+ nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0;
+ Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp );
+ Vec_Wrd_t * vSimsPi = vOuts ? Gia_ManCollectSims( pSwp, 0, vOuts, nMaxTries, nMinCexes, fUseSim, fUseSat, fVerbose, fVeryVerbose ) : NULL;
+ if ( vOuts == NULL )
+ printf( "There is no satisfiable outputs.\n" );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Sweep time", clkSweep );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ Vec_IntFreeP( &vOuts );
+ Gia_ManStop( pSwp );
+ nArgs = 0;
+ return vSimsPi;
+}
+void Min_ManTest2( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 0, 1, 1 );
+ Vec_WrdFreeP( &vSimsPi );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSim5.c b/src/aig/gia/giaReshape1.c
index ab33c218..52b40bdc 100644
--- a/src/aig/gia/giaSim5.c
+++ b/src/aig/gia/giaReshape1.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaSim5.c]
+ FileName [giaReshape.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
- Synopsis [Simulation engine.]
+ Synopsis []
Author [Alan Mishchenko]
@@ -14,23 +14,19 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaSim5.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
-#include "base/main/main.h"
ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-void Sim_Init( Abc_Frame_t * pAbc ) {}
-void Sim_End( Abc_Frame_t * pAbc ) {}
-void Gia_DatFree( Gia_Dat_t * p ) {}
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -40,12 +36,16 @@ void Gia_DatFree( Gia_Dat_t * p ) {}
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
+Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
+{
+ return NULL;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaReshape2.c
index 6ce89cf0..98a4d855 100644
--- a/src/aig/gia/giaSim4.c
+++ b/src/aig/gia/giaReshape2.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaSim4.c]
+ FileName [giaReshape.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
- Synopsis [Simulation engine.]
+ Synopsis []
Author [Alan Mishchenko]
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaSim4.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
@@ -35,15 +35,15 @@ ABC_NAMESPACE_IMPL_START
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
-int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose )
+Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
{
- return 0;
+ return NULL;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c
index b8c0e294..33fd5276 100644
--- a/src/aig/gia/giaResub.c
+++ b/src/aig/gia/giaResub.c
@@ -22,10 +22,10 @@
#include "misc/vec/vecWec.h"
#include "misc/vec/vecQue.h"
#include "misc/vec/vecHsh.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
-
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -271,6 +271,520 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Resubstitution data-structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+typedef struct Gia_ResbMan_t_ Gia_ResbMan_t;
+struct Gia_ResbMan_t_
+{
+ int nWords;
+ int nLimit;
+ int nDivsMax;
+ int iChoice;
+ int fUseXor;
+ int fDebug;
+ int fVerbose;
+ int fVeryVerbose;
+ Vec_Ptr_t * vDivs;
+ Vec_Int_t * vGates;
+ Vec_Int_t * vUnateLits[2];
+ Vec_Int_t * vNotUnateVars[2];
+ Vec_Int_t * vUnatePairs[2];
+ Vec_Int_t * vBinateVars;
+ Vec_Int_t * vUnateLitsW[2];
+ Vec_Int_t * vUnatePairsW[2];
+ Vec_Wec_t * vSorter;
+ word * pSets[2];
+ word * pDivA;
+ word * pDivB;
+ Vec_Wrd_t * vSims;
+};
+Gia_ResbMan_t * Gia_ResbAlloc( int nWords )
+{
+ Gia_ResbMan_t * p = ABC_CALLOC( Gia_ResbMan_t, 1 );
+ p->nWords = nWords;
+ p->vUnateLits[0] = Vec_IntAlloc( 100 );
+ p->vUnateLits[1] = Vec_IntAlloc( 100 );
+ p->vNotUnateVars[0] = Vec_IntAlloc( 100 );
+ p->vNotUnateVars[1] = Vec_IntAlloc( 100 );
+ p->vUnatePairs[0] = Vec_IntAlloc( 100 );
+ p->vUnatePairs[1] = Vec_IntAlloc( 100 );
+ p->vUnateLitsW[0] = Vec_IntAlloc( 100 );
+ p->vUnateLitsW[1] = Vec_IntAlloc( 100 );
+ p->vUnatePairsW[0] = Vec_IntAlloc( 100 );
+ p->vUnatePairsW[1] = Vec_IntAlloc( 100 );
+ p->vSorter = Vec_WecAlloc( nWords*64 );
+ p->vBinateVars = Vec_IntAlloc( 100 );
+ p->vGates = Vec_IntAlloc( 100 );
+ p->vDivs = Vec_PtrAlloc( 100 );
+ p->pSets[0] = ABC_CALLOC( word, nWords );
+ p->pSets[1] = ABC_CALLOC( word, nWords );
+ p->pDivA = ABC_CALLOC( word, nWords );
+ p->pDivB = ABC_CALLOC( word, nWords );
+ p->vSims = Vec_WrdAlloc( 100 );
+ return p;
+}
+void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int fVeryVerbose )
+{
+ assert( p->nWords == nWords );
+ p->nLimit = nLimit;
+ p->nDivsMax = nDivsMax;
+ p->iChoice = iChoice;
+ p->fUseXor = fUseXor;
+ p->fDebug = fDebug;
+ p->fVerbose = fVerbose;
+ p->fVeryVerbose = fVeryVerbose;
+ Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 );
+ Abc_TtCopy( p->pSets[1], (word *)Vec_PtrEntry(vDivs, 1), nWords, 0 );
+ Vec_PtrClear( p->vDivs );
+ Vec_PtrAppend( p->vDivs, vDivs );
+ Vec_IntClear( p->vGates );
+ Vec_IntClear( p->vUnateLits[0] );
+ Vec_IntClear( p->vUnateLits[1] );
+ Vec_IntClear( p->vNotUnateVars[0] );
+ Vec_IntClear( p->vNotUnateVars[1] );
+ Vec_IntClear( p->vUnatePairs[0] );
+ Vec_IntClear( p->vUnatePairs[1] );
+ Vec_IntClear( p->vUnateLitsW[0] );
+ Vec_IntClear( p->vUnateLitsW[1] );
+ Vec_IntClear( p->vUnatePairsW[0] );
+ Vec_IntClear( p->vUnatePairsW[1] );
+ Vec_IntClear( p->vBinateVars );
+}
+void Gia_ResbFree( Gia_ResbMan_t * p )
+{
+ Vec_IntFree( p->vUnateLits[0] );
+ Vec_IntFree( p->vUnateLits[1] );
+ Vec_IntFree( p->vNotUnateVars[0] );
+ Vec_IntFree( p->vNotUnateVars[1] );
+ Vec_IntFree( p->vUnatePairs[0] );
+ Vec_IntFree( p->vUnatePairs[1] );
+ Vec_IntFree( p->vUnateLitsW[0] );
+ Vec_IntFree( p->vUnateLitsW[1] );
+ Vec_IntFree( p->vUnatePairsW[0] );
+ Vec_IntFree( p->vUnatePairsW[1] );
+ Vec_IntFree( p->vBinateVars );
+ Vec_IntFree( p->vGates );
+ Vec_WrdFree( p->vSims );
+ Vec_PtrFree( p->vDivs );
+ Vec_WecFree( p->vSorter );
+ ABC_FREE( p->pSets[0] );
+ ABC_FREE( p->pSets[1] );
+ ABC_FREE( p->pDivA );
+ ABC_FREE( p->pDivB );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Print resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManResubPrintNode( Vec_Int_t * vRes, int nVars, int Node, int fCompl )
+{
+ extern void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit );
+ int iLit0 = Vec_IntEntry( vRes, 2*Node + 0 );
+ int iLit1 = Vec_IntEntry( vRes, 2*Node + 1 );
+ assert( iLit0 != iLit1 );
+ if ( iLit0 > iLit1 && Abc_LitIsCompl(fCompl) ) // xor
+ {
+ printf( "~" );
+ fCompl = 0;
+ }
+ printf( "(" );
+ Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit0, fCompl) );
+ printf( " %c ", iLit0 > iLit1 ? '^' : (fCompl ? '|' : '&') );
+ Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit1, fCompl) );
+ printf( ")" );
+}
+void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit )
+{
+ if ( Abc_Lit2Var(iLit) < nVars )
+ {
+ if ( nVars < 26 )
+ printf( "%s%c", Abc_LitIsCompl(iLit) ? "~":"", 'a' + Abc_Lit2Var(iLit)-2 );
+ else
+ printf( "%si%d", Abc_LitIsCompl(iLit) ? "~":"", Abc_Lit2Var(iLit)-2 );
+ }
+ else
+ Gia_ManResubPrintNode( vRes, nVars, Abc_Lit2Var(iLit) - nVars, Abc_LitIsCompl(iLit) );
+}
+int Gia_ManResubPrint( Vec_Int_t * vRes, int nVars )
+{
+ int iTopLit;
+ if ( Vec_IntSize(vRes) == 0 )
+ return printf( "none" );
+ assert( Vec_IntSize(vRes) % 2 == 1 );
+ iTopLit = Vec_IntEntryLast(vRes);
+ if ( iTopLit == 0 )
+ return printf( "const0" );
+ if ( iTopLit == 1 )
+ return printf( "const1" );
+ Gia_ManResubPrintLit( vRes, nVars, iTopLit );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubVerify( Gia_ResbMan_t * p, word * pFunc )
+{
+ int nVars = Vec_PtrSize(p->vDivs);
+ int iTopLit, RetValue;
+ word * pDivRes;
+ if ( Vec_IntSize(p->vGates) == 0 )
+ return -1;
+ iTopLit = Vec_IntEntryLast(p->vGates);
+ assert( iTopLit >= 0 );
+ if ( iTopLit == 0 )
+ {
+ if ( pFunc ) Abc_TtClear( pFunc, p->nWords );
+ return Abc_TtIsConst0( p->pSets[1], p->nWords );
+ }
+ if ( iTopLit == 1 )
+ {
+ if ( pFunc ) Abc_TtFill( pFunc, p->nWords );
+ return Abc_TtIsConst0( p->pSets[0], p->nWords );
+ }
+ if ( Abc_Lit2Var(iTopLit) < nVars )
+ {
+ assert( Vec_IntSize(p->vGates) == 1 );
+ pDivRes = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iTopLit) );
+ }
+ else
+ {
+ int i, iLit0, iLit1;
+ assert( Vec_IntSize(p->vGates) > 1 );
+ assert( Vec_IntSize(p->vGates) % 2 == 1 );
+ assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(p->vGates)/2-1 );
+ Vec_WrdFill( p->vSims, p->nWords * Vec_IntSize(p->vGates)/2, 0 );
+ Vec_IntForEachEntryDouble( p->vGates, iLit0, iLit1, i )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ word * pDiv0 = iVar0 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar0) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar0 - nVars));
+ word * pDiv1 = iVar1 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar1) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar1 - nVars));
+ word * pDiv = Vec_WrdEntryP(p->vSims, p->nWords*i/2);
+ if ( iVar0 < iVar1 )
+ Abc_TtAndCompl( pDiv, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), p->nWords );
+ else if ( iVar0 > iVar1 )
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ Abc_TtXor( pDiv, pDiv0, pDiv1, p->nWords, 0 );
+ }
+ else assert( 0 );
+ }
+ pDivRes = Vec_WrdEntryP( p->vSims, p->nWords*(Vec_IntSize(p->vGates)/2-1) );
+ }
+ if ( Abc_LitIsCompl(iTopLit) )
+ RetValue = !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 1, p->nWords);
+ else
+ RetValue = !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 1, p->nWords);
+ if ( pFunc ) Abc_TtCopy( pFunc, pDivRes, p->nWords, Abc_LitIsCompl(iTopLit) );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Construct AIG manager from gates.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManConstructFromMap( Gia_Man_t * pNew, Vec_Int_t * vGates, int nVars, Vec_Int_t * vUsed, Vec_Int_t * vCopy, int fHash )
+{
+ int i, iLit0, iLit1, iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ assert( Vec_IntSize(vUsed) == nVars );
+ assert( Vec_IntSize(vGates) > 1 );
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 );
+ Vec_IntClear( vCopy );
+ Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ int iRes0 = iVar0 < nVars ? Vec_IntEntry(vUsed, iVar0) : Vec_IntEntry(vCopy, iVar0 - nVars);
+ int iRes1 = iVar1 < nVars ? Vec_IntEntry(vUsed, iVar1) : Vec_IntEntry(vCopy, iVar1 - nVars);
+ if ( iVar0 < iVar1 )
+ {
+ if ( fHash )
+ iLitRes = Gia_ManHashAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ else
+ iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ }
+ else if ( iVar0 > iVar1 )
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ if ( fHash )
+ iLitRes = Gia_ManHashXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ else
+ iLitRes = Gia_ManAppendXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ }
+ else assert( 0 );
+ Vec_IntPush( vCopy, iLitRes );
+ }
+ assert( Vec_IntSize(vCopy) == Vec_IntSize(vGates)/2 );
+ iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 );
+ return iLitRes;
+}
+Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nDivs )
+{
+ Vec_Int_t * vGates; int i, k, iLit;
+ Vec_Int_t * vCopy = Vec_IntAlloc( 100 );
+ Vec_Int_t * vUsed = Vec_IntStartFull( nDivs );
+ Gia_Man_t * pNew = Gia_ManStart( 100 );
+ pNew->pName = Abc_UtilStrsav( "resub" );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 )
+ Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) );
+ }
+ }
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nDivs )
+ iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) );
+ else
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, nDivs, vUsed, vCopy, 0 );
+ Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) );
+ }
+ Vec_IntFree( vCopy );
+ Vec_IntFree( vUsed );
+ return pNew;
+}
+Gia_Man_t * Gia_ManConstructFromGates2( Vec_Wec_t * vFuncs, Vec_Wec_t * vDivs, int nObjs, Vec_Int_t ** pvSupp )
+{
+ Vec_Int_t * vGates; int i, k, iVar, iLit;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCopy = Vec_IntAlloc( 100 );
+ Vec_Wec_t * vUseds = Vec_WecStart( Vec_WecSize(vDivs) );
+ Vec_Int_t * vMap = Vec_IntStartFull( nObjs );
+ Gia_Man_t * pNew = Gia_ManStart( 100 );
+ pNew->pName = Abc_UtilStrsav( "resub" );
+ assert( Vec_WecSize(vFuncs) == Vec_WecSize(vDivs) );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < Vec_IntSize(vDiv) && Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) == -1 )
+ Vec_IntWriteEntry( vMap, Vec_IntPushReturn(vSupp, Vec_IntEntry(vDiv, iVar)), 0 );
+ }
+ }
+ Vec_IntSort( vSupp, 0 );
+ Vec_IntForEachEntry( vSupp, iVar, k )
+ Vec_IntWriteEntry( vMap, iVar, Gia_ManAppendCi(pNew) );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i );
+ Vec_IntFill( vUsed, Vec_IntSize(vDiv), -1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < Vec_IntSize(vDiv) )
+ {
+ assert( Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) > 0 );
+ Vec_IntWriteEntry( vUsed, iVar, Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) );
+ }
+ }
+ }
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i );
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < Vec_IntSize(vDiv) )
+ iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) );
+ else
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, Vec_IntSize(vDiv), vUsed, vCopy, 0 );
+ Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) );
+ }
+ Vec_IntFree( vMap );
+ Vec_IntFree( vCopy );
+ Vec_WecFree( vUseds );
+ if ( pvSupp )
+ *pvSupp = vSupp;
+ else
+ Vec_IntFree( vSupp );
+ return pNew;
+}
+Vec_Int_t * Gia_ManToGates( Gia_Man_t * p )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 2*Gia_ManAndNum(p) + 1 );
+ Gia_Obj_t * pRoot = Gia_ManCo( p, 0 );
+ int iRoot = Gia_ObjFaninId0p(p, pRoot) - 1;
+ int nVars = Gia_ManCiNum(p);
+ assert( Gia_ManCoNum(p) == 1 );
+ if ( iRoot == -1 )
+ Vec_IntPush( vRes, Gia_ObjFaninC0(pRoot) );
+ else if ( iRoot < nVars )
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) );
+ else
+ {
+ Gia_Obj_t * pObj, * pLast = NULL; int i;
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ int iLit0 = Abc_Var2Lit( Gia_ObjFaninId0(pObj, i) - 1, Gia_ObjFaninC0(pObj) );
+ int iLit1 = Abc_Var2Lit( Gia_ObjFaninId1(pObj, i) - 1, Gia_ObjFaninC1(pObj) );
+ if ( iLit0 > iLit1 )
+ iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1;
+ Vec_IntPushTwo( vRes, 4 + iLit0, 4 + iLit1 );
+ pLast = pObj;
+ }
+ assert( pLast == Gia_ObjFanin0(pRoot) );
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) );
+ }
+ assert( Vec_IntSize(vRes) == 2*Gia_ManAndNum(p) + 1 );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Construct AIG manager from gates.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManInsertOrder_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 )
+ return;
+ if ( pObj->fPhase )
+ {
+ int nVars = Gia_ManObjNum(p);
+ int k, iLit, Index = Vec_IntFind( vObjs, iObj );
+ Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index );
+ assert( Gia_ObjIsCo(pObj) || Gia_ObjIsAnd(pObj) );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ if ( Abc_Lit2Var(iLit) < nVars )
+ Gia_ManInsertOrder_rec( p, Abc_Lit2Var(iLit), vObjs, vFuncs, vNodes );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes );
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId1p(p, pObj), vObjs, vFuncs, vNodes );
+ }
+ else assert( Gia_ObjIsCi(pObj) );
+ if ( !Gia_ObjIsCi(pObj) )
+ Vec_IntPush( vNodes, iObj );
+}
+Vec_Int_t * Gia_ManInsertOrder( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs )
+{
+ int i, Id;
+ Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManForEachCoId( p, Id, i )
+ Gia_ManInsertOrder_rec( p, Id, vObjs, vFuncs, vNodes );
+ return vNodes;
+}
+Gia_Man_t * Gia_ManInsertFromGates( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, nVars = Gia_ManObjNum(p);
+ Vec_Int_t * vUsed = Vec_IntStartFull( nVars );
+ Vec_Int_t * vNodes, * vCopy = Vec_IntAlloc(100);
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ pObj->fPhase = 1;
+ vNodes = Gia_ManInsertOrder( p, vObjs, vFuncs );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) + 1000 );
+ Gia_ManHashStart( pNew );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ if ( !pObj->fPhase )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else assert( 0 );
+ }
+ else
+ {
+ int k, iLit, Index = Vec_IntFind( vObjs, Gia_ObjId(p, pObj) );
+ Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index );
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nVars )
+ iLitRes = Gia_ManObj(p, Abc_Lit2Var(iTopLit))->Value;
+ else
+ {
+ Vec_IntForEachEntry( vGates, iLit, k )
+ Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), Gia_ManObj(p, Abc_Lit2Var(iLit))->Value );
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, nVars, vUsed, vCopy, 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), -1 );
+ }
+ pObj->Value = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) );
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ pObj->fPhase = 0;
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vUsed );
+ Vec_IntFree( vCopy );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
/**Function*************************************************************
Synopsis [Perform resubstitution.]
@@ -282,6 +796,1257 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
SeeAlso []
***********************************************************************/
+static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr2, int fVerbose )
+{
+ int * pBeg1 = vArr1->pArray;
+ int * pBeg2 = vArr2->pArray;
+ int * pEnd1 = vArr1->pArray + vArr1->nSize;
+ int * pEnd2 = vArr2->pArray + vArr2->nSize;
+ int * pStart1 = vArr1->pArray;
+ int * pStart2 = vArr2->pArray;
+ int nRemoved = 0;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( Abc_Lit2Var(*pBeg1) == Abc_Lit2Var(*pBeg2) )
+ {
+ if ( *pBeg1 != *pBeg2 )
+ return *pBeg1;
+ else
+ pBeg1++, pBeg2++;
+ nRemoved++;
+ }
+ else if ( *pBeg1 < *pBeg2 )
+ *pStart1++ = *pBeg1++;
+ else
+ *pStart2++ = *pBeg2++;
+ }
+ while ( pBeg1 < pEnd1 )
+ *pStart1++ = *pBeg1++;
+ while ( pBeg2 < pEnd2 )
+ *pStart2++ = *pBeg2++;
+ Vec_IntShrink( vArr1, pStart1 - vArr1->pArray );
+ Vec_IntShrink( vArr2, pStart2 - vArr2->pArray );
+ //if ( fVerbose ) printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) );
+ return -1;
+}
+
+void Gia_ManFindOneUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vNotUnateVars )
+{
+ word * pDiv; int i;
+ Vec_IntClear( vUnateLits );
+ Vec_IntClear( vNotUnateVars );
+ Vec_PtrForEachEntryStart( word *, vDivs, pDiv, i, 2 )
+ if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 0, nWords ) )
+ Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 0) );
+ else if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 1, nWords ) )
+ Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 1) );
+ else
+ Vec_IntPush( vNotUnateVars, i );
+}
+int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2], int fVerbose )
+{
+ int n;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ Gia_ManFindOneUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vNotUnateVars[n] );
+ if ( fVerbose ) printf( "U%d =%4d ", n, Vec_IntSize(vUnateLits[n]) );
+ }
+ return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1], fVerbose );
+}
+
+static inline int Gia_ManDivCover( word * pOff, word * pOn, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords )
+{
+ //assert( !Abc_TtIntersectOne(pOff, 0, pDivA, ComplA, nWords) );
+ //assert( !Abc_TtIntersectOne(pOff, 0, pDivB, ComplB, nWords) );
+ return !Abc_TtIntersectTwo( pOn, 0, pDivA, !ComplA, pDivB, !ComplB, nWords );
+}
+int Gia_ManFindTwoUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, int * pnPairs )
+{
+ int i, k, iDiv0_, iDiv1_, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ (*pnPairs) = 0;
+ Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0_, Cover0, i )
+ {
+ if ( 2*Cover0 < nTotal )
+ break;
+ Vec_IntForEachEntryTwoStart( vUnateLits, vUnateLitsW, iDiv1_, Cover1, k, i+1 )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1));
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ (*pnPairs)++;
+ if ( Gia_ManDivCover(pOff, pOn, pDiv1, Abc_LitIsCompl(iDiv1), pDiv0, Abc_LitIsCompl(iDiv0), nWords) )
+ return Abc_Var2Lit((Abc_LitNot(iDiv1) << 15) | Abc_LitNot(iDiv0), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindTwoUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], int fVerbose )
+{
+ int n, iLit, nPairs;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ //int nPairsAll = Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2;
+ iLit = Gia_ManFindTwoUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], &nPairs );
+ if ( fVerbose ) printf( "UU%d =%5d ", n, nPairs );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond(iLit, n);
+ }
+ return -1;
+}
+
+void Gia_ManFindXorInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs )
+{
+ int i, k, iDiv0_, iDiv1_;
+ int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 );
+ Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 )
+ Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0);
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1);
+ if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 0, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 0) );
+ else if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 1, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 1) );
+ }
+}
+int Gia_ManFindXor( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose )
+{
+ int n;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ Vec_IntClear( vUnatePairs[n] );
+ Gia_ManFindXorInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] );
+ if ( fVerbose ) printf( "UX%d =%5d ", n, Vec_IntSize(vUnatePairs[n]) );
+ }
+ return Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose );
+}
+
+void Gia_ManFindUnatePairsInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs )
+{
+ int n, i, k, iDiv0_, iDiv1_;
+ int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 );
+ Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 )
+ Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0);
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1);
+ for ( n = 0; n < 4; n++ )
+ {
+ int iLit0 = Abc_Var2Lit( iDiv0, n&1 );
+ int iLit1 = Abc_Var2Lit( iDiv1, n>>1 );
+ //if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) )
+ if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) && Abc_TtIntersectTwo( pOn, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((iLit1 << 15) | iLit0, 0) );
+ }
+ }
+}
+void Gia_ManFindUnatePairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose )
+{
+ int n, RetValue;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ int nBefore = Vec_IntSize(vUnatePairs[n]);
+ Gia_ManFindUnatePairsInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] );
+ if ( fVerbose ) printf( "UP%d =%5d ", n, Vec_IntSize(vUnatePairs[n])-nBefore );
+ }
+ RetValue = Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose );
+ assert( RetValue == -1 );
+}
+
+void Gia_ManDeriveDivPair( int iDiv, Vec_Ptr_t * vDivs, int nWords, word * pRes )
+{
+ int fComp = Abc_LitIsCompl(iDiv);
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1));
+ if ( iDiv0 < iDiv1 )
+ {
+ assert( !fComp );
+ Abc_TtAndCompl( pRes, pDiv0, Abc_LitIsCompl(iDiv0), pDiv1, Abc_LitIsCompl(iDiv1), nWords );
+ }
+ else
+ {
+ assert( !Abc_LitIsCompl(iDiv0) );
+ assert( !Abc_LitIsCompl(iDiv1) );
+ Abc_TtXor( pRes, pDiv0, pDiv1, nWords, 0 );
+ }
+}
+int Gia_ManFindDivGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnateLitsW, Vec_Int_t * vUnatePairsW, word * pDivTemp )
+{
+ int i, k, iDiv0, iDiv1, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0, Cover0, i )
+ {
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ if ( 2*Cover0 < nTotal )
+ break;
+ Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv1, Cover1, k )
+ {
+ int fComp1 = Abc_LitIsCompl(iDiv1);
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTemp );
+ if ( Gia_ManDivCover(pOff, pOn, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fComp1, nWords) )
+ return Abc_Var2Lit((Abc_Var2Lit(k, 1) << 15) | Abc_LitNot(iDiv0), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindDivGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnateLitsW[2], Vec_Int_t * vUnatePairsW[2], word * pDivTemp )
+{
+ int n, iLit;
+ for ( n = 0; n < 2; n++ )
+ {
+ iLit = Gia_ManFindDivGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnatePairs[n], vUnateLitsW[n], vUnatePairsW[n], pDivTemp );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond( iLit, n );
+ }
+ return -1;
+}
+
+int Gia_ManFindGateGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, word * pDivTempA, word * pDivTempB )
+{
+ int i, k, iDiv0, iDiv1, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv0, Cover0, k )
+ {
+ int fCompA = Abc_LitIsCompl(iDiv0);
+ if ( 2*Cover0 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv0, vDivs, nWords, pDivTempA );
+ Vec_IntForEachEntryTwoStart( vUnatePairs, vUnatePairsW, iDiv1, Cover1, i, k+1 )
+ {
+ int fCompB = Abc_LitIsCompl(iDiv1);
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTempB );
+ if ( Gia_ManDivCover(pOff, pOn, pDivTempA, fCompA, pDivTempB, fCompB, nWords) )
+ return Abc_Var2Lit((Abc_Var2Lit(i, 1) << 15) | Abc_Var2Lit(k, 1), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindGateGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2], word * pDivTempA, word * pDivTempB )
+{
+ int n, iLit;
+ for ( n = 0; n < 2; n++ )
+ {
+ iLit = Gia_ManFindGateGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], vUnatePairsW[n], pDivTempA, pDivTempB );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond( iLit, n );
+ }
+ return -1;
+}
+
+void Gia_ManSortUnatesInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, Vec_Wec_t * vSorter )
+{
+ int i, k, iLit;
+ Vec_Int_t * vLevel;
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vUnateLits, iLit, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iLit));
+ //assert( !Abc_TtIntersectOne( pOff, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecMask(pDiv, pOn, nWords, Abc_LitIsCompl(iLit)), iLit );
+ }
+ Vec_IntClear( vUnateLits );
+ Vec_IntClear( vUnateLitsW );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iLit, i )
+ {
+ Vec_IntPush( vUnateLits, iLit );
+ Vec_IntPush( vUnateLitsW, k );
+ }
+ //Vec_IntPrint( Vec_WecEntry(vSorter, 0) );
+ Vec_WecClear( vSorter );
+}
+void Gia_ManSortUnates( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter )
+{
+ int n;
+ for ( n = 0; n < 2; n++ )
+ Gia_ManSortUnatesInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter );
+}
+
+void Gia_ManSortPairsInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, Vec_Wec_t * vSorter )
+{
+ int i, k, iPair;
+ Vec_Int_t * vLevel;
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vUnatePairs, iPair, i )
+ {
+ int fComp = Abc_LitIsCompl(iPair);
+ int iLit0 = Abc_Lit2Var(iPair) & 0x7FFF;
+ int iLit1 = Abc_Lit2Var(iPair) >> 15;
+ word * pDiv0 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit0) );
+ word * pDiv1 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit1) );
+ if ( iLit0 < iLit1 )
+ {
+ assert( !fComp );
+ //assert( !Abc_TtIntersectTwo( pOff, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOn, nWords), iPair );
+ }
+ else
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ //assert( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, fComp, nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOn, nWords), iPair );
+ }
+ }
+ Vec_IntClear( vUnatePairs );
+ Vec_IntClear( vUnatePairsW );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iPair, i )
+ {
+ Vec_IntPush( vUnatePairs, iPair );
+ Vec_IntPush( vUnatePairsW, k );
+ }
+ //Vec_IntPrint( Vec_WecEntry(vSorter, 0) );
+ Vec_WecClear( vSorter );
+
+}
+void Gia_ManSortPairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter )
+{
+ int n;
+ for ( n = 0; n < 2; n++ )
+ Gia_ManSortPairsInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter );
+}
+
+void Gia_ManSortBinate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Wec_t * vSorter )
+{
+ Vec_Int_t * vLevel;
+ int nMints[2] = { Abc_TtCountOnesVec(pSets[0], nWords), Abc_TtCountOnesVec(pSets[1], nWords) };
+ word * pBig = nMints[0] > nMints[1] ? pSets[0] : pSets[1];
+ word * pSmo = nMints[0] > nMints[1] ? pSets[1] : pSets[0];
+ int Big = Abc_MaxInt( nMints[0], nMints[1] );
+ int Smo = Abc_MinInt( nMints[0], nMints[1] );
+ int i, k, iDiv, Gain;
+
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vBinateVars, iDiv, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry( vDivs, iDiv );
+ int nInter[2] = { Abc_TtCountOnesVecMask(pBig, pDiv, nWords, 0), Abc_TtCountOnesVecMask(pSmo, pDiv, nWords, 0) };
+ if ( nInter[0] < Big/2 ) // complement the divisor
+ {
+ nInter[0] = Big - nInter[0];
+ nInter[1] = Smo - nInter[1];
+ }
+ assert( nInter[0] >= Big/2 );
+ Gain = Abc_MaxInt( 0, nInter[0] - Big/2 + Smo/2 - nInter[1] );
+ Vec_WecPush( vSorter, Gain, iDiv );
+ }
+
+ Vec_IntClear( vBinateVars );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iDiv, i )
+ Vec_IntPush( vBinateVars, iDiv );
+ Vec_WecClear( vSorter );
+
+ if ( Vec_IntSize(vBinateVars) > 2000 )
+ Vec_IntShrink( vBinateVars, 2000 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubFindBestBinate( Gia_ResbMan_t * p )
+{
+ int nMintsAll = Abc_TtCountOnesVec(p->pSets[0], p->nWords) + Abc_TtCountOnesVec(p->pSets[1], p->nWords);
+ int i, iDiv, iLitBest = -1, CostBest = -1;
+//Vec_IntPrint( p->vBinateVars );
+//Dau_DsdPrintFromTruth( p->pSets[0], 6 );
+//Dau_DsdPrintFromTruth( p->pSets[1], 6 );
+ Vec_IntForEachEntry( p->vBinateVars, iDiv, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry(p->vDivs, iDiv);
+ int nMints0 = Abc_TtCountOnesVecMask( pDiv, p->pSets[0], p->nWords, 0 );
+ int nMints1 = Abc_TtCountOnesVecMask( pDiv, p->pSets[1], p->nWords, 0 );
+ if ( CostBest < nMints0 + nMints1 )
+ {
+ CostBest = nMints0 + nMints1;
+ iLitBest = Abc_Var2Lit( iDiv, 0 );
+ }
+ if ( CostBest < nMintsAll - nMints0 - nMints1 )
+ {
+ CostBest = nMintsAll - nMints0 - nMints1;
+ iLitBest = Abc_Var2Lit( iDiv, 1 );
+ }
+ }
+ return iLitBest;
+}
+int Gia_ManResubAddNode( Gia_ResbMan_t * p, int iLit0, int iLit1, int Type )
+{
+ int iNode = Vec_PtrSize(p->vDivs) + Vec_IntSize(p->vGates)/2;
+ int fFlip = (Type == 2) ^ (iLit0 > iLit1);
+ int iFan0 = fFlip ? iLit1 : iLit0;
+ int iFan1 = fFlip ? iLit0 : iLit1;
+ assert( iLit0 != iLit1 );
+ if ( Type == 2 )
+ assert( iFan0 > iFan1 );
+ else
+ assert( iFan0 < iFan1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iFan0, Type==1), Abc_LitNotCond(iFan1, Type==1) );
+ return Abc_Var2Lit( iNode, Type==1 );
+}
+int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit, int Depth )
+{
+ extern int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth );
+ int iDivBest, iResLit0, iResLit1, nNodes;
+ word * pDiv, * pCopy[2];
+ if ( Depth == 0 )
+ return -1;
+ if ( nLimit < 3 )
+ return -1;
+ iDivBest = Gia_ManResubFindBestBinate( p );
+ if ( iDivBest == -1 )
+ return -1;
+ pCopy[0] = ABC_CALLOC( word, p->nWords );
+ pCopy[1] = ABC_CALLOC( word, p->nWords );
+ Abc_TtCopy( pCopy[0], p->pSets[0], p->nWords, 0 );
+ Abc_TtCopy( pCopy[1], p->pSets[1], p->nWords, 0 );
+ pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDivBest) );
+ Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) );
+ Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) );
+ nNodes = Vec_IntSize(p->vGates)/2;
+ //iResLit0 = Gia_ManResubPerform_rec( p, nLimit-3 );
+ iResLit0 = Gia_ManResubPerform_rec( p, nLimit, 0 );
+ if ( iResLit0 == -1 )
+ iResLit0 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 );
+ if ( iResLit0 == -1 )
+ {
+ ABC_FREE( pCopy[0] );
+ ABC_FREE( pCopy[1] );
+ return -1;
+ }
+ Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) );
+ Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) );
+ ABC_FREE( pCopy[0] );
+ ABC_FREE( pCopy[1] );
+ nNodes = Vec_IntSize(p->vGates)/2 - nNodes;
+ if ( nLimit-nNodes < 3 )
+ return -1;
+ //iResLit1 = Gia_ManResubPerform_rec( p, nLimit-3-nNodes );
+ iResLit1 = Gia_ManResubPerform_rec( p, nLimit, 0 );
+ if ( iResLit1 == -1 )
+ iResLit1 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 );
+ if ( iResLit1 == -1 )
+ return -1;
+ else
+ {
+ int iLit0 = Gia_ManResubAddNode( p, Abc_LitNot(iDivBest), iResLit0, 0 );
+ int iLit1 = Gia_ManResubAddNode( p, iDivBest, iResLit1, 0 );
+ return Gia_ManResubAddNode( p, iLit0, iLit1, 1 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth )
+{
+ int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs);
+ if ( p->fVerbose )
+ {
+ int nMints[2] = { Abc_TtCountOnesVec(p->pSets[0], p->nWords), Abc_TtCountOnesVec(p->pSets[1], p->nWords) };
+ printf( " " );
+ printf( "ISF: " );
+ printf( "0=%5d (%5.2f %%) ", nMints[0], 100.0*nMints[0]/(64*p->nWords) );
+ printf( "1=%5d (%5.2f %%) ", nMints[1], 100.0*nMints[1]/(64*p->nWords) );
+ }
+ if ( Abc_TtIsConst0( p->pSets[1], p->nWords ) )
+ return 0;
+ if ( Abc_TtIsConst0( p->pSets[0], p->nWords ) )
+ return 1;
+ iResLit = Gia_ManFindOneUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars, p->fVerbose );
+ if ( iResLit >= 0 ) // buffer
+ return iResLit;
+ if ( nLimit == 0 )
+ return -1;
+ Gia_ManSortUnates( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->vSorter );
+ iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->fVerbose );
+ if ( iResLit >= 0 ) // and
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15;
+ assert( iDiv0 < iDiv1 );
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ return Abc_Var2Lit( iNode, fComp );
+ }
+ Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars );
+ if ( Depth )
+ return Gia_ManResubPerformMux_rec( p, nLimit, Depth );
+ if ( Vec_IntSize(p->vBinateVars) > p->nDivsMax )
+ Vec_IntShrink( p->vBinateVars, p->nDivsMax );
+ if ( p->fVerbose ) printf( " B = %3d", Vec_IntSize(p->vBinateVars) );
+ //Gia_ManSortBinate( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vSorter );
+ if ( p->fUseXor )
+ {
+ iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose );
+ if ( iResLit >= 0 ) // xor
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15;
+ assert( !Abc_LitIsCompl(iDiv0) );
+ assert( !Abc_LitIsCompl(iDiv1) );
+ assert( iDiv0 > iDiv1 );
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ return Abc_Var2Lit( iNode, fComp );
+ }
+ }
+ if ( nLimit == 1 )
+ return -1;
+ Gia_ManFindUnatePairs( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose );
+ Gia_ManSortPairs( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->vSorter );
+ iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->vUnateLitsW, p->vUnatePairsW, p->pDivA );
+ if ( iResLit >= 0 ) // and(div,pair)
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // div
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair
+
+ int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) );
+ int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1);
+ int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF;
+ int iDiv11 = Abc_Lit2Var(Div1) >> 15;
+
+ Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 );
+ Vec_IntPushTwo( p->vGates, iDiv0, Abc_Var2Lit(iNode, fComp1) );
+ return Abc_Var2Lit( iNode+1, fComp );
+ }
+// if ( nLimit == 2 )
+// return -1;
+ if ( nLimit >= 3 )
+ {
+ iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->pDivA, p->pDivB );
+ if ( iResLit >= 0 ) // and(pair,pair)
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // pair
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair
+
+ int Div0 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv0) );
+ int fComp0 = Abc_LitIsCompl(Div0) ^ Abc_LitIsCompl(iDiv0);
+ int iDiv00 = Abc_Lit2Var(Div0) & 0x7FFF;
+ int iDiv01 = Abc_Lit2Var(Div0) >> 15;
+
+ int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) );
+ int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1);
+ int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF;
+ int iDiv11 = Abc_Lit2Var(Div1) >> 15;
+
+ Vec_IntPushTwo( p->vGates, iDiv00, iDiv01 );
+ Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 );
+ Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) );
+ return Abc_Var2Lit( iNode+2, fComp );
+ }
+ }
+// if ( nLimit == 3 )
+// return -1;
+ if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 )
+ return -1;
+
+ TopOneW[0] = Vec_IntSize(p->vUnateLitsW[0]) ? Vec_IntEntry(p->vUnateLitsW[0], 0) : 0;
+ TopOneW[1] = Vec_IntSize(p->vUnateLitsW[1]) ? Vec_IntEntry(p->vUnateLitsW[1], 0) : 0;
+
+ TopTwoW[0] = Vec_IntSize(p->vUnatePairsW[0]) ? Vec_IntEntry(p->vUnatePairsW[0], 0) : 0;
+ TopTwoW[1] = Vec_IntSize(p->vUnatePairsW[1]) ? Vec_IntEntry(p->vUnatePairsW[1], 0) : 0;
+
+ Max1 = Abc_MaxInt(TopOneW[0], TopOneW[1]);
+ Max2 = Abc_MaxInt(TopTwoW[0], TopTwoW[1]);
+ if ( Abc_MaxInt(Max1, Max2) == 0 )
+ return -1;
+
+ if ( Max1 > Max2/2 )
+ {
+ if ( nLimit >= 2 && (Max1 == TopOneW[0] || Max1 == TopOneW[1]) )
+ {
+ int fUseOr = Max1 == TopOneW[0];
+ int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n" );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-1, Depth );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ if ( iDiv < iResLit )
+ Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) );
+ else
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_LitNot(iDiv) );
+ return Abc_Var2Lit( iNode, fUseOr );
+ }
+ }
+ if ( Max2 == 0 )
+ return -1;
+/*
+ if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] )
+ {
+ int fUseOr = Max2 == TopTwoW[0];
+ int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n " );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-2 );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) );
+ return Abc_Var2Lit( iNode+1, fUseOr );
+ }
+ }
+*/
+ }
+ else
+ {
+ if ( nLimit >= 3 && (Max2 == TopTwoW[0] || Max2 == TopTwoW[1]) )
+ {
+ int fUseOr = Max2 == TopTwoW[0];
+ int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n" );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-2, Depth );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) );
+ return Abc_Var2Lit( iNode+1, fUseOr );
+ }
+ }
+ if ( Max1 == 0 )
+ return -1;
+/*
+ if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] )
+ {
+ int fUseOr = Max1 == TopOneW[0];
+ int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n " );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-1 );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) );
+ return Abc_Var2Lit( iNode, fUseOr );
+ }
+ }
+*/
+ }
+ return -1;
+}
+void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int Depth )
+{
+ int Res;
+ Gia_ResbInit( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, fVerbose );
+ Res = Gia_ManResubPerform_rec( p, nLimit, Depth );
+ if ( Res >= 0 )
+ Vec_IntPush( p->vGates, Res );
+ else
+ Vec_IntClear( p->vGates );
+ if ( fVerbose )
+ printf( "\n" );
+}
+Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth )
+{
+ Vec_Int_t * vRes;
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords );
+ Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, Depth );
+ if ( fVerbose )
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ //if ( fVerbose )
+ // printf( "\n" );
+ if ( !Gia_ManResubVerify(p, pFunc) )
+ {
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ printf( "Verification FAILED.\n" );
+ }
+ else if ( fDebug && fVerbose )
+ printf( "Verification succeeded." );
+ if ( fVerbose )
+ printf( "\n" );
+ vRes = Vec_IntDup( p->vGates );
+ Gia_ResbFree( p );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Gia_ResbMan_t * s_pResbMan = NULL;
+
+void Abc_ResubPrepareManager( int nWords )
+{
+ if ( s_pResbMan != NULL )
+ Gia_ResbFree( s_pResbMan );
+ s_pResbMan = NULL;
+ if ( nWords > 0 )
+ s_pResbMan = Gia_ResbAlloc( nWords );
+}
+
+int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray )
+{
+ Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs };
+ assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager()
+ Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose==2, 0 );
+ if ( fVerbose )
+ {
+ int nGates = Vec_IntSize(s_pResbMan->vGates)/2;
+ if ( nGates )
+ {
+ printf( " Gain = %2d Gates = %2d __________ F = ", nLimit+1-nGates, nGates );
+ Gia_ManResubPrint( s_pResbMan->vGates, nDivs );
+ printf( "\n" );
+ }
+ }
+ if ( fDebug )
+ {
+ if ( !Gia_ManResubVerify(s_pResbMan, NULL) )
+ {
+ Gia_ManResubPrint( s_pResbMan->vGates, nDivs );
+ printf( "Verification FAILED.\n" );
+ }
+ //else
+ // printf( "Verification succeeded.\n" );
+ }
+ *ppArray = Vec_IntArray(s_pResbMan->vGates);
+ assert( Vec_IntSize(s_pResbMan->vGates)/2 <= nLimit );
+ return Vec_IntSize(s_pResbMan->vGates);
+}
+
+void Abc_ResubDumpProblem( char * pFileName, void ** ppDivs, int nDivs, int nWords )
+{
+ Vec_Wrd_t * vSims = Vec_WrdAlloc( nDivs * nWords );
+ word ** pDivs = (word **)ppDivs;
+ int d, w;
+ for ( d = 0; d < nDivs; d++ )
+ for ( w = 0; w < nWords; w++ )
+ Vec_WrdPush( vSims, pDivs[d][w] );
+ Vec_WrdDumpHex( pFileName, vSims, nWords, 1 );
+ Vec_WrdFree( vSims );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+extern void Extra_PrintHex( FILE * pFile, unsigned * pTruth, int nVars );
+extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
+
+void Gia_ManResubTest3()
+{
+ int nVars = 4;
+ int fVerbose = 1;
+ word Divs[6] = { 0, 0,
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00)
+ };
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 );
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i, k, ArraySize, * pArray;
+ for ( i = 0; i < 6; i++ )
+ Vec_PtrPush( vDivs, Divs+i );
+ Abc_ResubPrepareManager( 1 );
+ for ( i = 0; i < (1<<(1<<nVars)); i++ ) //if ( i == 0xCA )
+ {
+ word Truth = Abc_Tt6Stretch( i, nVars );
+ Divs[0] = ~Truth;
+ Divs[1] = Truth;
+ printf( "%3d : ", i );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, nVars );
+ printf( " " );
+ Dau_DsdPrintFromTruth2( &Truth, nVars );
+ printf( " " );
+
+ //Abc_ResubDumpProblem( "temp.resub", (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1 );
+ ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 16, 50, 0, 0, 1, fVerbose, &pArray );
+ printf( "\n" );
+
+ Vec_IntClear( vRes );
+ for ( k = 0; k < ArraySize; k++ )
+ Vec_IntPush( vRes, pArray[k] );
+
+ if ( i == 1000 )
+ break;
+ }
+ Abc_ResubPrepareManager( 0 );
+ Vec_IntFree( vRes );
+ Vec_PtrFree( vDivs );
+}
+void Gia_ManResubTest3_()
+{
+ Gia_ResbMan_t * p = Gia_ResbAlloc( 1 );
+ word Divs[6] = { 0, 0,
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00)
+ };
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 );
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i;
+ for ( i = 0; i < 6; i++ )
+ Vec_PtrPush( vDivs, Divs+i );
+
+ {
+ word Truth = (Divs[2] | Divs[3]) & (Divs[4] & Divs[5]);
+// word Truth = (~Divs[2] | Divs[3]) | ~Divs[4];
+ Divs[0] = ~Truth;
+ Divs[1] = Truth;
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 6 );
+ printf( " " );
+ Dau_DsdPrintFromTruth2( &Truth, 6 );
+ printf( " " );
+ Gia_ManResubPerform( p, vDivs, 1, 100, 0, 50, 1, 1, 0, 0 );
+ }
+ Gia_ResbFree( p );
+ Vec_IntFree( vRes );
+ Vec_PtrFree( vDivs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns )
+{
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords*2 );
+ Vec_Ptr_t * vDivs = Vec_PtrAllocSimInfo( nIns+2, nWords*2 );
+ word * pSim; int i;
+ Vec_PtrForEachEntry( word *, vDivs, pSim, i )
+ {
+ if ( i == 0 )
+ {
+ memset( pSim, 0x00, sizeof(word)*nWords );
+ memset( pSim+nWords, 0xFF, sizeof(word)*nWords );
+ }
+ else if ( i == 1 )
+ {
+ memset( pSim, 0xFF, sizeof(word)*nWords );
+ memset( pSim+nWords, 0x00, sizeof(word)*nWords );
+ }
+ else
+ {
+ memmove( pSim, Vec_WrdEntryP(vOn, (i-2)*nWords), sizeof(word)*nWords );
+ memmove( pSim+nWords, Vec_WrdEntryP(vOff, (i-2)*nWords), sizeof(word)*nWords );
+ }
+ }
+ Gia_ManResubPerform( p, vDivs, nWords*2, 100, 0, 50, 1, 1, 0, 0 );
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ printf( "\n" );
+ //Vec_PtrFree( vDivs );
+ Gia_ResbFree( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords )
+{
+ //int i, nVars = 6, pVarSet[10] = { 2, 189, 2127, 2125, 177, 178 };
+ int i, nVars = 3, pVarSet[10] = { 2, 3, 4 };
+ word * pOff = (word *)Vec_PtrEntry( vDivs, 0 );
+ word * pOn = (word *)Vec_PtrEntry( vDivs, 1 );
+ Vec_Int_t * vValue = Vec_IntStartFull( 1 << 6 );
+ printf( "Verifying resub:\n" );
+ for ( i = 0; i < 64*nWords; i++ )
+ {
+ int v, Mint = 0, Value = Abc_TtGetBit(pOn, i);
+ if ( !Abc_TtGetBit(pOff, i) && !Value )
+ continue;
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, pVarSet[v]), i) )
+ Mint |= 1 << v;
+ if ( Vec_IntEntry(vValue, Mint) == -1 )
+ Vec_IntWriteEntry(vValue, Mint, Value);
+ else if ( Vec_IntEntry(vValue, Mint) != Value )
+ printf( "Mismatch in pattern %d\n", i );
+ }
+ printf( "Finished verifying resub.\n" );
+ Vec_IntFree( vValue );
+}
+Vec_Ptr_t * Gia_ManDeriveDivs( Vec_Wrd_t * vSims, int nWords )
+{
+ int i, nDivs = Vec_WrdSize(vSims)/nWords;
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( nDivs );
+ for ( i = 0; i < nDivs; i++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vSims, nWords*i) );
+ return vDivs;
+}
+Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose )
+{
+ return NULL;
+}
+Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose )
+{
+ int nWords = 0;
+ Gia_Man_t * pMan = NULL;
+ Vec_Wrd_t * vSims = Vec_WrdReadHex( pFileName, &nWords, 1 );
+ Vec_Ptr_t * vDivs = vSims ? Gia_ManDeriveDivs( vSims, nWords ) : NULL;
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords );
+ //Gia_ManCheckResub( vDivs, nWords );
+ if ( Vec_PtrSize(vDivs) >= (1<<14) )
+ {
+ printf( "Reducing all divs from %d to %d.\n", Vec_PtrSize(vDivs), (1<<14)-1 );
+ Vec_PtrShrink( vDivs, (1<<14)-1 );
+ }
+ assert( Vec_PtrSize(vDivs) < (1<<14) );
+ Gia_ManResubPerform( p, vDivs, nWords, 100, 50, iChoice, fUseXor, 1, 1, 0 );
+ if ( Vec_IntSize(p->vGates) )
+ {
+ Vec_Wec_t * vGates = Vec_WecStart(1);
+ Vec_IntAppend( Vec_WecEntry(vGates, 0), p->vGates );
+ pMan = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) );
+ Vec_WecFree( vGates );
+ }
+ else
+ printf( "Decomposition did not succeed.\n" );
+ Gia_ResbFree( p );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vSims );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManUnivTfo_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes, Vec_Int_t * vPos )
+{
+ int i, iFan, Count = 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( vNodes && Gia_ObjIsCo(Gia_ManObj(p, iObj)) )
+ Vec_IntPush( vNodes, iObj );
+ if ( vPos && Gia_ObjIsCo(Gia_ManObj(p, iObj)) )
+ Vec_IntPush( vPos, iObj );
+ Gia_ObjForEachFanoutStaticId( p, iObj, iFan, i )
+ Count += Gia_ManUnivTfo_rec( p, iFan, vNodes, vPos );
+ return Count;
+}
+int Gia_ManUnivTfo( Gia_Man_t * p, int * pObjs, int nObjs, Vec_Int_t ** pvNodes, Vec_Int_t ** pvPos )
+{
+ int i, Count = 0;
+ if ( pvNodes )
+ {
+ if ( *pvNodes )
+ Vec_IntClear( *pvNodes );
+ else
+ *pvNodes = Vec_IntAlloc( 100 );
+ }
+ if ( pvPos )
+ {
+ if ( *pvPos )
+ Vec_IntClear( *pvPos );
+ else
+ *pvPos = Vec_IntAlloc( 100 );
+ }
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nObjs; i++ )
+ Count += Gia_ManUnivTfo_rec( p, pObjs[i], pvNodes ? *pvNodes : NULL, pvPos ? *pvPos : NULL );
+ if ( pvNodes )
+ Vec_IntSort( *pvNodes, 0 );
+ if ( pvPos )
+ Vec_IntSort( *pvPos, 0 );
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tuning resub.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManTryResub( Gia_Man_t * p )
+{
+ int nLimit = 20;
+ int nDivsMax = 200;
+ int iChoice = 0;
+ int fUseXor = 1;
+ int fDebug = 1;
+ int fVerbose = 0;
+ abctime clk, clkResub = 0, clkStart = Abc_Clock();
+ Vec_Ptr_t * vvSims = Vec_PtrAlloc( 100 );
+ Vec_Wrd_t * vSims;
+ word * pSets[2], * pFunc;
+ Gia_Obj_t * pObj, * pObj2;
+ int i, i2, nWords, nNonDec = 0, nTotal = 0;
+ assert( Gia_ManCiNum(p) < 16 );
+ Vec_WrdFreeP( &p->vSimsPi );
+ p->vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
+ nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p);
+ //Vec_WrdPrintHex( p->vSimsPi, nWords );
+ pSets[0] = ABC_CALLOC( word, nWords );
+ pSets[1] = ABC_CALLOC( word, nWords );
+ vSims = Gia_ManSimPatSim( p );
+ Gia_ManLevelNum(p);
+ Gia_ManCreateRefs(p);
+ Abc_ResubPrepareManager( nWords );
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Vec_Int_t vGates;
+ int * pArray, nArray, nTfo, iObj = Gia_ObjId(p, pObj);
+ int Level = Gia_ObjLevel(p, pObj);
+ int nMffc = Gia_NodeMffcSizeMark(p, pObj);
+ pFunc = Vec_WrdEntryP( vSims, nWords*iObj );
+ Abc_TtCopy( pSets[0], pFunc, nWords, 1 );
+ Abc_TtCopy( pSets[1], pFunc, nWords, 0 );
+ Vec_PtrClear( vvSims );
+ Vec_PtrPushTwo( vvSims, pSets[0], pSets[1] );
+ nTfo = Gia_ManUnivTfo( p, &iObj, 1, NULL, NULL );
+ Gia_ManForEachCi( p, pObj2, i2 )
+ Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) );
+ Gia_ManForEachAnd( p, pObj2, i2 )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj2) && !Gia_ObjIsTravIdPrevious(p, pObj2) && Gia_ObjLevel(p, pObj2) <= Level )
+ Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) );
+ if ( fVerbose )
+ printf( "%3d : Lev = %2d Mffc = %2d Divs = %3d Tfo = %3d\n", iObj, Level, nMffc, Vec_PtrSize(vvSims)-2, nTfo );
+ clk = Abc_Clock();
+ nArray = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vvSims), Vec_PtrSize(vvSims), nWords, Abc_MinInt(nMffc-1, nLimit), nDivsMax, iChoice, fUseXor, fDebug, fVerbose, &pArray );
+ clkResub += Abc_Clock() - clk;
+ vGates.nSize = vGates.nCap = nArray;
+ vGates.pArray = pArray;
+ assert( nMffc > Vec_IntSize(&vGates)/2 );
+ if ( Vec_IntSize(&vGates) > 0 )
+ nTotal += nMffc - Vec_IntSize(&vGates)/2;
+ nNonDec += Vec_IntSize(&vGates) == 0;
+ }
+ printf( "Total nodes = %5d. Non-realizable = %5d. Gain = %6d. ", Gia_ManAndNum(p), nNonDec, nTotal );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
+ Abc_PrintTime( 1, "Pure resub time", clkResub );
+ Abc_ResubPrepareManager( 0 );
+ Gia_ManStaticFanoutStop( p );
+ Vec_PtrFree( vvSims );
+ Vec_WrdFree( vSims );
+ ABC_FREE( pSets[0] );
+ ABC_FREE( pSets[1] );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Deriving a subset.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManDeriveShrink( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) )
+ continue;
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 );
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 );
+ k++;
+ }
+ Vec_WrdShrink( vFuncs, 2*k*nWords );
+ return k;
+}
+void Gia_ManDeriveCounts( Vec_Wrd_t * vFuncs, int nWords, Vec_Int_t * vCounts )
+{
+ int i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ Vec_IntClear( vCounts );
+ for ( i = 0; i < 2*nFuncs; i++ )
+ Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vFuncs, i*nWords), nWords) );
+}
+int Gia_ManDeriveCost( Vec_Wrd_t * vFuncs, int nWords, word * pMask, Vec_Int_t * vCounts )
+{
+ int i, Res = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ int Total[2] = { Vec_IntEntry(vCounts, 2*i+0), Vec_IntEntry(vCounts, 2*i+1) };
+ int This[2] = { Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+0)*nWords), pMask, nWords, 0),
+ Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+1)*nWords), pMask, nWords, 0) };
+ assert( Total[0] >= This[0] && Total[1] >= This[1] );
+ Res += This[0] * This[1] + (Total[0] - This[0]) * (Total[1] - This[1]);
+ }
+ return Res;
+}
+int Gia_ManDeriveSimpleCost( Vec_Int_t * vCounts )
+{
+ int i, Ent1, Ent2, Res = 0;
+ Vec_IntForEachEntryDouble( vCounts, Ent1, Ent2, i )
+ Res += Ent1*Ent2;
+ return Res;
+}
+void Gia_ManDeriveNext( Vec_Wrd_t * vFuncs, int nWords, word * pMask )
+{
+ int i, iStop = Vec_WrdSize(vFuncs); word Data;
+ int nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ Vec_WrdForEachEntryStop( vFuncs, Data, i, iStop )
+ Vec_WrdPush( vFuncs, Data );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0n = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1n = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ word * pFunc0p = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords + iStop);
+ word * pFunc1p = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords + iStop);
+ Abc_TtAnd( pFunc0p, pFunc0n, pMask, nWords, 0 );
+ Abc_TtAnd( pFunc1p, pFunc1n, pMask, nWords, 0 );
+ Abc_TtSharp( pFunc0n, pFunc0n, pMask, nWords );
+ Abc_TtSharp( pFunc1n, pFunc1n, pMask, nWords );
+ }
+}
+Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t * vObjs, Vec_Wrd_t * vSims, int nWords, int fVerbose )
+{
+ int i, k, iObj, CostBestPrev, nFuncs = Vec_WrdSize(vFuncs) / nWords;
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCounts = Vec_IntAlloc( nFuncs * 2 );
+ Vec_Wrd_t * vFSims = Vec_WrdDup( vFuncs );
+ assert( nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ assert( Gia_ManObjNum(p) * nWords == Vec_WrdSize(vSims) );
+ assert( Vec_IntSize(vObjs) <= Gia_ManCandNum(p) );
+ nFuncs = Gia_ManDeriveShrink( vFSims, nWords );
+ Gia_ManDeriveCounts( vFSims, nWords, vCounts );
+ assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFSims) );
+ CostBestPrev = Gia_ManDeriveSimpleCost( vCounts );
+ if ( fVerbose )
+ printf( "Processing %d functions and %d objects with cost %d\n", nFuncs, Vec_IntSize(vObjs), CostBestPrev );
+ for ( i = 0; nFuncs > 0; i++ )
+ {
+ int iObjBest = -1, CountThis, Count0 = ABC_INFINITY, CountBest = ABC_INFINITY;
+ Vec_IntForEachEntry( vObjs, iObj, k )
+ {
+ if ( Vec_IntFind(vRes, iObj) >= 0 )
+ continue;
+ CountThis = Gia_ManDeriveCost( vFSims, nWords, Vec_WrdEntryP(vSims, iObj*nWords), vCounts );
+ if ( CountBest > CountThis )
+ {
+ CountBest = CountThis;
+ iObjBest = iObj;
+ }
+ if ( !k ) Count0 = CountThis;
+ }
+ if ( Count0 < CostBestPrev )
+ {
+ CountBest = Count0;
+ iObjBest = Vec_IntEntry(vObjs, 0);
+ }
+ Gia_ManDeriveNext( vFSims, nWords, Vec_WrdEntryP(vSims, iObjBest*nWords) );
+ nFuncs = Gia_ManDeriveShrink( vFSims, nWords );
+ Gia_ManDeriveCounts( vFSims, nWords, vCounts );
+ assert( CountBest == Gia_ManDeriveSimpleCost(vCounts) );
+ Vec_IntPush( vRes, iObjBest );
+ CostBestPrev = CountBest;
+ if ( fVerbose )
+ printf( "Iter %2d : Funcs = %6d. Object %6d. Cost %6d.\n", i, nFuncs, iObjBest, CountBest );
+ }
+ Vec_IntFree( vCounts );
+ Vec_WrdFree( vFSims );
+ return vRes;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c
new file mode 100644
index 00000000..1219526f
--- /dev/null
+++ b/src/aig/gia/giaResub2.c
@@ -0,0 +1,1558 @@
+/**CFile****************************************************************
+
+ FileName [giaResub2.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: giaResub2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/util/utilTruth.h"
+#include "misc/vec/vecHsh.h"
+#include "opt/dau/dau.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Gia_Rsb2Man_t_ Gia_Rsb2Man_t;
+struct Gia_Rsb2Man_t_
+{
+ // hyper-parameters
+ int nDivsMax;
+ int nLevelIncrease;
+ int fUseXor;
+ int fUseZeroCost;
+ int fDebug;
+ int fVerbose;
+ // input AIG
+ int nObjs;
+ int nPis;
+ int nNodes;
+ int nPos;
+ int iFirstPo;
+ int Level;
+ int nMffc;
+ // intermediate data
+ Vec_Int_t vObjs;
+ Vec_Wrd_t vSims;
+ Vec_Ptr_t vpDivs;
+ Vec_Int_t vDivs;
+ Vec_Int_t vLevels;
+ Vec_Int_t vRefs;
+ Vec_Int_t vCopies;
+ Vec_Int_t vTried;
+ word Truth0;
+ word Truth1;
+ word CareSet;
+};
+
+extern void Abc_ResubPrepareManager( int nWords );
+extern int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rsb2Man_t * Gia_Rsb2ManAlloc()
+{
+ Gia_Rsb2Man_t * p = ABC_CALLOC( Gia_Rsb2Man_t, 1 );
+ return p;
+}
+void Gia_Rsb2ManFree( Gia_Rsb2Man_t * p )
+{
+ Vec_IntErase( &p->vObjs );
+ Vec_WrdErase( &p->vSims );
+ Vec_PtrErase( &p->vpDivs );
+ Vec_IntErase( &p->vDivs );
+ Vec_IntErase( &p->vLevels );
+ Vec_IntErase( &p->vRefs );
+ Vec_IntErase( &p->vCopies );
+ Vec_IntErase( &p->vTried );
+ ABC_FREE( p );
+}
+void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose )
+{
+ int i;
+ // hyper-parameters
+ p->nDivsMax = nDivsMax;
+ p->nLevelIncrease = nLevelIncrease;
+ p->fUseXor = fUseXor;
+ p->fUseZeroCost = fUseZeroCost;
+ p->fDebug = fDebug;
+ p->fVerbose = fVerbose;
+ // user data
+ Vec_IntClear( &p->vObjs );
+ Vec_IntPushArray( &p->vObjs, pObjs, 2*nObjs );
+ assert( pObjs[0] == 0 );
+ assert( pObjs[1] == 0 );
+ p->nObjs = nObjs;
+ p->nPis = 0;
+ p->nNodes = 0;
+ p->nPos = 0;
+ p->iFirstPo = 0;
+ for ( i = 1; i < nObjs; i++ )
+ {
+ if ( pObjs[2*i+0] == 0 && pObjs[2*i+1] == 0 )
+ p->nPis++;
+ else if ( pObjs[2*i+0] == pObjs[2*i+1] )
+ p->nPos++;
+ else
+ p->nNodes++;
+ }
+ assert( nObjs == 1 + p->nPis + p->nNodes + p->nPos );
+ p->iFirstPo = nObjs - p->nPos;
+ Vec_WrdClear( &p->vSims );
+ Vec_WrdGrow( &p->vSims, 2*nObjs );
+ Vec_WrdPush( &p->vSims, 0 );
+ Vec_WrdPush( &p->vSims, 0 );
+ for ( i = 0; i < p->nPis; i++ )
+ {
+ Vec_WrdPush( &p->vSims, s_Truths6[i] );
+ Vec_WrdPush( &p->vSims, ~s_Truths6[i] );
+ }
+ p->vSims.nSize = 2*p->nObjs;
+ Vec_IntClear( &p->vDivs );
+ Vec_IntClear( &p->vLevels );
+ Vec_IntClear( &p->vRefs );
+ Vec_IntClear( &p->vCopies );
+ Vec_IntClear( &p->vTried );
+ Vec_PtrClear( &p->vpDivs );
+ Vec_IntGrow( &p->vDivs, nObjs );
+ Vec_IntGrow( &p->vLevels, nObjs );
+ Vec_IntGrow( &p->vRefs, nObjs );
+ Vec_IntGrow( &p->vCopies, nObjs );
+ Vec_IntGrow( &p->vTried, nObjs );
+ Vec_PtrGrow( &p->vpDivs, nObjs );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_Rsb2ManPrint( Gia_Rsb2Man_t * p )
+{
+ int i, * pObjs = Vec_IntArray( &p->vObjs );
+ printf( "PI = %d. PO = %d. Obj = %d.\n", p->nPis, p->nPos, p->nObjs );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]),
+ Abc_LitIsCompl(pObjs[2*i+1]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+1]) );
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ printf( "%2d = %c%2d;\n", i,
+ Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]) );
+}
+
+int Gia_Rsb2ManLevel( Gia_Rsb2Man_t * p )
+{
+ int i, * pLevs, Level = 0;
+ Vec_IntClear( &p->vLevels );
+ Vec_IntGrow( &p->vLevels, p->nObjs );
+ pLevs = Vec_IntArray( &p->vLevels );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ pLevs[i] = 1 + Abc_MaxInt( pLevs[2*i+0]/2, pLevs[2*i+1]/2 );
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ Level = Abc_MaxInt( Level, pLevs[i] = pLevs[2*i+0]/2 );
+ return Level;
+}
+word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i; word Res = 0;
+ int * pObjs = Vec_IntArray( &p->vObjs );
+ word * pSims = Vec_WrdArray( &p->vSims );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ {
+ if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]];
+ else if ( pObjs[2*i+0] > pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]];
+ else assert( 0 );
+ pSims[2*i+1] = ~pSims[2*i+0];
+ }
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]];
+ ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] );
+ for ( i = iNode + 1; i < p->iFirstPo; i++ )
+ {
+ if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]];
+ else if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]];
+ else assert( 0 );
+ pSims[2*i+1] = ~pSims[2*i+0];
+ }
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ Res |= pSims[2*i+0] ^ pSims[pObjs[2*i+0]];
+ ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] );
+ return Res;
+}
+// marks MFFC and returns its size
+int Gia_Rsb2ManDeref_rec( Gia_Rsb2Man_t * p, int * pObjs, int * pRefs, int iNode )
+{
+ int Counter = 1;
+ if ( iNode <= p->nPis )
+ return 0;
+ if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+0])] == 0 )
+ Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+0]) );
+ if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+1])] == 0 )
+ Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+1]) );
+ return Counter;
+}
+int Gia_Rsb2ManMffc( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i, * pRefs, * pObjs;
+ Vec_IntFill( &p->vRefs, p->nObjs, 0 );
+ pRefs = Vec_IntArray( &p->vRefs );
+ pObjs = Vec_IntArray( &p->vObjs );
+ assert( pObjs[2*iNode+0] != pObjs[2*iNode+1] );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ pRefs[Abc_Lit2Var(pObjs[2*i+0])]++,
+ pRefs[Abc_Lit2Var(pObjs[2*i+1])]++;
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ pRefs[Abc_Lit2Var(pObjs[2*i+0])]++;
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ assert( pRefs[i] );
+ pRefs[iNode] = 0;
+ for ( i = iNode + 1; i < p->iFirstPo; i++ )
+ if ( !pRefs[Abc_Lit2Var(pObjs[2*i+0])] || !pRefs[Abc_Lit2Var(pObjs[2*i+1])] )
+ pRefs[i] = 0;
+ return Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, iNode );
+}
+// collects divisors and maps them into nodes
+// assumes MFFC is already marked
+int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i, iNodeLevel = 0;
+ int * pRefs = Vec_IntArray( &p->vRefs );
+ p->CareSet = Gia_Rsb2ManOdcs( p, iNode );
+ p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, 2*iNode);
+ p->Truth0 = p->CareSet & ~p->Truth1;
+ Vec_PtrClear( &p->vpDivs );
+ Vec_PtrPush( &p->vpDivs, &p->Truth0 );
+ Vec_PtrPush( &p->vpDivs, &p->Truth1 );
+ Vec_IntClear( &p->vDivs );
+ Vec_IntPushTwo( &p->vDivs, -1, -1 );
+ for ( i = 1; i <= p->nPis; i++ )
+ {
+ Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) );
+ Vec_IntPush( &p->vDivs, i );
+ }
+ p->nMffc = Gia_Rsb2ManMffc( p, iNode );
+ if ( p->nLevelIncrease >= 0 )
+ {
+ p->Level = Gia_Rsb2ManLevel(p);
+ iNodeLevel = Vec_IntEntry(&p->vLevels, iNode);
+ }
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ {
+ if ( !pRefs[i] || (p->nLevelIncrease >= 0 && Vec_IntEntry(&p->vLevels, i) > iNodeLevel + p->nLevelIncrease) )
+ continue;
+ Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) );
+ Vec_IntPush( &p->vDivs, i );
+ }
+ assert( Vec_IntSize(&p->vDivs) == Vec_PtrSize(&p->vpDivs) );
+ return Vec_IntSize(&p->vDivs);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_Rsb2AddNode( Vec_Int_t * vRes, int iLit0, int iLit1, int iRes0, int iRes1 )
+{
+ int iLitMin = iRes0 < iRes1 ? Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)) : Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1));
+ int iLitMax = iRes0 < iRes1 ? Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) : Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0));
+ int iLitRes = Vec_IntSize(vRes);
+ if ( iLit0 < iLit1 ) // and
+ {
+ if ( iLitMin == 0 )
+ return 0;
+ if ( iLitMin == 1 )
+ return iLitMax;
+ if ( iLitMin == Abc_LitNot(iLitMax) )
+ return 0;
+ }
+ else if ( iLit0 > iLit1 ) // xor
+ {
+ if ( iLitMin == 0 )
+ return iLitMax;
+ if ( iLitMin == 1 )
+ return Abc_LitNot(iLitMax);
+ if ( iLitMin == Abc_LitNot(iLitMax) )
+ return 1;
+ }
+ else assert( 0 );
+ assert( iLitMin >= 2 && iLitMax >= 2 );
+ if ( iLit0 < iLit1 ) // and
+ Vec_IntPushTwo( vRes, iLitMin, iLitMax );
+ else if ( iLit0 > iLit1 ) // xor
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ Vec_IntPushTwo( vRes, iLitMax, iLitMin );
+ }
+ else assert( 0 );
+ return iLitRes;
+}
+int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies, int iObj )
+{
+ if ( Vec_IntEntry(vCopies, iObj) >= 0 )
+ return Vec_IntEntry(vCopies, iObj);
+ assert( iObj > nPis );
+ if ( iObj == iNode )
+ {
+ int nVars = Vec_IntSize(vDivs);
+ int iLitRes = -1, iTopLit = Vec_IntEntryLast( vResub );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nVars )
+ iLitRes = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iTopLit)) );
+ else
+ {
+ Vec_Int_t * vCopy = Vec_IntAlloc( 10 );
+ int k, iLit, iLit0, iLit1;
+ Vec_IntForEachEntryStop( vResub, iLit, k, Vec_IntSize(vResub)-1 )
+ if ( Abc_Lit2Var(iLit) < nVars )
+ Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iLit)) );
+ Vec_IntForEachEntryDouble( vResub, iLit0, iLit1, k )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ int iRes0 = iVar0 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar0)) : Vec_IntEntry(vCopy, iVar0 - nVars);
+ int iRes1 = iVar1 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar1)) : Vec_IntEntry(vCopy, iVar1 - nVars);
+ iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 );
+ Vec_IntPush( vCopy, iLitRes );
+ }
+ Vec_IntFree( vCopy );
+ }
+ iLitRes = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) );
+ Vec_IntWriteEntry( vCopies, iObj, iLitRes );
+ return iLitRes;
+ }
+ else
+ {
+ int iLit0 = Vec_IntEntry( vObjs, 2*iObj+0 );
+ int iLit1 = Vec_IntEntry( vObjs, 2*iObj+1 );
+ int iRes0 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit0) );
+ int iRes1 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit1) );
+ int iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 );
+ Vec_IntWriteEntry( vCopies, iObj, iLitRes );
+ return iLitRes;
+ }
+}
+Vec_Int_t * Gia_Rsb2ManInsert( int nPis, int nPos, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies )
+{
+ int i, nObjs = Vec_IntSize(vObjs)/2, iFirstPo = nObjs - nPos;
+ Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vObjs) );
+//Vec_IntPrint( vDivs );
+//Vec_IntPrint( vResub );
+ Vec_IntFill( vCopies, Vec_IntSize(vObjs), -1 );
+ Vec_IntFill( vRes, 2*(nPis + 1), 0 );
+ for ( i = 0; i <= nPis; i++ )
+ Vec_IntWriteEntry( vCopies, i, 2*i );
+ for ( i = iFirstPo; i < nObjs; i++ )
+ Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var( Vec_IntEntry(vObjs, 2*i) ) );
+ for ( i = iFirstPo; i < nObjs; i++ )
+ {
+ int iLitNew = Abc_Lit2LitL( Vec_IntArray(vCopies), Vec_IntEntry(vObjs, 2*i) );
+ Vec_IntPushTwo( vRes, iLitNew, iLitNew );
+ }
+ return vRes;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ResubPrintDivs( void ** ppDivs, int nDivs )
+{
+ word ** pDivs = (word **)ppDivs;
+ int i;
+ for ( i = 0; i < nDivs; i++ )
+ {
+ printf( "Div %2d : ", i );
+ Dau_DsdPrintFromTruth( pDivs[i], 6 );
+ }
+}
+int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast )
+{
+ int iNode;
+ //for ( iNode = iFirst; iNode < iLast; iNode++ )
+ for ( iNode = iLast - 1; iNode >= iFirst; iNode-- )
+ if ( Vec_IntFind(vTried, iNode) == -1 )
+ return iNode;
+ return -1;
+}
+int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs )
+{
+ int iNode, nChanges = 0, RetValue = 0;
+ Gia_Rsb2Man_t * p = Gia_Rsb2ManAlloc();
+ Gia_Rsb2ManStart( p, pObjs, nObjs, nDivsMax, nLevelIncrease, fUseXor, fUseZeroCost, fDebug, fVerbose );
+ *ppArray = NULL;
+ while ( (iNode = Abc_ResubNodeToTry(&p->vTried, p->nPis+1, p->iFirstPo)) > 0 )
+ {
+ int nDivs = Gia_Rsb2ManDivs( p, iNode );
+ int * pResub, nResub = Abc_ResubComputeFunction( Vec_PtrArray(&p->vpDivs), nDivs, 1, p->nMffc-1, nDivsMax, 0, fUseXor, fDebug, fVerbose, &pResub );
+ if ( nResub == 0 )
+ Vec_IntPush( &p->vTried, iNode );
+ else
+ {
+ int i, k = 0, iTried;
+ Vec_Int_t vResub = { nResub, nResub, pResub };
+ Vec_Int_t * vRes = Gia_Rsb2ManInsert( p->nPis, p->nPos, &p->vObjs, iNode, &vResub, &p->vDivs, &p->vCopies );
+ //printf( "\nResubing node %d:\n", iNode );
+ //Gia_Rsb2ManPrint( p );
+ p->nObjs = Vec_IntSize(vRes)/2;
+ p->iFirstPo = p->nObjs - p->nPos;
+ Vec_IntClear( &p->vObjs );
+ Vec_IntAppend( &p->vObjs, vRes );
+ Vec_IntFree( vRes );
+ Vec_IntForEachEntry( &p->vTried, iTried, i )
+ if ( Vec_IntEntry(&p->vCopies, iTried) > Abc_Var2Lit(p->nPis, 0) ) // internal node
+ Vec_IntWriteEntry( &p->vTried, k++, Abc_Lit2Var(Vec_IntEntry(&p->vCopies, iTried)) );
+ Vec_IntShrink( &p->vTried, k );
+ nChanges++;
+ //Gia_Rsb2ManPrint( p );
+ }
+ }
+ if ( nChanges )
+ {
+ RetValue = p->nObjs;
+ *ppArray = p->vObjs.pArray;
+ Vec_IntZero( &p->vObjs );
+ }
+ Gia_Rsb2ManFree( p );
+ if ( pnResubs )
+ *pnResubs = nChanges;
+ return RetValue;
+}
+int Abc_ResubComputeWindow2( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs )
+{
+ *ppArray = ABC_ALLOC( int, 2*nObjs );
+ memmove( *ppArray, pObjs, 2*nObjs * sizeof(int) );
+ if ( pnResubs )
+ *pnResubs = 0;
+ return nObjs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManToResub( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, * pObjs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) );
+ assert( Gia_ManIsNormalized(p) );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ continue;
+ pObjs[2*i+0] = Gia_ObjFaninLit0(Gia_ManObj(p, i), i);
+ if ( Gia_ObjIsCo(pObj) )
+ pObjs[2*i+1] = pObjs[2*i+0];
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObjs[2*i+1] = Gia_ObjFaninLit1(Gia_ManObj(p, i), i);
+ else assert( 0 );
+ }
+ return pObjs;
+}
+Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs, int nIns )
+{
+ Gia_Man_t * pNew = Gia_ManStart( nObjs );
+ int i;
+ for ( i = 1; i < nObjs; i++ )
+ {
+ if ( pObjs[2*i] == 0 && i <= nIns ) // pi
+ Gia_ManAppendCi( pNew );
+ else if ( pObjs[2*i] == pObjs[2*i+1] ) // po
+ Gia_ManAppendCo( pNew, pObjs[2*i] );
+ else if ( pObjs[2*i] < pObjs[2*i+1] )
+ Gia_ManAppendAnd( pNew, pObjs[2*i], pObjs[2*i+1] );
+ else if ( pObjs[2*i] > pObjs[2*i+1] )
+ Gia_ManAppendXor( pNew, pObjs[2*i], pObjs[2*i+1] );
+ else assert( 0 );
+ }
+ return pNew;
+}
+Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ int nResubs, nObjsNew, * pObjsNew, * pObjs = Gia_ManToResub( p );
+//Gia_ManPrint( p );
+ Abc_ResubPrepareManager( 1 );
+ nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew, &nResubs );
+ //printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 );
+ Abc_ResubPrepareManager( 0 );
+ if ( nObjsNew )
+ {
+ pNew = Gia_ManFromResub( pObjsNew, nObjsNew, Gia_ManCiNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ }
+ else
+ pNew = Gia_ManDup( p );
+ ABC_FREE( pObjs );
+ ABC_FREE( pObjsNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creating a window with support composed of primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// returns the number of nodes added to the window when is iPivot is added
+// the window nodes in vNodes are labeled with the current traversal ID
+// the new node iPivot and its fanout are temporarily labeled and then unlabeled
+int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, int iPivot2, Vec_Wec_t * vLevels, Vec_Int_t * vNodes )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, Count = 0;
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // precondition: the new object to be added (iPivot) is not in the window
+ assert( !Gia_ObjIsTravIdCurrentId(p, iPivot) );
+ // add the object to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrentId( p, iPivot );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot), iPivot );
+ // the same about the second node if it is given
+ if ( iPivot2 != -1 )
+ {
+ // precondition: the new object to be added (iPivot2) is not in the window
+ assert( !Gia_ObjIsTravIdCurrentId(p, iPivot2) );
+ // add the object to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrentId( p, iPivot2 );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot2), iPivot2 );
+ }
+ // iterate through all objects and explore their fanouts
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ // count the number of nodes in the structure
+ Count++;
+ }
+ }
+ // iterate through the nodes in the levelized structure
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ if ( vNodes == NULL ) // it was a test run - unmark the node
+ Gia_ObjSetTravIdPrevious( p, pObj );
+ else // it was a real run - permanently add to the node to the window
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ // clean the levelized structure
+ Vec_IntClear( vLevel );
+ }
+ // return the number of nodes to be added
+ return Count;
+}
+// find the first PI to add based on the fanout count
+int Gia_WinAddCiWithMaxFanouts( Gia_Man_t * p )
+{
+ int i, Id, nMaxFan = -1, iMaxFan = -1;
+ Gia_ManForEachCiId( p, Id, i )
+ if ( nMaxFan < Gia_ObjFanoutNumId(p, Id) )
+ {
+ nMaxFan = Gia_ObjFanoutNumId(p, Id);
+ iMaxFan = Id;
+ }
+ assert( iMaxFan >= 0 );
+ return iMaxFan;
+}
+// find the next PI to add based on how many nodes will be added to the window
+int Gia_WinAddCiWithMaxDivisors( Gia_Man_t * p, Vec_Wec_t * vLevels )
+{
+ int i, Id, nCurFan, nMaxFan = -1, iMaxFan = -1;
+ Gia_ManForEachCiId( p, Id, i )
+ {
+ if ( Gia_ObjIsTravIdCurrentId( p, Id ) )
+ continue;
+ nCurFan = Gia_WinTryAddingNode( p, Id, -1, vLevels, NULL );
+ if ( nMaxFan < nCurFan )
+ {
+ nMaxFan = nCurFan;
+ iMaxFan = Id;
+ }
+ }
+ assert( iMaxFan >= 0 );
+ return iMaxFan;
+}
+// check if the node has unmarked fanouts
+int Gia_WinNodeHasUnmarkedFanouts( Gia_Man_t * p, int iPivot )
+{
+ int f, iFan;
+ Gia_ObjForEachFanoutStaticId( p, iPivot, iFan, f )
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFan) )
+ return 1;
+ return 0;
+}
+// this is a translation procedure, which converts the array of node IDs (vObjs)
+// into the internal represnetation for the resub engine, which is returned
+// (this procedure is not needed when we simply construct a window)
+Vec_Int_t * Gia_RsbCiTranslate( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Int_t * vMap )
+{
+ int i, iObj, Lit0, Lit1, Fan0, Fan1;
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ assert( Vec_IntSize(vMap) == Gia_ManObjNum(p) );
+ Vec_IntPushTwo( vNodes, 0, 0 ); // const0 node
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ assert( Gia_ObjIsTravIdCurrentId(p, iObj) );
+ Fan0 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, iObj));
+ Fan1 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId1(pObj, iObj));
+ Lit0 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan0, Gia_ObjFaninC0(pObj) );
+ Lit1 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan1, Gia_ObjFaninC1(pObj) );
+ Vec_IntWriteEntry( vMap, iObj, Vec_IntSize(vNodes) );
+ Vec_IntPushTwo( vNodes, Lit0, Lit1 );
+ }
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ if ( Gia_WinNodeHasUnmarkedFanouts( p, iObj ) )
+ Vec_IntPushTwo( vNodes, Vec_IntEntry(vMap, iObj), Vec_IntEntry(vMap, iObj) );
+ return vNodes;
+}
+// construct a high-volume window support by the given number (nPis) of primary inputs
+Vec_Int_t * Gia_RsbCiWindow( Gia_Man_t * p, int nPis )
+{
+ Vec_Int_t * vRes; int i, iMaxFan;
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 );
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManIncrementTravId(p);
+ // add the first one
+ iMaxFan = Gia_WinAddCiWithMaxFanouts( p );
+ Gia_ObjSetTravIdCurrentId( p, iMaxFan );
+ Vec_IntPush( vNodes, iMaxFan );
+ // add remaining ones
+ for ( i = 1; i < nPis; i++ )
+ {
+ iMaxFan = Gia_WinAddCiWithMaxDivisors( p, vLevels );
+ Gia_WinTryAddingNode( p, iMaxFan, -1, vLevels, vNodes );
+ }
+ Vec_IntSort( vNodes, 0 );
+ vRes = Gia_RsbCiTranslate( p, vNodes, vMap );
+ Gia_ManStaticFanoutStop( p );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vMap );
+//Vec_IntPrint( vNodes );
+ Vec_IntFree( vNodes );
+ return vRes;
+}
+void Gia_RsbCiWindowTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vWin = Gia_RsbCiWindow( p, 6 );
+ //Vec_IntPrint( vWin );
+ Vec_IntFree( vWin );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Return initial window for the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int iObj, int n ) { return n ? Gia_ObjFaninId1(pObj, iObj) : Gia_ObjFaninId0(pObj, iObj); }
+
+static inline int Gia_ObjTravIsTopTwo( Gia_Man_t * p, int iNodeA ) { return (p->pTravIds[iNodeA] >= p->nTravIds - 1); }
+static inline int Gia_ObjTravIsSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { return (p->pTravIds[iNodeA] == p->pTravIds[iNodeB]); }
+static inline void Gia_ObjTravSetSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { p->pTravIds[iNodeA] = p->pTravIds[iNodeB]; }
+
+// collect nodes on the path from the meeting point to the root node, excluding the meeting point
+void Gia_RsbWindowGather( Gia_Man_t * p, Vec_Int_t * vPaths, int iNode, Vec_Int_t * vVisited )
+{
+ int iPrev;
+ if ( iNode == 0 )
+ return;
+ Vec_IntPush( vVisited, iNode );
+ iPrev = Vec_IntEntry( vPaths, iNode );
+ if ( iPrev == 0 )
+ return;
+ assert( Gia_ObjTravIsSame(p, iPrev, iNode) );
+ Gia_RsbWindowGather( p, vPaths, iPrev, vVisited );
+}
+// explore the frontier of nodes in the breadth-first traversal
+int Gia_RsbWindowExplore( Gia_Man_t * p, Vec_Int_t * vVisited, int iStart, Vec_Int_t * vPaths, int * piMeet, int * piNode )
+{
+ int i, n, iObj, iLimit = Vec_IntSize( vVisited );
+ *piMeet = *piNode = 0;
+ Vec_IntForEachEntryStartStop( vVisited, iObj, i, iStart, iLimit )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = Gia_ObjFaninId( pObj, iObj, n );
+ // if the node was visited on the paths to both fanins, collect it
+ if ( Gia_ObjTravIsTopTwo(p, iObj) && Gia_ObjTravIsTopTwo(p, iFan) && !Gia_ObjTravIsSame(p, iObj, iFan) )
+ {
+ *piMeet = iFan;
+ *piNode = iObj;
+ return 1;
+ }
+ // if the node was visited already on this path, skip it
+ if ( Gia_ObjTravIsTopTwo(p, iFan) )
+ {
+ assert( Gia_ObjTravIsSame(p, iObj, iFan) );
+ continue;
+ }
+ // label the node as visited
+ Gia_ObjTravSetSame( p, iFan, iObj );
+ Vec_IntWriteEntry( vPaths, iFan, iObj );
+ Vec_IntPush( vVisited, iFan );
+ }
+ }
+ return 0;
+}
+Vec_Int_t * Gia_RsbWindowInit( Gia_Man_t * p, Vec_Int_t * vPaths, int iPivot, int nIter )
+{
+ Vec_Int_t * vVisited = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pPivot = Gia_ManObj( p, iPivot );
+ int i, n, iStart = 0;
+ assert( Gia_ObjIsAnd(pPivot) );
+ // start paths for both fanins of the pivot node
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = Gia_ObjFaninId( pPivot, iPivot, n );
+ Gia_ManIncrementTravId(p);
+ Vec_IntPush( vVisited, iFan );
+ Vec_IntWriteEntry( vPaths, iFan, 0 );
+ Gia_ObjSetTravIdCurrentId( p, iFan );
+ }
+ // perform several iterations of breadth-first search
+ for ( i = 0; i < nIter; i++ )
+ {
+ int iMeet, iNode, iNext = Vec_IntSize(vVisited);
+ if ( Gia_RsbWindowExplore( p, vVisited, iStart, vPaths, &iMeet, &iNode ) )
+ {
+ // found the shared path
+ if ( Gia_ObjIsTravIdCurrentId(p, iMeet) )
+ assert( Gia_ObjIsTravIdPreviousId(p, iNode) );
+ else if ( Gia_ObjIsTravIdPreviousId(p, iMeet) )
+ assert( Gia_ObjIsTravIdCurrentId(p, iNode) );
+ else assert( 0 );
+ // collect the initial window
+ Vec_IntClear( vVisited );
+ Gia_RsbWindowGather( p, vPaths, Vec_IntEntry(vPaths, iMeet), vVisited );
+ Gia_RsbWindowGather( p, vPaths, iNode, vVisited );
+ Vec_IntPush( vVisited, iPivot );
+ break;
+ }
+ iStart = iNext;
+ }
+ // if no meeting point is found, make sure to return NULL
+ if ( i == nIter )
+ Vec_IntFreeP( &vVisited );
+ return vVisited;
+}
+Vec_Int_t * Gia_RsbCreateWindowInputs( Gia_Man_t * p, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc(10);
+ Gia_Obj_t * pObj; int i, n, iObj;
+ Gia_ManIncrementTravId(p);
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = n ? Gia_ObjFaninId1p(p, pObj) : Gia_ObjFaninId0p(p, pObj);
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFan) )
+ Vec_IntPushUnique( vInputs, iFan );
+ }
+ }
+ Vec_IntForEachEntry( vInputs, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntPush( vWin, iObj );
+ }
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Grow window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbAddSideInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, iObj;
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // precondition: window nodes are labeled with the current ID
+ Vec_IntForEachEntry( vWin, iObj, i )
+ {
+ assert( Gia_ObjIsTravIdCurrentId(p, iObj) );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj );
+ }
+ // iterate through all objects and explore their fanouts
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ Vec_IntPush( vWin, Gia_ObjId(p, pFanout) );
+ }
+ }
+ // iterate through the nodes in the levelized structure
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Vec_IntClear( vLevel );
+}
+// expland inputs until saturation while adding the side-fanouts
+void Gia_RsbExpandInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vInputs )
+{
+ Gia_Obj_t * pObj;
+ int i, n, iFans[2], fChange = 1;
+ while ( fChange )
+ {
+ fChange = 0;
+ Gia_ManForEachObjVec( vInputs, p, pObj, i )
+ {
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ iFans[0] = Gia_ObjFaninId0p(p, pObj);
+ iFans[1] = Gia_ObjFaninId1p(p, pObj);
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFans[0]) && !Gia_ObjIsTravIdCurrentId(p, iFans[1]) )
+ continue;
+ Vec_IntRemove( vInputs, Gia_ObjId(p, pObj) );
+ assert( Vec_IntFind(vWin, Gia_ObjId(p, pObj)) >= 0 );
+ for ( n = 0; n < 2; n++ )
+ {
+ if ( Gia_ObjIsTravIdCurrentId(p, iFans[n]) )
+ continue;
+ assert( Vec_IntFind(vInputs, iFans[n]) == -1 );
+ Vec_IntPush( vInputs, iFans[n] );
+ Gia_WinTryAddingNode( p, iFans[n], -1, vLevels, vWin );
+ assert( Gia_ObjIsTravIdCurrentId(p, iFans[n]) );
+ }
+ fChange = 1;
+ }
+ }
+}
+// select the best input to expand, based on its contribution to the window size
+int Gia_RsbSelectOneInput( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vIns )
+{
+ int i, iNode = 0, WeightThis, WeightBest = -1;
+ Gia_Obj_t * pObj;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ int iFan0 = Gia_ObjFaninId0p(p, pObj);
+ int iFan1 = Gia_ObjFaninId1p(p, pObj);
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ WeightThis = Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, NULL );
+ if ( WeightBest < WeightThis )
+ {
+ WeightBest = WeightThis;
+ iNode = Gia_ObjId(p, pObj);
+ }
+ }
+ return iNode;
+}
+// grow the initial window as long as it fits the input count limit
+void Gia_RsbWindowGrow( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax )
+{
+ int iNode;
+ Gia_RsbAddSideInputs( p, vLevels, vWin );
+ Gia_RsbExpandInputs( p, vLevels, vWin, vIns );
+ while ( Vec_IntSize(vIns) < nInputsMax && (iNode = Gia_RsbSelectOneInput(p, vLevels, vIns)) )
+ {
+ int iFan0 = Gia_ObjFaninId0p(p, Gia_ManObj(p, iNode));
+ int iFan1 = Gia_ObjFaninId1p(p, Gia_ManObj(p, iNode));
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, vWin );
+ assert( Gia_ObjIsTravIdCurrentId(p, iFan0) && Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ Vec_IntRemove( vIns, iNode );
+ Vec_IntPushTwo( vIns, iFan0, iFan1 );
+ Gia_RsbExpandInputs( p, vLevels, vWin, vIns );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Grow window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WinCreateFromCut_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vWin )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId0(pObj, iObj), vWin );
+ Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId1(pObj, iObj), vWin );
+ Vec_IntPush( vWin, iObj );
+}
+// uses levelized structure (vLevels) to collect in array vWin divisors supported by the cut (vIn)
+void Gia_WinCreateFromCut( Gia_Man_t * p, int iPivot, Vec_Int_t * vIn, Vec_Wec_t * vLevels, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, iObj, Level;
+ Vec_Int_t * vUsed = Vec_IntAlloc( 100 );
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // clean the resulting array
+ Vec_IntClear( vWin );
+ // collect leaves
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vIn, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntPush( vWin, iObj );
+ }
+ // collect internal cone
+ Gia_WinCreateFromCut_rec( p, iPivot, vWin );
+ // add nodes to the levelized structure
+ Vec_IntForEachEntry( vWin, iObj, i )
+ {
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj );
+ Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevelId(p, iObj) );
+ }
+ // iterate through all objects and explore their fanouts
+ //Vec_WecForEachLevel( vLevels, vLevel, k )
+ Vec_IntForEachEntry( vUsed, Level, k )
+ {
+ vLevel = Vec_WecEntry( vLevels, Level );
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ Vec_IntPush( vWin, Gia_ObjId(p, pFanout) );
+ Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevel(p, pFanout) );
+ }
+ }
+ Vec_IntClear( vLevel );
+ }
+ Vec_IntSort( vWin, 0 );
+ Vec_IntFree( vUsed );
+}
+// update the cut until both fanins of AND nodes are not in the cut
+int Gia_RsbExpandCut( Gia_Man_t * p, Vec_Int_t * vIns )
+{
+ int fOnlyPis = 0, fChange = 1, nSize = Vec_IntSize(vIns);
+ while ( fChange )
+ {
+ Gia_Obj_t * pObj;
+ int i, iFan0, iFan1, fHave0, fHave1;
+ fOnlyPis = 1;
+ fChange = 0;
+ // check if some nodes can be expanded without increasing cut size
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ {
+ assert( Gia_ObjIsTravIdCurrent(p, pObj) );
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ fOnlyPis = 0;
+ iFan0 = Gia_ObjFaninId0p(p, pObj);
+ iFan1 = Gia_ObjFaninId1p(p, pObj);
+ fHave0 = Gia_ObjIsTravIdCurrentId(p, iFan0);
+ fHave1 = Gia_ObjIsTravIdCurrentId(p, iFan1);
+ if ( !fHave0 && !fHave1 )
+ continue;
+ // can expand because one of the fanins is already in the cut
+ // remove current cut node
+ Vec_IntDrop( vIns, i );
+ // add missing fanin
+ if ( !fHave0 )
+ {
+ Vec_IntPush( vIns, iFan0 );
+ Gia_ObjSetTravIdCurrentId( p, iFan0 );
+ }
+ if ( !fHave1 )
+ {
+ Vec_IntPush( vIns, iFan1 );
+ Gia_ObjSetTravIdCurrentId( p, iFan1 );
+ }
+ fChange = 1;
+ break;
+ }
+ }
+ assert( Vec_IntSize(vIns) <= nSize );
+ return fOnlyPis;
+}
+int Gia_RsbFindFaninAdd( int iFan, int pFanins[32], int pFaninCounts[32], int nFanins )
+{
+ int i;
+ for ( i = 0; i < nFanins; i++ )
+ if ( pFanins[i] == iFan )
+ break;
+ pFanins[i] = iFan;
+ pFaninCounts[i]++;
+ return nFanins + (i == nFanins);
+}
+int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns )
+{
+ Gia_Obj_t * pObj;
+ int nFanins = 0, pFanins[64] = {0}, pFaninCounts[64] = {0};
+ int i, iFan0, iFan1, iFanMax = -1, CountMax = 0;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ {
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ iFan0 = Gia_ObjFaninId0p(p, pObj);
+ iFan1 = Gia_ObjFaninId1p(p, pObj);
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) );
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ nFanins = Gia_RsbFindFaninAdd( iFan0, pFanins, pFaninCounts, nFanins );
+ nFanins = Gia_RsbFindFaninAdd( iFan1, pFanins, pFaninCounts, nFanins );
+ assert( nFanins < 64 );
+ }
+ // find fanin with the highest count
+ if ( p->vFanoutNums != NULL )
+ {
+ for ( i = 0; i < nFanins; i++ )
+ if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjFanoutNumId(p, iFanMax) < Gia_ObjFanoutNumId(p, pFanins[i]))) )
+ {
+ CountMax = pFaninCounts[i];
+ iFanMax = pFanins[i];
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nFanins; i++ )
+ if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjRefNumId(p, iFanMax) < Gia_ObjRefNumId(p, pFanins[i]))) )
+ {
+ CountMax = pFaninCounts[i];
+ iFanMax = pFanins[i];
+ }
+ }
+ return iFanMax;
+}
+// precondition: nodes in vWin and in vIns are marked with the current ID
+void Gia_RsbWindowGrow2( Gia_Man_t * p, int iObj, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax )
+{
+ // window will be recomputed later
+ Vec_IntClear( vWin );
+ // expand the cut without increasing its cost
+ if ( !Gia_RsbExpandCut( p, vIns ) )
+ {
+ // save it as the best cut
+ Vec_Int_t * vBest = Vec_IntSize(vIns) <= nInputsMax ? Vec_IntDup(vIns) : NULL;
+ int fOnlyPis = 0, Iter = 0;
+ // iterate expansion until
+ // (1) the cut cannot be expanded because all leaves are PIs
+ // (2) the cut size exceeded the limit for 5 consecutive iterations
+ while ( !fOnlyPis && (Vec_IntSize(vIns) <= nInputsMax || Iter < 5) )
+ {
+ int iFanBest = Gia_RsbFindFaninToAddToCut( p, vIns );
+ Vec_IntPush( vIns, iFanBest );
+ Gia_ObjSetTravIdCurrentId( p, iFanBest );
+ fOnlyPis = Gia_RsbExpandCut( p, vIns );
+ if ( Vec_IntSize(vIns) > nInputsMax )
+ Iter++;
+ else
+ Iter = 0;
+ if ( Vec_IntSize(vIns) <= nInputsMax && (!vBest || Vec_IntSize(vBest) <= Vec_IntSize(vIns)) )
+ {
+ if ( vBest )
+ Vec_IntClear(vBest);
+ else
+ vBest = Vec_IntAlloc( 10 );
+ Vec_IntAppend( vBest, vIns );
+ }
+ }
+ if ( vBest )
+ {
+ Vec_IntClear( vIns );
+ Vec_IntAppend( vIns, vBest );
+ Vec_IntFree( vBest );
+ }
+ else
+ assert( Vec_IntSize(vIns) > nInputsMax );
+ }
+ if ( vLevels && Vec_IntSize(vIns) <= nInputsMax )
+ {
+ Vec_IntSort( vIns, 0 );
+ Gia_WinCreateFromCut( p, iObj, vIns, vLevels, vWin );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMax, Vec_Wec_t * vLevels, Vec_Int_t * vPaths, Vec_Int_t ** pvWin, Vec_Int_t ** pvIns )
+{
+ Vec_Int_t * vWin, * vIns;
+ *pvWin = *pvIns = NULL;
+ vWin = Gia_RsbWindowInit( p, vPaths, iObj, nLevelsMax );
+ if ( vWin == NULL )
+ return 0;
+ vIns = Gia_RsbCreateWindowInputs( p, vWin );
+ // vWin and vIns are labeled with the current trav ID
+ //Vec_IntPrint( vWin );
+ //Vec_IntPrint( vIns );
+ if ( Vec_IntSize(vIns) <= nInputsMax + 3 ) // consider windows, which initially has a larger input space
+ Gia_RsbWindowGrow2( p, iObj, vLevels, vWin, vIns, nInputsMax );
+ if ( Vec_IntSize(vIns) <= nInputsMax )
+ {
+ Vec_IntSort( vWin, 0 );
+ Vec_IntSort( vIns, 0 );
+ *pvWin = vWin;
+ *pvIns = vIns;
+ return 1;
+ }
+ else
+ {
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ return 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive GIA from the window]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_RsbFindOutputs( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vRefs )
+{
+ Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj; int i;
+ Gia_ManIncrementTravId( p );
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), 1 );
+ }
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjFanoutNum(p, pObj) != Vec_IntEntry(vRefs, Gia_ObjId(p, pObj)) )
+ Vec_IntPush( vOuts, Gia_ObjId(p, pObj) );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), -1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), -1 );
+ }
+ return vOuts;
+}
+
+Gia_Man_t * Gia_RsbDeriveGiaFromWindows( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vOuts )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !~pObj->Value )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vOuts, p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ManHashStop( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Naive truth-table-based verification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word Gia_LutComputeTruth66_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ word Truth0, Truth1;
+ if ( Gia_ObjIsCi(pObj) )
+ return s_Truths6[Gia_ObjCioId(pObj)];
+ if ( Gia_ObjIsConst0(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Truth0 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin0(pObj) );
+ Truth1 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin1(pObj) );
+ if ( Gia_ObjFaninC0(pObj) )
+ Truth0 = ~Truth0;
+ if ( Gia_ObjFaninC1(pObj) )
+ Truth1 = ~Truth1;
+ return Truth0 & Truth1;
+}
+int Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 )
+{
+ int i, fFailed = 0;
+ assert( Gia_ManCoNum(p1) == Gia_ManCoNum(p2) );
+ for ( i = 0; i < Gia_ManCoNum(p1); i++ )
+ {
+ Gia_Obj_t * pPo1 = Gia_ManCo(p1, i);
+ Gia_Obj_t * pPo2 = Gia_ManCo(p2, i);
+ word word1 = Gia_LutComputeTruth66_rec( p1, Gia_ObjFanin0(pPo1) );
+ word word2 = Gia_LutComputeTruth66_rec( p2, Gia_ObjFanin0(pPo2) );
+ if ( Gia_ObjFaninC0(pPo1) )
+ word1 = ~word1;
+ if ( Gia_ObjFaninC0(pPo2) )
+ word2 = ~word2;
+ if ( word1 != word2 )
+ {
+ //Dau_DsdPrintFromTruth( &word1, 6 );
+ //Dau_DsdPrintFromTruth( &word2, 6 );
+ printf( "Verification failed for output %d (out of %d).\n", i, Gia_ManCoNum(p1) );
+ fFailed = 1;
+ }
+ }
+// if ( !fFailed )
+// printf( "Verification succeeded for %d outputs.\n", Gia_ManCoNum(p1) );
+ return !fFailed;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Enumerate windows of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax )
+{
+ int fVerbose = 0;
+ int fUseHash = 0;
+ int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0, nNodeGain = 0;
+ Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 );
+ Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) );
+ Hsh_VecMan_t * pHash = Hsh_VecManStart( 1000 );
+ Gia_Obj_t * pObj;
+ Gia_Man_t * pIn, * pOut;
+ abctime clk = Abc_Clock();
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Vec_Int_t * vWin, * vIns, * vOuts;
+ if ( !Gia_RsbWindowCompute( p, i, nInputsMax, nLevelsMax, vLevels, vPaths, &vWin, &vIns ) )
+ continue;
+ vOuts = Gia_RsbFindOutputs( p, vWin, vIns, vRefs );
+ nWins++;
+ nWinSize += Vec_IntSize(vWin);
+ nInsSize += Vec_IntSize(vIns);
+ nOutSize += Vec_IntSize(vOuts);
+
+
+ if ( fVerbose )
+ {
+ printf( "\n\nObj %d\n", i );
+ Vec_IntPrint( vWin );
+ Vec_IntPrint( vIns );
+ Vec_IntPrint( vOuts );
+ printf( "\n" );
+ }
+ else if ( Vec_IntSize(vWin) > 1000 )
+ printf( "Obj %d. Window: Ins = %d. Ands = %d. Outs = %d.\n",
+ i, Vec_IntSize(vIns), Vec_IntSize(vWin)-Vec_IntSize(vIns), Vec_IntSize(vOuts) );
+
+ if ( fUseHash )
+ {
+ int nEntries = Hsh_VecSize(pHash);
+ Hsh_VecManAdd( pHash, vWin );
+ if ( nEntries == Hsh_VecSize(pHash) )
+ {
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ Vec_IntFree( vOuts );
+ continue;
+ }
+ }
+
+ pIn = Gia_RsbDeriveGiaFromWindows( p, vWin, vIns, vOuts );
+ pOut = Gia_ManResub2Test( pIn );
+ //pOut = Gia_ManDup( pIn );
+ if ( !Gia_ManVerifyTwoTruths( pIn, pOut ) )
+ {
+ Gia_ManPrint( pIn );
+ Gia_ManPrint( pOut );
+ pOut = pOut;
+ }
+
+ nNodeGain += Gia_ManAndNum(pIn) - Gia_ManAndNum(pOut);
+ Gia_ManStop( pIn );
+ Gia_ManStop( pOut );
+
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ Vec_IntFree( vOuts );
+ }
+ Gia_ManStaticFanoutStop( p );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vPaths );
+ Vec_IntFree( vRefs );
+ printf( "Computed windows for %d nodes (out of %d). Unique = %d. Ave inputs = %.2f. Ave outputs = %.2f. Ave volume = %.2f. Gain = %d. ",
+ nWins, Gia_ManAndNum(p), Hsh_VecSize(pHash), 1.0*nInsSize/Abc_MaxInt(1,nWins),
+ 1.0*nOutSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins), nNodeGain );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Hsh_VecManStop( pHash );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Apply k-resub to one AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_RsbTryOneWindow( Gia_Man_t * p )
+{
+ return Gia_ManResub2Test( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Apply k-resub to one AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbTestArray()
+{
+ int Array[1000] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 3, 7, 15, 17, 8, 19,
+ 5, 20, 5, 12, 8, 24, 4, 12, 9, 28, 27, 31, 23, 32, 4, 13, 8, 36, 5,
+ 13, 18, 40, 9, 18, 5, 44, 19, 36, 9, 48, 47, 51, 10, 18, 40, 54, 8,
+ 56, 25, 37, 44, 61, 59, 63, 8, 28, 8, 18, 25, 68, 66, 70, 64, 73, 11,
+ 19, 8, 13, 76, 78, 10, 19, 40, 82, 9, 84, 81, 87, 20, 61, 19, 28, 30,
+ 92, 91, 95, 88, 96, 74, 98, 9, 40, 49, 103, 27, 104, 10, 107, 8, 40,
+ 9, 24, 111, 113, 11, 115, 109, 117, 11, 66, 51, 121, 118, 122, 18, 36,
+ 18, 110, 93, 127, 10, 131, 129, 133, 11, 38, 32, 137, 103, 138, 19, 141,
+ 134, 143, 28, 76, 9, 146, 11, 110, 19, 150, 149, 153, 87, 95, 9, 19, 10,
+ 159, 61, 160, 18, 30, 61, 158, 9, 12, 25, 169, 19, 171, 111, 173, 10, 175,
+ 167, 177, 18, 102, 4, 20, 18, 171, 183, 185, 11, 187, 181, 189, 178, 190,
+ 24, 44, 11, 194, 8, 54, 4, 198, 197, 201, 45, 49, 10, 39, 9, 126, 73, 209,
+ 11, 211, 54, 168, 213, 215, 43, 167, 67, 218, 10, 221, 26, 54, 18, 18, 34,
+ 34, 38, 38, 40, 40, 42, 42, 52, 52, 100, 100, 124, 124, 126, 126, 144, 144,
+ 148, 148, 154, 154, 156, 156, 162, 162, 164, 164, 192, 192, 70, 70, 202,
+ 202, 204, 204, 206, 206, 216, 216, 222, 222, 224, 224
+ };
+ int i, iFan0, iFan1, nResubs;
+ int * pRes;
+ // create the internal array
+ Vec_Int_t * vArray = Vec_IntAlloc( 100 );
+ for ( i = 0; i < 50 || Array[i] > 0; i++ )
+ Vec_IntPush( vArray, Array[i] );
+ Vec_IntPrint( vArray );
+ // check the nodes
+ printf( "Constant0 and primary inputs:\n" );
+ Vec_IntForEachEntryDouble( vArray, iFan0, iFan1, i )
+ {
+ if ( iFan0 != iFan1 )
+ break;
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0),
+ Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) );
+ }
+ printf( "Primary outputs:\n" );
+ Vec_IntForEachEntryDoubleStart( vArray, iFan0, iFan1, i, 14 )
+ {
+ if ( iFan0 != iFan1 )
+ continue;
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0),
+ Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) );
+ }
+ // run the resub
+ Abc_ResubPrepareManager( 1 );
+ Abc_ResubComputeWindow( Vec_IntArray(vArray), Vec_IntSize(vArray)/2, 10, -1, 0, 0, 1, 1, &pRes, &nResubs );
+ Abc_ResubPrepareManager( 0 );
+ Vec_IntFree( vArray );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computing cuts of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose )
+{
+ int c, nLevelMax = 8;
+ abctime clk = Abc_Clock();
+ Vec_Wec_t * vCuts = Vec_WecStart( nCuts );
+ Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) );
+ srand( time(NULL) );
+ for ( c = 0; c < nCuts; )
+ {
+ Vec_Int_t * vCut, * vWin = NULL;
+ while ( vWin == NULL )
+ {
+ int iPivot = 1 + Gia_ManCiNum(p) + rand() % Gia_ManAndNum(p);
+ assert( Gia_ObjIsAnd(Gia_ManObj(p, iPivot)) );
+ vWin = Gia_RsbWindowInit( p, vPaths, iPivot, nLevelMax );
+ }
+ vCut = Gia_RsbCreateWindowInputs( p, vWin );
+ if ( Vec_IntSize(vCut) >= nCutSize - 2 && Vec_IntSize(vCut) <= nCutSize )
+ {
+ Vec_IntPush( Vec_WecEntry(vCuts, c), Vec_IntSize(vCut) );
+ Vec_IntAppend( Vec_WecEntry(vCuts, c++), vCut );
+ }
+ Vec_IntFree( vCut );
+ Vec_IntFree( vWin );
+ }
+ Vec_IntFree( vPaths );
+ Abc_PrintTime( 0, "Computing cuts ", Abc_Clock() - clk );
+ return vCuts;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaResub3.c b/src/aig/gia/giaResub3.c
new file mode 100644
index 00000000..71e182d1
--- /dev/null
+++ b/src/aig/gia/giaResub3.c
@@ -0,0 +1,54 @@
+/**CFile****************************************************************
+
+ FileName [giaResub3.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Resubstitution computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaResub3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformNewResub( Gia_Man_t * p, int nWinCount, int nCutSize, int nProcs, int fVerbose )
+{
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaScript.c b/src/aig/gia/giaScript.c
index 334b1ee9..b52288a9 100644
--- a/src/aig/gia/giaScript.c
+++ b/src/aig/gia/giaScript.c
@@ -88,7 +88,12 @@ Gia_Man_t * Gia_ManAigSyn2( Gia_Man_t * pInit, int fOldAlgo, int fCoarsen, int f
p = Gia_ManDup( pInit );
Gia_ManTransferTiming( p, pInit );
if ( Gia_ManAndNum(p) == 0 )
- return p;
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ Gia_ManStop( p );
+ return pNew;
+ }
// delay optimization
if ( fDelayMin && p->pManTime == NULL )
{
@@ -157,7 +162,12 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
pPars->nRelaxRatio = 40;
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ //Gia_ManStop( p );
+ return pNew;
+ }
// perform balancing
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
if ( fVerbose ) Gia_ManPrintStats( pNew, NULL );
@@ -189,7 +199,12 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
pPars->nRelaxRatio = 40;
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ //Gia_ManStop( p );
+ return pNew;
+ }
//Gia_ManAigPrintPiLevels( p );
// perform balancing
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c
index 001bd8ac..ecad182f 100644
--- a/src/aig/gia/giaSim.c
+++ b/src/aig/gia/giaSim.c
@@ -1222,6 +1222,172 @@ int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 )
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimOneBit( Gia_Man_t * p, Vec_Int_t * vValues )
+{
+ Gia_Obj_t * pObj; int k;
+ assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) );
+
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->fMark0 = Vec_IntEntry(vValues, k);
+ Gia_ManForEachAnd( p, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+
+ Gia_ManForEachCi( p, pObj, k )
+ printf( "%d", k % 10 );
+ printf( "\n" );
+ Gia_ManForEachCi( p, pObj, k )
+ printf( "%d", Vec_IntEntry(vValues, k) );
+ printf( "\n" );
+
+ Gia_ManForEachCo( p, pObj, k )
+ printf( "%d", k % 10 );
+ printf( "\n" );
+ Gia_ManForEachCo( p, pObj, k )
+ printf( "%d", pObj->fMark0 );
+ printf( "\n" );
+ printf( "\n" );
+}
+void Gia_ManSimOneBitTest2( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFill( vValues, Vec_IntSize(vValues)/2, 1 );
+ Vec_IntFillExtra( vValues, Gia_ManCiNum(p), 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 1 );
+ Vec_IntWriteEntry( vValues, 255, 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 0 );
+ Vec_IntWriteEntry( vValues, 255, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 0 );
+ Vec_IntWriteEntry( vValues, 255, 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFree( vValues );
+}
+void Gia_ManSimOneBitTest3( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFree( vValues );
+}
+
+
+void Gia_ManSimOneBitTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ int i, k;
+ for ( i = 0; i < 10; i++ )
+ {
+ for ( k = 0; k < Vec_IntSize(vValues); k++ )
+ Vec_IntWriteEntry( vValues, k, Vec_IntEntry(vValues, k) ^ (rand()&1) );
+
+ printf( "Values = %d ", Vec_IntSum(vValues) );
+ Gia_ManSimOneBit( p, vValues );
+ }
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c
index c53c1db8..c31064fe 100644
--- a/src/aig/gia/giaSimBase.c
+++ b/src/aig/gia/giaSimBase.c
@@ -21,6 +21,7 @@
#include "gia.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
+//#include <immintrin.h>
ABC_NAMESPACE_IMPL_START
@@ -112,7 +113,13 @@ static inline void Gia_ManSimPatSimPo( Gia_Man_t * p, int i, Gia_Obj_t * pObj, i
word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i);
word * pSims2 = pSims + nWords*i; int w;
for ( w = 0; w < nWords; w++ )
- pSims2[w] = (pSims0[w] ^ Diff0);
+ pSims2[w] = (pSims0[w] ^ Diff0);
+}
+static inline void Gia_ManSimPatSimNot( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims) + nWords*i; int w;
+ for ( w = 0; w < nWords; w++ )
+ pSims[w] = ~pSims[w];
}
Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia )
{
@@ -127,6 +134,427 @@ Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia )
Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
return vSims;
}
+Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts )
+{
+ Gia_Obj_t * pObj;
+ int i, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(pGia);
+ Vec_Wrd_t * vSimsCo = fOuts ? Vec_WrdStart( Gia_ManCoNum(pGia) * nWords ) : NULL;
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
+ assert( Vec_WrdSize(vSimsPi) % Gia_ManCiNum(pGia) == 0 );
+ Gia_ManSimPatAssignInputs( pGia, nWords, vSims, vSimsPi );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims );
+ Gia_ManForEachCo( pGia, pObj, i )
+ Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ if ( !fOuts )
+ return vSims;
+ Gia_ManForEachCo( pGia, pObj, i )
+ memcpy( Vec_WrdEntryP(vSimsCo, i*nWords), Vec_WrdEntryP(vSims, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords );
+ Vec_WrdFree( vSims );
+ return vSimsCo;
+}
+static inline void Gia_ManSimPatSimAnd3( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC )
+{
+ word pComps[2] = { ~(word)0, 0 };
+ word Diff0 = pComps[Gia_ObjFaninC0(pObj)];
+ word Diff1 = pComps[Gia_ObjFaninC1(pObj)];
+ word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSims2 = Vec_WrdArray(vSims) + nWords*i;
+ word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w;
+ if ( Gia_ObjIsXor(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSimsC0[w] |= pSimsC2[w];
+ pSimsC1[w] |= pSimsC2[w];
+ }
+ else
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSimsC0[w] |= (pSims2[w] | (pSims0[w] ^ Diff0)) & pSimsC2[w];
+ pSimsC1[w] |= (pSims2[w] | (pSims1[w] ^ Diff1)) & pSimsC2[w];
+ }
+}
+Vec_Wrd_t * Gia_ManSimPatSimIn( Gia_Man_t * pGia, Vec_Wrd_t * vSims, int fIns, Vec_Int_t * vAnds )
+{
+ Gia_Obj_t * pObj;
+ int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia);
+ Vec_Wrd_t * vSimsCi = fIns ? Vec_WrdStart( Gia_ManCiNum(pGia) * nWords ) : NULL;
+ Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) );
+ assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 );
+ if ( vAnds )
+ Vec_IntForEachEntry( vAnds, Id, i )
+ memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords );
+ else
+ Gia_ManForEachCoDriverId( pGia, Id, i )
+ memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords );
+ Gia_ManForEachAndReverse( pGia, pObj, i )
+ Gia_ManSimPatSimAnd3( pGia, i, pObj, nWords, vSims, vSimsC );
+ if ( !fIns )
+ return vSimsC;
+ Gia_ManForEachCi( pGia, pObj, i )
+ memcpy( Vec_WrdEntryP(vSimsCi, i*nWords), Vec_WrdEntryP(vSimsC, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords );
+ Vec_WrdFree( vSimsC );
+ return vSimsCi;
+}
+void Gia_ManSimPatSimInTest( Gia_Man_t * pGia )
+{
+ int nWords = 10;
+ Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 );
+ Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL );
+ int nOnes = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) );
+ int nTotal = 64*nWords*Gia_ManCandNum(pGia);
+ printf( "Ratio = %6.2f %%\n", 100.0*nOnes/nTotal );
+ Vec_WrdFree( vSims );
+ Vec_WrdFree( vSims2 );
+ Vec_WrdFree( vSimsCi );
+}
+static inline void Gia_ManSimPatSimAnd4( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC )
+{
+ word pComps[2] = { ~(word)0, 0 };
+ word Diff0 = pComps[Gia_ObjFaninC0(pObj)];
+ word Diff1 = pComps[Gia_ObjFaninC1(pObj)];
+ word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w;
+ if ( Gia_ObjIsXor(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pSimsC2[w] = pSimsC0[w] & pSimsC1[w];
+ else
+ for ( w = 0; w < nWords; w++ )
+ pSimsC2[w] = (pSimsC0[w] & pSimsC1[w]) | ((pSims0[w] ^ Diff0) & pSimsC0[w]) | ((pSims1[w] ^ Diff1) & pSimsC1[w]);
+}
+Vec_Wrd_t * Gia_ManSimPatSimC( Gia_Man_t * pGia, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsCiC )
+{
+ Gia_Obj_t * pObj;
+ int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia);
+ Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) );
+ assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 );
+ memset( Vec_WrdEntryP(vSimsC, 0), 0xFF, sizeof(word)*nWords );
+ Gia_ManForEachCiId( pGia, Id, i )
+ memmove( Vec_WrdEntryP(vSimsC, Id*nWords), Vec_WrdEntryP(vSimsCiC, i*nWords), sizeof(word)*nWords );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd4( pGia, i, pObj, nWords, vSims, vSimsC );
+ return vSimsC;
+}
+void Gia_ManSimPatSimCTest( Gia_Man_t * pGia )
+{
+ int nWords = 10;
+ Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 );
+ Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL );
+ Vec_Wrd_t * vSimsCi2 = Gia_ManSimPatSimIn( pGia, vSims, 1, NULL );
+ Vec_Wrd_t * vSims3 = Gia_ManSimPatSimC( pGia, vSims, vSimsCi2 );
+ int nOnes2 = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) );
+ int nOnes3 = Abc_TtCountOnesVec( Vec_WrdArray(vSims3), Vec_WrdSize(vSims3) );
+ int nTotal = 64*nWords*Gia_ManCandNum(pGia);
+ printf( "Ratio = %6.2f %% Ratio = %6.2f %%\n", 100.0*nOnes2/nTotal, 100.0*nOnes3/nTotal );
+ Vec_WrdFree( vSims );
+ Vec_WrdFree( vSims2 );
+ Vec_WrdFree( vSims3 );
+ Vec_WrdFree( vSimsCi );
+ Vec_WrdFree( vSimsCi2 );
+}
+void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_ManForEachObjVec( vObjs, pGia, pObj, i )
+ if ( i == 0 )
+ Gia_ManSimPatSimNot( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ else if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManSimPatSimAnd( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ else if ( !Gia_ObjIsCo(pObj) ) assert(0);
+}
+void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords )
+{
+ Vec_WrdDumpHex( pFileName, vSimsIn, nWords, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word * Gia_ManDeriveFuncs( Gia_Man_t * p )
+{
+ int nVars2 = (Gia_ManCiNum(p) + 6)/2;
+ int nVars3 = Gia_ManCiNum(p) - nVars2;
+ int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) );
+ int nWords2 = Abc_Truth6WordNum( nVars2 );
+ word * pRes = ABC_ALLOC( word, Gia_ManCoNum(p) * nWords );
+ Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) );
+ Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 );
+ Gia_Obj_t * pObj; int i, v, m;
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+ for ( i = 0; i < nVars2; i++ )
+ Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*(i+1)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 );
+ Vec_PtrFree( vTruths );
+ for ( m = 0; m < (1 << nVars3); m++ )
+ {
+ for ( v = 0; v < nVars3; v++ )
+ Abc_TtConst( Vec_WrdEntryP(vSims, nWords2*(nVars2+v+1)), nWords2, (m >> v) & 1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj), pObj, nWords2, vSims );
+ Gia_ManForEachCo( p, pObj, i )
+ Abc_TtCopy( pRes + i*nWords + m*nWords2, Vec_WrdEntryP(vSims, nWords2*Gia_ObjId(p, pObj)), nWords2, 0 );
+ }
+ Vec_WrdFree( vSims );
+ return pRes;
+}
+Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p )
+{
+ extern int Gia_ManFindMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift );
+ extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+ int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) );
+ int nCofs = 1 << (Gia_ManCiNum(p) - 6);
+ word * pRes = Gia_ManDeriveFuncs( p );
+ Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 16 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( 6 );
+ Vec_Int_t * vCtrls = Vec_IntAlloc( nCofs );
+ Vec_Int_t * vDatas = Vec_IntAlloc( Gia_ManCoNum(p) );
+ Gia_Man_t * pNew, * pTemp; int i, o;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( i < 6 ? vLeaves : vCtrls, Gia_ManAppendCi(pNew) );
+ Gia_ManHashAlloc( pNew );
+ for ( o = 0; o < Gia_ManCoNum(p); o++ )
+ {
+ Vec_IntClear( vDatas );
+ for ( i = 0; i < nWords; i++ )
+ Vec_IntPush( vDatas, Kit_TruthToGia(pNew, (unsigned *)(pRes+o*nWords+i), 6, vMemory, vLeaves, 1) );
+ Gia_ManAppendCo( pNew, Gia_ManFindMuxTree_rec(pNew, Vec_IntArray(vCtrls), Vec_IntSize(vCtrls), vDatas, 0) );
+ }
+ Gia_ManHashStop( pNew );
+ ABC_FREE( pRes );
+ Vec_IntFree( vMemory );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vCtrls );
+ Vec_IntFree( vDatas );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Gia_ManTransferTiming( pNew, p );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManComputeTfos_rec( Gia_Man_t * p, int iObj, int iRoot, Vec_Int_t * vNode )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) )
+ return 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(pObj, iObj), iRoot, vNode ) |
+ Gia_ManComputeTfos_rec( p, Gia_ObjFaninId1(pObj, iObj), iRoot, vNode ) )
+ {
+ Gia_ObjSetTravIdPreviousId(p, iObj);
+ Vec_IntPush( vNode, iObj );
+ return 1;
+ }
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ return 0;
+}
+Vec_Wec_t * Gia_ManComputeTfos( Gia_Man_t * p )
+{
+ Vec_Wec_t * vNodes = Vec_WecStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ int i, o, IdCi, IdCo;
+ Gia_ManForEachCiId( p, IdCi, i )
+ {
+ Vec_Int_t * vNode = Vec_WecEntry( vNodes, i );
+ Gia_ManIncrementTravId( p );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdPreviousId(p, IdCi);
+ Vec_IntPush( vNode, IdCi );
+ Vec_IntClear( vTemp );
+ Gia_ManForEachCoId( p, IdCo, o )
+ if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(Gia_ManObj(p, IdCo), IdCo), IdCi, vNode ) )
+ Vec_IntPush( vTemp, Gia_ManObjNum(p) + (o >> 1) );
+ Vec_IntUniqify( vTemp );
+ Vec_IntAppend( vNode, vTemp );
+ }
+ Vec_IntFree( vTemp );
+ Vec_WecSort( vNodes, 1 );
+ //Vec_WecPrint( vNodes, 0 );
+ //Gia_AigerWrite( p, "dump.aig", 0, 0, 0 );
+ return vNodes;
+}
+int Gia_ManFindDividerVar( Gia_Man_t * p, int fVerbose )
+{
+ int iVar, Target = 1 << 28;
+ for ( iVar = 6; iVar < Gia_ManCiNum(p); iVar++ )
+ if ( (1 << (iVar-3)) * Gia_ManObjNum(p) > Target )
+ break;
+ if ( iVar == Gia_ManCiNum(p) )
+ iVar = Gia_ManCiNum(p) - 1;
+ if ( fVerbose )
+ printf( "Split var = %d. Rounds = %d. Bytes per node = %d. Total = %.2f MB.\n", iVar, 1 << (Gia_ManCiNum(p) - iVar), 1 << (iVar-3), 1.0*(1 << (iVar-3)) * Gia_ManObjNum(p)/(1<<20) );
+ return iVar;
+}
+int Gia_ManComparePair( Gia_Man_t * p, Vec_Wrd_t * vSims, int iOut, int nWords2 )
+{
+ Gia_Obj_t * pObj0 = Gia_ManCo( p, 2*iOut+0 );
+ Gia_Obj_t * pObj1 = Gia_ManCo( p, 2*iOut+1 );
+ word * pSim0 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj0) );
+ word * pSim1 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj1) );
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj0), pObj0, nWords2, vSims );
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj1), pObj1, nWords2, vSims );
+ return Abc_TtEqual( pSim0, pSim1, nWords2 );
+}
+int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose )
+{
+ abctime clk = Abc_Clock(); int fWarning = 0;
+ //int nVars2 = (Gia_ManCiNum(p) + 6)/2;
+ int nVars2 = Gia_ManFindDividerVar( p, fVerbose );
+ int nVars3 = Gia_ManCiNum(p) - nVars2;
+ int nWords2 = Abc_Truth6WordNum( nVars2 );
+ Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) );
+ Vec_Wec_t * vNodes = Gia_ManComputeTfos( p );
+ Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 );
+ Gia_Obj_t * pObj; Vec_Int_t * vNode; int i, m, iObj;
+ Vec_WecForEachLevelStop( vNodes, vNode, i, nVars2 )
+ Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 );
+ Vec_PtrFree( vTruths );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims );
+ for ( i = 0; i < Gia_ManCoNum(p)/2; i++ )
+ {
+ if ( !Gia_ManComparePair( p, vSims, i, nWords2 ) )
+ {
+ printf( "Miter is asserted for output %d.\n", i );
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 0;
+ }
+ }
+ for ( m = 0; m < (1 << nVars3); m++ )
+ {
+ int iVar = m ? Abc_TtSuppFindFirst( m ^ (m >> 1) ^ (m-1) ^ ((m-1) >> 1) ) : 0;
+ vNode = Vec_WecEntry( vNodes, nVars2+iVar );
+ Abc_TtNot( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), nWords2 );
+ Vec_IntForEachEntryStart( vNode, iObj, i, 1 )
+ {
+ if ( iObj < Gia_ManObjNum(p) )
+ {
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManSimPatSimAnd( p, iObj, pObj, nWords2, vSims );
+ }
+ else if ( !Gia_ManComparePair( p, vSims, iObj - Gia_ManObjNum(p), nWords2 ) )
+ {
+ printf( "Miter is asserted for output %d.\n", iObj - Gia_ManObjNum(p) );
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 0;
+ }
+ }
+ //for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ // printf( "%3d : ", i), Extra_PrintHex2( stdout, (unsigned *)Vec_WrdEntryP(vSims, i), 6 ), printf( "\n" );
+ if ( !fWarning && Abc_Clock() > clk + 5*CLOCKS_PER_SEC )
+ printf( "The computation is expected to take about %.2f sec.\n", 5.0*(1 << nVars3)/m ), fWarning = 1;
+ //if ( (m & 0x3F) == 0x3F )
+ if ( fVerbose && (m & 0xFF) == 0xFF )
+ printf( "Finished %6d (out of %6d)...\n", m, 1 << nVars3 );
+ }
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimPatAssignInputs2( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn )
+{
+ int i, Id;
+ assert( Vec_WrdSize(vSims) == 2 * nWords * Gia_ManObjNum(p) );
+ assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) );
+ Gia_ManForEachCiId( p, Id, i )
+ {
+ Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+0), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 0 );
+ Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+1), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 1 );
+ }
+}
+static inline void Gia_ManSimPatSimAnd2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims);
+ word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i);
+ word * pSims1 = pSims + nWords*Gia_ObjFaninLit1(pObj, i);
+ word * pSims2 = pSims + nWords*(2*i+0);
+ word * pSims3 = pSims + nWords*(2*i+1); int w;
+ assert( !Gia_ObjIsXor(pObj) );
+// if ( Gia_ObjIsXor(pObj) )
+// for ( w = 0; w < nWords; w++ )
+// pSims2[w] = pSims0[w] ^ pSims1[w];
+// else
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSims2[w] = pSims0[w] & pSims1[w];
+ pSims3[w] = ~pSims2[w];
+ }
+ //_mm256_storeu_ps( (float *)pSims2, _mm256_and_ps(_mm256_loadu_ps((float *)pSims0), _mm256_loadu_ps((float *)pSims1)) );
+}
+static inline void Gia_ManSimPatSimPo2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims);
+ word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i);
+ word * pSims2 = pSims + nWords*i; int w;
+ for ( w = 0; w < nWords; w++ )
+ pSims2[w] = pSims0[w];
+}
+Vec_Wrd_t * Gia_ManSimPatSim2( Gia_Man_t * pGia )
+{
+ Gia_Obj_t * pObj;
+ int i, nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia);
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords * 2 );
+ assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 );
+ Gia_ManSimPatAssignInputs2( pGia, nWords, vSims, pGia->vSimsPi );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd2( pGia, i, pObj, nWords, vSims );
+ Gia_ManForEachCo( pGia, pObj, i )
+ Gia_ManSimPatSimPo2( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ return vSims;
+}
/**Function*************************************************************
@@ -248,7 +676,6 @@ Vec_Wrd_t * Gia_ManSimBitPacking( Gia_Man_t * p, Vec_Int_t * vCexStore, int nCex
return vSimsRes;
}
-
/**Function*************************************************************
Synopsis []
@@ -306,87 +733,6 @@ Gia_Man_t * Gia_ManSimPatGenMiter( Gia_Man_t * p, Vec_Wrd_t * vSims )
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords )
-{
- int k, Digit, nDigits = nWords*16;
- for ( k = 0; k < nDigits; k++ )
- {
- Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15);
- if ( Digit < 10 )
- fprintf( pFile, "%d", Digit );
- else
- fprintf( pFile, "%c", 'A' + Digit-10 );
- }
- fprintf( pFile, "\n" );
-}
-void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords )
-{
- int i, nNodes = Vec_WrdSize(vSimsIn) / nWords;
- FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\" for writing.\n", pFileName );
- return;
- }
- assert( Vec_WrdSize(vSimsIn) % nWords == 0 );
- for ( i = 0; i < nNodes; i++ )
- Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords );
- fclose( pFile );
- printf( "Written %d words of simulation data into file \"%s\".\n", nWords, pFileName );
-}
-int Gia_ManSimPatReadOne( char c )
-{
- int Digit = 0;
- if ( c >= '0' && c <= '9' )
- Digit = c - '0';
- else if ( c >= 'A' && c <= 'F' )
- Digit = c - 'A' + 10;
- else if ( c >= 'a' && c <= 'f' )
- Digit = c - 'a' + 10;
- else assert( 0 );
- assert( Digit >= 0 && Digit < 16 );
- return Digit;
-}
-Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName )
-{
- Vec_Wrd_t * vSimsIn = NULL;
- int c, nWords = -1, nChars = 0; word Num = 0;
- FILE * pFile = fopen( pFileName, "rb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\" for reading.\n", pFileName );
- return NULL;
- }
- vSimsIn = Vec_WrdAlloc( 1000 );
- while ( (c = fgetc(pFile)) != EOF )
- {
- if ( c == '\n' && nWords == -1 )
- nWords = Vec_WrdSize(vSimsIn);
- if ( c == '\n' || c == '\r' || c == '\t' || c == ' ' )
- continue;
- Num |= (word)Gia_ManSimPatReadOne((char)c) << (nChars * 4);
- if ( ++nChars < 16 )
- continue;
- Vec_WrdPush( vSimsIn, Num );
- nChars = 0;
- Num = 0;
- }
- assert( Vec_WrdSize(vSimsIn) % nWords == 0 );
- fclose( pFile );
- printf( "Read %d words of simulation data.\n", nWords );
- return vSimsIn;
-}
/**Function*************************************************************
@@ -2029,6 +2375,331 @@ void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
+/**Function*************************************************************
+
+ Synopsis [Trying vectorized simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimTest( Gia_Man_t * pGia )
+{
+ int n, nWords = 4;
+ Vec_Wrd_t * vSim1, * vSim2;
+ Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ abctime clk = Abc_Clock();
+
+ pGia->vSimsPi = vSim0;
+ for ( n = 0; n < 20; n++ )
+ {
+ vSim1 = Gia_ManSimPatSim( pGia );
+ Vec_WrdFree( vSim1 );
+ }
+ Abc_PrintTime( 1, "Time1", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ for ( n = 0; n < 20; n++ )
+ {
+ vSim2 = Gia_ManSimPatSim2( pGia );
+ Vec_WrdFree( vSim2 );
+ }
+ Abc_PrintTime( 1, "Time2", Abc_Clock() - clk );
+
+ pGia->vSimsPi = NULL;
+ Vec_WrdFree( vSim0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Trying compiled simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimGen( Gia_Man_t * pGia )
+{
+ int nWords = 4;
+ Gia_Obj_t * pObj;
+ Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ FILE * pFile = fopen( "comp_sim.c", "wb" );
+ int i, k, Id;
+ fprintf( pFile, "#include <stdio.h>\n" );
+ fprintf( pFile, "#include <stdlib.h>\n" );
+ fprintf( pFile, "#include <time.h>\n" );
+ fprintf( pFile, "int main()\n" );
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " clock_t clkThis = clock();\n" );
+ fprintf( pFile, " unsigned long Res = 0;\n" );
+ fprintf( pFile, " int i;\n" );
+ fprintf( pFile, " srand(time(NULL));\n" );
+ fprintf( pFile, " for ( i = 0; i < 2000; i++ )\n" );
+ fprintf( pFile, " {\n" );
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = 0x%08x%08x;\n", 0, k, 0, 0 );
+ Gia_ManForEachCiId( pGia, Id, i )
+ {
+ //word * pSim = Vec_WrdEntryP(vSim0, i*nWords);
+ //unsigned * pSimU = (unsigned *)pSim;
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = ((unsigned long)rand() << 48) | ((unsigned long)rand() << 32) | ((unsigned long)rand() << 16) | (unsigned long)rand();\n", Id, k );
+ }
+ Gia_ManForEachAnd( pGia, pObj, Id )
+ {
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = %cs%07d_%d & %cs%07d_%d;\n", Id, k,
+ Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k,
+ Gia_ObjFaninC1(pObj) ? ' ' : '~', Gia_ObjFaninId1(pObj, Id), k );
+ }
+ Gia_ManForEachCoId( pGia, Id, i )
+ {
+ pObj = Gia_ManObj(pGia, Id);
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " Res ^= %cs%07d_%d;\n", Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k );
+ }
+ Vec_WrdFree( vSim0 );
+ fprintf( pFile, " }\n" );
+ fprintf( pFile, " printf( \"Res = 0x%%08x \", (unsigned)Res );\n" );
+ fprintf( pFile, " printf( \"Time = %%6.2f sec\\n\", (float)(clock() - clkThis)/CLOCKS_PER_SEC );\n" );
+ fprintf( pFile, " return 1;\n" );
+ fprintf( pFile, "}\n" );
+ fclose( pFile );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Trying vectorized simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose )
+{
+ Vec_Wrd_t * vSim0, * vSim1, * vSim2;
+ abctime clk = Abc_Clock();
+ int n, i, RetValue = 1;
+ printf( "Simulating %d round with %d machine words.\n", nRounds, nWords );
+ Abc_RandomW(0);
+ for ( n = 0; RetValue && n < nRounds; n++ )
+ {
+ vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(p0) * nWords );
+ p0->vSimsPi = vSim0;
+ p1->vSimsPi = vSim0;
+ vSim1 = Gia_ManSimPatSim( p0 );
+ vSim2 = Gia_ManSimPatSim( p1 );
+ for ( i = 0; i < Gia_ManCoNum(p0); i++ )
+ {
+ word * pSim1 = Vec_WrdEntryP(vSim1, Gia_ObjId(p0, Gia_ManCo(p0, i))*nWords);
+ word * pSim2 = Vec_WrdEntryP(vSim2, Gia_ObjId(p1, Gia_ManCo(p1, i))*nWords);
+ if ( memcmp(pSim1, pSim2, sizeof(word)*nWords) )
+ {
+ printf( "Output %d failed simulation at round %d. ", i, n );
+ RetValue = 0;
+ break;
+ }
+ }
+ Vec_WrdFree( vSim1 );
+ Vec_WrdFree( vSim2 );
+ Vec_WrdFree( vSim0 );
+ p0->vSimsPi = NULL;
+ p1->vSimsPi = NULL;
+ }
+ if ( RetValue == 1 )
+ printf( "Simulation did not detect a bug. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Serialization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes )
+{
+ word * pInfo = Vec_WrdArray(vSimsPi); int w, i;
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ Vec_IntClear( vRes );
+ for ( w = 0; w < Vec_WrdSize(vSimsPi); w++ )
+ if ( pCare[w] )
+ for ( i = 0; i < 64; i++ )
+ if ( Abc_TtGetBit(pCare, w*64+i) )
+ Vec_IntPush( vRes, Abc_Var2Lit(w*64+i, Abc_TtGetBit(pInfo, w*64+i)) );
+ Vec_IntPush( vRes, Vec_WrdSize(vSimsPi) );
+}
+Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Vec_PtrSize(vSims) );
+ Vec_Int_t * vLevel; int i;
+ Vec_WecForEachLevel( vRes, vLevel, i )
+ Gia_ManSim2ArrayOne( (Vec_Wrd_t *)Vec_PtrEntry(vSims, i), vLevel );
+ return vRes;
+}
+
+Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes )
+{
+ int i, iLit, nWords = Vec_IntEntryLast(vRes);
+ Vec_Wrd_t * vSimsPi = Vec_WrdStart( 2*nWords );
+ word * pInfo = Vec_WrdArray(vSimsPi);
+ word * pCare = pInfo + nWords;
+ Vec_IntPop( vRes );
+ Vec_IntForEachEntry( vRes, iLit, i )
+ {
+ Abc_TtXorBit( pCare, Abc_Lit2Var(iLit) );
+ if ( Abc_LitIsCompl(iLit) )
+ Abc_TtXorBit( pInfo, Abc_Lit2Var(iLit) );
+ }
+ Vec_IntPush( vRes, nWords );
+ Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 );
+ return vSimsPi;
+}
+Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes )
+{
+ Vec_Ptr_t * vSims = Vec_PtrAlloc( Vec_WecSize(vRes) );
+ Vec_Int_t * vLevel; int i;
+ Vec_WecForEachLevel( vRes, vLevel, i )
+ Vec_PtrPush( vSims, Gia_ManArray2SimOne(vLevel) );
+ return vSims;
+}
+
+void Gia_ManSimArrayTest( Vec_Wrd_t * vSimsPi )
+{
+ Vec_Ptr_t * vTemp = Vec_PtrAlloc( 2 );
+ Vec_PtrPushTwo( vTemp, vSimsPi, vSimsPi );
+ {
+ Vec_Wec_t * vRes = Gia_ManSim2Array( vTemp );
+ Vec_WecDumpBin( "temp.sims", vRes, 1 );
+ {
+ Vec_Wec_t * vRes = Vec_WecReadBin( "temp.sims", 1 );
+ Vec_Ptr_t * vTemp2 = Gia_ManArray2Sim( vRes );
+ Vec_Wrd_t * vSimsPi2 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 0 );
+ Vec_Wrd_t * vSimsPi3 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 1 );
+
+ Abc_TtAnd( Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi)+Vec_WrdSize(vSimsPi), Vec_WrdSize(vSimsPi), 0 );
+
+ vSimsPi->nSize *= 2;
+ vSimsPi2->nSize *= 2;
+ vSimsPi3->nSize *= 2;
+ Vec_WrdDumpHex( "test1.hex", vSimsPi, 1, 1 );
+ Vec_WrdDumpHex( "test2.hex", vSimsPi2, 1, 1 );
+ Vec_WrdDumpHex( "test3.hex", vSimsPi3, 1, 1 );
+ vSimsPi->nSize /= 2;
+ vSimsPi2->nSize /= 2;
+ vSimsPi3->nSize /= 2;
+
+ if ( Vec_WrdEqual( vSimsPi, vSimsPi2 ) )
+ printf( "Success.\n" );
+ else
+ printf( "Failure.\n" );
+ if ( Vec_WrdEqual( vSimsPi, vSimsPi3 ) )
+ printf( "Success.\n" );
+ else
+ printf( "Failure.\n" );
+ Vec_WrdFree( vSimsPi2 );
+ Vec_WrdFree( vSimsPi3 );
+ Vec_PtrFree( vTemp2 );
+ Vec_WecFree( vRes );
+ }
+ Vec_WecFree( vRes );
+ }
+ Vec_PtrFree( vTemp );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Serialization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose )
+{
+ Vec_Wrd_t * vLevel;
+ int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ nSize = Vec_PtrSize(p);
+ RetValue = fwrite( &nSize, 1, sizeof(int), pFile );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i )
+ {
+ nSize = Vec_WrdSize(vLevel);
+ RetValue += fwrite( &nSize, 1, sizeof(int), pFile );
+ RetValue += fwrite( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile );
+ }
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Written %d arrays into file \"%s\".\n", Vec_PtrSize(p), pFileName );
+}
+Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose )
+{
+ Vec_Ptr_t * p = NULL; Vec_Wrd_t * vLevel; int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize == 0 )
+ {
+ printf( "The input file is empty.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nSize % (int)sizeof(int) > 0 )
+ {
+ printf( "Cannot read file with integers because it is not aligned at 4 bytes (remainder = %d).\n", nSize % (int)sizeof(int) );
+ fclose( pFile );
+ return NULL;
+ }
+ rewind( pFile );
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ p = Vec_PtrAlloc( nSize );
+ for ( i = 0; i < nSize; i++ )
+ Vec_PtrPush( p, Vec_WrdAlloc(100) );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i )
+ {
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ Vec_WrdFill( vLevel, nSize, 0 );
+ RetValue = fread( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile );
+ assert( RetValue == 8*nSize );
+ }
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Read %d arrays from file \"%s\".\n", Vec_PtrSize(p), pFileName );
+ return p;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c
new file mode 100644
index 00000000..94f53998
--- /dev/null
+++ b/src/aig/gia/giaStoch.c
@@ -0,0 +1,448 @@
+/**CFile****************************************************************
+
+ FileName [giaDeep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Experiments with synthesis.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "base/main/main.h"
+#include "base/cmd/cmd.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupMapping( Gia_Man_t * pNew, Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pFanin; int i, k;
+ Vec_Int_t * vMapping = p->vMapping ? Vec_IntAlloc( Vec_IntSize(p->vMapping) ) : NULL;
+ if ( p->vMapping == NULL )
+ return;
+ Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 );
+ Gia_ManForEachLut( p, i )
+ {
+ pObj = Gia_ManObj( p, i );
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFaninObj( p, i, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ pNew->vMapping = vMapping;
+}
+Gia_Man_t * Gia_ManDupWithMapping( Gia_Man_t * pGia )
+{
+ Gia_Man_t * pCopy = Gia_ManDup(pGia);
+ Gia_ManDupMapping( pCopy, pGia );
+ return pCopy;
+}
+void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript )
+{
+ Gia_Man_t * pGia, * pNew; int i;
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ {
+ Gia_Man_t * pCopy = Gia_ManDupWithMapping(pGia);
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pGia );
+ if ( Abc_FrameIsBatchMode() )
+ {
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
+ return;
+ }
+ }
+ else
+ {
+ Abc_FrameSetBatchMode( 1 );
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
+ Abc_FrameSetBatchMode( 0 );
+ return;
+ }
+ Abc_FrameSetBatchMode( 0 );
+ }
+ pNew = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ if ( Gia_ManHasMapping(pNew) && Gia_ManHasMapping(pCopy) )
+ {
+ if ( Gia_ManLutNum(pNew) < Gia_ManLutNum(pCopy) )
+ {
+ Gia_ManStop( pCopy );
+ pCopy = Gia_ManDupWithMapping( pNew );
+ }
+ }
+ else
+ {
+ if ( Gia_ManAndNum(pNew) < Gia_ManAndNum(pCopy) )
+ {
+ Gia_ManStop( pCopy );
+ pCopy = Gia_ManDup( pNew );
+ }
+ }
+ Vec_PtrWriteEntry( vAigs, i, pCopy );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCollectNodes_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vAnds )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjUpdateTravIdCurrentId( p, iObj ) )
+ return;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) || iObj == 0 )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0(pObj, iObj), vAnds );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId1(pObj, iObj), vAnds );
+ Vec_IntPush( vAnds, iObj );
+}
+void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
+{
+ int i, iObj;
+ if ( !Gia_ManHasMapping(p) )
+ return;
+ Vec_IntClear( vAnds );
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vCis, iObj, i )
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntForEachEntry( vCos, iObj, i )
+ Gia_ManCollectNodes_rec( p, iObj, vAnds );
+}
+Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
+{
+ Vec_Int_t * vMapping; int i;
+ Gia_Man_t * pNew; Gia_Obj_t * pObj;
+ pNew = Gia_ManStart( 1+Vec_IntSize(vCis)+Vec_IntSize(vAnds)+Vec_IntSize(vCos) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vCis, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vCos, p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 );
+ if ( !Gia_ManHasMapping(p) )
+ return pNew;
+ vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ {
+ Gia_Obj_t * pFanin; int k;
+ int iObj = Gia_ObjId(p, pObj);
+ if ( !Gia_ObjIsLut(p, iObj) )
+ continue;
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(p, iObj) );
+ Gia_LutForEachFaninObj( p, iObj, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ pNew->vMapping = vMapping;
+ return pNew;
+}
+Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript )
+{
+ Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i;
+ for ( i = 0; i < Vec_WecSize(vCis); i++ )
+ {
+ Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) );
+ Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) );
+ }
+ Gia_ManStochSynthesis( vAigs, pScript );
+ return vAigs;
+}
+Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash )
+{
+ Gia_Man_t * pGia, * pNew;
+ Gia_Obj_t * pObj; int i, k;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManCleanValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ if ( fHash )
+ Gia_ManHashAlloc( pNew );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ {
+ Vec_Int_t * vCi = Vec_WecEntry( vCis, i );
+ Vec_Int_t * vCo = Vec_WecEntry( vCos, i );
+ Gia_ManCleanValue( pGia );
+ Gia_ManConst0(pGia)->Value = 0;
+ Gia_ManForEachObjVec( vCi, p, pObj, k )
+ Gia_ManCi(pGia, k)->Value = pObj->Value;
+ if ( fHash )
+ Gia_ManForEachAnd( pGia, pObj, k )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ Gia_ManForEachAnd( pGia, pObj, k )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vCo, p, pObj, k )
+ pObj->Value = Gia_ObjFanin0Copy(Gia_ManCo(pGia, k));
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ if ( fHash )
+ {
+ pNew = Gia_ManCleanup( pGia = pNew );
+ Gia_ManStop( pGia );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+Gia_Man_t * Gia_ManDupStitchMap( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs )
+{
+ Vec_Int_t * vMapping; int n;
+ Gia_Man_t * pGia, * pNew = Gia_ManDupStitch( p, vCis, vAnds, vCos, vAigs, !Gia_ManHasMapping(p) );
+ if ( !Gia_ManHasMapping(p) )
+ return pNew;
+ vMapping = Vec_IntAlloc( Vec_IntSize(p->vMapping) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, n )
+ {
+ Gia_Obj_t * pFanin; int iObj, k;
+ //printf( "Gia %d has %d Luts\n", n, Gia_ManLutNum(pGia) );
+
+ Gia_ManForEachLut( pGia, iObj )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(pGia, iObj) );
+ Gia_LutForEachFaninObj( pGia, iObj, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ }
+ pNew->vMapping = vMapping;
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vPart = Vec_WecPushLevel( vRes );
+ int i, iStart = Seed % Gia_ManCoNum(p);
+ //Gia_ManLevelNum( p );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, (iStart+i) % Gia_ManCoNum(p) );
+ if ( Vec_IntSize(vPart) > nMaxSize )
+ vPart = Vec_WecPushLevel( vRes );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0p(p, pObj), vPart );
+ }
+ if ( Vec_IntSize(vPart) == 0 )
+ Vec_WecShrink( vRes, Vec_WecSize(vRes)-1 );
+ //Vec_WecPrint( vRes, 0 );
+ return vRes;
+}
+Vec_Wec_t * Gia_ManStochInputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f;
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ assert( Vec_IntSize(vVec) == 0 );
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ if ( Gia_ManHasMapping(p) )
+ {
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iFan) )
+ Vec_IntPush( vVec, iFan );
+ }
+ else
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ iObj = Gia_ObjFaninId0p(p, pObj);
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ iObj = Gia_ObjFaninId1p(p, pObj);
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ }
+ }
+ assert( Vec_IntSize(vVec) > 0 );
+ }
+ return vRes;
+}
+Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f;
+ if ( Gia_ManHasMapping(p) )
+ {
+ Gia_ManSetLutRefs( p );
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ assert( Vec_IntSize(vVec) == 0 );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ Gia_ObjLutRefDecId( p, iFan );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ if ( Gia_ObjLutRefNumId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ Gia_ObjLutRefIncId( p, iFan );
+ assert( Vec_IntSize(vVec) > 0 );
+ }
+ }
+ else
+ {
+ Gia_ManCreateRefs( p );
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ Gia_ObjRefDecId( p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ObjRefDecId( p, Gia_ObjFaninId1p(p, pObj) );
+ }
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ if ( Gia_ObjRefNum(p, pObj) )
+ Vec_IntPush( vVec, Gia_ObjId(p, pObj) );
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ Gia_ObjRefIncId( p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ObjRefIncId( p, Gia_ObjFaninId1p(p, pObj) );
+ }
+ }
+ }
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript )
+{
+ abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
+ abctime clkStart = Abc_Clock();
+ int fMapped = Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ int nLutEnd, nLutBeg = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
+ int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ Abc_Random(1);
+ for ( i = 0; i < 10+Seed; i++ )
+ Abc_Random(0);
+ if ( fVerbose )
+ printf( "Running %d iterations of script \"%s\".\n", nIters, pScript );
+ for ( i = 0; i < nIters; i++ )
+ {
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
+ Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
+ Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
+ Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
+ Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript );
+ Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
+ int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
+ if ( fVerbose )
+ printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
+ i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
+ fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
+ fMapped ? "LUTs" : "ANDs" );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ Gia_ManStop( pGia );
+ Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
+ Vec_WecFree( vAnds );
+ Vec_WecFree( vIns );
+ Vec_WecFree( vOuts );
+ if ( nTimeToStop && Abc_Clock() > nTimeToStop )
+ {
+ printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
+ break;
+ }
+ }
+ fMapped &= Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ nLutEnd = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
+ nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ if ( fVerbose )
+ printf( "Cumulatively reduced %d %s after %d iterations. ",
+ fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "ANDs", nIters );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaStr.c b/src/aig/gia/giaStr.c
index 085738c3..a87662a8 100644
--- a/src/aig/gia/giaStr.c
+++ b/src/aig/gia/giaStr.c
@@ -736,7 +736,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
if ( p->vStore == NULL )
p->vStore = Vec_IntAlloc( STR_SUPER );
Gia_ManFillValue( p );
- pNtk = Str_NtkCreate( Gia_ManObjNum(p), 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) );
+ pNtk = Str_NtkCreate( Gia_ManObjNum(p) + 10000, 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) + 10000 );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachObj1( p, pObj, i )
{
@@ -749,7 +749,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
pObj->Value = Str_ObjCreate( pNtk, STR_PO, 1, &iFanin );
}
}
- assert( pNtk->nObjs <= Gia_ManObjNum(p) );
+ //assert( pNtk->nObjs <= Gia_ManObjNum(p) );
return pNtk;
}
Str_Ntk_t * Str_ManNormalize( Gia_Man_t * p )
@@ -859,21 +859,23 @@ static inline void transpose64( word A[64] )
static inline int Str_ManNum( Gia_Man_t * p, int iObj ) { return Vec_IntEntry(&p->vCopies, iObj); }
static inline void Str_ManSetNum( Gia_Man_t * p, int iObj, int Num ) { Vec_IntWriteEntry(&p->vCopies, iObj, Num); }
-int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word Matrix[256], int nLimit )
+int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word * Matrix, int nLimit )
{
int fVerbose = 0;
- int Levels[256];
+ int * Levels = NULL;
int nSize = Vec_IntSize(vSuper);
int Prev = nSize, nLevels = 1;
int i, k, iLit, iFanin, nSizeNew;
word Mask;
assert( nSize > 2 );
+ assert( nSize <= nLimit );
if ( nSize > 64 )
{
for ( i = 0; i < 64; i++ )
Matrix[i] = 0;
return 0;
}
+ Levels = ABC_ALLOC( int, nLimit+256 );
// mark current nodes
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vSuper, iLit, i )
@@ -948,6 +950,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
if ( nSizeNew == 0 )
{
Vec_IntShrink( vSuper, nSize );
+ ABC_FREE( Levels );
return 0;
}
/*
@@ -979,6 +982,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
}
i = 0;
}
+ ABC_FREE( Levels );
Vec_IntShrink( vSuper, nSize );
return nSizeNew;
}
@@ -1088,15 +1092,14 @@ int Str_NtkBalanceTwo( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, int i,
void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize )
{
- word pMatrix[256];
- int Limit = 256;
+ word * pMatrix = ABC_ALLOC( word, pObj->nFanins+256 );
Vec_Int_t * vSuper = pNew->vSuper;
Vec_Int_t * vCosts = pNew->vStore;
int * pSuper = Vec_IntArray(vSuper);
int * pCost = Vec_IntArray(vCosts);
int k, iLit, MatrixSize = 0;
- assert( Limit <= Vec_IntCap(vSuper) );
- assert( Limit <= Vec_IntCap(vCosts) );
+ assert( (int)pObj->nFanins <= Vec_IntCap(vSuper) );
+ assert( (int)pObj->nFanins <= Vec_IntCap(vCosts) );
// collect nodes
Vec_IntClear( vSuper );
@@ -1111,11 +1114,13 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
if ( Vec_IntSize(vSuper) == 1 )
{
pObj->iCopy = Vec_IntEntry(vSuper, 0);
+ ABC_FREE( pMatrix );
return;
}
if ( Vec_IntSize(vSuper) == 2 )
{
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
+ ABC_FREE( pMatrix );
return;
}
@@ -1127,7 +1132,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
// compute affinity
if ( Vec_IntSize(vSuper) < 64 )
- MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
+ MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
// start the new product
while ( Vec_IntSize(vSuper) > 2 )
@@ -1147,7 +1152,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
// compute affinity
if ( Vec_IntSize(vSuper) == 64 )
- MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
+ MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
assert( Vec_IntSize(vSuper) <= 64 );
// Str_PrintState( pCost, pSuper, pMatrix, Vec_IntSize(vSuper) );
@@ -1236,6 +1241,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
continue;
}
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
+ ABC_FREE( pMatrix );
/*
// simple
diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c
new file mode 100644
index 00000000..f95d815d
--- /dev/null
+++ b/src/aig/gia/giaSupps.c
@@ -0,0 +1,817 @@
+/**CFile****************************************************************
+
+ FileName [giaSupp.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Support computation manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "base/main/mainInt.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
+#include "misc/vec/vecHsh.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Supp_Man_t_ Supp_Man_t;
+struct Supp_Man_t_
+{
+ // user data
+ int nIters; // optimization rounds
+ int nRounds; // optimization rounds
+ int nWords; // the number of simulation words
+ int nDivWords; // the number of divisor words
+ Vec_Wrd_t * vIsfs; // functions to synthesize
+ Vec_Int_t * vCands; // candidate divisors
+ Vec_Int_t * vWeights; // divisor weights (optional)
+ Vec_Wrd_t * vSims; // simulation values
+ Vec_Wrd_t * vSimsC; // simulation values
+ Gia_Man_t * pGia; // used for object names
+ // computed data
+ Vec_Wrd_t * vDivs[2]; // simulation values
+ Vec_Wrd_t * vPats[2]; // simulation values
+ Vec_Ptr_t * vMatrix; // simulation values
+ Vec_Wrd_t * vMask; // simulation values
+ Vec_Wrd_t * vRowTemp; // simulation values
+ Vec_Int_t * vCosts; // candidate costs
+ Hsh_VecMan_t * pHash; // subsets considered
+ Vec_Wrd_t * vSFuncs; // ISF storage
+ Vec_Int_t * vSStarts; // subset function starts
+ Vec_Int_t * vSCount; // subset function count
+ Vec_Int_t * vSPairs; // subset pair count
+ Vec_Int_t * vTemp; // temporary
+ Vec_Int_t * vTempSets; // temporary
+ Vec_Int_t * vTempPairs; // temporary
+ Vec_Wec_t * vSolutions; // solutions for each node count
+};
+
+extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ManFuncInit( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) )
+ continue;
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 );
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 );
+ k++;
+ }
+ Vec_WrdShrink( vFuncs, 2*k*nWords );
+ return k;
+}
+int Supp_ManCostInit( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int Res = 0, i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ Res += Abc_TtCountOnesVec(pFunc0, nWords) * Abc_TtCountOnesVec(pFunc1, nWords);
+ }
+ assert( nFuncs < 128 );
+ assert( Res < (1 << 24) );
+ return (nFuncs << 24) | Res;
+}
+void Supp_ManInit( Supp_Man_t * p )
+{
+ int Value, nFuncs, iSet = Hsh_VecManAdd( p->pHash, p->vTemp ); // empty set
+ assert( iSet == 0 );
+ Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) );
+ Vec_WrdAppend( p->vSFuncs, p->vIsfs );
+ nFuncs = Supp_ManFuncInit( p->vSFuncs, p->nWords );
+ assert( Vec_WrdSize(p->vSFuncs) == 2 * nFuncs * p->nWords );
+ Value = Supp_ManCostInit(p->vSFuncs, p->nWords);
+ Vec_IntPush( p->vSCount, Value >> 24 );
+ Vec_IntPush( p->vSPairs, Value & 0xFFFFFF );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_DeriveLines( Supp_Man_t * p )
+{
+ int n, i, iObj, nWords = p->nWords;
+ int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) );
+ for ( n = 0; n < 2; n++ )
+ {
+ p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords );
+ p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords );
+ if ( p->vSimsC )
+ Vec_IntForEachEntry( p->vCands, iObj, i )
+ Abc_TtAndSharp( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
+ else
+ Vec_IntForEachEntry( p->vCands, iObj, i )
+ Abc_TtCopy( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
+ Extra_BitMatrixTransposeP( p->vDivs[n], nWords, p->vPats[n], nDivWords );
+ }
+ return nDivWords;
+}
+Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, int nIters, int nRounds )
+{
+ Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 );
+ p->nIters = nIters;
+ p->nRounds = nRounds;
+ p->nWords = nWords;
+ p->vIsfs = vIsfs;
+ p->vCands = vCands;
+ p->vWeights = vWeights;
+ p->vSims = vSims;
+ p->vSimsC = vSimsC;
+ p->pGia = pGia;
+ // computed data
+ p->nDivWords = Supp_DeriveLines( p );
+ p->vMatrix = Vec_PtrAlloc( 100 );
+ p->vMask = Vec_WrdAlloc( 100 );
+ p->vRowTemp = Vec_WrdStart( 64*p->nDivWords );
+ p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) );
+ p->pHash = Hsh_VecManStart( 1000 );
+ p->vSFuncs = Vec_WrdAlloc( 1000 );
+ p->vSStarts = Vec_IntAlloc( 1000 );
+ p->vSCount = Vec_IntAlloc( 1000 );
+ p->vSPairs = Vec_IntAlloc( 1000 );
+ p->vSolutions = Vec_WecStart( 16 );
+ p->vTemp = Vec_IntAlloc( 10 );
+ p->vTempSets = Vec_IntAlloc( 10 );
+ p->vTempPairs = Vec_IntAlloc( 10 );
+ Supp_ManInit( p );
+ return p;
+}
+void Supp_ManCleanMatrix( Supp_Man_t * p )
+{
+ Vec_Wrd_t * vTemp; int i;
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, i )
+ Vec_WrdFreeP( &vTemp );
+ Vec_PtrClear( p->vMatrix );
+}
+void Supp_ManDelete( Supp_Man_t * p )
+{
+ Supp_ManCleanMatrix( p );
+ Vec_WrdFreeP( &p->vDivs[0] );
+ Vec_WrdFreeP( &p->vDivs[1] );
+ Vec_WrdFreeP( &p->vPats[0] );
+ Vec_WrdFreeP( &p->vPats[1] );
+ Vec_PtrFreeP( &p->vMatrix );
+ Vec_WrdFreeP( &p->vMask );
+ Vec_WrdFreeP( &p->vRowTemp );
+ Vec_IntFreeP( &p->vCosts );
+ Hsh_VecManStop( p->pHash );
+ Vec_WrdFreeP( &p->vSFuncs );
+ Vec_IntFreeP( &p->vSStarts );
+ Vec_IntFreeP( &p->vSCount );
+ Vec_IntFreeP( &p->vSPairs );
+ Vec_WecFreeP( &p->vSolutions );
+ Vec_IntFreeP( &p->vTemp );
+ Vec_IntFreeP( &p->vTempSets );
+ Vec_IntFreeP( &p->vTempPairs );
+ ABC_FREE( p );
+}
+int Supp_ManMemory( Supp_Man_t * p )
+{
+ int nMem = sizeof(Supp_Man_t);
+ nMem += 2*(int)Vec_WrdMemory( p->vDivs[0] );
+ nMem += 2*(int)Vec_WrdMemory( p->vPats[0] );
+ nMem += (Vec_PtrSize(p->vMatrix)+1)*(int)Vec_WrdMemory( p->vRowTemp );
+ nMem += (int)Vec_WrdMemory( p->vMask );
+ nMem += (int)Vec_IntMemory( p->vCosts );
+ nMem += (int)Hsh_VecManMemory( p->pHash );
+ nMem += (int)Vec_WrdMemory( p->vSFuncs );
+ nMem += (int)Vec_IntMemory( p->vSStarts );
+ nMem += (int)Vec_IntMemory( p->vSCount );
+ nMem += (int)Vec_IntMemory( p->vSPairs );
+ nMem += (int)Vec_WecMemory( p->vSolutions );
+ nMem += (int)Vec_IntMemory( p->vTemp );
+ nMem += (int)Vec_IntMemory( p->vTempSets );
+ nMem += (int)Vec_IntMemory( p->vTempPairs );
+ return nMem;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ArrayWeight( Vec_Int_t * vRes, Vec_Int_t * vWeights )
+{
+ int i, iObj, Cost = 0;
+ if ( !vWeights )
+ return Vec_IntSize(vRes);
+ Vec_IntForEachEntry( vRes, iObj, i )
+ Cost += Vec_IntEntry(vWeights, iObj);
+ return Cost;
+}
+int Supp_SetWeight( Supp_Man_t * p, int iSet )
+{
+ return Supp_ArrayWeight( Hsh_VecReadEntry(p->pHash, iSet), p->vWeights );
+}
+int Supp_SetSize( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntSize( Hsh_VecReadEntry(p->pHash, iSet) );
+}
+int Supp_SetFuncNum( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntEntry(p->vSCount, iSet);
+}
+int Supp_SetPairNum( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntEntry(p->vSPairs, iSet);
+}
+void Supp_SetConvert( Vec_Int_t * vSet, Vec_Int_t * vCands )
+{
+ int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Vec_IntWriteEntry( vSet, i, Vec_IntEntry(vCands, iObj) );
+}
+void Supp_PrintNodes( Gia_Man_t * pGia, Vec_Int_t * vObjs, int Skip, int Limit )
+{
+ int i, iObj;
+ //printf( "Considering %d targets: ", Vec_IntSize(vObjs) );
+ Vec_IntForEachEntryStart( vObjs, iObj, i, Skip )
+ {
+ if ( iObj < 0 )
+ continue;
+ printf( "(%d)", iObj );
+ if ( pGia && pGia->vWeights && Vec_IntEntry(pGia->vWeights, iObj) > 0 )
+ printf( "(%d)", Vec_IntEntry(pGia->vWeights, iObj) );
+ if ( pGia )
+ printf( " %s ", Gia_ObjName(pGia, iObj)+2 );
+ else
+ printf( " n%d ", iObj );
+ if ( i >= Limit )
+ {
+ printf( "... " );
+ break;
+ }
+ }
+ printf( "Cost = %d", Supp_ArrayWeight(vObjs, pGia ? pGia->vWeights : NULL) );
+ printf( "\n" );
+}
+void Supp_PrintOne( Supp_Man_t * p, int iSet )
+{
+ Vec_Int_t * vSet = Hsh_VecReadEntry(p->pHash, iSet);
+ printf( "Set %5d : ", iSet );
+ printf( "Funcs %2d ", Supp_SetFuncNum(p, iSet) );
+ printf( "Pairs %4d ", Supp_SetPairNum(p, iSet) );
+ printf( "Start %8d ", Vec_IntEntry(p->vSStarts, iSet) );
+ printf( "Weight %4d ", Supp_ArrayWeight(vSet, p->vWeights) );
+ Vec_IntClearAppend( p->vTemp, vSet );
+ Supp_SetConvert( p->vTemp, p->vCands );
+ Supp_PrintNodes( p->pGia, p->vTemp, 0, 6 );
+}
+int Supp_ManRefine1( Supp_Man_t * p, int iSet, int iObj )
+{
+ word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords );
+ word * pIsf; int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int i, n, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0;
+ if ( Vec_WrdSize(p->vSFuncs) + 4*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) )
+ Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) );
+ pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords };
+ for ( f = 0; f < 2; f++ )
+ {
+ int nOnes[2], Start = Vec_WrdSize(p->vSFuncs);
+ for ( n = 0; n < 2; n++ )
+ {
+ word * pLimit = Vec_WrdLimit(p->vSFuncs);
+ if ( f )
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[n][w] & pSet[w] );
+ else
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[n][w] & ~pSet[w] );
+ nOnes[n] = Abc_TtCountOnesVec( pLimit, p->nWords );
+ }
+ if ( nOnes[0] && nOnes[1] )
+ Res += nOnes[0] * nOnes[1];
+ else
+ Vec_WrdShrink( p->vSFuncs, Start );
+ }
+ }
+ assert( Res < (1 << 24) );
+ nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords;
+ assert( nFuncsNew < 128 );
+ assert( nFuncsNew >= 0 && nFuncsNew <= 2*nFuncs );
+ return (nFuncsNew << 24) | Res;
+}
+void Supp_ManRefine( Supp_Man_t * p, int iSet, int iObj, int * pnFuncs, int * pnPairs )
+{
+ word * pDivs0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords );
+ word * pDivs1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords );
+ word * pIsf; int nFuncs = Supp_SetFuncNum(p, iSet);
+ int i, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0;
+ if ( Vec_WrdSize(p->vSFuncs) + 6*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) )
+ Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) );
+ if ( Vec_WrdSize(p->vSFuncs) == Vec_IntEntry(p->vSStarts, iSet) )
+ pIsf = Vec_WrdLimit( p->vSFuncs );
+ else
+ pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords };
+ for ( f = 0; f < 3; f++ )
+ {
+ int nOnes[2], Start = Vec_WrdSize(p->vSFuncs);
+ word * pLimit[2] = { Vec_WrdLimit(p->vSFuncs), Vec_WrdLimit(p->vSFuncs) + p->nWords };
+ if ( f == 0 )
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs0[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs1[w] );
+ }
+ else if ( f == 1 )
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs1[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs0[w] );
+ }
+ else
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & ~pDivs0[w] & ~pDivs1[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] );
+ }
+ nOnes[0] = Abc_TtCountOnesVec( pLimit[0], p->nWords );
+ nOnes[1] = Abc_TtCountOnesVec( pLimit[1], p->nWords );
+ if ( nOnes[0] && nOnes[1] )
+ Res += nOnes[0] * nOnes[1];
+ else
+ Vec_WrdShrink( p->vSFuncs, Start );
+ }
+ }
+ assert( Res < (1 << 24) );
+ nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords;
+ *pnFuncs = nFuncsNew;
+ *pnPairs = Res;
+}
+int Supp_ManSubsetAdd( Supp_Man_t * p, int iSet, int iObj, int fVerbose )
+{
+ int iSetNew, nEntries = Hsh_VecSize( p->pHash );
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet );
+ Vec_IntClear( p->vTemp );
+ Vec_IntAppend( p->vTemp, vSet );
+ Vec_IntPushOrder( p->vTemp, iObj );
+ assert( Vec_IntIsOrdered(p->vTemp, 0) );
+ iSetNew = Hsh_VecManAdd( p->pHash, p->vTemp );
+ if ( iSetNew == nEntries ) // new entry
+ {
+ int nFuncs, nPairs;
+ Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) );
+ Supp_ManRefine( p, iSet, iObj, &nFuncs, &nPairs );
+ Vec_IntPush( p->vSCount, nFuncs );
+ Vec_IntPush( p->vSPairs, nPairs );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSStarts) );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSCount) );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSPairs) );
+ if ( Supp_SetFuncNum(p, iSetNew) == 0 && Supp_SetSize(p, iSetNew) < Vec_WecSize(p->vSolutions) )
+ Vec_WecPush( p->vSolutions, Supp_SetSize(p, iSetNew), iSetNew );
+ if ( fVerbose )
+ Supp_PrintOne( p, iSetNew );
+ }
+ return iSetNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ComputePair1( Supp_Man_t * p, int iSet )
+{
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int iFunc = Random % nFuncs;
+ word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords };
+ int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords);
+ int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords);
+ if ( 1 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords );
+ assert( Abc_TtGetBit(pSet, iBit0) == Abc_TtGetBit(pSet, iBit1) );
+ }
+ }
+ return (iBit0 << 16) | iBit1;
+}
+int Supp_ComputePair( Supp_Man_t * p, int iSet )
+{
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int iFunc = Random % nFuncs;
+ word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords };
+ int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords);
+ int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords);
+ if ( 1 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ word * pSet0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords );
+ word * pSet1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords );
+ int Value00 = Abc_TtGetBit(pSet0, iBit0);
+ int Value01 = Abc_TtGetBit(pSet0, iBit1);
+ int Value10 = Abc_TtGetBit(pSet1, iBit0);
+ int Value11 = Abc_TtGetBit(pSet1, iBit1);
+ assert( !Value00 || !Value11 );
+ assert( !Value01 || !Value10 );
+ }
+ }
+ return (iBit0 << 16) | iBit1;
+}
+Vec_Int_t * Supp_Compute64Pairs( Supp_Man_t * p, Vec_Int_t * vSets )
+{
+ int i;
+ Vec_IntClear( p->vTempPairs );
+ for ( i = 0; i < 64; i++ )
+ {
+ int Rand = 0xFFFFFF & Abc_Random(0);
+ int iSet = Vec_IntEntry( vSets, Rand % Vec_IntSize(vSets) );
+ Vec_IntPush( p->vTempPairs, Supp_ComputePair(p, iSet) );
+ }
+ return p->vTempPairs;
+}
+void Supp_ManFillBlock( Supp_Man_t * p, Vec_Int_t * vPairs, Vec_Wrd_t * vRes )
+{
+ int i, Pair;
+ assert( Vec_IntSize(vPairs) == 64 );
+ Vec_IntForEachEntry( vPairs, Pair, i )
+ {
+ int iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF;
+ word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords);
+ word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords);
+ word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords);
+ word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords);
+ word * pPat = Vec_WrdEntryP(p->vRowTemp, i*p->nDivWords);
+ Abc_TtAnd( pPat, pPat00, pPat11, p->nDivWords, 0 );
+ Abc_TtOrAnd( pPat, pPat01, pPat10, p->nDivWords );
+ }
+ Extra_BitMatrixTransposeP( p->vRowTemp, p->nDivWords, vRes, 1 );
+}
+void Supp_ManAddPatterns( Supp_Man_t * p, Vec_Int_t * vSets )
+{
+ Vec_Int_t * vPairs = Supp_Compute64Pairs( p, vSets );
+ Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords );
+ Supp_ManFillBlock( p, vPairs, vRow );
+ Vec_PtrPush( p->vMatrix, vRow );
+}
+Vec_Int_t * Supp_ManCollectOnes( word * pSim, int nWords )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 ); int i;
+ for ( i = 0; i < 64*nWords; i++ )
+ if ( Abc_TtGetBit(pSim, i) )
+ Vec_IntPush( vRes, i );
+ return vRes;
+}
+Vec_Int_t * Supp_Compute64PairsFunc( Supp_Man_t * p, Vec_Int_t * vBits0, Vec_Int_t * vBits1 )
+{
+ int i;
+ Vec_IntClear( p->vTempPairs );
+ for ( i = 0; i < 64; i++ )
+ {
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int iBit0 = Vec_IntEntry( vBits0, (Random & 0xFFF) % Vec_IntSize(vBits0) );
+ int iBit1 = Vec_IntEntry( vBits1, (Random >> 12) % Vec_IntSize(vBits1) );
+ Vec_IntPush( p->vTempPairs, (iBit0 << 16) | iBit1 );
+ }
+ return p->vTempPairs;
+}
+void Supp_ManAddPatternsFunc( Supp_Man_t * p, int nBatches )
+{
+ int b;
+ Vec_Int_t * vBits0 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 0*p->nWords), p->nWords );
+ Vec_Int_t * vBits1 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 1*p->nWords), p->nWords );
+ for ( b = 0; b < nBatches; b++ )
+ {
+ Vec_Int_t * vPairs = Supp_Compute64PairsFunc( p, vBits0, vBits1 );
+ Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords );
+ Supp_ManFillBlock( p, vPairs, vRow );
+ Vec_PtrPush( p->vMatrix, vRow );
+ }
+ Vec_IntFree( vBits0 );
+ Vec_IntFree( vBits1 );
+}
+int Supp_FindNextDiv( Supp_Man_t * p, int Pair )
+{
+ int iDiv, iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF;
+ word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords);
+ word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords);
+ word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords);
+ word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords);
+ int iDiv1 = Abc_TtFindFirstAndBit2( pPat00, pPat11, p->nDivWords );
+ int iDiv2 = Abc_TtFindFirstAndBit2( pPat01, pPat10, p->nDivWords );
+ iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1;
+ iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2;
+ iDiv = Abc_MinInt( iDiv1, iDiv2 );
+ assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) );
+ return iDiv;
+}
+int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose )
+{
+ Vec_IntClear( p->vTempSets );
+ while ( Supp_SetFuncNum(p, iSet) > 0 )
+ {
+ int Pair = Supp_ComputePair( p, iSet );
+ int iDiv = Supp_FindNextDiv( p, Pair );
+ iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
+ if ( Supp_SetFuncNum(p, iSet) > 0 )
+ Vec_IntPush( p->vTempSets, iSet );
+ }
+ if ( Vec_IntSize(p->vTempSets) < 2 )
+ return iSet;
+ Supp_ManAddPatterns( p, p->vTempSets );
+ return iSet;
+}
+int Supp_ManSubsetRemove( Supp_Man_t * p, int iSet, int iPos )
+{
+ int i, iSetNew = 0, nSize = Supp_SetSize(p, iSet);
+ for ( i = 0; i < nSize; i++ )
+ if ( i != iPos && Supp_SetFuncNum(p, iSetNew) > 0 )
+ iSetNew = Supp_ManSubsetAdd( p, iSetNew, Vec_IntEntry(Hsh_VecReadEntry(p->pHash, iSet), i), 0 );
+ return iSetNew;
+}
+int Supp_ManMinimize( Supp_Man_t * p, int iSet0, int r, int fVerbose )
+{
+ int i, nSize = Supp_SetSize(p, iSet0);
+ Vec_Int_t * vPerm = Vec_IntStartNatural( Supp_SetSize(p, iSet0) );
+ Vec_IntRandomizeOrder( vPerm );
+ Vec_IntClear( p->vTempSets );
+ if ( fVerbose )
+ printf( "Removing items from %d:\n", iSet0 );
+ // make sure we first try to remove items with higher weight
+ for ( i = 0; i < nSize; i++ )
+ {
+ int Index = Vec_IntEntry( vPerm, i );
+ int iSet = Supp_ManSubsetRemove( p, iSet0, Index );
+ if ( fVerbose )
+ printf( "Item %2d : ", Index );
+ if ( fVerbose )
+ Supp_PrintOne( p, iSet );
+ if ( Supp_SetFuncNum(p, iSet) == 0 )
+ {
+ Vec_IntFree( vPerm );
+ return Supp_ManMinimize( p, iSet, r, fVerbose );
+ }
+ Vec_IntPush( p->vTempSets, iSet );
+ }
+ Supp_ManAddPatterns( p, p->vTempSets );
+ Vec_IntFree( vPerm );
+ return iSet0;
+}
+int Supp_ManFindNextObj( Supp_Man_t * p, int fVerbose )
+{
+ Vec_Wrd_t * vTemp; int r, k, iDiv;
+ word Sim, * pMask = Vec_WrdArray(p->vMask);
+ assert( Vec_WrdSize(p->vMask) == Vec_PtrSize(p->vMatrix) );
+ Vec_IntFill( p->vCosts, Vec_IntSize(p->vCosts), 0 );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r )
+ Vec_WrdForEachEntryStop( vTemp, Sim, k, Vec_IntSize(p->vCosts) )
+ Vec_IntAddToEntry( p->vCosts, k, Abc_TtCountOnes(Sim & pMask[r]) );
+ iDiv = Vec_IntArgMax( p->vCosts );
+ if ( fVerbose )
+ printf( "Choosing divisor %d with weight %d.\n", iDiv, Vec_IntEntry(p->vCosts, iDiv) );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r )
+ pMask[r] &= ~Vec_WrdEntry( vTemp, iDiv );
+ return iDiv;
+}
+int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose )
+{
+ int iSet = 0;
+ Vec_WrdFill( p->vMask, Vec_PtrSize(p->vMatrix), ~(word)0 );
+ if ( fVerbose )
+ printf( "\nBuilding a new set:\n" );
+ while ( Supp_SetPairNum(p, iSet) )
+ {
+ int iDiv = Supp_ManFindNextObj( p, fVerbose );
+ iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
+ if ( Abc_TtIsConst0(Vec_WrdArray(p->vMask), Vec_WrdSize(p->vMask)) )
+ break;
+ }
+ if ( fVerbose )
+ printf( "Adding random part:\n" );
+ return Supp_ManRandomSolution( p, iSet, fVerbose );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVerbose, Vec_Int_t ** pvDivs )
+{
+ Vec_Int_t * vLevel, * vRes = NULL;
+ int i, k, iSet, nFuncs = 0, Count = 0;
+ int iSolBest = -1, Cost, CostBest = ABC_INFINITY;
+ Vec_WecForEachLevel( vSols, vLevel, i )
+ {
+ Count += Vec_IntSize(vLevel) > 0;
+ Vec_IntForEachEntry( vLevel, iSet, k )
+ {
+ if ( fVerbose )
+ printf( "%3d : ", nFuncs++ );
+ Cost = Gia_ManEvalSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, Hsh_VecReadEntry(p->pHash, iSet), p->nWords, fVerbose );
+ if ( Cost == -1 )
+ continue;
+ if ( CostBest > Cost )
+ {
+ CostBest = Cost;
+ iSolBest = iSet;
+ }
+ if ( nFuncs > 5 )
+ break;
+ }
+ if ( Count == 2 || k < Vec_IntSize(vLevel) )
+ break;
+ }
+ if ( iSolBest > 0 && (CostBest >> 2) < 50 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj;
+ vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 );
+ assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 );
+ if ( vRes && pvDivs )
+ {
+ Vec_IntClear( *pvDivs );
+ Vec_IntPushTwo( *pvDivs, -1, -1 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
+ }
+ }
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_FindGivenOne( Supp_Man_t * p )
+{
+ int i, iObj, iSet = 0;
+ Vec_Int_t * vSet = Vec_IntStart( 2 );
+ //extern void Patch_GenerateSet11( Gia_Man_t * p, Vec_Int_t * vDivs, Vec_Int_t * vCands );
+ //Patch_GenerateSet11( p->pGia, vSet, p->vCands );
+ Vec_IntDrop( vSet, 0 );
+ Vec_IntDrop( vSet, 0 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ iSet = Supp_ManSubsetAdd( p, iSet, iObj, 1 );
+ Vec_IntFree( vSet );
+ return iSet;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, Vec_Int_t ** pvDivs, int nIters, int nRounds, int fVerbose )
+{
+ int fVeryVerbose = 0;
+ int i, r, iSet, iBest = -1;
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vRes = NULL;
+ Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
+ if ( Supp_SetFuncNum(p, 0) == 0 )
+ {
+ Supp_ManDelete( p );
+ Vec_IntClear( *pvDivs );
+ Vec_IntPushTwo( *pvDivs, -1, -1 );
+ vRes = Vec_IntAlloc( 1 );
+ Vec_IntPush( vRes, Abc_TtIsConst0(Vec_WrdArray(vIsfs), nWords) );
+ return vRes;
+ }
+ if ( fVerbose )
+ printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
+ Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) );
+ //iBest = Supp_FindGivenOne( p );
+ if ( iBest == -1 )
+ for ( i = 0; i < p->nIters; i++ )
+ {
+ Supp_ManAddPatternsFunc( p, i );
+ iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose );
+ for ( r = 0; r < p->nRounds; r++ )
+ {
+ if ( fVeryVerbose )
+ printf( "\n\nITER %d ROUND %d\n", i, r );
+ iSet = Supp_ManMinimize( p, iSet, r, fVeryVerbose );
+ if ( iBest == -1 || Supp_SetWeight(p, iBest) > Supp_SetWeight(p, iSet) )
+ //if ( Supp_SetSize(p, iBest) > Supp_SetSize(p, iSet) )
+ {
+ if ( fVeryVerbose )
+ printf( "\nThe best solution found:\n" );
+ if ( fVeryVerbose )
+ Supp_PrintOne( p, iSet );
+ iBest = iSet;
+ }
+ iSet = Supp_ManReconstruct( p, fVeryVerbose );
+ }
+ if ( fVeryVerbose )
+ printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) );
+ Supp_ManCleanMatrix( p );
+ }
+ if ( fVerbose )
+ {
+ printf( "Explored %d divisor sets. Found %d solutions. Memory usage %.2f MB. ",
+ Hsh_VecSize(p->pHash), Vec_WecSizeSize(p->vSolutions), 1.0*Supp_ManMemory(p)/(1<<20) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ printf( "The best solution: " );
+ if ( iBest == -1 )
+ printf( "No solution.\n" );
+ else
+ Supp_PrintOne( p, iBest );
+ }
+ vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs );
+ Supp_ManDelete( p );
+// if ( vRes && Vec_IntSize(vRes) == 0 )
+// Vec_IntFreeP( &vRes );
+ return vRes;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSweep.c b/src/aig/gia/giaSweep.c
index 1d66caee..8a7fcbd0 100644
--- a/src/aig/gia/giaSweep.c
+++ b/src/aig/gia/giaSweep.c
@@ -388,6 +388,14 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
int i, iLast, iBox, nBoxes = Tim_ManBoxNum( pManTime );
Vec_Int_t * vCarryOuts = Vec_IntAlloc( nBoxes );
+
+ // Create and populate reference count (and free later) only if not already
+ // done.
+ int createRefs = (p->pRefs == NULL);
+ if (createRefs) {
+ Gia_ManCreateRefs( p );
+ }
+
for ( i = 0; i < nBoxes; i++ )
{
iLast = Tim_ManBoxInputLast( pManTime, i );
@@ -398,9 +406,24 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
if ( iBox == -1 )
continue;
assert( Gia_ObjIsCi(pObj) );
- if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) )
+ if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) ) {
Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
+
+ // We have identified a carry connection. Check if the carry out
+ // of the destination box is unconnected. If so then add it to
+ // the carry list as well.
+ iLast = Tim_ManBoxOutputLast(pManTime, i);
+ pObj = Gia_ManCi(p, iLast);
+ if ( Gia_ObjRefNum(p, pObj) == 0 ) {
+ Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
+ }
+ }
+ }
+
+ if (createRefs) {
+ ABC_FREE( p->pRefs );
}
+
return vCarryOuts;
}
diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c
index 91c4fa24..c24748ed 100644
--- a/src/aig/gia/giaTruth.c
+++ b/src/aig/gia/giaTruth.c
@@ -118,27 +118,6 @@ word Gia_LutComputeTruth6Map( Gia_Man_t * p, int iPo, Vec_Int_t * vMap )
SeeAlso []
***********************************************************************/
-static unsigned s_Truths5[5] = {
- 0xAAAAAAAA,
- 0xCCCCCCCC,
- 0xF0F0F0F0,
- 0xFF00FF00,
- 0xFFFF0000,
-};
-static inline int Abc_Tt5HasVar( unsigned t, int iVar )
-{
- return ((t << (1<<iVar)) & s_Truths5[iVar]) != (t & s_Truths5[iVar]);
-}
-static inline unsigned Abc_Tt5Cofactor0( unsigned t, int iVar )
-{
- assert( iVar >= 0 && iVar < 6 );
- return (t & ~s_Truths5[iVar]) | ((t & ~s_Truths5[iVar]) << (1<<iVar));
-}
-static inline unsigned Abc_Tt5Cofactor1( unsigned t, int iVar )
-{
- assert( iVar >= 0 && iVar < 6 );
- return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<<iVar));
-}
int Gia_Truth5ToGia( Gia_Man_t * p, int * pVarLits, int nVars, unsigned Truth, int fHash )
{
int Var, Lit0, Lit1;
@@ -645,9 +624,18 @@ word * Gia_ObjComputeTruthTableCut( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t
{
Gia_Obj_t * pTemp;
word * pTruth, * pTruthL, * pTruth0, * pTruth1;
- int i, iObj, Id0, Id1;
+ int i, iObj, Id0, Id1, Index = Vec_IntFind(vLeaves, Gia_ObjId(p, pRoot));
assert( p->vTtMemory != NULL );
assert( Vec_IntSize(vLeaves) <= p->nTtVars );
+ if ( Index >= 0 )
+ return Gla_ObjTruthElem( p, Index );
+ if ( Gia_ObjIsConst0(pRoot) )
+ {
+ if ( Vec_WrdSize(p->vTtMemory) < p->nTtWords )
+ Vec_WrdFillExtra( p->vTtMemory, p->nTtWords, 0 );
+ return Gla_ObjTruthConst0( p, Gla_ObjTruthFree1(p) );
+ }
+ assert( Gia_ObjIsAnd(pRoot) );
// extend ID numbers
if ( Vec_IntSize(p->vTtNums) < Gia_ManObjNum(p) )
Vec_IntFillExtra( p->vTtNums, Gia_ManObjNum(p), -ABC_INFINITY );
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index d0ec969f..431be5b7 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -522,6 +522,28 @@ int Gia_ManLevelNum( Gia_Man_t * p )
}
return p->nLevels;
}
+int Gia_ManLevelRNum( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
+ p->nLevels = 0;
+ Gia_ManForEachObjReverse( p, pObj, i )
+ {
+ if ( !p->fGiaSimple && Gia_ObjIsBuf(pObj) )
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), Gia_ObjLevel(p, pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1+Gia_ObjLevel(p, pObj) );
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId1(pObj, i), 1+Gia_ObjLevel(p, pObj) );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1 );
+ else
+ p->nLevels = Abc_MaxInt( p->nLevels, Gia_ObjLevel(p, pObj) );
+ }
+ return p->nLevels;
+}
float Gia_ManLevelAve( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
@@ -1101,19 +1123,20 @@ int Gia_NodeDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
SeeAlso []
***********************************************************************/
-int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
+int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode, int fMark )
{
Gia_Obj_t * pFanin;
int Counter = 0;
if ( Gia_ObjIsCi(pNode) )
return 0;
assert( Gia_ObjIsAnd(pNode) );
+ if ( fMark ) Gia_ObjSetTravIdCurrent(p, pNode);
pFanin = Gia_ObjFanin0(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
- Counter += Gia_NodeRef_rec( p, pFanin );
+ Counter += Gia_NodeRef_rec( p, pFanin, fMark );
pFanin = Gia_ObjFanin1(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
- Counter += Gia_NodeRef_rec( p, pFanin );
+ Counter += Gia_NodeRef_rec( p, pFanin, fMark );
return Counter + 1;
}
@@ -1152,7 +1175,19 @@ int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode )
assert( !Gia_IsComplement(pNode) );
assert( Gia_ObjIsCand(pNode) );
ConeSize1 = Gia_NodeDeref_rec( p, pNode );
- ConeSize2 = Gia_NodeRef_rec( p, pNode );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 );
+ assert( ConeSize1 == ConeSize2 );
+ assert( ConeSize1 >= 0 );
+ return ConeSize1;
+}
+int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode )
+{
+ int ConeSize1, ConeSize2;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsCand(pNode) );
+ ConeSize1 = Gia_NodeDeref_rec( p, pNode );
+ Gia_ManIncrementTravId( p );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 1 );
assert( ConeSize1 == ConeSize2 );
assert( ConeSize1 >= 0 );
return ConeSize1;
@@ -1193,7 +1228,7 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp )
ConeSize1 = Gia_NodeDeref_rec( p, pNode );
Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp );
Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp );
- ConeSize2 = Gia_NodeRef_rec( p, pNode );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 );
assert( ConeSize1 == ConeSize2 );
assert( ConeSize1 >= 0 );
return ConeSize1;
@@ -1201,6 +1236,53 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_NodeMffcMapping_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMapping, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj; int i, iNode, Count = 1;
+ if ( !iObj || Vec_IntEntry(vMapping, iObj) )
+ return 0;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ Gia_NodeMffcSizeSupp( p, pObj, vSupp );
+ Vec_IntSort( vSupp, 0 );
+ Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Vec_IntSize(vSupp) );
+ Vec_IntAppend( vMapping, vSupp );
+ Vec_IntPush( vMapping, iObj );
+ Vec_IntForEachEntry( vSupp, iNode, i )
+ Count += Gia_NodeMffcMapping_rec( p, iNode, vMapping, vSupp );
+ return Count;
+}
+int Gia_NodeMffcMapping( Gia_Man_t * p )
+{
+ int i, Id, Count = 0;
+ int * pRefsOld;
+ Vec_Int_t * vMapping, * vSupp = Vec_IntAlloc( 100 );
+ vMapping = Vec_IntAlloc( 2 * Gia_ManObjNum(p) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 );
+ pRefsOld = p->pRefs; p->pRefs = NULL;
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachCoDriverId( p, Id, i )
+ Count += Gia_NodeMffcMapping_rec( p, Id, vMapping, vSupp );
+ p->pRefs = pRefsOld;
+ Vec_IntFree( vSupp );
+ p->vMapping = vMapping;
+ //printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(p) );
+ return Count;
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if AIG has dangling nodes.]
Description []
@@ -2027,11 +2109,13 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName )
Gia_ManForEachObj( p, pObj, i )
if ( i && Gia_ObjIsLut(p, i) )
{
+ word truth;
pLuts[iLut].Type = 3;
Gia_LutForEachFanin( p, i, iFan, k )
pLuts[iLut].pFans[k] = Gia_ManObj(p, iFan)->Value;
pLuts[iLut].nFans = k;
- *(word *)pLuts[iLut].pTruth = Gia_LutComputeTruth6(p, i, vTruths);
+ truth = Gia_LutComputeTruth6(p, i, vTruths);
+ memcpy( pLuts[iLut].pTruth, &truth, sizeof(word) );
pObj->Value = pLuts[iLut].Out = Abc_Var2Lit( iLut, 0 );
iLut++;
}
@@ -2290,6 +2374,713 @@ Gia_Man_t * Gia_ManDupWithMuxPos( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Collect distance info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManRingAdd( Gia_Man_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vDists, int Dist )
+{
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ Vec_IntWriteEntry( vDists, iObj, Dist );
+ Vec_IntPush( vRes, iObj );
+}
+void Gia_ManCollectRing( Gia_Man_t * p, Vec_Int_t * vStart, Vec_Int_t * vRes, Vec_Int_t * vDists )
+{
+ int i, k, iObj, iFan;
+ Vec_IntForEachEntry( vStart, iObj, i )
+ {
+ int Weight = Vec_IntEntry( vDists, iObj );
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ assert( Weight > 0 );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManRingAdd( p, Gia_ObjFaninId0(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) );
+ Gia_ManRingAdd( p, Gia_ObjFaninId1(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin1(pObj)) );
+ }
+ Gia_ObjForEachFanoutStaticId( p, iObj, iFan, k )
+ Gia_ManRingAdd( p, iFan, vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ManObj(p, iFan)) );
+ }
+}
+Vec_Int_t * Gia_ManComputeDistanceInt( Gia_Man_t * p, int iTarg, Vec_Int_t * vObjs, int fVerbose )
+{
+ int i, iObj;
+ Vec_Int_t * vDists, * vStart, * vNexts;
+ vStart = Vec_IntAlloc( 100 );
+ vNexts = Vec_IntAlloc( 100 );
+ vDists = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ if ( vObjs )
+ {
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ Vec_IntWriteEntry( vDists, iObj, 1 );
+ Vec_IntPush( vStart, iObj );
+ }
+ }
+ else
+ {
+ Gia_ObjSetTravIdCurrentId(p, iTarg);
+ Vec_IntWriteEntry( vDists, iTarg, 1 );
+ Vec_IntPush( vStart, iTarg );
+ }
+ for ( i = 0; ; i++ )
+ {
+ if ( fVerbose )
+ printf( "Ring %2d : %6d\n", i, Vec_IntSize(vDists)-Vec_IntCountZero(vDists) );
+ Gia_ManCollectRing( p, vStart, vNexts, vDists );
+ if ( Vec_IntSize(vNexts) == 0 )
+ break;
+ Vec_IntClear( vStart );
+ ABC_SWAP( Vec_Int_t, *vStart, *vNexts );
+ }
+ Vec_IntFree( vStart );
+ Vec_IntFree( vNexts );
+ return vDists;
+}
+Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose )
+{
+ Vec_Int_t * vDists;
+ if ( p->vFanoutNums )
+ vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose );
+ else
+ {
+ Gia_ManStaticFanoutStart( p );
+ vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose );
+ Gia_ManStaticFanoutStop( p );
+ }
+ return vDists;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ComputeTest()
+{
+ char * pStart, Line [1000]; float Total = 0;
+ char * pFileName = "data.txt";
+ FILE * pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ { printf( "Input file \"%s\" cannot be opened.\n", pFileName ); return; }
+ while ( fgets( Line, 1000, pFile ) != NULL )
+ {
+ if ( !strstr(Line, "xxx") )
+ continue;
+ if ( !strstr(Line, "yyy") )
+ continue;
+ //printf( "%s", Line );
+ pStart = strstr(Line, "zzz");
+ if ( pStart == NULL )
+ continue;
+ //printf( "%s", pStart + 4 );
+ Total += -atof( pStart + 4 );
+ }
+ printf( "Total = %.2f\n", Total );
+ fclose( pFile );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes sum total of support size of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSumTotalOfSupportSizes( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
+ int i, nResult = 0;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ nResult += Vec_IntSize( Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
+ Vec_WecFree( vSupps );
+ return nResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes sum total of support size of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSumTotalOfSupportSizes2( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) );
+ int r, nResult = 0, nRounds = (Gia_ManCiNum(p) + 63)/64;
+ for ( r = 0; r < nRounds; r++ )
+ {
+ Gia_Obj_t * pObj;
+ int i, Limit = r == nRounds-1 ? Gia_ManCiNum(p) % 64 : 64;
+ for ( i = 0; i < Limit; i++ )
+ Vec_WrdWriteEntry( vSims, 1+64*r+i, (word)1 << i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_WrdWriteEntry( vSims, i, Vec_WrdEntry(vSims, Gia_ObjFaninId0(pObj, i)) | Vec_WrdEntry(vSims, Gia_ObjFaninId1(pObj, i)) );
+ Gia_ManForEachCo( p, pObj, i )
+ nResult += Abc_TtCountOnes( Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj)) );
+ for ( i = 0; i < Limit; i++ )
+ Vec_WrdWriteEntry( vSims, 1+64*r+i, 0 );
+ }
+ Vec_WrdFree( vSims );
+ return nResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeCofs( Gia_Man_t * p, int nVars )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i, m;
+ Gia_Obj_t * pSink = Gia_ManCo(p, 0);
+ Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( m = 0; m < (1 << nVars); m++ )
+ {
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManCi(p, Gia_ManCiNum(p)-nVars+i)->Value = (m >> i) & 1;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) );
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeCofs2( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pSink; int i, o, m;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vAnds = Vec_IntAlloc( 1000 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ assert( (int)pObj->Value == Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ) );
+ }
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pSink, o )
+ {
+ int Fanin = Gia_ObjFaninId0p( p, pSink );
+ Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 );
+ Vec_IntClear( vSupp );
+ Vec_IntClear( vAnds );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) );
+ Vec_IntFree( vNodes );
+ Vec_IntSort( vSupp, 0 );
+ for ( m = 0; m < 5; m++ )
+ {
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0;
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //if ( m == 4 )
+ // Gia_ManAppendCo( pNew, 0 );
+ //else
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) );
+ Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 );
+ }
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vAnds );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeDepAig( Gia_Man_t * p, int iIn, int iOut )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i, n, iLits[2];
+ Gia_Obj_t * pPivot = Gia_ManCi(p, iIn);
+ Gia_Obj_t * pSink = Gia_ManCo(p, iOut);
+ Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( n = 0; n < 2; n++ )
+ {
+ pPivot->Value = n;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ iLits[n] = Gia_ObjFanin0Copy(pSink);
+ }
+ Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[1], Abc_LitNot(iLits[0])) );
+ Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[0], Abc_LitNot(iLits[1])) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+int Gia_ManComputeDep( Gia_Man_t * p, int iIn, int iOut )
+{
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pNew = Gia_ManComputeDepAig( p, iIn, iOut );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pNew, 100000, 0 );
+ int iLit[2] = { Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 0) ), Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 1) ) };
+ Gia_ManStop( pNew );
+ Gia_ManStop( pSwp );
+ if ( iLit[0] == 0 && iLit[1] == 0 )
+ return 2;
+ if ( iLit[1] == 0 )
+ return 1;
+ if ( iLit[0] == 0 )
+ return 0;
+ return -1;
+}
+Gia_Man_t * Gia_ManComputeDepTest( Gia_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ int i;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ printf( "%3d : %3d\n", i, Gia_ManComputeDep(p, i, 0) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return Gia_ManDup(p);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute support diffs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManComputeSupports( Gia_Man_t * p )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Gia_ManCoNum(p) );
+ Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj; int i;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_IntAppend( Vec_WecEntry(vRes, i), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
+ Vec_WecFree( vSupps );
+ return vRes;
+}
+Vec_Wec_t * Gia_ManComputeSharing( Vec_Wec_t * vSupps )
+{
+ Vec_Wec_t * vDiffs = Vec_WecStart( Vec_WecSize(vSupps) );
+ Vec_Int_t * vNew, * vOld; int i;
+ Vec_WecForEachLevelTwo( vDiffs, vSupps, vNew, vOld, i ) if ( i )
+ Vec_IntTwoFindCommon( Vec_WecEntry(vSupps, i-1), vOld, vNew );
+ return vDiffs;
+}
+Vec_Str_t * Gia_ManConvertDump( Gia_Man_t * p, Vec_Wec_t * vSupps )
+{
+ int fPrintDep = 1;
+ int nSize = Gia_ManCoNum(p) * (Gia_ManCiNum(p) + 1) + 1;
+ Vec_Str_t * vRes = Vec_StrAlloc( nSize );
+ Vec_Int_t * vLevel; int i, k, Obj;
+ assert( Gia_ManCoNum(p) == Vec_WecSize(vSupps) );
+ Vec_StrFill( vRes, nSize-1, '_' );
+ Vec_StrPush( vRes, '\0' );
+ Vec_WecForEachLevel( vSupps, vLevel, i )
+ {
+ Vec_IntForEachEntry( vLevel, Obj, k )
+ {
+ if ( !fPrintDep )
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' );
+ else
+ {
+ int Value = Gia_ManComputeDep( p, Obj, i );
+ if ( Value == -1 )
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' );
+ else
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, (char)('0'+Value) );
+ }
+ }
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Gia_ManCiNum(p), '\n' );
+ //printf( "Output %d\n", i );
+ }
+ return vRes;
+}
+void Gia_ManDumpSuppFile( Vec_Str_t * p, char * pFileName )
+{
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ else
+ {
+ int nOuts = Vec_StrCountEntry(p, '\n');
+ int nIns = Vec_StrSize(p)/Vec_StrCountEntry(p, '\n') - 1;
+ int nSize1 = Vec_StrSize(p) - 1;
+ int nSize2 = fwrite( Vec_StrArray(p), 1, nSize1, pFile );
+ assert( nSize1 == nSize2 );
+ printf( "Successfully dumped file \"%s\" with support data for %d outputs and %d inputs.\n", pFileName, nOuts, nIns );
+ }
+ fclose( pFile );
+}
+void Gia_ManDumpSuppFileTest3( Gia_Man_t * p, char * pFileName )
+{
+ Vec_Wec_t * vSupps = Gia_ManComputeSupports( p );
+ Vec_Wec_t * vDiffs = Gia_ManComputeSharing( vSupps );
+ Vec_Wec_t * vDiffs2 = Gia_ManComputeSharing( vDiffs );
+ Vec_Str_t * vRes = Gia_ManConvertDump( p, vDiffs2 );
+ Gia_ManDumpSuppFile( vRes, pFileName );
+ Vec_WecFree( vDiffs2 );
+ Vec_WecFree( vDiffs );
+ Vec_WecFree( vSupps );
+ Vec_StrFree( vRes );
+}
+void Gia_ManDumpSuppFileTest( Gia_Man_t * p, char * pFileName )
+{
+ Vec_Wec_t * vSupps = Gia_ManComputeSupports( p );
+ Vec_Str_t * vRes = Gia_ManConvertDump( p, vSupps );
+ Gia_ManDumpSuppFile( vRes, pFileName );
+ Vec_WecFree( vSupps );
+ Vec_StrFree( vRes );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Compute support diffs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManConvertSupp_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManConvertSupp( Gia_Man_t * p )
+{
+ int fOnly1 = 0;
+ int fVerbose = 1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObjPi, * pObjRi, * pObjRo;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vAnds = Vec_IntAlloc( 100 );
+ int i, n, iLits[2];
+ assert( Gia_ManRegNum(p) && Gia_ManRegNum(p) % 8 == 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObjPi, i )
+ pObjPi->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pObjRi, i )
+ {
+ pObjRo = Gia_ObjRiToRo(p, pObjRi);
+ if ( (i - Gia_ManPoNum(p)) % 8 != 0 )
+ continue;
+ if ( fOnly1 )
+ {
+ assert( pObjRo->Value == ~0 );
+ for ( n = 0; n < 2; n++ )
+ {
+ pObjRo->Value = n;
+ Gia_ManIncrementTravId( p );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) );
+ iLits[n] = Gia_ObjFanin0Copy(pObjRi);
+ }
+ pObjRo->Value = ~0;
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) );
+ }
+ else
+ {
+ int Fanin = Gia_ObjFaninId0p( p, pObjRi );
+ Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 );
+ Gia_Obj_t * pObj; int i, m;
+ Vec_IntClear( vSupp );
+ Vec_IntClear( vAnds );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) );
+ Vec_IntFree( vNodes );
+ Vec_IntSort( vSupp, 0 );
+ for ( m = 0; m < 4; m++ )
+ {
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0;
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //if ( m == 4 )
+ // Gia_ManAppendCo( pNew, 0 );
+ //else
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObjRi) );
+ //Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 );
+ }
+ }
+ }
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vAnds );
+ Gia_ManHashStop( pNew );
+ //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ if ( fVerbose )
+ printf( "Transformed %d outputs, ", Gia_ManPoNum(pNew) );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transform flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManTransformCond2( Gia_Man_t * p )
+{
+ int fVerbose = 1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObjPi, * pObjRi, * pObjRo;
+ int i, n, iTempLit, iLits[2];
+ assert( Gia_ManRegNum(p) > 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObjPi, i )
+ pObjPi->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pObjRi, i )
+ {
+ //if ( (i - Gia_ManPoNum(p)) % 8 != 0 )
+ // continue;
+ pObjRo = Gia_ObjRiToRo(p, pObjRi);
+ iTempLit = pObjRo->Value;
+ for ( n = 0; n < 2; n++ )
+ {
+ pObjRo->Value = n;
+ Gia_ManIncrementTravId( p );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) );
+ iLits[n] = Gia_ObjFanin0Copy(pObjRi);
+ }
+ pObjRo->Value = iTempLit;
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) );
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[0], Abc_LitNot(iLits[1]) )) );
+ }
+ Gia_ManHashStop( pNew );
+ //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ if ( fVerbose )
+ printf( "Created %d outputs. ", Gia_ManPoNum(pNew) );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Gia_ManDetectSims( Gia_Man_t * p, int iCo, int nWords )
+{
+ extern int Cec4_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit );
+ Vec_Wrd_t * vSim = Vec_WrdStart( nWords * Gia_ManCiNum(p) );
+ Vec_Int_t * vPat = Vec_IntAlloc( Gia_ManCiNum(p) );
+ Vec_Int_t * vVis = Vec_IntAlloc( Gia_ManAndNum(p) );
+ Gia_Obj_t * pObj = Gia_ManCo( p, iCo ), * pTemp; int iLit, i, k, nTries = 0;
+ if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(p) )
+ return NULL;
+ Gia_ManForEachObj( p, pTemp, k )
+ assert( !pTemp->fMark0 && !pTemp->fMark1 );
+ for ( i = 0; i < 64*nWords; )
+ {
+ int Res = Cec4_ManGeneratePatterns_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat, vVis );
+ if ( Res )
+ {
+ Vec_IntForEachEntry( vPat, iLit, k )
+ {
+ if ( Abc_LitIsCompl(iLit) )
+ continue;
+ pTemp = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ assert( Gia_ObjIsCi(pTemp) );
+ Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(vSim, nWords*Gia_ObjCioId(pTemp)), i );
+ }
+ i++;
+ }
+ Gia_ManForEachObjVec( vVis, p, pTemp, k )
+ pTemp->fMark0 = pTemp->fMark1 = 0;
+ nTries++;
+ }
+ //printf( "%d ", nTries );
+ Vec_IntFree( vPat );
+ Vec_IntFree( vVis );
+ return vSim;
+}
+Vec_Wrd_t * Vec_WrdInterleave( Vec_Wrd_t * p1, Vec_Wrd_t * p2, int nWords, int nIns )
+{
+ Vec_Wrd_t * p = Vec_WrdAlloc( Vec_WrdSize(p1)+Vec_WrdSize(p2) );
+ int i, k;
+ assert( Vec_WrdSize(p1) == nWords*nIns );
+ assert( Vec_WrdSize(p2) == nWords*nIns );
+ for ( i = 0; i < nIns; i++ )
+ {
+ for ( k = 0; k < nWords; k++ )
+ Vec_WrdPush( p, Vec_WrdEntry(p1, i*nWords+k) );
+ for ( k = 0; k < nWords; k++ )
+ Vec_WrdPush( p, Vec_WrdEntry(p2, i*nWords+k) );
+ }
+ return p;
+}
+Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p )
+{
+ extern void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns );
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSims;
+ Vec_Wrd_t * vSim[4];
+ Vec_Wrd_t * vInt[6];
+ int i;
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ vSims = Gia_ManDetectSims( p, i, 1 );
+ if ( i >= Gia_ManCoNum(p)-4 )
+ vSim[i-(Gia_ManCoNum(p)-4)] = vSims;
+ else
+ Vec_WrdFreeP( &vSims );
+ //Vec_PtrPush( vAll, vSims );
+ }
+ vInt[0] = Vec_WrdInterleave( vSim[0], vSim[1], 1, Gia_ManCiNum(p) );
+ vInt[1] = Vec_WrdInterleave( vSim[0], vSim[2], 1, Gia_ManCiNum(p) );
+ vInt[2] = Vec_WrdInterleave( vSim[0], vSim[3], 1, Gia_ManCiNum(p) );
+ vInt[3] = Vec_WrdInterleave( vSim[1], vSim[2], 1, Gia_ManCiNum(p) );
+ vInt[4] = Vec_WrdInterleave( vSim[1], vSim[3], 1, Gia_ManCiNum(p) );
+ vInt[5] = Vec_WrdInterleave( vSim[2], vSim[3], 1, Gia_ManCiNum(p) );
+
+ Gia_ManResubPair( vInt[0], vInt[5], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[1], vInt[4], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[2], vInt[3], 2, Gia_ManCiNum(p) );
+
+ Gia_ManResubPair( vInt[5], vInt[0], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[4], vInt[1], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[3], vInt[2], 2, Gia_ManCiNum(p) );
+
+/*
+ for ( i = 0; i < 4; i++ )
+ for ( k = i+1; k < 4; k++ )
+ Gia_ManResubPair( vSim[i], vSim[k], 1, Gia_ManCiNum(p) );
+*/
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 26909410..d801a243 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -14,8 +14,10 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaCSatOld.c \
src/aig/gia/giaCSat.c \
src/aig/gia/giaCSat2.c \
+ src/aig/gia/giaCSat3.c \
src/aig/gia/giaCTas.c \
src/aig/gia/giaCut.c \
+ src/aig/gia/giaDecs.c \
src/aig/gia/giaDeep.c \
src/aig/gia/giaDfs.c \
src/aig/gia/giaDup.c \
@@ -51,14 +53,21 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaMem.c \
src/aig/gia/giaMfs.c \
src/aig/gia/giaMini.c \
+ src/aig/gia/giaMinLut.c \
+ src/aig/gia/giaMinLut2.c \
src/aig/gia/giaMuxes.c \
src/aig/gia/giaNf.c \
src/aig/gia/giaOf.c \
src/aig/gia/giaPack.c \
src/aig/gia/giaPat.c \
+ src/aig/gia/giaPat2.c \
src/aig/gia/giaPf.c \
src/aig/gia/giaQbf.c \
+ src/aig/gia/giaReshape1.c \
+ src/aig/gia/giaReshape2.c \
src/aig/gia/giaResub.c \
+ src/aig/gia/giaResub2.c \
+ src/aig/gia/giaResub3.c \
src/aig/gia/giaRetime.c \
src/aig/gia/giaRex.c \
src/aig/gia/giaSatEdge.c \
@@ -75,16 +84,16 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaShrink7.c \
src/aig/gia/giaSim.c \
src/aig/gia/giaSim2.c \
- src/aig/gia/giaSim4.c \
- src/aig/gia/giaSim5.c \
src/aig/gia/giaSimBase.c \
src/aig/gia/giaSort.c \
src/aig/gia/giaSpeedup.c \
src/aig/gia/giaSplit.c \
src/aig/gia/giaStg.c \
+ src/aig/gia/giaStoch.c \
src/aig/gia/giaStr.c \
src/aig/gia/giaSupMin.c \
src/aig/gia/giaSupp.c \
+ src/aig/gia/giaSupps.c \
src/aig/gia/giaSweep.c \
src/aig/gia/giaSweeper.c \
src/aig/gia/giaSwitch.c \
diff --git a/src/aig/hop/hopBalance.c b/src/aig/hop/hopBalance.c
index e9aa4d4d..a3ce1c86 100644
--- a/src/aig/hop/hopBalance.c
+++ b/src/aig/hop/hopBalance.c
@@ -246,7 +246,7 @@ Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Ty
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Hop_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Hop_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
diff --git a/src/aig/ivy/ivyBalance.c b/src/aig/ivy/ivyBalance.c
index 6eba318c..2bcc69ee 100644
--- a/src/aig/ivy/ivyBalance.c
+++ b/src/aig/ivy/ivyBalance.c
@@ -178,7 +178,7 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Ty
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Ivy_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Ivy_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
diff --git a/src/aig/ivy/ivyCutTrav.c b/src/aig/ivy/ivyCutTrav.c
index 74212b10..b1cdb456 100644
--- a/src/aig/ivy/ivyCutTrav.c
+++ b/src/aig/ivy/ivyCutTrav.c
@@ -329,7 +329,7 @@ void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNode
} while ( Vec_PtrSize(vNodes) < nNodeLimit );
// sort nodes by level
- Vec_PtrSort( vNodes, (int (*)(void))Ivy_CompareNodesByLevel );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Ivy_CompareNodesByLevel );
// make sure the nodes are ordered in the increasing number of levels
pFanin = (Ivy_Obj_t *)Vec_PtrEntry( vNodes, 0 );
pPivot = (Ivy_Obj_t *)Vec_PtrEntryLast( vNodes );
diff --git a/src/aig/ivy/ivyRwrAlg.c b/src/aig/ivy/ivyRwrAlg.c
index ce605003..53fe5817 100644
--- a/src/aig/ivy/ivyRwrAlg.c
+++ b/src/aig/ivy/ivyRwrAlg.c
@@ -371,7 +371,7 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave
if ( Vec_PtrSize(vFront) <= 2 )
return 1;
// sort the entries in increasing order
- Vec_PtrSort( vFront, (int (*)(void))Ivy_ManFindAlgCutCompare );
+ Vec_PtrSort( vFront, (int (*)(const void *, const void *))Ivy_ManFindAlgCutCompare );
// remove duplicates from vFront and save the nodes in vLeaves
pPrev = Vec_PtrEntry(vFront, 0);
Vec_PtrPush( vLeaves, pPrev );
diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h
index 2fd7ab24..c3d6e176 100644
--- a/src/aig/miniaig/abcOper.h
+++ b/src/aig/miniaig/abcOper.h
@@ -29,7 +29,9 @@
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_START
+#endif
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
@@ -232,6 +234,26 @@ static inline const char * Abc_OperName( int Type )
return NULL;
}
+// printing operator types
+static inline const char * Abc_OperNameSimple( int Type )
+{
+ if ( Type == ABC_OPER_NONE ) return NULL;
+ if ( Type == ABC_OPER_CONST_F ) return "buf";
+ if ( Type == ABC_OPER_CONST_T ) return "buf";
+ if ( Type == ABC_OPER_CONST_X ) return "buf";
+ if ( Type == ABC_OPER_CONST_Z ) return "buf";
+ if ( Type == ABC_OPER_BIT_BUF ) return "buf";
+ if ( Type == ABC_OPER_BIT_INV ) return "not";
+ if ( Type == ABC_OPER_BIT_AND ) return "and";
+ if ( Type == ABC_OPER_BIT_OR ) return "or";
+ if ( Type == ABC_OPER_BIT_XOR ) return "xor";
+ if ( Type == ABC_OPER_BIT_NAND ) return "nand";
+ if ( Type == ABC_OPER_BIT_NOR ) return "nor";
+ if ( Type == ABC_OPER_BIT_NXOR ) return "xnor";
+ assert( 0 );
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -244,9 +266,9 @@ static inline const char * Abc_OperName( int Type )
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_END
-
+#endif
#endif
diff --git a/src/aig/miniaig/minilut.h b/src/aig/miniaig/minilut.h
index b080c983..2a27ccad 100644
--- a/src/aig/miniaig/minilut.h
+++ b/src/aig/miniaig/minilut.h
@@ -179,7 +179,37 @@ static void Mini_LutPrintStats( Mini_Lut_t * p )
nNodes = 0;
Mini_LutForEachNode( p, i )
nNodes++;
- printf( "PI = %d. PO = %d. LUT = %d.\n", nPis, nPos, nNodes );
+ printf( "PI = %d. PO = %d. LUT = %d. FF = %d.\n", nPis, nPos, nNodes, p->nRegs );
+}
+static void Mini_LutPrint( Mini_Lut_t * p )
+{
+ int i, k, Fan;
+ printf( "MiniLUT statistics: " );
+ Mini_LutPrintStats( p );
+ printf( "Printout of nodes:\n" );
+ for ( i = 0; i < p->nSize; i++ )
+ {
+ printf( "%6d : ", i );
+ if ( Mini_LutNodeIsConst(p, i) )
+ printf( "Const%d", i );
+ else if ( Mini_LutNodeIsPi(p, i) )
+ printf( "PI" );
+ else if ( Mini_LutNodeIsPo(p, i) )
+ printf( "PO" );
+ else if ( Mini_LutNodeIsNode(p, i) )
+ {
+ printf( "LUT%d Fanins:", p->LutSize );
+ Mini_LutForEachFanin( p, i, Fan, k )
+ printf( " %6d", Fan );
+ while ( k++ < p->LutSize )
+ printf( " " );
+ printf( " Function: " );
+ for ( k = 31; k >= 0; k-- )
+ printf( "%c", '0' + ((p->pTruths[i] >> k) & 1) );
+ }
+ printf( "\n" );
+ }
+ printf( "End of printout.\n" );
}
// serialization
diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h
index 8d630159..68c2779c 100644
--- a/src/aig/miniaig/ndr.h
+++ b/src/aig/miniaig/ndr.h
@@ -33,7 +33,9 @@
#include "abcOper.h"
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_START
+#endif
#ifdef _WIN32
#define inline __inline
@@ -215,8 +217,9 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch
return;
if ( ObjType == ABC_OPER_LUT )
{
- word Truth = (word)pFunc;
- Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
+ //word Truth = (word)pFunc;
+ //Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
+ Ndr_DataPushArray( p, Type, 2, (int *)&pFunc );
}
else
{
@@ -334,7 +337,7 @@ static inline int Ndr_DataObjNum( Ndr_Data_t * p, int Mod )
}
// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
-static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames )
+static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames, int fSimple )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
int * pOuts = NDR_ALLOC( int, Ndr_DataCoNum(p, Mod) );
@@ -377,6 +380,8 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
break;
if ( k < i )
continue;
+ if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
+ continue;
fprintf( pFile, " wire " );
Ndr_ObjWriteRange( p, Obj, pFile, 1 );
fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) );
@@ -459,6 +464,24 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
fprintf( pFile, ");\n" );
continue;
}
+ if ( fSimple )
+ {
+ if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
+ continue;
+ nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
+ fprintf( pFile, " %s ( %s", Abc_OperNameSimple(Type), Ndr_ObjReadOutName(p, Obj, pNames) );
+ if ( nArray == 0 )
+ fprintf( pFile, ", %s );\n", (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
+ else if ( nArray == 1 && Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE) == ABC_OPER_BIT_BUF )
+ fprintf( pFile, ", %s );\n", pNames[pArray[0]] );
+ else
+ {
+ for ( i = 0; i < nArray; i++ )
+ fprintf( pFile, ", %s", pNames[pArray[i]] );
+ fprintf( pFile, " );\n" );
+ }
+ continue;
+ }
fprintf( pFile, " assign %s = ", Ndr_ObjReadOutName(p, Obj, pNames) );
nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
if ( nArray == 0 )
@@ -492,15 +515,15 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
}
// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
-static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames )
+static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames, int fSimple )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int Mod;
FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
- if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; }
+ if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
Ndr_DesForEachMod( p, Mod )
- Ndr_WriteVerilogModule( pFile, p, Mod, pNames );
+ Ndr_WriteVerilogModule( pFile, p, Mod, pNames, fSimple );
if ( pFileName ) fclose( pFile );
}
@@ -613,7 +636,7 @@ static inline void Ndr_Write( char * pFileName, void * pDesign )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int RetValue;
FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; }
+ if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
RetValue = (int)fwrite( p->pBody, 4, p->pBody[0], pFile );
RetValue = (int)fwrite( p->pHead, 1, p->pBody[0], pFile );
fclose( pFile );
@@ -642,7 +665,7 @@ static inline void Ndr_ModuleTest()
// array of fanins of node s
int Fanins[2] = { NameIdA, NameIdC };
// map name IDs into char strings
- char * ppNames[5] = { NULL, "add10", "a", "s", "const10" };
+ //char * ppNames[5] = { NULL, "add10", "a", "s", "const10" };
// create a new module
void * pDesign = Ndr_Create( 1 );
@@ -651,13 +674,13 @@ static inline void Ndr_ModuleTest()
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdA, NULL ); // no fanins
- Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, "4'b1010" ); // no fanins
+ Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, (char*)"4'b1010" ); // no fanins
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 3, 0, 0, 2, Fanins, 1, &NameIdS, NULL ); // fanins are a and const10
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdS, 0, NULL, NULL ); // fanin is a
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "add4.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"add4.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -686,6 +709,7 @@ static inline void Ndr_ModuleTest()
static inline void Ndr_ModuleTestAdder()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"a", "b", "s", "co", // 1, 2, 3, 4
@@ -693,6 +717,7 @@ static inline void Ndr_ModuleTestAdder()
"r0", "s0", "rco", // 9, 10, 11
"r1", "s1", "add8" // 12, 13, 14
};
+*/
// fanins
int FaninA = 1;
int FaninB = 2;
@@ -744,8 +769,8 @@ static inline void Ndr_ModuleTestAdder()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "add8.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"add8.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -772,6 +797,7 @@ static inline void Ndr_ModuleTestAdder()
static inline void Ndr_ModuleTestHierarchy()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"mux21w", "mux41w", // 1, 2
@@ -781,6 +807,7 @@ static inline void Ndr_ModuleTestHierarchy()
"t0", "t1", // 12, 13
"i0", "i1", "i2" // 14, 15, 16
};
+*/
// fanins
int FaninSel = 3;
int FaninSel0 = 10;
@@ -830,8 +857,8 @@ static inline void Ndr_ModuleTestHierarchy()
Ndr_AddObject( pDesign, Module41, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "mux41w.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"mux41w.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -859,6 +886,7 @@ static inline void Ndr_ModuleTestHierarchy()
static inline void Ndr_ModuleTestMemory()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"clk", "raddr", "waddr", "data", "mem_init", "out", // 1, 2, 3, 4, 5, 6
@@ -868,6 +896,7 @@ static inline void Ndr_ModuleTestMemory()
"i_read1", "i_read2", // 15, 16
"i_write1", "i_write2", "memtest" // 17, 18, 19
};
+*/
// inputs
int NameIdClk = 1;
int NameIdRaddr = 2;
@@ -919,8 +948,8 @@ static inline void Ndr_ModuleTestMemory()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_COMP_NOTEQU, 0, 0, 0, 0, 2, FaninsComp, 1, &NameIdComp, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "memtest.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"memtest.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -934,7 +963,7 @@ static inline void Ndr_ModuleTestMemory()
static inline void Ndr_ModuleTestFlop()
{
// map name IDs into char strings
- char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
+ //char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
// name IDs
int NameIdData = 2;
int NameIdClk = 3;
@@ -968,8 +997,8 @@ static inline void Ndr_ModuleTestFlop()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "flop.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"flop.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1022,8 +1051,8 @@ static inline void Ndr_ModuleTestSelSel()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 2, 0, 0, 1, &NameIdOut,0, NULL, NULL );
// write Verilog for verification
- //Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "sel.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"sel.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1056,7 +1085,7 @@ static inline void Ndr_ModuleTestDec()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "dec.ndr", pDesign );
+ Ndr_Write( (char*)"dec.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1092,7 +1121,7 @@ static inline void Ndr_ModuleTestAddSub()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "addsub.ndr", pDesign );
+ Ndr_Write( (char*)"addsub.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1116,16 +1145,20 @@ static inline void Ndr_ModuleTestLut()
int ModuleID = Ndr_AddModule( pDesign, 1 );
+ unsigned pTruth[2] = { 0x88888888, 0x88888888 };
+
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
- Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)(ABC_CONST(0x8)) );
+ Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)pTruth );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "lut_test.ndr", pDesign );
+ Ndr_Write( (char*)"lut_test.ndr", pDesign );
Ndr_Delete( pDesign );
}
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_END
+#endif
#endif
diff --git a/src/aig/saig/saigConstr.c b/src/aig/saig/saigConstr.c
index ac58839b..90e82816 100644
--- a/src/aig/saig/saigConstr.c
+++ b/src/aig/saig/saigConstr.c
@@ -300,8 +300,8 @@ Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig )
Vec_VecFree( (Vec_Vec_t *)vConsAll );
return Aig_ManDupDfs( pAig );
}
- Vec_PtrSort( vOuts, (int (*)(void))Saig_ManDupCompare );
- Vec_PtrSort( vCons, (int (*)(void))Saig_ManDupCompare );
+ Vec_PtrSort( vOuts, (int (*)(const void *, const void *))Saig_ManDupCompare );
+ Vec_PtrSort( vCons, (int (*)(const void *, const void *))Saig_ManDupCompare );
Vec_PtrPush( vOutsAll, vOuts );
Vec_PtrPush( vConsAll, vCons );
}
diff --git a/src/aig/saig/saigIso.c b/src/aig/saig/saigIso.c
index 40500361..7b8d488a 100644
--- a/src/aig/saig/saigIso.c
+++ b/src/aig/saig/saigIso.c
@@ -63,7 +63,7 @@ Vec_Int_t * Saig_ManFindIsoPermCos( Aig_Man_t * pAig, Vec_Int_t * vPermCis )
pObj->iData = Abc_Var2Lit( pFanin->iData, Aig_ObjFaninC0(pObj) );
Vec_PtrPush( vRoots, pObj );
}
- Vec_PtrSort( vRoots, (int (*)(void))Iso_ObjCompareByData );
+ Vec_PtrSort( vRoots, (int (*)(const void *, const void *))Iso_ObjCompareByData );
Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i )
Vec_IntPush( vPermCos, Aig_ObjCioId(pObj) );
Vec_PtrFree( vRoots );
@@ -467,7 +467,7 @@ Aig_Man_t * Iso_ManFilterPos( Aig_Man_t * pAig, Vec_Ptr_t ** pvPosEquivs, int fV
// sort the infos
clk = Abc_Clock();
- Vec_PtrSort( vBuffers, (int (*)(void))Iso_StoCompareVecStr );
+ Vec_PtrSort( vBuffers, (int (*)(const void *, const void *))Iso_StoCompareVecStr );
// create classes
clk = Abc_Clock();
diff --git a/src/aig/saig/saigIsoFast.c b/src/aig/saig/saigIsoFast.c
index 7393e7fc..10d1384d 100644
--- a/src/aig/saig/saigIsoFast.c
+++ b/src/aig/saig/saigIsoFast.c
@@ -303,7 +303,7 @@ Vec_Vec_t * Saig_IsoDetectFast( Aig_Man_t * pAig )
// sort the infos
clk = Abc_Clock();
- Vec_PtrSort( vInfos, (int (*)(void))Iso_StoCompareVecInt );
+ Vec_PtrSort( vInfos, (int (*)(const void *, const void *))Iso_StoCompareVecInt );
// create classes
clk = Abc_Clock();
diff --git a/src/aig/saig/saigIsoSlow.c b/src/aig/saig/saigIsoSlow.c
index a0e2d1d0..4784d98a 100644
--- a/src/aig/saig/saigIsoSlow.c
+++ b/src/aig/saig/saigIsoSlow.c
@@ -572,8 +572,8 @@ void Iso_ManCollectClasses( Iso_Man_t * p )
}
}
clk = Abc_Clock();
- Vec_PtrSort( p->vSingles, (int (*)(void))Iso_ObjCompare );
- Vec_PtrSort( p->vClasses, (int (*)(void))Iso_ObjCompare );
+ Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Iso_ObjCompare );
+ Vec_PtrSort( p->vClasses, (int (*)(const void *, const void *))Iso_ObjCompare );
p->timeSort += Abc_Clock() - clk;
assert( Vec_PtrSize(p->vSingles) == p->nSingles );
assert( Vec_PtrSize(p->vClasses) == p->nClasses );
@@ -1115,8 +1115,8 @@ Vec_Int_t * Iso_ManFinalize( Iso_Man_t * p )
Vec_PtrPush( p->vTemp1, pObj );
}
// sort CIs by their IDs
- Vec_PtrSort( p->vTemp1, (int (*)(void))Iso_ObjCompareByData );
- Vec_PtrSort( p->vTemp2, (int (*)(void))Iso_ObjCompareByData );
+ Vec_PtrSort( p->vTemp1, (int (*)(const void *, const void *))Iso_ObjCompareByData );
+ Vec_PtrSort( p->vTemp2, (int (*)(const void *, const void *))Iso_ObjCompareByData );
// create the result
vRes = Vec_IntAlloc( Aig_ManCiNum(p->pAig) );
Vec_PtrForEachEntry( Aig_Obj_t *, p->vTemp1, pObj, i )
diff --git a/src/aig/saig/saigWnd.c b/src/aig/saig/saigWnd.c
index ce70e7b4..949a2728 100644
--- a/src/aig/saig/saigWnd.c
+++ b/src/aig/saig/saigWnd.c
@@ -106,7 +106,7 @@ Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist )
vNodes = Vec_PtrAlloc( 1000 );
Aig_ManIncrementTravId( p );
Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists );
- Vec_PtrSort( vNodes, (int (*)(void))Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease );
// make sure LI/LO are labeled/unlabeled mutually
Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
assert( Aig_ObjIsTravIdCurrent(p, pObjLi) ==