abcBridge-0.10.0.0: abc-build/src/base/abc/abcFanio.c
/**CFile****************************************************************
FileName [abcFanio.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Various procedures to connect fanins/fanouts.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_IntPushMem( Mem_Step_t * pMemMan, Vec_Int_t * p, int Entry )
{
if ( p->nSize == p->nCap )
{
int * pArray;
int i;
if ( p->nSize == 0 )
p->nCap = 1;
if ( pMemMan )
pArray = (int *)Mem_StepEntryFetch( pMemMan, p->nCap * 8 );
else
pArray = ABC_ALLOC( int, p->nCap * 2 );
if ( p->pArray )
{
for ( i = 0; i < p->nSize; i++ )
pArray[i] = p->pArray[i];
if ( pMemMan )
Mem_StepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
else
ABC_FREE( p->pArray );
}
p->nCap *= 2;
p->pArray = pArray;
}
p->pArray[p->nSize++] = Entry;
}
/**Function*************************************************************
Synopsis [Creates fanout/fanin relationship between the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pFaninR = Abc_ObjRegular(pFanin);
assert( !Abc_ObjIsComplement(pObj) );
assert( pObj->pNtk == pFaninR->pNtk );
assert( pObj->Id >= 0 && pFaninR->Id >= 0 );
assert( !Abc_ObjIsPi(pObj) && !Abc_ObjIsPo(pFaninR) ); // fanin of PI or fanout of PO
assert( !Abc_ObjIsCo(pObj) || !Abc_ObjFaninNum(pObj) ); // CO with two fanins
assert( !Abc_ObjIsNet(pObj) || !Abc_ObjFaninNum(pObj) ); // net with two fanins
Vec_IntPushMem( pObj->pNtk->pMmStep, &pObj->vFanins, pFaninR->Id );
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
}
/**Function*************************************************************
Synopsis [Destroys fanout/fanin relationship between the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
{
assert( !Abc_ObjIsComplement(pObj) );
assert( !Abc_ObjIsComplement(pFanin) );
assert( pObj->pNtk == pFanin->pNtk );
assert( pObj->Id >= 0 && pFanin->Id >= 0 );
if ( !Vec_IntRemove( &pObj->vFanins, pFanin->Id ) )
{
printf( "The obj %d is not found among the fanins of obj %d ...\n", pFanin->Id, pObj->Id );
return;
}
if ( !Vec_IntRemove( &pFanin->vFanouts, pObj->Id ) )
{
printf( "The obj %d is not found among the fanouts of obj %d ...\n", pObj->Id, pFanin->Id );
return;
}
}
/**Function*************************************************************
Synopsis [Destroys fanout/fanin relationship between the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRemoveFanins( Abc_Obj_t * pObj )
{
Vec_Int_t * vFaninsOld;
Abc_Obj_t * pFanin;
int k;
// remove old fanins
vFaninsOld = &pObj->vFanins;
for ( k = vFaninsOld->nSize - 1; k >= 0; k-- )
{
pFanin = Abc_NtkObj( pObj->pNtk, vFaninsOld->pArray[k] );
Abc_ObjDeleteFanin( pObj, pFanin );
}
pObj->fCompl0 = 0;
pObj->fCompl1 = 0;
assert( vFaninsOld->nSize == 0 );
}
/**Function*************************************************************
Synopsis [Replaces a fanin of the node.]
Description [The node is pObj. An old fanin of this node (pFaninOld) has to be
replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin
are not complemented. The new fanin can be complemented. In this case, the
polarity of the new fanin will change, compared to the polarity of the old fanin.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew )
{
Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew);
int iFanin;//, nLats;//, fCompl;
assert( !Abc_ObjIsComplement(pObj) );
assert( !Abc_ObjIsComplement(pFaninOld) );
assert( pFaninOld != pFaninNewR );
// assert( pObj != pFaninOld );
// assert( pObj != pFaninNewR );
assert( pObj->pNtk == pFaninOld->pNtk );
assert( pObj->pNtk == pFaninNewR->pNtk );
if ( (iFanin = Vec_IntFind( &pObj->vFanins, pFaninOld->Id )) == -1 )
{
printf( "Node %s is not among", Abc_ObjName(pFaninOld) );
printf( " the fanins of node %s...\n", Abc_ObjName(pObj) );
return;
}
// remember the attributes of the old fanin
// fCompl = Abc_ObjFaninC(pObj, iFanin);
// replace the old fanin entry by the new fanin entry (removes attributes)
Vec_IntWriteEntry( &pObj->vFanins, iFanin, pFaninNewR->Id );
// set the attributes of the new fanin
// if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) )
// Abc_ObjSetFaninC( pObj, iFanin );
if ( Abc_ObjIsComplement(pFaninNew) )
Abc_ObjXorFaninC( pObj, iFanin );
// if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) )
// Seq_ObjSetFaninL( pObj, iFanin, nLats );
// update the fanout of the fanin
if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) )
{
printf( "Node %s is not among", Abc_ObjName(pObj) );
printf( " the fanouts of its old fanin %s...\n", Abc_ObjName(pFaninOld) );
// return;
}
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, pObj->Id );
}
/**Function*************************************************************
Synopsis [Inserts one-input node of the type specified between the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type )
{
Abc_Obj_t * pNodeNew;
int iFanoutIndex, iFaninIndex;
// find pNodeOut among the fanouts of pNodeIn
if ( (iFanoutIndex = Vec_IntFind( &pNodeIn->vFanouts, pNodeOut->Id )) == -1 )
{
printf( "Node %s is not among", Abc_ObjName(pNodeOut) );
printf( " the fanouts of node %s...\n", Abc_ObjName(pNodeIn) );
return NULL;
}
// find pNodeIn among the fanins of pNodeOut
if ( (iFaninIndex = Vec_IntFind( &pNodeOut->vFanins, pNodeIn->Id )) == -1 )
{
printf( "Node %s is not among", Abc_ObjName(pNodeIn) );
printf( " the fanins of node %s...\n", Abc_ObjName(pNodeOut) );
return NULL;
}
// create the new node
pNodeNew = Abc_NtkCreateObj( pNodeIn->pNtk, Type );
// add pNodeIn as fanin and pNodeOut as fanout
Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanins, pNodeIn->Id );
Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanouts, pNodeOut->Id );
// update the fanout of pNodeIn
Vec_IntWriteEntry( &pNodeIn->vFanouts, iFanoutIndex, pNodeNew->Id );
// update the fanin of pNodeOut
Vec_IntWriteEntry( &pNodeOut->vFanins, iFaninIndex, pNodeNew->Id );
return pNodeNew;
}
/**Function*************************************************************
Synopsis [Transfers fanout from the old node to the new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
{
Vec_Ptr_t * vFanouts;
int nFanoutsOld, i;
assert( !Abc_ObjIsComplement(pNodeFrom) );
assert( !Abc_ObjIsComplement(pNodeTo) );
assert( !Abc_ObjIsPo(pNodeFrom) && !Abc_ObjIsPo(pNodeTo) );
assert( pNodeFrom->pNtk == pNodeTo->pNtk );
assert( pNodeFrom != pNodeTo );
assert( !Abc_ObjIsNode(pNodeFrom) || Abc_ObjFanoutNum(pNodeFrom) > 0 );
// get the fanouts of the old node
nFanoutsOld = Abc_ObjFanoutNum(pNodeTo);
vFanouts = Vec_PtrAlloc( nFanoutsOld );
Abc_NodeCollectFanouts( pNodeFrom, vFanouts );
// patch the fanin of each of them
for ( i = 0; i < vFanouts->nSize; i++ )
Abc_ObjPatchFanin( (Abc_Obj_t *)vFanouts->pArray[i], pNodeFrom, pNodeTo );
assert( Abc_ObjFanoutNum(pNodeFrom) == 0 );
assert( Abc_ObjFanoutNum(pNodeTo) == nFanoutsOld + vFanouts->nSize );
Vec_PtrFree( vFanouts );
}
/**Function*************************************************************
Synopsis [Replaces the node by a new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
{
assert( !Abc_ObjIsComplement(pNodeOld) );
assert( !Abc_ObjIsComplement(pNodeNew) );
assert( pNodeOld->pNtk == pNodeNew->pNtk );
assert( pNodeOld != pNodeNew );
assert( Abc_ObjFanoutNum(pNodeOld) > 0 );
// transfer the fanouts to the old node
Abc_ObjTransferFanout( pNodeOld, pNodeNew );
// remove the old node
Abc_NtkDeleteObj_rec( pNodeOld, 1 );
}
/**Function*************************************************************
Synopsis [Returns the index of the fanin in the fanin list of the fanout.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pObj;
int i;
Abc_ObjForEachFanin( pFanout, pObj, i )
if ( pObj == pFanin )
return i;
return -1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END