summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/abc/abc.h33
-rw-r--r--src/base/abc/abcAig.c1
-rw-r--r--src/base/abc/abcFanio.c1
-rw-r--r--src/base/abc/abcFunc.c39
-rw-r--r--src/base/abc/abcNetlist.c10
-rw-r--r--src/base/abc/abcNtk.c14
-rw-r--r--src/base/abc/abcObj.c2
-rw-r--r--src/base/abc/abcSop.c45
-rw-r--r--src/base/abci/abc.c469
-rw-r--r--src/base/abci/abcAuto.c2
-rw-r--r--src/base/abci/abcBalance.c63
-rw-r--r--src/base/abci/abcClpBdd.c4
-rw-r--r--src/base/abci/abcCut.c45
-rw-r--r--src/base/abci/abcDsd.c2
-rw-r--r--src/base/abci/abcEspresso.c8
-rw-r--r--src/base/abci/abcFraig.c2
-rw-r--r--src/base/abci/abcFxu.c8
-rw-r--r--src/base/abci/abcGen.c261
-rw-r--r--src/base/abci/abcMap.c6
-rw-r--r--src/base/abci/abcMiter.c122
-rw-r--r--src/base/abci/abcNewAig.c8
-rw-r--r--src/base/abci/abcNtbdd.c39
-rw-r--r--src/base/abci/abcPrint.c16
-rw-r--r--src/base/abci/abcProve.c143
-rw-r--r--src/base/abci/abcRefactor.c4
-rw-r--r--src/base/abci/abcRestruct.c19
-rw-r--r--src/base/abci/abcResub.c102
-rw-r--r--src/base/abci/abcRewrite.c4
-rw-r--r--src/base/abci/abcRr.c601
-rw-r--r--src/base/abci/abcSat.c48
-rw-r--r--src/base/abci/abcStrash.c21
-rw-r--r--src/base/abci/abcSymm.c2
-rw-r--r--src/base/abci/abcTrace.c804
-rw-r--r--src/base/abci/abcUnate.c2
-rw-r--r--src/base/abci/abcUnreach.c8
-rw-r--r--src/base/abci/abcVanEijk.c2
-rw-r--r--src/base/abci/abcVanImp.c2
-rw-r--r--src/base/abci/abcVerify.c9
-rw-r--r--src/base/abci/abc_.c3
-rw-r--r--src/base/abci/module.make3
-rw-r--r--src/base/cmd/cmd.c200
-rw-r--r--src/base/io/ioRead.c3
-rw-r--r--src/base/io/ioReadBench.c2
-rw-r--r--src/base/io/ioWriteCnf.c40
-rw-r--r--src/base/io/ioWriteDot.c8
-rw-r--r--src/base/io/ioWriteList.c30
-rw-r--r--src/base/main/main.h1
-rw-r--r--src/base/main/mainFrame.c20
-rw-r--r--src/base/main/mainInt.h1
-rw-r--r--src/base/seq/seqAigCore.c2
-rw-r--r--src/base/seq/seqMapIter.c2
-rw-r--r--src/base/seq/seqRetCore.c8
-rw-r--r--src/map/pga/pgaMatch.c2
-rw-r--r--src/misc/extra/extra.h88
-rw-r--r--src/misc/extra/extraUtilFile.c59
-rw-r--r--src/misc/extra/extraUtilProgress.c8
-rw-r--r--src/misc/extra/extraUtilTruth.c1076
-rw-r--r--src/misc/extra/module.make1
-rw-r--r--src/misc/vec/vecInt.h27
-rw-r--r--src/misc/vec/vecVec.h22
-rw-r--r--src/opt/cut/cut.h15
-rw-r--r--src/opt/cut/cutInt.h11
-rw-r--r--src/opt/cut/cutMan.c42
-rw-r--r--src/opt/cut/cutNode.c47
-rw-r--r--src/opt/cut/cutOracle.c2
-rw-r--r--src/opt/cut/cutPre22.c983
-rw-r--r--src/opt/cut/cutSeq.c6
-rw-r--r--src/opt/cut/cutTruth.c124
-rw-r--r--src/opt/cut/module.make1
-rw-r--r--src/opt/rwr/rwrEva.c2
-rw-r--r--src/sat/aig/rwrTruth.c2
-rw-r--r--src/sat/asat/added.c27
-rw-r--r--src/sat/asat/jfront.c514
-rw-r--r--src/sat/asat/module.make1
-rw-r--r--src/sat/asat/solver.c40
-rw-r--r--src/sat/asat/solver.h14
-rw-r--r--src/sat/csat/csat_apis.c23
-rw-r--r--src/sat/fraig/fraig.h27
-rw-r--r--src/sat/fraig/fraigApi.c2
-rw-r--r--src/sat/fraig/fraigInt.h6
-rw-r--r--src/sat/fraig/fraigMan.c40
-rw-r--r--src/sat/fraig/fraigNode.c1
-rw-r--r--src/sat/fraig/fraigPrime.c6
-rw-r--r--src/sat/fraig/fraigSat.c50
-rw-r--r--src/sat/msat/msatOrderJ.c44
85 files changed, 6185 insertions, 422 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index c68c74e2..e0f0df99 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -154,6 +154,7 @@ struct Abc_Ntk_t_
Abc_NtkFunc_t ntkFunc; // functionality of the network
char * pName; // the network name
char * pSpec; // the name of the spec file if present
+ int Id; // network ID
// name representation
stmm_table * tName2Net; // the table hashing net names into net pointer
stmm_table * tObj2Name; // the table hashing PI/PO/latch pointers into names
@@ -210,7 +211,7 @@ struct Abc_Ntk_t_
// maximum/minimum operators
#define ABC_MIN(a,b) (((a) < (b))? (a) : (b))
#define ABC_MAX(a,b) (((a) > (b))? (a) : (b))
-#define ABC_INFINITY (10000000)
+#define ABC_INFINITY (100000000)
// transforming floats into ints and back
static inline int Abc_Float2Int( float Val ) { return *((int *)&Val); }
@@ -439,10 +440,10 @@ extern bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk );
extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
/*=== abcCollapse.c ==========================================================*/
-extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fVerbose );
+extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose );
/*=== abcCut.c ==========================================================*/
-extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti );
-extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti );
+extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree );
+extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree );
extern void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fFirst );
extern void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj );
extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
@@ -492,6 +493,8 @@ extern int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk );
extern int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode );
/*=== abcMiter.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+extern Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+extern Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues );
extern Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 );
extern Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist );
extern Abc_Ntk_t * Abc_NtkMiterQuantifyPis( Abc_Ntk_t * pNtk );
@@ -554,7 +557,7 @@ extern Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk );
/*=== abcNtbdd.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi );
extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
-extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fLatchOnly );
+extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fLatchOnly, int fReorder, int fVerbose );
extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk );
/*=== abcNtk.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
@@ -584,7 +587,7 @@ extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode,
extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes );
extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
/*=== abcProve.c ==========================================================*/
-extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, int nConfLimit, int nImpLimit, int fUseRewrite, int fUseFraig, int fVerbose );
+extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams );
/*=== abcReconv.c ==========================================================*/
extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop );
extern void Abc_NtkManCutStop( Abc_ManCut_t * p );
@@ -607,8 +610,8 @@ extern int Abc_NodeRef_rec( Abc_Obj_t * pNode );
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld );
/*=== abcSat.c ==========================================================*/
-extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbose );
-extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
+extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose );
+extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront );
/*=== abcSop.c ==========================================================*/
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
@@ -623,6 +626,7 @@ extern char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars );
+extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
extern int Abc_SopGetCubeNum( char * pSop );
@@ -672,6 +676,19 @@ extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk );
extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR );
extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj );
extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj );
+/*=== abcTrace.c ==========================================================*/
+extern void Abc_HManStart();
+extern void Abc_HManStop();
+extern int Abc_HManIsRunning();
+extern int Abc_HManGetNewNtkId();
+extern void Abc_HManAddObj( Abc_Obj_t * pObj );
+extern void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
+extern void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin );
+extern void Abc_HManRemoveFanins( Abc_Obj_t * pObj );
+extern void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto );
+extern void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu );
+extern int Abc_HManPopulate( Abc_Ntk_t * pNtk );
+extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew );
/*=== abcUtil.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c
index f2f50f77..7eb62416 100644
--- a/src/base/abc/abcAig.c
+++ b/src/base/abc/abcAig.c
@@ -807,6 +807,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
Abc_AigAndDelete( pMan, pFanout );
// remove the fanins of the old fanout
Abc_ObjRemoveFanins( pFanout );
+ Abc_HManRemoveFanins( pFanout );
// recreate the old fanout with new fanins and add it to the table
Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) );
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index 59dff196..60e847d0 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -50,6 +50,7 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
+ Abc_HManAddFanin( pObj, pFanin );
}
diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c
index cb20cec3..da50a9aa 100644
--- a/src/base/abc/abcFunc.c
+++ b/src/base/abc/abcFunc.c
@@ -24,6 +24,8 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define ABC_MUX_CUBES 100000
+
static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
////////////////////////////////////////////////////////////////////////
@@ -205,6 +207,7 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk )
int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
{
Abc_Obj_t * pNode;
+ Extra_MmFlex_t * pManNew;
DdManager * dd = pNtk->pManFunc;
DdNode * bFunc;
Vec_Str_t * vCube;
@@ -217,10 +220,8 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
assert( Abc_NtkIsBddLogic(pNtk) );
Cudd_zddVarsFromBddVars( dd, 2 );
- // allocate the new manager
- pNtk->pManFunc = Extra_MmFlexStart();
- // update the network type
- pNtk->ntkFunc = ABC_FUNC_SOP;
+ // create the new manager
+ pManNew = Extra_MmFlexStart();
// go through the objects
vCube = Vec_StrAlloc( 100 );
@@ -228,17 +229,30 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
{
assert( pNode->pData );
bFunc = pNode->pData;
- pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, fMode );
- if ( pNode->pData == NULL )
+ pNode->pNext = (Abc_Obj_t *)Abc_ConvertBddToSop( pManNew, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, fMode );
+ if ( pNode->pNext == NULL )
{
+ Extra_MmFlexStop( pManNew, 0 );
+ Abc_NtkCleanNext( pNtk );
+// printf( "Converting from BDDs to SOPs has failed.\n" );
Vec_StrFree( vCube );
- Cudd_Quit( dd );
return 0;
}
- Cudd_RecursiveDeref( dd, bFunc );
}
Vec_StrFree( vCube );
+ // update the network type
+ pNtk->ntkFunc = ABC_FUNC_SOP;
+ // set the new manager
+ pNtk->pManFunc = pManNew;
+ // transfer from next to data
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Cudd_RecursiveDeref( dd, pNode->pData );
+ pNode->pData = pNode->pNext;
+ pNode->pNext = NULL;
+ }
+
// check for remaining references in the package
Extra_StopManager( dd );
return 1;
@@ -339,6 +353,13 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun
assert( 0 );
}
+ if ( nCubes > ABC_MUX_CUBES )
+ {
+ Cudd_RecursiveDerefZdd( dd, zCover );
+ printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MUX_CUBES );
+ return NULL;
+ }
+
// allocate memory for the cover
if ( pMan )
pSop = Extra_MmFlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 );
@@ -468,6 +489,8 @@ void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes )
(*pnCubes)++;
return;
}
+ if ( (*pnCubes) > ABC_MUX_CUBES )
+ return;
extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 );
Abc_CountZddCubes_rec( dd, zC0, pnCubes );
Abc_CountZddCubes_rec( dd, zC1, pnCubes );
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index d289cd35..737d63c2 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -62,7 +62,7 @@ Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy );
// collect the CO nodes
Abc_NtkFinalize( pNtk, pNtkNew );
- // fix the problem with CO pointing directing to CIs
+ // fix the problem with CO pointing directly to CIs
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// duplicate EXDC
if ( pNtk->pExdc )
@@ -101,7 +101,8 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect )
}
else if ( Abc_NtkIsBddLogic(pNtk) )
{
- Abc_NtkBddToSop(pNtk, fDirect);
+ if ( !Abc_NtkBddToSop(pNtk, fDirect) )
+ return NULL;
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
Abc_NtkSopToBdd(pNtk);
}
@@ -157,7 +158,10 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk,0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk,0) )
+ return NULL;
+ }
// start the netlist by creating PI/PO/Latch objects
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc );
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index 0692819b..60ad2412 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -50,6 +50,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
memset( pNtk, 0, sizeof(Abc_Ntk_t) );
pNtk->ntkType = Type;
pNtk->ntkFunc = Func;
+ pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId();
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLats = Vec_PtrAlloc( 100 );
@@ -136,6 +137,14 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Vec_PtrPush( pNtkNew->vCis, pObjNew );
Vec_PtrPush( pNtkNew->vCos, pObjNew );
}
+ if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
+ {
+ Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) );
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Abc_HManAddProto( pObj->pCopy, pObj );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_HManAddProto( pObj->pCopy, pObj );
+ }
// transfer the names
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
@@ -407,6 +416,11 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
+ if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
+ {
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ Abc_HManAddProto( pObj->pCopy, pObj );
+ }
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index d6adfeb2..0ffe3298 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -50,6 +50,8 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
pObj->pNtk = pNtk;
pObj->Type = Type;
pObj->Id = -1;
+ if ( pNtk->ntkType != ABC_NTK_NETLIST )
+ Abc_HManAddObj( pObj );
return pObj;
}
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
index 1e59b17b..d5cc65f1 100644
--- a/src/base/abc/abcSop.c
+++ b/src/base/abc/abcSop.c
@@ -61,7 +61,7 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
/**Function*************************************************************
- Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
+ Synopsis [Creates the constant 1 cover with the given number of variables and cubes.]
Description []
@@ -92,7 +92,7 @@ char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars )
/**Function*************************************************************
- Synopsis [Starts the constant 1 cover with 0 variables.]
+ Synopsis [Creates the constant 1 cover with 0 variables.]
Description []
@@ -108,7 +108,7 @@ char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan )
/**Function*************************************************************
- Synopsis [Starts the constant 1 cover with 0 variables.]
+ Synopsis [Creates the constant 1 cover with 0 variables.]
Description []
@@ -124,7 +124,7 @@ char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan )
/**Function*************************************************************
- Synopsis [Starts the AND2 cover.]
+ Synopsis [Creates the AND2 cover.]
Description []
@@ -147,7 +147,7 @@ char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 )
/**Function*************************************************************
- Synopsis [Starts the multi-input AND cover.]
+ Synopsis [Creates the multi-input AND cover.]
Description []
@@ -169,7 +169,7 @@ char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl )
/**Function*************************************************************
- Synopsis [Starts the multi-input NAND cover.]
+ Synopsis [Creates the multi-input NAND cover.]
Description []
@@ -191,7 +191,7 @@ char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
- Synopsis [Starts the multi-input OR cover.]
+ Synopsis [Creates the multi-input OR cover.]
Description []
@@ -213,7 +213,7 @@ char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl )
/**Function*************************************************************
- Synopsis [Starts the multi-input OR cover.]
+ Synopsis [Creates the multi-input OR cover.]
Description []
@@ -238,7 +238,7 @@ char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl
/**Function*************************************************************
- Synopsis [Starts the multi-input NOR cover.]
+ Synopsis [Creates the multi-input NOR cover.]
Description []
@@ -259,7 +259,7 @@ char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
- Synopsis [Starts the multi-input XOR cover.]
+ Synopsis [Creates the multi-input XOR cover.]
Description []
@@ -276,7 +276,7 @@ char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
- Synopsis [Starts the multi-input XOR cover (special case).]
+ Synopsis [Creates the multi-input XOR cover (special case).]
Description []
@@ -296,7 +296,7 @@ char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
- Synopsis [Starts the multi-input XNOR cover.]
+ Synopsis [Creates the multi-input XNOR cover.]
Description []
@@ -313,7 +313,24 @@ char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
- Synopsis [Starts the inv cover.]
+ Synopsis [Creates the MUX cover.]
+
+ Description [The first input of MUX is the control. The second input
+ is DATA1. The third input is DATA0.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_SopCreateMux( Extra_MmFlex_t * pMan )
+{
+ return Abc_SopRegister(pMan, "11- 1\n0-1 1\n");
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the inv cover.]
Description []
@@ -329,7 +346,7 @@ char * Abc_SopCreateInv( Extra_MmFlex_t * pMan )
/**Function*************************************************************
- Synopsis [Starts the buf cover.]
+ Synopsis [Creates the buf cover.]
Description []
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index ffab5116..26ef2b66 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -64,6 +64,7 @@ static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv
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_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -82,6 +83,7 @@ static int Abc_CommandExdcSet ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandEspresso ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -115,6 +117,9 @@ static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -167,6 +172,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", "rr", Abc_CommandRr, 1 );
// Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 );
@@ -185,6 +191,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 );
Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 );
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
@@ -218,9 +225,13 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
+ Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
+
// Rwt_Man4ExploreStart();
// Map_Var3Print();
// Map_Var4Test();
+
}
/**Function*************************************************************
@@ -1598,6 +1609,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk, * pNtkRes;
int fBddSizeMax;
int fDualRail;
+ int fReorder;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
@@ -1605,10 +1617,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fReorder = 1;
fDualRail = 0;
fBddSizeMax = 1000000;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Bdh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Brdh" ) ) != EOF )
{
switch ( c )
{
@@ -1626,6 +1639,9 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDualRail ^= 1;
break;
+ case 'r':
+ fReorder ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -1647,11 +1663,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( Abc_NtkIsStrash(pNtk) )
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, 1 );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, 1 );
else
{
pNtk = Abc_NtkStrash( pNtk, 0, 0 );
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, 1 );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, 1 );
Abc_NtkDelete( pNtk );
}
if ( pNtkRes == NULL )
@@ -1664,9 +1680,10 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: collapse [-B num] [-dh]\n" );
+ fprintf( pErr, "usage: collapse [-B num] [-rdh]\n" );
fprintf( pErr, "\t collapses the network by constructing global BDDs\n" );
fprintf( pErr, "\t-B num : limit on live BDD nodes during collapsing [default = %d]\n", fBddSizeMax );
+ fprintf( pErr, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" );
fprintf( pErr, "\t-d : toggles dual-rail collapsing mode [default = %s]\n", fDualRail? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@@ -2759,6 +2776,102 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRr( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c, Window;
+ int nFaninLevels;
+ int nFanoutLevels;
+ int fUseFanouts;
+ int fVerbose;
+ extern int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFanouts, int fVerbose );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nFaninLevels = 3;
+ nFanoutLevels = 3;
+ fUseFanouts = 0;
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Wfvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'W':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-W\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Window = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Window < 0 )
+ goto usage;
+ nFaninLevels = Window / 10;
+ nFanoutLevels = Window % 10;
+ break;
+ case 'f':
+ fUseFanouts ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command can only be applied to an AIG (run \"strash\").\n" );
+ return 1;
+ }
+ if ( Abc_NtkGetChoiceNum(pNtk) )
+ {
+ fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
+ return 1;
+ }
+
+ // modify the current network
+ if ( !Abc_NtkRR( pNtk, nFaninLevels, nFanoutLevels, fUseFanouts, fVerbose ) )
+ {
+ fprintf( pErr, "Redundancy removal has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: rr [-W NM] [-fvh]\n" );
+ fprintf( pErr, "\t performs redundancy removal in the current network\n" );
+ fprintf( pErr, "\t-W NM : window size as the number of TFI (N) and TFO (M) logic levels [default = %d%d]\n", nFaninLevels, nFanoutLevels );
+ fprintf( pErr, "\t-f : toggle RR w.r.t. fanouts [default = %s]\n", fUseFanouts? "yes": "no" );
+ fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
/**Function*************************************************************
@@ -3806,10 +3919,12 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
pParams->fTruth = 0; // compute truth tables
pParams->fFilter = 1; // filter dominated cuts
pParams->fDrop = 0; // drop cuts on the fly
- pParams->fMulti = 0; // use multi-input AND-gates
+ pParams->fDag = 0; // compute DAG cuts
+ pParams->fTree = 0; // compute tree cuts
+ pParams->fFancy = 0; // compute something fancy
pParams->fVerbose = 0; // the verbosiness flag
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdmvoh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyzvoh" ) ) != EOF )
{
switch ( c )
{
@@ -3844,8 +3959,14 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
pParams->fDrop ^= 1;
break;
- case 'm':
- pParams->fMulti ^= 1;
+ case 'x':
+ pParams->fDag ^= 1;
+ break;
+ case 'y':
+ pParams->fTree ^= 1;
+ break;
+ case 'z':
+ pParams->fFancy ^= 1;
break;
case 'v':
pParams->fVerbose ^= 1;
@@ -3875,6 +3996,11 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Can only compute the cuts for %d <= K <= %d.\n", CUT_SIZE_MIN, CUT_SIZE_MAX );
return 1;
}
+ if ( pParams->fDag && pParams->fTree )
+ {
+ fprintf( pErr, "Cannot compute both DAG cuts and tree cuts at the same time.\n" );
+ return 1;
+ }
if ( fOracle )
pParams->fRecord = 1;
@@ -3891,14 +4017,16 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdmvh]\n" );
+ fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzvh]\n" );
fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" );
fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );
fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax );
fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
fprintf( pErr, "\t-f : toggle filtering of duplicated/dominated [default = %s]\n", pParams->fFilter? "yes": "no" );
fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
- fprintf( pErr, "\t-m : toggle computing only factor-cuts [default = %s]\n", pParams->fMulti? "yes": "no" );
+ fprintf( pErr, "\t-x : toggle computing only DAG cuts [default = %s]\n", pParams->fDag? "yes": "no" );
+ fprintf( pErr, "\t-y : toggle computing only tree cuts [default = %s]\n", pParams->fTree? "yes": "no" );
+ fprintf( pErr, "\t-z : toggle fancy computations [default = %s]\n", pParams->fFancy? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@@ -4160,6 +4288,99 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int nVars;
+ int fAdder;
+ int fSorter;
+ int fVerbose;
+ char * FileName;
+ extern void Abc_GenAdder( char * pFileName, int nVars );
+ extern void Abc_GenSorter( char * pFileName, int nVars );
+
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nVars = 8;
+ fAdder = 0;
+ fSorter = 0;
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Nasvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nVars = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nVars < 0 )
+ goto usage;
+ break;
+ case 'a':
+ fAdder ^= 1;
+ break;
+ case 's':
+ fSorter ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != globalUtilOptind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[globalUtilOptind];
+ if ( fAdder )
+ Abc_GenAdder( FileName, nVars );
+ else if ( fSorter )
+ Abc_GenSorter( FileName, nVars );
+ else
+ printf( "Type of circuit is not specified.\n" );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: gen [-N] [-asvh] <file>\n" );
+ fprintf( pErr, "\t generates simple circuits\n" );
+ fprintf( pErr, "\t-N num : the number of variables [default = %d]\n", nVars );
+ fprintf( pErr, "\t-a : toggle ripple-carry adder [default = %s]\n", fAdder? "yes": "no" );
+ fprintf( pErr, "\t-s : toggle simple sorter [default = %s]\n", fSorter? "yes": "no" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\t<file> : output file name\n");
+ return 1;
+}
+
/**Function*************************************************************
@@ -4175,7 +4396,7 @@ usage:
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtkRes;
+ Abc_Ntk_t * pNtk;//, * pNtkRes;
int c;
// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk );
@@ -4195,25 +4416,27 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+/*
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
-
if ( Abc_NtkIsSeq(pNtk) )
{
fprintf( pErr, "Only works for non-sequential networks.\n" );
return 1;
}
+*/
// Abc_NtkTestEsop( pNtk );
// Abc_NtkTestSop( pNtk );
// printf( "This command is currently not used.\n" );
// run the command
// pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 );
-
// pNtkRes = Abc_NtkNewAig( pNtk );
+
+/*
pNtkRes = NULL;
if ( pNtkRes == NULL )
{
@@ -4222,6 +4445,14 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+*/
+
+// if ( Cut_CellIsRunning() )
+// Cut_CellDumpToFile();
+// else
+// Cut_CellPrecompute();
+ Cut_CellLoad();
+
return 0;
usage:
@@ -6459,6 +6690,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk;
int c;
int RetValue;
+ int fJFront;
int fVerbose;
int nConfLimit;
int nImpLimit;
@@ -6469,11 +6701,12 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fJFront = 0;
fVerbose = 0;
nConfLimit = 100000;
nImpLimit = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CIvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CIvjh" ) ) != EOF )
{
switch ( c )
{
@@ -6499,6 +6732,9 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nImpLimit < 0 )
goto usage;
break;
+ case 'j':
+ fJFront ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -6528,13 +6764,13 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
clk = clock();
if ( Abc_NtkIsStrash(pNtk) )
{
- RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fVerbose );
+ RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fJFront, fVerbose );
}
else
{
Abc_Ntk_t * pTemp;
pTemp = Abc_NtkStrash( pNtk, 0, 0 );
- RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fVerbose );
+ RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fJFront, fVerbose );
pNtk->pModel = pTemp->pModel; pTemp->pModel = NULL;
Abc_NtkDelete( pTemp );
}
@@ -6544,7 +6780,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pNtk, pNtk->pModel );
if ( pSimInfo[0] != 1 )
- printf( "ERROR in Abc_NtkMiterProve(): Generated counter example is invalid.\n" );
+ printf( "ERROR in Abc_NtkMiterSat(): Generated counter example is invalid.\n" );
free( pSimInfo );
}
@@ -6559,11 +6795,12 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: sat [-C num] [-I num] [-vh]\n" );
+ fprintf( pErr, "usage: sat [-C num] [-I num] [-jvh]\n" );
fprintf( pErr, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
fprintf( pErr, "\t derives CNF from the current network and leave it unchanged\n" );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
+ fprintf( pErr, "\t-j : toggle the use of J-frontier [default = %s]\n", fJFront? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@@ -6584,60 +6821,72 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkTemp;
- int c;
- int RetValue;
- int fVerbose;
- int fRewrite;
- int fFraig;
- int nConfLimit;
- int nImpLimit;
- int clk;
+ Prove_Params_t Params, * pParams = &Params;
+ int c, clk, RetValue;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
- fVerbose = 0;
- fRewrite = 1;
- fFraig = 1;
- nConfLimit = 300000;
- nImpLimit = 0;
+ Prove_ParamsSetDefault( pParams );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CIrfvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLrfvh" ) ) != EOF )
{
switch ( c )
{
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nItersMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pParams->nItersMax < 0 )
+ goto usage;
+ break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
- nConfLimit = atoi(argv[globalUtilOptind]);
+ pParams->nMiteringLimitStart = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nConfLimit < 0 )
+ if ( pParams->nMiteringLimitStart < 0 )
goto usage;
break;
- case 'I':
+ case 'F':
if ( globalUtilOptind >= argc )
{
- fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
+ fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
- nImpLimit = atoi(argv[globalUtilOptind]);
+ pParams->nFraigingLimitStart = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nImpLimit < 0 )
+ if ( pParams->nFraigingLimitStart < 0 )
+ goto usage;
+ break;
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nMiteringLimitLast = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pParams->nMiteringLimitLast < 0 )
goto usage;
break;
case 'r':
- fRewrite ^= 1;
+ pParams->fUseRewriting ^= 1;
break;
case 'f':
- fFraig ^= 1;
+ pParams->fUseFraiging ^= 1;
break;
case 'v':
- fVerbose ^= 1;
+ pParams->fVerbose ^= 1;
break;
case 'h':
goto usage;
@@ -6674,7 +6923,7 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
else
pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 );
- RetValue = Abc_NtkMiterProve( &pNtkTemp, nConfLimit, nImpLimit, fRewrite, fFraig, fVerbose );
+ RetValue = Abc_NtkMiterProve( &pNtkTemp, pParams );
// verify that the pattern is correct
if ( RetValue == 0 )
@@ -6699,19 +6948,143 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: prove [-C num] [-I num] [-rfvh]\n" );
+ fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-rfvh]\n" );
fprintf( pErr, "\t solves combinational miter by rewriting, FRAIGing, and SAT\n" );
fprintf( pErr, "\t replaces the current network by the cone modified by rewriting\n" );
- fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
- fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
- fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", fRewrite? "yes": "no" );
- fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", fFraig? "yes": "no" );
- fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax );
+ fprintf( pErr, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart );
+ fprintf( pErr, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart );
+ fprintf( pErr, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast );
+ fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" );
+ fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", pParams->fUseFraiging? "yes": "no" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandTraceStart( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command is applicable to AIGs.\n" );
+ return 1;
+ }
+
+ Abc_HManStart();
+ if ( !Abc_HManPopulate( pNtk ) )
+ {
+ fprintf( pErr, "Failed to start the tracing database.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: trace_start [-h]\n" );
+ fprintf( pErr, "\t starts verification tracing\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command is applicable to AIGs.\n" );
+ return 1;
+ }
+
+ if ( !Abc_HManIsRunning(pNtk) )
+ {
+ fprintf( pErr, "The tracing database is not available.\n" );
+ return 1;
+ }
+
+ if ( !Abc_HManVerify( 1, pNtk->Id ) )
+ fprintf( pErr, "Verification failed.\n" );
+ Abc_HManStop();
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: trace_check [-h]\n" );
+ fprintf( pErr, "\t checks the current network using verification trace\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcAuto.c b/src/base/abci/abcAuto.c
index fb818ff3..cc6e8913 100644
--- a/src/base/abci/abcAuto.c
+++ b/src/base/abci/abcAuto.c
@@ -51,7 +51,7 @@ void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose )
int nOutputs, nInputs, i;
// compute the global BDDs
- if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
+ if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return;
// get information about the network
diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c
index 919ea3b2..9e9212aa 100644
--- a/src/base/abci/abcBalance.c
+++ b/src/base/abci/abcBalance.c
@@ -29,6 +29,8 @@ static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode,
static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int Level, int fDuplicate, bool fSelective );
static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate, bool fSelective );
static void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk );
+static Vec_Ptr_t * Abc_NodeBalanceConeExor( Abc_Obj_t * pNode );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -227,6 +229,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
return pNodeOld->pCopy;
assert( Abc_ObjIsNode(pNodeOld) );
// get the implication supergate
+// Abc_NodeBalanceConeExor( pNodeOld );
vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate, fSelective );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
@@ -260,6 +263,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
assert( pNodeOld->pCopy == NULL );
// mark the old node with the new node
pNodeOld->pCopy = vSuper->pArray[0];
+ Abc_HManAddProto( pNodeOld->pCopy, pNodeOld );
vSuper->nSize = 0;
return pNodeOld->pCopy;
}
@@ -351,6 +355,65 @@ int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst,
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeBalanceConeExor_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst )
+{
+ int RetValue1, RetValue2, i;
+ // check if the node occurs in the same polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == pNode )
+ return 1;
+ // if the new node is complemented or a PI, another gate begins
+ if ( !fFirst && (!pNode->fExor || !Abc_ObjIsNode(pNode)) )
+ {
+ Vec_PtrPush( vSuper, pNode );
+ return 0;
+ }
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_ObjIsNode(pNode) );
+ assert( pNode->fExor );
+ // go through the branches
+ RetValue1 = Abc_NodeBalanceConeExor_rec( Abc_ObjFanin0(Abc_ObjFanin0(pNode)), vSuper, 0 );
+ RetValue2 = Abc_NodeBalanceConeExor_rec( Abc_ObjFanin1(Abc_ObjFanin0(pNode)), vSuper, 0 );
+ if ( RetValue1 == -1 || RetValue2 == -1 )
+ return -1;
+ // return 1 if at least one branch has a duplicate
+ return RetValue1 || RetValue2;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NodeBalanceConeExor( Abc_Obj_t * pNode )
+{
+ Vec_Ptr_t * vSuper;
+ if ( !pNode->fExor )
+ return NULL;
+ vSuper = Vec_PtrAlloc( 10 );
+ Abc_NodeBalanceConeExor_rec( pNode, vSuper, 1 );
+ printf( "%d ", Vec_PtrSize(vSuper) );
+ Vec_PtrFree( vSuper );
+ return NULL;
+}
+
/**Function*************************************************************
diff --git a/src/base/abci/abcClpBdd.c b/src/base/abci/abcClpBdd.c
index 84016436..eed18e1b 100644
--- a/src/base/abci/abcClpBdd.c
+++ b/src/base/abci/abcClpBdd.c
@@ -43,14 +43,14 @@ static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd,
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fVerbose )
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose )
{
Abc_Ntk_t * pNtkNew;
assert( Abc_NtkIsStrash(pNtk) );
// compute the global BDDs
- if ( Abc_NtkGlobalBdds(pNtk, fBddSizeMax, 0) == NULL )
+ if ( Abc_NtkGlobalBdds(pNtk, fBddSizeMax, 0, fReorder, fVerbose) == NULL )
return NULL;
if ( fVerbose )
printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );
diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c
index 2b1816c4..2752dc69 100644
--- a/src/base/abci/abcCut.c
+++ b/src/base/abci/abcCut.c
@@ -29,6 +29,9 @@
static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
+
+extern int nTotal, nGood, nEqual;
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -46,6 +49,7 @@ static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
***********************************************************************/
Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
{
+ ProgressBar * pProgress;
Cut_Man_t * p;
Abc_Obj_t * pObj, * pNode;
Vec_Ptr_t * vNodes;
@@ -56,6 +60,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
+ nTotal = nGood = nEqual = 0;
+
assert( Abc_NtkIsStrash(pNtk) );
// start the manager
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
@@ -69,6 +75,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
// compute cuts for internal nodes
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
vChoices = Vec_IntAlloc( 100 );
+ pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
// when we reached a CO, it is time to deallocate the cuts
@@ -81,8 +88,9 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
// compute the cuts to the internal node
- Abc_NodeGetCuts( p, pObj, pParams->fMulti );
+ Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
// consider dropping the fanins cuts
if ( pParams->fDrop )
{
@@ -98,11 +106,16 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
Cut_NodeUnionCuts( p, vChoices );
}
}
+ Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
Vec_IntFree( vChoices );
PRT( "Total", clock() - clk );
//Abc_NtkPrintCuts_( p, pNtk, 0 );
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
+
+ // temporary printout of stats
+ if ( nTotal )
+ printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
return p;
}
@@ -276,14 +289,14 @@ printf( "Converged after %d iterations.\n", nIters );
SeeAlso []
***********************************************************************/
-void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti )
+void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
{
void * pList;
if ( pList = Abc_NodeReadCuts( p, pObj ) )
return pList;
- Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fMulti );
- Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fMulti );
- return Abc_NodeGetCuts( p, pObj, fMulti );
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
+ return Abc_NodeGetCuts( p, pObj, fDag, fTree );
}
/**Function*************************************************************
@@ -297,14 +310,28 @@ void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti )
SeeAlso []
***********************************************************************/
-void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti )
+void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
{
-// int fTriv = (!fMulti) || pObj->fMarkB;
- int fTriv = (!fMulti) || (pObj->vFanouts.nSize > 1 && !Abc_NodeIsMuxControlType(pObj));
+ Abc_Obj_t * pFanin;
+ int fDagNode, fTriv, TreeCode = 0;
assert( Abc_NtkIsStrash(pObj->pNtk) );
assert( Abc_ObjFaninNum(pObj) == 2 );
+ // check if the node is a DAG node
+ fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
+ // increment the counter of DAG nodes
+ if ( fDagNode ) Cut_ManIncrementDagNodes( p );
+ // add the trivial cut if the node is a DAG node, or if we compute all cuts
+ fTriv = fDagNode || !fDag;
+ // check if fanins are DAG nodes
+ if ( fTree )
+ {
+ pFanin = Abc_ObjFanin0(pObj);
+ TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
+ pFanin = Abc_ObjFanin1(pObj);
+ TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
+ }
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
- Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv );
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
}
/**Function*************************************************************
diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c
index 18a85a04..79d2b729 100644
--- a/src/base/abci/abcDsd.c
+++ b/src/base/abci/abcDsd.c
@@ -60,7 +60,7 @@ Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool
assert( Abc_NtkIsStrash(pNtk) );
// perform FPGA mapping
- if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
+ if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return NULL;
if ( fVerbose )
printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );
diff --git a/src/base/abci/abcEspresso.c b/src/base/abci/abcEspresso.c
index 744169b5..ad43534d 100644
--- a/src/base/abci/abcEspresso.c
+++ b/src/base/abci/abcEspresso.c
@@ -54,7 +54,13 @@ void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose )
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkUnmap(pNtk);
else if ( Abc_NtkHasBdd(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
// minimize SOPs of all nodes
Abc_NtkForEachNode( pNtk, pNode, i )
if ( i ) Abc_NodeEspresso( pNode );
diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c
index 4aae6ba5..2f54dcee 100644
--- a/src/base/abci/abcFraig.c
+++ b/src/base/abci/abcFraig.c
@@ -684,7 +684,7 @@ int Abc_NtkFraigStore( Abc_Ntk_t * pNtk )
// set the number of networks stored
Abc_FrameSetNtkStoreSize( Abc_FrameReadNtkStoreSize() + 1 );
}
- printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
+// printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
return 1;
}
diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c
index b377da1d..a8e656ce 100644
--- a/src/base/abci/abcFxu.c
+++ b/src/base/abci/abcFxu.c
@@ -57,7 +57,13 @@ bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
if ( Abc_NtkIsMappedLogic(pNtk) )
Abc_NtkUnmap(pNtk);
else if ( Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return 0;
+ }
+ }
else
{ // to make sure the SOPs are SCC-free
// Abc_NtkSopToBdd(pNtk);
diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c
new file mode 100644
index 00000000..626e5e1e
--- /dev/null
+++ b/src/base/abci/abcGen.c
@@ -0,0 +1,261 @@
+/**CFile****************************************************************
+
+ FileName [abc_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+void Abc_WriteLayer( FILE * pFile, int nVars, int fSkip1 );
+void Abc_WriteComp( FILE * pFile );
+void Abc_WriteFullAdder( FILE * pFile );
+
+void Abc_GenAdder( char * pFileName, int nVars );
+void Abc_GenSorter( char * pFileName, int nVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_GenAdder( char * pFileName, int nVars )
+{
+ FILE * pFile;
+ int i;
+
+ assert( nVars > 0 );
+
+ pFile = fopen( pFileName, "w" );
+ fprintf( pFile, "# %d-bit ripple-carry adder generated by ABC on %s\n", nVars, Extra_TimeStamp() );
+ fprintf( pFile, ".model Adder%02d\n", nVars );
+
+ fprintf( pFile, ".inputs" );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " a%02d", i );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " b%02d", i );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, ".outputs" );
+ for ( i = 0; i <= nVars; i++ )
+ fprintf( pFile, " y%02d", i );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, ".names c\n" );
+ if ( nVars == 1 )
+ fprintf( pFile, ".subckt FA a=a00 b=b00 cin=c s=y00 cout=y01\n" );
+ else
+ {
+ fprintf( pFile, ".subckt FA a=a00 b=b00 cin=c s=y00 cout=%02d\n", 0 );
+ for ( i = 1; i < nVars-1; i++ )
+ fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=%02d s=y%02d cout=%02d\n", i, i, i-1, i, i );
+ fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=%02d s=y%02d cout=y%02d\n", i, i, i-1, i, i+1 );
+ }
+ fprintf( pFile, ".end\n" );
+ fprintf( pFile, "\n" );
+
+ Abc_WriteFullAdder( pFile );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_GenSorter( char * pFileName, int nVars )
+{
+ FILE * pFile;
+ int i, k, Counter, nDigits;
+
+ assert( nVars > 1 );
+
+ pFile = fopen( pFileName, "w" );
+ fprintf( pFile, "# %d-bit sorter generated by ABC on %s\n", nVars, Extra_TimeStamp() );
+ fprintf( pFile, ".model Sorter%02d\n", nVars );
+
+ fprintf( pFile, ".inputs" );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " x%02d", i );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, ".outputs" );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " y%02d", i );
+ fprintf( pFile, "\n" );
+
+ Counter = 0;
+ nDigits = Extra_Base10Log( (nVars-2)*nVars );
+ if ( nVars == 2 )
+ fprintf( pFile, ".subckt Comp a=x00 b=x01 x=y00 y=y01\n" );
+ else
+ {
+ fprintf( pFile, ".subckt Layer0" );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " x%02d=x%02d", k, k );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
+ fprintf( pFile, "\n" );
+ Counter -= nVars;
+ for ( i = 1; i < nVars-2; i++ )
+ {
+ fprintf( pFile, ".subckt Layer%d", (i&1) );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
+ fprintf( pFile, "\n" );
+ Counter -= nVars;
+ }
+ fprintf( pFile, ".subckt Layer%d", (i&1) );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, " y%02d=y%02d", k, k );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, ".end\n" );
+ fprintf( pFile, "\n" );
+
+ Abc_WriteLayer( pFile, nVars, 0 );
+ Abc_WriteLayer( pFile, nVars, 1 );
+ Abc_WriteComp( pFile );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_WriteLayer( FILE * pFile, int nVars, int fSkip1 )
+{
+ int i;
+ fprintf( pFile, ".model Layer%d\n", fSkip1 );
+ fprintf( pFile, ".inputs" );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " x%02d", i );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".outputs" );
+ for ( i = 0; i < nVars; i++ )
+ fprintf( pFile, " y%02d", i );
+ fprintf( pFile, "\n" );
+ if ( fSkip1 )
+ {
+ fprintf( pFile, ".names x00 y00\n" );
+ fprintf( pFile, "1 1\n" );
+ i = 1;
+ }
+ else
+ i = 0;
+ for ( ; i + 1 < nVars; i += 2 )
+ fprintf( pFile, ".subckt Comp a=x%02d b=x%02d x=y%02d y=y%02d\n", i, i+1, i, i+1 );
+ if ( i < nVars )
+ {
+ fprintf( pFile, ".names x%02d y%02d\n", i, i );
+ fprintf( pFile, "1 1\n" );
+ }
+ fprintf( pFile, ".end\n" );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_WriteComp( FILE * pFile )
+{
+ fprintf( pFile, ".model Comp\n" );
+ fprintf( pFile, ".inputs a b\n" );
+ fprintf( pFile, ".outputs x y\n" );
+ fprintf( pFile, ".names a b x\n" );
+ fprintf( pFile, "11 1\n" );
+ fprintf( pFile, ".names a b y\n" );
+ fprintf( pFile, "1- 1\n" );
+ fprintf( pFile, "-1 1\n" );
+ fprintf( pFile, ".end\n" );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_WriteFullAdder( FILE * pFile )
+{
+ fprintf( pFile, ".model FA\n" );
+ fprintf( pFile, ".inputs a b cin\n" );
+ fprintf( pFile, ".outputs s cout\n" );
+ fprintf( pFile, ".names a b k\n" );
+ fprintf( pFile, "10 1\n" );
+ fprintf( pFile, "01 1\n" );
+ fprintf( pFile, ".names k cin s\n" );
+ fprintf( pFile, "10 1\n" );
+ fprintf( pFile, "01 1\n" );
+ fprintf( pFile, ".names a b cin cout\n" );
+ fprintf( pFile, "11- 1\n" );
+ fprintf( pFile, "1-1 1\n" );
+ fprintf( pFile, "-11 1\n" );
+ fprintf( pFile, ".end\n" );
+ fprintf( pFile, "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c
index 25d9e30f..c579eb84 100644
--- a/src/base/abci/abcMap.c
+++ b/src/base/abci/abcMap.c
@@ -522,7 +522,11 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// duplicate the network
pNtkNew2 = Abc_NtkDup( pNtk );
pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1, 0 );
- Abc_NtkBddToSop( pNtkNew, 0 );
+ if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return NULL;
+ }
// set the old network to point to the new network
Abc_NtkForEachCi( pNtk, pNode, i )
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
index c0658d5e..87ea57f3 100644
--- a/src/base/abci/abcMiter.c
+++ b/src/base/abci/abcMiter.c
@@ -282,7 +282,129 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
+/**Function*************************************************************
+
+ Synopsis [Derives the AND of two miters.]
+
+ Description [The network should have the same names of PIs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ char Buffer[100];
+ Abc_Ntk_t * pNtkMiter;
+ Abc_Obj_t * pOutput1, * pOutput2;
+ Abc_Obj_t * pRoot1, * pRoot2, * pMiter;
+
+ assert( Abc_NtkIsStrash(pNtk1) );
+ assert( Abc_NtkIsStrash(pNtk2) );
+ assert( 1 == Abc_NtkCoNum(pNtk1) );
+ assert( 1 == Abc_NtkCoNum(pNtk2) );
+ assert( 0 == Abc_NtkLatchNum(pNtk1) );
+ assert( 0 == Abc_NtkLatchNum(pNtk2) );
+ assert( Abc_NtkCiNum(pNtk1) == Abc_NtkCiNum(pNtk2) );
+
+ // start the new network
+ pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
+ sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName );
+ pNtkMiter->pName = Extra_UtilStrsav(Buffer);
+
+ // perform strashing
+ Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, 1 );
+ Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
+ Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
+// Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, 1 );
+ pRoot1 = Abc_NtkPo(pNtk1,0);
+ pRoot2 = Abc_NtkPo(pNtk2,0);
+ pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot1)->pCopy, Abc_ObjFaninC0(pRoot1) );
+ pOutput2 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot2)->pCopy, Abc_ObjFaninC0(pRoot2) );
+
+ // create the miter of the two outputs
+ pMiter = Abc_AigAnd( pNtkMiter->pManFunc, pOutput1, pOutput2 );
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
+
+ // make sure that everything is okay
+ if ( !Abc_NtkCheck( pNtkMiter ) )
+ {
+ printf( "Abc_NtkMiterAnd: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkMiter );
+ return NULL;
+ }
+ return pNtkMiter;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the cofactor of the miter w.r.t. the set of vars.]
+
+ Description [The array of variable values contains -1/0/1 for each PI.
+ -1 means this PI remains, 0/1 means this PI is set to 0/1.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues )
+{
+ char Buffer[100];
+ Abc_Ntk_t * pNtkMiter;
+ Abc_Obj_t * pRoot, * pOutput1;
+ int Value, i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( 1 == Abc_NtkCoNum(pNtk) );
+
+ // start the new network
+ pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
+ sprintf( Buffer, "%s_miter", pNtk->pName );
+ pNtkMiter->pName = Extra_UtilStrsav(Buffer);
+
+ // get the root output
+ pRoot = Abc_NtkCo( pNtk, 0 );
+
+ // perform strashing
+ Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
+ // set the first cofactor
+ Vec_IntForEachEntry( vPiValues, Value, i )
+ {
+ if ( Value == -1 )
+ continue;
+ if ( Value == 0 )
+ {
+ Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
+ continue;
+ }
+ if ( Value == 1 )
+ {
+ Abc_NtkCi(pNtk, i)->pCopy = Abc_NtkConst1(pNtkMiter);
+ continue;
+ }
+ assert( 0 );
+ }
+ // add the first cofactor
+ Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
+
+ // save the output
+ pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot)->pCopy, Abc_ObjFaninC0(pRoot) );
+
+ // create the miter of the two outputs
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pOutput1 );
+ // make sure that everything is okay
+ if ( !Abc_NtkCheck( pNtkMiter ) )
+ {
+ printf( "Abc_NtkMiterCofactor: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkMiter );
+ return NULL;
+ }
+ return pNtkMiter;
+}
/**Function*************************************************************
Synopsis [Derives the miter of two cofactors of one output.]
diff --git a/src/base/abci/abcNewAig.c b/src/base/abci/abcNewAig.c
index 209fc991..62ae51ed 100644
--- a/src/base/abci/abcNewAig.c
+++ b/src/base/abci/abcNewAig.c
@@ -65,7 +65,13 @@ Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk )
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
index d92da31b..33f432f4 100644
--- a/src/base/abci/abcNtbdd.c
+++ b/src/base/abci/abcNtbdd.c
@@ -27,7 +27,7 @@
static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node );
-static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax );
+static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax, ProgressBar * pProgress, int * pCounter, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -243,15 +243,14 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
SeeAlso []
***********************************************************************/
-DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly )
+DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly, int fReorder, int fVerbose )
{
- int fReorder = 1;
ProgressBar * pProgress;
Vec_Ptr_t * vFuncsGlob;
Abc_Obj_t * pNode;
DdNode * bFunc;
DdManager * dd;
- int i;
+ int i, Counter;
// start the manager
assert( pNtk->pManGlob == NULL );
@@ -269,18 +268,20 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
// collect the global functions of the COs
vFuncsGlob = Vec_PtrAlloc( 100 );
+ Counter = 0;
if ( fLatchOnly )
{
// construct the BDDs
- pProgress = Extra_ProgressBarStart( stdout, Abc_NtkLatchNum(pNtk) );
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pNode, i )
{
- Extra_ProgressBarUpdate( pProgress, i, NULL );
- bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax );
+// Extra_ProgressBarUpdate( pProgress, i, NULL );
+ bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax, pProgress, &Counter, fVerbose );
if ( bFunc == NULL )
{
+ if ( fVerbose )
printf( "Constructing global BDDs is aborted.\n" );
- Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vFuncsGlob );
Cudd_Quit( dd );
return NULL;
}
@@ -292,15 +293,16 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
else
{
// construct the BDDs
- pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
{
- Extra_ProgressBarUpdate( pProgress, i, NULL );
- bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax );
+// Extra_ProgressBarUpdate( pProgress, i, NULL );
+ bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax, pProgress, &Counter, fVerbose );
if ( bFunc == NULL )
{
+ if ( fVerbose )
printf( "Constructing global BDDs is aborted.\n" );
- Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vFuncsGlob );
Cudd_Quit( dd );
return NULL;
}
@@ -339,12 +341,14 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
SeeAlso []
***********************************************************************/
-DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax )
+DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax, ProgressBar * pProgress, int * pCounter, int fVerbose )
{
DdNode * bFunc, * bFunc0, * bFunc1;
assert( !Abc_ObjIsComplement(pNode) );
if ( Cudd_ReadKeys(dd)-Cudd_ReadDead(dd) > (unsigned)nBddSizeMax )
{
+ Extra_ProgressBarStop( pProgress );
+ if ( fVerbose )
printf( "The number of live nodes reached %d.\n", nBddSizeMax );
fflush( stdout );
return NULL;
@@ -353,11 +357,11 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize
if ( pNode->pCopy )
return (DdNode *)pNode->pCopy;
// compute the result for both branches
- bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0), nBddSizeMax );
+ bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0), nBddSizeMax, pProgress, pCounter, fVerbose );
if ( bFunc0 == NULL )
return NULL;
Cudd_Ref( bFunc0 );
- bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1), nBddSizeMax );
+ bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1), nBddSizeMax, pProgress, pCounter, fVerbose );
if ( bFunc1 == NULL )
return NULL;
Cudd_Ref( bFunc1 );
@@ -370,6 +374,9 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize
// set the result
assert( pNode->pCopy == NULL );
pNode->pCopy = (Abc_Obj_t *)bFunc;
+ // increment the progress bar
+ if ( pProgress )
+ Extra_ProgressBarUpdate( pProgress, (*pCounter)++, NULL );
return bFunc;
}
@@ -427,7 +434,7 @@ double Abc_NtkSpacePercentage( Abc_Obj_t * pNode )
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pCopy = (Abc_Obj_t *)dd->vars[i];
// build the BDD of the cone
- bFunc = Abc_NodeGlobalBdds_rec( dd, pNodeR, 10000000 ); Cudd_Ref( bFunc );
+ bFunc = Abc_NodeGlobalBdds_rec( dd, pNodeR, 10000000, NULL, NULL, 1 ); Cudd_Ref( bFunc );
bFunc = Cudd_NotCond( bFunc, pNode != pNodeR );
// count minterms
Result = Cudd_CountMinterm( dd, bFunc, dd->size );
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index d299a29d..56b70c5b 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -28,6 +28,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+//extern int s_TotalNodes = 0;
+//extern int s_TotalChanges = 0;
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -147,6 +150,11 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fclose( pTable );
}
*/
+/*
+ s_TotalNodes += Abc_NtkNodeNum(pNtk);
+ printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n",
+ s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges );
+*/
}
/**Function*************************************************************
@@ -644,7 +652,13 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary )
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
// get hold of the SOP of the node
CountConst = CountBuf = CountInv = CountAnd = CountOr = CountOther = CounterTotal = 0;
diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c
index ae4bb250..c0e904bf 100644
--- a/src/base/abci/abcProve.c
+++ b/src/base/abci/abcProve.c
@@ -20,6 +20,7 @@
#include "abc.h"
#include "fraig.h"
+#include "math.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -32,10 +33,11 @@ extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails );
static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-
+
/**Function*************************************************************
Synopsis [Attempts to solve the miter using a number of tricks.]
@@ -50,106 +52,126 @@ static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fV
SeeAlso []
***********************************************************************/
-int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, int nConfLimit, int nImpLimit, int fUseRewrite, int fUseFraig, int fVerbose )
+int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
{
+ Prove_Params_t * pParams = pPars;
Abc_Ntk_t * pNtk, * pNtkTemp;
- int nConfsStart = 1000, nImpsStart = 0, nBTLimitStart = 2; // was 5000
- int nConfs, nImps, nBTLimit, RetValue, nSatFails;
- int nIter = 0, clk, timeStart = clock();
+ int RetValue, nIter, Counter, clk, timeStart = clock();
// get the starting network
pNtk = *ppNtk;
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkPoNum(pNtk) == 1 );
- // set the initial limits
- nConfs = !nConfLimit? nConfsStart : ABC_MIN( nConfsStart, nConfLimit );
- nImps = !nImpLimit ? nImpsStart : ABC_MIN( nImpsStart , nImpLimit );
- nBTLimit = nBTLimitStart;
-
- if ( fVerbose )
- printf( "Global resource limits: ConfsLim = %6d. ImpsLim = %d.\n", nConfLimit, nImpLimit );
+ if ( pParams->fVerbose )
+ {
+ printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n",
+ pParams->nItersMax, pParams->fUseRewriting? "yes":"no", pParams->fUseFraiging? "yes":"no" );
+ printf( "Mitering = %d (%3.1f). Rewriting = %d (%3.1f). Fraiging = %d (%3.1f).\n",
+ pParams->nMiteringLimitStart, pParams->nMiteringLimitMulti,
+ pParams->nRewritingLimitStart, pParams->nRewritingLimitMulti,
+ pParams->nFraigingLimitStart, pParams->nFraigingLimitMulti );
+ printf( "Mitering last = %d.\n",
+ pParams->nMiteringLimitLast );
+ }
// if SAT only, solve without iteration
- if ( !fUseRewrite && !fUseFraig )
+ if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
{
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, 0 );
- Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
+ RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
+ Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
*ppNtk = pNtk;
return RetValue;
}
// check the current resource limits
- do {
- nIter++;
-
- if ( fVerbose )
+ for ( nIter = 0; nIter < pParams->nItersMax; nIter++ )
+ {
+ if ( pParams->fVerbose )
{
- printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter, nConfs, nBTLimit );
+ printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter+1,
+ (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)),
+ (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)) );
fflush( stdout );
}
// try brute-force SAT
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, nConfs, nImps, 0 );
- Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
+ RetValue = Abc_NtkMiterSat( pNtk, (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), 0, 0, 0 );
+ Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
if ( RetValue >= 0 )
break;
- if ( fUseRewrite )
+ // try rewriting
+ if ( pParams->fUseRewriting )
{
clk = clock();
-
- // try rewriting
- Abc_NtkRewrite( pNtk, 0, 0, 0 );
- if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
- break;
- Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
- if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
- break;
- pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
- if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
- break;
-
- Abc_NtkMiterPrint( pNtk, "Rewriting ", clk, fVerbose );
+ Counter = (int)(pParams->nRewritingLimitStart * pow(pParams->nRewritingLimitMulti,nIter));
+ while ( 1 )
+ {
+ Abc_NtkRewrite( pNtk, 0, 0, 0 );
+ if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
+ break;
+ if ( --Counter == 0 )
+ break;
+ Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
+ if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
+ break;
+ if ( --Counter == 0 )
+ break;
+ pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
+ if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
+ break;
+ if ( --Counter == 0 )
+ break;
+ }
+ Abc_NtkMiterPrint( pNtk, "Rewriting ", clk, pParams->fVerbose );
}
-
- if ( fUseFraig )
+
+ if ( pParams->fUseFraiging )
{
+ int nSatFails;
// try FRAIGing
clk = clock();
- pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, nBTLimit, &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp );
- Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, fVerbose );
+ pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp );
+ Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, pParams->fVerbose );
// printf( "NumFails = %d\n", nSatFails );
if ( RetValue >= 0 )
break;
}
- else
- nSatFails = 1000;
-
- // increase resource limits
-// nConfs = ABC_MIN( nConfs * 3 / 2, 1000000000 ); // was 4/2
- nConfs = nSatFails * nBTLimit / 2;
- nImps = ABC_MIN( nImps * 3 / 2, 1000000000 );
- nBTLimit = ABC_MIN( nBTLimit * 8, 1000000000 );
-
- // timeout at 5 minutes
-// if ( clock() - timeStart >= 1200 * CLOCKS_PER_SEC )
-// break;
- if ( nIter == 7 )
- break;
}
-// while ( (nConfLimit == 0 || nConfs <= nConfLimit) &&
-// (nImpLimit == 0 || nImps <= nImpLimit ) );
- while ( 1 );
// try to prove it using brute force SAT
+ if ( RetValue < 0 && pParams->fUseBdds )
+ {
+ if ( pParams->fVerbose )
+ {
+ printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit );
+ fflush( stdout );
+ }
+ clk = clock();
+ pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 );
+ if ( pNtk )
+ {
+ Abc_NtkDelete( pNtkTemp );
+ RetValue = ( (Abc_NtkNodeNum(pNtk) == 1) && (Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->pData == Cudd_ReadLogicZero(pNtk->pManFunc)) );
+ }
+ else
+ pNtk = pNtkTemp;
+ Abc_NtkMiterPrint( pNtk, "BDD building", clk, pParams->fVerbose );
+ }
+
if ( RetValue < 0 )
{
+ if ( pParams->fVerbose )
+ {
+ printf( "Attempting SAT with conflict limit %d ...\n", pParams->nMiteringLimitLast );
+ fflush( stdout );
+ }
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, 0 );
- Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
+ RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
+ Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
}
// assign the model if it was proved by rewriting (const 1 miter)
@@ -240,7 +262,8 @@ void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose
{
if ( !fVerbose )
return;
- printf( "Nodes = %7d. Levels = %4d. ", Abc_NtkNodeNum(pNtk), Abc_AigGetLevelNum(pNtk) );
+ printf( "Nodes = %7d. Levels = %4d. ", Abc_NtkNodeNum(pNtk),
+ Abc_NtkIsStrash(pNtk)? Abc_AigGetLevelNum(pNtk) : Abc_NtkGetLevelNum(pNtk) );
PRT( pString, clock() - clk );
}
diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c
index c968025f..9ea3ad71 100644
--- a/src/base/abci/abcRefactor.c
+++ b/src/base/abci/abcRefactor.c
@@ -132,6 +132,10 @@ clk = clock();
Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain );
pManRef->timeNtk += clock() - clk;
Dec_GraphFree( pFForm );
+// {
+// extern int s_TotalChanges;
+// s_TotalChanges++;
+// }
}
Extra_ProgressBarStop( pProgress );
pManRef->timeTotal = clock() - clkStart;
diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c
index 32e878b8..49208772 100644
--- a/src/base/abci/abcRestruct.c
+++ b/src/base/abci/abcRestruct.c
@@ -74,7 +74,7 @@ static Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, C
static Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCut );
static Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded );
-static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fMulti );
+static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag );
static Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose );
static void Abc_NtkManRstStop( Abc_ManRst_t * p );
static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
@@ -145,7 +145,7 @@ pManRst->timeCut += clock() - clk;
break;
// get the cuts for the given node
clk = clock();
- pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti );
+ pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 );
pManRst->timeCut += clock() - clk;
// perform restructuring
@@ -203,7 +203,7 @@ pManRst->timeTotal = clock() - clkStart;
***********************************************************************/
void Abc_RestructNodeDivisors( Abc_ManRst_t * p, Abc_Obj_t * pRoot, int nNodesSaved )
{
- Abc_Obj_t * pNode, * pFanin, * pFanout;
+ Abc_Obj_t * pNode, * pFanout;//, * pFanin;
int i, k;
// start with the leaves
Vec_PtrClear( p->vDecs );
@@ -276,7 +276,7 @@ Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_
{
Dec_Graph_t * pGraph;
Cut_Cut_t * pCut;
- int nCuts;
+// int nCuts;
p->nNodesConsidered++;
/*
// count the number of cuts with four inputs or more
@@ -949,7 +949,7 @@ Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd
SeeAlso []
***********************************************************************/
-Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fMulti )
+Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag )
{
static Cut_Params_t Params, * pParams = &Params;
Cut_Man_t * pManCut;
@@ -963,7 +963,8 @@ Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fM
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 0; // compute sequential cuts
pParams->fDrop = 0; // drop cuts on the fly
- pParams->fMulti = fMulti; // compute factor-cuts
+ pParams->fDag = fDag; // compute DAG cuts
+ pParams->fTree = 0; // compute tree cuts
pParams->fVerbose = 0; // the verbosiness flag
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
pManCut = Cut_ManStart( pParams );
@@ -1351,9 +1352,9 @@ Dec_Graph_t * Abc_NodeMffcSingleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int n
***********************************************************************/
Dec_Graph_t * Abc_NodeMffcDoubleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
{
- Dec_Graph_t * pGraph;
- unsigned uRoot, uNode;
- int i;
+// Dec_Graph_t * pGraph;
+// unsigned uRoot, uNode;
+// int i;
return NULL;
diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c
index 71a4466f..e9de4858 100644
--- a/src/base/abci/abcResub.c
+++ b/src/base/abci/abcResub.c
@@ -25,6 +25,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define ABC_RS_DIV1_MAX 150 // the max number of divisors to consider
+#define ABC_RS_DIV2_MAX 500 // the max number of pair-wise divisors to consider
+
typedef struct Abc_ManRes_t_ Abc_ManRes_t;
struct Abc_ManRes_t_
{
@@ -79,6 +82,7 @@ struct Abc_ManRes_t_
int nUsedNodeTotal;
int nTotalDivs;
int nTotalLeaves;
+ int nTotalGain;
};
// external procedures
@@ -90,8 +94,8 @@ static void Abc_ManResubPrint( Abc_ManRes_t * p );
// other procedures
static int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required );
-static int Abc_ManResubMffc( Abc_ManRes_t * p, Vec_Ptr_t * vDivs, Abc_Obj_t * pRoot, int nLeaves );
static void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords );
+static void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
static void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required );
static void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required );
@@ -136,13 +140,17 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd
// cleanup the AIG
Abc_AigCleanup(pNtk->pManFunc);
// start the managers
- pManCut = Abc_NtkManCutStart( nCutMax, 10000, 100000, 100000 );
- pManRes = Abc_ManResubStart( nCutMax, 200 );
+ pManCut = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 );
+ pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX );
// compute the reverse levels if level update is requested
if ( fUpdateLevel )
Abc_NtkStartReverseLevels( pNtk );
+ if ( Abc_NtkLatchNum(pNtk) )
+ Abc_NtkForEachLatch(pNtk, pNode, i)
+ pNode->pNext = pNode->pData;
+
// resynthesize each node once
nNodes = Abc_NtkObjNumMax(pNtk);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
@@ -179,13 +187,16 @@ clk = clock();
pManRes->timeRes += clock() - clk;
if ( pFForm == NULL )
continue;
+ pManRes->nTotalGain += pManRes->nLastGain;
/*
- if ( pNode->Id % 25 == 0 )
+ if ( pManRes->nLeaves == 4 && pManRes->nMffc == 2 && pManRes->nLastGain == 1 )
+ {
printf( "%6d : L = %2d. V = %2d. Mffc = %2d. Divs = %3d. Up = %3d. Un = %3d. B = %3d.\n",
pNode->Id, pManRes->nLeaves, Abc_CutVolumeCheck(pNode, vLeaves), pManRes->nMffc, pManRes->nDivs,
pManRes->vDivs1UP->nSize, pManRes->vDivs1UN->nSize, pManRes->vDivs1B->nSize );
+ Abc_ManResubPrintDivs( pManRes, pNode, vLeaves );
+ }
*/
-
// acceptable replacement found, update the graph
clk = clock();
Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRes->nLastGain );
@@ -207,6 +218,10 @@ pManRes->timeTotal = clock() - clkStart;
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->pData = NULL;
+ if ( Abc_NtkLatchNum(pNtk) )
+ Abc_NtkForEachLatch(pNtk, pNode, i)
+ pNode->pData = pNode->pNext, pNode->pNext = NULL;
+
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
@@ -340,6 +355,7 @@ void Abc_ManResubPrint( Abc_ManRes_t * p )
); PRT( "TOTAL ", p->timeTotal );
printf( "Total leaves = %8d.\n", p->nTotalLeaves );
printf( "Total divisors = %8d.\n", p->nTotalDivs );
+ printf( "Total gain = %8d.\n", p->nTotalGain );
}
@@ -382,7 +398,7 @@ void Abc_ManResubCollectDivs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vInternal )
***********************************************************************/
int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required )
{
- Abc_Obj_t * pNode, * pFanout;//, * pFanin;
+ Abc_Obj_t * pNode, * pFanout;
int i, k, Limit, Counter;
Vec_PtrClear( p->vDivs1UP );
@@ -451,10 +467,24 @@ Quits :
assert( pRoot == Vec_PtrEntryLast(p->vDivs) );
assert( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) <= Vec_PtrSize(p->vSims) - p->nLeavesMax );
+ return 1;
+}
-/*
-if (pRoot->Id == 15281 )
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves )
{
+ Abc_Obj_t * pFanin, * pNode;
+ int i, k;
// print the nodes
Vec_PtrForEachEntry( p->vDivs, pNode, i )
{
@@ -488,59 +518,7 @@ if (pRoot->Id == 15281 )
}
printf( "\n" );
}
-*/
- return 1;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_ManResubMffc( Abc_ManRes_t * p, Vec_Ptr_t * vDivs, Abc_Obj_t * pRoot, int nLeaves )
-{
- Abc_Obj_t * pObj;
- int Counter, i, k;
- // increment the traversal ID for the leaves
- // increment the fanout counters of the leaves
- Abc_NtkIncrementTravId( pRoot->pNtk );
- Vec_PtrForEachEntryStop( vDivs, pObj, i, nLeaves )
- {
- pObj->vFanouts.nSize++;
- Abc_NodeSetTravIdCurrent( pObj );
- }
- // make sure the node is in the cone and is no one of the leaves
- assert( Abc_NodeIsTravIdPrevious(pRoot) );
- Counter = Abc_NodeMffcLabel( pRoot );
- // remove the extra counters
- Vec_PtrForEachEntryStop( vDivs, pObj, i, nLeaves )
- pObj->vFanouts.nSize--;
-
- // sort the nodes by level!!!
-
- // move the labeled nodes to the end
- Vec_PtrClear( p->vTemp );
- k = nLeaves;
- Vec_PtrForEachEntryStart( vDivs, pObj, i, nLeaves )
- if ( Abc_NodeIsTravIdCurrent(pObj) )
- Vec_PtrPush( p->vTemp, pObj );
- else
- Vec_PtrWriteEntry( vDivs, k++, pObj );
- // add the labeled nodes
- Vec_PtrForEachEntry( p->vTemp, pObj, i )
- Vec_PtrWriteEntry( vDivs, k++, pObj );
- assert( k == Vec_PtrSize(p->vDivs) );
- assert( pRoot == Vec_PtrEntryLast(p->vDivs) );
- return Counter;
-}
/**Function*************************************************************
@@ -928,7 +906,7 @@ void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required )
puData1 = pObj1->pData;
- if ( Vec_PtrSize(p->vDivs2UP0) < 500 )
+ if ( Vec_PtrSize(p->vDivs2UP0) < ABC_RS_DIV2_MAX )
{
// get positive unate divisors
for ( w = 0; w < p->nWords; w++ )
@@ -965,7 +943,7 @@ void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required )
}
}
- if ( Vec_PtrSize(p->vDivs2UN0) < 500 )
+ if ( Vec_PtrSize(p->vDivs2UN0) < ABC_RS_DIV2_MAX )
{
// get negative unate divisors
for ( w = 0; w < p->nWords; w++ )
diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c
index f3360421..f11e5e9d 100644
--- a/src/base/abci/abcRewrite.c
+++ b/src/base/abci/abcRewrite.c
@@ -110,6 +110,10 @@ clk = clock();
Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
Rwr_ManAddTimeUpdate( pManRwr, clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
+// {
+// extern int s_TotalChanges;
+// s_TotalChanges++;
+// }
}
}
Extra_ProgressBarStop( pProgress );
diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c
new file mode 100644
index 00000000..3a6a29c9
--- /dev/null
+++ b/src/base/abci/abcRr.c
@@ -0,0 +1,601 @@
+/**CFile****************************************************************
+
+ FileName [abcRr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Redundancy removal.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Abc_RRMan_t_ Abc_RRMan_t;
+struct Abc_RRMan_t_
+{
+ // the parameters
+ Abc_Ntk_t * pNtk; // the network
+ int nFaninLevels; // the number of fanin levels
+ int nFanoutLevels; // the number of fanout levels
+ // the node/fanin/fanout
+ Abc_Obj_t * pNode; // the node
+ Abc_Obj_t * pFanin; // the fanin
+ Abc_Obj_t * pFanout; // the fanout
+ // the intermediate cones
+ Vec_Ptr_t * vFaninLeaves; // the leaves of the fanin cone
+ Vec_Ptr_t * vFanoutRoots; // the roots of the fanout cone
+ // the window
+ Vec_Ptr_t * vLeaves; // the leaves of the window
+ Vec_Ptr_t * vCone; // the internal nodes of the window
+ Vec_Ptr_t * vRoots; // the roots of the window
+ Abc_Ntk_t * pWnd; // the window derived for the edge
+ // the miter
+ Abc_Ntk_t * pMiter; // the miter derived from the window
+ Prove_Params_t * pParams; // the miter proving parameters
+};
+
+static Abc_RRMan_t * Abc_RRManStart();
+static void Abc_RRManStop( Abc_RRMan_t * p );
+static void Abc_RRManClean( Abc_RRMan_t * p );
+static int Abc_NtkRRProve( Abc_RRMan_t * p );
+static int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Abc_Obj_t * pFanout );
+static int Abc_NtkRRWindow( Abc_RRMan_t * p );
+
+static int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit );
+static int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout );
+static int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit );
+static void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
+static Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vRoots );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Removes stuck-at redundancies.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFanouts, int fVerbose )
+{
+ ProgressBar * pProgress;
+ Abc_RRMan_t * p;
+ Abc_Obj_t * pNode, * pFanin, * pFanout;
+ int i, k, m, nNodes;
+ // start the manager
+ p = Abc_RRManStart( nFaninLevels, nFanoutLevels );
+ p->pNtk = pNtk;
+ p->nFaninLevels = nFaninLevels;
+ p->nFanoutLevels = nFanoutLevels;
+ // go through the nodes
+ nNodes = Abc_NtkObjNumMax(pNtk);
+ pProgress = Extra_ProgressBarStart( stdout, nNodes );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // stop if all nodes have been tried once
+ if ( i >= nNodes )
+ break;
+ // skip the constant node
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // skip the nodes with many fanouts
+ if ( Abc_ObjFanoutNum(pNode) > 1000 )
+ continue;
+ // construct the window
+ if ( !fUseFanouts )
+ {
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ {
+ Abc_RRManClean( p );
+ p->pNode = pNode;
+ p->pFanin = pFanin;
+ p->pFanout = NULL;
+ if ( !Abc_NtkRRWindow( p ) )
+ continue;
+ if ( !Abc_NtkRRProve( p ) )
+ continue;
+ Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
+ break;
+ }
+ continue;
+ }
+ // use the fanouts
+ Abc_ObjForEachFanout( pNode, pFanout, m )
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ {
+ Abc_RRManClean( p );
+ p->pNode = pNode;
+ p->pFanin = pFanin;
+ p->pFanout = pFanout;
+ if ( !Abc_NtkRRWindow( p ) )
+ continue;
+ if ( !Abc_NtkRRProve( p ) )
+ continue;
+ Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
+ break;
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Abc_RRManStop( p );
+ // put the nodes into the DFS order and reassign their IDs
+ Abc_NtkReassignIds( pNtk );
+ Abc_NtkGetLevelNum( pNtk );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRR: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Start the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_RRMan_t * Abc_RRManStart()
+{
+ Abc_RRMan_t * p;
+ p = ALLOC( Abc_RRMan_t, 1 );
+ memset( p, 0, sizeof(Abc_RRMan_t) );
+ p->vFaninLeaves = Vec_PtrAlloc( 100 ); // the leaves of the fanin cone
+ p->vFanoutRoots = Vec_PtrAlloc( 100 ); // the roots of the fanout cone
+ p->vLeaves = Vec_PtrAlloc( 100 ); // the leaves of the window
+ p->vCone = Vec_PtrAlloc( 100 ); // the internal nodes of the window
+ p->vRoots = Vec_PtrAlloc( 100 ); // the roots of the window
+ p->pParams = ALLOC( Prove_Params_t, 1 );
+ memset( p->pParams, 0, sizeof(Prove_Params_t) );
+ Prove_ParamsSetDefault( p->pParams );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_RRManStop( Abc_RRMan_t * p )
+{
+ Abc_RRManClean( p );
+ Vec_PtrFree( p->vFaninLeaves );
+ Vec_PtrFree( p->vFanoutRoots );
+ Vec_PtrFree( p->vLeaves );
+ Vec_PtrFree( p->vCone );
+ Vec_PtrFree( p->vRoots );
+ free( p->pParams );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Clean the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_RRManClean( Abc_RRMan_t * p )
+{
+ p->pNode = NULL;
+ p->pFanin = NULL;
+ p->pFanout = NULL;
+ Vec_PtrClear( p->vFaninLeaves );
+ Vec_PtrClear( p->vFanoutRoots );
+ Vec_PtrClear( p->vLeaves );
+ Vec_PtrClear( p->vCone );
+ Vec_PtrClear( p->vRoots );
+ if ( p->pWnd ) Abc_NtkDelete( p->pWnd );
+ if ( p->pMiter ) Abc_NtkDelete( p->pMiter );
+ p->pWnd = NULL;
+ p->pMiter = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the miter is constant 0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRProve( Abc_RRMan_t * p )
+{
+ Abc_Ntk_t * pWndCopy;
+ int RetValue;
+ pWndCopy = Abc_NtkDup( p->pWnd );
+ Abc_NtkRRUpdate( pWndCopy, p->pNode->pCopy, p->pFanin->pCopy, p->pFanout? p->pFanout->pCopy : NULL );
+ p->pMiter = Abc_NtkMiter( p->pWnd, pWndCopy, 1 );
+ RetValue = Abc_NtkMiterProve( &p->pMiter, p->pParams );
+ if ( RetValue == 1 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the network after redundancy removal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Abc_Obj_t * pFanout )
+{
+ Abc_Obj_t * pNodeNew, * pFanoutNew;
+ assert( pFanout == NULL );
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( !Abc_ObjIsComplement(pFanin) );
+ assert( !Abc_ObjIsComplement(pFanout) );
+ // find the node after redundancy removal
+ if ( pFanin == Abc_ObjFanin0(pNode) )
+ pNodeNew = Abc_ObjChild1(pNode);
+ else if ( pFanin == Abc_ObjFanin1(pNode) )
+ pNodeNew = Abc_ObjChild0(pNode);
+ else assert( 0 );
+ // replace
+ if ( pFanout == NULL )
+ {
+ Abc_AigReplace( pNtk->pManFunc, pNode, pNodeNew, 0 );
+ return 1;
+ }
+ // find the fanout after redundancy removal
+ if ( pNode == Abc_ObjFanin0(pFanout) )
+ pFanoutNew = Abc_AigAnd( pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC0(pFanout)), Abc_ObjChild1(pFanout) );
+ else if ( pNode == Abc_ObjFanin1(pFanout) )
+ pFanoutNew = Abc_AigAnd( pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC1(pFanout)), Abc_ObjChild0(pFanout) );
+ else assert( 0 );
+ // replace
+ Abc_AigReplace( pNtk->pManFunc, pFanout, pFanoutNew, 0 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs window for checking RR.]
+
+ Description [If the window (p->pWnd) with the given scope (p->nFaninLevels,
+ p->nFanoutLevels) cannot be constructed, returns 0. Otherwise, returns 1.
+ The levels are measured from the fanin node (pFanin) and the fanout node
+ (pEdgeFanout), respectively.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRWindow( Abc_RRMan_t * p )
+{
+ Abc_Obj_t * pObj, * pFanout, * pEdgeFanin, * pEdgeFanout;
+ int i, k;
+
+ // get the edge
+ pEdgeFanout = p->pFanout? p->pFanout : p->pNode;
+ pEdgeFanin = p->pFanout? p->pNode : p->pFanin;
+
+ // start the TFI leaves with the fanin
+ Abc_NtkIncrementTravId( p->pNtk );
+ Abc_NodeSetTravIdCurrent( p->pFanin );
+ Vec_PtrPush( p->vFaninLeaves, p->pFanin );
+ // mark the TFI cone and collect the leaves down to the given level
+ while ( Abc_NtkRRTfi_int(p->vFaninLeaves, p->pFanin->Level - p->nFaninLevels) );
+
+ // collect the TFO cone of the leaves
+ Abc_NtkIncrementTravId( p->pNtk );
+ Vec_PtrForEachEntry( p->vFaninLeaves, pObj, i )
+ {
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ {
+ if ( !Abc_ObjIsNode(pFanout) )
+ continue;
+ if ( pFanout->Level > pEdgeFanout->Level + p->nFanoutLevels )
+ continue;
+ if ( Abc_NodeIsTravIdCurrent(pFanout) )
+ continue;
+ Abc_NodeSetTravIdCurrent( pFanout );
+ Vec_PtrPush( p->vFanoutRoots, pFanout );
+ }
+ }
+ // mark the TFO cone and collect the leaves up to the given level (while skipping the edge)
+ while ( Abc_NtkRRTfo_int(p->vFanoutRoots, pEdgeFanout->Level + p->nFanoutLevels, pEdgeFanin, pEdgeFanout) );
+ // unmark the nodes
+ Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
+ pObj->fMarkA = 0;
+
+ // mark the current roots
+ Abc_NtkIncrementTravId( p->pNtk );
+ Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
+ Abc_NodeSetTravIdCurrent( pObj );
+ // collect roots reachable from the fanout (p->vRoots)
+ if ( !Abc_NtkRRTfo_rec( pEdgeFanout, p->vRoots, pEdgeFanout->Level + p->nFanoutLevels + 5 ) )
+ return 0;
+
+ // collect the DFS-ordered new cone (p->vCone) and new leaves (p->vLeaves)
+ // using the previous marks coming from the TFO cone
+ Vec_PtrForEachEntry( p->vRoots, pObj, i )
+ Abc_NtkRRTfi_rec( pObj, p->vLeaves, p->vCone );
+ // unmark the nodes
+ Vec_PtrForEachEntry( p->vCone, pObj, i )
+ pObj->fMarkA = 0;
+ Vec_PtrForEachEntry( p->vLeaves, pObj, i )
+ pObj->fMarkA = 0;
+
+ // create a new network
+ p->pWnd = Abc_NtkWindow( p->pNtk, p->vLeaves, p->vCone, p->vRoots );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the nodes in the TFI and collects their leaves.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit )
+{
+ Abc_Obj_t * pObj, * pNext;
+ int i, k, LevelMax, nSize;
+ // find the maximum level of leaves
+ LevelMax = 0;
+ Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
+ if ( LevelMax < (int)pObj->Level )
+ LevelMax = pObj->Level;
+ // if the nodes are all PIs, LevelMax == 0
+ if ( LevelMax == 0 || LevelMax <= LevelLimit )
+ return 0;
+ // expand the nodes with the minimum level
+ nSize = Vec_PtrSize(vFaninLeaves);
+ Vec_PtrForEachEntryStop( vFaninLeaves, pObj, i, nSize )
+ {
+ if ( LevelMax != (int)pObj->Level )
+ continue;
+ Abc_ObjForEachFanin( pObj, pNext, k )
+ {
+ if ( Abc_NodeIsTravIdCurrent(pNext) )
+ continue;
+ Abc_NodeSetTravIdCurrent( pNext );
+ Vec_PtrPush( vFaninLeaves, pNext );
+ }
+ }
+ // remove old nodes (cannot remove a PI)
+ k = 0;
+ Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
+ {
+ if ( LevelMax == (int)pObj->Level )
+ continue;
+ Vec_PtrWriteEntry( vFaninLeaves, k++, pObj );
+ }
+ Vec_PtrShrink( vFaninLeaves, k );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the nodes in the TFO and collects their roots.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout )
+{
+ Abc_Obj_t * pObj, * pNext;
+ int i, k, LevelMin, nSize;
+ // find the minimum level of roots
+ LevelMin = ABC_INFINITY;
+ Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
+ if ( Abc_ObjIsNode(pObj) && !pObj->fMarkA && LevelMin > (int)pObj->Level )
+ LevelMin = pObj->Level;
+ // if the nodes are all POs, LevelMin == ABC_INFINITY
+ if ( LevelMin == ABC_INFINITY || LevelMin > LevelLimit )
+ return 0;
+ // expand the nodes with the minimum level
+ nSize = Vec_PtrSize(vFanoutRoots);
+ Vec_PtrForEachEntryStop( vFanoutRoots, pObj, i, nSize )
+ {
+ if ( LevelMin != (int)pObj->Level )
+ continue;
+ Abc_ObjForEachFanout( pObj, pNext, k )
+ {
+ if ( !Abc_ObjIsNode(pNext) || pNext->Level > (unsigned)LevelLimit )
+ {
+ pObj->fMarkA = 1;
+ continue;
+ }
+ if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
+ continue;
+ if ( Abc_NodeIsTravIdCurrent(pNext) )
+ continue;
+ Abc_NodeSetTravIdCurrent( pNext );
+ Vec_PtrPush( vFanoutRoots, pNext );
+ }
+ }
+ // remove old nodes
+ k = 0;
+ Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
+ {
+ if ( LevelMin == (int)pObj->Level )
+ {
+ // check if the node has external fanouts
+ Abc_ObjForEachFanout( pObj, pNext, k )
+ {
+ if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
+ continue;
+ if ( !Abc_NodeIsTravIdCurrent(pNext) )
+ break;
+ }
+ // if external fanout is found, do not remove the node
+ if ( pNext )
+ continue;
+ }
+ Vec_PtrWriteEntry( vFanoutRoots, k++, pObj );
+ }
+ Vec_PtrShrink( vFanoutRoots, k );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the roots in the TFO of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ if ( Abc_ObjIsCo(pNode) || pNode->Level > (unsigned)LevelLimit )
+ return 0;
+ if ( Abc_NodeIsTravIdCurrent(pNode) )
+ {
+ Vec_PtrPushUnique( vRoots, pNode );
+ return 1;
+ }
+ Abc_NodeSetTravIdCurrent( pNode );
+ Abc_ObjForEachFanout( pNode, pFanout, i )
+ if ( !Abc_NtkRRTfo_rec( pFanout, vRoots, LevelLimit ) )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ // skip visited nodes
+ if ( pNode->fMarkA )
+ return;
+ pNode->fMarkA = 1;
+ // add the node if it was not visited in the previus run
+ if ( !Abc_NodeIsTravIdPrevious(pNode) )
+ {
+ Vec_PtrPush( vLeaves, pNode );
+ return;
+ }
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ Abc_NtkRRTfi_rec( pFanin, vLeaves, vCone );
+ Vec_PtrPush( vCone, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vRoots )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the network
+ pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc );
+ // duplicate the name and the spec
+ pNtkNew->pName = Extra_UtilStrsav( "temp" );
+ // map the constant nodes
+ if ( Abc_NtkConst1(pNtk) )
+ Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
+ // create and map the PIs
+ Vec_PtrForEachEntry( vLeaves, pObj, i )
+ pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
+ // copy the AND gates
+ Vec_PtrForEachEntry( vCone, pObj, i )
+ pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
+ // compare the number of nodes before and after
+ if ( Vec_PtrSize(vCone) != Abc_NtkNodeNum(pNtkNew) )
+ printf( "Warning: Structural hashing during windowing reduced %d nodes (this is a bug).\n",
+ Vec_PtrSize(vCone) - Abc_NtkNodeNum(pNtkNew) );
+ // create the POs
+ Vec_PtrForEachEntry( vRoots, pObj, i )
+ Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObj->pCopy );
+ // add the PI/PO names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ // check
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkWindow: The network check has failed.\n" );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c
index f7400313..9348231b 100644
--- a/src/base/abci/abcSat.c
+++ b/src/base/abci/abcSat.c
@@ -24,7 +24,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
+extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
static nMuxes;
////////////////////////////////////////////////////////////////////////
@@ -42,7 +42,7 @@ static nMuxes;
SeeAlso []
***********************************************************************/
-int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbose )
+int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose )
{
solver * pSat;
lbool status;
@@ -56,7 +56,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbo
// load clauses into the solver
clk = clock();
- pSat = Abc_NtkMiterSatCreate( pNtk );
+ pSat = Abc_NtkMiterSatCreate( pNtk, fJFront );
if ( pSat == NULL )
return 1;
// printf( "Created SAT problem with %d variable and %d clauses. ", solver_nvars(pSat), solver_nclauses(pSat) );
@@ -107,6 +107,8 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbo
Vec_IntFree( vCiIds );
}
// free the solver
+ if ( fVerbose )
+ Asat_SatPrintStats( stdout, pSat );
solver_delete( pSat );
return RetValue;
}
@@ -391,12 +393,14 @@ void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNo
SeeAlso []
***********************************************************************/
-int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
+int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
{
Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
Vec_Ptr_t * vNodes, * vSuper;
- Vec_Int_t * vVars;
+ Vec_Int_t * vVars, * vFanio;
+ Vec_Vec_t * vCircuit;
int i, k, fUseMuxes = 1;
+ int clk1 = clock(), clk;
assert( Abc_NtkIsStrash(pNtk) );
@@ -408,6 +412,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
+ if ( fJFront )
+ vCircuit = Vec_VecAlloc( 1000 );
+// vCircuit = Vec_VecStart( 184 );
// add the clause for the constant node
pNode = Abc_NtkConst1(pNtk);
@@ -485,6 +492,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
if ( vSuper->nSize == 0 )
{
if ( !Abc_NtkClauseTriv( pSat, Abc_ObjNot(pNode), vVars ) )
+// if ( !Abc_NtkClauseTriv( pSat, pNode, vVars ) )
return 0;
}
else
@@ -493,6 +501,32 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
return 0;
}
}
+ // add the variables to the J-frontier
+ if ( !fJFront )
+ continue;
+ // make sure that the fanin entries go first
+ assert( pNode->pCopy );
+ Vec_VecExpand( vCircuit, (int)pNode->pCopy );
+ vFanio = Vec_VecEntry( vCircuit, (int)pNode->pCopy );
+ Vec_PtrForEachEntryReverse( vSuper, pFanin, k )
+// Vec_PtrForEachEntry( vSuper, pFanin, k )
+ {
+ pFanin = Abc_ObjRegular( pFanin );
+ assert( pFanin->pCopy && pFanin->pCopy != pNode->pCopy );
+ Vec_IntPushFirst( vFanio, (int)pFanin->pCopy );
+ Vec_VecPush( vCircuit, (int)pFanin->pCopy, pNode->pCopy );
+ }
+ }
+
+ // create the variable order
+ if ( fJFront )
+ {
+ clk = clock();
+ Asat_JManStart( pSat, vCircuit );
+ Vec_VecFree( vCircuit );
+ PRT( "Setup", clock() - clk );
+// Asat_JManStop( pSat );
+// PRT( "Total", clock() - clk1 );
}
// delete
@@ -513,7 +547,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
+solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront )
{
solver * pSat;
Abc_Obj_t * pNode;
@@ -522,7 +556,7 @@ solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
nMuxes = 0;
pSat = solver_new();
- RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk );
+ RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk, fJFront );
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->fMarkA = 0;
// Asat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );
diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c
index fbaca324..cfbd4694 100644
--- a/src/base/abci/abcStrash.c
+++ b/src/base/abci/abcStrash.c
@@ -58,7 +58,13 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return NULL;
+ }
+ }
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
@@ -72,7 +78,9 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
- printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
+ {
+// printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
+ }
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
@@ -108,7 +116,13 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
assert( Abc_NtkIsStrash(pNtk1) );
assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
if ( Abc_NtkIsBddLogic(pNtk2) )
- Abc_NtkBddToSop(pNtk2, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk2, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return 0;
+ }
+ }
// check that the networks have the same PIs
// reorder PIs of pNtk2 according to pNtk1
if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) )
@@ -163,6 +177,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes
assert( pObj->pCopy == NULL );
// mark the old object with the new AIG node
pObj->pCopy = pNodeNew;
+ Abc_HManAddProto( pObj->pCopy, pObj );
}
Vec_PtrFree( vNodes );
Extra_ProgressBarStop( pProgress );
diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c
index 35cf896f..fad3bd92 100644
--- a/src/base/abci/abcSymm.c
+++ b/src/base/abci/abcSymm.c
@@ -88,7 +88,7 @@ void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
// compute the global functions
clk = clock();
- dd = Abc_NtkGlobalBdds( pNtk, 10000000, 0 );
+ dd = Abc_NtkGlobalBdds( pNtk, 10000000, 0, 1, fVerbose );
Cudd_AutodynDisable( dd );
Cudd_zddVarsFromBddVars( dd, 2 );
clkBdd = clock() - clk;
diff --git a/src/base/abci/abcTrace.c b/src/base/abci/abcTrace.c
new file mode 100644
index 00000000..0275c0a1
--- /dev/null
+++ b/src/base/abci/abcTrace.c
@@ -0,0 +1,804 @@
+/**CFile****************************************************************
+
+ FileName [abcHistory.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcHistory.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define ABC_SIM_VARS 16 // the max number of variables in the cone
+#define ABC_SIM_OBJS 200 // the max number of objects in the cone
+
+typedef struct Abc_HMan_t_ Abc_HMan_t;
+typedef struct Abc_HObj_t_ Abc_HObj_t;
+typedef struct Abc_HNum_t_ Abc_HNum_t;
+
+struct Abc_HNum_t_
+{
+ unsigned fCompl : 1; // set to 1 if the node is complemented
+ unsigned NtkId : 6; // the network ID
+ unsigned ObjId : 24; // the node ID
+};
+
+struct Abc_HObj_t_
+{
+ // object info
+ unsigned fProof : 1; // set to 1 if the node is proved
+ unsigned fPhase : 1; // set to 1 if the node's phase differs from Old
+ unsigned fPi : 1; // the node is a PI
+ unsigned fPo : 1; // the node is a PO
+ unsigned fConst : 1; // the node is a constant
+ unsigned fVisited: 1; // the flag shows if the node is visited
+ unsigned NtkId : 10; // the network ID
+ unsigned Num : 16; // a temporary number
+ // history record
+ Abc_HNum_t Fan0; // immediate fanin
+ Abc_HNum_t Fan1; // immediate fanin
+ Abc_HNum_t Proto; // old node if present
+// Abc_HNum_t Equ; // equiv node if present
+};
+
+struct Abc_HMan_t_
+{
+ // storage for history information
+ Vec_Vec_t * vNtks; // the history nodes belonging to each network
+ Vec_Int_t * vProof; // flags showing if the network is proved
+ // storage for simulation info
+ int nVarsMax; // the max number of cone leaves
+ int nObjsMax; // the max number of cone nodes
+ Vec_Ptr_t * vObjs; // the cone nodes
+ int nBits; // the number of simulation bits
+ int nWords; // the number of unsigneds for siminfo
+ int nWordsCur; // the current number of words
+ Vec_Ptr_t * vSims; // simulation info
+ unsigned * pInfo; // pointer to simulation info
+ // other info
+ Vec_Ptr_t * vCone0;
+ Vec_Ptr_t * vCone1;
+ // memory manager
+ Extra_MmFixed_t* pMmObj; // memory manager for objects
+};
+
+static Abc_HMan_t * s_pHMan = NULL;
+
+static inline int Abc_HObjProof( Abc_HObj_t * p ) { return p->fProof; }
+static inline int Abc_HObjPhase( Abc_HObj_t * p ) { return p->fPhase; }
+static inline int Abc_HObjPi ( Abc_HObj_t * p ) { return p->fPi; }
+static inline int Abc_HObjPo ( Abc_HObj_t * p ) { return p->fPo; }
+static inline int Abc_HObjConst( Abc_HObj_t * p ) { return p->fConst; }
+static inline int Abc_HObjNtkId( Abc_HObj_t * p ) { return p->NtkId; }
+static inline int Abc_HObjNum ( Abc_HObj_t * p ) { return p->Num; }
+static inline Abc_HObj_t * Abc_HObjFanin0( Abc_HObj_t * p ) { return !p->Fan0.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan0.NtkId), p->Fan0.ObjId ); }
+static inline Abc_HObj_t * Abc_HObjFanin1( Abc_HObj_t * p ) { return !p->Fan1.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan1.NtkId), p->Fan1.ObjId ); }
+static inline Abc_HObj_t * Abc_HObjProto ( Abc_HObj_t * p ) { return !p->Proto.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Proto.NtkId), p->Proto.ObjId ); }
+static inline int Abc_HObjFaninC0( Abc_HObj_t * p ) { return p->Fan0.fCompl; }
+static inline int Abc_HObjFaninC1( Abc_HObj_t * p ) { return p->Fan1.fCompl; }
+
+static inline Abc_HObj_t * Abc_ObjHObj( Abc_Obj_t * p ) { return Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->pNtk->Id), p->Id ); }
+
+static int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew );
+static int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew );
+
+static Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew );
+static Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHOld, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
+static int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManStart()
+{
+ Abc_HMan_t * p;
+ unsigned * pData;
+ int i, k;
+ assert( s_pHMan == NULL );
+ assert( sizeof(unsigned) == 4 );
+ // allocate manager
+ p = ALLOC( Abc_HMan_t, 1 );
+ memset( p, 0, sizeof(Abc_HMan_t) );
+ // allocate storage for all nodes
+ p->vNtks = Vec_VecStart( 1 );
+ p->vProof = Vec_IntStart( 1 );
+ // allocate temporary storage for objects
+ p->nVarsMax = ABC_SIM_VARS;
+ p->nObjsMax = ABC_SIM_OBJS;
+ p->vObjs = Vec_PtrAlloc( p->nObjsMax );
+ // allocate simulation info
+ p->nBits = (1 << p->nVarsMax);
+ p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32);
+ p->pInfo = ALLOC( unsigned, p->nWords * p->nObjsMax );
+ memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nVarsMax );
+ p->vSims = Vec_PtrAlloc( p->nObjsMax );
+ for ( i = 0; i < p->nObjsMax; i++ )
+ Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords );
+ // set elementary truth tables
+ for ( k = 0; k < p->nVarsMax; k++ )
+ {
+ pData = p->vSims->pArray[k];
+ for ( i = 0; i < p->nBits; i++ )
+ if ( i & (1 << k) )
+ pData[i/32] |= (1 << (i%32));
+ }
+ // allocate storage for the nodes
+ p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) );
+ p->vCone0 = Vec_PtrAlloc( p->nObjsMax );
+ p->vCone1 = Vec_PtrAlloc( p->nObjsMax );
+ s_pHMan = p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManStop()
+{
+ assert( s_pHMan != NULL );
+ Extra_MmFixedStop( s_pHMan->pMmObj, 0 );
+ Vec_PtrFree( s_pHMan->vObjs );
+ Vec_PtrFree( s_pHMan->vSims );
+ Vec_VecFree( s_pHMan->vNtks );
+ Vec_IntFree( s_pHMan->vProof );
+ Vec_PtrFree( s_pHMan->vCone0 );
+ Vec_PtrFree( s_pHMan->vCone1 );
+ free( s_pHMan->pInfo );
+ free( s_pHMan );
+ s_pHMan = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManIsRunning()
+{
+ return s_pHMan != NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when a new network is created.]
+
+ Description [Returns the new ID for the network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManGetNewNtkId()
+{
+ if ( s_pHMan == NULL )
+ return 0;
+ return Vec_VecSize( s_pHMan->vNtks ); // what if the new network has no nodes?
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when the object is created.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManAddObj( Abc_Obj_t * pObj )
+{
+ Abc_HObj_t * pHObj;
+ if ( s_pHMan == NULL )
+ return;
+ pHObj = (Abc_HObj_t *)Extra_MmFixedEntryFetch( s_pHMan->pMmObj );
+ memset( pHObj, 0, sizeof(Abc_HObj_t) );
+ // set the object type
+ pHObj->NtkId = pObj->pNtk->Id;
+ if ( Abc_ObjIsCi(pObj) )
+ pHObj->fPi = 1;
+ else if ( Abc_ObjIsCo(pObj) )
+ pHObj->fPo = 1;
+ Vec_VecPush( s_pHMan->vNtks, pObj->pNtk->Id, pHObj );
+ // set the proof parameter for the network
+ if ( Vec_IntSize( s_pHMan->vProof ) == pObj->pNtk->Id )
+ Vec_IntPush( s_pHMan->vProof, 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when the fanin is added to the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
+{
+ Abc_HObj_t * pHObj;
+ int fCompl;
+ if ( s_pHMan == NULL )
+ return;
+ // take off the complemented attribute
+ assert( !Abc_ObjIsComplement(pObj) );
+ fCompl = Abc_ObjIsComplement(pFanin);
+ pFanin = Abc_ObjRegular(pFanin);
+ // add the fanin
+ assert( pObj->pNtk == pFanin->pNtk );
+ pHObj = Abc_ObjHObj(pObj);
+ if ( pHObj->Fan0.NtkId == 0 )
+ {
+ pHObj->Fan0.NtkId = pFanin->pNtk->Id;
+ pHObj->Fan0.ObjId = pFanin->Id;
+ pHObj->Fan0.fCompl = fCompl;
+ }
+ else if ( pHObj->Fan1.NtkId == 0 )
+ {
+ pHObj->Fan1.NtkId = pFanin->pNtk->Id;
+ pHObj->Fan1.ObjId = pFanin->Id;
+ pHObj->Fan1.fCompl = fCompl;
+ }
+ else assert( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when the fanin's input should be complemented.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin )
+{
+ Abc_HObj_t * pHObj;
+ if ( s_pHMan == NULL )
+ return;
+ assert( iFanin < 2 );
+ pHObj = Abc_ObjHObj(pObj);
+ if ( iFanin == 0 )
+ pHObj->Fan0.fCompl ^= 1;
+ else if ( iFanin == 1 )
+ pHObj->Fan1.fCompl ^= 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when the fanin is added to the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManRemoveFanins( Abc_Obj_t * pObj )
+{
+ Abc_HObj_t * pHObj;
+ if ( s_pHMan == NULL )
+ return;
+ assert( !Abc_ObjIsComplement(pObj) );
+ pHObj = Abc_ObjHObj(pObj);
+ pHObj->Fan0.NtkId = 0;
+ pHObj->Fan0.ObjId = 0;
+ pHObj->Fan0.fCompl = 0;
+ pHObj->Fan1.NtkId = 0;
+ pHObj->Fan1.ObjId = 0;
+ pHObj->Fan1.fCompl = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when a new prototype of the old object is set.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto )
+{
+ Abc_HObj_t * pHObj;
+ if ( s_pHMan == NULL )
+ return;
+ // ignore polarity for now
+ pObj = Abc_ObjRegular(pObj);
+ pProto = Abc_ObjRegular(pProto);
+ // set the prototype
+ assert( pObj->pNtk != pProto->pNtk );
+ if ( pObj->pNtk->Id == 0 )
+ return;
+ pHObj = Abc_ObjHObj(pObj);
+ pHObj->Proto.NtkId = pProto->pNtk->Id;
+ pHObj->Proto.ObjId = pProto->Id;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Called when an equivalent node is created.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu )
+{
+/*
+ Abc_HObj_t * pHObj;
+ if ( s_pHMan == NULL )
+ return;
+ // ignore polarity for now
+ pObj = Abc_ObjRegular(pObj);
+ pEqu = Abc_ObjRegular(pEqu);
+ // set the equivalent node
+ assert( pObj->pNtk == pEqu->pNtk );
+ pHObj = Abc_ObjHObj(pObj);
+ Abc_ObjHObj(pObj)->Equ.NtkId = pEqu->pNtk->Id;
+ Abc_ObjHObj(pObj)->Equ.ObjId = pEqu->Id;
+*/
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Starts the verification procedure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManPopulate( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ if ( !Abc_NtkIsStrash(pNtk) )
+ return 0;
+ // allocate the network ID
+ pNtk->Id = Abc_HManGetNewNtkId();
+ assert( pNtk->Id == 1 );
+ // create the objects
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ Abc_HManAddObj( pObj );
+ if ( Abc_ObjFaninNum(pObj) > 0 )
+ Abc_HManAddFanin( pObj, Abc_ObjChild0(pObj) );
+ if ( Abc_ObjFaninNum(pObj) > 1 )
+ Abc_HManAddFanin( pObj, Abc_ObjChild1(pObj) );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [The main verification procedure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManVerify( int NtkIdOld, int NtkIdNew )
+{
+ int i;
+ // prove the equality pairwise
+ for ( i = NtkIdOld; i < NtkIdNew; i++ )
+ {
+ if ( Vec_IntEntry(s_pHMan->vProof, i) )
+ continue;
+ if ( !Abc_HManVerifyPair( i, i+1 ) )
+ return 0;
+ Vec_IntWriteEntry( s_pHMan->vProof, i, 1 );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies two networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew )
+{
+ Vec_Ptr_t * vNtkNew, * vNtkOld, * vPosNew;
+ Abc_HObj_t * pHObj;
+ int i;
+ // get hold of the network nodes
+ vNtkNew = Vec_VecEntry( s_pHMan->vNtks, NtkIdNew );
+ vNtkOld = Vec_VecEntry( s_pHMan->vNtks, NtkIdOld );
+ Vec_PtrForEachEntry( vNtkNew, pHObj, i )
+ pHObj->fVisited = 0;
+ Vec_PtrForEachEntry( vNtkOld, pHObj, i )
+ pHObj->fVisited = 0;
+ // collect new POs
+ vPosNew = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( vNtkNew, pHObj, i )
+ if ( pHObj->fPo )
+ Vec_PtrPush( vPosNew, pHObj );
+ // prove them recursively (assuming PO ordering is the same)
+ Vec_PtrForEachEntry( vPosNew, pHObj, i )
+ {
+ if ( Abc_HObjProto(pHObj) == NULL )
+ {
+ printf( "History: PO %d has no prototype\n", i );
+ return 0;
+ }
+ if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
+ {
+ printf( "History: Verification failed for outputs of PO pair number %d\n", i );
+ return 0;
+ }
+ }
+ printf( "History: Verification succeeded.\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively verifies two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew )
+{
+ Vec_Ptr_t * vLeaves;
+ Abc_HObj_t * pHObj, * pHPro0, * pHPro1;
+ int i, fPhase;
+
+ assert( Abc_HObjProto(pHNew) == pHOld );
+ if ( pHNew->fProof )
+ return 1;
+ pHNew->fProof = 1;
+ // consider simple cases
+ if ( pHNew->fPi || pHNew->fConst )
+ return 1;
+ if ( pHNew->fPo )
+ {
+ if ( !Abc_HManVerifyNodes_rec( Abc_HObjFanin0(pHOld), Abc_HObjFanin0(pHNew) ) )
+ return 0;
+ if ( (Abc_HObjFaninC0(pHOld) ^ Abc_HObjFaninC0(pHNew)) != (int)pHNew->fPhase )
+ {
+ printf( "History: Phase of PO nodes does not agree.\n" );
+ return 0;
+ }
+ return 1;
+ }
+ // the elementary node
+ pHPro0 = Abc_HObjProto( Abc_HObjFanin0(pHNew) );
+ pHPro1 = Abc_HObjProto( Abc_HObjFanin1(pHNew) );
+ if ( pHPro0 && pHPro1 )
+ {
+ if ( !Abc_HManVerifyNodes_rec( pHPro0, Abc_HObjFanin0(pHNew) ) )
+ return 0;
+ if ( !Abc_HManVerifyNodes_rec( pHPro1, Abc_HObjFanin1(pHNew) ) )
+ return 0;
+ if ( Abc_HObjFanin0(pHOld) != pHPro0 || Abc_HObjFanin1(pHOld) != pHPro1 )
+ {
+ printf( "History: Internal node does not match.\n" );
+ return 0;
+ }
+ if ( Abc_HObjFaninC0(pHOld) != Abc_HObjFaninC0(pHNew) ||
+ Abc_HObjFaninC1(pHOld) != Abc_HObjFaninC1(pHNew) )
+ {
+ printf( "History: Phase of internal node does not match.\n" );
+ return 0;
+ }
+ return 1;
+ }
+ // collect the leaves
+ vLeaves = Abc_HManCollectLeaves( pHNew );
+ if ( Vec_PtrSize(vLeaves) > 16 )
+ {
+ printf( "History: The bound on the number of inputs is exceeded.\n" );
+ return 0;
+ }
+ s_pHMan->nWordsCur = ((1 << Vec_PtrSize(vLeaves)) <= 32)? 1 : ((1 << Vec_PtrSize(vLeaves)) / 32);
+ // prove recursively
+ Vec_PtrForEachEntry( vLeaves, pHObj, i )
+ if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
+ {
+ Vec_PtrFree( vLeaves );
+ return 0;
+ }
+ // get the first node
+ Abc_HManCollectCone( pHNew, vLeaves, s_pHMan->vCone1 );
+ if ( Vec_PtrSize(s_pHMan->vCone1) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
+ {
+ printf( "History: The bound on the number of cone nodes is exceeded.\n" );
+ return 0;
+ }
+ // get the second cone
+ Vec_PtrForEachEntry( vLeaves, pHObj, i )
+ Vec_PtrWriteEntry( vLeaves, i, Abc_HObjProto(pHObj) );
+ Abc_HManCollectCone( pHOld, vLeaves, s_pHMan->vCone0 );
+ if ( Vec_PtrSize(s_pHMan->vCone0) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
+ {
+ printf( "History: The bound on the number of cone nodes is exceeded.\n" );
+ return 0;
+ }
+ // compare the truth tables
+ if ( !Abc_HManSimulate( s_pHMan->vCone0, s_pHMan->vCone1, Vec_PtrSize(vLeaves), &fPhase ) )
+ {
+ Vec_PtrFree( vLeaves );
+ printf( "History: Verification failed at an internal node.\n" );
+ return 0;
+ }
+ printf( "Succeeded.\n" );
+ pHNew->fPhase = fPhase;
+ Vec_PtrFree( vLeaves );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds the leaves of the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManCollectLeaves_rec( Abc_HObj_t * pHNew, Vec_Ptr_t * vLeaves )
+{
+ Abc_HObj_t * pHPro;
+ if ( pHPro = Abc_HObjProto( pHNew ) )
+ {
+ Vec_PtrPushUnique( vLeaves, pHNew );
+ return;
+ }
+ assert( !pHNew->fPi && !pHNew->fPo && !pHNew->fConst );
+ Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
+ Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds the leaves of the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew )
+{
+ Vec_Ptr_t * vLeaves;
+ vLeaves = Vec_PtrAlloc( 100 );
+ Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
+ Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
+ return vLeaves;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManCollectCone_rec( Abc_HObj_t * pHObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
+{
+ if ( pHObj->fVisited )
+ return;
+ pHObj->fVisited = 1;
+ assert( !pHObj->fPi && !pHObj->fPo && !pHObj->fConst );
+ Abc_HManCollectCone_rec( Abc_HObjFanin0(pHObj), vLeaves, vCone );
+ Abc_HManCollectCone_rec( Abc_HObjFanin1(pHObj), vLeaves, vCone );
+ pHObj->Num = Vec_PtrSize(vCone);
+ Vec_PtrPush( vCone, pHObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
+{
+ Abc_HObj_t * pHObj;
+ int i;
+ Vec_PtrClear( vCone );
+ Vec_PtrForEachEntry( vLeaves, pHObj, i )
+ {
+ pHObj->fVisited = 1;
+ pHObj->Num = Vec_PtrSize(vCone);
+ Vec_PtrPush( vCone, pHObj );
+ }
+ Abc_HManCollectCone_rec( Abc_HObjFanin0(pHRoot), vLeaves, vCone );
+ Abc_HManCollectCone_rec( Abc_HObjFanin1(pHRoot), vLeaves, vCone );
+ return vCone;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_HManSimulateOne( Vec_Ptr_t * vCone, int nLeaves, int fUsePhase )
+{
+ Abc_HObj_t * pHObj, * pHFan0, * pHFan1;
+ unsigned * puData0, * puData1, * puData;
+ int k, i, fComp0, fComp1;
+ // set the leaves
+ Vec_PtrForEachEntryStart( vCone, pHObj, i, nLeaves )
+ {
+ pHFan0 = Abc_HObjFanin0(pHObj);
+ pHFan1 = Abc_HObjFanin1(pHObj);
+ // consider the case of interver or buffer
+ if ( pHFan1 == NULL )
+ {
+ puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
+ puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
+ Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
+ fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
+ if ( fComp0 )
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = ~puData0[k];
+ else
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = puData0[k];
+ continue;
+ }
+ // get the pointers to simulation data
+ puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
+ puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
+ Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
+ puData1 = ((int)pHFan1->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan1->Num) :
+ Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan1->Num-nLeaves);
+ // here are the phases
+ fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
+ fComp1 = Abc_HObjFaninC1(pHObj) ^ (fUsePhase && (int)pHFan1->Num < nLeaves && pHFan1->fPhase);
+ // simulate
+ if ( fComp0 && fComp1 )
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = ~puData0[k] & ~puData1[k];
+ else if ( fComp0 )
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = ~puData0[k] & puData1[k];
+ else if ( fComp1 )
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = puData0[k] & ~puData1[k];
+ else
+ for ( k = 0; k < s_pHMan->nWordsCur; k++ )
+ puData[k] = puData0[k] & puData1[k];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase )
+{
+ unsigned * pDataTop, * pDataLast;
+ int w;
+ // simulate the first one
+ Abc_HManSimulateOne( vCone0, nLeaves, 0 );
+ // save the last simulation value
+ pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone0))->Num );
+ pDataLast = Vec_PtrEntry( s_pHMan->vSims, Vec_PtrSize(s_pHMan->vSims)-1 );
+ for ( w = 0; w < s_pHMan->nWordsCur; w++ )
+ pDataLast[w] = pDataTop[w];
+ // simulate the other one
+ Abc_HManSimulateOne( vCone1, nLeaves, 1 );
+ // complement the output if needed
+ pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone1))->Num );
+ // mask unused bits
+ if ( nLeaves < 5 )
+ {
+ pDataTop[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
+ pDataLast[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
+ }
+ if ( *pPhase = ((pDataTop[0] & 1) != (pDataLast[0] & 1)) )
+ for ( w = 0; w < s_pHMan->nWordsCur; w++ )
+ pDataTop[w] = ~pDataTop[w];
+ // compare
+ for ( w = 0; w < s_pHMan->nWordsCur; w++ )
+ if ( pDataLast[w] != pDataTop[w] )
+ return 0;
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcUnate.c b/src/base/abci/abcUnate.c
index 88188655..48b7eb92 100644
--- a/src/base/abci/abcUnate.c
+++ b/src/base/abci/abcUnate.c
@@ -73,7 +73,7 @@ void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose )
int clkBdd, clkUnate;
// compute the global BDDs
- if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
+ if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return;
clkBdd = clock() - clk;
diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c
index 5690013b..f1ec3847 100644
--- a/src/base/abci/abcUnreach.c
+++ b/src/base/abci/abcUnreach.c
@@ -58,7 +58,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose )
}
// compute the global BDDs of the latches
- dd = Abc_NtkGlobalBdds( pNtk, 10000000, 1 );
+ dd = Abc_NtkGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
if ( dd == NULL )
return 0;
if ( fVerbose )
@@ -331,7 +331,11 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// transform the network to the SOP representation
- Abc_NtkBddToSop( pNtkNew, 0 );
+ if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return NULL;
+ }
return pNtkNew;
}
diff --git a/src/base/abci/abcVanEijk.c b/src/base/abci/abcVanEijk.c
index c178c013..8d8784e0 100644
--- a/src/base/abci/abcVanEijk.c
+++ b/src/base/abci/abcVanEijk.c
@@ -713,7 +713,7 @@ Fraig_Man_t * Abc_NtkVanEijkFraig( Abc_Ntk_t * pMulti, int fInit )
Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses )
{
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pClass, * pNode, * pRepr, * pObj, *pObjNew;
+ Abc_Obj_t * pClass, * pNode, * pRepr, * pObj;//, *pObjNew;
Abc_Obj_t * pMiter, * pTotal;
Vec_Ptr_t * vCone;
int i, k;
diff --git a/src/base/abci/abcVanImp.c b/src/base/abci/abcVanImp.c
index c92667a3..77de5185 100644
--- a/src/base/abci/abcVanImp.c
+++ b/src/base/abci/abcVanImp.c
@@ -870,7 +870,7 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I
{
Abc_Ntk_t * pNtkNew;
Vec_Ptr_t * vCone;
- Abc_Obj_t * pObj, * pMiter, * pTotal, * pNode, * pNode1, * pNode2, * pObjNew;
+ Abc_Obj_t * pObj, * pMiter, * pTotal, * pNode, * pNode1, * pNode2;//, * pObjNew;
unsigned Imp;
int i, k;
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index 5456693b..e0c65058 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -85,7 +85,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
- RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0 );
+ RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )
@@ -112,6 +112,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
***********************************************************************/
void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
+ Prove_Params_t Params, * pParams = &Params;
// Fraig_Params_t Params;
// Fraig_Man_t * pMan;
Abc_Ntk_t * pMiter;
@@ -171,7 +172,9 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
Abc_NtkDelete( pMiter );
*/
// solve the CNF using the SAT solver
- RetValue = Abc_NtkMiterProve( &pMiter, 0, 0, 1, 1, 0 );
+ Prove_ParamsSetDefault( pParams );
+ pParams->nItersMax = 5;
+ RetValue = Abc_NtkMiterProve( &pMiter, pParams );
if ( RetValue == -1 )
printf( "Networks are undecided (resource limits is reached).\n" );
else if ( RetValue == 0 )
@@ -254,7 +257,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
- RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0 );
+ RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )
diff --git a/src/base/abci/abc_.c b/src/base/abci/abc_.c
index 50558bdb..75ec88c3 100644
--- a/src/base/abci/abc_.c
+++ b/src/base/abci/abc_.c
@@ -23,7 +23,7 @@
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -40,6 +40,7 @@
***********************************************************************/
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index 4339b520..41223c0b 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -10,6 +10,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcFpga.c \
src/base/abci/abcFraig.c \
src/base/abci/abcFxu.c \
+ src/base/abci/abcGen.c \
src/base/abci/abcMap.c \
src/base/abci/abcMiter.c \
src/base/abci/abcNtbdd.c \
@@ -22,11 +23,13 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcRestruct.c \
src/base/abci/abcResub.c \
src/base/abci/abcRewrite.c \
+ src/base/abci/abcRr.c \
src/base/abci/abcSat.c \
src/base/abci/abcStrash.c \
src/base/abci/abcSweep.c \
src/base/abci/abcSymm.c \
src/base/abci/abcTiming.c \
+ src/base/abci/abcTrace.c \
src/base/abci/abcUnate.c \
src/base/abci/abcUnreach.c \
src/base/abci/abcVanEijk.c \
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index c2c09697..0d90679d 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -18,6 +18,10 @@
***********************************************************************/
+#ifdef WIN32
+#include <process.h>
+#endif
+
#include "mainInt.h"
#include "cmdInt.h"
#include "abc.h"
@@ -45,6 +49,7 @@ static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv
#endif
static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -85,6 +90,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1);
+ Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0);
}
/**Function********************************************************************
@@ -1253,6 +1259,11 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
// write out the current network
pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
+ if ( pNetlist == NULL )
+ {
+ fprintf( pErr, "Cannot produce the intermediate network.\n" );
+ goto usage;
+ }
Io_WriteBlif( pNetlist, "_sis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
@@ -1389,6 +1400,11 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
// write out the current network
pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
+ if ( pNetlist == NULL )
+ {
+ fprintf( pErr, "Cannot produce the intermediate network.\n" );
+ goto usage;
+ }
Io_WriteBlif( pNetlist, "_mvsis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
@@ -1454,6 +1470,190 @@ usage:
}
+/**Function********************************************************************
+
+ Synopsis [Calls Capo internally.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ FILE * pFile;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNetlist;
+ char Command[1000], Buffer[100];
+ char * pProgNameCapoWin = "capo.exe";
+ char * pProgNameCapoUnix = "capo";
+ char * pProgNameGnuplotWin = "wgnuplot.exe";
+ char * pProgNameGnuplotUnix = "gnuplot";
+ char * pProgNameCapo;
+ char * pProgNameGnuplot;
+ char * pPlotFileName;
+ int i;
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ goto usage;
+ }
+
+ if ( strcmp( argv[0], "capo" ) != 0 )
+ {
+ fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
+ goto usage;
+ }
+
+ if ( argc > 1 )
+ {
+ if ( strcmp( argv[1], "-h" ) == 0 )
+ goto usage;
+ if ( strcmp( argv[1], "-?" ) == 0 )
+ goto usage;
+ }
+
+ // get the names from the resource file
+ if ( Cmd_FlagReadByName(pAbc, "capowin") )
+ pProgNameCapoWin = Cmd_FlagReadByName(pAbc, "capowin");
+ if ( Cmd_FlagReadByName(pAbc, "capounix") )
+ pProgNameCapoUnix = Cmd_FlagReadByName(pAbc, "capounix");
+
+ // check if capo is available
+ if ( (pFile = fopen( pProgNameCapoWin, "r" )) )
+ pProgNameCapo = pProgNameCapoWin;
+ else if ( (pFile = fopen( pProgNameCapoUnix, "r" )) )
+ pProgNameCapo = pProgNameCapoUnix;
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameCapoWin, pProgNameCapoUnix );
+ goto usage;
+ }
+ fclose( pFile );
+
+ if ( Abc_NtkIsMappedLogic(pNtk) )
+ {
+ Abc_NtkUnmap(pNtk);
+ printf( "The current network is unmapped before calling Capo.\n" );
+ }
+
+ // write out the current network
+ pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
+ if ( pNetlist == NULL )
+ {
+ fprintf( pErr, "Cannot produce the intermediate network.\n" );
+ goto usage;
+ }
+ Io_WriteBlif( pNetlist, "_capo_in.blif", 1 );
+ Abc_NtkDelete( pNetlist );
+
+ // create the file for Capo
+ sprintf( Command, "%s -f _capo_in.blif -log out.txt ", pProgNameCapo );
+ pPlotFileName = NULL;
+ for ( i = 1; i < argc; i++ )
+ {
+ sprintf( Buffer, " %s", argv[i] );
+ strcat( Command, Buffer );
+ if ( !strcmp( argv[i], "-plot" ) )
+ pPlotFileName = argv[i+1];
+ }
+
+ // call Capo
+ if ( system( Command ) )
+ {
+ fprintf( pErr, "The following command has returned non-zero exit status:\n" );
+ fprintf( pErr, "\"%s\"\n", Command );
+ unlink( "_capo_in.blif" );
+ goto usage;
+ }
+ // remove temporary networks
+ unlink( "_capo_in.blif" );
+ if ( pPlotFileName == NULL )
+ return 0;
+
+ // get the file name
+ sprintf( Buffer, "%s.plt", pPlotFileName );
+ pPlotFileName = Buffer;
+
+ // read in the Capo plotting output
+ if ( (pFile = fopen( pPlotFileName, "r" )) == NULL )
+ {
+ fprintf( pErr, "Cannot open the plot file \"%s\".\n\n", pPlotFileName );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // get the names from the plotting software
+ if ( Cmd_FlagReadByName(pAbc, "gnuplotwin") )
+ pProgNameGnuplotWin = Cmd_FlagReadByName(pAbc, "gnuplotwin");
+ if ( Cmd_FlagReadByName(pAbc, "gnuplotunix") )
+ pProgNameGnuplotUnix = Cmd_FlagReadByName(pAbc, "gnuplotunix");
+
+ // check if Gnuplot is available
+ if ( (pFile = fopen( pProgNameGnuplotWin, "r" )) )
+ pProgNameGnuplot = pProgNameGnuplotWin;
+ else if ( (pFile = fopen( pProgNameGnuplotUnix, "r" )) )
+ pProgNameGnuplot = pProgNameGnuplotUnix;
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameGnuplotWin, pProgNameGnuplotUnix );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // spawn the viewer
+#ifdef WIN32
+ if ( _spawnl( _P_NOWAIT, pProgNameGnuplot, pProgNameGnuplot, pPlotFileName, NULL ) == -1 )
+ {
+ fprintf( stdout, "Cannot find \"%s\".\n", pProgNameGnuplot );
+ goto usage;
+ }
+#else
+ {
+ sprintf( Command, "%s %s ", pProgNameGnuplot, pPlotFileName );
+ if ( system( Command ) == -1 )
+ {
+ fprintf( stdout, "Cannot execute \"%s\".\n", Command );
+ goto usage;
+ }
+ }
+#endif
+
+ // remove temporary networks
+// unlink( pPlotFileName );
+ return 0;
+
+usage:
+ fprintf( pErr, "\n" );
+ fprintf( pErr, "Usage: capo [-h] <com>\n");
+ fprintf( pErr, " peforms placement of the current network using Capo\n" );
+ fprintf( pErr, " a Capo binary should be present in the same directory\n" );
+ fprintf( pErr, " (if plotting, the Gnuplot binary should also be present)\n" );
+ fprintf( pErr, " -h : print the command usage\n" );
+ fprintf( pErr, " <com> : a Capo command\n" );
+ fprintf( pErr, " Example 1: capo\n" );
+ fprintf( pErr, " (performs placement with default options)\n" );
+ fprintf( pErr, " Example 2: capo -AR <aspec_ratio> -WS <whitespace_percentage> -save\n" );
+ fprintf( pErr, " (specifies the aspect ratio [default = 1.0] and\n" );
+ fprintf( pErr, " the whitespace percentage [0%%; 100%%) [default = 15%%])\n" );
+ fprintf( pErr, " Example 3: capo -plot <base_fileName>\n" );
+ fprintf( pErr, " (produces <base_fileName.plt> and visualize it using Gnuplot)\n" );
+ fprintf( pErr, " Example 4: capo -help\n" );
+ fprintf( pErr, " (prints the default usage message of the Capo binary)\n" );
+ fprintf( pErr, " Please refer to the Capo webpage for additional information:\n" );
+ fprintf( pErr, " http://vlsicad.eecs.umich.edu/BK/PDtools/\n" );
+ return 1; // error exit
+}
+
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioRead.c b/src/base/io/ioRead.c
index 6422461c..70e648a7 100644
--- a/src/base/io/ioRead.c
+++ b/src/base/io/ioRead.c
@@ -42,6 +42,9 @@
Abc_Ntk_t * Io_Read( char * pFileName, int fCheck )
{
Abc_Ntk_t * pNtk, * pTemp;
+// extern int s_TotalNodes;
+// extern int s_TotalChanges;
+// s_TotalNodes = s_TotalChanges = 0;
// set the new network
if ( Extra_FileNameCheckExtension( pFileName, "blif" ) )
pNtk = Io_ReadBlif( pFileName, fCheck );
diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c
index 1cb0ae5d..aa7f82e3 100644
--- a/src/base/io/ioReadBench.c
+++ b/src/base/io/ioReadBench.c
@@ -136,7 +136,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Abc_ObjSetData( pNode, Abc_SopCreateNor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "XOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateXor(pNtk->pManFunc, nNames) );
- else if ( strcmp(pType, "NXOR") == 0 )
+ else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNxor(pNtk->pManFunc, nNames) );
else if ( strncmp(pType, "BUF", 3) == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );
diff --git a/src/base/io/ioWriteCnf.c b/src/base/io/ioWriteCnf.c
index 9e5ceb9f..24612566 100644
--- a/src/base/io/ioWriteCnf.c
+++ b/src/base/io/ioWriteCnf.c
@@ -23,6 +23,8 @@
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * s_pNtk = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -57,15 +59,51 @@ int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName )
fprintf( stdout, "Io_WriteCnf(): Currently can only process the miter for combinational circuits.\n" );
return 0;
}
+ if ( Abc_NtkNodeNum(pNtk) == 0 )
+ {
+ fprintf( stdout, "The network has no logic nodes. No CNF file is generaled.\n" );
+ return 0;
+ }
// create solver with clauses
- pSat = Abc_NtkMiterSatCreate( pNtk );
+ pSat = Abc_NtkMiterSatCreate( pNtk, 0 );
+ if ( pSat == NULL )
+ {
+ fprintf( stdout, "The problem is trivially UNSAT. No CNF file is generated.\n" );
+ return 1;
+ }
// write the clauses
+ s_pNtk = pNtk;
Asat_SolverWriteDimacs( pSat, pFileName, 0, 0, 1 );
+ s_pNtk = NULL;
// free the solver
solver_delete( pSat );
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Output the mapping of PIs into variable numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars )
+{
+ extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
+ Abc_Ntk_t * pNtk = s_pNtk;
+ Vec_Int_t * vCiIds;
+ Abc_Obj_t * pObj;
+ int i;
+ vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
+ fprintf( pFile, "c PI variable numbers: <PI_name> <SAT_var_number>\n" );
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ fprintf( pFile, "c %s %d\n", Abc_ObjName(pObj), Vec_IntEntry(vCiIds, i) + (int)(incrementVars > 0) );
+ Vec_IntFree( vCiIds );
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index dbf157bf..ed6acb24 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -412,7 +412,13 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
// mark the nodes from the set
Vec_PtrForEachEntry( vNodes, pNode, i )
diff --git a/src/base/io/ioWriteList.c b/src/base/io/ioWriteList.c
index ab216eb3..f0981a8e 100644
--- a/src/base/io/ioWriteList.c
+++ b/src/base/io/ioWriteList.c
@@ -120,8 +120,8 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
if ( Abc_ObjFanoutNum( Abc_NtkConst1(pNtk) ) > 0 )
Io_WriteListEdge( pFile, Abc_NtkConst1(pNtk) );
- // write the PO edges
- Abc_NtkForEachCi( pNtk, pObj, i )
+ // write the PI edges
+ Abc_NtkForEachPi( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
// write the internal nodes
@@ -132,7 +132,7 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
if ( fUseHost )
Io_WriteListHost( pFile, pNtk );
else
- Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_NtkForEachPo( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
fprintf( pFile, "\n" );
@@ -157,12 +157,13 @@ void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj )
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
Abc_ObjForEachFanout( pObj, pFanout, i )
{
- fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pFanout), Abc_ObjName(pObj), Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
- if ( i == Abc_ObjFanoutNum(pObj) - 1 )
- fprintf( pFile, "." );
- else
+ fprintf( pFile, " %s", Abc_ObjName(pFanout) );
+ fprintf( pFile, " ([%s_to_", Abc_ObjName(pObj) );
+ fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
+ if ( i != Abc_ObjFanoutNum(pObj) - 1 )
fprintf( pFile, "," );
}
+ fprintf( pFile, "." );
fprintf( pFile, "\n" );
}
@@ -186,22 +187,19 @@ void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk )
{
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
fprintf( pFile, " %s ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), "HOST", 0 );
- if ( i == Abc_NtkPoNum(pNtk) - 1 )
- fprintf( pFile, "." );
- else
- fprintf( pFile, "," );
+ fprintf( pFile, "." );
+ fprintf( pFile, "\n" );
}
- fprintf( pFile, "\n" );
fprintf( pFile, "%-10s > ", "HOST" );
Abc_NtkForEachPi( pNtk, pObj, i )
{
- fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pObj), "HOST", Abc_ObjName(pObj), 0 );
- if ( i == Abc_NtkPiNum(pNtk) - 1 )
- fprintf( pFile, "." );
- else
+ fprintf( pFile, " %s", Abc_ObjName(pObj) );
+ fprintf( pFile, " ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), 0 );
+ if ( i != Abc_NtkPiNum(pNtk) - 1 )
fprintf( pFile, "," );
}
+ fprintf( pFile, "." );
fprintf( pFile, "\n" );
}
diff --git a/src/base/main/main.h b/src/base/main/main.h
index 9b483904..fe511314 100644
--- a/src/base/main/main.h
+++ b/src/base/main/main.h
@@ -81,6 +81,7 @@ extern FILE * Abc_FrameReadErr( Abc_Frame_t * p );
extern bool Abc_FrameReadMode( Abc_Frame_t * p );
extern bool Abc_FrameSetMode( Abc_Frame_t * p, bool fNameMode );
extern void Abc_FrameRestart( Abc_Frame_t * p );
+extern bool Abc_FrameShowProgress( Abc_Frame_t * p );
extern void Abc_FrameSetCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNet );
extern void Abc_FrameSwapCurrentAndBackup( Abc_Frame_t * p );
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index b3208740..5747443c 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -111,9 +111,12 @@ Abc_Frame_t * Abc_FrameAllocate()
// set the starting step
p->nSteps = 1;
p->fBatchMode = 0;
+ p->fProgress = 1;
// initialize decomposition manager
define_cube_size(20);
set_espresso_flags();
+ // initialize the trace manager
+// Abc_HManStart();
return p;
}
@@ -132,6 +135,7 @@ Abc_Frame_t * Abc_FrameAllocate()
void Abc_FrameDeallocate( Abc_Frame_t * p )
{
extern void undefine_cube_size();
+// Abc_HManStop();
undefine_cube_size();
if ( p->pManDec ) Dec_ManStop( p->pManDec );
if ( p->dd ) Extra_StopManager( p->dd );
@@ -155,6 +159,22 @@ void Abc_FrameRestart( Abc_Frame_t * p )
{
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_FrameShowProgress( Abc_Frame_t * p )
+{
+ return p->fProgress;
+}
+
/**Function*************************************************************
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index d2bca1ab..109e91c8 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -55,6 +55,7 @@ struct Abc_Frame_t_
int nSteps; // the counter of different network processed
int fAutoexac; // marks the autoexec mode
int fBatchMode; // are we invoked in batch mode?
+ int fProgress; // shows progress bars
// output streams
FILE * Out;
FILE * Err;
diff --git a/src/base/seq/seqAigCore.c b/src/base/seq/seqAigCore.c
index e74f3fa7..813b1ed8 100644
--- a/src/base/seq/seqAigCore.c
+++ b/src/base/seq/seqAigCore.c
@@ -358,7 +358,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int
// solve the miter
clk = clock();
// RetValue = Abc_NtkMiterSat_OldAndRusty( pNtkCnf, 30, 0 );
- RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0 );
+ RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0, 0 );
if ( fVerbose )
if ( clock() - clk > 100 )
{
diff --git a/src/base/seq/seqMapIter.c b/src/base/seq/seqMapIter.c
index 67ac4a7d..185c05f3 100644
--- a/src/base/seq/seqMapIter.c
+++ b/src/base/seq/seqMapIter.c
@@ -613,7 +613,7 @@ void Seq_MapCanonicizeTruthTables( Abc_Ntk_t * pNtk )
if ( pList == NULL )
continue;
for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
- Cut_TruthCanonicize( pCut );
+ Cut_TruthNCanonicize( pCut );
}
}
diff --git a/src/base/seq/seqRetCore.c b/src/base/seq/seqRetCore.c
index 0805a838..38915bf4 100644
--- a/src/base/seq/seqRetCore.c
+++ b/src/base/seq/seqRetCore.c
@@ -107,7 +107,13 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose )
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
- Abc_NtkBddToSop(pNtk, 0);
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return NULL;
+ }
+ }
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_SEQ, ABC_FUNC_AIG );
diff --git a/src/map/pga/pgaMatch.c b/src/map/pga/pgaMatch.c
index a4c57089..086a85d4 100644
--- a/src/map/pga/pgaMatch.c
+++ b/src/map/pga/pgaMatch.c
@@ -73,7 +73,7 @@ void Pga_MappingMatches( Pga_Man_t * p, int Mode )
continue;
// get the cuts
clk = clock();
- pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0 );
+ pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0, 0 );
p->timeCuts += clock() - clk;
// match the node
Pga_MappingMatchNode( p, pObj->Id, pList, Mode );
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h
index 1b6abaa6..e02ec82a 100644
--- a/src/misc/extra/extra.h
+++ b/src/misc/extra/extra.h
@@ -293,6 +293,8 @@ extern char * Extra_TimeStamp();
extern char * Extra_StringAppend( char * pStrGiven, char * pStrAdd );
extern unsigned Extra_ReadBinary( char * Buffer );
extern void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits );
+extern int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars );
+extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars );
extern void Extra_PrintHex( FILE * pFile, unsigned uTruth, int nVars );
extern void Extra_PrintSymbols( FILE * pFile, char Char, int nTimes, int fPrintNewLine );
@@ -390,30 +392,68 @@ extern void Extra_ProgressBarStop( ProgressBar * p );
extern void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString );
static inline void Extra_ProgressBarUpdate( ProgressBar * p, int nItemsCur, char * pString )
-{ if ( nItemsCur < *((int*)p) ) return; Extra_ProgressBarUpdate_int(p, nItemsCur, pString); }
-
-/*=== extraUtilIntVec.c ================================================================*/
-
-typedef struct Extra_IntVec_t_ Extra_IntVec_t;
-extern Extra_IntVec_t * Extra_IntVecAlloc( int nCap );
-extern Extra_IntVec_t * Extra_IntVecAllocArray( int * pArray, int nSize );
-extern Extra_IntVec_t * Extra_IntVecAllocArrayCopy( int * pArray, int nSize );
-extern Extra_IntVec_t * Extra_IntVecDup( Extra_IntVec_t * pVec );
-extern Extra_IntVec_t * Extra_IntVecDupArray( Extra_IntVec_t * pVec );
-extern void Extra_IntVecFree( Extra_IntVec_t * p );
-extern void Extra_IntVecFill( Extra_IntVec_t * p, int nSize, int Entry );
-extern int * Extra_IntVecReleaseArray( Extra_IntVec_t * p );
-extern int * Extra_IntVecReadArray( Extra_IntVec_t * p );
-extern int Extra_IntVecReadSize( Extra_IntVec_t * p );
-extern int Extra_IntVecReadEntry( Extra_IntVec_t * p, int i );
-extern int Extra_IntVecReadEntryLast( Extra_IntVec_t * p );
-extern void Extra_IntVecWriteEntry( Extra_IntVec_t * p, int i, int Entry );
-extern void Extra_IntVecGrow( Extra_IntVec_t * p, int nCapMin );
-extern void Extra_IntVecShrink( Extra_IntVec_t * p, int nSizeNew );
-extern void Extra_IntVecClear( Extra_IntVec_t * p );
-extern void Extra_IntVecPush( Extra_IntVec_t * p, int Entry );
-extern int Extra_IntVecPop( Extra_IntVec_t * p );
-extern void Extra_IntVecSort( Extra_IntVec_t * p );
+{ if ( p && nItemsCur < *((int*)p) ) return; Extra_ProgressBarUpdate_int(p, nItemsCur, pString); }
+
+/*=== extraUtilTruth.c ================================================================*/
+
+static inline int Extra_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
+static inline int Extra_WordCountOnes( unsigned uWord )
+{
+ uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
+ uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
+ uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
+ uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
+ return (uWord & 0x0000FFFF) + (uWord>>16);
+}
+static inline int Extra_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars )
+{
+ int w;
+ for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
+ if ( pIn0[w] != pIn1[w] )
+ return 0;
+ return 1;
+}
+static inline void Extra_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = pIn[w];
+}
+static inline void Extra_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = ~pIn[w];
+}
+static inline void Extra_TruthAnd( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
+{
+ int w;
+ for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = pIn0[w] & pIn1[w];
+}
+static inline void Extra_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
+{
+ int w;
+ for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = ~(pIn0[w] & pIn1[w]);
+}
+
+extern void Extra_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start );
+extern void Extra_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
+extern void Extra_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
+extern DdNode * Extra_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars );
+extern int Extra_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
+extern int Extra_TruthSupportSize( unsigned * pTruth, int nVars );
+extern int Extra_TruthSupport( unsigned * pTruth, int nVars );
+extern void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar );
+extern void Extra_TruthCofactor1( unsigned * pTruth, int nVars, int iVar );
+extern void Extra_TruthCombine( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar );
+extern void Extra_TruthChangePhase( unsigned * pTruth, int nVars, int iVar );
+extern int Extra_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );
+extern int Extra_TruthCountOnes( unsigned * pTruth, int nVars );
+extern void Extra_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore );
+extern unsigned Extra_TruthHash( unsigned * pIn, int nWords );
+extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );
/*=== extraUtilUtil.c ================================================================*/
diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c
index b00125d1..9a47750f 100644
--- a/src/misc/extra/extraUtilFile.c
+++ b/src/misc/extra/extraUtilFile.c
@@ -320,6 +320,65 @@ void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits )
/**Function*************************************************************
+ Synopsis [Reads the hex unsigned into the bit-string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars )
+{
+ int nDigits, Digit, k, c;
+ Sign[0] = 0;
+ // write the number into the file
+ nDigits = (1 << nVars) / 4;
+ for ( k = 0; k < nDigits; k++ )
+ {
+ c = nDigits-1-k;
+ if ( pString[c] >= '0' && pString[c] <= '9' )
+ Digit = pString[c] - '0';
+ else if ( pString[c] >= 'A' && pString[c] <= 'F' )
+ Digit = pString[c] - 'A' + 10;
+ else if ( pString[c] >= 'a' && pString[c] <= 'f' )
+ Digit = pString[c] - 'a' + 10;
+ else { assert( 0 ); return 0; }
+ Sign[k/8] |= ( (Digit & 15) << ((k%8) * 4) );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the hex unsigned into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars )
+{
+ int nDigits, Digit, k;
+ // write the number into the file
+ nDigits = (1 << nVars) / 4;
+ for ( k = nDigits - 1; k >= 0; k-- )
+ {
+ Digit = ((Sign[k/8] >> ((k%8) * 4)) & 15);
+ if ( Digit < 10 )
+ fprintf( pFile, "%d", Digit );
+ else
+ fprintf( pFile, "%c", 'a' + Digit-10 );
+ }
+// fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
Synopsis [Prints the hex unsigned into a file.]
Description []
diff --git a/src/misc/extra/extraUtilProgress.c b/src/misc/extra/extraUtilProgress.c
index 8956af2f..ddd6197a 100644
--- a/src/misc/extra/extraUtilProgress.c
+++ b/src/misc/extra/extraUtilProgress.c
@@ -58,6 +58,10 @@ static void Extra_ProgressBarClean( ProgressBar * p );
ProgressBar * Extra_ProgressBarStart( FILE * pFile, int nItemsTotal )
{
ProgressBar * p;
+ extern int Abc_FrameShowProgress( void * p );
+ extern void * Abc_FrameGetGlobalFrame();
+
+ if ( !Abc_FrameShowProgress(Abc_FrameGetGlobalFrame()) ) return NULL;
p = ALLOC( ProgressBar, 1 );
memset( p, 0, sizeof(ProgressBar) );
p->pFile = pFile;
@@ -82,6 +86,7 @@ ProgressBar * Extra_ProgressBarStart( FILE * pFile, int nItemsTotal )
***********************************************************************/
void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString )
{
+ if ( p == NULL ) return;
if ( nItemsCur < p->nItemsNext )
return;
if ( nItemsCur > p->nItemsTotal )
@@ -107,6 +112,7 @@ void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString
***********************************************************************/
void Extra_ProgressBarStop( ProgressBar * p )
{
+ if ( p == NULL ) return;
Extra_ProgressBarClean( p );
FREE( p );
}
@@ -125,6 +131,7 @@ void Extra_ProgressBarStop( ProgressBar * p )
void Extra_ProgressBarShow( ProgressBar * p, char * pString )
{
int i;
+ if ( p == NULL ) return;
if ( pString )
fprintf( p->pFile, "%s ", pString );
for ( i = (pString? strlen(pString) + 1 : 0); i < p->posCur; i++ )
@@ -151,6 +158,7 @@ void Extra_ProgressBarShow( ProgressBar * p, char * pString )
void Extra_ProgressBarClean( ProgressBar * p )
{
int i;
+ if ( p == NULL ) return;
for ( i = 0; i <= p->posTotal; i++ )
fprintf( p->pFile, " " );
fprintf( p->pFile, "\r" );
diff --git a/src/misc/extra/extraUtilTruth.c b/src/misc/extra/extraUtilTruth.c
new file mode 100644
index 00000000..2d6f307c
--- /dev/null
+++ b/src/misc/extra/extraUtilTruth.c
@@ -0,0 +1,1076 @@
+/**CFile****************************************************************
+
+ FileName [extraUtilMisc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [extra]
+
+ Synopsis [Various procedures for truth table manipulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: extraUtilMisc.c,v 1.0 2003/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "extra.h"
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations */
+/*---------------------------------------------------------------------------*/
+
+static unsigned s_VarMasks[5][2] = {
+ { 0x33333333, 0xAAAAAAAA },
+ { 0x55555555, 0xCCCCCCCC },
+ { 0x0F0F0F0F, 0xF0F0F0F0 },
+ { 0x00FF00FF, 0xFF00FF00 },
+ { 0x0000FFFF, 0xFFFF0000 }
+};
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations */
+/*---------------------------------------------------------------------------*/
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes */
+/*---------------------------------------------------------------------------*/
+
+/**AutomaticEnd***************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions */
+/*---------------------------------------------------------------------------*/
+
+/**Function*************************************************************
+
+ Synopsis [Swaps two adjacent variables in the truth table.]
+
+ Description [Swaps var number Start and var number Start+1 (0-based numbers).
+ The input truth table is pIn. The output truth table is pOut.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int iVar )
+{
+ static unsigned PMasks[4][3] = {
+ { 0x99999999, 0x22222222, 0x44444444 },
+ { 0xC3C3C3C3, 0x0C0C0C0C, 0x30303030 },
+ { 0xF00FF00F, 0x00F000F0, 0x0F000F00 },
+ { 0xFF0000FF, 0x0000FF00, 0x00FF0000 }
+ };
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step, Shift;
+
+ assert( iVar < nVars - 1 );
+ if ( iVar < 4 )
+ {
+ Shift = (1 << iVar);
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pIn[i] & PMasks[iVar][0]) | ((pIn[i] & PMasks[iVar][1]) << Shift) | ((pIn[i] & PMasks[iVar][2]) >> Shift);
+ }
+ else if ( iVar > 4 )
+ {
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 4*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ pOut[i] = pIn[i];
+ for ( i = 0; i < Step; i++ )
+ pOut[Step+i] = pIn[2*Step+i];
+ for ( i = 0; i < Step; i++ )
+ pOut[2*Step+i] = pIn[Step+i];
+ for ( i = 0; i < Step; i++ )
+ pOut[3*Step+i] = pIn[3*Step+i];
+ pIn += 4*Step;
+ pOut += 4*Step;
+ }
+ }
+ else // if ( iVar == 4 )
+ {
+ for ( i = 0; i < nWords; i += 2 )
+ {
+ pOut[i] = (pIn[i] & 0x0000FFFF) | ((pIn[i+1] & 0x0000FFFF) << 16);
+ pOut[i+1] = (pIn[i+1] & 0xFFFF0000) | ((pIn[i] & 0xFFFF0000) >> 16);
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Swaps two adjacent variables in the truth table.]
+
+ Description [Swaps var number Start and var number Start+1 (0-based numbers).
+ The input truth table is pIn. The output truth table is pOut.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthSwapAdjacentVars2( unsigned * pIn, unsigned * pOut, int nVars, int Start )
+{
+ int nWords = (nVars <= 5)? 1 : (1 << (nVars-5));
+ int i, k, Step;
+
+ assert( Start < nVars - 1 );
+ switch ( Start )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pIn[i] & 0x99999999) | ((pIn[i] & 0x22222222) << 1) | ((pIn[i] & 0x44444444) >> 1);
+ return;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pIn[i] & 0xC3C3C3C3) | ((pIn[i] & 0x0C0C0C0C) << 2) | ((pIn[i] & 0x30303030) >> 2);
+ return;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pIn[i] & 0xF00FF00F) | ((pIn[i] & 0x00F000F0) << 4) | ((pIn[i] & 0x0F000F00) >> 4);
+ return;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pIn[i] & 0xFF0000FF) | ((pIn[i] & 0x0000FF00) << 8) | ((pIn[i] & 0x00FF0000) >> 8);
+ return;
+ case 4:
+ for ( i = 0; i < nWords; i += 2 )
+ {
+ pOut[i] = (pIn[i] & 0x0000FFFF) | ((pIn[i+1] & 0x0000FFFF) << 16);
+ pOut[i+1] = (pIn[i+1] & 0xFFFF0000) | ((pIn[i] & 0xFFFF0000) >> 16);
+ }
+ return;
+ default:
+ Step = (1 << (Start - 5));
+ for ( k = 0; k < nWords; k += 4*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ pOut[i] = pIn[i];
+ for ( i = 0; i < Step; i++ )
+ pOut[Step+i] = pIn[2*Step+i];
+ for ( i = 0; i < Step; i++ )
+ pOut[2*Step+i] = pIn[Step+i];
+ for ( i = 0; i < Step; i++ )
+ pOut[3*Step+i] = pIn[3*Step+i];
+ pIn += 4*Step;
+ pOut += 4*Step;
+ }
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Expands the truth table according to the phase.]
+
+ Description [The input and output truth tables are in pIn/pOut. The current number
+ of variables is nVars. The total number of variables in nVarsAll. The last variable
+ (Phase) contains shows how the variables should be moved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase )
+{
+ unsigned * pTemp;
+ int i, k, Var = nVars - 1, Counter = 0;
+ for ( i = nVarsAll - 1; i >= 0; i-- )
+ if ( Phase & (1 << i) )
+ {
+ for ( k = Var; k < i; k++ )
+ {
+ Extra_TruthSwapAdjacentVars( pOut, pIn, nVarsAll, k );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ Counter++;
+ }
+ Var--;
+ }
+ assert( Var == -1 );
+ // swap if it was moved an even number of times
+ if ( !(Counter & 1) )
+ Extra_TruthCopy( pOut, pIn, nVarsAll );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Shrinks the truth table according to the phase.]
+
+ Description [The input and output truth tables are in pIn/pOut. The current number
+ of variables is nVars. The total number of variables in nVarsAll. The last variable
+ (Phase) contains shows how the variables should be moved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase )
+{
+ unsigned * pTemp;
+ int i, k, Var = 0, Counter = 0;
+ for ( i = 0; i < nVarsAll; i++ )
+ if ( Phase & (1 << i) )
+ {
+ for ( k = i-1; k >= Var; k-- )
+ {
+ Extra_TruthSwapAdjacentVars( pOut, pIn, nVarsAll, k );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ Counter++;
+ }
+ Var++;
+ }
+ assert( Var == nVars );
+ // swap if it was moved an even number of times
+ if ( !(Counter & 1) )
+ Extra_TruthCopy( pOut, pIn, nVarsAll );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs truth table computation.]
+
+ Description [Note the caching makes no sense for this procedure.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Extra_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nVars, int nVarsTotal )
+{
+ DdNode * bF0, * bF1, * bF;
+ if ( nVars == 0 )
+ {
+ if ( pTruth[iBit/32] & (1 << iBit%32) )
+ return b1;
+ return b0;
+ }
+ if ( nVars == 5 )
+ {
+ if ( pTruth[iBit/32] == 0xFFFFFFFF )
+ return b1;
+ if ( pTruth[iBit/32] == 0 )
+ return b0;
+ }
+ // other special cases can be added
+ bF0 = Extra_TruthToBdd_rec( dd, pTruth, iBit, nVars-1, nVarsTotal ); Cudd_Ref( bF0 );
+ bF1 = Extra_TruthToBdd_rec( dd, pTruth, iBit+(1<<(nVars-1)), nVars-1, nVarsTotal ); Cudd_Ref( bF1 );
+ bF = Cudd_bddIte( dd, dd->vars[nVarsTotal-nVars], bF1, bF0 ); Cudd_Ref( bF );
+ Cudd_RecursiveDeref( dd, bF0 );
+ Cudd_RecursiveDeref( dd, bF1 );
+ Cudd_Deref( bF );
+ return bF;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute BDD corresponding to the truth table.]
+
+ Description [If truth table has N vars, the BDD depends on N topmost
+ variables of the BDD manager. The most significant variable of the table
+ is encoded by the topmost variable of the manager. BDD construction is
+ very efficient in this case because BDD is constructed one node at a time,
+ by simply adding BDD nodes on top of existent BDD nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Extra_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars )
+{
+ return Extra_TruthToBdd_rec( dd, pTruth, 0, nVars, nVars );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if TT depends on the given variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step;
+
+ assert( iVar < nVars );
+ switch ( iVar )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ if ( (pTruth[i] & 0x55555555) != ((pTruth[i] & 0xAAAAAAAA) >> 1) )
+ return 1;
+ return 0;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ if ( (pTruth[i] & 0x33333333) != ((pTruth[i] & 0xCCCCCCCC) >> 2) )
+ return 1;
+ return 0;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ if ( (pTruth[i] & 0x0F0F0F0F) != ((pTruth[i] & 0xF0F0F0F0) >> 4) )
+ return 1;
+ return 0;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ if ( (pTruth[i] & 0x00FF00FF) != ((pTruth[i] & 0xFF00FF00) >> 8) )
+ return 1;
+ return 0;
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ if ( (pTruth[i] & 0x0000FFFF) != ((pTruth[i] & 0xFFFF0000) >> 16) )
+ return 1;
+ return 0;
+ default:
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 2*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ if ( pTruth[i] != pTruth[Step+i] )
+ return 1;
+ pTruth += 2*Step;
+ }
+ return 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of support vars.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthSupportSize( unsigned * pTruth, int nVars )
+{
+ int i, Counter = 0;
+ for ( i = 0; i < nVars; i++ )
+ Counter += Extra_TruthVarInSupport( pTruth, nVars, i );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns support of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthSupport( unsigned * pTruth, int nVars )
+{
+ int i, Support = 0;
+ for ( i = 0; i < nVars; i++ )
+ if ( Extra_TruthVarInSupport( pTruth, nVars, i ) )
+ Support |= (1 << i);
+ return Support;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes positive cofactor of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthCofactor1( unsigned * pTruth, int nVars, int iVar )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step;
+
+ assert( iVar < nVars );
+ switch ( iVar )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0xAAAAAAAA) | ((pTruth[i] & 0xAAAAAAAA) >> 1);
+ return;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0xCCCCCCCC) | ((pTruth[i] & 0xCCCCCCCC) >> 2);
+ return;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0xF0F0F0F0) | ((pTruth[i] & 0xF0F0F0F0) >> 4);
+ return;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0xFF00FF00) | ((pTruth[i] & 0xFF00FF00) >> 8);
+ return;
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0xFFFF0000) | ((pTruth[i] & 0xFFFF0000) >> 16);
+ return;
+ default:
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 2*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ pTruth[i] = pTruth[Step+i];
+ pTruth += 2*Step;
+ }
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes negative cofactor of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step;
+
+ assert( iVar < nVars );
+ switch ( iVar )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0x55555555) | ((pTruth[i] & 0x55555555) << 1);
+ return;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0x33333333) | ((pTruth[i] & 0x33333333) << 2);
+ return;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0x0F0F0F0F) | ((pTruth[i] & 0x0F0F0F0F) << 4);
+ return;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0x00FF00FF) | ((pTruth[i] & 0x00FF00FF) << 8);
+ return;
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = (pTruth[i] & 0x0000FFFF) | ((pTruth[i] & 0x0000FFFF) << 16);
+ return;
+ default:
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 2*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ pTruth[Step+i] = pTruth[i];
+ pTruth += 2*Step;
+ }
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes negative cofactor of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthCombine( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step;
+
+ assert( iVar < nVars );
+ switch ( iVar )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pCof0[i] & 0x55555555) | (pCof1[i] & 0xAAAAAAAA);
+ return;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pCof0[i] & 0x33333333) | (pCof1[i] & 0xCCCCCCCC);
+ return;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pCof0[i] & 0x0F0F0F0F) | (pCof1[i] & 0xF0F0F0F0);
+ return;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pCof0[i] & 0x00FF00FF) | (pCof1[i] & 0xFF00FF00);
+ return;
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (pCof0[i] & 0x0000FFFF) | (pCof1[i] & 0xFFFF0000);
+ return;
+ default:
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 2*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ {
+ pOut[i] = pCof0[i];
+ pOut[Step+i] = pCof1[i];
+ }
+ pOut += 2*Step;
+ }
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks symmetry of two variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthVarsSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1 )
+{
+ static unsigned uTemp0[16], uTemp1[16];
+ assert( nVars <= 9 );
+ // compute Cof01
+ Extra_TruthCopy( uTemp0, pTruth, nVars );
+ Extra_TruthCofactor0( uTemp0, nVars, iVar0 );
+ Extra_TruthCofactor1( uTemp0, nVars, iVar1 );
+ // compute Cof10
+ Extra_TruthCopy( uTemp1, pTruth, nVars );
+ Extra_TruthCofactor1( uTemp1, nVars, iVar0 );
+ Extra_TruthCofactor0( uTemp1, nVars, iVar1 );
+ // compare
+ return Extra_TruthIsEqual( uTemp0, uTemp1, nVars );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks antisymmetry of two variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthVarsAntiSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1 )
+{
+ static unsigned uTemp0[16], uTemp1[16];
+ assert( nVars <= 9 );
+ // compute Cof00
+ Extra_TruthCopy( uTemp0, pTruth, nVars );
+ Extra_TruthCofactor0( uTemp0, nVars, iVar0 );
+ Extra_TruthCofactor0( uTemp0, nVars, iVar1 );
+ // compute Cof11
+ Extra_TruthCopy( uTemp1, pTruth, nVars );
+ Extra_TruthCofactor1( uTemp1, nVars, iVar0 );
+ Extra_TruthCofactor1( uTemp1, nVars, iVar1 );
+ // compare
+ return Extra_TruthIsEqual( uTemp0, uTemp1, nVars );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Changes phase of the function w.r.t. one variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthChangePhase( unsigned * pTruth, int nVars, int iVar )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Step;
+ unsigned Temp;
+
+ assert( iVar < nVars );
+ switch ( iVar )
+ {
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ((pTruth[i] & 0x55555555) << 1) | ((pTruth[i] & 0xAAAAAAAA) >> 1);
+ return;
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ((pTruth[i] & 0x33333333) << 2) | ((pTruth[i] & 0xCCCCCCCC) >> 2);
+ return;
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ((pTruth[i] & 0x0F0F0F0F) << 4) | ((pTruth[i] & 0xF0F0F0F0) >> 4);
+ return;
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ((pTruth[i] & 0x00FF00FF) << 8) | ((pTruth[i] & 0xFF00FF00) >> 8);
+ return;
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ((pTruth[i] & 0x0000FFFF) << 16) | ((pTruth[i] & 0xFFFF0000) >> 16);
+ return;
+ default:
+ Step = (1 << (iVar - 5));
+ for ( k = 0; k < nWords; k += 2*Step )
+ {
+ for ( i = 0; i < Step; i++ )
+ {
+ Temp = pTruth[i];
+ pTruth[i] = pTruth[Step+i];
+ pTruth[Step+i] = Temp;
+ }
+ pTruth += 2*Step;
+ }
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Changes phase of the function w.r.t. one variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthCountOnes( unsigned * pTruth, int nVars )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, Counter = 0;
+ for ( i = 0; i < nWords; i++ )
+ Counter += Extra_WordCountOnes( pTruth[i] );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes minimum overlap in supports of cofactors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Extra_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin )
+{
+ static unsigned uCofactor[16];
+ int i, ValueCur, ValueMin, VarMin;
+ unsigned uSupp0, uSupp1;
+ assert( nVars <= 9 );
+ ValueMin = 32;
+ for ( i = 0; i < nVars; i++ )
+ {
+ // get negative cofactor
+ Extra_TruthCopy( uCofactor, pTruth, nVars );
+ Extra_TruthCofactor0( uCofactor, nVars, i );
+ uSupp0 = Extra_TruthSupport( uCofactor, nVars );
+//Extra_PrintBinary( stdout, &uSupp0, 8 ); printf( "\n" );
+ // get positive cofactor
+ Extra_TruthCopy( uCofactor, pTruth, nVars );
+ Extra_TruthCofactor1( uCofactor, nVars, i );
+ uSupp1 = Extra_TruthSupport( uCofactor, nVars );
+//Extra_PrintBinary( stdout, &uSupp1, 8 ); printf( "\n" );
+ // get the number of common vars
+ ValueCur = Extra_WordCountOnes( uSupp0 & uSupp1 );
+ if ( ValueMin > ValueCur )
+ {
+ ValueMin = ValueCur;
+ VarMin = i;
+ }
+ if ( ValueMin == 0 )
+ break;
+ }
+ if ( pVarMin )
+ *pVarMin = VarMin;
+ return ValueMin;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of 1's in each cofactor.]
+
+ Description [The resulting numbers are stored in the array of shorts,
+ whose length is 2*nVars. The number of 1's is counted in a different
+ space than the original function. For example, if the function depends
+ on k variables, the cofactors are assumed to depend on k-1 variables.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, k, Counter;
+ memset( pStore, 0, sizeof(short) * 2 * nVars );
+ if ( nVars <= 5 )
+ {
+ if ( nVars > 0 )
+ {
+ pStore[2*0+0] = Extra_WordCountOnes( pTruth[0] & 0x55555555 );
+ pStore[2*0+1] = Extra_WordCountOnes( pTruth[0] & 0xAAAAAAAA );
+ }
+ if ( nVars > 1 )
+ {
+ pStore[2*1+0] = Extra_WordCountOnes( pTruth[0] & 0x33333333 );
+ pStore[2*1+1] = Extra_WordCountOnes( pTruth[0] & 0xCCCCCCCC );
+ }
+ if ( nVars > 2 )
+ {
+ pStore[2*2+0] = Extra_WordCountOnes( pTruth[0] & 0x0F0F0F0F );
+ pStore[2*2+1] = Extra_WordCountOnes( pTruth[0] & 0xF0F0F0F0 );
+ }
+ if ( nVars > 3 )
+ {
+ pStore[2*3+0] = Extra_WordCountOnes( pTruth[0] & 0x00FF00FF );
+ pStore[2*3+1] = Extra_WordCountOnes( pTruth[0] & 0xFF00FF00 );
+ }
+ if ( nVars > 4 )
+ {
+ pStore[2*4+0] = Extra_WordCountOnes( pTruth[0] & 0x0000FFFF );
+ pStore[2*4+1] = Extra_WordCountOnes( pTruth[0] & 0xFFFF0000 );
+ }
+ return;
+ }
+ // nVars >= 6
+ // count 1's for all other variables
+ for ( k = 0; k < nWords; k++ )
+ {
+ Counter = Extra_WordCountOnes( pTruth[k] );
+ for ( i = 5; i < nVars; i++ )
+ if ( k & (1 << (i-5)) )
+ pStore[2*i+1] += Counter;
+ else
+ pStore[2*i+0] += Counter;
+ }
+ // count 1's for the first five variables
+ for ( k = 0; k < nWords/2; k++ )
+ {
+ pStore[2*0+0] += Extra_WordCountOnes( (pTruth[0] & 0x55555555) | ((pTruth[1] & 0x55555555) << 1) );
+ pStore[2*0+1] += Extra_WordCountOnes( (pTruth[0] & 0xAAAAAAAA) | ((pTruth[1] & 0xAAAAAAAA) >> 1) );
+ pStore[2*1+0] += Extra_WordCountOnes( (pTruth[0] & 0x33333333) | ((pTruth[1] & 0x33333333) << 2) );
+ pStore[2*1+1] += Extra_WordCountOnes( (pTruth[0] & 0xCCCCCCCC) | ((pTruth[1] & 0xCCCCCCCC) >> 2) );
+ pStore[2*2+0] += Extra_WordCountOnes( (pTruth[0] & 0x0F0F0F0F) | ((pTruth[1] & 0x0F0F0F0F) << 4) );
+ pStore[2*2+1] += Extra_WordCountOnes( (pTruth[0] & 0xF0F0F0F0) | ((pTruth[1] & 0xF0F0F0F0) >> 4) );
+ pStore[2*3+0] += Extra_WordCountOnes( (pTruth[0] & 0x00FF00FF) | ((pTruth[1] & 0x00FF00FF) << 8) );
+ pStore[2*3+1] += Extra_WordCountOnes( (pTruth[0] & 0xFF00FF00) | ((pTruth[1] & 0xFF00FF00) >> 8) );
+ pStore[2*4+0] += Extra_WordCountOnes( (pTruth[0] & 0x0000FFFF) | ((pTruth[1] & 0x0000FFFF) << 16) );
+ pStore[2*4+1] += Extra_WordCountOnes( (pTruth[0] & 0xFFFF0000) | ((pTruth[1] & 0xFFFF0000) >> 16) );
+ pTruth += 2;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Canonicize the truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Extra_TruthHash( unsigned * pIn, int nWords )
+{
+ // The 1,024 smallest prime numbers used to compute the hash value
+ // http://www.math.utah.edu/~alfeld/math/primelist.html
+ static int HashPrimes[1024] = { 2, 3, 5,
+ 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191,
+ 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
+ 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401,
+ 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
+ 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
+ 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877,
+ 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
+ 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193,
+ 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
+ 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
+ 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
+ 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601,
+ 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699,
+ 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
+ 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
+ 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029,
+ 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137,
+ 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+ 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
+ 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459,
+ 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593,
+ 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
+ 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
+ 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
+ 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023,
+ 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
+ 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
+ 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373,
+ 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,
+ 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+ 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
+ 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833,
+ 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931,
+ 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
+ 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
+ 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283,
+ 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423,
+ 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
+ 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
+ 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789,
+ 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931,
+ 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+ 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147,
+ 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
+ 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413,
+ 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
+ 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647,
+ 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743,
+ 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
+ 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
+ 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121,
+ 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247,
+ 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343,
+ 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+ 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607,
+ 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733,
+ 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857,
+ 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
+ 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,
+ 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229,
+ 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369,
+ 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
+ 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603,
+ 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
+ 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873,
+ 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+ 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123,
+ 8147, 8161 };
+ int i;
+ unsigned uHashKey;
+ assert( nWords <= 1024 );
+ uHashKey = 0;
+ for ( i = 0; i < nWords; i++ )
+ uHashKey ^= HashPrimes[i] * pIn[i];
+ return uHashKey;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Canonicize the truth table.]
+
+ Description [Returns the phase. ]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore )
+{
+ unsigned * pIn = pInOut, * pOut = pAux, * pTemp;
+ int nWords = Extra_TruthWordNum( nVars );
+ int i, Temp, fChange, Counter, nOnes;//, k, j, w, Limit;
+ unsigned uCanonPhase;
+
+ // canonicize output
+ uCanonPhase = 0;
+ nOnes = Extra_TruthCountOnes(pIn, nVars);
+ if ( (nOnes > nWords * 16) || ((nOnes == nWords * 16) && (pIn[0] & 1)) )
+ {
+ uCanonPhase |= (1 << nVars);
+ Extra_TruthNot( pIn, pIn, nVars );
+ }
+
+ // collect the minterm counts
+ Extra_TruthCountOnesInCofs( pIn, nVars, pStore );
+
+ // canonicize phase
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( pStore[2*i+0] <= pStore[2*i+1] )
+ continue;
+ uCanonPhase |= (1 << i);
+ Temp = pStore[2*i+0];
+ pStore[2*i+0] = pStore[2*i+1];
+ pStore[2*i+1] = Temp;
+ Extra_TruthChangePhase( pIn, nVars, i );
+ }
+
+// Extra_PrintHexadecimal( stdout, pIn, nVars );
+// printf( "\n" );
+
+ // permute
+ Counter = 0;
+ do {
+ fChange = 0;
+ for ( i = 0; i < nVars-1; i++ )
+ {
+ if ( pStore[2*i] <= pStore[2*(i+1)] )
+ continue;
+ Counter++;
+ fChange = 1;
+
+ Temp = pCanonPerm[i];
+ pCanonPerm[i] = pCanonPerm[i+1];
+ pCanonPerm[i+1] = Temp;
+
+ Temp = pStore[2*i];
+ pStore[2*i] = pStore[2*(i+1)];
+ pStore[2*(i+1)] = Temp;
+
+ Temp = pStore[2*i+1];
+ pStore[2*i+1] = pStore[2*(i+1)+1];
+ pStore[2*(i+1)+1] = Temp;
+
+ Extra_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ }
+ } while ( fChange );
+
+/*
+ Extra_PrintBinary( stdout, &uCanonPhase, nVars+1 ); printf( " : " );
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d=%d/%d ", pCanonPerm[i], pStore[2*i], pStore[2*i+1] );
+ printf( " C = %d\n", Counter );
+ Extra_PrintHexadecimal( stdout, pIn, nVars );
+ printf( "\n" );
+*/
+
+/*
+ // process symmetric variable groups
+ uSymms = 0;
+ for ( i = 0; i < nVars-1; i++ )
+ {
+ if ( pStore[2*i] != pStore[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ if ( pStore[2*i] != pStore[2*i+1] )
+ continue;
+ if ( Extra_TruthVarsSymm( pIn, nVars, i, i+1 ) )
+ continue;
+ if ( Extra_TruthVarsAntiSymm( pIn, nVars, i, i+1 ) )
+ Extra_TruthChangePhase( pIn, nVars, i+1 );
+ }
+*/
+
+/*
+ // process symmetric variable groups
+ uSymms = 0;
+ for ( i = 0; i < nVars-1; i++ )
+ {
+ if ( pStore[2*i] != pStore[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ // i and i+1 can be symmetric
+ // find the end of this group
+ for ( k = i+1; k < nVars; k++ )
+ if ( pStore[2*i] != pStore[2*k] )
+ break;
+ Limit = k;
+ assert( i < Limit-1 );
+ // go through the variables in this group
+ for ( j = i + 1; j < Limit; j++ )
+ {
+ // check symmetry
+ if ( Extra_TruthVarsSymm( pIn, nVars, i, j ) )
+ {
+ uSymms |= (1 << j);
+ continue;
+ }
+ // they are phase-unknown
+ if ( pStore[2*i] == pStore[2*i+1] )
+ {
+ if ( Extra_TruthVarsAntiSymm( pIn, nVars, i, j ) )
+ {
+ Extra_TruthChangePhase( pIn, nVars, j );
+ uCanonPhase ^= (1 << j);
+ uSymms |= (1 << j);
+ continue;
+ }
+ }
+
+ // they are not symmetric - move j as far as it goes in the group
+ for ( k = j; k < Limit-1; k++ )
+ {
+ Counter++;
+
+ Temp = pCanonPerm[k];
+ pCanonPerm[k] = pCanonPerm[k+1];
+ pCanonPerm[k+1] = Temp;
+
+ assert( pStore[2*k] == pStore[2*(k+1)] );
+ Extra_TruthSwapAdjacentVars( pOut, pIn, nVars, k );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ }
+ Limit--;
+ j--;
+ }
+ i = Limit - 1;
+ }
+*/
+
+ // swap if it was moved an even number of times
+ if ( Counter & 1 )
+ Extra_TruthCopy( pOut, pIn, nVars );
+ return uCanonPhase;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/misc/extra/module.make b/src/misc/extra/module.make
index c4da05e4..93b24311 100644
--- a/src/misc/extra/module.make
+++ b/src/misc/extra/module.make
@@ -10,4 +10,5 @@ SRC += src/misc/extra/extraBddAuto.c \
src/misc/extra/extraUtilMisc.c \
src/misc/extra/extraUtilProgress.c \
src/misc/extra/extraUtilReader.c \
+ src/misc/extra/extraUtilTruth.c \
src/misc/extra/extraUtilUtil.c
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index ee848df7..5a627623 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -457,6 +457,33 @@ static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
SeeAlso []
***********************************************************************/
+static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize - 1; i >= 1; i-- )
+ p->pArray[i] = p->pArray[i-1];
+ p->pArray[0] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
{
if ( p->nSize == p->nCap )
diff --git a/src/misc/vec/vecVec.h b/src/misc/vec/vecVec.h
index 8518184a..54dcaa37 100644
--- a/src/misc/vec/vecVec.h
+++ b/src/misc/vec/vecVec.h
@@ -123,6 +123,28 @@ static inline Vec_Vec_t * Vec_VecStart( int nSize )
/**Function*************************************************************
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
+{
+ int i;
+ if ( p->nSize >= Level + 1 )
+ return;
+ Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
+ for ( i = p->nSize; i <= Level; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = Level + 1;
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
diff --git a/src/opt/cut/cut.h b/src/opt/cut/cut.h
index 0a1cd41a..c2142c4f 100644
--- a/src/opt/cut/cut.h
+++ b/src/opt/cut/cut.h
@@ -59,8 +59,10 @@ struct Cut_ParamsStruct_t_
int fFilter; // filter dominated cuts
int fSeq; // compute sequential cuts
int fDrop; // drop cuts on the fly
- int fMulti; // compute factor-cuts
+ int fDag; // compute only DAG cuts
+ int fTree; // compute only tree cuts
int fRecord; // record the cut computation flow
+ int fFancy; // perform fancy computations
int fVerbose; // the verbosiness flag
};
@@ -117,8 +119,9 @@ extern void Cut_ManPrintStats( Cut_Man_t * p );
extern void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal );
extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts );
extern int Cut_ManReadVarsMax( Cut_Man_t * p );
+extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
/*=== cutNode.c ==========================================================*/
-extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv );
+extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes );
extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst );
/*=== cutSeq.c ==========================================================*/
@@ -135,7 +138,13 @@ extern void Cut_OracleNodeSetTriv( Cut_Oracle_t * p, int Node );
extern Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 );
extern void Cut_OracleTryDroppingCuts( Cut_Oracle_t * p, int Node );
/*=== cutTruth.c ==========================================================*/
-extern void Cut_TruthCanonicize( Cut_Cut_t * pCut );
+extern void Cut_TruthNCanonicize( Cut_Cut_t * pCut );
+/*=== cutPre22.c ==========================================================*/
+extern void Cut_CellPrecompute();
+extern void Cut_CellLoad();
+extern int Cut_CellIsRunning();
+extern void Cut_CellDumpToFile();
+extern int Cut_CellTruthLookup( unsigned * pTruth, int nVars );
#ifdef __cplusplus
}
diff --git a/src/opt/cut/cutInt.h b/src/opt/cut/cutInt.h
index 375d2213..c6246ad7 100644
--- a/src/opt/cut/cutInt.h
+++ b/src/opt/cut/cutInt.h
@@ -65,13 +65,13 @@ struct Cut_ManStruct_t_
Cut_Cut_t * pStore1[2];
Cut_Cut_t * pCompareOld;
Cut_Cut_t * pCompareNew;
+ unsigned * puTemp[4];
// record of the cut computation
Vec_Int_t * vNodeCuts; // the number of cuts for each node
Vec_Int_t * vNodeStarts; // the number of the starting cut of each node
Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut
// statistics
int nCutsCur;
- int nCutsMulti;
int nCutsAlloc;
int nCutsDealloc;
int nCutsPeak;
@@ -79,8 +79,8 @@ struct Cut_ManStruct_t_
int nCutsFilter;
int nCutsLimit;
int nNodes;
- int nNodesMulti;
- int nNodesMulti0;
+ int nNodesDag;
+ int nNodesNoCuts;
// runtime
int timeMerge;
int timeUnion;
@@ -130,7 +130,7 @@ extern void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut
/*=== cutMerge.c ==========================================================*/
extern Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 );
/*=== cutNode.c ==========================================================*/
-extern void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv );
+extern void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode );
extern int Cut_CutListVerify( Cut_Cut_t * pList );
/*=== cutTable.c ==========================================================*/
extern Cut_HashTable_t * Cut_TableStart( int Size );
@@ -139,7 +139,8 @@ extern int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t
extern void Cut_TableClear( Cut_HashTable_t * pTable );
extern int Cut_TableReadTime( Cut_HashTable_t * pTable );
/*=== cutTruth.c ==========================================================*/
-extern void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
+extern void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
+extern void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
#endif
diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c
index 8269da06..0cd01bc9 100644
--- a/src/opt/cut/cutMan.c
+++ b/src/opt/cut/cutMan.c
@@ -61,22 +61,30 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
Vec_PtrFill( p->vCutsOld, pParams->nIdsMax, NULL );
p->vCutsTemp = Vec_PtrAlloc( pParams->nCutSet );
Vec_PtrFill( p->vCutsTemp, pParams->nCutSet, NULL );
+ if ( pParams->fTruth && pParams->nVarsMax > 5 )
+ {
+ pParams->fTruth = 0;
+ printf( "Skipping computation of truth tables for sequential cuts with more than 5 inputs.\n" );
+ }
}
- assert( !pParams->fTruth || pParams->nVarsMax <= 5 );
// entry size
p->EntrySize = sizeof(Cut_Cut_t) + pParams->nVarsMax * sizeof(int);
if ( pParams->fTruth )
{
- if ( pParams->nVarsMax > 8 )
+ if ( pParams->nVarsMax > 14 )
{
pParams->fTruth = 0;
- printf( "Skipping computation of truth table for more than 8 inputs.\n" );
+ printf( "Skipping computation of truth table for more than %d inputs.\n", 14 );
}
else
{
p->nTruthWords = Cut_TruthWords( pParams->nVarsMax );
p->EntrySize += p->nTruthWords * sizeof(unsigned);
}
+ p->puTemp[0] = ALLOC( unsigned, 4 * p->nTruthWords );
+ p->puTemp[1] = p->puTemp[0] + p->nTruthWords;
+ p->puTemp[2] = p->puTemp[1] + p->nTruthWords;
+ p->puTemp[3] = p->puTemp[2] + p->nTruthWords;
}
// enable cut computation recording
if ( pParams->fRecord )
@@ -120,6 +128,7 @@ void Cut_ManStop( Cut_Man_t * p )
if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts );
if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts );
if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs );
+ if ( p->puTemp[0] ) free( p->puTemp[0] );
Extra_MmFixedStop( p->pMmCuts, 0 );
free( p );
@@ -153,15 +162,10 @@ void Cut_ManPrintStats( Cut_Man_t * p )
printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
printf( "The cut size = %8d bytes.\n", p->EntrySize );
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
- if ( p->pParams->fMulti )
- {
- printf( "Factor-cut computation statistics:\n" );
printf( "Total nodes = %8d.\n", p->nNodes );
- printf( "Factor nodes = %8d.\n", p->nNodesMulti );
- printf( "Factor nodes 0 = %8d.\n", p->nNodesMulti0 );
- printf( "Factor cuts = %8d.\n", p->nCutsMulti );
- printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsMulti))/(p->nNodesMulti-p->nNodesMulti0) );
- }
+ printf( "DAG nodes = %8d.\n", p->nNodesDag );
+ printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag );
+ printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts );
PRT( "Merge ", p->timeMerge );
PRT( "Union ", p->timeUnion );
PRT( "Filter", p->timeFilter );
@@ -229,6 +233,22 @@ int Cut_ManReadVarsMax( Cut_Man_t * p )
return p->pParams->nVarsMax;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_ManIncrementDagNodes( Cut_Man_t * p )
+{
+ p->nNodesDag++;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/cut/cutNode.c b/src/opt/cut/cutNode.c
index cace83bd..b651dac9 100644
--- a/src/opt/cut/cutNode.c
+++ b/src/opt/cut/cutNode.c
@@ -277,7 +277,7 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
}
// compute the truth table
if ( p->pParams->fTruth )
- Cut_TruthCompute( pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
+ Cut_TruthCompute( p, pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
// add to the list
Cut_ListAdd( pSuperList, pCut );
// return status (0 if okay; 1 if exceeded the limit)
@@ -295,7 +295,7 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
SeeAlso []
***********************************************************************/
-Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv )
+Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode )
{
Cut_List_t Super, * pSuper = &Super;
Cut_Cut_t * pList, * pCut;
@@ -312,7 +312,7 @@ Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1,
// compute the cuts
clk = clock();
Cut_ListStart( pSuper );
- Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv );
+ Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv, TreeCode );
pList = Cut_ListFinish( pSuper );
p->timeMerge += clock() - clk;
// verify the result of cut computation
@@ -351,9 +351,9 @@ p->timeMerge += clock() - clk;
SeeAlso []
***********************************************************************/
-void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv )
+void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode )
{
- Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1;
+ Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1, * pStore0, * pStore1;
int i, nCutsOld, Limit;
// start with the elementary cut
if ( fTriv )
@@ -375,6 +375,19 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
// set temporary variables
p->fCompl0 = fCompl0;
p->fCompl1 = fCompl1;
+ // if tree cuts are computed, make sure only the unit cuts propagate over the DAG nodes
+ if ( TreeCode & 1 )
+ {
+ assert( pList0->nLeaves == 1 );
+ pStore0 = pList0->pNext;
+ pList0->pNext = NULL;
+ }
+ if ( TreeCode & 2 )
+ {
+ assert( pList1->nLeaves == 1 );
+ pStore1 = pList1->pNext;
+ pList1->pNext = NULL;
+ }
// find the point in the list where the max-var cuts begin
Cut_ListForEachCut( pList0, pStop0 )
if ( pStop0->nLeaves == (unsigned)Limit )
@@ -386,8 +399,10 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
// small by small
Cut_ListForEachCutStop( pList0, pTemp0, pStop0 )
Cut_ListForEachCutStop( pList1, pTemp1, pStop1 )
+ {
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
- return;
+ goto Quits;
+ }
// small by large
Cut_ListForEachCutStop( pList0, pTemp0, pStop0 )
Cut_ListForEachCut( pStop1, pTemp1 )
@@ -395,7 +410,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( (pTemp0->uSign & pTemp1->uSign) != pTemp0->uSign )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
- return;
+ goto Quits;
}
// small by large
Cut_ListForEachCutStop( pList1, pTemp1, pStop1 )
@@ -404,7 +419,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( (pTemp0->uSign & pTemp1->uSign) != pTemp1->uSign )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
- return;
+ goto Quits;
}
// large by large
Cut_ListForEachCut( pStop0, pTemp0 )
@@ -419,15 +434,15 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( i < Limit )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
- return;
+ goto Quits;
}
- if ( fTriv )
- {
- p->nCutsMulti += p->nCutsCur - nCutsOld;
- p->nNodesMulti++;
- if ( p->nCutsCur == nCutsOld )
- p->nNodesMulti0++;
- }
+ if ( p->nNodeCuts == 0 )
+ p->nNodesNoCuts++;
+Quits:
+ if ( TreeCode & 1 )
+ pList0->pNext = pStore0;
+ if ( TreeCode & 2 )
+ pList1->pNext = pStore1;
}
/**Function*************************************************************
diff --git a/src/opt/cut/cutOracle.c b/src/opt/cut/cutOracle.c
index cad0069a..8e1ad3da 100644
--- a/src/opt/cut/cutOracle.c
+++ b/src/opt/cut/cutOracle.c
@@ -366,7 +366,7 @@ Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int No
ppTail = &pCut->pNext;
// compute the truth table
if ( p->pParams->fTruth )
- Cut_TruthCompute( pCut, pCut0, pCut1, fCompl0, fCompl1 );
+ Cut_TruthComputeOld( pCut, pCut0, pCut1, fCompl0, fCompl1 );
}
*ppTail = NULL;
diff --git a/src/opt/cut/cutPre22.c b/src/opt/cut/cutPre22.c
new file mode 100644
index 00000000..dd52b694
--- /dev/null
+++ b/src/opt/cut/cutPre22.c
@@ -0,0 +1,983 @@
+/**CFile****************************************************************
+
+ FileName [cutPre22.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Precomputes truth tables for the 2x2 macro cell.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cutInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define CUT_CELL_MVAR 9
+
+typedef struct Cut_Cell_t_ Cut_Cell_t;
+typedef struct Cut_CMan_t_ Cut_CMan_t;
+
+struct Cut_Cell_t_
+{
+ Cut_Cell_t * pNext; // pointer to the next cell in the table
+ Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
+ Cut_Cell_t * pParent; // pointer to the cell used to derive this one
+ int nUsed; // the number of times the cell is used
+ char Box[4]; // functions in the boxes
+ unsigned nVars : 4; // the number of variables
+ unsigned CrossBar0 : 4; // the variable set equal
+ unsigned CrossBar1 : 4; // the variable set equal
+ unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
+ unsigned CanonPhase : 18; // the canonical phase
+ char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
+ short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
+ unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
+};
+
+struct Cut_CMan_t_
+{
+ // storage for canonical cells
+ Extra_MmFixed_t * pMem;
+ st_table * tTable;
+ Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1];
+ // elementary truth tables
+ unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
+ // temporary truth tables
+ unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
+ unsigned puAux[1<<(CUT_CELL_MVAR-5)];
+ // statistical variables
+ int nTotal;
+ int nGood;
+ int nVarCounts[CUT_CELL_MVAR+1];
+ int nSymGroups[CUT_CELL_MVAR+1];
+ int nSymGroupsE[CUT_CELL_MVAR+1];
+ int timeCanon;
+ int timeSupp;
+ int timeTable;
+ int nCellFound;
+ int nCellNotFound;
+};
+
+// NP-classes of functions of 3 variables (22)
+static char * s_NP3[22] = {
+ " 0\n", // 00 const 0 // 0 vars
+ " 1\n", // 01 const 1 // 0 vars
+ "1 1\n", // 02 a // 1 vars
+ "11 1\n", // 03 ab // 2 vars
+ "11 0\n", // 04 (ab)' // 2 vars
+ "10 1\n01 1\n", // 05 a<+>b // 2 vars
+ "111 1\n", // 06 0s abc // 3 vars
+ "111 0\n", // 07 (abc)' //
+ "11- 1\n1-1 1\n", // 08 1p a(b+c) //
+ "11- 0\n1-1 0\n", // 09 (a(b+c))' //
+ "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
+ "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
+ "101 1\n110 1\n", // 12 4p a(b<+>c) //
+ "101 0\n110 0\n", // 13 (a(b<+>c))' //
+ "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
+ "111 1\n000 1\n", // 15 6s abc+a'b'c' //
+ "111 0\n000 0\n", // 16 (abc+a'b'c')' //
+ "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
+ "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
+ "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
+ "100 1\n-11 1\n", // 20 9p ab'c'+bc //
+ "100 0\n-11 0\n" // 21 (ab'c'+bc)' //
+};
+
+// NP-classes of functions of 3 variables (22)
+static char * s_NP3Names[22] = {
+ " const 0 ",
+ " const 1 ",
+ " a ",
+ " ab ",
+ " (ab)' ",
+ " a<+>b ",
+ "0s abc ",
+ " (abc)' ",
+ "1p a(b+c) ",
+ " (a(b+c))' ",
+ "2s a<+>b<+>c ",
+ "3p a<+>bc ",
+ "4p a(b<+>c) ",
+ " (a(b<+>c))' ",
+ "5s ab+bc+ac ",
+ "6s abc+a'b'c' ",
+ " (abc+a'b'c')' ",
+ "7 ab+bc+a'c ",
+ "8s a'bc+ab'c+abc' ",
+ " (a'bc+ab'c+abc')' ",
+ "9p ab'c'+bc ",
+ " (ab'c'+bc)' "
+};
+
+// the number of variables in each function
+static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+// NPN classes of functions of exactly 3 inputs (10)
+static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
+
+// NPN classes of functions of exactly 3 inputs that are symmetric (5)
+static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
+
+// NPN classes of functions of exactly 3 inputs (4)
+static int s_NPNe3p[10] = { 8, 11, 12, 20 };
+
+static Cut_CMan_t * Cut_CManStart();
+static void Cut_CManStop( Cut_CMan_t * p );
+static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
+static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
+static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
+static void Cut_CellSuppMin( Cut_Cell_t * pCell );
+static void Cut_CellCrossBar( Cut_Cell_t * pCell );
+
+
+static Cut_CMan_t * s_pCMan = NULL;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start the precomputation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellLoad()
+{
+ FILE * pFile;
+ char * pFileName = "cells22_daomap_iwls.txt";
+ char pString[1000];
+ Cut_CMan_t * p;
+ Cut_Cell_t * pCell;
+ int Length; //, i;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\".\n", pFileName );
+ return;
+ }
+ // start the manager
+ p = Cut_CManStart();
+ // load truth tables
+ while ( fgets(pString, 1000, pFile) )
+ {
+ Length = strlen(pString);
+ pString[Length--] = 0;
+ if ( Length == 0 )
+ continue;
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = Extra_Base2Log(Length*4);
+ pCell->nUsed = 1;
+// Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
+ Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
+ Cut_CellSuppMin( pCell );
+/*
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+*/
+ // add to the table
+ p->nTotal++;
+ if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
+ p->nGood++;
+ }
+ printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
+ fclose( pFile );
+// return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Precomputes truth tables for the 2x2 macro cell.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellPrecompute()
+{
+ Cut_CMan_t * p;
+ Cut_Cell_t * pCell, * pTemp;
+ int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock();
+
+ p = Cut_CManStart();
+
+ // precompute truth tables
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
+/*
+ if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
+ {
+ Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
+ for ( i = 0; i < pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
+ printf( "\n" );
+ }
+*/
+/*
+ // go through symmetric roots
+ for ( k = 0; k < 5; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = i1; i2 < 22; i2++ )
+ for ( i3 = i2; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3s[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+
+ // go through partially symmetric roots
+ for ( k = 0; k < 4; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = i2; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3p[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+
+ // go through non-symmetric functions
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = 0; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = 17;
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+*/
+
+ // go through non-symmetric functions
+ for ( k = 0; k < 10; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = 0; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
+ // minimize the support
+ Cut_CellSuppMin( pCell );
+
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ {
+ p->nGood++;
+ p->nVarCounts[pCell->nVars]++;
+
+ if ( pCell->nVars )
+ for ( i = 0; i < (int)pCell->nVars-1; i++ )
+ {
+ if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ // i and i+1 can be symmetric
+ // find the end of this group
+ for ( j = i+1; j < (int)pCell->nVars; j++ )
+ if ( pCell->Store[2*i] != pCell->Store[2*j] )
+ break;
+
+ if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
+ p->nSymGroupsE[j-i]++;
+ else
+ p->nSymGroups[j-i]++;
+ i = j - 1;
+ }
+/*
+ if ( pCell->nVars == 3 )
+ {
+ Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ printf( "\n" );
+ }
+*/
+ }
+ }
+
+ printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
+ PRT( "Time", clock() - clk );
+ printf( "Cells: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nVarCounts[i] );
+ printf( "\nDiffs: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroups[i] );
+ printf( "\nEquals: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroupsE[i] );
+ printf( "\n" );
+
+ // continue adding new cells using support
+ for ( k = CUT_CELL_MVAR; k > 3; k-- )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ for ( i1 = 0; i1 < k; i1++ )
+ for ( i2 = i1+1; i2 < k; i2++ )
+ for ( c = 0; c < 3; c++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = pTemp->nVars;
+ pCell->pParent = pTemp;
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // fill in the truth table
+ Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
+ // create the cross-bar
+ pCell->CrossBar0 = i1;
+ pCell->CrossBar1 = i2;
+ pCell->CrossBarPhase = c;
+ Cut_CellCrossBar( pCell );
+ // minimize the support
+//clk2 = clock();
+ Cut_CellSuppMin( pCell );
+//p->timeSupp += clock() - clk2;
+ // canonicize
+//clk2 = clock();
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+//p->timeCanon += clock() - clk2;
+
+ // add to the table
+//clk2 = clock();
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ {
+ p->nGood++;
+ p->nVarCounts[pCell->nVars]++;
+
+ for ( i = 0; i < (int)pCell->nVars-1; i++ )
+ {
+ if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ // i and i+1 can be symmetric
+ // find the end of this group
+ for ( j = i+1; j < (int)pCell->nVars; j++ )
+ if ( pCell->Store[2*i] != pCell->Store[2*j] )
+ break;
+
+ if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
+ p->nSymGroupsE[j-i]++;
+ else
+ p->nSymGroups[j-i]++;
+ i = j - 1;
+ }
+/*
+ if ( pCell->nVars == 3 )
+ {
+ Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ printf( "\n" );
+ }
+*/
+ }
+//p->timeTable += clock() - clk2;
+ }
+
+ printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
+ PRT( "Time", clock() - clk );
+ printf( "Cells: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nVarCounts[i] );
+ printf( "\nDiffs: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroups[i] );
+ printf( "\nEquals: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroupsE[i] );
+ printf( "\n" );
+ }
+// printf( "\n" );
+ PRT( "Supp ", p->timeSupp );
+ PRT( "Canon", p->timeCanon );
+ PRT( "Table", p->timeTable );
+// Cut_CManStop( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check the table.]
+
+ Description [Returns 1 if such a truth table already exists.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell )
+{
+ Cut_Cell_t ** pSlot, * pTemp;
+ unsigned Hash;
+ Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
+ if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) )
+ *pSlot = NULL;
+ for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
+ {
+ if ( pTemp->nVars != pCell->nVars )
+ continue;
+ if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
+ return 1;
+ }
+ // the entry is new
+ pCell->pNext = *pSlot;
+ *pSlot = pCell;
+ // add it to the variable support list
+ pCell->pNextVar = p->pSameVar[pCell->nVars];
+ p->pSameVar[pCell->nVars] = pCell;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellSuppMin( Cut_Cell_t * pCell )
+{
+ static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
+ unsigned * pIn, * pOut, * pTemp;
+ int i, k, Counter, Temp;
+
+ // go backward through the support variables and remove redundant
+ for ( k = pCell->nVars - 1; k >= 0; k-- )
+ if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
+ {
+ // shift all the variables above this one
+ Counter = 0;
+ pIn = pCell->uTruth; pOut = uTemp;
+ for ( i = k; i < (int)pCell->nVars - 1; i++ )
+ {
+ Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ // swap the support vars
+ Temp = pCell->CanonPerm[i];
+ pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
+ pCell->CanonPerm[i+1] = Temp;
+ Counter++;
+ }
+ // return the function back into its place
+ if ( Counter & 1 )
+ Extra_TruthCopy( pOut, pIn, pCell->nVars );
+ // remove one variable
+ pCell->nVars--;
+// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellCrossBar( Cut_Cell_t * pCell )
+{
+ static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
+ static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
+ Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
+ Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
+ if ( pCell->CanonPhase == 0 )
+ {
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else if ( pCell->CanonPhase == 1 )
+ {
+ Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else if ( pCell->CanonPhase == 2 )
+ {
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else assert( 0 );
+ Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i;
+
+ assert( Type < 22 );
+ switch ( Type )
+ {
+ // " 0\n", // 00 const 0
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = 0;
+ return;
+ // " 1\n", // 01 const 1
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = 0xFFFFFFFF;
+ return;
+ // "1 1\n", // 02 a
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i];
+ return;
+ // "11 1\n", // 03 ab
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & InB[i];
+ return;
+ // "11 0\n", // 04 (ab)'
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & InB[i]);
+ return;
+ // "10 1\n01 1\n", // 05 a<+>b
+ case 5:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ InB[i];
+ return;
+ // "111 1\n", // 06 + abc
+ case 6:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & InB[i] & InC[i];
+ return;
+ // "111 0\n", // 07 (abc)'
+ case 7:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & InB[i] & InC[i]);
+ return;
+ // "11- 1\n1-1 1\n", // 08 + a(b+c)
+ case 8:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & (InB[i] | InC[i]);
+ return;
+ // "11- 0\n1-1 0\n", // 09 (a(b+c))'
+ case 9:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
+ return;
+ // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
+ case 10:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ InB[i] ^ InC[i];
+ return;
+ // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
+ case 11:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ (InB[i] & InC[i]);
+ return;
+ // "101 1\n110 1\n", // 12 + a(b<+>c)
+ case 12:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & (InB[i] ^ InC[i]);
+ return;
+ // "101 0\n110 0\n", // 13 (a(b<+>c))'
+ case 13:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
+ return;
+ // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
+ case 14:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
+ return;
+ // "111 1\n000 1\n", // 15 + abc+a'b'c'
+ case 15:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
+ return;
+ // "111 0\n000 0\n", // 16 (abc+a'b'c')'
+ case 16:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
+ return;
+ // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
+ case 17:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
+ return;
+ // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
+ case 18:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
+ return;
+ // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
+ case 19:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
+ return;
+ // "100 1\n-11 1\n", // 20 + ab'c'+bc
+ case 20:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
+ return;
+ // "100 0\n-11 0\n" // 21 (ab'c'+bc)'
+ case 21:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
+ return;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Start the precomputation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_CMan_t * Cut_CManStart()
+{
+ Cut_CMan_t * p;
+ int i, k;
+ // start the manager
+ assert( sizeof(unsigned) == 4 );
+ p = ALLOC( Cut_CMan_t, 1 );
+ memset( p, 0, sizeof(Cut_CMan_t) );
+ // start the table and the memory manager
+ p->tTable = st_init_table(st_ptrcmp,st_ptrhash);
+ p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
+ // set elementary truth tables
+ for ( k = 0; k < CUT_CELL_MVAR; k++ )
+ for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
+ if ( i & (1 << k) )
+ p->uInputs[k][i/32] |= (1 << (i%32));
+ s_pCMan = p;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CManStop( Cut_CMan_t * p )
+{
+ st_free_table( p->tTable );
+ Extra_MmFixedStop( p->pMem, 0 );
+ free( p );
+}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellIsRunning()
+{
+ return s_pCMan != NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellDumpToFile()
+{
+ FILE * pFile;
+ Cut_CMan_t * p = s_pCMan;
+ Cut_Cell_t * pTemp;
+ char * pFileName = "celllib22.txt";
+ int NumUsed[10][5] = {{0}};
+ int BoxUsed[22][5] = {{0}};
+ int i, k, Counter;
+ int clk = clock();
+
+ if ( p == NULL )
+ {
+ printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
+ return;
+ }
+
+ // count the number of cells used
+ for ( k = CUT_CELL_MVAR; k >= 0; k-- )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ {
+ if ( pTemp->nUsed == 0 )
+ NumUsed[k][0]++;
+ else if ( pTemp->nUsed < 10 )
+ NumUsed[k][1]++;
+ else if ( pTemp->nUsed < 100 )
+ NumUsed[k][2]++;
+ else if ( pTemp->nUsed < 1000 )
+ NumUsed[k][3]++;
+ else
+ NumUsed[k][4]++;
+
+ for ( i = 0; i < 4; i++ )
+ if ( pTemp->nUsed == 0 )
+ BoxUsed[ pTemp->Box[i] ][0]++;
+ else if ( pTemp->nUsed < 10 )
+ BoxUsed[ pTemp->Box[i] ][1]++;
+ else if ( pTemp->nUsed < 100 )
+ BoxUsed[ pTemp->Box[i] ][2]++;
+ else if ( pTemp->nUsed < 1000 )
+ BoxUsed[ pTemp->Box[i] ][3]++;
+ else
+ BoxUsed[ pTemp->Box[i] ][4]++;
+ }
+ }
+
+ printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
+ for ( k = 0; k <= CUT_CELL_MVAR; k++ )
+ {
+ printf( "%3d : ", k );
+ for ( i = 0; i < 5; i++ )
+ printf( "%8d ", NumUsed[k][i] );
+ printf( "\n" );
+ }
+ printf( "Box usage:\n" );
+ for ( k = 0; k < 22; k++ )
+ {
+ printf( "%3d : ", k );
+ for ( i = 0; i < 5; i++ )
+ printf( "%8d ", BoxUsed[k][i] );
+ printf( " %s", s_NP3Names[k] );
+ printf( "\n" );
+ }
+
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
+ return;
+ }
+
+ Counter = 0;
+ for ( k = 0; k <= CUT_CELL_MVAR; k++ )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ if ( pTemp->nUsed > 0 )
+ {
+ Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
+ fprintf( pFile, "\n" );
+ Counter++;
+ }
+ fprintf( pFile, "\n" );
+ }
+ fclose( pFile );
+
+ printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
+
+ PRT( "Time", clock() - clk );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Looks up if the given function exists in the hash table.]
+
+ Description [If the function exists, returns 1, meaning that it can be
+ implemented using two levels of 3-input LUTs. If the function does not
+ exist, return 0.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
+{
+ Cut_CMan_t * p = s_pCMan;
+ Cut_Cell_t * pTemp;
+ Cut_Cell_t Cell, * pCell = &Cell;
+ unsigned Hash;
+ int i;
+
+ // cell manager is not defined
+ if ( p == NULL )
+ {
+ printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
+ return 0;
+ }
+
+ // canonicize
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = nVars;
+ Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
+ Cut_CellSuppMin( pCell );
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+
+
+ // check if the cell exists
+ Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
+ if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) )
+ {
+ for ( ; pTemp; pTemp = pTemp->pNext )
+ {
+ if ( pTemp->nVars != pCell->nVars )
+ continue;
+ if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
+ {
+ pTemp->nUsed++;
+ p->nCellFound++;
+ return 1;
+ }
+ }
+ }
+ p->nCellNotFound++;
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/cut/cutSeq.c b/src/opt/cut/cutSeq.c
index 4b8738a2..d36f94f7 100644
--- a/src/opt/cut/cutSeq.c
+++ b/src/opt/cut/cutSeq.c
@@ -109,9 +109,9 @@ void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int
// merge the old and the new
clk = clock();
Cut_ListStart( pSuper );
- Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0 );
- Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0 );
- Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv );
+ Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0, 0 );
+ Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0, 0 );
+ Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv, 0 );
pListNew = Cut_ListFinish( pSuper );
p->timeMerge += clock() - clk;
diff --git a/src/opt/cut/cutTruth.c b/src/opt/cut/cutTruth.c
index b65e5eff..54b3aac0 100644
--- a/src/opt/cut/cutTruth.c
+++ b/src/opt/cut/cutTruth.c
@@ -20,17 +20,27 @@
#include "cutInt.h"
+/*
+ Truth tables computed in this package are represented as bit-strings
+ stored in the cut data structure. Cuts of any number of inputs have
+ the truth table with 2^k bits, where k is the max number of cut inputs.
+*/
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern int nTotal = 0;
+extern int nGood = 0;
+extern int nEqual = 0;
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Performs truth table computation.]
+ Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]
Description []
@@ -60,6 +70,48 @@ static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 )
Synopsis [Performs truth table computation.]
+ Description [This procedure cannot be used while recording oracle
+ because it will overwrite Num0 and Num1.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_TruthNCanonicize( Cut_Cut_t * pCut )
+{
+ unsigned uTruth;
+ unsigned * uCanon2;
+ char * pPhases2;
+ assert( pCut->nVarsMax < 6 );
+
+ // get the direct truth table
+ uTruth = *Cut_CutReadTruth(pCut);
+
+ // compute the direct truth table
+ Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
+// uCanon[0] = uCanon2[0];
+// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
+// uPhases[0] = pPhases2[0];
+ pCut->uCanon0 = uCanon2[0];
+ pCut->Num0 = pPhases2[0];
+
+ // get the complemented truth table
+ uTruth = ~*Cut_CutReadTruth(pCut);
+
+ // compute the direct truth table
+ Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
+// uCanon[0] = uCanon2[0];
+// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
+// uPhases[0] = pPhases2[0];
+ pCut->uCanon1 = uCanon2[0];
+ pCut->Num1 = pPhases2[0];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs truth table computation.]
+
Description []
SideEffects []
@@ -67,7 +119,7 @@ static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 )
SeeAlso []
***********************************************************************/
-void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
+void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
static unsigned uTruth0[8], uTruth1[8];
int nTruthWords = Cut_TruthWords( pCut->nVarsMax );
@@ -111,43 +163,55 @@ void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, i
Synopsis [Performs truth table computation.]
- Description [This procedure cannot be used while recording oracle
- because it will overwrite Num0 and Num1.]
+ Description []
SideEffects []
SeeAlso []
***********************************************************************/
-void Cut_TruthCanonicize( Cut_Cut_t * pCut )
+void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
- unsigned uTruth;
- unsigned * uCanon2;
- char * pPhases2;
- assert( pCut->nVarsMax < 6 );
-
- // get the direct truth table
- uTruth = *Cut_CutReadTruth(pCut);
-
- // compute the direct truth table
- Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
-// uCanon[0] = uCanon2[0];
-// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
-// uPhases[0] = pPhases2[0];
- pCut->uCanon0 = uCanon2[0];
- pCut->Num0 = pPhases2[0];
+ // permute the first table
+ if ( fCompl0 )
+ Extra_TruthNot( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax );
+ else
+ Extra_TruthCopy( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax );
+ Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut0) );
+ // permute the second table
+ if ( fCompl1 )
+ Extra_TruthNot( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax );
+ else
+ Extra_TruthCopy( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax );
+ Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut1) );
+ // produce the resulting table
+ if ( pCut->fCompl )
+ Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
+ else
+ Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
+ // quit if no fancy computation is needed
+ if ( !p->pParams->fFancy )
+ return;
+
+ // count the total number of truth tables computed
+ nTotal++;
+
+ // MAPPING INTO ALTERA 6-2 LOGIC BLOCKS
+ // call this procedure to find the minimum number of common variables in the cofactors
+ // if this number is less or equal than 3, the cut can be implemented using the 6-2 logic block
+// if ( Extra_TruthMinCofSuppOverlap( Cut_CutReadTruth(pCut), pCut->nVarsMax, NULL ) <= 3 )
+// nGood++;
+
+ // MAPPING INTO ACTEL 2x2 CELLS
+ // call this procedure to see if a semi-canonical form can be found in the lookup table
+ // (if it exists, then a two-level 3-input LUT implementation of the cut exists)
+ // Before this procedure is called, cell manager should be defined by calling
+ // Cut_CellLoad (make sure file "cells22_daomap_iwls.txt" is available in the working dir)
+ if ( Cut_CellIsRunning() && pCut->nVarsMax <= 9 )
+ nGood += Cut_CellTruthLookup( Cut_CutReadTruth(pCut), pCut->nVarsMax );
+}
- // get the complemented truth table
- uTruth = ~*Cut_CutReadTruth(pCut);
- // compute the direct truth table
- Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
-// uCanon[0] = uCanon2[0];
-// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
-// uPhases[0] = pPhases2[0];
- pCut->uCanon1 = uCanon2[0];
- pCut->Num1 = pPhases2[0];
-}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/opt/cut/module.make b/src/opt/cut/module.make
index af2d8fc1..132e730b 100644
--- a/src/opt/cut/module.make
+++ b/src/opt/cut/module.make
@@ -4,5 +4,6 @@ SRC += src/opt/cut/cutApi.c \
src/opt/cut/cutMerge.c \
src/opt/cut/cutNode.c \
src/opt/cut/cutOracle.c \
+ src/opt/cut/cutPre22.c \
src/opt/cut/cutSeq.c \
src/opt/cut/cutTruth.c
diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c
index b83a524f..55132a75 100644
--- a/src/opt/rwr/rwrEva.c
+++ b/src/opt/rwr/rwrEva.c
@@ -66,7 +66,7 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int
Required = fUpdateLevel? Abc_NodeReadRequiredLevel(pNode) : ABC_INFINITY;
// get the node's cuts
clk = clock();
- pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0 );
+ pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
assert( pCut != NULL );
p->timeCut += clock() - clk;
diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c
index 63a437ce..92a39f0a 100644
--- a/src/sat/aig/rwrTruth.c
+++ b/src/sat/aig/rwrTruth.c
@@ -95,7 +95,7 @@ static inline int Aig_WordCountOnes( unsigned val )
val = (val & 0x33333333) + ((val>>2) & 0x33333333);
val = (val & 0x0F0F0F0F) + ((val>>4) & 0x0F0F0F0F);
val = (val & 0x00FF00FF) + ((val>>8) & 0x00FF00FF);
- return (val & 0x0000FFFF) + (val>>8);
+ return (val & 0x0000FFFF) + (val>>16);
}
/**Function*************************************************************
diff --git a/src/sat/asat/added.c b/src/sat/asat/added.c
index 497087fb..e1b1bb2a 100644
--- a/src/sat/asat/added.c
+++ b/src/sat/asat/added.c
@@ -41,6 +41,7 @@ static inline int lit_sign(lit l) { return (l & 1); }
static void Asat_ClauseWriteDimacs( FILE * pFile, clause * pC, bool fIncrement );
+extern void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -77,6 +78,7 @@ void Asat_SolverWriteDimacs( solver * p, char * pFileName, lit* assumptionsBegin
return;
}
fprintf( pFile, "c CNF generated by ABC on %s\n", Extra_TimeStamp() );
+// Io_WriteCnfOutputPiMapping( pFile, incrementVars );
fprintf( pFile, "p cnf %d %d\n", p->size, nClauses );
// write the original clauses
@@ -161,6 +163,31 @@ int * solver_get_model( solver * p, int * pVars, int nVars )
return pModel;
}
+/**Function*************************************************************
+
+ Synopsis [Writes the given clause in a file in DIMACS format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_SatPrintStats( FILE * pFile, solver * p )
+{
+ printf( "Start = %4d. Conf = %6d. Dec = %6d. Prop = %7d. Insp = %8d.\n",
+ (int)p->solver_stats.starts,
+ (int)p->solver_stats.conflicts,
+ (int)p->solver_stats.decisions,
+ (int)p->solver_stats.propagations,
+ (int)p->solver_stats.inspects );
+ printf( "Total runtime = %7.2f sec. Var select = %7.2f sec. Var update = %7.2f sec.\n",
+ (float)(p->timeTotal)/(float)(CLOCKS_PER_SEC),
+ (float)(p->timeSelect)/(float)(CLOCKS_PER_SEC),
+ (float)(p->timeUpdate)/(float)(CLOCKS_PER_SEC) );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/asat/jfront.c b/src/sat/asat/jfront.c
new file mode 100644
index 00000000..1def6a37
--- /dev/null
+++ b/src/sat/asat/jfront.c
@@ -0,0 +1,514 @@
+/**CFile****************************************************************
+
+ FileName [jfront.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [C-language MiniSat solver.]
+
+ Synopsis [Implementation of J-frontier.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: jfront.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <assert.h>
+#include "solver.h"
+#include "extra.h"
+#include "vec.h"
+
+/*
+ At any time during the solving process, the J-frontier is the set of currently
+ unassigned variables, each of which has at least one fanin/fanout variable that
+ is currently assigned. In the context of a CNF-based solver, default decisions
+ based on variable activity are modified to choose the most active variable among
+ those currently on the J-frontier.
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// variable on the J-frontier
+typedef struct Asat_JVar_t_ Asat_JVar_t;
+struct Asat_JVar_t_
+{
+ unsigned int Num; // variable number
+ unsigned int nRefs; // the number of adjacent assigned vars
+ unsigned int Prev; // the previous variable
+ unsigned int Next; // the next variable
+ unsigned int nFans; // the number of fanins/fanouts
+ unsigned int Fans[0]; // the fanin/fanout variables
+};
+
+// the J-frontier as a ring of variables
+// (ring is used instead of list because it allows to control the insertion point)
+typedef struct Asat_JRing_t_ Asat_JRing_t;
+struct Asat_JRing_t_
+{
+ Asat_JVar_t * pRoot; // the pointer to the root
+ int nItems; // the number of variables in the ring
+};
+
+// the J-frontier manager
+struct Asat_JMan_t_
+{
+ solver * pSat; // the SAT solver
+ Asat_JRing_t rVars; // the ring of variables
+ Vec_Ptr_t * vVars; // the pointers to variables
+ Extra_MmFlex_t * pMem; // the memory manager for variables
+};
+
+// getting hold of the given variable
+static inline Asat_JVar_t * Asat_JManVar( Asat_JMan_t * p, int Num ) { return !Num? NULL : Vec_PtrEntry(p->vVars, Num); }
+static inline Asat_JVar_t * Asat_JVarPrev( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Prev); }
+static inline Asat_JVar_t * Asat_JVarNext( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Next); }
+
+//The solver can communicate to the variable order the following parts:
+//- the array of current assignments (pSat->pAssigns)
+//- the array of variable activities (pSat->pdActivity)
+//- the array of variables currently in the cone
+//- the array of arrays of variables adjacent to each other
+
+static inline int Asat_JVarIsInBoundary( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return pVar->Next > 0; }
+static inline int Asat_JVarIsAssigned( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return p->pSat->assigns[pVar->Num] != l_Undef; }
+//static inline int Asat_JVarIsUsedInCone( Asat_JMan_t * p, int Var ) { return p->pSat->vVarsUsed->pArray[i]; }
+
+// manipulating the ring of variables
+static void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar );
+static void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar );
+
+// iterator through the entries in J-boundary
+#define Asat_JRingForEachEntry( p, pVar, pNext ) \
+ for ( pVar = p->rVars.pRoot, \
+ pNext = pVar? Asat_JVarNext(p, pVar) : NULL; \
+ pVar; \
+ pVar = (pNext != p->rVars.pRoot)? pNext : NULL, \
+ pNext = pVar? Asat_JVarNext(p, pVar) : NULL )
+
+// iterator through the adjacent variables
+#define Asat_JVarForEachFanio( p, pVar, pFan, i ) \
+ for ( i = 0; (i < pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ )
+
+extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start the J-frontier.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Asat_JMan_t * Asat_JManStart( solver * pSat, void * pCircuit )
+{
+ Vec_Vec_t * vCircuit = pCircuit;
+ Asat_JMan_t * p;
+ Asat_JVar_t * pVar;
+ Vec_Int_t * vConnect;
+ int i, nBytes, Entry, k;
+ // make sure the number of variables is less than sizeof(unsigned int)
+ assert( Vec_VecSize(vCircuit) < (1 << 16) );
+ assert( Vec_VecSize(vCircuit) == pSat->size );
+ // allocate the manager
+ p = ALLOC( Asat_JMan_t, 1 );
+ memset( p, 0, sizeof(Asat_JMan_t) );
+ p->pSat = pSat;
+ p->pMem = Extra_MmFlexStart();
+ // fill in the variables
+ p->vVars = Vec_PtrAlloc( Vec_VecSize(vCircuit) );
+ for ( i = 0; i < Vec_VecSize(vCircuit); i++ )
+ {
+ vConnect = Vec_VecEntry( vCircuit, i );
+ nBytes = sizeof(Asat_JVar_t) + sizeof(int) * Vec_IntSize(vConnect);
+ nBytes = sizeof(void *) * (nBytes / sizeof(void *) + ((nBytes % sizeof(void *)) != 0));
+ pVar = (Asat_JVar_t *)Extra_MmFlexEntryFetch( p->pMem, nBytes );
+ memset( pVar, 0, nBytes );
+ pVar->Num = i;
+ // add fanins/fanouts
+ pVar->nFans = Vec_IntSize( vConnect );
+ Vec_IntForEachEntry( vConnect, Entry, k )
+ pVar->Fans[k] = Entry;
+ // add the variable
+ Vec_PtrPush( p->vVars, pVar );
+ }
+ // set the current assignments
+ Vec_PtrForEachEntryStart( p->vVars, pVar, i, 1 )
+ {
+// if ( !Asat_JVarIsUsedInCone(p, pVar) )
+// continue;
+ // skip assigned vars, vars in the boundary, and vars not used in the cone
+ if ( Asat_JVarIsAssigned(p, pVar) )
+ Asat_JManAssign( p, pVar->Num );
+ }
+
+ pSat->pJMan = p;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the J-frontier.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_JManStop( solver * pSat )
+{
+ Asat_JMan_t * p = pSat->pJMan;
+ if ( p == NULL )
+ return;
+ pSat->pJMan = NULL;
+ Extra_MmFlexStop( p->pMem, 0 );
+ Vec_PtrFree( p->vVars );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Asat_JManCheck( Asat_JMan_t * p )
+{
+ Asat_JVar_t * pVar, * pNext, * pFan;
+// Msat_IntVec_t * vRound;
+// int * pRound, nRound;
+// int * pVars, nVars, i, k;
+ int i, k;
+ int Counter = 0;
+
+ // go through all the variables in the boundary
+ Asat_JRingForEachEntry( p, pVar, pNext )
+ {
+ assert( !Asat_JVarIsAssigned(p, pVar) );
+ // go though all the variables in the neighborhood
+ // and check that it is true that there is least one assigned
+// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVar->Num );
+// nRound = Msat_IntVecReadSize( vRound );
+// pRound = Msat_IntVecReadArray( vRound );
+// for ( i = 0; i < nRound; i++ )
+ Asat_JVarForEachFanio( p, pVar, pFan, i )
+ {
+// if ( !Asat_JVarIsUsedInCone(p, pFan) )
+// continue;
+ if ( Asat_JVarIsAssigned(p, pFan) )
+ break;
+ }
+// assert( i != pVar->nFans );
+// if ( i == pVar->nFans )
+// return 0;
+ if ( i == pVar->nFans )
+ Counter++;
+ }
+ if ( Counter > 0 )
+ printf( "%d(%d) ", Counter, p->rVars.nItems );
+
+ // we may also check other unassigned variables in the cone
+ // to make sure that if they are not in J-boundary,
+ // then they do not have an assigned neighbor
+// nVars = Msat_IntVecReadSize( p->pSat->vConeVars );
+// pVars = Msat_IntVecReadArray( p->pSat->vConeVars );
+// for ( i = 0; i < nVars; i++ )
+ Vec_PtrForEachEntry( p->vVars, pVar, i )
+ {
+// assert( Asat_JVarIsUsedInCone(p, pVar) );
+ // skip assigned vars, vars in the boundary, and vars not used in the cone
+ if ( Asat_JVarIsAssigned(p, pVar) || Asat_JVarIsInBoundary(p, pVar) )
+ continue;
+ // make sure, it does not have assigned neighbors
+// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
+// nRound = Msat_IntVecReadSize( vRound );
+// pRound = Msat_IntVecReadArray( vRound );
+// for ( i = 0; i < nRound; i++ )
+ Asat_JVarForEachFanio( p, pVar, pFan, k )
+ {
+// if ( !Asat_JVarIsUsedInCone(p, pFan) )
+// continue;
+ if ( Asat_JVarIsAssigned(p, pFan) )
+ break;
+ }
+// assert( k == pVar->nFans );
+// if ( k != pVar->nFans )
+// return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_JManAssign( Asat_JMan_t * p, int Var )
+{
+// Msat_IntVec_t * vRound;
+ Asat_JVar_t * pVar, * pFan;
+ int i, clk = clock();
+
+ // make sure the variable is in the boundary
+ assert( Var < Vec_PtrSize(p->vVars) );
+ // if it is not in the boundary (initial decision, random decision), do not remove
+ pVar = Asat_JManVar( p, Var );
+ if ( Asat_JVarIsInBoundary( p, pVar ) )
+ Asat_JRingRemove( p, pVar );
+ // add to the boundary those neighbors that are (1) unassigned, (2) not in boundary
+ // because for them we know that there is a variable (Var) which is assigned
+// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
+// for ( i = 0; i < vRound->nSize; i++ )
+ Asat_JVarForEachFanio( p, pVar, pFan, i )
+ {
+// if ( !Asat_JVarIsUsedInCone(p, pFan) )
+// continue;
+ pFan->nRefs++;
+ if ( Asat_JVarIsAssigned(p, pFan) || Asat_JVarIsInBoundary(p, pFan) )
+ continue;
+ Asat_JRingAddLast( p, pFan );
+ }
+//timeSelect += clock() - clk;
+// Asat_JManCheck( p );
+ p->pSat->timeUpdate += clock() - clk;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_JManUnassign( Asat_JMan_t * p, int Var )
+{
+// Msat_IntVec_t * vRound, * vRound2;
+ Asat_JVar_t * pVar, * pFan;
+ int i, clk = clock();//, k
+
+ // make sure the variable is not in the boundary
+ assert( Var < Vec_PtrSize(p->vVars) );
+ pVar = Asat_JManVar( p, Var );
+ assert( !Asat_JVarIsInBoundary( p, pVar ) );
+ // go through its neigbors - if one of them is assigned add this var
+ // add to the boundary those neighbors that are not there already
+ // this will also get rid of variable outside of the current cone
+ // because they are unassigned in Msat_SolverPrepare()
+// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
+// for ( i = 0; i < vRound->nSize; i++ )
+// if ( Asat_JVarIsAssigned(p, vRound->pArray[i]) )
+// break;
+// if ( i != vRound->nSize )
+// Asat_JRingAddLast( &p->rVars, &p->pVars[Var] );
+ if ( pVar->nRefs != 0 )
+ Asat_JRingAddLast( p, pVar );
+
+/*
+ // unassigning a variable may lead to its adjacents dropping from the boundary
+ for ( i = 0; i < vRound->nSize; i++ )
+ if ( Asat_JVarIsInBoundary(p, vRound->pArray[i]) )
+ { // the neighbor is in the J-boundary (and unassigned)
+ assert( !Asat_JVarIsAssigned(p, vRound->pArray[i]) );
+ vRound2 = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[vRound->pArray[i]];
+ // go through its neighbors and determine if there is at least one assigned
+ for ( k = 0; k < vRound2->nSize; k++ )
+ if ( Asat_JVarIsAssigned(p, vRound2->pArray[k]) )
+ break;
+ if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
+ Asat_JRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
+ }
+*/
+ Asat_JVarForEachFanio( p, pVar, pFan, i )
+ {
+// if ( !Asat_JVarIsUsedInCone(p, pFan) )
+// continue;
+ assert( pFan->nRefs > 0 );
+ pFan->nRefs--;
+ if ( !Asat_JVarIsInBoundary(p, pFan) )
+ continue;
+ // the neighbor is in the J-boundary (and unassigned)
+ assert( !Asat_JVarIsAssigned(p, pFan) );
+ // if there is no assigned vars, delete this one
+ if ( pFan->nRefs == 0 )
+ Asat_JRingRemove( p, pFan );
+ }
+
+//timeSelect += clock() - clk;
+// Asat_JManCheck( p );
+ p->pSat->timeUpdate += clock() - clk;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Asat_JManSelect( Asat_JMan_t * p )
+{
+ Asat_JVar_t * pVar, * pNext, * pVarBest;
+ double * pdActs = p->pSat->activity;
+ double dfActBest;
+ int clk = clock();
+
+ pVarBest = NULL;
+ dfActBest = -1.0;
+ Asat_JRingForEachEntry( p, pVar, pNext )
+ {
+ if ( dfActBest <= pdActs[pVar->Num] )//+ 0.00001 )
+ {
+ dfActBest = pdActs[pVar->Num];
+ pVarBest = pVar;
+ }
+ }
+//timeSelect += clock() - clk;
+//timeAssign += clock() - clk;
+//if ( pVarBest && pVarBest->Num % 1000 == 0 )
+//printf( "%d ", p->rVars.nItems );
+
+// Asat_JManCheck( p );
+ p->pSat->timeSelect += clock() - clk;
+ if ( pVarBest )
+ {
+// assert( Asat_JVarIsUsedInCone(p, pVarBest) );
+ return pVarBest->Num;
+ }
+ return var_Undef;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds node to the end of the ring.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar )
+{
+ Asat_JRing_t * pRing = &p->rVars;
+//printf( "adding %d\n", pVar->Num );
+ // check that the node is not in a ring
+ assert( pVar->Prev == 0 );
+ assert( pVar->Next == 0 );
+ // if the ring is empty, make the node point to itself
+ pRing->nItems++;
+ if ( pRing->pRoot == NULL )
+ {
+ pRing->pRoot = pVar;
+// pVar->pPrev = pVar;
+ pVar->Prev = pVar->Num;
+// pVar->pNext = pVar;
+ pVar->Next = pVar->Num;
+ return;
+ }
+ // if the ring is not empty, add it as the last entry
+// pVar->pPrev = pRing->pRoot->pPrev;
+ pVar->Prev = pRing->pRoot->Prev;
+// pVar->pNext = pRing->pRoot;
+ pVar->Next = pRing->pRoot->Num;
+// pVar->pPrev->pNext = pVar;
+ Asat_JVarPrev(p, pVar)->Next = pVar->Num;
+// pVar->pNext->pPrev = pVar;
+ Asat_JVarNext(p, pVar)->Prev = pVar->Num;
+
+ // move the root so that it points to the new entry
+// pRing->pRoot = pRing->pRoot->pPrev;
+ pRing->pRoot = Asat_JVarPrev(p, pRing->pRoot);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes the node from the ring.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar )
+{
+ Asat_JRing_t * pRing = &p->rVars;
+//printf( "removing %d\n", pVar->Num );
+ // check that the var is in a ring
+ assert( pVar->Prev );
+ assert( pVar->Next );
+ pRing->nItems--;
+ if ( pRing->nItems == 0 )
+ {
+ assert( pRing->pRoot == pVar );
+// pVar->pPrev = NULL;
+ pVar->Prev = 0;
+// pVar->pNext = NULL;
+ pVar->Next = 0;
+ pRing->pRoot = NULL;
+ return;
+ }
+ // move the root if needed
+ if ( pRing->pRoot == pVar )
+// pRing->pRoot = pVar->pNext;
+ pRing->pRoot = Asat_JVarNext(p, pVar);
+ // move the root to the next entry after pVar
+ // this way all the additions to the list will be traversed first
+// pRing->pRoot = pVar->pNext;
+ pRing->pRoot = Asat_JVarPrev(p, pVar);
+ // delete the node
+// pVar->pPrev->pNext = pVar->pNext;
+ Asat_JVarPrev(p, pVar)->Next = Asat_JVarNext(p, pVar)->Num;
+// pVar->pNext->pPrev = pVar->pPrev;
+ Asat_JVarNext(p, pVar)->Prev = Asat_JVarPrev(p, pVar)->Num;
+// pVar->pPrev = NULL;
+ pVar->Prev = 0;
+// pVar->pNext = NULL;
+ pVar->Next = 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/asat/module.make b/src/sat/asat/module.make
index d5cf69bf..26489191 100644
--- a/src/sat/asat/module.make
+++ b/src/sat/asat/module.make
@@ -1,3 +1,4 @@
SRC += src/sat/asat/added.c \
src/sat/asat/asatmem.c \
+ src/sat/asat/jfront.c \
src/sat/asat/solver.c
diff --git a/src/sat/asat/solver.c b/src/sat/asat/solver.c
index 1130d437..6d76d890 100644
--- a/src/sat/asat/solver.c
+++ b/src/sat/asat/solver.c
@@ -121,6 +121,7 @@ static inline void vec_remove(vec* v, void* e)
static inline void order_update(solver* s, int v) // updateorder
{
+// int clk = clock();
int* orderpos = s->orderpos;
double* activity = s->activity;
int* heap = (int*)vec_begin(&s->order);
@@ -138,6 +139,7 @@ static inline void order_update(solver* s, int v) // updateorder
}
heap[i] = x;
orderpos[x] = i;
+// s->timeUpdate += clock() - clk;
}
static inline void order_assigned(solver* s, int v)
@@ -146,16 +148,19 @@ static inline void order_assigned(solver* s, int v)
static inline void order_unassigned(solver* s, int v) // undoorder
{
+// int clk = clock();
int* orderpos = s->orderpos;
if (orderpos[v] == -1){
orderpos[v] = vec_size(&s->order);
vec_push(&s->order,(void*)v);
order_update(s,v);
}
+// s->timeUpdate += clock() - clk;
}
static int order_select(solver* s, float random_var_freq) // selectvar
{
+// int clk = clock();
int* heap;
double* activity;
int* orderpos;
@@ -215,9 +220,15 @@ static int order_select(solver* s, float random_var_freq) // selectvar
return next;
}
+// s->timeSelect += clock() - clk;
return var_Undef;
}
+// J-frontier
+extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
+extern void Asat_JManUnassign( Asat_JMan_t * p, int Var );
+extern int Asat_JManSelect( Asat_JMan_t * p );
+
//=================================================================================================
// Activity functions:
@@ -236,7 +247,7 @@ static inline void act_var_bump(solver* s, int v) {
//printf("bump %d %f\n", v-1, activity[v]);
- if (s->orderpos[v] != -1)
+ if ( s->pJMan == NULL && s->orderpos[v] != -1 )
order_update(s,v);
}
@@ -422,7 +433,10 @@ static inline bool enqueue(solver* s, lit l, clause* from)
reasons[v] = from;
s->trail[s->qtail++] = l;
- order_assigned(s, v);
+ if ( s->pJMan )
+ Asat_JManAssign( s->pJMan, v );
+ else
+ order_assigned(s, v);
return 1;
}
}
@@ -460,8 +474,12 @@ static inline void solver_canceluntil(solver* s, int level) {
reasons[x] = (clause*)0;
}
- for (c = s->qhead-1; c >= bound; c--)
- order_unassigned(s,lit_var(trail[c]));
+ if ( s->pJMan )
+ for (c = s->qtail-1; c >= bound; c--)
+ Asat_JManUnassign( s->pJMan, lit_var(trail[c]) );
+ else
+ for (c = s->qhead-1; c >= bound; c--)
+ order_unassigned( s, lit_var(trail[c]) );
s->qhead = s->qtail = bound;
vec_resize(&s->trail_lim,level);
@@ -803,7 +821,7 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
int* levels = s->levels;
double var_decay = 0.95;
double clause_decay = 0.999;
- double random_var_freq = 0.02;
+ double random_var_freq = 0.0;//0.02;
int conflictC = 0;
vec learnt_clause;
@@ -872,7 +890,10 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
// New variable decision:
s->solver_stats.decisions++;
- next = order_select(s,(float)random_var_freq);
+ if ( s->pJMan )
+ next = Asat_JManSelect( s->pJMan );
+ else
+ next = order_select(s,(float)random_var_freq);
if (next == var_Undef){
// Model found:
@@ -953,7 +974,10 @@ solver* solver_new(void)
#else
s->pMem = Asat_MmStepStart( 10 );
#endif
-
+ s->pJMan = NULL;
+ s->timeTotal = clock();
+ s->timeSelect = 0;
+ s->timeUpdate = 0;
return s;
}
@@ -998,6 +1022,7 @@ void solver_delete(solver* s)
free(s->tags );
}
+ if ( s->pJMan ) Asat_JManStop( s );
free(s);
}
@@ -1155,6 +1180,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit
printf("==============================================================================\n");
solver_canceluntil(s,0);
+ s->timeTotal = clock() - s->timeTotal;
return status;
}
diff --git a/src/sat/asat/solver.h b/src/sat/asat/solver.h
index 62815656..3684d259 100644
--- a/src/sat/asat/solver.h
+++ b/src/sat/asat/solver.h
@@ -64,6 +64,8 @@ static inline lit toLitCond (int v, int c) { return v + v + (int)(c != 0); }
//=================================================================================================
// Public interface:
+typedef struct Asat_JMan_t_ Asat_JMan_t;
+
struct solver_t;
typedef struct solver_t solver;
@@ -82,6 +84,12 @@ extern int solver_nclauses(solver* s);
extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
lit* assumptionsBegin, lit* assumptionsEnd,
int incrementVars);
+extern void Asat_SatPrintStats( FILE * pFile, solver * p );
+
+// J-frontier support
+extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
+extern void Asat_JManStop( solver * pSat );
+
struct stats_t
{
@@ -143,7 +151,13 @@ struct solver_t
// the memory manager
Asat_MmStep_t * pMem;
+ // J-frontier
+ Asat_JMan_t * pJMan;
+
stats solver_stats;
+ int timeTotal;
+ int timeSelect;
+ int timeUpdate;
};
#ifdef __cplusplus
diff --git a/src/sat/csat/csat_apis.c b/src/sat/csat/csat_apis.c
index 2129bfb0..9184cab9 100644
--- a/src/sat/csat/csat_apis.c
+++ b/src/sat/csat/csat_apis.c
@@ -17,6 +17,7 @@
***********************************************************************/
#include "abc.h"
+#include "fraig.h"
#include "csat_apis.h"
////////////////////////////////////////////////////////////////////////
@@ -105,6 +106,8 @@ ABC_Manager ABC_InitManager()
***********************************************************************/
void ABC_ReleaseManager( ABC_Manager mng )
{
+ CSAT_Target_ResultT * p_res = ABC_Get_Target_Result( mng,0 );
+ ABC_TargetResFree(p_res);
if ( mng->tNode2Name ) stmm_free_table( mng->tNode2Name );
if ( mng->tName2Node ) stmm_free_table( mng->tName2Node );
if ( mng->pMmNames ) Extra_MmFlexStop( mng->pMmNames, 0 );
@@ -536,6 +539,7 @@ void ABC_AnalyzeTargets( ABC_Manager mng )
***********************************************************************/
enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
{
+ Prove_Params_t Params, * pParams = &Params;
int RetValue, i;
// check if the target network is available
@@ -544,9 +548,16 @@ enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
// try to prove the miter using a number of techniques
if ( mng->mode )
- RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0 );
+ RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0, 0 );
else
- RetValue = Abc_NtkMiterProve( &mng->pTarget, mng->nConfLimit, mng->nImpLimit, 1, 1, 0 );
+ {
+ // set default parameters for CEC
+ Prove_ParamsSetDefault( pParams );
+ // set infinite resource limit for the final mitering
+ pParams->nMiteringLimitLast = ABC_INFINITY;
+ // call the checker
+ RetValue = Abc_NtkMiterProve( &mng->pTarget, pParams );
+ }
// analyze the result
mng->pResult = ABC_TargetResAlloc( Abc_NtkCiNum(mng->pTarget) );
@@ -658,6 +669,14 @@ void ABC_TargetResFree( CSAT_Target_ResultT * p )
{
if ( p == NULL )
return;
+ if( p->names )
+ {
+ int i = 0;
+ for ( i = 0; i < p->no_sig; i++ )
+ {
+ FREE(p->names[i]);
+ }
+ }
FREE( p->names );
FREE( p->values );
free( p );
diff --git a/src/sat/fraig/fraig.h b/src/sat/fraig/fraig.h
index 4e2a295e..d6215465 100644
--- a/src/sat/fraig/fraig.h
+++ b/src/sat/fraig/fraig.h
@@ -41,6 +41,7 @@ typedef struct Fraig_NodeVecStruct_t_ Fraig_NodeVec_t;
typedef struct Fraig_HashTableStruct_t_ Fraig_HashTable_t;
typedef struct Fraig_ParamsStruct_t_ Fraig_Params_t;
typedef struct Fraig_PatternsStruct_t_ Fraig_Patterns_t;
+typedef struct Prove_ParamsStruct_t_ Prove_Params_t;
struct Fraig_ParamsStruct_t_
{
@@ -61,6 +62,31 @@ struct Fraig_ParamsStruct_t_
int fInternal; // is set to 1 for internal fraig calls
};
+struct Prove_ParamsStruct_t_
+{
+ // general parameters
+ int fUseFraiging; // enables fraiging
+ int fUseRewriting; // enables rewriting
+ int fUseBdds; // enables BDD construction when other methods fail
+ int fVerbose; // prints verbose stats
+ // iterations
+ int nItersMax; // the number of iterations
+ // mitering
+ int nMiteringLimitStart; // starting mitering limit
+ float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ // rewriting
+ int nRewritingLimitStart; // the number of rewriting iterations
+ float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ // fraiging
+ int nFraigingLimitStart; // starting backtrack(conflict) limit
+ float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ // last-gasp BDD construction
+ int nBddSizeLimit; // the number of BDD nodes when construction is aborted
+ int fBddReorder; // enables dynamic BDD variable reordering
+ // last-gasp mitering
+ int nMiteringLimitLast; // final mitering limit
+};
+
////////////////////////////////////////////////////////////////////////
/// GLOBAL VARIABLES ///
////////////////////////////////////////////////////////////////////////
@@ -155,6 +181,7 @@ extern Fraig_Node_t * Fraig_NodeMux( Fraig_Man_t * p, Fraig_Node_t * pNode,
extern void Fraig_NodeSetChoice( Fraig_Man_t * pMan, Fraig_Node_t * pNodeOld, Fraig_Node_t * pNodeNew );
/*=== fraigMan.c =============================================================*/
+extern void Prove_ParamsSetDefault( Prove_Params_t * pParams );
extern void Fraig_ParamsSetDefault( Fraig_Params_t * pParams );
extern void Fraig_ParamsSetDefaultFull( Fraig_Params_t * pParams );
extern Fraig_Man_t * Fraig_ManCreate( Fraig_Params_t * pParams );
diff --git a/src/sat/fraig/fraigApi.c b/src/sat/fraig/fraigApi.c
index 3b8da17f..b4bdbcab 100644
--- a/src/sat/fraig/fraigApi.c
+++ b/src/sat/fraig/fraigApi.c
@@ -65,7 +65,7 @@ int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p ) {
// returns the number of dynamic patterns proved useful to distinquish some FRAIG nodes (this number is more than 0 after the first garbage collection of patterns)
int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p ) { return p->iPatsPerm; }
// returns the number of times FRAIG package timed out
-int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFails; }
+int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFailsReal; }
/**Function*************************************************************
diff --git a/src/sat/fraig/fraigInt.h b/src/sat/fraig/fraigInt.h
index 890af13c..8e016331 100644
--- a/src/sat/fraig/fraigInt.h
+++ b/src/sat/fraig/fraigInt.h
@@ -189,7 +189,8 @@ struct Fraig_ManStruct_t_
int nSatCalls; // the number of times equivalence checking was called
int nSatProof; // the number of times a proof was found
int nSatCounter; // the number of times a counter example was found
- int nSatFails; // the number of times the SAT solver failed to complete
+ int nSatFails; // the number of times the SAT solver failed to complete due to resource limit or prediction
+ int nSatFailsReal; // the number of times the SAT solver failed to complete due to resource limit
int nSatCallsImp; // the number of times equivalence checking was called
int nSatProofImp; // the number of times a proof was found
@@ -243,8 +244,9 @@ struct Fraig_NodeStruct_t_
unsigned fMark3 : 1; // the mark used for traversals
unsigned fFeedUse : 1; // the presence of the variable in the feedback
unsigned fFeedVal : 1; // the value of the variable in the feedback
+ unsigned fFailTfo : 1; // the node is in the TFO of the failed SAT run
unsigned nFanouts : 2; // the indicator of fanouts (none, one, or many)
- unsigned nOnes : 21; // the number of 1's in the random sim info
+ unsigned nOnes : 20; // the number of 1's in the random sim info
// the children of the node
Fraig_Node_t * p1; // the first child
diff --git a/src/sat/fraig/fraigMan.c b/src/sat/fraig/fraigMan.c
index ff6faa33..3268ac3a 100644
--- a/src/sat/fraig/fraigMan.c
+++ b/src/sat/fraig/fraigMan.c
@@ -40,6 +40,42 @@ int timeAssign;
SeeAlso []
***********************************************************************/
+void Prove_ParamsSetDefault( Prove_Params_t * pParams )
+{
+ // general parameters
+ pParams->fUseFraiging = 1; // enables fraiging
+ pParams->fUseRewriting = 1; // enables rewriting
+ pParams->fUseBdds = 1; // enables BDD construction when other methods fail
+ pParams->fVerbose = 0; // prints verbose stats
+ // iterations
+ pParams->nItersMax = 6; // the number of iterations
+ // mitering
+ pParams->nMiteringLimitStart = 1000; // starting mitering limit
+ pParams->nMiteringLimitMulti = 2.0; // multiplicative coefficient to increase the limit in each iteration
+ // rewriting
+ pParams->nRewritingLimitStart = 3; // the number of rewriting iterations
+ pParams->nRewritingLimitMulti = 1.0; // multiplicative coefficient to increase the limit in each iteration
+ // fraiging
+ pParams->nFraigingLimitStart = 2; // starting backtrack(conflict) limit
+ pParams->nFraigingLimitMulti = 8.0; // multiplicative coefficient to increase the limit in each iteration
+ // last-gasp BDD construction
+ pParams->nBddSizeLimit = 1000000; // the number of BDD nodes when construction is aborted
+ pParams->fBddReorder = 1; // enables dynamic BDD variable reordering
+ // last-gasp mitering
+ pParams->nMiteringLimitLast = 1000000; // final mitering limit
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default parameters of the package.]
+
+ Description [This set of parameters is tuned for equivalence checking.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Fraig_ParamsSetDefault( Fraig_Params_t * pParams )
{
memset( pParams, 0, sizeof(Fraig_Params_t) );
@@ -271,8 +307,8 @@ void Fraig_ManPrintStats( Fraig_Man_t * p )
(sizeof(Fraig_Node_t) + sizeof(unsigned)*(p->nWordsRand + p->nWordsDyna) /*+ p->nSuppWords*sizeof(unsigned)*/))/(1<<20);
printf( "Words: Random = %d. Dynamic = %d. Used = %d. Memory = %0.2f Mb.\n",
p->nWordsRand, p->nWordsDyna, p->iWordPerm, nMemory );
- printf( "Proof = %d. Counter-example = %d. Fail = %d. Zero = %d.\n",
- p->nSatProof, p->nSatCounter, p->nSatFails, p->nSatZeros );
+ printf( "Proof = %d. Counter-example = %d. Fail = %d. FailReal = %d. Zero = %d.\n",
+ p->nSatProof, p->nSatCounter, p->nSatFails, p->nSatFailsReal, p->nSatZeros );
printf( "Nodes: Final = %d. Total = %d. Mux = %d. (Exor = %d.) ClaVars = %d.\n",
Fraig_CountNodes(p,0), p->vNodes->nSize, Fraig_ManCountMuxes(p), Fraig_ManCountExors(p), p->nVarsClauses );
if ( p->pSat ) Msat_SolverPrintStats( p->pSat );
diff --git a/src/sat/fraig/fraigNode.c b/src/sat/fraig/fraigNode.c
index 84509e9e..6e3d3c7d 100644
--- a/src/sat/fraig/fraigNode.c
+++ b/src/sat/fraig/fraigNode.c
@@ -176,6 +176,7 @@ Fraig_Node_t * Fraig_NodeCreate( Fraig_Man_t * p, Fraig_Node_t * p1, Fraig_Node_
// compute the level of this node
pNode->Level = 1 + FRAIG_MAX(Fraig_Regular(p1)->Level, Fraig_Regular(p2)->Level);
pNode->fInv = Fraig_NodeIsSimComplement(p1) & Fraig_NodeIsSimComplement(p2);
+ pNode->fFailTfo = Fraig_Regular(p1)->fFailTfo | Fraig_Regular(p2)->fFailTfo;
// derive the simulation info
clk = clock();
diff --git a/src/sat/fraig/fraigPrime.c b/src/sat/fraig/fraigPrime.c
index 9745b7e6..127ad478 100644
--- a/src/sat/fraig/fraigPrime.c
+++ b/src/sat/fraig/fraigPrime.c
@@ -22,7 +22,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-// The 1,000 smallest prime numbers used to compute the hash value
+// The 1,024 smallest prime numbers used to compute the hash value
// http://www.math.utah.edu/~alfeld/math/primelist.html
int s_FraigPrimes[FRAIG_MAX_PRIMES] = { 2, 3, 5,
7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
@@ -93,7 +93,9 @@ int s_FraigPrimes[FRAIG_MAX_PRIMES] = { 2, 3, 5,
7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603,
7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873,
-7877, 7879, 7883, 7901, 7907, 7919 };
+7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123,
+8147, 8161 };
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
diff --git a/src/sat/fraig/fraigSat.c b/src/sat/fraig/fraigSat.c
index d4358772..aa28a4f2 100644
--- a/src/sat/fraig/fraigSat.c
+++ b/src/sat/fraig/fraigSat.c
@@ -17,6 +17,7 @@
***********************************************************************/
#include "fraigInt.h"
+#include "math.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -304,6 +305,20 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t *
assert( !Fraig_IsComplement(pOld) );
assert( pNew != pOld );
+ // if at least one of the nodes is a failed node, perform adjustments:
+ // if the backtrack limit is small, simply skip this node
+ // if the backtrack limit is > 10, take the quare root of the limit
+ if ( nBTLimit > 0 && (pOld->fFailTfo || pNew->fFailTfo) )
+ {
+ p->nSatFails++;
+// return 0;
+// if ( nBTLimit > 10 )
+// nBTLimit /= 10;
+ if ( nBTLimit <= 10 )
+ return 0;
+ nBTLimit = (int)sqrt(nBTLimit);
+ }
+
p->nSatCalls++;
// make sure the solver is allocated and has enough variables
@@ -394,13 +409,27 @@ PRT( "time", clock() - clk );
// record the counter example
Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
+
+// if ( pOld->fFailTfo || pNew->fFailTfo )
+// printf( "*" );
+// printf( "s(%d)", pNew->Level );
p->nSatCounter++;
return 0;
}
else // if ( RetValue1 == MSAT_UNKNOWN )
{
p->time3 += clock() - clk;
- p->nSatFails++;
+
+// if ( pOld->fFailTfo || pNew->fFailTfo )
+// printf( "*" );
+// printf( "T(%d)", pNew->Level );
+
+ // mark the node as the failed node
+ if ( pOld != p->pConst1 )
+ pOld->fFailTfo = 1;
+ pNew->fFailTfo = 1;
+// p->nSatFails++;
+ p->nSatFailsReal++;
return 0;
}
@@ -454,17 +483,34 @@ PRT( "time", clock() - clk );
// record the counter example
Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
p->nSatCounter++;
+
+// if ( pOld->fFailTfo || pNew->fFailTfo )
+// printf( "*" );
+// printf( "s(%d)", pNew->Level );
return 0;
}
else // if ( RetValue1 == MSAT_UNKNOWN )
{
p->time3 += clock() - clk;
- p->nSatFails++;
+
+// if ( pOld->fFailTfo || pNew->fFailTfo )
+// printf( "*" );
+// printf( "T(%d)", pNew->Level );
+
+ // mark the node as the failed node
+ pOld->fFailTfo = 1;
+ pNew->fFailTfo = 1;
+// p->nSatFails++;
+ p->nSatFailsReal++;
return 0;
}
// return SAT proof
p->nSatProof++;
+
+// if ( pOld->fFailTfo || pNew->fFailTfo )
+// printf( "*" );
+// printf( "u(%d)", pNew->Level );
return 1;
}
diff --git a/src/sat/msat/msatOrderJ.c b/src/sat/msat/msatOrderJ.c
index 5cba1165..4db7ff7b 100644
--- a/src/sat/msat/msatOrderJ.c
+++ b/src/sat/msat/msatOrderJ.c
@@ -38,7 +38,7 @@ struct Msat_OrderVar_t_
{
Msat_OrderVar_t * pNext;
Msat_OrderVar_t * pPrev;
- int Num;
+ int Num;
};
// the ring of variables data structure (J-boundary)
@@ -170,7 +170,8 @@ int Msat_OrderCheck( Msat_Order_t * p )
Msat_OrderVar_t * pVar, * pNext;
Msat_IntVec_t * vRound;
int * pRound, nRound;
- int * pVars, nVars, i;
+ int * pVars, nVars, i, k;
+ int Counter = 0;
// go through all the variables in the boundary
Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
@@ -188,10 +189,14 @@ int Msat_OrderCheck( Msat_Order_t * p )
if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
break;
}
- assert( i != nRound );
- if ( i != nRound )
- return 0;
+// assert( i != nRound );
+// if ( i == nRound )
+// return 0;
+ if ( i == nRound )
+ Counter++;
}
+ if ( Counter > 0 )
+ printf( "%d(%d) ", Counter, p->rVars.nItems );
// we may also check other unassigned variables in the cone
// to make sure that if they are not in J-boundary,
@@ -209,16 +214,16 @@ int Msat_OrderCheck( Msat_Order_t * p )
vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
nRound = Msat_IntVecReadSize( vRound );
pRound = Msat_IntVecReadArray( vRound );
- for ( i = 0; i < nRound; i++ )
+ for ( k = 0; k < nRound; k++ )
{
- if ( !Msat_OrderVarIsUsedInCone(p, pRound[i]) )
+ if ( !Msat_OrderVarIsUsedInCone(p, pRound[k]) )
continue;
- if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
+ if ( Msat_OrderVarIsAssigned(p, pRound[k]) )
break;
}
- assert( i == nRound );
- if ( i == nRound )
- return 0;
+// assert( k == nRound );
+// if ( k != nRound )
+// return 0;
}
return 1;
}
@@ -256,7 +261,7 @@ int Msat_OrderVarSelect( Msat_Order_t * p )
Msat_OrderVar_t * pVar, * pNext, * pVarBest;
double * pdActs = p->pSat->pdActivity;
double dfActBest;
- int clk = clock();
+// int clk = clock();
pVarBest = NULL;
dfActBest = -1.0;
@@ -268,12 +273,13 @@ int Msat_OrderVarSelect( Msat_Order_t * p )
pVarBest = pVar;
}
}
-timeSelect += clock() - clk;
-timeAssign += clock() - clk;
+//timeSelect += clock() - clk;
+//timeAssign += clock() - clk;
//if ( pVarBest && pVarBest->Num % 1000 == 0 )
//printf( "%d ", p->rVars.nItems );
+// Msat_OrderCheck( p );
if ( pVarBest )
{
assert( Msat_OrderVarIsUsedInCone(p, pVarBest->Num) );
@@ -296,7 +302,7 @@ timeAssign += clock() - clk;
void Msat_OrderVarAssigned( Msat_Order_t * p, int Var )
{
Msat_IntVec_t * vRound;
- int i, clk = clock();
+ int i;//, clk = clock();
// make sure the variable is in the boundary
assert( Var < p->nVarsAlloc );
@@ -316,7 +322,7 @@ void Msat_OrderVarAssigned( Msat_Order_t * p, int Var )
continue;
Msat_OrderRingAddLast( &p->rVars, &p->pVars[vRound->pArray[i]] );
}
-timeSelect += clock() - clk;
+//timeSelect += clock() - clk;
// Msat_OrderCheck( p );
}
@@ -334,7 +340,7 @@ timeSelect += clock() - clk;
void Msat_OrderVarUnassigned( Msat_Order_t * p, int Var )
{
Msat_IntVec_t * vRound, * vRound2;
- int i, k, clk = clock();
+ int i, k;//, clk = clock();
// make sure the variable is not in the boundary
assert( Var < p->nVarsAlloc );
@@ -363,7 +369,7 @@ void Msat_OrderVarUnassigned( Msat_Order_t * p, int Var )
if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
Msat_OrderRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
}
-timeSelect += clock() - clk;
+//timeSelect += clock() - clk;
// Msat_OrderCheck( p );
}
@@ -450,7 +456,7 @@ void Msat_OrderRingRemove( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar )
pRing->pRoot = pVar->pNext;
// move the root to the next entry after pVar
// this way all the additions to the list will be traversed first
-// pRing->pRoot = pVar->pNext;
+// pRing->pRoot = pVar->pPrev;
// delete the node
pVar->pPrev->pNext = pVar->pNext;
pVar->pNext->pPrev = pVar->pPrev;