blob: 9ff4f4bc308e57210c61e77bbe315468d48a0c5a [file] [log] [blame]
/**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