diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
commit | 8014f25f6db719fa62336f997963532a14c568f6 (patch) | |
tree | c691ee91a3a2d452a2bd24ac89a8c717beaa7af7 /src/proof/cec | |
parent | c44cc5de9429e6b4f1c05045fcf43c9cb96437b5 (diff) | |
download | abc-8014f25f6db719fa62336f997963532a14c568f6.tar.gz abc-8014f25f6db719fa62336f997963532a14c568f6.tar.bz2 abc-8014f25f6db719fa62336f997963532a14c568f6.zip |
Major restructuring of the code.
Diffstat (limited to 'src/proof/cec')
-rw-r--r-- | src/proof/cec/cec.c | 53 | ||||
-rw-r--r-- | src/proof/cec/cec.h | 233 | ||||
-rw-r--r-- | src/proof/cec/cecCec.c | 373 | ||||
-rw-r--r-- | src/proof/cec/cecChoice.c | 409 | ||||
-rw-r--r-- | src/proof/cec/cecClass.c | 931 | ||||
-rw-r--r-- | src/proof/cec/cecCore.c | 542 | ||||
-rw-r--r-- | src/proof/cec/cecCorr.c | 1137 | ||||
-rw-r--r-- | src/proof/cec/cecCorr_updated.c | 1027 | ||||
-rw-r--r-- | src/proof/cec/cecInt.h | 225 | ||||
-rw-r--r-- | src/proof/cec/cecIso.c | 375 | ||||
-rw-r--r-- | src/proof/cec/cecMan.c | 297 | ||||
-rw-r--r-- | src/proof/cec/cecPat.c | 569 | ||||
-rw-r--r-- | src/proof/cec/cecSeq.c | 448 | ||||
-rw-r--r-- | src/proof/cec/cecSim.c | 53 | ||||
-rw-r--r-- | src/proof/cec/cecSolve.c | 1023 | ||||
-rw-r--r-- | src/proof/cec/cecSweep.c | 299 | ||||
-rw-r--r-- | src/proof/cec/cecSynth.c | 380 | ||||
-rw-r--r-- | src/proof/cec/module.make | 13 |
18 files changed, 8387 insertions, 0 deletions
diff --git a/src/proof/cec/cec.c b/src/proof/cec/cec.c new file mode 100644 index 00000000..6968a599 --- /dev/null +++ b/src/proof/cec/cec.c @@ -0,0 +1,53 @@ +/**CFile**************************************************************** + + FileName [cec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h new file mode 100644 index 00000000..10b06c28 --- /dev/null +++ b/src/proof/cec/cec.h @@ -0,0 +1,233 @@ +/**CFile**************************************************************** + + FileName [cec.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__aig__cec__cec_h +#define ABC__aig__cec__cec_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// dynamic SAT parameters +typedef struct Cec_ParSat_t_ Cec_ParSat_t; +struct Cec_ParSat_t_ +{ + int nBTLimit; // conflict limit at a node + int nSatVarMax; // the max number of SAT variables + int nCallsRecycle; // calls to perform before recycling SAT solver + int fNonChrono; // use non-chronological backtracling (for circuit SAT only) + int fPolarFlip; // flops polarity of variables + int fCheckMiter; // the circuit is the miter +// int fFirstStop; // stop on the first sat output + int fLearnCls; // perform clause learning + int fVerbose; // verbose stats +}; + +// simulation parameters +typedef struct Cec_ParSim_t_ Cec_ParSim_t; +struct Cec_ParSim_t_ +{ + int nWords; // the number of simulation words + int nFrames; // the number of simulation frames + int nRounds; // the number of simulation rounds + int nNonRefines; // the max number of rounds without refinement + int TimeLimit; // the runtime limit in seconds + int fDualOut; // miter with separate outputs + 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 fConstCorr; // consider only constants + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// semiformal parameters +typedef struct Cec_ParSmf_t_ Cec_ParSmf_t; +struct Cec_ParSmf_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int nFrames; // the max number of time frames + int nNonRefines; // the max number of rounds without refinement + int nMinOutputs; // the min outputs to accumulate + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fDualOut; // miter with separate outputs + int fCheckMiter; // the circuit is the miter +// int fFirstStop; // stop on the first sat output + int fVerbose; // verbose stats +}; + +// combinational SAT sweeping parameters +typedef struct Cec_ParFra_t_ Cec_ParFra_t; +struct Cec_ParFra_t_ +{ + int nWords; // the number of simulation words + int nRounds; // the number of simulation rounds + int nItersMax; // the maximum number of iterations of SAT sweeping + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int nLevelMax; // restriction on the level nodes to be swept + int nDepthMax; // the depth in terms of steps of speculative reduction + int fRewriting; // enables AIG rewriting + int fCheckMiter; // the circuit is the miter +// int fFirstStop; // stop on the first sat output + int fDualOut; // miter with separate outputs + int fColorDiff; // miter with separate outputs + int fSatSweeping; // enable SAT sweeping + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + int iOutFail; // the failed output +}; + +// combinational equivalence checking parameters +typedef struct Cec_ParCec_t_ Cec_ParCec_t; +struct Cec_ParCec_t_ +{ + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds +// int fFirstStop; // stop on the first sat output + int fUseSmartCnf; // use smart CNF computation + int fRewriting; // enables AIG rewriting + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + int iOutFail; // the number of failed output +}; + +// 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 nPrefix; // the number of time frames in the prefix + int nBTLimit; // conflict limit at a node + int nLevelMax; // (scorr only) the max number of levels + int nStepsMax; // (scorr only) the max number of induction steps + int fLatchCorr; // consider only latch outputs + int fConstCorr; // consider only constants + int fUseRings; // use rings + int fMakeChoices; // use equilvaences as choices + int fUseCSat; // use circuit-based solver +// int fFirstStop; // stop on the first sat output + int fUseSmartCnf; // use smart CNF computation + int fVerboseFlops; // verbose stats + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + // callback + void * pData; + void * pFunc; +}; + +// 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 fUseRings; // use rings + int fUseCSat; // use circuit-based solver + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// sequential synthesis parameters +typedef struct Cec_ParSeq_t_ Cec_ParSeq_t; +struct Cec_ParSeq_t_ +{ + int fUseLcorr; // enables latch correspondence + int fUseScorr; // enables signal correspondence + int nBTLimit; // (scorr/lcorr) conflict limit at a node + int nFrames; // (scorr/lcorr) the number of timeframes + int nLevelMax; // (scorr only) the max number of levels + int fConsts; // (scl only) merging constants + int fEquivs; // (scl only) merging equivalences + int fUseMiniSat; // enables MiniSat in lcorr/scorr + int nMinDomSize; // the size of minimum clock domain + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== 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 int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); +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 ); +/*=== cecSeq.c ==========================================================*/ +extern int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex ); +extern int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ); +extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); +/*=== cecSynth.c ==========================================================*/ +extern int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p ); +extern int Cec_SeqReadVerbose( Cec_ParSeq_t * p ); +extern void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * pPars ); +extern int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c new file mode 100644 index 00000000..1460ba91 --- /dev/null +++ b/src/proof/cec/cecCec.c @@ -0,0 +1,373 @@ +/**CFile**************************************************************** + + FileName [cecCec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Integrated combinatinal equivalence checker.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" +#include "src/proof/fra/fra.h" +#include "src/aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) +{ + int i; + assert( p->pCexComb == NULL ); + p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char, + sizeof(Abc_Cex_t) + sizeof(unsigned) * Abc_BitWordNum(Gia_ManCiNum(p)) ); + p->pCexComb->iPo = iOut; + p->pCexComb->nPis = Gia_ManCiNum(p); + p->pCexComb->nBits = Gia_ManCiNum(p); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + if ( pValues[i] ) + Abc_InfoSetBit( p->pCexComb->pData, i ); +} + +/**Function************************************************************* + + Synopsis [Interface to the old CEC engine] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail ) +{ +// extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); + extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ); + Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter ); + Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp, 0 ); + int RetValue, iOut, nOuts, clkTotal = clock(); + if ( piOutFail ) + *piOutFail = -1; + Gia_ManStop( pTemp ); + // run CEC on this miter + RetValue = Fra_FraigCec( &pMiterCec, 10000000, fVerbose ); + // report the miter + if ( RetValue == 1 ) + { + Abc_Print( 1, "Networks are equivalent. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); + } + else if ( RetValue == 0 ) + { + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); + if ( pMiterCec->pData == NULL ) + Abc_Print( 1, "Counter-example is not available.\n" ); + else + { + iOut = Ssw_SecCexResimulate( pMiterCec, (int *)pMiterCec->pData, &nOuts ); + if ( iOut == -1 ) + Abc_Print( 1, "Counter-example verification has failed.\n" ); + else + { +// Aig_Obj_t * pObj = Aig_ManPo(pMiterCec, iOut); +// Aig_Obj_t * pFan = Aig_ObjFanin0(pObj); + Abc_Print( 1, "Primary output %d has failed", iOut ); + if ( nOuts-1 >= 0 ) + Abc_Print( 1, ", along with other %d incorrect outputs", nOuts-1 ); + Abc_Print( 1, ".\n" ); + if ( piOutFail ) + *piOutFail = iOut; + } + Cec_ManTransformPattern( pMiter, iOut, (int *)pMiterCec->pData ); + } + } + else + { + Abc_Print( 1, "Networks are UNDECIDED. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); + } + fflush( stdout ); + Aig_ManStop( pMiterCec ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars ) +{ + int fDumpUndecided = 0; + Cec_ParFra_t ParsFra, * pParsFra = &ParsFra; + Gia_Man_t * p, * pNew; + int RetValue, clk = clock(); + double clkTotal = clock(); + // preprocess + p = Gia_ManDup( pInit ); + Gia_ManEquivFixOutputPairs( p ); + p = Gia_ManCleanup( pNew = p ); + Gia_ManStop( pNew ); + // sweep for equivalences + Cec_ManFraSetDefaultParams( pParsFra ); + pParsFra->nItersMax = 1000; + pParsFra->nBTLimit = pPars->nBTLimit; + pParsFra->TimeLimit = pPars->TimeLimit; + pParsFra->fVerbose = pPars->fVerbose; + pParsFra->fCheckMiter = 1; + pParsFra->fDualOut = 1; + pNew = Cec_ManSatSweeping( p, pParsFra ); + pPars->iOutFail = pParsFra->iOutFail; + // update + pInit->pCexComb = p->pCexComb; p->pCexComb = NULL; + Gia_ManStop( p ); + p = pInit; + // continue + if ( pNew == NULL ) + { + if ( p->pCexComb != NULL ) + { + if ( p->pCexComb && !Gia_ManVerifyCex( p, p->pCexComb, 1 ) ) + Abc_Print( 1, "Counter-example simulation has failed.\n" ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); + return 0; + } + p = Gia_ManDup( pInit ); + Gia_ManEquivFixOutputPairs( p ); + p = Gia_ManCleanup( pNew = p ); + Gia_ManStop( pNew ); + pNew = p; + } + if ( Gia_ManAndNum(pNew) == 0 ) + { + Gia_Obj_t * pObj1, * pObj2; + int i; + Gia_ManForEachPo( pNew, pObj1, i ) + { + pObj2 = Gia_ManPo( pNew, ++i ); + if ( Gia_ObjChild0(pObj1) != Gia_ObjChild0(pObj2) ) + { + Abc_Print( 1, "Networks are NOT EQUIVALENT. Outputs %d trivially differ. ", i/2 ); + Abc_PrintTime( 1, "Time", clock() - clk ); + Gia_ManStop( pNew ); + pPars->iOutFail = i/2; + return 0; + } + } + Abc_Print( 1, "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); + Gia_ManStop( pNew ); + return 1; + } + if ( pPars->fVerbose ) + { + Abc_Print( 1, "Networks are UNDECIDED after the new CEC engine. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } + if ( fDumpUndecided ) + { + ABC_FREE( pNew->pReprs ); + ABC_FREE( pNew->pNexts ); + Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 ); + Abc_Print( 1, "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" ); + } + if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) + { + Gia_ManStop( pNew ); + return -1; + } + // call other solver + if ( pPars->fVerbose ) + Abc_Print( 1, "Calling the old CEC engine.\n" ); + fflush( stdout ); + RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose, &pPars->iOutFail ); + p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL; + if ( p->pCexComb && !Gia_ManVerifyCex( p, p->pCexComb, 1 ) ) + Abc_Print( 1, "Counter-example simulation has failed.\n" ); + Gia_ManStop( pNew ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + Gia_Man_t * pMiter; + int RetValue; + Cec_ManCecSetDefaultParams( pPars ); + pPars->fVerbose = fVerbose; + pMiter = Gia_ManMiter( p0, p1, 1, 0, pPars->fVerbose ); + if ( pMiter == NULL ) + return -1; + RetValue = Cec_ManVerify( pMiter, pPars ); + p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL; + Gia_ManStop( pMiter ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [New CEC engine applied to two circuits.] + + Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided. + Counter-example is returned in the first manager as pAig0->pSeqModel. + The format is given in Abc_Cex_t (file "abc\src\aig\gia\gia.h").] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose ) +{ + Gia_Man_t * p0, * p1, * pTemp; + int RetValue; + + p0 = Gia_ManFromAig( pAig0 ); + p0 = Gia_ManCleanup( pTemp = p0 ); + Gia_ManStop( pTemp ); + + p1 = Gia_ManFromAig( pAig1 ); + p1 = Gia_ManCleanup( pTemp = p1 ); + Gia_ManStop( pTemp ); + + RetValue = Cec_ManVerifyTwo( p0, p1, fVerbose ); + pAig0->pSeqModel = p0->pCexComb; p0->pCexComb = NULL; + Gia_ManStop( p0 ); + Gia_ManStop( p1 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Implementation of new signal correspodence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Cec_LatchCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat ) +{ + Gia_Man_t * pGia; + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->fLatchCorr = 1; + pCorPars->fUseCSat = fUseCSat; + pCorPars->nBTLimit = nConfs; + pGia = Gia_ManFromAigSimple( pAig ); + Cec_ManLSCorrespondenceClasses( pGia, pCorPars ); + Gia_ManReprToAigRepr( pAig, pGia ); + Gia_ManStop( pGia ); + return Aig_ManDupSimple( pAig ); +} + +/**Function************************************************************* + + Synopsis [Implementation of new signal correspodence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Cec_SignalCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat ) +{ + Gia_Man_t * pGia; + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->fUseCSat = fUseCSat; + pCorPars->nBTLimit = nConfs; + pGia = Gia_ManFromAigSimple( pAig ); + Cec_ManLSCorrespondenceClasses( pGia, pCorPars ); + Gia_ManReprToAigRepr( pAig, pGia ); + Gia_ManStop( pGia ); + return Aig_ManDupSimple( pAig ); +} + +/**Function************************************************************* + + Synopsis [Implementation of fraiging.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Cec_FraigCombinational( Aig_Man_t * pAig, int nConfs, int fVerbose ) +{ + Gia_Man_t * pGia; + Cec_ParFra_t FraPars, * pFraPars = &FraPars; + Cec_ManFraSetDefaultParams( pFraPars ); + pFraPars->fSatSweeping = 1; + pFraPars->nBTLimit = nConfs; + pFraPars->nItersMax = 20; + pFraPars->fVerbose = fVerbose; + pGia = Gia_ManFromAigSimple( pAig ); + Cec_ManSatSweeping( pGia, pFraPars ); + Gia_ManReprToAigRepr( pAig, pGia ); + Gia_ManStop( pGia ); + return Aig_ManDupSimple( pAig ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecChoice.c b/src/proof/cec/cecChoice.c new file mode 100644 index 00000000..3ddb975e --- /dev/null +++ b/src/proof/cec/cecChoice.c @@ -0,0 +1,409 @@ +/**CFile**************************************************************** + + FileName [cecChoice.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational 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" +#include "src/aig/gia/giaAig.h" +#include "src/proof/dch/dch.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Cec_ManCombSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ); + +extern int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore ); +extern int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes the real value of the literal w/o spec reduction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cec_ManCombSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + assert( Gia_ObjIsAnd(pObj) ); + Cec_ManCombSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Cec_ManCombSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Recursively performs speculative reduction for the object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManCombSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr; + if ( ~pObj->Value ) + return; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + Cec_ManCombSpecReduce_rec( pNew, p, pRepr ); + pObj->Value = Abc_LitNotCond( pRepr->Value, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + return; + } + pObj->Value = Cec_ManCombSpecReal( pNew, p, pObj ); +} + +/**Function************************************************************* + + Synopsis [Derives SRM for signal correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManCombSpecReduce( Gia_Man_t * p, Vec_Int_t ** pvOutputs, int fRings ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + Vec_Int_t * vXorLits; + int i, iPrev, iObj, iPrevNew, iObjNew; + assert( p->pReprs != NULL ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + *pvOutputs = Vec_IntAlloc( 1000 ); + vXorLits = Vec_IntAlloc( 1000 ); + if ( fRings ) + { + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsConst( p, i ) ) + { + iObjNew = Cec_ManCombSpecReal( pNew, p, pObj ); + iObjNew = Abc_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 ) + { + iPrevNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iPrev) ); + iObjNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iObj) ); + iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Abc_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, Abc_LitNot(iObjNew)) ); + } + iPrev = iObj; + } + iObj = i; + iPrevNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iPrev) ); + iObjNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iObj) ); + iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Abc_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, Abc_LitNot(iObjNew)) ); + } + } + } + } + else + { + Gia_ManForEachObj1( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Cec_ManCombSpecReal( pNew, p, pRepr ); + iObjNew = Cec_ManCombSpecReal( pNew, p, pObj ); + iObjNew = Abc_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_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); + pNew = Gia_ManCleanup( pTemp = pNew ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) +{ + int nItersMax = 1000; + Vec_Str_t * vStatus; + Vec_Int_t * vOutputs; + Vec_Int_t * vCexStore; + 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 ); + Gia_ManRandom( 1 ); + // prepare simulation manager + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nFrames = pPars->nRounds; + pParsSim->fVerbose = pPars->fVerbose; + pParsSim->fLatchCorr = 0; + pParsSim->fSeqSimulate = 0; + // create equivalence classes of registers + pSim = Cec_ManSimStart( pAig, pParsSim ); + Cec_ManSimClassesPrepare( pSim, -1 ); + Cec_ManSimClassesRefine( pSim ); + // prepare SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVerbose; + if ( pPars->fVerbose ) + { + Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Ring = %d. CSat = %d.\n", + Gia_ManObjNum(pAig), Gia_ManAndNum(pAig), pPars->nBTLimit, pPars->fUseRings, pPars->fUseCSat ); + Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk ); + } + // perform refinement of equivalence classes + for ( r = 0; r < nItersMax; r++ ) + { + clk = clock(); + // perform speculative reduction + clk2 = clock(); + pSrm = Cec_ManCombSpecReduce( pAig, &vOutputs, pPars->fUseRings ); + assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManCiNum(pSrm) == Gia_ManCiNum(pAig) ); + clkSrm += clock() - clk2; + if ( Gia_ManCoNum(pSrm) == 0 ) + { + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk ); + Vec_IntFree( vOutputs ); + Gia_ManStop( pSrm ); + break; + } +//Gia_DumpAiger( pSrm, "choicesrm", r, 2 ); + // found counter-examples to speculation + clk2 = clock(); + if ( pPars->fUseCSat ) + vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); + else + vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); + Gia_ManStop( pSrm ); + clkSat += clock() - clk2; + if ( Vec_IntSize(vCexStore) == 0 ) + { + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk ); + Vec_IntFree( vCexStore ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); + break; + } + // refine classes with these counter-examples + clk2 = clock(); + RetValue = Cec_ManResimulateCounterExamplesComb( pSim, vCexStore ); + Vec_IntFree( vCexStore ); + clkSim += clock() - clk2; + Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); +//Gia_ManEquivPrintClasses( pAig, 1, 0 ); + } + // check the overflow + if ( r == nItersMax ) + Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" ); + Cec_ManSimStop( pSim ); + clkTotal = clock() - clkTotal; + // report the results + if ( pPars->fVerbose ) + { + Abc_PrintTimeP( 1, "Srm ", clkSrm, clkTotal ); + Abc_PrintTimeP( 1, "Sat ", clkSat, clkTotal ); + Abc_PrintTimeP( 1, "Sim ", clkSim, clkTotal ); + Abc_PrintTimeP( 1, "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); + Abc_PrintTime( 1, "TOTAL", clkTotal ); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Computes choices for the vector of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManChoiceComputationVec( Gia_Man_t * pGia, int nGias, Cec_ParChc_t * pPars ) +{ + Gia_Man_t * pNew; + int RetValue; + // compute equivalences of the miter +// pMiter = Gia_ManChoiceMiter( vGias ); +// Gia_ManSetRegNum( pMiter, 0 ); + RetValue = Cec_ManChoiceComputation_int( pGia, pPars ); + // derive AIG with choices + pNew = Gia_ManEquivToChoices( pGia, nGias ); + Gia_ManHasChoices( pNew ); +// Gia_ManStop( pMiter ); + // report the results + if ( pPars->fVerbose ) + { +// Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", +// Gia_ManAndNum(pAig), Gia_ManAndNum(pNew), +// 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), +// Gia_ManRegNum(pAig), Gia_ManRegNum(pNew), +// 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Computes choices for one AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pParsChc ) +{ +// extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); + Dch_Pars_t Pars, * pPars = &Pars; + Aig_Man_t * pMan, * pManNew; + Gia_Man_t * pGia; + if ( 0 ) + { + pGia = Cec_ManChoiceComputationVec( pAig, 3, pParsChc ); + } + else + { + pMan = Gia_ManToAig( pAig, 0 ); + Dch_ManSetDefaultParams( pPars ); + pPars->fUseGia = 1; + pPars->nBTLimit = pParsChc->nBTLimit; + pPars->fUseCSat = pParsChc->fUseCSat; + pPars->fVerbose = pParsChc->fVerbose; + pManNew = Dar_ManChoiceNew( pMan, pPars ); + pGia = Gia_ManFromAig( pManNew ); + Aig_ManStop( pManNew ); +// Aig_ManStop( pMan ); + } + return pGia; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [Takes several AIGs and performs choicing.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars ) +{ + Cec_ParChc_t ParsChc, * pParsChc = &ParsChc; + Aig_Man_t * pAig; + if ( pPars->fVerbose ) + Abc_PrintTime( 1, "Synthesis time", pPars->timeSynth ); + Cec_ManChcSetDefaultParams( pParsChc ); + pParsChc->nBTLimit = pPars->nBTLimit; + pParsChc->fUseCSat = pPars->fUseCSat; + if ( pParsChc->fUseCSat && pParsChc->nBTLimit > 100 ) + pParsChc->nBTLimit = 100; + pParsChc->fVerbose = pPars->fVerbose; + pGia = Cec_ManChoiceComputationVec( pGia, 3, pParsChc ); + Gia_ManSetRegNum( pGia, Gia_ManRegNum(pGia) ); + pAig = Gia_ManToAig( pGia, 1 ); + Gia_ManStop( pGia ); + return pAig; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecClass.c b/src/proof/cec/cecClass.c new file mode 100644 index 00000000..46e585a9 --- /dev/null +++ b/src/proof/cec/cecClass.c @@ -0,0 +1,931 @@ +/**CFile**************************************************************** + + FileName [cecClass.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Equivalence class refinement.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; } +static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; } + +static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Compares simulation info of one node with constant 0.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimCompareConst( unsigned * p, int nWords ) +{ + int w; + if ( p[0] & 1 ) + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != ~0 ) + return 0; + return 1; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != 0 ) + return 0; + return 1; + } +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords ) +{ + int w; + if ( (p0[0] & 1) == (p1[0] & 1) ) + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != p1[w] ) + return 0; + return 1; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != ~p1[w] ) + return 0; + return 1; + } +} + +/**Function************************************************************* + + Synopsis [Returns the number of the first non-equal bit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords ) +{ + int w; + if ( p[0] & 1 ) + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != ~0 ) + return 32*w + Gia_WordFindFirstBit( ~p[w] ); + return -1; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != 0 ) + return 32*w + Gia_WordFindFirstBit( p[w] ); + return -1; + } +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords ) +{ + int w; + if ( (p0[0] & 1) == (p1[0] & 1) ) + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != p1[w] ) + return 32*w + Gia_WordFindFirstBit( p0[w] ^ p1[w] ); + return -1; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != ~p1[w] ) + return 32*w + Gia_WordFindFirstBit( p0[w] ^ ~p1[w] ); + return -1; + } +} + +/**Function************************************************************* + + Synopsis [Returns the number of the first non-equal bit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimCompareConstScore( unsigned * p, int nWords, int * pScores ) +{ + int w, b; + if ( p[0] & 1 ) + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != ~0 ) + for ( b = 0; b < 32; b++ ) + if ( ((~p[w]) >> b ) & 1 ) + pScores[32*w + b]++; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p[w] != 0 ) + for ( b = 0; b < 32; b++ ) + if ( ((p[w]) >> b ) & 1 ) + pScores[32*w + b]++; + } +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimCompareEqualScore( unsigned * p0, unsigned * p1, int nWords, int * pScores ) +{ + int w, b; + if ( (p0[0] & 1) == (p1[0] & 1) ) + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != p1[w] ) + for ( b = 0; b < 32; b++ ) + if ( ((p0[w] ^ p1[w]) >> b ) & 1 ) + pScores[32*w + b]++; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( p0[w] != ~p1[w] ) + for ( b = 0; b < 32; b++ ) + if ( ((p0[w] ^ ~p1[w]) >> b ) & 1 ) + pScores[32*w + b]++; + } +} + +/**Function************************************************************* + + Synopsis [Creates equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass ) +{ + int Repr = GIA_VOID, EntPrev = -1, Ent, i; + assert( Vec_IntSize(vClass) > 0 ); + Vec_IntForEachEntry( vClass, Ent, i ) + { + if ( i == 0 ) + { + Repr = Ent; + Gia_ObjSetRepr( p, Ent, GIA_VOID ); + EntPrev = Ent; + } + else + { + assert( Repr < Ent ); + Gia_ObjSetRepr( p, Ent, Repr ); + Gia_ObjSetNext( p, EntPrev, Ent ); + EntPrev = Ent; + } + } + Gia_ObjSetNext( p, EntPrev, 0 ); +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i ) +{ + unsigned * pSim0, * pSim1; + int Ent; + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Vec_IntPush( p->vClassOld, i ); + pSim0 = Cec_ObjSim(p, i); + Gia_ClassForEachObj1( p->pAig, i, Ent ) + { + pSim1 = Cec_ObjSim(p, Ent); + if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) ) + Vec_IntPush( p->vClassOld, Ent ); + else + { + Vec_IntPush( p->vClassNew, Ent ); + if ( p->pBestState ) + Cec_ManSimCompareEqualScore( pSim0, pSim1, p->nWords, p->pScores ); + } + } + if ( Vec_IntSize( p->vClassNew ) == 0 ) + return 0; + Cec_ManSimClassCreate( p->pAig, p->vClassOld ); + Cec_ManSimClassCreate( p->pAig, p->vClassNew ); + if ( Vec_IntSize(p->vClassNew) > 1 ) + return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); + return 1; +} + +/**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 [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0; + int i; + if ( pSim[0] & 1 ) + for ( i = 0; i < nWords; i++ ) + uHash ^= ~pSim[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nWords; i++ ) + uHash ^= pSim[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Resets pointers to the simulation memory.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimMemRelink( Cec_ManSim_t * p ) +{ + unsigned * pPlace, Ent; + pPlace = (unsigned *)&p->MemFree; + for ( Ent = p->nMems * (p->nWords + 1); + Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc; + Ent += p->nWords + 1 ) + { + *pPlace = Ent; + pPlace = p->pMems + Ent; + } + *pPlace = 0; + p->nWordsOld = p->nWords; +} + +/**Function************************************************************* + + Synopsis [References simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i ) +{ + unsigned * pSim; + assert( p->pSimInfo[i] == 0 ); + if ( p->MemFree == 0 ) + { + if ( p->nWordsAlloc == 0 ) + { + assert( p->pMems == NULL ); + p->nWordsAlloc = (1<<17); // -> 1Mb + p->nMems = 1; + } + p->nWordsAlloc *= 2; + p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc ); + Cec_ManSimMemRelink( p ); + } + p->pSimInfo[i] = p->MemFree; + pSim = p->pMems + p->MemFree; + p->MemFree = pSim[0]; + pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) ); + p->nMems++; + if ( p->nMemsMax < p->nMems ) + p->nMemsMax = p->nMems; + return pSim; +} + +/**Function************************************************************* + + Synopsis [Dereferences simulaton info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i ) +{ + unsigned * pSim; + assert( p->pSimInfo[i] > 0 ); + pSim = p->pMems + p->pSimInfo[i]; + if ( --pSim[0] == 0 ) + { + pSim[0] = p->MemFree; + p->MemFree = p->pSimInfo[i]; + p->pSimInfo[i] = 0; + p->nMems--; + } + return pSim; +} + +/**Function************************************************************* + + Synopsis [Refines nodes belonging to candidate constant class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined ) +{ + unsigned * pSim; + int * pTable, nTableSize, i, k, Key; + if ( Vec_IntSize(vRefined) == 0 ) + return; + nTableSize = Abc_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 ); + pTable = ABC_CALLOC( int, nTableSize ); + Vec_IntForEachEntry( vRefined, i, k ) + { + pSim = Cec_ObjSim( p, i ); + assert( !Cec_ManSimCompareConst( pSim, p->nWords ) ); + Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize ); + if ( pTable[Key] == 0 ) + { + assert( Gia_ObjRepr(p->pAig, i) == 0 ); + assert( Gia_ObjNext(p->pAig, i) == 0 ); + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); + } + else + { + Gia_ObjSetNext( p->pAig, pTable[Key], i ); + Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pAig, i, pTable[Key] ); + assert( Gia_ObjRepr(p->pAig, i) > 0 ); + } + pTable[Key] = i; + } + Vec_IntForEachEntry( vRefined, i, k ) + { + if ( Gia_ObjIsHead( p->pAig, i ) ) + Cec_ManSimClassRefineOne( p, i ); + } + Vec_IntForEachEntry( vRefined, i, k ) + Cec_ManSimSimDeref( p, i ); + ABC_FREE( pTable ); +} + + +/**Function************************************************************* + + Synopsis [Saves the input pattern with the given number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat ) +{ + unsigned * pInfo; + int i; + assert( p->pCexComb == NULL ); + assert( iPat >= 0 && iPat < 32 * p->nWords ); + p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char, + sizeof(Abc_Cex_t) + sizeof(unsigned) * Abc_BitWordNum(Gia_ManCiNum(p->pAig)) ); + p->pCexComb->iPo = p->iOut; + p->pCexComb->nPis = Gia_ManCiNum(p->pAig); + p->pCexComb->nBits = Gia_ManCiNum(p->pAig); + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i ); + if ( Abc_InfoHasBit( pInfo, iPat ) ) + Abc_InfoSetBit( p->pCexComb->pData, i ); + } +} + +/**Function************************************************************* + + Synopsis [Find the best pattern using the scores.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimFindBestPattern( Cec_ManSim_t * p ) +{ + unsigned * pInfo; + int i, ScoreBest = 0, iPatBest = 1; // set the first pattern + // find the best pattern + for ( i = 0; i < 32 * p->nWords; i++ ) + if ( ScoreBest < p->pScores[i] ) + { + ScoreBest = p->pScores[i]; + iPatBest = i; + } + // compare this with the available patterns - and save + if ( p->pBestState->iPo <= ScoreBest ) + { + assert( p->pBestState->nRegs == Gia_ManRegNum(p->pAig) ); + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); + if ( Abc_InfoHasBit(p->pBestState->pData, i) != Abc_InfoHasBit(pInfo, iPatBest) ) + Abc_InfoXorBit( p->pBestState->pData, i ); + } + p->pBestState->iPo = ScoreBest; + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if computation should stop.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p ) +{ + unsigned * pInfo, * pInfo2; + int i; + if ( !p->pPars->fCheckMiter ) + return 0; + assert( p->vCoSimInfo != NULL ); + // compare outputs with 0 + if ( p->pPars->fDualOut ) + { + assert( (Gia_ManPoNum(p->pAig) & 1) == 0 ); + for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i ); + pInfo2 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, ++i ); + if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i/2; + Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig)/2 ); + if ( p->pCexes[i/2] == NULL ) + { + p->nOuts++; + p->pCexes[i/2] = (void *)1; + } + } + } + } + else + { + for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i ); + if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) ) + { + if ( p->iOut == -1 ) + { + p->iOut = i; + Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) ); + } + if ( p->pCexes == NULL ) + p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig) ); + if ( p->pCexes[i] == NULL ) + { + p->nOuts++; + p->pCexes[i] = (void *)1; + } + } + } + } + return p->pCexes != NULL; +} + +/**Function************************************************************* + + Synopsis [Simulates one round.] + + Description [Returns the number of PO entry if failed; 0 otherwise.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) +{ + Gia_Obj_t * pObj; + unsigned * pRes0, * pRes1, * pRes; + int i, k, w, Ent, iCiId = 0, iCoId = 0; + // prepare internal storage + if ( p->nWordsOld != p->nWords ) + Cec_ManSimMemRelink( p ); + p->nMemsMax = 0; + // allocate score counters + ABC_FREE( p->pScores ); + if ( p->pBestState ) + p->pScores = ABC_CALLOC( int, 32 * p->nWords ); + // simulate nodes + Vec_IntClear( p->vRefinedC ); + if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) ) + { + pRes = Cec_ManSimSimRef( p, 0 ); + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = 0; + } + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + if ( Gia_ObjValue(pObj) == 0 ) + { + iCiId++; + continue; + } + pRes = Cec_ManSimSimRef( p, i ); + if ( vInfoCis ) + { + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, iCiId++ ); + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = pRes0[w-1]; + } + else + { + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = Gia_ManRandom( 0 ); + } + // make sure the first pattern is always zero + pRes[1] ^= (pRes[1] & 1); + goto references; + } + if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin + { + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + if ( vInfoCos ) + { + pRes = (unsigned *)Vec_PtrEntry( vInfoCos, iCoId++ ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 1; w <= p->nWords; w++ ) + pRes[w-1] = ~pRes0[w]; + else + for ( w = 1; w <= p->nWords; w++ ) + pRes[w-1] = pRes0[w]; + } + continue; + } + assert( Gia_ObjValue(pObj) ); + pRes = Cec_ManSimSimRef( p, i ); + pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); + pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) ); + +// Abc_Print( 1, "%d,%d ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) ); + + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = ~(pRes0[w] | pRes1[w]); + else + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = ~pRes0[w] & pRes1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = pRes0[w] & ~pRes1[w]; + else + for ( w = 1; w <= p->nWords; w++ ) + pRes[w] = pRes0[w] & pRes1[w]; + } + +references: + // if this node is candidate constant, collect it + if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) ) + { + pRes[0]++; + Vec_IntPush( p->vRefinedC, i ); + if ( p->pBestState ) + Cec_ManSimCompareConstScore( pRes + 1, p->nWords, p->pScores ); + } + // if the node belongs to a class, save it + if ( Gia_ObjIsClass(p->pAig, i) ) + pRes[0]++; + // if this is the last node of the class, process it + if ( Gia_ObjIsTail(p->pAig, i) ) + { + Vec_IntClear( p->vClassTemp ); + Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent ) + Vec_IntPush( p->vClassTemp, Ent ); + Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) ); + Vec_IntForEachEntry( p->vClassTemp, Ent, k ) + Cec_ManSimSimDeref( p, Ent ); + } + } + + if ( p->pPars->fConstCorr ) + { + Vec_IntForEachEntry( p->vRefinedC, i, k ) + { + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); + Cec_ManSimSimDeref( p, i ); + } + Vec_IntClear( p->vRefinedC ); + } + + if ( Vec_IntSize(p->vRefinedC) > 0 ) + Cec_ManSimProcessRefined( p, p->vRefinedC ); + assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) ); + assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) ); + assert( p->nMems == 1 ); + if ( p->nMems != 1 ) + Abc_Print( 1, "Cec_ManSimSimulateRound(): Memory management error!\n" ); + if ( p->pPars->fVeryVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + if ( p->pBestState ) + Cec_ManSimFindBestPattern( p ); +/* + if ( p->nMems > 1 ) { + for ( i = 1; i < p->nObjs; i++ ) + if ( p->pSims[i] ) { + int x = 0; + } + } +*/ + return Cec_ManSimAnalyzeOutputs( p ); +} + + + +/**Function************************************************************* + + Synopsis [Creates simulation info for this round.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ) +{ + unsigned * pRes0, * pRes1; + int i, w; + if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 ) + { + assert( vInfoCis && vInfoCos ); + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Gia_ManRandom( 0 ); + } + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i ); + pRes1 = (unsigned *)Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } + } + else + { + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i ); + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = Gia_ManRandom( 0 ); + } + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the bug is found.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pAig->pReprs == NULL ); + // allocate representation + p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) ); + p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + // create references + Gia_ManSetRefs( p->pAig ); + // set starting representative of internal nodes to be constant 0 + if ( p->pPars->fLatchCorr ) + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); + else if ( LevelMax == -1 ) + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); + else + { + Gia_ManLevelNum( p->pAig ); + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) && Gia_ObjLevel(p->pAig,pObj) <= LevelMax) ? 0 : GIA_VOID ); + Vec_IntFreeP( &p->pAig->vLevels ); + } + // if sequential simulation, set starting representative of ROs to be constant 0 + if ( p->pPars->fSeqSimulate ) + Gia_ManForEachRo( p->pAig, pObj, i ) + if ( pObj->Value ) + Gia_ObjSetRepr( p->pAig, Gia_ObjId(p->pAig, pObj), 0 ); + // perform simulation + p->nWords = 1; + do { + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + for ( i = 0; i < 4; i++ ) + { + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; + } + p->nWords = 2 * p->nWords + 1; + } + while ( p->nWords <= p->pPars->nWords ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the bug is found.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimClassesRefine( Cec_ManSim_t * p ) +{ + int i; + Gia_ManSetRefs( p->pAig ); + p->nWords = p->pPars->nWords; + for ( i = 0; i < p->pPars->nRounds; i++ ) + { + if ( (i % (p->pPars->nRounds / 5)) == 0 && p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo ); + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; + } + if ( p->pPars->fVerbose ) + Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); + return 0; +} +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecCore.c b/src/proof/cec/cecCore.c new file mode 100644 index 00000000..bf41304b --- /dev/null +++ b/src/proof/cec/cecCore.c @@ -0,0 +1,542 @@ +/**CFile**************************************************************** + + FileName [cecCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSat_t) ); + p->nBTLimit = 100; // conflict limit at a node + p->nSatVarMax = 2000; // the max number of SAT variables + p->nCallsRecycle = 200; // calls to perform before recycling SAT solver + p->fNonChrono = 0; // use non-chronological backtracling (for circuit SAT only) + p->fPolarFlip = 1; // flops polarity of variables + p->fCheckMiter = 0; // the circuit is the miter +// p->fFirstStop = 0; // stop on the first sat output + p->fLearnCls = 0; // perform clause learning + p->fVerbose = 0; // verbose stats +} + +/**Function************ ************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSim_t) ); + p->nWords = 31; // the number of simulation words + p->nFrames = 100; // the number of simulation frames + p->nRounds = 20; // the max number of simulation rounds + p->nNonRefines = 3; // the max number of rounds without refinement + p->TimeLimit = 0; // the runtime limit in seconds + p->fCheckMiter = 0; // the circuit is the miter +// p->fFirstStop = 0; // stop on the first sat output + p->fDualOut = 0; // miter with separate outputs + p->fConstCorr = 0; // consider only constants + p->fSeqSimulate = 0; // performs sequential simulation + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************ ************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSmfSetDefaultParams( Cec_ParSmf_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSmf_t) ); + p->nWords = 31; // the number of simulation words + p->nRounds = 200; // the number of simulation rounds + p->nFrames = 200; // the max number of time frames + p->nNonRefines = 3; // the max number of rounds without refinement + p->nMinOutputs = 0; // the min outputs to accumulate + p->nBTLimit = 100; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fDualOut = 0; // miter with separate outputs + p->fCheckMiter = 0; // the circuit is the miter +// p->fFirstStop = 0; // stop on the first sat output + p->fVerbose = 0; // verbose stats +} + +/**Function************ ************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ) +{ + memset( p, 0, sizeof(Cec_ParFra_t) ); + p->nWords = 15; // the number of simulation words + p->nRounds = 15; // the number of simulation rounds + p->TimeLimit = 0; // the runtime limit in seconds + p->nItersMax = 10; // the maximum number of iterations of SAT sweeping + p->nBTLimit = 100; // conflict limit at a node + p->nLevelMax = 0; // restriction on the level of nodes to be swept + p->nDepthMax = 1; // the depth in terms of steps of speculative reduction + p->fRewriting = 0; // enables AIG rewriting + p->fCheckMiter = 0; // the circuit is the miter +// p->fFirstStop = 0; // stop on the first sat output + p->fDualOut = 0; // miter with separate outputs + p->fColorDiff = 0; // miter with separate outputs + p->fSatSweeping = 0; // enable SAT sweeping + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the failed output +} + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ) +{ + memset( p, 0, sizeof(Cec_ParCec_t) ); + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds +// p->fFirstStop = 0; // stop on the first sat output + p->fUseSmartCnf = 0; // use smart CNF computation + p->fRewriting = 0; // enables AIG rewriting + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the number of failed output +} + +/**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->nLevelMax = -1; // (scorr only) the max number of levels + p->nStepsMax = -1; // (scorr only) the max number of induction steps + p->fLatchCorr = 0; // consider only latch outputs + p->fConstCorr = 0; // consider only constants + 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->fUseRings = 1; // use rings + p->fUseCSat = 0; // use circuit-based solver + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + + Synopsis [Core procedure for SAT sweeping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) +{ + Gia_Man_t * pNew; + Cec_ManPat_t * pPat; + pPat = Cec_ManPatStart(); + Cec_ManSatSolve( pPat, pAig, pPars ); +// pNew = Gia_ManDupDfsSkip( pAig ); + pNew = Gia_ManDup( pAig ); + Cec_ManPatStop( pPat ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Core procedure for simulation.] + + Description [Returns 1 if refinement has happened.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSimulationOne( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * pSim; + int RetValue = 0, clkTotal = clock(); + pSim = Cec_ManSimStart( pAig, pPars ); + if ( (pAig->pReprs == NULL && (RetValue = Cec_ManSimClassesPrepare( pSim, -1 ))) || + (RetValue == 0 && (RetValue = Cec_ManSimClassesRefine( pSim ))) ) + Abc_Print( 1, "The number of failed outputs of the miter = %6d. (Words = %4d. Frames = %4d.)\n", + pSim->nOuts, pPars->nWords, pPars->nFrames ); + if ( pPars->fVerbose ) + Abc_PrintTime( 1, "Time", clock() - clkTotal ); + Cec_ManSimStop( pSim ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Core procedure for simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + int r, nLitsOld, nLitsNew, nCountNoRef = 0, fStop = 0; + Gia_ManRandom( 1 ); + if ( pPars->fSeqSimulate ) + Abc_Print( 1, "Performing rounds of random simulation of %d frames with %d words.\n", + pPars->nRounds, pPars->nFrames, pPars->nWords ); + nLitsOld = Gia_ManEquivCountLits( pAig ); + for ( r = 0; r < pPars->nRounds; r++ ) + { + if ( Cec_ManSimulationOne( pAig, pPars ) ) + { + fStop = 1; + break; + } + // decide when to stop + nLitsNew = Gia_ManEquivCountLits( pAig ); + if ( nLitsOld == 0 || nLitsOld > nLitsNew ) + { + nLitsOld = nLitsNew; + nCountNoRef = 0; + } + else if ( ++nCountNoRef == pPars->nNonRefines ) + { + r++; + break; + } + assert( nLitsOld == nLitsNew ); + } +// if ( pPars->fVerbose ) + if ( r == pPars->nRounds || fStop ) + Abc_Print( 1, "Random simulation is stopped after %d rounds.\n", r ); + else + Abc_Print( 1, "Random simulation saturated after %d rounds.\n", r ); + if ( pPars->fCheckMiter ) + { + int nNonConsts = Cec_ManCountNonConstOutputs( pAig ); + if ( nNonConsts ) + Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); + } +} + +/**Function************************************************************* + + Synopsis [Core procedure for SAT sweeping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) +{ + int fOutputResult = 0; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Gia_Man_t * pIni, * pSrm, * pTemp; + Cec_ManFra_t * p; + Cec_ManSim_t * pSim; + Cec_ManPat_t * pPat; + int i, fTimeOut = 0, nMatches = 0, clk, clk2; + double clkTotal = clock(); + + // duplicate AIG and transfer equivalence classes + Gia_ManRandom( 1 ); + pIni = Gia_ManDup(pAig); + pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL; + pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL; + + // prepare the managers + // SAT sweeping + p = Cec_ManFraStart( pIni, pPars ); + if ( pPars->fDualOut ) + pPars->fColorDiff = 1; + // simulation + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nFrames = pPars->nRounds; + pParsSim->fCheckMiter = pPars->fCheckMiter; + pParsSim->fDualOut = pPars->fDualOut; + pParsSim->fVerbose = pPars->fVerbose; + pSim = Cec_ManSimStart( p->pAig, pParsSim ); + // SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVeryVerbose; + // simulation patterns + pPat = Cec_ManPatStart(); + pPat->fVerbose = pPars->fVeryVerbose; + + // start equivalence classes +clk = clock(); + if ( p->pAig->pReprs == NULL ) + { + if ( Cec_ManSimClassesPrepare(pSim, -1) || Cec_ManSimClassesRefine(pSim) ) + { + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + } +p->timeSim += clock() - clk; + // perform solving + for ( i = 1; i <= pPars->nItersMax; i++ ) + { + clk2 = clock(); + nMatches = 0; + if ( pPars->fDualOut ) + { + nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose ); +// p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig ); +// Gia_ManEquivTransform( p->pAig, 1 ); + } + pSrm = Cec_ManFraSpecReduction( p ); + +// Gia_WriteAiger( pSrm, "gia_srm.aig", 0, 0 ); + + if ( pPars->fVeryVerbose ) + Gia_ManPrintStats( pSrm, 0 ); + if ( Gia_ManCoNum(pSrm) == 0 ) + { + Gia_ManStop( pSrm ); + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Considered all available candidate equivalences.\n" ); + if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) > 0 ) + { + if ( pPars->fColorDiff ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } + else + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Switching into normal mode.\n" ); + pPars->fDualOut = 0; + } + continue; + } + break; + } +clk = clock(); + Cec_ManSatSolve( pPat, pSrm, pParsSat ); +p->timeSat += clock() - clk; + if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) ) + { + Gia_ManStop( pSrm ); + Gia_ManStop( p->pAig ); + p->pAig = NULL; + goto finalize; + } + Gia_ManStop( pSrm ); + + // update the manager + pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDualOut ); + if ( p->pAig == NULL ) + { + p->pAig = pTemp; + break; + } + Gia_ManStop( pTemp ); + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", + i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) ); + Abc_PrintTime( 1, "Time", clock() - clk2 ); + } + if ( Gia_ManAndNum(p->pAig) == 0 ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Network after reduction is empty.\n" ); + break; + } + // check resource limits + if ( p->pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit ) + { + fTimeOut = 1; + break; + } +// if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved ) + if ( p->nAllFailed > p->nAllProved + p->nAllDisproved ) + { + if ( pParsSat->nBTLimit >= 10001 ) + break; + if ( pPars->fSatSweeping ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Exceeded the limit on the number of conflicts (%d).\n", pParsSat->nBTLimit ); + break; + } + pParsSat->nBTLimit *= 10; + if ( p->pPars->fVerbose ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Increasing conflict limit to %d.\n", pParsSat->nBTLimit ); + if ( fOutputResult ) + { + Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 ); + Abc_Print( 1,"The result is written into file \"%s\".\n", "gia_cec_temp.aig" ); + } + } + } + if ( pPars->fDualOut && pPars->fColorDiff && (Gia_ManAndNum(p->pAig) < 100000 || p->nAllProved + p->nAllDisproved < 10) ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Switching into reduced mode.\n" ); + pPars->fColorDiff = 0; + } +// if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) < 20000 ) + else if ( pPars->fDualOut && (Gia_ManAndNum(p->pAig) < 20000 || p->nAllProved + p->nAllDisproved < 10) ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Switching into normal mode.\n" ); + pPars->fColorDiff = 0; + pPars->fDualOut = 0; + } + } +finalize: + if ( p->pPars->fVerbose && p->pAig ) + { + Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + Gia_ManAndNum(pAig), Gia_ManAndNum(p->pAig), + 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(p->pAig))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), + Gia_ManRegNum(pAig), Gia_ManRegNum(p->pAig), + 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(p->pAig))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); + Abc_PrintTimeP( 1, "Sim ", p->timeSim, clock() - (int)clkTotal ); + Abc_PrintTimeP( 1, "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal ); + Abc_PrintTimeP( 1, "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal ); + Abc_PrintTime( 1, "Time", (int)(clock() - clkTotal) ); + } + + pTemp = p->pAig; p->pAig = NULL; + if ( pTemp == NULL && pSim->iOut >= 0 ) + { + Abc_Print( 1, "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut ); + pPars->iOutFail = pSim->iOut; + } + else if ( pSim->pCexes ) + Abc_Print( 1, "Disproved %d outputs of the miter.\n", pSim->nOuts ); + if ( fTimeOut ) + Abc_Print( 1, "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC ); + + pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL; + Cec_ManSimStop( pSim ); + Cec_ManPatStop( pPat ); + Cec_ManFraStop( p ); + return pTemp; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c new file mode 100644 index 00000000..6f3ce785 --- /dev/null +++ b/src/proof/cec/cecCorr.c @@ -0,0 +1,1137 @@ +/**CFile**************************************************************** + + FileName [cecCorr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Latch/signal correspondence computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix ); + +//////////////////////////////////////////////////////////////////////// +/// 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, int nPrefix ) +{ + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f, nPrefix ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f, nPrefix ); + return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) ); + } + if ( f == 0 ) + { + assert( Gia_ObjIsRo(p, pObj) ); + return Gia_ObjCopyF(p, f, pObj); + } + assert( f && Gia_ObjIsRo(p, pObj) ); + pObj = Gia_ObjRoToRi( p, pObj ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1, nPrefix ); + 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, int nPrefix ) +{ + Gia_Obj_t * pRepr; + int iLitNew; + if ( ~Gia_ObjCopyF(p, f, pObj) ) + return; + if ( f >= nPrefix && (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f, nPrefix ); + iLitNew = Abc_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, nPrefix ); + 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 = Abc_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))) ) + 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 ) ) + { + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 ); + iObjNew = Abc_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 ) + { + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 ); + iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Abc_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, Abc_LitNot(iObjNew)) ); + } + iPrev = iObj; + } + iObj = i; + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 ); + iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); + iObjNew = Abc_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, Abc_LitNot(iObjNew)) ); + } + } + } + } + else + { + Gia_ManForEachObj1( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 ); + iObjNew = Abc_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 ); +//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); + pNew = Gia_ManCleanup( pTemp = pNew ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Derives SRM for signal correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix, 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, iPrevNew, iObjNew; + assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix ); + assert( Gia_ManRegNum(p) > 0 ); + assert( p->pReprs != NULL ); + p->pCopies = ABC_FALLOC( int, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p) ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( (nFrames+nPrefix) * Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachRo( p, pObj, i ) + { + Gia_ManAppendCi(pNew); + Gia_ObjSetCopyF( p, 0, pObj, 0 ); + } + for ( f = 0; f < nFrames+nPrefix+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 ); + for ( f = nPrefix; f < nFrames+nPrefix; f++ ) + { + Gia_ManForEachObj1( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, f, nPrefix ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix ); + iObjNew = Abc_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 ); +//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); + pNew = Gia_ManCleanup( pTemp = pNew ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Initializes simulation info for lcorr/scorr counter-examples.] + + 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 = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Gia_ManRandom( 0 ); + } +} + +/**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 = (unsigned *)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) ); +// Abc_Print( 1, "%d -> %d ", i, Gia_ObjId(p, pRepr) ); + // transfer info from the representative + pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); + for ( w = 0; w < nWords; w++ ) + pInfoObj[w] = pInfoRepr[w]; + } +// Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Collects information about remapping.] + + 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) ); +// Abc_Print( 1, "%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 = (unsigned *)Vec_PtrEntry( vInfo, iObj ); + pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, iRepr ); + for ( w = 0; w < nWords; w++ ) + { + assert( pInfoObj[w] == 0 ); + pInfoObj[w] = pInfoRepr[w]; + } + } +} + +/**Function************************************************************* + + Synopsis [Packs one counter-examples into the 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 = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); + if ( Abc_InfoHasBit( pPres, iBit ) && + Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); + Abc_InfoSetBit( pPres, iBit ); + if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) + Abc_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Performs bitpacking of counter-examples.] + + 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++ ) ); + // add pattern to storage + for ( k = 1; k < nBits; k++ ) + if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) + break; + kMax = Abc_MaxInt( kMax, k ); + if ( k == nBits-1 ) + break; + } + Vec_PtrFree( vPres ); + Vec_IntFree( vPat ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [Performs bitpacking of counter-examples.] + + 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++ ); +// Abc_Print( 1, "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 = (unsigned *)Vec_PtrEntry( vInfo, Abc_Lit2Var(iLit) ); + if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(iLit) ) + Abc_InfoXorBit( pInfo, iBit ); + } + if ( ++iBit == nBits ) + break; + } +// Abc_Print( 1, "added %d bits\n", iBit-1 ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [Resimulates counter-examples derived by the SAT solver.] + + 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->nFrames = nFrames; + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords ); + while ( iStart < Vec_IntSize(vCexStore) ) + { + 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 [Resimulates counter-examples derived by the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore ) +{ + Vec_Ptr_t * vSimInfo; + int RetValue = 0, iStart = 0; + Gia_ManSetRefs( pSim->pAig ); + pSim->pPars->nFrames = 1; + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(pSim->pAig), pSim->pPars->nWords ); + while ( iStart < Vec_IntSize(vCexStore) ) + { + Cec_ManStartSimInfo( vSimInfo, 0 ); + iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart ); + RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo ); + } + assert( iStart == Vec_IntSize(vCexStore) ); + Vec_PtrFree( vSimInfo ); + return RetValue; +} + +/**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; + int Counter = 0; + 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) ) + Counter++; +// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) +// Abc_Print( 1, "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 ) ) +// Abc_Print( 1, "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; + } + } +// if ( Counter ) +// Abc_Print( 1, "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCorrReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + Gia_ManCorrReduce_rec( pNew, p, pRepr ); + pObj->Value = Abc_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Prints statistics during solving.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManRefinedClassPrintStats( 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; + if ( iIter == -1 ) + Abc_Print( 1, "BMC : " ); + else + Abc_Print( 1, "%3d : ", iIter ); + Abc_Print( 1, "c =%8d cl =%7d lit =%8d ", Counter0, Counter, nLits ); + if ( vStatus ) + Vec_StrForEachEntry( vStatus, Entry, i ) + { + if ( Entry == 1 ) + nProve++; + else if ( Entry == 0 ) + nDispr++; + else if ( Entry == -1 ) + nFail++; + } + Abc_Print( 1, "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail ); + Abc_PrintTime( 1, "T", Time ); +} + +/**Function************************************************************* + + Synopsis [Runs BMC for the equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPrefs ) +{ + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Vec_Str_t * vStatus; + Vec_Int_t * vOutputs; + Vec_Int_t * vCexStore; + Cec_ManSim_t * pSim; + Gia_Man_t * pSrm; + int fChanges, RetValue; + // prepare simulation manager + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nFrames = pPars->nRounds; + pParsSim->fVerbose = pPars->fVerbose; + pParsSim->fLatchCorr = pPars->fLatchCorr; + pParsSim->fSeqSimulate = 1; + pSim = Cec_ManSimStart( pAig, pParsSim ); + // prepare SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVerbose; + fChanges = 1; + while ( fChanges ) + { + int clkBmc = clock(); + fChanges = 0; + pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings ); + if ( Gia_ManPoNum(pSrm) == 0 ) + { + Gia_ManStop( pSrm ); + Vec_IntFree( vOutputs ); + break; + } + pParsSat->nBTLimit *= 10; + if ( pPars->fUseCSat ) + vCexStore = Tas_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); + else + vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); + // refine classes with these counter-examples + if ( Vec_IntSize(vCexStore) ) + { + RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nPrefs ); + Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); + fChanges = 1; + } + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, vStatus, -1, clock() - clkBmc ); + // recycle + Vec_IntFree( vCexStore ); + Vec_StrFree( vStatus ); + Gia_ManStop( pSrm ); + Vec_IntFree( vOutputs ); + } + Cec_ManSimStop( pSim ); +} + +/**Function************************************************************* + + Synopsis [Internal procedure for register correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{ + int nIterMax = 100000; + int nAddFrames = 1; // additional timeframes to simulate + int fRunBmcFirst = 1; + Vec_Str_t * vStatus; + Vec_Int_t * vOutputs; + Vec_Int_t * vCexStore; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Cec_ManSim_t * pSim; + Gia_Man_t * pSrm; + int r, RetValue, clkTotal = clock(); + int clkSat = 0, clkSim = 0, clkSrm = 0; + int clk2, clk = clock(); + if ( Gia_ManRegNum(pAig) == 0 ) + { + Abc_Print( 1, "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" ); + return 0; + } + Gia_ManRandom( 1 ); + // prepare simulation manager + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nWords = pPars->nWords; + pParsSim->nFrames = pPars->nFrames; + pParsSim->fVerbose = pPars->fVerbose; + pParsSim->fLatchCorr = pPars->fLatchCorr; + pParsSim->fConstCorr = pPars->fConstCorr; + pParsSim->fSeqSimulate = 1; + // create equivalence classes of registers + pSim = Cec_ManSimStart( pAig, pParsSim ); + if ( pAig->pReprs == NULL ) + { + Cec_ManSimClassesPrepare( pSim, pPars->nLevelMax ); + Cec_ManSimClassesRefine( pSim ); + } + // prepare SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVerbose; + if ( pPars->fVerbose ) + { + Abc_Print( 1, "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_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk ); + } + // check the base case + if ( fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) ) + Cec_ManLSCorrespondenceBmc( pAig, pPars, 0 ); + if ( pPars->pFunc ) + { + ((int (*)(void *))pPars->pFunc)( pPars->pData ); + ((int (*)(void *))pPars->pFunc)( pPars->pData ); + } + if ( pPars->nStepsMax == 0 ) + { + Abc_Print( 1, "Stopped signal correspondence after BMC.\n" ); + Cec_ManSimStop( pSim ); + return 1; + } + // perform refinement of equivalence classes + for ( r = 0; r < nIterMax; r++ ) + { + if ( pPars->nStepsMax == r ) + { + Cec_ManSimStop( pSim ); + Abc_Print( 1, "Stopped signal correspondence after %d refiment iterations.\n", r ); + return 1; + } + 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_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); + 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_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); +//Gia_ManEquivPrintClasses( pAig, 1, 0 ); + if ( pPars->pFunc ) + ((int (*)(void *))pPars->pFunc)( pPars->pData ); + } + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk ); + // check the overflow + if ( r == nIterMax ) + Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" ); + Cec_ManSimStop( pSim ); + // check the base case + if ( !fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) ) + Cec_ManLSCorrespondenceBmc( pAig, pPars, 0 ); + clkTotal = clock() - clkTotal; + // report the results + 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_PrintTime( 1, "TOTAL", clkTotal ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes new initial state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames ) +{ + Gia_Obj_t * pObj, * pObjRo, * pObjRi; + unsigned * pInitState; + int i, f; + Gia_ManRandom( 1 ); +// Abc_Print( 1, "Simulating %d timeframes.\n", nFrames ); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark1 = 0; + for ( f = 0; f < nFrames; f++ ) + { + Gia_ManConst0(pAig)->fMark1 = 0; + Gia_ManForEachPi( pAig, pObj, i ) + pObj->fMark1 = Gia_ManRandom(0) & 1; + Gia_ManForEachAnd( pAig, pObj, i ) + pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachRi( pAig, pObj, i ) + pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, i ) + pObjRo->fMark1 = pObjRi->fMark1; + } + pInitState = ABC_CALLOC( unsigned, Abc_BitWordNum(Gia_ManRegNum(pAig)) ); + Gia_ManForEachRo( pAig, pObj, i ) + { + if ( pObj->fMark1 ) + Abc_InfoSetBit( pInitState, i ); +// Abc_Print( 1, "%d", pObj->fMark1 ); + } +// Abc_Print( 1, "\n" ); + Gia_ManCleanMark1( pAig ); + return pInitState; +} + +/**Function************************************************************* + + Synopsis [Prints flop equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPrintFlopEquivs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pRepr; + int i; + assert( p->vNamesIn != NULL ); + Gia_ManForEachRo( p, pObj, i ) + { + if ( Gia_ObjIsConst(p, Gia_ObjId(p, pObj)) ) + Abc_Print( 1, "Original flop %s is proved equivalent to constant.\n", Vec_PtrEntry(p->vNamesIn, Gia_ObjCioId(pObj)) ); + else if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + if ( Gia_ObjIsCi(pRepr) ) + Abc_Print( 1, "Original flop %s is proved equivalent to flop %s.\n", + Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ), + Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pRepr) ) ); + else + Abc_Print( 1, "Original flop %s is proved equivalent to internal node %d.\n", + Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ), Gia_ObjId(p, pRepr) ); + } + } +} + + +/**Function************************************************************* + + Synopsis [Top-level procedure for register correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{ + Gia_Man_t * pNew, * pTemp; + unsigned * pInitState; + int RetValue; + ABC_FREE( pAig->pReprs ); + ABC_FREE( pAig->pNexts ); + if ( pPars->nPrefix == 0 ) + RetValue = Cec_ManLSCorrespondenceClasses( pAig, pPars ); + else + { + // compute the cycles AIG + pInitState = Cec_ManComputeInitState( pAig, pPars->nPrefix ); + pTemp = Gia_ManDupFlip( pAig, (int *)pInitState ); + ABC_FREE( pInitState ); + // compute classes of this AIG + RetValue = Cec_ManLSCorrespondenceClasses( pTemp, pPars ); + // transfer the class info + pAig->pReprs = pTemp->pReprs; pTemp->pReprs = NULL; + pAig->pNexts = pTemp->pNexts; pTemp->pNexts = NULL; + // perform additional BMC + pPars->fUseCSat = 0; + pPars->nBTLimit = Abc_MaxInt( pPars->nBTLimit, 1000 ); + Cec_ManLSCorrespondenceBmc( pAig, pPars, pPars->nPrefix ); +/* + // transfer the class info back + pTemp->pReprs = pAig->pReprs; pAig->pReprs = NULL; + pTemp->pNexts = pAig->pNexts; pAig->pNexts = NULL; + // continue refining + RetValue = Cec_ManLSCorrespondenceClasses( pTemp, pPars ); + // transfer the class info + pAig->pReprs = pTemp->pReprs; pTemp->pReprs = NULL; + pAig->pNexts = pTemp->pNexts; pTemp->pNexts = NULL; +*/ + Gia_ManStop( pTemp ); + } + // derive reduced AIG + if ( pPars->fMakeChoices ) + { + pNew = Gia_ManEquivToChoices( pAig, 1 ); + Gia_ManHasChoices( pNew ); + } + else + { +// Gia_ManEquivImprove( pAig ); + pNew = Gia_ManCorrReduce( pAig ); + pNew = Gia_ManSeqCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + //Gia_WriteAiger( pNew, "reduced.aig", 0, 0 ); + } + // report the results + if ( pPars->fVerbose ) + { + Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + Gia_ManAndNum(pAig), Gia_ManAndNum(pNew), + 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), + Gia_ManRegNum(pAig), Gia_ManRegNum(pNew), + 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); + } + if ( pPars->nPrefix && (Gia_ManAndNum(pNew) < Gia_ManAndNum(pAig) || Gia_ManRegNum(pNew) < Gia_ManRegNum(pAig)) ) + Abc_Print( 1, "The reduced AIG was produced using %d-th invariants and will not verify.\n", pPars->nPrefix ); + // print verbose info about equivalences + if ( pPars->fVerboseFlops ) + { + if ( pAig->vNamesIn == NULL ) + Abc_Print( 1, "Flop output names are not available. Use command \"&get -n\".\n" ); + else + Cec_ManPrintFlopEquivs( pAig ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecCorr_updated.c b/src/proof/cec/cecCorr_updated.c new file mode 100644 index 00000000..1db30705 --- /dev/null +++ b/src/proof/cec/cecCorr_updated.c @@ -0,0 +1,1027 @@ +/**CFile**************************************************************** + + FileName [cecCorr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Latch/signal correspondence computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecCorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix ); + +//////////////////////////////////////////////////////////////////////// +/// 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, int nPrefix ) +{ + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f, nPrefix ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f, nPrefix ); + return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) ); + } + if ( f == 0 ) + { + assert( Gia_ObjIsRo(p, pObj) ); + return Gia_ObjCopyF(p, f, pObj); + } + assert( f && Gia_ObjIsRo(p, pObj) ); + pObj = Gia_ObjRoToRi( p, pObj ); + Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1, nPrefix ); + 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, int nPrefix ) +{ + Gia_Obj_t * pRepr; + int iLitNew; + if ( ~Gia_ObjCopyF(p, f, pObj) ) + return; + if ( f >= nPrefix && (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f, nPrefix ); + 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, nPrefix ); + 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 = Gia_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))) ) + 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 ) ) + { + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 ); + 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 ) + { + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 ); + 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; + iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 ); + 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; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames, 0 ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 ); + 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 [Derives SRM for signal correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix, 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, iPrevNew, iObjNew; + assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix ); + assert( Gia_ManRegNum(p) > 0 ); + assert( p->pReprs != NULL ); + p->pCopies = ABC_FALLOC( int, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p) ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( (nFrames+nPrefix) * Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachRo( p, pObj, i ) + { + Gia_ManAppendCi(pNew); + Gia_ObjSetCopyF( p, 0, pObj, 0 ); + } + for ( f = 0; f < nFrames+nPrefix+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 ); + for ( f = nPrefix; f < nFrames+nPrefix; f++ ) + { + Gia_ManForEachObj1( p, pObj, i ) + { + pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); + if ( pRepr == NULL ) + continue; + iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, f, nPrefix ); + iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix ); + 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 [Initializes simulation info for lcorr/scorr counter-examples.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops, int * pInitState ) +{ + 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 ); + if ( pInitState && Gia_InfoHasBit(pInitState, k) ) + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~0; +// pInfo[0] <<= 1; + } + else + { + 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] = Gia_ManRandom( 0 ); + } +} + +/**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 [Collects information about remapping.] + + 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, int * pInitState ) +{ + 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( pInitState || pInfoObj[w] == 0 ); + pInfoObj[w] = pInfoRepr[w]; + } + } +} + +/**Function************************************************************* + + Synopsis [Packs one counter-examples into the 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 ( Gia_InfoHasBit( pPres, iBit ) && + Gia_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])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Performs bitpacking of counter-examples.] + + 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++ ) ); + // add pattern to storage + for ( k = 1; k < nBits; k++ ) + if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) + break; + kMax = Abc_MaxInt( kMax, k ); + if ( k == nBits-1 ) + break; + } + Vec_PtrFree( vPres ); + Vec_IntFree( vPat ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [Performs bitpacking of counter-examples.] + + 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 ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(iLit) ) + Gia_InfoXorBit( pInfo, iBit ); + } + if ( ++iBit == nBits ) + break; + } +// printf( "added %d bits\n", iBit-1 ); + return iStart; +} + +/**Function************************************************************* + + Synopsis [Resimulates counter-examples derived by the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames, int * pInitState ) +{ + 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) ) + { + Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig), pInitState ); + iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart ); +// iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart ); +// Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo ); + Gia_ManCorrPerformRemapping( vPairs, vSimInfo, pInitState ); + 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 [Resimulates counter-examples derived by the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore ) +{ + Vec_Ptr_t * vSimInfo; + int RetValue = 0, iStart = 0; + Gia_ManSetRefs( pSim->pAig ); + pSim->pPars->nRounds = 1; + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(pSim->pAig), pSim->pPars->nWords ); + while ( iStart < Vec_IntSize(vCexStore) ) + { + Cec_ManStartSimInfo( vSimInfo, 0, NULL ); + iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart ); + RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo ); + } + assert( iStart == Vec_IntSize(vCexStore) ); + Vec_PtrFree( vSimInfo ); + return RetValue; +} + +/**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; + int Counter = 0; + 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) ) + Counter++; +// 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; + } + } +// if ( Counter ) +// printf( "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCorrReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + Gia_ManCorrReduce_rec( pNew, p, pRepr ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrReduce( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Prints statistics during solving.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManRefinedClassPrintStats( 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; + if ( iIter == -1 ) + printf( "BMC : " ); + else + printf( "%3d : ", iIter ); + printf( "c =%8d cl =%7d lit =%8d ", 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 [Computes new initial state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames ) +{ + Gia_Obj_t * pObj, * pObjRo, * pObjRi; + unsigned * pInitState; + int i, f; + printf( "Simulating %d timeframes.\n", nFrames ); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark1 = 0; + for ( f = 0; f < nFrames; f++ ) + { + Gia_ManConst0(pAig)->fMark1 = 0; + Gia_ManForEachPi( pAig, pObj, i ) + pObj->fMark1 = Gia_ManRandom(0) & 1; +// pObj->fMark1 = 1; + Gia_ManForEachAnd( pAig, pObj, i ) + pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachRi( pAig, pObj, i ) + pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, i ) + pObjRo->fMark1 = pObjRi->fMark1; + } + pInitState = ABC_CALLOC( unsigned, Gia_BitWordNum(Gia_ManRegNum(pAig)) ); + Gia_ManForEachRo( pAig, pObj, i ) + { + if ( pObj->fMark1 ) + Gia_InfoSetBit( pInitState, i ); +// printf( "%d", pObj->fMark1 ); + } +// printf( "\n" ); + Gia_ManCleanMark1( pAig ); + return pInitState; +} + +/**Function************************************************************* + + Synopsis [Internal procedure for register correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{ + int nIterMax = 100000; + int nAddFrames = 1; // additional timeframes to simulate + Vec_Str_t * vStatus; + Vec_Int_t * vOutputs; + Vec_Int_t * vCexStore; + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Cec_ManSim_t * pSim; + Gia_Man_t * pSrm; + unsigned * pInitState = NULL; + int r, RetValue, clkTotal = clock(); + int clkSat = 0, clkSim = 0, clkSrm = 0; + 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 0; + } + Gia_ManRandom( 1 ); + // derive initial state for resimulation + if ( pPars->nPrefix ) +// pInitState = Cec_ManComputeInitState( pAig, 5+(1<<20)/Gia_ManAndNum(pAig) ); + pInitState = Cec_ManComputeInitState( pAig, 100 ); + // 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, pInitState ); + 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_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk ); + } + // perform refinement of equivalence classes + for ( r = 0; r < nIterMax; 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_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); + 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, pInitState ); + Vec_IntFree( vCexStore ); + clkSim += clock() - clk2; + Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk ); + Vec_StrFree( vStatus ); + Vec_IntFree( vOutputs ); +//Gia_ManEquivPrintClasses( pAig, 1, 0 ); + } + ABC_FREE( pInitState ); + // check the base case + if ( (!pPars->fLatchCorr || pPars->nFrames > 1) || pPars->nPrefix ) + { + int fChanges = 1; + while ( fChanges ) + { + int clkBmc = clock(); + fChanges = 0; + pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, pPars->nPrefix, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings ); + if ( Gia_ManPoNum(pSrm) == 0 ) + { + Gia_ManStop( pSrm ); + Vec_IntFree( vOutputs ); + break; + } + pParsSat->nBTLimit *= 10; + if ( pPars->nPrefix ) + { + pParsSat->nBTLimit = 10000; + vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); + } + else if ( pPars->fUseCSat ) + vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); + else + vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); + // refine classes with these counter-examples + if ( Vec_IntSize(vCexStore) ) + { + clk2 = clock(); + RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames + pPars->nPrefix, NULL ); + clkSim += clock() - clk2; + Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); + fChanges = 1; + } + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, vStatus, -1, clock() - clkBmc ); + // recycle + Vec_IntFree( vCexStore ); + Vec_StrFree( vStatus ); + Gia_ManStop( pSrm ); + Vec_IntFree( vOutputs ); + } + } + else + { + if ( pPars->fVerbose ) + Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk ); + } + // check the overflow + if ( r == nIterMax ) + printf( "The refinement was not finished. The result may be incorrect.\n" ); + Cec_ManSimStop( pSim ); + clkTotal = clock() - clkTotal; + // report the results + 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 ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Top-level procedure for register correspondence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{ + Gia_Man_t * pNew, * pTemp; + int RetValue; + RetValue = Cec_ManLSCorrespondenceClasses( pAig, pPars ); + // derive reduced AIG + if ( pPars->fMakeChoices ) + { + pNew = Gia_ManEquivToChoices( pAig, 1 ); + Gia_ManHasChoices( pNew ); + } + else + { + Gia_ManEquivImprove( pAig ); + pNew = Gia_ManCorrReduce( pAig ); + pNew = Gia_ManSeqCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + //Gia_WriteAiger( pNew, "reduced.aig", 0, 0 ); + } + // report the results + if ( pPars->fVerbose ) + { + printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + Gia_ManAndNum(pAig), Gia_ManAndNum(pNew), + 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), + Gia_ManRegNum(pAig), Gia_ManRegNum(pNew), + 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecInt.h b/src/proof/cec/cecInt.h new file mode 100644 index 00000000..371dedda --- /dev/null +++ b/src/proof/cec/cecInt.h @@ -0,0 +1,225 @@ +/**CFile**************************************************************** + + FileName [cecInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__aig__cec__cecInt_h +#define ABC__aig__cec__cecInt_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "src/sat/bsat/satSolver.h" +#include "src/misc/bar/bar.h" +#include "src/aig/gia/gia.h" +#include "cec.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// simulation pattern manager +typedef struct Cec_ManPat_t_ Cec_ManPat_t; +struct Cec_ManPat_t_ +{ + Vec_Int_t * vPattern1; // pattern in terms of primary inputs + Vec_Int_t * vPattern2; // pattern in terms of primary inputs + Vec_Str_t * vStorage; // storage for compressed patterns + int iStart; // position in the array where recent patterns begin + int nPats; // total number of recent patterns + int nPatsAll; // total number of all patterns + int nPatLits; // total number of literals in recent patterns + int nPatLitsAll; // total number of literals in all patterns + int nPatLitsMin; // total number of literals in minimized recent patterns + int nPatLitsMinAll; // total number of literals in minimized all patterns + int nSeries; // simulation series + int fVerbose; // verbose stats + // runtime statistics + int timeFind; // detecting the pattern + int timeShrink; // minimizing the pattern + int timeVerify; // verifying the result of minimisation + int timeSort; // sorting literals + int timePack; // packing into sim info structures + int timeTotal; // total runtime + int timeTotalSave; // total runtime for saving +}; + +// SAT solving manager +typedef struct Cec_ManSat_t_ Cec_ManSat_t; +struct Cec_ManSat_t_ +{ + // parameters + Cec_ParSat_t * pPars; + // AIGs used in the package + Gia_Man_t * pAig; // the AIG whose outputs are considered + Vec_Int_t * vStatus; // status for each output + // SAT solving + sat_solver * pSat; // recyclable SAT solver + int nSatVars; // the counter of SAT variables + int * pSatVars; // mapping of each node into its SAT var + Vec_Ptr_t * vUsedNodes; // nodes whose SAT vars are assigned + 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; // 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 +}; + +// combinational simulation manager +typedef struct Cec_ManSim_t_ Cec_ManSim_t; +struct Cec_ManSim_t_ +{ + // parameters + Gia_Man_t * pAig; // the AIG to be used for simulation + Cec_ParSim_t * pPars; // simulation parameters + int nWords; // the number of simulation words + // recycable memory + int * pSimInfo; // simulation information offsets + unsigned * pMems; // allocated simulaton memory + int nWordsAlloc; // the number of allocated entries + int nMems; // the number of used entries + int nMemsMax; // the max number of used entries + int MemFree; // next free entry + int nWordsOld; // the number of simulation words after previous relink + // internal simulation info + Vec_Ptr_t * vCiSimInfo; // CI simulation info + Vec_Ptr_t * vCoSimInfo; // CO simulation info + // counter examples + void ** pCexes; // counter-examples for each output + int iOut; // first failed output + int nOuts; // the number of failed outputs + Abc_Cex_t * pCexComb; // counter-example for the first failed output + Abc_Cex_t * pBestState; // the state that led to most of the refinements + // scoring simulation patterns + int * pScores; // counters of refinement for each pattern + // temporaries + Vec_Int_t * vClassOld; // old class numbers + Vec_Int_t * vClassNew; // new class numbers + Vec_Int_t * vClassTemp; // temporary storage + Vec_Int_t * vRefinedC; // refined const reprs +}; + +// combinational simulation manager +typedef struct Cec_ManFra_t_ Cec_ManFra_t; +struct Cec_ManFra_t_ +{ + // parameters + Gia_Man_t * pAig; // the AIG to be used for simulation + Cec_ParFra_t * pPars; // SAT sweeping parameters + // simulation patterns + Vec_Int_t * vXorNodes; // nodes used in speculative reduction + int nAllProved; // total number of proved nodes + int nAllDisproved; // total number of disproved nodes + int nAllFailed; // total number of failed nodes + // runtime stats + int timeSim; // unsat + int timePat; // unsat + int timeSat; // sat + int timeTotal; // total runtime +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== cecCorr.c ============================================================*/ +extern void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time ); +/*=== cecClass.c ============================================================*/ +extern int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i ); +extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax ); +extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p ); +extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); +/*=== cecIso.c ============================================================*/ +extern int * Cec_ManDetectIsomorphism( Gia_Man_t * p ); +/*=== cecMan.c ============================================================*/ +extern Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); +extern void Cec_ManSatPrintStats( Cec_ManSat_t * p ); +extern void Cec_ManSatStop( Cec_ManSat_t * p ); +extern Cec_ManPat_t * Cec_ManPatStart(); +extern void Cec_ManPatPrintStats( Cec_ManPat_t * p ); +extern void Cec_ManPatStop( Cec_ManPat_t * p ); +extern Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); +extern void Cec_ManSimStop( Cec_ManSim_t * p ); +extern Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ); +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, Abc_Cex_t * pBestState, int fCheckMiter ); +extern void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ); +extern int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig ); +extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); +/*=== 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 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 ); +extern int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ); +extern int Cec_ManSatCheckNodeTwo( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 ); +extern void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 ); +extern Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * p ); +/*=== 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 ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/proof/cec/cecIso.c b/src/proof/cec/cecIso.c new file mode 100644 index 00000000..f1ca2ff7 --- /dev/null +++ b/src/proof/cec/cecIso.c @@ -0,0 +1,375 @@ +/**CFile**************************************************************** + + FileName [cecIso.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecIso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline unsigned * Cec_ManIsoInfo( unsigned * pStore, int nWords, int Id ) { return pStore + nWords * Id; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes simulation info for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoSimulate( Gia_Obj_t * pObj, int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId0(pObj, Id) ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId1(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Copies simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoCopy( int IdDest, int IdSour, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, IdDest ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, IdSour ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = pInfo1[w]; +} + +/**Function************************************************************* + + Synopsis [Compares simulation info of two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoEqual( int Id0, int Id1, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id0 ); + unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Id1 ); + int w; + for ( w = 0; w < nWords; w++ ) + if ( pInfo0[w] != pInfo1[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Generates random simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoRandom( int Id, unsigned * pStore, int nWords ) +{ + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + int w; + for ( w = 0; w < nWords; w++ ) + pInfo0[w] = Gia_ManRandom( 0 ); +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simuation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoHashKey( int Id, unsigned * pStore, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id ); + unsigned uHash = 0; + int i; + for ( i = 0; i < nWords; i++ ) + uHash ^= pInfo0[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Adds node to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoTableAdd( Gia_Man_t * p, int Id, unsigned * pStore, int nWords, int * pTable, int nTableSize ) +{ + Gia_Obj_t * pTemp; + int Key, Ent, Counter = 0, Color = Gia_ObjColors( p, Id ); + assert( Color == 1 || Color == 2 ); + Key = Gia_ManIsoHashKey( Id, pStore, nWords, nTableSize ); + for ( Ent = pTable[Key], pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( Gia_ObjColors( p, Ent ) != Color ) + continue; + if ( !Gia_ManIsoEqual( Id, Ent, pStore, nWords ) ) + continue; + // found node with the same color and signature - mark it and do not add new node + pTemp->fMark0 = 1; + return; + } + // did not find the node with the same color and signature - add new node + pTemp = Gia_ManObj( p, Id ); + assert( pTemp->Value == 0 ); + assert( pTemp->fMark0 == 0 ); + pTemp->Value = pTable[Key]; + pTable[Key] = Id; +} + +/**Function************************************************************* + + Synopsis [Extracts equivalence class candidates from one bin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManIsoExtractClasses( Gia_Man_t * p, int Bin, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + Gia_Obj_t * pTemp; + int Ent; + Vec_IntClear( vNodesA ); + Vec_IntClear( vNodesB ); + for ( Ent = Bin, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp; + Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) ) + { + if ( pTemp->fMark0 ) + { + pTemp->fMark0 = 0; + continue; + } + if ( Gia_ObjColors( p, Ent ) == 1 ) + Vec_IntPush( vNodesA, Ent ); + else + Vec_IntPush( vNodesB, Ent ); + } + return Vec_IntSize(vNodesA) > 0 && Vec_IntSize(vNodesB) > 0; +} + +/**Function************************************************************* + + Synopsis [Matches nodes in the extacted classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManIsoMatchNodes( int * pIso, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB ) +{ + int k0, k1, IdA, IdB; + Vec_IntForEachEntry( vNodesA, IdA, k0 ) + Vec_IntForEachEntry( vNodesB, IdB, k1 ) + { + if ( Gia_ManIsoEqual( IdA, IdB, pStore, nWords ) ) + { + assert( pIso[IdA] == 0 ); + assert( pIso[IdB] == 0 ); + assert( IdA != IdB ); + pIso[IdA] = IdB; + pIso[IdB] = IdA; + continue; + } + } +} + +/**Function************************************************************* + + Synopsis [Transforms iso into equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManTransformClasses( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts && p->pIso ); + memset( p->pReprs, 0, sizeof(int) * Gia_ManObjNum(p) ); + memset( p->pNexts, 0, sizeof(int) * Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( p->pIso[i] && p->pIso[i] < i ) + { + p->pReprs[i].iRepr = p->pIso[i]; + p->pNexts[p->pIso[i]] = i; + } + } +} + +/**Function************************************************************* + + Synopsis [Finds node correspondences in the miter.] + + Description [Assumes that the colors are assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Cec_ManDetectIsomorphism( Gia_Man_t * p ) +{ + int nWords = 2; + Gia_Obj_t * pObj; + Vec_Int_t * vNodesA, * vNodesB; + unsigned * pStore, Counter; + int i, * pIso, * pTable, nTableSize; + // start equivalence classes + pIso = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + { + assert( Gia_ObjColors(p, i) == 0 ); + continue; + } + assert( Gia_ObjColors(p, i) ); + if ( Gia_ObjColors(p, i) == 3 ) + pIso[i] = i; + } + // start simulation info + pStore = ABC_ALLOC( unsigned, Gia_ManObjNum(p) * nWords ); + // simulate and create table + nTableSize = Abc_PrimeCudd( 100 + Gia_ManObjNum(p)/2 ); + pTable = ABC_CALLOC( int, nTableSize ); + Gia_ManCleanValue( p ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( pIso[i] == 0 ) // simulate + Gia_ManIsoSimulate( pObj, i, pStore, nWords ); + else if ( pIso[i] < i ) // copy + Gia_ManIsoCopy( i, pIso[i], pStore, nWords ); + else // generate + Gia_ManIsoRandom( i, pStore, nWords ); + if ( pIso[i] == 0 ) + Gia_ManIsoTableAdd( p, i, pStore, nWords, pTable, nTableSize ); + } + // create equivalence classes + vNodesA = Vec_IntAlloc( 100 ); + vNodesB = Vec_IntAlloc( 100 ); + for ( i = 0; i < nTableSize; i++ ) + if ( Gia_ManIsoExtractClasses( p, pTable[i], pStore, nWords, vNodesA, vNodesB ) ) + Gia_ManIsoMatchNodes( pIso, pStore, nWords, vNodesA, vNodesB ); + Vec_IntFree( vNodesA ); + Vec_IntFree( vNodesB ); + // collect info + Counter = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + Counter += (pIso[i] && pIso[i] < i); +/* + if ( pIso[i] && pIso[i] < i ) + { + if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) || + (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) ) + Abc_Print( 1, "1" ); + else + Abc_Print( 1, "0" ); + } +*/ + } + Abc_Print( 1, "Computed %d pairs of structurally equivalent nodes.\n", Counter ); +// p->pIso = pIso; +// Cec_ManTransformClasses( p ); + + ABC_FREE( pTable ); + ABC_FREE( pStore ); + return pIso; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecMan.c b/src/proof/cec/cecMan.c new file mode 100644 index 00000000..f03ec701 --- /dev/null +++ b/src/proof/cec/cecMan.c @@ -0,0 +1,297 @@ +/**CFile**************************************************************** + + FileName [cecMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Manager procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) +{ + Cec_ManSat_t * p; + // create interpolation manager + p = ABC_ALLOC( Cec_ManSat_t, 1 ); + memset( p, 0, sizeof(Cec_ManSat_t) ); + p->pPars = pPars; + p->pAig = pAig; + // SAT solving + p->nSatVars = 1; + 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; +} + +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatPrintStats( Cec_ManSat_t * p ) +{ + Abc_Print( 1, "CO = %8d ", Gia_ManCoNum(p->pAig) ); + Abc_Print( 1, "AND = %8d ", Gia_ManAndNum(p->pAig) ); + Abc_Print( 1, "Conf = %5d ", p->pPars->nBTLimit ); + Abc_Print( 1, "MinVar = %5d ", p->pPars->nSatVarMax ); + Abc_Print( 1, "MinCalls = %5d\n", p->pPars->nCallsRecycle ); + Abc_Print( 1, "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal : 0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + Abc_PrintTimeP( 1, "Time", p->timeSatUnsat, p->timeTotal ); + Abc_Print( 1, "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal : 0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + Abc_PrintTimeP( 1, "Time", p->timeSatSat, p->timeTotal ); + Abc_Print( 1, "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal : 0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + Abc_PrintTimeP( 1, "Time", p->timeSatUndec, p->timeTotal ); + Abc_PrintTime( 1, "Total time", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Frees the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ); + ABC_FREE( p ); +} + + + +/**Function************************************************************* + + Synopsis [Creates AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec_ManPat_t * Cec_ManPatStart() +{ + Cec_ManPat_t * p; + p = ABC_CALLOC( Cec_ManPat_t, 1 ); + p->vStorage = Vec_StrAlloc( 1<<20 ); + p->vPattern1 = Vec_IntAlloc( 1000 ); + p->vPattern2 = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatPrintStats( Cec_ManPat_t * p ) +{ + Abc_Print( 1, "Latest: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", + p->nPats, p->nPatLits, p->nPatLitsMin, 1.0 * p->nPatLitsMin/p->nPats, + 1.0*(Vec_StrSize(p->vStorage)-p->iStart)/(1<<20) ); + Abc_Print( 1, "Total: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", + p->nPatsAll, p->nPatLitsAll, p->nPatLitsMinAll, 1.0 * p->nPatLitsMinAll/p->nPatsAll, + 1.0*Vec_StrSize(p->vStorage)/(1<<20) ); + Abc_PrintTimeP( 1, "Finding ", p->timeFind, p->timeTotal ); + Abc_PrintTimeP( 1, "Shrinking", p->timeShrink, p->timeTotal ); + Abc_PrintTimeP( 1, "Verifying", p->timeVerify, p->timeTotal ); + Abc_PrintTimeP( 1, "Sorting ", p->timeSort, p->timeTotal ); + Abc_PrintTimeP( 1, "Packing ", p->timePack, p->timeTotal ); + Abc_PrintTime( 1, "TOTAL ", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatStop( Cec_ManPat_t * p ) +{ + Vec_StrFree( p->vStorage ); + Vec_IntFree( p->vPattern1 ); + Vec_IntFree( p->vPattern2 ); + ABC_FREE( p ); +} + + + +/**Function************************************************************* + + Synopsis [Creates AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) +{ + Cec_ManSim_t * p; + p = ABC_ALLOC( Cec_ManSim_t, 1 ); + memset( p, 0, sizeof(Cec_ManSim_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->nWords = pPars->nWords; + p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); + p->vClassOld = Vec_IntAlloc( 1000 ); + p->vClassNew = Vec_IntAlloc( 1000 ); + p->vClassTemp = Vec_IntAlloc( 1000 ); + p->vRefinedC = Vec_IntAlloc( 10000 ); + p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords ); + if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) ) + { + p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords ); + Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords ); + } + p->iOut = -1; + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSimStop( Cec_ManSim_t * p ) +{ + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + if ( p->vCiSimInfo ) + Vec_PtrFree( p->vCiSimInfo ); + if ( p->vCoSimInfo ) + Vec_PtrFree( p->vCoSimInfo ); + ABC_FREE( p->pScores ); + ABC_FREE( p->pCexComb ); + ABC_FREE( p->pCexes ); + ABC_FREE( p->pMems ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Creates AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) +{ + Cec_ManFra_t * p; + p = ABC_ALLOC( Cec_ManFra_t, 1 ); + memset( p, 0, sizeof(Cec_ManFra_t) ); + p->pAig = pAig; + p->pPars = pPars; + p->vXorNodes = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraStop( Cec_ManFra_t * p ) +{ + Vec_IntFree( p->vXorNodes ); + ABC_FREE( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecPat.c b/src/proof/cec/cecPat.c new file mode 100644 index 00000000..cb1dae46 --- /dev/null +++ b/src/proof/cec/cecPat.c @@ -0,0 +1,569 @@ +/**CFile**************************************************************** + + FileName [cecPat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Simulation pattern manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cec_ManPatStoreNum( Cec_ManPat_t * p, int Num ) +{ + unsigned x = (unsigned)Num; + assert( Num >= 0 ); + while ( x & ~0x7f ) + { + Vec_StrPush( p->vStorage, (char)((x & 0x7f) | 0x80) ); + x >>= 7; + } + Vec_StrPush( p->vStorage, (char)x ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cec_ManPatRestoreNum( Cec_ManPat_t * p ) +{ + int ch, i, x = 0; + for ( i = 0; (ch = Vec_StrEntry(p->vStorage, p->iStart++)) & 0x80; i++ ) + x |= (ch & 0x7f) << (7 * i); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cec_ManPatStore( Cec_ManPat_t * p, Vec_Int_t * vPat ) +{ + int i, Number, NumberPrev; + assert( Vec_IntSize(vPat) > 0 ); + Cec_ManPatStoreNum( p, Vec_IntSize(vPat) ); + NumberPrev = Vec_IntEntry( vPat, 0 ); + Cec_ManPatStoreNum( p, NumberPrev ); + Vec_IntForEachEntryStart( vPat, Number, i, 1 ) + { + assert( NumberPrev < Number ); + Cec_ManPatStoreNum( p, Number - NumberPrev ); + NumberPrev = Number; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cec_ManPatRestore( Cec_ManPat_t * p, Vec_Int_t * vPat ) +{ + int i, Size, Number; + Vec_IntClear( vPat ); + Size = Cec_ManPatRestoreNum( p ); + Number = Cec_ManPatRestoreNum( p ); + Vec_IntPush( vPat, Number ); + for ( i = 1; i < Size; i++ ) + { + Number += Cec_ManPatRestoreNum( p ); + Vec_IntPush( vPat, Number ); + } + assert( Vec_IntSize(vPat) == Size ); +} + + +/**Function************************************************************* + + Synopsis [Derives satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManPatComputePattern_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Counter = 0; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + pObj->fMark1 = Cec_ObjSatVarValue( pSat, pObj ); + return 1; + } + assert( Gia_ObjIsAnd(pObj) ); + Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin0(pObj) ); + Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin1(pObj) ); + pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Derives satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatComputePattern1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + if ( pObj->fMark1 == 1 ) + { + Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat ); + Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat ); + } + else + { + assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 || + (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ); + if ( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ) + Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat ); + else + Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat ); + } +} + +/**Function************************************************************* + + Synopsis [Derives satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatComputePattern2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + if ( pObj->fMark1 == 1 ) + { + Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat ); + Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat ); + } + else + { + assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 || + (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ); + if ( (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ) + Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat ); + else + Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat ); + } +} + +/**Function************************************************************* + + Synopsis [Derives satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManPatComputePattern3_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Value0, Value1, Value; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return (pObj->fMark1 << 1) | pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + pObj->fMark0 = 1; + pObj->fMark1 = 1; + return GIA_UND; + } + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) ); + Value1 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin1(pObj) ); + Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); + pObj->fMark0 = (Value & 1); + pObj->fMark1 = ((Value >> 1) & 1); + return Value; +} + +/**Function************************************************************* + + Synopsis [Derives satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) +{ + Gia_Obj_t * pTemp; + int i, Value; + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vPat, Value, i ) + { + pTemp = Gia_ManCi( p, Abc_Lit2Var(Value) ); +// assert( Abc_LitIsCompl(Value) != (int)pTemp->fMark1 ); + if ( pTemp->fMark1 ) + { + pTemp->fMark0 = 0; + pTemp->fMark1 = 1; + } + else + { + pTemp->fMark0 = 1; + pTemp->fMark1 = 0; + } + Gia_ObjSetTravIdCurrent( p, pTemp ); + } + Value = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) ); + Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) ); + if ( Value != GIA_ONE ) + Abc_Print( 1, "Cec_ManPatVerifyPattern(): Verification failed.\n" ); + assert( Value == GIA_ONE ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatComputePattern4_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + pObj->fMark0 = 0; + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) ); + Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + assert( Gia_ObjIsCo(pObj) ); + Gia_ManIncrementTravId( p ); + Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManPatSavePattern( Cec_ManPat_t * pMan, Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + Vec_Int_t * vPat; + int nPatLits, clk, clkTotal = clock(); + assert( Gia_ObjIsCo(pObj) ); + pMan->nPats++; + pMan->nPatsAll++; + // compute values in the cone of influence +clk = clock(); + Gia_ManIncrementTravId( p->pAig ); + nPatLits = Cec_ManPatComputePattern_rec( p, p->pAig, Gia_ObjFanin0(pObj) ); + assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 1 ); + pMan->nPatLits += nPatLits; + pMan->nPatLitsAll += nPatLits; +pMan->timeFind += clock() - clk; + // compute sensitizing path +clk = clock(); + Vec_IntClear( pMan->vPattern1 ); + Gia_ManIncrementTravId( p->pAig ); + Cec_ManPatComputePattern1_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern1 ); + // compute sensitizing path + Vec_IntClear( pMan->vPattern2 ); + Gia_ManIncrementTravId( p->pAig ); + Cec_ManPatComputePattern2_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern2 ); + // compare patterns + vPat = Vec_IntSize(pMan->vPattern1) < Vec_IntSize(pMan->vPattern2) ? pMan->vPattern1 : pMan->vPattern2; + pMan->nPatLitsMin += Vec_IntSize(vPat); + pMan->nPatLitsMinAll += Vec_IntSize(vPat); +pMan->timeShrink += clock() - clk; + // verify pattern using ternary simulation +clk = clock(); + Cec_ManPatVerifyPattern( p->pAig, pObj, vPat ); +pMan->timeVerify += clock() - clk; + // sort pattern +clk = clock(); + Vec_IntSort( vPat, 0 ); +pMan->timeSort += clock() - clk; + // save pattern + Cec_ManPatStore( pMan, vPat ); + pMan->timeTotal += clock() - clkTotal; +} + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Cec_ManPatCollectTry( 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 = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); + if ( Abc_InfoHasBit( pPres, iBit ) && + Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); + Abc_InfoSetBit( pPres, iBit ); + if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) + Abc_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWordsInit ) +{ + Vec_Int_t * vPat = pMan->vPattern1; + Vec_Ptr_t * vInfo, * vPres; + int k, kMax = -1, nPatterns = 0; + int iStartOld = pMan->iStart; + int nWords = nWordsInit; + int nBits = 32 * nWords; + int clk = clock(); + vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); + Gia_ManRandomInfo( vInfo, 0, 0, nWords ); + vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); + Vec_PtrCleanSimInfo( vPres, 0, nWords ); + while ( pMan->iStart < Vec_StrSize(pMan->vStorage) ) + { + nPatterns++; + Cec_ManPatRestore( pMan, vPat ); + 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; + kMax = Abc_MaxInt( kMax, k ); + if ( k == nBits-1 ) + { + Vec_PtrReallocSimInfo( vInfo ); + Gia_ManRandomInfo( vInfo, 0, nWords, 2*nWords ); + Vec_PtrReallocSimInfo( vPres ); + Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); + nWords *= 2; + nBits *= 2; + } + } + Vec_PtrFree( vPres ); + pMan->nSeries = Vec_PtrReadWordsSimInfo(vInfo) / nWordsInit; + pMan->timePack += clock() - clk; + pMan->timeTotal += clock() - clk; + pMan->iStart = iStartOld; + if ( pMan->fVerbose ) + { + Abc_Print( 1, "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ", + nPatterns, kMax, nWordsInit*32, pMan->nSeries ); + ABC_PRT( "Time", clock() - clk ); + Cec_ManPatPrintStats( pMan ); + } + 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 ); + Gia_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 = Abc_MaxInt( kMax, k ); + if ( k == nBits-1 ) + { + Vec_PtrReallocSimInfo( vInfo ); + Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords ); + Gia_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords ); + + Vec_PtrReallocSimInfo( vPres ); + Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); + nWords *= 2; + nBits *= 2; + } + } +// Abc_Print( 1, "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); + Vec_PtrFree( vPres ); + Vec_IntFree( vPat ); + return vInfo; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSeq.c b/src/proof/cec/cecSeq.c new file mode 100644 index 00000000..21ed8656 --- /dev/null +++ b/src/proof/cec/cecSeq.c @@ -0,0 +1,448 @@ +/**CFile**************************************************************** + + FileName [cecSeq.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Refinement of sequential equivalence classes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets register values from the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ) +{ + unsigned * pInfo; + int k, i, w, nWords; + assert( pCex->nBits == pCex->nRegs + pCex->nPis * (pCex->iFrame + 1) ); + assert( pCex->nBits - pCex->nRegs + Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) ); + nWords = Vec_PtrReadWordsSimInfo( vInfo ); +/* + // user register values + assert( pCex->nRegs == Gia_ManRegNum(pAig) ); + for ( k = 0; k < pCex->nRegs; k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Abc_InfoHasBit( pCex->pData, k )? ~0 : 0; + } +*/ + // print warning about register values + for ( k = 0; k < pCex->nRegs; k++ ) + if ( Abc_InfoHasBit( pCex->pData, k ) ) + break; + if ( k < pCex->nRegs ) + Abc_Print( 0, "The CEX has flop values different from 0, but they are currently not used by \"resim\".\n" ); + + // assign zero register values + for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + for ( i = pCex->nRegs; i < pCex->nBits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k++ ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Gia_ManRandom(0); + // set simulation pattern and make sure it is second (first will be erased during simulation) + pInfo[0] = (pInfo[0] << 1) | Abc_InfoHasBit( pCex->pData, i ); + pInfo[0] <<= 1; + } + for ( ; k < Vec_PtrSize(vInfo); k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Gia_ManRandom(0); + } +} + +/**Function************************************************************* + + Synopsis [Sets register values from the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ) +{ + unsigned * pInfo; + int k, w, nWords; + nWords = Vec_PtrReadWordsSimInfo( vInfo ); + assert( pCex == NULL || Gia_ManRegNum(pAig) == pCex->nRegs ); + assert( Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) ); + for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = (pCex && Abc_InfoHasBit(pCex->pData, k))? ~0 : 0; + } + + for ( ; k < Vec_PtrSize(vInfo); k++ ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Gia_ManRandom( 0 ); + } +} + +/**Function************************************************************* + + Synopsis [Resimulates the classes using sequential simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ) +{ + unsigned * pInfo0, * pInfo1; + int f, i, k, w; +// assert( Gia_ManRegNum(p->pAig) > 0 ); + assert( Vec_PtrSize(vInfo) == Gia_ManRegNum(p->pAig) + Gia_ManPiNum(p->pAig) * p->pPars->nFrames ); + for ( k = 0; k < Gia_ManRegNum(p->pAig); k++ ) + { + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + k ); + for ( w = 0; w < p->nWords; w++ ) + pInfo1[w] = pInfo0[w]; + } + for ( f = 0; f < p->pPars->nFrames; f++ ) + { + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k++ ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i ); + for ( w = 0; w < p->nWords; w++ ) + pInfo1[w] = pInfo0[w]; + } + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + pInfo0 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + i ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); + for ( w = 0; w < p->nWords; w++ ) + pInfo1[w] = pInfo0[w]; + } + if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) ) + return 1; + } + assert( k == Vec_PtrSize(vInfo) ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Resimulates information to refine equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Abc_Cex_t * pBestState, int fCheckMiter ) +{ + Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; + Cec_ManSim_t * pSim; + int RetValue, clkTotal = clock(); + assert( (Vec_PtrSize(vSimInfo) - Gia_ManRegNum(pAig)) % Gia_ManPiNum(pAig) == 0 ); + Cec_ManSimSetDefaultParams( pParsSim ); + pParsSim->nFrames = (Vec_PtrSize(vSimInfo) - Gia_ManRegNum(pAig)) / Gia_ManPiNum(pAig); + pParsSim->nWords = Vec_PtrReadWordsSimInfo( vSimInfo ); + pParsSim->fCheckMiter = fCheckMiter; + Gia_ManSetRefs( pAig ); + pSim = Cec_ManSimStart( pAig, pParsSim ); + if ( pBestState ) + pSim->pBestState = pBestState; + RetValue = Cec_ManSeqResimulate( pSim, vSimInfo ); + pSim->pBestState = NULL; + Cec_ManSimStop( pSim ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Resimuates one counter-example to refine equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex ) +{ + Vec_Ptr_t * vSimInfo; + int RetValue, clkTotal = clock(); + if ( pCex == NULL ) + { + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Counter-example is not available.\n" ); + return -1; + } + if ( pAig->pReprs == NULL ) + { + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Equivalence classes are not available.\n" ); + return -1; + } + if ( Gia_ManRegNum(pAig) == 0 ) + { + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" ); + return -1; + } +// if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) + if ( Gia_ManPiNum(pAig) != pCex->nPis ) + { + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" ); + return -1; + } + if ( pPars->fVerbose ) + Abc_Print( 1, "Resimulating %d timeframes.\n", pPars->nFrames + pCex->iFrame + 1 ); + Gia_ManRandom( 1 ); + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) + + Gia_ManPiNum(pAig) * (pPars->nFrames + pCex->iFrame + 1), 1 ); + Cec_ManSeqDeriveInfoFromCex( vSimInfo, pAig, pCex ); + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( pAig, 0, 0 ); + RetValue = Cec_ManSeqResimulateInfo( pAig, vSimInfo, NULL, pPars->fCheckMiter ); + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( pAig, 0, 0 ); + Vec_PtrFree( vSimInfo ); + if ( pPars->fVerbose ) + ABC_PRT( "Time", clock() - clkTotal ); +// if ( RetValue && pPars->fCheckMiter ) +// Abc_Print( 1, "Cec_ManSeqResimulateCounter(): An output of the miter is asserted!\n" ); + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Returns the number of POs that are not const0 cands.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( pAig->pReprs == NULL ) + return -1; + Gia_ManForEachPo( pAig, pObj, i ) + if ( !Gia_ObjIsConst( pAig, Gia_ObjFaninId0p(pAig, pObj) ) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Returns the number of POs that are not const0 cands.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ) +{ + Gia_Obj_t * pObj; + int i, RetValue = 0; + if ( pAig->pReprs == NULL ) + return 0; + // label internal nodes driving POs + Gia_ManForEachPo( pAig, pObj, i ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + // check if there are non-labled equivs + Gia_ManForEachObj( pAig, pObj, i ) + if ( Gia_ObjIsCand(pObj) && !pObj->fMark0 && Gia_ObjRepr(pAig, i) != GIA_VOID ) + { + RetValue = 1; + break; + } + // clean internal nodes driving POs + Gia_ManForEachPo( pAig, pObj, i ) + Gia_ObjFanin0(pObj)->fMark0 = 0; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Performs semiformal refinement of equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) +{ + int nAddFrames = 16; // additional timeframes to simulate + int nCountNoRef = 0; + int nFramesReal; + Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; + Vec_Ptr_t * vSimInfo; + Vec_Str_t * vStatus; + Abc_Cex_t * pState; + Gia_Man_t * pSrm, * pReduce, * pAux; + int r, nPats, RetValue = 0; + if ( pAig->pReprs == NULL ) + { + Abc_Print( 1, "Cec_ManSeqSemiformal(): Equivalence classes are not available.\n" ); + return -1; + } + if ( Gia_ManRegNum(pAig) == 0 ) + { + Abc_Print( 1, "Cec_ManSeqSemiformal(): Not a sequential AIG.\n" ); + return -1; + } + Gia_ManRandom( 1 ); + // prepare starting pattern + pState = Abc_CexAlloc( Gia_ManRegNum(pAig), 0, 0 ); + pState->iFrame = -1; + pState->iPo = -1; + // prepare SAT solving + Cec_ManSatSetDefaultParams( pParsSat ); + pParsSat->nBTLimit = pPars->nBTLimit; + pParsSat->fVerbose = pPars->fVerbose; + if ( pParsSat->fVerbose ) + { + Abc_Print( 1, "Starting: " ); + Gia_ManEquivPrintClasses( pAig, 0, 0 ); + } + // perform the given number of BMC rounds + Gia_ManCleanMark0( pAig ); + for ( r = 0; r < pPars->nRounds; r++ ) + { + if ( !Cec_ManCheckNonTrivialCands(pAig) ) + { + Abc_Print( 1, "Cec_ManSeqSemiformal: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); + break; + } +// Abc_CexPrint( pState ); + // derive speculatively reduced model +// pSrm = Gia_ManSpecReduceInit( pAig, pState, pPars->nFrames, pPars->fDualOut ); + pSrm = Gia_ManSpecReduceInitFrames( pAig, pState, pPars->nFrames, &nFramesReal, pPars->fDualOut, pPars->nMinOutputs ); + if ( pSrm == NULL ) + { + Abc_Print( 1, "Quitting refinement because miter could not be unrolled.\n" ); + break; + } + assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == (Gia_ManPiNum(pAig) * nFramesReal) ); + if ( pPars->fVerbose ) + Abc_Print( 1, "Unrolled for %d frames.\n", nFramesReal ); + // allocate room for simulation info + vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) + + Gia_ManPiNum(pAig) * (nFramesReal + nAddFrames), pPars->nWords ); + Cec_ManSeqDeriveInfoInitRandom( vSimInfo, pAig, pState ); + // fill in simulation info with counter-examples + 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, pPars->fCheckMiter ); + Vec_PtrFree( vSimInfo ); + assert( pState->iPo >= 0 ); // hit counter + pState->iPo = -1; + if ( pPars->fVerbose ) + { + Abc_Print( 1, "BMC = %3d ", nPats ); + Gia_ManEquivPrintClasses( pAig, 0, 0 ); + } + + // write equivalence classes + Gia_WriteAiger( pAig, "gore.aig", 0, 0 ); + // reduce the model + pReduce = Gia_ManSpecReduce( pAig, 0, 0, 1, 0, 0 ); + if ( pReduce ) + { + pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); + Gia_ManStop( pAux ); + Gia_WriteAiger( pReduce, "gsrm.aig", 0, 0 ); +// Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", "gsrm.aig" ); +// Gia_ManPrintStatsShort( pReduce ); + Gia_ManStop( pReduce ); + } + + if ( RetValue ) + { + Abc_Print( 1, "Cec_ManSeqSemiformal(): An output of the miter is asserted. Refinement stopped.\n" ); + break; + } + // decide when to stop + if ( nPats > 0 ) + nCountNoRef = 0; + else if ( ++nCountNoRef == pPars->nNonRefines ) + break; + } + ABC_FREE( pState ); + if ( pPars->fCheckMiter ) + { + int nNonConsts = Cec_ManCountNonConstOutputs( pAig ); + if ( nNonConsts ) + Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); + } + return RetValue; +} + +//&r s13207.aig; &ps; ≡ &ps; &semi -R 2 -vm +//&r bug/50/temp.aig; &ps; &equiv -smv; &semi -v +//r mentor/1_05c.blif; st; &get; &ps; &equiv -smv; &semi -mv +//&r bug/50/hdl1.aig; &ps; &equiv -smv; &semi -mv; &srm; &r gsrm.aig; &ps + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSim.c b/src/proof/cec/cecSim.c new file mode 100644 index 00000000..92f8fc2e --- /dev/null +++ b/src/proof/cec/cecSim.c @@ -0,0 +1,53 @@ +/**CFile**************************************************************** + + FileName [cecSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Simulation manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSolve.c b/src/proof/cec/cecSolve.c new file mode 100644 index 00000000..bd7202e4 --- /dev/null +++ b/src/proof/cec/cecSolve.c @@ -0,0 +1,1023 @@ +/**CFile**************************************************************** + + FileName [cecSolve.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Performs one round of SAT solving.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSolve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Cec_ObjSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj ) { return p->pSatVars[Gia_ObjId(p->pAig,pObj)]; } +static inline void Cec_ObjSetSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj, int Num ) { p->pSatVars[Gia_ObjId(p->pAig,pObj)] = Num; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns value of the SAT variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + return sat_solver_var_value( p->pSat, Cec_ObjSatNum(p, pObj) ); +} + +/**Function************************************************************* + + Synopsis [Addes clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_AddClausesMux( Cec_ManSat_t * p, Gia_Obj_t * pNode ) +{ + Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; + int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + + assert( !Gia_IsComplement( pNode ) ); + assert( Gia_ObjIsMuxType( pNode ) ); + // get nodes (I = if, T = then, E = else) + pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); + // get the variable numbers + VarF = Cec_ObjSatNum(p,pNode); + VarI = Cec_ObjSatNum(p,pNodeI); + VarT = Cec_ObjSatNum(p,Gia_Regular(pNodeT)); + VarE = Cec_ObjSatNum(p,Gia_Regular(pNodeE)); + // get the complementation flags + fCompT = Gia_IsComplement(pNodeT); + fCompE = Gia_IsComplement(pNodeE); + + // f = ITE(i, t, e) + + // i' + t' + f + // i' + t + f' + // i + e' + f + // i + e + f' + + // create four clauses + pLits[0] = toLitCond(VarI, 1); + pLits[1] = toLitCond(VarT, 1^fCompT); + pLits[2] = toLitCond(VarF, 0); + if ( p->pPars->fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); + pLits[0] = toLitCond(VarI, 1); + pLits[1] = toLitCond(VarT, 0^fCompT); + pLits[2] = toLitCond(VarF, 1); + if ( p->pPars->fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); + pLits[0] = toLitCond(VarI, 0); + pLits[1] = toLitCond(VarE, 1^fCompE); + pLits[2] = toLitCond(VarF, 0); + if ( p->pPars->fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); + pLits[0] = toLitCond(VarI, 0); + pLits[1] = toLitCond(VarE, 0^fCompE); + pLits[2] = toLitCond(VarF, 1); + if ( p->pPars->fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); + + // two additional clauses + // t' & e' -> f' + // t & e -> f + + // t + e + f' + // t' + e' + f + + if ( VarT == VarE ) + { +// assert( fCompT == !fCompE ); + return; + } + + pLits[0] = toLitCond(VarT, 0^fCompT); + pLits[1] = toLitCond(VarE, 0^fCompE); + pLits[2] = toLitCond(VarF, 1); + if ( p->pPars->fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); + pLits[0] = toLitCond(VarT, 1^fCompT); + pLits[1] = toLitCond(VarE, 1^fCompE); + pLits[2] = toLitCond(VarF, 0); + if ( p->pPars->fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Addes clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper ) +{ + Gia_Obj_t * pFanin; + int * pLits, nLits, RetValue, i; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsAnd( pNode ) ); + // create storage for literals + nLits = Vec_PtrSize(vSuper) + 1; + pLits = ABC_ALLOC( int, nLits ); + // suppose AND-gate is A & B = C + // add !A => !C or A + !C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[0] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); + pLits[1] = toLitCond(Cec_ObjSatNum(p,pNode), 1); + if ( p->pPars->fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] ); + if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); + } + // add A & B => C or !A + !B + C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[i] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); + if ( p->pPars->fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] ); + } + } + pLits[nLits-1] = toLitCond(Cec_ObjSatNum(p,pNode), 0); + if ( p->pPars->fPolarFlip ) + { + if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] ); + } + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); + assert( RetValue ); + ABC_FREE( pLits ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) || + (!fFirst && Gia_ObjValue(pObj) > 1) || + (fUseMuxes && Gia_ObjIsMuxType(pObj)) ) + { + Vec_PtrPushUnique( vSuper, pObj ); + return; + } + // go through the branches + Cec_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); + Cec_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsCi(pObj) ); + Vec_PtrClear( vSuper ); + Cec_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} + +/**Function************************************************************* + + Synopsis [Updates the solver clause database.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ObjAddToFrontier( Cec_ManSat_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier ) +{ + assert( !Gia_IsComplement(pObj) ); + if ( Cec_ObjSatNum(p,pObj) ) + return; + assert( Cec_ObjSatNum(p,pObj) == 0 ); + if ( Gia_ObjIsConst0(pObj) ) + return; + Vec_PtrPush( p->vUsedNodes, pObj ); + Cec_ObjSetSatNum( p, pObj, p->nSatVars++ ); + if ( Gia_ObjIsAnd(pObj) ) + Vec_PtrPush( vFrontier, pObj ); +} + +/**Function************************************************************* + + Synopsis [Updates the solver clause database.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + Vec_Ptr_t * vFrontier; + Gia_Obj_t * pNode, * pFanin; + int i, k, fUseMuxes = 1; + // quit if CNF is ready + if ( Cec_ObjSatNum(p,pObj) ) + return; + if ( Gia_ObjIsCi(pObj) ) + { + Vec_PtrPush( p->vUsedNodes, pObj ); + Cec_ObjSetSatNum( p, pObj, p->nSatVars++ ); + sat_solver_setnvars( p->pSat, p->nSatVars ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + // start the frontier + vFrontier = Vec_PtrAlloc( 100 ); + Cec_ObjAddToFrontier( p, pObj, vFrontier ); + // explore nodes in the frontier + Vec_PtrForEachEntry( Gia_Obj_t *, vFrontier, pNode, i ) + { + // create the supergate + assert( Cec_ObjSatNum(p,pNode) ); + if ( fUseMuxes && Gia_ObjIsMuxType(pNode) ) + { + Vec_PtrClear( p->vFanins ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier ); + Cec_AddClausesMux( p, pNode ); + } + else + { + Cec_CollectSuper( pNode, fUseMuxes, p->vFanins ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier ); + Cec_AddClausesSuper( p, pNode, p->vFanins ); + } + assert( Vec_PtrSize(p->vFanins) > 1 ); + } + Vec_PtrFree( vFrontier ); +} + + +/**Function************************************************************* + + Synopsis [Recycles the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) +{ + int Lit; + if ( p->pSat ) + { + Gia_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Gia_Obj_t *, p->vUsedNodes, pObj, i ) + Cec_ObjSetSatNum( p, pObj, 0 ); + Vec_PtrClear( p->vUsedNodes ); +// memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) ); + sat_solver_delete( p->pSat ); + } + p->pSat = sat_solver_new(); + p->pSat->factors = ABC_CALLOC( double, 1 ); + sat_solver_setnvars( p->pSat, 1000 ); + // var 0 is not used + // var 1 is reserved for const0 node - add the clause + p->nSatVars = 1; +// p->nSatVars = 0; + Lit = toLitCond( p->nSatVars, 1 ); + if ( p->pPars->fPolarFlip ) + Lit = lit_neg( Lit ); + sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + Cec_ObjSetSatNum( p, Gia_ManConst0(p->pAig), p->nSatVars++ ); + + p->nRecycles++; + p->nCallsSince = 0; +} + +/**Function************************************************************* + + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMin, int LevelMax ) +{ + float dActConeBumpMax = 20.0; + int iVar; + // skip visited variables + if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p->pAig, pObj); + // add the PI to the list + if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) ) + return; + // set the factor of this variable + // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump + if ( (iVar = Cec_ObjSatNum(p,pObj)) ) + { + p->pSat->factors[iVar] = dActConeBumpMax * (Gia_ObjLevel(p->pAig, pObj) - LevelMin)/(LevelMax - LevelMin); + veci_push(&p->pSat->act_vars, iVar); + } + // explore the fanins + Cec_SetActivityFactors_rec( p, Gia_ObjFanin0(pObj), LevelMin, LevelMax ); + Cec_SetActivityFactors_rec( p, Gia_ObjFanin1(pObj), LevelMin, LevelMax ); +} + +/**Function************************************************************* + + Synopsis [Sets variable activities in the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + float dActConeRatio = 0.5; + int LevelMin, LevelMax; + // reset the active variables + veci_resize(&p->pSat->act_vars, 0); + // prepare for traversal + Gia_ManIncrementTravId( p->pAig ); + // determine the min and max level to visit + assert( dActConeRatio > 0 && dActConeRatio < 1 ); + LevelMax = Gia_ObjLevel(p->pAig,pObj); + LevelMin = (int)(LevelMax * (1.0 - dActConeRatio)); + // traverse + Cec_SetActivityFactors_rec( p, pObj, LevelMin, LevelMax ); +//Cec_PrintActivity( p ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Runs equivalence test for the two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pObjR = Gia_Regular(pObj); + int nBTLimit = p->pPars->nBTLimit; + int Lit, RetValue, status, clk, clk2, nConflicts; + + if ( pObj == Gia_ManConst0(p->pAig) ) + return 1; + if ( pObj == Gia_ManConst1(p->pAig) ) + { + assert( 0 ); + return 0; + } + + p->nCallsSince++; // experiment with this!!! + p->nSatTotal++; + + // check if SAT solver needs recycling + if ( p->pSat == NULL || + (p->pPars->nSatVarMax && + p->nSatVars > p->pPars->nSatVarMax && + p->nCallsSince > p->pPars->nCallsRecycle) ) + Cec_ManSatSolverRecycle( p ); + + // if the nodes do not have SAT variables, allocate them +clk2 = clock(); + Cec_CnfNodeAddToSolver( p, pObjR ); +//ABC_PRT( "cnf", clock() - clk2 ); +//Abc_Print( 1, "%d \n", p->pSat->size ); + +clk2 = clock(); +// Cec_SetActivityFactors( p, pObjR ); +//ABC_PRT( "act", clock() - clk2 ); + + // propage unit clauses + if ( p->pSat->qtail != p->pSat->qhead ) + { + status = sat_solver_simplify(p->pSat); + assert( status != 0 ); + assert( p->pSat->qtail == p->pSat->qhead ); + } + + // solve under assumptions + // A = 1; B = 0 OR A = 1; B = 1 + Lit = toLitCond( Cec_ObjSatNum(p,pObjR), Gia_IsComplement(pObj) ); + if ( p->pPars->fPolarFlip ) + { + if ( pObjR->fPhase ) Lit = lit_neg( Lit ); + } +//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); +clk = clock(); + nConflicts = p->pSat->stats.conflicts; + +clk2 = clock(); + RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, + (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); +//ABC_PRT( "sat", clock() - clk2 ); + + if ( RetValue == l_False ) + { +p->timeSatUnsat += clock() - clk; + Lit = lit_neg( Lit ); + RetValue = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + assert( RetValue ); + p->nSatUnsat++; + p->nConfUnsat += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return 1; + } + else if ( RetValue == l_True ) + { +p->timeSatSat += clock() - clk; + p->nSatSat++; + p->nConfSat += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return 0; + } + else // if ( RetValue == l_Undef ) + { +p->timeSatUndec += clock() - clk; + p->nSatUndec++; + p->nConfUndec += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return -1; + } +} + +/**Function************************************************************* + + Synopsis [Runs equivalence test for the two nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManSatCheckNodeTwo( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 ) +{ + Gia_Obj_t * pObjR1 = Gia_Regular(pObj1); + Gia_Obj_t * pObjR2 = Gia_Regular(pObj2); + int nBTLimit = p->pPars->nBTLimit; + int Lits[2], RetValue, status, clk, clk2, nConflicts; + + if ( pObj1 == Gia_ManConst0(p->pAig) || pObj2 == Gia_ManConst0(p->pAig) || pObj1 == Gia_Not(pObj2) ) + return 1; + if ( pObj1 == Gia_ManConst1(p->pAig) && (pObj2 == NULL || pObj2 == Gia_ManConst1(p->pAig)) ) + { + assert( 0 ); + return 0; + } + + p->nCallsSince++; // experiment with this!!! + p->nSatTotal++; + + // check if SAT solver needs recycling + if ( p->pSat == NULL || + (p->pPars->nSatVarMax && + p->nSatVars > p->pPars->nSatVarMax && + p->nCallsSince > p->pPars->nCallsRecycle) ) + Cec_ManSatSolverRecycle( p ); + + // if the nodes do not have SAT variables, allocate them +clk2 = clock(); + Cec_CnfNodeAddToSolver( p, pObjR1 ); + Cec_CnfNodeAddToSolver( p, pObjR2 ); +//ABC_PRT( "cnf", clock() - clk2 ); +//Abc_Print( 1, "%d \n", p->pSat->size ); + +clk2 = clock(); +// Cec_SetActivityFactors( p, pObjR1 ); +// Cec_SetActivityFactors( p, pObjR2 ); +//ABC_PRT( "act", clock() - clk2 ); + + // propage unit clauses + if ( p->pSat->qtail != p->pSat->qhead ) + { + status = sat_solver_simplify(p->pSat); + assert( status != 0 ); + assert( p->pSat->qtail == p->pSat->qhead ); + } + + // solve under assumptions + // A = 1; B = 0 OR A = 1; B = 1 + Lits[0] = toLitCond( Cec_ObjSatNum(p,pObjR1), Gia_IsComplement(pObj1) ); + Lits[1] = toLitCond( Cec_ObjSatNum(p,pObjR2), Gia_IsComplement(pObj2) ); + if ( p->pPars->fPolarFlip ) + { + if ( pObjR1->fPhase ) Lits[0] = lit_neg( Lits[0] ); + if ( pObjR2->fPhase ) Lits[1] = lit_neg( Lits[1] ); + } +//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); +clk = clock(); + nConflicts = p->pSat->stats.conflicts; + +clk2 = clock(); + RetValue = sat_solver_solve( p->pSat, Lits, Lits + 2, + (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); +//ABC_PRT( "sat", clock() - clk2 ); + + if ( RetValue == l_False ) + { +p->timeSatUnsat += clock() - clk; + Lits[0] = lit_neg( Lits[0] ); + Lits[1] = lit_neg( Lits[1] ); + RetValue = sat_solver_addclause( p->pSat, Lits, Lits + 2 ); + assert( RetValue ); + p->nSatUnsat++; + p->nConfUnsat += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return 1; + } + else if ( RetValue == l_True ) + { +p->timeSatSat += clock() - clk; + p->nSatSat++; + p->nConfSat += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return 0; + } + else // if ( RetValue == l_Undef ) + { +p->timeSatUndec += clock() - clk; + p->nSatUndec++; + p->nConfUndec += p->pSat->stats.conflicts - nConflicts; +//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); + return -1; + } +} + + +/**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 [] + +***********************************************************************/ +void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ) +{ + Bar_Progress_t * pProgress = NULL; + Cec_ManSat_t * p; + Gia_Obj_t * pObj; + int i, status, clk = clock(), clk2; + // reset the manager + if ( pPat ) + { + pPat->iStart = Vec_StrSize(pPat->vStorage); + pPat->nPats = 0; + pPat->nPatLits = 0; + pPat->nPatLitsMin = 0; + } + Gia_ManSetPhase( pAig ); + Gia_ManLevelNum( pAig ); + Gia_ManIncrementTravId( pAig ); + p = Cec_ManSatCreate( pAig, pPars ); + pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); + Gia_ManForEachCo( pAig, pObj, i ) + { + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) + { + pObj->fMark0 = 0; + pObj->fMark1 = 1; + continue; + } + Bar_ProgressUpdate( pProgress, i, "SAT..." ); +clk2 = clock(); + status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) ); + pObj->fMark0 = (status == 0); + pObj->fMark1 = (status == 1); +/* + if ( status == -1 ) + { + Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); + Gia_WriteAiger( pTemp, "gia_hard.aig", 0, 0 ); + Gia_ManStop( pTemp ); + Abc_Print( 1, "Dumping hard cone into file \"%s\".\n", "gia_hard.aig" ); + } +*/ + if ( status != 0 ) + continue; + // save the pattern + if ( pPat ) + { + int clk3 = clock(); + Cec_ManPatSavePattern( pPat, p, pObj ); + pPat->timeTotalSave += clock() - clk3; + } + // quit if one of them is solved + if ( pPars->fCheckMiter ) + break; + } + p->timeTotal = clock() - clk; + Bar_ProgressStop( pProgress ); + if ( pPars->fVerbose ) + Cec_ManSatPrintStats( p ); + Cec_ManSatStop( p ); +} + + + +/**Function************************************************************* + + Synopsis [Returns the pattern stored.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * pSat ) +{ + return pSat->vCex; +} + +/**Function************************************************************* + + Synopsis [Save values in the cone of influence.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vInfo, int iPat, int nRegs ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) ); + if ( Cec_ObjSatVarValue( pSat, pObj ) != Abc_InfoHasBit( pInfo, iPat ) ) + Abc_InfoXorBit( pInfo, iPat ); + pSat->nCexLits++; +// Vec_IntPush( pSat->vCex, Abc_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Cec_ManSatSolveSeq_rec( pSat, p, Gia_ObjFanin0(pObj), vInfo, iPat, nRegs ); + Cec_ManSatSolveSeq_rec( pSat, p, Gia_ObjFanin1(pObj), vInfo, iPat, nRegs ); +} + +/**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_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 = 0, nPatsInit, nPats; + int i, status, clk = clock(); + nPatsInit = nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); + Gia_ManSetPhase( pAig ); + Gia_ManLevelNum( pAig ); + Gia_ManIncrementTravId( 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) ) + { +// Abc_Print( 1, "Constant 1 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 0 ); + } + else + { +// Abc_Print( 1, "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) ); +//Abc_Print( 1, "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 ); +// 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 ( iPat == 32 * 15 * 16 - 1 ) +// break; + } + p->timeTotal = clock() - clk; + Bar_ProgressStop( pProgress ); + if ( pPars->fVerbose ) + Cec_ManSatPrintStats( p ); +// Abc_Print( 1, "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, Abc_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 [Save patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 ) +{ + Vec_IntClear( p->vCex ); + Gia_ManIncrementTravId( p->pAig ); + Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj1) ); + if ( pObj2 ) + Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj2) ); +} + +/**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_ManIncrementTravId( 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) ) + { +// Abc_Print( 1, "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, p->vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { +// Abc_Print( 1, "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + status = Cec_ManSatCheckNode( p, Gia_ObjChild0(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) ); + Cec_ManSavePattern( p, Gia_ObjFanin0(pObj), NULL ); +// 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 /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSweep.c b/src/proof/cec/cecSweep.c new file mode 100644 index 00000000..4523810e --- /dev/null +++ b/src/proof/cec/cecSweep.c @@ -0,0 +1,299 @@ +/**CFile**************************************************************** + + FileName [cecSweep.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [SAT sweeping manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSweep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs limited speculative reduction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr = NULL; + int iRes0, iRes1, iRepr, iNode, iMiter; + int i, fCompl, * piCopies, * pDepths; + Gia_ManSetPhase( p->pAig ); + Vec_IntClear( p->vXorNodes ); + if ( p->pPars->nLevelMax ) + Gia_ManLevelNum( p->pAig ); + pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) ); + pNew->pName = Abc_UtilStrsav( p->pAig->pName ); + Gia_ManHashAlloc( pNew ); + piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) ); + pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) ); + piCopies[0] = 0; + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + piCopies[i] = Gia_ManAppendCi( pNew ); + continue; + } + if ( Gia_ObjIsCo(pObj) ) + continue; + if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 || + piCopies[Gia_ObjFaninId1(pObj,i)] == -1 ) + continue; + iRes0 = Abc_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) ); + iRes1 = Abc_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) ); + iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 ); + pDepths[i] = Abc_MaxInt( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] ); + if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID || Gia_ObjFailed(p->pAig, i) ) + continue; + assert( Gia_ObjRepr(p->pAig, i) < i ); + iRepr = piCopies[Gia_ObjRepr(p->pAig, i)]; + if ( iRepr == -1 ) + continue; + if ( Abc_LitRegular(iNode) == Abc_LitRegular(iRepr) ) + continue; + if ( p->pPars->nLevelMax && + (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax || + Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) ) + continue; + if ( p->pPars->fDualOut ) + { +// if ( i % 1000 == 0 && Gia_ObjRepr(p->pAig, i) ) +// Gia_ManEquivPrintOne( p->pAig, Gia_ObjRepr(p->pAig, i), 0 ); + if ( p->pPars->fColorDiff ) + { + if ( !Gia_ObjDiffColors( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + else + { + if ( !Gia_ObjDiffColors2( p->pAig, Gia_ObjRepr(p->pAig, i), i ) ) + continue; + } + } + pRepr = Gia_ManObj( p->pAig, Gia_ObjRepr(p->pAig, i) ); + fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr); + piCopies[i] = Abc_LitNotCond( iRepr, fCompl ); + if ( Gia_ObjProved(p->pAig, i) ) + continue; + // produce speculative miter + iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] ); + Gia_ManAppendCo( pNew, iMiter ); + Vec_IntPush( p->vXorNodes, Gia_ObjRepr(p->pAig, i) ); + Vec_IntPush( p->vXorNodes, i ); + // add to the depth of this node + pDepths[i] = 1 + Abc_MaxInt( pDepths[i], pDepths[Gia_ObjRepr(p->pAig, i)] ); + if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax ) + piCopies[i] = -1; + } + ABC_FREE( piCopies ); + ABC_FREE( pDepths ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate_rec( Gia_Obj_t * pObj ) +{ + int Result; + if ( pObj->fMark0 ) + return 1; + if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) ) + return 0; + Result = (Cec_ManFraClassesUpdate_rec( Gia_ObjFanin0(pObj) ) | + Cec_ManFraClassesUpdate_rec( Gia_ObjFanin1(pObj) )); + return pObj->fMark0 = Result; +} + +/**Function************************************************************* + + Synopsis [Creates simulation info for this round.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vInfo, int nSeries ) +{ + unsigned * pRes0, * pRes1; + int i, w; + for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) + { + pRes0 = (unsigned *)Vec_PtrEntry( vCiInfo, i ); + pRes1 = (unsigned *)Vec_PtrEntry( vInfo, i ); + pRes1 += p->nWords * nSeries; + for ( w = 0; w < p->nWords; w++ ) + pRes0[w] = pRes1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Updates equivalence classes using the patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ) +{ + Vec_Ptr_t * vInfo; + Gia_Obj_t * pObj, * pObjOld, * pReprOld; + int i, k, iRepr, iNode, clk; +clk = clock(); + vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), pSim->nWords ); +p->timePat += clock() - clk; +clk = clock(); + if ( vInfo != NULL ) + { + Gia_ManSetRefs( p->pAig ); + for ( i = 0; i < pPat->nSeries; i++ ) + { + Cec_ManFraCreateInfo( pSim, pSim->vCiSimInfo, vInfo, i ); + if ( Cec_ManSimSimulateRound( pSim, pSim->vCiSimInfo, pSim->vCoSimInfo ) ) + { + Vec_PtrFree( vInfo ); + return 1; + } + } + Vec_PtrFree( vInfo ); + } +p->timeSim += clock() - clk; + assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) ); + // mark the transitive fanout of failed nodes + if ( p->pPars->nDepthMax != 1 ) + { + Gia_ManCleanMark0( p->pAig ); + Gia_ManCleanMark1( p->pAig ); + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; +// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1; + Gia_ManObj(p->pAig, iNode)->fMark0 = 1; + } + // mark the nodes reachable through the failed nodes + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0); + // unmark the disproved nodes + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved + continue; + pObjOld = Gia_ManObj(p->pAig, iNode); + assert( pObjOld->fMark0 == 1 ); + if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 ) + pObjOld->fMark1 = 1; + } + // clean marks + Gia_ManForEachAnd( p->pAig, pObjOld, k ) + if ( pObjOld->fMark1 ) + { + pObjOld->fMark0 = 0; + pObjOld->fMark1 = 0; + } + } + // set the results + p->nAllProved = p->nAllDisproved = p->nAllFailed = 0; + Gia_ManForEachCo( pNew, pObj, k ) + { + iRepr = Vec_IntEntry( p->vXorNodes, 2*k ); + iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 ); + pReprOld = Gia_ManObj(p->pAig, iRepr); + pObjOld = Gia_ManObj(p->pAig, iNode); + if ( pObj->fMark1 ) + { // proved + assert( pObj->fMark0 == 0 ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + assert( iRepr == Gia_ObjRepr(p->pAig, iNode) ); + Gia_ObjSetProved( p->pAig, iNode ); + p->nAllProved++; + } + } + else if ( pObj->fMark0 ) + { // disproved + assert( pObj->fMark1 == 0 ); + if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 ) +// if ( pObjOld->fMark0 == 0 ) + { + if ( iRepr == Gia_ObjRepr(p->pAig, iNode) ) + Abc_Print( 1, "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" ); + p->nAllDisproved++; + } + } + else + { // failed + assert( pObj->fMark0 == 0 ); + assert( pObj->fMark1 == 0 ); + assert( !Gia_ObjFailed(p->pAig, iNode) ); + assert( !Gia_ObjProved(p->pAig, iNode) ); + Gia_ObjSetFailed( p->pAig, iNode ); + p->nAllFailed++; + } + } + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSynth.c b/src/proof/cec/cecSynth.c new file mode 100644 index 00000000..21470dd4 --- /dev/null +++ b/src/proof/cec/cecSynth.c @@ -0,0 +1,380 @@ +/**CFile**************************************************************** + + FileName [cecSynth.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Partitioned sequential synthesis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSynth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" +#include "src/aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Populate sequential synthesis parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSeq_t) ); + p->fUseLcorr = 0; // enables latch correspondence + p->fUseScorr = 0; // enables signal correspondence + p->nBTLimit = 1000; // (scorr/lcorr) conflict limit at a node + p->nFrames = 1; // (scorr only) the number of timeframes + p->nLevelMax = -1; // (scorr only) the max number of levels + p->fConsts = 1; // (scl only) merging constants + p->fEquivs = 1; // (scl only) merging equivalences + p->fUseMiniSat = 0; // enables MiniSat in lcorr/scorr + p->nMinDomSize = 100; // the size of minimum clock domain + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p ) +{ + return p->nMinDomSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SeqReadVerbose( Cec_ParSeq_t * p ) +{ + return p->fVerbose; +} + +/**Function************************************************************* + + Synopsis [Computes partitioning of registers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManRegCreatePart( Gia_Man_t * p, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vNodes, * vRoots; + int i, iOut, nCountPis, nCountRegs; + int * pMapBack; + // collect/mark nodes/PIs in the DFS order from the roots + Gia_ManIncrementTravId( p ); + vRoots = Vec_IntAlloc( Vec_IntSize(vPart) ); + Vec_IntForEachEntry( vPart, iOut, i ) + Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ManCo(p, Gia_ManPoNum(p)+iOut)) ); + vNodes = Gia_ManCollectNodesCis( p, Vec_IntArray(vRoots), Vec_IntSize(vRoots) ); + Vec_IntFree( vRoots ); + // unmark register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + Gia_ObjSetTravIdPrevious( p, Gia_ManCi(p, Gia_ManPiNum(p)+iOut) ); + // count pure PIs + nCountPis = nCountRegs = 0; + Gia_ManForEachPi( p, pObj, i ) + nCountPis += Gia_ObjIsTravIdCurrent(p, pObj); + // count outputs of other registers + Gia_ManForEachRo( p, pObj, i ) + nCountRegs += Gia_ObjIsTravIdCurrent(p, pObj); // should be !Gia_... ??? + if ( pnCountPis ) + *pnCountPis = nCountPis; + if ( pnCountRegs ) + *pnCountRegs = nCountRegs; + // clean old manager + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + // create the new manager + pNew = Gia_ManStart( Vec_IntSize(vNodes) ); + // create the PIs + Gia_ManForEachCi( p, pObj, i ) + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + pObj->Value = Gia_ManAppendCi(pNew); + // add variables for the register outputs + // create fake POs to hold the register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ObjSetTravIdCurrent( p, pObj ); // added + } + // create the nodes + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + // add real POs for the registers + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCo( p, Gia_ManPoNum(p)+iOut ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Vec_IntSize(vPart) ); + // create map + if ( ppMapBack ) + { + pMapBack = ABC_FALLOC( int, Gia_ManObjNum(pNew) ); + // map constant nodes + pMapBack[0] = 0; + // logic cones of register outputs + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { +// pObjNew = Aig_Regular(pObj->pData); +// pMapBack[pObjNew->Id] = pObj->Id; + assert( Abc_Lit2Var(Gia_ObjValue(pObj)) >= 0 ); + assert( Abc_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) ); + pMapBack[ Abc_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj); + } + // map register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); +// pObjNew = pObj->pData; +// pMapBack[pObjNew->Id] = pObj->Id; + assert( Abc_Lit2Var(Gia_ObjValue(pObj)) >= 0 ); + assert( Abc_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) ); + pMapBack[ Abc_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj); + } + *ppMapBack = pMapBack; + } + Vec_IntFree( vNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transfers the classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_TransferMappedClasses( Gia_Man_t * pPart, int * pMapBack, int * pReprs ) +{ + Gia_Obj_t * pObj; + int i, Id1, Id2, nClasses; + if ( pPart->pReprs == NULL ) + return 0; + nClasses = 0; + Gia_ManForEachObj( pPart, pObj, i ) + { + if ( Gia_ObjRepr(pPart, i) == GIA_VOID ) + continue; + assert( i < Gia_ManObjNum(pPart) ); + assert( Gia_ObjRepr(pPart, i) < Gia_ManObjNum(pPart) ); + Id1 = pMapBack[ i ]; + Id2 = pMapBack[ Gia_ObjRepr(pPart, i) ]; + if ( Id1 == Id2 ) + continue; + if ( Id1 < Id2 ) + pReprs[Id2] = Id1; + else + pReprs[Id1] = Id2; + nClasses++; + } + return nClasses; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManFindRepr_rec( int * pReprs, int Id ) +{ + if ( pReprs[Id] == 0 ) + return 0; + if ( pReprs[Id] == ~0 ) + return Id; + return Gia_ManFindRepr_rec( pReprs, pReprs[Id] ); +} + +/**Function************************************************************* + + Synopsis [Normalizes equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManNormalizeEquivalences( Gia_Man_t * p, int * pReprs ) +{ + int i, iRepr; + assert( p->pReprs == NULL ); + assert( p->pNexts == NULL ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + Gia_ObjSetRepr( p, i, GIA_VOID ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( pReprs[i] == ~0 ) + continue; + iRepr = Gia_ManFindRepr_rec( pReprs, i ); + Gia_ObjSetRepr( p, i, iRepr ); + } + p->pNexts = Gia_ManDeriveNexts( p ); +} + +/**Function************************************************************* + + Synopsis [Partitioned sequential synthesis.] + + Description [Returns AIG annotated with equivalence classes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars ) +{ + int fPrintParts = 0; + char Buffer[100]; + Gia_Man_t * pTemp; + Vec_Ptr_t * vParts = (Vec_Ptr_t *)p->vClockDoms; + Vec_Int_t * vPart; + int * pMapBack, * pReprs; + int i, nCountPis, nCountRegs; + int nClasses, clk = clock(); + + // save parameters + if ( fPrintParts ) + { + // print partitions + Abc_Print( 1, "The following clock domains are used:\n" ); + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) + { + pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, NULL ); + sprintf( Buffer, "part%03d.aig", i ); + Gia_WriteAiger( pTemp, Buffer, 0, 0 ); + Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n", + i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp) ); + Gia_ManStop( pTemp ); + } + } + + // perform sequential synthesis for clock domains + pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) ); + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) + { + pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, &pMapBack ); + if ( nCountPis > 0 ) + { + if ( pPars->fUseScorr ) + { + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->nBTLimit = pPars->nBTLimit; + pCorPars->nLevelMax = pPars->nLevelMax; + pCorPars->fVerbose = pPars->fVeryVerbose; + pCorPars->fUseCSat = 1; + Cec_ManLSCorrespondenceClasses( pTemp, pCorPars ); + } + else if ( pPars->fUseLcorr ) + { + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->fLatchCorr = 1; + pCorPars->nBTLimit = pPars->nBTLimit; + pCorPars->fVerbose = pPars->fVeryVerbose; + pCorPars->fUseCSat = 1; + Cec_ManLSCorrespondenceClasses( pTemp, pCorPars ); + } + else + { +// pNew = Gia_ManSeqStructSweep( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose ); +// Gia_ManStop( pNew ); + Gia_ManSeqCleanupClasses( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose ); + } +//Abc_Print( 1, "Part equivalences = %d.\n", Gia_ManEquivCountLitsAll(pTemp) ); + nClasses = Gia_TransferMappedClasses( pTemp, pMapBack, pReprs ); + if ( pPars->fVerbose ) + { + Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. Cl = %5d.\n", + i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp), nClasses ); + } + } + Gia_ManStop( pTemp ); + ABC_FREE( pMapBack ); + } + + // generate resulting equivalences + Gia_ManNormalizeEquivalences( p, pReprs ); +//Abc_Print( 1, "Total equivalences = %d.\n", Gia_ManEquivCountLitsAll(p) ); + ABC_FREE( pReprs ); + if ( pPars->fVerbose ) + { + Abc_PrintTime( 1, "Total time", clock() - clk ); + } + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make new file mode 100644 index 00000000..bac6e9bc --- /dev/null +++ b/src/proof/cec/module.make @@ -0,0 +1,13 @@ +SRC += src/proof/cec/cecCec.c \ + src/proof/cec/cecChoice.c \ + src/proof/cec/cecClass.c \ + src/proof/cec/cecCore.c \ + src/proof/cec/cecCorr.c \ + src/proof/cec/cecIso.c \ + src/proof/cec/cecMan.c \ + src/proof/cec/cecPat.c \ + src/proof/cec/cecSeq.c \ + src/proof/cec/cecSim.c \ + src/proof/cec/cecSolve.c \ + src/proof/cec/cecSynth.c \ + src/proof/cec/cecSweep.c |