| /**CFile**************************************************************** |
| |
| FileName [ivyFanout.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [And-Inverter Graph package.] |
| |
| Synopsis [Representation of the fanouts.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - May 11, 2006.] |
| |
| Revision [$Id: ivyFanout.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "ivy.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| // getting hold of the next fanout of the node |
| static inline Ivy_Obj_t * Ivy_ObjNextFanout( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| if ( pFanout == NULL ) |
| return NULL; |
| if ( Ivy_ObjFanin0(pFanout) == pObj ) |
| return pFanout->pNextFan0; |
| assert( Ivy_ObjFanin1(pFanout) == pObj ); |
| return pFanout->pNextFan1; |
| } |
| |
| // getting hold of the previous fanout of the node |
| static inline Ivy_Obj_t * Ivy_ObjPrevFanout( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| if ( pFanout == NULL ) |
| return NULL; |
| if ( Ivy_ObjFanin0(pFanout) == pObj ) |
| return pFanout->pPrevFan0; |
| assert( Ivy_ObjFanin1(pFanout) == pObj ); |
| return pFanout->pPrevFan1; |
| } |
| |
| // getting hold of the place where the next fanout will be attached |
| static inline Ivy_Obj_t ** Ivy_ObjNextFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| if ( Ivy_ObjFanin0(pFanout) == pObj ) |
| return &pFanout->pNextFan0; |
| assert( Ivy_ObjFanin1(pFanout) == pObj ); |
| return &pFanout->pNextFan1; |
| } |
| |
| // getting hold of the place where the next fanout will be attached |
| static inline Ivy_Obj_t ** Ivy_ObjPrevFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| if ( Ivy_ObjFanin0(pFanout) == pObj ) |
| return &pFanout->pPrevFan0; |
| assert( Ivy_ObjFanin1(pFanout) == pObj ); |
| return &pFanout->pPrevFan1; |
| } |
| |
| // getting hold of the place where the next fanout will be attached |
| static inline Ivy_Obj_t ** Ivy_ObjPrevNextFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| Ivy_Obj_t * pTemp; |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| pTemp = Ivy_ObjPrevFanout(pObj, pFanout); |
| if ( pTemp == NULL ) |
| return &pObj->pFanout; |
| if ( Ivy_ObjFanin0(pTemp) == pObj ) |
| return &pTemp->pNextFan0; |
| assert( Ivy_ObjFanin1(pTemp) == pObj ); |
| return &pTemp->pNextFan1; |
| } |
| |
| // getting hold of the place where the next fanout will be attached |
| static inline Ivy_Obj_t ** Ivy_ObjNextPrevFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) |
| { |
| Ivy_Obj_t * pTemp; |
| assert( !Ivy_IsComplement(pObj) ); |
| assert( !Ivy_IsComplement(pFanout) ); |
| pTemp = Ivy_ObjNextFanout(pObj, pFanout); |
| if ( pTemp == NULL ) |
| return NULL; |
| if ( Ivy_ObjFanin0(pTemp) == pObj ) |
| return &pTemp->pPrevFan0; |
| assert( Ivy_ObjFanin1(pTemp) == pObj ); |
| return &pTemp->pPrevFan1; |
| } |
| |
| // iterator through the fanouts of the node |
| #define Ivy_ObjForEachFanoutInt( pObj, pFanout ) \ |
| for ( pFanout = (pObj)->pFanout; pFanout; \ |
| pFanout = Ivy_ObjNextFanout(pObj, pFanout) ) |
| |
| // safe iterator through the fanouts of the node |
| #define Ivy_ObjForEachFanoutIntSafe( pObj, pFanout, pFanout2 ) \ |
| for ( pFanout = (pObj)->pFanout, \ |
| pFanout2 = Ivy_ObjNextFanout(pObj, pFanout); \ |
| pFanout; \ |
| pFanout = pFanout2, \ |
| pFanout2 = Ivy_ObjNextFanout(pObj, pFanout) ) |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Starts the fanout representation.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ManStartFanout( Ivy_Man_t * p ) |
| { |
| Ivy_Obj_t * pObj; |
| int i; |
| assert( !p->fFanout ); |
| p->fFanout = 1; |
| Ivy_ManForEachObj( p, pObj, i ) |
| { |
| if ( Ivy_ObjFanin0(pObj) ) |
| Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj ); |
| if ( Ivy_ObjFanin1(pObj) ) |
| Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Stops the fanout representation.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ManStopFanout( Ivy_Man_t * p ) |
| { |
| Ivy_Obj_t * pObj; |
| int i; |
| assert( p->fFanout ); |
| p->fFanout = 0; |
| Ivy_ManForEachObj( p, pObj, i ) |
| pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Add the fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ObjAddFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanout ) |
| { |
| assert( p->fFanout ); |
| if ( pFanin->pFanout ) |
| { |
| *Ivy_ObjNextFanoutPlace(pFanin, pFanout) = pFanin->pFanout; |
| *Ivy_ObjPrevFanoutPlace(pFanin, pFanin->pFanout) = pFanout; |
| } |
| pFanin->pFanout = pFanout; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Removes the fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanout ) |
| { |
| Ivy_Obj_t ** ppPlace1, ** ppPlace2, ** ppPlaceN; |
| assert( pFanin->pFanout != NULL ); |
| |
| ppPlace1 = Ivy_ObjNextFanoutPlace(pFanin, pFanout); |
| ppPlaceN = Ivy_ObjPrevNextFanoutPlace(pFanin, pFanout); |
| assert( *ppPlaceN == pFanout ); |
| if ( ppPlaceN ) |
| *ppPlaceN = *ppPlace1; |
| |
| ppPlace2 = Ivy_ObjPrevFanoutPlace(pFanin, pFanout); |
| ppPlaceN = Ivy_ObjNextPrevFanoutPlace(pFanin, pFanout); |
| assert( ppPlaceN == NULL || *ppPlaceN == pFanout ); |
| if ( ppPlaceN ) |
| *ppPlaceN = *ppPlace2; |
| |
| *ppPlace1 = NULL; |
| *ppPlace2 = NULL; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Replaces the fanout of pOld to be pFanoutNew.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanoutOld, Ivy_Obj_t * pFanoutNew ) |
| { |
| Ivy_Obj_t ** ppPlace; |
| ppPlace = Ivy_ObjPrevNextFanoutPlace(pFanin, pFanoutOld); |
| assert( *ppPlace == pFanoutOld ); |
| if ( ppPlace ) |
| *ppPlace = pFanoutNew; |
| ppPlace = Ivy_ObjNextPrevFanoutPlace(pFanin, pFanoutOld); |
| assert( ppPlace == NULL || *ppPlace == pFanoutOld ); |
| if ( ppPlace ) |
| *ppPlace = pFanoutNew; |
| // assuming that pFanoutNew already points to the next fanout |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Starts iteration through the fanouts.] |
| |
| Description [Copies the currently available fanouts into the array.] |
| |
| SideEffects [Can be used while the fanouts are being removed.] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray ) |
| { |
| Ivy_Obj_t * pFanout; |
| assert( p->fFanout ); |
| assert( !Ivy_IsComplement(pObj) ); |
| Vec_PtrClear( vArray ); |
| Ivy_ObjForEachFanoutInt( pObj, pFanout ) |
| Vec_PtrPush( vArray, pFanout ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reads one fanout.] |
| |
| Description [Returns fanout if there is only one fanout.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ) |
| { |
| return pObj->pFanout; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reads one fanout.] |
| |
| Description [Returns fanout if there is only one fanout.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ) |
| { |
| Ivy_Obj_t * pFanout; |
| int Counter = 0; |
| Ivy_ObjForEachFanoutInt( pObj, pFanout ) |
| Counter++; |
| return Counter; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |