| /**CFile**************************************************************** |
| |
| FileName [sswBmc.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Inductive prover with constraints.] |
| |
| Synopsis [Bounded model checker using dynamic unrolling.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - September 1, 2008.] |
| |
| Revision [$Id: sswBmc.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "sswInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Incrementally unroll the timeframes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Aig_Obj_t * Ssw_BmcUnroll_rec( Ssw_Frm_t * pFrm, Aig_Obj_t * pObj, int f ) |
| { |
| Aig_Obj_t * pRes, * pRes0, * pRes1; |
| if ( (pRes = Ssw_ObjFrame_(pFrm, pObj, f)) ) |
| return pRes; |
| if ( Aig_ObjIsConst1(pObj) ) |
| pRes = Aig_ManConst1( pFrm->pFrames ); |
| else if ( Saig_ObjIsPi(pFrm->pAig, pObj) ) |
| pRes = Aig_ObjCreateCi( pFrm->pFrames ); |
| else if ( Aig_ObjIsCo(pObj) ) |
| { |
| Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f ); |
| pRes = Ssw_ObjChild0Fra_( pFrm, pObj, f ); |
| } |
| else if ( Saig_ObjIsLo(pFrm->pAig, pObj) ) |
| { |
| if ( f == 0 ) |
| pRes = Aig_ManConst0( pFrm->pFrames ); |
| else |
| pRes = Ssw_BmcUnroll_rec( pFrm, Saig_ObjLoToLi(pFrm->pAig, pObj), f-1 ); |
| } |
| else |
| { |
| assert( Aig_ObjIsNode(pObj) ); |
| Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f ); |
| Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin1(pObj), f ); |
| pRes0 = Ssw_ObjChild0Fra_( pFrm, pObj, f ); |
| pRes1 = Ssw_ObjChild1Fra_( pFrm, pObj, f ); |
| pRes = Aig_And( pFrm->pFrames, pRes0, pRes1 ); |
| } |
| Ssw_ObjSetFrame_( pFrm, pObj, f, pRes ); |
| return pRes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives counter-example.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iPo, int iFrame ) |
| { |
| Abc_Cex_t * pCex; |
| Aig_Obj_t * pObj, * pObjFrames; |
| int f, i, nShift; |
| assert( Saig_ManRegNum(pFrm->pAig) > 0 ); |
| // allocate the counter example |
| pCex = Abc_CexAlloc( Saig_ManRegNum(pFrm->pAig), Saig_ManPiNum(pFrm->pAig), iFrame + 1 ); |
| pCex->iPo = iPo; |
| pCex->iFrame = iFrame; |
| // create data-bits |
| nShift = Saig_ManRegNum(pFrm->pAig); |
| for ( f = 0; f <= iFrame; f++, nShift += Saig_ManPiNum(pFrm->pAig) ) |
| Saig_ManForEachPi( pFrm->pAig, pObj, i ) |
| { |
| pObjFrames = Ssw_ObjFrame_(pFrm, pObj, f); |
| if ( pObjFrames == NULL ) |
| continue; |
| if ( Ssw_CnfGetNodeValue( pSat, pObjFrames ) ) |
| Abc_InfoSetBit( pCex->pData, nShift + i ); |
| } |
| return pCex; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs BMC for the given AIG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame ) |
| { |
| Ssw_Frm_t * pFrm; |
| Ssw_Sat_t * pSat; |
| Aig_Obj_t * pObj, * pObjFrame; |
| int status, Lit, i, f, RetValue; |
| abctime clkPart; |
| |
| // start managers |
| assert( Saig_ManRegNum(pAig) > 0 ); |
| Aig_ManSetCioIds( pAig ); |
| pSat = Ssw_SatStart( 0 ); |
| pFrm = Ssw_FrmStart( pAig ); |
| pFrm->pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * 3 ); |
| // report statistics |
| if ( fVerbose ) |
| { |
| Abc_Print( 1, "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n", |
| Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), |
| Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) ); |
| fflush( stdout ); |
| } |
| // perform dynamic unrolling |
| RetValue = -1; |
| for ( f = 0; f < nFramesMax; f++ ) |
| { |
| clkPart = Abc_Clock(); |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| // unroll the circuit for this output |
| Ssw_BmcUnroll_rec( pFrm, pObj, f ); |
| pObjFrame = Ssw_ObjFrame_( pFrm, pObj, f ); |
| Ssw_CnfNodeAddToSolver( pSat, Aig_Regular(pObjFrame) ); |
| status = sat_solver_simplify(pSat->pSat); |
| assert( status ); |
| // solve |
| Lit = toLitCond( Ssw_ObjSatNum(pSat,pObjFrame), Aig_IsComplement(pObjFrame) ); |
| if ( fVerbose ) |
| { |
| Abc_Print( 1, "Solving output %2d of frame %3d ... \r", |
| i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); |
| } |
| status = sat_solver_solve( pSat->pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); |
| if ( status == l_False ) |
| { |
| /* |
| Lit = lit_neg( Lit ); |
| RetValue = sat_solver_addclause( pSat->pSat, &Lit, &Lit + 1 ); |
| assert( RetValue ); |
| if ( pSat->pSat->qtail != pSat->pSat->qhead ) |
| { |
| RetValue = sat_solver_simplify(pSat->pSat); |
| assert( RetValue ); |
| } |
| */ |
| RetValue = 1; |
| continue; |
| } |
| else if ( status == l_True ) |
| { |
| pAig->pSeqModel = Ssw_BmcGetCounterExample( pFrm, pSat, i, f ); |
| if ( piFrame ) |
| *piFrame = f; |
| RetValue = 0; |
| break; |
| } |
| else |
| { |
| if ( piFrame ) |
| *piFrame = f; |
| RetValue = -1; |
| break; |
| } |
| } |
| if ( fVerbose ) |
| { |
| Abc_Print( 1, "Solved %2d outputs of frame %3d. ", Saig_ManPoNum(pAig), f ); |
| Abc_Print( 1, "Conf =%8.0f. Var =%8d. AIG=%9d. ", |
| (double)pSat->pSat->stats.conflicts, |
| pSat->nSatVars, Aig_ManNodeNum(pFrm->pFrames) ); |
| ABC_PRT( "T", Abc_Clock() - clkPart ); |
| clkPart = Abc_Clock(); |
| fflush( stdout ); |
| } |
| if ( RetValue != 1 ) |
| break; |
| } |
| |
| Ssw_SatStop( pSat ); |
| Ssw_FrmStop( pFrm ); |
| return RetValue; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |