/**CFile**************************************************************** FileName [hopOper.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Minimalistic And-Inverter Graph package.] Synopsis [AIG operations.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - May 11, 2006.] Revision [$Id: hopOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] ***********************************************************************/ #include "hop.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// // procedure to detect an EXOR gate static inline int Hop_ObjIsExorType( Hop_Obj_t * p0, Hop_Obj_t * p1, Hop_Obj_t ** ppFan0, Hop_Obj_t ** ppFan1 ) { if ( !Hop_IsComplement(p0) || !Hop_IsComplement(p1) ) return 0; p0 = Hop_Regular(p0); p1 = Hop_Regular(p1); if ( !Hop_ObjIsAnd(p0) || !Hop_ObjIsAnd(p1) ) return 0; if ( Hop_ObjFanin0(p0) != Hop_ObjFanin0(p1) || Hop_ObjFanin1(p0) != Hop_ObjFanin1(p1) ) return 0; if ( Hop_ObjFaninC0(p0) == Hop_ObjFaninC0(p1) || Hop_ObjFaninC1(p0) == Hop_ObjFaninC1(p1) ) return 0; *ppFan0 = Hop_ObjChild0(p0); *ppFan1 = Hop_ObjChild1(p0); return 1; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns i-th elementary variable.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_IthVar( Hop_Man_t * p, int i ) { int v; for ( v = Hop_ManPiNum(p); v <= i; v++ ) Hop_ObjCreatePi( p ); assert( i < Vec_PtrSize(p->vPis) ); return Hop_ManPi( p, i ); } /**Function************************************************************* Synopsis [Perform one operation.] Description [The argument nodes can be complemented.] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Oper( Hop_Man_t * p, Hop_Obj_t * p0, Hop_Obj_t * p1, Hop_Type_t Type ) { if ( Type == AIG_AND ) return Hop_And( p, p0, p1 ); if ( Type == AIG_EXOR ) return Hop_Exor( p, p0, p1 ); assert( 0 ); return NULL; } /**Function************************************************************* Synopsis [Performs canonicization step.] Description [The argument nodes can be complemented.] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_And( Hop_Man_t * p, Hop_Obj_t * p0, Hop_Obj_t * p1 ) { Hop_Obj_t * pGhost, * pResult; // Hop_Obj_t * pFan0, * pFan1; // check trivial cases if ( p0 == p1 ) return p0; if ( p0 == Hop_Not(p1) ) return Hop_Not(p->pConst1); if ( Hop_Regular(p0) == p->pConst1 ) return p0 == p->pConst1 ? p1 : Hop_Not(p->pConst1); if ( Hop_Regular(p1) == p->pConst1 ) return p1 == p->pConst1 ? p0 : Hop_Not(p->pConst1); // check if it can be an EXOR gate // if ( Hop_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) // return Hop_Exor( p, pFan0, pFan1 ); // check the table pGhost = Hop_ObjCreateGhost( p, p0, p1, AIG_AND ); if ( (pResult = Hop_TableLookup( p, pGhost )) ) return pResult; return Hop_ObjCreate( p, pGhost ); } /**Function************************************************************* Synopsis [Performs canonicization step.] Description [The argument nodes can be complemented.] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Exor( Hop_Man_t * p, Hop_Obj_t * p0, Hop_Obj_t * p1 ) { /* Hop_Obj_t * pGhost, * pResult; // check trivial cases if ( p0 == p1 ) return Hop_Not(p->pConst1); if ( p0 == Hop_Not(p1) ) return p->pConst1; if ( Hop_Regular(p0) == p->pConst1 ) return Hop_NotCond( p1, p0 == p->pConst1 ); if ( Hop_Regular(p1) == p->pConst1 ) return Hop_NotCond( p0, p1 == p->pConst1 ); // check the table pGhost = Hop_ObjCreateGhost( p, p0, p1, AIG_EXOR ); if ( pResult = Hop_TableLookup( p, pGhost ) ) return pResult; return Hop_ObjCreate( p, pGhost ); */ return Hop_Or( p, Hop_And(p, p0, Hop_Not(p1)), Hop_And(p, Hop_Not(p0), p1) ); } /**Function************************************************************* Synopsis [Implements Boolean OR.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Or( Hop_Man_t * p, Hop_Obj_t * p0, Hop_Obj_t * p1 ) { return Hop_Not( Hop_And( p, Hop_Not(p0), Hop_Not(p1) ) ); } /**Function************************************************************* Synopsis [Implements ITE operation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Mux( Hop_Man_t * p, Hop_Obj_t * pC, Hop_Obj_t * p1, Hop_Obj_t * p0 ) { /* Hop_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; int Count0, Count1; // consider trivial cases if ( p0 == Hop_Not(p1) ) return Hop_Exor( p, pC, p0 ); // other cases can be added // implement the first MUX (F = C * x1 + C' * x0) // check for constants here!!! pTempA1 = Hop_TableLookup( p, Hop_ObjCreateGhost(p, pC, p1, AIG_AND) ); pTempA2 = Hop_TableLookup( p, Hop_ObjCreateGhost(p, Hop_Not(pC), p0, AIG_AND) ); if ( pTempA1 && pTempA2 ) { pTemp = Hop_TableLookup( p, Hop_ObjCreateGhost(p, Hop_Not(pTempA1), Hop_Not(pTempA2), AIG_AND) ); if ( pTemp ) return Hop_Not(pTemp); } Count0 = (pTempA1 != NULL) + (pTempA2 != NULL); // implement the second MUX (F' = C * x1' + C' * x0') pTempB1 = Hop_TableLookup( p, Hop_ObjCreateGhost(p, pC, Hop_Not(p1), AIG_AND) ); pTempB2 = Hop_TableLookup( p, Hop_ObjCreateGhost(p, Hop_Not(pC), Hop_Not(p0), AIG_AND) ); if ( pTempB1 && pTempB2 ) { pTemp = Hop_TableLookup( p, Hop_ObjCreateGhost(p, Hop_Not(pTempB1), Hop_Not(pTempB2), AIG_AND) ); if ( pTemp ) return pTemp; } Count1 = (pTempB1 != NULL) + (pTempB2 != NULL); // compare and decide which one to implement if ( Count0 >= Count1 ) { pTempA1 = pTempA1? pTempA1 : Hop_And(p, pC, p1); pTempA2 = pTempA2? pTempA2 : Hop_And(p, Hop_Not(pC), p0); return Hop_Or( p, pTempA1, pTempA2 ); } pTempB1 = pTempB1? pTempB1 : Hop_And(p, pC, Hop_Not(p1)); pTempB2 = pTempB2? pTempB2 : Hop_And(p, Hop_Not(pC), Hop_Not(p0)); return Hop_Not( Hop_Or( p, pTempB1, pTempB2 ) ); */ return Hop_Or( p, Hop_And(p, pC, p1), Hop_And(p, Hop_Not(pC), p0) ); } /**Function************************************************************* Synopsis [Implements ITE operation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Maj( Hop_Man_t * p, Hop_Obj_t * pA, Hop_Obj_t * pB, Hop_Obj_t * pC ) { return Hop_Or( p, Hop_Or(p, Hop_And(p, pA, pB), Hop_And(p, pA, pC)), Hop_And(p, pB, pC) ); } /**Function************************************************************* Synopsis [Constructs the well-balanced tree of gates.] Description [Disregards levels and possible logic sharing.] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Multi_rec( Hop_Man_t * p, Hop_Obj_t ** ppObjs, int nObjs, Hop_Type_t Type ) { Hop_Obj_t * pObj1, * pObj2; if ( nObjs == 1 ) return ppObjs[0]; pObj1 = Hop_Multi_rec( p, ppObjs, nObjs/2, Type ); pObj2 = Hop_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type ); return Hop_Oper( p, pObj1, pObj2, Type ); } /**Function************************************************************* Synopsis [Old code.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Multi( Hop_Man_t * p, Hop_Obj_t ** pArgs, int nArgs, Hop_Type_t Type ) { assert( Type == AIG_AND || Type == AIG_EXOR ); assert( nArgs > 0 ); return Hop_Multi_rec( p, pArgs, nArgs, Type ); } /**Function************************************************************* Synopsis [Implements the miter.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_Miter( Hop_Man_t * p, Vec_Ptr_t * vPairs ) { int i; assert( vPairs->nSize > 0 ); assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP for ( i = 0; i < vPairs->nSize; i += 2 ) vPairs->pArray[i/2] = Hop_Not( Hop_Exor( p, (Hop_Obj_t *)vPairs->pArray[i], (Hop_Obj_t *)vPairs->pArray[i+1] ) ); vPairs->nSize = vPairs->nSize/2; return Hop_Not( Hop_Multi_rec( p, (Hop_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_AND ) ); } /**Function************************************************************* Synopsis [Creates AND function with nVars inputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_CreateAnd( Hop_Man_t * p, int nVars ) { Hop_Obj_t * pFunc; int i; pFunc = Hop_ManConst1( p ); for ( i = 0; i < nVars; i++ ) pFunc = Hop_And( p, pFunc, Hop_IthVar(p, i) ); return pFunc; } /**Function************************************************************* Synopsis [Creates AND function with nVars inputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_CreateOr( Hop_Man_t * p, int nVars ) { Hop_Obj_t * pFunc; int i; pFunc = Hop_ManConst0( p ); for ( i = 0; i < nVars; i++ ) pFunc = Hop_Or( p, pFunc, Hop_IthVar(p, i) ); return pFunc; } /**Function************************************************************* Synopsis [Creates AND function with nVars inputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_CreateExor( Hop_Man_t * p, int nVars ) { Hop_Obj_t * pFunc; int i; pFunc = Hop_ManConst0( p ); for ( i = 0; i < nVars; i++ ) pFunc = Hop_Exor( p, pFunc, Hop_IthVar(p, i) ); return pFunc; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END