| /**CFile**************************************************************** |
| |
| FileName [sswLcorr.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Inductive prover with constraints.] |
| |
| Synopsis [Latch correspondence.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - September 1, 2008.] |
| |
| Revision [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "sswInt.h" |
| //#include "bar.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Tranfers simulation information from FRAIG to AIG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssw_ManSweepTransfer( Ssw_Man_t * p ) |
| { |
| Aig_Obj_t * pObj, * pObjFraig; |
| unsigned * pInfo; |
| int i; |
| // transfer simulation information |
| Aig_ManForEachCi( p->pAig, pObj, i ) |
| { |
| pObjFraig = Ssw_ObjFrame( p, pObj, 0 ); |
| if ( pObjFraig == Aig_ManConst0(p->pFrames) ) |
| { |
| Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 ); |
| continue; |
| } |
| assert( !Aig_IsComplement(pObjFraig) ); |
| assert( Aig_ObjIsCi(pObjFraig) ); |
| pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjCioId(pObjFraig) ); |
| Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs one round of simulation with counter-examples.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ssw_ManSweepResimulate( Ssw_Man_t * p ) |
| { |
| int RetValue1, RetValue2; |
| abctime clk = Abc_Clock(); |
| // transfer PI simulation information from storage |
| Ssw_ManSweepTransfer( p ); |
| // simulate internal nodes |
| Ssw_SmlSimulateOneFrame( p->pSml ); |
| // check equivalence classes |
| RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 ); |
| RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 ); |
| // prepare simulation info for the next round |
| Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 ); |
| p->nPatterns = 0; |
| p->nSimRounds++; |
| p->timeSimSat += Abc_Clock() - clk; |
| return RetValue1 > 0 || RetValue2 > 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Saves one counter-example into internal storage.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand ) |
| { |
| Aig_Obj_t * pObj; |
| unsigned * pInfo; |
| int i, nVarNum, Value; |
| Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i ) |
| { |
| nVarNum = Ssw_ObjSatNum( p->pMSat, pObj ); |
| assert( nVarNum > 0 ); |
| Value = sat_solver_var_value( p->pMSat->pSat, nVarNum ); |
| if ( Value == 0 ) |
| continue; |
| pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjCioId(pObj) ); |
| Abc_InfoSetBit( pInfo, p->nPatterns ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Builds fraiged logic cone of the node.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj ) |
| { |
| Aig_Obj_t * pObjNew; |
| assert( !Aig_IsComplement(pObj) ); |
| if ( Ssw_ObjFrame( p, pObj, 0 ) ) |
| return; |
| assert( Aig_ObjIsNode(pObj) ); |
| Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) ); |
| Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) ); |
| pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) ); |
| Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Recycles the SAT solver.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj ) |
| { |
| Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi; |
| int RetValue; |
| abctime clk; |
| assert( Aig_ObjIsCi(pObj) ); |
| assert( Aig_ObjIsCi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) ); |
| // check if it makes sense to skip some calls |
| if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat ) |
| { |
| if ( ++p->nCallsDelta < 0 ) |
| return; |
| } |
| p->nCallsDelta = 0; |
| clk = Abc_Clock(); |
| // get the fraiged node |
| pObjLi = Saig_ObjLoToLi( p->pAig, pObj ); |
| Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) ); |
| pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 ); |
| // get the fraiged representative |
| if ( Aig_ObjIsCi(pObjRepr) ) |
| { |
| pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr ); |
| Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) ); |
| pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 ); |
| } |
| else |
| pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 ); |
| p->timeReduce += Abc_Clock() - clk; |
| // if the fraiged nodes are the same, return |
| if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) |
| return; |
| p->nRecycleCalls++; |
| p->nCallsCount++; |
| |
| // check equivalence of the two nodes |
| if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) ) |
| { |
| p->nPatterns++; |
| p->nStrangers++; |
| p->fRefined = 1; |
| } |
| else |
| { |
| RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); |
| if ( RetValue == 1 ) // proved equivalence |
| { |
| p->nCallsUnsat++; |
| return; |
| } |
| if ( RetValue == -1 ) // timed out |
| { |
| Ssw_ClassesRemoveNode( p->ppClasses, pObj ); |
| p->nCallsUnsat++; |
| p->fRefined = 1; |
| return; |
| } |
| else // disproved equivalence |
| { |
| Ssw_SmlAddPattern( p, pObjRepr, pObj ); |
| p->nPatterns++; |
| p->nCallsSat++; |
| p->fRefined = 1; |
| } |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs one iteration of sweeping latches.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ssw_ManSweepLatch( Ssw_Man_t * p ) |
| { |
| // Bar_Progress_t * pProgress = NULL; |
| Vec_Ptr_t * vClass; |
| Aig_Obj_t * pObj, * pRepr, * pTemp; |
| int i, k; |
| |
| // start the timeframe |
| p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) ); |
| // map constants and PIs |
| Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) ); |
| Saig_ManForEachPi( p->pAig, pObj, i ) |
| Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreateCi(p->pFrames) ); |
| |
| // implement equivalence classes |
| Saig_ManForEachLo( p->pAig, pObj, i ) |
| { |
| pRepr = Aig_ObjRepr( p->pAig, pObj ); |
| if ( pRepr == NULL ) |
| { |
| pTemp = Aig_ObjCreateCi(p->pFrames); |
| pTemp->pData = pObj; |
| } |
| else |
| pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase ); |
| Ssw_ObjSetFrame( p, pObj, 0, pTemp ); |
| } |
| Aig_ManSetCioIds( p->pFrames ); |
| |
| // prepare simulation info |
| assert( p->vSimInfo == NULL ); |
| p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManCiNum(p->pFrames), 1 ); |
| Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 ); |
| |
| // go through the registers |
| // if ( p->pPars->fVerbose ) |
| // pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) ); |
| vClass = Vec_PtrAlloc( 100 ); |
| p->fRefined = 0; |
| p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0; |
| Saig_ManForEachLo( p->pAig, pObj, i ) |
| { |
| // if ( p->pPars->fVerbose ) |
| // Bar_ProgressUpdate( pProgress, i, NULL ); |
| // consider the case of constant candidate |
| if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) |
| Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj ); |
| else |
| { |
| // consider the case of equivalence class |
| Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass ); |
| if ( Vec_PtrSize(vClass) == 0 ) |
| continue; |
| // try to prove equivalences in this class |
| Vec_PtrForEachEntry( Aig_Obj_t *, vClass, pTemp, k ) |
| if ( Aig_ObjRepr(p->pAig, pTemp) == pObj ) |
| { |
| Ssw_ManSweepLatchOne( p, pObj, pTemp ); |
| if ( p->nPatterns == 32 ) |
| break; |
| } |
| } |
| // resimulate |
| if ( p->nPatterns == 32 ) |
| Ssw_ManSweepResimulate( p ); |
| // attempt recycling the SAT solver |
| if ( p->pPars->nSatVarMax && |
| p->pMSat->nSatVars > p->pPars->nSatVarMax && |
| p->nRecycleCalls > p->pPars->nRecycleCalls ) |
| { |
| p->nVarsMax = Abc_MaxInt( p->nVarsMax, p->pMSat->nSatVars ); |
| p->nCallsMax = Abc_MaxInt( p->nCallsMax, p->pMSat->nSolverCalls ); |
| Ssw_SatStop( p->pMSat ); |
| p->pMSat = Ssw_SatStart( 0 ); |
| p->nRecycles++; |
| p->nRecycleCalls = 0; |
| } |
| } |
| // ABC_PRT( "reduce", p->timeReduce ); |
| // Aig_TableProfile( p->pFrames ); |
| // Abc_Print( 1, "And gates = %d\n", Aig_ManNodeNum(p->pFrames) ); |
| // resimulate |
| if ( p->nPatterns > 0 ) |
| Ssw_ManSweepResimulate( p ); |
| // cleanup |
| Vec_PtrFree( vClass ); |
| // if ( p->pPars->fVerbose ) |
| // Bar_ProgressStop( pProgress ); |
| |
| // cleanup |
| // Ssw_ClassesCheck( p->ppClasses ); |
| return p->fRefined; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |