| /**CFile**************************************************************** |
| |
| FileName [resDivs.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Resynthesis package.] |
| |
| Synopsis [Collect divisors for the given window.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - January 15, 2007.] |
| |
| Revision [$Id: resDivs.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "base/abc/abc.h" |
| #include "resInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static void Res_WinMarkTfi( Res_Win_t * p ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds candidate divisors of the node to its window.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Res_WinDivisors( Res_Win_t * p, int nLevDivMax ) |
| { |
| Abc_Obj_t * pObj, * pFanout, * pFanin; |
| int k, f, m; |
| |
| // set the maximum level of the divisors |
| p->nLevDivMax = nLevDivMax; |
| |
| // mark the TFI with the current trav ID |
| Abc_NtkIncrementTravId( p->pNode->pNtk ); |
| Res_WinMarkTfi( p ); |
| |
| // mark with the current trav ID those nodes that should not be divisors: |
| // (1) the node and its TFO |
| // (2) the MFFC of the node |
| // (3) the node's fanins (these are treated as a special case) |
| Abc_NtkIncrementTravId( p->pNode->pNtk ); |
| Res_WinSweepLeafTfo_rec( p->pNode, p->nLevDivMax ); |
| Res_WinVisitMffc( p->pNode ); |
| Abc_ObjForEachFanin( p->pNode, pObj, k ) |
| Abc_NodeSetTravIdCurrent( pObj ); |
| |
| // at this point the nodes are marked with two trav IDs: |
| // nodes to be collected as divisors are marked with previous trav ID |
| // nodes to be avoided as divisors are marked with current trav ID |
| |
| // start collecting the divisors |
| Vec_PtrClear( p->vDivs ); |
| Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, k ) |
| { |
| assert( (int)pObj->Level >= p->nLevLeafMin ); |
| if ( !Abc_NodeIsTravIdPrevious(pObj) ) |
| continue; |
| if ( (int)pObj->Level > p->nLevDivMax ) |
| continue; |
| Vec_PtrPush( p->vDivs, pObj ); |
| } |
| // add the internal nodes to the data structure |
| Vec_PtrForEachEntry( Abc_Obj_t *, p->vNodes, pObj, k ) |
| { |
| if ( !Abc_NodeIsTravIdPrevious(pObj) ) |
| continue; |
| if ( (int)pObj->Level > p->nLevDivMax ) |
| continue; |
| Vec_PtrPush( p->vDivs, pObj ); |
| } |
| |
| // explore the fanouts of already collected divisors |
| p->nDivsPlus = 0; |
| Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pObj, k ) |
| { |
| // consider fanouts of this node |
| Abc_ObjForEachFanout( pObj, pFanout, f ) |
| { |
| // stop if there are too many fanouts |
| if ( f > 20 ) |
| break; |
| // skip nodes that are already added |
| if ( Abc_NodeIsTravIdPrevious(pFanout) ) |
| continue; |
| // skip nodes in the TFO or in the MFFC of node |
| if ( Abc_NodeIsTravIdCurrent(pFanout) ) |
| continue; |
| // skip COs |
| if ( !Abc_ObjIsNode(pFanout) ) |
| continue; |
| // skip nodes with large level |
| if ( (int)pFanout->Level > p->nLevDivMax ) |
| continue; |
| // skip nodes whose fanins are not divisors |
| Abc_ObjForEachFanin( pFanout, pFanin, m ) |
| if ( !Abc_NodeIsTravIdPrevious(pFanin) ) |
| break; |
| if ( m < Abc_ObjFaninNum(pFanout) ) |
| continue; |
| // add the node to the divisors |
| Vec_PtrPush( p->vDivs, pFanout ); |
| Vec_PtrPush( p->vNodes, pFanout ); |
| Abc_NodeSetTravIdPrevious( pFanout ); |
| p->nDivsPlus++; |
| } |
| } |
| /* |
| printf( "Node level = %d. ", Abc_ObjLevel(p->pNode) ); |
| Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs, pObj, k, Vec_PtrSize(p->vDivs)-p->nDivsPlus ) |
| printf( "%d ", Abc_ObjLevel(pObj) ); |
| printf( "\n" ); |
| */ |
| //printf( "%d ", p->nDivsPlus ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks the TFI cone of the node.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Res_WinMarkTfi_rec( Res_Win_t * p, Abc_Obj_t * pObj ) |
| { |
| Abc_Obj_t * pFanin; |
| int i; |
| if ( Abc_NodeIsTravIdCurrent(pObj) ) |
| return; |
| Abc_NodeSetTravIdCurrent( pObj ); |
| assert( Abc_ObjIsNode(pObj) ); |
| // visit the fanins of the node |
| Abc_ObjForEachFanin( pObj, pFanin, i ) |
| Res_WinMarkTfi_rec( p, pFanin ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks the TFI cone of the node.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Res_WinMarkTfi( Res_Win_t * p ) |
| { |
| Abc_Obj_t * pObj; |
| int i; |
| // mark the leaves |
| Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, i ) |
| Abc_NodeSetTravIdCurrent( pObj ); |
| // start from the node |
| Res_WinMarkTfi_rec( p, p->pNode ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks the TFO of the collected nodes up to the given level.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit ) |
| { |
| Abc_Obj_t * pFanout; |
| int i; |
| if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit ) |
| return; |
| if ( Abc_NodeIsTravIdCurrent(pObj) ) |
| return; |
| Abc_NodeSetTravIdCurrent( pObj ); |
| Abc_ObjForEachFanout( pObj, pFanout, i ) |
| Res_WinSweepLeafTfo_rec( pFanout, nLevelLimit ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Dereferences the node's MFFC.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Res_NodeDeref_rec( Abc_Obj_t * pNode ) |
| { |
| Abc_Obj_t * pFanin; |
| int i, Counter = 1; |
| if ( Abc_ObjIsCi(pNode) ) |
| return 0; |
| Abc_NodeSetTravIdCurrent( pNode ); |
| Abc_ObjForEachFanin( pNode, pFanin, i ) |
| { |
| assert( pFanin->vFanouts.nSize > 0 ); |
| if ( --pFanin->vFanouts.nSize == 0 ) |
| Counter += Res_NodeDeref_rec( pFanin ); |
| } |
| return Counter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [References the node's MFFC.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Res_NodeRef_rec( Abc_Obj_t * pNode ) |
| { |
| Abc_Obj_t * pFanin; |
| int i, Counter = 1; |
| if ( Abc_ObjIsCi(pNode) ) |
| return 0; |
| Abc_ObjForEachFanin( pNode, pFanin, i ) |
| { |
| if ( pFanin->vFanouts.nSize++ == 0 ) |
| Counter += Res_NodeRef_rec( pFanin ); |
| } |
| return Counter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Labels MFFC of the node with the current trav ID.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Res_WinVisitMffc( Abc_Obj_t * pNode ) |
| { |
| int Count1, Count2; |
| assert( Abc_ObjIsNode(pNode) ); |
| // dereference the node (mark with the current trav ID) |
| Count1 = Res_NodeDeref_rec( pNode ); |
| // reference it back |
| Count2 = Res_NodeRef_rec( pNode ); |
| assert( Count1 == Count2 ); |
| return Count1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |