/**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