diff options
Diffstat (limited to 'src/aig/gia/giaUtil.c')
-rw-r--r-- | src/aig/gia/giaUtil.c | 518 |
1 files changed, 518 insertions, 0 deletions
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c new file mode 100644 index 00000000..ef433159 --- /dev/null +++ b/src/aig/gia/giaUtil.c @@ -0,0 +1,518 @@ +/**CFile**************************************************************** + + FileName [giaUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Various utilities.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetMark0( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 1; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanMark0( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 0; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetMark1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark1 = 1; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanMark1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark1 = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanValue( Gia_Man_t * p ) +{ + int i; + for ( i = 0; i < p->nObjs; i++ ) + p->pObjs[i].Value = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFillValue( Gia_Man_t * p ) +{ + int i; + for ( i = 0; i < p->nObjs; i++ ) + p->pObjs[i].Value = ~0; +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetPhase( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj)); + else if ( Gia_ObjIsCo(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)); + else + pObj->fPhase = 0; + } +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLevelNum( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + if ( p->pLevels ) + return p->nLevels; + p->nLevels = 0; + p->pLevels = ABC_ALLOC( int, p->nObjsAlloc ); + Gia_ManForEachObj( p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + { + if ( p->pLevels[Gia_ObjFaninId0(pObj, i)] > p->pLevels[Gia_ObjFaninId1(pObj, i)] ) + p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId0(pObj, i)]; + else + p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId1(pObj, i)]; + if ( p->nLevels < p->pLevels[i] ) + p->nLevels = p->pLevels[i]; + } + else if ( Gia_ObjIsCo(pObj) ) + p->pLevels[i] = p->pLevels[Gia_ObjFaninId0(pObj, i)]; + else + p->pLevels[i] = 0; + return p->nLevels; +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + pObj->Value = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->Value++; + Gia_ObjFanin1(pObj)->Value++; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->Value++; + } +} + +/**Function************************************************************* + + Synopsis [Assigns references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCreateRefs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pRefs == NULL ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjRefFanin0Inc( p, pObj ); + Gia_ObjRefFanin1Inc( p, pObj ); + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjRefFanin0Inc( p, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Computes the maximum frontier size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCrossCut( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, nCutCur = 0, nCutMax = 0; + Gia_ManSetRefs( p ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( pObj->Value ) + nCutCur++; + if ( nCutMax < nCutCur ) + nCutMax = nCutCur; + if ( Gia_ObjIsAnd(pObj) ) + { + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + nCutCur--; + if ( --Gia_ObjFanin1(pObj)->Value == 0 ) + nCutCur--; + } + else if ( Gia_ObjIsCo(pObj) ) + { + if ( --Gia_ObjFanin0(pObj)->Value == 0 ) + nCutCur--; + } + } +// Gia_ManForEachObj( p, pObj, i ) +// assert( pObj->Value == 0 ); + return nCutMax; +} + +/**Function************************************************************* + + Synopsis [Makes sure the manager is normalized.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManIsNormalized( Gia_Man_t * p ) +{ + int i, nOffset; + nOffset = 1; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + if ( !Gia_ObjIsCi( Gia_ManObj(p, nOffset+i) ) ) + return 0; + nOffset = 1 + Gia_ManCiNum(p) + Gia_ManAndNum(p); + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + if ( !Gia_ObjIsCo( Gia_ManObj(p, nOffset+i) ) ) + return 0; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Collects PO Ids into one array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ) +{ + Vec_Int_t * vStart; + int Entry, i; + vStart = Vec_IntAlloc( Gia_ManPoNum(p) ); + Vec_IntForEachEntryStop( p->vCos, Entry, i, Gia_ManPoNum(p) ) + Vec_IntPush( vStart, Entry ); + return vStart; +} + + +/**Function************************************************************* + + Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjIsMuxType( Gia_Obj_t * pNode ) +{ + Gia_Obj_t * pNode0, * pNode1; + // check that the node is regular + assert( !Gia_IsComplement(pNode) ); + // if the node is not AND, this is not MUX + if ( !Gia_ObjIsAnd(pNode) ) + return 0; + // if the children are not complemented, this is not MUX + if ( !Gia_ObjFaninC0(pNode) || !Gia_ObjFaninC1(pNode) ) + return 0; + // get children + pNode0 = Gia_ObjFanin0(pNode); + pNode1 = Gia_ObjFanin1(pNode); + // if the children are not ANDs, this is not MUX + if ( !Gia_ObjIsAnd(pNode0) || !Gia_ObjIsAnd(pNode1) ) + return 0; + // otherwise the node is MUX iff it has a pair of equal grandchildren + return (Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1))) || + (Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1))); +} + + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are inputs of the EXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ) +{ + Gia_Obj_t * p0, * p1; + assert( !Gia_IsComplement(pObj) ); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + p0 = Gia_ObjChild0(pObj); + p1 = Gia_ObjChild1(pObj); + if ( !Gia_IsComplement(p0) || !Gia_IsComplement(p1) ) + return 0; + p0 = Gia_Regular(p0); + p1 = Gia_Regular(p1); + if ( !Gia_ObjIsAnd(p0) || !Gia_ObjIsAnd(p1) ) + return 0; + if ( Gia_ObjFanin0(p0) != Gia_ObjFanin0(p1) || Gia_ObjFanin1(p0) != Gia_ObjFanin1(p1) ) + return 0; + if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) ) + return 0; + *ppFan0 = Gia_ObjChild0(p0); + *ppFan1 = Gia_ObjChild1(p0); + return 1; +} + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are control and data inputs of a MUX.] + + Description [If the node is a MUX, returns the control variable C. + Assigns nodes T and E to be the then and else variables of the MUX. + Node C is never complemented. Nodes T and E can be complemented. + This function also recognizes EXOR/NEXOR gates as MUXes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ) +{ + Gia_Obj_t * pNode0, * pNode1; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsMuxType(pNode) ); + // get children + pNode0 = Gia_ObjFanin0(pNode); + pNode1 = Gia_ObjFanin1(pNode); + + // find the control variable + if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin0(pNode0) == Gia_ObjFanin1(pNode1) && (Gia_ObjFaninC0(pNode0) ^ Gia_ObjFaninC1(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p1) ) + if ( Gia_ObjFaninC0(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + return Gia_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode1));//pNode2->p1); + return Gia_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Gia_ObjFanin1(pNode0) == Gia_ObjFanin0(pNode1) && (Gia_ObjFaninC1(pNode0) ^ Gia_ObjFaninC0(pNode1)) ) + { +// if ( FrGia_IsComplement(pNode1->p2) ) + if ( Gia_ObjFaninC1(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + return Gia_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Gia_Not(Gia_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Gia_Not(Gia_ObjChild1(pNode1));//pNode2->p2); + return Gia_ObjChild1(pNode0);//pNode1->p2; + } + } + assert( 0 ); // this is not MUX + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |