/**CFile**************************************************************** FileName [acecStruct.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [CEC for arithmetic circuits.] Synopsis [Core procedures.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p ) { Vec_Int_t * vXors = Vec_IntAlloc( 100 ); Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) ); Gia_Obj_t * pFan0, * pFan1, * pObj; int i, k = 0, Entry; Gia_ManForEachAnd( p, pObj, i ) { if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) continue; Vec_IntPush( vXors, i ); Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 ); Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 ); } // collect XORs that not inputs of other XORs Vec_IntForEachEntry( vXors, Entry, i ) if ( !Vec_BitEntry(vXorIns, Entry) ) Vec_IntWriteEntry( vXors, k++, Entry ); Vec_IntShrink( vXors, k ); Vec_BitFree( vXorIns ); return vXors; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots ) { Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); Gia_Obj_t * pFan0, * pFan1, * pObj; int i, k, Fanins[2], Entry, Rank; // map roots into their ranks Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); Vec_IntForEachEntry( vXorRoots, Entry, i ) Vec_IntWriteEntry( vRanks, Entry, i ); // map nodes into their ranks Gia_ManForEachAndReverse( p, pObj, i ) { if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) continue; Rank = Vec_IntEntry( vRanks, i ); // skip XORs that are not part of any tree if ( Rank == -1 ) continue; // iterate through XOR inputs Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); for ( k = 0; k < 2; k++ ) { Entry = Vec_IntEntry( vRanks, Fanins[k] ); if ( Entry == Rank ) // the same tree -- allow fanout in this tree continue; if ( Entry == -1 ) Vec_IntWriteEntry( vRanks, Fanins[k], Rank ); else Vec_IntPush( vDoubles, Fanins[k] ); if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k]))) printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank ); } } // remove duplicated entries Vec_IntForEachEntry( vDoubles, Entry, i ) Vec_IntWriteEntry( vRanks, Entry, -1 ); Vec_IntFree( vDoubles ); return vRanks; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks ) { Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) ); Gia_Obj_t * pFan0, * pFan1, * pObj; int i, k, Fanins[2], Rank; Gia_ManForEachAnd( p, pObj, i ) { if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) continue; Vec_BitWriteEntry( vMapXors, i, 1 ); Rank = Vec_IntEntry( vRanks, i ); // skip XORs that are not part of any tree if ( Rank == -1 ) continue; // iterate through XOR inputs Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); for ( k = 0; k < 2; k++ ) { if ( Vec_BitEntry(vMapXors, Fanins[k]) ) { assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) ); continue; } Vec_WecPush( vTreeLeaves, Rank, Fanins[k] ); } } Vec_BitFree( vMapXors ); return vTreeLeaves; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks ) { Vec_Int_t * vShadows = Vec_IntDup( vRanks ); Gia_Obj_t * pObj; int i, Shad0, Shad1; Gia_ManForEachCi( p, pObj, i ) Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 ); Gia_ManForEachAnd( p, pObj, i ) { if ( Vec_IntEntry(vShadows, i) >= 0 ) continue; Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i)); Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i)); if ( Shad0 == Shad1 && Shad0 != -1 ) Vec_IntWriteEntry(vShadows, i, Shad0); } return vShadows; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks ) { Gia_Obj_t * pObj; int nSize; if ( Gia_ObjIsTravIdCurrentId(p, iNode) ) return 0; Gia_ObjSetTravIdCurrentId(p, iNode); pObj = Gia_ManObj(p, iNode); assert( Gia_ObjIsAnd(pObj) ); if ( Vec_IntEntry(vRanks, iNode) == Rank ) return 1; nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks ); nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks ); return nSize; } Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves ) { Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) ); Vec_Int_t * vTree; int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp; Vec_WecForEachLevel( vTreeLeaves, vTree, i ) Vec_IntForEachEntry( vTree, Node, k ) { Gia_Obj_t * pObj = Gia_ManObj(p, Node); if ( !Gia_ObjIsAnd(pObj) ) continue; Fanins[0] = Gia_ObjFaninId0(pObj, Node); Fanins[1] = Gia_ObjFaninId1(pObj, Node); Shad0 = Vec_IntEntry(vShadows, Fanins[0]); Shad1 = Vec_IntEntry(vShadows, Fanins[1]); if ( Shad0 != Shad1 || Shad0 == -1 ) continue; // check support size of Node in terms of the shadow of its fanins Rank = Vec_IntEntry( vRanks, Node ); assert( Rank != Shad0 ); Gia_ManIncrementTravId( p ); nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks ); assert( nSupp > 1 ); if ( nSupp > 3 ) continue; Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank ); } return vNexts; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Acec_StructTest( Gia_Man_t * p ) { } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END