abc/src/sat/aig/aigNode.c

317 lines
9.4 KiB
C

/**CFile****************************************************************
FileName [aigNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Aig_Node_t * Aig_NodeCreate( Aig_Man_t * p )
{
Aig_Node_t * pNode;
// create the node
pNode = (Aig_Node_t *)Aig_MemFixedEntryFetch( p->mmNodes );
memset( pNode, 0, sizeof(Aig_Node_t) );
// assign the number and add to the array of nodes
pNode->pMan = p;
pNode->Id = p->vNodes->nSize;
Vec_PtrPush( p->vNodes, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Creates the constant 1 node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreateConst( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_NONE;
pNode->fPhase = 1; // sim value for 000... pattern
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary input node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreatePi( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
Vec_PtrPush( p->vPis, pNode );
pNode->Type = AIG_PI;
pNode->fPhase = 0; // sim value for 000... pattern
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary output node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreatePo( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_PO;
Vec_PtrPush( p->vPos, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary output node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeConnectPo( Aig_Man_t * p, Aig_Node_t * pNode, Aig_Node_t * pFanin )
{
assert( Aig_NodeIsPo(pNode) );
assert( !Aig_IsComplement(pNode) );
// connect to the fanin
pNode->Fans[0].fComp = Aig_IsComplement(pFanin);
pNode->Fans[0].iNode = Aig_Regular(pFanin)->Id;
pNode->fPhase = pNode->Fans[0].fComp ^ Aig_Regular(pFanin)->fPhase; // sim value for 000... pattern
pNode->Level = Aig_Regular(pFanin)->Level;
Aig_Regular(pFanin)->nRefs++;
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin, pNode );
// update global level if needed
if ( p->nLevelMax < (int)pNode->Level )
p->nLevelMax = pNode->Level;
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreateAnd( Aig_Man_t * p, Aig_Node_t * pFanin0, Aig_Node_t * pFanin1 )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_AND;
Aig_NodeConnectAnd( pFanin0, pFanin1, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Connects the nodes to the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeConnectAnd( Aig_Node_t * pFanin0, Aig_Node_t * pFanin1, Aig_Node_t * pNode )
{
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsAnd(pNode) );
// add the fanins
pNode->Fans[0].fComp = Aig_IsComplement(pFanin0);
pNode->Fans[0].iNode = Aig_Regular(pFanin0)->Id;
pNode->Fans[1].fComp = Aig_IsComplement(pFanin1);
pNode->Fans[1].iNode = Aig_Regular(pFanin1)->Id;
// compute the phase (sim value for 000... pattern)
pNode->fPhase = (pNode->Fans[0].fComp ^ Aig_Regular(pFanin0)->fPhase) &
(pNode->Fans[1].fComp ^ Aig_Regular(pFanin1)->fPhase);
pNode->Level = Aig_NodeGetLevelNew(pNode);
// reference the fanins
Aig_Regular(pFanin0)->nRefs++;
Aig_Regular(pFanin1)->nRefs++;
// add the fanouts
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin0, pNode );
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin1, pNode );
// add the node to the structural hash table
Aig_TableInsertNode( pNode->pMan, pFanin0, pFanin1, pNode );
}
/**Function*************************************************************
Synopsis [Connects the nodes to the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeDisconnectAnd( Aig_Node_t * pNode )
{
Aig_Node_t * pFanin0, * pFanin1;
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsAnd(pNode) );
// get the fanins
pFanin0 = Aig_NodeFanin0(pNode);
pFanin1 = Aig_NodeFanin1(pNode);
// dereference the fanins
pFanin0->nRefs--;
pFanin0->nRefs--;
// remove the fanouts
if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin0, pNode );
if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin1, pNode );
// remove the node from the structural hash table
Aig_TableDeleteNode( pNode->pMan, pNode );
}
/**Function*************************************************************
Synopsis [Performs internal deletion step.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeDeleteAnd_rec( Aig_Man_t * pMan, Aig_Node_t * pRoot )
{
Aig_Node_t * pNode0, * pNode1;
// make sure the node is regular and dangling
assert( !Aig_IsComplement(pRoot) );
assert( pRoot->nRefs == 0 );
assert( Aig_NodeIsAnd(pRoot) );
// remember the children
pNode0 = Aig_NodeFanin0(pRoot);
pNode1 = Aig_NodeFanin1(pRoot);
// disconnect the node
Aig_NodeDisconnectAnd( pRoot );
// recycle the node
Vec_PtrWriteEntry( pMan->vNodes, pRoot->Id, NULL );
memset( pRoot, 0, sizeof(Aig_Node_t) ); // this is a temporary hack to skip dead children below!!!
Aig_MemFixedEntryRecycle( pMan->mmNodes, (char *)pRoot );
// call recursively
if ( Aig_NodeIsAnd(pNode0) && pNode0->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pNode0 );
if ( Aig_NodeIsAnd(pNode1) && pNode1->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pNode1 );
}
/**Function*************************************************************
Synopsis [Prints the AIG node for debugging purposes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodePrint( Aig_Node_t * pNode )
{
Aig_Node_t * pNodeR = Aig_Regular(pNode);
if ( Aig_NodeIsPi(pNode) )
{
printf( "PI %4s%s.\n", Aig_NodeName(pNode), Aig_IsComplement(pNode)? "\'" : "" );
return;
}
if ( Aig_NodeIsConst(pNode) )
{
printf( "Constant 1 %s.\n", Aig_IsComplement(pNode)? "(complemented)" : "" );
return;
}
// print the node's function
printf( "%7s%s", Aig_NodeName(pNodeR), Aig_IsComplement(pNode)? "\'" : "" );
printf( " = " );
printf( "%7s%s", Aig_NodeName(Aig_NodeFanin0(pNodeR)), Aig_NodeFaninC0(pNodeR)? "\'" : "" );
printf( " * " );
printf( "%7s%s", Aig_NodeName(Aig_NodeFanin1(pNodeR)), Aig_NodeFaninC1(pNodeR)? "\'" : "" );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Returns the name of the node.]
Description [The name should be used before this procedure is called again.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Aig_NodeName( Aig_Node_t * pNode )
{
static char Buffer[100];
sprintf( Buffer, "%d", Aig_Regular(pNode)->Id );
return Buffer;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////