hopDfs.c 13.6 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [hopDfs.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Minimalistic And-Inverter Graph package.]

  Synopsis    [DFS traversal procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - May 11, 2006.]

Alan Mishchenko committed
17
  Revision    [$Id: hopDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20

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

Alan Mishchenko committed
21
#include "hop.h"
Alan Mishchenko committed
22

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
45
void Hop_ManDfs_rec( Hop_Obj_t * pObj, Vec_Ptr_t * vNodes )
Alan Mishchenko committed
46
{
Alan Mishchenko committed
47 48
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
49
        return;
Alan Mishchenko committed
50 51 52 53
    Hop_ManDfs_rec( Hop_ObjFanin0(pObj), vNodes );
    Hop_ManDfs_rec( Hop_ObjFanin1(pObj), vNodes );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA(pObj);
Alan Mishchenko committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67
    Vec_PtrPush( vNodes, pObj );
}

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

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
68
Vec_Ptr_t * Hop_ManDfs( Hop_Man_t * p )
Alan Mishchenko committed
69 70
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
71
    Hop_Obj_t * pObj;
Alan Mishchenko committed
72
    int i;
Alan Mishchenko committed
73 74 75 76 77
    vNodes = Vec_PtrAlloc( Hop_ManNodeNum(p) );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ManDfs_rec( pObj, vNodes );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ObjClearMarkA(pObj);
Alan Mishchenko committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91
    return vNodes;
}

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

  Synopsis    [Collects internal nodes in the DFS order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
92
Vec_Ptr_t * Hop_ManDfsNode( Hop_Man_t * p, Hop_Obj_t * pNode )
Alan Mishchenko committed
93 94
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
95
    Hop_Obj_t * pObj;
Alan Mishchenko committed
96
    int i;
Alan Mishchenko committed
97
    assert( !Hop_IsComplement(pNode) );
Alan Mishchenko committed
98
    vNodes = Vec_PtrAlloc( 16 );
Alan Mishchenko committed
99
    Hop_ManDfs_rec( pNode, vNodes );
100
    Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i )
Alan Mishchenko committed
101
        Hop_ObjClearMarkA(pObj);
Alan Mishchenko committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115
    return vNodes;
}

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

  Synopsis    [Computes the max number of levels in the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
116
int Hop_ManCountLevels( Hop_Man_t * p )
Alan Mishchenko committed
117 118
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
119
    Hop_Obj_t * pObj;
Alan Mishchenko committed
120 121
    int i, LevelsMax, Level0, Level1;
    // initialize the levels
Alan Mishchenko committed
122 123
    Hop_ManConst1(p)->pData = NULL;
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
124 125
        pObj->pData = NULL;
    // compute levels in a DFS order
Alan Mishchenko committed
126
    vNodes = Hop_ManDfs( p );
127
    Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i )
Alan Mishchenko committed
128
    {
Alan Mishchenko committed
129 130
        Level0 = (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData;
        Level1 = (int)(ABC_PTRUINT_T)Hop_ObjFanin1(pObj)->pData;
Alan Mishchenko committed
131
        pObj->pData = (void *)(ABC_PTRUINT_T)(1 + Hop_ObjIsExor(pObj) + ABC_MAX(Level0, Level1));
Alan Mishchenko committed
132 133 134 135
    }
    Vec_PtrFree( vNodes );
    // get levels of the POs
    LevelsMax = 0;
Alan Mishchenko committed
136
    Hop_ManForEachPo( p, pObj, i )
Alan Mishchenko committed
137
        LevelsMax = ABC_MAX( LevelsMax, (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData );
Alan Mishchenko committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151
    return LevelsMax;
}

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

  Synopsis    [Creates correct reference counters at each node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
152
void Hop_ManCreateRefs( Hop_Man_t * p )
Alan Mishchenko committed
153
{
Alan Mishchenko committed
154
    Hop_Obj_t * pObj;
Alan Mishchenko committed
155 156 157 158 159
    int i;
    if ( p->fRefCount )
        return;
    p->fRefCount = 1;
    // clear refs
Alan Mishchenko committed
160 161 162 163 164 165 166
    Hop_ObjClearRef( Hop_ManConst1(p) );
    Hop_ManForEachPi( p, pObj, i )
        Hop_ObjClearRef( pObj );
    Hop_ManForEachNode( p, pObj, i )
        Hop_ObjClearRef( pObj );
    Hop_ManForEachPo( p, pObj, i )
        Hop_ObjClearRef( pObj );
Alan Mishchenko committed
167
    // set refs
Alan Mishchenko committed
168
    Hop_ManForEachNode( p, pObj, i )
Alan Mishchenko committed
169
    {
Alan Mishchenko committed
170 171
        Hop_ObjRef( Hop_ObjFanin0(pObj) );
        Hop_ObjRef( Hop_ObjFanin1(pObj) );
Alan Mishchenko committed
172
    }
Alan Mishchenko committed
173 174
    Hop_ManForEachPo( p, pObj, i )
        Hop_ObjRef( Hop_ObjFanin0(pObj) );
Alan Mishchenko committed
175 176 177 178 179 180 181 182 183 184 185 186 187
}

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

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
188
void Hop_ConeMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
189
{
Alan Mishchenko committed
190 191
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
192
        return;
Alan Mishchenko committed
193 194 195 196
    Hop_ConeMark_rec( Hop_ObjFanin0(pObj) );
    Hop_ConeMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
197 198 199 200 201 202 203 204 205 206 207 208 209
}

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

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
210
void Hop_ConeCleanAndMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
211
{
Alan Mishchenko committed
212 213
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
214
        return;
Alan Mishchenko committed
215 216 217 218
    Hop_ConeCleanAndMark_rec( Hop_ObjFanin0(pObj) );
    Hop_ConeCleanAndMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232
    pObj->pData = NULL;
}

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

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
233
int Hop_ConeCountAndMark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
234 235
{
    int Counter;
Alan Mishchenko committed
236 237
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
238
        return 0;
Alan Mishchenko committed
239 240 241 242
    Counter = 1 + Hop_ConeCountAndMark_rec( Hop_ObjFanin0(pObj) ) + 
        Hop_ConeCountAndMark_rec( Hop_ObjFanin1(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
243 244 245 246 247 248 249 250 251 252 253 254 255 256
    return Counter;
}

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

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
257
void Hop_ConeUnmark_rec( Hop_Obj_t * pObj )
Alan Mishchenko committed
258
{
Alan Mishchenko committed
259 260
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
261
        return;
Alan Mishchenko committed
262 263 264 265
    Hop_ConeUnmark_rec( Hop_ObjFanin0(pObj) ); 
    Hop_ConeUnmark_rec( Hop_ObjFanin1(pObj) );
    assert( Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjClearMarkA( pObj );
Alan Mishchenko committed
266 267 268 269 270 271 272 273 274 275 276 277 278
}

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

  Synopsis    [Counts the number of AIG nodes rooted at this cone.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
279
int Hop_DagSize( Hop_Obj_t * pObj )
Alan Mishchenko committed
280 281
{
    int Counter;
Alan Mishchenko committed
282 283
    Counter = Hop_ConeCountAndMark_rec( Hop_Regular(pObj) );
    Hop_ConeUnmark_rec( Hop_Regular(pObj) );
Alan Mishchenko committed
284 285 286 287 288 289 290 291 292 293 294 295 296 297
    return Counter;
}

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

  Synopsis    [Transfers the AIG from one manager into another.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
298
void Hop_Transfer_rec( Hop_Man_t * pDest, Hop_Obj_t * pObj )
Alan Mishchenko committed
299
{
Alan Mishchenko committed
300 301
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
302
        return;
Alan Mishchenko committed
303 304 305 306 307
    Hop_Transfer_rec( pDest, Hop_ObjFanin0(pObj) ); 
    Hop_Transfer_rec( pDest, Hop_ObjFanin1(pObj) );
    pObj->pData = Hop_And( pDest, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
308 309 310 311 312 313 314 315 316 317 318 319 320
}

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

  Synopsis    [Transfers the AIG from one manager into another.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
321
Hop_Obj_t * Hop_Transfer( Hop_Man_t * pSour, Hop_Man_t * pDest, Hop_Obj_t * pRoot, int nVars )
Alan Mishchenko committed
322
{
Alan Mishchenko committed
323
    Hop_Obj_t * pObj;
Alan Mishchenko committed
324 325 326 327
    int i;
    // solve simple cases
    if ( pSour == pDest )
        return pRoot;
Alan Mishchenko committed
328 329
    if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
        return Hop_NotCond( Hop_ManConst1(pDest), Hop_IsComplement(pRoot) );
Alan Mishchenko committed
330
    // set the PI mapping
Alan Mishchenko committed
331
    Hop_ManForEachPi( pSour, pObj, i )
Alan Mishchenko committed
332 333 334
    {
        if ( i == nVars )
           break;
Alan Mishchenko committed
335
        pObj->pData = Hop_IthVar(pDest, i);
Alan Mishchenko committed
336
    }
Alan Mishchenko committed
337
    // transfer and set markings
Alan Mishchenko committed
338
    Hop_Transfer_rec( pDest, Hop_Regular(pRoot) );
Alan Mishchenko committed
339
    // clear the markings
Alan Mishchenko committed
340
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
341
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
342 343
}

Alan Mishchenko committed
344 345 346 347 348 349 350 351 352 353 354
/**Function*************************************************************

  Synopsis    [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
355
void Hop_Compose_rec( Hop_Man_t * p, Hop_Obj_t * pObj, Hop_Obj_t * pFunc, Hop_Obj_t * pVar )
Alan Mishchenko committed
356
{
Alan Mishchenko committed
357 358
    assert( !Hop_IsComplement(pObj) );
    if ( Hop_ObjIsMarkA(pObj) )
Alan Mishchenko committed
359
        return;
Alan Mishchenko committed
360
    if ( Hop_ObjIsConst1(pObj) || Hop_ObjIsPi(pObj) )
Alan Mishchenko committed
361 362 363 364
    {
        pObj->pData = pObj == pVar ? pFunc : pObj;
        return;
    }
Alan Mishchenko committed
365 366 367 368 369
    Hop_Compose_rec( p, Hop_ObjFanin0(pObj), pFunc, pVar ); 
    Hop_Compose_rec( p, Hop_ObjFanin1(pObj), pFunc, pVar );
    pObj->pData = Hop_And( p, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
Alan Mishchenko committed
370 371 372 373 374 375 376 377 378 379 380 381 382
}

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

  Synopsis    [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
383
Hop_Obj_t * Hop_Compose( Hop_Man_t * p, Hop_Obj_t * pRoot, Hop_Obj_t * pFunc, int iVar )
Alan Mishchenko committed
384 385
{
    // quit if the PI variable is not defined
Alan Mishchenko committed
386
    if ( iVar >= Hop_ManPiNum(p) )
Alan Mishchenko committed
387
    {
Alan Mishchenko committed
388
        printf( "Hop_Compose(): The PI variable %d is not defined.\n", iVar );
Alan Mishchenko committed
389 390 391
        return NULL;
    }
    // recursively perform composition
Alan Mishchenko committed
392
    Hop_Compose_rec( p, Hop_Regular(pRoot), pFunc, Hop_ManPi(p, iVar) );
Alan Mishchenko committed
393
    // clear the markings
Alan Mishchenko committed
394
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
395
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
396 397
}

Alan Mishchenko committed
398 399
/**Function*************************************************************

Alan Mishchenko committed
400
  Synopsis    [Remaps the AIG (pRoot) to have the given support (uSupp).]
Alan Mishchenko committed
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Hop_Remap_rec( Hop_Man_t * p, Hop_Obj_t * pObj )
{
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
        return;
    Hop_Remap_rec( p, Hop_ObjFanin0(pObj) ); 
    Hop_Remap_rec( p, Hop_ObjFanin1(pObj) );
    pObj->pData = Hop_And( p, Hop_ObjChild0Copy(pObj), Hop_ObjChild1Copy(pObj) );
    assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
    Hop_ObjSetMarkA( pObj );
}

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

Alan Mishchenko committed
423
  Synopsis    [Remaps the AIG (pRoot) to have the given support (uSupp).]
Alan Mishchenko committed
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 451 452 453 454 455 456 457 458 459 460 461 462

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Hop_Obj_t * Hop_Remap( Hop_Man_t * p, Hop_Obj_t * pRoot, unsigned uSupp, int nVars )
{
    Hop_Obj_t * pObj;
    int i, k;
    // quit if the PI variable is not defined
    if ( nVars > Hop_ManPiNum(p) )
    {
        printf( "Hop_Remap(): The number of variables (%d) is more than the manager size (%d).\n", nVars, Hop_ManPiNum(p) );
        return NULL;
    }
    // return if constant
    if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
        return pRoot;
    if ( uSupp == 0 )
        return Hop_NotCond( Hop_ManConst0(p), Hop_ObjPhaseCompl(pRoot) );
    // set the PI mapping
    k = 0;
    Hop_ManForEachPi( p, pObj, i )
    {
        if ( i == nVars )
           break;
        if ( uSupp & (1 << i) )
            pObj->pData = Hop_IthVar(p, k++);
        else
            pObj->pData = Hop_ManConst0(p);
    }
    assert( k > 0 && k < nVars );
    // recursively perform composition
    Hop_Remap_rec( p, Hop_Regular(pRoot) );
    // clear the markings
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
463
    return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
Alan Mishchenko committed
464 465
}

Alan Mishchenko committed
466 467 468 469 470
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


471 472
ABC_NAMESPACE_IMPL_END