acecNorm.c 7.17 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
/**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 );
79 80 81 82 83 84 85 86 87 88 89 90 91
            //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 );

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
            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) );
125
    return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ));
126
}
127
Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits )
128 129 130 131
{
    Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) );
    Vec_Int_t * vLevel, * vRootRanks;  
    int i, k, iLit, iLitNew;
132 133 134 135 136 137 138 139 140 141 142
    // 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
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    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;
161
    Vec_Int_t * vRootRanks, * vLevel, * vTemp;
162 163 164 165 166 167 168 169 170 171
    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 )
172
        vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL );
173 174 175 176
    else
    {
        assert( pBox->vShared != NULL );
        assert( pBox->vUnique != NULL );
177 178 179
        vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL );
        vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks );
        Vec_IntFree( vTemp );
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    }
    // 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     []

***********************************************************************/
210
Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose )
211
{
212
    Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL;
213
    Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
214 215
    Gia_Man_t * pNew  = Acec_InsertBox( pBox, 1 );
    Acec_BoxFreeP( &pBox );
216
    Vec_BitFreeP( &vIgnore );
217 218 219 220 221 222 223 224 225 226
    return pNew;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END