bdcCore.c 9.49 KB
Newer Older
Alan Mishchenko committed
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
/**CFile****************************************************************

  FileName    [bdcCore.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Truth-table-based bi-decomposition engine.]

  Synopsis    [The gateway to bi-decomposition.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - January 30, 2007.]

  Revision    [$Id: bdcCore.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $]

***********************************************************************/

#include "bdcInt.h"

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
27

Alan Mishchenko committed
28 29 30 31 32 33
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

Alan Mishchenko committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  Synopsis    [Accessing contents of the node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Bdc_Fun_t *  Bdc_ManFunc( Bdc_Man_t * p, int i )               { return Bdc_FunWithId(p, i); }
Bdc_Fun_t *  Bdc_ManRoot( Bdc_Man_t * p )                      { return p->pRoot;            }
int          Bdc_ManNodeNum( Bdc_Man_t * p )                   { return p->nNodes;           }
Bdc_Fun_t *  Bdc_FuncFanin0( Bdc_Fun_t * p )                   { return p->pFan0;            }
Bdc_Fun_t *  Bdc_FuncFanin1( Bdc_Fun_t * p )                   { return p->pFan1;            }
void *       Bdc_FuncCopy( Bdc_Fun_t * p )                     { return p->pCopy;            }
void         Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy )    { p->pCopy = pCopy;           }

/**Function*************************************************************

Alan Mishchenko committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66
  Synopsis    [Allocate resynthesis manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars )
{
    Bdc_Man_t * p;
    p = ALLOC( Bdc_Man_t, 1 );
    memset( p, 0, sizeof(Bdc_Man_t) );
Alan Mishchenko committed
67
    assert( pPars->nVarsMax > 2 && pPars->nVarsMax < 16 );
Alan Mishchenko committed
68 69 70 71 72 73
    p->pPars = pPars;
    p->nWords = Kit_TruthWordNum( pPars->nVarsMax );
    p->nDivsLimit = 200;
    // internal nodes
    p->nNodesAlloc = 512;
    p->pNodes = ALLOC( Bdc_Fun_t, p->nNodesAlloc );
Alan Mishchenko committed
74 75
    // memory
    p->vMemory = Vec_IntStart( 4 * p->nWords * p->nNodesAlloc );
Alan Mishchenko committed
76 77 78 79 80 81
    // set up hash table
    p->nTableSize = (1 << p->pPars->nVarsMax);
    p->pTable = ALLOC( Bdc_Fun_t *, p->nTableSize );
    memset( p->pTable, 0, sizeof(Bdc_Fun_t *) * p->nTableSize );
    p->vSpots = Vec_IntAlloc( 256 );
    // truth tables
Alan Mishchenko committed
82 83 84 85 86
    p->vTruths = Vec_PtrAllocTruthTables( p->pPars->nVarsMax );
    p->puTemp1 = ALLOC( unsigned, 4 * p->nWords );
    p->puTemp2 = p->puTemp1 + p->nWords;
    p->puTemp3 = p->puTemp2 + p->nWords;
    p->puTemp4 = p->puTemp3 + p->nWords;
Alan Mishchenko committed
87 88 89 90 91
    // start the internal ISFs
    p->pIsfOL = &p->IsfOL;  Bdc_IsfStart( p, p->pIsfOL );
    p->pIsfOR = &p->IsfOR;  Bdc_IsfStart( p, p->pIsfOR );
    p->pIsfAL = &p->IsfAL;  Bdc_IsfStart( p, p->pIsfAL );
    p->pIsfAR = &p->IsfAR;  Bdc_IsfStart( p, p->pIsfAR );   
Alan Mishchenko committed
92
    return p; 
Alan Mishchenko committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
}

/**Function*************************************************************

  Synopsis    [Deallocate resynthesis manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Bdc_ManFree( Bdc_Man_t * p )
{
Alan Mishchenko committed
108 109 110 111 112 113 114 115 116 117 118 119
    if ( p->pPars->fVerbose )
    {
        printf( "Bi-decomposition stats: Calls = %d.  Nodes = %d. Reuse = %d.\n", 
            p->numCalls, p->numNodes, p->numReuse );
        printf( "ANDs = %d.  ORs = %d.  Weak = %d.  Muxes = %d.  Memory = %.2f K\n", 
            p->numAnds, p->numOrs, p->numWeaks, p->numMuxes, 4.0 * Vec_IntSize(p->vMemory) / (1<<10) );
        PRT( "Cache", p->timeCache );
        PRT( "Check", p->timeCheck );
        PRT( "Muxes", p->timeMuxes );
        PRT( "Supps", p->timeSupps );
        PRT( "TOTAL", p->timeTotal );
    }
Alan Mishchenko committed
120 121 122
    Vec_IntFree( p->vMemory );
    Vec_IntFree( p->vSpots );
    Vec_PtrFree( p->vTruths );
Alan Mishchenko committed
123
    free( p->puTemp1 );
Alan Mishchenko committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    free( p->pNodes );
    free( p->pTable );
    free( p );
}

/**Function*************************************************************

  Synopsis    [Clears the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Bdc_ManPrepare( Bdc_Man_t * p, Vec_Ptr_t * vDivs )
{
    unsigned * puTruth;
    Bdc_Fun_t * pNode;
    int i;
    Bdc_TableClear( p );
    Vec_IntClear( p->vMemory );
    // add constant 1 and elementary vars
Alan Mishchenko committed
148 149 150 151 152
    p->nNodes = 0;
    p->nNodesNew = - 1 - p->nVars - (vDivs? Vec_PtrSize(vDivs) : 0);
    // add constant 1
    pNode = Bdc_FunNew( p );
    pNode->Type = BDC_TYPE_CONST1;
Alan Mishchenko committed
153 154
    pNode->puFunc = (unsigned *)Vec_IntFetch(p->vMemory, p->nWords); 
    Kit_TruthFill( pNode->puFunc, p->nVars );
Alan Mishchenko committed
155 156 157 158
    pNode->uSupp = 0;
    Bdc_TableAdd( p, pNode );
    // add variables
    for ( i = 0; i < p->nVars; i++ )
Alan Mishchenko committed
159 160 161 162
    {
        pNode = Bdc_FunNew( p );
        pNode->Type = BDC_TYPE_PI;
        pNode->puFunc = Vec_PtrEntry( p->vTruths, i );
Alan Mishchenko committed
163
        pNode->uSupp = (1 << i);
Alan Mishchenko committed
164 165 166
        Bdc_TableAdd( p, pNode );
    }
    // add the divisors
Alan Mishchenko committed
167
    if ( vDivs )
Alan Mishchenko committed
168 169 170 171 172 173 174 175 176 177
    Vec_PtrForEachEntry( vDivs, puTruth, i )
    {
        pNode = Bdc_FunNew( p );
        pNode->Type = BDC_TYPE_PI;
        pNode->puFunc = puTruth;
        pNode->uSupp = Kit_TruthSupport( puTruth, p->nVars );
        Bdc_TableAdd( p, pNode );
        if ( i == p->nDivsLimit )
            break;
    }
Alan Mishchenko committed
178 179 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 210 211
    assert( p->nNodesNew == 0 );
}

/**Function*************************************************************

  Synopsis    [Clears the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Bdc_ManDecPrint( Bdc_Man_t * p )
{
    Bdc_Fun_t * pNode;
    int i;
    printf( " 0 : Const 1\n" );
    for ( i = 1; i < p->nNodes; i++ )
    {
        printf( " %d : ", i );
        pNode = p->pNodes + i;
        if ( pNode->Type == BDC_TYPE_PI )
            printf( "PI   " );
        else
        {
            printf( "%s%d &", Bdc_IsComplement(pNode->pFan0)? "-":"", Bdc_FunId(p,Bdc_Regular(pNode->pFan0)) );
            printf( " %s%d   ", Bdc_IsComplement(pNode->pFan1)? "-":"", Bdc_FunId(p,Bdc_Regular(pNode->pFan1)) );
        }
        Extra_PrintBinary( stdout, pNode->puFunc, (1<<p->nVars) );
        printf( "\n" );
    }
    printf( "Root = %s%d.\n", Bdc_IsComplement(p->pRoot)? "-":"", Bdc_FunId(p,Bdc_Regular(p->pRoot)) );
Alan Mishchenko committed
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
}

/**Function*************************************************************

  Synopsis    [Performs decomposition of one function.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int nVars, Vec_Ptr_t * vDivs, int nNodesMax )
{
    Bdc_Isf_t Isf, * pIsf = &Isf;
Alan Mishchenko committed
228
    int clk = clock();
Alan Mishchenko committed
229
    assert( nVars <= p->pPars->nVarsMax );
Alan Mishchenko committed
230 231 232
    // set current manager parameters
    p->nVars = nVars;
    p->nWords = Kit_TruthWordNum( nVars );
Alan Mishchenko committed
233
    p->nNodesMax = nNodesMax;
Alan Mishchenko committed
234
    Bdc_ManPrepare( p, vDivs );
Alan Mishchenko committed
235 236 237 238 239
    if ( puCare && Kit_TruthIsConst0( puCare, nVars ) )
    {
        p->pRoot = Bdc_Not(p->pNodes);
        return 0;
    }
Alan Mishchenko committed
240 241
    // copy the function
    Bdc_IsfStart( p, pIsf );
Alan Mishchenko committed
242 243 244 245 246 247 248 249 250 251
    if ( puCare )
    {
        Kit_TruthAnd( pIsf->puOn, puCare, puFunc, p->nVars );
        Kit_TruthSharp( pIsf->puOff, puCare, puFunc, p->nVars );
    }
    else
    {
        Kit_TruthCopy( pIsf->puOn, puFunc, p->nVars );
        Kit_TruthNot( pIsf->puOff, puFunc, p->nVars );
    }
Alan Mishchenko committed
252
    Bdc_SuppMinimize( p, pIsf );
Alan Mishchenko committed
253
    // call decomposition
Alan Mishchenko committed
254
    p->pRoot = Bdc_ManDecompose_rec( p, pIsf );
Alan Mishchenko committed
255 256 257
    p->timeTotal += clock() - clk;
    p->numCalls++;
    p->numNodes += p->nNodesNew;
Alan Mishchenko committed
258 259
    if ( p->pRoot == NULL )
        return -1;
Alan Mishchenko committed
260 261 262
    if ( !Bdc_ManNodeVerify( p, pIsf, p->pRoot ) )
        printf( "Bdc_ManDecompose(): Internal verification failed.\n" );
//    assert( Bdc_ManNodeVerify( p, pIsf, p->pRoot ) );
Alan Mishchenko committed
263 264 265
    return p->nNodesNew;
}

Alan Mishchenko committed
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
/**Function*************************************************************

  Synopsis    [Performs decomposition of one function.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Bdc_ManDecomposeTest( unsigned uTruth, int nVars )
{
    static int Counter = 0;
    static int Total = 0;
    Bdc_Par_t Pars = {0}, * pPars = &Pars;
    Bdc_Man_t * p;
    int RetValue;
//    unsigned uCare = ~0x888f888f;
    unsigned uCare = ~0;
//    unsigned uFunc =  0x88888888;
//    unsigned uFunc =  0xf888f888;
//    unsigned uFunc =  0x117e117e;
//    unsigned uFunc =  0x018b018b;
    unsigned uFunc = uTruth; 

    pPars->nVarsMax = 8;
    p = Bdc_ManAlloc( pPars );
    RetValue = Bdc_ManDecompose( p, &uFunc, &uCare, nVars, NULL, 1000 );
    Total += RetValue;
    printf( "%5d : Nodes = %5d. Total = %8d.\n", ++Counter, RetValue, Total );
//    Bdc_ManDecPrint( p );
    Bdc_ManFree( p );
}

Alan Mishchenko committed
301 302 303 304 305 306

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