blob: f2acb37b2776d5e8f5f15f1e4a7062a08c428f4c [file] [log] [blame]
/**CFile****************************************************************
FileName [acecNorm.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CEC for arithmetic circuits.]
Synopsis [Adder tree normalization.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acecInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] )
{
int And, Or;
Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] );
And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) );
Or = Gia_ManAppendOr2( pNew, Out[1], And );
Out[0] = Abc_LitNot( Or );
}
void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] )
{
int In2[2], Out1[2], Out2[2];
Acec_InsertHadd( pNew, In, Out1 );
In2[0] = Out1[0];
In2[1] = In[2];
Acec_InsertHadd( pNew, In2, Out2 );
Out[0] = Out2[0];
Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] );
}
Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap )
{
Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 );
Vec_Int_t * vLevel;
int i, In[3], Out[2];
Vec_WecForEachLevel( vLeafMap, vLevel, i )
{
if ( Vec_IntSize(vLevel) == 0 )
{
Vec_IntPush( vRootRanks, 0 );
continue;
}
while ( Vec_IntSize(vLevel) > 1 )
{
if ( Vec_IntSize(vLevel) == 2 )
Vec_IntPush( vLevel, 0 );
//In[2] = Vec_IntPop( vLevel );
//In[1] = Vec_IntPop( vLevel );
//In[0] = Vec_IntPop( vLevel );
In[0] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
In[1] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
In[2] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
Acec_InsertFadd( pNew, In, Out );
Vec_IntPush( vLevel, Out[0] );
if ( i+1 < Vec_WecSize(vLeafMap) )
vLevel = Vec_WecEntry(vLeafMap, i+1);
else
vLevel = Vec_WecPushLevel(vLeafMap);
Vec_IntPush( vLevel, Out[1] );
vLevel = Vec_WecEntry(vLeafMap, i);
}
assert( Vec_IntSize(vLevel) == 1 );
Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) );
}
return vRootRanks;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( ~pObj->Value )
return pObj->Value;
assert( Gia_ObjIsAnd(pObj) );
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) );
return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ));
}
Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits )
{
Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) );
Vec_Int_t * vLevel, * vRootRanks;
int i, k, iLit, iLitNew;
// add roo literals
if ( vRootLits )
Vec_IntForEachEntry( vRootLits, iLit, i )
{
if ( i < Vec_WecSize(vLeafMap) )
vLevel = Vec_WecEntry(vLeafMap, i);
else
vLevel = Vec_WecPushLevel(vLeafMap);
Vec_IntPush( vLevel, iLit );
}
// add other literals
Vec_WecForEachLevel( vLeafLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
iLitNew = Acec_InsertBox_rec( pNew, p, pObj );
iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
Vec_WecPush( vLeafMap, i, iLitNew );
}
// construct map of root literals
vRootRanks = Acec_InsertTree( pNew, vLeafMap );
Vec_WecFree( vLeafMap );
return vRootRanks;
}
Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll )
{
Gia_Man_t * p = pBox->pGia;
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
Vec_Int_t * vRootRanks, * vLevel, * vTemp;
int i, k, iLit, iLitNew;
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManFillValue(p);
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
// implement tree
if ( fAll )
vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL );
else
{
assert( pBox->vShared != NULL );
assert( pBox->vUnique != NULL );
vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL );
vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks );
Vec_IntFree( vTemp );
}
// update polarity of literals
Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i );
pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
}
Vec_IntFree( vRootRanks );
// construct the outputs
Gia_ManForEachCo( p, pObj, i )
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose )
{
Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL;
Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 );
Acec_BoxFreeP( &pBox );
Vec_BitFreeP( &vIgnore );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END