summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2022-07-04 16:02:44 +0200
committerMiodrag Milanovic <mmicko@gmail.com>2022-07-04 16:02:44 +0200
commit163af36fee3bdc3fe0e8ce629cba333cb2cff199 (patch)
treec4004a295813151478fe8b36a41725457cc6ea17 /src
parent18634305282c81b0f4a08de4ebca6ccc95b11748 (diff)
parentc23cd0a7c5f4264b3209f127885b8d5432f2fd5a (diff)
downloadabc-163af36fee3bdc3fe0e8ce629cba333cb2cff199.tar.gz
abc-163af36fee3bdc3fe0e8ce629cba333cb2cff199.tar.bz2
abc-163af36fee3bdc3fe0e8ce629cba333cb2cff199.zip
Merge remote-tracking branch 'upstream/master' into yosys-experimental
Diffstat (limited to 'src')
-rw-r--r--src/aig/aig/aigDup.c2
-rw-r--r--src/aig/aig/aigUtil.c2
-rw-r--r--src/aig/gia/gia.h3
-rw-r--r--src/aig/gia/giaAig.c26
-rw-r--r--src/aig/gia/giaCSatP.c1209
-rw-r--r--src/aig/gia/giaCSatP.h117
-rw-r--r--src/aig/gia/giaCex.c2
-rw-r--r--src/aig/gia/giaDup.c321
-rw-r--r--src/aig/gia/giaMan.c2
-rw-r--r--src/aig/gia/giaMini.c48
-rw-r--r--src/aig/gia/giaMuxes.c67
-rw-r--r--src/aig/gia/giaPat2.c97
-rw-r--r--src/aig/gia/giaResub6.c451
-rw-r--r--src/aig/gia/giaSif.c257
-rw-r--r--src/aig/gia/giaSimBase.c81
-rw-r--r--src/aig/gia/giaSupps.c142
-rw-r--r--src/aig/gia/giaSwitch.c8
-rw-r--r--src/aig/gia/giaUtil.c50
-rw-r--r--src/aig/gia/module.make3
-rw-r--r--src/aig/ioa/ioaReadAig.c2
-rw-r--r--src/aig/miniaig/abcOper.h4
-rw-r--r--src/aig/miniaig/miniaig.h284
-rw-r--r--src/base/abc/abc.h5
-rw-r--r--src/base/abc/abcAig.c5
-rw-r--r--src/base/abc/abcCheck.c5
-rw-r--r--src/base/abc/abcMinBase.c25
-rw-r--r--src/base/abc/abcNtk.c46
-rw-r--r--src/base/abc/abcSop.c69
-rw-r--r--src/base/abci/abc.c843
-rw-r--r--src/base/abci/abcDar.c36
-rw-r--r--src/base/abci/abcExact.c2
-rw-r--r--src/base/abci/abcNpn.c15
-rw-r--r--src/base/abci/abcNtbdd.c3
-rw-r--r--src/base/abci/abcRefactor.c34
-rw-r--r--src/base/abci/abcRestruct.c2
-rw-r--r--src/base/abci/abcResub.c2
-rw-r--r--src/base/abci/abcRewrite.c31
-rw-r--r--src/base/abci/abcRr.c5
-rw-r--r--src/base/abci/abcTiming.c2
-rw-r--r--src/base/acb/acbTest.c2
-rw-r--r--src/base/cmd/cmd.c8
-rw-r--r--src/base/cmd/cmdLoad.c3
-rw-r--r--src/base/cmd/cmdUtils.c87
-rw-r--r--src/base/io/io.c106
-rw-r--r--src/base/io/ioWriteGml.c12
-rw-r--r--src/base/main/mainInit.c4
-rw-r--r--src/base/main/mainInt.h1
-rw-r--r--src/base/wlc/wlcBlast.c50
-rw-r--r--src/base/wlc/wlcCom.c24
-rw-r--r--src/base/wlc/wlcMem.c2
-rw-r--r--src/base/wln/module.make5
-rw-r--r--src/base/wln/wln.h4
-rw-r--r--src/base/wln/wlnBlast.c388
-rw-r--r--src/base/wln/wlnCom.c532
-rw-r--r--src/base/wln/wlnGuide.c95
-rw-r--r--src/base/wln/wlnRead.c2866
-rw-r--r--src/base/wln/wlnRtl.c211
-rw-r--r--src/bdd/cudd/cuddAddIte.c25
-rw-r--r--src/bdd/cudd/cuddAddNeg.c20
-rw-r--r--src/bdd/cudd/cuddBddAbs.c19
-rw-r--r--src/bdd/cudd/cuddBddIte.c24
-rw-r--r--src/bdd/cudd/cuddClip.c32
-rw-r--r--src/bdd/cudd/cuddMatMult.c21
-rw-r--r--src/bdd/cudd/cuddPriority.c24
-rw-r--r--src/bdd/cudd/cuddSat.c44
-rw-r--r--src/bdd/cudd/cuddZddIsop.c20
-rw-r--r--src/bool/dec/decAbc.c7
-rw-r--r--src/bool/kit/kitDsd.c2
-rw-r--r--src/map/amap/amapRead.c66
-rw-r--r--src/map/amap/amapUniq.c7
-rw-r--r--src/map/if/if.h4
-rw-r--r--src/map/if/ifCore.c2
-rw-r--r--src/map/if/ifCut.c62
-rw-r--r--src/map/if/ifDsd.c8
-rw-r--r--src/map/if/ifMan.c2
-rw-r--r--src/map/mio/mioRead.c61
-rw-r--r--src/map/mio/mioUtils.c5
-rw-r--r--src/map/scl/sclLiberty.c6
-rw-r--r--src/misc/extra/extraUtilMisc.c2
-rw-r--r--src/misc/util/utilTruth.h18
-rw-r--r--src/misc/vec/vecInt.h2
-rw-r--r--src/misc/vec/vecWrd.h8
-rw-r--r--src/opt/dau/dauCanon.c2
-rw-r--r--src/proof/acec/acecBo.c77
-rw-r--r--src/proof/acec/acecXor.c44
-rw-r--r--src/proof/cec/cec.h2
-rw-r--r--src/proof/cec/cecCec.c15
-rw-r--r--src/proof/cec/cecCorr.c38
-rw-r--r--src/proof/cec/cecSatG2.c135
-rw-r--r--src/proof/cec/cecSatG3.c2342
-rw-r--r--src/proof/cec/cecSolveG.c2
-rw-r--r--src/proof/cec/module.make1
-rw-r--r--src/proof/ssw/ssw.h1
-rw-r--r--src/proof/ssw/sswCore.c25
-rw-r--r--src/sat/bsat2/Solver.cpp2
-rw-r--r--src/sat/glucose/AbcGlucose.cpp11
-rw-r--r--src/sat/glucose/AbcGlucose.h2
-rw-r--r--src/sat/glucose/AbcGlucoseCmd.cpp11
-rw-r--r--src/sat/glucose/Glucose.cpp2
-rw-r--r--src/sat/glucose2/AbcGlucose2.cpp19
-rw-r--r--src/sat/glucose2/AbcGlucose2.h1
-rw-r--r--src/sat/glucose2/CGlucoseCore.h79
-rw-r--r--src/sat/glucose2/Glucose2.cpp29
-rw-r--r--src/sat/glucose2/Solver.h8
-rw-r--r--src/sat/msat/msatClause.c2
-rw-r--r--src/sat/msat/msatSolverSearch.c10
106 files changed, 11769 insertions, 290 deletions
diff --git a/src/aig/aig/aigDup.c b/src/aig/aig/aigDup.c
index 3ccd8dab..234192cb 100644
--- a/src/aig/aig/aigDup.c
+++ b/src/aig/aig/aigDup.c
@@ -1154,7 +1154,7 @@ Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs )
Aig_Man_t * pNew;
Aig_Obj_t * pObj = NULL;
int i;
- assert( Aig_ManRegNum(p) > 0 );
+ //assert( Aig_ManRegNum(p) > 0 );
assert( iPoNum < Aig_ManCoNum(p)-Aig_ManRegNum(p) );
// create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c
index 52f9a184..68be112f 100644
--- a/src/aig/aig/aigUtil.c
+++ b/src/aig/aig/aigUtil.c
@@ -1333,7 +1333,7 @@ void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex )
pAig->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Aig_ManObjNumMax(pAig) ) );
// the register values in the counter-example should be zero
Saig_ManForEachLo( pAig, pObj, k )
- assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
+ assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
// iterate through the timeframes
nObjs = Aig_ManObjNumMax(pAig);
for ( i = 0; i <= pCex->iFrame; i++ )
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index 5548def6..488f12cf 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -1312,6 +1312,8 @@ extern Gia_Man_t * Gia_ManDupLastPis( Gia_Man_t * p, int nLastPis );
extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState );
extern Gia_Man_t * Gia_ManDupCycled( Gia_Man_t * pAig, Abc_Cex_t * pCex, int nFrames );
extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupNoBuf( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupMap( Gia_Man_t * p, Vec_Int_t * vMap );
extern Gia_Man_t * Gia_ManDup2( Gia_Man_t * p1, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis );
@@ -1351,6 +1353,7 @@ extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int n
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose );
+extern Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOut, int fVerbose );
extern Gia_Man_t * Gia_ManDupAndOr( Gia_Man_t * p, int nOuts, int fUseOr, int fCompl );
extern Gia_Man_t * Gia_ManDupZeroUndc( Gia_Man_t * p, char * pInit, int nNewPis, int fGiaSimple, int fVerbose );
extern Gia_Man_t * Gia_ManMiter2( Gia_Man_t * p, char * pInit, int fVerbose );
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index 91a9c600..c764a099 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -611,6 +611,27 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose )
SeeAlso []
***********************************************************************/
+int Gia_ManTestChoices( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vPointed = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Gia_ObjSibl(p, i) )
+ Vec_IntWriteEntry( vPointed, Gia_ObjSibl(p, i), 1 );
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_IntEntry(vPointed, i) && Gia_ObjRefNumId(p, i) > 0 )
+ {
+ printf( "Gia_ManCheckChoices: Member %d", i );
+ printf( " of a choice node has %d fanouts.\n", Gia_ObjRefNumId(p, i) );
+ ABC_FREE( p->pRefs );
+ Vec_IntFree( vPointed );
+ return 0;
+ }
+ ABC_FREE( p->pRefs );
+ Vec_IntFree( vPointed );
+ return 1;
+}
Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
{
int fUseMapping = 0;
@@ -628,6 +649,11 @@ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
// pGia = Gia_ManFromAig( pNew );
pGia = Gia_ManFromAigChoices( pNew );
Aig_ManStop( pNew );
+ if ( !p->pManTime && !Gia_ManTestChoices(pGia) )
+ {
+ Gia_ManStop( pGia );
+ pGia = Gia_ManDup( p );
+ }
Gia_ManTransferTiming( pGia, p );
return pGia;
}
diff --git a/src/aig/gia/giaCSatP.c b/src/aig/gia/giaCSatP.c
new file mode 100644
index 00000000..00ab880b
--- /dev/null
+++ b/src/aig/gia/giaCSatP.c
@@ -0,0 +1,1209 @@
+/**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"
+#include "giaCSatP.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+//#define gia_assert(exp) ((void)0)
+//#define gia_assert(exp) (assert(exp))
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+static inline int CbsP_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; }
+static inline void CbsP_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; }
+static inline void CbsP_VarUnassign( CbsP_Man_t * pMan, Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; pVar->fMark1 = 0; pMan->vValue->pArray[Gia_ObjId(pMan->pAig,pVar)] = ~0; }
+static inline int CbsP_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; }
+static inline void CbsP_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; }
+static inline int CbsP_VarIsJust( Gia_Obj_t * pVar ) { return Gia_ObjIsAnd(pVar) && !CbsP_VarIsAssigned(Gia_ObjFanin0(pVar)) && !CbsP_VarIsAssigned(Gia_ObjFanin1(pVar)); }
+static inline int CbsP_VarFanin0Value( Gia_Obj_t * pVar ) { return !CbsP_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (CbsP_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); }
+static inline int CbsP_VarFanin1Value( Gia_Obj_t * pVar ) { return !CbsP_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (CbsP_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); }
+
+static inline int CbsP_VarDecLevel( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*Value); }
+static inline Gia_Obj_t * CbsP_VarReason0( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*Value+1); }
+static inline Gia_Obj_t * CbsP_VarReason1( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*Value+2); }
+static inline int CbsP_ClauseDecLevel( CbsP_Man_t * p, int hClause ) { return CbsP_VarDecLevel( p, p->pClauses.pData[hClause] ); }
+
+#define CbsP_QueForEachEntry( Que, pObj, i ) \
+ for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ )
+
+#define CbsP_ClauseForEachVar( p, hClause, pObj ) \
+ for ( (p)->pIter = (p)->pClauses.pData + hClause; (pObj = *pIter); (p)->pIter++ )
+#define CbsP_ClauseForEachVar1( p, hClause, pObj ) \
+ for ( (p)->pIter = (p)->pClauses.pData+hClause+1; (pObj = *pIter); (p)->pIter++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets default values of the parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CbsP_SetDefaultParams( CbsP_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(CbsP_Par_t) );
+ pPars->nBTLimit = 1000; // limit on the number of conflicts
+ pPars->nJustLimit = 100; // limit on the size of justification queue
+ pPars->fUseHighest = 1; // use node with the highest ID
+ pPars->fUseLowest = 0; // use node with the highest ID
+ pPars->fUseMaxFF = 0; // use node with the largest fanin fanout
+ pPars->fVerbose = 1; // print detailed statistics
+
+ pPars->fUseProved = 1;
+
+
+ pPars->nJscanThis = 0;
+ pPars->nRscanThis = 0;
+ pPars->maxJscanUndec = 0;
+ pPars->maxRscanUndec = 0;
+ pPars->maxJscanSolved = 0;
+ pPars->maxRscanSolved = 0;
+
+
+ pPars->accJscanSat = 0;
+ pPars->accJscanUnsat = 0;
+ pPars->accJscanUndec = 0;
+ pPars->accRscanSat = 0;
+ pPars->accRscanUnsat = 0;
+ pPars->accRscanUndec = 0;
+ pPars->nSat = 0;
+ pPars->nUnsat = 0;
+ pPars->nUndec = 0;
+
+ pPars->nJscanLimit = 100;
+ pPars->nRscanLimit = 100;
+ pPars->nPropLimit = 500;
+}
+void CbsP_ManSetConflictNum( CbsP_Man_t * p, int Num )
+{
+ p->Pars.nBTLimit = Num;
+}
+
+static inline void CbsP_UpdateRecord( CbsP_Par_t * pPars, int res ){
+ if( CBS_UNDEC == res ){
+ pPars->nUndec ++ ;
+ if( pPars-> maxJscanUndec < pPars->nJscanThis )
+ pPars-> maxJscanUndec = pPars->nJscanThis;
+ if( pPars-> maxRscanUndec < pPars->nRscanThis )
+ pPars-> maxRscanUndec = pPars->nRscanThis;
+ if( pPars-> maxPropUndec < pPars->nPropThis )
+ pPars-> maxPropUndec = pPars->nPropThis;
+
+ pPars->accJscanUndec += pPars->nJscanThis;
+ pPars->accRscanUndec += pPars->nRscanThis;
+ pPars-> accPropUndec += pPars->nPropThis;
+ } else {
+ if( pPars->maxJscanSolved < pPars->nJscanThis )
+ pPars->maxJscanSolved = pPars->nJscanThis;
+ if( pPars->maxRscanSolved < pPars->nRscanThis )
+ pPars->maxRscanSolved = pPars->nRscanThis;
+ if( pPars-> maxPropSolved < pPars->nPropThis )
+ pPars-> maxPropSolved = pPars->nPropThis;
+ if( CBS_SAT == res ){
+ pPars->nSat ++ ;
+ pPars->accJscanSat += pPars->nJscanThis;
+ pPars->accRscanSat += pPars->nRscanThis;
+ pPars-> accPropSat += pPars->nPropThis;
+ } else
+ if( CBS_UNSAT == res ){
+ pPars->nUnsat ++ ;
+ pPars->accJscanUnsat += pPars->nJscanThis;
+ pPars->accRscanUnsat += pPars->nRscanThis;
+ pPars-> accPropUnsat += pPars->nPropThis;
+ }
+ }
+
+}
+
+void CbsP_PrintRecord( CbsP_Par_t * pPars ){
+ printf("max of solved: jscan# %13d rscan %13d prop %13d\n" , pPars->maxJscanSolved, pPars->maxRscanSolved , pPars->maxPropSolved );
+ printf("max of undec: jscan# %13d rscan %13d prop %13d\n" , pPars->maxJscanUndec , pPars->maxRscanUndec , pPars->maxPropUndec );
+ printf("acc of sat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanSat , pPars->accRscanSat , pPars->accPropSat );
+ printf("acc of unsat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUnsat , pPars->accRscanUnsat , pPars->accPropUnsat );
+ printf("acc of undec: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUndec , pPars->accRscanUndec , pPars->accPropUndec );
+ if( pPars->nSat )
+ printf("avg of sat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanSat / pPars->nSat , pPars->accRscanSat / pPars->nSat , pPars->accPropSat / pPars->nSat );
+ if( pPars->nUnsat )
+ printf("avg of unsat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUnsat / pPars->nUnsat , pPars->accRscanUnsat / pPars->nUnsat , pPars->accPropUnsat / pPars->nUnsat );
+ if( pPars->nUndec )
+ printf("avg of undec: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUndec / pPars->nUndec , pPars->accRscanUndec / pPars->nUndec , pPars->accPropUndec / pPars->nUndec );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+CbsP_Man_t * CbsP_ManAlloc( Gia_Man_t * pGia )
+{
+ CbsP_Man_t * p;
+ p = ABC_CALLOC( CbsP_Man_t, 1 );
+ p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000;
+ p->pProp.pData = ABC_ALLOC( Gia_Obj_t *, p->pProp.nSize );
+ p->pJust.pData = ABC_ALLOC( Gia_Obj_t *, p->pJust.nSize );
+ p->pClauses.pData = ABC_ALLOC( Gia_Obj_t *, p->pClauses.nSize );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->vModel = Vec_IntAlloc( 1000 );
+ p->vLevReas = Vec_IntAlloc( 1000 );
+ p->vTemp = Vec_PtrAlloc( 1000 );
+ p->pAig = pGia;
+ p->vValue = Vec_IntAlloc( Gia_ManObjNum(pGia) );
+ Vec_IntFill( p->vValue, Gia_ManObjNum(pGia), ~0 );
+ //memset( p->vValue->pArray, (unsigned) ~0, sizeof(int) * Gia_ManObjNum(pGia) );
+ CbsP_SetDefaultParams( &p->Pars );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CbsP_ManStop( CbsP_Man_t * p )
+{
+ Vec_IntFree( p->vLevReas );
+ Vec_IntFree( p->vModel );
+ Vec_PtrFree( p->vTemp );
+ Vec_IntFree( p->vValue );
+ ABC_FREE( p->pClauses.pData );
+ ABC_FREE( p->pProp.pData );
+ ABC_FREE( p->pJust.pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * CbsP_ReadModel( CbsP_Man_t * p )
+{
+ return p->vModel;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the solver is out of limits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+static inline int CbsP_ManCheckPropLimits( CbsP_Man_t * p )
+{
+ return p->Pars.nPropThis > p->Pars.nPropLimit;
+}
+static inline int CbsP_ManCheckLimits( CbsP_Man_t * p )
+{
+ return CbsP_ManCheckPropLimits(p) || p->Pars.nJscanThis > p->Pars.nJscanLimit || p->Pars.nRscanThis > p->Pars.nRscanLimit || 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 CbsP_ManSaveModel( CbsP_Man_t * p, Vec_Int_t * vCex )
+{
+ Gia_Obj_t * pVar;
+ int i;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ CbsP_QueForEachEntry( p->pProp, pVar, i )
+ if ( Gia_ObjIsCi(pVar) )
+ Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !CbsP_VarValue(pVar)) );
+// Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjCioId(pVar), !CbsP_VarValue(pVar)) );
+}
+static inline void CbsP_ManSaveModelAll( CbsP_Man_t * p, Vec_Int_t * vCex )
+{
+ Gia_Obj_t * pVar;
+ int i;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ CbsP_QueForEachEntry( p->pProp, pVar, i )
+ Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !CbsP_VarValue(pVar)) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_QueIsEmpty( CbsP_Que_t * p )
+{
+ return p->iHead == p->iTail;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_QuePush( CbsP_Que_t * p, Gia_Obj_t * pObj )
+{
+ assert( !Gia_IsComplement(pObj) );
+ if ( p->iTail == p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( Gia_Obj_t *, p->pData, p->nSize );
+ }
+ p->pData[p->iTail++] = pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the object in the queue.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_QueHasNode( CbsP_Que_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pTemp;
+ int i;
+ CbsP_QueForEachEntry( *p, pTemp, i )
+ if ( pTemp == pObj )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_QueStore( CbsP_Que_t * p, int * piHeadOld, int * piTailOld )
+{
+ int i;
+ *piHeadOld = p->iHead;
+ *piTailOld = p->iTail;
+ for ( i = *piHeadOld; i < *piTailOld; i++ )
+ CbsP_QuePush( p, p->pData[i] );
+ p->iHead = *piTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_QueRestore( CbsP_Que_t * p, int iHeadOld, int iTailOld )
+{
+ p->iHead = iHeadOld;
+ p->iTail = iTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalized the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_QueFinish( CbsP_Que_t * p )
+{
+ int iHeadOld = p->iHead;
+ assert( p->iHead < p->iTail );
+ CbsP_QuePush( p, NULL );
+ p->iHead = p->iTail;
+ return iHeadOld;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Max number of fanins fanouts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_VarFaninFanoutMax( CbsP_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Count0, Count1;
+ assert( !Gia_IsComplement(pObj) );
+ assert( Gia_ObjIsAnd(pObj) );
+ Count0 = Gia_ObjRefNum( p->pAig, Gia_ObjFanin0(pObj) );
+ Count1 = Gia_ObjRefNum( p->pAig, Gia_ObjFanin1(pObj) );
+ return Abc_MaxInt( Count0, Count1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * CbsP_ManDecideHighest( CbsP_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i;
+ CbsP_QueForEachEntry( p->pJust, pObj, i )
+ if ( pObjMax == NULL || pObjMax < pObj )
+ pObjMax = pObj;
+ return pObjMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the lowest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * CbsP_ManDecideLowest( CbsP_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMin = NULL;
+ int i;
+ CbsP_QueForEachEntry( p->pJust, pObj, i )
+ if ( pObjMin == NULL || pObjMin > pObj )
+ pObjMin = pObj;
+ return pObjMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the maximum number of fanin fanouts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * CbsP_ManDecideMaxFF( CbsP_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i, iMaxFF = 0, iCurFF;
+ assert( p->pAig->pRefs != NULL );
+ CbsP_QueForEachEntry( p->pJust, pObj, i )
+ {
+ iCurFF = CbsP_VarFaninFanoutMax( p, pObj );
+ assert( iCurFF > 0 );
+ if ( iMaxFF < iCurFF )
+ {
+ iMaxFF = iCurFF;
+ pObjMax = pObj;
+ }
+ }
+ return pObjMax;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_ManCancelUntil( CbsP_Man_t * p, int iBound )
+{
+ Gia_Obj_t * pVar;
+ int i;
+ assert( iBound <= p->pProp.iTail );
+ p->pProp.iHead = iBound;
+ CbsP_QueForEachEntry( p->pProp, pVar, i )
+ CbsP_VarUnassign( p, pVar );
+ p->pProp.iTail = iBound;
+ Vec_IntShrink( p->vLevReas, 3*iBound );
+}
+
+//int s_Counter = 0;
+
+/**Function*************************************************************
+
+ Synopsis [Assigns the variables a value.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_ManAssign( CbsP_Man_t * p, Gia_Obj_t * pObj, int Level, Gia_Obj_t * pRes0, Gia_Obj_t * pRes1 )
+{
+ Gia_Obj_t * pObjR = Gia_Regular(pObj);
+ assert( Gia_ObjIsCand(pObjR) );
+ assert( !CbsP_VarIsAssigned(pObjR) );
+ CbsP_VarAssign( pObjR );
+ CbsP_VarSetValue( pObjR, !Gia_IsComplement(pObj) );
+ assert( p->vValue->pArray[Gia_ObjId(p->pAig,pObjR)] == ~0 );
+ p->vValue->pArray[Gia_ObjId(p->pAig,pObjR)] = p->pProp.iTail;
+ CbsP_QuePush( &p->pProp, pObjR );
+ Vec_IntPush( p->vLevReas, Level );
+ Vec_IntPush( p->vLevReas, pRes0 ? pRes0-pObjR : 0 );
+ Vec_IntPush( p->vLevReas, pRes1 ? pRes1-pObjR : 0 );
+ assert( Vec_IntSize(p->vLevReas) == 3 * p->pProp.iTail );
+ if( pRes0 )
+ p->Pars.nPropThis ++ ;
+// s_Counter++;
+// s_Counter = Abc_MaxIntInt( s_Counter, Vec_IntSize(p->vLevReas)/3 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns clause size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_ManClauseSize( CbsP_Man_t * p, int hClause )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t ** pIter;
+ for ( pIter = pQue->pData + hClause; *pIter; pIter++ );
+ return pIter - pQue->pData - hClause ;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_ManPrintClause( CbsP_Man_t * p, int Level, int hClause )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i;
+ assert( CbsP_QueIsEmpty( pQue ) );
+ printf( "Level %2d : ", Level );
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ printf( "%d=%d(%d) ", Gia_ObjId(p->pAig, pObj), CbsP_VarValue(pObj), CbsP_VarDecLevel(p, pObj) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_ManPrintClauseNew( CbsP_Man_t * p, int Level, int hClause )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i;
+ assert( CbsP_QueIsEmpty( pQue ) );
+ printf( "Level %2d : ", Level );
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ printf( "%c%d ", CbsP_VarValue(pObj)? '+':'-', Gia_ObjId(p->pAig, pObj) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void CbsP_ManDeriveReason( CbsP_Man_t * p, int Level )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj, * pReason;
+ int i, k, iLitLevel;
+ assert( pQue->pData[pQue->iHead] == NULL );
+ assert( pQue->iHead + 1 < pQue->iTail );
+/*
+ for ( i = pQue->iHead + 1; i < pQue->iTail; i++ )
+ {
+ pObj = pQue->pData[i];
+ assert( pObj->fMark0 == 1 );
+ }
+*/
+ // compact literals
+ Vec_PtrClear( p->vTemp );
+ for ( i = k = pQue->iHead + 1; i < pQue->iTail; i++ )
+ {
+ pObj = pQue->pData[i];
+ if ( !pObj->fMark0 ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fMark0 = 0;
+ Vec_PtrPush( p->vTemp, pObj );
+ // check decision level
+ iLitLevel = CbsP_VarDecLevel( p, pObj );
+ if ( iLitLevel < Level )
+ {
+ pQue->pData[k++] = pObj;
+ continue;
+ }
+ assert( iLitLevel == Level );
+ pReason = CbsP_VarReason0( p, pObj );
+ if ( pReason == pObj ) // no reason
+ {
+ //assert( pQue->pData[pQue->iHead] == NULL );
+ pQue->pData[pQue->iHead] = pObj;
+ continue;
+ }
+ CbsP_QuePush( pQue, pReason );
+ pReason = CbsP_VarReason1( p, pObj );
+ if ( pReason != pObj ) // second reason
+ CbsP_QuePush( pQue, pReason );
+ }
+ assert( pQue->pData[pQue->iHead] != NULL );
+ pQue->iTail = k;
+ // clear the marks
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i )
+ pObj->fMark0 = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_ManAnalyze( CbsP_Man_t * p, int Level, Gia_Obj_t * pVar, Gia_Obj_t * pFan0, Gia_Obj_t * pFan1 )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ assert( CbsP_VarIsAssigned(pVar) );
+ assert( CbsP_VarIsAssigned(pFan0) );
+ assert( pFan1 == NULL || CbsP_VarIsAssigned(pFan1) );
+ assert( CbsP_QueIsEmpty( pQue ) );
+ CbsP_QuePush( pQue, NULL );
+ CbsP_QuePush( pQue, pVar );
+ CbsP_QuePush( pQue, pFan0 );
+ if ( pFan1 )
+ CbsP_QuePush( pQue, pFan1 );
+ CbsP_ManDeriveReason( p, Level );
+ return CbsP_QueFinish( pQue );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs resolution of two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_ManResolve( CbsP_Man_t * p, int Level, int hClause0, int hClause1 )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i, LevelMax = -1, LevelCur;
+ assert( pQue->pData[hClause0] != NULL );
+ assert( pQue->pData[hClause0] == pQue->pData[hClause1] );
+/*
+ for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ )
+ assert( pObj->fMark0 == 1 );
+ for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ )
+ assert( pObj->fMark0 == 1 );
+*/
+ assert( CbsP_QueIsEmpty( pQue ) );
+ CbsP_QuePush( pQue, NULL );
+ for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ )
+ {
+ if ( !pObj->fMark0 ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fMark0 = 0;
+ CbsP_QuePush( pQue, pObj );
+ p->Pars.nRscanThis ++ ;
+ LevelCur = CbsP_VarDecLevel( p, pObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ )
+ {
+ if ( !pObj->fMark0 ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fMark0 = 0;
+ CbsP_QuePush( pQue, pObj );
+ p->Pars.nRscanThis ++ ;
+ LevelCur = CbsP_VarDecLevel( p, pObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = pQue->iHead + 1; i < pQue->iTail; i++ )
+ pQue->pData[i]->fMark0 = 1;
+ CbsP_ManDeriveReason( p, LevelMax );
+ return CbsP_QueFinish( pQue );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns clause handle if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_ManPropagateOne( CbsP_Man_t * p, Gia_Obj_t * pVar, int Level )
+{
+ int Value0, Value1;
+ assert( !Gia_IsComplement(pVar) );
+ assert( CbsP_VarIsAssigned(pVar) );
+ if ( Gia_ObjIsCi(pVar) )
+ return 0;
+ assert( Gia_ObjIsAnd(pVar) );
+ Value0 = CbsP_VarFanin0Value(pVar);
+ Value1 = CbsP_VarFanin1Value(pVar);
+ if ( CbsP_VarValue(pVar) )
+ { // value is 1
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ {
+ if ( Value0 == 0 && Value1 != 0 )
+ return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), NULL );
+ if ( Value0 != 0 && Value1 == 0 )
+ return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin1(pVar), NULL );
+ assert( Value0 == 0 && Value1 == 0 );
+ return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ }
+ if ( Value0 == 2 ) // first is unassigned
+ CbsP_ManAssign( p, Gia_ObjChild0(pVar), Level, pVar, NULL );
+ if ( Value1 == 2 ) // first is unassigned
+ CbsP_ManAssign( p, Gia_ObjChild1(pVar), Level, pVar, NULL );
+ return 0;
+ }
+ // value is 0
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ return 0;
+ if ( Value0 == 1 && Value1 == 1 ) // both are 1
+ return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ if ( Value0 == 1 || Value1 == 1 ) // one is 1
+ {
+ if ( Value0 == 2 ) // first is unassigned
+ CbsP_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) );
+ if ( Value1 == 2 ) // second is unassigned
+ CbsP_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) );
+ return 0;
+ }
+ assert( CbsP_VarIsJust(pVar) );
+ assert( !CbsP_QueHasNode( &p->pJust, pVar ) );
+ CbsP_QuePush( &p->pJust, pVar );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int CbsP_ManPropagateTwo( CbsP_Man_t * p, Gia_Obj_t * pVar, int Level )
+{
+ int Value0, Value1;
+ assert( !Gia_IsComplement(pVar) );
+ assert( Gia_ObjIsAnd(pVar) );
+ assert( CbsP_VarIsAssigned(pVar) );
+ assert( !CbsP_VarValue(pVar) );
+ Value0 = CbsP_VarFanin0Value(pVar);
+ Value1 = CbsP_VarFanin1Value(pVar);
+ // value is 0
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ return 0;
+ if ( Value0 == 1 && Value1 == 1 ) // both are 1
+ return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ assert( Value0 == 1 || Value1 == 1 );
+ if ( Value0 == 2 ) // first is unassigned
+ CbsP_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) );
+ if ( Value1 == 2 ) // first is unassigned
+ CbsP_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates all variables.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CbsP_ManPropagate( CbsP_Man_t * p, int Level )
+{
+ int hClause;
+ Gia_Obj_t * pVar;
+ int i, k;
+ while ( 1 )
+ {
+ CbsP_QueForEachEntry( p->pProp, pVar, i )
+ {
+ if ( (hClause = CbsP_ManPropagateOne( p, pVar, Level )) )
+ return hClause;
+ if( CbsP_ManCheckPropLimits(p) )
+ return 0;
+ }
+ p->pProp.iHead = p->pProp.iTail;
+ k = p->pJust.iHead;
+ CbsP_QueForEachEntry( p->pJust, pVar, i )
+ {
+ if ( CbsP_VarIsJust( pVar ) )
+ p->pJust.pData[k++] = pVar;
+ else if ( (hClause = CbsP_ManPropagateTwo( p, pVar, Level )) )
+ return hClause;
+ if( CbsP_ManCheckPropLimits(p) )
+ return 0;
+ }
+ if ( k == p->pJust.iTail )
+ break;
+ p->pJust.iTail = k;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solve the problem recursively.]
+
+ Description [Returns learnt clause if unsat, NULL if sat or undecided.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CbsP_ManSolve_rec( CbsP_Man_t * p, int Level )
+{
+ CbsP_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pVar = NULL, * pDecVar;
+ int hClause, hLearn0, hLearn1;
+ int iPropHead, iJustHead, iJustTail;
+ // propagate assignments
+ assert( !CbsP_QueIsEmpty(&p->pProp) );
+ if ( (hClause = CbsP_ManPropagate( p, Level )) )
+ return hClause;
+
+ // quit using resource limits
+ if ( CbsP_ManCheckLimits( p ) )
+ return 0;
+ // check for satisfying assignment
+ assert( CbsP_QueIsEmpty(&p->pProp) );
+ if ( CbsP_QueIsEmpty(&p->pJust) )
+ return 0;
+ p->Pars.nJustThis = Abc_MaxInt( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead );
+ // remember the state before branching
+ iPropHead = p->pProp.iHead;
+ CbsP_QueStore( &p->pJust, &iJustHead, &iJustTail );
+ p->Pars.nJscanThis += iJustTail - iJustHead;
+ if ( CbsP_ManCheckLimits( p ) )
+ return 0;
+ // find the decision variable
+ if ( p->Pars.fUseHighest )
+ pVar = CbsP_ManDecideHighest( p );
+ else if ( p->Pars.fUseLowest )
+ pVar = CbsP_ManDecideLowest( p );
+ else if ( p->Pars.fUseMaxFF )
+ pVar = CbsP_ManDecideMaxFF( p );
+ else assert( 0 );
+ assert( CbsP_VarIsJust( pVar ) );
+ // chose decision variable using fanout count
+
+ if ( Gia_ObjRefNum(p->pAig, Gia_ObjFanin0(pVar)) > Gia_ObjRefNum(p->pAig, Gia_ObjFanin1(pVar)) )
+ pDecVar = Gia_Not(Gia_ObjChild0(pVar));
+ else
+ pDecVar = Gia_Not(Gia_ObjChild1(pVar));
+
+// pDecVar = Gia_NotCond( Gia_Regular(pDecVar), Gia_Regular(pDecVar)->fPhase );
+// pDecVar = Gia_Not(pDecVar);
+ // decide on first fanin
+ CbsP_ManAssign( p, pDecVar, Level+1, NULL, NULL );
+ if ( !(hLearn0 = CbsP_ManSolve_rec( p, Level+1 )) )
+ return 0;
+ if ( CbsP_ManCheckLimits( p ) )
+ return 0;
+ if ( pQue->pData[hLearn0] != Gia_Regular(pDecVar) )
+ return hLearn0;
+ CbsP_ManCancelUntil( p, iPropHead );
+ CbsP_QueRestore( &p->pJust, iJustHead, iJustTail );
+ // decide on second fanin
+ CbsP_ManAssign( p, Gia_Not(pDecVar), Level+1, NULL, NULL );
+ if ( !(hLearn1 = CbsP_ManSolve_rec( p, Level+1 )) )
+ return 0;
+ if ( CbsP_ManCheckLimits( p ) )
+ return 0;
+ if ( pQue->pData[hLearn1] != Gia_Regular(pDecVar) )
+ return hLearn1;
+ hClause = CbsP_ManResolve( p, Level, hLearn0, hLearn1 );
+// CbsP_ManPrintClauseNew( p, Level, hClause );
+// if ( Level > CbsP_ClauseDecLevel(p, hClause) )
+// p->Pars.nBTThisNc++;
+ p->Pars.nBTThis++;
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Looking for a satisfying assignment of the node.]
+
+ Description [Assumes that each node has flag pObj->fMark0 set to 0.
+ Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided.
+ The node may be complemented. ]
+
+ SideEffects [The two procedures differ in the CEX format.]
+
+ SeeAlso []
+
+***********************************************************************/
+int CbsP_ManSolve( CbsP_Man_t * p, Gia_Obj_t * pObj )
+{
+ int RetValue = 0;
+// s_Counter = 0;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
+ CbsP_ManAssign( p, pObj, 0, NULL, NULL );
+ if ( !CbsP_ManSolve_rec(p, 0) && !CbsP_ManCheckLimits(p) )
+ CbsP_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ CbsP_ManCancelUntil( p, 0 );
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( CbsP_ManCheckLimits( p ) )
+ RetValue = -1;
+// printf( "%d ", s_Counter );
+ return RetValue;
+}
+int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 )
+{
+ abctime clk = Abc_Clock();
+ int RetValue = 0;
+// s_Counter = 0;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
+ p->Pars.nJscanThis = p->Pars.nRscanThis = p->Pars.nPropThis = 0;
+ CbsP_ManAssign( p, pObj, 0, NULL, NULL );
+ if ( pObj2 )
+ CbsP_ManAssign( p, pObj2, 0, NULL, NULL );
+ if ( !CbsP_ManSolve_rec(p, 0) && !CbsP_ManCheckLimits(p) )
+ CbsP_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ CbsP_ManCancelUntil( p, 0 );
+
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( CbsP_ManCheckLimits( p ) )
+ RetValue = -1;
+
+ if( CBS_SAT == RetValue ){
+ p->nSatSat ++;
+ p->timeSatSat += Abc_Clock() - clk;
+ p->nConfSat += p->Pars.nBTThis;
+ } else
+ if( CBS_UNSAT == RetValue ){
+ p->nSatUnsat ++;
+ p->timeSatUnsat += Abc_Clock() - clk;
+ p->nConfUnsat += p->Pars.nBTThis;
+ } else {
+ p->nSatUndec ++;
+ p->timeSatUndec += Abc_Clock() - clk;
+ p->nConfUndec += p->Pars.nBTThis;
+ }
+// printf( "%d ", s_Counter );
+ CbsP_UpdateRecord(&p->Pars,RetValue);
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CbsP_ManSatPrintStats( CbsP_Man_t * p )
+{
+ printf( "CO = %8d ", Gia_ManCoNum(p->pAig) );
+ printf( "AND = %8d ", Gia_ManAndNum(p->pAig) );
+ printf( "Conf = %6d ", p->Pars.nBTLimit );
+ printf( "JustMax = %5d ", p->Pars.nJustLimit );
+ printf( "\n" );
+ printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
+ printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
+ printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+ ABC_PRT( "Total time", p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure to test the new SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * CbsP_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 );
+ CbsP_Man_t * p;
+ Vec_Int_t * vCex, * vVisit, * vCexStore;
+ Vec_Str_t * vStatus;
+ Gia_Obj_t * pRoot;
+ int i, status;
+ abctime clk, clkTotal = Abc_Clock();
+ assert( Gia_ManRegNum(pAig) == 0 );
+// Gia_ManCollectTest( pAig );
+ // prepare AIG
+ Gia_ManCreateRefs( pAig );
+ Gia_ManCleanMark0( pAig );
+ Gia_ManCleanMark1( pAig );
+ Gia_ManFillValue( pAig ); // maps nodes into trail ids
+ Gia_ManSetPhase( pAig ); // maps nodes into trail ids
+ // create logic network
+ p = CbsP_ManAlloc( pAig );
+ p->Pars.nBTLimit = nConfs;
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ vVisit = Vec_IntAlloc( 100 );
+ vCex = CbsP_ReadModel( p );
+ // solve for each output
+ Gia_ManForEachCo( pAig, pRoot, i )
+ {
+// printf( "\n" );
+
+ Vec_IntClear( vCex );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) )
+ {
+ if ( Gia_ObjFaninC0(pRoot) )
+ {
+// printf( "Constant 1 output of SRM!!!\n" );
+ Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example
+ Vec_StrPush( vStatus, 0 );
+ }
+ else
+ {
+// printf( "Constant 0 output of SRM!!!\n" );
+ Vec_StrPush( vStatus, 1 );
+ }
+ continue;
+ }
+ clk = Abc_Clock();
+ p->Pars.fUseHighest = 1;
+ p->Pars.fUseLowest = 0;
+ status = CbsP_ManSolve( p, Gia_ObjChild0(pRoot) );
+// printf( "\n" );
+/*
+ if ( status == -1 )
+ {
+ p->Pars.fUseHighest = 0;
+ p->Pars.fUseLowest = 1;
+ status = CbsP_ManSolve( p, Gia_ObjChild0(pRoot) );
+ }
+*/
+ 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 )
+ {
+ if ( f0Proved )
+ Gia_ManPatchCoDriver( pAig, i, 0 );
+ 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 )
+ CbsP_ManSatPrintStats( p );
+// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
+ CbsP_ManStop( p );
+ *pvStatus = vStatus;
+
+// printf( "Total number of cex literals = %d. (Ave = %d)\n",
+// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
+// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat );
+ return vCexStore;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCSatP.h b/src/aig/gia/giaCSatP.h
new file mode 100644
index 00000000..4182cd14
--- /dev/null
+++ b/src/aig/gia/giaCSatP.h
@@ -0,0 +1,117 @@
+#ifndef ABC__aig__gia__giaCSatP_h
+#define ABC__aig__gia__giaCSatP_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "gia.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+typedef struct CbsP_Par_t_ CbsP_Par_t;
+struct CbsP_Par_t_
+{
+ // conflict limits
+ int nBTLimit; // limit on the number of conflicts
+ int nJustLimit; // limit on the size of justification queue
+ // current parameters
+ int nBTThis; // number of conflicts
+ int nBTThisNc; // number of conflicts
+ int nJustThis; // max size of the frontier
+ int nBTTotal; // total number of conflicts
+ int nJustTotal; // total size of the frontier
+ // decision heuristics
+ int fUseHighest; // use node with the highest ID
+ int fUseLowest; // use node with the highest ID
+ int fUseMaxFF; // use node with the largest fanin fanout
+ // other
+ int fVerbose;
+ int fUseProved;
+
+ // statistics
+ int nJscanThis;
+ int nRscanThis;
+ int nPropThis;
+ int maxJscanUndec;
+ int maxRscanUndec;
+ int maxPropUndec;
+ int maxJscanSolved;
+ int maxRscanSolved;
+ int maxPropSolved;
+ int nSat, nUnsat, nUndec;
+ long accJscanSat;
+ long accJscanUnsat;
+ long accJscanUndec;
+ long accRscanSat;
+ long accRscanUnsat;
+ long accRscanUndec;
+ long accPropSat;
+ long accPropUnsat;
+ long accPropUndec;
+
+ // other limits
+ int nJscanLimit;
+ int nRscanLimit;
+ int nPropLimit;
+};
+
+typedef struct CbsP_Que_t_ CbsP_Que_t;
+struct CbsP_Que_t_
+{
+ int iHead; // beginning of the queue
+ int iTail; // end of the queue
+ int nSize; // allocated size
+ Gia_Obj_t ** pData; // nodes stored in the queue
+};
+
+typedef struct CbsP_Man_t_ CbsP_Man_t;
+struct CbsP_Man_t_
+{
+ CbsP_Par_t Pars; // parameters
+ Gia_Man_t * pAig; // AIG manager
+ CbsP_Que_t pProp; // propagation queue
+ CbsP_Que_t pJust; // justification queue
+ CbsP_Que_t pClauses; // clause queue
+ Gia_Obj_t ** pIter; // iterator through clause vars
+ Vec_Int_t * vLevReas; // levels and decisions
+ Vec_Int_t * vValue;
+ Vec_Int_t * vModel; // satisfying assignment
+ Vec_Ptr_t * vTemp; // temporary storage
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ // runtime stats
+ abctime timeSatUnsat; // unsat
+ abctime timeSatSat; // sat
+ abctime timeSatUndec; // undecided
+ abctime timeTotal; // total runtime
+};
+
+CbsP_Man_t * CbsP_ManAlloc( Gia_Man_t * pGia );
+void CbsP_ManStop( CbsP_Man_t * p );
+void CbsP_ManSatPrintStats( CbsP_Man_t * p );
+void CbsP_PrintRecord( CbsP_Par_t * pPars );
+int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
+
+#define CBS_UNSAT 1
+#define CBS_SAT 0
+#define CBS_UNDEC -1
+
+ABC_NAMESPACE_HEADER_END
+
+
+#endif
diff --git a/src/aig/gia/giaCex.c b/src/aig/gia/giaCex.c
index b0e72284..d1241873 100644
--- a/src/aig/gia/giaCex.c
+++ b/src/aig/gia/giaCex.c
@@ -195,7 +195,7 @@ void Gia_ManCounterExampleValueStart( Gia_Man_t * pGia, Abc_Cex_t * pCex )
pGia->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Gia_ManObjNum(pGia) ) );
// the register values in the counter-example should be zero
Gia_ManForEachRo( pGia, pObj, k )
- assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
+ assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
// iterate through the timeframes
nObjs = Gia_ManObjNum(pGia);
for ( i = 0; i <= pCex->iFrame; i++ )
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index b3fcd295..cc501562 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -811,6 +811,55 @@ Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis )
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
}
+Gia_Man_t * Gia_ManDupNoBuf( Gia_Man_t * 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_ManConst0(p)->Value = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+Gia_Man_t * Gia_ManDupMap( Gia_Man_t * p, Vec_Int_t * vMap )
+{
+ 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_ManConst0(p)->Value = 0;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Vec_IntEntry(vMap, i) >= 0 )
+ pObj->Value = Gia_ManObj( p, Vec_IntEntry(vMap, i) )->Value;
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
/**Function*************************************************************
@@ -865,7 +914,9 @@ Gia_Man_t * Gia_ManDupPerm( Gia_Man_t * p, Vec_Int_t * vPiPerm )
// Vec_IntFree( vPiPermInv );
Gia_ManForEachObj1( p, pObj, i )
{
- if ( Gia_ObjIsAnd(pObj) )
+ if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
else if ( Gia_ObjIsCi(pObj) )
{
@@ -1086,6 +1137,23 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo )
Gia_ManSetRegNum( pNew, Gia_ManRegNum(pOne) + Gia_ManRegNum(pTwo) );
return pNew;
}
+void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs )
+{
+ Gia_Obj_t * pObj; int i;
+ assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Vec_IntEntry(vLits, i);
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( fBufs && Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Vec_IntClear( vLits );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
+ assert( Vec_IntSize(vLits) == Gia_ManCoNum(p) );
+}
/**Function*************************************************************
@@ -2934,6 +3002,92 @@ Gia_Man_t * Gia_ManMiter( Gia_Man_t * p0, Gia_Man_t * p1, int nInsDup, int fDual
/**Function*************************************************************
+ Synopsis [Creates miter of two designs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOut, int fVerbose )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, iLit;
+ int nInputs1 = Gia_ManCiNum(pTop) - Gia_ManCoNum(pBot);
+ int nInputs2 = Gia_ManCiNum(pBot) - Gia_ManCoNum(pTop);
+ if ( nInputs1 == nInputs2 )
+ printf( "Assuming that the circuits have %d shared inputs, ordered first.\n", nInputs1 );
+ else
+ {
+ printf( "The number of inputs and outputs does not match.\n" );
+ return NULL;
+ }
+ pNew = Gia_ManStart( Gia_ManObjNum(pBot) + Gia_ManObjNum(pTop) );
+ pNew->pName = Abc_UtilStrsav( "miter" );
+ Gia_ManFillValue( pBot );
+ Gia_ManFillValue( pTop );
+ Gia_ManConst0(pBot)->Value = 0;
+ Gia_ManConst0(pTop)->Value = 0;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCi( pBot, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+// Gia_ManForEachCo( pBot, pObj, i )
+// Gia_ManMiter_rec( pNew, pBot, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachAnd( pBot, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ Gia_ManForEachCo( pBot, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ Gia_ManForEachCi( pTop, pObj, i )
+ if ( i < nInputs1 )
+ pObj->Value = Gia_ManCi(pBot, i)->Value;
+ else
+ pObj->Value = Gia_ManCo(pBot, i-nInputs1)->Value;
+// Gia_ManForEachCo( pTop, pObj, i )
+// Gia_ManMiter_rec( pNew, pTop, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachAnd( pTop, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ Gia_ManForEachCo( pTop, pObj, i )
+ {
+ if ( fDualOut )
+ {
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ManCi(pBot, i+nInputs1)->Value );
+ }
+ else
+ {
+ iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ManCi(pBot, i+nInputs1)->Value );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ }
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ assert( (pBot->vBarBufs == NULL) == (pTop->vBarBufs == NULL) );
+ if ( pBot->vBarBufs )
+ {
+ pNew->vBarBufs = Vec_IntAlloc( 1000 );
+ Vec_IntAppend( pNew->vBarBufs, pBot->vBarBufs );
+ Vec_IntAppend( pNew->vBarBufs, pTop->vBarBufs );
+ //printf( "Miter has %d buffers (%d groups).\n", pNew->nBufs, Vec_IntSize(pNew->vBarBufs) );
+ }
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Computes the AND of all POs.]
Description []
@@ -5067,6 +5221,171 @@ Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManDupUifBoxTypes( Vec_Int_t * vBarBufs )
+{
+ Vec_Int_t * vTypes = Vec_IntAlloc( 10 );
+ int i, Entry;
+ Vec_IntForEachEntry( vBarBufs, Entry, i )
+ if ( Vec_IntFind(vTypes, Entry & 0xFFFE) < 0 )
+ Vec_IntPush( vTypes, Entry & 0xFFFE );
+ return vTypes;
+}
+Vec_Wec_t ** Gia_ManDupUifBuildMap( Gia_Man_t * p )
+{
+ Vec_Int_t * vTypes = Gia_ManDupUifBoxTypes( p->vBarBufs );
+ Vec_Wec_t ** pvMap = ABC_ALLOC( Vec_Wec_t *, 2*Vec_IntSize(vTypes) );
+ Vec_Int_t * vBufs = Vec_IntAlloc( p->nBufs );
+ Gia_Obj_t * pObj; int i, Item, j, k = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ if ( Gia_ObjIsBuf(pObj) )
+ Vec_IntPush( vBufs, i );
+ assert( p->nBufs == Vec_IntSize(vBufs) );
+ for ( i = 0; i < 2*Vec_IntSize(vTypes); i++ )
+ pvMap[i] = Vec_WecAlloc( 10 );
+ Vec_IntForEachEntry( p->vBarBufs, Item, i )
+ {
+ int Type = Vec_IntFind( vTypes, Item & 0xFFFE );
+ Vec_Int_t * vVec = Vec_WecPushLevel(pvMap[2*Type + (Item&1)]);
+ for ( j = 0; j < (Item >> 16); j++ )
+ Vec_IntPush( vVec, Vec_IntEntry(vBufs, k++) );
+ }
+ assert( p->nBufs == k );
+ for ( i = 0; i < Vec_IntSize(vTypes); i++ )
+ assert( Vec_WecSize(pvMap[2*i+0]) == Vec_WecSize(pvMap[2*i+1]) );
+ Vec_IntFree( vTypes );
+ Vec_IntFree( vBufs );
+ return pvMap;
+}
+int Gia_ManDupUifConstrOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vVec0, Vec_Int_t * vVec1 )
+{
+ Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(vVec0) );
+ int i, o0, o1, iRes;
+ Vec_IntForEachEntryTwo( vVec0, vVec1, o0, o1, i )
+ Vec_IntPush( vTemp, Gia_ManHashXor(pNew, Gia_ManObj(p, o0)->Value, Abc_LitNot(Gia_ManObj(p, o1)->Value)) );
+ iRes = Gia_ManHashAndMulti( pNew, vTemp );
+ Vec_IntFree( vTemp );
+ return iRes;
+}
+int Gia_ManDupUifConstr( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t ** pvMap, int nTypes )
+{
+ int t, i, k, iUif = 1;
+ for ( t = 0; t < nTypes; t++ )
+ {
+ assert( Vec_WecSize(pvMap[2*t+0]) == Vec_WecSize(pvMap[2*t+1]) );
+ for ( i = 0; i < Vec_WecSize(pvMap[2*t+0]); i++ )
+ for ( k = i + 1; k < Vec_WecSize(pvMap[2*t+0]); k++ )
+ {
+ int iCond1 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[2*t+0], i), Vec_WecEntry(pvMap[2*t+0], k) );
+ int iCond2 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[2*t+1], i), Vec_WecEntry(pvMap[2*t+1], k) );
+ int iRes = Gia_ManHashOr( pNew, Abc_LitNot(iCond1), iCond2 );
+ iUif = Gia_ManHashAnd( pNew, iUif, iRes );
+ }
+ }
+ return iUif;
+}
+Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p )
+{
+ Vec_Int_t * vTypes = Gia_ManDupUifBoxTypes( p->vBarBufs );
+ Vec_Wec_t ** pvMap = Gia_ManDupUifBuildMap( p );
+ Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj;
+ int i, iUif = 0;
+ 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_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ }
+ iUif = Gia_ManDupUifConstr( pNew, p, pvMap, Vec_IntSize(vTypes) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, pObj->Value, iUif) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ for ( i = 0; i < 2*Vec_IntSize(vTypes); i++ )
+ Vec_WecFree( pvMap[i] );
+ ABC_FREE( pvMap );
+ if ( p->vBarBufs )
+ pNew->vBarBufs = Vec_IntDup( p->vBarBufs );
+ printf( "Added UIF constraints for %d type%s of boxes.\n", Vec_IntSize(vTypes), Vec_IntSize(vTypes) > 1 ? "s" :"" );
+ Vec_IntFree( vTypes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManDupBlackBoxBuildMap( Gia_Man_t * p )
+{
+ Vec_Int_t * vMap = Vec_IntAlloc( p->nBufs ); int i, Item;
+ Vec_IntForEachEntry( p->vBarBufs, Item, i )
+ Vec_IntFillExtra( vMap, Vec_IntSize(vMap) + (Item >> 16), Item & 1 );
+ assert( p->nBufs == Vec_IntSize(vMap) );
+ return vMap;
+}
+Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p )
+{
+ Vec_Int_t * vMap = Gia_ManDupBlackBoxBuildMap( p );
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, k = 0, iCi = 0, nCis = Gia_ManCiNum(p) + Vec_IntSum(vMap);
+ 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 < nCis; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) )
+ {
+ if ( Vec_IntEntry(vMap, k++) ) // out
+ pObj->Value = Gia_ManCiLit(pNew, iCi++);
+ else
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ }
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManCiLit(pNew, iCi++);
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ assert( k == p->nBufs && iCi == nCis );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vMap );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index a40673a7..ec733b85 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -539,7 +539,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars )
Abc_Print( 1, " %s =%8d", p->pMuxes? "nod" : "and", Gia_ManAndNum(p) );
SetConsoleTextAttribute( hConsole, 13 ); // magenta
Abc_Print( 1, " lev =%5d", Gia_ManLevelNum(p) );
- Abc_Print( 1, " (%.2f)", Gia_ManLevelAve(p) );
+ Abc_Print( 1, " (%7.2f)", Gia_ManLevelAve(p) );
SetConsoleTextAttribute( hConsole, 7 ); // normal
}
#else
diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c
index 6cc528f2..f0558cc4 100644
--- a/src/aig/gia/giaMini.c
+++ b/src/aig/gia/giaMini.c
@@ -182,13 +182,56 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc )
SeeAlso []
***********************************************************************/
+void Gia_ManReadMiniAigNames( char * pFileName, Gia_Man_t * pGia )
+{
+ char * filename3 = Abc_UtilStrsavTwo( pFileName, ".ilo" );
+ FILE * pFile = fopen( filename3, "rb" );
+ if ( pFile )
+ {
+ char Buffer[5000], * pName; int i, iLines = 0;
+ Vec_Ptr_t * vTemp = Vec_PtrAlloc( Gia_ManRegNum(pGia) );
+ assert( pGia->vNamesIn == NULL );
+ pGia->vNamesIn = Vec_PtrAlloc( Gia_ManCiNum(pGia) );
+ assert( pGia->vNamesOut == NULL );
+ pGia->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pGia) );
+ while ( fgets(Buffer, 5000, pFile) )
+ {
+ if ( Buffer[strlen(Buffer)-1] == '\n' )
+ Buffer[strlen(Buffer)-1] = 0;
+ if ( iLines < Gia_ManPiNum(pGia) )
+ Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(Buffer) );
+ else if ( iLines < Gia_ManCiNum(pGia) )
+ Vec_PtrPush( vTemp, Abc_UtilStrsav(Buffer) );
+ else
+ Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsav(Buffer) );
+ iLines++;
+ }
+ Vec_PtrForEachEntry( char *, vTemp, pName, i )
+ {
+ Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(pName) );
+ Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsavTwo(pName, "_in") );
+ }
+ Vec_PtrFreeFree( vTemp );
+ fclose( pFile );
+ printf( "Read ILO names into file \"%s\".\n", filename3 );
+ }
+ ABC_FREE( filename3 );
+}
Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple )
{
Mini_Aig_t * p = Mini_AigLoad( pFileName );
- Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
+ Gia_Man_t * pTemp, * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
ABC_FREE( pGia->pName );
pGia->pName = Extra_FileNameGeneric( pFileName );
Mini_AigStop( p );
+ Gia_ManReadMiniAigNames( pFileName, pGia );
+ if ( !Gia_ManIsNormalized(pGia) )
+ {
+ pGia = Gia_ManDupNormalize( pTemp = pGia, 0 );
+ ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesIn, pGia->vNamesIn );
+ ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesOut, pGia->vNamesOut );
+ Gia_ManStop( pTemp );
+ }
return pGia;
}
void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName )
@@ -764,7 +807,10 @@ int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc )
if ( pAbc->pGia2 == NULL )
printf( "Internal GIA with equivalence classes is not available.\n" );
if ( pAbc->pGia2->pReprs == NULL )
+ {
printf( "Equivalence classes of internal GIA are not available.\n" );
+ return NULL;
+ }
if ( Gia_ManObjNum(pAbc->pGia2) != Gia_ManObjNum(pAbc->pGiaMiniAig) )
printf( "Internal GIA with equivalence classes is not directly derived from MiniAig.\n" );
// derive the set of equivalent node pairs
diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c
index 7b3aa54c..ff542c30 100644
--- a/src/aig/gia/giaMuxes.c
+++ b/src/aig/gia/giaMuxes.c
@@ -149,6 +149,73 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit )
/**Function*************************************************************
+ Synopsis [Creates AIG with XORs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew; Gia_Obj_t * pObj, * pFan0, * pFan1;
+ Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) );
+ int i, iLit0, iLit1, nXors = 0, nObjs = 0;
+ Gia_ManForEachObj( p, pObj, i )
+ pObj->fMark0 = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan0)), 1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan1)), 1 );
+ pObj->fMark0 = 1;
+ nXors++;
+ }
+ else
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0(pObj, i), 1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1(pObj, i), 1 );
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ nObjs += Vec_IntEntry(vRefs, i) > 0;
+ pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Gia_ManCoNum(p) + nObjs );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsBuf(pObj) )
+ pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( pObj->fMark0 )
+ {
+ Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1);
+ iLit0 = Abc_LitNotCond( Gia_Regular(pFan0)->Value, Gia_IsComplement(pFan0) );
+ iLit1 = Abc_LitNotCond( Gia_Regular(pFan1)->Value, Gia_IsComplement(pFan1) );
+ pObj->Value = Gia_ManAppendXorReal( pNew, iLit0, iLit1 );
+ }
+ else if ( Vec_IntEntry(vRefs, i) > 0 )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ assert( pNew->nObjs == pNew->nObjsAlloc );
+ pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjs );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Vec_IntFree( vRefs );
+ //printf( "Created %d XORs.\n", nXors );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Derives GIA without MUXes.]
Description []
diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c
index f14ce34a..dff2c59d 100644
--- a/src/aig/gia/giaPat2.c
+++ b/src/aig/gia/giaPat2.c
@@ -346,7 +346,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
else if ( Val0 == 4 && Val1 != 4 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
- else if ( Val1 == 4 && Val1 != 4 )
+ else if ( Val1 == 4 && Val0 != 4 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
else if ( Abc_Random(0) & 1 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
@@ -890,6 +890,8 @@ int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit )
}
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 )
{
+ int fUseSynthesis = 1;
+ abctime clkSim = Abc_Clock(), clkSat = Abc_Clock();
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 );
@@ -945,6 +947,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) );
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) );
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) );
+ clkSim = Abc_Clock() - clkSim;
if ( fUseSat )
Gia_ManForEachCoVec( vOuts, p, pObj, i )
@@ -952,11 +955,13 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
continue;
{
+ abctime clk = Abc_Clock();
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 );
+ Gia_Man_t * pCon1= fUseSynthesis ? Gia_ManAigSyn2( pCon, 0, 1, 0, 100, 0, 0, 0 ) : NULL;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( fUseSynthesis ? pCon1 : 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 );
@@ -972,8 +977,11 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
while ( nAllCalls++ < 100 )
{
int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon);
- sat_solver_randomize( pSat, iVar, nVars );
+ if ( nAllCalls > 1 )
+ sat_solver_randomize( pSat, iVar, nVars );
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
+ if ( status != l_True )
+ break;
assert( status == l_True );
Vec_IntClear( vLits );
for ( v = 0; v < nVars; v++ )
@@ -1004,11 +1012,22 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
sat_solver_delete( pSat );
Cnf_DataFree( pCnf );
Gia_ManStop( pCon );
+ Gia_ManStopP( &pCon1 );
Vec_IntFree( vMap );
+ if ( fVerbose )
+ {
+ printf( "SAT solving for output %3d (cexes = %5d) : ", i, nCurrCexes );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
}
}
+ clkSat = Abc_Clock() - clkSat - clkSim;
if ( fVerbose )
printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Simulation time ", clkSim );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "SAT solving time ", clkSat );
//Vec_WecPrint( vCexes, 0 );
if ( vOuts != vOuts0 )
Vec_IntFreeP( &vOuts );
@@ -1076,7 +1095,7 @@ Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes )
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;
+ //int fVeryVerbose = 0;
Vec_Wrd_t * vSimsPi = NULL;
Vec_Int_t * vLevel;
int w, nBits, nTotal = 0, fFailed = ABC_INFINITY;
@@ -1259,39 +1278,51 @@ Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts,
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 )
+ if ( Vec_IntSum(vStats[2]) == 0 )
{
- printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
- Gia_ManPrintStats( pSwp2, NULL );
- Vec_IntForEachEntry( vOuts, iObj, i )
+ for ( i = 0; i < 3; i++ )
+ Vec_IntFree( vStats[i] );
+ Vec_IntFree( vMap );
+ Gia_ManStop( pSwp2 );
+ Vec_WecFree( vCexes );
+ return NULL;
+ }
+ else
+ {
+ 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( "%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;
+ 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;
}
- 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 )
{
diff --git a/src/aig/gia/giaResub6.c b/src/aig/gia/giaResub6.c
new file mode 100644
index 00000000..3203a699
--- /dev/null
+++ b/src/aig/gia/giaResub6.c
@@ -0,0 +1,451 @@
+/**CFile****************************************************************
+
+ FileName [giaResub6.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Resubstitution.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaResub6.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_NODE 100
+
+typedef struct Res6_Man_t_ Res6_Man_t;
+struct Res6_Man_t_
+{
+ int nIns; // inputs
+ int nDivs; // divisors
+ int nDivsA; // divisors alloc
+ int nOuts; // outputs
+ int nPats; // patterns
+ int nWords; // words
+ Vec_Wrd_t vIns; // input sim data
+ Vec_Wrd_t vOuts; // input sim data
+ word ** ppLits; // literal sim info
+ word ** ppSets; // set sim info
+ Vec_Int_t vSol; // current solution
+ Vec_Int_t vSolBest; // best solution
+ Vec_Int_t vTempBest;// current best solution
+};
+
+extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Res6_Man_t * Res6_ManStart( int nIns, int nNodes, int nOuts, int nPats )
+{
+ Res6_Man_t * p; int i;
+ p = ABC_CALLOC( Res6_Man_t, 1 );
+ p->nIns = nIns;
+ p->nDivs = 1 + nIns + nNodes;
+ p->nDivsA = p->nDivs + MAX_NODE;
+ p->nOuts = nOuts;
+ p->nPats = nPats;
+ p->nWords =(nPats + 63)/64;
+ Vec_WrdFill( &p->vIns, 2*p->nDivsA*p->nWords, 0 );
+ Vec_WrdFill( &p->vOuts, (1 << nOuts)*p->nWords, 0 );
+ p->ppLits = ABC_CALLOC( word *, 2*p->nDivsA );
+ p->ppSets = ABC_CALLOC( word *, 1 << nOuts );
+ for ( i = 0; i < 2*p->nDivsA; i++ )
+ p->ppLits[i] = Vec_WrdEntryP( &p->vIns, i*p->nWords );
+ for ( i = 0; i < (1 << nOuts); i++ )
+ p->ppSets[i] = Vec_WrdEntryP( &p->vOuts, i*p->nWords );
+ Abc_TtFill( p->ppLits[1], p->nWords );
+ Vec_IntGrow( &p->vSol, 2*MAX_NODE+nOuts );
+ Vec_IntGrow( &p->vSolBest, 2*MAX_NODE+nOuts );
+ Vec_IntGrow( &p->vTempBest, 2*MAX_NODE+nOuts );
+ return p;
+}
+static inline void Res6_ManStop( Res6_Man_t * p )
+{
+ Vec_WrdErase( &p->vIns );
+ Vec_WrdErase( &p->vOuts );
+ Vec_IntErase( &p->vSol );
+ Vec_IntErase( &p->vSolBest );
+ Vec_IntErase( &p->vTempBest );
+ ABC_FREE( p->ppLits );
+ ABC_FREE( p->ppSets );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Res6_Man_t * Res6_ManRead( char * pFileName )
+{
+ Res6_Man_t * p = NULL;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ printf( "Cannot open input file \"%s\".\n", pFileName );
+ else
+ {
+ int i, k, nIns, nNodes, nOuts, nPats;
+ char Temp[100], Buffer[100];
+ char * pLine = fgets( Buffer, 100, pFile );
+ if ( pLine == NULL )
+ {
+ printf( "Cannot read the header line of input file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ if ( 5 != sscanf(pLine, "%s %d %d %d %d", Temp, &nIns, &nNodes, &nOuts, &nPats) )
+ {
+ printf( "Cannot read the parameters from the header of input file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ p = Res6_ManStart( nIns, nNodes, nOuts, nPats );
+ pLine = ABC_ALLOC( char, nPats + 100 );
+ for ( i = 1; i < p->nDivs; i++ )
+ {
+ char * pNext = fgets( pLine, nPats + 100, pFile );
+ if ( pNext == NULL )
+ {
+ printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName );
+ Res6_ManStop( p );
+ ABC_FREE( pLine );
+ fclose( pFile );
+ return NULL;
+ }
+ for ( k = 0; k < p->nPats; k++ )
+ if ( pNext[k] == '0' )
+ Abc_TtSetBit( p->ppLits[2*i+1], k );
+ else if ( pNext[k] == '1' )
+ Abc_TtSetBit( p->ppLits[2*i], k );
+ }
+ for ( i = 0; i < (1 << p->nOuts); i++ )
+ {
+ char * pNext = fgets( pLine, nPats + 100, pFile );
+ if ( pNext == NULL )
+ {
+ printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName );
+ Res6_ManStop( p );
+ ABC_FREE( pLine );
+ fclose( pFile );
+ return NULL;
+ }
+ for ( k = 0; k < p->nPats; k++ )
+ if ( pNext[k] == '1' )
+ Abc_TtSetBit( p->ppSets[i], k );
+ }
+ ABC_FREE( pLine );
+ fclose( pFile );
+ }
+ return p;
+}
+void Res6_ManWrite( char * pFileName, Res6_Man_t * p )
+{
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file \"%s\".\n", pFileName );
+ else
+ {
+ int i, k;
+ fprintf( pFile, "resyn %d %d %d %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
+ for ( i = 1; i < p->nDivs; i++, fputc('\n', pFile) )
+ for ( k = 0; k < p->nPats; k++ )
+ if ( Abc_TtGetBit(p->ppLits[2*i+1], k) )
+ fputc( '0', pFile );
+ else if ( Abc_TtGetBit(p->ppLits[2*i], k) )
+ fputc( '1', pFile );
+ else
+ fputc( '-', pFile );
+ for ( i = 0; i < (1 << p->nOuts); i++, fputc('\n', pFile) )
+ for ( k = 0; k < p->nPats; k++ )
+ fputc( '0' + Abc_TtGetBit(p->ppSets[i], k), pFile );
+ fclose( pFile );
+ }
+}
+void Res6_ManPrintProblem( Res6_Man_t * p, int fVerbose )
+{
+ int i, nInputs = (p->nIns && p->nIns < 6) ? p->nIns : 6;
+ printf( "Problem: In = %d Div = %d Out = %d Pattern = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
+ if ( !fVerbose )
+ return;
+ printf( "%02d : %s\n", 0, "const0" );
+ printf( "%02d : %s\n", 1, "const1" );
+ for ( i = 1; i < p->nDivs; i++ )
+ {
+ if ( nInputs < 6 )
+ {
+ *p->ppLits[2*i+0] = Abc_Tt6Stretch( *p->ppLits[2*i+0], nInputs );
+ *p->ppLits[2*i+1] = Abc_Tt6Stretch( *p->ppLits[2*i+1], nInputs );
+ }
+ printf("%02d : ", 2*i+0), Dau_DsdPrintFromTruth2(p->ppLits[2*i+0], nInputs), printf( "\n" );
+ printf("%02d : ", 2*i+1), Dau_DsdPrintFromTruth2(p->ppLits[2*i+1], nInputs), printf( "\n" );
+ }
+ for ( i = 0; i < (1 << p->nOuts); i++ )
+ {
+ if ( nInputs < 6 )
+ *p->ppSets[i] = Abc_Tt6Stretch( *p->ppSets[i], nInputs );
+ printf("%02d : ", i), Dau_DsdPrintFromTruth2(p->ppSets[i], nInputs), printf( "\n" );
+ }
+}
+static inline Vec_Int_t * Res6_ManReadSol( char * pFileName )
+{
+ Vec_Int_t * vRes = NULL; int Num;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ printf( "Cannot open input file \"%s\".\n", pFileName );
+ else
+ {
+ while ( fgetc(pFile) != '\n' );
+ vRes = Vec_IntAlloc( 10 );
+ while ( fscanf(pFile, "%d", &Num) == 1 )
+ Vec_IntPush( vRes, Num );
+ fclose ( pFile );
+ }
+ return vRes;
+}
+static inline void Res6_ManWriteSol( char * pFileName, Vec_Int_t * p )
+{
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file \"%s\".\n", pFileName );
+ else
+ {
+ int i, iLit;
+ Vec_IntForEachEntry( p, iLit, i )
+ fprintf( pFile, "%d ", iLit );
+ fclose ( pFile );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Res6_LitSign( int iLit )
+{
+ return Abc_LitIsCompl(iLit) ? '~' : ' ';
+}
+static inline int Res6_LitChar( int iLit, int nDivs )
+{
+ return Abc_Lit2Var(iLit) < nDivs ? (nDivs < 28 ? 'a'+Abc_Lit2Var(iLit)-1 : 'd') : 'x';
+}
+static inline void Res6_LitPrint( int iLit, int nDivs )
+{
+ if ( iLit < 2 )
+ printf( "%d", iLit );
+ else
+ {
+ printf( "%c%c", Res6_LitSign(iLit), Res6_LitChar(iLit, nDivs) );
+ if ( Abc_Lit2Var(iLit) >= nDivs || nDivs >= 28 )
+ printf( "%d", Abc_Lit2Var(iLit) );
+ }
+}
+Vec_Int_t * Res6_FindSupport( Vec_Int_t * vSol, int nDivs )
+{
+ int i, iLit;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 10 );
+ Vec_IntForEachEntry( vSol, iLit, i )
+ if ( iLit >= 2 && iLit < 2*nDivs )
+ Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
+ return vSupp;
+}
+void Res6_PrintSuppSims( Vec_Int_t * vSol, word ** ppLits, int nWords, int nDivs )
+{
+ Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs );
+ int i, k, iObj;
+ Vec_IntForEachEntry( vSupp, iObj, i )
+ {
+ for ( k = 0; k < 64*nWords; k++ )
+ if ( Abc_TtGetBit(ppLits[2*iObj+1], k) )
+ printf( "0" );
+ else if ( Abc_TtGetBit(ppLits[2*iObj], k) )
+ printf( "1" );
+ else
+ printf( "-" );
+ printf( "\n" );
+ }
+ for ( k = 0; k < 64*nWords; k++ )
+ {
+ Vec_IntForEachEntry( vSupp, iObj, i )
+ if ( Abc_TtGetBit(ppLits[2*iObj+1], k) )
+ printf( "0" );
+ else if ( Abc_TtGetBit(ppLits[2*iObj+0], k) )
+ printf( "1" );
+ else
+ printf( "-" );
+ printf( "\n" );
+ if ( k == 9 )
+ break;
+ }
+ Vec_IntFree( vSupp );
+}
+int Res6_FindSupportSize( Vec_Int_t * vSol, int nDivs )
+{
+ Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs );
+ int Res = Vec_IntSize(vSupp);
+ Vec_IntFree( vSupp );
+ return Res;
+}
+void Res6_PrintSolution( Vec_Int_t * vSol, int nDivs )
+{
+ int iNode, nNodes = Vec_IntSize(vSol)/2-1;
+ assert( Vec_IntSize(vSol) % 2 == 0 );
+ printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", Res6_FindSupportSize(vSol, nDivs), nDivs-1, nNodes, 1 );
+ for ( iNode = 0; iNode <= nNodes; iNode++ )
+ {
+ int * pLits = Vec_IntEntryP( vSol, 2*iNode );
+ printf( "x%-2d = ", nDivs + iNode );
+ Res6_LitPrint( pLits[0], nDivs );
+ if ( pLits[0] != pLits[1] )
+ {
+ printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' );
+ Res6_LitPrint( pLits[1], nDivs );
+ }
+ printf( "\n" );
+ }
+}
+int Res6_FindGetCost( Res6_Man_t * p, int iDiv )
+{
+ int w, Cost = 0;
+ //printf( "DivLit = %d\n", iDiv );
+ //Abc_TtPrintBinary1( stdout, p->ppLits[iDiv], p->nIns ); printf( "\n" );
+ //printf( "Set0\n" );
+ //Abc_TtPrintBinary1( stdout, p->ppSets[0], p->nIns ); printf( "\n" );
+ //printf( "Set1\n" );
+ //Abc_TtPrintBinary1( stdout, p->ppSets[1], p->nIns ); printf( "\n" );
+ for ( w = 0; w < p->nWords; w++ )
+ Cost += Abc_TtCountOnes( (p->ppLits[iDiv][w] & p->ppSets[0][w]) | (p->ppLits[iDiv^1][w] & p->ppSets[1][w]) );
+ return Cost;
+}
+int Res6_FindBestDiv( Res6_Man_t * p, int * pCost )
+{
+ int d, dBest = -1, CostBest = ABC_INFINITY;
+ for ( d = 0; d < 2*p->nDivs; d++ )
+ {
+ int Cost = Res6_FindGetCost( p, d );
+ printf( "Div = %d Cost = %d\n", d, Cost );
+ if ( CostBest >= Cost )
+ CostBest = Cost, dBest = d;
+ }
+ if ( pCost )
+ *pCost = CostBest;
+ return dBest;
+}
+int Res6_FindBestEval( Res6_Man_t * p, Vec_Int_t * vSol, int Start )
+{
+ int i, iLit0, iLit1;
+ assert( Vec_IntSize(vSol) % 2 == 0 );
+ Vec_IntForEachEntryDoubleStart( vSol, iLit0, iLit1, i, 2*Start )
+ {
+ if ( iLit0 > iLit1 )
+ {
+ Abc_TtXor( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
+ Abc_TtXor( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 );
+ }
+ else
+ {
+ Abc_TtAnd( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
+ Abc_TtOr ( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords );
+ }
+
+ //printf( "Node %d\n", i/2 );
+ //Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+0], 6 ); printf( "\n" );
+ //Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+1], 6 ); printf( "\n" );
+ }
+ return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Res6_ManResubVerify( Res6_Man_t * p, Vec_Int_t * vSol )
+{
+ int Cost = Res6_FindBestEval( p, vSol, 0 );
+ if ( Cost == 0 )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats );
+}
+void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose )
+{
+ char FileNameSol[1000];
+ if ( pFileNameSol )
+ strcpy( FileNameSol, pFileNameSol );
+ else
+ {
+ strcpy( FileNameSol, pFileNameRes );
+ strcpy( FileNameSol + strlen(FileNameSol) - strlen(".resub"), ".sol" );
+ }
+ {
+ Res6_Man_t * p = Res6_ManRead( pFileNameRes );
+ Vec_Int_t * vSol = Res6_ManReadSol( FileNameSol );
+ if ( p == NULL || vSol == NULL )
+ return;
+ if ( fVerbose )
+ Res6_ManPrintProblem( p, 0 );
+ if ( fVerbose )
+ Res6_PrintSolution( vSol, p->nDivs );
+ //if ( fVerbose )
+ // Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs );
+ Res6_ManResubVerify( p, vSol );
+ Vec_IntFree( vSol );
+ Res6_ManStop( p );
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSif.c b/src/aig/gia/giaSif.c
new file mode 100644
index 00000000..d25ae5db
--- /dev/null
+++ b/src/aig/gia/giaSif.c
@@ -0,0 +1,257 @@
+/**CFile****************************************************************
+
+ FileName [giaSif.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: giaSif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManCutMerge( int * pCut, int * pCut1, int * pCut2, int nSize )
+{
+ int * pBeg = pCut+1;
+ int * pBeg1 = pCut1+1;
+ int * pBeg2 = pCut2+1;
+ int * pEnd1 = pBeg1 + pCut1[0];
+ int * pEnd2 = pBeg2 + pCut2[0];
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( pBeg == pCut+nSize )
+ {
+ pCut[0] = -1;
+ return;
+ }
+ if ( *pBeg1 == *pBeg2 )
+ *pBeg++ = *pBeg1++, pBeg2++;
+ else if ( *pBeg1 < *pBeg2 )
+ *pBeg++ = *pBeg1++;
+ else
+ *pBeg++ = *pBeg2++;
+ }
+ while ( pBeg1 < pEnd1 )
+ {
+ if ( pBeg == pCut+nSize )
+ {
+ pCut[0] = -1;
+ return;
+ }
+ *pBeg++ = *pBeg1++;
+ }
+ while ( pBeg2 < pEnd2 )
+ {
+ if ( pBeg == pCut+nSize )
+ {
+ pCut[0] = -1;
+ return;
+ }
+ *pBeg++ = *pBeg2++;
+ }
+ pCut[0] = pBeg-(pCut+1);
+ assert( pCut[0] < nSize );
+}
+static inline int Gia_ManCutChoice( Gia_Man_t * p, int Level, int iObj, int iSibl, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
+{
+ int * pCut = Vec_IntEntryP( vCuts, iObj*nSize );
+ int * pCut2 = Vec_IntEntryP( vCuts, iSibl*nSize );
+ int Level2 = Vec_IntEntry( vTimes, iSibl ); int i;
+ assert( iObj > iSibl );
+ if ( Level < Level2 || (Level == Level2 && pCut[0] <= pCut2[0]) )
+ return Level;
+ for ( i = 0; i <= pCut2[0]; i++ )
+ pCut[i] = pCut2[i];
+ return Level2;
+}
+static inline int Gia_ManCutOne( Gia_Man_t * p, int iObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ int iFan0 = Gia_ObjFaninId0(pObj, iObj);
+ int iFan1 = Gia_ObjFaninId1(pObj, iObj);
+ int Cut0[2] = { 1, iFan0 };
+ int Cut1[2] = { 1, iFan1 };
+ int * pCut = Vec_IntEntryP( vCuts, iObj*nSize );
+ int * pCut0 = Vec_IntEntryP( vCuts, iFan0*nSize );
+ int * pCut1 = Vec_IntEntryP( vCuts, iFan1*nSize );
+ int Level_ = Vec_IntEntry( vTimes, iObj );
+ int Level0 = Vec_IntEntry( vTimes, iFan0 );
+ int Level1 = Vec_IntEntry( vTimes, iFan1 );
+ int Level = Abc_MaxInt( Level0, Level1 );
+ if ( Level == 0 )
+ Level = 1;
+ if ( Level0 == Level1 )
+ Gia_ManCutMerge( pCut, pCut0, pCut1, nSize );
+ else if ( Level0 > Level1 )
+ Gia_ManCutMerge( pCut, pCut0, Cut1, nSize );
+ else //if ( Level0 < Level1 )
+ Gia_ManCutMerge( pCut, pCut1, Cut0, nSize );
+ if ( pCut[0] == -1 )
+ {
+ pCut[0] = 2;
+ pCut[1] = iFan0;
+ pCut[2] = iFan1;
+ Level++;
+ }
+ if ( Gia_ObjSibl(p, iObj) )
+ Level = Gia_ManCutChoice( p, Level, iObj, Gia_ObjSibl(p, iObj), vCuts, vTimes, nSize );
+ assert( pCut[0] > 0 && pCut[0] < nSize );
+ Vec_IntUpdateEntry( vTimes, iObj, Level );
+ return Level > Level_;
+}
+int Gia_ManCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period )
+{
+ int i, fChange = 0, nSize = nLutSize+1;
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
+ Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObjRo), Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRi)) - Period );
+ Gia_ManForEachAnd( p, pObj, i )
+ fChange |= Gia_ManCutOne( p, i, vCuts, vTimes, nSize );
+ Gia_ManForEachRi( p, pObj, i )
+ Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) );
+ return fChange;
+}
+int Gia_ManCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters )
+{
+ Gia_Obj_t * pObj; int i;
+ assert( Gia_ManRegNum(p) > 0 );
+ Vec_IntFill( vTimes, Gia_ManObjNum(p), -ABC_INFINITY );
+ Vec_IntWriteEntry( vTimes, 0, 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 );
+ for ( *pIters = 0; *pIters < 100; (*pIters)++ )
+ {
+ if ( !Gia_ManCheckIter(p, vCuts, vTimes, nLutSize, Period) )
+ return 1;
+ Gia_ManForEachPo( p, pObj, i )
+ if ( Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) > Period )
+ return 0;
+ }
+ return 0;
+}
+static inline void Gia_ManPrintCutOne( Gia_Man_t * p, int iObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
+{
+ int i, * pCut = Vec_IntEntryP( vCuts, iObj*nSize );
+ printf( "Obj %4d : Depth %d CutSize %d Cut {", iObj, Vec_IntEntry(vTimes, iObj), pCut[0] );
+ for ( i = 1; i <= pCut[0]; i++ )
+ printf( " %d", pCut[i] );
+ printf( " }\n" );
+}
+int Gia_ManTestMapComb( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize )
+{
+ Gia_Obj_t * pObj; int i, Id, Res = 0, nSize = nLutSize+1;
+ Vec_IntFill( vTimes, Gia_ManObjNum(p), 0 );
+ Gia_ManForEachCiId( p, Id, i )
+ Vec_IntWriteEntry( vCuts, Id*nSize, 1 );
+ Gia_ManForEachCiId( p, Id, i )
+ Vec_IntWriteEntry( vCuts, Id*nSize+1, Id );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ManCutOne( p, i, vCuts, vTimes, nSize );
+ Gia_ManForEachCo( p, pObj, i )
+ Res = Abc_MaxInt( Res, Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) );
+ //Gia_ManForEachAnd( p, pObj, i )
+ // Gia_ManPrintCutOne( p, i, vCuts, vTimes, nSize );
+ return Res;
+}
+void Gia_ManPrintTimes( Gia_Man_t * p, Vec_Int_t * vTimes, int Period )
+{
+ int Pos[16] = {0};
+ int Neg[16] = {0};
+ Gia_Obj_t * pObj; int i;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ int Time = Vec_IntEntry(vTimes, i)-Period;
+ Time = Abc_MinInt( Time, 10*Period );
+ Time = Abc_MaxInt( Time, -10*Period );
+ if ( Time >= 0 )
+ Pos[(Time + Period-1)/Period]++;
+ else
+ Neg[(-Time + Period-1)/Period]++;
+ }
+ printf( "Statistics: " );
+ for ( i = 15; i > 0; i-- )
+ if ( Neg[i] )
+ printf( " -%d=%d", i, Neg[i] );
+ for ( i = 0; i < 16; i++ )
+ if ( Pos[i] )
+ printf( " %d=%d", i, Pos[i] );
+ printf( "\n" );
+}
+Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose )
+{
+ int nIters, nSize = nLutSize+1; // (2+1+nSize)*4=40 bytes/node
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vCuts = Vec_IntStart( Gia_ManObjNum(p) * nSize );
+ Vec_Int_t * vTimes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ int Lower = 0;
+ int Upper = Gia_ManTestMapComb( p, vCuts, vTimes, nLutSize );
+ if ( fVerbose && Gia_ManRegNum(p) )
+ printf( "Clock period %2d is %s\n", Lower, 0 ? "Yes" : "No " );
+ if ( fVerbose && Gia_ManRegNum(p) )
+ printf( "Clock period %2d is %s\n", Upper, 1 ? "Yes" : "No " );
+ while ( Gia_ManRegNum(p) > 0 && Upper - Lower > 1 )
+ {
+ int Middle = (Upper + Lower) / 2;
+ int Status = Gia_ManCheckPeriod( p, vCuts, vTimes, nLutSize, Middle, &nIters );
+ if ( Status )
+ Upper = Middle;
+ else
+ Lower = Middle;
+ if ( fVerbose )
+ printf( "Clock period %2d is %s after %d iterations\n", Middle, Status ? "Yes" : "No ", nIters );
+ }
+ if ( fVerbose )
+ printf( "Clock period = %2d ", Upper );
+ if ( fVerbose )
+ printf( "LUT size = %d ", nLutSize );
+ if ( fVerbose )
+ printf( "Memory usage = %.2f MB ", 4.0*(2+1+nSize)*Gia_ManObjNum(p)/(1 << 20) );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ //Gia_ManCheckPeriod( p, vCuts, vTimes, nLutSize, Upper, &nIters );
+ //Gia_ManPrintTimes( p, vTimes, Upper );
+ Vec_IntFree( vCuts );
+ Vec_IntFree( vTimes );
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c
index c31064fe..002f6bc2 100644
--- a/src/aig/gia/giaSimBase.c
+++ b/src/aig/gia/giaSimBase.c
@@ -750,7 +750,7 @@ void Gia_ManSimProfile( Gia_Man_t * pGia )
Vec_Wrd_t * vSims = Gia_ManSimPatSim( pGia );
int nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia);
int nC0s = 0, nC1s = 0, nUnique = Gia_ManSimPatHashPatterns( pGia, nWords, vSims, &nC0s, &nC1s );
- printf( "Simulating %d patterns leads to %d unique objects (%.2f %% out of %d), Const0 = %d. Const1 = %d.\n",
+ printf( "Simulating %d patterns leads to %d unique objects (%.2f %% out of %d). Const0 = %d. Const1 = %d.\n",
64*nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pGia), Gia_ManCandNum(pGia), nC0s, nC1s );
Vec_WrdFree( vSims );
}
@@ -2485,15 +2485,21 @@ void Gia_ManSimGen( Gia_Man_t * pGia )
SeeAlso []
***********************************************************************/
-int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose )
+int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int TimeLimit, int fVerbose )
{
Vec_Wrd_t * vSim0, * vSim1, * vSim2;
abctime clk = Abc_Clock();
int n, i, RetValue = 1;
+ int TimeStop = TimeLimit ? TimeLimit * CLOCKS_PER_SEC + Abc_Clock() : 0; // in CPU ticks
printf( "Simulating %d round with %d machine words.\n", nRounds, nWords );
Abc_RandomW(0);
for ( n = 0; RetValue && n < nRounds; n++ )
{
+ if ( TimeStop && Abc_Clock() > TimeStop )
+ {
+ printf( "Computation timed out after %d seconds and %d rounds.\n", TimeLimit, n );
+ break;
+ }
vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(p0) * nWords );
p0->vSimsPi = vSim0;
p1->vSimsPi = vSim0;
@@ -2700,6 +2706,77 @@ Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose )
return p;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCompareSims( Gia_Man_t * pHie, Gia_Man_t * pFlat, int nWords, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSims = pFlat->vSimsPi = pHie->vSimsPi = Vec_WrdStartRandom( Gia_ManCiNum(pFlat) * nWords );
+ Vec_Wrd_t * vSims0 = Gia_ManSimPatSim( pFlat );
+ Vec_Wrd_t * vSims1 = Gia_ManSimPatSim( pHie );
+ Gia_Obj_t * pObj; int * pSpot, * pSpot2, i, nC0s = 0, nC1s = 0, nUnique = 0, nFound[3] = {0}, nBoundary = 0, nMatched = 0;
+ Vec_Mem_t * vStore = Vec_MemAlloc( nWords, 12 ); // 2^12 N-word entries per page
+ pFlat->vSimsPi = NULL;
+ pHie->vSimsPi = NULL;
+ Vec_WrdFree( vSims );
+
+ printf( "Comparing two AIGs using %d simulation words.\n", nWords );
+ printf( "Hierarchical: " ); Gia_ManPrintStats( pHie, NULL );
+ printf( "Flat: " ); Gia_ManPrintStats( pFlat, NULL );
+
+ Vec_MemHashAlloc( vStore, 1 << 12 );
+ Gia_ManForEachCand( pFlat, pObj, i )
+ {
+ word * pSim = Vec_WrdEntryP(vSims0, i*nWords);
+ nC0s += Abc_TtIsConst0(pSim, nWords);
+ nC1s += Abc_TtIsConst1(pSim, nWords);
+ Vec_MemHashInsert( vStore, pSim );
+ }
+ nUnique = Vec_MemEntryNum( vStore );
+ printf( "Simulating %d patterns through the second (flat) AIG leads to %d unique objects (%.2f %% out of %d). Const0 = %d. Const1 = %d.\n",
+ 64*nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pFlat), Gia_ManCandNum(pFlat), nC0s, nC1s );
+
+ assert( Gia_ManCiNum(pFlat) == Gia_ManCiNum(pHie) );
+ Gia_ManForEachCand( pHie, pObj, i )
+ {
+ word * pSim = Vec_WrdEntryP(vSims1, i*nWords);
+ pSpot = Vec_MemHashLookup( vStore, pSim );
+ Abc_TtNot( pSim, nWords );
+ pSpot2 = Vec_MemHashLookup( vStore, pSim );
+ Abc_TtNot( pSim, nWords );
+ nBoundary += Gia_ObjIsBuf(pObj);
+ if ( *pSpot != -1 || *pSpot2 != -1 )
+ {
+ nMatched++;
+ continue;
+ }
+ //Extra_PrintBinary( stdout, (unsigned *)pSim, 64*nWords ); printf("\n");
+ nFound[1] += Gia_ObjIsBuf(pObj);
+ nFound[2]++;
+ //if ( Gia_ObjIsBuf(pObj) )
+ // printf( "%d(%d) ", i, nBoundary-1 );
+ }
+ Vec_MemHashFree( vStore );
+ Vec_MemFree( vStore );
+ Vec_WrdFree( vSims0 );
+ Vec_WrdFree( vSims1 );
+
+ printf( "The first (hierarchical) AIG has %d (%.2f %%) matches, %d (%.2f %%) mismatches, including %d (%.2f %%) on the boundary. ",
+ nMatched, 100.0*nMatched /Abc_MaxInt(1, Gia_ManCandNum(pHie)),
+ nFound[2], 100.0*nFound[2]/Abc_MaxInt(1, Gia_ManCandNum(pHie)),
+ nFound[1], 100.0*nFound[1]/Abc_MaxInt(1, nBoundary) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c
index f95d815d..96721d66 100644
--- a/src/aig/gia/giaSupps.c
+++ b/src/aig/gia/giaSupps.c
@@ -46,6 +46,7 @@ struct Supp_Man_t_
Gia_Man_t * pGia; // used for object names
// computed data
Vec_Wrd_t * vDivs[2]; // simulation values
+ Vec_Wrd_t * vDivsC[2]; // simulation values
Vec_Wrd_t * vPats[2]; // simulation values
Vec_Ptr_t * vMatrix; // simulation values
Vec_Wrd_t * vMask; // simulation values
@@ -138,13 +139,15 @@ int Supp_DeriveLines( Supp_Man_t * p )
{
int n, i, iObj, nWords = p->nWords;
int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) );
+ //Vec_IntPrint( p->vCands );
for ( n = 0; n < 2; n++ )
{
p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords );
p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords );
+ //p->vDivsC[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 );
+ Abc_TtAndSharp( Vec_WrdEntryP(p->vDivsC[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 );
@@ -194,6 +197,8 @@ void Supp_ManDelete( Supp_Man_t * p )
Supp_ManCleanMatrix( p );
Vec_WrdFreeP( &p->vDivs[0] );
Vec_WrdFreeP( &p->vDivs[1] );
+ Vec_WrdFreeP( &p->vDivsC[0] );
+ Vec_WrdFreeP( &p->vDivsC[1] );
Vec_WrdFreeP( &p->vPats[0] );
Vec_WrdFreeP( &p->vPats[1] );
Vec_PtrFreeP( &p->vMatrix );
@@ -656,6 +661,110 @@ int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose )
return Supp_ManRandomSolution( p, iSet, fVerbose );
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int s_Counter = 0;
+
+void Supp_DeriveDumpSims( FILE * pFile, Vec_Wrd_t * vDivs, int nWords )
+{
+ int i, k, nDivs = Vec_WrdSize(vDivs)/nWords;
+ for ( i = 0; i < nDivs; i++ )
+ {
+ word * pSim = Vec_WrdEntryP(vDivs, i*nWords);
+ for ( k = 0; k < 64*nWords; k++ )
+ fprintf( pFile, "%c", '0'+Abc_TtGetBit(pSim, k) );
+ fprintf( pFile, "\n" );
+ }
+}
+void Supp_DeriveDumpSimsC( FILE * pFile, Vec_Wrd_t * vDivs[2], int nWords )
+{
+ int i, k, nDivs = Vec_WrdSize(vDivs[0])/nWords;
+ for ( i = 0; i < nDivs; i++ )
+ {
+ word * pSim0 = Vec_WrdEntryP(vDivs[0], i*nWords);
+ word * pSim1 = Vec_WrdEntryP(vDivs[1], i*nWords);
+ for ( k = 0; k < 64*nWords; k++ )
+ if ( Abc_TtGetBit(pSim0, k) )
+ fprintf( pFile, "0" );
+ else if ( Abc_TtGetBit(pSim1, k) )
+ fprintf( pFile, "1" );
+ else
+ fprintf( pFile, "-" );
+ fprintf( pFile, "\n" );
+ }
+}
+void Supp_DeriveDumpProb( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords )
+{
+ char Buffer[100]; int nDivs = Vec_WrdSize(vDivs)/nWords;
+ int RetValue = sprintf( Buffer, "%02d.resub", s_Counter );
+ FILE * pFile = fopen( Buffer, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file.\n" );
+ fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
+ //fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords );
+ Supp_DeriveDumpSims( pFile, vDivs, nWords );
+ Supp_DeriveDumpSims( pFile, vIsfs, nWords );
+ fclose ( pFile );
+ RetValue = 0;
+}
+void Supp_DeriveDumpProbC( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs[2], int nWords )
+{
+ char Buffer[100]; int nDivs = Vec_WrdSize(vDivs[0])/nWords;
+ int RetValue = sprintf( Buffer, "%02d.resub", s_Counter );
+ FILE * pFile = fopen( Buffer, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file.\n" );
+ fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
+ //fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords );
+ Supp_DeriveDumpSimsC( pFile, vDivs, nWords );
+ Supp_DeriveDumpSims( pFile, vIsfs, nWords );
+ fclose ( pFile );
+ RetValue = 0;
+}
+void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs )
+{
+ char Buffer[100];
+ int RetValue = sprintf( Buffer, "%02d.sol", s_Counter );
+ int i, iLit, iLitRes = -1, nSupp = Vec_IntSize(vSet);
+ FILE * pFile = fopen( Buffer, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file.\n" );
+ fprintf( pFile, "sol name aig %d\n", Vec_IntSize(vRes)/2 );
+ //Vec_IntPrint( vSet );
+ //Vec_IntPrint( vRes );
+ Vec_IntForEachEntry( vRes, iLit, i )
+ {
+ assert( iLit != 2 && iLit != 3 );
+ if ( iLit < 2 )
+ iLitRes = iLit;
+ else if ( iLit-4 < 2*nSupp )
+ {
+ int iDiv = Vec_IntEntry(vSet, Abc_Lit2Var(iLit-4));
+ assert( iDiv >= 0 && iDiv < nDivs );
+ iLitRes = Abc_Var2Lit(1+iDiv, Abc_LitIsCompl(iLit));
+ }
+ else
+ iLitRes = iLit + 2*((nDivs+1)-(nSupp+2));
+ fprintf( pFile, "%d ", iLitRes );
+ }
+ if ( Vec_IntSize(vRes) & 1 )
+ fprintf( pFile, "%d ", iLitRes );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+ RetValue = 0;
+ printf( "Dumped solution info file \"%s\".\n", Buffer );
+}
+
/**Function*************************************************************
Synopsis []
@@ -705,6 +814,10 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
Vec_IntForEachEntry( vSet, iObj, i )
Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
}
+ //Supp_DeriveDumpProbC( p->vIsfs, p->vDivsC, p->nWords );
+ //Supp_DeriveDumpProb( p->vIsfs, p->vDivs[1], p->nWords );
+ //Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords );
+ //s_Counter++;
}
return vRes;
}
@@ -802,11 +915,38 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
Supp_PrintOne( p, iBest );
}
vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs );
+ //Vec_IntPrint( vRes );
Supp_ManDelete( p );
// if ( vRes && Vec_IntSize(vRes) == 0 )
// Vec_IntFreeP( &vRes );
return vRes;
}
+void Supp_ManComputeTest( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsPi, 0 );
+ int i, iPoId, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p);
+ Vec_Wrd_t * vIsfs = Vec_WrdStart( 2*nWords );
+ Vec_Int_t * vCands = Vec_IntAlloc( 4 );
+ Vec_Int_t * vRes;
+
+// for ( i = 0; i < Gia_ManCiNum(p)+5; i++ )
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( vCands, 1+i );
+
+ iPoId = Gia_ObjId(p, Gia_ManPo(p, 0));
+ Abc_TtCopy( Vec_WrdEntryP(vIsfs, 0*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 1 );
+ Abc_TtCopy( Vec_WrdEntryP(vIsfs, 1*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 0 );
+
+ vRes = Supp_ManCompute( vIsfs, vCands, NULL, vSims, NULL, nWords, p, NULL, 1, 1, 0 );
+ Vec_IntPrint( vRes );
+
+ Vec_WrdFree( vSimsPi );
+ Vec_WrdFree( vSims );
+ Vec_WrdFree( vIsfs );
+ Vec_IntFree( vCands );
+ Vec_IntFree( vRes );
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c
index b1c5eb82..4722ef0f 100644
--- a/src/aig/gia/giaSwitch.c
+++ b/src/aig/gia/giaSwitch.c
@@ -795,6 +795,14 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO
Gia_ManForEachAnd( p, pObj, i )
SwiTotal += pSwi[Gia_ObjFaninId0(pObj, i)] + pSwi[Gia_ObjFaninId1(pObj, i)];
}
+ if ( 0 )
+ {
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ printf( "Switch %6.2f ", pSwi[i] );
+ Gia_ObjPrint( p, pObj );
+ }
+ }
Vec_IntFree( vSwitching );
return SwiTotal;
}
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index 431be5b7..d8130550 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -3080,7 +3080,55 @@ Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p )
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
return NULL;
}
-
+void Gia_ManWriteSol( Gia_Man_t * p, char * pFileName )
+{
+ char * pBasicName = Extra_FileNameGeneric( pFileName );
+ char * pFileName2 = Abc_UtilStrsavTwo( pBasicName, ".sol" );
+ FILE * pFile = fopen( pFileName2, "wb" );
+ ABC_FREE( pBasicName );
+ if ( pFile == NULL )
+ printf( "Cannot open output file \"%s\".\n", pFileName2 );
+ else
+ {
+ Gia_Obj_t * pObj; int i;
+ Gia_ManForEachAnd( p, pObj, i )
+ fprintf( pFile, "%d %d ", Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ fprintf( pFile, "%d %d ", Gia_ObjFaninLit0p(p, pObj), Gia_ObjFaninLit0p(p, pObj) );
+ fclose( pFile );
+ printf( "Finished writing solution file \"%s\".\n", pFileName2 );
+ }
+ ABC_FREE( pFileName2 );
+}
+void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName )
+{
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open output file \"%s\".\n", pFileName );
+ else
+ {
+ Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
+ int i, k, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p);
+ word * pTemp = ABC_ALLOC( word, nWords );
+ fprintf( pFile, "%d %d %d %d\n", Gia_ManCiNum(p), 0, Gia_ManCoNum(p), 1 << Gia_ManCiNum(p) );
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Abc_TtPrintBinary1( pFile, Vec_WrdEntryP(vSimsPi, i*nWords), Gia_ManCiNum(p) ), fprintf(pFile, "\n");
+ for ( i = 0; i < (1 << Gia_ManCoNum(p)); i++ )
+ {
+ Abc_TtFill( pTemp, nWords );
+ for ( k = 0; k < Gia_ManCoNum(p); k++ )
+ Abc_TtAndCompl( pTemp, pTemp, 0, Vec_WrdEntryP(vSimsPo, k*nWords), !((i>>k)&1), nWords );
+ Abc_TtPrintBinary1( pFile, pTemp, Gia_ManCiNum(p) ), fprintf(pFile, "\n");
+ }
+ ABC_FREE( pTemp );
+ fclose( pFile );
+ Vec_WrdFree( vSimsPi );
+ Vec_WrdFree( vSimsPo );
+ printf( "Finished writing resub file \"%s\".\n", pFileName );
+ Gia_ManWriteSol( p, pFileName );
+ }
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index d801a243..171d8be3 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -15,6 +15,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaCSat.c \
src/aig/gia/giaCSat2.c \
src/aig/gia/giaCSat3.c \
+ src/aig/gia/giaCSatP.c \
src/aig/gia/giaCTas.c \
src/aig/gia/giaCut.c \
src/aig/gia/giaDecs.c \
@@ -68,6 +69,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaResub.c \
src/aig/gia/giaResub2.c \
src/aig/gia/giaResub3.c \
+ src/aig/gia/giaResub6.c \
src/aig/gia/giaRetime.c \
src/aig/gia/giaRex.c \
src/aig/gia/giaSatEdge.c \
@@ -82,6 +84,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaShrink.c \
src/aig/gia/giaShrink6.c \
src/aig/gia/giaShrink7.c \
+ src/aig/gia/giaSif.c \
src/aig/gia/giaSim.c \
src/aig/gia/giaSim2.c \
src/aig/gia/giaSimBase.c \
diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c
index 1d1dcbe2..c1eceef0 100644
--- a/src/aig/ioa/ioaReadAig.c
+++ b/src/aig/ioa/ioaReadAig.c
@@ -438,7 +438,7 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck )
// read the file into the buffer
nFileSize = Ioa_FileSize( pFileName );
pFile = fopen( pFileName, "rb" );
- pContents = ABC_ALLOC( char, nFileSize );
+ pContents = ABC_CALLOC( char, nFileSize+1 );
RetValue = fread( pContents, nFileSize, 1, pFile );
fclose( pFile );
diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h
index c3d6e176..cbe2a0f3 100644
--- a/src/aig/miniaig/abcOper.h
+++ b/src/aig/miniaig/abcOper.h
@@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )
if ( Type == ABC_OPER_ZEROPAD ) return "zPad";
if ( Type == ABC_OPER_SIGNEXT ) return "sExt";
+ if ( Type == ABC_OPER_BIT_MUX ) return "mux";
+ if ( Type == ABC_OPER_SEL_NMUX ) return "nmux";
+ if ( Type == ABC_OPER_SEL_SEL ) return "pmux";
+
if ( Type == ABC_OPER_CONST ) return "const";
if ( Type == ABC_OPER_TABLE ) return "table";
if ( Type == ABC_OPER_LUT ) return "lut";
diff --git a/src/aig/miniaig/miniaig.h b/src/aig/miniaig/miniaig.h
index 12061144..0365b946 100644
--- a/src/aig/miniaig/miniaig.h
+++ b/src/aig/miniaig/miniaig.h
@@ -30,7 +30,9 @@
#include <string.h>
#include <assert.h>
+#ifndef _VERIFIC_DATABASE_H_
ABC_NAMESPACE_HEADER_START
+#endif
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
@@ -92,13 +94,13 @@ static void Mini_AigPush( Mini_Aig_t * p, int Lit0, int Lit1 )
static int Mini_AigNodeFanin0( Mini_Aig_t * p, int Id )
{
assert( Id >= 0 && 2*Id < p->nSize );
- assert( p->pArray[2*Id] == 0x7FFFFFFF || p->pArray[2*Id] < 2*Id );
+ assert( p->pArray[2*Id] == MINI_AIG_NULL || p->pArray[2*Id] < 2*Id );
return p->pArray[2*Id];
}
static int Mini_AigNodeFanin1( Mini_Aig_t * p, int Id )
{
assert( Id >= 0 && 2*Id < p->nSize );
- assert( p->pArray[2*Id+1] == 0x7FFFFFFF || p->pArray[2*Id+1] < 2*Id );
+ assert( p->pArray[2*Id+1] == MINI_AIG_NULL || p->pArray[2*Id+1] < 2*Id );
return p->pArray[2*Id+1];
}
@@ -170,7 +172,7 @@ static int Mini_AigAndNum( Mini_Aig_t * p )
}
static void Mini_AigPrintStats( Mini_Aig_t * p )
{
- printf( "PI = %d. PO = %d. Node = %d.\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigAndNum(p) );
+ printf( "MiniAIG stats: PI = %d PO = %d FF = %d AND = %d\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigRegNum(p), Mini_AigAndNum(p) );
}
// serialization
@@ -233,7 +235,10 @@ static int Mini_AigAnd( Mini_Aig_t * p, int Lit0, int Lit1 )
int Lit = p->nSize;
assert( Lit0 >= 0 && Lit0 < Lit );
assert( Lit1 >= 0 && Lit1 < Lit );
- Mini_AigPush( p, Lit0, Lit1 );
+ if ( Lit0 < Lit1 )
+ Mini_AigPush( p, Lit0, Lit1 );
+ else
+ Mini_AigPush( p, Lit1, Lit0 );
return Lit;
}
static int Mini_AigOr( Mini_Aig_t * p, int Lit0, int Lit1 )
@@ -250,6 +255,61 @@ static int Mini_AigXor( Mini_Aig_t * p, int Lit0, int Lit1 )
{
return Mini_AigMux( p, Lit0, Mini_AigLitNot(Lit1), Lit1 );
}
+static int Mini_AigXorSpecial( Mini_Aig_t * p, int Lit0, int Lit1 )
+{
+ int Lit = p->nSize;
+ assert( Lit0 >= 0 && Lit0 < Lit );
+ assert( Lit1 >= 0 && Lit1 < Lit );
+ if ( Lit0 > Lit1 )
+ Mini_AigPush( p, Lit0, Lit1 );
+ else
+ Mini_AigPush( p, Lit1, Lit0 );
+ return Lit;
+}
+static int Mini_AigAndMulti( Mini_Aig_t * p, int * pLits, int nLits )
+{
+ int i;
+ assert( nLits > 0 );
+ while ( nLits > 1 )
+ {
+ for ( i = 0; i < nLits/2; i++ )
+ pLits[i] = Mini_AigAnd(p, pLits[2*i], pLits[2*i+1]);
+ if ( nLits & 1 )
+ pLits[i++] = pLits[nLits-1];
+ nLits = i;
+ }
+ return pLits[0];
+}
+static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int nCtrl, int * pData, int nData )
+{
+ int i, c;
+ assert( nData > 0 );
+ if ( nCtrl == 0 )
+ return pData[0];
+ assert( nData <= (1 << nCtrl) );
+ for ( c = 0; c < nCtrl; c++ )
+ {
+ for ( i = 0; i < nData/2; i++ )
+ pData[i] = Mini_AigMux( p, pCtrl[c], pData[2*i+1], pData[2*i] );
+ if ( nData & 1 )
+ pData[i++] = Mini_AigMux( p, pCtrl[c], 0, pData[nData-1] );
+ nData = i;
+ }
+ assert( nData == 1 );
+ return pData[0];
+}
+static int Mini_AigMuxMulti_rec( Mini_Aig_t * p, int * pCtrl, int * pData, int nData )
+{
+ int Res0, Res1;
+ assert( nData > 0 );
+ if ( nData == 1 )
+ return pData[0];
+ assert( nData % 2 == 0 );
+ Res0 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData, nData/2 );
+ Res1 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData+nData/2, nData/2 );
+ return Mini_AigMux( p, pCtrl[0], Res1, Res0 );
+}
+
static unsigned s_MiniTruths5[5] = {
0xAAAAAAAA,
@@ -308,6 +368,20 @@ static inline int Mini_AigTruth( Mini_Aig_t * p, int * pVarLits, int nVars, unsi
Lit1 = Mini_AigTruth( p, pVarLits, Var, Mini_AigTt5Cofactor1(Truth, Var) );
return Mini_AigMuxProp( p, pVarLits[Var], Lit1, Lit0 );
}
+static char * Mini_AigPhase( Mini_Aig_t * p )
+{
+ char * pRes = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) );
+ int i;
+ Mini_AigForEachAnd( p, i )
+ {
+ int iFaninLit0 = Mini_AigNodeFanin0( p, i );
+ int iFaninLit1 = Mini_AigNodeFanin1( p, i );
+ int Phase0 = pRes[Mini_AigLit2Var(iFaninLit0)] ^ Mini_AigLitIsCompl(iFaninLit0);
+ int Phase1 = pRes[Mini_AigLit2Var(iFaninLit1)] ^ Mini_AigLitIsCompl(iFaninLit1);
+ pRes[i] = Phase0 & Phase1;
+ }
+ return pRes;
+}
// procedure to check the topological order during AIG construction
static int Mini_AigCheck( Mini_Aig_t * p )
@@ -340,11 +414,11 @@ static int Mini_AigCheck( Mini_Aig_t * p )
static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_t * p )
{
int i, k, iFaninLit0, iFaninLit1, Length = strlen(pModuleName), nPos = Mini_AigPoNum(p);
- Vec_Bit_t * vObjIsPi = Vec_BitStart( Mini_AigNodeNum(p) );
+ char * pObjIsPi = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) );
FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); return; }
+ if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); MINI_AIG_FREE( pObjIsPi ); return; }
// write interface
- fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() );
+ //fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() );
fprintf( pFile, "module %s (\n", pModuleName );
if ( Mini_AigPiNum(p) > 0 )
{
@@ -354,7 +428,7 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
{
if ( k++ % 12 == 0 ) fprintf( pFile, "\n%*s", Length+10, "" );
fprintf( pFile, "i%d, ", i );
- Vec_BitWriteEntry( vObjIsPi, i, 1 );
+ pObjIsPi[i] = 1;
}
}
fprintf( pFile, "\n%*soutput wire", Length+10, "" );
@@ -371,9 +445,9 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
iFaninLit0 = Mini_AigNodeFanin0( p, i );
iFaninLit1 = Mini_AigNodeFanin1( p, i );
fprintf( pFile, " assign n%d = ", i );
- fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 );
+ fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 );
fprintf( pFile, " & " );
- fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit1 >> 1) ? 'i':'n', iFaninLit1 >> 1 );
+ fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", pObjIsPi[iFaninLit1 >> 1] ? 'i':'n', iFaninLit1 >> 1 );
fprintf( pFile, ";\n" );
}
// write assigns
@@ -382,19 +456,205 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
{
iFaninLit0 = Mini_AigNodeFanin0( p, i );
fprintf( pFile, " assign o%d = ", i );
- fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 );
+ fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 );
fprintf( pFile, ";\n" );
}
fprintf( pFile, "\nendmodule // %s \n\n\n", pModuleName );
- Vec_BitFree( vObjIsPi );
+ MINI_AIG_FREE( pObjIsPi );
fclose( pFile );
}
+// checks if MiniAIG is normalized (first inputs, then internal nodes, then outputs)
+static int Mini_AigIsNormalized( Mini_Aig_t * p )
+{
+ int nCiNum = Mini_AigPiNum(p);
+ int nCoNum = Mini_AigPoNum(p);
+ int i, nOffset = 1;
+ for ( i = 0; i < nCiNum; i++ )
+ if ( !Mini_AigNodeIsPi( p, nOffset+i ) )
+ return 0;
+ nOffset = Mini_AigNodeNum(p) - nCoNum;
+ for ( i = 0; i < nCoNum; i++ )
+ if ( !Mini_AigNodeIsPo( p, nOffset+i ) )
+ return 0;
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// MiniAIG reading from / write into AIGER ///
+////////////////////////////////////////////////////////////////////////
+
+static unsigned Mini_AigerReadUnsigned( 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 void Mini_AigerWriteUnsigned( FILE * pFile, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+ fputc( ch, pFile );
+ x >>= 7;
+ }
+ ch = x;
+ fputc( ch, pFile );
+}
+static int * Mini_AigerReadInt( char * pFileName, int * pnObjs, int * pnIns, int * pnLatches, int * pnOuts, int * pnAnds )
+{
+ int i, Temp, nTotal, nObjs, nIns, nLatches, nOuts, nAnds, * pObjs;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Mini_AigerRead(): Cannot open the output file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' )
+ {
+ fprintf( stdout, "Mini_AigerRead(): Can only read binary AIGER.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLatches, &nOuts, &nAnds) != 5 )
+ {
+ fprintf( stdout, "Mini_AigerRead(): Cannot read the header line.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nTotal != nIns + nLatches + nAnds )
+ {
+ fprintf( stdout, "The number of objects does not match.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ nObjs = 1 + nIns + 2*nLatches + nOuts + nAnds;
+ pObjs = MINI_AIG_CALLOC( int, nObjs * 2 );
+ for ( i = 0; i <= nIns + nLatches; i++ )
+ pObjs[2*i] = pObjs[2*i+1] = MINI_AIG_NULL;
+ // read flop input literals
+ for ( i = 0; i < nLatches; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nLatches+i)+0] = Temp;
+ pObjs[2*(nObjs-nLatches+i)+1] = MINI_AIG_NULL;
+ }
+ // read output literals
+ for ( i = 0; i < nOuts; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nOuts-nLatches+i)+0] = Temp;
+ pObjs[2*(nObjs-nOuts-nLatches+i)+1] = MINI_AIG_NULL;
+ }
+ // read the binary part
+ while ( fgetc(pFile) != '\n' );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1+nIns+nLatches+i);
+ int uLit1 = uLit - Mini_AigerReadUnsigned( pFile );
+ int uLit0 = uLit1 - Mini_AigerReadUnsigned( pFile );
+ pObjs[uLit+0] = uLit0;
+ pObjs[uLit+1] = uLit1;
+ }
+ fclose( pFile );
+ if ( pnObjs ) *pnObjs = nObjs;
+ if ( pnIns ) *pnIns = nIns;
+ if ( pnLatches ) *pnLatches = nLatches;
+ if ( pnOuts ) *pnOuts = nOuts;
+ if ( pnAnds ) *pnAnds = nAnds;
+ return pObjs;
+}
+static Mini_Aig_t * Mini_AigerRead( char * pFileName, int fVerbose )
+{
+ Mini_Aig_t * p;
+ int nObjs, nIns, nLatches, nOuts, nAnds, * pObjs = Mini_AigerReadInt( pFileName, &nObjs, &nIns, &nLatches, &nOuts, &nAnds );
+ if ( pObjs == NULL )
+ return NULL;
+ p = MINI_AIG_CALLOC( Mini_Aig_t, 1 );
+ p->nCap = 2*nObjs;
+ p->nSize = 2*nObjs;
+ p->nRegs = nLatches;
+ p->pArray = pObjs;
+ if ( fVerbose )
+ printf( "Loaded MiniAIG from the AIGER file \"%s\".\n", pFileName );
+ return p;
+}
+
+static void Mini_AigerWriteInt( char * pFileName, int * pObjs, int nObjs, int nIns, int nLatches, int nOuts, int nAnds )
+{
+ FILE * pFile = fopen( pFileName, "wb" ); int i;
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Mini_AigerWrite(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+ fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLatches + nAnds, nIns, nLatches, nOuts, nAnds );
+ for ( i = 0; i < nLatches; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLatches+i)+0] );
+ for ( i = 0; i < nOuts; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLatches+i)+0] );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1+nIns+nLatches+i);
+ int uLit0 = pObjs[uLit+0];
+ int uLit1 = pObjs[uLit+1];
+ Mini_AigerWriteUnsigned( pFile, uLit - uLit1 );
+ Mini_AigerWriteUnsigned( pFile, uLit1 - uLit0 );
+ }
+ fprintf( pFile, "c\n" );
+ fclose( pFile );
+}
+static void Mini_AigerWrite( char * pFileName, Mini_Aig_t * p, int fVerbose )
+{
+ int i, nIns = 0, nOuts = 0, nAnds = 0;
+ assert( Mini_AigIsNormalized(p) );
+ for ( i = 1; i < Mini_AigNodeNum(p); i++ )
+ {
+ if ( Mini_AigNodeIsPi(p, i) )
+ nIns++;
+ else if ( Mini_AigNodeIsPo(p, i) )
+ nOuts++;
+ else
+ nAnds++;
+ }
+ Mini_AigerWriteInt( pFileName, p->pArray, p->nSize/2, nIns - p->nRegs, p->nRegs, nOuts - p->nRegs, nAnds );
+ if ( fVerbose )
+ printf( "Written MiniAIG into the AIGER file \"%s\".\n", pFileName );
+}
+static void Mini_AigerTest( char * pFileNameIn, char * pFileNameOut )
+{
+ Mini_Aig_t * p = Mini_AigerRead( pFileNameIn, 1 );
+ if ( p == NULL )
+ return;
+ printf( "Finished reading input file \"%s\".\n", pFileNameIn );
+ Mini_AigerWrite( pFileNameOut, p, 1 );
+ printf( "Finished writing output file \"%s\".\n", pFileNameOut );
+ Mini_AigStop( p );
+}
+
+/*
+int main( int argc, char ** argv )
+{
+ if ( argc != 3 )
+ return 0;
+ Mini_AigerTest( argv[1], argv[2] );
+ return 1;
+}
+*/
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#ifndef _VERIFIC_DATABASE_H_
ABC_NAMESPACE_HEADER_END
+#endif
#endif
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index e7f6c0ad..b4e22a38 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -559,7 +559,7 @@ extern ABC_DLL Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, A
extern ABC_DLL Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern ABC_DLL Abc_Obj_t * Abc_AigMux( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * p1, Abc_Obj_t * p0 );
extern ABC_DLL Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs, int fImplic );
-extern ABC_DLL void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel );
+extern ABC_DLL int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel );
extern ABC_DLL void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld );
extern ABC_DLL void Abc_AigRehash( Abc_Aig_t * pMan );
extern ABC_DLL int Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode );
@@ -784,6 +784,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop );
+extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSops );
extern ABC_DLL void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemoveLatches );
@@ -920,6 +921,8 @@ extern ABC_DLL int Abc_SopIsExorType( char * pSop );
extern ABC_DLL int Abc_SopCheck( char * pSop, int nFanins );
extern ABC_DLL char * Abc_SopFromTruthBin( char * pTruth );
extern ABC_DLL char * Abc_SopFromTruthHex( char * pTruth );
+extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth );
+extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth );
extern ABC_DLL char * Abc_SopEncoderPos( Mem_Flex_t * pMan, int iValue, int nValues );
extern ABC_DLL char * Abc_SopEncoderLog( Mem_Flex_t * pMan, int iBit, int nValues );
extern ABC_DLL char * Abc_SopDecoderPos( Mem_Flex_t * pMan, int nValues );
diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c
index d3347a13..636fe30a 100644
--- a/src/base/abc/abcAig.c
+++ b/src/base/abc/abcAig.c
@@ -847,7 +847,7 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
SeeAlso []
***********************************************************************/
-void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel )
+int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel )
{
assert( Vec_PtrSize(pMan->vStackReplaceOld) == 0 );
assert( Vec_PtrSize(pMan->vStackReplaceNew) == 0 );
@@ -859,6 +859,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f
{
pOld = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceOld );
pNew = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceNew );
+ if ( Abc_ObjFanoutNum(pOld) == 0 )
+ return 0;
Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel );
}
if ( fUpdateLevel )
@@ -867,6 +869,7 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f
if ( pMan->pNtkAig->vLevelsR )
Abc_AigUpdateLevelR_int( pMan );
}
+ return 1;
}
/**Function*************************************************************
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index a7448530..c492b709 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -177,7 +177,10 @@ int Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
// check the nodes
if ( Abc_NtkIsStrash(pNtk) )
- Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc );
+ {
+ if ( !Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc ) )
+ return 0;
+ }
else
{
Abc_NtkForEachNode( pNtk, pNode, i )
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
index 3f441e99..92dbd0c9 100644
--- a/src/base/abc/abcMinBase.c
+++ b/src/base/abc/abcMinBase.c
@@ -113,6 +113,7 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
DdNode * bTemp, ** pbVars;
Vec_Str_t * vSupport;
int i, nVars, j, iFanin, iFanin2, k = 0;
+ int ddSize, fDupFanins = 0;
assert( Abc_NtkIsBddLogic(pNode->pNtk) );
assert( Abc_ObjIsNode(pNode) );
@@ -126,8 +127,14 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
return 0;
}
- // remove unused fanins
- pbVars = ABC_CALLOC( DdNode *, Abc_ObjFaninNum(pNode) );
+ // remove unused fanins.
+
+ // By default, every BDD variable stays equivalent to itself.
+ ddSize = Cudd_ReadSize( dd );
+ pbVars = ABC_CALLOC( DdNode *, ddSize );
+ for (i = 0; i < ddSize; i += 1 ) {
+ pbVars[i] = Cudd_bddIthVar( dd, i );
+ }
Vec_IntForEachEntry( &pNode->vFanins, iFanin, i )
{
Abc_Obj_t * pFanin = Abc_NtkObj( pNode->pNtk, iFanin );
@@ -140,19 +147,29 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
Vec_IntForEachEntryStop( &pNode->vFanins, iFanin2, j, k )
if ( iFanin == iFanin2 )
break;
+ fDupFanins |= (int)(j < k);
if ( j == k )
Vec_IntWriteEntry( &pNode->vFanins, k++, iFanin );
else if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) )
printf( "The obj %d is not found among the fanouts of obj %d ...\n", pNode->Id, iFanin );
+
+ // i-th variable becomes equivalent to j-th variable (can be itself)
pbVars[i] = Cudd_bddIthVar( dd, j );
}
Vec_IntShrink( &pNode->vFanins, k );
// update the function of the node
- pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars ); Cudd_Ref( (DdNode *)pNode->pData );
- Cudd_RecursiveDeref( dd, bTemp );
+ if ( ! Cudd_IsConstant((DdNode *) pNode->pData ) ) {
+ pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars );
+ Cudd_Ref( (DdNode *)pNode->pData );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
Vec_StrFree( vSupport );
ABC_FREE( pbVars );
+
+ // try again if node had duplicated fanins
+ if ( fDupFanins )
+ Abc_NodeMinimumBase( pNode );
return 1;
}
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index f8e40b41..63353344 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -1272,6 +1272,52 @@ Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop )
/**Function*************************************************************
+ Synopsis [Creates the network composed of one node with the given SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSop )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pFanin, * pNode, * pNodePo;
+ Vec_Ptr_t * vNames;
+ int i, k, nVars; char Buffer[10];
+ char * pSop = (char *)Vec_PtrEntry(vSop, 0);
+ // start the network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ pNtkNew->pName = Extra_UtilStrsav("ex");
+ // create PIs
+ Vec_PtrPush( pNtkNew->vObjs, NULL );
+ nVars = Abc_SopGetVarNum( pSop );
+ vNames = Abc_NodeGetFakeNames( nVars );
+ for ( i = 0; i < nVars; i++ )
+ Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), (char *)Vec_PtrEntry(vNames, i), NULL );
+ Abc_NodeFreeNames( vNames );
+ // create the node, add PIs as fanins, set the function
+ Vec_PtrForEachEntry( char *, vSop, pSop, i )
+ {
+ pNode = Abc_NtkCreateNode( pNtkNew );
+ Abc_NtkForEachPi( pNtkNew, pFanin, k )
+ Abc_ObjAddFanin( pNode, pFanin );
+ pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop );
+ // create the only PO
+ pNodePo = Abc_NtkCreatePo(pNtkNew);
+ Abc_ObjAddFanin( pNodePo, pNode );
+ sprintf( Buffer, "F%d", i );
+ Abc_ObjAssignName( pNodePo, Buffer, NULL );
+ }
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Deletes the Ntk.]
Description []
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
index b91214af..8250102a 100644
--- a/src/base/abc/abcSop.c
+++ b/src/base/abc/abcSop.c
@@ -907,6 +907,41 @@ int Abc_SopCheck( char * pSop, int nFanins )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopCheckReadTruth( Vec_Ptr_t * vRes, char * pToken, int fHex )
+{
+ char * pBase; int nVars;
+ int Log2 = Abc_Base2Log( strlen(pToken) );
+ if ( (1 << Log2) != (int)strlen(pToken) )
+ {
+ printf( "The truth table length (%d) is not power-of-2.\n", (int)strlen(pToken) );
+ Vec_PtrFreeData( vRes );
+ Vec_PtrShrink( vRes, 0 );
+ return 0;
+ }
+ if ( Vec_PtrSize(vRes) == 0 )
+ return 1;
+ pBase = (char *)Vec_PtrEntry( vRes, 0 );
+ nVars = Abc_SopGetVarNum( pBase );
+ if ( nVars != Log2+2*fHex )
+ {
+ printf( "Truth table #1 has %d vars while truth table #%d has %d vars.\n", nVars, Vec_PtrSize(vRes)+1, Log2+2*fHex );
+ Vec_PtrFreeData( vRes );
+ Vec_PtrShrink( vRes, 0 );
+ return 0;
+ }
+ return 1;
+}
/**Function*************************************************************
@@ -964,8 +999,8 @@ char * Abc_SopFromTruthBin( char * pTruth )
{
pCube = pSopCover + i * (nVars + 3);
for ( b = 0; b < nVars; b++ )
- if ( Mint & (1 << (nVars-1-b)) )
-// if ( Mint & (1 << b) )
+// if ( Mint & (1 << (nVars-1-b)) )
+ if ( Mint & (1 << b) )
pCube[b] = '1';
else
pCube[b] = '0';
@@ -976,6 +1011,21 @@ char * Abc_SopFromTruthBin( char * pTruth )
Vec_IntFree( vMints );
return pSopCover;
}
+Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 );
+ char * pCopy = Abc_UtilStrsav(pTruth);
+ char * pToken = strtok( pCopy, " \r\n\t|" );
+ while ( pToken )
+ {
+ if ( !Abc_SopCheckReadTruth( vRes, pToken, 0 ) )
+ break;
+ Vec_PtrPush( vRes, Abc_SopFromTruthBin(pToken) );
+ pToken = strtok( NULL, " \r\n\t|" );
+ }
+ ABC_FREE( pCopy );
+ return vRes;
+}
/**Function*************************************************************
@@ -1058,6 +1108,21 @@ char * Abc_SopFromTruthHex( char * pTruth )
Vec_IntFree( vMints );
return pSopCover;
}
+Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 );
+ char * pCopy = Abc_UtilStrsav(pTruth);
+ char * pToken = strtok( pCopy, " \r\n\t|" );
+ while ( pToken )
+ {
+ if ( !Abc_SopCheckReadTruth( vRes, pToken, 1 ) )
+ break;
+ Vec_PtrPush( vRes, Abc_SopFromTruthHex(pToken) );
+ pToken = strtok( NULL, " \r\n\t|" );
+ }
+ ABC_FREE( pCopy );
+ return vRes;
+}
/**Function*************************************************************
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 29732bc6..33a8315c 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -146,6 +146,7 @@ static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRestructure ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandResubstitute ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandResubCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -337,6 +338,7 @@ static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sat3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Kissat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -469,6 +471,7 @@ static int Abc_CommandAbc9Reduce ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9EquivMark ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9EquivFilter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9ICec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Verify ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -482,6 +485,7 @@ static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Iff ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Iiff ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9If2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Sif ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Jf ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Kf ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Lf ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -518,6 +522,8 @@ static int Abc_CommandAbc9Iso ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9IsoNpn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9IsoSt ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Compare ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9RevEng ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Uif ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9CexInfo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Cycle ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Cone ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -890,6 +896,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 );
// Cmd_CommandAdd( pAbc, "Synthesis", "restructure", Abc_CommandRestructure, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "resub", Abc_CommandResubstitute, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 );
@@ -1081,6 +1088,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 );
Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 );
Cmd_CommandAdd( pAbc, "Verification", "&sat3", Abc_CommandAbc9Sat3, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "&kissat", Abc_CommandAbc9Kissat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 );
@@ -1212,6 +1220,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&equiv_mark", Abc_CommandAbc9EquivMark, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&equiv_filter", Abc_CommandAbc9EquivFilter, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cec", Abc_CommandAbc9Cec, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&icec", Abc_CommandAbc9ICec, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&verify", Abc_CommandAbc9Verify, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sweep", Abc_CommandAbc9Sweep, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&force", Abc_CommandAbc9Force, 0 );
@@ -1225,6 +1234,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&iff", Abc_CommandAbc9Iff, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&iiff", Abc_CommandAbc9Iiff, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&if2", Abc_CommandAbc9If2, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&sif", Abc_CommandAbc9Sif, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&jf", Abc_CommandAbc9Jf, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&kf", Abc_CommandAbc9Kf, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&lf", Abc_CommandAbc9Lf, 0 );
@@ -1261,6 +1271,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&isonpn", Abc_CommandAbc9IsoNpn, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&isost", Abc_CommandAbc9IsoSt, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&compare", Abc_CommandAbc9Compare, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&reveng", Abc_CommandAbc9RevEng, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&uif", Abc_CommandAbc9Uif, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cexinfo", Abc_CommandAbc9CexInfo, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cycle", Abc_CommandAbc9Cycle, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cone", Abc_CommandAbc9Cone, 0 );
@@ -6961,6 +6973,7 @@ usage:
Abc_Print( -2, "\t 9: adjustable algorithm (heuristic) by XueGong Zhou at Fudan University, Shanghai\n" );
Abc_Print( -2, "\t 10: adjustable algorithm (exact) by XueGong Zhou at Fudan University, Shanghai\n" );
Abc_Print( -2, "\t 11: new cost-aware exact algorithm by XueGong Zhou at Fudan University, Shanghai\n" );
+ Abc_Print( -2, "\t 12: new fast hybrid semi-canonical form (permutation only)\n" );
Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" );
Abc_Print( -2, "\t-d : toggle dumping resulting functions into a file [default = %s]\n", fDumpRes? "yes": "no" );
Abc_Print( -2, "\t-b : toggle dumping in binary format [default = %s]\n", fBinary? "yes": "no" );
@@ -7309,8 +7322,8 @@ usage:
***********************************************************************/
int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup;
+ int c, RetValue;
int fUpdateLevel;
int fPrecompute;
int fUseZeros;
@@ -7380,10 +7393,21 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// modify the current network
- if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ) )
+ pDup = Abc_NtkDup( pNtk );
+ RetValue = Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable );
+ if ( RetValue == -1 )
{
- Abc_Print( -1, "Rewriting has failed.\n" );
- return 1;
+ Abc_FrameReplaceCurrentNetwork( pAbc, pDup );
+ printf( "An error occurred during computation. The original network is restored.\n" );
+ }
+ else
+ {
+ Abc_NtkDelete( pDup );
+ if ( RetValue == 0 )
+ {
+ Abc_Print( 0, "Rewriting has failed.\n" );
+ return 1;
+ }
}
return 0;
@@ -7412,8 +7436,8 @@ usage:
***********************************************************************/
int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup;
+ int c, RetValue;
int nNodeSizeMax;
int nConeSizeMax;
int fUpdateLevel;
@@ -7503,10 +7527,21 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// modify the current network
- if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ) )
+ pDup = Abc_NtkDup( pNtk );
+ RetValue = Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose );
+ if ( RetValue == -1 )
{
- Abc_Print( -1, "Refactoring has failed.\n" );
- return 1;
+ Abc_FrameReplaceCurrentNetwork( pAbc, pDup );
+ printf( "An error occurred during computation. The original network is restored.\n" );
+ }
+ else
+ {
+ Abc_NtkDelete( pDup );
+ if ( RetValue == 0 )
+ {
+ Abc_Print( 0, "Refactoring has failed.\n" );
+ return 1;
+ }
}
return 0;
@@ -7771,6 +7806,64 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandResubCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose );
+ char * pFileR = NULL, * pFileS = NULL;
+ int fVerbose = 0, c;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == globalUtilOptind + 2 )
+ {
+ pFileR = argv[globalUtilOptind];
+ pFileS = argv[globalUtilOptind+1];
+ }
+ else if ( argc == globalUtilOptind + 1 )
+ {
+ pFileR = argv[globalUtilOptind];
+ pFileS = NULL;
+ }
+ else
+ {
+ Abc_Print( -1, "Incorrect number of command line arguments.\n" );
+ return 1;
+ }
+ Res6_ManResubCheck( pFileR, pFileS, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: resub_check [-vh] <file1> <file2>\n" );
+ Abc_Print( -2, "\t checks solution to a resub problem\n" );
+ Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t<file1> : resub problem file name\n");
+ Abc_Print( -2, "\t<file2> : (optional) solution file name\n");
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandRr( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -13971,6 +14064,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
//Dau_NetworkEnumTest();
//Extra_SimulationTest( nDivMax, nNumOnes, fNewOrder );
//Mnist_ExperimentWithScaling( nDecMax );
+ //Gyx_ProblemSolveTest();
return 0;
usage:
Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" );
@@ -19674,10 +19768,10 @@ usage:
int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char * pStruct = NULL;
- int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1;
+ int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1, nInputs = 0;
If_DsdMan_t * pDsdMan = (If_DsdMan_t *)Abc_FrameReadManDsd();
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KCPSfasvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCPISfasvh" ) ) != EOF )
{
switch ( c )
{
@@ -19710,6 +19804,15 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv )
nProcs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ nInputs = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
case 'S':
if ( globalUtilOptind >= argc )
{
@@ -19750,18 +19853,19 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "DSD manager matched with cell %s should be cleaned by \"dsd_filter -m\" before matching with cell %s.\n", pStructCur, pStruct );
return 0;
}
- Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, fVerbose );
+ Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, nInputs, fVerbose );
}
else
If_DsdManTune( pDsdMan, LutSize, fFast, fAdd, fSpec, fVerbose );
return 0;
usage:
- Abc_Print( -2, "usage: dsd_match [-KCP num] [-fasvh] [-S str]\n" );
+ Abc_Print( -2, "usage: dsd_match [-KCPI num] [-fasvh] [-S str]\n" );
Abc_Print( -2, "\t matches DSD structures with the given cell\n" );
Abc_Print( -2, "\t-K num : LUT size used for tuning [default = %d]\n", LutSize );
Abc_Print( -2, "\t-C num : the maximum number of conflicts [default = %d]\n", nConfls );
Abc_Print( -2, "\t-P num : the maximum number of processes [default = %d]\n", nProcs );
+ Abc_Print( -2, "\t-I num : skip checking if support is less than this [default = %d]\n", nInputs );
Abc_Print( -2, "\t-f : toggles using fast check [default = %s]\n", fFast? "yes": "no" );
Abc_Print( -2, "\t-a : toggles adding tuning to the current one [default = %s]\n", fAdd? "yes": "no" );
Abc_Print( -2, "\t-s : toggles using specialized check [default = %s]\n", fSpec? "yes": "no" );
@@ -21522,15 +21626,14 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pNtkRes;
Ssw_Pars_t Pars, * pPars = &Pars;
- int nConstrs = 0;
- int c;
+ int c, nConstrs = 0;
extern Abc_Ntk_t * Abc_NtkDarSeqSweep2( Abc_Ntk_t * pNtk, Ssw_Pars_t * pPars );
pNtk = Abc_FrameReadNtk(pAbc);
// set defaults
Ssw_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNcmplkodsefqvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNXcmplkodsefqvwh" ) ) != EOF )
{
switch ( c )
{
@@ -21644,6 +21747,17 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nConstrs < 0 )
goto usage;
break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nLimitMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLimitMax < 0 )
+ goto usage;
+ break;
case 'c':
pPars->fConstrs ^= 1;
break;
@@ -21765,7 +21879,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: scorr [-PQFCLSIVMN <num>] [-cmplkodsefqvwh]\n" );
+ Abc_Print( -2, "usage: scorr [-PQFCLSIVMNX <num>] [-cmplkodsefqvwh]\n" );
Abc_Print( -2, "\t performs sequential sweep using K-step induction\n" );
Abc_Print( -2, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
Abc_Print( -2, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
@@ -21778,6 +21892,7 @@ usage:
Abc_Print( -2, "\t-V num : min var num needed to recycle the SAT solver [default = %d]\n", pPars->nSatVarMax2 );
Abc_Print( -2, "\t-M num : min call num needed to recycle the SAT solver [default = %d]\n", pPars->nRecycleCalls2 );
Abc_Print( -2, "\t-N num : set last <num> POs to be constraints (use with -c) [default = %d]\n", nConstrs );
+ Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax );
Abc_Print( -2, "\t-c : toggle using explicit constraints [default = %s]\n", pPars->fConstrs? "yes": "no" );
Abc_Print( -2, "\t-m : toggle full merge if constraints are present [default = %s]\n", pPars->fMergeFull? "yes": "no" );
Abc_Print( -2, "\t-p : toggle aligning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" );
@@ -22088,10 +22203,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
int nFramesP;
int nConfMax;
int nVarsMax;
+ int nLimitMax;
int fNewAlgor;
int fVerbose;
extern Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose );
- extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose );
+ extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
@@ -22101,10 +22217,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
nFramesP = 0;
nConfMax = 1000;
nVarsMax = 1000;
+ nLimitMax = 0;
fNewAlgor = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "PCSnvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "PCSXnvh" ) ) != EOF )
{
switch ( c )
{
@@ -22141,6 +22258,17 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nVarsMax < 0 )
goto usage;
break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLimitMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLimitMax < 0 )
+ goto usage;
+ break;
case 'n':
fNewAlgor ^= 1;
break;
@@ -22174,7 +22302,7 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( fNewAlgor )
- pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, fVerbose );
+ pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, nLimitMax, fVerbose );
else
pNtkRes = Abc_NtkDarLcorr( pNtk, nFramesP, nConfMax, fVerbose );
if ( pNtkRes == NULL )
@@ -22187,11 +22315,12 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: lcorr [-PCS num] [-nvh]\n" );
+ Abc_Print( -2, "usage: lcorr [-PCSX num] [-nvh]\n" );
Abc_Print( -2, "\t computes latch correspondence using 1-step induction\n" );
Abc_Print( -2, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfMax );
Abc_Print( -2, "\t-S num : the max number of SAT variables [default = %d]\n", nVarsMax );
+ Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", nLimitMax );
Abc_Print( -2, "\t-n : toggle using new algorithm [default = %s]\n", fNewAlgor? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -25822,6 +25951,117 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Kissat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
+ extern void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose );
+ int c, nConfs = 0, nTimeLimit = 0, fSat = 0, fUnsat = 0, fPrintCex = 0, fVerbose = 0;
+ char * pArgs = NULL;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTAsucvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConfs = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nConfs < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nTimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nTimeLimit < 0 )
+ goto usage;
+ break;
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by a file name.\n" );
+ goto usage;
+ }
+ pArgs = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 's':
+ fSat ^= 1;
+ break;
+ case 'u':
+ fUnsat ^= 1;
+ break;
+ case 'c':
+ fPrintCex ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ Gia_ManKissatCall( pAbc, argv[globalUtilOptind], pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose );
+ return 0;
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" );
+ return 1;
+ }
+ else
+ {
+ int nLutSize = 8;
+ int fCnfObjIds = 0;
+ int fAddOrCla = 1;
+ char * pFileName = "_temp_.cnf";
+ Mf_ManDumpCnf( pAbc->pGia, pFileName, nLutSize, fCnfObjIds, fAddOrCla, fVerbose );
+ Gia_ManKissatCall( pAbc, pFileName, pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose );
+ unlink( pFileName );
+ }
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &kissat [-CT num] [-sucvh] [-A string] <file.cnf>\n" );
+ Abc_Print( -2, "\t run SAT solver Kissat, by Armin Biere (https://github.com/arminbiere/kissat)\n" );
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfs );
+ Abc_Print( -2, "\t-T num : runtime limit in seconds [default = %d]\n", nTimeLimit );
+ Abc_Print( -2, "\t-s : expect a satisfiable problem [default = %s]\n", fSat ? "yes": "no" );
+ Abc_Print( -2, "\t-u : expect an unsatisfiable problem [default = %s]\n", fUnsat ? "yes": "no" );
+ Abc_Print( -2, "\t-c : prints satisfying assignment if satisfiable [default = %s]\n", fPrintCex ? "yes": "no" );
+ Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose ? "yes": "no" );
+ Abc_Print( -2, "\t-A num : string containing additional command-line args for the Kissat binary [default = %s]\n", pArgs ? pArgs : "unused" );
+ Abc_Print( -2, "\t (in particular, <&kissat -A \"--help\"> prints all command-line args of Kissat)\n" );
+ Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n");
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandPSat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -29960,6 +30200,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
extern void Abc3_ReadShowHie( char * pFileName, int fFlat );
extern Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose );
extern Gia_Man_t * Gia_FileSimpleRead( char * pFileName, int fNames, char * pFileW );
+ extern Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p );
Gia_Man_t * pAig = NULL;
FILE * pFile;
char ** pArgvNew;
@@ -29972,8 +30213,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
int fGiaSimple = 0;
int fSkipStrash = 0;
int fNewReader = 0;
+ int fDetectXors = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "csmnlpvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "csxmnlpvh" ) ) != EOF )
{
switch ( c )
{
@@ -29983,6 +30225,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
case 's':
fSkipStrash ^= 1;
break;
+ case 'x':
+ fDetectXors ^= 1;
+ break;
case 'm':
fMiniAig ^= 1;
break;
@@ -30037,16 +30282,25 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
// else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
// Abc3_ReadShowHie( FileName, fSkipStrash );
else
+ {
pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 );
+ if ( fDetectXors )
+ {
+ Gia_Man_t * pTemp;
+ pAig = Gia_ManCreateXors( pTemp = pAig );
+ Gia_ManStop( pTemp );
+ }
+ }
if ( pAig )
Abc_FrameUpdateGia( pAbc, pAig );
return 0;
usage:
- Abc_Print( -2, "usage: &r [-csmnlvh] <file>\n" );
+ Abc_Print( -2, "usage: &r [-csxmnlvh] <file>\n" );
Abc_Print( -2, "\t reads the current AIG from the AIGER file\n" );
Abc_Print( -2, "\t-c : toggles reading simple AIG [default = %s]\n", fGiaSimple? "yes": "no" );
Abc_Print( -2, "\t-s : toggles structural hashing while reading [default = %s]\n", !fSkipStrash? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggles detecting XORs while reading [default = %s]\n", fDetectXors? "yes": "no" );
Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fMiniAig? "yes": "no" );
Abc_Print( -2, "\t-n : toggles reading MiniAIG as a set of supergates [default = %s]\n", fMiniAig2? "yes": "no" );
Abc_Print( -2, "\t-l : toggles reading MiniLUT rather than AIGER file [default = %s]\n", fMiniLut? "yes": "no" );
@@ -32598,9 +32852,10 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
int fNormal = 0;
int fRevFans = 0;
int fRevOuts = 0;
+ int fLeveled = 0;
int fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "nfovh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nfolvh" ) ) != EOF )
{
switch ( c )
{
@@ -32613,6 +32868,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'o':
fRevOuts ^= 1;
break;
+ case 'l':
+ fLeveled ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -32627,7 +32885,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Dfs(): There is no AIG.\n" );
return 1;
}
- if ( fNormal )
+ if ( fLeveled )
+ pTemp = Gia_ManDupLevelized( pAbc->pGia );
+ else if ( fNormal )
pTemp = Gia_ManDupOrderAiger( pAbc->pGia );
else
pTemp = Gia_ManDupOrderDfsReverse( pAbc->pGia, fRevFans, fRevOuts );
@@ -32635,12 +32895,13 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &dfs [-nfovh]\n" );
+ Abc_Print( -2, "usage: &dfs [-nfolvh]\n" );
Abc_Print( -2, "\t orders objects in the DFS order\n" );
- Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" );
- Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" );
+ Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" );
Abc_Print( -2, "\t-o : toggle using reverse output traversal order [default = %s]\n", fRevOuts? "yes": "no" );
- Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-l : toggle using levelized order [default = %s]\n", fLeveled? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -32794,7 +33055,7 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose );
+ extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int TimeLimit, int fVerbose );
Gia_Man_t * pGias[2]; FILE * pFile;
char ** pArgvNew; int nArgcNew;
int c, RetValue = 0, fVerbose = 0, nWords = 16, nRounds = 10, RandSeed = 1, TimeLimit = 0;
@@ -32941,7 +33202,7 @@ int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "The number of COs does not match.\n" );
return 1;
}
- RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, fVerbose );
+ RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, TimeLimit, fVerbose );
if ( pGias[0] != pAbc->pGia )
Gia_ManStopP( &pGias[0] );
Gia_ManStopP( &pGias[1] );
@@ -36374,7 +36635,7 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
Cec_ManCorSetDefaultParams( pPars );
pPars->fLatchCorr = 1;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "FCPrcvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXrcvwh" ) ) != EOF )
{
switch ( c )
{
@@ -36411,6 +36672,17 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nPrefix < 0 )
goto usage;
break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nLimitMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLimitMax < 0 )
+ goto usage;
+ break;
case 'r':
pPars->fUseRings ^= 1;
break;
@@ -36453,11 +36725,12 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &lcorr [-FCP num] [-rcvwh]\n" );
+ Abc_Print( -2, "usage: &lcorr [-FCPX num] [-rcvwh]\n" );
Abc_Print( -2, "\t performs latch correpondence computation\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix );
+ Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax );
Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" );
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
@@ -36486,7 +36759,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Cec_ManCorSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "FCPpkrecqwvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXpkrecqwvh" ) ) != EOF )
{
switch ( c )
{
@@ -36523,6 +36796,17 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nPrefix < 0 )
goto usage;
break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nLimitMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLimitMax < 0 )
+ goto usage;
+ break;
case 'p':
fPartition ^= 1;
break;
@@ -36580,11 +36864,12 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &scorr [-FCP num] [-pkrecqwvh]\n" );
+ Abc_Print( -2, "usage: &scorr [-FCPX num] [-pkrecqwvh]\n" );
Abc_Print( -2, "\t performs signal correpondence computation\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix );
+ Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax );
Abc_Print( -2, "\t-p : toggle using partitioning for the input AIG [default = %s]\n", fPartition? "yes": "no" );
Abc_Print( -2, "\t-k : toggle using constant correspondence [default = %s]\n", pPars->fConstCorr? "yes": "no" );
Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" );
@@ -36910,11 +37195,14 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
+ extern void Cec4_ManSimulateTest5( Gia_Man_t * p, int nConfs, int fVerbose );
+ extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle );
Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp;
- int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0;
+ int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0, fUseSave = 0;
+ int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500;
Cec4_ManSetParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxyswvh" ) ) != EOF )
{
switch ( c )
{
@@ -37039,7 +37327,13 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
fUseAlgoG ^= 1;
break;
case 'x':
- fUseAlgoG2 ^= 1;
+ fUseAlgoX ^= 1;
+ break;
+ case 'y':
+ fUseAlgoY ^= 1;
+ break;
+ case 's':
+ fUseSave ^= 1;
break;
case 'w':
pPars->fVeryVerbose ^= 1;
@@ -37056,19 +37350,32 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Fraig(): There is no AIG.\n" );
return 1;
}
- if ( fUseAlgo )
+ if ( fUseSave )
+ {
+ Cec4_ManSimulateTest5( pAbc->pGia, pPars->nBTLimit, pPars->fVerbose );
+ return 0;
+ }
+ else if ( fUseAlgo )
pTemp = Cec2_ManSimulateTest( pAbc->pGia, pPars );
else if ( fUseAlgoG )
pTemp = Cec3_ManSimulateTest( pAbc->pGia, pPars );
- else if ( fUseAlgoG2 )
+ else if ( fUseAlgoX )
pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars );
- else
+ else if ( fUseAlgoY )
+ pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars, fCbs, approxLim, subBatchSz, adaRecycle );
+ else
pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 );
+ if ( pAbc->pGia->pCexSeq != NULL )
+ {
+ pAbc->Status = 0;
+ pAbc->nFrames = 0;
+ Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq );
+ }
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngwvh]\n" );
+ Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngxyswvh]\n" );
Abc_Print( -2, "\t performs combinational SAT sweeping\n" );
Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType );
Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords );
@@ -37086,6 +37393,9 @@ usage:
Abc_Print( -2, "\t-k : toggle using logic cones in the SAT solver [default = %s]\n", pPars->fUseCones? "yes": "no" );
Abc_Print( -2, "\t-n : toggle using new implementation [default = %s]\n", fUseAlgo? "yes": "no" );
Abc_Print( -2, "\t-g : toggle using another new implementation [default = %s]\n", fUseAlgoG? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggle using another new implementation [default = %s]\n", fUseAlgoX? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggle using another new implementation [default = %s]\n", fUseAlgoY? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggle dumping equivalences into a file [default = %s]\n", fUseSave? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -37663,10 +37973,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pFile;
Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
char ** pArgvNew;
- int c, nArgcNew, fUseSim = 0, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
+ int c, nArgcNew, fUseSim = 0, fUseNewX = 0, fUseNewY = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
Cec_ManCecSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxtvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxytvwh" ) ) != EOF )
{
switch ( c )
{
@@ -37708,7 +38018,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fSilent ^= 1;
break;
case 'x':
- fUseNew ^= 1;
+ fUseNewX ^= 1;
+ break;
+ case 'y':
+ fUseNewY ^= 1;
break;
case 't':
fUseSim ^= 1;
@@ -37865,7 +38178,22 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
// compute the miter
- pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose );
+ if ( Gia_ManCiNum(pGias[0]) < 6 )
+ {
+ Gia_Man_t * pGias0 = Gia_ManDup( pGias[0] );
+ Gia_Man_t * pGias1 = Gia_ManDup( pGias[1] );
+ for ( c = Gia_ManCiNum(pGias[0]); c < 6; c++ )
+ {
+ Gia_ManAppendCi(pGias0);
+ Gia_ManAppendCi(pGias1);
+ }
+ pMiter = Gia_ManMiter( pGias0, pGias1, 0, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose );
+ Gia_ManStop( pGias0 );
+ Gia_ManStop( pGias1 );
+ }
+ else
+ pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose );
+
if ( pMiter )
{
if ( fDumpMiter )
@@ -37896,7 +38224,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Networks are UNDECIDED. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
- else if ( fUseNew )
+ else if ( fUseNewX )
{
abctime clk = Abc_Clock();
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
@@ -37908,6 +38236,18 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
Gia_ManStop( pNew );
}
+ else if ( fUseNewY )
+ {
+ abctime clk = Abc_Clock();
+ extern Gia_Man_t * Cec5_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pNew = Cec5_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Gia_ManStop( pNew );
+ }
else
{
pAbc->Status = Cec_ManVerify( pMiter, pPars );
@@ -37921,7 +38261,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxtvwh]\n" );
+ Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxytvwh]\n" );
Abc_Print( -2, "\t new combinational equivalence checker\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
@@ -37930,7 +38270,8 @@ usage:
Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
Abc_Print( -2, "\t-a : toggle writing dual-output miter [default = %s]\n", fDumpMiter? "yes":"no");
Abc_Print( -2, "\t-s : toggle silent operation [default = %s]\n", pPars->fSilent ? "yes":"no");
- Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no");
+ Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNewX? "yes":"no");
+ Abc_Print( -2, "\t-y : toggle using new solver [default = %s]\n", fUseNewY? "yes":"no");
Abc_Print( -2, "\t-t : toggle using simulation [default = %s]\n", fUseSim? "yes":"no");
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no");
@@ -37949,6 +38290,191 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9ICec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ FILE * pFile;
+ Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
+ char ** pArgvNew;
+ int c, nArgcNew, fUseNew = 0, fDumpMiter = 0;
+ Cec_ManCecSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTaxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBTLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBTLimit < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->TimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->TimeLimit < 0 )
+ goto usage;
+ break;
+ case 'a':
+ fDumpMiter ^= 1;
+ break;
+ case 'x':
+ fUseNew ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fVeryVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew > 2 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" );
+ return 1;
+ }
+ if ( nArgcNew == 2 )
+ {
+ char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp;
+ int n;
+ for ( n = 0; n < 2; n++ )
+ {
+ // fix the wrong symbol
+ for ( pTemp = pFileNames[n]; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( pFileNames[n], "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] );
+ if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 );
+ if ( pGias[n] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] );
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ char * FileName, * pTemp;
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" );
+ return 1;
+ }
+ pGias[0] = pAbc->pGia;
+ if ( nArgcNew == 1 )
+ FileName = pArgvNew[0];
+ else
+ {
+ assert( nArgcNew == 0 );
+ if ( pAbc->pGia->pSpec == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ FileName = pAbc->pGia->pSpec;
+ }
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 );
+ if ( pGias[1] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ // compute the miter
+ pMiter = Gia_ManMiterInverse( pGias[0], pGias[1], !fUseNew, pPars->fVerbose );
+ if ( pMiter )
+ {
+ if ( fDumpMiter )
+ {
+ Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "cec_miter.aig" );
+ Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0, 0 );
+ }
+ if ( fUseNew )
+ {
+ abctime clk = Abc_Clock();
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Gia_ManStop( pNew );
+ }
+ else
+ {
+ pAbc->Status = Cec_ManVerify( pMiter, pPars );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
+ }
+ Gia_ManStop( pMiter );
+ }
+ if ( pGias[0] != pAbc->pGia )
+ Gia_ManStop( pGias[0] );
+ Gia_ManStop( pGias[1] );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &icec [-CT num] [-axvwh]\n" );
+ Abc_Print( -2, "\t combinational equivalence checker for inverse circuits\n" );
+ Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
+ Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
+ Abc_Print( -2, "\t-a : toggle writing the miter [default = %s]\n", fDumpMiter? "yes":"no");
+ Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no");
+ Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
+ Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no");
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Verify( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char * pFileSpec = NULL;
@@ -39699,6 +40225,68 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Sif( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose );
+ Gia_Man_t * pNew;
+ int c, nLutSize = 6, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nLutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLutSize < 2 || nLutSize > 16 )
+ {
+ Abc_Print( -1, "LUT size %d is not supported.\n", nLutSize );
+ goto usage;
+ }
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Empty GIA network.\n" );
+ return 1;
+ }
+ pNew = Gia_ManTestSif( pAbc->pGia, nLutSize, fVerbose );
+ if ( pNew != NULL )
+ Abc_FrameUpdateGia( pAbc, pNew );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &sif [-K num] [-vh]\n" );
+ Abc_Print( -2, "\t performs technology mapping\n" );
+ Abc_Print( -2, "\t-K num : sets the LUT size for the mapping [default = %d]\n", nLutSize );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Jf( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char Buffer[200];
@@ -43491,6 +44079,144 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9RevEng( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManCompareSims( Gia_Man_t * pHie, Gia_Man_t * pFlat, int nWords, int fVerbose );
+ Gia_Man_t * pGia0, * pGia1;
+ char ** pArgvNew; int nArgcNew;
+ int c, nWords = 4, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Wvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'W':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nWords = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nWords < 0 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9RevEng(): There is no AIG.\n" );
+ return 1;
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9RevEng(): This command expects one AIG file name on the command line.\n" );
+ return 1;
+ }
+ pGia0 = pAbc->pGia;
+ pGia1 = Gia_AigerRead( pArgvNew[0], 0, 0, 0 );
+ if ( pGia0 == NULL || pGia1 == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9RevEng(): Reading input files did not work.\n" );
+ return 1;
+ }
+ Gia_ManCompareSims( pGia0, pGia1, nWords, fVerbose );
+ Gia_ManStop( pGia1 );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &reveng [-W num] [-vh] <file>\n" );
+ Abc_Print( -2, "\t compares two AIGs for structural similarity\n" );
+ Abc_Print( -2, "\t the current AIG is expected to contain some hierarchy\n" );
+ Abc_Print( -2, "\t the given AIG from <file> is expected to be flat\n" );
+ Abc_Print( -2, "\t-W num : the number of 64-bit words of simulation info [default = %d]\n", nWords );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Uif( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p );
+ extern Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p );
+ Gia_Man_t * pNew = NULL, * pTemp = NULL;
+ int c, fBlackBox = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fBlackBox ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Uif(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( pAbc->pGia->vBarBufs == NULL || Vec_IntSize(pAbc->pGia->vBarBufs) == 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Uif(): Hierarchy is not defined.\n" );
+ return 1;
+ }
+ pNew = Gia_ManDupUif( pAbc->pGia );
+ if ( fBlackBox )
+ {
+ pNew = Gia_ManDupBlackBox( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ }
+ Abc_FrameUpdateGia( pAbc, pNew );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &uif [-bvh]\n" );
+ Abc_Print( -2, "\t eagerly adds UIF constraints when hierarchy is present\n" );
+ Abc_Print( -2, "\t-b : toggle blackboxing while adding constraints [default = %s]\n", fBlackBox? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9CexInfo( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose );
@@ -43612,9 +44338,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
Vec_Int_t * vPos;
- int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0;
+ int c, nRegs = 0, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fComb = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaecvh" ) ) != EOF )
{
switch ( c )
{
@@ -43679,6 +44405,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'e':
fExtractAll ^= 1;
break;
+ case 'c':
+ fComb ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -43742,20 +44471,27 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
}
+ nRegs = Gia_ManRegNum( pAbc->pGia );
+ if ( fComb )
+ pAbc->pGia->nRegs = 0;
if ( iOutNum < 0 || iOutNum + nOutRange > Gia_ManPoNum(pAbc->pGia) )
{
Abc_Print( -1, "Abc_CommandAbc9Cone(): Range of outputs to extract is incorrect.\n" );
+ if ( fComb )
+ Gia_ManSetRegNum( pAbc->pGia, nRegs );
return 1;
}
vPos = Vec_IntStartRange( iOutNum, nOutRange );
pTemp = Gia_ManDupCones( pAbc->pGia, Vec_IntArray(vPos), nOutRange, !fUseAllCis );
+ if ( fComb )
+ Gia_ManSetRegNum( pAbc->pGia, nRegs );
Vec_IntFree( vPos );
if ( pTemp )
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" );
+ Abc_Print( -2, "usage: &cone [-ORPLW num] [-aecvh]\n" );
Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" );
Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum );
Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange );
@@ -43764,6 +44500,7 @@ usage:
Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow );
Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" );
Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle performing cone extraction combinationally [default = %s]\n", fComb? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 483f65b9..76c7cf54 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -658,6 +658,33 @@ Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan )
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia )
+{
+ Aig_Man_t * pMan = Gia_ManToAig( pGia, 0 ); int Res;
+ Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ), * pTemp;
+ //pNtk->pName = Extra_UtilStrsav(pGia->pName);
+ Aig_ManStop( pMan );
+ // collapse the network
+ pNtk = Abc_NtkCollapse( pTemp = pNtk, 10000, 0, 1, 0, 0, 0 );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ return 0;
+ Res = Abc_NtkGetBddNodeNum( pNtk );
+ Abc_NtkDelete( pNtk );
+ return Res == 0;
+}
+
/**Function*************************************************************
@@ -1204,7 +1231,11 @@ Abc_Ntk_t * Abc_NtkFromDarChoices( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
Aig_ManForEachCo( pMan, pObj, i )
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
if ( !Abc_NtkCheck( pNtkNew ) )
- Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed.\n" );
+ {
+ Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed. Returning original network.\n" );
+ Abc_NtkDelete( pNtkNew );
+ pNtkNew = Abc_NtkDup( pNtkOld );
+ }
// verify topological order
if ( 0 )
@@ -2271,7 +2302,7 @@ Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int f
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose )
+Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose )
{
Ssw_Pars_t Pars, * pPars = &Pars;
Aig_Man_t * pMan, * pTemp;
@@ -2283,6 +2314,7 @@ Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, in
pPars->fLatchCorrOpt = 1;
pPars->nBTLimit = nConfMax;
pPars->nSatVarMax = nVarsMax;
+ pPars->nLimitMax = nLimitMax;
pPars->fVerbose = fVerbose;
pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars );
Aig_ManStop( pTemp );
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 42cf11c5..64225c61 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -1034,7 +1034,7 @@ static word * Ses_ManDeriveTruth( Ses_Man_t * pSes, char * pSol, int fInvert )
for ( i = 0; i < nGates; ++i )
{
f = *p++;
- assert( *p++ == 2 );
+ assert( *p == 2 ), p++;
j = *p++;
k = *p++;
diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c
index e109a9cf..92b47c17 100644
--- a/src/base/abci/abcNpn.c
+++ b/src/base/abci/abcNpn.c
@@ -208,6 +208,8 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
pAlgoName = "adjustable algorithm (exact) ";
else if ( NpnType == 11 )
pAlgoName = "new cost-aware exact algorithm ";
+ else if ( NpnType == 12 )
+ pAlgoName = "new hybrid fast (P) ";
assert( p->nVars <= 16 );
if ( pAlgoName )
@@ -356,6 +358,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
}
Abc_TtHieManStop(pMan);
}
+ else if ( NpnType == 12 )
+ {
+ for ( i = 0; i < p->nFuncs; i++ )
+ {
+ if ( fVerbose )
+ printf( "%7d : ", i );
+ uCanonPhase = Abc_TtCanonicizePerm( p->pFuncs[i], p->nVars, pCanonPerm );
+ if ( fVerbose )
+ Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
+ }
+ }
else assert( 0 );
clk = Abc_Clock() - clk;
printf( "Classes =%9d ", Abc_TruthNpnCountUnique(p) );
@@ -419,7 +432,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int f
{
if ( fVerbose )
printf( "Using truth tables from file \"%s\"...\n", pFileName );
- if ( NpnType >= 0 && NpnType <= 11 )
+ if ( NpnType >= 0 && NpnType <= 12 )
Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose );
else
printf( "Unknown canonical form value (%d).\n", NpnType );
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
index cbf4bbb8..9de88980 100644
--- a/src/base/abci/abcNtbdd.c
+++ b/src/base/abci/abcNtbdd.c
@@ -237,7 +237,8 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
{
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
assert( !Cudd_IsComplement(bFunc) );
- if ( bFunc == b1 || bFunc == a1 )
+ assert( b1 == a1 );
+ if ( bFunc == a1 )
return Abc_NtkCreateNodeConst1(pNtkNew);
if ( bFunc == a0 )
return Abc_NtkCreateNodeConst0(pNtkNew);
diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c
index 3cc6d793..8ec5944f 100644
--- a/src/base/abci/abcRefactor.c
+++ b/src/base/abci/abcRefactor.c
@@ -325,7 +325,7 @@ void Abc_NtkManRefPrintStats( Abc_ManRef_t * p )
***********************************************************************/
int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRef_t * pManRef;
Abc_ManCut_t * pManCut;
@@ -333,7 +333,7 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int f
Vec_Ptr_t * vFanins;
Abc_Obj_t * pNode;
abctime clk, clkStart = Abc_Clock();
- int i, nNodes;
+ int i, nNodes, RetValue = 1;
assert( Abc_NtkIsStrash(pNtk) );
// cleanup the AIG
@@ -377,7 +377,12 @@ pManRef->timeRes += Abc_Clock() - clk;
continue;
// acceptable replacement found, update the graph
clk = Abc_Clock();
- Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain );
+ if ( !Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain ) )
+ {
+ Dec_GraphFree( pFForm );
+ RetValue = -1;
+ break;
+ }
pManRef->timeNtk += Abc_Clock() - clk;
Dec_GraphFree( pFForm );
}
@@ -394,18 +399,21 @@ pManRef->timeTotal = Abc_Clock() - clkStart;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
- // fix the levels
- if ( fUpdateLevel )
- Abc_NtkStopReverseLevels( pNtk );
- else
- Abc_NtkLevel( pNtk );
- // check
- if ( !Abc_NtkCheck( pNtk ) )
+ if ( RetValue != -1 )
{
- printf( "Abc_NtkRefactor: The network check has failed.\n" );
- return 0;
+ // fix the levels
+ if ( fUpdateLevel )
+ Abc_NtkStopReverseLevels( pNtk );
+ else
+ Abc_NtkLevel( pNtk );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRefactor: The network check has failed.\n" );
+ return 0;
+ }
}
- return 1;
+ return RetValue;
}
diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c
index ef5dd451..87f15238 100644
--- a/src/base/abci/abcRestruct.c
+++ b/src/base/abci/abcRestruct.c
@@ -105,7 +105,7 @@ static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
***********************************************************************/
int Abc_NtkRestructure( Abc_Ntk_t * pNtk, int nCutMax, int fUpdateLevel, int fUseZeros, int fVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRst_t * pManRst;
Cut_Man_t * pManCut;
diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c
index b8934e23..dc1b6036 100644
--- a/src/base/abci/abcResub.c
+++ b/src/base/abci/abcResub.c
@@ -136,7 +136,7 @@ extern abctime s_ResubTime;
***********************************************************************/
int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRes_t * pManRes;
Abc_ManCut_t * pManCut;
diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c
index 0b0881a6..1da7e4e8 100644
--- a/src/base/abci/abcRewrite.c
+++ b/src/base/abci/abcRewrite.c
@@ -60,14 +60,14 @@ extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets
***********************************************************************/
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Cut_Man_t * pManCut;
Rwr_Man_t * pManRwr;
Abc_Obj_t * pNode;
// Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL;
Dec_Graph_t * pGraph;
- int i, nNodes, nGain, fCompl;
+ int i, nNodes, nGain, fCompl, RetValue = 1;
abctime clk, clkStart = Abc_Clock();
assert( Abc_NtkIsStrash(pNtk) );
@@ -138,7 +138,11 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
// complement the FF if needed
if ( fCompl ) Dec_GraphComplement( pGraph );
clk = Abc_Clock();
- Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
+ if ( !Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ) )
+ {
+ RetValue = -1;
+ break;
+ }
Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
@@ -175,17 +179,20 @@ Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart );
}
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
- if ( fUpdateLevel )
- Abc_NtkStopReverseLevels( pNtk );
- else
- Abc_NtkLevel( pNtk );
- // check
- if ( !Abc_NtkCheck( pNtk ) )
+ if ( RetValue >= 0 )
{
- printf( "Abc_NtkRewrite: The network check has failed.\n" );
- return 0;
+ if ( fUpdateLevel )
+ Abc_NtkStopReverseLevels( pNtk );
+ else
+ Abc_NtkLevel( pNtk );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRewrite: The network check has failed.\n" );
+ return 0;
+ }
}
- return 1;
+ return RetValue;
}
diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c
index 52d1fd32..86c5f13e 100644
--- a/src/base/abci/abcRr.c
+++ b/src/base/abci/abcRr.c
@@ -397,10 +397,7 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab
else assert( 0 );
// replace
if ( pFanout == NULL )
- {
- Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 );
- return 1;
- }
+ return Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 );
// find the fanout after redundancy removal
if ( pNode == Abc_ObjFanin0(pFanout) )
pFanoutNew = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC0(pFanout)), Abc_ObjChild1(pFanout) );
diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c
index 84cda931..1341630b 100644
--- a/src/base/abci/abcTiming.c
+++ b/src/base/abci/abcTiming.c
@@ -608,7 +608,7 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
}
if ( pNtkOld->pManTime->tOutLoad )
{
- pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) );
+ pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCoNum(pNtkOld) );
memcpy( pNtkNew->pManTime->tOutLoad, pNtkOld->pManTime->tOutLoad, sizeof(Abc_Time_t) * Abc_NtkCoNum(pNtkOld) );
}
diff --git a/src/base/acb/acbTest.c b/src/base/acb/acbTest.c
index 1faea72a..6290b88e 100644
--- a/src/base/acb/acbTest.c
+++ b/src/base/acb/acbTest.c
@@ -466,7 +466,7 @@ Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type
***********************************************************************/
void Acb_OutputFile( char * pFileName, Acb_Ntk_t * pNtkF, int * pModel )
{
- char * pFileName0 = pFileName? pFileName : "output";
+ const char * pFileName0 = pFileName? pFileName : "output";
FILE * pFile = fopen( pFileName0, "wb" );
if ( pFile == NULL )
{
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 259c9d78..98368ef8 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -1161,7 +1161,7 @@ int CmdCommandScanDir( Abc_Frame_t * pAbc, int argc, char **argv )
struct _finddata_t c_file;
char * pDirStr = NULL;
char* pDirCur = NULL;
- long hFile;
+ ABC_PTRINT_T hFile;
char c;
Extra_UtilGetoptReset();
@@ -1354,7 +1354,7 @@ void CnfDupFileUnzip( char * pOldName )
int CmdCommandRenameFiles( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
char pNewName[1000];
char * pDirStr = NULL;
char * pDirCur = NULL;
@@ -1515,7 +1515,7 @@ usage:
int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
int fLong = 0;
int fOnlyBLIF = 0;
char Buffer[25];
@@ -1618,7 +1618,7 @@ usage:
int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
FILE * pFile = NULL;
char * pFileStr = "test.s";
char * pDirStr = NULL;
diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c
index accd9440..bd511fec 100644
--- a/src/base/cmd/cmdLoad.c
+++ b/src/base/cmd/cmdLoad.c
@@ -114,7 +114,8 @@ Vec_Ptr_t * CmdCollectFileNames()
{
Vec_Ptr_t * vFileNames;
struct _finddata_t c_file;
- long hFile;
+ //long hFile;
+ ABC_PTRINT_T hFile;
if( (hFile = _findfirst( "*.exe", &c_file )) == -1L )
{
// Abc_Print( 0, "No files with extention \"%s\" in the current directory.\n", "exe" );
diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c
index c10e9134..0759ca9c 100644
--- a/src/base/cmd/cmdUtils.c
+++ b/src/base/cmd/cmdUtils.c
@@ -20,6 +20,7 @@
#include "base/abc/abc.h"
#include "base/main/mainInt.h"
+#include "misc/util/utilSignal.h"
#include "cmdInt.h"
#include <ctype.h>
@@ -462,7 +463,7 @@ FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFi
else
{
// print the path/name of the resource file 'abc.rc' that is being loaded
- if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 )
+ if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 )
Abc_Print( 1, "Loading resource file \"%s\".\n", sRealName );
}
}
@@ -752,6 +753,90 @@ void CmdPrintTable( st__table * tTable, int fAliases )
ABC_FREE( ppNames );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose )
+{
+ char Command[1000], Buffer[100];
+ char * pNameWin = "kissat.exe";
+ char * pNameUnix = "kissat";
+ char * pKissatName = NULL;
+ //FILE * pFile = NULL;
+
+ // get the names from the resource file
+ if ( Cmd_FlagReadByName(pAbc, "kissatwin") )
+ pNameWin = Cmd_FlagReadByName(pAbc, "kissatwin");
+ if ( Cmd_FlagReadByName(pAbc, "kissatunix") )
+ pNameUnix = Cmd_FlagReadByName(pAbc, "kissatunix");
+/*
+ // check if the binary is available
+ if ( (pFile = fopen( pNameWin, "r" )) )
+ pKissatName = pNameWin;
+ else if ( (pFile = fopen( pNameUnix, "r" )) )
+ pKissatName = pNameUnix;
+ else if ( pFile == NULL )
+ {
+ fprintf( stdout, "Cannot find Kissat binary \"%s\" or \"%s\" in the current directory.\n", pNameWin, pNameUnix );
+ return;
+ }
+ fclose( pFile );
+*/
+
+#ifdef _WIN32
+ pKissatName = pNameWin;
+#else
+ pKissatName = pNameUnix;
+#endif
+
+ sprintf( Command, "%s", pKissatName );
+ if ( pArgs )
+ {
+ strcat( Command, " " );
+ strcat( Command, pArgs );
+ }
+ if ( !pArgs || (strcmp(pArgs, "-h") && strcmp(pArgs, "--help")) )
+ {
+ if ( !fVerbose )
+ strcat( Command, " -q" );
+ if ( !fPrintCex )
+ strcat( Command, " -n" );
+ if ( fSat )
+ strcat( Command, " --sat" );
+ if ( fUnsat )
+ strcat( Command, " --unsat" );
+ if ( nConfs )
+ {
+ sprintf( Buffer, " --conflicts=%d", nConfs );
+ strcat( Command, Buffer );
+ }
+ if ( nTimeLimit )
+ {
+ sprintf( Buffer, " --time=%d", nTimeLimit );
+ strcat( Command, Buffer );
+ }
+ strcat( Command, " " );
+ strcat( Command, pFileName );
+ }
+ if ( fVerbose )
+ printf( "Running command: %s\n", Command );
+ if ( Util_SignalSystem( Command ) == -1 )
+ {
+ fprintf( stdout, "The following command has returned a strange exit status:\n" );
+ fprintf( stdout, "\"%s\"\n", Command );
+ }
+}
+
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 5408ccba..b8d1d7db 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -85,6 +85,7 @@ static int IoCommandWriteTruths ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteStatus ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteSmv ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteJson ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteResub ( Abc_Frame_t * pAbc, int argc, char **argv );
extern void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk );
@@ -157,6 +158,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "write_status", IoCommandWriteStatus, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_smv", IoCommandWriteSmv, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_json", IoCommandWriteJson, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "&write_resub", IoCommandWriteResub, 0 );
}
/**Function*************************************************************
@@ -1402,7 +1404,7 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk;
char * pStr = NULL;
- char * pSopCover;
+ Vec_Ptr_t * vSops;
int fHex = 1;
int fFile = 0;
int c;
@@ -1429,28 +1431,36 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
if ( fFile )
+ {
+ FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "The file \"%s\" cannot be found.\n", argv[globalUtilOptind] );
+ return 1;
+ }
+ else
+ fclose( pFile );
pStr = Extra_FileReadContents( argv[globalUtilOptind] );
+ }
else
pStr = argv[globalUtilOptind];
- while ( pStr[ strlen(pStr) - 1 ] == '\n' || pStr[ strlen(pStr) - 1 ] == '\r' )
- pStr[ strlen(pStr) - 1 ] = '\0';
// convert truth table to SOP
if ( fHex )
- pSopCover = Abc_SopFromTruthHex(pStr);
+ vSops = Abc_SopFromTruthsHex(pStr);
else
- pSopCover = Abc_SopFromTruthBin(pStr);
+ vSops = Abc_SopFromTruthsBin(pStr);
if ( fFile )
ABC_FREE( pStr );
- if ( pSopCover == NULL || pSopCover[0] == 0 )
+ if ( Vec_PtrSize(vSops) == 0 )
{
- ABC_FREE( pSopCover );
+ Vec_PtrFreeFree( vSops );
fprintf( pAbc->Err, "Reading truth table has failed.\n" );
return 1;
}
- pNtk = Abc_NtkCreateWithNode( pSopCover );
- ABC_FREE( pSopCover );
+ pNtk = Abc_NtkCreateWithNodes( vSops );
+ Vec_PtrFreeFree( vSops );
if ( pNtk == NULL )
{
fprintf( pAbc->Err, "Deriving the network has failed.\n" );
@@ -1463,9 +1473,9 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pAbc->Err, "usage: read_truth [-xfh] <truth> <file>\n" );
- fprintf( pAbc->Err, "\t creates network with node having given truth table\n" );
- fprintf( pAbc->Err, "\t-x : toggles between bin and hex representation [default = %s]\n", fHex? "hex":"bin" );
- fprintf( pAbc->Err, "\t-f : toggles reading truth table from file [default = %s]\n", fFile? "yes": "no" );
+ fprintf( pAbc->Err, "\t creates network with node(s) having given truth table(s)\n" );
+ fprintf( pAbc->Err, "\t-x : toggles between bin and hex notation [default = %s]\n", fHex? "hex":"bin" );
+ fprintf( pAbc->Err, "\t-f : toggles reading truth table(s) from file [default = %s]\n", fFile? "yes": "no" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
fprintf( pAbc->Err, "\ttruth : truth table with most signficant bit first (e.g. 1000 for AND(a,b))\n" );
fprintf( pAbc->Err, "\tfile : file name with the truth table\n" );
@@ -3582,19 +3592,23 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
word * pTruth;
int nBytes;
int fReverse = 0;
- int fBinary = 0;
+ int fHex = 1;
+ int fBinaryFile = 0;
int c, i;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "rbh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "rxbh" ) ) != EOF )
{
switch ( c )
{
case 'r':
fReverse ^= 1;
break;
+ case 'x':
+ fHex ^= 1;
+ break;
case 'b':
- fBinary ^= 1;
+ fBinaryFile ^= 1;
break;
case 'h':
goto usage;
@@ -3632,19 +3646,22 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
Gia_ManForEachCo( pAbc->pGia, pObj, i )
{
pTruth = Gia_ObjComputeTruthTable( pAbc->pGia, pObj );
- if ( fBinary )
+ if ( fBinaryFile )
fwrite( pTruth, nBytes, 1, pFile );
- else
+ else if ( fHex )
Extra_PrintHex( pFile, (unsigned *)pTruth, Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" );
+ else
+ Extra_PrintBinary( pFile, (unsigned *)pTruth, 1 << Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" );
}
fclose( pFile );
return 0;
usage:
- fprintf( pAbc->Err, "usage: &write_truths [-rbh] <file>\n" );
+ fprintf( pAbc->Err, "usage: &write_truths [-rxbh] <file>\n" );
fprintf( pAbc->Err, "\t writes truth tables of each PO of GIA manager into a file\n" );
fprintf( pAbc->Err, "\t-r : toggle reversing bits in the truth table [default = %s]\n", fReverse? "yes":"no" );
- fprintf( pAbc->Err, "\t-b : toggle using binary format [default = %s]\n", fBinary? "yes":"no" );
+ fprintf( pAbc->Err, "\t-x : toggle writing in the hex notation [default = %s]\n", fHex? "yes":"no" );
+ fprintf( pAbc->Err, "\t-b : toggle using binary file format [default = %s]\n", fBinaryFile? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
@@ -3797,6 +3814,57 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteResub( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ extern void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName );
+ char * pFileName;
+ int c;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ pFileName = argv[globalUtilOptind];
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "IoCommandWriteResub(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( Gia_ManCiNum(pAbc->pGia) > 20 )
+ {
+ Abc_Print( -1, "IoCommandWriteResub(): The number of inputs is wrong.\n" );
+ return 1;
+ }
+ Gia_ManWriteResub( pAbc->pGia, pFileName );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: &write_resub [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network in resub format\n" );
+ fprintf( pAbc->Err, "\t-h : print the help message\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .json)\n" );
+ return 1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteGml.c b/src/base/io/ioWriteGml.c
index 49a90d9c..1164188f 100644
--- a/src/base/io/ioWriteGml.c
+++ b/src/base/io/ioWriteGml.c
@@ -61,6 +61,18 @@ void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName )
fprintf( pFile, "# GML for \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
fprintf( pFile, "graph [\n" );
+ // output constant node in the AIG if it has fanouts
+ if ( Abc_NtkIsStrash(pNtk) )
+ {
+ pObj = Abc_AigConst1( pNtk );
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ {
+ fprintf( pFile, "\n" );
+ fprintf( pFile, " node [ id %5d label \"%s\"\n", pObj->Id, Abc_ObjName(pObj) );
+ fprintf( pFile, " graphics [ type \"ellipse\" fill \"#CCCCFF\" ]\n" ); // grey
+ fprintf( pFile, " ]\n" );
+ }
+ }
// output the POs
fprintf( pFile, "\n" );
Abc_NtkForEachPo( pNtk, pObj, i )
diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c
index 693cea90..d3ce672f 100644
--- a/src/base/main/mainInit.c
+++ b/src/base/main/mainInit.c
@@ -49,6 +49,8 @@ extern void Scl_Init( Abc_Frame_t * pAbc );
extern void Scl_End( Abc_Frame_t * pAbc );
extern void Wlc_Init( Abc_Frame_t * pAbc );
extern void Wlc_End( Abc_Frame_t * pAbc );
+extern void Wln_Init( Abc_Frame_t * pAbc );
+extern void Wln_End( Abc_Frame_t * pAbc );
extern void Bac_Init( Abc_Frame_t * pAbc );
extern void Bac_End( Abc_Frame_t * pAbc );
extern void Cba_Init( Abc_Frame_t * pAbc );
@@ -116,6 +118,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
Load_Init( pAbc );
Scl_Init( pAbc );
Wlc_Init( pAbc );
+ Wln_Init( pAbc );
Bac_Init( pAbc );
Cba_Init( pAbc );
Pla_Init( pAbc );
@@ -156,6 +159,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc )
Load_End( pAbc );
Scl_End( pAbc );
Wlc_End( pAbc );
+ Wln_End( pAbc );
Bac_End( pAbc );
Cba_End( pAbc );
Pla_End( pAbc );
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index e860878e..5325adfe 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -145,6 +145,7 @@ struct Abc_Frame_t_
void * pAbc85Delay;
void * pAbcWlc;
Vec_Int_t * pAbcWlcInv;
+ void * pAbcRtl;
void * pAbcBac;
void * pAbcCba;
void * pAbcPla;
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index 6e910cd8..cf7ae5df 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -1930,9 +1930,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
// create combinational outputs in the normal manager
pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
- pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL;
- pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
- pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL;
+ pFans1 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,2)) ) : NULL; // reset
+ pFans2 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; // set
+ pFans3 = Wlc_ObjFaninNum(pObj) > 4 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,4)) ) : NULL; // enable
for ( k = 0; k < nRange; k++ )
Gia_ManAppendCo( pNew, pFans0[k] );
Gia_ManAppendCo( pNew, pFans1[0] );
@@ -2588,6 +2588,50 @@ Gia_Man_t * Wlc_BlastArray( char * pFileName )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis )
+{
+ Vec_Int_t * vPerm = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSizes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vOffs = Vec_IntAlloc( 100 );
+ Wlc_Obj_t * pObj;
+ int i, k, First, Size, nBitCis = 0, fChange = 1;
+ Wlc_NtkForEachPi( pNtk, pObj, i )
+ {
+ Vec_IntPush( vOffs, nBitCis );
+ Vec_IntPush( vSizes, Wlc_ObjRange(pObj) );
+ nBitCis += Wlc_ObjRange(pObj);
+ }
+ for ( k = 0; fChange; k++ )
+ {
+ fChange = 0;
+ Vec_IntForEachEntryTwo( vOffs, vSizes, First, Size, i )
+ if ( k < Size )
+ {
+ Vec_IntPush( vPerm, First+k );
+ fChange = 1;
+ }
+ }
+ assert( Vec_IntSize(vPerm) == nBitCis );
+ Vec_IntFree( vOffs );
+ Vec_IntFree( vSizes );
+ Vec_IntReverseOrder( vPerm );
+ for ( i = Vec_IntSize(vPerm); i < nPis; i++ )
+ Vec_IntPush( vPerm, i );
+ //Vec_IntPrint( vPerm );
+ return vPerm;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index 39f1bebd..e981e0fa 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -21,7 +21,7 @@
#include "wlc.h"
#include "base/wln/wln.h"
#include "base/main/mainInt.h"
-#include "aig/miniaig/ndr.h"
+//#include "aig/miniaig/ndr.h"
ABC_NAMESPACE_IMPL_START
@@ -88,7 +88,7 @@ void Wlc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Word level", "%memabs2", Abc_CommandMemAbs2, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 );
+// Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%retime", Abc_CommandRetime, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 );
@@ -295,7 +295,6 @@ usage:
return 1;
}
-
/**Function********************************************************************
Synopsis []
@@ -1032,12 +1031,12 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Wlc_NtkPrintInputInfo( Wlc_Ntk_t * pNtk );
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0;
+ Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0, fReorder = 0;
Wlc_BstPar_t Par, * pPar = &Par;
Wlc_BstParDefault( pPar );
pPar->nOutputRange = 2;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestnizvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestrnizvh" ) ) != EOF )
{
switch ( c )
{
@@ -1119,6 +1118,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
pPar->fCreateMiter ^= 1;
fMiter ^= 1;
break;
+ case 'r':
+ fReorder ^= 1;
+ break;
case 'n':
fDumpNames ^= 1;
break;
@@ -1198,10 +1200,19 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Finished dumping file \"pio_name_map.txt\" containing PI/PO name mapping.\n" );
}
}
+ if ( fReorder )
+ {
+ extern Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis );
+ Vec_Int_t * vPiPerm = Wlc_ComputePerm( pNtk, Gia_ManPiNum(pNew) );
+ Gia_Man_t * pTemp = Gia_ManDupPerm( pNew, vPiPerm );
+ Vec_IntFree( vPiPerm );
+ Gia_ManStop( pNew );
+ pNew = pTemp;
+ }
Abc_FrameUpdateGia( pAbc, pNew );
return 0;
usage:
- Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestnizvh]\n" );
+ Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestrnizvh]\n" );
Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" );
Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput );
Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange );
@@ -1218,6 +1229,7 @@ usage:
Abc_Print( -2, "\t-e : toggle creating miter with output word bits combined [default = %s]\n", pPar->fCreateWordMiter? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" );
Abc_Print( -2, "\t-t : toggle creating regular multi-output miter [default = %s]\n", fMiter? "yes": "no" );
+ Abc_Print( -2, "\t-r : toggle using interleaved variable ordering [default = %s]\n", fReorder? "yes": "no" );
Abc_Print( -2, "\t-n : toggle dumping signal names into a text file [default = %s]\n", fDumpNames? "yes": "no" );
Abc_Print( -2, "\t-i : toggle to print input names after blasting [default = %s]\n", fPrintInputInfo ? "yes": "no" );
Abc_Print( -2, "\t-z : toggle saving flop names after blasting [default = %s]\n", pPar->fSaveFfNames ? "yes": "no" );
diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c
index da0fc846..b2d5c5ee 100644
--- a/src/base/wlc/wlcMem.c
+++ b/src/base/wlc/wlcMem.c
@@ -800,7 +800,7 @@ void Wlc_NtkTrace_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int iFrame, Vec_Int_t *
{
int Index = 3*(iFrame*Vec_IntSize(vMemObjs) + iNum);
int Value = (int)Vec_WrdEntry( vValues, Index );
- assert( Value == 0 && Value == 1 );
+ assert( Value == 0 || Value == 1 );
Wlc_NtkTrace_rec( p, Value ? Wlc_ObjFanin2(p, pObj) : Wlc_ObjFanin1(p, pObj), iFrame, vMemObjs, vValues, ValueA, vRes );
Vec_IntPush( vRes, (iObj << 11) | (iFrame << 1) | Value );
}
diff --git a/src/base/wln/module.make b/src/base/wln/module.make
index 748c104c..c1939126 100644
--- a/src/base/wln/module.make
+++ b/src/base/wln/module.make
@@ -1,8 +1,13 @@
SRC += src/base/wln/wln.c \
+ src/base/wln/wlnBlast.c \
+ src/base/wln/wlnCom.c \
+ src/base/wln/wlnGuide.c \
src/base/wln/wlnMem.c \
src/base/wln/wlnNdr.c \
src/base/wln/wlnNtk.c \
src/base/wln/wlnObj.c \
+ src/base/wln/wlnRead.c \
src/base/wln/wlnRetime.c \
+ src/base/wln/wlnRtl.c \
src/base/wln/wlnWlc.c \
src/base/wln/wlnWriteVer.c
diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h
index 93a1a92a..c658a2fe 100644
--- a/src/base/wln/wln.h
+++ b/src/base/wln/wln.h
@@ -251,6 +251,10 @@ extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );
/*=== wlcWriteVer.c ========================================================*/
extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName );
+/*=== wlcRead.c ========================================================*/
+typedef struct Rtl_Lib_t_ Rtl_Lib_t;
+extern Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec );
+extern void Rtl_LibFree( Rtl_Lib_t * p );
ABC_NAMESPACE_HEADER_END
diff --git a/src/base/wln/wlnBlast.c b/src/base/wln/wlnBlast.c
new file mode 100644
index 00000000..a3ac73c0
--- /dev/null
+++ b/src/base/wln/wlnBlast.c
@@ -0,0 +1,388 @@
+/**CFile****************************************************************
+
+ FileName [wlnBlast.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/wlc/wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_VecExtend( Vec_Int_t * p, int nRange, int fSigned )
+{
+ Vec_IntFillExtra( p, nRange, fSigned ? Vec_IntEntryLast(p) : 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 )
+{
+ extern void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes );
+ extern int Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type );
+ extern int Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern int Wlc_NtkCountConstBits( int * pArray, int nSize );
+ extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes );
+ extern void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes );
+
+ int k, iLit, iLit0, iLit1;
+ if ( nIns == 1 )
+ {
+ Vec_Int_t * vArg = vDatas;
+ Vec_Int_t * vRes = vDatas+3;
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_BIT_INV ) // Y = ~A $not
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, Abc_LitNot(iLit) );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_BUF ) // Y = +A $pos
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, iLit );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MIN ) // Y = -A $neg
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Wlc_BlastMinus( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_AND ) // Y = &A $reduce_and
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_AND ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_OR ) // Y = |A $reduce_or $reduce_bool
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_XOR ) // Y = ^A $reduce_xor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_XOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_NXOR ) // Y = ~^A $reduce_xnor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_NXOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_NOT ) // Y = !A $logic_not
+ {
+ int iLit = Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR );
+ assert( nRange == 1 );
+ Vec_IntFill( vRes, 1, Abc_LitNot(iLit) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ assert( 0 );
+ return;
+ }
+
+ if ( nIns == 2 )
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vRes = vDatas+3;
+ int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(Vec_IntSize(vArg0), Vec_IntSize(vArg1)) );
+ int nSizeArg0 = Vec_IntSize(vArg0);
+ int nSizeArg1 = Vec_IntSize(vArg1);
+ Rtl_VecExtend( vArg0, nRangeMax, fSign0 );
+ Rtl_VecExtend( vArg1, nRangeMax, fSign1 );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_LOGIC_AND ) // Y = A && B $logic_and
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_OR ) // Y = A || B $logic_or
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+
+ if ( Type == ABC_OPER_BIT_AND ) // Y = A & B $and
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_OR ) // Y = A | B $or
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_XOR ) // Y = A ^ B $xor
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_NXOR ) // Y = A ~^ B $xnor
+ {
+ assert( Vec_IntSize(vArg0) == nRange );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Abc_LitNot(Gia_ManHashXor(pNew, iLit0, iLit1)) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
+ if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
+ if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
+ if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
+ if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
+ if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
+*/
+ if ( Type == ABC_OPER_COMP_EQU || Type == ABC_OPER_COMP_NOTEQU )
+ {
+ iLit = 0;
+ assert( nRange == 1 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, Type == ABC_OPER_COMP_EQU) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_COMP_LESS || Type == ABC_OPER_COMP_LESSEQU ||
+ Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_MOREEQU )
+ {
+ int fSigned = fSign0 && fSign1;
+ int fSwap = (Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_LESSEQU);
+ int fCompl = (Type == ABC_OPER_COMP_MOREEQU || Type == ABC_OPER_COMP_LESSEQU);
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( nRange == 1 );
+ if ( fSwap )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fSigned )
+ iLit = Wlc_BlastLessSigned( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ else
+ iLit = Wlc_BlastLess( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ iLit = Abc_LitNotCond( iLit, fCompl );
+ Vec_IntFill( vRes, 1, iLit );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
+ if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
+ if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
+ if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
+*/
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA ||
+ Type == ABC_OPER_SHIFT_L || Type == ABC_OPER_SHIFT_LA )
+ {
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA )
+ Wlc_BlastShiftRight( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, fSign0 && Type == ABC_OPER_SHIFT_RA, vRes );
+ else
+ Wlc_BlastShiftLeft( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, 0, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
+ if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
+ if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
+ if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
+ if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
+ if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
+*/
+ if ( Type == ABC_OPER_ARI_ADD || Type == ABC_OPER_ARI_SUB )
+ {
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ Vec_IntAppend( vRes, vArg0 );
+ if ( Type == ABC_OPER_ARI_ADD )
+ Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 0 ); // result is in pFan0 (vRes)
+ else
+ Wlc_BlastSubtract( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 1 ); // result is in pFan0 (vRes)
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MUL )
+ {
+ int fBooth = 1;
+ int fCla = 0;
+ int fSigned = fSign0 && fSign1;
+ Vec_IntShrink( vArg0, nSizeArg0 );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fBooth )
+ Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ else
+ Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ if ( nRange > Vec_IntSize(vRes) )
+ Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
+ else
+ Vec_IntShrink( vRes, nRange );
+ assert( Vec_IntSize(vRes) == nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_DIV || Type == ABC_OPER_ARI_MOD )
+ {
+ int fDivBy0 = 1; // correct with 1
+ int fSigned = fSign0 && fSign1;
+ if ( fSigned )
+ Wlc_BlastDividerSigned( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ else
+ Wlc_BlastDivider( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ Vec_IntShrink( vRes, nRange );
+ if ( !fDivBy0 )
+ Wlc_BlastZeroCondition( pNew, Vec_IntArray(vArg1), nRange, vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_POW )
+ {
+ Vec_Int_t * vTemp = vDatas+4;
+ Vec_IntGrow( vTemp, nRangeMax );
+ Vec_IntGrow( vRes, nRangeMax );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ Wlc_BlastPower( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), Vec_IntSize(vArg1), vTemp, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ }
+
+ if ( nIns == 3 )
+ {
+ if ( Type == ABC_OPER_SEL_NMUX ) // $mux
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ int iCtrl = Vec_IntEntry(vArgS, 0);
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ //Vec_IntPrint( vArgS );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vArg0) == nRange );
+ assert( Vec_IntSize(vArgS) == 1 );
+ assert( Vec_IntSize(vRes) == 0 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashMux(pNew, iCtrl, iLit1, iLit0) );
+ return;
+ }
+ if ( Type == ABC_OPER_SEL_SEL ) // $pmux
+ {
+ int i, k, iLit;
+ Vec_Int_t * vArgA = vDatas;
+ Vec_Int_t * vArgB = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ Vec_Int_t * vTemp = vDatas+4;
+ assert( Vec_IntSize(vArgA) == nRange ); // widthA = widthY
+ assert( Vec_IntSize(vArgB) == Vec_IntSize(vArgA)*Vec_IntSize(vArgS) ); // widthB == widthA*widthS
+ assert( Vec_IntSize(vRes) == 0 );
+ for ( i = 0; i < nRange; i++ )
+ {
+ int iCond = 1;
+ Vec_IntClear( vTemp );
+ Vec_IntForEachEntry( vArgS, iLit, k ) // iLit = S[i]
+ {
+ //Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i]
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*k+i)) ) ); // B[widthA*k+i]
+ iCond = Gia_ManHashAnd( pNew, iCond, Abc_LitNot(iLit) );
+ }
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iCond, Vec_IntEntry(vArgA, i)) ) );
+ Vec_IntPush( vRes, Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ) );
+ }
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c
new file mode 100644
index 00000000..eb96132b
--- /dev/null
+++ b/src/base/wln/wlnCom.c
@@ -0,0 +1,532 @@
+/**CFile****************************************************************
+
+ FileName [wlnCom.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnCom.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/main/mainInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandHierarchy ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static inline Rtl_Lib_t * Wln_AbcGetRtl( Abc_Frame_t * pAbc ) { return (Rtl_Lib_t *)pAbc->pAbcRtl; }
+static inline void Wln_AbcFreeRtl( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wln_AbcGetRtl(pAbc)); }
+static inline void Wln_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib ) { Wln_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_Init( Abc_Frame_t * pAbc )
+{
+ Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%hierarchy", Abc_CommandHierarchy, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%collapse", Abc_CommandCollapse, 0 );
+ //Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%print", Abc_CommandPrint, 0 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Wln_End( Abc_Frame_t * pAbc )
+{
+ Wln_AbcUpdateRtl( pAbc, NULL );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose );
+ extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose );
+
+ FILE * pFile;
+ char * pFileName = NULL;
+ char * pTopModule= NULL;
+ int fBlast = 0;
+ int fInvert = 0;
+ int fTechMap = 1;
+ int fSkipStrash = 0;
+ int fCollapse = 0;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" );
+ goto usage;
+ }
+ pTopModule = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'b':
+ fBlast ^= 1;
+ break;
+ case 'i':
+ fInvert ^= 1;
+ break;
+ case 's':
+ fSkipStrash ^= 1;
+ break;
+ case 'm':
+ fTechMap ^= 1;
+ break;
+ case 'c':
+ fCollapse ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ {
+ printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" );
+ return 0;
+ }
+ // get the file name
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
+ {
+ Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName );
+ if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( 1, "\n" );
+ return 0;
+ }
+ fclose( pFile );
+
+ // perform reading
+ if ( fBlast )
+ {
+ Gia_Man_t * pNew = NULL;
+ if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else
+ {
+ printf( "Abc_CommandYosys(): Unknown file extension.\n" );
+ return 0;
+ }
+ Abc_FrameUpdateGia( pAbc, pNew );
+ }
+ else
+ {
+ Rtl_Lib_t * pLib = NULL;
+ if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else
+ {
+ printf( "Abc_CommandYosys(): Unknown file extension.\n" );
+ return 0;
+ }
+ Wln_AbcUpdateRtl( pAbc, pLib );
+ }
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%yosys [-T <module>] [-bismcvh] <file_name>\n" );
+ Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" );
+ Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" );
+ Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" );
+ Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" );
+ Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose );
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ char ** pArgvNew; int nArgcNew;
+ int c, fInv = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'i':
+ fInv ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 0 && nArgcNew != 2 )
+ {
+ Abc_Print( -1, "Abc_CommandGraft(): This command expects one AIG file name on the command line.\n" );
+ return 1;
+ }
+ Wln_LibGraftOne( pLib, pArgvNew, nArgcNew, fInv, fVerbose );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%graft [-ivh] <module1_name> <module2_name>\n" );
+ Abc_Print( -2, "\t replace instances of module1 by those of module2\n" );
+ Abc_Print( -2, "\t-i : toggle using inverse grafting [default = %s]\n", fInv? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandHierarchy( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose );
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ char ** pArgvNew; int nArgcNew;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew < 0 )
+ {
+ Abc_Print( -1, "Abc_CommandHierarchy(): This command expects one AIG file name on the command line.\n" );
+ return 1;
+ }
+ Wln_LibMarkHierarchy( pLib, pArgvNew, nArgcNew, fVerbose );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%hierarchy [-vh] <module_name>\n" );
+ Abc_Print( -2, "\t marks the module whose instances may later be treated as black boxes\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose );
+ Gia_Man_t * pNew = NULL;
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ char * pTopModule = NULL;
+ int c, fInv = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Tcvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" );
+ goto usage;
+ }
+ pTopModule = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'c':
+ fInv ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ pNew = Rtl_LibCollapse( pLib, pTopModule, fVerbose );
+ if ( fInv )
+ Gia_ManInvertPos( pNew );
+ Abc_FrameUpdateGia( pAbc, pNew );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%collapse [-T <module>] [-cvh] <file_name>\n" );
+ Abc_Print( -2, "\t collapse hierarchical design into an AIG\n" );
+ Abc_Print( -2, "\t-T : specify the top module of the design [default = none]\n" );
+ Abc_Print( -2, "\t-c : toggle complementing miter outputs after collapsing [default = %s]\n", fInv? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandPrint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Rtl_LibPrintStats( Rtl_Lib_t * p );
+ extern void Rtl_LibPrintHieStats( Rtl_Lib_t * p );
+ extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p );
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ int c, fHie = 0, fDesign = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "pdvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'p':
+ fHie ^= 1;
+ break;
+ case 'd':
+ fDesign ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ Rtl_LibPrintStats( pLib );
+ if ( fHie )
+ Rtl_LibPrintHieStats( pLib );
+ if ( fDesign )
+ Rtl_LibPrint( NULL, pLib );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%print [-pdvh]\n" );
+ Abc_Print( -2, "\t print statistics about the hierarchical design\n" );
+ Abc_Print( -2, "\t-p : toggle printing of the hierarchy [default = %s]\n", fHie? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle printing of the design [default = %s]\n", fDesign? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : text file name with guidance for solving\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Rtl_LibBlast( Rtl_Lib_t * pLib );
+ extern void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots, int fInv );
+ extern void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk );
+ extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib );
+ extern void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p );
+
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ int c, fOldBlast = 0, fPrepro = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'o':
+ fOldBlast ^= 1;
+ break;
+ case 'p':
+ fPrepro ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ char * pFileName = argv[globalUtilOptind];
+ FILE * pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ Abc_Print( -1, "Cannot open file \"%s\" with the input test patterns.\n", pFileName );
+ return 0;
+ }
+ fclose( pFile );
+ printf( "Using guidance from file \"%s\".\n", pFileName );
+ Wln_SolveWithGuidance( pFileName, pLib );
+ }
+ else
+ {
+ printf( "Solving the miter without guidance.\n" );
+ if ( fOldBlast )
+ Rtl_LibBlast( pLib );
+ else
+ Rtl_LibBlast2( pLib, NULL, 0 );
+ if ( fPrepro )
+ Rtl_LibPreprocess( pLib );
+ Rtl_LibSolve( pLib, NULL );
+ }
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%solve [-opvh] <file>\n" );
+ Abc_Print( -2, "\t solving properties for the hierarchical design\n" );
+ Abc_Print( -2, "\t-o : toggle using old bit-blasting procedure [default = %s]\n", fOldBlast? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : text file name with guidance for solving\n");
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnGuide.c b/src/base/wln/wlnGuide.c
new file mode 100644
index 00000000..b7e656eb
--- /dev/null
+++ b/src/base/wln/wlnGuide.c
@@ -0,0 +1,95 @@
+/**CFile****************************************************************
+
+ FileName [wln.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p )
+{
+ char * pBuffer = Abc_UtilStrsavTwo( "\\", pToken );
+ int RetValue = Abc_NamStrFindOrAdd( p, pBuffer, NULL );
+ ABC_FREE( pBuffer );
+ return RetValue;
+}
+void Wln_PrintGuidance( Vec_Wec_t * vGuide, Abc_Nam_t * p )
+{
+ Vec_Int_t * vLevel; int i, k, Obj;
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ Vec_IntForEachEntry( vLevel, Obj, k )
+ printf( "%s ", Obj >= 0 ? Abc_NamStr(p, Obj) : "[unknown]" );
+ printf( "\n" );
+ }
+}
+Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p )
+{
+ char * pBuffer = ABC_CALLOC( char, 10000 ), * pToken;
+ Vec_Wec_t * vTokens = Vec_WecAlloc( 100 ); Vec_Int_t * vLevel;
+ FILE * pFile = fopen( pFileName, "rb" );
+ while ( fgets( pBuffer, 10000, pFile ) )
+ {
+ if ( pBuffer[0] == '#' )
+ continue;
+ vLevel = Vec_WecPushLevel( vTokens );
+ pToken = strtok( pBuffer, " \t\r\n" );
+ while ( pToken )
+ {
+ Vec_IntPush( vLevel, Vec_IntSize(vLevel) < 2 ? Abc_NamStrFindOrAdd(p, pToken, NULL) : Wln_ReadFindToken(pToken, p) );
+ pToken = strtok( NULL, " \t\r\n" );
+ }
+ if ( Vec_IntSize(vLevel) % 4 == 3 ) // account for "property"
+ Vec_IntPush( vLevel, -1 );
+ assert( Vec_IntSize(vLevel) % 4 == 0 );
+ }
+ fclose( pFile );
+ if ( Vec_WecSize(vTokens) == 0 )
+ printf( "Guidance is empty.\n" );
+ //Wln_PrintGuidance( vTokens, p );
+ ABC_FREE( pBuffer );
+ return vTokens;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c
new file mode 100644
index 00000000..a27d38d2
--- /dev/null
+++ b/src/base/wln/wlnRead.c
@@ -0,0 +1,2866 @@
+/**CFile****************************************************************
+
+ FileName [wln.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "proof/cec/cec.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_LINE 1000000
+
+#define MAX_MAP 32
+#define CELL_NUM 8
+#define WIRE_NUM 5
+#define TEMP_NUM 5
+#define CONST_SHIFT 99
+
+//typedef struct Rtl_Lib_t_ Rtl_Lib_t;
+struct Rtl_Lib_t_
+{
+ char * pSpec; // input file name
+ Vec_Ptr_t * vNtks; // modules
+ Abc_Nam_t * pManName; // object names
+ Vec_Int_t vConsts; // constants
+ Vec_Int_t vSlices; // selections
+ Vec_Int_t vConcats; // concatenations
+ FILE * pFile; // temp file
+ Vec_Int_t * vTokens; // temp tokens
+ int pMap[MAX_MAP]; // temp map
+ Vec_Int_t * vMap; // mapping NameId into wires
+ Vec_Int_t * vDirects; // direct equivalences
+ Vec_Int_t * vInverses; // inverse equivalences
+ Vec_Int_t vAttrTemp; // temp
+ Vec_Int_t vTemp[TEMP_NUM]; // temp
+};
+
+typedef struct Rtl_Ntk_t_ Rtl_Ntk_t;
+struct Rtl_Ntk_t_
+{
+ int NameId; // model name
+ int nInputs; // word-level inputs
+ int nOutputs; // word-level outputs
+ Vec_Int_t vWires; // wires (name{upto,signed,in,out}+width+offset+number)
+ Vec_Int_t vCells; // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[7]mark+(attr+params+conns))
+ Vec_Int_t vConns; // connection pairs
+ Vec_Int_t vStore; // storage for cells
+ Vec_Int_t vAttrs; // attributes
+ Rtl_Lib_t * pLib; // parent
+ Vec_Int_t vOrder; // topological order
+ Vec_Int_t vLits; // bit-level view
+ Vec_Int_t vDrivers; // bit-level view
+ Vec_Int_t vBitTemp; // storage for bits
+ Vec_Int_t vBitTemp2; // storage for bits
+ Gia_Man_t * pGia; // derived by bit-blasting
+ int Slice0; // first slice
+ int Slice1; // last slice
+ int iCopy; // place in array
+ int fRoot; // denote root network
+};
+
+static inline int Rtl_LibNtkNum( Rtl_Lib_t * pLib ) { return Vec_PtrSize(pLib->vNtks); }
+static inline Rtl_Ntk_t * Rtl_LibNtk( Rtl_Lib_t * pLib, int i ) { return (Rtl_Ntk_t *)Vec_PtrEntry(pLib->vNtks, i); }
+static inline Rtl_Ntk_t * Rtl_LibTop( Rtl_Lib_t * pLib ) { return Rtl_LibNtk( pLib, Rtl_LibNtkNum(pLib)-1 ); }
+static inline char * Rtl_LibStr( Rtl_Lib_t * pLib, int h ) { return Abc_NamStr(pLib->pManName, h); }
+static inline int Rtl_LibStrId( Rtl_Lib_t * pLib, char * s ) { return Abc_NamStrFind(pLib->pManName, s); }
+
+static inline Rtl_Ntk_t * Rtl_NtkModule( Rtl_Ntk_t * p, int i ) { return Rtl_LibNtk( p->pLib, i ); }
+
+static inline int Rtl_NtkStrId( Rtl_Ntk_t * p, char * s ) { return Abc_NamStrFind(p->pLib->pManName, s); }
+static inline char * Rtl_NtkStr( Rtl_Ntk_t * p, int h ) { return Abc_NamStr(p->pLib->pManName, h); }
+static inline char * Rtl_NtkName( Rtl_Ntk_t * p ) { return Rtl_NtkStr(p, p->NameId); }
+
+static inline FILE * Rtl_NtkFile( Rtl_Ntk_t * p ) { return p->pLib->pFile; }
+static inline int Rtl_NtkTokId( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Vec_IntEntry(p->pLib->vTokens, i) : -1; }
+static inline char * Rtl_NtkTokStr( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Rtl_NtkStr(p, Vec_IntEntry(p->pLib->vTokens, i)) : NULL; }
+static inline int Rtl_NtkTokCheck( Rtl_Ntk_t * p, int i, int Tok ) { return i == p->pLib->pMap[Tok]; }
+static inline int Rtl_NtkPosCheck( Rtl_Ntk_t * p, int i, int Tok ) { return Vec_IntEntry(p->pLib->vTokens, i) == p->pLib->pMap[Tok]; }
+
+static inline int Rtl_NtkInputNum( Rtl_Ntk_t * p ) { return p->nInputs; }
+static inline int Rtl_NtkOutputNum( Rtl_Ntk_t * p ) { return p->nOutputs; }
+static inline int Rtl_NtkAttrNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vAttrs)/2; }
+static inline int Rtl_NtkWireNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vWires)/WIRE_NUM; }
+static inline int Rtl_NtkCellNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vCells); }
+static inline int Rtl_NtkConNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vConns)/2; }
+static inline int Rtl_NtkObjNum( Rtl_Ntk_t * p ) { return p->nInputs + p->nOutputs + Rtl_NtkCellNum(p) + Rtl_NtkConNum(p); }
+
+static inline int * Rtl_NtkWire( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vWires, WIRE_NUM*i); }
+static inline int * Rtl_NtkCell( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vStore, Vec_IntEntry(&p->vCells, i)); }
+static inline int * Rtl_NtkCon( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vConns, 2*i); }
+
+static inline int Rtl_WireName( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i) >> 4; }
+static inline char * Rtl_WireNameStr( Rtl_Ntk_t * p, int i ) { return Rtl_NtkStr(p, Rtl_WireName(p, i)); }
+static inline int Rtl_WireFirst( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i); }
+static inline int Rtl_WireWidth( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+1); }
+static inline int Rtl_WireOffset( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+2); }
+static inline int Rtl_WireNumber( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+3); }
+static inline int Rtl_WireBitStart( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+4); }
+static inline int Rtl_WireMapNameToId( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(p->pLib->vMap, i); }
+
+static inline int Rtl_CellType( int * pCell ) { return pCell[0]; }
+static inline int Rtl_CellName( int * pCell ) { return pCell[1]; }
+static inline int Rtl_CellModule( int * pCell ) { return pCell[2]; }
+static inline int Rtl_CellInputNum( int * pCell ) { return pCell[3]; }
+static inline int Rtl_CellOutputNum( int * pCell ) { return pCell[6]-pCell[3]; }
+static inline int Rtl_CellAttrNum( int * pCell ) { return pCell[4]; }
+static inline int Rtl_CellParamNum( int * pCell ) { return pCell[5]; }
+static inline int Rtl_CellConNum( int * pCell ) { return pCell[6]; }
+static inline int Rtl_CellMark( int * pCell ) { return pCell[7]; }
+static inline Rtl_Ntk_t * Rtl_CellNtk( Rtl_Ntk_t * p, int * pCell ) { return Rtl_CellModule(pCell) >= ABC_INFINITY ? Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY) : NULL; }
+
+static inline char * Rtl_CellTypeStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellType(pCell)); }
+static inline char * Rtl_CellNameStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellName(pCell)); }
+
+static inline int Rtl_SigIsNone( int s ) { return (s & 0x3) == 0; }
+static inline int Rtl_SigIsConst( int s ) { return (s & 0x3) == 1; }
+static inline int Rtl_SigIsSlice( int s ) { return (s & 0x3) == 2; }
+static inline int Rtl_SigIsConcat( int s ) { return (s & 0x3) == 3; }
+
+#define Rtl_NtkForEachAttr( p, Par, Val, i ) \
+ for ( i = 0; i < Rtl_NtkAttrNum(p) && (Par = Vec_IntEntry(&p->vAttrs, 2*i)) && (Val = Vec_IntEntry(&p->vAttrs, 2*i+1)); i++ )
+#define Rtl_NtkForEachWire( p, pWire, i ) \
+ for ( i = 0; i < Rtl_NtkWireNum(p) && (pWire = Vec_IntEntryP(&p->vWires, WIRE_NUM*i)); i++ )
+#define Rtl_NtkForEachCell( p, pCell, i ) \
+ for ( i = 0; i < Rtl_NtkCellNum(p) && (pCell = Rtl_NtkCell(p, i)); i++ )
+#define Rtl_NtkForEachCon( p, pCon, i ) \
+ for ( i = 0; i < Rtl_NtkConNum(p) && (pCon = Vec_IntEntryP(&p->vConns, 2*i)); i++ )
+
+#define Rtl_CellForEachAttr( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[4] && (Par = pCell[CELL_NUM+2*i]) && (Val = pCell[CELL_NUM+2*i+1]); i++ )
+#define Rtl_CellForEachParam( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[5] && (Par = pCell[CELL_NUM+2*(pCell[4]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+i)+1]); i++ )
+#define Rtl_CellForEachConnect( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[6] && (Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)+1]); i++ )
+
+#define Rtl_CellForEachInput( p, pCell, Par, Val, i ) \
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i >= Rtl_CellInputNum(pCell) ) continue; else
+#define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else
+
+extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+extern int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia );
+extern int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rtl_Ntk_t * Rtl_NtkAlloc( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p = ABC_CALLOC( Rtl_Ntk_t, 1 );
+ Vec_IntGrow( &p->vWires, 4 );
+ Vec_IntGrow( &p->vCells, 4 );
+ Vec_IntGrow( &p->vConns, 4 );
+ Vec_IntGrow( &p->vStore, 8 );
+ Vec_IntGrow( &p->vAttrs, 8 );
+ Vec_PtrPush( pLib->vNtks, (void *)p );
+ p->pLib = pLib;
+ return p;
+}
+void Rtl_NtkFree( Rtl_Ntk_t * p )
+{
+ Gia_ManStopP( &p->pGia );
+ ABC_FREE( p->vWires.pArray );
+ ABC_FREE( p->vCells.pArray );
+ ABC_FREE( p->vConns.pArray );
+ ABC_FREE( p->vStore.pArray );
+ ABC_FREE( p->vAttrs.pArray );
+ ABC_FREE( p->vOrder.pArray );
+ ABC_FREE( p->vLits.pArray );
+ ABC_FREE( p->vDrivers.pArray );
+ ABC_FREE( p->vBitTemp.pArray );
+ ABC_FREE( p->vBitTemp2.pArray );
+ ABC_FREE( p );
+}
+void Rtl_NtkCountPio( Rtl_Ntk_t * p, int Counts[4] )
+{
+ int i, * pWire;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ Counts[0]++, Counts[1] += pWire[1];
+ if ( pWire[0] & 2 ) // PO
+ Counts[2]++, Counts[3] += pWire[1];
+ }
+ assert( p->nInputs == Counts[0] );
+ assert( p->nOutputs == Counts[2] );
+}
+void Rtl_NtkPrintOpers( Rtl_Ntk_t * p )
+{
+ int i, * pCell, nBlack = 0, nUser = 0, Counts[ABC_OPER_LAST] = {0};
+ if ( Rtl_NtkCellNum(p) == 0 )
+ return;
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Counts[Rtl_CellModule(pCell)]++;
+ else if ( Rtl_CellModule(pCell) == ABC_OPER_LAST-1 )
+ nBlack++;
+ else
+ nUser++;
+ printf( "There are %d instances in this network:\n", Rtl_NtkCellNum(p) );
+ if ( nBlack )
+ printf( " %s (%d)", "blackbox", nBlack );
+ if ( nUser )
+ printf( " %s (%d)", "user", nUser );
+ for ( i = 0; i < ABC_OPER_LAST; i++ )
+ if ( Counts[i] )
+ printf( " %s (%d)", Abc_OperName(i), Counts[i] );
+ printf( "\n" );
+}
+void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs )
+{
+ int Counts[4] = {0}; Rtl_NtkCountPio( p, Counts );
+ printf( "%*s : ", nNameSymbs, Rtl_NtkName(p) );
+ printf( "PI = %5d (%5d) ", Counts[0], Counts[1] );
+ printf( "PO = %5d (%5d) ", Counts[2], Counts[3] );
+ printf( "Wire = %6d ", Rtl_NtkWireNum(p) );
+ printf( "Cell = %6d ", Rtl_NtkCellNum(p) );
+ printf( "Con = %6d", Rtl_NtkConNum(p) );
+ printf( "\n" );
+ //Rtl_NtkPrintOpers( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkPrintHieStats( Rtl_Ntk_t * p, int nOffset )
+{
+ Vec_Int_t * vFound = Vec_IntAlloc( 100 );
+ int i, * pCell;
+ for ( i = 0; i < 5*(nOffset-1); i++ )
+ printf( " " );
+ if ( nOffset )
+ printf( "|--> " );
+ printf( "%s\n", Rtl_NtkName(p) );
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ {
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ assert( pCell[6] == pModel->nInputs+pModel->nOutputs );
+ if ( Vec_IntFind(vFound, pModel->NameId) >= 0 )
+ continue;
+ Vec_IntPush( vFound, pModel->NameId );
+ Rtl_NtkPrintHieStats( pModel, nOffset+1 );
+ }
+ Vec_IntFree( vFound );
+}
+void Rtl_LibPrintHieStats( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ printf( "Hierarchy found in \"%s\":\n", p->pSpec );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ {
+ printf( "\n" );
+ printf( "MODULE %d: ", i );
+ Rtl_NtkPrintHieStats( pNtk, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rtl_Lib_t * Rtl_LibAlloc()
+{
+ Rtl_Lib_t * p = ABC_CALLOC( Rtl_Lib_t, 1 );
+ p->vNtks = Vec_PtrAlloc( 100 );
+ Vec_IntGrow( &p->vConsts, 1000 );
+ Vec_IntGrow( &p->vSlices, 1000 );
+ Vec_IntGrow( &p->vConcats, 1000 );
+ return p;
+}
+void Rtl_LibFree( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkFree( pNtk );
+ ABC_FREE( p->vConsts.pArray );
+ ABC_FREE( p->vSlices.pArray );
+ ABC_FREE( p->vConcats.pArray );
+ ABC_FREE( p->vAttrTemp.pArray );
+ for ( i = 0; i < TEMP_NUM; i++ )
+ ABC_FREE( p->vTemp[i].pArray );
+ Vec_IntFreeP( &p->vMap );
+ Vec_IntFreeP( &p->vDirects );
+ Vec_IntFreeP( &p->vInverses );
+ Vec_IntFreeP( &p->vTokens );
+ Abc_NamStop( p->pManName );
+ Vec_PtrFree( p->vNtks );
+ ABC_FREE( p->pSpec );
+ ABC_FREE( p );
+}
+int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( pNtk->NameId == NameId )
+ return i;
+ return -1;
+}
+int Rtl_LibFindModule2( Rtl_Lib_t * p, int NameId, int iNtk0 )
+{
+ char * pName = Rtl_LibStr( p, NameId );
+ Rtl_Ntk_t * pNtk0 = Rtl_LibNtk( p, iNtk0 );
+ Rtl_Ntk_t * pNtk; int i;
+ int Counts0[4] = {0}; Rtl_NtkCountPio( pNtk0, Counts0 );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( strstr(Rtl_NtkName(pNtk), pName+1) )
+ {
+ int Counts[4] = {0}; Rtl_NtkCountPio( pNtk, Counts );
+ if ( Counts[1] == Counts0[1] && Counts[3] == Counts0[3] )
+ return i;
+ }
+ return -1;
+}
+int Rtl_LibFindTwoModules( Rtl_Lib_t * p, int Name1, int Name2 )
+{
+ int iNtk1 = Rtl_LibFindModule( p, Name1 );
+ if ( Name2 == -1 )
+ return (iNtk1 << 16) | iNtk1;
+ else if ( iNtk1 == -1 )
+ return -1;
+ else
+ {
+ int Counts1[4] = {0}, Counts2[4] = {0};
+ int iNtk2 = Rtl_LibFindModule( p, Name2 );
+ if ( iNtk2 == -1 )
+ return -1;
+ else
+ {
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ Rtl_NtkCountPio( pNtk1, Counts1 );
+ Rtl_NtkCountPio( pNtk2, Counts2 );
+ if ( Counts1[1] != Counts2[1] || Counts1[3] != Counts2[3] )
+ iNtk1 = Rtl_LibFindModule2( p, Name1, iNtk2 );
+ return (iNtk1 << 16) | iNtk2;
+ }
+ }
+}
+void Rtl_LibPrintStats( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i, nSymbs = 0;
+ printf( "Modules found in \"%s\":\n", p->pSpec );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ nSymbs = Abc_MaxInt( nSymbs, strlen(Rtl_NtkName(pNtk)) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkPrintStats( pNtk, nSymbs + 2 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+typedef enum {
+ RTL_NONE = 0, // 0: unused
+ RTL_MODULE, // 1: "module"
+ RTL_END, // 2: "end"
+ RTL_INPUT, // 3: "input"
+ RTL_OUTPUT, // 4: "output"
+ RTL_INOUT, // 5: "inout"
+ RTL_UPTO, // 6: "upto"
+ RTL_SIGNED, // 7: "signed"
+ RTL_OFFSET, // 8: "offset"
+ RTL_PARAMETER, // 9: "parameter"
+ RTL_WIRE, // 10: "wire"
+ RTL_CONNECT, // 11: "connect"
+ RTL_CELL, // 12: "cell"
+ RTL_WIDTH, // 13: "width"
+ RTL_ATTRIBUTE, // 14: "attribute"
+ RTL_UNUSED // 15: unused
+} Rtl_Type_t;
+
+static inline char * Rtl_Num2Name( int i )
+{
+ if ( i == 1 ) return "module";
+ if ( i == 2 ) return "end";
+ if ( i == 3 ) return "input";
+ if ( i == 4 ) return "output";
+ if ( i == 5 ) return "inout";
+ if ( i == 6 ) return "upto";
+ if ( i == 7 ) return "signed";
+ if ( i == 8 ) return "offset";
+ if ( i == 9 ) return "parameter";
+ if ( i == 10 ) return "wire";
+ if ( i == 11 ) return "connect";
+ if ( i == 12 ) return "cell";
+ if ( i == 13 ) return "width";
+ if ( i == 14 ) return "attribute";
+ return NULL;
+}
+
+static inline void Rtl_LibDeriveMap( Rtl_Lib_t * p )
+{
+ int i;
+ p->pMap[0] = -1;
+ for ( i = 1; i < RTL_UNUSED; i++ )
+ p->pMap[i] = Abc_NamStrFind( p->pManName, Rtl_Num2Name(i) );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rtl_LibReadType( char * pType )
+{
+ if ( !strcmp(pType, "$not") ) return ABC_OPER_BIT_INV; // Y = ~A $not
+ if ( !strcmp(pType, "$pos") ) return ABC_OPER_BIT_BUF; // Y = +A $pos
+ if ( !strcmp(pType, "$neg") ) return ABC_OPER_ARI_MIN; // Y = -A $neg
+ if ( !strcmp(pType, "$reduce_and") ) return ABC_OPER_RED_AND; // Y = &A $reduce_and
+ if ( !strcmp(pType, "$reduce_or") ) return ABC_OPER_RED_OR; // Y = |A $reduce_or
+ if ( !strcmp(pType, "$reduce_xor") ) return ABC_OPER_RED_XOR; // Y = ^A $reduce_xor
+ if ( !strcmp(pType, "$reduce_xnor") ) return ABC_OPER_RED_NXOR; // Y = ~^A $reduce_xnor
+ if ( !strcmp(pType, "$reduce_bool") ) return ABC_OPER_RED_OR; // Y = |A $reduce_bool
+ if ( !strcmp(pType, "$logic_not") ) return ABC_OPER_LOGIC_NOT; // Y = !A $logic_not
+
+ if ( !strcmp(pType, "$and") ) return ABC_OPER_BIT_AND; // Y = A & B $and
+ if ( !strcmp(pType, "$or") ) return ABC_OPER_BIT_OR; // Y = A | B $or
+ if ( !strcmp(pType, "$xor") ) return ABC_OPER_BIT_XOR; // Y = A ^ B $xor
+ if ( !strcmp(pType, "$xnor") ) return ABC_OPER_BIT_NXOR; // Y = A ~^ B $xnor
+
+ if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
+ if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
+ if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
+ if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
+
+ if ( !strcmp(pType, "$shiftx") ) return ABC_OPER_SHIFT_R; // Y = A << B $shl <== temporary
+
+ if ( !strcmp(pType, "$logic_and") ) return ABC_OPER_LOGIC_AND; // Y = A && B $logic_and
+ if ( !strcmp(pType, "$logic_or") ) return ABC_OPER_LOGIC_OR; // Y = A || B $logic_or
+
+ if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
+ if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
+ if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
+ if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
+ if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
+ if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
+ if ( !strcmp(pType, "$eqx") ) return ABC_OPER_COMP_EQU; // Y = A === B $eqx
+ if ( !strcmp(pType, "$nex") ) return ABC_OPER_COMP_NOTEQU; // Y = A !== B $nex
+
+ if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
+ if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
+ if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
+ if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
+ if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
+ if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
+
+ if ( !strcmp(pType, "$modfoor") ) return ABC_OPER_NONE; // [N/A] $modfoor
+ if ( !strcmp(pType, "$divfloor") ) return ABC_OPER_NONE; // [N/A] $divfloor
+
+ if ( !strcmp(pType, "$mux") ) return ABC_OPER_SEL_NMUX; // $mux
+ if ( !strcmp(pType, "$pmux") ) return ABC_OPER_SEL_SEL; // $pmux
+
+ if ( !strcmp(pType, "$dff") ) return ABC_OPER_DFF;
+ if ( !strcmp(pType, "$adff") ) return ABC_OPER_DFF;
+ if ( !strcmp(pType, "$sdff") ) return ABC_OPER_DFF;
+ assert( 0 );
+ return -1;
+}
+int Rtl_NtkReadType( Rtl_Ntk_t * p, int Type )
+{
+ extern int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId );
+ char * pType = Rtl_NtkStr( p, Type );
+ if ( pType[0] == '$' && strncmp(pType,"$paramod",strlen("$paramod")) )
+ return Rtl_LibReadType( pType );
+ return ABC_INFINITY + Rtl_LibFindModule( p->pLib, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [There is no need to normalize ranges in Yosys.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rtl_NtkRangeWires( Rtl_Ntk_t * p )
+{
+ int i, * pWire, nBits = 0;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ //printf( "%s -> %d\n", Rtl_WireNameStr(p, i), nBits );
+ pWire[4] = nBits, nBits += Rtl_WireWidth(p, i);
+ }
+ return nBits;
+}
+void Rtl_NtkMapWires( Rtl_Ntk_t * p, int fUnmap )
+{
+ int i, Value;
+ assert( Vec_IntSize(p->pLib->vMap) == Abc_NamObjNumMax(p->pLib->pManName) );
+ for ( i = 0; i < Rtl_NtkWireNum(p); i++ )
+ {
+ int NameId = Rtl_WireName( p, i );
+ assert( Vec_IntEntry(p->pLib->vMap, NameId) == (fUnmap ? i : -1) );
+ Vec_IntWriteEntry( p->pLib->vMap, NameId, fUnmap ? -1 : i );
+ }
+ if ( fUnmap )
+ Vec_IntForEachEntry( p->pLib->vMap, Value, i )
+ assert( Value == -1 );
+}
+void Rtl_NtkNormRanges( Rtl_Ntk_t * p )
+{
+ int i, * pWire;
+ Rtl_NtkMapWires( p, 0 );
+ for ( i = p->Slice0; i < p->Slice1; i += 3 )
+ {
+ int NameId = Vec_IntEntry( &p->pLib->vSlices, i );
+ int Left = Vec_IntEntry( &p->pLib->vSlices, i+1 );
+ int Right = Vec_IntEntry( &p->pLib->vSlices, i+2 );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int Offset = Rtl_WireOffset( p, Wire );
+ int First = Rtl_WireFirst( p, Wire );
+ assert( First >> 4 == NameId );
+ if ( Offset );
+ {
+ Left -= Offset;
+ Right -= Offset;
+ }
+ if ( First & 8 ) // upto
+ {
+ Vec_IntWriteEntry( &p->pLib->vSlices, i+1, Right );
+ Vec_IntWriteEntry( &p->pLib->vSlices, i+2, Left );
+ }
+ }
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+0, Rtl_WireFirst(p, i) & ~0x8 ); // upto
+ Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+2, 0 ); // offset
+ }
+ Rtl_NtkMapWires( p, 1 );
+}
+void Rtl_LibNormRanges( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkNormRanges( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Rlt_NtkFindIOPerm( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vCost = Vec_IntAlloc( 100 );
+ int i, * pWire, * pPerm = NULL, Count = 0;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ int First = Rtl_WireFirst( p, i );
+ int Number = Rtl_WireNumber( p, i );
+ int fIsPi = (int)((First & 1) > 0);
+ int fIsPo = (int)((First & 2) > 0);
+ assert( (fIsPi || fIsPo) == (Number > 0) );
+ if ( fIsPi || fIsPo )
+ Vec_IntPush( vCost, fIsPo*ABC_INFINITY + Number );
+ else
+ Vec_IntPush( vCost, 2*ABC_INFINITY + Count++ );
+ }
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vCost), Vec_IntSize(vCost) );
+ Vec_IntFree( vCost );
+ return pPerm;
+}
+void Rtl_NtkOrderWires( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(&p->vWires) );
+ int i, k, * pWire, * pPerm = Rlt_NtkFindIOPerm( p );
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ pWire = Vec_IntEntryP( &p->vWires, WIRE_NUM*pPerm[i] );
+ for ( k = 0; k < WIRE_NUM; k++ )
+ Vec_IntPush( vTemp, pWire[k] );
+ }
+ ABC_FREE( pPerm );
+ assert( Vec_IntSize(&p->vWires) == Vec_IntSize(vTemp) );
+ ABC_SWAP( Vec_Int_t, p->vWires, *vTemp );
+ Vec_IntFree( vTemp );
+}
+void Rtl_LibUpdateInstances( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vMap = p->pLib->vMap;
+ Vec_Int_t * vTemp = &p->pLib->vTemp[2];
+ int i, k, Par, Val, * pCell, Value;
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ {
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ assert( pCell[6] == pModel->nInputs+pModel->nOutputs );
+ Rtl_CellForEachConnect( p, pCell, Par, Val, k )
+ Vec_IntWriteEntry( vMap, Par >> 2, k );
+ Vec_IntClear( vTemp );
+ for ( k = 0; k < pCell[6]; k++ )
+ {
+ int Perm = Vec_IntEntry( vMap, Rtl_WireName(pModel, k) );
+ int Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)];
+ int Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)+1];
+ assert( (Par >> 2) == Rtl_WireName(pModel, k) );
+ Vec_IntWriteEntry( vMap, Par >> 2, -1 );
+ Vec_IntPushTwo( vTemp, Par, Val );
+ assert( Perm >= 0 );
+ }
+ memcpy( pCell+CELL_NUM+2*(pCell[4]+pCell[5]), Vec_IntArray(vTemp), sizeof(int)*Vec_IntSize(vTemp) );
+ }
+ Vec_IntForEachEntry( p->pLib->vMap, Value, i )
+ assert( Value == -1 );
+}
+void Rtl_LibOrderWires( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkOrderWires( p );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_LibUpdateInstances( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig );
+
+int Rtl_NtkCountWireRange( Rtl_Ntk_t * p, int NameId )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int Width = Rtl_WireWidth( p, Wire );
+ return Width;
+}
+int Rtl_NtkCountSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ return pSlice[1] - pSlice[2] + 1;
+}
+int Rtl_NtkCountConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i, nBits = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ nBits += Rtl_NtkCountSignalRange( p, pConcat[i] );
+ return nBits;
+}
+int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ return Rtl_NtkCountWireRange( p, Sig >> 2 );
+ if ( Rtl_SigIsSlice(Sig) )
+ return Rtl_NtkCountSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ if ( Rtl_SigIsConcat(Sig) )
+ return Rtl_NtkCountConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ return ABC_INFINITY;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig );
+
+int Rtl_NtkCheckWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right <= Left && Right >= 0 );
+ for ( i = Right; i <= Left; i++ )
+ if ( Vec_IntEntry(&p->vLits, First+i) == -1 )
+ return 0;
+ return 1;
+}
+int Rtl_NtkCheckSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ return Rtl_NtkCheckWireRange( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+int Rtl_NtkCheckConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ if ( !Rtl_NtkCheckSignalRange( p, pConcat[i] ) )
+ return 0;
+ return 1;
+}
+int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ return Rtl_NtkCheckWireRange( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ return 1;
+ else if ( Rtl_SigIsSlice(Sig) )
+ return Rtl_NtkCheckSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ return Rtl_NtkCheckConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+ return -1;
+}
+
+
+extern void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value );
+
+void Rtl_NtkSetWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int Value )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right <= Left && Right >= 0 );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) == -1 );
+ Vec_IntWriteEntry(&p->vLits, First+i, Value );
+ }
+ //printf( "Finished setting wire %s\n", Rtl_NtkStr(p, NameId) );
+}
+void Rtl_NtkSetSliceRange( Rtl_Ntk_t * p, int * pSlice, int Value )
+{
+ Rtl_NtkSetWireRange( p, pSlice[0], pSlice[1], pSlice[2], Value );
+}
+void Rtl_NtkSetConcatRange( Rtl_Ntk_t * p, int * pConcat, int Value )
+{
+ int i;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ Rtl_NtkSetSignalRange( p, pConcat[i], Value );
+}
+void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkSetWireRange( p, Sig >> 2, -1, -1, Value );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkSetSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), Value );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkSetConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), Value );
+ else if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+}
+
+
+void Rtl_NtkInitInputs( Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) == -1 );
+ Vec_IntWriteEntry( &p->vLits, First+b, Vec_IntSize(&p->vOrder) );
+ }
+ Vec_IntPush( &p->vOrder, i );
+ //printf( "Finished setting input %s\n", Rtl_WireNameStr(p, i) );
+ }
+}
+Vec_Int_t * Rtl_NtkCollectOutputs( Rtl_Ntk_t * p )
+{
+ //char * pNtkName = Rtl_NtkName(p);
+ int b, i;
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ //char * pName = Rtl_WireNameStr(p, p->nInputs + i);
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) != -1 );
+ Vec_IntPush( vRes, Vec_IntEntry(&p->vLits, First+b) );
+ }
+ }
+ return vRes;
+}
+int Rtl_NtkReviewCells( Rtl_Ntk_t * p )
+{
+ int i, k, Par, Val, * pCell, RetValue = 0;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ if ( pCell[7] )
+ continue;
+ Rtl_CellForEachInput( p, pCell, Par, Val, k )
+ if ( !Rtl_NtkCheckSignalRange( p, Val ) )
+ break;
+ if ( k < Rtl_CellInputNum(pCell) )
+ continue;
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ Rtl_NtkSetSignalRange( p, Val, Vec_IntSize(&p->vOrder) );
+ Vec_IntPush( &p->vOrder, p->nInputs + i );
+ pCell[7] = 1;
+ RetValue = 1;
+ //printf( "Setting cell %s as propagated.\n", Rtl_CellNameStr(p, pCell) );
+ }
+ return RetValue;
+}
+int Rtl_NtkReviewConnections( Rtl_Ntk_t * p )
+{
+ int i, * pCon, RetValue = 0;
+ Rtl_NtkForEachCon( p, pCon, i )
+ {
+ int Status0 = Rtl_NtkCheckSignalRange( p, pCon[0] );
+ int Status1 = Rtl_NtkCheckSignalRange( p, pCon[1] );
+ if ( Status0 == Status1 )
+ continue;
+ if ( !Status0 && Status1 )
+ ABC_SWAP( int, pCon[0], pCon[1] )
+ Rtl_NtkSetSignalRange( p, pCon[1], Vec_IntSize(&p->vOrder) );
+ Vec_IntPush( &p->vOrder, p->nInputs + Rtl_NtkCellNum(p) + i );
+ RetValue = 1;
+ }
+ return RetValue;
+}
+void Rtl_NtkPrintCellOrder( Rtl_Ntk_t * p )
+{
+ int i, iCell;
+ Vec_IntForEachEntry( &p->vOrder, iCell, i )
+ {
+ printf( "%4d : ", i );
+ printf( "Cell %4d ", iCell );
+ if ( iCell < p->nInputs )
+ printf( "Type Input " );
+ else if ( iCell < p->nInputs + Rtl_NtkCellNum(p) )
+ {
+ int * pCell = Rtl_NtkCell( p, iCell - p->nInputs );
+ printf( "Type %4d ", Rtl_CellType(pCell) );
+ printf( "%16s ", Rtl_CellTypeStr(p, pCell) );
+ printf( "%16s ", Rtl_CellNameStr(p, pCell) );
+ }
+ else
+ printf( "Type Connection " );
+ printf( "\n" );
+ }
+}
+void Rtl_NtkPrintUnusedCells( Rtl_Ntk_t * p )
+{
+ int i, * pCell;
+ printf( "\n*** Printing unused cells:\n" );
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ if ( pCell[7] )
+ continue;
+ printf( "Unused cell %s %s\n", Rtl_CellTypeStr(p, pCell), Rtl_CellNameStr(p, pCell) );
+ }
+ printf( "\n" );
+}
+void Rtl_NtkOrderCells( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vRes;
+ int nBits = Rtl_NtkRangeWires( p );
+ Vec_IntFill( &p->vLits, nBits, -1 );
+
+ Vec_IntClear( &p->vOrder );
+ Vec_IntGrow( &p->vOrder, Rtl_NtkObjNum(p) );
+ Rtl_NtkInitInputs( p );
+
+ Rtl_NtkMapWires( p, 0 );
+//Vec_IntPrint(&p->vLits);
+
+ Rtl_NtkReviewConnections( p );
+ while ( Rtl_NtkReviewCells(p) | Rtl_NtkReviewConnections(p) );
+ Rtl_NtkMapWires( p, 1 );
+
+ vRes = Rtl_NtkCollectOutputs( p );
+ Vec_IntFree( vRes );
+
+ //Rtl_NtkPrintCellOrder( p );
+}
+void Rtl_LibOrderCells( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ assert( Vec_IntSize(pLib->vMap) == Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkOrderCells( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_TokenUnspace( char * p )
+{
+ int i, Length = strlen(p), Quote = 0;
+ for ( i = 0; i < Length; i++ )
+ if ( p[i] == '\"' )
+ Quote ^= 1;
+ else if ( Quote && p[i] == ' ' )
+ p[i] = '\"';
+}
+void Rtl_TokenRespace( char * p )
+{
+ int i, Length = strlen(p);
+ assert( p[0] == '\"' && p[Length-1] == '\"' );
+ for ( i = 1; i < Length-1; i++ )
+ if ( p[i] == '\"' )
+ p[i] = ' ';
+}
+Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p )
+{
+ Vec_Int_t * vTokens;
+ char * pTemp, * pBuffer;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ Abc_NamStrFindOrAdd( p, "module", NULL );
+ assert( Abc_NamObjNumMax(p) == 2 );
+ vTokens = Vec_IntAlloc( 1000 );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ {
+ if ( pBuffer[0] == '#' )
+ continue;
+ Rtl_TokenUnspace( pBuffer );
+ pTemp = strtok( pBuffer, " \t\r\n" );
+ if ( pTemp == NULL )
+ continue;
+ while ( pTemp )
+ {
+ if ( *pTemp == '\"' ) Rtl_TokenRespace( pTemp );
+ Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pTemp, NULL) );
+ pTemp = strtok( NULL, " \t\r\n" );
+ }
+ Vec_IntPush( vTokens, -1 );
+ }
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ return vTokens;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkPrintConst( Rtl_Ntk_t * p, int * pConst )
+{
+ int i;
+ if ( pConst[0] == -1 )
+ {
+ fprintf( Rtl_NtkFile(p), " %d", pConst[1] );
+ return;
+ }
+ fprintf( Rtl_NtkFile(p), " %d\'", pConst[0] );
+ for ( i = pConst[0] - 1; i >= 0; i-- )
+ fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit((unsigned *)pConst+1,i) );
+}
+void Rtl_NtkPrintSlice( Rtl_Ntk_t * p, int * pSlice )
+{
+ fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, pSlice[0]) );
+ if ( pSlice[1] == pSlice[2] )
+ fprintf( Rtl_NtkFile(p), " [%d]", pSlice[1] );
+ else
+ fprintf( Rtl_NtkFile(p), " [%d:%d]", pSlice[1], pSlice[2] );
+}
+void Rtl_NtkPrintConcat( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ fprintf( Rtl_NtkFile(p), " {" );
+ for ( i = 1; i <= pConcat[0]; i++ )
+ Rtl_NtkPrintSig( p, pConcat[i] );
+ fprintf( Rtl_NtkFile(p), " }" );
+}
+void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, Sig >> 2) );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkPrintConst( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkPrintSlice( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkPrintConcat( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+void Rtl_NtkPrintWire( Rtl_Ntk_t * p, int * pWire )
+{
+ fprintf( Rtl_NtkFile(p), " wire" );
+ if ( pWire[1] != 1 ) fprintf( Rtl_NtkFile(p), " width %d", pWire[1] );
+ if ( pWire[2] != 0 ) fprintf( Rtl_NtkFile(p), " offset %d", pWire[2] );
+ if ( pWire[0] & 8 ) fprintf( Rtl_NtkFile(p), " upto" );
+ if ( pWire[0] & 1 ) fprintf( Rtl_NtkFile(p), " input %d", pWire[3] );
+ if ( pWire[0] & 2 ) fprintf( Rtl_NtkFile(p), " output %d", pWire[3] );
+ if ( pWire[0] & 4 ) fprintf( Rtl_NtkFile(p), " signed" );
+ fprintf( Rtl_NtkFile(p), " %s\n", Rtl_NtkStr(p, pWire[0] >> 4) );
+}
+void Rtl_NtkPrintCell( Rtl_Ntk_t * p, int * pCell )
+{
+ int i, Par, Val;
+ Rtl_CellForEachAttr( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) );
+ fprintf( Rtl_NtkFile(p), " cell %s %s\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkStr(p, pCell[1]) );
+ Rtl_CellForEachParam( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " connect" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ fprintf( Rtl_NtkFile(p), " end\n" );
+}
+void Rtl_NtkPrintConnection( Rtl_Ntk_t * p, int * pCon )
+{
+ fprintf( Rtl_NtkFile(p), " connect" );
+ Rtl_NtkPrintSig( p, pCon[0] );
+ Rtl_NtkPrintSig( p, pCon[1] );
+ fprintf( Rtl_NtkFile(p), "\n" );
+}
+void Rtl_NtkPrint( Rtl_Ntk_t * p )
+{
+ int i, Par, Val, * pWire, * pCell, * pCon;
+ fprintf( Rtl_NtkFile(p), "\n" );
+ Rtl_NtkForEachAttr( p, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), "attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) );
+ fprintf( Rtl_NtkFile(p), "module %s\n", Rtl_NtkName(p) );
+ Rtl_NtkForEachWire( p, pWire, i )
+ Rtl_NtkPrintWire( p, pWire );
+ Rtl_NtkForEachCell( p, pCell, i )
+ Rtl_NtkPrintCell( p, pCell );
+ Rtl_NtkForEachCon( p, pCon, i )
+ Rtl_NtkPrintConnection( p, pCon );
+ fprintf( Rtl_NtkFile(p), "end\n" );
+}
+void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p )
+{
+ p->pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
+ if ( p->pFile == NULL )
+ {
+ printf( "Cannot open output file \"%s\".\n", pFileName );
+ return;
+ }
+ else
+ {
+ Rtl_Ntk_t * pNtk; int i;
+ fprintf( p->pFile, "\n" );
+ fprintf( p->pFile, "# Generated by ABC on %s\n", Extra_TimeStamp() );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkPrint( pNtk );
+ if ( p->pFile != stdout )
+ fclose( p->pFile );
+ p->pFile = NULL;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos );
+
+int Rtl_NtkReadConst( Rtl_Ntk_t * p, char * pConst )
+{
+ Vec_Int_t * vConst = &p->pLib->vConsts;
+ int RetVal = Vec_IntSize( vConst );
+ int Width = atoi( pConst );
+ assert( pConst[0] >= '0' && pConst[0] <= '9' );
+ if ( strstr(pConst, "\'") )
+ {
+ int Length = strlen(pConst);
+ int nWords = (Width + 31) / 32;
+ int i, * pArray;
+ Vec_IntPush( vConst, Width );
+ Vec_IntFillExtra( vConst, Vec_IntSize(vConst) + nWords, 0 );
+ pArray = Vec_IntEntryP( vConst, RetVal + 1 );
+ for ( i = Length-1; i >= Length-Width; i-- )
+ if ( pConst[i] == '1' )
+ Abc_InfoSetBit( (unsigned *)pArray, Length-1-i );
+ }
+ else
+ {
+ Vec_IntPush( vConst, -1 );
+ Vec_IntPush( vConst, Width );
+ }
+ return (RetVal << 2) | 1;
+}
+int Rtl_NtkReadSlice( Rtl_Ntk_t * p, char * pSlice, int NameId )
+{
+ Vec_Int_t * vSlice = &p->pLib->vSlices;
+ int RetVal = Vec_IntSize( vSlice );
+ int Left = atoi( pSlice+1 );
+ char * pTwo = strstr( pSlice, ":" );
+ int Right = pTwo ? atoi( pTwo+1 ) : Left;
+ assert( pSlice[0] == '[' && pSlice[strlen(pSlice)-1] == ']' );
+ Vec_IntPush( vSlice, NameId );
+ Vec_IntPush( vSlice, Left );
+ Vec_IntPush( vSlice, Right );
+ return (RetVal << 2) | 2;
+}
+int Rtl_NtkReadConcat( Rtl_Ntk_t * p, int * pPos )
+{
+ Vec_Int_t * vConcat = &p->pLib->vConcats;
+ int RetVal = Vec_IntSize( vConcat ); char * pTok;
+ Vec_IntPush( vConcat, ABC_INFINITY );
+ do {
+ int Sig = Rtl_NtkReadSig( p, pPos );
+ Vec_IntPush( vConcat, Sig );
+ pTok = Rtl_NtkTokStr( p, *pPos );
+ }
+ while ( pTok[0] != '}' );
+ Vec_IntWriteEntry( vConcat, RetVal, Vec_IntSize(vConcat) - RetVal - 1 );
+ assert( pTok[0] == '}' );
+ (*pPos)++;
+ return (RetVal << 2) | 3;
+}
+int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos )
+{
+ int NameId = Rtl_NtkTokId( p, *pPos );
+ char * pSig = Rtl_NtkTokStr( p, (*pPos)++ );
+ if ( pSig[0] >= '0' && pSig[0] <= '9' )
+ return Rtl_NtkReadConst( p, pSig );
+ if ( pSig[0] == '{' )
+ return Rtl_NtkReadConcat( p, pPos );
+ else
+ {
+ char * pNext = Rtl_NtkTokStr( p, *pPos );
+ if ( pNext && pNext[0] == '[' )
+ {
+ (*pPos)++;
+ return Rtl_NtkReadSlice( p, pNext, NameId );
+ }
+ else
+ return NameId << 2;
+ }
+}
+int Rtl_NtkReadWire( Rtl_Ntk_t * p, int iPos )
+{
+ int i, Entry, Prev = -1;
+ int Width = 1, Upto = 0, Offset = 0, Out = 0, In = 0, Number = 0, Signed = 0;
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_WIRE) );
+ Vec_IntClear( &p->pLib->vAttrTemp );
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos )
+ {
+ //char * pTok = Rtl_NtkTokStr(p, i);
+ if ( Entry == -1 )
+ break;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_WIDTH) )
+ Width = atoi( Rtl_NtkTokStr(p, ++i) );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_OFFSET) )
+ Offset = atoi( Rtl_NtkTokStr(p, ++i) );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_INPUT) )
+ Number = atoi( Rtl_NtkTokStr(p, ++i) ), In = 1, p->nInputs++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_OUTPUT) )
+ Number = atoi( Rtl_NtkTokStr(p, ++i) ), Out = 1, p->nOutputs++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_SIGNED) )
+ Signed = 1;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_UPTO) )
+ Upto = 1;
+ Prev = Entry;
+ }
+ // add WIRE_NUM=5 entries
+ Vec_IntPush( &p->vWires, (Prev << 4) | (Upto << 3) | (Signed << 2) | (Out << 1) | (In << 0) );
+ Vec_IntPush( &p->vWires, Width );
+ Vec_IntPush( &p->vWires, Offset );
+ Vec_IntPush( &p->vWires, Number );
+ Vec_IntPush( &p->vWires, -1 );
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ return i;
+}
+int Rtl_NtkReadAttribute( Rtl_Ntk_t * p, int iPos )
+{
+//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
+//char * pTok2 = Rtl_NtkTokStr(p, iPos);
+//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_ATTRIBUTE) );
+ Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) );
+ Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) );
+ assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) );
+ return iPos;
+}
+int Rtl_NtkReadAttribute2( Rtl_Lib_t * p, int iPos )
+{
+//char * pTok1 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos-1));
+//char * pTok2 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos) );
+//char * pTok3 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos+1));
+ assert( Vec_IntEntry(p->vTokens, iPos-1) == p->pMap[RTL_ATTRIBUTE] );
+ Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) );
+ Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) );
+ assert( Vec_IntEntry(p->vTokens, iPos) == p->pMap[RTL_NONE] );
+ return iPos;
+}
+int Rtl_NtkReadConnect( Rtl_Ntk_t * p, int iPos )
+{
+//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
+//char * pTok2 = Rtl_NtkTokStr(p, iPos);
+//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CONNECT) );
+ Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) );
+ Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) );
+ assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) );
+ return iPos;
+}
+int Rtl_NtkReadCell( Rtl_Ntk_t * p, int iPos )
+{
+ Vec_Int_t * vAttrs = &p->pLib->vAttrTemp;
+ int iPosPars, iPosCons, Par, Val, i, Entry;
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CELL) );
+ Vec_IntPush( &p->vCells, Vec_IntSize(&p->vStore) );
+ Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 0
+ Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 1
+ Vec_IntPush( &p->vStore, -1 );
+ Vec_IntPush( &p->vStore, -1 );
+ assert( Vec_IntSize(vAttrs) % 2 == 0 );
+ Vec_IntPush( &p->vStore, Vec_IntSize(vAttrs)/2 );
+ iPosPars = Vec_IntSize(&p->vStore);
+ Vec_IntPush( &p->vStore, 0 ); // 5
+ iPosCons = Vec_IntSize(&p->vStore);
+ Vec_IntPush( &p->vStore, 0 ); // 6
+ Vec_IntPush( &p->vStore, 0 ); // 7
+ assert( Vec_IntSize(&p->vStore) == Vec_IntEntryLast(&p->vCells)+CELL_NUM );
+ Vec_IntAppend( &p->vStore, vAttrs );
+ Vec_IntClear( vAttrs );
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos )
+ {
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_END) )
+ break;
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) || Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) )
+ {
+ int iPosCount = Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) ? iPosPars : iPosCons;
+ Vec_IntAddToEntry( &p->vStore, iPosCount, 1 );
+ i++;
+ Par = Rtl_NtkReadSig(p, &i);
+ Val = Rtl_NtkReadSig(p, &i);
+ Vec_IntPushTwo( &p->vStore, Par, Val );
+ }
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ }
+ assert( Rtl_NtkPosCheck(p, i, RTL_END) );
+ i++;
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ return i;
+}
+int Wln_ReadMatchEnd( Rtl_Ntk_t * p, int Mod )
+{
+ int i, Entry, Count = 0;
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, Mod )
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) )
+ Count++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_END) )
+ {
+ if ( Count == 0 )
+ return i;
+ Count--;
+ }
+ assert( 0 );
+ return -1;
+}
+int Rtl_NtkReadNtk( Rtl_Lib_t * pLib, int Mod )
+{
+ Rtl_Ntk_t * p = Rtl_NtkAlloc( pLib );
+ Vec_Int_t * vAttrs = &p->pLib->vAttrTemp;
+ int End = Wln_ReadMatchEnd( p, Mod ), i, Entry;
+ assert( Rtl_NtkPosCheck(p, Mod-1, RTL_MODULE) );
+ assert( Rtl_NtkPosCheck(p, End, RTL_END) );
+ p->NameId = Rtl_NtkTokId( p, Mod );
+ p->Slice0 = Vec_IntSize( &pLib->vSlices );
+ Vec_IntAppend( &p->vAttrs, vAttrs );
+ Vec_IntClear( vAttrs );
+ Vec_IntForEachEntryStartStop( pLib->vTokens, Entry, i, Mod, End )
+ {
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_WIRE) )
+ i = Rtl_NtkReadWire( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_ATTRIBUTE) )
+ i = Rtl_NtkReadAttribute( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) )
+ i = Rtl_NtkReadCell( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) )
+ i = Rtl_NtkReadConnect( p, i+1 );
+ }
+ p->Slice1 = Vec_IntSize( &pLib->vSlices );
+ assert( Vec_IntSize(&p->vWires) % WIRE_NUM == 0 );
+ return End;
+}
+void Rtl_NtkReportUndefs( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vNames, * vCounts;
+ int i, iName, * pCell;
+ vNames = Vec_IntAlloc( 10 );
+ vCounts = Vec_IntAlloc( 10 );
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )
+ {
+ iName = Vec_IntFind(vNames, Rtl_CellType(pCell));
+ if ( iName == -1 )
+ {
+ iName = Vec_IntSize(vNames);
+ Vec_IntPush( vNames, Rtl_CellType(pCell) );
+ Vec_IntPush( vCounts, 0 );
+ }
+ Vec_IntAddToEntry( vCounts, iName, 1 );
+ }
+ Vec_IntForEachEntry( vNames, iName, i )
+ printf( " %s (%d)", Rtl_NtkStr(p, iName), Vec_IntEntry(vCounts, i) );
+ printf( "\n" );
+ Vec_IntFree( vNames );
+ Vec_IntFree( vCounts );
+}
+int Rtl_NtkSetParents( Rtl_Ntk_t * p )
+{
+ int i, * pCell, nUndef = 0;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ pCell[2] = Rtl_NtkReadType( p, Rtl_CellType(pCell) );
+ if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )
+ nUndef++;
+ else
+ pCell[3] = Rtl_CellModule(pCell) < ABC_INFINITY ? pCell[6]-1 : Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY)->nInputs;
+ }
+ if ( !nUndef )
+ return 0;
+ printf( "Module \"%s\" has %d blackbox instances: ", Rtl_NtkName(p), nUndef );
+ Rtl_NtkReportUndefs( p );
+ return nUndef;
+}
+void Rtl_LibSetParents( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkSetParents( pNtk );
+}
+void Rtl_LibReorderModules_rec( Rtl_Ntk_t * p, Vec_Ptr_t * vNew )
+{
+ int i, * pCell;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell );
+ if ( pMod && pMod->iCopy == -1 )
+ Rtl_LibReorderModules_rec( pMod, vNew );
+ }
+ assert( p->iCopy == -1 );
+ p->iCopy = Vec_PtrSize(vNew);
+ Vec_PtrPush( vNew, p );
+}
+int Rtl_LibCountInsts( Rtl_Lib_t * p, Rtl_Ntk_t * pOne )
+{
+ Rtl_Ntk_t * pNtk; int n, i, * pCell, Count = 0;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, n )
+ Rtl_NtkForEachCell( pNtk, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell );
+ if ( pMod && pMod == pOne )
+ Count++;
+ }
+ return Count;
+}
+void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p )
+{
+ int i, * pCell;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell );
+ if ( pMod && pMod->iCopy >= 0 )
+ pCell[2] = ABC_INFINITY + pMod->iCopy;
+ }
+}
+void Rtl_LibUpdateBoxes( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkUpdateBoxes( pNtk );
+}
+void Rtl_LibReorderModules( Rtl_Lib_t * p )
+{
+ Vec_Ptr_t * vNew = Vec_PtrAlloc( Vec_PtrSize(p->vNtks) );
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( pNtk->iCopy == -1 )
+ Rtl_LibReorderModules_rec( pNtk, vNew );
+ assert( Vec_PtrSize(p->vNtks) == Vec_PtrSize(vNew) );
+ Rtl_LibUpdateBoxes( p );
+ Vec_PtrClear( p->vNtks );
+ Vec_PtrAppend( p->vNtks, vNew );
+ Vec_PtrFree( vNew );
+}
+Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec )
+{
+ Rtl_Lib_t * p = Rtl_LibAlloc(); int i, Entry;
+ p->pSpec = Abc_UtilStrsav( pFileSpec );
+ p->pManName = Abc_NamStart( 1000, 50 );
+ p->vTokens = Rtl_NtkReadFile( pFileName, p->pManName );
+ Rtl_LibDeriveMap( p );
+ Vec_IntClear( &p->vAttrTemp );
+ Vec_IntForEachEntry( p->vTokens, Entry, i )
+ if ( Entry == p->pMap[RTL_MODULE] )
+ i = Rtl_NtkReadNtk( p, i+1 );
+ else if ( Entry == p->pMap[RTL_ATTRIBUTE] )
+ i = Rtl_NtkReadAttribute2( p, i+1 );
+ Rtl_LibSetParents( p );
+ Rtl_LibReorderModules( p );
+ Rtl_LibOrderWires( p );
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit );
+
+int Rtl_NtkMapWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int iCell, int iBit )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vDrivers, 2*(First+i)) == -4 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+0, iCell );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+1, iBit + (i - Right) );
+ }
+ return Left - Right + 1;
+}
+int Rtl_NtkMapSliceRange( Rtl_Ntk_t * p, int * pSlice, int iCell, int iBit )
+{
+ return Rtl_NtkMapWireRange( p, pSlice[0], pSlice[1], pSlice[2], iCell, iBit );
+}
+int Rtl_NtkMapConcatRange( Rtl_Ntk_t * p, int * pConcat, int iCell, int iBit )
+{
+ int i, k = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ k += Rtl_NtkMapSignalRange( p, pConcat[i], iCell, iBit+k );
+ return k;
+}
+int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit )
+{
+ int nBits = ABC_INFINITY;
+ if ( Rtl_SigIsNone(Sig) )
+ nBits = Rtl_NtkMapWireRange( p, Sig >> 2, -1, -1, iCell, iBit );
+ if ( Rtl_SigIsSlice(Sig) )
+ nBits = Rtl_NtkMapSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), iCell, iBit );
+ if ( Rtl_SigIsConcat(Sig) )
+ nBits = Rtl_NtkMapConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), iCell, iBit );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ return nBits;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkCollectWireInfo( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ Vec_IntPush( &p->vBitTemp, First+i );
+}
+void Rtl_NtkCollectConstInfo( Rtl_Ntk_t * p, int * pConst )
+{
+ int i, nLimit = pConst[0];
+ if ( nLimit == -1 )
+ nLimit = 32;
+ for ( i = 0; i < nLimit; i++ )
+ Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i)-CONST_SHIFT );
+}
+void Rtl_NtkCollectSliceInfo( Rtl_Ntk_t * p, int * pSlice )
+{
+ Rtl_NtkCollectWireInfo( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+void Rtl_NtkCollectConcatInfo( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = pConcat[0]; i >= 1; i-- )
+ Rtl_NtkCollectSignalInfo( p, pConcat[i] );
+}
+void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkCollectWireInfo( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkCollectConstInfo( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkCollectSliceInfo( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkCollectConcatInfo( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkCollectWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) != -1 );
+ Vec_IntPush( &p->vBitTemp, Vec_IntEntry(&p->vLits, First+i) );
+ }
+}
+void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst )
+{
+ int i, nLimit = pConst[0];
+ if ( nLimit == -1 )
+ nLimit = 32;
+ for ( i = 0; i < nLimit; i++ )
+ Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i) );
+}
+void Rtl_NtkCollectSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ Rtl_NtkCollectWireRange( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+void Rtl_NtkCollectConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = pConcat[0]; i >= 1; i-- )
+ Rtl_NtkCollectSignalRange( p, pConcat[i] );
+}
+void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkCollectWireRange( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkCollectConstRange( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkCollectSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkCollectConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+
+
+extern int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits );
+
+int Rtl_NtkInsertWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int * pLits, int nLits )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i, k = 0;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) == -1 );
+ Vec_IntWriteEntry(&p->vLits, First+i, pLits[k++] );
+ }
+ assert( k <= nLits );
+ return k;
+}
+int Rtl_NtkInsertSliceRange( Rtl_Ntk_t * p, int * pSlice, int * pLits, int nLits )
+{
+ return Rtl_NtkInsertWireRange( p, pSlice[0], pSlice[1], pSlice[2], pLits, nLits );
+}
+int Rtl_NtkInsertConcatRange( Rtl_Ntk_t * p, int * pConcat, int * pLits, int nLits )
+{
+ int i, k = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ k += Rtl_NtkInsertSignalRange( p, pConcat[i], pLits+k, nLits-k );
+ assert( k <= nLits );
+ return k;
+}
+int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits )
+{
+ int nBits = ABC_INFINITY;
+ if ( Rtl_SigIsNone(Sig) )
+ nBits = Rtl_NtkInsertWireRange( p, Sig >> 2, -1, -1, pLits, nLits );
+ if ( Rtl_SigIsSlice(Sig) )
+ nBits = Rtl_NtkInsertSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), pLits, nLits );
+ if ( Rtl_SigIsConcat(Sig) )
+ nBits = Rtl_NtkInsertConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), pLits, nLits );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ assert( nBits == nLits );
+ return nBits;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkBlastInputs( Gia_Man_t * pNew, Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) == -1 );
+ Vec_IntWriteEntry( &p->vLits, First+b, Gia_ManAppendCi(pNew) );
+ }
+ }
+}
+void Rtl_NtkBlastOutputs( Gia_Man_t * pNew, Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) != -1 );
+ Gia_ManAppendCo( pNew, Vec_IntEntry(&p->vLits, First+b) );
+ }
+ }
+}
+void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon )
+{
+ int nBits;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalRange( p, pCon[0] );
+ nBits = Rtl_NtkInsertSignalRange( p, pCon[1], Vec_IntArray(&p->vBitTemp), Vec_IntSize(&p->vBitTemp) );
+ assert( nBits == Vec_IntSize(&p->vBitTemp) );
+ //printf( "Finished blasting connection (Value = %d).\n", Vec_IntEntry(&p->vBitTemp, 0) );
+}
+void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell )
+{
+ extern void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs );
+ extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p );
+ extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs );
+ extern int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts );
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ int nIns = 0, nOuts = 0, nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 );
+ int k, Par, Val, iThis = -1, nBits = 0;
+ //int fFound = 0;
+ int fFound = p->pLib->vInverses && (iThis = Vec_IntFind(p->pLib->vInverses, pModel->NameId)) >= 0;
+ //int iThat = fFound ? Vec_IntEntry( p->pLib->vInverses, iThis ^ 1 ) : -1;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_CellForEachInput( p, pCell, Par, Val, k )
+ Rtl_NtkCollectSignalRange( p, Val );
+ assert( pModel->pGia );
+ if ( fFound )
+ {
+ nIns = nOuts1;
+ Vec_IntForEachEntry( &p->vBitTemp, Val, k )
+ Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val );
+ Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) );
+ }
+ else if ( pModel->fRoot )
+ {
+ nIns = Vec_IntSize(&p->vBitTemp);
+ Vec_IntForEachEntry( &p->vBitTemp, Val, k )
+ //Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val );
+ Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) );
+ Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) );
+ }
+ if ( fFound || pModel->fRoot )
+ Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 0 );
+ else
+ {
+ Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 1 );
+ Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs );
+ }
+ if ( pModel->fRoot || fFound )
+ {
+ nOuts = Vec_IntSize(&p->vBitTemp);
+ Vec_IntForEachEntry( &p->vBitTemp, Val, k )
+ Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) );
+ Vec_IntPush( pNew->vBarBufs, (nOuts << 16) | Abc_Var2Lit(pModel->NameId, 1) );
+ printf( "Added %d input buffers and %d output buffers for module %s.\n", nIns, nOuts, Rtl_NtkName(pModel) );
+ }
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits );
+ assert( nBits == Vec_IntSize(&p->vBitTemp) );
+}
+
+int Rtl_NtkCellParamValue( Rtl_Ntk_t * p, int * pCell, char * pParam )
+{
+ int ParamId = Rtl_NtkStrId( p, pParam );
+ int i, Par, Val, ValOut = ABC_INFINITY, * pConst;
+// p->pLib->pFile = stdout;
+// Rtl_CellForEachParam( p, pCell, Par, Val, i )
+// fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ Rtl_CellForEachParam( p, pCell, Par, Val, i )
+ if ( (Par >> 2) == ParamId )
+ {
+ assert( Rtl_SigIsConst(Val) );
+ pConst = Vec_IntEntryP( &p->pLib->vConsts, Val >> 2 );
+ assert( pConst[0] < 32 );
+ ValOut = pConst[1];
+ }
+ return ValOut;
+}
+void Rtl_NtkBlastOperator( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell )
+{
+ extern void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 );
+ Vec_Int_t * vRes = &p->pLib->vTemp[3];
+ int i, Par, Val, ValOut = -1, nBits = 0, nRange = -1;
+ int fSign0 = Rtl_NtkCellParamValue( p, pCell, "\\A_SIGNED" );
+ int fSign1 = Rtl_NtkCellParamValue( p, pCell, "\\B_SIGNED" );
+ Rtl_CellForEachOutput( p, pCell, Par, ValOut, i )
+ nRange = Rtl_NtkCountSignalRange( p, ValOut );
+ assert( nRange > 0 );
+ for ( i = 0; i < TEMP_NUM; i++ )
+ Vec_IntClear( &p->pLib->vTemp[i] );
+ //printf( "Starting blasting cell %s.\n", Rtl_CellNameStr(p, pCell) );
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalRange( p, Val );
+ Vec_IntAppend( &p->pLib->vTemp[i], &p->vBitTemp );
+ }
+ Rtl_NtkBlastNode( pNew, Rtl_CellModule(pCell), Rtl_CellInputNum(pCell), p->pLib->vTemp, nRange, fSign0, fSign1 );
+ assert( Vec_IntSize(vRes) > 0 );
+ nBits = Rtl_NtkInsertSignalRange( p, ValOut, Vec_IntArray(vRes)+nBits, Vec_IntSize(vRes)-nBits );
+ assert( nBits == Vec_IntSize(vRes) );
+ //printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) );
+}
+char * Rtl_ShortenName( char * pName, int nSize )
+{
+ static char Buffer[1000];
+ if ( (int)strlen(pName) <= nSize )
+ return pName;
+ Buffer[0] = 0;
+ strcat( Buffer, pName );
+ //Buffer[nSize-4] = ' ';
+ Buffer[nSize-3] = '.';
+ Buffer[nSize-2] = '.';
+ Buffer[nSize-1] = '.';
+ Buffer[nSize-0] = 0;
+ return Buffer;
+}
+void Rtl_NtkPrintBufOne( Rtl_Lib_t * p, int Lit )
+{
+ printf( "%s (%c%d) ", Rtl_LibStr(p, Abc_Lit2Var(Lit&0xFFFF)), Abc_LitIsCompl(Lit)? 'o' : 'i', Lit >> 16 );
+}
+void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs )
+{
+ int i, Lit;
+ if ( Vec_IntSize(vBufs) )
+ printf( "Found %d buffers (%d groups): ", p->pGia->nBufs, Vec_IntSize(vBufs) );
+ Vec_IntForEachEntry( vBufs, Lit, i )
+ Rtl_NtkPrintBufOne( p->pLib, Lit );
+ if ( Vec_IntSize(vBufs) )
+ printf( "\n" );
+}
+Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p )
+{
+ int fDump = 0;
+ Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 );
+ int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p );
+ Vec_IntFill( &p->vLits, nBits, -1 );
+ Rtl_NtkMapWires( p, 0 );
+ Rtl_NtkBlastInputs( pNew, p );
+ Gia_ManHashAlloc( pNew );
+ Vec_IntForEachEntry( &p->vOrder, iObj, i )
+ {
+ iObj -= Rtl_NtkInputNum(p);
+ if ( iObj < 0 )
+ continue;
+ if ( iObj >= Rtl_NtkCellNum(p) )
+ {
+ Rtl_NtkBlastConnect( pNew, p, Rtl_NtkCon(p, iObj - Rtl_NtkCellNum(p)) );
+ continue;
+ }
+ pCell = Rtl_NtkCell(p, iObj);
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ Rtl_NtkBlastHierarchy( pNew, p, pCell );
+ else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Rtl_NtkBlastOperator( pNew, p, pCell );
+ else
+ printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) );
+ }
+ Gia_ManHashStop( pNew );
+ Rtl_NtkBlastOutputs( pNew, p );
+ Rtl_NtkMapWires( p, 1 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ if ( fDump )
+ {
+ char Buffer[100]; static int counter = 0;
+ sprintf( Buffer, "old%02d.aig", counter++ );
+ Gia_AigerWrite( pNew, Buffer, 0, 0, 0 );
+ printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) );
+ }
+ else
+ printf( "Derived AIG for module %-20s : ", Rtl_ShortenName(Rtl_NtkName(p), 20) );
+ Gia_ManPrintStats( pNew, NULL );
+ return pNew;
+}
+void Rtl_LibBlast( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ if ( p->pGia == NULL )
+ p->pGia = Rtl_NtkBlast( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// -4 unassigned
+// -3 other bit
+// -2 constant
+// -1 primary input
+// 0+ cell
+int Rtl_NtkBlastCons( Rtl_Ntk_t * p )
+{
+ int c, i, iBit0, iBit1, * pCon, * pDri0, * pDri1, nChanges = 0;
+ Rtl_NtkForEachCon( p, pCon, c )
+ {
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, pCon[1] );
+ Vec_IntClearAppend( &p->vBitTemp2, &p->vBitTemp );
+
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, pCon[0] );
+ assert( Vec_IntSize(&p->vBitTemp2) == Vec_IntSize(&p->vBitTemp) );
+
+ Vec_IntForEachEntryTwo( &p->vBitTemp, &p->vBitTemp2, iBit0, iBit1, i )
+ {
+ pDri0 = iBit0 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit0) : NULL;
+ pDri1 = iBit1 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit1) : NULL;
+ assert( iBit0 >= 0 || iBit1 >= 0 );
+ if ( iBit0 < 0 )
+ {
+ if ( pDri1[0] == -4 )
+ {
+ assert( pDri1[1] == -4 );
+ pDri1[0] = -2;
+ pDri1[1] = iBit0+CONST_SHIFT;
+ nChanges++;
+ }
+ continue;
+ }
+ if ( iBit1 < 0 )
+ {
+ if ( pDri0[0] == -4 )
+ {
+ assert( pDri0[1] == -4 );
+ pDri0[0] = -2;
+ pDri0[1] = iBit1+CONST_SHIFT;
+ nChanges++;
+ }
+ continue;
+ }
+ if ( pDri0[0] == -4 && pDri1[0] != -4 )
+ {
+ assert( pDri0[1] == -4 );
+ pDri0[0] = -3;
+ pDri0[1] = iBit1;
+ nChanges++;
+ continue;
+ }
+ if ( pDri1[0] == -4 && pDri0[0] != -4 )
+ {
+ assert( pDri1[1] == -4 );
+ pDri1[0] = -3;
+ pDri1[1] = iBit0;
+ nChanges++;
+ continue;
+ }
+ }
+ }
+ //printf( "Changes %d\n", nChanges );
+ return nChanges;
+}
+void Rtl_NtkBlastMap( Rtl_Ntk_t * p, int nBits )
+{
+ int i, k, Par, Val, * pCell, iBit = 0;
+ Vec_IntFill( &p->vDrivers, 2*nBits, -4 );
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( k = 0; k < Width; k++ )
+ {
+ assert( Vec_IntEntry(&p->vDrivers, 2*(First+k)) == -4 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+0, -1 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+1, iBit++ );
+ }
+ }
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ int iBit = 0;
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ iBit += Rtl_NtkMapSignalRange( p, Val, i, iBit );
+ }
+ for ( i = 0; i < 100; i++ )
+ if ( !Rtl_NtkBlastCons(p) )
+ break;
+ if ( i == 100 )
+ printf( "Mapping connections did not succeed after %d iterations.\n", i );
+// else
+// printf( "Mapping connections converged after %d iterations.\n", i );
+}
+int Rtl_NtkCollectOrComputeBit( Rtl_Ntk_t * p, int iBit )
+{
+ extern void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver );
+ if ( Vec_IntEntry(&p->vLits, iBit) == -1 )
+ {
+ int * pDriver = Vec_IntEntryP(&p->vDrivers, 2*iBit);
+ assert( pDriver[0] != -4 );
+ Rtl_NtkBlast2_rec( p, iBit, pDriver );
+ }
+ assert( Vec_IntEntry(&p->vLits, iBit) >= 0 );
+ return Vec_IntEntry(&p->vLits, iBit);
+}
+int Rtl_NtkBlast2Spec( Rtl_Ntk_t * p, int * pCell, int iInput )
+{
+ int i, Par, Val, pLits[3] = {-1, -1, -1}, iBit;
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_Int_t * vTemp;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, Val );
+ vTemp = Vec_IntDup( &p->vBitTemp );
+ iBit = Vec_IntEntry( vTemp, i==2 ? 0 : iInput );
+ if ( iBit >= 0 )
+ pLits[i] = Rtl_NtkCollectOrComputeBit( p, iBit );
+ else
+ pLits[i] = iBit+CONST_SHIFT;
+ assert( pLits[i] >= 0 );
+ Vec_IntFree( vTemp );
+ }
+ return Gia_ManHashMux(p->pGia, pLits[2], pLits[1], pLits[0]);
+}
+void Rtl_NtkBlastPrepareInputs( Rtl_Ntk_t * p, int * pCell )
+{
+ int i, k, Par, Val, iBit;
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_Int_t * vTemp;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, Val );
+ vTemp = Vec_IntDup( &p->vBitTemp );
+ Vec_IntForEachEntry( vTemp, iBit, k )
+ if ( iBit >= 0 )
+ Rtl_NtkCollectOrComputeBit( p, iBit );
+ Vec_IntFree( vTemp );
+ }
+}
+void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver )
+{
+ //char * pName = Rtl_NtkName(p);
+ assert( pDriver[0] != -1 );
+ if ( pDriver[0] == -3 )
+ {
+ int * pDriver1 = Vec_IntEntryP( &p->vDrivers, 2*pDriver[1] );
+ if ( Vec_IntEntry(&p->vLits, pDriver[1]) == -1 )
+ Rtl_NtkBlast2_rec( p, pDriver[1], pDriver1 );
+ assert( Vec_IntEntry(&p->vLits, pDriver[1]) >= 0 );
+ Vec_IntWriteEntry( &p->vLits, iBit, Vec_IntEntry(&p->vLits, pDriver[1]) );
+ return;
+ }
+ if ( pDriver[0] == -2 )
+ {
+ Vec_IntWriteEntry( &p->vLits, iBit, pDriver[1] );
+ return;
+ }
+ else
+ {
+ int * pCell = Rtl_NtkCell(p, pDriver[0]);
+ assert( pDriver[0] >= 0 );
+ if ( Rtl_CellModule(pCell) == ABC_OPER_SEL_NMUX ) // special case
+ {
+ int iLit = Rtl_NtkBlast2Spec( p, pCell, pDriver[1] );
+ Vec_IntWriteEntry( &p->vLits, iBit, iLit );
+ return;
+ }
+ Rtl_NtkBlastPrepareInputs( p, pCell );
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ Rtl_NtkBlastHierarchy( p->pGia, p, pCell );
+ else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Rtl_NtkBlastOperator( p->pGia, p, pCell );
+ else
+ printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) );
+ }
+}
+Gia_Man_t * Rtl_NtkBlast2( Rtl_Ntk_t * p )
+{
+ int fDump = 0;
+ Gia_Man_t * pTemp;
+ int i, b, nBits = Rtl_NtkRangeWires( p );
+ Vec_IntFill( &p->vLits, nBits, -1 );
+printf( "Blasting %s...\r", Rtl_NtkName(p) );
+ Rtl_NtkMapWires( p, 0 );
+ Rtl_NtkBlastMap( p, nBits );
+ assert( p->pGia == NULL );
+ p->pGia = Gia_ManStart( 1000 );
+ p->pGia->vBarBufs = Vec_IntAlloc( 1000 );
+ Rtl_NtkBlastInputs( p->pGia, p );
+ Gia_ManHashAlloc( p->pGia );
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ Rtl_NtkCollectOrComputeBit( p, First+b );
+ }
+ Gia_ManHashStop( p->pGia );
+ Rtl_NtkBlastOutputs( p->pGia, p );
+ Rtl_NtkMapWires( p, 1 );
+ p->pGia = Gia_ManCleanup( pTemp = p->pGia );
+ ABC_SWAP( Vec_Int_t *, p->pGia->vBarBufs, pTemp->vBarBufs );
+ Gia_ManStop( pTemp );
+// if ( p->fRoot )
+// Rtl_NtkPrintBufs( p, p->pGia->vBarBufs );
+ if ( fDump )
+ {
+ char Buffer[100]; static int counter = 0;
+ sprintf( Buffer, "old%02d.aig", counter++ );
+ Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 );
+ printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) );
+ }
+ else
+ printf( "Derived AIG for module %-20s : ", Rtl_ShortenName(Rtl_NtkName(p), 20) );
+ Gia_ManPrintStats( p->pGia, NULL );
+ return p->pGia;
+}
+void Rtl_LibMark_rec( Rtl_Ntk_t * pNtk )
+{
+ int i, * pCell;
+ if ( pNtk->iCopy == -1 )
+ return;
+ Rtl_NtkForEachCell( pNtk, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell );
+ if ( pMod )
+ Rtl_LibMark_rec( pMod );
+ }
+ assert( pNtk->iCopy == -2 );
+ pNtk->iCopy = -1;
+}
+void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots, int fInv )
+{
+ Rtl_Ntk_t * pNtk; int i, iNtk;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ if ( vRoots )
+ {
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -2;//, pNtk->fRoot = 0;
+ Vec_IntForEachEntry( vRoots, iNtk, i )
+ {
+ Rtl_Ntk_t * pNtk = Rtl_LibNtk(pLib, iNtk);
+ //pNtk->fRoot = fInv;
+ Rtl_LibMark_rec( pNtk );
+ }
+ }
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ if ( pNtk->iCopy == -1 && pNtk->pGia == NULL )
+ pNtk->pGia = Rtl_NtkBlast2( pNtk );
+// Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+// if ( pNtk->iCopy == -2 )
+// printf( "Skipping network \"%s\" during bit-blasting.\n", Rtl_NtkName(pNtk) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+}
+void Rtl_LibBlastClean( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Gia_ManStopP( &pNtk->pGia );
+}
+void Rtl_LibSetReplace( Rtl_Lib_t * p, Vec_Wec_t * vGuide )
+{
+ Vec_Int_t * vLevel; int i, iNtk1, iNtk2;
+ Rtl_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Type = Vec_IntEntry( vLevel, 1 );
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+ if ( Type != Rtl_LibStrId(p, "equal") )
+ continue;
+ iNtk1 = iNtk >> 16;
+ iNtk2 = iNtk & 0xFFFF;
+ pNtk1 = Rtl_LibNtk(p, iNtk1);
+ pNtk2 = Rtl_LibNtk(p, iNtk2);
+ pNtk1->iCopy = iNtk2;
+ if ( iNtk1 == iNtk2 )
+ printf( "Preparing to prove \"%s\".\n", Rtl_NtkName(pNtk1) );
+ else
+ printf( "Preparing to replace \"%s\" by \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_LibPreprocess( Rtl_Lib_t * pLib )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * p1 = NULL, * p2 = NULL, * p;
+ int i, k, Status, fFound = 0;
+ printf( "Performing preprocessing for verification.\n" );
+ // find similar modules
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p1, i )
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p2, k )
+ {
+ if ( i >= k )
+ continue;
+ if ( Gia_ManCiNum(p1->pGia) != Gia_ManCiNum(p2->pGia) ||
+ Gia_ManCoNum(p1->pGia) != Gia_ManCoNum(p2->pGia) )
+ continue;
+ // two similar modules
+ Status = Cec_ManVerifyTwo( p1->pGia, p2->pGia, 0 );
+ if ( Status != 1 )
+ continue;
+ printf( "Proved equivalent modules: %s == %s\n", Rtl_NtkName(p1), Rtl_NtkName(p2) );
+ // inline
+ if ( Gia_ManAndNum(p1->pGia) > Gia_ManAndNum(p2->pGia) )
+ ABC_SWAP( Gia_Man_t *, p1->pGia, p2->pGia );
+ assert( Gia_ManAndNum(p1->pGia) <= Gia_ManAndNum(p2->pGia) );
+ Gia_ManStopP( &p2->pGia );
+ p2->pGia = Gia_ManDup( p1->pGia );
+ fFound = 1;
+ goto finish;
+ }
+finish:
+ if ( fFound == 0 )
+ printf( "Preprocessing not succeded.\n" );
+ Abc_PrintTime( 1, "Preprocessing time", Abc_Clock() - clk );
+ // blast AIGs again
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ if ( p != p1 && p != p2 )
+ Gia_ManStopP( &p->pGia );
+ //Rtl_LibBlast( pLib );
+ Rtl_LibBlast2( pLib, NULL, 0 );
+}
+void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk )
+{
+ extern Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p );
+ abctime clk = Abc_Clock(); int Status;
+ Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib );
+ Gia_Man_t * pGia2 = Gia_ManReduceBuffers( pLib, pTop->pGia );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pGia2, 1000000, 0 );
+ int RetValue = Gia_ManAndNum(pSwp);
+ char * pFileName = "miter_to_solve.aig";
+ printf( "Dumped the miter into file \"%s\".\n", pFileName );
+ Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 );
+ Gia_ManStop( pSwp );
+ Gia_ManStop( pGia2 );
+ if ( RetValue == 0 )
+ printf( "Verification problem solved after SAT sweeping! " );
+ else
+ {
+ Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia );
+ Gia_ManInvertPos( pCopy );
+ Gia_ManAppendCo( pCopy, 0 );
+ Status = Cec_ManVerifySimple( pCopy );
+ Gia_ManStop( pCopy );
+ if ( Status == 1 )
+ printf( "Verification problem solved after CEC! " );
+ else
+ printf( "Verification problem is NOT solved (miter has %d nodes)! ", RetValue );
+ }
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ printf( "\nProving equivalence of \"%s\" and \"%s\"...\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ if ( Gia_ManCiNum(pNtk1->pGia) != Gia_ManCiNum(pNtk2->pGia) ||
+ Gia_ManCoNum(pNtk1->pGia) != Gia_ManCoNum(pNtk2->pGia) )
+ {
+ printf( "The number of inputs/outputs does not match.\n" );
+ }
+ else if ( 1 )
+ {
+ Gia_Man_t * pGia = Gia_ManMiter( pNtk1->pGia, pNtk2->pGia, 0, 0, 0, 0, 0 );
+ if ( Abc_NtkFromGiaCollapse( pGia ) )
+ Abc_Print( 1, "Networks are equivalent after collapsing. " );
+ else
+ {
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 );
+ //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Gia_ManStopP( &pNew );
+ Gia_ManStopP( &pGia );
+ }
+ }
+ else
+ {
+ int Status = Cec_ManVerifyTwo( pNtk1->pGia, pNtk2->pGia, 0 );
+ if ( Status == 1 )
+ printf( "The networks are equivalent. " );
+ else
+ printf( "The networks are NOT equivalent. " );
+ }
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts )
+{
+ int i, * pWire, Counts[4] = {0}, nBits = 0;
+ assert( p->nOutputs == 1 );
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ Counts[0]++, Counts[1] += pWire[1];
+ if ( pWire[0] & 2 ) // PO
+ Counts[2]++, Counts[3] += pWire[1];
+ }
+ assert( p->nInputs == Counts[0] );
+ assert( p->nOutputs == Counts[2] );
+ *pnOuts = Counts[3];
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ {
+ if ( pWire[1] == Counts[3] )
+ return nBits;
+ nBits += pWire[1];
+ }
+ }
+ return -1;
+}
+Gia_Man_t * Gia_ManMoveSharedFirst( Gia_Man_t * pGia, int iFirst, int nBits )
+{
+ Vec_Int_t * vPiPerm = Vec_IntAlloc( Gia_ManPiNum(pGia) );
+ Gia_Man_t * pTemp; int i, n;
+ for ( n = 0; n < 2; n++ )
+ for ( i = 0; i < Gia_ManPiNum(pGia); i++ )
+ if ( n == (i >= iFirst && i < iFirst + nBits) )
+ Vec_IntPush( vPiPerm, i );
+ pTemp = Gia_ManDupPerm( pGia, vPiPerm );
+ if ( pGia->vBarBufs )
+ pTemp->vBarBufs = Vec_IntDup( pGia->vBarBufs );
+ Vec_IntFree( vPiPerm );
+ return pTemp;
+}
+Vec_Int_t * Gia_ManCollectBufs( Gia_Man_t * p, int iFirst, int nBufs )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj; int i, iBuf = 0;
+ assert( iFirst >= 0 && iFirst + nBufs < p->nBufs );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Gia_ObjIsBuf(pObj) && iBuf >= iFirst && iBuf < iFirst + nBufs )
+ Vec_IntPush( vRes, i );
+ iBuf += Gia_ObjIsBuf(pObj);
+ }
+ assert( iBuf == p->nBufs );
+ return vRes;
+}
+Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 64 );
+ Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280-64, 64 );
+ //Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 1280/2 );
+ //Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280/2, 1280/2 );
+ int i, One, Two;
+ printf( "Reducing %d buffers... Size(vOne) = %d. Size(vTwo) = %d. \n", p->nBufs, Vec_IntSize(vOne), Vec_IntSize(vTwo) );
+ assert( p->nBufs == 1280 );
+ Vec_IntForEachEntryTwo( vOne, vTwo, One, Two, i )
+ Vec_IntWriteEntry( vMap, Two, One );
+ Vec_IntFree( vOne );
+ Vec_IntFree( vTwo );
+Gia_ManPrintStats( p, NULL );
+ //pNew = Gia_ManDupNoBuf( p );
+ pNew = Gia_ManDupMap( p, vMap );
+Gia_ManPrintStats( pNew, NULL );
+ Vec_IntFree( vMap );
+ //Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs );
+ //printf( "Found %d buffers.\n", p->nBufs );
+ return pNew;
+}
+void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ int Res = printf( "\nProving inverse equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ int nOuts1, iFirst1 = Gia_ManFindFirst( pNtk1, &nOuts1 );
+ int nOuts2, iFirst2 = Gia_ManFindFirst( pNtk2, &nOuts2 );
+ Gia_Man_t * pGia1 = Gia_ManMoveSharedFirst( pNtk1->pGia, iFirst1, nOuts1 );
+ Gia_Man_t * pGia2 = Gia_ManMoveSharedFirst( pNtk2->pGia, iFirst2, nOuts2 );
+ if ( 1 )
+ {
+ char * pFileName = "inv_miter.aig";
+ Gia_Man_t * pGia = Gia_ManMiterInverse( pGia1, pGia2, 0, 0 );
+ //Gia_Man_t * pGia2 = Gia_ManReduceBuffers( p, pGia );
+ Gia_Man_t * pGia2 = Gia_ManDupNoBuf( pGia );
+ printf( "Dumping inverse miter into file \"%s\".\n", pFileName );
+ Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 );
+ printf( "Dumped the miter into file \"%s\".\n", pFileName );
+ if ( Abc_NtkFromGiaCollapse( pGia2 ) )
+ Abc_Print( 1, "Networks are equivalent after collapsing. " );
+ else
+ {
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia2, 10000000, 0 );
+ Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs );
+ //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Gia_ManStopP( &pNew );
+ }
+ Gia_ManStopP( &pGia2 );
+ Gia_ManStopP( &pGia );
+ }
+ else
+ {
+ int Status = Cec_ManVerifyTwoInv( pGia1, pGia2, 0 );
+ if ( Status == 1 )
+ printf( "The networks are equivalent. " );
+ else
+ printf( "The networks are NOT equivalent. " );
+ }
+ Res = 0;
+ Gia_ManStopP( &pGia1 );
+ Gia_ManStopP( &pGia2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk )
+{
+ Rtl_Ntk_t * pNtk = Rtl_LibNtk( p, iNtk );
+ printf( "\nProving property \"%s\".\n", Rtl_NtkName(pNtk) );
+ Rtl_NtkPrintBufs( pNtk, pNtk->pGia->vBarBufs );
+ Rtl_LibSolve( p, pNtk );
+}
+Vec_Int_t * Wln_ReadNtkRoots( Rtl_Lib_t * p, Vec_Wec_t * vGuide )
+{
+ Vec_Int_t * vLevel; int i;
+ Vec_Int_t * vRoots = Vec_IntAlloc( 100 );
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+/*
+ else
+ {
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk >> 16 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk & 0xFFFF );
+ printf( "Matching \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ }
+*/
+ Vec_IntPushTwo( vRoots, iNtk >> 16, iNtk & 0xFFFF );
+ }
+ return vRoots;
+}
+void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p )
+{
+ extern Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p );
+ Vec_Wec_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName );
+ Vec_Int_t * vRoots, * vLevel; int i, iNtk1, iNtk2, fInv = 0;
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ if ( Vec_IntEntry( vLevel, 1 ) == Rtl_LibStrId(p, "inverse") )
+ fInv = 1;
+ Vec_IntFillExtra( p->vMap, Abc_NamObjNumMax(p->pManName), -1 );
+ Rtl_LibSetReplace( p, vGuide );
+ Rtl_LibUpdateBoxes( p );
+ Rtl_LibReorderModules( p );
+ vRoots = Wln_ReadNtkRoots( p, vGuide );
+ Rtl_LibBlast2( p, vRoots, fInv );
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Prove = Vec_IntEntry( vLevel, 0 );
+ int Type = Vec_IntEntry( vLevel, 1 );
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+ iNtk1 = iNtk >> 16;
+ iNtk2 = iNtk & 0xFFFF;
+ if ( Prove != Rtl_LibStrId(p, "prove") )
+ printf( "Unknown task in line %d.\n", i );
+ //else if ( iNtk1 == -1 )
+ // printf( "Network %s cannot be found in this design.\n", Rtl_LibStr(p, Name1) );
+ else
+ {
+ if ( Type == Rtl_LibStrId(p, "equal") )
+ Wln_SolveEqual( p, iNtk1, iNtk2 );
+ else if ( Type == Rtl_LibStrId(p, "inverse") )
+ Wln_SolveInverse( p, iNtk1, iNtk2 );
+ else if ( Type == Rtl_LibStrId(p, "property") )
+ Wln_SolveProperty( p, iNtk1 );
+ continue;
+ }
+ break;
+ }
+ Rtl_LibBlastClean( p );
+ Vec_WecFree( vGuide );
+ Vec_IntFree( vRoots );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+static inline void Gia_ManPatchBufDriver( Gia_Man_t * p, int iObj, int iLit0 )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ assert( iObj > Abc_Lit2Var(iLit0) );
+ pObj->iDiff0 = pObj->iDiff1 = iObj - Abc_Lit2Var(iLit0);
+ pObj->fCompl0 = pObj->fCompl1 = Abc_LitIsCompl(iLit0);
+}
+
+Gia_Man_t * Rtl_ReduceInverse( Rtl_Lib_t * pLib, Gia_Man_t * p )
+{
+ int fVerbose = 1;
+ Gia_Man_t * pNew = NULL;
+ Vec_Wec_t * vBufs = Vec_WecStart( Vec_IntSize(p->vBarBufs) );
+ Vec_Int_t * vPairs = Vec_IntAlloc( 10 );
+ Vec_Int_t * vTypes = Vec_IntAlloc( p->nBufs );
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj; int i, k = 0, Entry, Buf0, Buf1, fChange = 1;
+ Vec_IntForEachEntry( p->vBarBufs, Entry, i )
+ Vec_IntFillExtra( vTypes, Vec_IntSize(vTypes) + (Entry >> 16), i );
+ assert( Vec_IntSize(vTypes) == p->nBufs );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Gia_ObjIsBuf(pObj) )
+ {
+ Vec_WecPush( vBufs, Vec_IntEntry(vTypes, k), i );
+ Vec_IntWriteEntry( vMap, i, Vec_IntEntry(vTypes, k++) );
+ }
+ assert( k == p->nBufs );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Gia_ObjIsBuf(pObj) && Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) )
+ Vec_IntPushUnique( vPairs, (Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, i)) << 16) | (Vec_IntEntry(vMap, i) & 0xFFFF) );
+ if ( fVerbose )
+ {
+ printf( "Connected boundaries:\n" );
+ Vec_IntForEachEntry( vPairs, Entry, i )
+ {
+ printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF );
+ Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) );
+ printf( " -> " );
+ Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) );
+ printf( "\n" );
+ }
+ }
+ while ( fChange )
+ {
+ int Entry1, Entry2, j;
+ fChange = 0;
+ Vec_IntForEachEntryDouble( vPairs, Entry1, Entry2, j )
+ if ( (Entry1 & 0xFFFF) + 1 == (Entry2 >> 16) )
+ {
+ Vec_IntWriteEntry( vPairs, j, ((Entry1 >> 16) << 16) | (Entry2 & 0xFFFF) );
+ Vec_IntDrop( vPairs, j+1 );
+ fChange = 1;
+ break;
+ }
+ }
+// printf( "Before:\n" );
+// Vec_IntForEachEntry( vPairs, Entry, i )
+// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF );
+ Vec_IntForEachEntry( vPairs, Entry, i )
+ Vec_IntWriteEntry( vPairs, i, (((Entry >> 16) - 1) << 16) | ((Entry & 0xFFFF) + 1) );
+// printf( "After:\n" );
+// Vec_IntForEachEntry( vPairs, Entry, i )
+// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF );
+ if ( fVerbose )
+ {
+ printf( "Transformed boundaries:\n" );
+ Vec_IntForEachEntry( vPairs, Entry, i )
+ {
+ printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF );
+ Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) );
+ printf( " -> " );
+ Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) );
+ printf( "\n" );
+ }
+ }
+ Vec_IntForEachEntry( vPairs, Entry, i )
+ {
+ Vec_Int_t * vLevel0 = Vec_WecEntry( vBufs, Entry >> 16 );
+ Vec_Int_t * vLevel1 = Vec_WecEntry( vBufs, Entry & 0xFFFF );
+ Vec_IntForEachEntryTwo( vLevel0, vLevel1, Buf0, Buf1, k )
+ Gia_ManPatchBufDriver( p, Buf1, Gia_ObjFaninLit0(Gia_ManObj(p, Buf0), Buf0) );
+ }
+ pNew = Gia_ManRehash( p, 0 );
+ Vec_IntFree( vPairs );
+ Vec_IntFree( vTypes );
+ Vec_IntFree( vMap );
+ Vec_WecFree( vBufs );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rtl_LibReturnNtk( Rtl_Lib_t * p, char * pModule )
+{
+ int NameId = Wln_ReadFindToken( pModule, p->pManName );
+ int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1;
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find module \"%s\" in the current design.\n", pModule );
+ return -1;
+ }
+ return iNtk;
+}
+Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose )
+{
+ Gia_Man_t * pGia = NULL;
+ int NameId = Wln_ReadFindToken( pTopModule, p->pManName );
+ int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1;
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find top module \"%s\".\n", pTopModule );
+ return NULL;
+ }
+ else
+ {
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * pTop = Rtl_LibNtk(p, iNtk);
+ Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
+ Vec_IntPush( vRoots, iNtk );
+ Rtl_LibBlast2( p, vRoots, 1 );
+ pGia = Gia_ManDup( pTop->pGia );
+ //Gia_AigerWrite( pGia, "temp_miter.aig", 0, 0, 0 );
+ if ( pTop->pGia->vBarBufs )
+ pGia->vBarBufs = Vec_IntDup( pTop->pGia->vBarBufs );
+ printf( "Derived global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Rtl_NtkPrintBufs( pTop, pGia->vBarBufs );
+ Rtl_LibBlastClean( p );
+ Vec_IntFree( vRoots );
+ if ( p->vInverses )
+ {
+ Gia_Man_t * pTemp;
+ pGia = Rtl_ReduceInverse( p, pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ }
+ return pGia;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose )
+{
+ if ( nModules == 0 )
+ {
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_IntFreeP( &p->vInverses );
+ if ( p->vDirects )
+ {
+ int iName1, iName2;
+ Vec_IntForEachEntryDouble( p->vDirects, iName1, iName2, i )
+ {
+ int iNtk1 = Rtl_LibFindModule(p, iName1);
+ int iNtk2 = Rtl_LibFindModule(p, iName2);
+ //Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ pNtk2->iCopy = iNtk1;
+ }
+ Rtl_LibUpdateBoxes( p );
+ Rtl_LibReorderModules( p );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_IntFreeP( &p->vDirects );
+ }
+ }
+ else
+ {
+ int Name1 = Wln_ReadFindToken( pModules[0], p->pManName );
+ int Name2 = Wln_ReadFindToken( pModules[1], p->pManName );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ return;
+ }
+ else
+ {
+ int iNtk1 = iNtk >> 16;
+ int iNtk2 = iNtk & 0xFFFF;
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1);
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2);
+ assert( iNtk1 != iNtk2 );
+ if ( fInv )
+ {
+ printf( "Setting \"%s\" (appearing %d times) and \"%s\" (appearing %d times) as inverse-equivalent.\n",
+ Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) );
+ if ( p->vInverses == NULL )
+ p->vInverses = Vec_IntAlloc( 10 );
+ Vec_IntPushTwo( p->vInverses, pNtk1->NameId, pNtk2->NameId );
+ }
+ else
+ {
+ printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n",
+ Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) );
+ pNtk1->iCopy = iNtk2;
+ // Rtl_LibSetReplace( p, vGuide );
+ Rtl_LibUpdateBoxes( p );
+ Rtl_LibReorderModules( p );
+ if ( p->vDirects == NULL )
+ p->vDirects = Vec_IntAlloc( 10 );
+ Vec_IntPushTwo( p->vDirects, pNtk1->NameId, pNtk2->NameId );
+ }
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ if ( nModules == 0 ) // clean labels
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->fRoot = 0;
+ for ( i = 0; i < nModules; i++ )
+ {
+ int iNtk = Rtl_LibReturnNtk( p, ppModule[i] );
+ if ( iNtk == -1 )
+ continue;
+ pNtk = Rtl_LibNtk( p, iNtk );
+ pNtk->fRoot = 1;
+ printf( "Marking module \"%s\" (appearing %d times in the hierarchy).\n", ppModule[i], Rtl_LibCountInsts(p, pNtk) );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c
new file mode 100644
index 00000000..fa0f0cd5
--- /dev/null
+++ b/src/base/wln/wlnRtl.c
@@ -0,0 +1,211 @@
+/**CFile****************************************************************
+
+ FileName [wlnRtl.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Constructing WLN network from Rtl data structure.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnRtl.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/main/main.h"
+
+#ifdef WIN32
+#include <process.h>
+#define unlink _unlink
+#else
+#include <unistd.h>
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define MAX_LINE 1000000
+
+void Rtl_NtkCleanFile( char * pFileName )
+{
+ char * pBuffer, * pFileName2 = "_temp__.rtlil";
+ FILE * pFile = fopen( pFileName, "rb" );
+ FILE * pFile2;
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ pFile2 = fopen( pFileName2, "wb" );
+ if ( pFile2 == NULL )
+ {
+ fclose( pFile );
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName2 );
+ return;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ if ( !strstr(pBuffer, "attribute \\src") )
+ fputs( pBuffer, pFile2 );
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ fclose( pFile2 );
+}
+
+void Rtl_NtkCleanFile2( char * pFileName )
+{
+ char * pBuffer, * pFileName2 = "_temp__.v";
+ FILE * pFile = fopen( pFileName, "rb" );
+ FILE * pFile2;
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ pFile2 = fopen( pFileName2, "wb" );
+ if ( pFile2 == NULL )
+ {
+ fclose( pFile );
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName2 );
+ return;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ if ( !strstr(pBuffer, "//") )
+ fputs( pBuffer, pFile2 );
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ fclose( pFile2 );
+}
+
+char * Wln_GetYosysName()
+{
+ char * pYosysName = NULL;
+ char * pYosysNameWin = "yosys.exe";
+ char * pYosysNameUnix = "yosys";
+ if ( Abc_FrameReadFlag("yosyswin") )
+ pYosysNameWin = Abc_FrameReadFlag("yosyswin");
+ if ( Abc_FrameReadFlag("yosysunix") )
+ pYosysNameUnix = Abc_FrameReadFlag("yosysunix");
+#ifdef WIN32
+ pYosysName = pYosysNameWin;
+#else
+ pYosysName = pYosysNameUnix;
+#endif
+ return pYosysName;
+}
+int Wln_ConvertToRtl( char * pCommand, char * pFileTemp )
+{
+ FILE * pFile;
+ if ( system( pCommand ) == -1 )
+ {
+ fprintf( stdout, "Cannot execute \"%s\".\n", pCommand );
+ return 0;
+ }
+ if ( (pFile = fopen(pFileTemp, "r")) == NULL )
+ {
+ fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileTemp );
+ return 0;
+ }
+ fclose( pFile );
+ return 1;
+}
+Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose )
+{
+ Rtl_Lib_t * pNtk = NULL;
+ char Command[1000];
+ char * pFileTemp = "_temp_.rtlil";
+ int fSVlog = strstr(pFileName, ".sv") != NULL;
+ if ( strstr(pFileName, ".rtl") )
+ return Rtl_LibReadFile( pFileName, pFileName );
+ sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s\"",
+ Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName,
+ pTopModule ? "-top " : "",
+ pTopModule ? pTopModule : "",
+ fCollapse ? "flatten; " : "",
+ pFileTemp );
+ if ( fVerbose )
+ printf( "%s\n", Command );
+ if ( !Wln_ConvertToRtl(Command, pFileTemp) )
+ return NULL;
+ pNtk = Rtl_LibReadFile( pFileTemp, pFileName );
+ if ( pNtk == NULL )
+ {
+ printf( "Dumped the design into file \"%s\".\n", pFileTemp );
+ return NULL;
+ }
+ Rtl_NtkCleanFile( pFileTemp );
+ unlink( pFileTemp );
+ return pNtk;
+}
+Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose )
+{
+ Gia_Man_t * pGia = NULL;
+ char Command[1000];
+ char * pFileTemp = "_temp_.aig";
+ int fRtlil = strstr(pFileName, ".rtl") != NULL;
+ int fSVlog = strstr(pFileName, ".sv") != NULL;
+ sprintf( Command, "%s -qp \"%s%s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"",
+ Wln_GetYosysName(),
+ fRtlil ? "read_rtlil" : "read_verilog",
+ fSVlog ? " -sv ":" ",
+ pFileName,
+ pTopModule ? "-top " : "-auto-top",
+ pTopModule ? pTopModule : "",
+ fTechMap ? "techmap; setundef -zero; " : "", pFileTemp );
+ if ( fVerbose )
+ printf( "%s\n", Command );
+ if ( !Wln_ConvertToRtl(Command, pFileTemp) )
+ return NULL;
+ pGia = Gia_AigerRead( pFileTemp, 0, fSkipStrash, 0 );
+ if ( pGia == NULL )
+ {
+ printf( "Converting to AIG has failed.\n" );
+ return NULL;
+ }
+ ABC_FREE( pGia->pName );
+ pGia->pName = pTopModule ? Abc_UtilStrsav(pTopModule) :
+ Extra_FileNameGeneric( Extra_FileNameWithoutPath(pFileName) );
+ unlink( pFileTemp );
+ // complement the outputs
+ if ( fInvert )
+ {
+ Gia_Obj_t * pObj; int i;
+ Gia_ManForEachPo( pGia, pObj, i )
+ Gia_ObjFlipFaninC0( pObj );
+ }
+ return pGia;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/bdd/cudd/cuddAddIte.c b/src/bdd/cudd/cuddAddIte.c
index 574159c6..5f95bf47 100644
--- a/src/bdd/cudd/cuddAddIte.c
+++ b/src/bdd/cudd/cuddAddIte.c
@@ -359,6 +359,22 @@ Cudd_addCmpl(
} /* end of Cudd_addCmpl */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 as a key
+ that can be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_addLeq_dummy(DdManager * dd, DdNode * f, DdNode * g)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Determines whether f is less than or equal to g.]
@@ -394,7 +410,11 @@ Cudd_addLeq(
if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */
/* Check cache. */
+#ifdef USE_CASH_DUMMY
+ tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq_dummy,f,g);
+#else
tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g);
+#endif
if (tmp != NULL) {
return(tmp == DD_ONE(dd));
}
@@ -416,8 +436,13 @@ Cudd_addLeq(
res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv);
/* Store result in cache and return. */
+#ifdef USE_CASH_DUMMY
+ cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq_dummy,f,g,
+ Cudd_NotCond(DD_ONE(dd),res==0));
+#else
cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g,
Cudd_NotCond(DD_ONE(dd),res==0));
+#endif
return(res);
} /* end of Cudd_addLeq */
diff --git a/src/bdd/cudd/cuddAddNeg.c b/src/bdd/cudd/cuddAddNeg.c
index ab36874d..22d11219 100644
--- a/src/bdd/cudd/cuddAddNeg.c
+++ b/src/bdd/cudd/cuddAddNeg.c
@@ -226,6 +226,22 @@ cuddAddNegateRecur(
} /* end of cuddAddNegateRecur */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup1 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_addRoundOff_dummy(DdManager * dd, DdNode * f)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Implements the recursive step of Cudd_addRoundOff.]
@@ -253,7 +269,11 @@ cuddAddRoundOffRecur(
res = cuddUniqueConst(dd,n);
return(res);
}
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP1) Cudd_addRoundOff_dummy;
+#else
cacheOp = (DD_CTFP1) Cudd_addRoundOff;
+#endif
res = cuddCacheLookup1(dd,cacheOp,f);
if (res != NULL) {
return(res);
diff --git a/src/bdd/cudd/cuddBddAbs.c b/src/bdd/cudd/cuddBddAbs.c
index bfdd08ba..e2345617 100644
--- a/src/bdd/cudd/cuddBddAbs.c
+++ b/src/bdd/cudd/cuddBddAbs.c
@@ -266,6 +266,21 @@ Cudd_bddBooleanDiff(
} /* end of Cudd_bddBooleanDiff */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_bddVarIsDependent_dummy(DdManager *dd, DdNode *f, DdNode *var)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
/**Function********************************************************************
Synopsis [Checks whether a variable is dependent on others in a
@@ -305,7 +320,11 @@ Cudd_bddVarIsDependent(
return(0);
}
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP) Cudd_bddVarIsDependent_dummy;
+#else
cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
+#endif
res = cuddCacheLookup2(dd,cacheOp,f,var);
if (res != NULL) {
return(res != zero);
diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c
index 803d5f19..2901096c 100644
--- a/src/bdd/cudd/cuddBddIte.c
+++ b/src/bdd/cudd/cuddBddIte.c
@@ -520,6 +520,22 @@ Cudd_bddXnor(
} /* end of Cudd_bddXnor */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_bddLeq_dummy(DdManager * dd, DdNode * f, DdNode * g)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Determines whether f is less than or equal to g.]
@@ -573,7 +589,11 @@ Cudd_bddLeq(
/* Here neither f nor g is constant. */
/* Check cache. */
+#ifdef USE_CASH_DUMMY
+ tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq_dummy,f,g);
+#else
tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
+#endif
if (tmp != NULL) {
return(tmp == one);
}
@@ -605,7 +625,11 @@ Cudd_bddLeq(
res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
/* Store result in cache and return. */
+#ifdef USE_CASH_DUMMY
+ cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq_dummy,f,g,(res ? one : zero));
+#else
cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
+#endif
return(res);
} /* end of Cudd_bddLeq */
diff --git a/src/bdd/cudd/cuddClip.c b/src/bdd/cudd/cuddClip.c
index 9e3572f9..32ee7f6e 100644
--- a/src/bdd/cudd/cuddClip.c
+++ b/src/bdd/cudd/cuddClip.c
@@ -250,6 +250,34 @@ cuddBddClippingAndAbstract(
/*---------------------------------------------------------------------------*/
/* Definition of static functions */
/*---------------------------------------------------------------------------*/
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_bddClippingAnd_dummy(DdManager *dd, DdNode *f, DdNode *g)
+{
+ assert(0);
+ return 0;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+cuddBddClippingAnd_dummy(DdManager *dd, DdNode *f, DdNode *g)
+{
+ assert(0);
+ return 0;
+}
+#endif
/**Function********************************************************************
@@ -309,8 +337,12 @@ cuddBddClippingAndRecur(
}
F = Cudd_Regular(f);
G = Cudd_Regular(g);
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP) (direction ? Cudd_bddClippingAnd_dummy : cuddBddClippingAnd_dummy);
+#else
cacheOp = (DD_CTFP)
(direction ? Cudd_bddClippingAnd : cuddBddClippingAnd);
+#endif
if (F->ref != 1 || G->ref != 1) {
r = cuddCacheLookup2(manager, cacheOp, f, g);
if (r != NULL) return(r);
diff --git a/src/bdd/cudd/cuddMatMult.c b/src/bdd/cudd/cuddMatMult.c
index e8cae2ce..3dafa226 100644
--- a/src/bdd/cudd/cuddMatMult.c
+++ b/src/bdd/cudd/cuddMatMult.c
@@ -319,6 +319,23 @@ Cudd_addOuterSum(
/* Definition of static functions */
/*---------------------------------------------------------------------------*/
+
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+addMMRecur_dummy(DdManager * dd, DdNode * A, DdNode * B)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.]
@@ -393,7 +410,11 @@ addMMRecur(
topA = cuddI(dd,A->index); topB = cuddI(dd,B->index);
topV = ddMin(topA,topB);
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP) addMMRecur_dummy;
+#else
cacheOp = (DD_CTFP) addMMRecur;
+#endif
res = cuddCacheLookup2(dd,cacheOp,A,B);
if (res != NULL) {
/* If the result is 0, there is no need to normalize.
diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c
index aae5a732..27da4dc6 100644
--- a/src/bdd/cudd/cuddPriority.c
+++ b/src/bdd/cudd/cuddPriority.c
@@ -1571,6 +1571,22 @@ cuddCProjectionRecur(
} /* end of cuddCProjectionRecur */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+DdNode *
+Cudd_bddClosestCube_dummy(DdManager *dd, DdNode *f, DdNode *g)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_bddClosestCube.]
@@ -1667,7 +1683,11 @@ cuddBddClosestCube(
F = Cudd_Regular(f);
G = Cudd_Regular(g);
if (F->ref != 1 || G->ref != 1) {
+#ifdef USE_CASH_DUMMY
+ res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube_dummy, f, g);
+#else
res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g);
+#endif
if (res != NULL) return(res);
}
@@ -1817,7 +1837,11 @@ cuddBddClosestCube(
/* Only cache results that are different from azero to avoid
** storing results that depend on the value of the bound. */
if ((F->ref != 1 || G->ref != 1) && res != azero)
+#ifdef USE_CASH_DUMMY
+ cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube_dummy, f, g, res);
+#else
cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res);
+#endif
cuddDeref(res);
return(res);
diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c
index 899901dd..976c59ab 100644
--- a/src/bdd/cudd/cuddSat.c
+++ b/src/bdd/cudd/cuddSat.c
@@ -390,6 +390,22 @@ Cudd_ShortestLength(
} /* end of Cudd_ShortestLength */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_Decreasing_dummy(DdManager * dd, DdNode * f, DdNode * g)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Determines whether a BDD is negative unate in a
@@ -434,7 +450,11 @@ Cudd_Decreasing(
/* From now on, f is not constant. */
/* Check cache. */
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP) Cudd_Decreasing_dummy;
+#else
cacheOp = (DD_CTFP) Cudd_Decreasing;
+#endif
res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
if (res != NULL) {
return(res);
@@ -768,6 +788,22 @@ Cudd_bddLeqUnless(
} /* end of Cudd_bddLeqUnless */
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+Cudd_EqualSupNorm_dummy(DdManager * dd, DdNode * f, DdNode * g)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Compares two ADDs for equality within tolerance.]
@@ -817,7 +853,11 @@ Cudd_EqualSupNorm(
/* We only insert the result in the cache if the comparison is
** successful. Therefore, if we hit we return 1. */
+#ifdef USE_CASH_DUMMY
+ r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm_dummy,f,g);
+#else
r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g);
+#endif
if (r != NULL) {
return(1);
}
@@ -832,7 +872,11 @@ Cudd_EqualSupNorm(
if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
+#ifdef USE_CASH_DUMMY
+ cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm_dummy,f,g,DD_ONE(dd));
+#else
cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd));
+#endif
return(1);
diff --git a/src/bdd/cudd/cuddZddIsop.c b/src/bdd/cudd/cuddZddIsop.c
index ace0807b..116b7c2f 100644
--- a/src/bdd/cudd/cuddZddIsop.c
+++ b/src/bdd/cudd/cuddZddIsop.c
@@ -219,6 +219,22 @@ Cudd_MakeBddFromZddCover(
/*---------------------------------------------------------------------------*/
+#ifdef USE_CASH_DUMMY
+/**Function********************************************************************
+
+ Synopsis We need to declare a function passed to cuddCacheLookup2 that can
+ be casted to DD_CTFP.
+
+******************************************************************************/
+static DdNode *
+cuddZddIsop_dummy(DdManager * dd, DdNode * L, DdNode * U)
+{
+ assert(0);
+ return 0;
+}
+#endif
+
+
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_zddIsop.]
@@ -273,7 +289,11 @@ cuddZddIsop(
** Hence we need a double hit in the cache to terminate the
** recursion. Clearly, collisions may evict only one of the two
** results. */
+#ifdef USE_CASH_DUMMY
+ cacheOp = (DD_CTFP) cuddZddIsop_dummy;
+#else
cacheOp = (DD_CTFP) cuddZddIsop;
+#endif
r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
if (r) {
*zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
diff --git a/src/bool/dec/decAbc.c b/src/bool/dec/decAbc.c
index 6602702c..e440a652 100644
--- a/src/bool/dec/decAbc.c
+++ b/src/bool/dec/decAbc.c
@@ -237,20 +237,21 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
SeeAlso []
***********************************************************************/
-void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
+int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
{
extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph );
Abc_Obj_t * pRootNew;
Abc_Ntk_t * pNtk = pRoot->pNtk;
- int nNodesNew, nNodesOld;
+ int nNodesNew, nNodesOld, RetValue;
nNodesOld = Abc_NtkNodeNum(pNtk);
// create the new structure of nodes
pRootNew = Dec_GraphToNetwork( pNtk, pGraph );
// remove the old nodes
- Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
+ RetValue = Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
// compare the gains
nNodesNew = Abc_NtkNodeNum(pNtk);
//assert( nGain <= nNodesOld - nNodesNew );
+ return RetValue;
}
diff --git a/src/bool/kit/kitDsd.c b/src/bool/kit/kitDsd.c
index 7d85214b..cd02db67 100644
--- a/src/bool/kit/kitDsd.c
+++ b/src/bool/kit/kitDsd.c
@@ -2497,7 +2497,7 @@ void Kit_DsdVerify( Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars )
p = Kit_DsdManAlloc( nVars, Kit_DsdNtkObjNum(pNtk)+2 );
pTruthC = Kit_DsdTruthCompute( p, pNtk );
if ( !Extra_TruthIsEqual( pTruth, pTruthC, nVars ) )
- printf( "Verification failed.\n" );
+ printf( "Verification failed for gate with %d inputs.\n", nVars );
Kit_DsdManFree( p );
}
diff --git a/src/map/amap/amapRead.c b/src/map/amap/amapRead.c
index 3ccfc011..9e6ee21c 100644
--- a/src/map/amap/amapRead.c
+++ b/src/map/amap/amapRead.c
@@ -126,41 +126,52 @@ void Amap_RemoveComments( char * pBuffer, int * pnDots, int * pnLines )
// (in the BLIF file, comments are lines starting with "#")
nDots = nLines = 0;
for ( pCur = pBuffer; *pCur; pCur++ )
- {
+ {
// if this is the beginning of comment
// clean it with spaces until the new line statement
- if ( *pCur == '#' )
- while ( *pCur != '\n' )
- *pCur++ = ' ';
-
+ if ( *pCur == '#' ) {
+ while ( *pCur != '\n' ) {
+ *pCur++ = ' ';
+ }
+ }
// count the number of new lines and dots
if ( *pCur == '\n' ) {
- if (*(pCur-1)=='\r') {
- // DOS(R) file support
- if (*(pCur-2)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-2) = ' ';
- *(pCur-1) = ' ';
- *pCur = ' ';
- }
- } else {
- // UNIX(TM) file support
- if (*(pCur-1)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-1) = ' ';
- *pCur = ' ';
+ if (pCur > pBuffer) {
+ if (*(pCur - 1) == '\r') {
+ // DOS(R) file support
+ if (pCur > (pBuffer + 1)) {
+ if (*(pCur - 2)!='\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 2) = ' ';
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ } else {
+ // UNIX(TM) file support
+ if (*(pCur - 1) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur-1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ }
}
+ else if ( *pCur == '.' ) {
+ nDots++;
}
- }
- else if ( *pCur == '.' )
- nDots++;
- }
+ }
+
if ( pnDots )
- *pnDots = nDots;
+ *pnDots = nDots;
if ( pnLines )
- *pnLines = nLines;
+ *pnLines = nLines;
}
/**Function*************************************************************
@@ -491,4 +502,3 @@ Amap_Lib_t * Amap_LibReadFile( char * pFileName, int fVerbose )
ABC_NAMESPACE_IMPL_END
-
diff --git a/src/map/amap/amapUniq.c b/src/map/amap/amapUniq.c
index dd858c96..e2be4343 100644
--- a/src/map/amap/amapUniq.c
+++ b/src/map/amap/amapUniq.c
@@ -278,15 +278,14 @@ Abc_Lit2Var(iFan2), (Abc_LitIsCompl(iFan2)?'-':'+') );
int ** Amap_LibLookupTableAlloc( Vec_Ptr_t * vVec, int fVerbose )
{
Vec_Int_t * vOne;
- int ** pRes, * pBuffer;
+ int ** pRes;
int i, k, nTotal, nSize, nEntries, Value;
// count the total size
nEntries = nSize = Vec_PtrSize( vVec );
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
nEntries += Vec_IntSize(vOne);
- pBuffer = ABC_ALLOC( int, nSize * sizeof(void *) + nEntries );
- pRes = (int **)pBuffer;
- pRes[0] = pBuffer + nSize * sizeof(void *);
+ pRes = (int **)ABC_ALLOC( char, nSize * sizeof(void *) + nEntries * sizeof(int) );
+ pRes[0] = (int *)((char *)pRes + nSize * sizeof(void *));
nTotal = 0;
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
{
diff --git a/src/map/if/if.h b/src/map/if/if.h
index aa9608c9..13fa4108 100644
--- a/src/map/if/if.h
+++ b/src/map/if/if.h
@@ -275,6 +275,8 @@ struct If_Man_t_
void * pUserMan;
Vec_Int_t * vDump;
int pDumpIns[16];
+ Vec_Str_t * vMarks;
+ Vec_Int_t * vVisited2;
// timing manager
Tim_Man_t * pManTim;
@@ -564,7 +566,7 @@ extern If_DsdMan_t * If_DsdManAlloc( int nVars, int nLutSize );
extern void If_DsdManAllocIsops( If_DsdMan_t * p, int nLutSize );
extern void If_DsdManPrint( If_DsdMan_t * p, char * pFileName, int Number, int Support, int fOccurs, int fTtDump, int fVerbose );
extern void If_DsdManTune( If_DsdMan_t * p, int LutSize, int fFast, int fAdd, int fSpec, int fVerbose );
-extern void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose );
+extern void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose );
extern void If_DsdManFree( If_DsdMan_t * p, int fVerbose );
extern void If_DsdManSave( If_DsdMan_t * p, char * pFileName );
extern If_DsdMan_t * If_DsdManLoad( char * pFileName );
diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c
index 0c9287a1..c03061af 100644
--- a/src/map/if/ifCore.c
+++ b/src/map/if/ifCore.c
@@ -106,6 +106,8 @@ int If_ManPerformMappingComb( If_Man_t * p )
If_Obj_t * pObj;
abctime clkTotal = Abc_Clock();
int i;
+ //p->vVisited2 = Vec_IntAlloc( 100 );
+ //p->vMarks = Vec_StrStart( If_ManObjNum(p) );
// set arrival times and fanout estimates
If_ManForEachCi( p, pObj, i )
diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c
index 2d6889c0..079781e0 100644
--- a/src/map/if/ifCut.c
+++ b/src/map/if/ifCut.c
@@ -1494,6 +1494,68 @@ int If_CutCountTotalFanins( If_Man_t * p )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutFilter2_rec( If_Man_t * p, If_Obj_t * pObj, int LevelMin )
+{
+ char * pVisited = Vec_StrEntryP(p->vMarks, pObj->Id);
+ if ( *pVisited )
+ return *pVisited;
+ Vec_IntPush( p->vVisited2, pObj->Id );
+ if ( (int)pObj->Level <= LevelMin )
+ return (*pVisited = 1);
+ if ( If_CutFilter2_rec( p, pObj->pFanin0, LevelMin ) == 1 )
+ return (*pVisited = 1);
+ if ( If_CutFilter2_rec( p, pObj->pFanin1, LevelMin ) == 1 )
+ return (*pVisited = 1);
+ return (*pVisited = 2);
+}
+int If_CutFilter2( If_Man_t * p, If_Obj_t * pNode, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf, * pTemp; int i, Count = 0;
+// printf( "Considering node %d and cut {", pNode->Id );
+// If_CutForEachLeaf( p, pCut, pLeaf, i )
+// printf( " %d", pLeaf->Id );
+// printf( " }\n" );
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ {
+ int k, iObj, RetValue, nLevelMin = ABC_INFINITY;
+ Vec_IntClear( p->vVisited2 );
+ If_CutForEachLeaf( p, pCut, pTemp, k )
+ {
+ if ( pTemp == pLeaf )
+ continue;
+ nLevelMin = Abc_MinInt( nLevelMin, (int)pTemp->Level );
+ assert( Vec_StrEntry(p->vMarks, pTemp->Id) == 0 );
+ Vec_StrWriteEntry( p->vMarks, pTemp->Id, 2 );
+ Vec_IntPush( p->vVisited2, pTemp->Id );
+ }
+ RetValue = If_CutFilter2_rec( p, pLeaf, nLevelMin );
+ Vec_IntForEachEntry( p->vVisited2, iObj, k )
+ Vec_StrWriteEntry( p->vMarks, iObj, 0 );
+ if ( RetValue == 2 )
+ {
+ Count++;
+ pCut->nLeaves--;
+ for ( k = i; k < (int)pCut->nLeaves; k++ )
+ pCut->pLeaves[k] = pCut->pLeaves[k+1];
+ i--;
+ }
+ }
+ //if ( Count )
+ // printf( "%d", Count );
+ return 0;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/if/ifDsd.c b/src/map/if/ifDsd.c
index ddfc1036..d33c42d6 100644
--- a/src/map/if/ifDsd.c
+++ b/src/map/if/ifDsd.c
@@ -2554,7 +2554,7 @@ void Id_DsdManTuneStr1( If_DsdMan_t * p, char * pStruct, int nConfls, int fVerbo
***********************************************************************/
#ifndef ABC_USE_PTHREADS
-void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose )
+void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose )
{
Id_DsdManTuneStr1( p, pStruct, nConfls, fVerbose );
}
@@ -2600,7 +2600,7 @@ void * Ifn_WorkerThread( void * pArg )
assert( 0 );
return NULL;
}
-void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose )
+void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose )
{
int fVeryVerbose = 0;
ProgressBar * pProgress = NULL;
@@ -2703,8 +2703,8 @@ void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs,
Extra_ProgressBarUpdate( pProgress, k, NULL );
pObj = If_DsdVecObj( &p->vObjs, k );
nVars = If_DsdObjSuppSize(pObj);
- //if ( nVars <= LutSize )
- // continue;
+ if ( nInputs && nVars < nInputs )
+ continue;
clk = Abc_Clock();
If_DsdManComputeTruthPtr( p, Abc_Var2Lit(k, 0), NULL, ThData[i].pTruth );
clkUsed += Abc_Clock() - clk;
diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c
index 4027b780..6ecd0eb8 100644
--- a/src/map/if/ifMan.c
+++ b/src/map/if/ifMan.c
@@ -273,6 +273,8 @@ void If_ManStop( If_Man_t * p )
Vec_IntFreeP( &p->vPairRes );
Vec_StrFreeP( &p->vPairPerms );
Vec_PtrFreeP( &p->vVisited );
+ Vec_StrFreeP( &p->vMarks );
+ Vec_IntFreeP( &p->vVisited2 );
if ( p->vPairHash )
Hash_IntManStop( p->vPairHash );
for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c
index c0a83cfd..c19c07d4 100644
--- a/src/map/mio/mioRead.c
+++ b/src/map/mio/mioRead.c
@@ -734,37 +734,48 @@ void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines )
// (in the BLIF file, comments are lines starting with "#")
nDots = nLines = 0;
for ( pCur = pBuffer; *pCur; pCur++ )
- {
+ {
// if this is the beginning of comment
// clean it with spaces until the new line statement
- if ( *pCur == '#' )
- while ( *pCur != '\n' )
- *pCur++ = ' ';
-
+ if ( *pCur == '#' ) {
+ while ( *pCur != '\n' ) {
+ *pCur++ = ' ';
+ }
+ }
// count the number of new lines and dots
if ( *pCur == '\n' ) {
- if (*(pCur-1)=='\r') {
- // DOS(R) file support
- if (*(pCur-2)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-2) = ' ';
- *(pCur-1) = ' ';
- *pCur = ' ';
- }
- } else {
- // UNIX(TM) file support
- if (*(pCur-1)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-1) = ' ';
- *pCur = ' ';
+ if (pCur > pBuffer) {
+ if (*(pCur - 1) == '\r') {
+ // DOS(R) file support
+ if (pCur > (pBuffer + 1)) {
+ if (*(pCur - 2) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 2) = ' ';
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ } else {
+ // UNIX(TM) file support
+ if (*(pCur - 1) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ }
}
+ else if ( *pCur == '.' ) {
+ nDots++;
}
- }
- else if ( *pCur == '.' )
- nDots++;
- }
+ }
+
if ( pnDots )
*pnDots = nDots;
if ( pnLines )
diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c
index c7180e1c..06e880c2 100644
--- a/src/map/mio/mioUtils.c
+++ b/src/map/mio/mioUtils.c
@@ -224,6 +224,7 @@ void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins )
***********************************************************************/
void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, int FormLen, int fPrintSops, int fAllPins )
{
+ //Vec_Int_t * vCover = Vec_IntAlloc( 1 << 10 ); int nLits;
char Buffer[5000];
Mio_Pin_t * pPin;
assert( NameLen+FormLen+2 < 5000 );
@@ -239,7 +240,11 @@ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen,
else // different pins
Mio_GateForEachPin( pGate, pPin )
Mio_WritePin( pFile, pPin, NameLen, 0 );
+ //nLits = 2*Kit_TruthLitNum((unsigned*)&pGate->uTruth, Mio_GateReadPinNum(pGate), vCover);
+ //if ( nLits != Mio_GateReadArea(pGate) )
+ // printf( " # %d ", nLits );
fprintf( pFile, "\n" );
+ //Vec_IntFree( vCover );
}
/**Function*************************************************************
diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c
index 4b6adab4..49b5c237 100644
--- a/src/map/scl/sclLiberty.c
+++ b/src/map/scl/sclLiberty.c
@@ -955,6 +955,8 @@ int Scl_LibertyReadPinDirection( Scl_Tree_t * p, Scl_Item_t * pPin )
return 0;
if ( !strcmp(pToken, "output") )
return 1;
+ if ( !strcmp(pToken, "internal") )
+ return 2;
break;
}
return -1;
@@ -1525,7 +1527,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
float CapOne, CapRise, CapFall;
if ( Scl_LibertyReadPinFormula(p, pPin) != NULL ) // skip output pin
continue;
- assert( Scl_LibertyReadPinDirection(p, pPin) == 0 );
+ assert( Scl_LibertyReadPinDirection(p, pPin) == 0 || Scl_LibertyReadPinDirection(p, pPin) == 2);
pName = Scl_LibertyReadString(p, pPin->Head);
Vec_PtrPush( vNameIns, Abc_UtilStrsav(pName) );
Vec_StrPutS_( vOut, pName );
@@ -1546,6 +1548,8 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
{
if ( !Scl_LibertyReadPinFormula(p, pPin) ) // skip input pin
continue;
+ if (Scl_LibertyReadPinDirection(p, pPin) == 2) // skip internal pin
+ continue;
assert( Scl_LibertyReadPinDirection(p, pPin) == 1 );
pName = Scl_LibertyReadString(p, pPin->Head);
Vec_StrPutS_( vOut, pName );
diff --git a/src/misc/extra/extraUtilMisc.c b/src/misc/extra/extraUtilMisc.c
index c38369cd..e081e9c6 100644
--- a/src/misc/extra/extraUtilMisc.c
+++ b/src/misc/extra/extraUtilMisc.c
@@ -1290,7 +1290,7 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha
{ 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
{ 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
};
- static char Cases[256] = {
+ static signed char Cases[256] = {
0, // 00000000
0, // 00000001
1, // 00000010
diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h
index d9efa55f..bc8ac3f0 100644
--- a/src/misc/util/utilTruth.h
+++ b/src/misc/util/utilTruth.h
@@ -1471,6 +1471,24 @@ static inline void Abc_TtPrintBinary( word * pTruth, int nVars )
printf( "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) );
printf( "\n" );
}
+static inline void Abc_TtPrintBinary1( FILE * pFile, word * pTruth, int nVars )
+{
+ word * pThis, * pLimit = pTruth + Abc_TtWordNum(nVars);
+ int k, Limit = Abc_MinInt( 64, (1 << nVars) );
+ assert( nVars >= 2 );
+ for ( pThis = pTruth; pThis < pLimit; pThis++ )
+ for ( k = 0; k < Limit; k++ )
+ fprintf( pFile, "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) );
+}
+static inline void Abc_TtPrintBinary2( FILE * pFile, word * pTruth, int nVars )
+{
+ word * pThis;
+ int k, Limit = Abc_MinInt( 64, (1 << nVars) );
+ assert( nVars >= 2 );
+ for ( pThis = pTruth + Abc_TtWordNum(nVars) - 1; pThis >= pTruth; pThis-- )
+ for ( k = Limit-1; k >= 0; k-- )
+ fprintf( pFile, "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) );
+}
/**Function*************************************************************
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index c15369d2..e4ea6cfe 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -61,6 +61,8 @@ struct Vec_Int_t_
for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
+#define Vec_IntForEachEntryReverseStart( vVec, pEntry, i, Start ) \
+ for ( i = Start; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
#define Vec_IntForEachEntryTwo( vVec1, vVec2, Entry1, Entry2, i ) \
for ( i = 0; (i < Vec_IntSize(vVec1)) && (((Entry1) = Vec_IntEntry(vVec1, i)), 1) && (((Entry2) = Vec_IntEntry(vVec2, i)), 1); i++ )
#define Vec_IntForEachEntryTwoStart( vVec1, vVec2, Entry1, Entry2, i, Start ) \
diff --git a/src/misc/vec/vecWrd.h b/src/misc/vec/vecWrd.h
index 8275702a..fdbb1866 100644
--- a/src/misc/vec/vecWrd.h
+++ b/src/misc/vec/vecWrd.h
@@ -195,6 +195,14 @@ static inline Vec_Wrd_t * Vec_WrdStartTruthTables( int nVars )
}
return p;
}
+static inline int Vec_WrdShiftOne( Vec_Wrd_t * p, int nWords )
+{
+ int i, nObjs = p->nSize/nWords;
+ assert( nObjs * nWords == p->nSize );
+ for ( i = 0; i < nObjs; i++ )
+ p->pArray[i*nWords] <<= 1;
+ return nObjs;
+}
/**Function*************************************************************
diff --git a/src/opt/dau/dauCanon.c b/src/opt/dau/dauCanon.c
index 89359611..dd954d9a 100644
--- a/src/opt/dau/dauCanon.c
+++ b/src/opt/dau/dauCanon.c
@@ -1027,7 +1027,7 @@ int Abc_TtCofactorPerm( word * pTruth, int i, int nWords, int fSwapOnly, char *
SeeAlso []
***********************************************************************/
-#define CANON_VERIFY
+//#define CANON_VERIFY
unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm )
{
int pStoreIn[17];
diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c
index 9cddcd13..51af0214 100644
--- a/src/proof/acec/acecBo.c
+++ b/src/proof/acec/acecBo.c
@@ -21,6 +21,7 @@
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -207,6 +208,82 @@ void Acec_DetectBoothTest( Gia_Man_t * p )
}
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManResubTest4()
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ unsigned T = 0xF335ACC0;
+ int a, b, c;
+ int i, k, f, y;
+ int Count = 0;
+ for ( a = 0; a < 2; a++ )
+ {
+ unsigned A = s_Truths5[a];
+ for ( b = 0; b < 3; b++ )
+ {
+ unsigned B = s_Truths5[2+b];
+ for ( c = 0; c < 3; c++ ) if ( c != b )
+ {
+ unsigned C = s_Truths5[2+c];
+ Vec_IntPush( vRes, A & B & C );
+ Vec_IntPush( vRes, A & B & ~C );
+ }
+ }
+ }
+ printf( "Size = %d.\n", Vec_IntSize(vRes) );
+ for ( i = 0; i < (1 << Vec_IntSize(vRes)); i++ )
+ {
+ unsigned F[7] = {0};
+ unsigned Y[3] = {0};
+ if ( Abc_TtCountOnes( (word)i ) >= 8 )
+ continue;
+ for ( f = k = 0; k < Vec_IntSize(vRes); k++ )
+ if ( ((i >> k) & 1) )
+ F[f++] = Vec_IntEntry(vRes, k);
+ {
+ unsigned S1 = (F[0] & F[1]) | (F[0] & F[2]) | (F[1] & F[2]);
+ unsigned C1 = F[0] ^ F[1] ^ F[2];
+ unsigned S2 = (F[3] & F[4]) | (F[3] & F[5]) | (F[4] & F[5]);
+ unsigned C2 = F[3] ^ F[4] ^ F[5];
+ unsigned S3 = (F[6] & S1) | (F[6] & S2) | (S1 & S2);
+ unsigned C3 = F[6] ^ S1 ^ S2;
+ unsigned S4 = (C1 & C2) | (C1 & C3) | (C2 & C3);
+ unsigned C4 = C1 ^ C2 ^ C3;
+ Y[0] = S3;
+ Y[1] = S4;
+ Y[2] = C4;
+ }
+ for ( y = 0; y < 3; y++ )
+ if ( Y[y] == T )
+ printf( "Found!\n" );
+ Count++;
+ }
+ printf( "Tried = %d.\n", Count );
+ Vec_IntFree( vRes );
+}
+void Gia_ManResubTest5()
+{
+ unsigned T = 0xF335ACC0;
+ int i;
+ for ( i = 0; i < 4; i++ )
+ {
+ unsigned x = i%2 ? Abc_Tt5Cofactor1(T, 0) : Abc_Tt5Cofactor0(T, 0);
+ unsigned y = i/2 ? Abc_Tt5Cofactor1(x, 1) : Abc_Tt5Cofactor0(x, 1);
+ word F = y;
+ F |= F << 32;
+ //Dau_DsdPrintFromTruth2( &F, 6 ); printf( "\n" );
+ }
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c
index 71e0b7b3..49d0a58f 100644
--- a/src/proof/acec/acecXor.c
+++ b/src/proof/acec/acecXor.c
@@ -21,6 +21,7 @@
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -425,6 +426,49 @@ Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose )
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManTestXor( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
+ int n, i, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p);
+ Gia_Obj_t * pObj; Vec_Wrd_t * vSims2;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Gia_Obj_t Obj = *pObj;
+ for ( n = 0; n < 2; n++ )
+ {
+ if ( n )
+ {
+ pObj->iDiff1 = pObj->iDiff0;
+ pObj->fCompl1 = pObj->fCompl0;
+ }
+ else
+ {
+ pObj->iDiff0 = pObj->iDiff1;
+ pObj->fCompl0 = pObj->fCompl1;
+ }
+ vSims2 = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
+ printf( "%2d %2d : %5d\n", i, n, Abc_TtCountOnesVecXor(Vec_WrdArray(vSims), Vec_WrdArray(vSims2), Vec_WrdSize(vSims2)) );
+ Vec_WrdFree( vSims2 );
+ *pObj = Obj;
+ }
+ }
+ Vec_WrdFree( vSimsPi );
+ Vec_WrdFree( vSims );
+ nWords = 0;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h
index 7c101570..92a08b3e 100644
--- a/src/proof/cec/cec.h
+++ b/src/proof/cec/cec.h
@@ -149,6 +149,7 @@ struct Cec_ParCor_t_
int nBTLimit; // conflict limit at a node
int nLevelMax; // (scorr only) the max number of levels
int nStepsMax; // (scorr only) the max number of induction steps
+ int nLimitMax; // (scorr only) stop after this many iterations if little or no improvement
int fLatchCorr; // consider only latch outputs
int fConstCorr; // consider only constants
int fUseRings; // use rings
@@ -206,6 +207,7 @@ struct Cec_ParSeq_t_
/*=== cecCec.c ==========================================================*/
extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars );
extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
+extern int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
extern int Cec_ManVerifySimple( Gia_Man_t * p );
/*=== cecChoice.c ==========================================================*/
extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars );
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
index cfa07ff8..f6a1ab52 100644
--- a/src/proof/cec/cecCec.c
+++ b/src/proof/cec/cecCec.c
@@ -465,6 +465,21 @@ int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
Gia_ManStop( pMiter );
return RetValue;
}
+int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ Gia_Man_t * pMiter;
+ int RetValue;
+ Cec_ManCecSetDefaultParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pMiter = Gia_ManMiterInverse( p0, p1, 1, pPars->fVerbose );
+ if ( pMiter == NULL )
+ return -1;
+ RetValue = Cec_ManVerify( pMiter, pPars );
+ p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL;
+ Gia_ManStop( pMiter );
+ return RetValue;
+}
/**Function*************************************************************
diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c
index ce7e0885..d1d8958f 100644
--- a/src/proof/cec/cecCorr.c
+++ b/src/proof/cec/cecCorr.c
@@ -756,6 +756,21 @@ void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIte
Abc_Print( 1, "%c ", Gia_ObjIsConst( p, Gia_ObjFaninId0p(p, Gia_ManPo(p, 0)) ) ? '+' : '-' );
Abc_PrintTime( 1, "T", Time );
}
+int Cec_ManCountLits( Gia_Man_t * p )
+{
+ int i, CounterX = 0, Counter0 = 0, Counter = 0;
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter0++;
+ else if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ }
+ CounterX -= Gia_ManCoNum(p);
+ return Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
+}
/**Function*************************************************************
@@ -777,7 +792,7 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr
Vec_Int_t * vCexStore;
Cec_ManSim_t * pSim;
Gia_Man_t * pSrm;
- int fChanges, RetValue;
+ int fChanges, RetValue, i;
// prepare simulation manager
Cec_ManSimSetDefaultParams( pParsSim );
pParsSim->nWords = pPars->nWords;
@@ -791,7 +806,7 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr
pParsSat->nBTLimit = pPars->nBTLimit;
pParsSat->fVerbose = pPars->fVerbose;
fChanges = 1;
- while ( fChanges )
+ for ( i = 0; fChanges && (!pPars->nLimitMax || i < pPars->nLimitMax); i++ )
{
abctime clkBmc = Abc_Clock();
fChanges = 0;
@@ -918,7 +933,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
Cec_ManSim_t * pSim;
Gia_Man_t * pSrm;
- int r, RetValue;
+ int r, RetValue, nPrev[4] = {0};
abctime clkTotal = Abc_Clock();
abctime clkSat = 0, clkSim = 0, clkSrm = 0;
abctime clk2, clk = Abc_Clock();
@@ -1031,6 +1046,23 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
Cec_ManSimStop( pSim );
return 0;
}
+ if ( pPars->nLimitMax )
+ {
+ int nCur = Cec_ManCountLits(pAig);
+ if ( r > 4 && nPrev[0] - nCur <= 4*pPars->nLimitMax )
+ {
+ printf( "Iterative refinement is stopped after iteration %d\n", r );
+ printf( "because refinement does not proceed quickly.\n" );
+ Cec_ManSimStop( pSim );
+ ABC_FREE( pAig->pReprs );
+ ABC_FREE( pAig->pNexts );
+ return 0;
+ }
+ nPrev[0] = nPrev[1];
+ nPrev[1] = nPrev[2];
+ nPrev[2] = nPrev[3];
+ nPrev[3] = nCur;
+ }
}
if ( pPars->fVerbose )
Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, Abc_Clock() - clk );
diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c
index ce299c66..2bbc03d2 100644
--- a/src/proof/cec/cecSatG2.c
+++ b/src/proof/cec/cecSatG2.c
@@ -1877,9 +1877,9 @@ void Cec4_ManSimulateTest2( Gia_Man_t * p, int nConfs, int fVerbose )
abctime clk = Abc_Clock();
Cec_ParFra_t ParsFra, * pPars = &ParsFra;
Cec4_ManSetParams( pPars );
- Cec4_ManPerformSweeping( p, pPars, NULL, 0 );
pPars->fVerbose = fVerbose;
pPars->nBTLimit = nConfs;
+ Cec4_ManPerformSweeping( p, pPars, NULL, 0 );
if ( fVerbose )
Abc_PrintTime( 1, "New choice computation time", Abc_Clock() - clk );
}
@@ -1912,6 +1912,139 @@ int Cec4_ManSimulateOnlyTest( Gia_Man_t * p, int fVerbose )
return Cec4_ManPerformSweeping( p, pPars, NULL, 1 );
}
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_ManSimulateTest5Int( Gia_Man_t * p, int nConfs, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec4_ManSetParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pPars->nBTLimit = nConfs;
+ Cec4_ManPerformSweeping( p, pPars, NULL, 0 );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Equivalence detection time", Abc_Clock() - clk );
+}
+Gia_Man_t * Gia_ManLocalRehash( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ int iLitNew = Gia_ManObj(pTemp, Abc_Lit2Var(pObj->Value))->Value;
+ if ( iLitNew == ~0 )
+ pObj->Value = iLitNew;
+ else
+ pObj->Value = Abc_LitNotCond(iLitNew, Abc_LitIsCompl(pObj->Value));
+ }
+ Gia_ManStop( pTemp );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+Vec_Int_t * Cec4_ManComputeMapping( Gia_Man_t * p, Gia_Man_t * pAig, int fVerbose )
+{
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vReprs = Vec_IntStartFull( Gia_ManObjNum(p) );
+ int * pAig2Abc = ABC_FALLOC( int, Gia_ManObjNum(pAig) );
+ int i, nConsts = 0, nReprs = 0;
+ pAig2Abc[0] = 0;
+ Gia_ManForEachCand( p, pObj, i )
+ {
+ int iLitGia = pObj->Value, iReprGia;
+ if ( iLitGia == -1 )
+ continue;
+ iReprGia = Gia_ObjReprSelf( pAig, Abc_Lit2Var(iLitGia) );
+ if ( pAig2Abc[iReprGia] == -1 )
+ pAig2Abc[iReprGia] = i;
+ else
+ {
+ int iLitGia2 = Gia_ManObj(p, pAig2Abc[iReprGia] )->Value;
+ assert( Gia_ObjReprSelf(pAig, Abc_Lit2Var(iLitGia)) == Gia_ObjReprSelf(pAig, Abc_Lit2Var(iLitGia2)) );
+ assert( i > pAig2Abc[iReprGia] );
+ Vec_IntWriteEntry( vReprs, i, pAig2Abc[iReprGia] );
+ if ( pAig2Abc[iReprGia] == 0 )
+ nConsts++;
+ else
+ nReprs++;
+ }
+ }
+ ABC_FREE( pAig2Abc );
+ if ( fVerbose )
+ printf( "Found %d const reprs and %d other reprs.\n", nConsts, nReprs );
+ return vReprs;
+}
+void Cec4_ManVerifyEquivs( Gia_Man_t * p, Vec_Int_t * vRes, int fVerbose )
+{
+ int i, iRepr, nWords = 4; word * pSim0, * pSim1;
+ Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(p) * nWords );
+ int nObjs = Vec_WrdShiftOne( vSimsCi, nWords ), nFails = 0;
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsCi, 0 );
+ assert( Vec_IntSize(vRes) == Gia_ManObjNum(p) );
+ assert( nObjs == Gia_ManCiNum(p) );
+ Vec_IntForEachEntry( vRes, iRepr, i )
+ {
+ if ( iRepr == -1 )
+ continue;
+ assert( i > iRepr );
+ pSim0 = Vec_WrdEntryP( vSims, nWords*i );
+ pSim1 = Vec_WrdEntryP( vSims, nWords*iRepr );
+ if ( (pSim0[0] ^ pSim1[0]) & 1 )
+ nFails += !Abc_TtOpposite(pSim0, pSim1, nWords);
+ else
+ nFails += !Abc_TtEqual(pSim0, pSim1, nWords);
+ }
+ Vec_WrdFree( vSimsCi );
+ Vec_WrdFree( vSims );
+ if ( nFails )
+ printf( "Verification failed at %d nodes.\n", nFails );
+ else if ( fVerbose )
+ printf( "Verification succeeded for all (%d) nodes.\n", Gia_ManCandNum(p) );
+}
+void Cec4_ManConvertToLits( Gia_Man_t * p, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj; int i, iRepr;
+ Gia_ManSetPhase( p );
+ Gia_ManForEachObj( p, pObj, i )
+ if ( (iRepr = Vec_IntEntry(vRes, i)) >= 0 )
+ Vec_IntWriteEntry( vRes, i, Abc_Var2Lit(iRepr, Gia_ManObj(p, iRepr)->fPhase ^ pObj->fPhase) );
+}
+void Cec4_ManSimulateTest5( Gia_Man_t * p, int nConfs, int fVerbose )
+{
+ Vec_Int_t * vRes = NULL;
+ Gia_Man_t * pAig = Gia_ManLocalRehash( p );
+ Cec4_ManSimulateTest5Int( pAig, nConfs, fVerbose );
+ vRes = Cec4_ManComputeMapping( p, pAig, fVerbose );
+ Cec4_ManVerifyEquivs( p, vRes, fVerbose );
+ Cec4_ManConvertToLits( p, vRes );
+ Vec_IntDumpBin( "_temp_.equiv", vRes, fVerbose );
+ Vec_IntFree( vRes );
+ Gia_ManStop( pAig );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/cec/cecSatG3.c b/src/proof/cec/cecSatG3.c
new file mode 100644
index 00000000..f8e3ad0a
--- /dev/null
+++ b/src/proof/cec/cecSatG3.c
@@ -0,0 +1,2342 @@
+/**CFile****************************************************************
+
+ FileName [cecSatG2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Detection of structural isomorphism.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSatG2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "cec.h"
+#include "aig/gia/giaCSatP.h"
+#include <stdlib.h>
+
+#define USE_GLUCOSE2
+
+#ifdef USE_GLUCOSE2
+
+#include "sat/glucose2/AbcGlucose2.h"
+
+#define sat_solver bmcg2_sat_solver
+#define sat_solver_start bmcg2_sat_solver_start
+#define sat_solver_stop bmcg2_sat_solver_stop
+#define sat_solver_addclause bmcg2_sat_solver_addclause
+#define sat_solver_add_and bmcg2_sat_solver_add_and
+#define sat_solver_add_xor bmcg2_sat_solver_add_xor
+#define sat_solver_addvar bmcg2_sat_solver_addvar
+#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue
+#define sat_solver_reset bmcg2_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg2_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg2_sat_solver_conflictnum
+#define sat_solver_solve bmcg2_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg2_sat_solver_read_cex
+#define sat_solver_jftr bmcg2_sat_solver_jftr
+#define sat_solver_set_jftr bmcg2_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg2_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg2_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg2_sat_solver_mark_cone
+
+#else
+
+#include "sat/glucose/AbcGlucose.h"
+
+#define sat_solver bmcg_sat_solver
+#define sat_solver_start bmcg_sat_solver_start
+#define sat_solver_stop bmcg_sat_solver_stop
+#define sat_solver_addclause bmcg_sat_solver_addclause
+#define sat_solver_add_and bmcg_sat_solver_add_and
+#define sat_solver_add_xor bmcg_sat_solver_add_xor
+#define sat_solver_addvar bmcg_sat_solver_addvar
+#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue
+#define sat_solver_reset bmcg_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg_sat_solver_conflictnum
+#define sat_solver_solve bmcg_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg_sat_solver_read_cex
+#define sat_solver_jftr bmcg_sat_solver_jftr
+#define sat_solver_set_jftr bmcg_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg_sat_solver_mark_cone
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// SAT solving manager
+typedef struct Cec5_Man_t_ Cec5_Man_t;
+struct Cec5_Man_t_
+{
+ Cec_ParFra_t * pPars; // parameters
+ Gia_Man_t * pAig; // user's AIG
+ Gia_Man_t * pNew; // internal AIG
+ // SAT solving
+ sat_solver * pSat; // SAT solver
+ Vec_Ptr_t * vFrontier; // CNF construction
+ Vec_Ptr_t * vFanins; // CNF construction
+ Vec_Int_t * vCexMin; // minimized CEX
+ Vec_Int_t * vClassUpdates; // updated equiv classes
+ Vec_Int_t * vCexStamps; // time stamps
+ Vec_Int_t * vCands;
+ Vec_Int_t * vVisit;
+ Vec_Int_t * vPat;
+ Vec_Int_t * vDisprPairs;
+ Vec_Bit_t * vFails;
+ Vec_Bit_t * vCoDrivers;
+ int iPosRead; // candidate reading position
+ int iPosWrite; // candidate writing position
+ int iLastConst; // last const node proved
+ // refinement
+ Vec_Int_t * vRefClasses;
+ Vec_Int_t * vRefNodes;
+ Vec_Int_t * vRefBins;
+ int * pTable;
+ int nTableSize;
+ // statistics
+ int nItersSim;
+ int nItersSat;
+ int nAndNodes;
+ int nPatterns;
+ int nSatSat;
+ int nSatUnsat;
+ int nSatUndec;
+ int nCallsSince;
+ int nSimulates;
+ int nRecycles;
+ int nConflicts[3][3];
+ int nGates[2];
+ int nFaster[2];
+ abctime timeCnf;
+ abctime timeGenPats;
+ abctime timeSatSat0;
+ abctime timeSatUnsat0;
+ abctime timeSatSat;
+ abctime timeSatUnsat;
+ abctime timeSatUndec;
+ abctime timeSim;
+ abctime timeRefine;
+ abctime timeResimGlo;
+ abctime timeResimLoc;
+ abctime timeStart;
+
+ int simTravId;
+ Vec_Int_t * vPiPatsCache;
+ int fEec;
+ int LocalBatchSize;
+ Vec_Bit_t * vCexSite;
+ int simBound;
+ int simStart;
+ int approxLim;
+ int simGlobalTop;
+ int simBatchFactor;
+ int adaRecycle;
+};
+
+static inline int Cec5_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopy2Array(p, Gia_ObjId(p, pObj)); }
+static inline int Cec5_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec5_ObjSatId(p, pObj) == -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), Num); Vec_IntPush(&p->vSuppVars, Gia_ObjId(p, pObj)); if ( Gia_ObjIsCi(pObj) ) Vec_IntPushTwo(&p->vCopiesTwo, Gia_ObjId(p, pObj), Num); assert(Vec_IntSize(&p->vVarMap) == Num); Vec_IntPush(&p->vVarMap, Gia_ObjId(p, pObj)); return Num; }
+static inline void Cec5_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec5_ObjSatId(p, pObj) != -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), -1); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Cec5_EvalCombine( Vec_Int_t * vPats, int nPats, int nInputs, int nWords )
+{
+ //Vec_Wrd_t * vSimsPi = Vec_WrdStart( nInputs * nWords );
+ Vec_Wrd_t * vSimsPi = Vec_WrdStartRandom( nInputs * nWords );
+ int i, k, iLit, iPat = 0; word * pSim;
+ for ( i = 0; i < Vec_IntSize(vPats); i += Vec_IntEntry(vPats, i), iPat++ )
+ for ( k = 1; k < Vec_IntEntry(vPats, i)-1; k++ )
+ if ( (iLit = Vec_IntEntry(vPats, i+k)) )
+ {
+ assert( Abc_Lit2Var(iLit) > 0 && Abc_Lit2Var(iLit) <= nInputs );
+ pSim = Vec_WrdEntryP( vSimsPi, (Abc_Lit2Var(iLit)-1)*nWords );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, iPat ) != Abc_LitIsCompl(iLit) )
+ Abc_InfoXorBit( (unsigned*)pSim, iPat );
+ }
+ assert( iPat == nPats );
+ return vSimsPi;
+}
+void Cec5_EvalPatterns( Gia_Man_t * p, Vec_Int_t * vPats, int nPats )
+{
+ int nWords = Abc_Bit6WordNum(nPats);
+ Vec_Wrd_t * vSimsPi = Cec5_EvalCombine( vPats, nPats, Gia_ManCiNum(p), nWords );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
+ int i, Count = 0, nErrors = 0;
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ int CountThis = Abc_TtCountOnesVec( Vec_WrdEntryP(vSimsPo, i*nWords), nWords );
+ if ( CountThis == 0 )
+ continue;
+ printf( "%d ", CountThis );
+ nErrors += CountThis;
+ Count++;
+ }
+ printf( "\nDetected %d error POs with %d errors (average %.2f).\n", Count, nErrors, 1.0*nErrors/Abc_MaxInt(1, Count) );
+ Vec_WrdFree( vSimsPi );
+ Vec_WrdFree( vSimsPo );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Default parameter settings.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec5_ManSetParams( Cec_ParFra_t * pPars )
+{
+ memset( pPars, 0, sizeof(Cec_ParFra_t) );
+ pPars->jType = 2; // solver type
+ pPars->fSatSweeping = 1; // conflict limit at a node
+ pPars->nWords = 4; // simulation words
+ pPars->nRounds = 10; // simulation rounds
+ pPars->nItersMax = 2000; // this is a miter
+ pPars->nBTLimit = 1000000; // use logic cones
+ pPars->nBTLimitPo = 0; // use logic outputs
+ pPars->nSatVarMax = 1000; // the max number of SAT variables before recycling SAT solver
+ pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver
+ pPars->nGenIters = 100; // pattern generation iterations
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec5_Man_t * Cec5_ManCreate( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
+{
+ Cec5_Man_t * p = ABC_CALLOC( Cec5_Man_t, 1 );
+ memset( p, 0, sizeof(Cec5_Man_t) );
+ p->timeStart = Abc_Clock();
+ p->pPars = pPars;
+ p->pAig = pAig;
+ p->pSat = sat_solver_start();
+ sat_solver_set_jftr( p->pSat, pPars->jType );
+ p->vFrontier = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vCexMin = Vec_IntAlloc( 100 );
+ p->vClassUpdates = Vec_IntAlloc( 100 );
+ p->vCexStamps = Vec_IntStart( Gia_ManObjNum(pAig) );
+ p->vCands = Vec_IntAlloc( 100 );
+ p->vVisit = Vec_IntAlloc( 100 );
+ p->vPat = Vec_IntAlloc( 100 );
+ p->vDisprPairs = Vec_IntAlloc( 100 );
+ p->vFails = Vec_BitStart( Gia_ManObjNum(pAig) );
+ //pAig->pData = p->pSat; // point AIG manager to the solver
+ //Vec_IntFreeP( &p->pAig->vPats );
+ //p->pAig->vPats = Vec_IntAlloc( 1000 );
+ p->simTravId = 0;
+ p->vPiPatsCache = Vec_IntAlloc( 100 );
+ p->fEec = 0;
+ p->LocalBatchSize= 8;
+ p->vCexSite = Vec_BitStart( Gia_ManObjNum(pAig) );
+ Vec_BitFill( p->vCexSite, Gia_ManObjNum(pAig), 0 );
+ p->simBound = pPars->nWords;
+ p->simStart = 0;
+ p->approxLim = 600;
+ p->simBatchFactor= 1;
+ p->simGlobalTop = 0;
+ p->adaRecycle = 500;
+ if ( pPars->nBTLimitPo )
+ {
+ int i, Driver;
+ p->vCoDrivers = Vec_BitStart( Gia_ManObjNum(pAig) );
+ Gia_ManForEachCoDriverId( pAig, Driver, i )
+ Vec_BitWriteEntry( p->vCoDrivers, Driver, 1 );
+ }
+ return p;
+}
+void Cec5_ManDestroy( Cec5_Man_t * p )
+{
+ if ( p->pPars->fVerbose )
+ {
+ abctime timeTotal = Abc_Clock() - p->timeStart;
+ abctime timeSat = p->timeSatSat0 + p->timeSatSat + p->timeSatUnsat0 + p->timeSatUnsat + p->timeSatUndec;
+ abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeResimLoc - p->timeGenPats;// - p->timeResimGlo;
+ ABC_PRTP( "SAT solving ", timeSat, timeTotal );
+ ABC_PRTP( " sat(easy) ", p->timeSatSat0, timeTotal );
+ ABC_PRTP( " sat ", p->timeSatSat, timeTotal );
+ ABC_PRTP( " unsat(easy)", p->timeSatUnsat0, timeTotal );
+ ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal );
+ ABC_PRTP( " fail ", p->timeSatUndec, timeTotal );
+ ABC_PRTP( "Generate CNF ", p->timeCnf, timeTotal );
+ ABC_PRTP( "Generate pats", p->timeGenPats, timeTotal );
+ ABC_PRTP( "Simulation ", p->timeSim, timeTotal );
+ ABC_PRTP( "Refinement ", p->timeRefine, timeTotal );
+ ABC_PRTP( "Resim global ", p->timeResimGlo, timeTotal );
+ ABC_PRTP( "Resim local ", p->timeResimLoc, timeTotal );
+ ABC_PRTP( "Other ", timeOther, timeTotal );
+ ABC_PRTP( "TOTAL ", timeTotal, timeTotal );
+ fflush( stdout );
+ }
+ //printf( "Recorded %d patterns with %d literals (average %.2f).\n",
+ // p->pAig->nBitPats, Vec_IntSize(p->pAig->vPats) - 2*p->pAig->nBitPats, 1.0*Vec_IntSize(p->pAig->vPats)/Abc_MaxInt(1, p->pAig->nBitPats)-2 );
+ //Cec5_EvalPatterns( p->pAig, p->pAig->vPats, p->pAig->nBitPats );
+ //Vec_IntFreeP( &p->pAig->vPats );
+ Vec_WrdFreeP( &p->pAig->vSims );
+ Vec_WrdFreeP( &p->pAig->vSimsPi );
+ Gia_ManCleanMark01( p->pAig );
+ sat_solver_stop( p->pSat );
+ Gia_ManStopP( &p->pNew );
+ Vec_PtrFreeP( &p->vFrontier );
+ Vec_PtrFreeP( &p->vFanins );
+ Vec_IntFreeP( &p->vCexMin );
+ Vec_IntFreeP( &p->vClassUpdates );
+ Vec_IntFreeP( &p->vCexStamps );
+ Vec_IntFreeP( &p->vCands );
+ Vec_IntFreeP( &p->vVisit );
+ Vec_IntFreeP( &p->vPat );
+ Vec_IntFreeP( &p->vDisprPairs );
+ Vec_BitFreeP( &p->vFails );
+ Vec_BitFreeP( &p->vCoDrivers );
+ Vec_IntFreeP( &p->vRefClasses );
+ Vec_IntFreeP( &p->vRefNodes );
+ Vec_IntFreeP( &p->vRefBins );
+ Vec_IntFreeP( &p->vPiPatsCache );
+ Vec_BitFreeP( &p->vCexSite );
+ ABC_FREE( p->pTable );
+ ABC_FREE( p );
+}
+Gia_Man_t * Cec5_ManStartNew( Gia_Man_t * pAig )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_Man_t * pNew = Gia_ManStart( Gia_ManObjNum(pAig) );
+ pNew->pName = Abc_UtilStrsav( pAig->pName );
+ pNew->pSpec = Abc_UtilStrsav( pAig->pSpec );
+ if ( pAig->pMuxes )
+ pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
+ Gia_ManFillValue( pAig );
+ Gia_ManConst0(pAig)->Value = 0;
+ Gia_ManForEachCi( pAig, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Vec_IntFill( &pNew->vCopies2, Gia_ManObjNum(pAig), -1 );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(pAig) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec5_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, sat_solver * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( pNode->fMark0 );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Cec5_ObjSatId(p, pNode);
+ VarI = Cec5_ObjSatId(p, pNodeI);
+ VarT = Cec5_ObjSatId(p, Gia_Regular(pNodeT));
+ VarE = Cec5_ObjSatId(p, Gia_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Gia_IsComplement(pNodeT);
+ fCompE = Gia_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+
+ // two additional clauses
+ // t' & e' -> f'
+ // t & e -> f
+
+ // t + e + f'
+ // t' + e' + f
+
+ if ( VarT == VarE )
+ {
+// assert( fCompT == !fCompE );
+ return;
+ }
+
+ pLits[0] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+}
+void Cec5_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, sat_solver * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsAnd( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ABC_ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = Abc_Var2Lit(Cec5_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = Abc_Var2Lit(Cec5_ObjSatId(p, pNode), 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = Abc_Var2Lit(Cec5_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = Abc_Var2Lit(Cec5_ObjSatId(p, pNode), 0);
+ if ( fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses and returns CNF variable of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec5_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||
+ (!fFirst && Gia_ObjValue(pObj) > 1) ||
+ (fUseMuxes && pObj->fMark0) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Cec5_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Cec5_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+void Cec5_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Cec5_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+void Cec5_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, sat_solver * pSat )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Cec5_ObjSatId(p, pObj) >= 0 )
+ return;
+ assert( Cec5_ObjSatId(p, pObj) == -1 );
+ Cec5_ObjSetSatId( p, pObj, sat_solver_addvar(pSat) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+int Cec5_ObjGetCnfVar( Cec5_Man_t * p, int iObj )
+{
+ int fUseSimple = 1; // enable simple CNF
+ int fUseMuxes = 1; // enable MUXes when using complex CNF
+ Gia_Obj_t * pNode, * pFanin;
+ Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj);
+ int i, k;
+ // quit if CNF is ready
+ if ( Cec5_ObjSatId(p->pNew,pObj) >= 0 )
+ return Cec5_ObjSatId(p->pNew,pObj);
+
+ assert( iObj > 0 );
+ if ( Gia_ObjIsCi(pObj) )
+ return Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( fUseSimple )
+ {
+ Gia_Obj_t * pFan0, * pFan1;
+ //if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ // printf( "%d", (Gia_IsComplement(pFan1) << 1) + Gia_IsComplement(pFan0) );
+ if ( p->pNew->pMuxes == NULL && Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) && Gia_IsComplement(pFan0) == Gia_IsComplement(pFan1) )
+ {
+ int iVar0 = Cec5_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan0)) );
+ int iVar1 = Cec5_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan1)) );
+ int iVar = Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ if ( p->pPars->jType < 2 )
+ sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, 0 );
+ if ( p->pPars->jType > 0 )
+ {
+ int Lit0 = Abc_Var2Lit( iVar0, 0 );
+ int Lit1 = Abc_Var2Lit( iVar1, 0 );
+ if ( Lit0 < Lit1 )
+ Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0;
+ assert( Lit0 > Lit1 );
+ sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 );
+ p->nGates[1]++;
+ }
+ }
+ else
+ {
+ int iVar0 = Cec5_ObjGetCnfVar( p, Gia_ObjFaninId0(pObj, iObj) );
+ int iVar1 = Cec5_ObjGetCnfVar( p, Gia_ObjFaninId1(pObj, iObj) );
+ int iVar = Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ if ( p->pPars->jType < 2 )
+ {
+ if ( Gia_ObjIsXor(pObj) )
+ sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) );
+ else
+ sat_solver_add_and( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ }
+ if ( p->pPars->jType > 0 )
+ {
+ int Lit0 = Abc_Var2Lit( iVar0, Gia_ObjFaninC0(pObj) );
+ int Lit1 = Abc_Var2Lit( iVar1, Gia_ObjFaninC1(pObj) );
+ if ( (Lit0 > Lit1) ^ Gia_ObjIsXor(pObj) )
+ Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0;
+ sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 );
+ p->nGates[Gia_ObjIsXor(pObj)]++;
+ }
+ }
+ return Cec5_ObjSatId( p->pNew, pObj );
+ }
+ assert( !Gia_ObjIsXor(pObj) );
+ // start the frontier
+ Vec_PtrClear( p->vFrontier );
+ Cec5_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Cec5_ObjSatId(p->pNew,pNode) >= 0 );
+ if ( fUseMuxes && pNode->fMark0 )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec5_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec5_AddClausesMux( p->pNew, pNode, p->pSat );
+ }
+ else
+ {
+ Cec5_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec5_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec5_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ return Cec5_ObjSatId(p->pNew,pObj);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Refinement of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word * Cec5_ObjSim( Gia_Man_t * p, int iObj )
+{
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
+}
+static inline int Cec5_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 )
+{
+ int w;
+ word * pSim0 = Cec5_ObjSim( p, iObj0 );
+ word * pSim1 = Cec5_ObjSim( p, iObj1 );
+ if ( (pSim0[0] & 1) == (pSim1[0] & 1) )
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != pSim1[w] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != ~pSim1[w] )
+ return 0;
+ return 1;
+ }
+}
+int Cec5_ManSimHashKey( word * pSim, int nSims, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned uHash = 0, * pSimU = (unsigned *)pSim;
+ int i, nSimsU = 2 * nSims;
+ if ( pSimU[0] & 1 )
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= ~pSimU[i] * s_Primes[i & 0xf];
+ else
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= pSimU[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+void Cec5_RefineOneClassIter( Gia_Man_t * p, int iRepr )
+{
+ int iObj, iPrev = iRepr, iPrev2, iRepr2;
+ assert( Gia_ObjRepr(p, iRepr) == GIA_VOID );
+ assert( Gia_ObjNext(p, iRepr) > 0 );
+ Gia_ClassForEachObj1( p, iRepr, iRepr2 )
+ if ( Cec5_ObjSimEqual(p, iRepr, iRepr2) )
+ iPrev = iRepr2;
+ else
+ break;
+ if ( iRepr2 <= 0 ) // no refinement
+ return;
+ // relink remaining nodes of the class
+ // nodes that are equal to iRepr, remain in the class of iRepr
+ // nodes that are not equal to iRepr, move to the class of iRepr2
+ Gia_ObjSetRepr( p, iRepr2, GIA_VOID );
+ assert( !Gia_ObjProved(p,iRepr2) );
+ iPrev2 = iRepr2;
+ for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
+ {
+ if ( Cec5_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr
+ {
+ Gia_ObjSetNext( p, iPrev, iObj );
+ iPrev = iObj;
+ }
+ else // moves to iRepr2
+ {
+ Gia_ObjSetRepr( p, iObj, iRepr2 );
+ Gia_ObjSetNext( p, iPrev2, iObj );
+ iPrev2 = iObj;
+ }
+ }
+ Gia_ObjSetNext( p, iPrev, -1 );
+ Gia_ObjSetNext( p, iPrev2, -1 );
+ // refine incrementally
+ if ( Gia_ObjNext(p, iRepr2) > 0 )
+ Cec5_RefineOneClassIter( p, iRepr2 );
+}
+void Cec5_RefineOneClass( Gia_Man_t * p, Cec5_Man_t * pMan, Vec_Int_t * vNodes )
+{
+ int k, iObj, Bin;
+ Vec_IntClear( pMan->vRefBins );
+ Vec_IntForEachEntryReverse( vNodes, iObj, k )
+ {
+ int Key = Cec5_ManSimHashKey( Cec5_ObjSim(p, iObj), p->nSimWords, pMan->nTableSize );
+ assert( Key >= 0 && Key < pMan->nTableSize );
+ if ( pMan->pTable[Key] == -1 )
+ Vec_IntPush( pMan->vRefBins, Key );
+ p->pNexts[iObj] = pMan->pTable[Key];
+ pMan->pTable[Key] = iObj;
+ }
+ Vec_IntForEachEntry( pMan->vRefBins, Bin, k )
+ {
+ int iRepr = pMan->pTable[Bin];
+ pMan->pTable[Bin] = -1;
+ assert( p->pReprs[iRepr].iRepr == GIA_VOID );
+ assert( p->pNexts[iRepr] != 0 );
+ assert( !Gia_ObjProved(p,iRepr) );
+ if ( p->pNexts[iRepr] == -1 )
+ continue;
+ for ( iObj = p->pNexts[iRepr]; iObj > 0; iObj = p->pNexts[iObj] )
+ p->pReprs[iObj].iRepr = iRepr;
+ Cec5_RefineOneClassIter( p, iRepr );
+ }
+ Vec_IntClear( pMan->vRefBins );
+}
+void Cec5_RefineClasses( Gia_Man_t * p, Cec5_Man_t * pMan, Vec_Int_t * vClasses )
+{
+ if ( Vec_IntSize(pMan->vRefClasses) == 0 )
+ return;
+ if ( Vec_IntSize(pMan->vRefNodes) > 0 )
+ Cec5_RefineOneClass( p, pMan, pMan->vRefNodes );
+ else
+ {
+ int i, k, iObj, iRepr;
+ Vec_IntForEachEntry( pMan->vRefClasses, iRepr, i )
+ {
+ assert( p->pReprs[iRepr].fColorA );
+ p->pReprs[iRepr].fColorA = 0;
+ Vec_IntClear( pMan->vRefNodes );
+ Vec_IntPush( pMan->vRefNodes, iRepr );
+ Gia_ClassForEachObj1( p, iRepr, k )
+ Vec_IntPush( pMan->vRefNodes, k );
+ Vec_IntForEachEntry( pMan->vRefNodes, iObj, k )
+ {
+ p->pReprs[iObj].iRepr = GIA_VOID;
+ p->pNexts[iObj] = -1;
+ }
+ Cec5_RefineOneClass( p, pMan, pMan->vRefNodes );
+ }
+ }
+ Vec_IntClear( pMan->vRefClasses );
+ Vec_IntClear( pMan->vRefNodes );
+}
+void Cec5_RefineInit( Gia_Man_t * p, Cec5_Man_t * pMan )
+{
+ Gia_Obj_t * pObj; int i;
+ if( pMan->fEec ){
+ assert( p->pReprs );
+ assert( p->pNexts );
+ } else {
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
+ p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) );
+ }
+
+ pMan->nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) );
+ pMan->pTable = ABC_FALLOC( int, pMan->nTableSize );
+ pMan->vRefNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+
+ pMan->vRefBins = Vec_IntAlloc( Gia_ManObjNum(p)/2 );
+ pMan->vRefClasses = Vec_IntAlloc( Gia_ManObjNum(p)/2 );
+
+ if( pMan->fEec ) return;
+
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( !Gia_ObjIsCo(pObj) && (!pMan->pPars->nLevelMax || Gia_ObjLevel(p, pObj) <= pMan->pPars->nLevelMax) )
+ Vec_IntPush( pMan->vRefNodes, i );
+ }
+
+ Vec_IntPush( pMan->vRefClasses, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cec5_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit )
+{
+ word * pSim = Cec5_ObjSim( p, iObj );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit )
+ Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline int Cec5_ObjSimGetInputBit( Gia_Man_t * p, int iObj )
+{
+ word * pSim = Cec5_ObjSim( p, iObj );
+ return Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline void Cec5_ObjSimRo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSimRo = Cec5_ObjSim( p, iObj );
+ word * pSimRi = Cec5_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimRo[w] = pSimRi[w];
+}
+static inline void Cec5_ObjSimCo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSimCo = Cec5_ObjSim( p, iObj );
+ word * pSimDri = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = ~pSimDri[w];
+ else
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = pSimDri[w];
+}
+static inline void Cec5_ObjSimAnd( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec5_ObjSim( p, iObj );
+ word * pSim0 = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec5_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = ~pSim0[w] & ~pSim1[w];
+ else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = ~pSim0[w] & pSim1[w];
+ else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = pSim0[w] & ~pSim1[w];
+ else
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = pSim0[w] & pSim1[w];
+}
+static inline void Cec5_ObjSimXor( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec5_ObjSim( p, iObj );
+ word * pSim0 = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec5_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) )
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = ~pSim0[w] ^ pSim1[w];
+ else
+ for ( w = pMan->simStart; w < pMan->simBound; w++ )
+ pSim[w] = pSim0[w] ^ pSim1[w];
+}
+static inline void Cec5_ObjSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec5_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = Gia_ManRandomW( 0 );
+ pSim[0] <<= 1;
+}
+static inline void Cec5_ObjClearSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec5_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = 0;
+}
+void Cec5_ManSimulateCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec5_ObjSimCi( p, Id );
+ p->iPatsPi = 0;
+}
+void Cec5_ManClearCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec5_ObjClearSimCi( p, Id );
+ p->iPatsPi = 0;
+}
+Abc_Cex_t * Cec5_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat )
+{
+ Abc_Cex_t * pCex;
+ int i, Id;
+ pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 );
+ pCex->iPo = iOut;
+ if ( iPat == -1 )
+ return pCex;
+ Gia_ManForEachCiId( p, Id, i )
+ if ( Abc_InfoHasBit((unsigned *)Cec5_ObjSim(p, Id), iPat) )
+ Abc_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+int Cec5_ManSimulateCos( Gia_Man_t * p )
+{
+ int i, Id;
+ // check outputs and generate CEX if they fail
+ Gia_ManForEachCoId( p, Id, i )
+ {
+ Cec5_ObjSimCo( p, Id );
+ if ( Cec5_ObjSimEqual(p, Id, 0) )
+ continue;
+ p->pCexSeq = Cec5_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec5_ObjSim(p, Id), p->nSimWords) );
+ return 0;
+ }
+ return 1;
+}
+void Cec5_ManSimulate( Gia_Man_t * p, Cec5_Man_t * pMan )
+{
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj; int i;
+ pMan->nSimulates++;
+ if ( pMan->pTable == NULL )
+ Cec5_RefineInit( p, pMan );
+ else
+ assert( Vec_IntSize(pMan->vRefClasses) == 0 );
+
+ pMan->simStart = pMan->simGlobalTop;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ int iRepr = Gia_ObjRepr( p, i );
+ if ( Gia_ObjIsXor(pObj) )
+ Cec5_ObjSimXor( p, pMan, i );
+ else
+ Cec5_ObjSimAnd( p, pMan, i );
+ if ( iRepr == GIA_VOID || p->pReprs[iRepr].fColorA || Cec5_ObjSimEqual(p, iRepr, i) )
+ continue;
+ p->pReprs[iRepr].fColorA = 1;
+ Vec_IntPush( pMan->vRefClasses, iRepr );
+ }
+ pMan->simStart = 0;
+ pMan->timeSim += Abc_Clock() - clk;
+ clk = Abc_Clock();
+ Cec5_RefineClasses( p, pMan, pMan->vRefClasses );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+void Cec5_ManSimulate_rec( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj )
+{
+ Gia_Obj_t * pObj;
+ int progress;
+ if ( !iObj || (progress = Vec_IntEntry(pMan->vCexStamps, iObj)) == pMan->simTravId )
+ return;
+ Vec_IntWriteEntry( pMan->vCexStamps, iObj, pMan->simTravId );
+ pObj = Gia_ManObj(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec5_ManSimulate_rec( p, pMan, Gia_ObjFaninId0(pObj, iObj) );
+ Cec5_ManSimulate_rec( p, pMan, Gia_ObjFaninId1(pObj, iObj) );
+ pMan->simStart = progress * pMan->LocalBatchSize / (sizeof(word)<<3);
+ if ( Gia_ObjIsXor(pObj) )
+ Cec5_ObjSimXor( p, pMan, iObj );
+ else
+ Cec5_ObjSimAnd( p, pMan, iObj );
+ pMan->simStart = 0;
+}
+void Cec5_ManSimAlloc( Gia_Man_t * p, int nWords, int fPrep )
+{
+ if( !fPrep ){
+ Vec_WrdFreeP( &p->vSimsPi );
+ p->vSimsPi = Vec_WrdStart( (Gia_ManCiNum(p) + 1) * nWords );
+ }
+ Vec_WrdFreeP( &p->vSims );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
+ p->nSimWords = nWords;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creating initial equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec5_ManPrintTfiConeStats( Gia_Man_t * p )
+{
+ Vec_Int_t * vRoots = Vec_IntAlloc( 100 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( 100 );
+ int i, k;
+ Gia_ManForEachClass0( p, i )
+ {
+ Vec_IntClear( vRoots );
+ if ( i % 100 != 0 )
+ continue;
+ Vec_IntPush( vRoots, i );
+ Gia_ClassForEachObj1( p, i, k )
+ Vec_IntPush( vRoots, k );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ printf( "Class %6d : ", i );
+ printf( "Roots = %6d ", Vec_IntSize(vRoots) );
+ printf( "Nodes = %6d ", Vec_IntSize(vNodes) );
+ printf( "\n" );
+ }
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vLeaves );
+}
+void Cec5_ManPrintStats( Gia_Man_t * p, Cec_ParFra_t * pPars, Cec5_Man_t * pMan, int fSim )
+{
+ static abctime clk = 0;
+ abctime clkThis = 0;
+ int i, nLits, Counter = 0, Counter0 = 0, CounterX = 0;
+ if ( !pPars->fVerbose )
+ return;
+ if ( pMan->nItersSim + pMan->nItersSat )
+ clkThis = Abc_Clock() - clk;
+ clk = Abc_Clock();
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter0++;
+ else if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ }
+ nLits = Gia_ManObjNum(p) - Counter - CounterX;
+ if ( fSim )
+ {
+ printf( "Sim %4d : ", pMan->nItersSim++ + pMan->nItersSat );
+ printf( "%6.2f %% ", 100.0*nLits/Gia_ManCandNum(p) );
+ }
+ else
+ {
+ printf( "SAT %4d : ", pMan->nItersSim + pMan->nItersSat++ );
+ printf( "%6.2f %% ", 100.0*pMan->nAndNodes/Gia_ManAndNum(p) );
+ }
+ printf( "P =%7d ", pMan ? pMan->nSatUnsat : 0 );
+ printf( "D =%7d ", pMan ? pMan->nSatSat : 0 );
+ printf( "F =%8d ", pMan ? pMan->nSatUndec : 0 );
+ //printf( "Last =%6d ", pMan ? pMan->iLastConst : 0 );
+ Abc_Print( 1, "cst =%9d cls =%8d lit =%9d ", Counter0, Counter, nLits );
+ Abc_PrintTime( 1, "Time", clkThis );
+}
+void Cec5_ManPrintClasses2( Gia_Man_t * p )
+{
+ int i, k;
+ Gia_ManForEachClass0( p, i )
+ {
+ printf( "Class %d : ", i );
+ Gia_ClassForEachObj1( p, i, k )
+ printf( "%d ", k );
+ printf( "\n" );
+ }
+}
+void Cec5_ManPrintClasses( Gia_Man_t * p )
+{
+ int k, Count = 0;
+ Gia_ClassForEachObj1( p, 0, k )
+ Count++;
+ printf( "Const0 class has %d entries.\n", Count );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec5_ManVerify_rec( Gia_Man_t * p, int iObj, sat_solver * pSat )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1 = sat_solver_read_cex_varvalue(pSat, Cec5_ObjSatId(p, pObj));
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec5_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec5_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1;
+}
+void Cec5_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, sat_solver * pSat )
+{
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec5_ManVerify_rec( p, iObj0, pSat );
+ Value1 = Cec5_ManVerify_rec( p, iObj1, pSat );
+ if ( (Value0 ^ Value1) == fPhase )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec5_ManCexVerify_rec( Gia_Man_t * p, int iObj )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1 = Cec5_ObjSimGetInputBit(p, iObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec5_ManCexVerify_rec( p, Gia_ObjFaninId0(pObj, iObj) ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec5_ManCexVerify_rec( p, Gia_ObjFaninId1(pObj, iObj) ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1;
+}
+void Cec5_ManCexVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase )
+{
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec5_ManCexVerify_rec( p, iObj0 );
+ Value1 = Cec5_ManCexVerify_rec( p, iObj1 );
+ if ( (Value0 ^ Value1) == fPhase )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs simulation patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+void Cec5_ManPackAddPatterns( Gia_Man_t * p, int iBit, Vec_Int_t * vLits )
+{
+ int k, Limit = Abc_MinInt( Vec_IntSize(vLits), 64 * p->nSimWords - 1 );
+ for ( k = 0; k < Limit; k++ )
+ {
+ int i, Lit, iBitLocal = (iBit + k + 1) % Limit + 1;
+ assert( iBitLocal > 0 && iBitLocal < 64 * p->nSimWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ if ( Abc_InfoHasBit( (unsigned *)pPres, iBitLocal ) )
+ continue;
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iBitLocal ) != Abc_LitIsCompl(Lit ^ (i == k)) )
+ Abc_InfoXorBit( (unsigned *)pInfo, iBitLocal );
+ }
+ }
+}
+int Cec5_ManPackAddPatternTry( Gia_Man_t * p, int iBit, Vec_Int_t * vLits )
+{
+ int i, Lit;
+ assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ if ( Abc_InfoHasBit( (unsigned *)pPres, iBit ) &&
+ Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) )
+ return 0;
+ }
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ Abc_InfoSetBit( (unsigned *)pPres, iBit );
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) )
+ Abc_InfoXorBit( (unsigned *)pInfo, iBit );
+ }
+ return 1;
+}
+int Cec5_ManPackAddPattern( Gia_Man_t * p, Vec_Int_t * vLits, int fExtend )
+{
+ int k;
+ for ( k = 1; k < 64 * p->nSimWords - 1; k++ )
+ {
+ if ( ++p->iPatsPi == 64 * p->nSimWords - 1 )
+ p->iPatsPi = 1;
+ if ( Cec5_ManPackAddPatternTry( p, p->iPatsPi, vLits ) )
+ {
+ if ( fExtend )
+ Cec5_ManPackAddPatterns( p, p->iPatsPi, vLits );
+ break;
+ }
+ }
+ if ( k == 64 * p->nSimWords - 1 )
+ {
+ p->iPatsPi = k;
+ if ( !Cec5_ManPackAddPatternTry( p, p->iPatsPi, vLits ) )
+ printf( "Internal error.\n" );
+ else if ( fExtend )
+ Cec5_ManPackAddPatterns( p, p->iPatsPi, vLits );
+ return 64 * p->nSimWords;
+ }
+ return k;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates counter-examples to refine the candidate equivalences.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cec5_ObjFan0IsAssigned( Gia_Obj_t * pObj )
+{
+ return Gia_ObjFanin0(pObj)->fMark0 || Gia_ObjFanin0(pObj)->fMark1;
+}
+static inline int Cec5_ObjFan1IsAssigned( Gia_Obj_t * pObj )
+{
+ return Gia_ObjFanin1(pObj)->fMark0 || Gia_ObjFanin1(pObj)->fMark1;
+}
+static inline int Cec5_ObjFan0HasValue( Gia_Obj_t * pObj, int v )
+{
+ return (v ^ Gia_ObjFaninC0(pObj)) ? Gia_ObjFanin0(pObj)->fMark1 : Gia_ObjFanin0(pObj)->fMark0;
+}
+static inline int Cec5_ObjFan1HasValue( Gia_Obj_t * pObj, int v )
+{
+ return (v ^ Gia_ObjFaninC1(pObj)) ? Gia_ObjFanin1(pObj)->fMark1 : Gia_ObjFanin1(pObj)->fMark0;
+}
+static inline int Cec5_ObjObjIsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited
+ if ( v )
+ return Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1);
+ return Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0);
+}
+static inline int Cec5_ObjFan0IsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ return Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Cec5_ObjObjIsImpliedValue( Gia_ObjFanin0(pObj), v ^ Gia_ObjFaninC0(pObj) );
+}
+static inline int Cec5_ObjFan1IsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ return Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Cec5_ObjObjIsImpliedValue( Gia_ObjFanin1(pObj), v ^ Gia_ObjFaninC1(pObj) );
+}
+int Cec5_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited
+ if ( Value ) pObj->fMark1 = 1; else pObj->fMark0 = 1;
+ Vec_IntPush( vVisit, Gia_ObjId(p, pObj) );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vPat, Abc_Var2Lit(Gia_ObjId(p, pObj), Value) );
+ return 1;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Gia_ObjIsXor(pObj) )
+ {
+ int Ass0 = Cec5_ObjFan0IsAssigned(pObj);
+ int Ass1 = Cec5_ObjFan1IsAssigned(pObj);
+ assert( Gia_ObjFaninC0(pObj) == 0 && Gia_ObjFaninC1(pObj) == 0 );
+ if ( Ass0 && Ass1 )
+ return Value == (Cec5_ObjFan0HasValue(pObj, 1) ^ Cec5_ObjFan1HasValue(pObj, 1));
+ if ( Ass0 )
+ {
+ int ValueInt = Value ^ Cec5_ObjFan0HasValue(pObj, 1);
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, ValueInt, vPat, vVisit) )
+ return 0;
+ }
+ else if ( Ass1 )
+ {
+ int ValueInt = Value ^ Cec5_ObjFan1HasValue(pObj, 1);
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, ValueInt, vPat, vVisit) )
+ return 0;
+ }
+ else if ( Abc_Random(0) & 1 )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, 0, vPat, vVisit) )
+ return 0;
+ if ( Cec5_ObjFan1HasValue(pObj, !Value) || (!Cec5_ObjFan1HasValue(pObj, Value) && !Cec5_ManGeneratePatterns_rec(p, pFan1, Value, vPat, vVisit)) )
+ return 0;
+ }
+ else
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, 1, vPat, vVisit) )
+ return 0;
+ if ( Cec5_ObjFan1HasValue(pObj, Value) || (!Cec5_ObjFan1HasValue(pObj, !Value) && !Cec5_ManGeneratePatterns_rec(p, pFan1, !Value, vPat, vVisit)) )
+ return 0;
+ }
+ assert( Value == (Cec5_ObjFan0HasValue(pObj, 1) ^ Cec5_ObjFan1HasValue(pObj, 1)) );
+ return 1;
+ }
+ else if ( Value )
+ {
+ if ( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) )
+ return 0;
+ if ( !Cec5_ObjFan0HasValue(pObj, 1) && !Cec5_ManGeneratePatterns_rec(p, pFan0, !Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ if ( !Cec5_ObjFan1HasValue(pObj, 1) && !Cec5_ManGeneratePatterns_rec(p, pFan1, !Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ assert( Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1) );
+ return 1;
+ }
+ else
+ {
+ if ( Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1) )
+ return 0;
+ if ( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) )
+ return 1;
+ if ( Cec5_ObjFan0HasValue(pObj, 1) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec5_ObjFan1HasValue(pObj, 1) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else
+ {
+ if ( Cec5_ObjFan0IsImpliedValue( pObj, 0 ) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec5_ObjFan1IsImpliedValue( pObj, 0 ) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec5_ObjFan0IsImpliedValue( pObj, 1 ) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec5_ObjFan1IsImpliedValue( pObj, 1 ) )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Abc_Random(0) & 1 )
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else
+ {
+ if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ }
+ assert( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) );
+ return 1;
+ }
+}
+int Cec5_ManGeneratePatternOne( Gia_Man_t * p, int iRepr, int iReprVal, int iCand, int iCandVal, Vec_Int_t * vPat, Vec_Int_t * vVisit )
+{
+ int Res, k;
+ Gia_Obj_t * pObj;
+ assert( iCand > 0 );
+ if ( !iRepr && iReprVal )
+ return 0;
+ Vec_IntClear( vPat );
+ Vec_IntClear( vVisit );
+ //Gia_ManForEachObj( p, pObj, k )
+ // assert( !pObj->fMark0 && !pObj->fMark1 );
+ Res = (!iRepr || Cec5_ManGeneratePatterns_rec(p, Gia_ManObj(p, iRepr), iReprVal, vPat, vVisit)) && Cec5_ManGeneratePatterns_rec(p, Gia_ManObj(p, iCand), iCandVal, vPat, vVisit);
+ Gia_ManForEachObjVec( vVisit, p, pObj, k )
+ pObj->fMark0 = pObj->fMark1 = 0;
+ return Res;
+}
+void Cec5_ManCandIterStart( Cec5_Man_t * p )
+{
+ int i, * pArray;
+ assert( p->iPosWrite == 0 );
+ assert( p->iPosRead == 0 );
+ assert( Vec_IntSize(p->vCands) == 0 );
+ for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ )
+ if ( Gia_ObjRepr(p->pAig, i) != GIA_VOID )
+ Vec_IntPush( p->vCands, i );
+ pArray = Vec_IntArray( p->vCands );
+ for ( i = 0; i < Vec_IntSize(p->vCands); i++ )
+ {
+ int iNew = Abc_Random(0) % Vec_IntSize(p->vCands);
+ ABC_SWAP( int, pArray[i], pArray[iNew] );
+ }
+}
+int Cec5_ManCandIterNext( Cec5_Man_t * p )
+{
+ while ( Vec_IntSize(p->vCands) > 0 )
+ {
+ int fStop, iCand = Vec_IntEntry( p->vCands, p->iPosRead );
+ if ( (fStop = (Gia_ObjRepr(p->pAig, iCand) != GIA_VOID)) )
+ Vec_IntWriteEntry( p->vCands, p->iPosWrite++, iCand );
+ if ( ++p->iPosRead == Vec_IntSize(p->vCands) )
+ {
+ Vec_IntShrink( p->vCands, p->iPosWrite );
+ p->iPosWrite = 0;
+ p->iPosRead = 0;
+ }
+ if ( fStop )
+ return iCand;
+ }
+ return 0;
+}
+int Cec5_ManGeneratePatterns( Cec5_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ int i, iCand, nPats = 100 * 64 * p->pAig->nSimWords, CountPat = 0, Packs = 0;
+ //int iRepr;
+ //Vec_IntForEachEntryDouble( p->vDisprPairs, iRepr, iCand, i )
+ // if ( iRepr == Gia_ObjRepr(p->pAig, iCand) )
+ // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is FAILED to disprove.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) );
+ // else
+ // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is disproved.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) );
+ //Vec_IntClear( p->vDisprPairs );
+ p->pAig->iPatsPi = 0;
+ Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 );
+ for ( i = 0; i < nPats; i++ )
+ if ( (iCand = Cec5_ManCandIterNext(p)) )
+ {
+ int iRepr = Gia_ObjRepr( p->pAig, iCand );
+ int iCandVal = Gia_ManObj(p->pAig, iCand)->fPhase;
+ int iReprVal = Gia_ManObj(p->pAig, iRepr)->fPhase;
+ int Res = Cec5_ManGeneratePatternOne( p->pAig, iRepr, iReprVal, iCand, !iCandVal, p->vPat, p->vVisit );
+ if ( !Res )
+ Res = Cec5_ManGeneratePatternOne( p->pAig, iRepr, !iReprVal, iCand, iCandVal, p->vPat, p->vVisit );
+ if ( Res )
+ {
+ int Ret = Cec5_ManPackAddPattern( p->pAig, p->vPat, 1 );
+ if ( p->pAig->vPats )
+ {
+ Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 );
+ Vec_IntAppend( p->pAig->vPats, p->vPat );
+ Vec_IntPush( p->pAig->vPats, -1 );
+ }
+ //Vec_IntPushTwo( p->vDisprPairs, iRepr, iCand );
+ Packs += Ret;
+ if ( 0 == (Ret % (64 * p->pAig->nSimWords / p->simBatchFactor)) )
+ break;
+ if ( ++CountPat == 8 * 64 * p->pAig->nSimWords )
+ break;
+ //Cec5_ManCexVerify( p->pAig, iRepr, iCand, iReprVal ^ iCandVal );
+ //Gia_ManCleanMark01( p->pAig );
+ }
+ }
+ p->timeGenPats += Abc_Clock() - clk;
+ p->nSatSat += CountPat;
+ //printf( "%3d : %6.2f %% : Generated %6d CEXs after trying %6d pairs. Ave packs = %9.2f Ave tries = %9.2f (Limit = %9.2f)\n",
+ // p->nItersSim++, 100.0*Vec_IntSize(p->vCands)/Gia_ManAndNum(p->pAig),
+ // CountPat, i, (float)Packs / Abc_MaxInt(1, CountPat), (float)i / Abc_MaxInt(1, CountPat), (float)nPats / p->pPars->nItersMax );
+ return CountPat >= i / p->pPars->nItersMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec5_ManSatSolverRecycle( Cec5_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ //printf( "Solver size = %d.\n", sat_solver_varnum(p->pSat) );
+ if( p->adaRecycle && p->adaRecycle < p->nConflicts[2][2] )
+ return;
+ p->nRecycles++;
+ p->nCallsSince = 0;
+ sat_solver_reset( p->pSat );
+ // clean mapping of AigIds into SatIds
+ Gia_ManForEachObjVec( &p->pNew->vSuppVars, p->pNew, pObj, i )
+ Cec5_ObjCleanSatId( p->pNew, pObj );
+ Vec_IntClear( &p->pNew->vSuppVars ); // AigIds for which SatId is defined
+ Vec_IntClear( &p->pNew->vCopiesTwo ); // pairs (CiAigId, SatId)
+ Vec_IntClear( &p->pNew->vVarMap ); // mapping of SatId into AigId
+}
+void Cec5_ManLoadInstance( Cec5_Man_t * p, int iObj0, int iObj1, int * piVar0, int * piVar1 ){
+ int iVar0 = Cec5_ObjGetCnfVar( p, iObj0 );
+ int iVar1 = Cec5_ObjGetCnfVar( p, iObj1 );
+ if( p->pPars->jType > 0 )
+ {
+ int nlim = p->approxLim;
+ bmcg2_sat_solver_markapprox( p->pSat, iVar0, iVar1, nlim );
+ }
+
+ * piVar0 = iVar0;
+ * piVar1 = iVar1;
+}
+
+int Cec5_ManSolveTwo( Cec5_Man_t * p, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose, int fEffort )
+{
+ abctime clk;
+ int nBTLimit = fEffort ? p->pPars->nBTLimitPo : (Vec_BitEntry(p->vFails, iObj0) || Vec_BitEntry(p->vFails, iObj1)) ? Abc_MaxInt(1, p->pPars->nBTLimit/10) : p->pPars->nBTLimit;
+ int nConfEnd, nConfBeg, status, iVar0, iVar1, Lits[2];
+ int UnsatConflicts[3] = {0};
+ //printf( "%d ", nBTLimit );
+ if ( iObj1 < iObj0 )
+ iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0;
+ assert( iObj0 < iObj1 );
+ *pfEasy = 0;
+ // check if SAT solver needs recycling
+ p->nCallsSince++;
+ if ( p->nCallsSince > p->pPars->nCallsRecycle &&
+ Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax )
+ Cec5_ManSatSolverRecycle( p );
+ // add more logic to the solver
+ if ( !iObj0 && Cec5_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 )
+ Cec5_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), sat_solver_addvar(p->pSat) );
+ clk = Abc_Clock();
+ Cec5_ManLoadInstance( p, iObj0, iObj1, &iVar0, &iVar1);
+ p->timeCnf += Abc_Clock() - clk;
+ // perform solving
+ Lits[0] = Abc_Var2Lit(iVar0, 1);
+ Lits[1] = Abc_Var2Lit(iVar1, fPhase);
+ sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ nConfBeg = sat_solver_conflictnum( p->pSat );
+ status = sat_solver_solve( p->pSat, Lits, 2 );
+ nConfEnd = sat_solver_conflictnum( p->pSat );
+ assert( nConfEnd >= nConfBeg );
+ p->nConflicts[2][2] = Abc_MaxInt(p->nConflicts[2][2], nConfEnd - nConfBeg);
+ if ( fVerbose )
+ {
+ if ( status == GLUCOSE_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ if ( iObj0 > 0 )
+ {
+ UnsatConflicts[0] = nConfEnd == nConfBeg;
+ UnsatConflicts[1] = nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]);
+ }
+ else
+ {
+ p->nConflicts[1][0] += nConfEnd == nConfBeg;
+ p->nConflicts[1][1] += nConfEnd - nConfBeg;
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ }
+ }
+ if ( status == GLUCOSE_UNSAT && iObj0 > 0 )
+ {
+ Lits[0] = Abc_Var2Lit(iVar0, 0);
+ Lits[1] = Abc_Var2Lit(iVar1, !fPhase);
+ sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ nConfBeg = sat_solver_conflictnum( p->pSat );
+ status = sat_solver_solve( p->pSat, Lits, 2 );
+ nConfEnd = sat_solver_conflictnum( p->pSat );
+ assert( nConfEnd >= nConfBeg );
+ p->nConflicts[2][2] = Abc_MaxInt(p->nConflicts[2][2], nConfEnd - nConfBeg);
+ if ( fVerbose )
+ {
+ if ( status == GLUCOSE_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ UnsatConflicts[0] &= nConfEnd == nConfBeg;
+ UnsatConflicts[1] += nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+
+ p->nConflicts[1][0] += UnsatConflicts[0];
+ p->nConflicts[1][1] += UnsatConflicts[1];
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]);
+ *pfEasy = UnsatConflicts[0];
+ }
+ }
+ }
+ //if ( status == GLUCOSE_UNDEC )
+ // printf( "* " );
+ return status;
+}
+void Cec5_FlushCache2Pattern( Cec5_Man_t * p ){
+ int j, iLit, nWrite = 0;
+ int iPatsOld = p->pAig->iPatsPi;
+ j = 0;
+ p->pAig->iPatsPi -- ;
+ while( j < p->vPiPatsCache->nSize ){
+ if( -1 < (iLit = p->vPiPatsCache->pArray[j++]) ){
+ Cec5_ObjSimSetInputBit( p->pAig, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) );
+ continue;
+ }
+ p->pAig->iPatsPi -- ;
+ nWrite ++ ;
+ }
+ p->pAig->iPatsPi += nWrite+1;
+ assert( iPatsOld == p->pAig->iPatsPi );
+ p->vPiPatsCache->nSize = 0;
+}
+void Cec5_ClearCexMarks( Cec5_Man_t * p ){
+ Vec_IntFill( p->vCexStamps, Gia_ManObjNum(p->pAig), 0 );
+ Vec_BitFill( p->vCexSite , Gia_ManObjNum(p->pAig), 0 );
+}
+void Cec5_ManCheckGlobalSim( Cec5_Man_t * p){
+ int iPatTop = p->pAig->iPatsPi;
+ if ( (iPatTop % (sizeof(word) * 8 * p->pAig->nSimWords / p->simBatchFactor)) == 0
+ || iPatTop == (int)sizeof(word) * 8 * p->pAig->nSimWords - 2 )
+ {
+ abctime clk2 = Abc_Clock();
+ Cec5_FlushCache2Pattern(p);
+ //p->simBound = iPatTop / (sizeof(word) * 8 * p->pAig->nSimWords / p->simBatchFactor)+2;//p->simTravId * p->LocalBatchSize / (sizeof(word) * 8<<3)+1;
+ p->simBound = iPatTop / (sizeof(word) * 8) + ((iPatTop % (sizeof(word) * 8)) ? 1: 0);
+ //if( iPatTop == sizeof(word) * 8 * p->pAig->nSimWords - 2 )
+ // p->simBound += 1;
+ //printf("re-sim %5d %5d bound %5d\n", p->pAig->iPatsPi, p->simTravId, p->simBound );
+ Cec5_ManSimulate( p->pAig, p );
+ p->simBound = p->pPars->nWords;
+ //printf( "FasterSmall = %d. FasterBig = %d.\n", p->nFaster[0], p->nFaster[1] );
+ p->nFaster[0] = p->nFaster[1] = 0;
+ //if ( p->nSatSat && p->nSatSat % 100 == 0 )
+ //Cec5_ManPrintStats( p->pAig, p->pPars, p, 0 );
+ Cec5_ClearCexMarks(p);
+ if( iPatTop == (int)sizeof(word) * 8 * p->pAig->nSimWords - 2 ){
+ Cec5_ManPrintStats( p->pAig, p->pPars, p, 0 );
+ p->pAig->iPatsPi = 0;
+ p->simTravId = 0;
+ p->simGlobalTop = 0;
+ } else {
+ //assert( 0 == iPatTop % (sizeof(word) * 8 * p->pAig->nSimWords) );
+ p->pAig->iPatsPi = iPatTop;
+ p->simGlobalTop = iPatTop / (sizeof(word) * 8 );
+ }
+ Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 );
+ p->timeResimGlo += Abc_Clock() - clk2;
+ }
+}
+int Cec5_ManSweepNode( Cec5_Man_t * p, int iObj, int iRepr )
+{
+ abctime clk = Abc_Clock();
+ int i, IdAig, IdSat, status, fEasy, RetValue = 1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj );
+ Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr );
+ int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase;
+ int fEffort = p->vCoDrivers ? Vec_BitEntry(p->vCoDrivers, iObj) || Vec_BitEntry(p->vCoDrivers, iRepr) : 0;
+ status = Cec5_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort );
+ if ( status == GLUCOSE_SAT )
+ {
+ int iLit;
+ Vec_BitWriteEntry( p->vCexSite, iObj, 1 );
+ //int iPatsOld = p->pAig->iPatsPi;
+ //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatSat++;
+ p->nPatterns++;
+ Vec_IntClear( p->vPat );
+ if ( p->pPars->jType == 0 )
+ {
+ Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i )
+ Vec_IntPush( p->vPat, Abc_Var2Lit(IdAig, sat_solver_read_cex_varvalue(p->pSat, IdSat)) );
+ }
+ else
+ {
+ int * pCex = sat_solver_read_cex( p->pSat );
+ int * pMap = Vec_IntArray(&p->pNew->vVarMap);
+ for ( i = 0; i < pCex[0]; )
+ Vec_IntPush( p->vPat, Abc_Lit2LitV(pMap, Abc_LitNot(pCex[++i])) );
+ }
+ assert( p->pAig->iPatsPi >= 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords - 1 );
+ p->pAig->iPatsPi++;
+// Vec_IntForEachEntry( p->vPat, iLit, i )
+// Cec5_ObjSimSetInputBit( p->pAig, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) );
+ Vec_IntForEachEntry( p->vPat, iLit, i )
+ Vec_IntPush( p->vPiPatsCache, iLit );
+ Vec_IntPush( p->vPiPatsCache, -1 );
+ if ( p->pAig->vPats )
+ {
+ Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 );
+ Vec_IntAppend( p->pAig->vPats, p->vPat );
+ Vec_IntPush( p->pAig->vPats, -1 );
+ }
+ //Cec5_ManPackAddPattern( p->pAig, p->vPat, 0 );
+ //assert( iPatsOld + 1 == p->pAig->iPatsPi );
+ if ( fEasy )
+ p->timeSatSat0 += Abc_Clock() - clk;
+ else
+ p->timeSatSat += Abc_Clock() - clk;
+ RetValue = 0;
+
+ p->simTravId = p->pAig->iPatsPi / p->LocalBatchSize;
+ if( (p->pAig->iPatsPi % p->LocalBatchSize) == 0 || 1 == p->LocalBatchSize )
+ Cec5_FlushCache2Pattern(p);
+
+ // this is not needed, but we keep it here anyway, because it takes very little time
+ //Cec5_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat );
+ // resimulated once in a while
+ //if ( p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 2 )
+ Cec5_ManCheckGlobalSim(p);
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatUnsat++;
+ pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl );
+ assert( !Gia_ObjProved( p->pAig, iObj ) );
+ Gia_ObjSetProved( p->pAig, iObj );
+ if ( iRepr == 0 )
+ p->iLastConst = iObj;
+ if ( fEasy )
+ p->timeSatUnsat0 += Abc_Clock() - clk;
+ else
+ p->timeSatUnsat += Abc_Clock() - clk;
+ RetValue = 1;
+ }
+ else
+ {
+ p->nSatUndec++;
+ assert( status == GLUCOSE_UNDEC );
+ Gia_ObjSetFailed( p->pAig, iObj );
+ Vec_BitWriteEntry( p->vFails, iObj, 1 );
+ //if ( iRepr )
+ //Vec_BitWriteEntry( p->vFails, iRepr, 1 );
+ p->timeSatUndec += Abc_Clock() - clk;
+ RetValue = 2;
+ }
+ return RetValue;
+}
+Gia_Obj_t * Cec5_ManFindRepr( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj )
+{
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pRepr = NULL;
+ int iMem, iRepr;
+ assert( Gia_ObjHasRepr(p, iObj) );
+ assert( !Gia_ObjProved(p, iObj) );
+ iRepr = Gia_ObjRepr(p, iObj);
+ assert( iRepr != iObj );
+ assert( !Gia_ObjProved(p, iRepr) );
+
+ pMan->simBound = pMan->simTravId * pMan->LocalBatchSize / (sizeof(word)<<3)+1;
+ assert( pMan->simBound <= pMan->pPars->nWords );
+
+ if( (Vec_BitEntry( pMan->vCexSite, iObj ) | Vec_BitEntry( pMan->vCexSite, iRepr ))
+ ||(Vec_IntEntry( pMan->vCexStamps, iObj ) != Vec_IntEntry( pMan->vCexStamps, iRepr )) ){
+ Cec5_ManSimulate_rec( p, pMan, iObj );
+ Cec5_ManSimulate_rec( p, pMan, iRepr );
+ }
+ if ( Cec5_ObjSimEqual(p, iObj, iRepr) )
+ {
+ pMan->timeResimLoc += Abc_Clock() - clk;
+ pRepr = Gia_ManObj(p, iRepr);
+ goto finalize;
+ }
+ Gia_ClassForEachObj1( p, iRepr, iMem )
+ {
+ if ( iObj == iMem )
+ break;
+ assert(iMem<iObj);
+ if ( Gia_ObjProved(p, iMem) || Gia_ObjFailed(p, iMem) )
+ continue;
+ if( Vec_IntEntry( pMan->vCexStamps, iObj ) != Vec_IntEntry( pMan->vCexStamps, iMem ) ){
+ Cec5_ManSimulate_rec( p, pMan, iMem );
+ Cec5_ManSimulate_rec( p, pMan, iObj );
+ }
+ if ( Cec5_ObjSimEqual(p, iObj, iMem) )
+ {
+ pMan->nFaster[0]++;
+ pMan->timeResimLoc += Abc_Clock() - clk;
+ pRepr = Gia_ManObj(p, iMem);
+ goto finalize;
+ }
+ }
+ pMan->nFaster[1]++;
+ pMan->timeResimLoc += Abc_Clock() - clk;
+finalize:
+ pMan->simBound = pMan->pPars->nWords;
+ return pRepr;
+}
+void Cec5_ManExtend( Cec5_Man_t * pMan, CbsP_Man_t * pCbs ){
+ while( pMan->pNew->vCopies2.nSize < Gia_ManObjNum(pMan->pNew) ){
+ Vec_IntPush( &pMan->pNew->vCopies2, -1 );
+ Vec_BitPush( pMan->vFails, 0 );
+ if( pCbs )
+ Vec_IntPush( pCbs->vValue, ~0 );
+ }
+}
+
+int Cec5_ManSweepNodeCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj, int iRepr, int fTagFail );
+int Cec5_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** ppNew, int fSimOnly, int fCbs, int approxLim, int subBatchSz, int adaRecycle )
+{
+ Gia_Obj_t * pObj, * pRepr;
+ CbsP_Man_t * pCbs = NULL;
+ int i, fSimulate = 1;
+ int fPrep = 0;
+ int AccuSat = 0;
+ int * vMerged;
+ int go_back = -1;
+
+ Cec5_Man_t * pMan = Cec5_ManCreate( p, pPars );
+ pMan->approxLim = approxLim;
+ if( pMan->simBatchFactor != subBatchSz ){
+ printf("overwrite default batch size: from %3d to %3d\n", pMan->simBatchFactor, subBatchSz);
+ pMan->simBatchFactor = subBatchSz;
+ }
+ if( pMan->adaRecycle != adaRecycle ){
+ printf("overwrite default adaptive recycle: from %3d to %3d\n", pMan->adaRecycle, adaRecycle);
+ pMan->adaRecycle = adaRecycle;
+ }
+ if ( pPars->fVerbose )
+ printf( "Solver type = %d. Simulate %d words in %d rounds. SAT with %d confs. Recycle after %d SAT calls.\n",
+ pPars->jType, pPars->nWords, pPars->nRounds, pPars->nBTLimit, pPars->nCallsRecycle );
+
+ if( fPrep )
+ pMan->fEec = 1;
+
+
+ // this is currently needed to have a correct mapping
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+
+ // check if any output trivially fails under all-0 pattern
+ Gia_ManRandom( 1 );
+ Gia_ManSetPhase( p );
+ if ( pPars->nLevelMax )
+ Gia_ManLevelNum(p);
+ //Gia_ManStaticFanoutStart( p );
+ if ( pPars->fCheckMiter )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( pObj->fPhase )
+ {
+ p->pCexSeq = Cec5_ManDeriveCex( p, i, -1 );
+ goto finalize;
+ }
+ }
+
+ // simulate one round and create classes
+ Cec5_ManSimAlloc( p, pPars->nWords, 0 );
+ Cec5_ManSimulateCis( p );
+ Cec5_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( pPars->fVerbose )
+ Cec5_ManPrintStats( p, pPars, pMan, 1 );
+
+ // perform simulation
+ for ( i = 0; i < pPars->nRounds; i++ )
+ {
+ Cec5_ManSimulateCis( p );
+ Cec5_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( i && i % (pPars->nRounds / 5) == 0 && pPars->fVerbose )
+ Cec5_ManPrintStats( p, pPars, pMan, 1 );
+ }
+ if ( fSimOnly )
+ goto finalize;
+
+
+ // perform additional simulation
+ Cec5_ManCandIterStart( pMan );
+ for ( i = 0; fSimulate && i < pPars->nGenIters; i++ )
+ {
+ Cec5_ManSimulateCis( p );
+ fSimulate = Cec5_ManGeneratePatterns( pMan );
+ Cec5_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( i && i % 5 == 0 && pPars->fVerbose )
+ Cec5_ManPrintStats( p, pPars, pMan, 1 );
+ if( pMan->nSatSat - AccuSat < p->nSimWords * (int)sizeof(word) * 8 )
+ break;
+
+ AccuSat = pMan->nSatSat;
+ }
+ if ( i && i % 5 && pPars->fVerbose )
+ Cec5_ManPrintStats( p, pPars, pMan, 1 );
+
+ vMerged = ABC_FALLOC(int, Gia_ManObjNum(p)); // refinement may move non-repr merge around . record the true merged performed
+
+ p->iPatsPi = 0;
+ Vec_WrdFill( p->vSimsPi, Vec_WrdSize(p->vSimsPi), 0 );
+ pMan->nSatSat = 0;
+ pMan->pNew = Cec5_ManStartNew( p );
+
+ if( fCbs ){
+ //Gia_ManCreateRefs( pMan->pNew );
+ pMan->pNew->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManCleanMark0( pMan->pNew );
+ Gia_ManCleanMark1( pMan->pNew );
+ Gia_ManFillValue ( pMan->pNew );
+ pCbs = CbsP_ManAlloc( p );
+ pCbs->pAig = pMan->pNew;
+ pCbs->Pars.nBTLimit = 100;//pPars->nBTLimit;
+ pCbs->Pars.nJustLimit = 100;
+ pCbs->Pars.nJscanLimit = 100;
+ pCbs->Pars.nRscanLimit = 100;
+ pCbs->Pars.nPropLimit = 100;
+
+ if( pPars->fVerbose ){
+ printf("cbs: clim = %4d jlim = %4d\n"
+ , pCbs->Pars.nBTLimit
+ , pCbs->Pars.nJustLimit );
+ }
+ }
+
+ //Gia_ManForEachAnd( p, pObj, i )
+ i = 0;
+resume:
+ for( ; i < Gia_ManObjNum(p) && (pObj = Gia_ManObj(p,i)); i ++ )
+ {
+ int status = 2;
+ Gia_Obj_t * pObjNew;
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+
+ Vec_BitWriteEntry( pMan->vCexSite, i
+ , Vec_BitEntry( pMan->vCexSite, Gia_ObjFaninId0(pObj,i) )
+ | Vec_BitEntry( pMan->vCexSite, Gia_ObjFaninId1(pObj,i) ) );
+
+ if ( Gia_ObjFailed(p,i) )
+ continue;
+ pMan->nAndNodes++;
+ if ( Gia_ObjProved(p, i) ){
+ pRepr = Gia_ManObj( p, vMerged[i] );
+ pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); // upate in case repr rehashed due to fanin its backtrace
+ continue;
+ }
+
+ if ( Gia_ObjIsXor(pObj) )
+ pObj->Value = Gia_ManHashXorReal( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+
+ Cec5_ManExtend( pMan, pCbs );
+
+ if ( pPars->nLevelMax && Gia_ObjLevel(p, pObj) > pPars->nLevelMax )
+ continue;
+
+ pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) );
+ if ( Gia_ObjIsAnd(pObjNew) )
+ if ( Vec_BitEntry(pMan->vFails, Gia_ObjFaninId0(pObjNew, Abc_Lit2Var(pObj->Value))) ||
+ Vec_BitEntry(pMan->vFails, Gia_ObjFaninId1(pObjNew, Abc_Lit2Var(pObj->Value))) )
+ Vec_BitWriteEntry( pMan->vFails, Abc_Lit2Var(pObjNew->Value), 1 );
+ //if ( Gia_ObjIsAnd(pObjNew) )
+ // Gia_ObjSetAndLevel( pMan->pNew, pObjNew );
+ // select representative based on candidate equivalence classes
+ pRepr = Gia_ObjReprObj( p, i );
+
+ if ( pRepr == NULL )
+ continue;
+
+ if ( 1 ) // select representative based on recent counter-examples
+ {
+ pRepr = Cec5_ManFindRepr( p, pMan, i );
+ if ( pRepr == NULL )
+ continue;
+ }
+ if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) )
+ {
+ assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) );
+ vMerged[i] = Gia_ObjId(p, pRepr);
+ Gia_ObjSetProved( p, i );
+ if ( Gia_ObjId(p, pRepr) == 0 )
+ pMan->iLastConst = i;
+
+ continue;
+ }
+
+ if ( fCbs && (status = Cec5_ManSweepNodeCbs(pMan, pCbs, i, Gia_ObjId(p, pRepr), 0)) && Gia_ObjProved(p, i) ){
+ vMerged[i] = Gia_ObjId(p, pRepr);
+ pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
+ }
+
+ if ( 2 == status && (status = Cec5_ManSweepNode(pMan, i, Gia_ObjId(p, pRepr))) && Gia_ObjProved(p, i) ){
+ vMerged[i] = Gia_ObjId(p, pRepr);
+ pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
+ }
+
+ if( 0 == status && -1 == go_back )
+ go_back = i;
+
+ if( 0 == pMan->nPatterns || 0!=status || pMan->nPatterns % (64 * p->nSimWords-2) )
+ continue;
+
+ if( -1 < go_back ){
+ //printf("go back to %6d from %6d\n", go_back, i );
+ pMan->nAndNodes -= i-go_back;
+ i = go_back-1, go_back = -1;
+ }
+ }
+ if ( p->iPatsPi > 0 )
+ {
+ abctime clk2 = Abc_Clock();
+ Cec5_FlushCache2Pattern(pMan);
+ Cec5_ManSimulate( p, pMan );
+ p->iPatsPi = 0;
+ pMan->simTravId = 0;
+ pMan->simGlobalTop = 0;
+ Cec5_ClearCexMarks(pMan);
+ pMan->timeResimGlo += Abc_Clock() - clk2;
+ if( -1 < go_back ){
+ i = go_back - 1;
+ go_back = -1;
+ goto resume;
+ }
+ }
+
+ ABC_FREE(vMerged);
+
+ if ( pPars->fVerbose )
+ Cec5_ManPrintStats( p, pPars, pMan, 0 );
+ if ( ppNew )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pMan->pNew, Gia_ObjFanin0Copy(pObj) );
+ *ppNew = Gia_ManCleanup( pMan->pNew );
+ }
+
+ if( fCbs ){
+ if ( pPars->fVerbose ){
+ CbsP_ManSatPrintStats( pCbs );
+ CbsP_PrintRecord(&pCbs->Pars);
+ }
+ }
+finalize:
+ if ( pPars->fVerbose )
+ printf( "SAT calls = %d: P = %d (0=%d a=%.2f m=%d) D = %d (0=%d a=%.2f m=%d) F = %d Sim = %d Recyc = %d Xor = %.2f %%\n",
+ pMan->nSatUnsat + pMan->nSatSat + pMan->nSatUndec,
+ pMan->nSatUnsat, pMan->nConflicts[1][0], (float)pMan->nConflicts[1][1]/Abc_MaxInt(1, pMan->nSatUnsat-pMan->nConflicts[1][0]), pMan->nConflicts[1][2],
+ pMan->nSatSat, pMan->nConflicts[0][0], (float)pMan->nConflicts[0][1]/Abc_MaxInt(1, pMan->nSatSat -pMan->nConflicts[0][0]), pMan->nConflicts[0][2],
+ pMan->nSatUndec,
+ pMan->nSimulates, pMan->nRecycles, 100.0*pMan->nGates[1]/Abc_MaxInt(1, pMan->nGates[0]+pMan->nGates[1]) );
+ Cec5_ManDestroy( pMan );
+ if( pCbs )
+ CbsP_ManStop(pCbs);
+ //Gia_ManStaticFanoutStop( p );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ return p->pCexSeq ? 0 : 1;
+}
+Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle )
+{
+ Gia_Man_t * pNew = NULL;
+ Cec5_ManPerformSweeping( p, pPars, &pNew, 0, fCbs, approxLim, subBatchSz, adaRecycle );
+ if ( pNew == NULL )
+ pNew = Gia_ManDup( p );
+ return pNew;
+}
+
+
+
+int Cec5_ManSolveTwoCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose, int fEffort )
+{
+// abctime clk;
+// int nBTLimit = fEffort ? p->pPars->nBTLimitPo : (Vec_BitEntry(p->vFails, iObj0) || Vec_BitEntry(p->vFails, iObj1)) ? Abc_MaxInt(1, p->pPars->nBTLimit/10) : p->pPars->nBTLimit;
+ Gia_Obj_t * pRepr, * pObj;
+ int nConfEnd, nConfBeg, status;//, iVar0, iVar1, Lits[2];
+ int UnsatConflicts[3] = {0};
+ //printf( "%d ", nBTLimit );
+ if ( iObj1 < iObj0 )
+ iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0;
+ assert( iObj0 < iObj1 );
+ pRepr = Gia_ManObj( p->pNew, iObj0 );
+ pObj = Gia_ManObj( p->pNew, iObj1 );
+ *pfEasy = 0;
+ // check if SAT solver needs recycling
+ p->nCallsSince++;
+// if ( p->nCallsSince > p->pPars->nCallsRecycle &&
+// Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax )
+// Cec5_ManSatSolverRecycle( p );
+// // add more logic to the solver
+// if ( !iObj0 && Cec5_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 )
+// Cec5_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), sat_solver_addvar(p->pSat) );
+// clk = Abc_Clock();
+// iVar0 = Cec5_ObjGetCnfVar( p, iObj0 );
+// iVar1 = Cec5_ObjGetCnfVar( p, iObj1 );
+// if( p->pPars->jType > 0 )
+// {
+// sat_solver_start_new_round( p->pSat );
+// sat_solver_mark_cone( p->pSat, Cec5_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj0)) );
+// sat_solver_mark_cone( p->pSat, Cec5_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj1)) );
+// }
+// p->timeCnf += Abc_Clock() - clk;
+ // perform solving
+// Lits[0] = Abc_Var2Lit(iVar0, 1);
+// Lits[1] = Abc_Var2Lit(iVar1, fPhase);
+// sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+// nConfBeg = sat_solver_conflictnum( p->pSat );
+// status = sat_solver_solve( p->pSat, Lits, 2 );
+// nConfEnd = sat_solver_conflictnum( p->pSat );
+ nConfBeg = 0;
+ if( !Gia_ObjIsConst0(pRepr) )
+ status = CbsP_ManSolve2(pCbs,Gia_Not(pObj),Gia_NotCond(pRepr, fPhase));
+ else
+ status = CbsP_ManSolve2(pCbs,Gia_NotCond(pObj,fPhase),NULL);
+ nConfEnd = pCbs->Pars.nBTThis;
+ assert( nConfEnd >= nConfBeg );
+ if ( fVerbose )
+ {
+ if ( status == CBS_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == CBS_UNSAT )
+ {
+ if ( iObj0 > 0 )
+ {
+ UnsatConflicts[0] = nConfEnd == nConfBeg;
+ UnsatConflicts[1] = nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ }
+ else
+ {
+ p->nConflicts[1][0] += nConfEnd == nConfBeg;
+ p->nConflicts[1][1] += nConfEnd - nConfBeg;
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ }
+ }
+ if ( status == CBS_UNSAT && iObj0 > 0 )
+ {
+ //Lits[0] = Abc_Var2Lit(iVar0, 0);
+ //Lits[1] = Abc_Var2Lit(iVar1, !fPhase);
+ //sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ //nConfBeg = sat_solver_conflictnum( p->pSat );
+ //status = sat_solver_solve( p->pSat, Lits, 2 );
+ //nConfEnd = sat_solver_conflictnum( p->pSat );
+ nConfBeg = 0;
+ status = CbsP_ManSolve2(pCbs,pObj,Gia_NotCond(pRepr,!fPhase));
+ nConfEnd = pCbs->Pars.nBTThis;
+ assert( nConfEnd >= nConfBeg );
+ if ( fVerbose )
+ {
+ if ( status == CBS_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == CBS_UNSAT )
+ {
+ UnsatConflicts[0] &= nConfEnd == nConfBeg;
+ UnsatConflicts[1] += nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+
+ p->nConflicts[1][0] += UnsatConflicts[0];
+ p->nConflicts[1][1] += UnsatConflicts[1];
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]);
+ *pfEasy = UnsatConflicts[0];
+ }
+ }
+ }
+ //if ( status == GLUCOSE_UNDEC )
+ // printf( "* " );
+ return status;
+}
+
+
+int Cec5_ManSweepNodeCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj, int iRepr, int fTagFail )
+{
+ extern int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
+ abctime clk = Abc_Clock();
+ int i, status, fEasy, RetValue = 1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj );
+ Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr );
+ int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase;
+ //int fCompl = pObj->fPhase ^ pRepr->fPhase;
+ int fEffort = p->vCoDrivers ? Vec_BitEntry(p->vCoDrivers, iObj) || Vec_BitEntry(p->vCoDrivers, iRepr) : 0;
+ //status = Cec5_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort );
+
+ status = Cec5_ManSolveTwoCbs( p, pCbs, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort );
+ //status = CbsP_ManSolve2(pCbs,pObj,pRepr);
+ if ( status == CBS_SAT )
+ {
+ int iLit;
+ Vec_BitWriteEntry( p->vCexSite, iObj, 1 );
+// int iPatsOld = p->pAig->iPatsPi;
+// //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatSat++;
+ p->nPatterns++;
+ Vec_IntClear( p->vPat );
+ Vec_IntForEachEntry( pCbs->vModel, iLit, i )
+ Vec_IntPush( p->vPat, Abc_LitNot(iLit) );
+ assert( p->pAig->iPatsPi >= 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords - 1 );
+ p->pAig->iPatsPi++;
+ Vec_IntForEachEntry( p->vPat, iLit, i )
+ Vec_IntPush( p->vPiPatsCache, iLit );
+ Vec_IntPush( p->vPiPatsCache, -1 );
+
+ if ( fEasy )
+ p->timeSatSat0 += Abc_Clock() - clk;
+ else
+ p->timeSatSat += Abc_Clock() - clk;
+ RetValue = 0;
+
+ p->simTravId = p->pAig->iPatsPi / p->LocalBatchSize;
+ if( (p->pAig->iPatsPi % p->LocalBatchSize) == 0 || 1 == p->LocalBatchSize )
+ Cec5_FlushCache2Pattern(p);
+
+// // this is not needed, but we keep it here anyway, because it takes very little time
+// //Cec5_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat );
+// // resimulated once in a while
+ Cec5_ManCheckGlobalSim(p);
+ }
+ else if ( status == CBS_UNSAT )
+ {
+ //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatUnsat++;
+ pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl );
+ assert( !Gia_ObjProved( p->pAig, iObj ) );
+ Gia_ObjSetProved( p->pAig, iObj );
+ if ( iRepr == 0 )
+ p->iLastConst = iObj;
+ if ( fEasy )
+ p->timeSatUnsat0 += Abc_Clock() - clk;
+ else
+ p->timeSatUnsat += Abc_Clock() - clk;
+ RetValue = 1;
+ }
+ else
+ {
+ if( fTagFail ){
+ p->nSatUndec++;
+ assert( status == CBS_UNDEC );
+ Gia_ObjSetFailed( p->pAig, iObj );
+ Gia_ObjSetFailed( p->pAig, iRepr );
+ Vec_BitWriteEntry( p->vFails, iObj, 1 );
+ p->timeSatUndec += Abc_Clock() - clk;
+ }
+ //if ( iRepr )
+ //Vec_BitWriteEntry( p->vFails, iRepr, 1 );
+ RetValue = 2;
+ }
+ return RetValue;
+}
+Gia_Man_t * Cec5_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose )
+{
+ int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500;
+ Gia_Man_t * pNew = NULL;
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec5_ManSetParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pPars->nBTLimit = nBTLimit;
+ Cec5_ManPerformSweeping( p, pPars, &pNew, 0, fCbs, approxLim, subBatchSz, adaRecycle );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSolveG.c b/src/proof/cec/cecSolveG.c
index 0bb68a7f..c4b01b50 100644
--- a/src/proof/cec/cecSolveG.c
+++ b/src/proof/cec/cecSolveG.c
@@ -445,7 +445,7 @@ void CecG_ManSatSolverRecycle( Cec_ManSat_t * p )
// memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) );
sat_solver_stop( p->pSat );
}
- p->pSat = sat_solver_start();
+ p->pSat = (struct sat_solver_t*)sat_solver_start();
assert( 0 <= p->pPars->SolverType && p->pPars->SolverType <= 2 );
sat_solver_set_jftr( p->pSat, p->pPars->SolverType );
//sat_solver_setnvars( p->pSat, 1000 ); // minisat only
diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make
index 23595f23..ed3dac11 100644
--- a/src/proof/cec/module.make
+++ b/src/proof/cec/module.make
@@ -9,6 +9,7 @@ SRC += src/proof/cec/cecCec.c \
src/proof/cec/cecSat.c \
src/proof/cec/cecSatG.c \
src/proof/cec/cecSatG2.c \
+ src/proof/cec/cecSatG3.c \
src/proof/cec/cecSeq.c \
src/proof/cec/cecSim.c \
src/proof/cec/cecSolve.c \
diff --git a/src/proof/ssw/ssw.h b/src/proof/ssw/ssw.h
index 9bd83964..c8275b7a 100644
--- a/src/proof/ssw/ssw.h
+++ b/src/proof/ssw/ssw.h
@@ -55,6 +55,7 @@ struct Ssw_Pars_t_
int nResimDelta; // the number of nodes to resimulate
int nStepsMax; // (scorr only) the max number of induction steps
int TimeLimit; // time out in seconds
+ int nLimitMax; // the limit on the number of iterations
int fPolarFlip; // uses polarity adjustment
int fLatchCorr; // perform register correspondence
int fConstCorr; // perform constant correspondence
diff --git a/src/proof/ssw/sswCore.c b/src/proof/ssw/sswCore.c
index 1036d7b4..b48db953 100644
--- a/src/proof/ssw/sswCore.c
+++ b/src/proof/ssw/sswCore.c
@@ -236,7 +236,7 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
{
int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal, nUniques;
Aig_Man_t * pAigNew;
- int RetValue, nIter = -1;
+ int RetValue, nIter = -1, nPrev[4] = {0};
abctime clk, clkTotal = Abc_Clock();
// get the starting stats
p->nLitsBeg = Ssw_ClassesLitNum( p->ppClasses );
@@ -352,7 +352,7 @@ clk = Abc_Clock();
{
printf( "Iterative refinement is stopped after iteration %d\n", nIter );
printf( "because the property output is no longer a candidate constant.\n" );
- // prepare to quite
+ // prepare to quit
p->nLitsEnd = p->nLitsBeg;
p->nNodesEnd = p->nNodesBeg;
p->nRegsEnd = p->nRegsBeg;
@@ -381,6 +381,27 @@ clk = Abc_Clock();
break;
if ( p->pPars->pFunc )
((int (*)(void *))p->pPars->pFunc)( p->pPars->pData );
+ if ( p->pPars->nLimitMax )
+ {
+ int nCur = Ssw_ClassesCand1Num(p->ppClasses);
+ if ( nIter > 4 && nPrev[0] - nCur <= 4*p->pPars->nLimitMax )
+ {
+ printf( "Iterative refinement is stopped after iteration %d\n", nIter );
+ printf( "because the refinment is very slow.\n" );
+ // prepare to quit
+ p->nLitsEnd = p->nLitsBeg;
+ p->nNodesEnd = p->nNodesBeg;
+ p->nRegsEnd = p->nRegsBeg;
+ // cleanup
+ Aig_ManSetPhase( p->pAig );
+ Aig_ManCleanMarkB( p->pAig );
+ return Aig_ManDupSimple( p->pAig );
+ }
+ nPrev[0] = nPrev[1];
+ nPrev[1] = nPrev[2];
+ nPrev[2] = nPrev[3];
+ nPrev[3] = nCur;
+ }
}
finalize:
diff --git a/src/sat/bsat2/Solver.cpp b/src/sat/bsat2/Solver.cpp
index 451beed8..0f8b415a 100644
--- a/src/sat/bsat2/Solver.cpp
+++ b/src/sat/bsat2/Solver.cpp
@@ -820,7 +820,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
diff --git a/src/sat/glucose/AbcGlucose.cpp b/src/sat/glucose/AbcGlucose.cpp
index ad595ab9..9c23e0d0 100644
--- a/src/sat/glucose/AbcGlucose.cpp
+++ b/src/sat/glucose/AbcGlucose.cpp
@@ -818,7 +818,7 @@ void Glucose_ReadDimacs( char * pFileName, SimpSolver& s )
SeeAlso []
***********************************************************************/
-void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars )
+void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars, int fDumpCnf )
{
abctime clk = Abc_Clock();
@@ -844,6 +844,15 @@ void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars )
S.eliminate(true);
printf( "c Simplication removed %d variables and %d clauses. ", S.eliminated_vars, S.eliminated_clauses );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ if ( fDumpCnf )
+ {
+ char * pFileCnf = Extra_FileNameGenericAppend( pFileName, "_out.cnf" );
+ S.toDimacs(pFileCnf);
+ printf( "Finished dumping CNF after preprocessing into file \"%s\".\n", pFileCnf );
+ printf( "SAT solving is not performed.\n" );
+ return;
+ }
}
vec<Lit> dummy;
diff --git a/src/sat/glucose/AbcGlucose.h b/src/sat/glucose/AbcGlucose.h
index 89a3652f..c73f9918 100644
--- a/src/sat/glucose/AbcGlucose.h
+++ b/src/sat/glucose/AbcGlucose.h
@@ -105,7 +105,7 @@ extern void bmcg_sat_solver_start_new_round( bmcg_sat_solver * s );
extern void bmcg_sat_solver_mark_cone( bmcg_sat_solver * s, int var );
-extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars );
+extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars, int fDumpCnf );
extern int Glucose_SolveAig( Gia_Man_t * p, Glucose_Pars * pPars );
ABC_NAMESPACE_HEADER_END
diff --git a/src/sat/glucose/AbcGlucoseCmd.cpp b/src/sat/glucose/AbcGlucoseCmd.cpp
index 2e819e49..bb957547 100644
--- a/src/sat/glucose/AbcGlucoseCmd.cpp
+++ b/src/sat/glucose/AbcGlucoseCmd.cpp
@@ -81,10 +81,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
int pre = 1;
int verb = 0;
int nConfls = 0;
+ int fDumpCnf = 0;
Glucose_Pars pPars;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Cpdvh" ) ) != EOF )
{
switch ( c )
{
@@ -102,6 +103,9 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'p':
pre ^= 1;
break;
+ case 'd':
+ fDumpCnf ^= 1;
+ break;
case 'v':
verb ^= 1;
break;
@@ -116,7 +120,7 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( argc == globalUtilOptind + 1 )
{
- Glucose_SolveCnf( argv[globalUtilOptind], &pPars );
+ Glucose_SolveCnf( argv[globalUtilOptind], &pPars, fDumpCnf );
return 0;
}
@@ -132,10 +136,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &glucose [-C num] [-pvh] <file.cnf>\n" );
+ Abc_Print( -2, "usage: &glucose [-C num] [-pdvh] <file.cnf>\n" );
Abc_Print( -2, "\t run Glucose 3.0 by Gilles Audemard and Laurent Simon\n" );
Abc_Print( -2, "\t-C num : conflict limit [default = %d]\n", nConfls );
Abc_Print( -2, "\t-p : enable preprocessing [default = %d]\n",pre);
+ Abc_Print( -2, "\t-d : enable dumping CNF after proprocessing [default = %d]\n",fDumpCnf);
Abc_Print( -2, "\t-v : verbosity [default = %d]\n",verb);
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n");
diff --git a/src/sat/glucose/Glucose.cpp b/src/sat/glucose/Glucose.cpp
index c975c6ca..cfb388de 100644
--- a/src/sat/glucose/Glucose.cpp
+++ b/src/sat/glucose/Glucose.cpp
@@ -1330,7 +1330,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
diff --git a/src/sat/glucose2/AbcGlucose2.cpp b/src/sat/glucose2/AbcGlucose2.cpp
index 9a8b97eb..99ca112a 100644
--- a/src/sat/glucose2/AbcGlucose2.cpp
+++ b/src/sat/glucose2/AbcGlucose2.cpp
@@ -132,6 +132,10 @@ void glucose2_solver_setstop(Gluco2::SimpSolver* S, int * pstop)
S->pstop = pstop;
}
+void glucose2_markapprox( Gluco2::SimpSolver* S, int v0, int v1, int nlim )
+{
+ S->markApprox(v0, v1, nlim);
+}
/**Function*************************************************************
@@ -228,6 +232,11 @@ void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop)
glucose2_solver_setstop((Gluco2::SimpSolver*)s, pstop);
}
+void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim)
+{
+ glucose2_markapprox((Gluco2::SimpSolver*)s, v0, v1, nlim);
+}
+
abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit)
{
abctime nRuntimeLimit = ((Gluco2::SimpSolver*)s)->nRuntimeLimit;
@@ -474,6 +483,11 @@ void glucose2_solver_setstop(Gluco2::Solver* S, int * pstop)
S->pstop = pstop;
}
+void glucose2_markapprox( Gluco2::Solver* S, int v0, int v1, int nlim )
+{
+ S->markApprox(v0, v1, nlim);
+}
+
/**Function*************************************************************
@@ -570,6 +584,11 @@ void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop)
glucose2_solver_setstop((Gluco2::Solver*)s, pstop);
}
+void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim)
+{
+ glucose2_markapprox((Gluco2::Solver*)s, v0, v1, nlim);
+}
+
abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit)
{
abctime nRuntimeLimit = ((Gluco2::Solver*)s)->nRuntimeLimit;
diff --git a/src/sat/glucose2/AbcGlucose2.h b/src/sat/glucose2/AbcGlucose2.h
index 9299d290..d1c15639 100644
--- a/src/sat/glucose2/AbcGlucose2.h
+++ b/src/sat/glucose2/AbcGlucose2.h
@@ -86,6 +86,7 @@ extern int bmcg2_sat_solver_elim_varnum(bmcg2_sat_solver* s);
extern int * bmcg2_sat_solver_read_cex( bmcg2_sat_solver* s );
extern int bmcg2_sat_solver_read_cex_varvalue( bmcg2_sat_solver* s, int );
extern void bmcg2_sat_solver_set_stop( bmcg2_sat_solver* s, int * pstop );
+extern void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim);
extern abctime bmcg2_sat_solver_set_runtime_limit( bmcg2_sat_solver* s, abctime Limit );
extern void bmcg2_sat_solver_set_conflict_budget( bmcg2_sat_solver* s, int Limit );
extern int bmcg2_sat_solver_varnum( bmcg2_sat_solver* s );
diff --git a/src/sat/glucose2/CGlucoseCore.h b/src/sat/glucose2/CGlucoseCore.h
index c0f96fc4..22de92d2 100644
--- a/src/sat/glucose2/CGlucoseCore.h
+++ b/src/sat/glucose2/CGlucoseCore.h
@@ -613,6 +613,85 @@ inline void Solver::prelocate( int base_var_num ){
polarity .prelocate( base_var_num );
}
+
+inline void Solver::markTill( Var v, int nlim ){
+ if( var2TravId[v] == travId )
+ return;
+
+ vMarked.push(v);
+
+ if( vMarked.size() >= nlim )
+ return;
+ if( var2TravId[v] == travId-1 || !isTwoFanin(v) )
+ goto finalize;
+
+ markTill( getFaninVar0(v), nlim );
+ markTill( getFaninVar1(v), nlim );
+finalize:
+ var2TravId[v] = travId;
+}
+
+inline void Solver::markApprox( Var v0, Var v1, int nlim ){
+ int i;
+ if( travId <= 1 || nSkipMark>=4 || 0 == nlim )
+ goto finalize;
+
+ vMarked.shrink_( vMarked.size() );
+ travId ++ ; // travId = t+1
+ assert(travId>1);
+
+ markTill(v0, nlim);
+ if( vMarked.size() >= nlim )
+ goto finalize;
+
+ markTill(v1, nlim);
+ if( vMarked.size() >= nlim )
+ goto finalize;
+
+ travId -- ; // travId = t
+ for(i = 0; i < vMarked.size(); i ++){
+ var2TravId [ vMarked[i] ] = travId; // set new nodes to time t
+ var2NodeData[ vMarked[i] ].sort = 0;
+ }
+ nSkipMark ++ ;
+ return;
+finalize:
+
+ travId ++ ;
+ nSkipMark = 0;
+ markCone(v0);
+ markCone(v1);
+}
+
+inline void Solver::loadJust_rec( Var v ){
+ //assert( value(v) != l_Undef );
+ if( var2TravId[v] == travId || value(v) == l_Undef )
+ return;
+ assert( var2TravId[v] == travId-1 );
+ var2TravId[v] = travId;
+ vMarked.push(v);
+
+ if( !isTwoFanin(v) ){
+ JustModel.push( mkLit( v, value(v) == l_False ) );
+ return;
+ }
+ loadJust_rec( getFaninVar0(v) );
+ loadJust_rec( getFaninVar1(v) );
+}
+inline void Solver::loadJust(){
+ int i;
+ travId ++ ;
+ JustModel.shrink_(JustModel.size());
+ vMarked.shrink_(vMarked.size());
+ JustModel.push(toLit(0));
+ for(i = 0; i < assumptions.size(); i ++)
+ loadJust_rec( var(assumptions[i]) );
+ JustModel[0] = toLit( JustModel.size()-1 );
+ travId -- ;
+ for(i = 0; i < vMarked.size(); i ++)
+ var2TravId[ vMarked[i] ] = travId;
+}
+
};
ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/Glucose2.cpp b/src/sat/glucose2/Glucose2.cpp
index 7a8b265b..d345cd0a 100644
--- a/src/sat/glucose2/Glucose2.cpp
+++ b/src/sat/glucose2/Glucose2.cpp
@@ -186,6 +186,7 @@ Solver::Solver() :
itpc = ca.alloc(tmp);
ca[itpc].shrink( ca[itpc].size() );
+ nSkipMark = 0;
#endif
}
@@ -1452,15 +1453,20 @@ printf("c ==================================[ Search Statistics (every %6d confl
if (status == l_True){
if( justUsage() ){
- JustModel.shrink_(JustModel.size());
- assert(jheap.empty());
- //JustModel.growTo(nVars());
- int i = 0, j = 0;
- JustModel.push(toLit(0));
- for (; i < trail.size(); i++)
- if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) )
- JustModel.push(trail[i]), j++;
- JustModel[0] = toLit(j);
+ if( nSkipMark ){
+ loadJust();
+ } else {
+ JustModel.shrink_(JustModel.size());
+ assert(jheap.empty());
+ //JustModel.growTo(nVars());
+ int i = 0, j = 0;
+ JustModel.push(toLit(0));
+ for (; i < trail.size(); i++)
+ if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) )
+ JustModel.push(trail[i]), j++;
+ JustModel[0] = toLit(j);
+ }
+
} else {
// Extend & copy model:
model.shrink_(model.size());
@@ -1535,7 +1541,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
@@ -1743,6 +1749,9 @@ void Solver::reset()
itpc = ca.alloc(tmp);
ca[itpc].shrink( ca[itpc].size() );
}
+
+ vMarked.shrink_( vMarked.size() );
+ nSkipMark = 0;
#endif
}
diff --git a/src/sat/glucose2/Solver.h b/src/sat/glucose2/Solver.h
index b1d38d79..004fdc95 100644
--- a/src/sat/glucose2/Solver.h
+++ b/src/sat/glucose2/Solver.h
@@ -453,7 +453,15 @@ protected:
Heap2<JustOrderLt2, JustKey> jheap;
vec<int> jlevel;
vec<int> jnext;
+
+ int nSkipMark;
+ void loadJust_rec( Var v );
+ void loadJust();
+ vec<Var> vMarked;
public:
+ void markTill( Var v0, int nlim );
+ void markApprox( Var v0, Var v1, int nlim );
+
void prelocate( int var_num );
void setVarFaninLits( Var v, Lit lit1, Lit lit2 );
void setVarFaninLits( int v, int lit1, int lit2 ){ setVarFaninLits( Var(v), toLit(lit1), toLit(lit2) ); }
diff --git a/src/sat/msat/msatClause.c b/src/sat/msat/msatClause.c
index 6b1b9e98..3d1fa2fc 100644
--- a/src/sat/msat/msatClause.c
+++ b/src/sat/msat/msatClause.c
@@ -522,7 +522,7 @@ void Msat_ClausePrintSymbols( Msat_Clause_t * pC )
// if ( pC->fLearned )
// printf( "Act = %.4f ", Msat_ClauseReadActivity(pC) );
for ( i = 0; i < (int)pC->nSize; i++ )
- printf(" "L_LIT, L_lit(pC->pData[i]));
+ printf(" " L_LIT, L_lit(pC->pData[i]));
}
printf( "\n" );
}
diff --git a/src/sat/msat/msatSolverSearch.c b/src/sat/msat/msatSolverSearch.c
index b3190e39..2eda5038 100644
--- a/src/sat/msat/msatSolverSearch.c
+++ b/src/sat/msat/msatSolverSearch.c
@@ -52,7 +52,7 @@ int Msat_SolverAssume( Msat_Solver_t * p, Msat_Lit_t Lit )
{
assert( Msat_QueueReadSize(p->pQueue) == 0 );
if ( p->fVerbose )
- printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "assume(" L_LIT ")\n", L_ind, L_lit(Lit));
Msat_IntVecPush( p->vTrailLim, Msat_IntVecReadSize(p->vTrail) );
// assert( Msat_IntVecReadSize(p->vTrailLim) <= Msat_IntVecReadSize(p->vTrail) + 1 );
// assert( Msat_IntVecReadSize( p->vTrailLim ) < p->nVars );
@@ -83,7 +83,7 @@ void Msat_SolverUndoOne( Msat_Solver_t * p )
Msat_OrderVarUnassigned( p->pOrder, Var );
if ( p->fVerbose )
- printf(L_IND"unbind("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "unbind(" L_LIT")\n", L_ind, L_lit(Lit));
}
/**Function*************************************************************
@@ -107,7 +107,7 @@ void Msat_SolverCancel( Msat_Solver_t * p )
{
Msat_Lit_t Lit;
Lit = Msat_IntVecReadEntry( p->vTrail, Msat_IntVecReadEntryLast(p->vTrailLim) );
- printf(L_IND"cancel("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "cancel(" L_LIT ")\n", L_ind, L_lit(Lit));
}
}
for ( c = Msat_IntVecReadSize(p->vTrail) - Msat_IntVecPop( p->vTrailLim ); c != 0; c-- )
@@ -188,7 +188,7 @@ int Msat_SolverEnqueue( Msat_Solver_t * p, Msat_Lit_t Lit, Msat_Clause_t * pC )
if ( p->fVerbose )
{
// printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(Lit));
- printf(L_IND"bind("L_LIT") ", L_ind, L_lit(Lit));
+ printf(L_IND "bind(" L_LIT ") ", L_ind, L_lit(Lit));
Msat_ClausePrintSymbols( pC );
}
p->pAssigns[Var] = Lit;
@@ -513,7 +513,7 @@ void Msat_SolverAnalyze( Msat_Solver_t * p, Msat_Clause_t * pC, Msat_IntVec_t *
nReasonSize = Msat_IntVecReadSize( vLits_out );
pReasonArray = Msat_IntVecReadArray( vLits_out );
for ( j = 0; j < nReasonSize; j++ )
- printf(" "L_LIT, L_lit(pReasonArray[j]));
+ printf(" " L_LIT, L_lit(pReasonArray[j]));
printf(" } at level %d\n", *pLevel_out);
}
}