diff options
Diffstat (limited to 'src/aig/gia/giaLogic.c')
-rw-r--r-- | src/aig/gia/giaLogic.c | 725 |
1 files changed, 725 insertions, 0 deletions
diff --git a/src/aig/gia/giaLogic.c b/src/aig/gia/giaLogic.c new file mode 100644 index 00000000..825cec02 --- /dev/null +++ b/src/aig/gia/giaLogic.c @@ -0,0 +1,725 @@ +/**CFile**************************************************************** + + FileName [giaLogic.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Logic network derived from AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaLogic.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <math.h> +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Log_Obj_t_ Log_Obj_t; +struct Log_Obj_t_ +{ + unsigned fTerm : 1; // terminal node (CI/CO) + unsigned fMark0 : 1; // first user-controlled mark + unsigned fMark1 : 1; // second user-controlled mark + unsigned nFanins : 28; // the number of fanins + unsigned nFanouts; // the number of fanouts + unsigned hHandle; // the handle of the node + union { + unsigned TravId; // user-specified value + unsigned iFanin; + }; + union { + unsigned Value; // user-specified value + unsigned iFanout; + }; + int Fanios[0]; // the array of fanins/fanouts +}; + +typedef struct Log_Man_t_ Log_Man_t; +struct Log_Man_t_ +{ + Gia_Man_t * pGia; // the original AIG manager + Vec_Int_t * vCis; // the vector of CIs (PIs + LOs) + Vec_Int_t * vCos; // the vector of COs (POs + LIs) + int nObjs; // the number of objects + int nNodes; // the number of nodes + int nTravIds; // traversal ID of the network + int * pObjData; // the array containing data for objects + int nObjData; // the size of array to store the logic network +}; + +static inline int Log_ManCiNum( Log_Man_t * p ) { return Vec_IntSize(p->vCis); } +static inline int Log_ManCoNum( Log_Man_t * p ) { return Vec_IntSize(p->vCos); } +static inline int Log_ManObjNum( Log_Man_t * p ) { return p->nObjs; } +static inline int Log_ManNodeNum( Log_Man_t * p ) { return p->nNodes; } + +static inline Log_Obj_t * Log_ManObj( Log_Man_t * p, unsigned hHandle ) { return (Log_Obj_t *)(p->pObjData + hHandle); } +static inline Log_Obj_t * Log_ManCi( Log_Man_t * p, int i ) { return Log_ManObj( p, Vec_IntEntry(p->vCis,i) ); } +static inline Log_Obj_t * Log_ManCo( Log_Man_t * p, int i ) { return Log_ManObj( p, Vec_IntEntry(p->vCos,i) ); } + +static inline int Log_ObjIsTerm( Log_Obj_t * pObj ) { return pObj->fTerm; } +static inline int Log_ObjIsCi( Log_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 0; } +static inline int Log_ObjIsCo( Log_Obj_t * pObj ) { return pObj->fTerm && pObj->nFanins == 1; } +static inline int Log_ObjIsNode( Log_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins > 0; } +static inline int Log_ObjIsConst0( Log_Obj_t * pObj ) { return!pObj->fTerm && pObj->nFanins == 0; } + +static inline int Log_ObjFaninNum( Log_Obj_t * pObj ) { return pObj->nFanins; } +static inline int Log_ObjFanoutNum( Log_Obj_t * pObj ) { return pObj->nFanouts; } +static inline int Log_ObjSize( Log_Obj_t * pObj ) { return sizeof(Log_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts; } +static inline Log_Obj_t * Log_ObjFanin( Log_Obj_t * pObj, int i ) { return (Log_Obj_t *)(((int *)pObj) - pObj->Fanios[i]); } +static inline Log_Obj_t * Log_ObjFanout( Log_Obj_t * pObj, int i ) { return (Log_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); } + +static inline void Log_ManResetTravId( Log_Man_t * p ) { extern void Log_ManCleanTravId( Log_Man_t * p ); Log_ManCleanTravId( p ); p->nTravIds = 1; } +static inline void Log_ManIncrementTravId( Log_Man_t * p ) { p->nTravIds++; } +static inline void Log_ObjSetTravId( Log_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; } +static inline void Log_ObjSetTravIdCurrent( Log_Man_t * p, Log_Obj_t * pObj ) { pObj->TravId = p->nTravIds; } +static inline void Log_ObjSetTravIdPrevious( Log_Man_t * p, Log_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1; } +static inline int Log_ObjIsTravIdCurrent( Log_Man_t * p, Log_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds); } +static inline int Log_ObjIsTravIdPrevious( Log_Man_t * p, Log_Obj_t * pObj ) { return ((int)pObj->TravId == p->nTravIds - 1); } + +#define Log_ManForEachObj( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Log_ManObj(p,i)); i += Log_ObjSize(pObj) ) +#define Log_ManForEachNode( p, pObj, i ) \ + for ( i = 0; (i < p->nObjData) && (pObj = Log_ManObj(p,i)); i += Log_ObjSize(pObj) ) if ( Log_ObjIsTerm(pObj) ) {} else +#define Log_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Log_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Log_ObjForEachFanin( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Log_ObjFanin(pObj,i)); i++ ) +#define Log_ObjForEachFanout( pObj, pNext, i ) \ + for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Log_ObjFanout(pObj,i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collect the fanin IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) +{ + if ( pObj->fMark0 ) + { + Vec_IntPushUnique( vSuper, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Log_ManCollectSuper( p, Gia_ObjFanin0(pObj), vSuper ); + Log_ManCollectSuper( p, Gia_ObjFanin1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCreateRefsSpecial( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + Gia_Obj_t * pObjC, * pObjD0, * pObjD1; + int i; + assert( p->pRefs == NULL ); + Gia_ManCleanMark0( p ); + Gia_ManCreateRefs( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + assert( pObj->fMark0 == 0 ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + // skip nodes whose fanins are PIs or are already marked + if ( Gia_ObjIsCi(pFan0) || pFan0->fMark0 || + Gia_ObjIsCi(pFan1) || pFan1->fMark0 ) + continue; + // skip nodes that are not MUX type + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + // the node is MUX type, mark it and its fanins + pObj->fMark0 = 1; + pFan0->fMark0 = 1; + pFan1->fMark0 = 1; + // deref the control + pObjC = Gia_ObjRecognizeMux( pObj, &pObjD1, &pObjD0 ); + Gia_ObjRefDec( p, Gia_Regular(pObjC) ); + if ( Gia_Regular(pObjD0) == Gia_Regular(pObjD1) ) + Gia_ObjRefDec( p, Gia_Regular(pObjD0) ); + } + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjRefs(p, pObj) > 0 ); + Gia_ManCleanMark0( p ); +} + +/**Function************************************************************* + + Synopsis [Assigns references while removing the MUX/XOR ones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManTransformRefs( Gia_Man_t * p, int * pnObjs, int * pnFanios ) +{ + Vec_Int_t * vSuper; + Gia_Obj_t * pObj, * pFanin; + int i, k, Counter; + assert( p->pRefs != NULL ); + + // mark nodes to be used in the logic network + Gia_ManCleanMark0( p ); + Gia_ManConst0(p)->fMark0 = 1; + // mark the inputs + Gia_ManForEachCi( p, pObj, i ) + pObj->fMark0 = 1; + // mark those nodes that have ref count more than 1 + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjRefs(p, pObj) > 1); + // mark the output drivers + Gia_ManForEachCoDriver( p, pObj, i ) + pObj->fMark0 = 1; + + // count the number of nodes + Counter = 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += pObj->fMark0; + *pnObjs = Counter + Gia_ManCoNum(p); + + // reset the references + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + // reference from internal nodes + Counter = 0; + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( pObj->fMark0 == 0 ) + continue; + Vec_IntClear( vSuper ); + pObj->fMark0 = 0; + Log_ManCollectSuper( p, pObj, vSuper ); + pObj->fMark0 = 1; + Gia_ManForEachObjVec( vSuper, p, pFanin, k ) + { + assert( pFanin->fMark0 ); + Gia_ObjRefInc( p, pFanin ); + } + Counter += Vec_IntSize( vSuper ); + } + Vec_IntFree( vSuper ); + // reference from outputs + Gia_ManForEachCoDriver( p, pObj, i ) + { + assert( pObj->fMark0 ); + Gia_ObjRefInc( p, pObj ); + } + *pnFanios = Counter + Gia_ManCoNum(p); +} + +/**Function************************************************************* + + Synopsis [Creates fanin/fanout pair.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ObjAddFanin( Log_Obj_t * pObj, Log_Obj_t * pFanin ) +{ + assert( pObj->iFanin < pObj->nFanins ); + assert( pFanin->iFanout < pFanin->nFanouts ); + pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] = + pObj->Fanios[pObj->iFanin++] = pObj->hHandle - pFanin->hHandle; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Log_Man_t * Log_ManStart( Gia_Man_t * pGia ) +{ + Log_Man_t * p; + Log_Obj_t * pObjLog, * pFanLog; + Gia_Obj_t * pObj, * pFanin; + Vec_Int_t * vSuper; + int nObjs, nFanios; + int i, k, hHandle = 0; + // prepare the AIG +// Gia_ManCreateRefs( pGia ); + Log_ManCreateRefsSpecial( pGia ); + Log_ManTransformRefs( pGia, &nObjs, &nFanios ); + Gia_ManFillValue( pGia ); + // create logic network + p = ABC_CALLOC( Log_Man_t, 1 ); + p->pGia = pGia; + p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); + p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); + p->nObjData = (sizeof(Log_Obj_t) / 4) * nObjs + 2 * nFanios; + p->pObjData = ABC_CALLOC( int, p->nObjData ); + // create constant node + Gia_ManConst0(pGia)->Value = hHandle; + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, Gia_ManConst0(pGia) ); + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nNodes++; + p->nObjs++; + // create the PIs + Gia_ManForEachCi( pGia, pObj, i ) + { + // create PI object + pObj->Value = hHandle; + Vec_IntPush( p->vCis, hHandle ); + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 0; + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + pObjLog->fTerm = 1; + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nObjs++; + } + // create internal nodes + vSuper = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( pGia, pObj, i ) + { + if ( pObj->fMark0 == 0 ) + { + assert( Gia_ObjRefs( pGia, pObj ) == 0 ); + continue; + } + assert( Gia_ObjRefs( pGia, pObj ) > 0 ); + // collect fanins + Vec_IntClear( vSuper ); + pObj->fMark0 = 0; + Log_ManCollectSuper( pGia, pObj, vSuper ); + pObj->fMark0 = 1; + // create node object + pObj->Value = hHandle; + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = Vec_IntSize( vSuper ); + pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); + // add fanins + Gia_ManForEachObjVec( vSuper, pGia, pFanin, k ) + { + pFanLog = Log_ManObj( p, Gia_ObjValue(pFanin) ); + Log_ObjAddFanin( pObjLog, pFanLog ); + } + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nNodes++; + p->nObjs++; + } + Vec_IntFree( vSuper ); + // create the POs + Gia_ManForEachCo( pGia, pObj, i ) + { + // create PO object + pObj->Value = hHandle; + Vec_IntPush( p->vCos, hHandle ); + pObjLog = Log_ManObj( p, hHandle ); + pObjLog->hHandle = hHandle; + pObjLog->nFanins = 1; + pObjLog->nFanouts = 0; + pObjLog->fTerm = 1; + // add fanins + pFanLog = Log_ManObj( p, Gia_ObjValue(Gia_ObjFanin0(pObj)) ); + Log_ObjAddFanin( pObjLog, pFanLog ); + // count objects + hHandle += Log_ObjSize( pObjLog ); + p->nObjs++; + } + Gia_ManCleanMark0( pGia ); + assert( nObjs == p->nObjs ); + assert( hHandle == p->nObjData ); + // make sure the fanin/fanout counters are correct + Gia_ManForEachObj( pGia, pObj, i ) + { + if ( !~Gia_ObjValue(pObj) ) + continue; + pObjLog = Log_ManObj( p, Gia_ObjValue(pObj) ); + assert( pObjLog->nFanins == pObjLog->iFanin ); + assert( pObjLog->nFanouts == pObjLog->iFanout ); + pObjLog->iFanin = pObjLog->iFanout = 0; + } + ABC_FREE( pGia->pRefs ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManPrintStats( Log_Man_t * p ) +{ +// if ( p->pName ) +// printf( "%8s : ", p->pName ); + printf( "i/o =%7d/%7d ", Log_ManCiNum(p), Log_ManCoNum(p) ); +// if ( Log_ManRegNum(p) ) +// printf( "ff =%7d ", Log_ManRegNum(p) ); + printf( "node =%8d ", Log_ManNodeNum(p) ); +// printf( "lev =%5d ", Log_ManLevelNum(p) ); +// printf( "cut =%5d ", Log_ManCrossCut(p) ); + printf( "mem =%5.2f Mb", 4.0*p->nObjData/(1<<20) ); +// printf( "obj =%5d ", Log_ManObjNum(p) ); + printf( "\n" ); + +// Log_ManSatExperiment( p ); +} + +/**Function************************************************************* + + Synopsis [Creates logic network isomorphic to the given AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManStop( Log_Man_t * p ) +{ + Vec_IntFree( p->vCis ); + Vec_IntFree( p->vCos ); + ABC_FREE( p->pObjData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCleanTravId( Log_Man_t * p ) +{ + Log_Obj_t * pObj; + int i; + Log_ManForEachObj( p, pObj, i ) + pObj->TravId = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManCleanValue( Log_Man_t * p ) +{ + Log_Obj_t * pObj; + int i; + Log_ManForEachObj( p, pObj, i ) + pObj->Value = 0; +} + +/**Function************************************************************* + + Synopsis [Prints the distribution of fanins/fanouts in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Log_ManPrintFanio( Log_Man_t * p ) +{ + char Buffer[100]; + Log_Obj_t * pNode; + Vec_Int_t * vFanins, * vFanouts; + int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll; + int i, k, nSizeMax; + + // determine the largest fanin and fanout + nFaninsMax = nFanoutsMax = 0; + nFaninsAll = nFanoutsAll = 0; + Log_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; // skip const 0 obj + nFanins = Log_ObjFaninNum(pNode); + nFanouts = Log_ObjFanoutNum(pNode); + nFaninsAll += nFanins; + nFanoutsAll += nFanouts; + nFaninsMax = ABC_MAX( nFaninsMax, nFanins ); + nFanoutsMax = ABC_MAX( nFanoutsMax, nFanouts ); + } + + // allocate storage for fanin/fanout numbers + nSizeMax = AIG_MAX( 10 * (Aig_Base10Log(nFaninsMax) + 1), 10 * (Aig_Base10Log(nFanoutsMax) + 1) ); + vFanins = Vec_IntStart( nSizeMax ); + vFanouts = Vec_IntStart( nSizeMax ); + + // count the number of fanins and fanouts + Log_ManForEachNode( p, pNode, i ) + { + if ( i == 0 ) continue; // skip const 0 obj + nFanins = Log_ObjFaninNum(pNode); + nFanouts = Log_ObjFanoutNum(pNode); + + if ( nFanins < 10 ) + Vec_IntAddToEntry( vFanins, nFanins, 1 ); + else if ( nFanins < 100 ) + Vec_IntAddToEntry( vFanins, 10 + nFanins/10, 1 ); + else if ( nFanins < 1000 ) + Vec_IntAddToEntry( vFanins, 20 + nFanins/100, 1 ); + else if ( nFanins < 10000 ) + Vec_IntAddToEntry( vFanins, 30 + nFanins/1000, 1 ); + else if ( nFanins < 100000 ) + Vec_IntAddToEntry( vFanins, 40 + nFanins/10000, 1 ); + else if ( nFanins < 1000000 ) + Vec_IntAddToEntry( vFanins, 50 + nFanins/100000, 1 ); + else if ( nFanins < 10000000 ) + Vec_IntAddToEntry( vFanins, 60 + nFanins/1000000, 1 ); + + if ( nFanouts < 10 ) + Vec_IntAddToEntry( vFanouts, nFanouts, 1 ); + else if ( nFanouts < 100 ) + Vec_IntAddToEntry( vFanouts, 10 + nFanouts/10, 1 ); + else if ( nFanouts < 1000 ) + Vec_IntAddToEntry( vFanouts, 20 + nFanouts/100, 1 ); + else if ( nFanouts < 10000 ) + Vec_IntAddToEntry( vFanouts, 30 + nFanouts/1000, 1 ); + else if ( nFanouts < 100000 ) + Vec_IntAddToEntry( vFanouts, 40 + nFanouts/10000, 1 ); + else if ( nFanouts < 1000000 ) + Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 ); + else if ( nFanouts < 10000000 ) + Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 ); + } + + printf( "The distribution of fanins and fanouts in the network:\n" ); + printf( " Number Nodes with fanin Nodes with fanout\n" ); + for ( k = 0; k < nSizeMax; k++ ) + { + if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) + continue; + if ( k < 10 ) + printf( "%15d : ", k ); + else + { + sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + printf( "%15s : ", Buffer ); + } + if ( vFanins->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanins->pArray[k] ); + printf( " " ); + if ( vFanouts->pArray[k] == 0 ) + printf( " " ); + else + printf( "%12d ", vFanouts->pArray[k] ); + printf( "\n" ); + } + Vec_IntFree( vFanins ); + Vec_IntFree( vFanouts ); + + printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f.\n", + nFaninsMax, 1.0*nFaninsAll/Log_ManNodeNum(p), + nFanoutsMax, 1.0*nFanoutsAll/Log_ManNodeNum(p) ); +} + +/**Function************************************************************* + + Synopsis [Computes the distance from the given object] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Log_ManComputeDistance( Log_Man_t * p, Log_Obj_t * pPivot ) +{ + Vec_Int_t * vThis, * vNext, * vTemp; + Log_Obj_t * pThis, * pNext; + int i, k, d, nVisited = 0; +// assert( Log_ObjIsTerm(pPivot) ); + vThis = Vec_IntAlloc( 1000 ); + vNext = Vec_IntAlloc( 1000 ); + Log_ManIncrementTravId( p ); + Log_ObjSetTravIdCurrent( p, pPivot ); + Vec_IntPush( vThis, pPivot->hHandle ); + for ( d = 0; Vec_IntSize(vThis) > 0; d++ ) + { + nVisited += Vec_IntSize(vThis); + Vec_IntClear( vNext ); + Log_ManForEachObjVec( vThis, p, pThis, i ) + { + Log_ObjForEachFanin( pThis, pNext, k ) + { + if ( Log_ObjIsTravIdCurrent(p, pNext) ) + continue; + Log_ObjSetTravIdCurrent(p, pNext); + Vec_IntPush( vNext, pNext->hHandle ); + nVisited += !Log_ObjIsTerm(pNext); + } + Log_ObjForEachFanout( pThis, pNext, k ) + { + if ( Log_ObjIsTravIdCurrent(p, pNext) ) + continue; + Log_ObjSetTravIdCurrent(p, pNext); + Vec_IntPush( vNext, pNext->hHandle ); + nVisited += !Log_ObjIsTerm(pNext); + } + } + vTemp = vThis; vThis = vNext; vNext = vTemp; + } + Vec_IntFree( vThis ); + Vec_IntFree( vNext ); + // check if there are several strongly connected components +// if ( nVisited < Log_ManNodeNum(p) ) +// printf( "Visited less nodes (%d) than present (%d).\n", nVisited, Log_ManNodeNum(p) ); + return d; +} + +/**Function************************************************************* + + Synopsis [Traverses from the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestDistanceInternal( Log_Man_t * p ) +{ + int nAttempts = 20; + int i, iNode, Dist, clk; + Log_Obj_t * pPivot, * pNext; + Aig_ManRandom( 1 ); + Log_ManResetTravId( p ); + // compute distances from several randomly selected PIs + clk = clock(); + printf( "From inputs: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Log_ManCiNum(p); + pPivot = Log_ManCi( p, iNode ); + if ( Log_ObjFanoutNum(pPivot) == 0 ) + { i--; continue; } + pNext = Log_ObjFanout( pPivot, 0 ); + if ( !Log_ObjIsNode(pNext) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); + // compute distances from several randomly selected POs + clk = clock(); + printf( "From outputs: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Log_ManCoNum(p); + pPivot = Log_ManCo( p, iNode ); + pNext = Log_ObjFanin( pPivot, 0 ); + if ( !Log_ObjIsNode(pNext) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); + // compute distances from several randomly selected nodes + clk = clock(); + printf( "From nodes: " ); + for ( i = 0; i < nAttempts; i++ ) + { + iNode = Aig_ManRandom( 0 ) % Gia_ManObjNum(p->pGia); + if ( !~Gia_ManObj(p->pGia, iNode)->Value ) + { i--; continue; } + pPivot = Log_ManObj( p, Gia_ManObj(p->pGia, iNode)->Value ); + if ( !Log_ObjIsNode(pPivot) ) + { i--; continue; } + Dist = Log_ManComputeDistance( p, pPivot ); + printf( "%d ", Dist ); + } + ABC_PRT( "Time", clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [Returns sorted array of node handles with largest fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestDistance( Gia_Man_t * pGia ) +{ + Log_Man_t * p; + int clk = clock(); + p = Log_ManStart( pGia ); +// Log_ManPrintFanio( p ); + Log_ManPrintStats( p ); +ABC_PRT( "Time", clock() - clk ); + Gia_ManTestDistanceInternal( p ); + Log_ManStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |