| /**CFile**************************************************************** |
| |
| FileName [bbrNtbdd.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [BDD-based reachability analysis.] |
| |
| Synopsis [Procedures to construct global BDDs for the network.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: bbrNtbdd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "bbr.h" |
| //#include "bar.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| typedef char ProgressBar; |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static inline void Aig_ObjSetGlobalBdd( Aig_Obj_t * pObj, DdNode * bFunc ) { pObj->pData = bFunc; } |
| static inline void Aig_ObjCleanGlobalBdd( DdManager * dd, Aig_Obj_t * pObj ) { Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); pObj->pData = NULL; } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives the global BDD for one AIG node.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| DdNode * Bbr_NodeGlobalBdds_rec( DdManager * dd, Aig_Obj_t * pNode, int nBddSizeMax, int fDropInternal, ProgressBar * pProgress, int * pCounter, int fVerbose ) |
| { |
| DdNode * bFunc, * bFunc0, * bFunc1; |
| assert( !Aig_IsComplement(pNode) ); |
| if ( Cudd_ReadKeys(dd)-Cudd_ReadDead(dd) > (unsigned)nBddSizeMax ) |
| { |
| // Extra_ProgressBarStop( pProgress ); |
| if ( fVerbose ) |
| printf( "The number of live nodes reached %d.\n", nBddSizeMax ); |
| fflush( stdout ); |
| return NULL; |
| } |
| // if the result is available return |
| if ( Aig_ObjGlobalBdd(pNode) == NULL ) |
| { |
| // compute the result for both branches |
| bFunc0 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin0(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); |
| if ( bFunc0 == NULL ) |
| return NULL; |
| Cudd_Ref( bFunc0 ); |
| bFunc1 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin1(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); |
| if ( bFunc1 == NULL ) |
| return NULL; |
| Cudd_Ref( bFunc1 ); |
| bFunc0 = Cudd_NotCond( bFunc0, Aig_ObjFaninC0(pNode) ); |
| bFunc1 = Cudd_NotCond( bFunc1, Aig_ObjFaninC1(pNode) ); |
| // get the final result |
| bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); |
| Cudd_RecursiveDeref( dd, bFunc0 ); |
| Cudd_RecursiveDeref( dd, bFunc1 ); |
| // add the number of used nodes |
| (*pCounter)++; |
| // set the result |
| assert( Aig_ObjGlobalBdd(pNode) == NULL ); |
| Aig_ObjSetGlobalBdd( pNode, bFunc ); |
| // increment the progress bar |
| // if ( pProgress ) |
| // Extra_ProgressBarUpdate( pProgress, *pCounter, NULL ); |
| } |
| // prepare the return value |
| bFunc = Aig_ObjGlobalBdd(pNode); |
| // dereference BDD at the node |
| if ( --pNode->nRefs == 0 && fDropInternal ) |
| { |
| Cudd_Deref( bFunc ); |
| Aig_ObjSetGlobalBdd( pNode, NULL ); |
| } |
| return bFunc; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Frees the global BDDs of the network.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Aig_ManFreeGlobalBdds( Aig_Man_t * p, DdManager * dd ) |
| { |
| Aig_Obj_t * pObj; |
| int i; |
| Aig_ManForEachObj( p, pObj, i ) |
| if ( Aig_ObjGlobalBdd(pObj) ) |
| Aig_ObjCleanGlobalBdd( dd, pObj ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the shared size of global BDDs of the COs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Aig_ManSizeOfGlobalBdds( Aig_Man_t * p ) |
| { |
| Vec_Ptr_t * vFuncsGlob; |
| Aig_Obj_t * pObj; |
| int RetValue, i; |
| // complement the global functions |
| vFuncsGlob = Vec_PtrAlloc( Aig_ManCoNum(p) ); |
| Aig_ManForEachCo( p, pObj, i ) |
| Vec_PtrPush( vFuncsGlob, Aig_ObjGlobalBdd(pObj) ); |
| RetValue = Cudd_SharingSize( (DdNode **)Vec_PtrArray(vFuncsGlob), Vec_PtrSize(vFuncsGlob) ); |
| Vec_PtrFree( vFuncsGlob ); |
| return RetValue; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Recursively computes global BDDs for the AIG in the manager.] |
| |
| Description [On exit, BDDs are stored in the pNode->pData fields.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| DdManager * Aig_ManComputeGlobalBdds( Aig_Man_t * p, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ) |
| { |
| ProgressBar * pProgress = NULL; |
| Aig_Obj_t * pObj; |
| DdManager * dd; |
| DdNode * bFunc; |
| int i, Counter; |
| // start the manager |
| dd = Cudd_Init( Aig_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); |
| // set reordering |
| if ( fReorder ) |
| Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); |
| // prepare to construct global BDDs |
| Aig_ManCleanData( p ); |
| // assign the constant node BDD |
| Aig_ObjSetGlobalBdd( Aig_ManConst1(p), dd->one ); Cudd_Ref( dd->one ); |
| // set the elementary variables |
| Aig_ManForEachCi( p, pObj, i ) |
| { |
| Aig_ObjSetGlobalBdd( pObj, dd->vars[i] ); Cudd_Ref( dd->vars[i] ); |
| } |
| |
| // collect the global functions of the COs |
| Counter = 0; |
| // construct the BDDs |
| // pProgress = Extra_ProgressBarStart( stdout, Aig_ManNodeNum(p) ); |
| Aig_ManForEachCo( p, pObj, i ) |
| { |
| bFunc = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin0(pObj), nBddSizeMax, fDropInternal, pProgress, &Counter, fVerbose ); |
| if ( bFunc == NULL ) |
| { |
| if ( fVerbose ) |
| printf( "Constructing global BDDs is aborted.\n" ); |
| Aig_ManFreeGlobalBdds( p, dd ); |
| Cudd_Quit( dd ); |
| // reset references |
| Aig_ManResetRefs( p ); |
| return NULL; |
| } |
| bFunc = Cudd_NotCond( bFunc, Aig_ObjFaninC0(pObj) ); Cudd_Ref( bFunc ); |
| Aig_ObjSetGlobalBdd( pObj, bFunc ); |
| } |
| // Extra_ProgressBarStop( pProgress ); |
| // reset references |
| Aig_ManResetRefs( p ); |
| // reorder one more time |
| if ( fReorder ) |
| { |
| Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); |
| Cudd_AutodynDisable( dd ); |
| } |
| // Cudd_PrintInfo( dd, stdout ); |
| return dd; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |