diff options
Diffstat (limited to 'src/proof/bbr/bbrReach.c')
-rw-r--r-- | src/proof/bbr/bbrReach.c | 615 |
1 files changed, 0 insertions, 615 deletions
diff --git a/src/proof/bbr/bbrReach.c b/src/proof/bbr/bbrReach.c deleted file mode 100644 index b5125ec7..00000000 --- a/src/proof/bbr/bbrReach.c +++ /dev/null @@ -1,615 +0,0 @@ -/**CFile**************************************************************** - - FileName [bbrReach.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [BDD-based reachability analysis.] - - Synopsis [Procedures to perform reachability analysis.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: bbrReach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "bbr.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, - DdNode ** pbParts, Vec_Ptr_t * vOnionRings, DdNode * bCubeFirst, - int iOutput, int fVerbose, int fSilent ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [This procedure sets default resynthesis parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Bbr_ManSetDefaultParams( Saig_ParBbr_t * p ) -{ - memset( p, 0, sizeof(Saig_ParBbr_t) ); - p->TimeLimit = 0; - p->nBddMax = 50000; - p->nIterMax = 1000; - p->fPartition = 1; - p->fReorder = 1; - p->fReorderImage = 1; - p->fVerbose = 0; - p->fSilent = 0; - p->iFrame = -1; -} - -/**Function******************************************************************** - - Synopsis [Performs the reordering-sensitive step of Extra_bddMove().] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -DdNode * Bbr_bddComputeRangeCube( DdManager * dd, int iStart, int iStop ) -{ - DdNode * bTemp, * bProd; - int i; - assert( iStart <= iStop ); - assert( iStart >= 0 && iStart <= dd->size ); - assert( iStop >= 0 && iStop <= dd->size ); - bProd = (dd)->one; Cudd_Ref( bProd ); - for ( i = iStart; i < iStop; i++ ) - { - bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] ); Cudd_Ref( bProd ); - Cudd_RecursiveDeref( dd, bTemp ); - } - Cudd_Deref( bProd ); - return bProd; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Bbr_StopManager( DdManager * dd ) -{ - int RetValue; - // check for remaining references in the package - RetValue = Cudd_CheckZeroRef( dd ); - if ( RetValue > 0 ) - printf( "\nThe number of referenced nodes = %d\n\n", RetValue ); -// Cudd_PrintInfo( dd, stdout ); - Cudd_Quit( dd ); -} - -/**Function************************************************************* - - Synopsis [Computes the initial state and sets up the variable map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Aig_ManInitStateVarMap( DdManager * dd, Aig_Man_t * p, int fVerbose ) -{ - DdNode ** pbVarsX, ** pbVarsY; - DdNode * bTemp, * bProd; - Aig_Obj_t * pLatch; - int i; - - // set the variable mapping for Cudd_bddVarMap() - pbVarsX = ABC_ALLOC( DdNode *, dd->size ); - pbVarsY = ABC_ALLOC( DdNode *, dd->size ); - bProd = (dd)->one; Cudd_Ref( bProd ); - Saig_ManForEachLo( p, pLatch, i ) - { - pbVarsX[i] = dd->vars[ Saig_ManPiNum(p) + i ]; - pbVarsY[i] = dd->vars[ Saig_ManCiNum(p) + i ]; - // get the initial value of the latch - bProd = Cudd_bddAnd( dd, bTemp = bProd, Cudd_Not(pbVarsX[i]) ); Cudd_Ref( bProd ); - Cudd_RecursiveDeref( dd, bTemp ); - } - Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Saig_ManRegNum(p) ); - ABC_FREE( pbVarsX ); - ABC_FREE( pbVarsY ); - - Cudd_Deref( bProd ); - return bProd; -} - -/**Function************************************************************* - - Synopsis [Collects the array of output BDDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode ** Aig_ManCreateOutputs( DdManager * dd, Aig_Man_t * p ) -{ - DdNode ** pbOutputs; - Aig_Obj_t * pNode; - int i; - // compute the transition relation - pbOutputs = ABC_ALLOC( DdNode *, Saig_ManPoNum(p) ); - Saig_ManForEachPo( p, pNode, i ) - { - pbOutputs[i] = Aig_ObjGlobalBdd(pNode); Cudd_Ref( pbOutputs[i] ); - } - return pbOutputs; -} - -/**Function************************************************************* - - Synopsis [Collects the array of partition BDDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode ** Aig_ManCreatePartitions( DdManager * dd, Aig_Man_t * p, int fReorder, int fVerbose ) -{ - DdNode ** pbParts; - DdNode * bVar; - Aig_Obj_t * pNode; - int i; - - // extand the BDD manager to represent NS variables - assert( dd->size == Saig_ManCiNum(p) ); - Cudd_bddIthVar( dd, Saig_ManCiNum(p) + Saig_ManRegNum(p) - 1 ); - - // enable reordering - if ( fReorder ) - Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); - else - Cudd_AutodynDisable( dd ); - - // compute the transition relation - pbParts = ABC_ALLOC( DdNode *, Saig_ManRegNum(p) ); - Saig_ManForEachLi( p, pNode, i ) - { - bVar = Cudd_bddIthVar( dd, Saig_ManCiNum(p) + i ); - pbParts[i] = Cudd_bddXnor( dd, bVar, Aig_ObjGlobalBdd(pNode) ); Cudd_Ref( pbParts[i] ); - } - // free global BDDs - Aig_ManFreeGlobalBdds( p, dd ); - - // reorder and disable reordering - if ( fReorder ) - { - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the partitions before reordering %d.\n", Cudd_SharingSize(pbParts,Saig_ManRegNum(p)) ); - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); - Cudd_AutodynDisable( dd ); - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the partitions after reordering %d.\n", Cudd_SharingSize(pbParts,Saig_ManRegNum(p)) ); - } - return pbParts; -} - -/**Function************************************************************* - - Synopsis [Computes the set of unreachable states.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, DdNode * bInitial, DdNode ** pbOutputs, Saig_ParBbr_t * pPars, int fCheckOutputs ) -{ - int fInternalReorder = 0; - Bbr_ImageTree_t * pTree = NULL; // Suppress "might be used uninitialized" - Bbr_ImageTree2_t * pTree2 = NULL; // Supprses "might be used uninitialized" - DdNode * bReached, * bCubeCs; - DdNode * bCurrent; - DdNode * bNext = NULL; // Suppress "might be used uninitialized" - DdNode * bTemp; - Cudd_ReorderingType method; - int i, nIters, nBddSize = 0, status; - int nThreshold = 10000; - abctime clk = Abc_Clock(); - Vec_Ptr_t * vOnionRings; - int fixedPoint = 0; - - status = Cudd_ReorderingStatus( dd, &method ); - if ( status ) - Cudd_AutodynDisable( dd ); - - // start the image computation - bCubeCs = Bbr_bddComputeRangeCube( dd, Saig_ManPiNum(p), Saig_ManCiNum(p) ); Cudd_Ref( bCubeCs ); - if ( pPars->fPartition ) - pTree = Bbr_bddImageStart( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), pPars->nBddMax, pPars->fVerbose ); - else - pTree2 = Bbr_bddImageStart2( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), pPars->fVerbose ); - Cudd_RecursiveDeref( dd, bCubeCs ); - if ( pTree == NULL ) - { - if ( !pPars->fSilent ) - printf( "BDDs blew up during qualitification scheduling. " ); - return -1; - } - - if ( status ) - Cudd_AutodynEnable( dd, method ); - - // start the onion rings - vOnionRings = Vec_PtrAlloc( 1000 ); - - // perform reachability analysis - bCurrent = bInitial; Cudd_Ref( bCurrent ); - bReached = bInitial; Cudd_Ref( bReached ); - Vec_PtrPush( vOnionRings, bCurrent ); Cudd_Ref( bCurrent ); - for ( nIters = 0; nIters < pPars->nIterMax; nIters++ ) - { - // check the runtime limit - if ( pPars->TimeLimit && pPars->TimeLimit <= (Abc_Clock()-clk)/CLOCKS_PER_SEC ) - { - printf( "Reached timeout after image computation (%d seconds).\n", pPars->TimeLimit ); - Vec_PtrFree( vOnionRings ); - // undo the image tree - if ( pPars->fPartition ) - Bbr_bddImageTreeDelete( pTree ); - else - Bbr_bddImageTreeDelete2( pTree2 ); - pPars->iFrame = nIters - 1; - return -1; - } - - // compute the next states - if ( pPars->fPartition ) - bNext = Bbr_bddImageCompute( pTree, bCurrent ); - else - bNext = Bbr_bddImageCompute2( pTree2, bCurrent ); - if ( bNext == NULL ) - { - if ( !pPars->fSilent ) - printf( "BDDs blew up during image computation. " ); - if ( pPars->fPartition ) - Bbr_bddImageTreeDelete( pTree ); - else - Bbr_bddImageTreeDelete2( pTree2 ); - Vec_PtrFree( vOnionRings ); - pPars->iFrame = nIters - 1; - return -1; - } - Cudd_Ref( bNext ); - Cudd_RecursiveDeref( dd, bCurrent ); - - // remap these states into the current state vars - bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext ); - Cudd_RecursiveDeref( dd, bTemp ); - // check if there are any new states - if ( Cudd_bddLeq( dd, bNext, bReached ) ) { - fixedPoint = 1; - break; - } - // check the BDD size - nBddSize = Cudd_DagSize(bNext); - if ( nBddSize > pPars->nBddMax ) - break; - // check the result - for ( i = 0; i < Saig_ManPoNum(p); i++ ) - { - if ( fCheckOutputs && !Cudd_bddLeq( dd, bNext, Cudd_Not(pbOutputs[i]) ) ) - { - DdNode * bIntersect; - bIntersect = Cudd_bddIntersect( dd, bNext, pbOutputs[i] ); Cudd_Ref( bIntersect ); - assert( p->pSeqModel == NULL ); - p->pSeqModel = Aig_ManVerifyUsingBddsCountExample( p, dd, pbParts, - vOnionRings, bIntersect, i, pPars->fVerbose, pPars->fSilent ); - Cudd_RecursiveDeref( dd, bIntersect ); - if ( !pPars->fSilent ) - Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", i, p->pName, Vec_PtrSize(vOnionRings) ); - Cudd_RecursiveDeref( dd, bReached ); - bReached = NULL; - pPars->iFrame = nIters; - break; - } - } - if ( i < Saig_ManPoNum(p) ) - break; - // get the new states - bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); - Vec_PtrPush( vOnionRings, bCurrent ); Cudd_Ref( bCurrent ); - // minimize the new states with the reached states -// bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); -// Cudd_RecursiveDeref( dd, bTemp ); - // add to the reached states - bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached ); - Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bNext ); - if ( pPars->fVerbose ) - fprintf( stdout, "Frame = %3d. BDD = %5d. ", nIters, nBddSize ); - if ( fInternalReorder && pPars->fReorder && nBddSize > nThreshold ) - { - if ( pPars->fVerbose ) - fprintf( stdout, "Reordering... Before = %5d. ", Cudd_DagSize(bReached) ); - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); - Cudd_AutodynDisable( dd ); - if ( pPars->fVerbose ) - fprintf( stdout, "After = %5d.\r", Cudd_DagSize(bReached) ); - nThreshold *= 2; - } - if ( pPars->fVerbose ) -// fprintf( stdout, "\r" ); - fprintf( stdout, "\n" ); - - if ( pPars->fVerbose ) - { - double nMints = Cudd_CountMinterm(dd, bReached, Saig_ManRegNum(p) ); -// Extra_bddPrint( dd, bReached );printf( "\n" ); - fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p)) ); - fflush( stdout ); - } - - } - Cudd_RecursiveDeref( dd, bNext ); - // free the onion rings - Vec_PtrForEachEntry( DdNode *, vOnionRings, bTemp, i ) - Cudd_RecursiveDeref( dd, bTemp ); - Vec_PtrFree( vOnionRings ); - // undo the image tree - if ( pPars->fPartition ) - Bbr_bddImageTreeDelete( pTree ); - else - Bbr_bddImageTreeDelete2( pTree2 ); - if ( bReached == NULL ) - return 0; // proved reachable - // report the stats - if ( pPars->fVerbose ) - { - double nMints = Cudd_CountMinterm(dd, bReached, Saig_ManRegNum(p) ); - if ( nIters > pPars->nIterMax || nBddSize > pPars->nBddMax ) - fprintf( stdout, "Reachability analysis is stopped after %d frames.\n", nIters ); - else - fprintf( stdout, "Reachability analysis completed after %d frames.\n", nIters ); - fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p)) ); - fflush( stdout ); - } -//ABC_PRB( dd, bReached ); - Cudd_RecursiveDeref( dd, bReached ); - // SPG - // - if ( fixedPoint ) { - if ( !pPars->fSilent ) { - printf( "The miter is proved unreachable after %d iterations. ", nIters ); - } - pPars->iFrame = nIters - 1; - return 1; - } - assert(nIters >= pPars->nIterMax || nBddSize >= pPars->nBddMax); - if ( !pPars->fSilent ) - printf( "Verified only for states reachable in %d frames. ", nIters ); - pPars->iFrame = nIters - 1; - return -1; // undecided -} - -/**Function************************************************************* - - Synopsis [Performs reachability to see if any PO can be asserted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, Saig_ParBbr_t * pPars ) -{ - int fCheckOutputs = !pPars->fSkipOutCheck; - DdManager * dd; - DdNode ** pbParts, ** pbOutputs; - DdNode * bInitial, * bTemp; - int RetValue, i; - abctime clk = Abc_Clock(); - Vec_Ptr_t * vOnionRings; - - assert( Saig_ManRegNum(p) > 0 ); - - // compute the global BDDs of the latches - dd = Aig_ManComputeGlobalBdds( p, pPars->nBddMax, 1, pPars->fReorder, pPars->fVerbose ); - if ( dd == NULL ) - { - if ( !pPars->fSilent ) - printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", pPars->nBddMax ); - return -1; - } - if ( pPars->fVerbose ) - printf( "Shared BDD size is %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); - - // check the runtime limit - if ( pPars->TimeLimit && pPars->TimeLimit <= (Abc_Clock()-clk)/CLOCKS_PER_SEC ) - { - printf( "Reached timeout after constructing global BDDs (%d seconds).\n", pPars->TimeLimit ); - Cudd_Quit( dd ); - return -1; - } - - // start the onion rings - vOnionRings = Vec_PtrAlloc( 1000 ); - - // save outputs - pbOutputs = Aig_ManCreateOutputs( dd, p ); - - // create partitions - pbParts = Aig_ManCreatePartitions( dd, p, pPars->fReorder, pPars->fVerbose ); - - // create the initial state and the variable map - bInitial = Aig_ManInitStateVarMap( dd, p, pPars->fVerbose ); Cudd_Ref( bInitial ); - - // set reordering - if ( pPars->fReorderImage ) - Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); - - // check the result - RetValue = -1; - for ( i = 0; i < Saig_ManPoNum(p); i++ ) - { - if ( fCheckOutputs && !Cudd_bddLeq( dd, bInitial, Cudd_Not(pbOutputs[i]) ) ) - { - DdNode * bIntersect; - bIntersect = Cudd_bddIntersect( dd, bInitial, pbOutputs[i] ); Cudd_Ref( bIntersect ); - assert( p->pSeqModel == NULL ); - p->pSeqModel = Aig_ManVerifyUsingBddsCountExample( p, dd, pbParts, - vOnionRings, bIntersect, i, pPars->fVerbose, pPars->fSilent ); - Cudd_RecursiveDeref( dd, bIntersect ); - if ( !pPars->fSilent ) - Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", i, p->pName, -1 ); - RetValue = 0; - break; - } - } - // free the onion rings - Vec_PtrForEachEntry( DdNode *, vOnionRings, bTemp, i ) - Cudd_RecursiveDeref( dd, bTemp ); - Vec_PtrFree( vOnionRings ); - // explore reachable states - if ( RetValue == -1 ) - RetValue = Aig_ManComputeReachable( dd, p, pbParts, bInitial, pbOutputs, pPars, fCheckOutputs ); - - // cleanup - Cudd_RecursiveDeref( dd, bInitial ); - for ( i = 0; i < Saig_ManRegNum(p); i++ ) - Cudd_RecursiveDeref( dd, pbParts[i] ); - ABC_FREE( pbParts ); - for ( i = 0; i < Saig_ManPoNum(p); i++ ) - Cudd_RecursiveDeref( dd, pbOutputs[i] ); - ABC_FREE( pbOutputs ); -// if ( RetValue == -1 ) - Cudd_Quit( dd ); -// else -// Bbr_StopManager( dd ); - - // report the runtime - if ( !pPars->fSilent ) - { - ABC_PRT( "Time", Abc_Clock() - clk ); - fflush( stdout ); - } - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Performs reachability to see if any PO can be asserted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, Saig_ParBbr_t * pPars ) -{ - Abc_Cex_t * pCexOld, * pCexNew; - Aig_Man_t * p; - Aig_Obj_t * pObj; - Vec_Int_t * vInputMap; - int i, k, Entry, iBitOld, iBitNew, RetValue; -// pPars->fVerbose = 1; - // check if there are PIs without fanout - Saig_ManForEachPi( pInit, pObj, i ) - if ( Aig_ObjRefs(pObj) == 0 ) - break; - if ( i == Saig_ManPiNum(pInit) ) - return Aig_ManVerifyUsingBdds_int( pInit, pPars ); - // create new AIG - p = Aig_ManDupTrim( pInit ); - assert( Aig_ManCiNum(p) < Aig_ManCiNum(pInit) ); - assert( Aig_ManRegNum(p) == Aig_ManRegNum(pInit) ); - RetValue = Aig_ManVerifyUsingBdds_int( p, pPars ); - if ( RetValue != 0 ) - { - Aig_ManStop( p ); - return RetValue; - } - // the problem is satisfiable - remap the pattern - pCexOld = p->pSeqModel; - assert( pCexOld != NULL ); - // create input map - vInputMap = Vec_IntAlloc( Saig_ManPiNum(pInit) ); - Saig_ManForEachPi( pInit, pObj, i ) - if ( pObj->pData != NULL ) - Vec_IntPush( vInputMap, Aig_ObjCioId((Aig_Obj_t *)pObj->pData) ); - else - Vec_IntPush( vInputMap, -1 ); - // create new pattern - pCexNew = Abc_CexAlloc( Saig_ManRegNum(pInit), Saig_ManPiNum(pInit), pCexOld->iFrame+1 ); - pCexNew->iFrame = pCexOld->iFrame; - pCexNew->iPo = pCexOld->iPo; - // copy the bit-data - for ( iBitOld = 0; iBitOld < pCexOld->nRegs; iBitOld++ ) - if ( Abc_InfoHasBit( pCexOld->pData, iBitOld ) ) - Abc_InfoSetBit( pCexNew->pData, iBitOld ); - // copy the primary input data - iBitNew = iBitOld; - for ( i = 0; i <= pCexNew->iFrame; i++ ) - { - Vec_IntForEachEntry( vInputMap, Entry, k ) - { - if ( Entry == -1 ) - continue; - if ( Abc_InfoHasBit( pCexOld->pData, iBitOld + Entry ) ) - Abc_InfoSetBit( pCexNew->pData, iBitNew + k ); - } - iBitOld += Saig_ManPiNum(p); - iBitNew += Saig_ManPiNum(pInit); - } - assert( iBitOld < iBitNew ); - assert( iBitOld == pCexOld->nBits ); - assert( iBitNew == pCexNew->nBits ); - Vec_IntFree( vInputMap ); - pInit->pSeqModel = pCexNew; - Aig_ManStop( p ); - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - |