abcReconv.c 24.6 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [abcReconv.c]
Alan Mishchenko committed
4 5 6 7 8

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

Alan Mishchenko committed
9
  Synopsis    [Computation of reconvergence-driven cuts.]
Alan Mishchenko committed
10 11 12 13 14 15 16

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

Alan Mishchenko committed
17
  Revision    [$Id: abcReconv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20 21

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

#include "abc.h"
22
#include "extra.h"
Alan Mishchenko committed
23

24 25 26
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
27 28 29 30 31 32 33 34 35
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

struct Abc_ManCut_t_
{
    // user specified parameters
    int              nNodeSizeMax;  // the limit on the size of the supernode
    int              nConeSizeMax;  // the limit on the size of the containing cone
Alan Mishchenko committed
36 37
    int              nNodeFanStop;  // the limit on the size of the supernode
    int              nConeFanStop;  // the limit on the size of the containing cone
Alan Mishchenko committed
38
    // internal parameters
Alan Mishchenko committed
39 40
    Vec_Ptr_t *      vNodeLeaves;   // fanins of the collapsed node (the cut)
    Vec_Ptr_t *      vConeLeaves;   // fanins of the containing cone
Alan Mishchenko committed
41
    Vec_Ptr_t *      vVisited;      // the visited nodes
Alan Mishchenko committed
42 43
    Vec_Vec_t *      vLevels;       // the data structure to compute TFO nodes
    Vec_Ptr_t *      vNodesTfo;     // the nodes in the TFO of the cut
Alan Mishchenko committed
44 45
};

Alan Mishchenko committed
46 47 48
static int   Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit );
static int   Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit );
static void  Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited );
Alan Mishchenko committed
49 50

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
51
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
52 53 54 55
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
56 57 58 59 60 61 62 63 64 65 66 67 68
  Synopsis    [Unmarks the TFI cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline void Abc_NodesMark( Vec_Ptr_t * vVisited )
{
    Abc_Obj_t * pNode;
    int i;
69
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
        pNode->fMarkA = 1;
}

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

  Synopsis    [Unmarks the TFI cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline void Abc_NodesUnmark( Vec_Ptr_t * vVisited )
{
    Abc_Obj_t * pNode;
    int i;
88
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102
        pNode->fMarkA = 0;
}

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

  Synopsis    [Unmarks the TFI cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
103
static inline void Abc_NodesUnmarkB( Vec_Ptr_t * vVisited )
Alan Mishchenko committed
104 105 106
{
    Abc_Obj_t * pNode;
    int i;
107
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
108
        pNode->fMarkB = 0;
Alan Mishchenko committed
109 110 111 112
}

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

Alan Mishchenko committed
113
  Synopsis    [Evaluate the cost of removing the node from the set of leaves.]
Alan Mishchenko committed
114

Alan Mishchenko committed
115 116
  Description [Returns the number of new leaves that will be brought in.
  Returns large number if the node cannot be removed from the set of leaves.]
Alan Mishchenko committed
117 118 119 120 121 122
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
123
static inline int Abc_NodeGetLeafCostOne( Abc_Obj_t * pNode, int nFaninLimit )
Alan Mishchenko committed
124
{
Alan Mishchenko committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    int Cost;
    // make sure the node is in the construction zone
    assert( pNode->fMarkB == 1 );  
    // cannot expand over the PI node
    if ( Abc_ObjIsCi(pNode) )
        return 999;
    // get the cost of the cone
    Cost = (!Abc_ObjFanin0(pNode)->fMarkB) + (!Abc_ObjFanin1(pNode)->fMarkB);
    // always accept if the number of leaves does not increase
    if ( Cost < 2 )
        return Cost;
    // skip nodes with many fanouts
    if ( Abc_ObjFanoutNum(pNode) > nFaninLimit )
        return 999;
    // return the number of nodes that will be on the leaves if this node is removed
    return Cost;
}

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

  Synopsis    [Evaluate the cost of removing the node from the set of leaves.]

  Description [Returns the number of new leaves that will be brought in.
  Returns large number if the node cannot be removed from the set of leaves.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline int Abc_NodeGetLeafCostTwo( Abc_Obj_t * pNode, int nFaninLimit, 
    Abc_Obj_t ** ppLeafToAdd, Abc_Obj_t ** pNodeToMark1, Abc_Obj_t ** pNodeToMark2 )
{
    Abc_Obj_t * pFanin0, * pFanin1, * pTemp;
    Abc_Obj_t * pGrand, * pGrandToAdd;
    // make sure the node is in the construction zone
    assert( pNode->fMarkB == 1 );  
    // cannot expand over the PI node
Alan Mishchenko committed
163 164 165
    if ( Abc_ObjIsCi(pNode) )
        return 999;
    // skip nodes with many fanouts
Alan Mishchenko committed
166 167 168 169 170 171 172 173 174
//    if ( Abc_ObjFanoutNum(pNode) > nFaninLimit )
//        return 999;
    // get the children
    pFanin0 = Abc_ObjFanin0(pNode);
    pFanin1 = Abc_ObjFanin1(pNode);
    assert( !pFanin0->fMarkB && !pFanin1->fMarkB );
    // count the number of unique grandchildren that will be included
    // return infinite cost if this number if more than 1
    if ( Abc_ObjIsCi(pFanin0) && Abc_ObjIsCi(pFanin1) )
Alan Mishchenko committed
175
        return 999;
Alan Mishchenko committed
176 177 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
    // consider the special case when a non-CI fanin can be dropped
    if ( !Abc_ObjIsCi(pFanin0) && Abc_ObjFanin0(pFanin0)->fMarkB && Abc_ObjFanin1(pFanin0)->fMarkB )
    {
        *ppLeafToAdd  = pFanin1;
        *pNodeToMark1 = pFanin0;
        *pNodeToMark2 = NULL;
        return 1;
    }
    if ( !Abc_ObjIsCi(pFanin1) && Abc_ObjFanin0(pFanin1)->fMarkB && Abc_ObjFanin1(pFanin1)->fMarkB )
    {
        *ppLeafToAdd  = pFanin0;
        *pNodeToMark1 = pFanin1;
        *pNodeToMark2 = NULL;
        return 1;
    }

    // make the first node CI if any
    if ( Abc_ObjIsCi(pFanin1) )
        pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp;
    // consider the first node
    pGrandToAdd = NULL;
    if ( Abc_ObjIsCi(pFanin0) )
    {
        *pNodeToMark1 = NULL;
        pGrandToAdd = pFanin0;
    }
    else
    {
        *pNodeToMark1 = pFanin0;
        pGrand = Abc_ObjFanin0(pFanin0);
        if ( !pGrand->fMarkB )
        {
            if ( pGrandToAdd && pGrandToAdd != pGrand )
                return 999;
            pGrandToAdd = pGrand;
        }
        pGrand = Abc_ObjFanin1(pFanin0);
        if ( !pGrand->fMarkB )
        {
            if ( pGrandToAdd && pGrandToAdd != pGrand )
                return 999;
            pGrandToAdd = pGrand;
        }
    }
    // consider the second node
    *pNodeToMark2 = pFanin1;
    pGrand = Abc_ObjFanin0(pFanin1);
    if ( !pGrand->fMarkB )
    {
        if ( pGrandToAdd && pGrandToAdd != pGrand )
            return 999;
        pGrandToAdd = pGrand;
    }
    pGrand = Abc_ObjFanin1(pFanin1);
    if ( !pGrand->fMarkB )
    {
        if ( pGrandToAdd && pGrandToAdd != pGrand )
Alan Mishchenko committed
233
            return 999;
Alan Mishchenko committed
234 235 236 237 238
        pGrandToAdd = pGrand;
    }
    assert( pGrandToAdd != NULL );
    *ppLeafToAdd = pGrandToAdd;
    return 1;
Alan Mishchenko committed
239 240 241 242 243 244
}


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

  Synopsis    [Finds a fanin-limited, reconvergence-driven cut for the node.]
Alan Mishchenko committed
245 246 247 248 249 250 251 252

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
253
Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, int fContain )
Alan Mishchenko committed
254
{
Alan Mishchenko committed
255
    Abc_Obj_t * pNode;
Alan Mishchenko committed
256 257
    int i;

Alan Mishchenko committed
258 259 260
    assert( !Abc_ObjIsComplement(pRoot) );
    assert( Abc_ObjIsNode(pRoot) );

Alan Mishchenko committed
261
    // start the visited nodes and mark them
Alan Mishchenko committed
262
    Vec_PtrClear( p->vVisited );
Alan Mishchenko committed
263 264 265
    Vec_PtrPush( p->vVisited, pRoot );
    Vec_PtrPush( p->vVisited, Abc_ObjFanin0(pRoot) );
    Vec_PtrPush( p->vVisited, Abc_ObjFanin1(pRoot) );
Alan Mishchenko committed
266
    pRoot->fMarkB = 1;
Alan Mishchenko committed
267 268
    Abc_ObjFanin0(pRoot)->fMarkB = 1;
    Abc_ObjFanin1(pRoot)->fMarkB = 1;
Alan Mishchenko committed
269

Alan Mishchenko committed
270 271 272 273 274
    // start the cut 
    Vec_PtrClear( p->vNodeLeaves );
    Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin0(pRoot) );
    Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin1(pRoot) );

Alan Mishchenko committed
275
    // compute the cut
Alan Mishchenko committed
276 277
    while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vNodeLeaves, p->nNodeSizeMax, p->nNodeFanStop ) );
    assert( Vec_PtrSize(p->vNodeLeaves) <= p->nNodeSizeMax );
Alan Mishchenko committed
278

Alan Mishchenko committed
279 280
    // return if containing cut is not requested
    if ( !fContain )
Alan Mishchenko committed
281
    {
Alan Mishchenko committed
282 283 284
        // unmark both fMarkA and fMarkB in tbe TFI
        Abc_NodesUnmarkB( p->vVisited );
        return p->vNodeLeaves;
Alan Mishchenko committed
285 286
    }

Alan Mishchenko committed
287
//printf( "\n\n\n" );
Alan Mishchenko committed
288 289 290
    // compute the containing cut
    assert( p->nNodeSizeMax < p->nConeSizeMax );
    // copy the current boundary
Alan Mishchenko committed
291
    Vec_PtrClear( p->vConeLeaves );
292
    Vec_PtrForEachEntry( Abc_Obj_t *, p->vNodeLeaves, pNode, i )
Alan Mishchenko committed
293
        Vec_PtrPush( p->vConeLeaves, pNode );
Alan Mishchenko committed
294
    // compute the containing cut
Alan Mishchenko committed
295 296
    while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vConeLeaves, p->nConeSizeMax, p->nConeFanStop ) );
    assert( Vec_PtrSize(p->vConeLeaves) <= p->nConeSizeMax );
Alan Mishchenko committed
297
    // unmark TFI using fMarkA and fMarkB
Alan Mishchenko committed
298 299
    Abc_NodesUnmarkB( p->vVisited );
    return p->vNodeLeaves;
Alan Mishchenko committed
300 301 302 303
}

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

Alan Mishchenko committed
304
  Synopsis    [Builds reconvergence-driven cut by changing one leaf at a time.]
Alan Mishchenko committed
305

Alan Mishchenko committed
306 307 308 309
  Description [This procedure looks at the current leaves and tries to change 
  one leaf at a time in such a way that the cut grows as little as possible.
  In evaluating the fanins, this procedure looks only at their immediate 
  predecessors (this is why it is called a one-level construction procedure).]
Alan Mishchenko committed
310 311 312 313 314 315
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
316
int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit )
Alan Mishchenko committed
317 318 319 320 321 322
{
    Abc_Obj_t * pNode, * pFaninBest, * pNext;
    int CostBest, CostCur, i;
    // find the best fanin
    CostBest   = 100;
    pFaninBest = NULL;
Alan Mishchenko committed
323
//printf( "Evaluating fanins of the cut:\n" );
324
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i )
Alan Mishchenko committed
325
    {
Alan Mishchenko committed
326 327
        CostCur = Abc_NodeGetLeafCostOne( pNode, nFaninLimit );
//printf( "    Fanin %s has cost %d.\n", Abc_ObjName(pNode), CostCur );
Alan Mishchenko committed
328 329 330
//        if ( CostBest > CostCur ) // performance improvement: expand the variable with the smallest level
        if ( CostBest > CostCur ||
             (CostBest == CostCur && pNode->Level > pFaninBest->Level) )
Alan Mishchenko committed
331
        {
Alan Mishchenko committed
332 333
            CostBest   = CostCur;
            pFaninBest = pNode;
Alan Mishchenko committed
334
        }
Alan Mishchenko committed
335 336
        if ( CostBest == 0 )
            break;
Alan Mishchenko committed
337 338 339
    }
    if ( pFaninBest == NULL )
        return 0;
Alan Mishchenko committed
340 341
//        return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit );

Alan Mishchenko committed
342
    assert( CostBest < 3 );
Alan Mishchenko committed
343
    if ( vLeaves->nSize - 1 + CostBest > nSizeLimit )
Alan Mishchenko committed
344
        return 0;
Alan Mishchenko committed
345 346
//        return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit );

Alan Mishchenko committed
347 348
    assert( Abc_ObjIsNode(pFaninBest) );
    // remove the node from the array
Alan Mishchenko committed
349 350 351
    Vec_PtrRemove( vLeaves, pFaninBest );
//printf( "Removing fanin %s.\n", Abc_ObjName(pFaninBest) );

Alan Mishchenko committed
352 353 354 355
    // add the left child to the fanins
    pNext = Abc_ObjFanin0(pFaninBest);
    if ( !pNext->fMarkB )
    {
Alan Mishchenko committed
356
//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) );
Alan Mishchenko committed
357
        pNext->fMarkB = 1;
Alan Mishchenko committed
358 359
        Vec_PtrPush( vLeaves, pNext );
        Vec_PtrPush( vVisited, pNext );
Alan Mishchenko committed
360 361 362 363 364
    }
    // add the right child to the fanins
    pNext = Abc_ObjFanin1(pFaninBest);
    if ( !pNext->fMarkB )
    {
Alan Mishchenko committed
365
//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) );
Alan Mishchenko committed
366
        pNext->fMarkB = 1;
Alan Mishchenko committed
367 368
        Vec_PtrPush( vLeaves, pNext );
        Vec_PtrPush( vVisited, pNext );
Alan Mishchenko committed
369
    }
Alan Mishchenko committed
370
    assert( vLeaves->nSize <= nSizeLimit );
Alan Mishchenko committed
371 372 373 374 375 376
    // keep doing this
    return 1;
}

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

Alan Mishchenko committed
377 378 379 380 381 382 383 384 385 386 387 388 389 390
  Synopsis    [Builds reconvergence-driven cut by changing one leaf at a time.]

  Description [This procedure looks at the current leaves and tries to change 
  one leaf at a time in such a way that the cut grows as little as possible.
  In evaluating the fanins, this procedure looks across two levels of fanins
  (this is why it is called a two-level construction procedure).]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit )
{
Alan Mishchenko committed
391 392
    Abc_Obj_t * pNode = NULL, * pLeafToAdd, * pNodeToMark1, * pNodeToMark2;
    int CostCur = 0, i;
Alan Mishchenko committed
393
    // find the best fanin
394
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i )
Alan Mishchenko committed
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
    {
        CostCur = Abc_NodeGetLeafCostTwo( pNode, nFaninLimit, &pLeafToAdd, &pNodeToMark1, &pNodeToMark2 );
        if ( CostCur < 2 )
            break;
    }
    if ( CostCur > 2 )
        return 0;
    // remove the node from the array
    Vec_PtrRemove( vLeaves, pNode );
    // add the node to the leaves
    if ( pLeafToAdd )
    {
        assert( !pLeafToAdd->fMarkB );
        pLeafToAdd->fMarkB = 1;
        Vec_PtrPush( vLeaves, pLeafToAdd );
        Vec_PtrPush( vVisited, pLeafToAdd );
    }
    // mark the other nodes
    if ( pNodeToMark1 )
    {
        assert( !pNodeToMark1->fMarkB );
        pNodeToMark1->fMarkB = 1;
        Vec_PtrPush( vVisited, pNodeToMark1 );
    }
    if ( pNodeToMark2 )
    {
        assert( !pNodeToMark2->fMarkB );
        pNodeToMark2->fMarkB = 1;
        Vec_PtrPush( vVisited, pNodeToMark2 );
    }
    // keep doing this
    return 1;
}


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

  Synopsis    [Get the nodes contained in the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited, int fIncludeFanins )
{
    Abc_Obj_t * pTemp;
    int i;
    // mark the fanins of the cone
    Abc_NodesMark( vLeaves );
    // collect the nodes in the DFS order
    Vec_PtrClear( vVisited );
    // add the fanins
    if ( fIncludeFanins )
451
        Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pTemp, i )
Alan Mishchenko committed
452 453 454 455 456 457 458 459 460 461 462
            Vec_PtrPush( vVisited, pTemp );
    // add other nodes
    for ( i = 0; i < nRoots; i++ )
        Abc_NodeConeMarkCollect_rec( ppRoots[i], vVisited );
    // unmark both sets
    Abc_NodesUnmark( vLeaves );
    Abc_NodesUnmark( vVisited );
}

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

Alan Mishchenko committed
463 464 465 466 467 468 469 470 471
  Synopsis    [Marks the TFI cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
472
void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited )
Alan Mishchenko committed
473 474 475 476 477 478
{
    if ( pNode->fMarkA == 1 )
        return;
    // visit transitive fanin 
    if ( Abc_ObjIsNode(pNode) )
    {
Alan Mishchenko committed
479 480
        Abc_NodeConeMarkCollect_rec( Abc_ObjFanin0(pNode), vVisited );
        Abc_NodeConeMarkCollect_rec( Abc_ObjFanin1(pNode), vVisited );
Alan Mishchenko committed
481 482 483 484 485 486 487 488
    }
    assert( pNode->fMarkA == 0 );
    pNode->fMarkA = 1;
    Vec_PtrPush( vVisited, pNode );
}

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

Alan Mishchenko committed
489
  Synopsis    [Returns BDD representing the logic function of the cone.]
Alan Mishchenko committed
490 491 492 493 494 495 496 497

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
498
DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited )
Alan Mishchenko committed
499
{
Alan Mishchenko committed
500
    Abc_Obj_t * pNode;
Alan Mishchenko committed
501
    DdNode * bFunc0, * bFunc1, * bFunc = NULL;
Alan Mishchenko committed
502
    int i;
Alan Mishchenko committed
503
    // get the nodes in the cut without fanins in the DFS order
Alan Mishchenko committed
504
    Abc_NodeConeCollect( &pRoot, 1, vLeaves, vVisited, 0 );
Alan Mishchenko committed
505
    // set the elementary BDDs
506
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i )
Alan Mishchenko committed
507 508
        pNode->pCopy = (Abc_Obj_t *)pbVars[i];
    // compute the BDDs for the collected nodes
509
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
510
    {
Alan Mishchenko committed
511
        assert( !Abc_ObjIsPi(pNode) );
512 513
        bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
        bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) );
Alan Mishchenko committed
514 515 516
        bFunc  = Cudd_bddAnd( dd, bFunc0, bFunc1 );    Cudd_Ref( bFunc );
        pNode->pCopy = (Abc_Obj_t *)bFunc;
    }
Alan Mishchenko committed
517
    assert(bFunc);
Alan Mishchenko committed
518 519
    Cudd_Ref( bFunc );
    // dereference the intermediate ones
520
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
521 522 523
        Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
    Cudd_Deref( bFunc );
    return bFunc;
Alan Mishchenko committed
524 525 526 527
}

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

Alan Mishchenko committed
528
  Synopsis    [Returns BDD representing the transition relation of the cone.]
Alan Mishchenko committed
529 530 531 532 533 534 535 536

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
537
DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited )
Alan Mishchenko committed
538
{
Alan Mishchenko committed
539 540
    DdNode * bFunc0, * bFunc1, * bFunc, * bTrans, * bTemp, * bCube, * bResult;
    Abc_Obj_t * pNode;
Alan Mishchenko committed
541
    int i;
Alan Mishchenko committed
542 543
    // get the nodes in the cut without fanins in the DFS order
    Abc_NodeConeCollect( (Abc_Obj_t **)vRoots->pArray, vRoots->nSize, vLeaves, vVisited, 0 );
Alan Mishchenko committed
544
    // set the elementary BDDs
545
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i )
Alan Mishchenko committed
546
        pNode->pCopy = (Abc_Obj_t *)pbVarsX[i];
Alan Mishchenko committed
547
    // compute the BDDs for the collected nodes
548
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
549
    {
550 551
        bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
        bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) );
Alan Mishchenko committed
552 553 554
        bFunc  = Cudd_bddAnd( dd, bFunc0, bFunc1 );    Cudd_Ref( bFunc );
        pNode->pCopy = (Abc_Obj_t *)bFunc;
    }
Alan Mishchenko committed
555 556
    // compute the transition relation of the cone
    bTrans = b1;    Cudd_Ref( bTrans );
557
    Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pNode, i )
Alan Mishchenko committed
558 559 560 561 562 563
    {
        bFunc = Cudd_bddXnor( dd, (DdNode *)pNode->pCopy, pbVarsY[i] );  Cudd_Ref( bFunc );
        bTrans = Cudd_bddAnd( dd, bTemp = bTrans, bFunc );               Cudd_Ref( bTrans );
        Cudd_RecursiveDeref( dd, bTemp );
        Cudd_RecursiveDeref( dd, bFunc );
    }
Alan Mishchenko committed
564
    // dereference the intermediate ones
565
    Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i )
Alan Mishchenko committed
566
        Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
Alan Mishchenko committed
567 568 569 570 571 572 573 574
    // compute don't-cares
    bCube = Extra_bddComputeRangeCube( dd, vRoots->nSize, vRoots->nSize + vLeaves->nSize );  Cudd_Ref( bCube );
    bResult = Cudd_bddExistAbstract( dd, bTrans, bCube );                Cudd_Ref( bResult );
    bResult = Cudd_Not( bResult );
    Cudd_RecursiveDeref( dd, bCube );
    Cudd_RecursiveDeref( dd, bTrans );
    Cudd_Deref( bResult );
    return bResult;
Alan Mishchenko committed
575
}
Alan Mishchenko committed
576
 
Alan Mishchenko committed
577 578 579 580 581 582 583 584 585 586 587
/**Function*************************************************************

  Synopsis    [Starts the resynthesis manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
588
Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop )
Alan Mishchenko committed
589 590
{
    Abc_ManCut_t * p;
Alan Mishchenko committed
591
    p = ABC_ALLOC( Abc_ManCut_t, 1 );
Alan Mishchenko committed
592
    memset( p, 0, sizeof(Abc_ManCut_t) );
Alan Mishchenko committed
593 594
    p->vNodeLeaves  = Vec_PtrAlloc( 100 );
    p->vConeLeaves  = Vec_PtrAlloc( 100 );
Alan Mishchenko committed
595
    p->vVisited     = Vec_PtrAlloc( 100 );
Alan Mishchenko committed
596
    p->vLevels      = Vec_VecAlloc( 100 );
Alan Mishchenko committed
597
    p->vNodesTfo    = Vec_PtrAlloc( 100 );
Alan Mishchenko committed
598 599
    p->nNodeSizeMax = nNodeSizeMax;
    p->nConeSizeMax = nConeSizeMax;
Alan Mishchenko committed
600 601
    p->nNodeFanStop = nNodeFanStop;
    p->nConeFanStop = nConeFanStop;
Alan Mishchenko committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    return p;
}

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

  Synopsis    [Stops the resynthesis manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkManCutStop( Abc_ManCut_t * p )
{
Alan Mishchenko committed
618 619
    Vec_PtrFree( p->vNodeLeaves );
    Vec_PtrFree( p->vConeLeaves );
Alan Mishchenko committed
620
    Vec_PtrFree( p->vVisited    );
Alan Mishchenko committed
621 622
    Vec_VecFree( p->vLevels );
    Vec_PtrFree( p->vNodesTfo );
Alan Mishchenko committed
623
    ABC_FREE( p );
Alan Mishchenko committed
624 625
}

Alan Mishchenko committed
626 627 628 629 630 631 632 633 634 635 636
/**Function*************************************************************

  Synopsis    [Returns the leaves of the cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
Vec_Ptr_t * Abc_NtkManCutReadCutLarge( Abc_ManCut_t * p )
{
    return p->vConeLeaves;
}

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

  Synopsis    [Returns the leaves of the cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
Vec_Ptr_t * Abc_NtkManCutReadCutSmall( Abc_ManCut_t * p )
{
    return p->vNodeLeaves;
}

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

  Synopsis    [Returns the leaves of the cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
669
Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p )
Alan Mishchenko committed
670
{
Alan Mishchenko committed
671
    return p->vVisited;
Alan Mishchenko committed
672
}
Alan Mishchenko committed
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691



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

  Synopsis    [Collects the TFO of the cut in the topological order.]

  Description [TFO of the cut is defined as a set of nodes, for which the cut
  is a cut, that is, every path from the collected nodes to the CIs goes through 
  a node in the cut. The nodes are collected if their level does not exceed
  the given number (LevelMax). The nodes are returned in the topological order.
  If the root node is given, its MFFC is marked, so that the collected nodes
  do not contain any nodes in the MFFC.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
692
Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int LevelMax )
Alan Mishchenko committed
693
{
Alan Mishchenko committed
694
    Abc_Ntk_t * pNtk = pRoot->pNtk;
Alan Mishchenko committed
695 696 697
    Vec_Ptr_t * vVec;
    Abc_Obj_t * pNode, * pFanout;
    int i, k, v, LevelMin;
Alan Mishchenko committed
698
    assert( Abc_NtkIsStrash(pNtk) );
Alan Mishchenko committed
699 700

    // assuming that the structure is clean
Alan Mishchenko committed
701
    Vec_VecForEachLevel( p->vLevels, vVec, i )
Alan Mishchenko committed
702 703 704 705
        assert( vVec->nSize == 0 );

    // put fanins into the structure while labeling them
    Abc_NtkIncrementTravId( pNtk );
Alan Mishchenko committed
706
    LevelMin = -1;
707
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i )
Alan Mishchenko committed
708 709 710 711
    {
        if ( pNode->Level > (unsigned)LevelMax )
            continue;
        Abc_NodeSetTravIdCurrent( pNode );
Alan Mishchenko committed
712
        Vec_VecPush( p->vLevels, pNode->Level, pNode );
Alan Mishchenko committed
713 714 715 716 717 718 719
        if ( LevelMin < (int)pNode->Level )
            LevelMin = pNode->Level;
    }
    assert( LevelMin >= 0 );

    // mark MFFC 
    if ( pRoot )
Alan Mishchenko committed
720
        Abc_NodeMffcLabelAig( pRoot );
Alan Mishchenko committed
721 722

    // go through the levels up
Alan Mishchenko committed
723
    Vec_PtrClear( p->vNodesTfo );
724
    Vec_VecForEachEntryStart( Abc_Obj_t *, p->vLevels, pNode, i, k, LevelMin )
Alan Mishchenko committed
725
    {
Alan Mishchenko committed
726 727
        if ( i > LevelMax )
            break;
Alan Mishchenko committed
728 729 730 731 732 733 734 735
        // if the node is not marked, it is not a fanin
        if ( !Abc_NodeIsTravIdCurrent(pNode) )
        {
            // check if it belongs to the TFO
            if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) || 
                 !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) )
                 continue;
            // save the node in the TFO and label it
Alan Mishchenko committed
736
            Vec_PtrPush( p->vNodesTfo, pNode );
Alan Mishchenko committed
737 738 739 740 741 742 743 744 745 746 747 748
            Abc_NodeSetTravIdCurrent( pNode );
        }
        // go through the fanouts and add them to the structure if they meet the conditions
        Abc_ObjForEachFanout( pNode, pFanout, v )
        {
            // skip if fanout is a CO or its level exceeds
            if ( Abc_ObjIsCo(pFanout) || pFanout->Level > (unsigned)LevelMax )
                continue;
            // skip if it is already added or if it is in MFFC
            if ( Abc_NodeIsTravIdCurrent(pFanout) )
                continue;
            // add it to the structure but do not mark it (until tested later)
Alan Mishchenko committed
749
            Vec_VecPushUnique( p->vLevels, pFanout->Level, pFanout );
Alan Mishchenko committed
750 751 752 753
        }
    }

    // clear the levelized structure
Alan Mishchenko committed
754 755 756 757
    Vec_VecForEachLevelStart( p->vLevels, vVec, i, LevelMin )
    {
        if ( i > LevelMax )
            break;
Alan Mishchenko committed
758
        Vec_PtrClear( vVec );
Alan Mishchenko committed
759 760
    }
    return p->vNodesTfo;
Alan Mishchenko committed
761 762 763 764 765 766 767
}

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


768 769
ABC_NAMESPACE_IMPL_END