summaryrefslogtreecommitdiffstats
path: root/src/abc8/aig/aigObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/abc8/aig/aigObj.c')
-rw-r--r--src/abc8/aig/aigObj.c431
1 files changed, 431 insertions, 0 deletions
diff --git a/src/abc8/aig/aigObj.c b/src/abc8/aig/aigObj.c
new file mode 100644
index 00000000..80838e19
--- /dev/null
+++ b/src/abc8/aig/aigObj.c
@@ -0,0 +1,431 @@
+/**CFile****************************************************************
+
+ FileName [aigObj.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [AIG package.]
+
+ Synopsis [Adding/removing objects.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - April 28, 2007.]
+
+ Revision [$Id: aigObj.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary input.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = AIG_OBJ_PI;
+ Vec_PtrPush( p->vPis, pObj );
+ p->nObjs[AIG_OBJ_PI]++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary output with the given driver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver )
+{
+ Aig_Obj_t * pObj;
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = AIG_OBJ_PO;
+ Vec_PtrPush( p->vPos, pObj );
+ Aig_ObjConnect( p, pObj, pDriver, NULL );
+ p->nObjs[AIG_OBJ_PO]++;
+ return pObj;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node assuming it does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
+{
+ Aig_Obj_t * pObj;
+ assert( !Aig_IsComplement(pGhost) );
+ assert( Aig_ObjIsHash(pGhost) );
+// assert( pGhost == &p->Ghost );
+ // get memory for the new object
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = pGhost->Type;
+ // add connections
+ Aig_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
+ // update node counters of the manager
+ p->nObjs[Aig_ObjType(pObj)]++;
+ assert( pObj->pData == NULL );
+ if ( p->pManHaig )
+ {
+ pGhost->pFanin0 = Aig_ObjHaig( pGhost->pFanin0 );
+ pGhost->pFanin1 = Aig_ObjHaig( pGhost->pFanin1 );
+ pObj->pHaig = Aig_ObjCreate( p->pManHaig, pGhost );
+ }
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the object to the fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( !Aig_ObjIsPi(pObj) );
+ // add the first fanin
+ pObj->pFanin0 = pFan0;
+ pObj->pFanin1 = pFan1;
+ // increment references of the fanins and add their fanouts
+ if ( pFan0 != NULL )
+ {
+ assert( Aig_ObjFanin0(pObj)->Type > 0 );
+ Aig_ObjRef( Aig_ObjFanin0(pObj) );
+ if ( p->pFanData )
+ Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj );
+ }
+ if ( pFan1 != NULL )
+ {
+ assert( Aig_ObjFanin1(pObj)->Type > 0 );
+ Aig_ObjRef( Aig_ObjFanin1(pObj) );
+ if ( p->pFanData )
+ Aig_ObjAddFanout( p, Aig_ObjFanin1(pObj), pObj );
+ }
+ // set level and phase
+ pObj->Level = Aig_ObjLevelNew( pObj );
+ pObj->fPhase = Aig_ObjPhaseReal(pFan0) & Aig_ObjPhaseReal(pFan1);
+ // add the node to the structural hash table
+ if ( Aig_ObjIsHash(pObj) )
+ Aig_TableInsert( p, pObj );
+ // add the node to the dynamically updated topological order
+// if ( p->pOrderData && Aig_ObjIsNode(pObj) )
+// Aig_ObjOrderInsert( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Disconnects the object from the fanins.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ // remove connections
+ if ( pObj->pFanin0 != NULL )
+ {
+ if ( p->pFanData )
+ Aig_ObjRemoveFanout( p, Aig_ObjFanin0(pObj), pObj );
+ Aig_ObjDeref(Aig_ObjFanin0(pObj));
+ }
+ if ( pObj->pFanin1 != NULL )
+ {
+ if ( p->pFanData )
+ Aig_ObjRemoveFanout( p, Aig_ObjFanin1(pObj), pObj );
+ Aig_ObjDeref(Aig_ObjFanin1(pObj));
+ }
+ // remove the node from the structural hash table
+ if ( Aig_ObjIsHash(pObj) )
+ Aig_TableDelete( p, pObj );
+ // add the first fanin
+ pObj->pFanin0 = NULL;
+ pObj->pFanin1 = NULL;
+ // remove the node from the dynamically updated topological order
+// if ( p->pOrderData && Aig_ObjIsNode(pObj) )
+// Aig_ObjOrderRemove( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( !Aig_ObjIsTerm(pObj) );
+ assert( Aig_ObjRefs(pObj) == 0 );
+ if ( p->pFanData && Aig_ObjIsBuf(pObj) )
+ Vec_PtrRemove( p->vBufs, pObj );
+ p->nObjs[pObj->Type]--;
+ Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
+ Aig_ManRecycleMemory( p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int fFreeTop )
+{
+ Aig_Obj_t * pFanin0, * pFanin1;
+ assert( !Aig_IsComplement(pObj) );
+ if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
+ return;
+ assert( !Aig_ObjIsPo(pObj) );
+ pFanin0 = Aig_ObjFanin0(pObj);
+ pFanin1 = Aig_ObjFanin1(pObj);
+ Aig_ObjDisconnect( p, pObj );
+ if ( fFreeTop )
+ Aig_ObjDelete( p, pObj );
+ if ( pFanin0 && !Aig_ObjIsNone(pFanin0) && Aig_ObjRefs(pFanin0) == 0 )
+ Aig_ObjDelete_rec( p, pFanin0, 1 );
+ if ( pFanin1 && !Aig_ObjIsNone(pFanin1) && Aig_ObjRefs(pFanin1) == 0 )
+ Aig_ObjDelete_rec( p, pFanin1, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces the first fanin of the node by the new fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjPatchFanin0( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFaninNew )
+{
+ Aig_Obj_t * pFaninOld;
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsPo(pObj) );
+ pFaninOld = Aig_ObjFanin0(pObj);
+ // decrement ref and remove fanout
+ if ( p->pFanData )
+ Aig_ObjRemoveFanout( p, pFaninOld, pObj );
+ Aig_ObjDeref( pFaninOld );
+ // update the fanin
+ pObj->pFanin0 = pFaninNew;
+ // increment ref and add fanout
+ if ( p->pFanData )
+ Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj );
+ Aig_ObjRef( Aig_ObjFanin0(pObj) );
+ // get rid of old fanin
+ if ( !Aig_ObjIsPi(pFaninOld) && !Aig_ObjIsConst1(pFaninOld) && Aig_ObjRefs(pFaninOld) == 0 )
+ Aig_ObjDelete_rec( p, pFaninOld, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces node with a buffer fanin by a node without them.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_NodeFixBufferFanins( Aig_Man_t * p, Aig_Obj_t * pObj, int fNodesOnly, int fUpdateLevel )
+{
+ Aig_Obj_t * pFanReal0, * pFanReal1, * pResult;
+ p->nBufFixes++;
+ if ( Aig_ObjIsPo(pObj) )
+ {
+ assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) );
+ pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
+ assert( Aig_ObjPhaseReal(Aig_ObjChild0(pObj)) == Aig_ObjPhaseReal(pFanReal0) );
+ Aig_ObjPatchFanin0( p, pObj, pFanReal0 );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) || Aig_ObjIsBuf(Aig_ObjFanin1(pObj)) );
+ // get the real fanins
+ pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
+ pFanReal1 = Aig_ObjReal_rec( Aig_ObjChild1(pObj) );
+ // get the new node
+ if ( Aig_ObjIsNode(pObj) )
+ pResult = Aig_Oper( p, pFanReal0, pFanReal1, Aig_ObjType(pObj) );
+// else if ( Aig_ObjIsLatch(pObj) )
+// pResult = Aig_Latch( p, pFanReal0, Aig_ObjInit(pObj) );
+ else
+ assert( 0 );
+ // replace the node with buffer by the node without buffer
+ Aig_ObjReplace( p, pObj, pResult, fNodesOnly, fUpdateLevel );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of dangling nodes removed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ManPropagateBuffers( Aig_Man_t * p, int fNodesOnly, int fUpdateLevel )
+{
+ Aig_Obj_t * pObj;
+ int nSteps;
+ assert( p->pFanData );
+ for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
+ {
+ // get the node with a buffer fanin
+ for ( pObj = Vec_PtrEntryLast(p->vBufs); Aig_ObjIsBuf(pObj); pObj = Aig_ObjFanout0(p, pObj) );
+ // replace this node by a node without buffer
+ Aig_NodeFixBufferFanins( p, pObj, fNodesOnly, fUpdateLevel );
+ // stop if a cycle occured
+ if ( nSteps > 1000000 )
+ {
+ printf( "Error: A cycle is encountered while propagating buffers.\n" );
+ break;
+ }
+ }
+ return nSteps;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces one object by another.]
+
+ Description [The new object (pObjNew) should be used instead of the old
+ object (pObjOld). If the new object is complemented or used, the buffer
+ is added and the new object remains in the manager; otherwise, the new
+ object is deleted.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjReplace( Aig_Man_t * p, Aig_Obj_t * pObjOld, Aig_Obj_t * pObjNew, int fNodesOnly, int fUpdateLevel )
+{
+ Aig_Obj_t * pObjNewR = Aig_Regular(pObjNew);
+ // the object to be replaced cannot be complemented
+ assert( !Aig_IsComplement(pObjOld) );
+ // the object to be replaced cannot be a terminal
+ assert( !Aig_ObjIsPi(pObjOld) && !Aig_ObjIsPo(pObjOld) );
+ // the object to be used cannot be a buffer or a PO
+ assert( !Aig_ObjIsBuf(pObjNewR) && !Aig_ObjIsPo(pObjNewR) );
+ // the object cannot be the same
+ assert( pObjOld != pObjNewR );
+ // make sure object is not pointing to itself
+ assert( pObjOld != Aig_ObjFanin0(pObjNewR) );
+ assert( pObjOld != Aig_ObjFanin1(pObjNewR) );
+ // map the HAIG nodes
+ if ( p->pManHaig != NULL )
+ {
+ assert( pObjNewR->pHaig != NULL );
+ assert( pObjNewR->pHaig->pHaig == NULL );
+ pObjNewR->pHaig->pHaig = pObjOld->pHaig;
+ }
+ // recursively delete the old node - but leave the object there
+ pObjNewR->nRefs++;
+ Aig_ObjDelete_rec( p, pObjOld, 0 );
+ pObjNewR->nRefs--;
+ // if the new object is complemented or already used, create a buffer
+ p->nObjs[pObjOld->Type]--;
+ if ( Aig_IsComplement(pObjNew) || Aig_ObjRefs(pObjNew) > 0 || (fNodesOnly && !Aig_ObjIsNode(pObjNew)) )
+ {
+ pObjOld->Type = AIG_OBJ_BUF;
+ Aig_ObjConnect( p, pObjOld, pObjNew, NULL );
+ p->nBufReplaces++;
+ }
+ else
+ {
+ Aig_Obj_t * pFanin0 = pObjNew->pFanin0;
+ Aig_Obj_t * pFanin1 = pObjNew->pFanin1;
+ int LevelOld = pObjOld->Level;
+ pObjOld->Type = pObjNew->Type;
+ Aig_ObjDisconnect( p, pObjNew );
+ Aig_ObjConnect( p, pObjOld, pFanin0, pFanin1 );
+ // update the haig node
+ pObjOld->pHaig = pObjNew->pHaig;
+ // delete the new object
+ Aig_ObjDelete( p, pObjNew );
+ // update levels
+ if ( p->pFanData )
+ {
+ pObjOld->Level = LevelOld;
+ Aig_ManUpdateLevel( p, pObjOld );
+ }
+ if ( fUpdateLevel )
+ {
+ Aig_ObjClearReverseLevel( p, pObjOld );
+ Aig_ManUpdateReverseLevel( p, pObjOld );
+ }
+ }
+ p->nObjs[pObjOld->Type]++;
+ // store buffers if fanout is allocated
+ if ( p->pFanData && Aig_ObjIsBuf(pObjOld) )
+ {
+ Vec_PtrPush( p->vBufs, pObjOld );
+ p->nBufMax = AIG_MAX( p->nBufMax, Vec_PtrSize(p->vBufs) );
+ Aig_ManPropagateBuffers( p, fNodesOnly, fUpdateLevel );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+