/**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