saigDup.c 17.6 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
/**CFile****************************************************************

  FileName    [saigDup.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Sequential AIG package.]

  Synopsis    [Various duplication procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

  Revision    [$Id: saigDup.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

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

#include "saig.h"

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    [Duplicates while ORing the POs of sequential circuit.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
45
Aig_Man_t * Saig_ManDupOrpos( Aig_Man_t * pAig )
Alan Mishchenko committed
46 47 48 49
{
    Aig_Man_t * pAigNew;
    Aig_Obj_t * pObj, * pMiter;
    int i;
50 51 52 53 54
    if ( pAig->nConstrs > 0 )
    {
        printf( "The AIG manager should have no constraints.\n" );
        return NULL;
    }
Alan Mishchenko committed
55 56
    // start the new manager
    pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
57
    pAigNew->pName = Abc_UtilStrsav( pAig->pName );
58
    pAigNew->nConstrs = pAig->nConstrs;
Alan Mishchenko committed
59 60 61
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
    // create variables for PIs
62 63
    Aig_ManForEachCi( pAig, pObj, i )
        pObj->pData = Aig_ObjCreateCi( pAigNew );
Alan Mishchenko committed
64 65 66 67 68 69 70
    // add internal nodes of this frame
    Aig_ManForEachNode( pAig, pObj, i )
        pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
    // create PO of the circuit
    pMiter = Aig_ManConst0( pAigNew );
    Saig_ManForEachPo( pAig, pObj, i )
        pMiter = Aig_Or( pAigNew, pMiter, Aig_ObjChild0Copy(pObj) );
71
    Aig_ObjCreateCo( pAigNew, pMiter );
Alan Mishchenko committed
72 73
    // transfer to register outputs
    Saig_ManForEachLi( pAig, pObj, i )
74
        Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
75 76 77 78 79
    Aig_ManCleanup( pAigNew );
    Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) );
    return pAigNew;
}

Alan Mishchenko committed
80 81
/**Function*************************************************************

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
  Synopsis    [Duplicates while ORing the POs of sequential circuit.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Man_t * Saig_ManCreateEquivMiter( Aig_Man_t * pAig, Vec_Int_t * vPairs )
{
    Aig_Man_t * pAigNew;
    Aig_Obj_t * pObj, * pObj2, * pMiter;
    int i;
    if ( pAig->nConstrs > 0 )
    {
        printf( "The AIG manager should have no constraints.\n" );
        return NULL;
    }
    // start the new manager
    pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
103
    pAigNew->pName = Abc_UtilStrsav( pAig->pName );
104 105 106 107
    pAigNew->nConstrs = pAig->nConstrs;
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
    // create variables for PIs
108 109
    Aig_ManForEachCi( pAig, pObj, i )
        pObj->pData = Aig_ObjCreateCi( pAigNew );
110 111 112 113 114
    // add internal nodes of this frame
    Aig_ManForEachNode( pAig, pObj, i )
        pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
    // create POs
    assert( Vec_IntSize(vPairs) % 2 == 0 );
115
    Aig_ManForEachObjVec( vPairs, pAig, pObj, i )
116 117
    {
        pObj2  = Aig_ManObj( pAig, Vec_IntEntry(vPairs, ++i) );
118
        pMiter = Aig_Exor( pAigNew, (Aig_Obj_t *)pObj->pData, (Aig_Obj_t *)pObj2->pData );
119
        pMiter = Aig_NotCond( pMiter, pObj->fPhase ^ pObj2->fPhase );
120
        Aig_ObjCreateCo( pAigNew, pMiter );
121 122 123
    }
    // transfer to register outputs
    Saig_ManForEachLi( pAig, pObj, i )
124
        Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
125 126 127 128 129 130 131
    Aig_ManCleanup( pAigNew );
    Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) );
    return pAigNew;
}

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

Alan Mishchenko committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  Synopsis    [Trims the model by removing PIs without fanout.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Man_t * Saig_ManTrimPis( Aig_Man_t * p )
{
    Aig_Man_t * pNew;
    Aig_Obj_t * pObj;
    int i, fAllPisHaveNoRefs;
    // check the refs of PIs    
    fAllPisHaveNoRefs = 1;
    Saig_ManForEachPi( p, pObj, i )
        if ( pObj->nRefs )
            fAllPisHaveNoRefs = 0;
    // start the new manager
    pNew = Aig_ManStart( Aig_ManObjNum(p) );
153
    pNew->pName = Abc_UtilStrsav( p->pName );
154
    pNew->nConstrs = p->nConstrs;
Alan Mishchenko committed
155
    // start mapping of the CI numbers
156
    pNew->vCiNumsOrig = Vec_IntAlloc( Aig_ManCiNum(p) );
Alan Mishchenko committed
157 158 159
    // map const and primary inputs
    Aig_ManCleanData( p );
    Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
160
    Aig_ManForEachCi( p, pObj, i )
Alan Mishchenko committed
161 162
        if ( fAllPisHaveNoRefs || pObj->nRefs || Saig_ObjIsLo(p, pObj) )
        {
163
            pObj->pData = Aig_ObjCreateCi( pNew );
Alan Mishchenko committed
164 165 166 167
            Vec_IntPush( pNew->vCiNumsOrig, Vec_IntEntry(p->vCiNumsOrig, i) );
        }
    Aig_ManForEachNode( p, pObj, i )
        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
168 169
    Aig_ManForEachCo( p, pObj, i )
        pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
170 171 172 173 174 175
    Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
    return pNew;
}

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

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
  Synopsis    [Duplicates the AIG manager recursively.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Obj_t * Saig_ManAbstractionDfs_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
{
    if ( pObj->pData )
        return (Aig_Obj_t *)pObj->pData;
    Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin0(pObj) );
    Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin1(pObj) );
    return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ));
}

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

Alan Mishchenko committed
196 197 198 199 200 201 202 203 204
  Synopsis    [Performs abstraction of the AIG to preserve the included flops.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
205
Aig_Man_t * Saig_ManDupAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops )
Alan Mishchenko committed
206
{ 
207
    Aig_Man_t * pNew;//, * pTemp;
Alan Mishchenko committed
208 209
    Aig_Obj_t * pObj, * pObjLi, * pObjLo;
    int i, Entry;
Alan Mishchenko committed
210
    Aig_ManCleanData( p );
Alan Mishchenko committed
211
    // start the new manager
212
    pNew = Aig_ManStart( 5000 );
213
    pNew->pName = Abc_UtilStrsav( p->pName );
Alan Mishchenko committed
214
    // map the constant node
Alan Mishchenko committed
215
    Aig_ManConst1(p)->pData = Aig_ManConst1( pNew );
Alan Mishchenko committed
216 217 218
    // label included flops
    Vec_IntForEachEntry( vFlops, Entry, i )
    {
Alan Mishchenko committed
219
        pObjLi = Saig_ManLi( p, Entry );
Alan Mishchenko committed
220 221
        assert( pObjLi->fMarkA == 0 );
        pObjLi->fMarkA = 1;
Alan Mishchenko committed
222
        pObjLo = Saig_ManLo( p, Entry );
Alan Mishchenko committed
223 224 225 226
        assert( pObjLo->fMarkA == 0 );
        pObjLo->fMarkA = 1;
    }
    // create variables for PIs
Alan Mishchenko committed
227
    assert( p->vCiNumsOrig == NULL );
228
    pNew->vCiNumsOrig = Vec_IntAlloc( Aig_ManCiNum(p) );
229
    Aig_ManForEachCi( p, pObj, i )
Alan Mishchenko committed
230
        if ( !pObj->fMarkA )
Alan Mishchenko committed
231
        {
232
            pObj->pData = Aig_ObjCreateCi( pNew );
Alan Mishchenko committed
233 234
            Vec_IntPush( pNew->vCiNumsOrig, i );
        }
Alan Mishchenko committed
235
    // create variables for LOs
236
    Aig_ManForEachCi( p, pObj, i )
Alan Mishchenko committed
237 238 239
        if ( pObj->fMarkA )
        {
            pObj->fMarkA = 0;
240
            pObj->pData = Aig_ObjCreateCi( pNew );
Alan Mishchenko committed
241
            Vec_IntPush( pNew->vCiNumsOrig, i );
Alan Mishchenko committed
242
        }
Alan Mishchenko committed
243
    // add internal nodes 
Alan Mishchenko committed
244 245
//    Aig_ManForEachNode( p, pObj, i )
//        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
Alan Mishchenko committed
246
    // create POs
Alan Mishchenko committed
247 248 249
    Saig_ManForEachPo( p, pObj, i )
    {
        Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin0(pObj) );
250
        Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
251
    }
Alan Mishchenko committed
252
    // create LIs
253
    Aig_ManForEachCo( p, pObj, i )
Alan Mishchenko committed
254 255 256
        if ( pObj->fMarkA )
        {
            pObj->fMarkA = 0;
Alan Mishchenko committed
257
            Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin0(pObj) );
258
            Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
259
        }
Alan Mishchenko committed
260 261 262
    Aig_ManSetRegNum( pNew, Vec_IntSize(vFlops) );
    Aig_ManSeqCleanup( pNew );
    // remove PIs without fanout
263 264
//    pNew = Saig_ManTrimPis( pTemp = pNew );
//    Aig_ManStop( pTemp );
Alan Mishchenko committed
265
    return pNew;
Alan Mishchenko committed
266 267
}

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
/**Function*************************************************************

  Synopsis    [Resimulates the counter-example.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Saig_ManVerifyCex( Aig_Man_t * pAig, Abc_Cex_t * p )
{
    Aig_Obj_t * pObj, * pObjRi, * pObjRo;
    int RetValue, i, k, iBit = 0;
    Aig_ManCleanMarkB(pAig);
    Aig_ManConst1(pAig)->fMarkB = 1;
    Saig_ManForEachLo( pAig, pObj, i )
286
        pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
287 288 289
    for ( i = 0; i <= p->iFrame; i++ )
    {
        Saig_ManForEachPi( pAig, pObj, k )
290
            pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
291 292 293
        Aig_ManForEachNode( pAig, pObj, k )
            pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & 
                           (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj));
294
        Aig_ManForEachCo( pAig, pObj, k )
295 296 297 298 299 300 301
            pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj);
        if ( i == p->iFrame )
            break;
        Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k )
            pObjRo->fMarkB = pObjRi->fMarkB;
    }
    assert( iBit == p->nBits );
302
    RetValue = Aig_ManCo(pAig, p->iPo)->fMarkB;
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
    Aig_ManCleanMarkB(pAig);
    return RetValue;
}

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

  Synopsis    [Resimulates the counter-example.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
318 319 320 321 322 323
Abc_Cex_t * Saig_ManExtendCex( Aig_Man_t * pAig, Abc_Cex_t * p )
{
    Abc_Cex_t * pNew;
    Aig_Obj_t * pObj, * pObjRi, * pObjRo;
    int RetValue, i, k, iBit = 0;
    // create new counter-example
324
    pNew = Abc_CexAlloc( 0, Aig_ManCiNum(pAig), p->iFrame + 1 );
325 326 327 328 329 330
    pNew->iPo = p->iPo;
    pNew->iFrame = p->iFrame;
    // simulate the AIG
    Aig_ManCleanMarkB(pAig);
    Aig_ManConst1(pAig)->fMarkB = 1;
    Saig_ManForEachLo( pAig, pObj, i )
331
        pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
332 333 334
    for ( i = 0; i <= p->iFrame; i++ )
    {
        Saig_ManForEachPi( pAig, pObj, k )
335
            pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
336
        ///////// write PI+LO values ////////////
337
        Aig_ManForEachCi( pAig, pObj, k )
338
            if ( pObj->fMarkB )
339
                Abc_InfoSetBit(pNew->pData, Aig_ManCiNum(pAig)*i + k);
340 341 342 343
        /////////////////////////////////////////
        Aig_ManForEachNode( pAig, pObj, k )
            pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & 
                           (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj));
344
        Aig_ManForEachCo( pAig, pObj, k )
345 346 347 348 349 350 351
            pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj);
        if ( i == p->iFrame )
            break;
        Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k )
            pObjRo->fMarkB = pObjRi->fMarkB;
    }
    assert( iBit == p->nBits );
352
    RetValue = Aig_ManCo(pAig, p->iPo)->fMarkB;
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
    Aig_ManCleanMarkB(pAig);
    if ( RetValue == 0 )
        printf( "Saig_ManExtendCex(): The counter-example is invalid!!!\n" );
    return pNew;
}

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

  Synopsis    [Resimulates the counter-example.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
370 371 372 373 374 375 376
int Saig_ManFindFailedPoCex( Aig_Man_t * pAig, Abc_Cex_t * p )
{
    Aig_Obj_t * pObj, * pObjRi, * pObjRo;
    int RetValue, i, k, iBit = 0;
    Aig_ManCleanMarkB(pAig);
    Aig_ManConst1(pAig)->fMarkB = 1;
    Saig_ManForEachLo( pAig, pObj, i )
377
        pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
378 379 380
    for ( i = 0; i <= p->iFrame; i++ )
    {
        Saig_ManForEachPi( pAig, pObj, k )
381
            pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
382 383 384
        Aig_ManForEachNode( pAig, pObj, k )
            pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & 
                           (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj));
385
        Aig_ManForEachCo( pAig, pObj, k )
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
            pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj);
        if ( i == p->iFrame )
            break;
        Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k )
            pObjRo->fMarkB = pObjRi->fMarkB;
    }
    assert( iBit == p->nBits );
    // remember the number of failed output
    RetValue = -1;
    Saig_ManForEachPo( pAig, pObj, i )
        if ( pObj->fMarkB )
        {
            RetValue = i;
            break;
        }
    Aig_ManCleanMarkB(pAig);
    return RetValue;
}

405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
/**Function*************************************************************

  Synopsis    [Duplicates while ORing the POs of sequential circuit.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Man_t * Saig_ManDupWithPhase( Aig_Man_t * pAig, Vec_Int_t * vInit )
{
    Aig_Man_t * pAigNew;
    Aig_Obj_t * pObj;
    int i;
    assert( Aig_ManRegNum(pAig) <= Vec_IntSize(vInit) );
    // start the new manager
    pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
424
    pAigNew->pName = Abc_UtilStrsav( pAig->pName );
425 426 427 428
    pAigNew->nConstrs = pAig->nConstrs;
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
    // create variables for PIs
429 430
    Aig_ManForEachCi( pAig, pObj, i )
        pObj->pData = Aig_ObjCreateCi( pAigNew );
431 432
    // update the flop variables
    Saig_ManForEachLo( pAig, pObj, i )
433
        pObj->pData = Aig_NotCond( (Aig_Obj_t *)pObj->pData, Vec_IntEntry(vInit, i) );
434 435 436 437 438
    // add internal nodes of this frame
    Aig_ManForEachNode( pAig, pObj, i )
        pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
    // transfer to register outputs
    Saig_ManForEachPo( pAig, pObj, i )
439
        Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
440 441
    // update the flop variables
    Saig_ManForEachLi( pAig, pObj, i )
442
        Aig_ObjCreateCo( pAigNew, Aig_NotCond(Aig_ObjChild0Copy(pObj), Vec_IntEntry(vInit, i)) );
443 444 445 446 447 448
    // finalize
    Aig_ManCleanup( pAigNew );
    Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) );
    return pAigNew;
}

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
/**Function*************************************************************

  Synopsis    [Copy an AIG structure related to the selected POs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Saig_ManDupCones_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNodes, Vec_Ptr_t * vRoots )
{
    if ( Aig_ObjIsTravIdCurrent(p, pObj) )
        return;
    Aig_ObjSetTravIdCurrent(p, pObj);
    if ( Aig_ObjIsNode(pObj) )
    {
        Saig_ManDupCones_rec( p, Aig_ObjFanin0(pObj), vLeaves, vNodes, vRoots );
        Saig_ManDupCones_rec( p, Aig_ObjFanin1(pObj), vLeaves, vNodes, vRoots );
        Vec_PtrPush( vNodes, pObj );
    }
471
    else if ( Aig_ObjIsCo(pObj) )
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
        Saig_ManDupCones_rec( p, Aig_ObjFanin0(pObj), vLeaves, vNodes, vRoots );
    else if ( Saig_ObjIsLo(p, pObj) )
        Vec_PtrPush( vRoots, Saig_ObjLoToLi(p, pObj) );
    else if ( Saig_ObjIsPi(p, pObj) )
        Vec_PtrPush( vLeaves, pObj );
    else assert( 0 );
}
Aig_Man_t * Saig_ManDupCones( Aig_Man_t * pAig, int * pPos, int nPos )
{
    Aig_Man_t * pAigNew;
    Vec_Ptr_t * vLeaves, * vNodes, * vRoots;
    Aig_Obj_t * pObj;
    int i;

    // collect initial POs
    vLeaves = Vec_PtrAlloc( 100 );
    vNodes = Vec_PtrAlloc( 100 );
    vRoots = Vec_PtrAlloc( 100 );
    for ( i = 0; i < nPos; i++ )
491
        Vec_PtrPush( vRoots, Aig_ManCo(pAig, pPos[i]) );
492 493 494 495 496 497 498 499 500 501 502 503 504 505

    // mark internal nodes
    Aig_ManIncrementTravId( pAig );
    Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) );
    Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i )
        Saig_ManDupCones_rec( pAig, pObj, vLeaves, vNodes, vRoots );

    // start the new manager
    pAigNew = Aig_ManStart( Vec_PtrSize(vNodes) );
    pAigNew->pName = Abc_UtilStrsav( pAig->pName );
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
    // create PIs
    Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i )
506
        pObj->pData = Aig_ObjCreateCi( pAigNew );
507 508
    // create LOs
    Vec_PtrForEachEntryStart( Aig_Obj_t *, vRoots, pObj, i, nPos )
509
        Saig_ObjLiToLo(pAig, pObj)->pData = Aig_ObjCreateCi( pAigNew );
510 511 512 513 514
    // create internal nodes
    Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
        pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
    // create COs
    Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i )
515
        Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
516 517 518 519 520 521 522 523 524
    // finalize
    Aig_ManSetRegNum( pAigNew, Vec_PtrSize(vRoots)-nPos );
    Vec_PtrFree( vLeaves );
    Vec_PtrFree( vNodes );
    Vec_PtrFree( vRoots );
    return pAigNew;

}

Alan Mishchenko committed
525 526 527 528 529
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


530 531
ABC_NAMESPACE_IMPL_END