blob: 34ed781f297117c285a96ffbdeddd0116afc6ade [file] [log] [blame]
/**CFile****************************************************************
FileName [ivyCanon.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis [Finding canonical form of objects.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: ivyCanon.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ivy.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1, int fCompl0, int fCompl1, Ivy_Type_t Type );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the canonical form of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
{
Ivy_Obj_t * pResult, * pLat0, * pLat1;
Ivy_Init_t Init, Init0, Init1;
int fCompl0, fCompl1;
Ivy_Type_t Type;
assert( Ivy_ObjIsNode(pGhost) );
assert( Ivy_ObjIsAnd(pGhost) || (!Ivy_ObjFaninC0(pGhost) && !Ivy_ObjFaninC1(pGhost)) );
assert( Ivy_ObjFaninId0(pGhost) != 0 && Ivy_ObjFaninId1(pGhost) != 0 );
// consider the case when the pair is canonical
if ( !Ivy_ObjIsLatch(Ivy_ObjFanin0(pGhost)) || !Ivy_ObjIsLatch(Ivy_ObjFanin1(pGhost)) )
{
if ( (pResult = Ivy_TableLookup( p, pGhost )) )
return pResult;
return Ivy_ObjCreate( p, pGhost );
}
/// remember the latches
pLat0 = Ivy_ObjFanin0(pGhost);
pLat1 = Ivy_ObjFanin1(pGhost);
// remember type and compls
Type = Ivy_ObjType(pGhost);
fCompl0 = Ivy_ObjFaninC0(pGhost);
fCompl1 = Ivy_ObjFaninC1(pGhost);
// call recursively
pResult = Ivy_Oper( p, Ivy_NotCond(Ivy_ObjFanin0(pLat0), fCompl0), Ivy_NotCond(Ivy_ObjFanin0(pLat1), fCompl1), Type );
// build latch on top of this
Init0 = Ivy_InitNotCond( Ivy_ObjInit(pLat0), fCompl0 );
Init1 = Ivy_InitNotCond( Ivy_ObjInit(pLat1), fCompl1 );
Init = (Type == IVY_AND)? Ivy_InitAnd(Init0, Init1) : Ivy_InitExor(Init0, Init1);
return Ivy_Latch( p, pResult, Init );
}
/**Function*************************************************************
Synopsis [Creates the canonical form of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_CanonAnd( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
{
Ivy_Obj_t * pGhost, * pResult;
pGhost = Ivy_ObjCreateGhost( p, pObj0, pObj1, IVY_AND, IVY_INIT_NONE );
pResult = Ivy_CanonPair_rec( p, pGhost );
return pResult;
}
/**Function*************************************************************
Synopsis [Creates the canonical form of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_CanonExor( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
{
Ivy_Obj_t * pGhost, * pResult;
int fCompl = Ivy_IsComplement(pObj0) ^ Ivy_IsComplement(pObj1);
pObj0 = Ivy_Regular(pObj0);
pObj1 = Ivy_Regular(pObj1);
pGhost = Ivy_ObjCreateGhost( p, pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE );
pResult = Ivy_CanonPair_rec( p, pGhost );
return Ivy_NotCond( pResult, fCompl );
}
/**Function*************************************************************
Synopsis [Creates the canonical form of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init )
{
Ivy_Obj_t * pGhost, * pResult;
int fCompl = Ivy_IsComplement(pObj);
pObj = Ivy_Regular(pObj);
pGhost = Ivy_ObjCreateGhost( p, pObj, NULL, IVY_LATCH, Ivy_InitNotCond(Init, fCompl) );
pResult = Ivy_TableLookup( p, pGhost );
if ( pResult == NULL )
pResult = Ivy_ObjCreate( p, pGhost );
return Ivy_NotCond( pResult, fCompl );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END