| /**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 "aig/gia/giaAig.h" |
| #include "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 ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| 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; |
| abctime clkSat = 0, clkSim = 0, clkSrm = 0, clkTotal = Abc_Clock(); |
| abctime clk2, clk = Abc_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, Abc_Clock() - clk ); |
| } |
| // perform refinement of equivalence classes |
| for ( r = 0; r < nItersMax; r++ ) |
| { |
| clk = Abc_Clock(); |
| // perform speculative reduction |
| clk2 = Abc_Clock(); |
| pSrm = Cec_ManCombSpecReduce( pAig, &vOutputs, pPars->fUseRings ); |
| assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManCiNum(pSrm) == Gia_ManCiNum(pAig) ); |
| clkSrm += Abc_Clock() - clk2; |
| if ( Gia_ManCoNum(pSrm) == 0 ) |
| { |
| if ( pPars->fVerbose ) |
| Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, Abc_Clock() - clk ); |
| Vec_IntFree( vOutputs ); |
| Gia_ManStop( pSrm ); |
| break; |
| } |
| //Gia_DumpAiger( pSrm, "choicesrm", r, 2 ); |
| // found counter-examples to speculation |
| clk2 = Abc_Clock(); |
| if ( pPars->fUseCSat ) |
| vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 ); |
| else |
| vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); |
| Gia_ManStop( pSrm ); |
| clkSat += Abc_Clock() - clk2; |
| if ( Vec_IntSize(vCexStore) == 0 ) |
| { |
| if ( pPars->fVerbose ) |
| Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, Abc_Clock() - clk ); |
| Vec_IntFree( vCexStore ); |
| Vec_StrFree( vStatus ); |
| Vec_IntFree( vOutputs ); |
| break; |
| } |
| // refine classes with these counter-examples |
| clk2 = Abc_Clock(); |
| RetValue = Cec_ManResimulateCounterExamplesComb( pSim, vCexStore ); |
| Vec_IntFree( vCexStore ); |
| clkSim += Abc_Clock() - clk2; |
| Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); |
| if ( pPars->fVerbose ) |
| Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, Abc_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 = Abc_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_very_old( 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 |
| |