blob: 2f5e765064e3da7374bcb7c6c12e8d5e6b47a3be [file] [log] [blame]
/**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