| /**CFile**************************************************************** |
| |
| FileName [absRpm.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Abstraction package.] |
| |
| Synopsis [Structural reparameterization.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: absRpm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "abs.h" |
| #include "misc/vec/vecWec.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static inline int Gia_ObjDom( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vDoms, Gia_ObjId(p, pObj)); } |
| static inline void Gia_ObjSetDom( Gia_Man_t * p, Gia_Obj_t * pObj, int d ) { Vec_IntWriteEntry(p->vDoms, Gia_ObjId(p, pObj), d); } |
| |
| static int Abs_ManSupport2( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ); |
| static int Abs_GiaObjDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode ); |
| static int Abs_GiaObjRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes one-node dominators.] |
| |
| Description [For each node, computes the closest one-node dominator, |
| which can be the node itself if the node has no other dominators.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManAddDom( Gia_Man_t * p, Gia_Obj_t * pObj, int iDom0 ) |
| { |
| int iDom1, iDomNext; |
| if ( Gia_ObjDom(p, pObj) == -1 ) |
| { |
| Gia_ObjSetDom( p, pObj, iDom0 ); |
| return; |
| } |
| iDom1 = Gia_ObjDom( p, pObj ); |
| while ( 1 ) |
| { |
| if ( iDom0 > iDom1 ) |
| { |
| iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom1) ); |
| if ( iDomNext == iDom1 ) |
| break; |
| iDom1 = iDomNext; |
| continue; |
| } |
| if ( iDom1 > iDom0 ) |
| { |
| iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom0) ); |
| if ( iDomNext == iDom0 ) |
| break; |
| iDom0 = iDomNext; |
| continue; |
| } |
| assert( iDom0 == iDom1 ); |
| Gia_ObjSetDom( p, pObj, iDom0 ); |
| return; |
| } |
| Gia_ObjSetDom( p, pObj, Gia_ObjId(p, pObj) ); |
| } |
| void Gia_ManComputeDoms( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| int i; |
| if ( p->vDoms == NULL ) |
| p->vDoms = Vec_IntAlloc( 0 ); |
| Vec_IntFill( p->vDoms, Gia_ManObjNum(p), -1 ); |
| Gia_ManForEachObjReverse( p, pObj, i ) |
| { |
| if ( i == 0 || Gia_ObjIsCi(pObj) ) |
| continue; |
| if ( pObj->fMark1 || (p->pRefs && Gia_ObjIsAnd(pObj) && Gia_ObjRefNum(p, pObj) == 0) ) |
| continue; |
| if ( Gia_ObjIsCo(pObj) ) |
| { |
| Gia_ObjSetDom( p, pObj, i ); |
| Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i ); |
| continue; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i ); |
| Gia_ManAddDom( p, Gia_ObjFanin1(pObj), i ); |
| } |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Wec_t * Gia_ManCreateSupps( Gia_Man_t * p, int fVerbose ) |
| { |
| abctime clk = Abc_Clock(); |
| Gia_Obj_t * pObj; int i, Id; |
| Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); |
| Gia_ManForEachCiId( p, Id, i ) |
| Vec_IntPush( Vec_WecEntry(vSupps, Id), i ); |
| Gia_ManForEachAnd( p, pObj, Id ) |
| Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)), |
| Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)), |
| Vec_WecEntry(vSupps, Id) ); |
| // Gia_ManForEachCo( p, pObj, i ) |
| // Vec_IntAppend( Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) ); |
| if ( fVerbose ) |
| Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk ); |
| return vSupps; |
| } |
| void Gia_ManDomTest( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vDoms = Vec_IntAlloc( 100 ); |
| Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); |
| Vec_Wec_t * vSupps = Gia_ManCreateSupps( p, 1 ); |
| Vec_Wec_t * vDomeds = Vec_WecStart( Gia_ManObjNum(p) ); |
| Gia_Obj_t * pObj, * pDom; int i, Id, nMffcSize; |
| Gia_ManCreateRefs( p ); |
| Gia_ManComputeDoms( p ); |
| Gia_ManForEachCi( p, pObj, i ) |
| { |
| if ( Gia_ObjDom(p, pObj) == -1 ) |
| continue; |
| for ( pDom = Gia_ManObj(p, Gia_ObjDom(p, pObj)); Gia_ObjIsAnd(pDom); pDom = Gia_ManObj(p, Gia_ObjDom(p, pDom)) ) |
| Vec_IntPush( Vec_WecEntry(vDomeds, Gia_ObjId(p, pDom)), i ); |
| } |
| Gia_ManForEachAnd( p, pObj, i ) |
| if ( Vec_IntEqual(Vec_WecEntry(vSupps, i), Vec_WecEntry(vDomeds, i)) ) |
| Vec_IntPush( vDoms, i ); |
| Vec_WecFree( vSupps ); |
| Vec_WecFree( vDomeds ); |
| |
| // check MFFC sizes |
| Vec_IntForEachEntry( vDoms, Id, i ) |
| Gia_ObjRefInc( p, Gia_ManObj(p, Id) ); |
| Vec_IntForEachEntry( vDoms, Id, i ) |
| { |
| nMffcSize = Gia_NodeMffcSizeSupp( p, Gia_ManObj(p, Id), vSupp ); |
| printf( "%d(%d:%d) ", Id, Vec_IntSize(vSupp), nMffcSize ); |
| } |
| printf( "\n" ); |
| Vec_IntForEachEntry( vDoms, Id, i ) |
| Gia_ObjRefDec( p, Gia_ManObj(p, Id) ); |
| |
| // Vec_IntPrint( vDoms ); |
| Vec_IntFree( vDoms ); |
| Vec_IntFree( vSupp ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManTestDoms2( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vNodes; |
| Gia_Obj_t * pObj, * pDom; |
| abctime clk = Abc_Clock(); |
| int i; |
| assert( p->vDoms == NULL ); |
| Gia_ManComputeDoms( p ); |
| /* |
| Gia_ManForEachPi( p, pObj, i ) |
| if ( Gia_ObjId(p, pObj) != Gia_ObjDom(p, pObj) ) |
| printf( "PI =%6d Id =%8d. Dom =%8d.\n", i, Gia_ObjId(p, pObj), Gia_ObjDom(p, pObj) ); |
| */ |
| Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); |
| // for each dominated PI, when if the PIs is in a leaf of the MFFC of the dominator |
| Gia_ManCleanMark1( p ); |
| Gia_ManForEachPi( p, pObj, i ) |
| pObj->fMark1 = 1; |
| vNodes = Vec_IntAlloc( 100 ); |
| Gia_ManCreateRefs( p ); |
| Gia_ManForEachPi( p, pObj, i ) |
| { |
| if ( Gia_ObjId(p, pObj) == Gia_ObjDom(p, pObj) ) |
| continue; |
| |
| pDom = Gia_ManObj(p, Gia_ObjDom(p, pObj)); |
| if ( Gia_ObjIsCo(pDom) ) |
| { |
| assert( Gia_ObjFanin0(pDom) == pObj ); |
| continue; |
| } |
| assert( Gia_ObjIsAnd(pDom) ); |
| Abs_GiaObjDeref_rec( p, pDom ); |
| Abs_ManSupport2( p, pDom, vNodes ); |
| Abs_GiaObjRef_rec( p, pDom ); |
| |
| if ( Vec_IntFind(vNodes, Gia_ObjId(p, pObj)) == -1 ) |
| printf( "FAILURE.\n" ); |
| // else |
| // printf( "Success.\n" ); |
| } |
| Vec_IntFree( vNodes ); |
| Gia_ManCleanMark1( p ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Collect PI doms.] |
| |
| Description [Assumes that some PIs and ANDs are marked with fMark1.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Gia_ManCollectDoms( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vNodes; |
| Gia_Obj_t * pObj; |
| int Lev, LevMax = ABC_INFINITY; |
| int i, iDom, iDomNext; |
| vNodes = Vec_IntAlloc( 100 ); |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| if ( !pObj->fMark1 ) |
| continue; |
| if ( p->pRefs && Gia_ObjRefNum(p, pObj) == 0 ) |
| continue; |
| iDom = Gia_ObjDom(p, pObj); |
| if ( iDom == -1 ) |
| continue; |
| if ( iDom == i ) |
| continue; |
| for ( Lev = 0; Lev < LevMax && Gia_ObjIsAnd( Gia_ManObj(p, iDom) ); Lev++ ) |
| { |
| Vec_IntPush( vNodes, iDom ); |
| iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom) ); |
| if ( iDomNext == iDom ) |
| break; |
| iDom = iDomNext; |
| } |
| } |
| Vec_IntUniqify( vNodes ); |
| return vNodes; |
| } |
| Vec_Int_t * Gia_ManComputePiDoms( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vNodes; |
| Gia_ManComputeDoms( p ); |
| vNodes = Gia_ManCollectDoms( p ); |
| // Vec_IntPrint( vNodes ); |
| return vNodes; |
| } |
| void Gia_ManTestDoms( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vNodes; |
| Gia_Obj_t * pObj; |
| int i; |
| // mark PIs |
| // Gia_ManCreateRefs( p ); |
| Gia_ManCleanMark1( p ); |
| Gia_ManForEachPi( p, pObj, i ) |
| pObj->fMark1 = 1; |
| // compute dominators |
| assert( p->vDoms == NULL ); |
| vNodes = Gia_ManComputePiDoms( p ); |
| // printf( "Nodes = %d. Doms = %d.\n", Gia_ManAndNum(p), Vec_IntSize(vNodes) ); |
| Vec_IntFree( vNodes ); |
| // unmark PIs |
| Gia_ManCleanMark1( p ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Counts flops without fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManCountFanoutlessFlops( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| int i; |
| int Counter = 0; |
| Gia_ManCreateRefs( p ); |
| Gia_ManForEachRo( p, pObj, i ) |
| if ( Gia_ObjRefNum(p, pObj) == 0 ) |
| Counter++; |
| printf( "Fanoutless flops = %d.\n", Counter ); |
| ABC_FREE( p->pRefs ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManCountPisNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPis, Vec_Int_t * vAnds ) |
| { |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) |
| return; |
| Gia_ObjSetTravIdCurrent(p, pObj); |
| if ( pObj->fMark1 ) |
| { |
| Vec_IntPush( vPis, Gia_ObjId(p, pObj) ); |
| return; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| Gia_ManCountPisNodes_rec( p, Gia_ObjFanin0(pObj), vPis, vAnds ); |
| Gia_ManCountPisNodes_rec( p, Gia_ObjFanin1(pObj), vPis, vAnds ); |
| Vec_IntPush( vAnds, Gia_ObjId(p, pObj) ); |
| } |
| void Gia_ManCountPisNodes( Gia_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vAnds ) |
| { |
| Gia_Obj_t * pObj; |
| int i; |
| // mark const0 and flop output |
| Gia_ManIncrementTravId( p ); |
| Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); |
| Gia_ManForEachRo( p, pObj, i ) |
| Gia_ObjSetTravIdCurrent( p, pObj ); |
| // count PIs and internal nodes reachable from COs |
| Vec_IntClear( vPis ); |
| Vec_IntClear( vAnds ); |
| Gia_ManForEachCo( p, pObj, i ) |
| Gia_ManCountPisNodes_rec( p, Gia_ObjFanin0(pObj), vPis, vAnds ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abs_GiaObjDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) |
| { |
| Gia_Obj_t * pFanin; |
| int Counter = 0; |
| if ( pNode->fMark1 || Gia_ObjIsRo(p, pNode) ) |
| return 0; |
| assert( Gia_ObjIsAnd(pNode) ); |
| pFanin = Gia_ObjFanin0(pNode); |
| assert( Gia_ObjRefNum(p, pFanin) > 0 ); |
| if ( Gia_ObjRefDec(p, pFanin) == 0 ) |
| Counter += Abs_GiaObjDeref_rec( p, pFanin ); |
| pFanin = Gia_ObjFanin1(pNode); |
| assert( Gia_ObjRefNum(p, pFanin) > 0 ); |
| if ( Gia_ObjRefDec(p, pFanin) == 0 ) |
| Counter += Abs_GiaObjDeref_rec( p, pFanin ); |
| return Counter + 1; |
| } |
| int Abs_GiaObjRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) |
| { |
| Gia_Obj_t * pFanin; |
| int Counter = 0; |
| if ( pNode->fMark1 || Gia_ObjIsRo(p, pNode) ) |
| return 0; |
| assert( Gia_ObjIsAnd(pNode) ); |
| pFanin = Gia_ObjFanin0(pNode); |
| if ( Gia_ObjRefInc(p, pFanin) == 0 ) |
| Counter += Abs_GiaObjRef_rec( p, pFanin ); |
| pFanin = Gia_ObjFanin1(pNode); |
| if ( Gia_ObjRefInc(p, pFanin) == 0 ) |
| Counter += Abs_GiaObjRef_rec( p, pFanin ); |
| return Counter + 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the number of nodes with zero refs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abs_GiaSortNodes( Gia_Man_t * p, Vec_Int_t * vSupp ) |
| { |
| Gia_Obj_t * pObj; |
| int nSize = Vec_IntSize(vSupp); |
| int i, RetValue; |
| Gia_ManForEachObjVec( vSupp, p, pObj, i ) |
| if ( i < nSize && Gia_ObjRefNum(p, pObj) == 0 && !Gia_ObjIsRo(p, pObj) ) // add removable leaves |
| { |
| assert( pObj->fMark1 ); |
| Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); |
| } |
| RetValue = Vec_IntSize(vSupp) - nSize; |
| Gia_ManForEachObjVec( vSupp, p, pObj, i ) |
| if ( i < nSize && !(Gia_ObjRefNum(p, pObj) == 0 && !Gia_ObjIsRo(p, pObj)) ) // add non-removable leaves |
| Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); |
| assert( Vec_IntSize(vSupp) == 2 * nSize ); |
| memmove( Vec_IntArray(vSupp), Vec_IntArray(vSupp) + nSize, sizeof(int) * nSize ); |
| Vec_IntShrink( vSupp, nSize ); |
| return RetValue; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes support in terms of PIs and flops.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Abs_ManSupport1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) |
| { |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) |
| return; |
| Gia_ObjSetTravIdCurrent(p, pObj); |
| if ( pObj->fMark1 || Gia_ObjIsRo(p, pObj) ) |
| { |
| Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); |
| return; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| Abs_ManSupport1_rec( p, Gia_ObjFanin0(pObj), vSupp ); |
| Abs_ManSupport1_rec( p, Gia_ObjFanin1(pObj), vSupp ); |
| } |
| int Abs_ManSupport1( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) |
| { |
| assert( Gia_ObjIsAnd(pObj) ); |
| Vec_IntClear( vSupp ); |
| Gia_ManIncrementTravId( p ); |
| Abs_ManSupport1_rec( p, pObj, vSupp ); |
| return Vec_IntSize(vSupp); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes support of the MFFC.] |
| |
| Description [Should be called when pObj's cone is dereferenced.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Abs_ManSupport2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) |
| { |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) |
| return; |
| Gia_ObjSetTravIdCurrent(p, pObj); |
| if ( pObj->fMark1 || Gia_ObjIsRo(p, pObj) || Gia_ObjRefNum(p, pObj) > 0 ) |
| { |
| Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); |
| return; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| Abs_ManSupport2_rec( p, Gia_ObjFanin0(pObj), vSupp ); |
| Abs_ManSupport2_rec( p, Gia_ObjFanin1(pObj), vSupp ); |
| } |
| int Abs_ManSupport2( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) |
| { |
| assert( Gia_ObjIsAnd(pObj) ); |
| Vec_IntClear( vSupp ); |
| Gia_ManIncrementTravId( p ); |
| Abs_ManSupport2_rec( p, Gia_ObjFanin0(pObj), vSupp ); |
| Abs_ManSupport2_rec( p, Gia_ObjFanin1(pObj), vSupp ); |
| Gia_ObjSetTravIdCurrent(p, pObj); |
| return Vec_IntSize(vSupp); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes support of the extended MFFC.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abs_ManSupport3( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) |
| { |
| Gia_Obj_t * pTemp, * pFan0, * pFan1; |
| int i, nSize0; |
| // collect MFFC |
| Abs_ManSupport2( p, pObj, vSupp ); |
| // move dominated to the front |
| nSize0 = Abs_GiaSortNodes( p, vSupp ); |
| assert( nSize0 > 0 ); |
| // consider remaining nodes |
| while ( 1 ) |
| { |
| int fChanges = 0; |
| Gia_ManForEachObjVec( vSupp, p, pTemp, i ) |
| { |
| if ( i < nSize0 ) |
| continue; |
| if ( !Gia_ObjIsAnd(pTemp) ) |
| continue; |
| assert( !pTemp->fMark1 ); |
| assert( Gia_ObjRefNum(p, pTemp) > 0 ); |
| pFan0 = Gia_ObjFanin0(pTemp); |
| pFan1 = Gia_ObjFanin1(pTemp); |
| if ( Gia_ObjIsTravIdCurrent(p, pFan0) && Gia_ObjIsTravIdCurrent(p, pFan1) ) |
| { |
| Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) ); |
| fChanges = 1; |
| break; |
| } |
| if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) |
| { |
| Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) ); |
| Vec_IntPush( vSupp, Gia_ObjId(p, pFan1) ); |
| assert( !Gia_ObjIsTravIdCurrent(p, pFan1) ); |
| Gia_ObjSetTravIdCurrent(p, pFan1); |
| fChanges = 1; |
| break; |
| } |
| if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) |
| { |
| Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) ); |
| Vec_IntPush( vSupp, Gia_ObjId(p, pFan0) ); |
| assert( !Gia_ObjIsTravIdCurrent(p, pFan0) ); |
| Gia_ObjSetTravIdCurrent(p, pFan0); |
| fChanges = 1; |
| break; |
| } |
| } |
| if ( !fChanges ) |
| break; |
| } |
| return Vec_IntSize(vSupp); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abs_GiaCofPrint( word * pTruth, int nSize, int nSize0, int Res ) |
| { |
| int i, Bit; |
| int nBits = (1 << nSize); |
| int nStep = (1 << nSize0); |
| int Mark[2] = {1,1}; |
| for ( i = 0; i < nBits; i++ ) |
| { |
| if ( i % nStep == 0 ) |
| { |
| printf( " " ); |
| assert( Res || (Mark[0] && Mark[1]) ); |
| Mark[0] = Mark[1] = 0; |
| } |
| Bit = Abc_InfoHasBit((unsigned *)pTruth, i); |
| Mark[Bit] = 1; |
| printf( "%d", Bit ); |
| } |
| printf( "\n" ); |
| assert( Res || (Mark[0] && Mark[1]) ); |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if truth table has no const cofactors.] |
| |
| Description [The cofactoring variables are the (nSize-nSize0) |
| most significant vars. Each cofactor depends on nSize0 vars.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abs_GiaCheckTruth( word * pTruth, int nSize, int nSize0 ) |
| { |
| unsigned char * pStr = (unsigned char *)pTruth; |
| int nStr = (nSize >= 3 ? (1 << (nSize - 3)) : 1); |
| int i, k, nSteps; |
| assert( nSize0 > 0 && nSize0 <= nSize ); |
| if ( nSize0 == 1 ) |
| { |
| for ( i = 0; i < nStr; i++ ) |
| if ( (((unsigned)pStr[i] ^ ((unsigned)pStr[i] >> 1)) & 0x55) != 0x55 ) |
| return 0; |
| return 1; |
| } |
| if ( nSize0 == 2 ) |
| { |
| for ( i = 0; i < nStr; i++ ) |
| if ( ((unsigned)pStr[i] & 0xF) == 0x0 || (((unsigned)pStr[i] >> 4) & 0xF) == 0x0 || |
| ((unsigned)pStr[i] & 0xF) == 0xF || (((unsigned)pStr[i] >> 4) & 0xF) == 0xF ) |
| return 0; |
| return 1; |
| } |
| assert( nSize0 >= 3 ); |
| nSteps = (1 << (nSize0 - 3)); |
| for ( i = 0; i < nStr; i += nSteps ) |
| { |
| for ( k = 0; k < nSteps; k++ ) |
| if ( ((unsigned)pStr[i+k] & 0xFF) != 0x00 ) |
| break; |
| if ( k == nSteps ) |
| break; |
| for ( k = 0; k < nSteps; k++ ) |
| if ( ((unsigned)pStr[i+k] & 0xFF) != 0xFF ) |
| break; |
| if ( k == nSteps ) |
| break; |
| } |
| assert( i <= nStr ); |
| return (int)( i == nStr ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if truth table has const cofactors.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Abs_RpmPerformMark( Gia_Man_t * p, int nCutMax, int fVerbose, int fVeryVerbose ) |
| { |
| Vec_Int_t * vPis, * vAnds, * vDoms; |
| Vec_Int_t * vSupp, * vSupp1, * vSupp2; |
| Gia_Obj_t * pObj; |
| word * pTruth; |
| int Iter, i, nSize0, nNodes; |
| int fHasConst, fChanges = 1; |
| Gia_ManCreateRefs( p ); |
| Gia_ManCleanMark1( p ); |
| Gia_ManForEachPi( p, pObj, i ) |
| pObj->fMark1 = 1; |
| vPis = Vec_IntAlloc( 100 ); |
| vAnds = Vec_IntAlloc( 100 ); |
| vSupp1 = Vec_IntAlloc( 100 ); |
| vSupp2 = Vec_IntAlloc( 100 ); |
| for ( Iter = 0; fChanges; Iter++ ) |
| { |
| fChanges = 0; |
| vDoms = Gia_ManComputePiDoms( p ); |
| // count the number of PIs and internal nodes |
| if ( fVerbose || fVeryVerbose ) |
| { |
| Gia_ManCountPisNodes( p, vPis, vAnds ); |
| printf( "Iter %3d : ", Iter ); |
| printf( "PI = %5d (%6.2f %%) ", Vec_IntSize(vPis), 100.0 * Vec_IntSize(vPis) / Gia_ManPiNum(p) ); |
| printf( "And = %6d (%6.2f %%) ", Vec_IntSize(vAnds), 100.0 * Vec_IntSize(vAnds) / Gia_ManAndNum(p) ); |
| printf( "Dom = %5d (%6.2f %%) ", Vec_IntSize(vDoms), 100.0 * Vec_IntSize(vDoms) / Gia_ManAndNum(p) ); |
| printf( "\n" ); |
| } |
| // pObj = Gia_ObjFanin0( Gia_ManPo(p, 1) ); |
| Gia_ManForEachObjVec( vDoms, p, pObj, i ) |
| { |
| assert( !pObj->fMark1 ); |
| assert( Gia_ObjRefNum( p, pObj ) > 0 ); |
| // dereference root node |
| nNodes = Abs_GiaObjDeref_rec( p, pObj ); |
| /* |
| // compute support of full cone |
| if ( Abs_ManSupport1(p, pObj, vSupp1) > nCutMax ) |
| // if ( 1 ) |
| { |
| // check support of MFFC |
| if ( Abs_ManSupport2(p, pObj, vSupp2) > nCutMax ) |
| // if ( 1 ) |
| { |
| Abs_GiaObjRef_rec( p, pObj ); |
| continue; |
| } |
| vSupp = vSupp2; |
| // printf( "-" ); |
| } |
| else |
| { |
| vSupp = vSupp1; |
| // printf( "+" ); |
| } |
| */ |
| if ( Abs_ManSupport2(p, pObj, vSupp2) > nCutMax ) |
| { |
| Abs_GiaObjRef_rec( p, pObj ); |
| continue; |
| } |
| vSupp = vSupp2; |
| |
| // order nodes by their ref counts |
| nSize0 = Abs_GiaSortNodes( p, vSupp ); |
| assert( nSize0 > 0 && nSize0 <= nCutMax ); |
| // check if truth table has const cofs |
| pTruth = Gia_ObjComputeTruthTableCut( p, pObj, vSupp ); |
| if ( pTruth == NULL ) |
| { |
| Abs_GiaObjRef_rec( p, pObj ); |
| continue; |
| } |
| fHasConst = !Abs_GiaCheckTruth( pTruth, Vec_IntSize(vSupp), nSize0 ); |
| if ( fVeryVerbose ) |
| { |
| printf( "Nodes =%3d ", nNodes ); |
| printf( "Size =%3d ", Vec_IntSize(vSupp) ); |
| printf( "Size0 =%3d ", nSize0 ); |
| printf( "%3s", fHasConst ? "yes" : "no" ); |
| Abs_GiaCofPrint( pTruth, Vec_IntSize(vSupp), nSize0, fHasConst ); |
| } |
| if ( fHasConst ) |
| { |
| Abs_GiaObjRef_rec( p, pObj ); |
| continue; |
| } |
| // pObj can be reparamed |
| pObj->fMark1 = 1; |
| fChanges = 1; |
| } |
| Vec_IntFree( vDoms ); |
| } |
| // count the number of PIs and internal nodes |
| if ( fVeryVerbose ) |
| { |
| Gia_ManCountPisNodes( p, vPis, vAnds ); |
| printf( "Iter %3d : ", Iter ); |
| printf( "PI = %5d (%6.2f %%) ", Vec_IntSize(vPis), 100.0 * Vec_IntSize(vPis) / Gia_ManPiNum(p) ); |
| printf( "And = %6d (%6.2f %%) ", Vec_IntSize(vAnds), 100.0 * Vec_IntSize(vAnds) / Gia_ManAndNum(p) ); |
| // printf( "Dom = %5d (%6.2f %%) ", Vec_IntSize(vDoms), 100.0 * Vec_IntSize(vDoms) / Gia_ManAndNum(p) ); |
| printf( "\n" ); |
| } |
| // cleanup |
| Vec_IntFree( vPis ); |
| Vec_IntFree( vAnds ); |
| Vec_IntFree( vSupp1 ); |
| Vec_IntFree( vSupp2 ); |
| // Gia_ManCleanMark1( p ); // this will erase markings |
| ABC_FREE( p->pRefs ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Assumed that fMark1 marks the internal PIs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManDupRpm( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vPis, * vAnds; |
| Gia_Man_t * pNew; |
| Gia_Obj_t * pObj; |
| int i; |
| // derive PIs and internal nodes |
| vPis = Vec_IntAlloc( 100 ); |
| vAnds = Vec_IntAlloc( 100 ); |
| Gia_ManCountPisNodes( p, vPis, vAnds ); |
| |
| // duplicate AIG |
| Gia_ManFillValue( p ); |
| pNew = Gia_ManStart( Gia_ManObjNum(p) ); |
| pNew->pName = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManConst0(p)->Value = 0; |
| // create PIs |
| Gia_ManForEachObjVec( vPis, p, pObj, i ) |
| pObj->Value = Gia_ManAppendCi(pNew); |
| // create flops |
| Gia_ManForEachRo( p, pObj, i ) |
| pObj->Value = Gia_ManAppendCi( pNew ); |
| // create internal nodes |
| Gia_ManForEachObjVec( vAnds, p, pObj, i ) |
| pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); |
| // create COs |
| Gia_ManForEachCo( p, pObj, i ) |
| Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); |
| Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); |
| |
| // cleanup |
| Vec_IntFree( vPis ); |
| Vec_IntFree( vAnds ); |
| return pNew; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs structural reparametrization.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Abs_RpmPerform( Gia_Man_t * p, int nCutMax, int fVerbose, int fVeryVerbose ) |
| { |
| Gia_Man_t * pNew; |
| // Gia_ManTestDoms( p ); |
| // return NULL; |
| // perform structural analysis |
| Gia_ObjComputeTruthTableStart( p, nCutMax ); |
| Abs_RpmPerformMark( p, nCutMax, fVerbose, fVeryVerbose ); |
| Gia_ObjComputeTruthTableStop( p ); |
| // derive new AIG |
| pNew = Gia_ManDupRpm( p ); |
| Gia_ManCleanMark1( p ); |
| return pNew; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |