diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2009-03-29 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2009-03-29 08:01:00 -0700 |
commit | 23fd11037a006089898cb13494305e402a11ec76 (patch) | |
tree | be45622eade1dc6e6b1cb6dd7ca8b115ca00b1cb /src | |
parent | d74d35aa4244a1e2e8e73c0776703528a5bd94db (diff) | |
download | abc-23fd11037a006089898cb13494305e402a11ec76.tar.gz abc-23fd11037a006089898cb13494305e402a11ec76.tar.bz2 abc-23fd11037a006089898cb13494305e402a11ec76.zip |
Version abc90329
Diffstat (limited to 'src')
56 files changed, 6834 insertions, 1739 deletions
diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index d9e57f7e..1f51f300 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -647,7 +647,7 @@ extern void Aig_ManCleanPioNumbers( Aig_Man_t * p ); extern int Aig_ManChoiceNum( Aig_Man_t * p ); extern char * Aig_FileNameGenericAppend( char * pBase, char * pSuffix ); extern unsigned Aig_ManRandom( int fReset ); -extern void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iWordStart, int iWordStop ); +extern void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop ); extern void Aig_NodeUnionLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ); extern void Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ); diff --git a/src/aig/aig/aigMffc.c b/src/aig/aig/aigMffc.c index 10887712..f681c76a 100644 --- a/src/aig/aig/aigMffc.c +++ b/src/aig/aig/aigMffc.c @@ -176,9 +176,15 @@ void Aig_NodeMffsSupp_rec( Aig_Man_t * p, Aig_Obj_t * pNode, unsigned LevelMin, int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t * vSupp ) { int ConeSize1, ConeSize2; + if ( vSupp ) Vec_PtrClear( vSupp ); + if ( !Aig_ObjIsNode(pNode) ) + { + if ( Aig_ObjIsPi(pNode) && vSupp ) + Vec_PtrPush( vSupp, pNode ); + return 0; + } assert( !Aig_IsComplement(pNode) ); assert( Aig_ObjIsNode(pNode) ); - if ( vSupp ) Vec_PtrClear( vSupp ); Aig_ManIncrementTravId( p ); ConeSize1 = Aig_NodeDeref_rec( pNode, LevelMin, NULL, NULL ); Aig_NodeMffsSupp_rec( p, pNode, LevelMin, vSupp, 1, NULL ); diff --git a/src/aig/aig/aigRepr.c b/src/aig/aig/aigRepr.c index 0ab02144..2d2f2f3d 100644 --- a/src/aig/aig/aigRepr.c +++ b/src/aig/aig/aigRepr.c @@ -287,6 +287,10 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered ) } else { +// Aig_ManForEachObj( p, pObj, i ) +// if ( p->pReprs[i] ) +// printf( "Substituting %d for %d.\n", p->pReprs[i]->Id, pObj->Id ); + Aig_ManForEachPo( p, pObj, i ) Aig_ManDupRepr_rec( pNew, p, Aig_ObjFanin0(pObj) ); } diff --git a/src/aig/aig/aigTable.c b/src/aig/aig/aigTable.c index 7ca4bb32..81635357 100644 --- a/src/aig/aig/aigTable.c +++ b/src/aig/aig/aigTable.c @@ -236,6 +236,7 @@ void Aig_TableProfile( Aig_Man_t * p ) { Aig_Obj_t * pEntry; int i, Counter; + printf( "Table size = %d. Entries = %d.\n", p->nTableSize, Aig_ManNodeNum(p) ); for ( i = 0; i < p->nTableSize; i++ ) { Counter = 0; diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c index 1852ff03..80d1f527 100644 --- a/src/aig/aig/aigUtil.c +++ b/src/aig/aig/aigUtil.c @@ -1189,11 +1189,11 @@ unsigned Aig_ManRandom( int fReset ) SeeAlso [] ***********************************************************************/ -void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iWordStart, int iWordStop ) +void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop ) { unsigned * pInfo; int i, w; - Vec_PtrForEachEntry( vInfo, pInfo, i ) + Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart ) for ( w = iWordStart; w < iWordStop; w++ ) pInfo[w] = Aig_ManRandom(0); } diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h index a97bd958..e26455ba 100644 --- a/src/aig/cec/cec.h +++ b/src/aig/cec/cec.h @@ -61,6 +61,7 @@ struct Cec_ParSim_t_ int fCheckMiter; // the circuit is the miter int fFirstStop; // stop on the first sat output int fSeqSimulate; // performs sequential simulation + int fLatchCorr; // consider only latch outputs int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -113,6 +114,36 @@ struct Cec_ParCec_t_ int fVerbose; // verbose stats }; +// sequential register correspodence parameters +typedef struct Cec_ParCor_t_ Cec_ParCor_t; +struct Cec_ParCor_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int nFrames; // the number of time frames + int nBTLimit; // conflict limit at a node + int fLatchCorr; // consider only latch outputs + int fUseRings; // use rings + int fUseCSat; // use circuit-based solver + int fFirstStop; // stop on the first sat output + int fUseSmartCnf; // use smart CNF computation + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// sequential register correspodence parameters +typedef struct Cec_ParChc_t_ Cec_ParChc_t; +struct Cec_ParChc_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int nBTLimit; // conflict limit at a node + int fFirstStop; // stop on the first sat output + int fUseSmartCnf; // use smart CNF computation + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -124,12 +155,18 @@ struct Cec_ParCec_t_ /*=== cecCec.c ==========================================================*/ extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ); extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); +/*=== cecChoice.c ==========================================================*/ +extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ); +/*=== cecCorr.c ==========================================================*/ +extern Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); /*=== cecCore.c ==========================================================*/ extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ); extern void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ); extern void Cec_ManSmfSetDefaultParams( Cec_ParSmf_t * p ); extern void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ); extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ); +extern void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p ); +extern void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p ); extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); diff --git a/src/aig/cec/cecChoice.c b/src/aig/cec/cecChoice.c new file mode 100644 index 00000000..ff30e1bb --- /dev/null +++ b/src/aig/cec/cecChoice.c @@ -0,0 +1,51 @@ +/**CFile**************************************************************** + + FileName [cecChoice.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Computation of structural choices.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecChoice.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c index 26ff543a..a8ed017a 100644 --- a/src/aig/cec/cecClass.c +++ b/src/aig/cec/cecClass.c @@ -293,6 +293,48 @@ int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i ) /**Function************************************************************* + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i ) +{ + int iRepr, Ent; + if ( Gia_ObjIsConst(p->pAig, i) ) + { + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); + return 1; + } + if ( !Gia_ObjIsClass(p->pAig, i) ) + return 0; + assert( Gia_ObjIsClass(p->pAig, i) ); + iRepr = Gia_ObjRepr( p->pAig, i ); + if ( iRepr == GIA_VOID ) + iRepr = i; + // collect nodes + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Gia_ClassForEachObj( p->pAig, iRepr, Ent ) + { + if ( Ent == i ) + Vec_IntPush( p->vClassNew, Ent ); + else + Vec_IntPush( p->vClassOld, Ent ); + } + assert( Vec_IntSize( p->vClassNew ) == 1 ); + Cec_ManSimClassCreate( p->pAig, p->vClassOld ); + Cec_ManSimClassCreate( p->pAig, p->vClassNew ); + assert( !Gia_ObjIsClass(p->pAig, i) ); + return 1; +} + +/**Function************************************************************* + Synopsis [Computes hash key of the simuation info.] Description [] @@ -797,8 +839,12 @@ int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ) p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) ); p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); // set starting representative of internal nodes to be constant 0 - Gia_ManForEachObj( p->pAig, pObj, i ) - Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); + if ( p->pPars->fLatchCorr ) + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); + else + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); // if sequential simulation, set starting representative of ROs to be constant 0 if ( p->pPars->fSeqSimulate ) Gia_ManForEachRo( p->pAig, pObj, i ) diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index 9274dcb8..d3c54948 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -156,6 +156,56 @@ void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ) /**Function************************************************************* + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p ) +{ + memset( p, 0, sizeof(Cec_ParCor_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->nFrames = 1; // the number of time frames + p->nBTLimit = 100; // conflict limit at a node + p->fLatchCorr = 0; // consider only latch outputs + p->fUseRings = 1; // combine classes into rings + p->fUseCSat = 1; // use circuit-based solver + p->fFirstStop = 0; // stop on the first sat output + p->fUseSmartCnf = 0; // use smart CNF computation + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p ) +{ + memset( p, 0, sizeof(Cec_ParChc_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->nBTLimit = 1000; // conflict limit at a node + p->fFirstStop = 0; // stop on the first sat output + p->fUseSmartCnf = 0; // use smart CNF computation + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + Synopsis [Core procedure for SAT sweeping.] Description [] @@ -171,7 +221,8 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) Cec_ManPat_t * pPat; pPat = Cec_ManPatStart(); Cec_ManSatSolve( pPat, pAig, pPars ); - pNew = Gia_ManDupDfsSkip( pAig ); +// pNew = Gia_ManDupDfsSkip( pAig ); + pNew = Gia_ManDup( pAig ); Cec_ManPatStop( pPat ); return pNew; } @@ -193,7 +244,7 @@ void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) int RetValue, clkTotal = clock(); if ( pPars->fSeqSimulate ) printf( "Performing sequential simulation of %d frames with %d words.\n", - pPars->nWords, pPars->nRounds ); + pPars->nRounds, pPars->nWords ); Aig_ManRandom( 1 ); pSim = Cec_ManSimStart( pAig, pPars ); if ( pAig->pReprs == NULL ) @@ -286,7 +337,7 @@ p->timeSim += clock() - clk; // Gia_WriteAiger( pSrm, "gia_srm.aig", 0, 0 ); if ( pPars->fVeryVerbose ) - Gia_ManPrintStats( pSrm ); + Gia_ManPrintStats( pSrm, 0 ); if ( Gia_ManCoNum(pSrm) == 0 ) { Gia_ManStop( pSrm ); diff --git a/src/aig/cec/cecCorr.c b/src/aig/cec/cecCorr.c new file mode 100644 index 00000000..abc76416 --- /dev/null +++ b/src/aig/cec/cecCorr.c @@ -0,0 +1,757 @@ +/**CFile**************************************************************** + + FileName [cecLcorr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinatinoal equivalence checking.] + + Synopsis [Flop correspondence computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecLcorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes the real value of the literal w/o spec reduction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f ); + return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) ); + } + assert( f && Gia_ObjIsRo(p, pObj) ); + pObj = Gia_ObjRoToRi( p, pObj ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1 ); + return Gia_ObjFanin0CopyF( p, f-1, pObj ); +} + +/**Function************************************************************* + + Synopsis [Recursively performs speculative reduction for the object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + Gia_Obj_t * pRepr; + int iLitNew; + if ( ~Gia_ObjCopyF(p, f, pObj) ) + return; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + if ( !Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f ); + iLitNew = Gia_LitNotCond( Gia_ObjCopyF(p, f, pRepr), Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + Gia_ObjSetCopyF( p, f, pObj, iLitNew ); + return; + } + } + assert( Gia_ObjIsCand(pObj) ); + iLitNew = Gia_ManCorrSpecReal( pNew, p, pObj, f ); + Gia_ObjSetCopyF( p, f, pObj, iLitNew ); +} + +/**Function************************************************************* + + Synopsis [Derives SRM for signal correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + Vec_Int_t * vXorLits; + int f, i, iPrev, iObj, iPrevNew, iObjNew; + assert( nFrames > 0 ); + assert( Gia_ManRegNum(p) > 0 ); + assert( p->pReprs != NULL ); + p->pCopies = ABC_FALLOC( int, (nFrames+fScorr)*Gia_ManObjNum(p) ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ObjSetCopyF( p, 0, Gia_ManConst0(p), 0 ); + Gia_ManForEachRo( p, pObj, i ) + Gia_ObjSetCopyF( p, 0, pObj, Gia_ManAppendCi(pNew) ); + Gia_ManForEachRo( p, pObj, i ) + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + if ( !Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) + Gia_ObjSetCopyF( p, 0, pObj, Gia_ObjCopyF(p, 0, pRepr) ); + } + for ( f = 0; f < nFrames+fScorr; f++ ) + { + Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) ); + } + *pvOutputs = Vec_IntAlloc( 1000 ); + vXorLits = Vec_IntAlloc( 1000 ); + if ( fRings ) + { + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsConst( p, i ) ) + { + if ( Gia_ObjIsFailedPair(p, 0, i) ) + continue; + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames ); + iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ); + if ( iObjNew != 0 ) + { + Vec_IntPush( *pvOutputs, 0 ); + Vec_IntPush( *pvOutputs, i ); + Vec_IntPush( vXorLits, iObjNew ); + } + } + else if ( Gia_ObjIsHead( p, i ) ) + { + iPrev = i; + Gia_ClassForEachObj1( p, i, iObj ) + { + if ( Gia_ObjIsFailedPair(p, iPrev, iObj) ) + { + iPrev = iObj; + continue; + } + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames ); + iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) ); + if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 ) + { + Vec_IntPush( *pvOutputs, iPrev ); + Vec_IntPush( *pvOutputs, iObj ); + Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) ); + } + iPrev = iObj; + } + iObj = i; + if ( Gia_ObjIsFailedPair(p, iPrev, iObj) ) + continue; + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames ); + iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) ); + if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 ) + { + Vec_IntPush( *pvOutputs, iPrev ); + Vec_IntPush( *pvOutputs, iObj ); + Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) ); + } + } + } + } + else + { + Gia_ManForEachObj1( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + if ( Gia_ObjIsFailedPair(p, Gia_ObjRepr(p, i), i) ) + continue; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames ); + iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + if ( iPrevNew != iObjNew ) + { + Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) ); + Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) ); + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) ); + } + } + } + Vec_IntForEachEntry( vXorLits, iObjNew, i ) + Gia_ManAppendCo( pNew, iObjNew ); + Vec_IntFree( vXorLits ); + Gia_ManHashStop( pNew ); + ABC_FREE( p->pCopies ); +//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); + pNew = Gia_ManCleanup( pTemp = pNew ); +//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Remaps simulation info from SRM to the original AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCorrRemapSimInfo( Gia_Man_t * p, Vec_Ptr_t * vInfo ) +{ + Gia_Obj_t * pObj, * pRepr; + unsigned * pInfoObj, * pInfoRepr; + int i, w, nWords; + nWords = Vec_PtrReadWordsSimInfo( vInfo ); + Gia_ManForEachRo( p, pObj, i ) + { + // skip ROs without representatives + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) ) + continue; + pInfoObj = Vec_PtrEntry( vInfo, i ); + for ( w = 0; w < nWords; w++ ) + assert( pInfoObj[w] == 0 ); + // skip ROs with constant representatives + if ( Gia_ObjIsConst0(pRepr) ) + continue; + assert( Gia_ObjIsRo(p, pRepr) ); +// printf( "%d -> %d ", i, Gia_ObjId(p, pRepr) ); + // transfer info from the representative + pInfoRepr = Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); + for ( w = 0; w < nWords; w++ ) + pInfoObj[w] = pInfoRepr[w]; + } +// printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Remaps simulation info from SRM to the original AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p ) +{ + Vec_Int_t * vPairs; + Gia_Obj_t * pObj, * pRepr; + int i; + vPairs = Vec_IntAlloc( 100 ); + Gia_ManForEachRo( p, pObj, i ) + { + // skip ROs without representatives + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); +// if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) ) + if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) + continue; + assert( Gia_ObjIsRo(p, pRepr) ); +// printf( "%d -> %d ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) ); + // remember the pair + Vec_IntPush( vPairs, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); + Vec_IntPush( vPairs, i ); + } + return vPairs; +} + +/**Function************************************************************* + + Synopsis [Remaps simulation info from SRM to the original AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo ) +{ + unsigned * pInfoObj, * pInfoRepr; + int w, i, iObj, iRepr, nWords; + nWords = Vec_PtrReadWordsSimInfo( vInfo ); + Vec_IntForEachEntry( vPairs, iRepr, i ) + { + iObj = Vec_IntEntry( vPairs, ++i ); + pInfoObj = Vec_PtrEntry( vInfo, iObj ); + pInfoRepr = Vec_PtrEntry( vInfo, iRepr ); + for ( w = 0; w < nWords; w++ ) + { + assert( pInfoObj[w] == 0 ); + pInfoObj[w] = pInfoRepr[w]; + } + } +} + +/**Function************************************************************* + + Synopsis [Updates equivalence classes by marking those that timed out.] + + Description [Returns 1 if all ndoes are proved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings ) +{ + int i, status, iRepr, iObj; + assert( 2 * Vec_StrSize(vStatus) == Vec_IntSize(vOutputs) ); + Vec_StrForEachEntry( vStatus, status, i ) + { + iRepr = Vec_IntEntry( vOutputs, 2*i ); + iObj = Vec_IntEntry( vOutputs, 2*i+1 ); + if ( status == 1 ) + continue; + if ( status == 0 ) + { +// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) +// printf( "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj ); + if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) + Cec_ManSimClassRemoveOne( pSim, iObj ); + continue; + } + if ( status == -1 ) + { +// if ( !Gia_ObjFailed( p, iObj ) ) +// printf( "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" ); +// Gia_ObjSetFailed( p, iRepr ); +// Gia_ObjSetFailed( p, iObj ); + if ( fRings ) + Cec_ManSimClassRemoveOne( pSim, iRepr ); + Cec_ManSimClassRemoveOne( pSim, iObj ); + continue; + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Marks all the nodes as proved.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetProvedNodes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, nLits = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjRepr(p, i) == GIA_VOID ) + continue; + if ( Gia_ObjIsFailedPair( p, Gia_ObjRepr(p, i), i ) ) + continue; + Gia_ObjSetProved( p, i ); + nLits++; + } +// printf( "Identified %d proved literals.\n", nLits ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManLCorrPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time ) +{ + int nLits, CounterX = 0, Counter0 = 0, Counter = 0; + int i, Entry, nProve = 0, nDispr = 0, nFail = 0; + for ( i = 1; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjIsNone(p, i) ) + CounterX++; + else if ( Gia_ObjIsConst(p, i) ) + Counter0++; + else if ( Gia_ObjIsHead(p, i) ) + Counter++; + } + CounterX -= Gia_ManCoNum(p); + nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; + printf( "%3d : c =%8d cl =%7d lit =%8d ", iIter, Counter0, Counter, nLits ); + if ( vStatus ) + Vec_StrForEachEntry( vStatus, Entry, i ) + { + if ( Entry == 1 ) + nProve++; + else if ( Entry == 0 ) + nDispr++; + else if ( Entry == -1 ) + nFail++; + } + printf( "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail ); + ABC_PRT( "T", Time ); +} + +/**Function************************************************************* + + Synopsis [Sets register values from the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops ) +{ + unsigned * pInfo; + int k, w, nWords; + nWords = Vec_PtrReadWordsSimInfo( vInfo ); + assert( nFlops <= Vec_PtrSize(vInfo) ); + for ( k = 0; k < nFlops; k++ ) + { + pInfo = Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ ) + { + pInfo = Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Aig_ManRandom( 0 ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart ) +{ + unsigned * pInfo; + int nBits = 32 * Vec_PtrReadWordsSimInfo(vInfo); + int k, iLit, nLits, Out, iBit = 1; + while ( iStart < Vec_IntSize(vCexStore) ) + { + // skip the output number +// iStart++; + Out = Vec_IntEntry( vCexStore, iStart++ ); +// printf( "iBit = %d. Out = %d.\n", iBit, Out ); + // get the number of items + nLits = Vec_IntEntry( vCexStore, iStart++ ); + if ( nLits <= 0 ) + continue; + // add pattern to storage + for ( k = 0; k < nLits; k++ ) + { + iLit = Vec_IntEntry( vCexStore, iStart++ ); + pInfo = Vec_PtrEntry( vInfo, Gia_Lit2Var(iLit) ); + if ( Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(iLit) ) + Aig_InfoXorBit( pInfo, iBit ); + } + if ( ++iBit == nBits ) + break; + } +// printf( "added %d bits\n", iBit-1 ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Cec_ManLoadCounterExamplesTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Aig_InfoHasBit( pPres, iBit ) && + Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Aig_InfoSetBit( pPres, iBit ); + if ( Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Aig_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart ) +{ + Vec_Int_t * vPat; + Vec_Ptr_t * vPres; + int nWords = Vec_PtrReadWordsSimInfo(vInfo); + int nBits = 32 * nWords; + int k, nSize, iBit = 1, kMax = 0; + vPat = Vec_IntAlloc( 100 ); + vPres = Vec_PtrAllocSimInfo( Vec_PtrSize(vInfo), nWords ); + Vec_PtrCleanSimInfo( vPres, 0, nWords ); + while ( iStart < Vec_IntSize(vCexStore) ) + { + // skip the output number + iStart++; + // get the number of items + nSize = Vec_IntEntry( vCexStore, iStart++ ); + if ( nSize <= 0 ) + continue; + // extract pattern + Vec_IntClear( vPat ); + for ( k = 0; k < nSize; k++ ) + { + Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) ); +// printf( "%d(%d) ", Vec_IntEntryLast(vPat)/2, (Vec_IntEntryLast(vPat)&1)==0 ); + } +// printf( "\n" ); + // add pattern to storage + for ( k = 1; k < nBits; k++ ) + if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) + break; +// for ( i = 0; i < 27; i++ ) +// printf( "%d(%d) ", i, Aig_InfoHasBit(Vec_PtrEntry(vInfo,i), k) ); +// printf( "\n" ); + + kMax = AIG_MAX( kMax, k ); + if ( k == nBits-1 ) + break; + } +// printf( "\n" ); +// printf( "kMax = %d.\n", kMax ); + Vec_PtrFree( vPres ); + Vec_IntFree( vPat ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames ) +{ + Vec_Int_t * vPairs; + Vec_Ptr_t * vSimInfo; + int RetValue = 0, iStart = 0; + vPairs = Gia_ManCorrCreateRemapping( pSim->pAig ); + Gia_ManSetRefs( pSim->pAig ); +// pSim->pPars->nWords = 63; + pSim->pPars->nRounds = nFrames; + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords ); + while ( iStart < Vec_IntSize(vCexStore) ) + { +//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 ); + Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig) ); + iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart ); +// iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart ); +// Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo ); + Gia_ManCorrPerformRemapping( vPairs, vSimInfo ); + RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo ); +// Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL ); + } +//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 ); + assert( iStart == Vec_IntSize(vCexStore) ); + Vec_PtrFree( vSimInfo ); + Vec_IntFree( vPairs ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{ + int nAddFrames = 2; // additional timeframes to simulate + Vec_Str_t * vStatus; + Vec_Int_t * vOutputs; + Vec_Int_t * vCexStore; + Gia_Man_t * pNew, * pTemp; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Cec_ManSim_t * pSim; + Gia_Man_t * pSrm; + int r, RetValue; + int clkSat = 0, clkSim = 0, clkSrm = 0, clkTotal = clock(); + int clk2, clk = clock(); + ABC_FREE( pAig->pReprs ); + ABC_FREE( pAig->pNexts ); + if ( Gia_ManRegNum(pAig) == 0 ) + { + printf( "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" ); + return NULL; + } + Aig_ManRandom( 1 ); + // prepare simulation manager + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nRounds = pPars->nRounds; + pParsSim->fVerbose = pPars->fVerbose; + pParsSim->fLatchCorr = pPars->fLatchCorr; + pParsSim->fSeqSimulate = 1; + // create equivalence classes of registers + pSim = Cec_ManSimStart( pAig, pParsSim ); + Cec_ManSimClassesPrepare( pSim ); + Cec_ManSimClassesRefine( pSim ); + // prepare SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVerbose; + if ( pPars->fVerbose ) + { + printf( "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n", + Gia_ManObjNum(pAig), Gia_ManAndNum(pAig), + pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat ); + Cec_ManLCorrPrintStats( pAig, NULL, 0, clock() - clk ); + } + // perform refinement of equivalence classes + for ( r = 0; r < 100000; r++ ) + { + clk = clock(); + // perform speculative reduction + clk2 = clock(); + pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings ); + assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig) ); + clkSrm += clock() - clk2; + if ( Gia_ManCoNum(pSrm) == 0 ) + { + Vec_IntFree( vOutputs ); + Gia_ManStop( pSrm ); + break; + } +//Gia_DumpAiger( pSrm, "corrsrm", r, 2 ); + + // found counter-examples to speculation + clk2 = clock(); + if ( pPars->fUseCSat ) + vCexStore = Cbs_ManSolveMiter( pSrm, pPars->nBTLimit, &vStatus ); + else + vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); + Gia_ManStop( pSrm ); + clkSat += clock() - clk2; + if ( Vec_IntSize(vCexStore) == 0 ) + { + Vec_IntFree( vCexStore ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); + break; + } + // refine classes with these counter-examples + clk2 = clock(); + RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames ); + Vec_IntFree( vCexStore ); + clkSim += clock() - clk2; + Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); + if ( pPars->fVerbose ) + Cec_ManLCorrPrintStats( pAig, vStatus, r+1, clock() - clk ); +//Gia_ManEquivPrintClasses( pAig, 1, 0 ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); + } + Cec_ManSimStop( pSim ); + clkTotal = clock() - clkTotal; + if ( pPars->fVerbose ) + Cec_ManLCorrPrintStats( pAig, NULL, r+1, clock() - clk ); + if ( pPars->fVerbose ) + { + ABC_PRTP( "Srm ", clkSrm, clkTotal ); + ABC_PRTP( "Sat ", clkSat, clkTotal ); + ABC_PRTP( "Sim ", clkSim, clkTotal ); + ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); + ABC_PRT( "TOTAL", clkTotal ); + } + // derive reduced AIG + Gia_ManSetProvedNodes( pAig ); + pNew = Gia_ManEquivReduce( pAig, 0, 0, 0 ); +//Gia_WriteAiger( pNew, "reduced.aig", 0, 0 ); + pNew = Gia_ManSeqCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h index ae4c6ff4..86af2614 100644 --- a/src/aig/cec/cecInt.h +++ b/src/aig/cec/cecInt.h @@ -85,15 +85,19 @@ struct Cec_ManSat_t_ int nRecycles; // the number of times SAT solver was recycled int nCallsSince; // the number of calls since the last recycle Vec_Ptr_t * vFanins; // fanins of the CNF node + // counter-examples + Vec_Int_t * vCex; // the latest counter-example + Vec_Int_t * vVisits; // temporary array for visited nodes // SAT calls statistics int nSatUnsat; // the number of proofs int nSatSat; // the number of failure int nSatUndec; // the number of timeouts int nSatTotal; // the number of calls + int nCexLits; // conflicts - int nConfUnsat; - int nConfSat; - int nConfUndec; + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems // runtime stats int timeSatUnsat; // unsat int timeSatSat; // sat @@ -164,6 +168,7 @@ struct Cec_ManFra_t_ /*=== cecCore.c ============================================================*/ /*=== cecClass.c ============================================================*/ +extern int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i ); extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ); extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p ); extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); @@ -183,10 +188,16 @@ extern void Cec_ManFraStop( Cec_ManFra_t * p ); /*=== cecPat.c ============================================================*/ extern void Cec_ManPatSavePattern( Cec_ManPat_t * pPat, Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWords ); +extern Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ); +/*=== cecSeq.c ============================================================*/ +extern int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ); +extern int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Gia_Cex_t * pBestState ); +extern void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex ); /*=== cecSolve.c ============================================================*/ extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj ); extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ); -extern void Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ); +extern Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ); +extern Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus ); /*=== ceFraeep.c ============================================================*/ extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ); extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c index 14f2493e..430d961e 100644 --- a/src/aig/cec/cecMan.c +++ b/src/aig/cec/cecMan.c @@ -52,6 +52,8 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); p->vUsedNodes = Vec_PtrAlloc( 1000 ); p->vFanins = Vec_PtrAlloc( 100 ); + p->vCex = Vec_IntAlloc( 100 ); + p->vVisits = Vec_IntAlloc( 100 ); return p; } @@ -81,6 +83,7 @@ void Cec_ManSatPrintStats( Cec_ManSat_t * p ) printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); } /**Function************************************************************* @@ -98,6 +101,8 @@ void Cec_ManSatStop( Cec_ManSat_t * p ) { if ( p->pSat ) sat_solver_delete( p->pSat ); + Vec_IntFree( p->vCex ); + Vec_IntFree( p->vVisits ); Vec_PtrFree( p->vUsedNodes ); Vec_PtrFree( p->vFanins ); ABC_FREE( p->pSatVars ); diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c index b80f1e44..dacc5daf 100644 --- a/src/aig/cec/cecPat.c +++ b/src/aig/cec/cecPat.c @@ -450,7 +450,7 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nW int nBits = 32 * nWords; int clk = clock(); vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); - Aig_ManRandomInfo( vInfo, 0, nWords ); + Aig_ManRandomInfo( vInfo, 0, 0, nWords ); vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); Vec_PtrCleanSimInfo( vPres, 0, nWords ); while ( pMan->iStart < Vec_StrSize(pMan->vStorage) ) @@ -464,7 +464,7 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nW if ( k == nBits-1 ) { Vec_PtrReallocSimInfo( vInfo ); - Aig_ManRandomInfo( vInfo, nWords, 2*nWords ); + Aig_ManRandomInfo( vInfo, 0, nWords, 2*nWords ); Vec_PtrReallocSimInfo( vPres ); Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); nWords *= 2; @@ -486,6 +486,77 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nW return vInfo; } + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ) +{ + Vec_Int_t * vPat; + Vec_Ptr_t * vInfo, * vPres; + int k, nSize, iStart, kMax = 0, nPatterns = 0; + int nWords = nWordsInit; + int nBits = 32 * nWords; +// int RetValue; + assert( nRegs <= nInputs ); + vPat = Vec_IntAlloc( 100 ); + + vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); + Vec_PtrCleanSimInfo( vInfo, 0, nWords ); + Aig_ManRandomInfo( vInfo, nRegs, 0, nWords ); + + vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); + Vec_PtrCleanSimInfo( vPres, 0, nWords ); + iStart = 0; + while ( iStart < Vec_IntSize(vCexStore) ) + { + nPatterns++; + // skip the output number + iStart++; + // get the number of items + nSize = Vec_IntEntry( vCexStore, iStart++ ); + if ( nSize <= 0 ) + continue; + // extract pattern + Vec_IntClear( vPat ); + for ( k = 0; k < nSize; k++ ) + Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) ); + // add pattern to storage + for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) ) + if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) + break; + +// k = kMax + 1; +// RetValue = Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ); +// assert( RetValue == 1 ); + + kMax = AIG_MAX( kMax, k ); + if ( k == nBits-1 ) + { + Vec_PtrReallocSimInfo( vInfo ); + Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords ); + Aig_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords ); + + Vec_PtrReallocSimInfo( vPres ); + Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); + nWords *= 2; + nBits *= 2; + } + } +// printf( "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); + Vec_PtrFree( vPres ); + Vec_IntFree( vPat ); + return vInfo; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecSeq.c b/src/aig/cec/cecSeq.c index 1a398e2e..e69b526e 100644 --- a/src/aig/cec/cecSeq.c +++ b/src/aig/cec/cecSeq.c @@ -42,23 +42,32 @@ void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex ) { unsigned * pInfo; - int k, w, nWords; + int k, i, w, nWords; assert( pCex->nBits == pCex->nRegs + pCex->nPis * (pCex->iFrame + 1) ); - assert( pCex->nBits <= Vec_PtrSize(vInfo) ); + assert( pCex->nBits - pCex->nRegs + Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) ); nWords = Vec_PtrReadWordsSimInfo( vInfo ); +/* for ( k = 0; k < pCex->nRegs; k++ ) { pInfo = Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = Aig_InfoHasBit( pCex->pData, k )? ~0 : 0; } - for ( ; k < pCex->nBits; k++ ) +*/ + for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) { pInfo = Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + + for ( i = pCex->nRegs; i < pCex->nBits; i++ ) + { + pInfo = Vec_PtrEntry( vInfo, k++ ); + for ( w = 0; w < nWords; w++ ) pInfo[w] = Aig_ManRandom(0); // set simulation pattern and make sure it is second (first will be erased during simulation) - pInfo[0] = (pInfo[0] << 1) | Aig_InfoHasBit( pCex->pData, k ); + pInfo[0] = (pInfo[0] << 1) | Aig_InfoHasBit( pCex->pData, i ); pInfo[0] <<= 1; } for ( ; k < Vec_PtrSize(vInfo); k++ ) @@ -85,13 +94,13 @@ void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Ce unsigned * pInfo; int k, w, nWords; nWords = Vec_PtrReadWordsSimInfo( vInfo ); - assert( Gia_ManRegNum(pAig) == pCex->nRegs ); + assert( pCex == NULL || Gia_ManRegNum(pAig) == pCex->nRegs ); assert( Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) ); for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) { pInfo = Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) - pInfo[w] = Aig_InfoHasBit( pCex->pData, k )? ~0 : 0; + pInfo[w] = (pCex && Aig_InfoHasBit(pCex->pData, k))? ~0 : 0; } for ( ; k < Vec_PtrSize(vInfo); k++ ) @@ -212,9 +221,10 @@ int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Gia_Cex printf( "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" ); return -1; } - if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) +// if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) + if ( Gia_ManPiNum(pAig) != pCex->nPis ) { - printf( "Cec_ManSeqResimulateCounter(): Parameters of the ccounter-example differ.\n" ); + printf( "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" ); return -1; } if ( pPars->fVerbose ) @@ -251,6 +261,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) int nAddFrames = 10; // additional timeframes to simulate Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; Vec_Ptr_t * vSimInfo; + Vec_Str_t * vStatus; Gia_Cex_t * pState; Gia_Man_t * pSrm; int r, nPats, RetValue = -1; @@ -284,13 +295,14 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) // Gia_ManPrintCounterExample( pState ); // derive speculatively reduced model pSrm = Gia_ManSpecReduceInit( pAig, pState, pPars->nFrames, pPars->fDualOut ); - assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManPiNum(pAig) * pPars->nFrames ); + assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == (Gia_ManPiNum(pAig) * pPars->nFrames) ); // allocate room for simulation info vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) + Gia_ManPiNum(pAig) * (pPars->nFrames + nAddFrames), pPars->nWords ); Cec_ManSeqDeriveInfoInitRandom( vSimInfo, pAig, pState ); // fill in simulation info with counter-examples - Cec_ManSatSolveSeq( vSimInfo, pSrm, pParsSat, Gia_ManRegNum(pAig), &nPats ); + vStatus = Cec_ManSatSolveSeq( vSimInfo, pSrm, pParsSat, Gia_ManRegNum(pAig), &nPats ); + Vec_StrFree( vStatus ); Gia_ManStop( pSrm ); // resimulate and refine the classes RetValue = Cec_ManSeqResimulateInfo( pAig, vSimInfo, pState ); diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c index 24d5c3ed..a69d1d2a 100644 --- a/src/aig/cec/cecSolve.c +++ b/src/aig/cec/cecSolve.c @@ -556,18 +556,10 @@ p->timeSatUndec += clock() - clk; ***********************************************************************/ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ) { - static int Counter; -// char Buffer[1000]; - Bar_Progress_t * pProgress = NULL; Cec_ManSat_t * p; Gia_Obj_t * pObj; int i, status, clk = clock(), clk2; - -// sprintf( Buffer, "gia%03d.aig", Counter++ ); -//Gia_WriteAiger( pAig, Buffer, 0, 0 ); -//printf( "Dumpted slice into file \"%s\".\n", Buffer ); - // reset the manager if ( pPat ) { @@ -595,13 +587,6 @@ clk2 = clock(); pObj->fMark0 = (status == 0); pObj->fMark1 = (status == 1); /* -printf( "Output %6d : ", i ); -printf( "conf = %6d ", p->pSat->stats.conflicts ); -printf( "prop = %6d ", p->pSat->stats.propagations ); -ABC_PRT( "time", clock() - clk2 ); -*/ - -/* if ( status == -1 ) { Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); @@ -653,6 +638,8 @@ void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pOb unsigned * pInfo = Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) ); if ( Cec_ObjSatVarValue( pSat, pObj ) != Aig_InfoHasBit( pInfo, iPat ) ) Aig_InfoXorBit( pInfo, iPat ); + pSat->nCexLits++; +// Vec_IntPush( pSat->vCex, Gia_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) ); return; } assert( Gia_ObjIsAnd(pObj) ); @@ -672,44 +659,207 @@ void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pOb SeeAlso [] ***********************************************************************/ -void Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ) +Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ) { Bar_Progress_t * pProgress = NULL; + Vec_Str_t * vStatus; Cec_ManSat_t * p; Gia_Obj_t * pObj; - int iPat = 1, nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); + int iPat = 0, nPatsInit, nPats; int i, status, clk = clock(); + nPatsInit = nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); Gia_ManSetPhase( pAig ); Gia_ManLevelNum( pAig ); Gia_ManResetTravId( pAig ); p = Cec_ManSatCreate( pAig, pPars ); + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); Gia_ManForEachCo( pAig, pObj, i ) { + Bar_ProgressUpdate( pProgress, i, "SAT..." ); if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) + { + if ( Gia_ObjFaninC0(pObj) ) + { + printf( "Constant 1 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 0 ); + } + else + { + printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } continue; - Bar_ProgressUpdate( pProgress, i, "BMC..." ); + } status = Cec_ManSatCheckNode( p, pObj ); +//printf( "output %d status = %d\n", i, status ); + Vec_StrPush( vStatus, (char)status ); if ( status != 0 ) continue; + // resize storage + if ( iPat == nPats ) + { + int nWords = Vec_PtrReadWordsSimInfo(vPatts); + Vec_PtrReallocSimInfo( vPatts ); + Vec_PtrCleanSimInfo( vPatts, nWords, 2*nWords ); + nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); + } + if ( iPat % nPatsInit == 0 ) + iPat++; // save the pattern Gia_ManIncrementTravId( pAig ); +// Vec_IntClear( p->vCex ); Cec_ManSatSolveSeq_rec( p, pAig, Gia_ObjFanin0(pObj), vPatts, iPat++, nRegs ); - if ( iPat == nPats ) - break; +// Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); +// Cec_ManSatAddToStore( p->vCexStore, p->vCex ); +// if ( iPat == nPats ) +// break; // quit if one of them is solved - if ( pPars->fFirstStop ) - break; +// if ( pPars->fFirstStop ) +// break; +// if ( iPat == 32 * 15 * 16 - 1 ) +// break; } p->timeTotal = clock() - clk; Bar_ProgressStop( pProgress ); if ( pPars->fVerbose ) Cec_ManSatPrintStats( p ); +// printf( "Total number of cex literals = %d. (Ave = %d)\n", p->nCexLits, p->nCexLits/p->nSatSat ); Cec_ManSatStop( p ); if ( pnPats ) *pnPats = iPat-1; + return vStatus; +} + + +/**Function************************************************************* + + Synopsis [Save values in the cone of influence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ) +{ + int i, Entry; + Vec_IntPush( vCexStore, Out ); + if ( vCex == NULL ) // timeout + { + Vec_IntPush( vCexStore, -1 ); + return; + } + // write the counter-example + Vec_IntPush( vCexStore, Vec_IntSize(vCex) ); + Vec_IntForEachEntry( vCex, Entry, i ) + Vec_IntPush( vCexStore, Entry ); +} + +/**Function************************************************************* + + Synopsis [Save values in the cone of influence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatSolveMiter_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + pSat->nCexLits++; + Vec_IntPush( pSat->vCex, Gia_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin0(pObj) ); + Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Performs one round of solving for the POs of the AIG.] + + Description [Labels the nodes that have been proved (pObj->fMark1) + and returns the set of satisfying assignments.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus ) +{ + Bar_Progress_t * pProgress = NULL; + Vec_Int_t * vCexStore; + Vec_Str_t * vStatus; + Cec_ManSat_t * p; + Gia_Obj_t * pObj; + int i, status, clk = clock(); + // prepare AIG + Gia_ManSetPhase( pAig ); + Gia_ManLevelNum( pAig ); + Gia_ManResetTravId( pAig ); + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + // perform solving + p = Cec_ManSatCreate( pAig, pPars ); + pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); + Gia_ManForEachCo( pAig, pObj, i ) + { + Vec_IntClear( p->vCex ); + Bar_ProgressUpdate( pProgress, i, "SAT..." ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) + { + if ( Gia_ObjFaninC0(pObj) ) + { + printf( "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, p->vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { + printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + status = Cec_ManSatCheckNode( p, pObj ); + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + continue; + } + if ( status == 1 ) + continue; + assert( status == 0 ); + // save the pattern + Gia_ManIncrementTravId( pAig ); + Cec_ManSatSolveMiter_rec( p, pAig, Gia_ObjFanin0(pObj) ); +// Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); + Cec_ManSatAddToStore( vCexStore, p->vCex, i ); + } + p->timeTotal = clock() - clk; + Bar_ProgressStop( pProgress ); +// if ( pPars->fVerbose ) +// Cec_ManSatPrintStats( p ); + Cec_ManSatStop( p ); + *pvStatus = vStatus; + return vCexStore; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make index 1fc9861c..35a18cae 100644 --- a/src/aig/cec/module.make +++ b/src/aig/cec/module.make @@ -1,6 +1,8 @@ SRC += src/aig/cec/cecCec.c \ + src/aig/cec/cecChoice.c \ src/aig/cec/cecClass.c \ src/aig/cec/cecCore.c \ + src/aig/cec/cecCorr.c \ src/aig/cec/cecIso.c \ src/aig/cec/cecMan.c \ src/aig/cec/cecPat.c \ diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 28d610e9..87c85516 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -52,6 +52,15 @@ struct Gia_Rpr_t_ unsigned fColorB : 1; // marks cone of B }; +typedef struct Gia_Plc_t_ Gia_Plc_t; +struct Gia_Plc_t_ +{ + unsigned fFixed : 1; // the placement of this object is fixed + unsigned xCoord : 15; // x-ooordinate of the placement + unsigned fUndef : 1; // the placement of this object is not assigned + unsigned yCoord : 15; // y-ooordinate of the placement +}; + typedef struct Gia_Obj_t_ Gia_Obj_t; struct Gia_Obj_t_ { @@ -117,6 +126,8 @@ struct Gia_Man_t_ Gia_Cex_t * pCexComb; // combinational counter-example int * pCopies; // intermediate copies Vec_Int_t * vFlopClasses; // classes of flops for retiming/merging/etc + unsigned char* pSwitching; // switching activity for each object + Gia_Plc_t * pPlacement; // placement of the objects }; @@ -247,7 +258,7 @@ static inline int Gia_ObjFanin0CopyF( Gia_Man_t * p, int f, Gia_Obj_t * static inline int Gia_ObjFanin1CopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjCopyF(p, f, Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj)); } static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) ); } -static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) ); } +static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, Gia_Regular(pObj)), Gia_IsComplement(pObj) ); } static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } @@ -375,8 +386,10 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; } static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; } static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } -static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } -static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } +static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } +static inline int Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0; } +static inline int Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k); } #define Gia_ManForEachConst( p, i ) \ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else @@ -419,6 +432,8 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re for ( i = 0; (i < Vec_IntSize(p->vCis)) && ((pObj) = Gia_ManCi(p, i)); i++ ) #define Gia_ManForEachCo( p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ ) +#define Gia_ManForEachCoReverse( p, pObj, i ) \ + for ( i = Vec_IntSize(p->vCos) - 1; (i >= 0) && ((pObj) = Gia_ManCo(p, i)); i-- ) #define Gia_ManForEachCoDriver( p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ObjFanin0(Gia_ManCo(p, i))); i++ ) #define Gia_ManForEachPi( p, pObj, i ) \ @@ -443,7 +458,9 @@ extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p ); /*=== giaAiger.c ===========================================================*/ extern Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ); extern void Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact ); +extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ); /*=== giaCsat.c ============================================================*/ +extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus ); /*=== giaCof.c =============================================================*/ extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes ); extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar ); @@ -455,6 +472,10 @@ extern void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ); /*=== giaDup.c ============================================================*/ +extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p ); + extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupSelf( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupFlopClass( Gia_Man_t * p, int iClass ); @@ -508,19 +529,22 @@ extern int Gia_ManHashXor( Gia_Man_t * p, int iLit0, int iLit1 ) extern int Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ); extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 ); extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p ); +extern void Gia_ManHashProfile( Gia_Man_t * p ); /*=== giaLogic.c ===========================================================*/ extern void Gia_ManTestDistance( Gia_Man_t * p ); extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ); /*=== giaMan.c ===========================================================*/ extern Gia_Man_t * Gia_ManStart( int nObjsMax ); extern void Gia_ManStop( Gia_Man_t * p ); -extern void Gia_ManPrintStats( Gia_Man_t * p ); +extern void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ); extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); /*=== giaMap.c ===========================================================*/ extern void Gia_ManPrintMappingStats( Gia_Man_t * p ); +/*=== giaPat.c ===========================================================*/ +extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); /*=== giaRetime.c ===========================================================*/ extern Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose ); /*=== giaSat.c ============================================================*/ @@ -535,6 +559,9 @@ extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ); /*=== giaSim.c ============================================================*/ extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); +/*=== giaSwitch.c ============================================================*/ +extern float Gia_ManEvaluateSwitching( Gia_Man_t * p ); +extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); /*=== giaTsim.c ============================================================*/ extern Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ); /*=== giaUtil.c ===========================================================*/ diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index da1a8c9f..adc58e6c 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -194,6 +194,25 @@ int Gia_ReadInt( unsigned char * pPos ) /**Function************************************************************* + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + Synopsis [Read equivalence classes from the string.] Description [] @@ -238,7 +257,7 @@ Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize ) /**Function************************************************************* - Synopsis [Reads decoded value.] + Synopsis [Read flop classes from the string.] Description [] @@ -247,12 +266,13 @@ Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize ) SeeAlso [] ***********************************************************************/ -unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize ) { - int Item = Gia_ReadAigerDecode( ppPos ); - if ( Item & 1 ) - return iPrev + (Item >> 1); - return iPrev - (Item >> 1); + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + assert( Vec_IntSize(vClasses) == nSize ); + memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); + *ppPos += 4 * nSize; } /**Function************************************************************* @@ -290,6 +310,50 @@ int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) /**Function************************************************************* + Synopsis [Read switching from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ + unsigned char * pSwitching; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc == nSize ); + pSwitching = ABC_ALLOC( unsigned char, nSize ); + memcpy( pSwitching, *ppPos, nSize ); + *ppPos += nSize; + return pSwitching; +} + +/**Function************************************************************* + + Synopsis [Read placement from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ + Gia_Plc_t * pPlacement; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); + memcpy( pPlacement, *ppPos, 4*nSize ); + *ppPos += 4 * nSize; + return pPlacement; +} + +/**Function************************************************************* + Synopsis [Reads the AIG in the binary AIGER format.] Description [] @@ -455,6 +519,13 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); pNew->pNexts = Gia_ManDeriveNexts( pNew ); } + if ( *pCur == 'f' ) + { + pCur++; + // read flop classes + pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); + Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); + } if ( *pCur == 'm' ) { pCur++; @@ -465,6 +536,13 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) { pCur++; // read placement + pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 's' ) + { + pCur++; + // read switching activity + pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); } if ( *pCur == 'n' ) { @@ -762,7 +840,10 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // create normalized AIG if ( !Gia_ManIsNormalized(pInit) ) + { + printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); p = Gia_ManDupNormalized( pInit ); + } else p = pInit; @@ -831,6 +912,15 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fwrite( pEquivs, 1, nEquivSize, pFile ); ABC_FREE( pEquivs ); } + // write flop classes + if ( p->vFlopClasses ) + { + char Buffer[10]; + int nSize = 4*Gia_ManRegNum(p); + fprintf( pFile, "f" ); + fwrite( Buffer, 1, 4, pFile ); + fwrite( Vec_IntArray(p->vFlopClasses), 1, nSize, pFile ); + } // write mapping if ( p->pMapping ) { @@ -841,6 +931,26 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ABC_FREE( pMaps ); } // write placement + if ( p->pPlacement ) + { + char Buffer[10]; + int nSize = 4*Gia_ManObjNum(p); + Gia_WriteInt( Buffer, nSize ); + fprintf( pFile, "p" ); + fwrite( Buffer, 1, 4, pFile ); + fwrite( p->pPlacement, 1, nSize, pFile ); + } + // write flop classes + if ( p->pSwitching ) + { + char Buffer[10]; + int nSize = Gia_ManObjNum(p); + Gia_WriteInt( Buffer, nSize ); + fprintf( pFile, "s" ); + fwrite( Buffer, 1, 4, pFile ); + fwrite( p->pSwitching, 1, nSize, pFile ); + } + // write name if ( p->pName ) fprintf( pFile, "n%s%c", p->pName, '\0' ); fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); @@ -850,6 +960,24 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int Gia_ManStop( p ); } +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ + char Buffer[100]; + sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); + Gia_WriteAiger( p, Buffer, 0, 0 ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaCSat2.c b/src/aig/gia/giaCSat.c index 1e7cc949..5fa9f40f 100644 --- a/src/aig/gia/giaCSat2.c +++ b/src/aig/gia/giaCSat.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [giaCSat2.c] + FileName [giaCSat.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -48,10 +48,10 @@ struct Cbs_Que_t_ { int iHead; // beginning of the queue int iTail; // end of the queue - int nSize; // allocated size + int nSize; // allocated size Gia_Obj_t ** pData; // nodes stored in the queue }; - + typedef struct Cbs_Man_t_ Cbs_Man_t; struct Cbs_Man_t_ { @@ -60,6 +60,20 @@ struct Cbs_Man_t_ Cbs_Que_t pProp; // propagation queue Cbs_Que_t pJust; // justification queue Vec_Int_t * vModel; // satisfying assignment + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + // runtime stats + int timeSatUnsat; // unsat + int timeSatSat; // sat + int timeSatUndec; // undecided + int timeTotal; // total runtime }; static inline int Cbs_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } @@ -196,7 +210,8 @@ static inline void Cbs_ManSaveModel( Cbs_Man_t * p, Vec_Int_t * vCex ) p->pProp.iHead = 0; Cbs_QueForEachEntry( p->pProp, pVar, i ) if ( Gia_ObjIsCi(pVar) ) - Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) ); +// Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) ); + Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pVar), !Cbs_VarValue(pVar)) ); } /**Function************************************************************* @@ -714,7 +729,7 @@ void Cbs_ManSolveTest( Gia_Man_t * pGia ) CountUndec++; else { - int iLit, k; +// int iLit, k; vCex = Cbs_ReadModel( p ); // printf( "complemented = %d. ", Gia_ObjFaninC0(pRoot) ); @@ -738,6 +753,132 @@ void Cbs_ManSolveTest( Gia_Man_t * pGia ) } +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cbs_ManSatPrintStats( Cbs_Man_t * p ) +{ + printf( "CO = %6d ", Gia_ManCoNum(p->pAig) ); + printf( "Conf = %5d ", p->Pars.nBTLimit ); + printf( "JustMax = %5d ", p->Pars.nJustLimit ); + printf( "\n" ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, 100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus ) +{ + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Cbs_Man_t * p; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot; + int i, status, clk, clkTotal = clock(); + assert( Gia_ManRegNum(pAig) == 0 ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + // create logic network + p = Cbs_ManAlloc(); + p->Pars.nBTLimit = nConfs; + p->pAig = pAig; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Cbs_ReadModel( p ); + // solve for each output + Gia_ManForEachCo( pAig, pRoot, i ) + { + Vec_IntClear( vCex ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) + { + if ( Gia_ObjFaninC0(pRoot) ) + { + printf( "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { + printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + clk = clock(); + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) ); + if ( status == -1 ) + { + p->Pars.fUseHighest = 0; + p->Pars.fUseLowest = 1; + status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) ); + } + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += clock() - clk; + continue; + } + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += clock() - clk; + continue; + } + p->nSatSat++; + p->nConfUnsat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); + p->timeSatSat += clock() - clk; + } + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = clock() - clkTotal; +// Cbs_ManSatPrintStats( p ); + Cbs_ManStop( p ); + *pvStatus = vStatus; +// printf( "Total number of cex literals = %d. (Ave = %d)\n", +// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat, +// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat ); + return vCexStore; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaCSat0.c b/src/aig/gia/giaCSat0.c deleted file mode 100644 index a0d567a2..00000000 --- a/src/aig/gia/giaCSat0.c +++ /dev/null @@ -1,328 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaCsat0.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Circuit-based SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaCsat0.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Sat_ObjXValue( Gia_Obj_t * pObj ) { return (pObj->fMark1 << 1) | pObj->fMark0; } -static inline void Sat_ObjSetXValue( Gia_Obj_t * pObj, int v) { pObj->fMark0 = (v & 1); pObj->fMark1 = ((v >> 1) & 1); } - -static inline int Sat_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->Value > 0; } -static inline void Sat_VarAssign( Gia_Obj_t * pVar, int i ) { assert(!pVar->Value); pVar->Value = i; } -static inline void Sat_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->Value); pVar->Value = 0; } -static inline int Sat_VarValue( Gia_Obj_t * pVar ) { assert(pVar->Value); return pVar->fMark0; } -static inline void Sat_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->Value); pVar->fMark0 = v; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Collects nodes in the cone and initialized them to x.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) -{ - if ( Sat_ObjXValue(pObj) == GIA_UND ) - return; - assert( pObj->Value == 0 ); - if ( Gia_ObjIsAnd(pObj) ) - { - Gia_SatCollectCone_rec( p, Gia_ObjFanin0(pObj), vVisit ); - Gia_SatCollectCone_rec( p, Gia_ObjFanin1(pObj), vVisit ); - } - assert( Sat_ObjXValue(pObj) == 0 ); - Sat_ObjSetXValue( pObj, GIA_UND ); - Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); -} - -/**Function************************************************************* - - Synopsis [Collects nodes in the cone and initialized them to x.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatCollectCone( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) -{ - assert( !Gia_IsComplement(pObj) ); - assert( !Gia_ObjIsConst0(pObj) ); - assert( Sat_ObjXValue(pObj) == 0 ); - Vec_IntClear( vVisit ); - Gia_SatCollectCone_rec( p, pObj, vVisit ); -} - -/**Function************************************************************* - - Synopsis [Collects nodes in the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ) -{ - Gia_Obj_t * pObj; - int i, Entry, Value, Value0, Value1; - assert( Gia_ObjIsCo(pRoot) ); - assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); - // collect nodes and initialized them to x - Gia_SatCollectCone( p, Gia_ObjFanin0(pRoot), vVisit ); - // set binary values to nodes in the counter-example - Vec_IntForEachEntry( vCex, Entry, i ) - { - pObj = Gia_NotCond( Gia_ManObj( p, Gia_Lit2Var(Entry) ), Gia_LitIsCompl(Entry) ); - Sat_ObjSetXValue( Gia_Regular(pObj), Gia_IsComplement(pObj)? GIA_ZER : GIA_ONE ); - assert( Sat_ObjXValue(Gia_Regular(pObj)) == (Gia_IsComplement(pObj)? GIA_ZER : GIA_ONE) ); - } - // simulate - Gia_ManForEachObjVec( vVisit, p, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - continue; - assert( Gia_ObjIsAnd(pObj) ); - Value0 = Sat_ObjXValue( Gia_ObjFanin0(pObj) ); - Value1 = Sat_ObjXValue( Gia_ObjFanin1(pObj) ); - Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); - Sat_ObjSetXValue( pObj, Value ); - } - Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pRoot) ); - if ( Value != GIA_ONE ) - printf( "Gia_SatVerifyPattern(): Verification FAILED.\n" ); -// else -// printf( "Gia_SatVerifyPattern(): Verification succeeded.\n" ); -// assert( Value == GIA_ONE ); - // clean the nodes - Gia_ManForEachObjVec( vVisit, p, pObj, i ) - Sat_ObjSetXValue( pObj, 0 ); -} - - -/**Function************************************************************* - - Synopsis [Undoes the assignment since the given value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatUndo_rec( Gia_Obj_t * pObj, unsigned Value, Vec_Int_t * vCex ) -{ - if ( pObj->Value < Value ) - return; - pObj->Value = 0; - if ( Gia_ObjIsCi(pObj) ) - { - if ( vCex ) Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pObj), !pObj->fPhase) ); - return; - } - Gia_SatUndo_rec( Gia_ObjFanin0(pObj), Value, vCex ); - Gia_SatUndo_rec( Gia_ObjFanin1(pObj), Value, vCex ); -} - -/**Function************************************************************* - - Synopsis [Propagates assignments.] - - Description [Returns 1 if UNSAT, 0 if SAT.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_SatProp_rec( Gia_Obj_t * pObj, unsigned Phase, unsigned * pValue, int * pnConfs ) -{ - int Value = *pValue; - if ( pObj->Value ) - return pObj->fPhase != Phase; - if ( Gia_ObjIsCi(pObj) ) - { - pObj->Value = Value; - pObj->fPhase = Phase; - return 0; - } - if ( Phase ) // output of AND should be 1 - { - if ( Gia_SatProp_rec( Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) - return 1; - if ( Gia_SatProp_rec( Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) - { - Gia_SatUndo_rec( Gia_ObjFanin0(pObj), Value, NULL ); - return 1; - } -/* - if ( Gia_SatProp_rec( Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) - return 1; - if ( Gia_SatProp_rec( Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) - { - Gia_SatUndo_rec( Gia_ObjFanin1(pObj), Value, NULL ); - return 1; - } -*/ - pObj->Value = Value; - pObj->fPhase = 1; - return 0; - } - // output of AND should be 0 - - (*pValue)++; - if ( !Gia_SatProp_rec( Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) - { - pObj->Value = Value; - pObj->fPhase = 0; - return 0; - } - if ( !*pnConfs ) - return 1; - - (*pValue)++; - if ( !Gia_SatProp_rec( Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) - { - pObj->Value = Value; - pObj->fPhase = 0; - return 0; - } - if ( !*pnConfs ) - return 1; - // cannot be satisfied - (*pnConfs)--; - return 1; -} - -/**Function************************************************************* - - Synopsis [Procedure to solve SAT for the node.] - - Description [Returns 1 if UNSAT, 0 if SAT, and -1 if undecided.] - - SideEffects [Precondition: pObj->Value should be 0.] - - SeeAlso [] - -***********************************************************************/ -int Gia_SatSolve( Gia_Obj_t * pObj, unsigned Phase, int nConfsMax, Vec_Int_t * vCex ) -{ - int Value = 1; - int nConfs = nConfsMax? nConfsMax : (1<<30); - assert( !Gia_IsComplement(pObj) ); - assert( !Gia_ObjIsConst0(pObj) ); - assert( pObj->Value == 0 ); - if ( Gia_SatProp_rec( pObj, Phase, &Value, &nConfs ) ) - { -// if ( nConfs ) -// printf( "UNSAT after %d conflicts\n", nConfsMax - nConfs ); -// else -// printf( "UNDEC after %d conflicts\n", nConfsMax ); - return nConfs? 1 : -1; - } - Vec_IntClear( vCex ); - Gia_SatUndo_rec( pObj, 1, vCex ); -// printf( "SAT after %d conflicts\n", nConfsMax - nConfs ); - return 0; -} - - - -/**Function************************************************************* - - Synopsis [Procedure to test the new SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatSolveTest( Gia_Man_t * p ) -{ - int nConfsMax = 1000; - int CountUnsat, CountSat, CountUndec; - Vec_Int_t * vCex; - Vec_Int_t * vVisit; - Gia_Obj_t * pRoot; - int i, RetValue, clk = clock(); - // prepare AIG - Gia_ManCleanValue( p ); - Gia_ManCleanMark0( p ); - Gia_ManCleanMark1( p ); - vCex = Vec_IntAlloc( 100 ); - vVisit = Vec_IntAlloc( 100 ); - // solve for each output - CountUnsat = CountSat = CountUndec = 0; - Gia_ManForEachCo( p, pRoot, i ) - { - if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) - continue; -//printf( "Output %6d : ", i ); - RetValue = Gia_SatSolve( Gia_ObjFanin0(pRoot), !Gia_ObjFaninC0(pRoot), nConfsMax, vCex ); - if ( RetValue == 1 ) - CountUnsat++; - else if ( RetValue == -1 ) - CountUndec++; - else - { -// Gia_Obj_t * pTemp; -// int k; - assert( RetValue == 0 ); - CountSat++; -/* - Vec_IntForEachEntry( vCex, pTemp, k ) -// printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjCioId(Gia_Regular(pTemp)) ); - printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjId(p,Gia_Regular(pTemp)) ); - printf( "\n" ); -*/ -// Gia_SatVerifyPattern( p, pRoot, vCex, vVisit ); - } -// Gia_ManCheckMark0( p ); -// Gia_ManCheckMark1( p ); - } - Vec_IntFree( vCex ); - Vec_IntFree( vVisit ); - printf( "Unsat = %d. Sat = %d. Undec = %d. ", CountUnsat, CountSat, CountUndec ); - ABC_PRT( "Time", clock() - clk ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSat1.c b/src/aig/gia/giaCSat1.c deleted file mode 100644 index 12b7071f..00000000 --- a/src/aig/gia/giaCSat1.c +++ /dev/null @@ -1,602 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaCsat1.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Circuit-based SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaCsat1.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - - -typedef struct Css_Fan_t_ Css_Fan_t; -struct Css_Fan_t_ -{ - unsigned iFan : 31; // ID of the fanin/fanout - unsigned fCompl : 1; // complemented attribute -}; - -typedef struct Css_Obj_t_ Css_Obj_t; -struct Css_Obj_t_ -{ - unsigned fCi : 1; // terminal node CI - unsigned fCo : 1; // terminal node CO - unsigned fAssign : 1; // assigned variable - unsigned fValue : 1; // variable value - unsigned fPhase : 1; // value under 000 pattern - unsigned nFanins : 5; // the number of fanins - unsigned nFanouts : 22; // total number of fanouts - unsigned hHandle; // application specific data - union { - unsigned iFanouts; // application specific data - int TravId; // ID of the node - }; - Css_Fan_t Fanios[0]; // the array of fanins/fanouts -}; - -typedef struct Css_Man_t_ Css_Man_t; -struct Css_Man_t_ -{ - Gia_Man_t * pGia; // the original AIG manager - Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) - Vec_Int_t * vCos; // the vector of COs (POs + LIs) - int nObjs; // the number of objects - int nNodes; // the number of nodes - int * pObjData; // the logic network defined for the AIG - int nObjData; // the size of array to store the logic network - int * pLevels; // the linked lists of levels - int nLevels; // the max number of logic levels - int nTravIds; // traversal ID to mark the cones - Vec_Int_t * vTrail; // sequence of assignments - int nConfsMax; // max number of conflicts -}; - -static inline unsigned Gia_ObjHandle( Gia_Obj_t * pObj ) { return pObj->Value; } - -static inline int Css_ObjIsCi( Css_Obj_t * pObj ) { return pObj->fCi; } -static inline int Css_ObjIsCo( Css_Obj_t * pObj ) { return pObj->fCo; } -static inline int Css_ObjIsNode( Css_Obj_t * pObj ) { return!pObj->fCi &&!pObj->fCo && pObj->nFanins > 0; } -static inline int Css_ObjIsConst0( Css_Obj_t * pObj ) { return!pObj->fCi &&!pObj->fCo && pObj->nFanins == 0;} - -static inline int Css_ObjFaninNum( Css_Obj_t * pObj ) { return pObj->nFanins; } -static inline int Css_ObjFanoutNum( Css_Obj_t * pObj ) { return pObj->nFanouts; } -static inline int Css_ObjSize( Css_Obj_t * pObj ) { return sizeof(Css_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } -static inline int Css_ObjId( Css_Obj_t * pObj ) { assert( 0 ); return -1; } - -static inline Css_Obj_t * Css_ManObj( Css_Man_t * p, unsigned iHandle ) { return (Css_Obj_t *)(p->pObjData + iHandle); } -static inline Css_Obj_t * Css_ObjFanin( Css_Obj_t * pObj, int i ) { return (Css_Obj_t *)(((int *)pObj) - pObj->Fanios[i].iFan); } -static inline Css_Obj_t * Css_ObjFanout( Css_Obj_t * pObj, int i ) { return (Css_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i].iFan); } -static inline int Css_ObjFaninC( Css_Obj_t * pObj, int i ) { return pObj->Fanios[i].fCompl; } -static inline int Css_ObjFanoutC( Css_Obj_t * pObj, int i ) { return pObj->Fanios[pObj->nFanins+i].fCompl; } - -static inline int Css_ManObjNum( Css_Man_t * p ) { return p->nObjs; } -static inline int Css_ManNodeNum( Css_Man_t * p ) { return p->nNodes; } - -static inline void Css_ManIncrementTravId( Css_Man_t * p ) { p->nTravIds++; } -static inline void Css_ObjSetTravId( Css_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; } -static inline void Css_ObjSetTravIdCurrent( Css_Man_t * p, Css_Obj_t * pObj ) { pObj->TravId = p->nTravIds; } -static inline void Css_ObjSetTravIdPrevious( Css_Man_t * p, Css_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1; } -static inline int Css_ObjIsTravIdCurrent( Css_Man_t * p, Css_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); } -static inline int Css_ObjIsTravIdPrevious( Css_Man_t * p, Css_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); } - -static inline int Css_VarIsAssigned( Css_Obj_t * pVar ) { return pVar->fAssign; } -static inline void Css_VarAssign( Css_Obj_t * pVar ) { assert(!pVar->fAssign); pVar->fAssign = 1; } -static inline void Css_VarUnassign( Css_Obj_t * pVar ) { assert(pVar->fAssign); pVar->fAssign = 0; } -static inline int Css_VarValue( Css_Obj_t * pVar ) { assert(pVar->fAssign); return pVar->fValue; } -static inline void Css_VarSetValue( Css_Obj_t * pVar, int v ) { assert(pVar->fAssign); pVar->fValue = v; } - -#define Css_ManForEachObj( p, pObj, i ) \ - for ( i = 0; (i < p->nObjData) && (pObj = Css_ManObj(p,i)); i += Css_ObjSize(pObj) ) -#define Css_ManForEachObjVecStart( vVec, p, pObj, i, iStart ) \ - for ( i = iStart; (i < Vec_IntSize(vVec)) && (pObj = Css_ManObj(p,Vec_IntEntry(vVec,i))); i++ ) -#define Css_ManForEachNode( p, pObj, i ) \ - for ( i = 0; (i < p->nObjData) && (pObj = Css_ManObj(p,i)); i += Css_ObjSize(pObj) ) if ( Css_ObjIsTerm(pObj) ) {} else -#define Css_ObjForEachFanin( pObj, pNext, i ) \ - for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Css_ObjFanin(pObj,i)); i++ ) -#define Css_ObjForEachFanout( pObj, pNext, i ) \ - for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Css_ObjFanout(pObj,i)); i++ ) -#define Css_ObjForEachFaninLit( pObj, pNext, fCompl, i ) \ - for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Css_ObjFanin(pObj,i)) && ((fCompl = Css_ObjFaninC(pObj,i)),1); i++ ) -#define Css_ObjForEachFanoutLit( pObj, pNext, fCompl, i ) \ - for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Css_ObjFanout(pObj,i)) && ((fCompl = Css_ObjFanoutC(pObj,i)),1); i++ ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates logic network isomorphic to the given AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Css_Man_t * Css_ManCreateLogicSimple( Gia_Man_t * pGia ) -{ - Css_Man_t * p; - Css_Obj_t * pObjLog, * pFanLog; - Gia_Obj_t * pObj; - int i, iHandle = 0; - p = ABC_CALLOC( Css_Man_t, 1 ); - p->pGia = pGia; - p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); - p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); - p->nObjData = (sizeof(Css_Obj_t) / 4) * Gia_ManObjNum(pGia) + 4 * Gia_ManAndNum(pGia) + 2 * Gia_ManCoNum(pGia); - p->pObjData = ABC_CALLOC( int, p->nObjData ); - ABC_FREE( pGia->pRefs ); - Gia_ManCreateRefs( pGia ); - Gia_ManForEachObj( pGia, pObj, i ) - { - pObj->Value = iHandle; - pObjLog = Css_ManObj( p, iHandle ); - pObjLog->nFanins = 0; - pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); - pObjLog->hHandle = iHandle; - pObjLog->iFanouts = 0; - if ( Gia_ObjIsAnd(pObj) ) - { - pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan = - pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = - pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); - - pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin1(pObj)) ); - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan = - pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = - pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC1(pObj); - - p->nNodes++; - } - else if ( Gia_ObjIsCo(pObj) ) - { - pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan = - pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; - pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = - pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); - - pObjLog->fCo = 1; - Vec_IntPush( p->vCos, iHandle ); - } - else if ( Gia_ObjIsCi(pObj) ) - { - pObjLog->fCi = 1; - Vec_IntPush( p->vCis, iHandle ); - } - iHandle += Css_ObjSize( pObjLog ); - p->nObjs++; - } - assert( iHandle == p->nObjData ); - Gia_ManForEachObj( pGia, pObj, i ) - { - pObjLog = Css_ManObj( p, Gia_ObjHandle(pObj) ); - assert( pObjLog->nFanouts == pObjLog->iFanouts ); - pObjLog->TravId = 0; - } - p->nTravIds = 1; - p->vTrail = Vec_IntAlloc( 100 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates logic network isomorphic to the given AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Css_ManStop( Css_Man_t * p ) -{ - Vec_IntFree( p->vTrail ); - Vec_IntFree( p->vCis ); - Vec_IntFree( p->vCos ); - ABC_FREE( p->pObjData ); - ABC_FREE( p->pLevels ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Propagates implications for the net.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Css_ManImplyNet_rec( Css_Man_t * p, Css_Obj_t * pVar, unsigned Value ) -{ - static inline Css_ManImplyNode_rec( Css_Man_t * p, Css_Obj_t * pVar ); - Css_Obj_t * pNext; - int i; - if ( !Css_ObjIsTravIdCurrent(p, pVar) ) - return 0; - // assign the variable - assert( !Css_VarIsAssigned(pVar) ); - Css_VarAssign( pVar ); - Css_VarSetValue( pVar, Value ); - Vec_IntPush( p->vTrail, pVar->hHandle ); - // propagate fanouts, then fanins - Css_ObjForEachFanout( pVar, pNext, i ) - if ( Css_ManImplyNode_rec( p, pNext ) ) - return 1; - Css_ObjForEachFanin( pVar, pNext, i ) - if ( Css_ManImplyNode_rec( p, pNext ) ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Propagates implications for the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Css_ManImplyNode_rec( Css_Man_t * p, Css_Obj_t * pVar ) -{ - Css_Obj_t * pFan0, * pFan1; - if ( Css_ObjIsCi(pVar) ) - return 0; - pFan0 = Css_ObjFanin(pVar, 0); - pFan1 = Css_ObjFanin(pVar, 1); - if ( !Css_VarIsAssigned(pVar) ) - { - if ( Css_VarIsAssigned(pFan0) ) - { - if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> propagate - return Css_ManImplyNet_rec(p, pVar, 0); - // assigned positive - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> propagate - return Css_ManImplyNet_rec(p, pVar, 0); - // asigned positive -> propagate - return Css_ManImplyNet_rec(p, pVar, 1); - } - return 0; - } - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> propagate - return Css_ManImplyNet_rec(p, pVar, 0); - return 0; - } - assert( 0 ); - return 0; - } - if ( Css_VarValue(pVar) ) // positive - { - if ( Css_VarIsAssigned(pFan0) ) - { - if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> conflict - return 1; - // check second var - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> conflict - return 1; - // positive + positive -> nothing to do - return 0; - } - } - else - { - // pFan0 unassigned -> enqueue first var -// Css_ManEnqueue( p, pFan0, !Css_ObjFaninC(pVar,0) ); - if ( Css_ManImplyNet_rec( p, pFan0, !Css_ObjFaninC(pVar,0) ) ) - return 1; - // check second var - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> conflict - return 1; - // positive + positive -> nothing to do - return 0; - } - } - // unassigned -> enqueue second var -// Css_ManEnqueue( p, pFan1, !Css_ObjFaninC(pVar,1) ); - return Css_ManImplyNet_rec( p, pFan1, !Css_ObjFaninC(pVar,1) ); - } - else // negative - { - if ( Css_VarIsAssigned(pFan0) ) - { - if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> nothing to do - return 0; - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> nothing to do - return 0; - // positive + positive -> conflict - return 1; - } - // positive + unassigned -> enqueue second var -// Css_ManEnqueue( p, pFan1, Css_ObjFaninC(pVar,1) ); - return Css_ManImplyNet_rec( p, pFan1, Css_ObjFaninC(pVar,1) ); - } - else - { - if ( Css_VarIsAssigned(pFan1) ) - { - if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> nothing to do - return 0; - // unassigned + positive -> enqueue first var -// Css_ManEnqueue( p, pFan0, Css_ObjFaninC(pVar,0) ); - return Css_ManImplyNet_rec( p, pFan0, Css_ObjFaninC(pVar,0) ); - } - } - } - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Css_ManCancelUntil( Css_Man_t * p, int iBound, Vec_Int_t * vCex ) -{ - Css_Obj_t * pVar; - int i; - Css_ManForEachObjVecStart( p->vTrail, p, pVar, i, iBound ) - { - if ( vCex ) - Vec_IntPush( vCex, Gia_Var2Lit(Css_ObjId(pVar), !pVar->fValue) ); - Css_VarUnassign( pVar ); - } - Vec_IntShrink( p->vTrail, iBound ); -} - -/**Function************************************************************* - - Synopsis [Justifies assignments.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Css_ManJustify( Css_Man_t * p, int iBegin ) -{ - Css_Obj_t * pVar, * pFan0, * pFan1; - int iState, iThis; - if ( p->nConfsMax == 0 ) - return 1; - // get the next variable to justify - Css_ManForEachObjVecStart( p->vTrail, p, pVar, iThis, iBegin ) - { - assert( Css_VarIsAssigned(pVar) ); - if ( Css_VarValue(pVar) || Css_ObjIsCi(pVar) ) - continue; - pFan0 = Css_ObjFanin(pVar,0); - pFan1 = Css_ObjFanin(pVar,0); - if ( !Css_VarIsAssigned(pFan0) && !Css_VarIsAssigned(pFan1) ) - break; - } - if ( iThis == Vec_IntSize(p->vTrail) ) // could not find - return 0; - // found variable to justify - assert( !Css_VarValue(pVar) && !Css_VarIsAssigned(pFan0) && !Css_VarIsAssigned(pFan1) ); - // remember the state of the stack - iState = Vec_IntSize( p->vTrail ); - // try to justify by setting first fanin to 0 - if ( !Css_ManImplyNet_rec(p, pFan0, 0) && !Css_ManJustify(p, iThis) ) - return 0; - Css_ManCancelUntil( p, iState, NULL ); - if ( p->nConfsMax == 0 ) - return 1; - // try to justify by setting second fanin to 0 - if ( !Css_ManImplyNet_rec(p, pFan1, 0) && !Css_ManJustify(p, iThis) ) - return 0; - Css_ManCancelUntil( p, iState, NULL ); - if ( p->nConfsMax == 0 ) - return 1; - p->nConfsMax--; - return 1; -} - -/**Function************************************************************* - - Synopsis [Marsk logic cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Css_ManMarkCone_rec( Css_Man_t * p, Css_Obj_t * pVar ) -{ - if ( Css_ObjIsTravIdCurrent(p, pVar) ) - return; - Css_ObjSetTravIdCurrent(p, pVar); - assert( !Css_VarIsAssigned(pVar) ); - if ( Css_ObjIsCi(pVar) ) - return; - else - { - Css_Obj_t * pNext; - int i; - Css_ObjForEachFanin( pVar, pNext, i ) - Css_ManMarkCone_rec( p, pNext ); - } -} - -/**Function************************************************************* - - Synopsis [Runs one call to the SAT solver.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Css_ManPrepare( Css_Man_t * p, int * pLits, int nLits ) -{ - Css_Obj_t * pVar; - int i; - // mark the cone - Css_ManIncrementTravId( p ); - for ( i = 0; i < nLits; i++ ) - { - pVar = Css_ManObj( p, Gia_Lit2Var(pLits[i]) ); - Css_ManMarkCone_rec( p, pVar ); - } - // assign literals - Vec_IntClear( p->vTrail ); - for ( i = 0; i < nLits; i++ ) - { - pVar = Css_ManObj( p, Gia_Lit2Var(pLits[i]) ); - if ( Css_ManImplyNet_rec( p, pVar, !Gia_LitIsCompl(pLits[i]) ) ) - { - Css_ManCancelUntil( p, 0, NULL ); - return 1; - } - } - return 0; -} - - -/**Function************************************************************* - - Synopsis [Runs one call to the SAT solver.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Css_ManSolve( Css_Man_t * p, int * pLits, int nLits, int nConfsMax, Vec_Int_t * vCex ) -{ - // propagate the assignments - if ( Css_ManPrepare( p, pLits, nLits ) ) - return 1; - // justify the assignments - p->nConfsMax = nConfsMax; - if ( Css_ManJustify( p, 0 ) ) - return p->nConfsMax? 1 : -1; - // derive model and return the solver to the initial state - Vec_IntClear( vCex ); - Css_ManCancelUntil( p, 0, vCex ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Procedure to test the new SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SatSolveTest2( Gia_Man_t * pGia ) -{ - extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); - int nConfsMax = 1000; - int CountUnsat, CountSat, CountUndec; - Css_Man_t * p; - Vec_Int_t * vCex; - Vec_Int_t * vVisit; - Gia_Obj_t * pRoot; - int i, RetValue, iLit, clk = clock(); - // create logic network - p = Css_ManCreateLogicSimple( pGia ); - // prepare AIG - Gia_ManCleanValue( pGia ); - Gia_ManCleanMark0( pGia ); - Gia_ManCleanMark1( pGia ); - vCex = Vec_IntAlloc( 100 ); - vVisit = Vec_IntAlloc( 100 ); - // solve for each output - CountUnsat = CountSat = CountUndec = 0; - Gia_ManForEachCo( pGia, pRoot, i ) - { - if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) - continue; -//printf( "Output %6d : ", i ); - iLit = Gia_Var2Lit( Gia_ObjHandle(Gia_ObjFanin0(pRoot)), Gia_ObjFaninC0(pRoot) ); - RetValue = Css_ManSolve( p, &iLit, 1, nConfsMax, vCex ); - if ( RetValue == 1 ) - CountUnsat++; - else if ( RetValue == -1 ) - CountUndec++; - else - { -// Gia_Obj_t * pTemp; -// int k; - assert( RetValue == 0 ); - CountSat++; -/* - Vec_PtrForEachEntry( vCex, pTemp, k ) -// printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjCioId(Gia_Regular(pTemp)) ); - printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjId(p,Gia_Regular(pTemp)) ); - printf( "\n" ); -*/ - Gia_SatVerifyPattern( pGia, pRoot, vCex, vVisit ); - } -// Gia_ManCheckMark0( p ); -// Gia_ManCheckMark1( p ); - } - Css_ManStop( p ); - Vec_IntFree( vCex ); - Vec_IntFree( vVisit ); - printf( "Unsat = %d. Sat = %d. Undec = %d. ", CountUnsat, CountSat, CountUndec ); - ABC_PRT( "Time", clock() - clk ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSatA.c b/src/aig/gia/giaCSatA.c deleted file mode 100644 index 12f6895a..00000000 --- a/src/aig/gia/giaCSatA.c +++ /dev/null @@ -1,103 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaSolver.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Circuit-based SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sat_Cla_t_ Sat_Cla_t; -struct Sat_Cla_t_ -{ - unsigned hWatch0; // watched list for 0 literal - unsigned hWatch1; // watched list for 1 literal - int Activity; // activity of the clause - int nLits; // the number of literals - int pLits[0]; // the array of literals -}; - -typedef struct Sat_Fan_t_ Sat_Fan_t; -struct Sat_Fan_t_ -{ - unsigned iFan : 31; // ID of the fanin/fanout - unsigned fCompl : 1; // complemented attribute -}; - -typedef struct Sat_Obj_t_ Sat_Obj_t; -struct Sat_Obj_t_ -{ - unsigned hHandle; // node handle - unsigned fAssign : 1; // terminal node (CI/CO) - unsigned fValue : 1; // value under 000 pattern - unsigned fMark0 : 1; // first user-controlled mark - unsigned fMark1 : 1; // second user-controlled mark - unsigned nFanouuts : 28; // the number of fanouts - unsigned nFanins : 8; // the number of fanins - unsigned Level : 24; // logic level - unsigned hNext; // next one on this level - unsigned hWatch0; // watched list for 0 literal - unsigned hWatch1; // watched list for 1 literal - unsigned hReason; // reason for this variable - unsigned Depth; // decision depth - Sat_Fan_t Fanios[0]; // the array of fanins/fanouts -}; - -typedef struct Sat_Man_t_ Sat_Man_t; -struct Sat_Man_t_ -{ - Gia_Man_t * pGia; // the original AIG manager - // circuit - Vec_Int_t vCis; // the vector of CIs (PIs + LOs) - Vec_Int_t vObjs; // the vector of objects - // learned clauses - Vec_Int_t vClauses; // the vector of clauses - // solver data - Vec_Int_t vTrail; // variable queue - Vec_Int_t vTrailLim; // pointer into the trail - int iHead; // variable queue - int iTail; // variable queue - int iRootLevel; // first decision - // levelized order - int iLevelTop; // the largest unassigned level - Vec_Int_t vLevels; // the linked lists of levels -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSatB.c b/src/aig/gia/giaCSatB.c deleted file mode 100644 index e1f68c6f..00000000 --- a/src/aig/gia/giaCSatB.c +++ /dev/null @@ -1,490 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaSolver.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Circuit-based SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sat_Man_t_ Sat_Man_t; -struct Sat_Man_t_ -{ - Gia_Man_t * pGia; // the original AIG manager - Vec_Int_t * vModel; // satisfying PI assignment - int nConfs; // cur number of conflicts - int nConfsMax; // max number of conflicts - int iHead; // variable queue - int iTail; // variable queue - int iJust; // head of justification - int nTrail; // variable queue size - int pTrail[0]; // variable queue data -}; - -static inline int Sat_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } -static inline void Sat_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; } -static inline void Sat_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; } -static inline int Sat_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; } -static inline void Sat_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; } - -extern void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ); -extern void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sat_Man_t * Sat_ManCreate( Gia_Man_t * pGia ) -{ - Sat_Man_t * p; - p = (Sat_Man_t *)ABC_ALLOC( char, sizeof(Sat_Man_t) + sizeof(int)*Gia_ManObjNum(pGia) ); - memset( p, 0, sizeof(Sat_Man_t) ); - p->pGia = pGia; - p->nTrail = Gia_ManObjNum(pGia); - p->vModel = Vec_IntAlloc( 1000 ); - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sat_ManDelete( Sat_Man_t * p ) -{ - Vec_IntFree( p->vModel ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Sat_ManCancelUntil( Sat_Man_t * p, int iBound ) -{ - Gia_Obj_t * pVar; - int i; - for ( i = p->iTail-1; i >= iBound; i-- ) - { - pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); - Sat_VarUnassign( pVar ); - } - p->iTail = p->iTail = iBound; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Sat_ManDeriveModel( Sat_Man_t * p ) -{ - Gia_Obj_t * pVar; - int i; - Vec_IntClear( p->vModel ); - for ( i = 0; i < p->iTail; i++ ) - { - pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); - if ( Gia_ObjIsCi(pVar) ) - Vec_IntPush( p->vModel, Gia_ObjCioId(pVar) ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Sat_ManEnqueue( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) -{ - assert( p->iTail < p->nTrail ); - Sat_VarAssign( pVar ); - Sat_VarSetValue( pVar, Value ); - p->pTrail[p->iTail++] = Gia_ObjId(p->pGia, pVar); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Sat_ManAssume( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) -{ - assert( p->iHead == p->iTail ); - Sat_ManEnqueue( p, pVar, Value ); -} - -/**Function************************************************************* - - Synopsis [Propagates one assignment.] - - Description [Returns 1 if there is no conflict, 0 otherwise.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Sat_ManPropagateOne( Sat_Man_t * p, int iPos ) -{ - Gia_Obj_t * pVar, * pFan0, * pFan1; - pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); - if ( Gia_ObjIsCi(pVar) ) - return 1; - pFan0 = Gia_ObjFanin0(pVar); - pFan1 = Gia_ObjFanin1(pVar); - if ( Sat_VarValue(pVar) ) // positive - { - if ( Sat_VarIsAssigned(pFan0) ) - { - if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> conflict - return 0; - // check second var - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict - return 0; - // positive + positive -> nothing to do - return 1; - } - } - else - { - // pFan0 unassigned -> enqueue first var - Sat_ManEnqueue( p, pFan0, !Gia_ObjFaninC0(pVar) ); - // check second var - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict - return 0; - // positive + positive -> nothing to do - return 1; - } - } - // unassigned -> enqueue second var - Sat_ManEnqueue( p, pFan1, !Gia_ObjFaninC1(pVar) ); - } - else // negative - { - if ( Sat_VarIsAssigned(pFan0) ) - { - if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> nothing to do - return 1; - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do - return 1; - // positive + positive -> conflict - return 0; - } - // positive + unassigned -> enqueue second var - Sat_ManEnqueue( p, pFan1, Gia_ObjFaninC1(pVar) ); - } - else - { - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do - return 1; - // unassigned + positive -> enqueue first var - Sat_ManEnqueue( p, pFan0, Gia_ObjFaninC0(pVar) ); - } - } - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Propagates assignments.] - - Description [Returns 1 if there is no conflict.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Sat_ManPropagate( Sat_Man_t * p ) -{ - assert( p->iHead <= p->iTail ); - for ( ; p->iHead < p->iTail; p->iHead++ ) - if ( !Sat_ManPropagateOne( p, p->pTrail[p->iHead] ) ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Propagates one assignment.] - - Description [Returns 1 if justified, 0 if conflict, -1 if needs justification.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Sat_ManJustifyNextOne( Sat_Man_t * p, int iPos ) -{ - Gia_Obj_t * pVar, * pFan0, * pFan1; - pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); - if ( Gia_ObjIsCi(pVar) ) - return 1; - pFan0 = Gia_ObjFanin0(pVar); - pFan1 = Gia_ObjFanin1(pVar); - if ( Sat_VarValue(pVar) ) // positive - return 1; - // nevative - if ( Sat_VarIsAssigned(pFan0) ) - { - if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> already justified - return 1; - // positive - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified - return 1; - // positive -> conflict - return 0; - } - // unasigned -> propagate - Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); - return Sat_ManPropagate(p); - } - if ( Sat_VarIsAssigned(pFan1) ) - { - if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified - return 1; - // positive - assert( !Sat_VarIsAssigned(pFan0) ); - // unasigned -> propagate - Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); - return Sat_ManPropagate(p); - } - return -1; -} - -/**Function************************************************************* - - Synopsis [Justifies assignments.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sat_ManJustify( Sat_Man_t * p ) -{ - Gia_Obj_t * pVar, * pFan0, * pFan1; - int RetValue, iState, iJustState; - if ( p->nConfs && p->nConfs >= p->nConfsMax ) - return -1; - // get the next variable to justify - assert( p->iJust <= p->iTail ); - iJustState = p->iJust; - for ( ; p->iJust < p->iTail; p->iJust++ ) - { - RetValue = Sat_ManJustifyNextOne( p, p->pTrail[p->iJust] ); - if ( RetValue == 0 ) - return 1; - if ( RetValue == -1 ) - break; - } - if ( p->iJust == p->iTail ) // could not find - return 0; - // found variable to justify - pVar = Gia_ManObj( p->pGia, p->pTrail[p->iJust] ); - pFan0 = Gia_ObjFanin0(pVar); - pFan1 = Gia_ObjFanin1(pVar); - assert( !Sat_VarValue(pVar) && !Sat_VarIsAssigned(pFan0) && !Sat_VarIsAssigned(pFan1) ); - // remember the state of the stack - iState = p->iHead; - // try to justify by setting first fanin to 0 - Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); - if ( Sat_ManPropagate(p) ) - { - RetValue = Sat_ManJustify(p); - if ( RetValue != 1 ) - return RetValue; - } - Sat_ManCancelUntil( p, iState ); - // try to justify by setting second fanin to 0 - Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); - if ( Sat_ManPropagate(p) ) - { - RetValue = Sat_ManJustify(p); - if ( RetValue != 1 ) - return RetValue; - } - Sat_ManCancelUntil( p, iState ); - p->iJust = iJustState; - p->nConfs++; - return 1; -} - -/**Function************************************************************* - - Synopsis [Runs one call to the SAT solver.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sat_ManPrepare( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) -{ - Gia_Obj_t * pVar; - int i; - // double check that vars are unassigned - Gia_ManForEachObj( p->pGia, pVar, i ) - assert( !Sat_VarIsAssigned(pVar) ); - // prepare - p->iHead = p->iTail = p->iJust = 0; - p->nConfsMax = nConfsMax; - // assign literals - for ( i = 0; i < nLits; i++ ) - { - pVar = Gia_ManObj( p->pGia, Gia_Lit2Var(pLits[i]) ); - if ( Sat_VarIsAssigned(pVar) ) // assigned - { - if ( Sat_VarValue(pVar) != Gia_LitIsCompl(pLits[i]) ) // compatible assignment - continue; - } - else // unassigned - { - Sat_ManAssume( p, pVar, !Gia_LitIsCompl(pLits[i]) ); - if ( Sat_ManPropagate(p) ) - continue; - } - // conflict - Sat_ManCancelUntil( p, 0 ); - return 1; - } - assert( p->iHead == p->iTail ); - return 0; -} - - -/**Function************************************************************* - - Synopsis [Runs one call to the SAT solver.] - - Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sat_ManSolve( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) -{ - int RetValue; - // propagate the assignments - if ( Sat_ManPrepare( p, pLits, nLits, nConfsMax ) ) - return 1; - // justify the assignments - RetValue = Sat_ManJustify( p ); - if ( RetValue == 0 ) // SAT - Sat_ManDeriveModel( p ); - // return the solver to the initial state - Sat_ManCancelUntil( p, 0 ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Testing the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ) -{ - Sat_Man_t * p; - int RetValue, iLit; - assert( Gia_ObjIsCo(pObj) ); - p = Sat_ManCreate( pGia ); - iLit = Gia_LitNot( Gia_ObjFaninLit0p(pGia, pObj) ); - RetValue = Sat_ManSolve( p, &iLit, 1, nConfsMax ); - if ( RetValue == 0 ) - { - Cec_ManPatVerifyPattern( pGia, pObj, p->vModel ); - Cec_ManPatCleanMark0( pGia, pObj ); - } - Sat_ManDelete( p ); - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index c5efa839..b256100c 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -859,7 +859,7 @@ Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose if ( fVerbose ) { printf( "Cofactoring %d signals.\n", Vec_IntSize(vSigs) ); - Gia_ManPrintStats( p ); + Gia_ManPrintStats( p, 0 ); } if ( Vec_IntSize( vSigs ) > 200 ) { @@ -885,7 +885,7 @@ Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose if ( fVerbose ) printf( "Cofactored variable %d.\n", iVar ); if ( fVerbose ) - Gia_ManPrintStats( pAig ); + Gia_ManPrintStats( pAig, 0 ); } Vec_IntFree( vSigsNew ); return pAig; diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 0c536dab..2510f572 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -30,6 +30,226 @@ /**Function************************************************************* + Synopsis [Removes pointers to the unmarked nodes..] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p ) +{ + Vec_Int_t * vClass; + int i, k, iNode, iRepr, iPrev; + if ( p->pReprs == NULL ) + return; + assert( pNew->pReprs == NULL && pNew->pNexts == NULL ); + // start representatives + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) ); + for ( i = 0; i < Gia_ManObjNum(pNew); i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + // iterate over constant candidates + Gia_ManForEachConst( p, i ) + Gia_ObjSetRepr( pNew, Gia_Lit2Var(Gia_ManObj(p, i)->Value), 0 ); + // iterate over class candidates + vClass = Vec_IntAlloc( 100 ); + Gia_ManForEachClass( p, i ) + { + Vec_IntClear( vClass ); + Gia_ClassForEachObj( p, i, k ) + Vec_IntPushUnique( vClass, Gia_Lit2Var(Gia_ManObj(p, k)->Value) ); + assert( Vec_IntSize( vClass ) > 1 ); + Vec_IntSort( vClass, 0 ); + iRepr = iPrev = Vec_IntEntry( vClass, 0 ); + Vec_IntForEachEntryStart( vClass, iNode, k, 1 ) + { + Gia_ObjSetRepr( pNew, iNode, iRepr ); + assert( iPrev < iNode ); + iPrev = iNode; + } + } + Vec_IntFree( vClass ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); +} + +/**Function************************************************************* + + Synopsis [Remaps combinational inputs when objects are DFS ordered.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupRemapCis( Gia_Man_t * pNew, Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + assert( Vec_IntSize(p->vCis) == Vec_IntSize(pNew->vCis) ); + Gia_ManForEachCi( p, pObj, i ) + { + assert( Gia_ObjCioId(pObj) == i ); + pObjNew = Gia_ObjFromLit( pNew, pObj->Value ); + assert( !Gia_IsComplement(pObjNew) ); + Vec_IntWriteEntry( pNew->vCis, i, Gia_ObjId(pNew, pObjNew) ); + Gia_ObjSetCioId( pObjNew, i ); + } +} + +/**Function************************************************************* + + Synopsis [Remaps combinational outputs when objects are DFS ordered.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupRemapCos( Gia_Man_t * pNew, Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + assert( Vec_IntSize(p->vCos) == Vec_IntSize(pNew->vCos) ); + Gia_ManForEachCo( p, pObj, i ) + { + assert( Gia_ObjCioId(pObj) == i ); + pObjNew = Gia_ObjFromLit( pNew, pObj->Value ); + assert( !Gia_IsComplement(pObjNew) ); + Vec_IntWriteEntry( pNew->vCos, i, Gia_ObjId(pNew, pObjNew) ); + Gia_ObjSetCioId( pObjNew, i ); + } +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + if ( Gia_ObjIsCi(pObj) ) + return pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupOrderDfs_rec( pNew, p, pObj ); + Gia_ManForEachCi( p, pObj, i ) + if ( !~pObj->Value ) + pObj->Value = Gia_ManAppendCi(pNew); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + Gia_ManDupRemapCis( pNew, p ); + Gia_ManDupRemapEquiv( pNew, p ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCoReverse( p, pObj, i ) + Gia_ManDupOrderDfs_rec( pNew, p, pObj ); + Gia_ManForEachCi( p, pObj, i ) + if ( !~pObj->Value ) + pObj->Value = Gia_ManAppendCi(pNew); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + Gia_ManDupRemapCis( pNew, p ); + Gia_ManDupRemapCos( pNew, p ); + Gia_ManDupRemapEquiv( pNew, p ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting first PIs, then nodes, then POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManDupRemapEquiv( pNew, p ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + assert( Gia_ManIsNormalized(pNew) ); + return pNew; +} + + + +/**Function************************************************************* + Synopsis [Duplicates AIG without any changes.] Description [] @@ -296,7 +516,7 @@ int Gia_ManDupDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) if ( pNew->pHTable ) return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} +} /**Function************************************************************* diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index 6c2f00df..fa172f70 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -36,6 +36,8 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define GIA_PLACE_SIZE 0x7fff +// objects will be placed in box [0, GIA_PLACE_SIZE] x [0, GIA_PLACE_SIZE] typedef float Emb_Dat_t; @@ -247,6 +249,7 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia ) Emb_ObjAddFanin( Emb_ManObj(p,Gia_ObjValue(pObjRo)), Emb_ManObj(p,Gia_ObjValue(pObjRi)) ); assert( nNodes == Emb_ManNodeNum(p) ); assert( hHandle == p->nObjData ); + assert( p->nObjs == Gia_ManObjNum(pGia) ); if ( hHandle != p->nObjData ) printf( "Emb_ManStartSimple(): Fatal error in internal representation.\n" ); // make sure the fanin/fanout counters are correct @@ -1407,7 +1410,7 @@ void Emb_ManComputeSolutions( Emb_Man_t * p, int nDims, int nSols ) /**Function************************************************************* - Synopsis [Projects into square of size [0;0xffff] x [0;0xffff].] + Synopsis [Projects into square of size [0;GIA_PLACE_SIZE] x [0;GIA_PLACE_SIZE].] Description [] @@ -1432,7 +1435,7 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) Min0 = ABC_MIN( Min0, pY0[k] ); Max0 = ABC_MAX( Max0, pY0[k] ); } - Str0 = 1.0*0xffff/(Max0 - Min0); + Str0 = 1.0*GIA_PLACE_SIZE/(Max0 - Min0); // update the coordinates for ( k = 0; k < p->nObjs; k++ ) pY0[k] = (pY0[k] != 0.0) ? ((pY0[k] - Min0) * Str0) : 0.0; @@ -1446,7 +1449,7 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) Min1 = ABC_MIN( Min1, pY1[k] ); Max1 = ABC_MAX( Max1, pY1[k] ); } - Str1 = 1.0*0xffff/(Max1 - Min1); + Str1 = 1.0*GIA_PLACE_SIZE/(Max1 - Min1); // update the coordinates for ( k = 0; k < p->nObjs; k++ ) pY1[k] = (pY1[k] != 0.0) ? ((pY1[k] - Min1) * Str1) : 0.0; @@ -1455,12 +1458,12 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols ) pPerm0 = Gia_SortFloats( pY0, NULL, p->nObjs ); pPerm1 = Gia_SortFloats( pY1, NULL, p->nObjs ); - // average solutions and project them into square [0;0xffff] x [0;0xffff] + // average solutions and project them into square [0;GIA_PLACE_SIZE] x [0;GIA_PLACE_SIZE] p->pPlacement = ABC_ALLOC( unsigned short, 2 * p->nObjs ); for ( k = 0; k < p->nObjs; k++ ) { - p->pPlacement[2*pPerm0[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); - p->pPlacement[2*pPerm1[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + p->pPlacement[2*pPerm0[k]+0] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); + p->pPlacement[2*pPerm1[k]+1] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); } ABC_FREE( pPerm0 ); ABC_FREE( pPerm1 ); @@ -1568,8 +1571,8 @@ void Emb_ManPlacementRefine( Emb_Man_t * p, int nIters, int fVerbose ) pPermY = Gia_SortFloats( pVertY, NULL, p->nObjs ); for ( k = 0; k < p->nObjs; k++ ) { - p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); - p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); + p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); + p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); } ABC_FREE( pPermX ); ABC_FREE( pPermY ); @@ -1783,7 +1786,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowI void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ) { Emb_Man_t * p; - int clk, clkSetup; + int i, clk, clkSetup; // Gia_ManTestDistance( pGia ); // transform AIG into internal data-structure @@ -1843,6 +1846,17 @@ if ( pPars->fVerbose ) ABC_PRT( "Image dump", clock() - clk ); } + // transfer placement + if ( Gia_ManObjNum(pGia) == p->nObjs ) + { + // assuming normalized ordering of the AIG + pGia->pPlacement = ABC_CALLOC( Gia_Plc_t, p->nObjs ); + for ( i = 0; i < p->nObjs; i++ ) + { + pGia->pPlacement[i].xCoord = p->pPlacement[2*i+0]; + pGia->pPlacement[i].yCoord = p->pPlacement[2*i+1]; + } + } Emb_ManStop( p ); } diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index b87c77e5..79345fd0 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -226,6 +226,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) assert( Gia_ManEquivCheckLits( p, nLits ) ); if ( fVerbose ) { + printf( "Const0 = " ); + Gia_ManForEachConst( p, i ) + printf( "%d ", i ); + printf( "\n" ); Counter = 0; Gia_ManForEachClass( p, i ) Gia_ManEquivPrintOne( p, i, ++Counter ); @@ -275,15 +279,15 @@ static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll, int fDualOut ) { Gia_Obj_t * pRepr; - if ( ~pObj->Value ) - return; - assert( Gia_ObjIsAnd(pObj) ); if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) ) { Gia_ManEquivReduce_rec( pNew, p, pRepr, fUseAll, fDualOut ); pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); return; } + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut ); Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj), fUseAll, fDualOut ); pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); @@ -303,18 +307,25 @@ void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose ) { Gia_Man_t * pNew; - Gia_Obj_t * pObj, * pRepr; + Gia_Obj_t * pObj; int i; + if ( !p->pReprs ) + { + printf( "Gia_ManEquivReduce(): Equivalence classes are not available.\n" ); + return NULL; + } if ( fDualOut && (Gia_ManPoNum(p) & 1) ) { printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" ); return NULL; } +/* if ( !Gia_ManCheckTopoOrder( p ) ) { printf( "Gia_ManEquivReduce(): AIG is not in a correct topological order.\n" ); return NULL; } +*/ Gia_ManSetPhase( p ); if ( fDualOut ) Gia_ManEquivSetColors( p, fVerbose ); @@ -323,11 +334,7 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fV Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) - { pObj->Value = Gia_ManAppendCi(pNew); - if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) ) - pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); - } Gia_ManHashAlloc( pNew ); Gia_ManForEachCo( p, pObj, i ) Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut ); @@ -662,11 +669,13 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ) printf( "Gia_ManSpecReduce(): Dual-output miter should have even number of POs.\n" ); return NULL; } +/* if ( !Gia_ManCheckTopoOrder( p ) ) { printf( "Gia_ManSpecReduce(): AIG is not in a correct topological order.\n" ); return NULL; } +*/ vXorLits = Vec_IntAlloc( 1000 ); Gia_ManSetPhase( p ); Gia_ManFillValue( p ); @@ -786,11 +795,13 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames printf( "Gia_ManSpecReduceInit(): Dual-output miter should have even number of POs.\n" ); return NULL; } +/* if ( !Gia_ManCheckTopoOrder( p ) ) { printf( "Gia_ManSpecReduceInit(): AIG is not in a correct topological order.\n" ); return NULL; } +*/ assert( pInit->nRegs == Gia_ManRegNum(p) && pInit->nPis == 0 ); p->pCopies = ABC_FALLOC( int, nFrames * Gia_ManObjNum(p) ); vXorLits = Vec_IntAlloc( 1000 ); diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c index 8bc38ed9..a7cae8fe 100644 --- a/src/aig/gia/giaHash.c +++ b/src/aig/gia/giaHash.c @@ -86,7 +86,7 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 ) void Gia_ManHashAlloc( Gia_Man_t * p ) { assert( p->pHTable == NULL ); - p->nHTable = Aig_PrimeCudd( p->nObjsAlloc / 3 ); + p->nHTable = Aig_PrimeCudd( p->nObjsAlloc ); p->pHTable = ABC_CALLOC( int, p->nHTable ); } @@ -174,6 +174,34 @@ void Gia_ManHashResize( Gia_Man_t * p ) ABC_FREE( pHTableOld ); } +/**Function******************************************************************** + + Synopsis [Profiles the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Gia_ManHashProfile( Gia_Man_t * p ) +{ + Gia_Obj_t * pEntry; + int i, Counter; + printf( "Table size = %d. Entries = %d.\n", p->nHTable, Gia_ManAndNum(p) ); + for ( i = 0; i < p->nHTable; i++ ) + { + Counter = 0; + for ( pEntry = (p->pHTable[i]? Gia_ManObj(p, Gia_Lit2Var(p->pHTable[i])) : NULL); + pEntry; + pEntry = (pEntry->Value? Gia_ManObj(p, Gia_Lit2Var(pEntry->Value)) : NULL) ) + Counter++; + if ( Counter ) + printf( "%d ", Counter ); + } + printf( "\n" ); +} /**Function************************************************************* diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 4439453d..dba90507 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -70,6 +70,8 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFree( p->vFlopClasses ); Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); + ABC_FREE( p->pPlacement ); + ABC_FREE( p->pSwitching ); ABC_FREE( p->pCexComb ); ABC_FREE( p->pIso ); ABC_FREE( p->pMapping ); @@ -128,17 +130,48 @@ void Gia_ManPrintClasses( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManPrintStats( Gia_Man_t * p ) +void Gia_ManPrintPlacement( Gia_Man_t * p ) +{ + int i, nFixed = 0, nUndef = 0; + if ( p->pPlacement == NULL ) + return; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + nFixed += p->pPlacement[i].fFixed; + nUndef += p->pPlacement[i].fUndef; + } + printf( "Placement: Objects = %8d. Fixed = %8d. Undef = %8d.\n", Gia_ManObjNum(p), nFixed, nUndef ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ) { if ( p->pName ) printf( "%8s : ", p->pName ); - printf( "i/o =%7d/%7d ", Gia_ManPiNum(p), Gia_ManPoNum(p) ); + printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) ); if ( Gia_ManRegNum(p) ) - printf( "ff =%7d ", Gia_ManRegNum(p) ); - printf( "and =%8d ", Gia_ManAndNum(p) ); - printf( "lev =%5d ", Gia_ManLevelNum(p) ); - printf( "cut =%5d ", Gia_ManCrossCut(p) ); - printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); + printf( " ff =%7d", Gia_ManRegNum(p) ); + printf( " and =%8d", Gia_ManAndNum(p) ); + printf( " lev =%5d", Gia_ManLevelNum(p) ); + printf( " cut =%5d", Gia_ManCrossCut(p) ); + printf( " mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); + if ( fSwitch ) + { + if ( p->pSwitching ) + printf( " power =%7.2f", Gia_ManEvaluateSwitching(p) ); + else + printf( " power =%7.2f", Gia_ManComputeSwitching(p, 48, 16, 0) ); + } // printf( "obj =%5d ", Gia_ManObjNum(p) ); printf( "\n" ); @@ -147,6 +180,8 @@ void Gia_ManPrintStats( Gia_Man_t * p ) Gia_ManEquivPrintClasses( p, 0, 0.0 ); if ( p->pMapping ) Gia_ManPrintMappingStats( p ); + if ( p->pPlacement ) + Gia_ManPrintPlacement( p ); // print register classes // Gia_ManPrintClasses( p ); } diff --git a/src/aig/gia/giaPat.c b/src/aig/gia/giaPat.c new file mode 100644 index 00000000..7968932c --- /dev/null +++ b/src/aig/gia/giaPat.c @@ -0,0 +1,129 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Sat_ObjXValue( Gia_Obj_t * pObj ) { return (pObj->fMark1 << 1) | pObj->fMark0; } +static inline void Sat_ObjSetXValue( Gia_Obj_t * pObj, int v) { pObj->fMark0 = (v & 1); pObj->fMark1 = ((v >> 1) & 1); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects nodes in the cone and initialized them to x.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SatCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) +{ + if ( Sat_ObjXValue(pObj) == GIA_UND ) + return; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_SatCollectCone_rec( p, Gia_ObjFanin0(pObj), vVisit ); + Gia_SatCollectCone_rec( p, Gia_ObjFanin1(pObj), vVisit ); + } + assert( Sat_ObjXValue(pObj) == 0 ); + Sat_ObjSetXValue( pObj, GIA_UND ); + Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects nodes in the cone and initialized them to x.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SatCollectCone( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsConst0(pObj) ); + assert( Sat_ObjXValue(pObj) == 0 ); + Vec_IntClear( vVisit ); + Gia_SatCollectCone_rec( p, pObj, vVisit ); +} + +/**Function************************************************************* + + Synopsis [Checks if the counter-examples asserts the output.] + + Description [Assumes that fMark0 and fMark1 are clean. Leaves them clean.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ) +{ + Gia_Obj_t * pObj; + int i, Entry, Value, Value0, Value1; + assert( Gia_ObjIsCo(pRoot) ); + assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); + // collect nodes and initialized them to x + Gia_SatCollectCone( p, Gia_ObjFanin0(pRoot), vVisit ); + // set binary values to nodes in the counter-example + Vec_IntForEachEntry( vCex, Entry, i ) +// Sat_ObjSetXValue( Gia_ManObj(p, Gia_Lit2Var(Entry)), Gia_LitIsCompl(Entry)? GIA_ZER : GIA_ONE ); + Sat_ObjSetXValue( Gia_ManCi(p, Gia_Lit2Var(Entry)), Gia_LitIsCompl(Entry)? GIA_ZER : GIA_ONE ); + // simulate + Gia_ManForEachObjVec( vVisit, p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + continue; + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Sat_ObjXValue( Gia_ObjFanin0(pObj) ); + Value1 = Sat_ObjXValue( Gia_ObjFanin1(pObj) ); + Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); + Sat_ObjSetXValue( pObj, Value ); + } + Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pRoot) ); + if ( Value != GIA_ONE ) + printf( "Gia_SatVerifyPattern(): Verification FAILED.\n" ); +// else +// printf( "Gia_SatVerifyPattern(): Verification succeeded.\n" ); +// assert( Value == GIA_ONE ); + // clean the nodes + Gia_ManForEachObjVec( vVisit, p, pObj, i ) + Sat_ObjSetXValue( pObj, 0 ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c index 71aefec3..713f224b 100644 --- a/src/aig/gia/giaSwitch.c +++ b/src/aig/gia/giaSwitch.c @@ -73,13 +73,13 @@ static inline unsigned * Gia_SwiDataCo( Gia_ManSwi_t * p, int i ) { return p->p void Gia_ManSetDefaultParamsSwi( Gia_ParSwi_t * p ) { memset( p, 0, sizeof(Gia_ParSwi_t) ); - p->nWords = 1; // the number of machine words of simulatation data + p->nWords = 10; // the number of machine words of simulatation data p->nIters = 48; // the number of all timeframes to simulate p->nPref = 16; // the number of first timeframes to skip when computing switching p->nRandPiFactor = 2; // primary input transition probability (-1=3/8; 0=1/2; 1=1/4; 2=1/8, etc) p->fProbOne = 0; // compute probability of signal being one (if 0, compute probability of switching) p->fProbTrans = 1; // compute signal transition probability (if 0, compute transition probability using probability of being one) - p->fVerbose = 1; // enables verbose output + p->fVerbose = 0; // enables verbose output } /**Function************************************************************* @@ -483,12 +483,14 @@ static inline void Gia_ManSwiSimulateRound( Gia_ManSwi_t * p, int fCount ) else if ( Gia_ObjIsCo(pObj) ) { assert( Gia_ObjValue(pObj) == GIA_NONE ); - Gia_ManSwiSimulateCo( p, iCos++, pObj ); +// Gia_ManSwiSimulateCo( p, iCos++, pObj ); + Gia_ManSwiSimulateCo( p, Gia_ObjCioId(pObj), pObj ); } else // if ( Gia_ObjIsCi(pObj) ) { assert( Gia_ObjValue(pObj) < p->pAig->nFront ); - Gia_ManSwiSimulateCi( p, pObj, iCis++ ); +// Gia_ManSwiSimulateCi( p, pObj, iCis++ ); + Gia_ManSwiSimulateCi( p, pObj, Gia_ObjCioId(pObj) ); } if ( fCount && !Gia_ObjIsCo(pObj) ) { @@ -498,8 +500,8 @@ static inline void Gia_ManSwiSimulateRound( Gia_ManSwi_t * p, int fCount ) p->pData1[i] += Gia_ManSwiSimInfoCountOnes( p, Gia_ObjValue(pObj) ); } } - assert( Gia_ManCiNum(p->pAig) == iCis ); - assert( Gia_ManCoNum(p->pAig) == iCos ); +// assert( Gia_ManCiNum(p->pAig) == iCis ); +// assert( Gia_ManCoNum(p->pAig) == iCos ); } /**Function************************************************************* @@ -633,12 +635,10 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref // set the default parameters Gia_ManSetDefaultParamsSwi( pPars ); // override some of the defaults - pPars->nWords = 10; // set number machine words to simulate pPars->nIters = nFrames; // set number of total timeframes if ( Abc_FrameReadFlag("seqsimframes") ) pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") ); pPars->nPref = nPref; // set number of first timeframes to skip - pPars->fVerbose = 0; // disable verbose output // decide what should be computed if ( fProbOne ) { @@ -666,7 +666,94 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref return vResult; } - //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Computes probability of switching (or of being 1).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManEvaluateSwitching( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + float SwitchTotal = 0.0; + int i; + assert( p->pSwitching ); + ABC_FREE( p->pRefs ); + Gia_ManCreateRefs( p ); + Gia_ManForEachObj( p, pObj, i ) + SwitchTotal += (float)Gia_ObjRefs(p, pObj) * p->pSwitching[i] / 255; + return SwitchTotal; +} + +/**Function************************************************************* + + Synopsis [Computes probability of switching (or of being 1).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ) +{ + Gia_Man_t * pDfs; + Gia_Obj_t * pObj, * pObjDfs; + Vec_Int_t * vSwitching; + float * pSwitching, Switch, SwitchTotal = 0.0, SwitchTotal2 = 0.0; + int i; + Gia_ParSwi_t Pars, * pPars = &Pars; + ABC_FREE( p->pSwitching ); + // set the default parameters + Gia_ManSetDefaultParamsSwi( pPars ); + // override some of the defaults + pPars->nIters = nFrames; // set number of total timeframes + pPars->nPref = nPref; // set number of first timeframes to skip + // decide what should be computed + if ( fProbOne ) + { + // if the user asked to compute propability of 1, we do not need transition information + pPars->fProbOne = 1; // enable computing probabiblity of being one + pPars->fProbTrans = 0; // disable computing transition probability + } + else + { + // if the user asked for transition propabability, we do not need to compute probability of 1 + pPars->fProbOne = 0; // disable computing probabiblity of being one + pPars->fProbTrans = 1; // enable computing transition probability + } + // derives the DFS ordered AIG + Gia_ManCreateRefs( p ); +// pDfs = Gia_ManDupOrderDfs( p ); + pDfs = Gia_ManDup( p ); + assert( Gia_ManObjNum(pDfs) == Gia_ManObjNum(p) ); + // perform the computation of switching activity + vSwitching = Gia_ManSwiSimulate( pDfs, pPars ); + // transfer the computed result to the original AIG + p->pSwitching = ABC_CALLOC( unsigned char, Gia_ManObjNum(p) ); + pSwitching = (float *)vSwitching->pArray; + Gia_ManForEachObj( p, pObj, i ) + { + pObjDfs = Gia_ObjFromLit( pDfs, pObj->Value ); + Switch = pSwitching[ Gia_ObjId(pDfs, pObjDfs) ]; + p->pSwitching[i] = (char)((Switch >= 1.0) ? 255 : (int)((0.002 + Switch) * 255)); // 0.00196 = (1/255)/2 + SwitchTotal += (float)Gia_ObjRefs(p, pObj) * p->pSwitching[i] / 255; +// SwitchTotal2 += Gia_ObjRefs(p, pObj) * Switch; +// printf( "%d = %.2f\n", i, Gia_ObjRefs(p, pObj) * Switch ); + } +// printf( "\nSwitch float = %f. Switch char = %f.\n", SwitchTotal2, SwitchTotal ); + Vec_IntFree( vSwitching ); + Gia_ManStop( pDfs ); + return SwitchTotal; +} + +//////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index d5ff628a..055d7580 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -2,6 +2,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaAig.c \ src/aig/gia/giaAiger.c \ src/aig/gia/giaCof.c \ + src/aig/gia/giaCSat.c \ src/aig/gia/giaDfs.c \ src/aig/gia/giaDup.c \ src/aig/gia/giaEmbed.c \ @@ -15,6 +16,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaHash.c \ src/aig/gia/giaMan.c \ src/aig/gia/giaMap.c \ + src/aig/gia/giaPat.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaScl.c \ src/aig/gia/giaSim.c \ diff --git a/src/aig/int/intCtrex.c b/src/aig/int/intCtrex.c index 98c01de6..c0bbec1c 100644 --- a/src/aig/int/intCtrex.c +++ b/src/aig/int/intCtrex.c @@ -111,6 +111,8 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) Cnf_DataFree( pCnf ); if ( pSat == NULL ) { + printf( "Counter-example generation in command \"int\" has failed.\n" ); + printf( "Use command \"bmc2\" to produce a valid counter-example.\n" ); Vec_IntFree( vCiIds ); return NULL; } diff --git a/src/aig/ssw/sswClass.c b/src/aig/ssw/sswClass.c index 5d0be217..967d29e9 100644 --- a/src/aig/ssw/sswClass.c +++ b/src/aig/ssw/sswClass.c @@ -391,7 +391,8 @@ void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr ) int i; printf( "{ " ); Ssw_ClassForEachNode( p, pRepr, pObj, i ) - printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); + printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level, + Aig_SupportSize(p->pAig,pObj), Aig_NodeMffsSupp(p->pAig,pObj,0,NULL) ); printf( "}\n" ); } @@ -418,7 +419,8 @@ void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose ) printf( "Constants { " ); Aig_ManForEachObj( p->pAig, pObj, i ) if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) - printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); + printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level, + Aig_SupportSize(p->pAig,pObj), Aig_NodeMffsSupp(p->pAig,pObj,0,NULL) ); printf( "}\n" ); Ssw_ManForEachClass( p, ppClass, i ) { diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c index 03df38e1..9a31a056 100644 --- a/src/aig/ssw/sswCore.c +++ b/src/aig/ssw/sswCore.c @@ -216,6 +216,7 @@ clk = clock(); p->timeTotal = clock() - clkTotal; pAigNew = Aig_ManDupRepr( p->pAig, 0 ); Aig_ManSeqCleanup( pAigNew ); +//Ssw_ClassesPrint( p->ppClasses, 1 ); // get the final stats p->nLitsEnd = Ssw_ClassesLitNum( p->ppClasses ); p->nNodesEnd = Aig_ManNodeNum(pAigNew); diff --git a/src/aig/ssw/sswLcorr.c b/src/aig/ssw/sswLcorr.c index 8cb8b81b..80bc5853 100644 --- a/src/aig/ssw/sswLcorr.c +++ b/src/aig/ssw/sswLcorr.c @@ -308,6 +308,9 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p ) p->nRecycleCalls = 0; } } +// ABC_PRT( "reduce", p->timeReduce ); +// Aig_TableProfile( p->pFrames ); +// printf( "And gates = %d\n", Aig_ManNodeNum(p->pFrames) ); // resimulate if ( p->nPatterns > 0 ) Ssw_ManSweepResimulate( p ); diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index 758bc1e2..df46fc06 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -595,6 +595,7 @@ Hop_Obj_t * Abc_ConvertSopToAigInternal( Hop_Man_t * pMan, char * pSop ) Hop_Obj_t * pAnd, * pSum; int i, Value, nFanins; char * pCube; + int fExor = Abc_SopIsExorType(pSop); // get the number of variables nFanins = Abc_SopGetVarNum(pSop); // go through the cubes of the node's SOP @@ -611,7 +612,10 @@ Hop_Obj_t * Abc_ConvertSopToAigInternal( Hop_Man_t * pMan, char * pSop ) pAnd = Hop_And( pMan, pAnd, Hop_Not(Hop_IthVar(pMan,i)) ); } // add to the sum of cubes - pSum = Hop_Or( pMan, pSum, pAnd ); + if ( fExor ) + pSum = Hop_Exor( pMan, pSum, pAnd ); + else + pSum = Hop_Or( pMan, pSum, pAnd ); } // decide whether to complement the result if ( Abc_SopIsComplement(pSop) ) @@ -637,11 +641,8 @@ Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop ) // consider the constant node if ( Abc_SopGetVarNum(pSop) == 0 ) return Hop_NotCond( Hop_ManConst1(pMan), Abc_SopIsConst0(pSop) ); - // consider the special case of EXOR function - if ( Abc_SopIsExorType(pSop) ) - return Hop_NotCond( Hop_CreateExor(pMan, Abc_SopGetVarNum(pSop)), Abc_SopIsComplement(pSop) ); // decide when to use factoring - if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 && !Abc_SopIsExorType(pSop) ) return Dec_GraphFactorSop( pMan, pSop ); return Abc_ConvertSopToAigInternal( pMan, pSop ); } diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c index 850e59e0..138dc9a1 100644 --- a/src/base/abc/abcLib.c +++ b/src/base/abc/abcLib.c @@ -82,6 +82,8 @@ void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) continue; // pNtk->pManFunc = NULL; pNtk->pDesign = NULL; + if ( pNtk->pManFunc == pNtkSave->pManFunc ) + pNtk->pManFunc = NULL; Abc_NtkDelete( pNtk ); } Vec_PtrFree( pLib->vModules ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index cf574ecb..876266af 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -128,7 +128,7 @@ static int Abc_CommandCareSet ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandCut ( 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_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCover ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDouble ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandInter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -297,6 +297,9 @@ static int Abc_CommandAbc9Retime ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandAbc9Enable ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Miter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Scl ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Scorr ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Choice ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Srm ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -448,7 +451,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 ); Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 ); Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 ); -// Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 ); + Cmd_CommandAdd( pAbc, "Various", "cover", Abc_CommandCover, 1 ); Cmd_CommandAdd( pAbc, "Various", "double", Abc_CommandDouble, 1 ); Cmd_CommandAdd( pAbc, "Various", "inter", Abc_CommandInter, 1 ); Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 ); @@ -610,6 +613,9 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "AIG", "&enable", Abc_CommandAbc9Enable, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&miter", Abc_CommandAbc9Miter, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&scl", Abc_CommandAbc9Scl, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&lcorr", Abc_CommandAbc9Lcorr, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&scorr", Abc_CommandAbc9Scorr, 0 ); + Cmd_CommandAdd( pAbc, "AIG", "&choice", Abc_CommandAbc9Choice, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&sat", Abc_CommandAbc9Sat, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&fraig", Abc_CommandAbc9Fraig, 0 ); Cmd_CommandAdd( pAbc, "AIG", "&srm", Abc_CommandAbc9Srm, 0 ); @@ -7575,7 +7581,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzamjvh]\n" ); + fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdcovamjvh]\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 ); @@ -7785,6 +7791,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) int fMesh; int fFpga; int fOneHot; + int fRandom; int fVerbose; char * FileName; extern void Abc_GenAdder( char * pFileName, int nVars ); @@ -7792,7 +7799,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_GenMesh( char * pFileName, int nVars ); extern void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars ); extern void Abc_GenOneHot( char * pFileName, int nVars ); - + extern void Abc_GenRandom( char * pFileName, int nPis ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -7805,9 +7812,10 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) fMesh = 0; fFpga = 0; fOneHot = 0; + fRandom = 0; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmftvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmftrvh" ) ) != EOF ) { switch ( c ) { @@ -7837,6 +7845,9 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': fOneHot ^= 1; break; + case 'r': + fRandom ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -7866,12 +7877,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) // Abc_GenFpga( FileName, 3, 2, 5 ); else if ( fOneHot ) Abc_GenOneHot( FileName, nVars ); + else if ( fRandom ) + Abc_GenRandom( FileName, nVars ); else printf( "Type of circuit is not specified.\n" ); return 0; usage: - fprintf( pErr, "usage: gen [-N num] [-asmftvh] <file>\n" ); + fprintf( pErr, "usage: gen [-N num] [-asmftrvh] <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 : generate ripple-carry adder [default = %s]\n", fAdder? "yes": "no" ); @@ -7879,13 +7892,13 @@ usage: fprintf( pErr, "\t-m : generate a mesh [default = %s]\n", fMesh? "yes": "no" ); fprintf( pErr, "\t-f : generate a LUT FPGA structure [default = %s]\n", fFpga? "yes": "no" ); fprintf( pErr, "\t-t : generate one-hotness conditions [default = %s]\n", fOneHot? "yes": "no" ); + fprintf( pErr, "\t-r : generate random single-output function [default = %s]\n", fRandom? "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************************************************************* Synopsis [] @@ -7897,79 +7910,52 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandCover( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes;//, * pNtkTemp; + Abc_Ntk_t * pNtk, * pNtkRes; int c; - int nLutMax; - int nPlaMax; - int RankCost; - int fFastMode; - int fRewriting; - int fSynthesis; int fVerbose; -// extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fEsop, bool fSop, bool fInvs, bool fVerbose ); - extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose ); + int fUseSop; + int fUseEsop; + int fUseInvs; + int nFaninMax; + extern Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set defaults - nLutMax = 8; - nPlaMax = 128; - RankCost = 96000; - fFastMode = 1; - fRewriting = 0; - fSynthesis = 0; - fVerbose = 0; + fUseSop = 1; + fUseEsop = 0; + fVerbose = 0; + fUseInvs = 1; + nFaninMax = 8; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "LPRfrsvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Nsxivh" ) ) != EOF ) { switch ( c ) { - case 'L': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" ); - goto usage; - } - nLutMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( nLutMax < 0 ) - goto usage; - break; - case 'P': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" ); - goto usage; - } - nPlaMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( nPlaMax < 0 ) - goto usage; - break; - case 'R': + case 'N': if ( globalUtilOptind >= argc ) { - fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); + fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); goto usage; } - RankCost = atoi(argv[globalUtilOptind]); + nFaninMax = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( RankCost < 0 ) + if ( nFaninMax < 0 ) goto usage; break; - case 'f': - fFastMode ^= 1; + case 's': + fUseSop ^= 1; break; - case 'r': - fRewriting ^= 1; + case 'x': + fUseEsop ^= 1; break; - case 's': - fSynthesis ^= 1; + case 'i': + fUseInvs ^= 1; break; case 'v': fVerbose ^= 1; @@ -7991,26 +7977,9 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Only works for strashed networks.\n" ); return 1; } -/* - if ( nLutMax < 2 || nLutMax > 12 || nPlaMax < 8 || nPlaMax > 128 ) - { - fprintf( pErr, "Incorrect LUT/PLA parameters.\n" ); - return 1; - } -*/ + // run the command -// pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fInvs, fVerbose ); -/* - if ( !Abc_NtkIsStrash(pNtk) ) - { - pNtkTemp = Abc_NtkStrash( pNtk, 0, 1, 0 ); - pNtkRes = Abc_NtkPlayer( pNtkTemp, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); - Abc_NtkDelete( pNtkTemp ); - } - else - pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); -*/ - pNtkRes = NULL; + pNtkRes = Abc_NtkSopEsopCover( pNtk, nFaninMax, fUseEsop, fUseSop, fUseInvs, fVerbose ); if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); @@ -8021,20 +7990,17 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: xyz [-L num] [-P num] [-R num] [-frsvh]\n" ); - fprintf( pErr, "\t specilized LUT/PLA decomposition\n" ); - fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax ); - fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax ); - fprintf( pErr, "\t-R num : maximum are of one decomposition rank [default = %d]\n", RankCost ); - fprintf( pErr, "\t-f : toggle using fast LUT mapping mode [default = %s]\n", fFastMode? "yes": "no" ); - fprintf( pErr, "\t-r : toggle using one pass of AIG rewriting [default = %s]\n", fRewriting? "yes": "no" ); - fprintf( pErr, "\t-s : toggle using synthesis by AIG rewriting [default = %s]\n", fSynthesis? "yes": "no" ); + fprintf( pErr, "usage: cover [-N num] [-sxvh]\n" ); + fprintf( pErr, "\t decomposition into a network of SOP/ESOP PLAs\n" ); + fprintf( pErr, "\t-N num : maximum number of inputs [default = %d]\n", nFaninMax ); + fprintf( pErr, "\t-s : toggle the use of SOPs [default = %s]\n", fUseSop? "yes": "no" ); + fprintf( pErr, "\t-x : toggle the use of ESOPs [default = %s]\n", fUseEsop? "yes": "no" ); +// fprintf( pErr, "\t-i : toggle the use of interters [default = %s]\n", fUseInvs? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } - /**Function************************************************************* Synopsis [] @@ -21930,11 +21896,15 @@ usage: int Abc_CommandAbc9Ps( Abc_Frame_t * pAbc, int argc, char ** argv ) { int c; + int fSwitch = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF ) { switch ( c ) { + case 'p': + fSwitch ^= 1; + break; case 'h': goto usage; default: @@ -21946,12 +21916,13 @@ int Abc_CommandAbc9Ps( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Ps(): There is no AIG.\n" ); return 1; } - Gia_ManPrintStats( pAbc->pAig ); + Gia_ManPrintStats( pAbc->pAig, fSwitch ); return 0; usage: - fprintf( stdout, "usage: &ps [-h]\n" ); + fprintf( stdout, "usage: &ps [-ph]\n" ); fprintf( stdout, "\t prints stats of the current AIG\n" ); + fprintf( stdout, "\t-p : toggle printing switching activity [default = %s]\n", fSwitch? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } @@ -22393,11 +22364,23 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; int c; + int fNormal = 0; + int fReverse = 0; + int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "nrvh" ) ) != EOF ) { switch ( c ) { + case 'n': + fNormal ^= 1; + break; + case 'r': + fReverse ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; case 'h': goto usage; default: @@ -22409,13 +22392,33 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Dfs(): There is no AIG.\n" ); return 1; } - pAbc->pAig = Gia_ManDupDfs( pTemp = pAbc->pAig ); + if ( fNormal ) + { + pAbc->pAig = Gia_ManDupOrderAiger( pTemp = pAbc->pAig ); + if ( fVerbose ) + printf( "AIG objects are reordered as follows: CIs, ANDs, COs.\n" ); + } + else if ( fReverse ) + { + pAbc->pAig = Gia_ManDupOrderDfsReverse( pTemp = pAbc->pAig ); + if ( fVerbose ) + printf( "AIG objects are reordered in the reserve DFS order.\n" ); + } + else + { + pAbc->pAig = Gia_ManDupOrderDfs( pTemp = pAbc->pAig ); + if ( fVerbose ) + printf( "AIG objects are reordered in the DFS order.\n" ); + } Gia_ManStop( pTemp ); return 0; usage: - fprintf( stdout, "usage: &dfs [-h]\n" ); + fprintf( stdout, "usage: &dfs [-nrvh]\n" ); fprintf( stdout, "\t orders objects in the DFS order\n" ); + fprintf( stdout, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); + fprintf( stdout, "\t-r : toggle using reverse DFS ordering [default = %s]\n", fReverse? "yes": "no" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; } @@ -23218,14 +23221,258 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParCor_t Pars, * pPars = &Pars; + Gia_Man_t * pTemp; + int c; + Cec_ManCorSetDefaultParams( pPars ); + pPars->fLatchCorr = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "FCfrcvh" ) ) != EOF ) + { + switch ( c ) + { + case 'F': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nFrames = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFrames < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'f': + pPars->fFirstStop ^= 1; + break; + case 'r': + pPars->fUseRings ^= 1; + break; + case 'c': + pPars->fUseCSat ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9Lcorr(): There is no AIG.\n" ); + return 1; + } + pAbc->pAig = Cec_ManLSCorrespondence( pTemp = pAbc->pAig, pPars ); + if ( pAbc->pAig == NULL ) + { + pAbc->pAig = pTemp; + printf( "Abc_CommandAbc9Lcorr(): Command has failed.\n" ); + } + else + Gia_ManStop( pTemp ); + return 0; + +usage: + fprintf( stdout, "usage: &lcorr [-FC num] [-frcvh]\n" ); + fprintf( stdout, "\t performs latch correpondence computation\n" ); + fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + fprintf( stdout, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); + fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-r : toggle using implication rings for equivalence classes [default = %s]\n", pPars->fUseRings? "yes": "no" ); + fprintf( stdout, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParCor_t Pars, * pPars = &Pars; + Gia_Man_t * pTemp; + int c; + Cec_ManCorSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "FCfrcvh" ) ) != EOF ) + { + switch ( c ) + { + case 'F': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nFrames = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFrames < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'f': + pPars->fFirstStop ^= 1; + break; + case 'r': + pPars->fUseRings ^= 1; + break; + case 'c': + pPars->fUseCSat ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9Scorr(): There is no AIG.\n" ); + return 1; + } + pAbc->pAig = Cec_ManLSCorrespondence( pTemp = pAbc->pAig, pPars ); + if ( pAbc->pAig == NULL ) + { + pAbc->pAig = pTemp; + printf( "Abc_CommandAbc9Scorr(): Command has failed.\n" ); + } + else + Gia_ManStop( pTemp ); + return 0; + +usage: + fprintf( stdout, "usage: &scorr [-FC num] [-frcvh]\n" ); + fprintf( stdout, "\t performs signal correpondence computation\n" ); + fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + fprintf( stdout, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); + fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-r : toggle using implication rings for equivalence classes [default = %s]\n", pPars->fUseRings? "yes": "no" ); + fprintf( stdout, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Choice( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParChc_t Pars, * pPars = &Pars; + Gia_Man_t * pTemp; + int c; + Cec_ManChcSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Cvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pAbc->pAig == NULL ) + { + printf( "Abc_CommandAbc9Choice(): There is no AIG.\n" ); + return 1; + } + printf("The command is not yet ready.\n" ); + return 0; + pAbc->pAig = Cec_ManChoiceComputation( pTemp = pAbc->pAig, pPars ); + if ( pAbc->pAig == NULL ) + { + pAbc->pAig = pTemp; + printf( "Abc_CommandAbc9Choice(): Command has failed.\n" ); + } + else + Gia_ManStop( pTemp ); + return 0; + +usage: + fprintf( stdout, "usage: &choice [-C num] [-vh]\n" ); + fprintf( stdout, "\t performs computation of structural choices\n" ); + fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + fprintf( stdout, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParSat_t ParsSat, * pPars = &ParsSat; Gia_Man_t * pTemp; int c; + int fCSat = 0; Cec_ManSatSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfcvh" ) ) != EOF ) { switch ( c ) { @@ -23268,6 +23515,9 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': pPars->fFirstStop ^= 1; break; + case 'c': + fCSat ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -23280,18 +23530,30 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Abc_CommandAbc9Sat(): There is no AIG.\n" ); return 1; } - pAbc->pAig = Cec_ManSatSolving( pTemp = pAbc->pAig, pPars ); - Gia_ManStop( pTemp ); + if ( fCSat ) + { + Vec_Int_t * vCounters; + Vec_Str_t * vStatus; + vCounters = Cbs_ManSolveMiter( pAbc->pAig, 10*pPars->nBTLimit, &vStatus ); + Vec_IntFree( vCounters ); + Vec_StrFree( vStatus ); + } + else + { + pAbc->pAig = Cec_ManSatSolving( pTemp = pAbc->pAig, pPars ); + Gia_ManStop( pTemp ); + } return 0; usage: - fprintf( stdout, "usage: &sat [-CSN <num>] [-mfvh]\n" ); + fprintf( stdout, "usage: &sat [-CSN <num>] [-mfcvh]\n" ); fprintf( stdout, "\t performs SAT solving for the combinational outputs\n" ); fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax ); fprintf( stdout, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle ); fprintf( stdout, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" ); fprintf( stdout, "\t-f : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); + fprintf( stdout, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", fCSat? "yes": "no" ); fprintf( stdout, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); fprintf( stdout, "\t-h : print the command usage\n"); return 1; @@ -23545,7 +23807,11 @@ int Abc_CommandAbc9Reduce( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pAbc->pAig == NULL ) pAbc->pAig = pTemp; else + { Gia_ManStop( pTemp ); + pAbc->pAig = Gia_ManSeqStructSweep( pTemp = pAbc->pAig, 1, 1, 0 ); + Gia_ManStop( pTemp ); + } return 0; usage: diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c index e40c21d6..f6111dfd 100644 --- a/src/base/abci/abcGen.c +++ b/src/base/abci/abcGen.c @@ -599,6 +599,56 @@ void Abc_GenOneHotIntervals( char * pFileName, int nPis, int nRegs, Vec_Ptr_t * fclose( pFile ); } +#include "aig.h" + +/**Function************************************************************* + + Synopsis [Generates structure of L K-LUTs implementing an N-var function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_GenRandom( char * pFileName, int nPis ) +{ + FILE * pFile; + unsigned * pTruth; + int i, b, w, nWords = Aig_TruthWordNum( nPis ); + int nDigitsIn; + Aig_ManRandom( 1 ); + pTruth = ABC_ALLOC( unsigned, nWords ); + for ( w = 0; w < nWords; w++ ) + pTruth[w] = Aig_ManRandom( 0 ); + pFile = fopen( pFileName, "w" ); + fprintf( pFile, "# Random function with %d inputs generated by ABC on %s\n", nPis, Extra_TimeStamp() ); + fprintf( pFile, ".model rand%d\n", nPis ); + fprintf( pFile, ".inputs" ); + nDigitsIn = Extra_Base10Log( nPis ); + for ( i = 0; i < nPis; i++ ) + fprintf( pFile, " i%0*d", nDigitsIn, i ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs f\n" ); + fprintf( pFile, ".names" ); + nDigitsIn = Extra_Base10Log( nPis ); + for ( i = 0; i < nPis; i++ ) + fprintf( pFile, " i%0*d", nDigitsIn, i ); + fprintf( pFile, " f\n" ); + for ( i = 0; i < (1<<nPis); i++ ) + if ( Aig_InfoHasBit(pTruth, i) ) + { + for ( b = nPis-1; b >= 0; b-- ) + fprintf( pFile, "%d", (i>>b)&1 ); + fprintf( pFile, " 1\n" ); + } + fprintf( pFile, ".end\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + ABC_FREE( pTruth ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index c7fa5a1e..9e0347d5 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -946,12 +946,8 @@ Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode ) if ( Abc_NodeIsConst(pNode) ) return Ivy_NotCond( Ivy_ManConst1(pMan), Abc_SopIsConst0(pSop) ); - // consider the special case of EXOR function - if ( Abc_SopIsExorType(pSop) ) - return Abc_NodeStrashAigExorAig( pMan, pNode, pSop ); - // decide when to use factoring - if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 && !Abc_SopIsExorType(pSop) ) return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop ); return Abc_NodeStrashAigSopAig( pMan, pNode, pSop ); } @@ -973,6 +969,7 @@ Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * Ivy_Obj_t * pAnd, * pSum; char * pCube; int i, nFanins; + int fExor = Abc_SopIsExorType(pSop); // get the number of node's fanins nFanins = Abc_ObjFaninNum( pNode ); @@ -991,7 +988,10 @@ Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pAnd = Ivy_And( pMan, pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) ); } // add to the sum of cubes - pSum = Ivy_Or( pMan, pSum, pAnd ); + if ( fExor ) + pSum = Ivy_Exor( pMan, pSum, pAnd ); + else + pSum = Ivy_Or( pMan, pSum, pAnd ); } // decide whether to complement the result if ( Abc_SopIsComplement(pSop) ) diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index b869f067..e65ce11a 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -135,8 +135,10 @@ float Abc_NtkMfsTotalSwitching( Abc_Ntk_t * pNtk ) Abc_NtkForEachObj( pNtk, pObjAbc, i ) { if ( (pObjAbc2 = Abc_ObjRegular(pObjAbc->pTemp)) && (pObjAig = Aig_Regular(pObjAbc2->pTemp)) ) + { Result += Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id]; -// Result += pSwitching[pObjAig->Id]; +// printf( "%d = %.2f\n", i, Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id] ); + } } Vec_IntFree( vSwitching ); Aig_ManStop( pAig ); diff --git a/src/base/io/io.c b/src/base/io/io.c index e8af161e..20f412e0 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1849,6 +1849,7 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv ) if ( argc != globalUtilOptind + 1 ) { + printf( "File name is missing on the command line.\n" ); goto usage; } // get the input file name diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index 95ea4fe5..34ea4294 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -1615,7 +1615,7 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; Vec_Str_t * vFunc = p->pMan->vFunc; - char * pProduct, * pOutput; + char * pProduct, * pOutput, c; int i, Polarity = -1; p->pMan->nTablesRead++; @@ -1626,7 +1626,8 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins ) if ( Vec_PtrSize(vTokens) == 1 ) { pOutput = Vec_PtrEntry( vTokens, 0 ); - if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) + c = pOutput[0]; + if ( (c!='0'&&c!='1'&&c!='x'&&c!='n') || pOutput[1] ) { sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Io_MvGetLine(p->pMan, pOutput), pOutput ); return NULL; @@ -1650,14 +1651,15 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins ) sprintf( p->pMan->sError, "Line %d: Cube \"%s\" has size different from the fanin count (%d).", Io_MvGetLine(p->pMan, pProduct), pProduct, nFanins ); return NULL; } - if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) + c = pOutput[0]; + if ( (c!='0'&&c!='1'&&c!='x'&&c!='n') || pOutput[1] ) { sprintf( p->pMan->sError, "Line %d: Output value \"%s\" is incorrect.", Io_MvGetLine(p->pMan, pProduct), pOutput ); return NULL; } if ( Polarity == -1 ) - Polarity = pOutput[0] - '0'; - else if ( Polarity != pOutput[0] - '0' ) + Polarity = (c=='1' || c=='x'); + else if ( Polarity != (c=='1' || c=='x') ) { sprintf( p->pMan->sError, "Line %d: Output value \"%s\" differs from the value in the first line of the table (%d).", Io_MvGetLine(p->pMan, pProduct), pOutput, Polarity ); return NULL; diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index aa213010..c318545b 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -2042,6 +2042,11 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox ) assert( !Ver_ObjIsConnected(pBox) ); assert( Ver_NtkIsDefined(pNtkBox) ); assert( !Abc_NtkHasBlackbox(pNtkBox) || Abc_NtkBoxNum(pNtkBox) == 1 ); + + if ( !strcmp(pNtkBox->pName,"add_4u_4u") ) + { + int s = 0; + } /* // clean the PI/PO nets Abc_NtkForEachPi( pNtkBox, pTerm, i ) @@ -2134,7 +2139,7 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox ) if ( Length > 0 ) { Vec_PtrForEachEntry( vBundles, pBundle, j ) - if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) ) + if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) && (int)strlen(pBundle->pNameFormal) == Length ) break; if ( j == Vec_PtrSize(vBundles) ) pBundle = NULL; @@ -2185,7 +2190,7 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox ) if ( Length > 0 ) { Vec_PtrForEachEntry( vBundles, pBundle, j ) - if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) ) + if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) && (int)strlen(pBundle->pNameFormal) == Length ) break; if ( j == Vec_PtrSize(vBundles) ) pBundle = NULL; @@ -2193,8 +2198,14 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox ) } if ( pBundle == NULL ) { + char Buffer[1000]; // printf( "Warning: The formal output %s is not driven when instantiating network %s in box %s.", // pNameFormal, pNtkBox->pName, Abc_ObjName(pBox) ); + pTermNew = Abc_NtkCreateBo( pNtk ); + sprintf( Buffer, "_temp_net%d", Abc_ObjId(pTermNew) ); + pNetAct = Abc_NtkFindOrCreateNet( pNtk, Buffer ); + Abc_ObjAddFanin( pTermNew, pBox ); + Abc_ObjAddFanin( pNetAct, pTermNew ); continue; } } diff --git a/src/map/cov/cov.h b/src/map/cov/cov.h new file mode 100644 index 00000000..8ca81740 --- /dev/null +++ b/src/map/cov/cov.h @@ -0,0 +1,111 @@ +/**CFile**************************************************************** + + FileName [cov.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cov.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __COV_H__ +#define __COV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "abc.h" +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Cov_Man_t_ Cov_Man_t; +typedef struct Cov_Obj_t_ Cov_Obj_t; + +// storage for node information +struct Cov_Obj_t_ +{ + Min_Cube_t * pCover[3]; // pos/neg/esop + Vec_Int_t * vSupp; // computed support (all nodes except CIs) +}; + +// storage for additional information +struct Cov_Man_t_ +{ + // general characteristics + int nFaninMax; // the number of vars + int nCubesMax; // the limit on the number of cubes in the intermediate covers + int nWords; // the number of words + Vec_Int_t * vFanCounts; // fanout counts + Vec_Ptr_t * vObjStrs; // object structures + void * pMemory; // memory for the internal data strctures + Min_Man_t * pManMin; // the cube manager + int fUseEsop; // enables ESOPs + int fUseSop; // enables SOPs + // arrays to map local variables + Vec_Int_t * vComTo0; // mapping of common variables into first fanin + Vec_Int_t * vComTo1; // mapping of common variables into second fanin + Vec_Int_t * vPairs0; // the first var in each pair of common vars + Vec_Int_t * vPairs1; // the second var in each pair of common vars + Vec_Int_t * vTriv0; // trival support of the first node + Vec_Int_t * vTriv1; // trival support of the second node + // statistics + int nSupps; // supports created + int nSuppsMax; // the maximum number of supports + int nBoundary; // the boundary size + int nNodes; // the number of nodes processed +}; + +static inline Cov_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Cov_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); } + +static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; } +static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; } + +static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; } +static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; } + +static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; } +static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== covBuild.c ==========================================================*/ +extern Abc_Ntk_t * Abc_NtkCovDerive( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkCovDeriveClean( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkCovDeriveRegular( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +/*=== covCore.c ===========================================================*/ +extern Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); +/*=== covMan.c ============================================================*/ +extern Cov_Man_t * Cov_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ); +extern void Cov_ManFree( Cov_Man_t * p ); +extern void Abc_NodeCovDropData( Cov_Man_t * p, Abc_Obj_t * pObj ); +/*=== covTest.c ===========================================================*/ +extern Abc_Ntk_t * Abc_NtkCovTestSop( Abc_Ntk_t * pNtk ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + + diff --git a/src/map/cov/covBuild.c b/src/map/cov/covBuild.c new file mode 100644 index 00000000..560178be --- /dev/null +++ b/src/map/cov/covBuild.c @@ -0,0 +1,539 @@ +/**CFile**************************************************************** + + FileName [covBuild.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Network construction procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp, int fCompl ) +{ + Vec_Int_t * vLits; + Abc_Obj_t * pNodeNew, * pFanin; + int i, iFanin, Lit; + // create empty cube + if ( pCube->nLits == 0 ) + { + if ( fCompl ) + return Abc_NtkCreateNodeConst0(pNtkNew); + return Abc_NtkCreateNodeConst1(pNtkNew); + } + // get the literals of this cube + vLits = Vec_IntAlloc( 10 ); + Min_CubeGetLits( pCube, vLits ); + assert( pCube->nLits == (unsigned)vLits->nSize ); + // create special case when there is only one literal + if ( pCube->nLits == 1 ) + { + iFanin = Vec_IntEntry(vLits,0); + pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); + Lit = Min_CubeGetVar(pCube, iFanin); + assert( Lit == 1 || Lit == 2 ); + Vec_IntFree( vLits ); + if ( (Lit == 1) ^ fCompl )// negative + return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy ); + return pFanin->pCopy; + } + assert( pCube->nLits > 1 ); + // create the AND cube + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < vLits->nSize; i++ ) + { + iFanin = Vec_IntEntry(vLits,i); + pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); + Lit = Min_CubeGetVar(pCube, iFanin); + assert( Lit == 1 || Lit == 2 ); + Vec_IntWriteEntry( vLits, i, Lit==1 ); + Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); + } + pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); + if ( fCompl ) + Abc_SopComplement( pNodeNew->pData ); + Vec_IntFree( vLits ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveNode_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level ) +{ + Min_Cube_t * pCover, * pCube; + Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; + Vec_Int_t * vSupp; + int Entry, nCubes, i; + + if ( Abc_ObjIsCi(pObj) ) + return pObj->pCopy; + assert( Abc_ObjIsNode(pObj) ); + // skip if already computed + if ( pObj->pCopy ) + return pObj->pCopy; + + // get the support and the cover + vSupp = Abc_ObjGetSupp( pObj ); + pCover = Abc_ObjGetCover2( pObj ); + assert( vSupp ); +/* + if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 ) + { + printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) ); + Min_CoverWrite( stdout, pCover ); + } +*/ +/* + // print the support of this node + printf( "{ " ); + Vec_IntForEachEntry( vSupp, Entry, i ) + printf( "%d ", Entry ); + printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) ); +*/ + // process the fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + Abc_NtkCovDeriveNode_rec( p, pNtkNew, pFanin, Level+1 ); + } + + // for each cube, construct the node + nCubes = Min_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); + else if ( nCubes == 1 ) + pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, 0 ); + else + { + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + Min_CoverForEachCube( pCover, pCube ) + { + pFaninNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCube, vSupp, 0 ); + Abc_ObjAddFanin( pNodeNew, pFaninNew ); + } + pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); + } +/* + printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); + } + printf( "\n" ); + Min_CoverWrite( stdout, pCover ); +*/ + pObj->pCopy = pNodeNew; + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDerive( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsStrash(pNtk) ); + // perform strashing + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // reconstruct the network + Abc_NtkForEachCo( pNtk, pObj, i ) + { + Abc_NtkCovDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 ); +// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id ); + } + // add the COs + Abc_NtkFinalize( pNtk, pNtkNew ); + Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkCovDerive: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + + + + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) +{ + assert( pObj->pCopy ); + if ( !fCompl ) + return pObj->pCopy; + if ( pObj->pCopy->pCopy == NULL ) + pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); + return pObj->pCopy->pCopy; + } + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) +{ + Vec_Int_t * vLits; + Abc_Obj_t * pNodeNew, * pFanin; + int i, iFanin, Lit; + // create empty cube + if ( pCube->nLits == 0 ) + return Abc_NtkCreateNodeConst1(pNtkNew); + // get the literals of this cube + vLits = Vec_IntAlloc( 10 ); + Min_CubeGetLits( pCube, vLits ); + assert( pCube->nLits == (unsigned)vLits->nSize ); + // create special case when there is only one literal + if ( pCube->nLits == 1 ) + { + iFanin = Vec_IntEntry(vLits,0); + pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); + Lit = Min_CubeGetVar(pCube, iFanin); + assert( Lit == 1 || Lit == 2 ); + Vec_IntFree( vLits ); +// if ( Lit == 1 )// negative +// return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy ); +// return pFanin->pCopy; + return Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ); + } + assert( pCube->nLits > 1 ); + // create the AND cube + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < vLits->nSize; i++ ) + { + iFanin = Vec_IntEntry(vLits,i); + pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); + Lit = Min_CubeGetVar(pCube, iFanin); + assert( Lit == 1 || Lit == 2 ); + Vec_IntWriteEntry( vLits, i, Lit==1 ); +// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); + Abc_ObjAddFanin( pNodeNew, Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ) ); + } +// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); + pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL ); + Vec_IntFree( vLits ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveNodeInv_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) +{ + Min_Cube_t * pCover, * pCube; + Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; + Vec_Int_t * vSupp; + int Entry, nCubes, i; + + // skip if already computed + if ( pObj->pCopy ) + return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl ); + assert( Abc_ObjIsNode(pObj) ); + + // get the support and the cover + vSupp = Abc_ObjGetSupp( pObj ); + pCover = Abc_ObjGetCover2( pObj ); + assert( vSupp ); + + // process the fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 ); + } + + // for each cube, construct the node + nCubes = Min_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); + else if ( nCubes == 1 ) + pNodeNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCover, vSupp ); + else + { + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + Min_CoverForEachCube( pCover, pCube ) + { + pFaninNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCube, vSupp ); + Abc_ObjAddFanin( pNodeNew, pFaninNew ); + } + pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); + } + + pObj->pCopy = pNodeNew; + return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl ); +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [The resulting network contains only pure AND/OR/EXOR gates + and inverters. This procedure is usedful to generate Verilog.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDeriveClean( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pNodeNew; + int i; + assert( Abc_NtkIsStrash(pNtk) ); + // perform strashing + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // reconstruct the network + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pNodeNew = Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); + Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); + } + // add the COs + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkCovDeriveInv: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + + + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDerive_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) +{ + int fVerbose = 0; + Min_Cube_t * pCover, * pCovers[3]; + Abc_Obj_t * pNodeNew, * pFanin; + Vec_Int_t * vSupp; + Vec_Str_t * vCover; + int i, Entry, nCubes, Type; + // skip if already computed + if ( pObj->pCopy ) + return pObj->pCopy; + assert( Abc_ObjIsNode(pObj) ); + // get the support and the cover + vSupp = Abc_ObjGetSupp( pObj ); + assert( vSupp ); + // choose the cover to implement + pCovers[0] = Abc_ObjGetCover( pObj, 0 ); + pCovers[1] = Abc_ObjGetCover( pObj, 1 ); + pCovers[2] = Abc_ObjGetCover2( pObj ); + // use positive polarity + if ( pCovers[0] + && (!pCovers[1] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[1])) + && (!pCovers[2] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[2])) ) + { + pCover = pCovers[0]; + Type = '1'; + } + else + // use negative polarity + if ( pCovers[1] + && (!pCovers[0] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[0])) + && (!pCovers[2] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[2])) ) + { + pCover = pCovers[1]; + Type = '0'; + } + else + // use XOR polarity + if ( pCovers[2] + && (!pCovers[0] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[0])) + && (!pCovers[1] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[1])) ) + { + pCover = pCovers[2]; + Type = 'x'; + } + else + assert( 0 ); + // print the support of this node + if ( fVerbose ) + { + printf( "{ " ); + Vec_IntForEachEntry( vSupp, Entry, i ) + printf( "%d ", Entry ); + printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) ); + } + // process the fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + Abc_NtkCovDerive_rec( p, pNtkNew, pFanin ); + } + // for each cube, construct the node + nCubes = Min_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); + else if ( nCubes == 1 ) + pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, Type == '0' ); + else + { + // create the node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); + } + // derive the function + vCover = Vec_StrAlloc( 100 ); + Min_CoverCreate( vCover, pCover, (char)Type ); + pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Vec_StrArray(vCover) ); + Vec_StrFree( vCover ); + } + +/* + printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFanin = Abc_NtkObj(pObj->pNtk, Entry); + printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); + } + printf( "\n" ); + Min_CoverWrite( stdout, pCover ); +*/ + return pObj->pCopy = pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDeriveRegular( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pNodeNew; + int i; + assert( Abc_NtkIsStrash(pNtk) ); + // perform strashing + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // reconstruct the network + if ( Abc_ObjFanoutNum(Abc_AigConst1(pNtk)) > 0 ) + Abc_AigConst1(pNtk)->pCopy = Abc_NtkCreateNodeConst1(pNtkNew); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pNodeNew = Abc_NtkCovDerive_rec( p, pNtkNew, Abc_ObjFanin0(pObj) ); + if ( Abc_ObjFaninC0(pObj) ) + { + if ( pNodeNew->pData && Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 1 ) + Abc_SopComplement( pNodeNew->pData ); + else + pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew ); + } + Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); + } + // add the COs + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkCovDerive: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covCore.c b/src/map/cov/covCore.c new file mode 100644 index 00000000..e36a4d2d --- /dev/null +++ b/src/map/cov/covCore.c @@ -0,0 +1,1023 @@ +/**CFile**************************************************************** + + FileName [covCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkCovCovers( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); +static int Abc_NtkCovCoversOne( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); +static void Abc_NtkCovCovers_rec( Cov_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ); +/* +static int Abc_NodeCovPropagateEsop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); +static int Abc_NodeCovPropagateSop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); +static int Abc_NodeCovUnionEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int Abc_NodeCovUnionSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int Abc_NodeCovProductEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int Abc_NodeCovProductSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +*/ +static int Abc_NodeCovPropagate( Cov_Man_t * p, Abc_Obj_t * pObj ); +static Min_Cube_t * Abc_NodeCovProduct( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); +static Min_Cube_t * Abc_NodeCovSum( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ) +{ + Abc_Ntk_t * pNtkNew; + Cov_Man_t * p; + + assert( Abc_NtkIsStrash(pNtk) ); + + // create the manager + p = Cov_ManAlloc( pNtk, nFaninMax ); + p->fUseEsop = fUseEsop; + p->fUseSop = fUseSop; + pNtk->pManCut = p; + + // perform mapping + Abc_NtkCovCovers( p, pNtk, fVerbose ); + + // derive the final network +// if ( fUseInvs ) +// pNtkNew = Abc_NtkCovDeriveClean( p, pNtk ); +// else +// pNtkNew = Abc_NtkCovDerive( p, pNtk ); +// pNtkNew = NULL; + pNtkNew = Abc_NtkCovDeriveRegular( p, pNtk ); + + Cov_ManFree( p ); + pNtk->pManCut = NULL; + + // make sure that everything is okay + if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkCov: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Compute the supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCovCovers( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) +{ + Abc_Obj_t * pObj; + int i, clk = clock(); + + // start the manager + p->vFanCounts = Abc_NtkFanoutCounts(pNtk); + + // set trivial cuts for the constant and the CIs + pObj = Abc_AigConst1(pNtk); + pObj->fMarkA = 1; + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->fMarkA = 1; + + // perform iterative decomposition + for ( i = 0; ; i++ ) + { + if ( fVerbose ) + printf( "Iter %d : ", i+1 ); + if ( Abc_NtkCovCoversOne(p, pNtk, fVerbose) ) + break; + } + + // clean the cut-point markers + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkA = 0; + +if ( fVerbose ) +{ +ABC_PRT( "Total", clock() - clk ); +} +} + +/**Function************************************************************* + + Synopsis [Compute the supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkCovCoversOne( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) +{ + ProgressBar * pProgress; + Abc_Obj_t * pObj; + Vec_Ptr_t * vBoundary; + int i, clk = clock(); + int Counter = 0; + int fStop = 1; + + // array to collect the nodes in the new boundary + vBoundary = Vec_PtrAlloc( 100 ); + + // start from the COs and mark visited nodes using pObj->fMarkB + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the solved nodes (including the CIs) + pObj = Abc_ObjFanin0(pObj); + if ( pObj->fMarkA ) + { + Counter++; + continue; + } + + // traverse the cone starting from this node + if ( Abc_ObjGetSupp(pObj) == NULL ) + Abc_NtkCovCovers_rec( p, pObj, vBoundary ); + + // count the number of solved cones + if ( Abc_ObjGetSupp(pObj) == NULL ) + fStop = 0; + else + Counter++; + +/* + printf( "%-15s : ", Abc_ObjName(pObj) ); + printf( "lev = %5d ", pObj->Level ); + if ( Abc_ObjGetSupp(pObj) == NULL ) + { + printf( "\n" ); + continue; + } + printf( "supp = %3d ", Abc_ObjGetSupp(pObj)->nSize ); + printf( "esop = %3d ", Min_CoverCountCubes( Abc_ObjGetCover2(pObj) ) ); + printf( "\n" ); +*/ + } + Extra_ProgressBarStop( pProgress ); + + // clean visited nodes + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkB = 0; + + // create the new boundary + p->nBoundary = 0; + Vec_PtrForEachEntry( vBoundary, pObj, i ) + { + if ( !pObj->fMarkA ) + { + pObj->fMarkA = 1; + p->nBoundary++; + } + } + Vec_PtrFree( vBoundary ); + +if ( fVerbose ) +{ + printf( "Outs = %4d (%4d) Node = %6d (%6d) Max = %6d Bound = %4d ", + Counter, Abc_NtkCoNum(pNtk), p->nSupps, Abc_NtkNodeNum(pNtk), p->nSuppsMax, p->nBoundary ); +ABC_PRT( "T", clock() - clk ); +} + return fStop; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCovCovers_rec( Cov_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ) +{ + Abc_Obj_t * pObj0, * pObj1; + // return if the support is already computed + if ( pObj->fMarkB || pObj->fMarkA )//|| Abc_ObjGetSupp(pObj) ) // why do we need Supp check here??? + return; + // mark as visited + pObj->fMarkB = 1; + // get the fanins + pObj0 = Abc_ObjFanin0(pObj); + pObj1 = Abc_ObjFanin1(pObj); + // solve for the fanins + Abc_NtkCovCovers_rec( p, pObj0, vBoundary ); + Abc_NtkCovCovers_rec( p, pObj1, vBoundary ); + // skip the node that spaced out + if ( !pObj0->fMarkA && !Abc_ObjGetSupp(pObj0) || // fanin is not ready + !pObj1->fMarkA && !Abc_ObjGetSupp(pObj1) || // fanin is not ready + !Abc_NodeCovPropagate( p, pObj ) ) // node's support or covers cannot be computed + { + // save the nodes of the future boundary + if ( !pObj0->fMarkA && Abc_ObjGetSupp(pObj0) ) + Vec_PtrPush( vBoundary, pObj0 ); + if ( !pObj1->fMarkA && Abc_ObjGetSupp(pObj1) ) + Vec_PtrPush( vBoundary, pObj1 ); + return; + } + // consider dropping the fanin supports +// Abc_NodeCovDropData( p, pObj0 ); +// Abc_NodeCovDropData( p, pObj1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NodeCovSupport( Cov_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1 ) +{ + Vec_Int_t * vSupp; + int k0, k1; + + assert( vSupp0 && vSupp1 ); + Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntClear( p->vPairs0 ); + Vec_IntClear( p->vPairs1 ); + + vSupp = Vec_IntAlloc( vSupp0->nSize + vSupp1->nSize ); + for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) + { + if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( p->vPairs0, k0 ); + Vec_IntPush( p->vPairs1, k1 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; k1++; + } + else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; + } + else + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + k1++; + } + } + for ( ; k0 < vSupp0->nSize; k0++ ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + } + for ( ; k1 < vSupp1->nSize; k1++ ) + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + } +/* + printf( "Zero : " ); + for ( k0 = 0; k0 < vSupp0->nSize; k0++ ) + printf( "%d ", vSupp0->pArray[k0] ); + printf( "\n" ); + + printf( "One : " ); + for ( k1 = 0; k1 < vSupp1->nSize; k1++ ) + printf( "%d ", vSupp1->pArray[k1] ); + printf( "\n" ); + + printf( "Sum : " ); + for ( k0 = 0; k0 < vSupp->nSize; k0++ ) + printf( "%d ", vSupp->pArray[k0] ); + printf( "\n" ); + printf( "\n" ); +*/ + return vSupp; +} + +/**Function************************************************************* + + Synopsis [Propagates all types of covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovPropagate( Cov_Man_t * p, Abc_Obj_t * pObj ) +{ + Min_Cube_t * pCoverP = NULL, * pCoverN = NULL, * pCoverX = NULL; + Min_Cube_t * pCov0, * pCov1, * pCover0, * pCover1; + Vec_Int_t * vSupp, * vSupp0, * vSupp1; + Abc_Obj_t * pObj0, * pObj1; + int fCompl0, fCompl1; + + pObj0 = Abc_ObjFanin0( pObj ); + pObj1 = Abc_ObjFanin1( pObj ); + + if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); + if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); + + // get the resulting support + vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); + vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); + vSupp = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + + // quit if support if too large + if ( vSupp->nSize > p->nFaninMax ) + { + Vec_IntFree( vSupp ); + return 0; + } + + // get the complemented attributes + fCompl0 = Abc_ObjFaninC0( pObj ); + fCompl1 = Abc_ObjFaninC1( pObj ); + + // propagate ESOP + if ( p->fUseEsop ) + { + // get the covers + pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); + pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); + if ( pCov0 && pCov1 ) + { + // complement the first if needed + if ( !fCompl0 ) + pCover0 = pCov0; + else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube + pCover0 = pCov0->pNext; + else + pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; + + // complement the second if needed + if ( !fCompl1 ) + pCover1 = pCov1; + else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube + pCover1 = pCov1->pNext; + else + pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; + + // derive the new cover + pCoverX = Abc_NodeCovProduct( p, pCover0, pCover1, 1, vSupp->nSize ); + } + } + // propagate SOPs + if ( p->fUseSop ) + { + // get the covers for the direct polarity + pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); + pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); + // derive the new cover + if ( pCover0 && pCover1 ) + pCoverP = Abc_NodeCovProduct( p, pCover0, pCover1, 0, vSupp->nSize ); + + // get the covers for the inverse polarity + pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); + pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); + // derive the new cover + if ( pCover0 && pCover1 ) + pCoverN = Abc_NodeCovSum( p, pCover0, pCover1, 0, vSupp->nSize ); + } + + // if none of the covers can be computed quit + if ( !pCoverX && !pCoverP && !pCoverN ) + { + Vec_IntFree( vSupp ); + return 0; + } + + // set the covers + assert( Abc_ObjGetSupp(pObj) == NULL ); + Abc_ObjSetSupp( pObj, vSupp ); + Abc_ObjSetCover( pObj, pCoverP, 0 ); + Abc_ObjSetCover( pObj, pCoverN, 1 ); + Abc_ObjSetCover2( pObj, pCoverX ); +//printf( "%3d : %4d %4d %4d\n", pObj->Id, Min_CoverCountCubes(pCoverP), Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverX) ); + + // count statistics + p->nSupps++; + p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); + return 1; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeCovProduct( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) +{ + Min_Cube_t * pCube, * pCube0, * pCube1; + Min_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 && pCover1 ); + + // clean storage + Min_ManClean( p->pManMin, nSupp ); + // go through the cube pairs + Min_CoverForEachCube( pCover0, pCube0 ) + Min_CoverForEachCube( pCover1, pCube1 ) + { + // go through the support variables of the cubes + for ( i = 0; i < p->vPairs0->nSize; i++ ) + { + Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); + Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); + if ( (Val0 & Val1) == 0 ) + break; + } + // check disjointness + if ( i < p->vPairs0->nSize ) + continue; + + if ( p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Min_CoverCollect( p->pManMin, nSupp ); +//Min_CoverWriteFile( pCover, "large", 1 ); + Min_CoverRecycle( p->pManMin, pCover ); + return NULL; + } + + // create the product cube + pCube = Min_CubeAlloc( p->pManMin ); + + // add the literals + pCube->nLits = 0; + for ( i = 0; i < nSupp; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + Val0 = 3; + else + Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + + if ( p->vComTo1->pArray[i] == -1 ) + Val1 = 3; + else + Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + + if ( (Val0 & Val1) == 3 ) + continue; + + Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); + pCube->nLits++; + } + // add the cube to storage + if ( fEsop ) + Min_EsopAddCube( p->pManMin, pCube ); + else + Min_SopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + if ( fEsop ) + Min_EsopMinimize( p->pManMin ); + else + Min_SopMinimize( p->pManMin ); + pCover = Min_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) + { +/* +Min_CoverWriteFile( pCover, "large", 1 ); + Min_CoverExpand( p->pManMin, pCover ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + Min_EsopMinimize( p->pManMin ); + pCover = Min_CoverCollect( p->pManMin, nSupp ); +*/ + Min_CoverRecycle( p->pManMin, pCover ); + return NULL; + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeCovSum( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) +{ + Min_Cube_t * pCube, * pCube0, * pCube1; + Min_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 && pCover1 ); + + // clean storage + Min_ManClean( p->pManMin, nSupp ); + Min_CoverForEachCube( pCover0, pCube0 ) + { + // create the cube + pCube = Min_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo0->nSize; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + continue; + Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + if ( Val0 == 3 ) + continue; + Min_CubeXorVar( pCube, i, Val0 ^ 3 ); + pCube->nLits++; + } + if ( p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Min_CoverCollect( p->pManMin, nSupp ); + Min_CoverRecycle( p->pManMin, pCover ); + return NULL; + } + // add the cube to storage + if ( fEsop ) + Min_EsopAddCube( p->pManMin, pCube ); + else + Min_SopAddCube( p->pManMin, pCube ); + } + Min_CoverForEachCube( pCover1, pCube1 ) + { + // create the cube + pCube = Min_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo1->nSize; i++ ) + { + if ( p->vComTo1->pArray[i] == -1 ) + continue; + Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + if ( Val1 == 3 ) + continue; + Min_CubeXorVar( pCube, i, Val1 ^ 3 ); + pCube->nLits++; + } + if ( p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Min_CoverCollect( p->pManMin, nSupp ); + Min_CoverRecycle( p->pManMin, pCover ); + return NULL; + } + // add the cube to storage + if ( fEsop ) + Min_EsopAddCube( p->pManMin, pCube ); + else + Min_SopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + if ( fEsop ) + Min_EsopMinimize( p->pManMin ); + else + Min_SopMinimize( p->pManMin ); + pCover = Min_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) + { + Min_CoverRecycle( p->pManMin, pCover ); + return NULL; + } + return pCover; +} + + + + + + + +#if 0 + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovPropagateEsop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) +{ + Min_Cube_t * pCover, * pCover0, * pCover1, * pCov0, * pCov1; + Vec_Int_t * vSupp, * vSupp0, * vSupp1; + + if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); + if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); + + // get the resulting support + vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); + vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); + vSupp = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + + // quit if support if too large + if ( vSupp->nSize > p->nFaninMax ) + { + Vec_IntFree( vSupp ); + return 0; + } + + // get the covers + pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); + pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); + + // complement the first if needed + if ( !Abc_ObjFaninC0(pObj) ) + pCover0 = pCov0; + else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube + pCover0 = pCov0->pNext; + else + pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; + + // complement the second if needed + if ( !Abc_ObjFaninC1(pObj) ) + pCover1 = pCov1; + else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube + pCover1 = pCov1->pNext; + else + pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; + + // derive and minimize the cover (quit if too large) + if ( !Abc_NodeCovProductEsop( p, pCover0, pCover1, vSupp->nSize ) ) + { + pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); + Min_CoverRecycle( p->pManMin, pCover ); + Vec_IntFree( vSupp ); + return 0; + } + + // minimize the cover + Min_EsopMinimize( p->pManMin ); + pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); + + // quit if the cover is too large + if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) + { + Min_CoverRecycle( p->pManMin, pCover ); + Vec_IntFree( vSupp ); + return 0; + } + + // count statistics + p->nSupps++; + p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); + + // set the covers + assert( Abc_ObjGetSupp(pObj) == NULL ); + Abc_ObjSetSupp( pObj, vSupp ); + Abc_ObjSetCover2( pObj, pCover ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovPropagateSop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) +{ + Min_Cube_t * pCoverP, * pCoverN, * pCover0, * pCover1; + Vec_Int_t * vSupp, * vSupp0, * vSupp1; + int fCompl0, fCompl1; + + if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); + if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); + + // get the resulting support + vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); + vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); + vSupp = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + + // quit if support if too large + if ( vSupp->nSize > p->nFaninMax ) + { + Vec_IntFree( vSupp ); + return 0; + } + + // get the complemented attributes + fCompl0 = Abc_ObjFaninC0(pObj); + fCompl1 = Abc_ObjFaninC1(pObj); + + // prepare the positive cover + pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); + pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); + + // derive and minimize the cover (quit if too large) + if ( !pCover0 || !pCover1 ) + pCoverP = NULL; + else if ( !Abc_NodeCovProductSop( p, pCover0, pCover1, vSupp->nSize ) ) + { + pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); + Min_CoverRecycle( p->pManMin, pCoverP ); + pCoverP = NULL; + } + else + { + Min_SopMinimize( p->pManMin ); + pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); + // quit if the cover is too large + if ( Min_CoverCountCubes(pCoverP) > p->nFaninMax ) + { + Min_CoverRecycle( p->pManMin, pCoverP ); + pCoverP = NULL; + } + } + + // prepare the negative cover + pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); + pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); + + // derive and minimize the cover (quit if too large) + if ( !pCover0 || !pCover1 ) + pCoverN = NULL; + else if ( !Abc_NodeCovUnionSop( p, pCover0, pCover1, vSupp->nSize ) ) + { + pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); + Min_CoverRecycle( p->pManMin, pCoverN ); + pCoverN = NULL; + } + else + { + Min_SopMinimize( p->pManMin ); + pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); + // quit if the cover is too large + if ( Min_CoverCountCubes(pCoverN) > p->nFaninMax ) + { + Min_CoverRecycle( p->pManMin, pCoverN ); + pCoverN = NULL; + } + } + + if ( pCoverP == NULL && pCoverN == NULL ) + { + Vec_IntFree( vSupp ); + return 0; + } + + // count statistics + p->nSupps++; + p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); + + // set the covers + assert( Abc_ObjGetSupp(pObj) == NULL ); + Abc_ObjSetSupp( pObj, vSupp ); + Abc_ObjSetCover( pObj, pCoverP, 0 ); + Abc_ObjSetCover( pObj, pCoverN, 1 ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovProductEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ + Min_Cube_t * pCube, * pCube0, * pCube1; + int i, Val0, Val1; + + // clean storage + Min_ManClean( p->pManMin, nSupp ); + if ( pCover0 == NULL || pCover1 == NULL ) + return 1; + + // go through the cube pairs + Min_CoverForEachCube( pCover0, pCube0 ) + Min_CoverForEachCube( pCover1, pCube1 ) + { + // go through the support variables of the cubes + for ( i = 0; i < p->vPairs0->nSize; i++ ) + { + Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); + Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); + if ( (Val0 & Val1) == 0 ) + break; + } + // check disjointness + if ( i < p->vPairs0->nSize ) + continue; + + if ( p->pManMin->nCubes >= p->nCubesMax ) + return 0; + + // create the product cube + pCube = Min_CubeAlloc( p->pManMin ); + + // add the literals + pCube->nLits = 0; + for ( i = 0; i < nSupp; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + Val0 = 3; + else + Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + + if ( p->vComTo1->pArray[i] == -1 ) + Val1 = 3; + else + Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + + if ( (Val0 & Val1) == 3 ) + continue; + + Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); + pCube->nLits++; + } + // add the cube to storage + Min_EsopAddCube( p->pManMin, pCube ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovProductSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ + return 1; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovUnionEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ + Min_Cube_t * pCube, * pCube0, * pCube1; + int i, Val0, Val1; + + // clean storage + Min_ManClean( p->pManMin, nSupp ); + if ( pCover0 ) + { + Min_CoverForEachCube( pCover0, pCube0 ) + { + // create the cube + pCube = Min_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo0->nSize; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + continue; + Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + if ( Val0 == 3 ) + continue; + Min_CubeXorVar( pCube, i, Val0 ^ 3 ); + pCube->nLits++; + } + if ( p->pManMin->nCubes >= p->nCubesMax ) + return 0; + // add the cube to storage + Min_EsopAddCube( p->pManMin, pCube ); + } + } + if ( pCover1 ) + { + Min_CoverForEachCube( pCover1, pCube1 ) + { + // create the cube + pCube = Min_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo1->nSize; i++ ) + { + if ( p->vComTo1->pArray[i] == -1 ) + continue; + Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + if ( Val1 == 3 ) + continue; + Min_CubeXorVar( pCube, i, Val1 ^ 3 ); + pCube->nLits++; + } + if ( p->pManMin->nCubes >= p->nCubesMax ) + return 0; + // add the cube to storage + Min_EsopAddCube( p->pManMin, pCube ); + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCovUnionSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ + return 1; +} + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covInt.h b/src/map/cov/covInt.h new file mode 100644 index 00000000..a06519c0 --- /dev/null +++ b/src/map/cov/covInt.h @@ -0,0 +1,643 @@ +/**CFile**************************************************************** + + FileName [covInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Internal declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Min_Man_t_ Min_Man_t; +typedef struct Min_Cube_t_ Min_Cube_t; + +struct Min_Man_t_ +{ + int nVars; // the number of vars + int nWords; // the number of words + Extra_MmFixed_t * pMemMan; // memory manager for cubes + // temporary cubes + Min_Cube_t * pOne0; // tautology cube + Min_Cube_t * pOne1; // tautology cube + Min_Cube_t * pTriv0[2]; // trivial cube + Min_Cube_t * pTriv1[2]; // trivial cube + Min_Cube_t * pTemp; // cube for computing the distance + Min_Cube_t * pBubble; // cube used as a separator + // temporary storage for the new cover + int nCubes; // the number of cubes + Min_Cube_t ** ppStore; // storage for cubes by number of literals +}; + +struct Min_Cube_t_ +{ + Min_Cube_t * pNext; // the pointer to the next cube in the cover + unsigned nVars : 10; // the number of variables + unsigned nWords : 12; // the number of machine words + unsigned nLits : 10; // the number of literals in the cube + unsigned uData[1]; // the bit-data for the cube +}; + + +// iterators through the entries in the linked lists of cubes +#define Min_CoverForEachCube( pCover, pCube ) \ + for ( pCube = pCover; \ + pCube; \ + pCube = pCube->pNext ) +#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \ + for ( pCube = pCover, \ + pCube2 = pCube? pCube->pNext: NULL; \ + pCube; \ + pCube = pCube2, \ + pCube2 = pCube? pCube->pNext: NULL ) +#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \ + for ( pCube = pCover, \ + ppPrev = &(pCover); \ + pCube; \ + ppPrev = &pCube->pNext, \ + pCube = pCube->pNext ) + +// macros to get hold of bits and values in the cubes +static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); } +static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); } +static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); } +static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); } + +/*=== covMinEsop.c ==========================================================*/ +extern void Min_EsopMinimize( Min_Man_t * p ); +extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); +/*=== covMinSop.c ==========================================================*/ +extern void Min_SopMinimize( Min_Man_t * p ); +extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); +/*=== covMinMan.c ==========================================================*/ +extern Min_Man_t * Min_ManAlloc( int nVars ); +extern void Min_ManClean( Min_Man_t * p, int nSupp ); +extern void Min_ManFree( Min_Man_t * p ); +/*=== covMinUtil.c ==========================================================*/ +extern void Min_CoverCreate( Vec_Str_t * vCover, Min_Cube_t * pCover, char Type ); +extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ); +extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ); +extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ); +extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ); +extern void Min_CoverCheck( Min_Man_t * p ); +extern int Min_CubeCheck( Min_Cube_t * pCube ); +extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ); +extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ); +extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) +{ + Min_Cube_t * pCube; + pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan ); + pCube->pNext = NULL; + pCube->nVars = p->nVars; + pCube->nWords = p->nWords; + pCube->nLits = 0; + memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords ); + return pCube; +} + +/**Function************************************************************* + + Synopsis [Creates the cube representing elementary var.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl ) +{ + Min_Cube_t * pCube; + pCube = Min_CubeAlloc( p ); + Min_CubeXorBit( pCube, iVar*2+fCompl ); + pCube->nLits = 1; + return pCube; +} + +/**Function************************************************************* + + Synopsis [Creates the cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) +{ + Min_Cube_t * pCube; + pCube = Min_CubeAlloc( p ); + memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords ); + pCube->nLits = pCopy->nLits; + return pCube; +} + +/**Function************************************************************* + + Synopsis [Recycles the cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) +{ + Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); +} + +/**Function************************************************************* + + Synopsis [Recycles the cube cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube, * pCube2; + Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); +} + + +/**Function************************************************************* + + Synopsis [Counts the number of cubes in the cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubeCountLits( Min_Cube_t * pCube ) +{ + unsigned uData; + int Count = 0, i, w; + for ( w = 0; w < (int)pCube->nWords; w++ ) + { + uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); + for ( i = 0; i < 32; i += 2 ) + if ( uData & (1 << i) ) + Count++; + } + return Count; +} + +/**Function************************************************************* + + Synopsis [Counts the number of cubes in the cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) +{ + unsigned uData; + int i, w; + Vec_IntClear( vLits ); + for ( w = 0; w < (int)pCube->nWords; w++ ) + { + uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); + for ( i = 0; i < 32; i += 2 ) + if ( uData & (1 << i) ) + Vec_IntPush( vLits, w*16 + i/2 ); + } +} + +/**Function************************************************************* + + Synopsis [Counts the number of cubes in the cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube; + int Count = 0; + Min_CoverForEachCube( pCover, pCube ) + Count++; + return Count; +} + + +/**Function************************************************************* + + Synopsis [Checks if two cubes are disjoint.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ + unsigned uData; + int i; + assert( pCube0->nVars == pCube1->nVars ); + for ( i = 0; i < (int)pCube0->nWords; i++ ) + { + uData = pCube0->uData[i] & pCube1->uData[i]; + uData = (uData | (uData >> 1)) & 0x55555555; + if ( uData != 0x55555555 ) + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Collects the disjoint variables of the two cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars ) +{ + unsigned uData; + int i, w; + Vec_IntClear( vVars ); + for ( w = 0; w < (int)pCube->nWords; w++ ) + { + uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555; + uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1)); + if ( uData == 0 ) + continue; + for ( i = 0; i < 32; i += 2 ) + if ( uData & (1 << i) ) + Vec_IntPush( vVars, w*16 + i/2 ); + } +} + +/**Function************************************************************* + + Synopsis [Checks if two cubes are disjoint.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp ) +{ + unsigned uData; + int i, fFound = 0; + for ( i = 0; i < (int)pCube0->nWords; i++ ) + { + uData = pCube0->uData[i] ^ pCube1->uData[i]; + if ( uData == 0 ) + { + if ( pTemp ) pTemp->uData[i] = 0; + continue; + } + if ( fFound ) + return 0; + uData = (uData | (uData >> 1)) & 0x55555555; + if ( (uData & (uData-1)) > 0 ) // more than one 1 + return 0; + if ( pTemp ) pTemp->uData[i] = uData | (uData << 1); + fFound = 1; + } + if ( fFound == 0 ) + { + printf( "\n" ); + Min_CubeWrite( stdout, pCube0 ); + Min_CubeWrite( stdout, pCube1 ); + printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Checks if two cubes are disjoint.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 ) +{ + unsigned uData;//, uData2; + int i, k, Var0 = -1, Var1 = -1; + for ( i = 0; i < (int)pCube0->nWords; i++ ) + { + uData = pCube0->uData[i] ^ pCube1->uData[i]; + if ( uData == 0 ) + continue; + if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s + return 0; + uData = (uData | (uData >> 1)) & 0x55555555; + if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 ) + return 0; + for ( k = 0; k < 32; k += 2 ) + if ( uData & (1 << k) ) + { + if ( Var0 == -1 ) + Var0 = 16 * i + k/2; + else if ( Var1 == -1 ) + Var1 = 16 * i + k/2; + else + return 0; + } + /* + if ( Var0 >= 0 ) + { + uData &= 0xFFFF; + uData2 = (uData >> 16); + if ( uData && uData2 ) + return 0; + if ( uData ) + { + } + uData }= uData2; + uData &= 0x + } + */ + } + if ( Var0 >= 0 && Var1 >= 0 ) + { + *pVar0 = Var0; + *pVar1 = Var1; + return 1; + } + if ( Var0 == -1 || Var1 == -1 ) + { + printf( "\n" ); + Min_CubeWrite( stdout, pCube0 ); + Min_CubeWrite( stdout, pCube1 ); + printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Makes the produce of two cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ + Min_Cube_t * pCube; + int i; + assert( pCube0->nVars == pCube1->nVars ); + pCube = Min_CubeAlloc( p ); + for ( i = 0; i < p->nWords; i++ ) + pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i]; + pCube->nLits = Min_CubeCountLits( pCube ); + return pCube; +} + +/**Function************************************************************* + + Synopsis [Makes the produce of two cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ + Min_Cube_t * pCube; + int i; + assert( pCube0->nVars == pCube1->nVars ); + pCube = Min_CubeAlloc( p ); + for ( i = 0; i < p->nWords; i++ ) + pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i]; + pCube->nLits = Min_CubeCountLits( pCube ); + return pCube; +} + +/**Function************************************************************* + + Synopsis [Makes the produce of two cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ + int i; + for ( i = 0; i < (int)pCube0->nWords; i++ ) + if ( pCube0->uData[i] != pCube1->uData[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ + int i; + for ( i = 0; i < (int)pCube0->nWords; i++ ) + if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Transforms the cube into the result of merging.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask ) +{ + int w; + for ( w = 0; w < (int)pCube->nWords; w++ ) + { + pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w]; + pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]); + } +} + +/**Function************************************************************* + + Synopsis [Transforms the cube into the result of distance-1 merging.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist ) +{ + int w; + for ( w = 0; w < (int)pCube->nWords; w++ ) + pCube->uData[w] |= pDist->uData[w]; +} + + + +/**Function************************************************************* + + Synopsis [Sorts the cover in the increasing number of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube, * pCube2, * pThis; + if ( pCover == NULL ) + { + Min_ManClean( p, p->nVars ); + return; + } + Min_ManClean( p, pCover->nVars ); + Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + { + // go through the linked list + Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) + if ( Min_CubesAreEqual( pCube, pThis ) ) + { + Min_CubeRecycle( p, pCube ); + break; + } + if ( pThis != NULL ) + continue; + pCube->pNext = p->ppStore[pCube->nLits]; + p->ppStore[pCube->nLits] = pCube; + p->nCubes++; + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ + Min_Cube_t * pThis; + int i; +/* + // this cube cannot be equal to any cube + Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) + { + if ( Min_CubesAreEqual( pCube, pThis ) ) + { + Min_CubeWrite( stdout, pCube ); + assert( 0 ); + } + } +*/ + // try to find a containing cube + for ( i = 0; i <= (int)pCube->nLits; i++ ) + Min_CoverForEachCube( p->ppStore[i], pThis ) + { + // skip the bubble + if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) + return 1; + } + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMan.c b/src/map/cov/covMan.c new file mode 100644 index 00000000..74a5cf8a --- /dev/null +++ b/src/map/cov/covMan.c @@ -0,0 +1,144 @@ +/**CFile**************************************************************** + + FileName [covMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Decomposition manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cov_Man_t * Cov_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ) +{ + Cov_Man_t * pMan; + Cov_Obj_t * pMem; + Abc_Obj_t * pObj; + int i; + assert( pNtk->pManCut == NULL ); + + // start the manager + pMan = ABC_ALLOC( Cov_Man_t, 1 ); + memset( pMan, 0, sizeof(Cov_Man_t) ); + pMan->nFaninMax = nFaninMax; + pMan->nCubesMax = 2 * pMan->nFaninMax; + pMan->nWords = Abc_BitWordNum( nFaninMax * 2 ); + + // get the cubes + pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax ); + pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax ); + pMan->vPairs0 = Vec_IntAlloc( nFaninMax ); + pMan->vPairs1 = Vec_IntAlloc( nFaninMax ); + pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 ); + pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 ); + + // allocate memory for object structures + pMan->pMemory = pMem = ABC_ALLOC( Cov_Obj_t, sizeof(Cov_Obj_t) * Abc_NtkObjNumMax(pNtk) ); + memset( pMem, 0, sizeof(Cov_Obj_t) * Abc_NtkObjNumMax(pNtk) ); + // allocate storage for the pointers to the memory + pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) ); + Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL ); + Abc_NtkForEachObj( pNtk, pObj, i ) + Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i ); + // create the cube manager + pMan->pManMin = Min_ManAlloc( nFaninMax ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cov_ManFree( Cov_Man_t * p ) +{ + Vec_Int_t * vSupp; + int i; + for ( i = 0; i < p->vObjStrs->nSize; i++ ) + { + vSupp = ((Cov_Obj_t *)p->vObjStrs->pArray[i])->vSupp; + if ( vSupp ) Vec_IntFree( vSupp ); + } + + Min_ManFree( p->pManMin ); + Vec_PtrFree( p->vObjStrs ); + Vec_IntFree( p->vFanCounts ); + Vec_IntFree( p->vTriv0 ); + Vec_IntFree( p->vTriv1 ); + Vec_IntFree( p->vComTo0 ); + Vec_IntFree( p->vComTo1 ); + Vec_IntFree( p->vPairs0 ); + Vec_IntFree( p->vPairs1 ); + ABC_FREE( p->pMemory ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Drop the covers at the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeCovDropData( Cov_Man_t * p, Abc_Obj_t * pObj ) +{ + int nFanouts; + assert( p->vFanCounts ); + nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id ); + assert( nFanouts > 0 ); + if ( --nFanouts == 0 ) + { + Vec_IntFree( Abc_ObjGetSupp(pObj) ); + Abc_ObjSetSupp( pObj, NULL ); + Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) ); + Abc_ObjSetCover2( pObj, NULL ); + p->nSupps--; + } + Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinEsop.c b/src/map/cov/covMinEsop.c new file mode 100644 index 00000000..7dd3db30 --- /dev/null +++ b/src/map/cov/covMinEsop.c @@ -0,0 +1,299 @@ +/**CFile**************************************************************** + + FileName [covMinEsop.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [ESOP manipulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Min_EsopRewrite( Min_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_EsopMinimize( Min_Man_t * p ) +{ + int nCubesInit, nCubesOld, nIter; + if ( p->nCubes < 3 ) + return; + nIter = 0; + nCubesInit = p->nCubes; + do { + nCubesOld = p->nCubes; + Min_EsopRewrite( p ); + nIter++; + } + while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); + +// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); +} + +/**Function************************************************************* + + Synopsis [Performs one round of rewriting using distance 2 cubes.] + + Description [The weakness of this procedure is that it tries each cube + with only one distance-2 cube. If this pair does not lead to improvement + the cube is inserted into the cover anyhow, and we try another pair. + A possible improvement would be to try this cube with all distance-2 + cubes, until an improvement is found, or until all such cubes are tried.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_EsopRewrite( Min_Man_t * p ) +{ + Min_Cube_t * pCube, ** ppPrev; + Min_Cube_t * pThis, ** ppPrevT; + int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld; + int nPairs = 0; + + // insert the bubble before the first cube + p->pBubble->pNext = p->ppStore[0]; + p->ppStore[0] = p->pBubble; + p->pBubble->nLits = 0; + + // go through the cubes + while ( 1 ) + { + // get the index of the bubble + Index = p->pBubble->nLits; + + // find the bubble + Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) + if ( pCube == p->pBubble ) + break; + assert( pCube == p->pBubble ); + + // remove the bubble, get the next cube after the bubble + *ppPrev = p->pBubble->pNext; + pCube = p->pBubble->pNext; + if ( pCube == NULL ) + for ( Index++; Index <= p->nVars; Index++ ) + if ( p->ppStore[Index] ) + { + ppPrev = &(p->ppStore[Index]); + pCube = p->ppStore[Index]; + break; + } + // stop if there is no more cubes + if ( pCube == NULL ) + break; + + // find the first dist2 cube + Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) + if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + break; + if ( pThis == NULL && Index < p->nVars ) + Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) + if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + break; + if ( pThis == NULL && Index < p->nVars - 1 ) + Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) + if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + break; + // continue if there is no dist2 cube + if ( pThis == NULL ) + { + // insert the bubble after the cube + p->pBubble->pNext = pCube->pNext; + pCube->pNext = p->pBubble; + p->pBubble->nLits = pCube->nLits; + continue; + } + nPairs++; + + // remove the cubes, insert the bubble instead of pCube + *ppPrevT = pThis->pNext; + *ppPrev = p->pBubble; + p->pBubble->pNext = pCube->pNext; + p->pBubble->nLits = pCube->nLits; + p->nCubes -= 2; + + // Exorlink-2: + // A{v00} B{v01} + A{v10} B{v11} = + // A{v00+v10} B{v01} + A{v10} B{v01+v11} = + // A{v00} B{v01+v11} + A{v00+v10} B{v11} + + // save the dist2 parameters + v00 = Min_CubeGetVar( pCube, Var0 ); + v01 = Min_CubeGetVar( pCube, Var1 ); + v10 = Min_CubeGetVar( pThis, Var0 ); + v11 = Min_CubeGetVar( pThis, Var1 ); +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + + // derive the first pair of resulting cubes + Min_CubeXorVar( pCube, Var0, v10 ); + pCube->nLits -= (v00 != 3); + pCube->nLits += ((v00 ^ v10) != 3); + Min_CubeXorVar( pThis, Var1, v01 ); + pThis->nLits -= (v11 != 3); + pThis->nLits += ((v01 ^ v11) != 3); + + // add the cubes + nCubesOld = p->nCubes; + Min_EsopAddCube( p, pCube ); + Min_EsopAddCube( p, pThis ); + // check if the cubes were absorbed + if ( p->nCubes < nCubesOld + 2 ) + continue; + + // pull out both cubes + assert( pThis == p->ppStore[pThis->nLits] ); + p->ppStore[pThis->nLits] = pThis->pNext; + assert( pCube == p->ppStore[pCube->nLits] ); + p->ppStore[pCube->nLits] = pCube->pNext; + p->nCubes -= 2; + + // derive the second pair of resulting cubes + Min_CubeXorVar( pCube, Var0, v10 ); + pCube->nLits -= ((v00 ^ v10) != 3); + pCube->nLits += (v00 != 3); + Min_CubeXorVar( pCube, Var1, v11 ); + pCube->nLits -= (v01 != 3); + pCube->nLits += ((v01 ^ v11) != 3); + + Min_CubeXorVar( pThis, Var0, v00 ); + pThis->nLits -= (v10 != 3); + pThis->nLits += ((v00 ^ v10) != 3); + Min_CubeXorVar( pThis, Var1, v01 ); + pThis->nLits -= ((v01 ^ v11) != 3); + pThis->nLits += (v11 != 3); + + // add them anyhow + Min_EsopAddCube( p, pCube ); + Min_EsopAddCube( p, pThis ); + } +// printf( "Pairs = %d ", nPairs ); +} + +/**Function************************************************************* + + Synopsis [Adds the cube to storage.] + + Description [Returns 0 if the cube is added or removed. Returns 1 + if the cube is glued with some other cube and has to be added again. + Do not forget to clean the storage!] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) +{ + Min_Cube_t * pThis, ** ppPrev; + // try to find the identical cube + Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) + { + if ( Min_CubesAreEqual( pCube, pThis ) ) + { + *ppPrev = pThis->pNext; + Min_CubeRecycle( p, pCube ); + Min_CubeRecycle( p, pThis ); + p->nCubes--; + return 0; + } + } + // find a distance-1 cube if it exists + if ( pCube->nLits < pCube->nVars ) + Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) + { + if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + { + *ppPrev = pThis->pNext; + Min_CubesTransform( pCube, pThis, p->pTemp ); + pCube->nLits++; + Min_CubeRecycle( p, pThis ); + p->nCubes--; + return 1; + } + } + Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) + { + if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + { + *ppPrev = pThis->pNext; + Min_CubesTransform( pCube, pThis, p->pTemp ); + pCube->nLits--; + Min_CubeRecycle( p, pThis ); + p->nCubes--; + return 1; + } + } + if ( pCube->nLits > 0 ) + Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) + { + if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + { + *ppPrev = pThis->pNext; + Min_CubesTransform( pCube, pThis, p->pTemp ); + Min_CubeRecycle( p, pThis ); + p->nCubes--; + return 1; + } + } + // add the cube + pCube->pNext = p->ppStore[pCube->nLits]; + p->ppStore[pCube->nLits] = pCube; + p->nCubes++; + return 0; +} + +/**Function************************************************************* + + Synopsis [Adds the cube to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ + assert( pCube != p->pBubble ); + assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); + while ( Min_EsopAddCubeInt( p, pCube ) ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinMan.c b/src/map/cov/covMinMan.c new file mode 100644 index 00000000..74aa2e8c --- /dev/null +++ b/src/map/cov/covMinMan.c @@ -0,0 +1,113 @@ +/**CFile**************************************************************** + + FileName [covMinMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [SOP manipulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the minimization manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Man_t * Min_ManAlloc( int nVars ) +{ + Min_Man_t * pMan; + // start the manager + pMan = ABC_ALLOC( Min_Man_t, 1 ); + memset( pMan, 0, sizeof(Min_Man_t) ); + pMan->nVars = nVars; + pMan->nWords = Abc_BitWordNum( nVars * 2 ); + pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) ); + // allocate storage for the temporary cover + pMan->ppStore = ABC_ALLOC( Min_Cube_t *, pMan->nVars + 1 ); + // create tautology cubes + Min_ManClean( pMan, nVars ); + pMan->pOne0 = Min_CubeAlloc( pMan ); + pMan->pOne1 = Min_CubeAlloc( pMan ); + pMan->pTemp = Min_CubeAlloc( pMan ); + pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0; + // create trivial cubes + Min_ManClean( pMan, 1 ); + pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 ); + pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 ); + pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 ); + pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 ); + Min_ManClean( pMan, nVars ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Cleans the minimization manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManClean( Min_Man_t * p, int nSupp ) +{ + // set the size of the cube manager + p->nVars = nSupp; + p->nWords = Abc_BitWordNum(2*nSupp); + // clean the storage + memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) ); + p->nCubes = 0; +} + +/**Function************************************************************* + + Synopsis [Stops the minimization manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManFree( Min_Man_t * p ) +{ + Extra_MmFixedStop( p->pMemMan ); + ABC_FREE( p->ppStore ); + ABC_FREE( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinSop.c b/src/map/cov/covMinSop.c new file mode 100644 index 00000000..731a6698 --- /dev/null +++ b/src/map/cov/covMinSop.c @@ -0,0 +1,615 @@ +/**CFile**************************************************************** + + FileName [covMinSop.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [SOP manipulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Min_SopRewrite( Min_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_SopMinimize( Min_Man_t * p ) +{ + int nCubesInit, nCubesOld, nIter; + if ( p->nCubes < 3 ) + return; + nIter = 0; + nCubesInit = p->nCubes; + do { + nCubesOld = p->nCubes; + Min_SopRewrite( p ); + nIter++; +// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); + } + while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); +// printf( "\n" ); + +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_SopRewrite( Min_Man_t * p ) +{ + Min_Cube_t * pCube, ** ppPrev; + Min_Cube_t * pThis, ** ppPrevT; + Min_Cube_t * pTemp; + int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld; + int nPairs = 0; +/* + { + Min_Cube_t * pCover; + pCover = Min_CoverCollect( p, p->nVars ); +printf( "\n\n" ); +Min_CoverWrite( stdout, pCover ); + Min_CoverExpand( p, pCover ); + } +*/ + + // insert the bubble before the first cube + p->pBubble->pNext = p->ppStore[0]; + p->ppStore[0] = p->pBubble; + p->pBubble->nLits = 0; + + // go through the cubes + while ( 1 ) + { + // get the index of the bubble + Index = p->pBubble->nLits; + + // find the bubble + Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) + if ( pCube == p->pBubble ) + break; + assert( pCube == p->pBubble ); + + // remove the bubble, get the next cube after the bubble + *ppPrev = p->pBubble->pNext; + pCube = p->pBubble->pNext; + if ( pCube == NULL ) + for ( Index++; Index <= p->nVars; Index++ ) + if ( p->ppStore[Index] ) + { + ppPrev = &(p->ppStore[Index]); + pCube = p->ppStore[Index]; + break; + } + // stop if there is no more cubes + if ( pCube == NULL ) + break; + + // find the first dist2 cube + Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) + if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + break; + if ( pThis == NULL && Index < p->nVars ) + Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) + if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + break; + // continue if there is no dist2 cube + if ( pThis == NULL ) + { + // insert the bubble after the cube + p->pBubble->pNext = pCube->pNext; + pCube->pNext = p->pBubble; + p->pBubble->nLits = pCube->nLits; + continue; + } + nPairs++; +/* +printf( "\n" ); +Min_CubeWrite( stdout, pCube ); +Min_CubeWrite( stdout, pThis ); +*/ + // remove the cubes, insert the bubble instead of pCube + *ppPrevT = pThis->pNext; + *ppPrev = p->pBubble; + p->pBubble->pNext = pCube->pNext; + p->pBubble->nLits = pCube->nLits; + p->nCubes -= 2; + + assert( pCube != p->pBubble && pThis != p->pBubble ); + + + // save the dist2 parameters + v00 = Min_CubeGetVar( pCube, Var0 ); + v01 = Min_CubeGetVar( pCube, Var1 ); + v10 = Min_CubeGetVar( pThis, Var0 ); + v11 = Min_CubeGetVar( pThis, Var1 ); + assert( v00 != v10 && v01 != v11 ); + assert( v00 != 3 || v01 != 3 ); + assert( v10 != 3 || v11 != 3 ); + +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + + // consider the case when both cubes have non-empty literals + if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 ) + { + assert( v00 == (v10 ^ 3) ); + assert( v01 == (v11 ^ 3) ); + // create the temporary cube equal to the first corner + Min_CubeXorVar( pCube, Var0, 3 ); + // check if this cube is contained + fCont0 = Min_CoverContainsCube( p, pCube ); + // create the temporary cube equal to the first corner + Min_CubeXorVar( pCube, Var0, 3 ); + Min_CubeXorVar( pCube, Var1, 3 ); +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + // check if this cube is contained + fCont1 = Min_CoverContainsCube( p, pCube ); + // undo the change + Min_CubeXorVar( pCube, Var1, 3 ); + + // check if the cubes can be overwritten + if ( fCont0 && fCont1 ) + { + // one of the cubes can be recycled, the other expanded and added + Min_CubeRecycle( p, pThis ); + // remove the literals + Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); + Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); + pCube->nLits -= 2; + Min_SopAddCube( p, pCube ); + } + else if ( fCont0 ) + { + // expand both cubes and add them + Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); + pCube->nLits--; + Min_SopAddCube( p, pCube ); + Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); + pThis->nLits--; + Min_SopAddCube( p, pThis ); + } + else if ( fCont1 ) + { + // expand both cubes and add them + Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); + pCube->nLits--; + Min_SopAddCube( p, pCube ); + Min_CubeXorVar( pThis, Var0, v10 ^ 3 ); + pThis->nLits--; + Min_SopAddCube( p, pThis ); + } + else + { + Min_SopAddCube( p, pCube ); + Min_SopAddCube( p, pThis ); + } + // otherwise, no change is possible + continue; + } + + // if one of them does not have DC lit, move it + if ( v00 != 3 && v01 != 3 ) + { + assert( v10 == 3 || v11 == 3 ); + pTemp = pCube; pCube = pThis; pThis = pTemp; + Index = v00; v00 = v10; v10 = Index; + Index = v01; v01 = v11; v11 = Index; + } + + // make sure the first cube has first var DC + if ( v00 != 3 ) + { + assert( v01 == 3 ); + Index = Var0; Var0 = Var1; Var1 = Index; + Index = v00; v00 = v01; v01 = Index; + Index = v10; v10 = v11; v11 = Index; + } + + // consider both cases: both have DC lit + if ( v00 == 3 && v11 == 3 ) + { + assert( v01 != 3 && v10 != 3 ); + // try the remaining minterm + // create the temporary cube equal to the first corner + Min_CubeXorVar( pCube, Var0, v10 ); + Min_CubeXorVar( pCube, Var1, 3 ); + pCube->nLits++; + // check if this cube is contained + fCont0 = Min_CoverContainsCube( p, pCube ); + // undo the cube transformations + Min_CubeXorVar( pCube, Var0, v10 ); + Min_CubeXorVar( pCube, Var1, 3 ); + pCube->nLits--; + // check the case when both are covered + if ( fCont0 ) + { + // one of the cubes can be recycled, the other expanded and added + Min_CubeRecycle( p, pThis ); + // remove the literals + Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); + pCube->nLits--; + Min_SopAddCube( p, pCube ); + } + else + { + // try two reduced cubes + Min_CubeXorVar( pCube, Var0, v10 ); + pCube->nLits++; + // remember the cubes + nCubesOld = p->nCubes; + Min_SopAddCube( p, pCube ); + // check if the cube is absorbed + if ( p->nCubes < nCubesOld + 1 ) + { // absorbed - add the second cube + Min_SopAddCube( p, pThis ); + } + else + { // remove this cube, and try another one + assert( pCube == p->ppStore[pCube->nLits] ); + p->ppStore[pCube->nLits] = pCube->pNext; + p->nCubes--; + + // return the cube to the previous state + Min_CubeXorVar( pCube, Var0, v10 ); + pCube->nLits--; + + // generate another reduced cube + Min_CubeXorVar( pThis, Var1, v01 ); + pThis->nLits++; + + // add both cubes + Min_SopAddCube( p, pCube ); + Min_SopAddCube( p, pThis ); + } + } + } + else // the first cube has DC lit + { + assert( v01 != 3 && v10 != 3 && v11 != 3 ); + // try the remaining minterm + // create the temporary cube equal to the minterm + Min_CubeXorVar( pThis, Var0, 3 ); + // check if this cube is contained + fCont0 = Min_CoverContainsCube( p, pThis ); + // undo the cube transformations + Min_CubeXorVar( pThis, Var0, 3 ); + // check the case when both are covered + if ( fCont0 ) + { + // one of the cubes can be recycled, the other expanded and added + Min_CubeRecycle( p, pThis ); + // remove the literals + Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); + pCube->nLits--; + Min_SopAddCube( p, pCube ); + } + else + { + // try reshaping the cubes + // reduce the first cube + Min_CubeXorVar( pCube, Var0, v10 ); + pCube->nLits++; + // expand the second cube + Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); + pThis->nLits--; + // add both cubes + Min_SopAddCube( p, pCube ); + Min_SopAddCube( p, pThis ); + } + } + } +// printf( "Pairs = %d ", nPairs ); +} + +/**Function************************************************************* + + Synopsis [Adds cube to the SOP cover stored in the manager.] + + Description [Returns 0 if the cube is added or removed. Returns 1 + if the cube is glued with some other cube and has to be added again.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) +{ + Min_Cube_t * pThis, * pThis2, ** ppPrev; + int i; + // try to find the identical cube + Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) + { + if ( Min_CubesAreEqual( pCube, pThis ) ) + { + Min_CubeRecycle( p, pCube ); + return 0; + } + } + // try to find a containing cube + for ( i = 0; i < (int)pCube->nLits; i++ ) + Min_CoverForEachCube( p->ppStore[i], pThis ) + { + if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) + { + Min_CubeRecycle( p, pCube ); + return 0; + } + } + // try to find distance one in the same bin + Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) + { + if ( Min_CubesDistOne( pCube, pThis, NULL ) ) + { + *ppPrev = pThis->pNext; + Min_CubesTransformOr( pCube, pThis ); + pCube->nLits--; + Min_CubeRecycle( p, pThis ); + p->nCubes--; + return 1; + } + } + + // clean the other cubes using this one + for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ ) + { + ppPrev = &p->ppStore[i]; + Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 ) + { + if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) ) + { + *ppPrev = pThis->pNext; + Min_CubeRecycle( p, pThis ); + p->nCubes--; + } + else + ppPrev = &pThis->pNext; + } + } + + // add the cube + pCube->pNext = p->ppStore[pCube->nLits]; + p->ppStore[pCube->nLits] = pCube; + p->nCubes++; + return 0; +} + +/**Function************************************************************* + + Synopsis [Adds the cube to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ + assert( Min_CubeCheck( pCube ) ); + assert( pCube != p->pBubble ); + assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); + while ( Min_SopAddCubeInt( p, pCube ) ); +} + + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_SopContain( Min_Man_t * p ) +{ + Min_Cube_t * pCube, * pCube2, ** ppPrev; + int i, k; + for ( i = 0; i <= p->nVars; i++ ) + { + Min_CoverForEachCube( p->ppStore[i], pCube ) + Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev ) + { + if ( !Min_CubesAreEqual( pCube, pCube2 ) ) + continue; + *ppPrev = pCube2->pNext; + Min_CubeRecycle( p, pCube2 ); + p->nCubes--; + } + for ( k = i + 1; k <= p->nVars; k++ ) + Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev ) + { + if ( !Min_CubeIsContained( pCube, pCube2 ) ) + continue; + *ppPrev = pCube2->pNext; + Min_CubeRecycle( p, pCube2 ); + p->nCubes--; + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_SopDist1Merge( Min_Man_t * p ) +{ + Min_Cube_t * pCube, * pCube2, * pCubeNew; + int i; + for ( i = p->nVars; i >= 0; i-- ) + { + Min_CoverForEachCube( p->ppStore[i], pCube ) + Min_CoverForEachCube( pCube->pNext, pCube2 ) + { + assert( pCube->nLits == pCube2->nLits ); + if ( !Min_CubesDistOne( pCube, pCube2, NULL ) ) + continue; + pCubeNew = Min_CubesXor( p, pCube, pCube2 ); + assert( pCubeNew->nLits == pCube->nLits - 1 ); + pCubeNew->pNext = p->ppStore[pCubeNew->nLits]; + p->ppStore[pCubeNew->nLits] = pCubeNew; + p->nCubes++; + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp ) +{ + Vec_Int_t * vVars; + Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev; + int Num, Value, i; + + // get the variables + vVars = Vec_IntAlloc( 100 ); + // create the tautology cube + pCover = Min_CubeAlloc( p ); + // sharp it with all cubes + Min_CoverForEachCube( pSharp, pCube ) + Min_CoverForEachCubePrev( pCover, pThis, ppPrev ) + { + if ( Min_CubesDisjoint( pThis, pCube ) ) + continue; + // remember the next pointer + pNext = pThis->pNext; + // get the variables, in which pThis is '-' while pCube is fixed + Min_CoverGetDisjVars( pThis, pCube, vVars ); + // generate the disjoint cubes + pReady = pThis; + Vec_IntForEachEntryReverse( vVars, Num, i ) + { + // correct the literal + Min_CubeXorVar( pReady, vVars->pArray[i], 3 ); + if ( i == 0 ) + break; + // create the new cube and clean this value + Value = Min_CubeGetVar( pReady, vVars->pArray[i] ); + pReady = Min_CubeDup( p, pReady ); + Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value ); + // add to the cover + *ppPrev = pReady; + ppPrev = &pReady->pNext; + } + pThis = pReady; + pThis->pNext = pNext; + } + Vec_IntFree( vVars ); + + // perform dist-1 merge and contain + Min_CoverExpandRemoveEqual( p, pCover ); + Min_SopDist1Merge( p ); + Min_SopContain( p ); + return Min_CoverCollect( p, p->nVars ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_SopCheck( Min_Man_t * p ) +{ + Min_Cube_t * pCube, * pThis; + int i; + + pCube = Min_CubeAlloc( p ); + Min_CubeXorBit( pCube, 2*0+1 ); + Min_CubeXorBit( pCube, 2*1+1 ); + Min_CubeXorBit( pCube, 2*2+0 ); + Min_CubeXorBit( pCube, 2*3+0 ); + Min_CubeXorBit( pCube, 2*4+0 ); + Min_CubeXorBit( pCube, 2*5+1 ); + Min_CubeXorBit( pCube, 2*6+1 ); + pCube->nLits = 7; + +// Min_CubeWrite( stdout, pCube ); + + // check that the cubes contain it + for ( i = 0; i <= p->nVars; i++ ) + Min_CoverForEachCube( p->ppStore[i], pThis ) + if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) + { + Min_CubeRecycle( p, pCube ); + return 1; + } + Min_CubeRecycle( p, pCube ); + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinUtil.c b/src/map/cov/covMinUtil.c new file mode 100644 index 00000000..c383a3e8 --- /dev/null +++ b/src/map/cov/covMinUtil.c @@ -0,0 +1,338 @@ +/**CFile**************************************************************** + + FileName [covMinUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Utilities.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CubeCreate( Vec_Str_t * vCover, Min_Cube_t * pCube, char Type ) +{ + int i; + assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); + for ( i = 0; i < (int)pCube->nVars; i++ ) + if ( Min_CubeHasBit(pCube, i*2) ) + { + if ( Min_CubeHasBit(pCube, i*2+1) ) +// fprintf( pFile, "-" ); + Vec_StrPush( vCover, '-' ); + else +// fprintf( pFile, "0" ); + Vec_StrPush( vCover, '0' ); + } + else + { + if ( Min_CubeHasBit(pCube, i*2+1) ) + // fprintf( pFile, "1" ); + Vec_StrPush( vCover, '1' ); + else +// fprintf( pFile, "?" ); + Vec_StrPush( vCover, '?' ); + } +// fprintf( pFile, " 1\n" ); + Vec_StrPush( vCover, ' ' ); + Vec_StrPush( vCover, Type ); + Vec_StrPush( vCover, '\n' ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverCreate( Vec_Str_t * vCover, Min_Cube_t * pCover, char Type ) +{ + Min_Cube_t * pCube; + assert( pCover != NULL ); + Vec_StrClear( vCover ); + Min_CoverForEachCube( pCover, pCube ) + Min_CubeCreate( vCover, pCube, Type ); + Vec_StrPush( vCover, 0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ) +{ + int i; + assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); + for ( i = 0; i < (int)pCube->nVars; i++ ) + if ( Min_CubeHasBit(pCube, i*2) ) + { + if ( Min_CubeHasBit(pCube, i*2+1) ) + fprintf( pFile, "-" ); + else + fprintf( pFile, "0" ); + } + else + { + if ( Min_CubeHasBit(pCube, i*2+1) ) + fprintf( pFile, "1" ); + else + fprintf( pFile, "?" ); + } + fprintf( pFile, " 1\n" ); +// fprintf( pFile, " %d\n", pCube->nLits ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube; + Min_CoverForEachCube( pCover, pCube ) + Min_CubeWrite( pFile, pCube ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) +{ + Min_Cube_t * pCube; + int i; + for ( i = 0; i <= p->nVars; i++ ) + { + Min_CoverForEachCube( p->ppStore[i], pCube ) + { + printf( "%2d : ", i ); + if ( pCube == p->pBubble ) + { + printf( "Bubble\n" ); + continue; + } + Min_CubeWrite( pFile, pCube ); + } + } + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) +{ + char Buffer[1000]; + Min_Cube_t * pCube; + FILE * pFile; + int i; + sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" ); + for ( i = strlen(Buffer) - 1; i >= 0; i-- ) + if ( Buffer[i] == '<' || Buffer[i] == '>' ) + Buffer[i] = '_'; + pFile = fopen( Buffer, "w" ); + fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() ); + fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 ); + fprintf( pFile, ".o %d\n", 1 ); + fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) ); + if ( fEsop ) fprintf( pFile, ".type esop\n" ); + Min_CoverForEachCube( pCover, pCube ) + Min_CubeWrite( pFile, pCube ); + fprintf( pFile, ".e\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverCheck( Min_Man_t * p ) +{ + Min_Cube_t * pCube; + int i; + for ( i = 0; i <= p->nVars; i++ ) + Min_CoverForEachCube( p->ppStore[i], pCube ) + assert( i == (int)pCube->nLits ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_CubeCheck( Min_Cube_t * pCube ) +{ + int i; + for ( i = 0; i < (int)pCube->nVars; i++ ) + if ( Min_CubeGetVar( pCube, i ) == 0 ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Converts the cover from the sorted structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ) +{ + Min_Cube_t * pCov = NULL, ** ppTail = &pCov; + Min_Cube_t * pCube, * pCube2; + int i; + for ( i = 0; i <= nSuppSize; i++ ) + { + Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 ) + { + assert( i == (int)pCube->nLits ); + *ppTail = pCube; + ppTail = &pCube->pNext; + assert( pCube->uData[0] ); // not a bubble + } + } + *ppTail = NULL; + return pCov; +} + +/**Function************************************************************* + + Synopsis [Sorts the cover in the increasing number of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube, * pCube2; + Min_ManClean( p, p->nVars ); + Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + { + pCube->pNext = p->ppStore[pCube->nLits]; + p->ppStore[pCube->nLits] = pCube; + p->nCubes++; + } +} + +/**Function************************************************************* + + Synopsis [Sorts the cover in the increasing number of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ) +{ + Min_Cube_t * pCube; + int i, Counter; + if ( pCover == NULL ) + return 0; + // clean the cube + for ( i = 0; i < (int)pCover->nWords; i++ ) + p->pTemp->uData[i] = ~((unsigned)0); + // add the bit data + Min_CoverForEachCube( pCover, pCube ) + for ( i = 0; i < (int)pCover->nWords; i++ ) + p->pTemp->uData[i] &= pCube->uData[i]; + // count the vars + Counter = 0; + for ( i = 0; i < (int)pCover->nVars; i++ ) + Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 ); + return Counter; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covTest.c b/src/map/cov/covTest.c new file mode 100644 index 00000000..39432c90 --- /dev/null +++ b/src/map/cov/covTest.c @@ -0,0 +1,417 @@ +/**CFile**************************************************************** + + FileName [covTest.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Mapping into network of SOPs/ESOPs.] + + Synopsis [Testing procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: covTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) +{ + Min_Cube_t * pCover; + Min_Cube_t * pCube0, * pCube1, * pCube; + if ( pCover0 == NULL || pCover1 == NULL ) + return NULL; + // clean storage + Min_ManClean( p, p->nVars ); + // go through the cube pairs + Min_CoverForEachCube( pCover0, pCube0 ) + Min_CoverForEachCube( pCover1, pCube1 ) + { + if ( Min_CubesDisjoint( pCube0, pCube1 ) ) + continue; + pCube = Min_CubesProduct( p, pCube0, pCube1 ); + // add the cube to storage + Min_SopAddCube( p, pCube ); + } + Min_SopMinimize( p ); + pCover = Min_CoverCollect( p, p->nVars ); + assert( p->nCubes == Min_CoverCountCubes(pCover) ); + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) +{ + Min_Cube_t * pCover; + Min_Cube_t * pThis, * pCube; + if ( pCover0 == NULL || pCover1 == NULL ) + return NULL; + // clean storage + Min_ManClean( p, p->nVars ); + // add the cubes to storage + Min_CoverForEachCube( pCover0, pThis ) + { + pCube = Min_CubeDup( p, pThis ); + Min_SopAddCube( p, pCube ); + } + Min_CoverForEachCube( pCover1, pThis ) + { + pCube = Min_CubeDup( p, pThis ); + Min_SopAddCube( p, pCube ); + } + Min_SopMinimize( p ); + pCover = Min_CoverCollect( p, p->nVars ); + assert( p->nCubes == Min_CoverCountCubes(pCover) ); + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) +{ + Min_Cube_t * pCov0[2], * pCov1[2]; + Min_Cube_t * pCoverP, * pCoverN; + Abc_Obj_t * pObj; + int i, nCubes, fCompl0, fCompl1; + + // set elementary vars + Vec_PtrForEachEntry( vSupp, pObj, i ) + { + pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); + pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 ); + } + + // get the cover for each node in the array + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + // get the complements + fCompl0 = Abc_ObjFaninC0(pObj); + fCompl1 = Abc_ObjFaninC1(pObj); + // get the covers + pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy; + pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext; + pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy; + pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext; + // compute the covers + pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] ); + pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] ); + // set the covers + pObj->pCopy = (Abc_Obj_t *)pCoverP; + pObj->pNext = (Abc_Obj_t *)pCoverN; + } + + nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) ); + +/* +printf( "\n\n" ); +Min_CoverWrite( stdout, pCoverP ); +printf( "\n\n" ); +Min_CoverWrite( stdout, pCoverN ); +*/ + +// printf( "\n" ); +// Min_CoverWrite( stdout, pCoverP ); + +// Min_CoverExpand( p, pCoverP ); +// Min_SopMinimize( p ); +// pCoverP = Min_CoverCollect( p, p->nVars ); + +// printf( "\n" ); +// Min_CoverWrite( stdout, pCoverP ); + +// nCubes = Min_CoverCountCubes(pCoverP); + + // clean the copy fields + Vec_PtrForEachEntry( vNodes, pObj, i ) + pObj->pCopy = pObj->pNext = NULL; + Vec_PtrForEachEntry( vSupp, pObj, i ) + pObj->pCopy = pObj->pNext = NULL; + +// Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 ); +// printf( "\n" ); +// Min_CoverWrite( stdout, pCoverP ); + +// printf( "\n" ); +// Min_CoverWrite( stdout, pCoverP ); +// printf( "\n" ); +// Min_CoverWrite( stdout, pCoverN ); + return nCubes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTestSop( Abc_Ntk_t * pNtk ) +{ + Min_Man_t * p; + Vec_Ptr_t * vSupp, * vNodes; + Abc_Obj_t * pObj; + int i, nCubes; + assert( Abc_NtkIsStrash(pNtk) ); + + Abc_NtkCleanCopy(pNtk); + Abc_NtkCleanNext(pNtk); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + if ( !Abc_ObjIsNode(Abc_ObjFanin0(pObj)) ) + { + printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); + continue; + } + + vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); + vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); + + printf( "%20s : Cone = %5d. Supp = %5d. ", + Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); +// if ( vSupp->nSize <= 128 ) + { + p = Min_ManAlloc( vSupp->nSize ); + nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes ); + printf( "Cubes = %5d. ", nCubes ); + Min_ManFree( p ); + } + printf( "\n" ); + + + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + } +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 ) +{ + Min_Cube_t * pCover0, * pCover1, * pCover; + Min_Cube_t * pCube0, * pCube1, * pCube; + + // complement the first if needed + if ( !fComp0 ) + pCover0 = pCov0; + else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube + pCover0 = pCov0->pNext; + else + pCover0 = p->pOne0, p->pOne0->pNext = pCov0; + + // complement the second if needed + if ( !fComp1 ) + pCover1 = pCov1; + else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube + pCover1 = pCov1->pNext; + else + pCover1 = p->pOne1, p->pOne1->pNext = pCov1; + + if ( pCover0 == NULL || pCover1 == NULL ) + return NULL; + + // clean storage + Min_ManClean( p, p->nVars ); + // go through the cube pairs + Min_CoverForEachCube( pCover0, pCube0 ) + Min_CoverForEachCube( pCover1, pCube1 ) + { + if ( Min_CubesDisjoint( pCube0, pCube1 ) ) + continue; + pCube = Min_CubesProduct( p, pCube0, pCube1 ); + // add the cube to storage + Min_EsopAddCube( p, pCube ); + } + + if ( p->nCubes > 10 ) + { +// printf( "(%d,", p->nCubes ); + Min_EsopMinimize( p ); +// printf( "%d) ", p->nCubes ); + } + + pCover = Min_CoverCollect( p, p->nVars ); + assert( p->nCubes == Min_CoverCountCubes(pCover) ); + +// if ( p->nCubes > 1000 ) +// printf( "%d ", p->nCubes ); + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) +{ + Min_Cube_t * pCover, * pCube; + Abc_Obj_t * pObj; + int i; + + // set elementary vars + Vec_PtrForEachEntry( vSupp, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); + + // get the cover for each node in the array + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + pCover = Abc_NodeDeriveCover( p, + (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy, + (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy, + Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); + pObj->pCopy = (Abc_Obj_t *)pCover; + if ( p->nCubes > 3000 ) + return -1; + } + + // add complement if needed + if ( Abc_ObjFaninC0(pRoot) ) + { + if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube + { + pCube = pCover; + pCover = pCover->pNext; + Min_CubeRecycle( p, pCube ); + p->nCubes--; + } + else + { + pCube = Min_CubeAlloc( p ); + pCube->pNext = pCover; + p->nCubes++; + } + } +/* + Min_CoverExpand( p, pCover ); + Min_EsopMinimize( p ); + pCover = Min_CoverCollect( p, p->nVars ); +*/ + // clean the copy fields + Vec_PtrForEachEntry( vNodes, pObj, i ) + pObj->pCopy = NULL; + Vec_PtrForEachEntry( vSupp, pObj, i ) + pObj->pCopy = NULL; + +// Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 ); +// Min_CoverWrite( stdout, pCover ); + return p->nCubes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTestEsop( Abc_Ntk_t * pNtk ) +{ + Min_Man_t * p; + Vec_Ptr_t * vSupp, * vNodes; + Abc_Obj_t * pObj; + int i, nCubes; + assert( Abc_NtkIsStrash(pNtk) ); + + Abc_NtkCleanCopy(pNtk); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + if ( !Abc_ObjIsNode(Abc_ObjFanin0(pObj)) ) + { + printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); + continue; + } + + vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); + vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); + + printf( "%20s : Cone = %5d. Supp = %5d. ", + Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); +// if ( vSupp->nSize <= 128 ) + { + p = Min_ManAlloc( vSupp->nSize ); + nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes ); + printf( "Cubes = %5d. ", nCubes ); + Min_ManFree( p ); + } + printf( "\n" ); + + + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/module.make b/src/map/cov/module.make new file mode 100644 index 00000000..5b68c64c --- /dev/null +++ b/src/map/cov/module.make @@ -0,0 +1,7 @@ +SRC += src/map/cov/covBuild.c \ + src/map/cov/covCore.c \ + src/map/cov/covMan.c \ + src/map/cov/covMinEsop.c \ + src/map/cov/covMinMan.c \ + src/map/cov/covMinSop.c \ + src/map/cov/covMinUtil.c |