giaIf.c 22 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
/**CFile****************************************************************

  FileName    [giaMap.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Scalable AIG package.]

  Synopsis    [Manipulation of mapping associated with the AIG.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "gia.h"
22 23
#include "aig/aig/aig.h"
#include "map/if/if.h"
24
#include "bool/kit/kit.h"
25 26 27

ABC_NAMESPACE_IMPL_START

Alan Mishchenko committed
28 29 30 31 32

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

33 34 35
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
extern int Abc_RecToGia2( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vLeaves, int fHash );

Alan Mishchenko committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Load the network into FPGA manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
51
void Gia_ManSetIfParsDefault( void * pp )
Alan Mishchenko committed
52
{
53
    If_Par_t * pPars = (If_Par_t *)pp;
Alan Mishchenko committed
54
//    extern void * Abc_FrameReadLibLut();
55
    If_Par_t * p = (If_Par_t *)pPars;
Alan Mishchenko committed
56
    // set defaults
57
    memset( p, 0, sizeof(If_Par_t) );
Alan Mishchenko committed
58
    // user-controlable paramters
59 60 61 62 63 64 65 66 67 68
    p->nLutSize    = -1;
//    p->nLutSize    =  6;
    p->nCutsMax    =  8;
    p->nFlowIters  =  1;
    p->nAreaIters  =  2;
    p->DelayTarget = -1;
    p->Epsilon     =  (float)0.005;
    p->fPreprocess =  1;
    p->fArea       =  0;
    p->fFancy      =  0;
69
    p->fExpRed     =  1; ////
70 71 72 73 74 75 76
    p->fLatchPaths =  0;
    p->fEdge       =  1;
    p->fPower      =  0;
    p->fCutMin     =  0;
    p->fSeqMap     =  0;
    p->fVerbose    =  0;
    p->pLutStruct  =  NULL;
Alan Mishchenko committed
77
    // internal parameters
78 79 80 81 82 83 84 85 86
    p->fTruth      =  0;
    p->nLatchesCi  =  0;
    p->nLatchesCo  =  0;
    p->fLiftLeaves =  0;
    p->fUseCoAttrs =  1;   // use CO attributes
    p->pLutLib     =  NULL;
    p->pTimesArr   =  NULL; 
    p->pTimesArr   =  NULL;   
    p->pFuncCost   =  NULL;   
Alan Mishchenko committed
87 88
}

89

Alan Mishchenko committed
90 91
/**Function*************************************************************

92
  Synopsis    [Prints mapping statistics.]
Alan Mishchenko committed
93 94 95 96 97 98 99 100

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
101
int Gia_ManLutFaninCount( Gia_Man_t * p )
Alan Mishchenko committed
102
{
103 104 105 106
    int i, Counter = 0;
    Gia_ManForEachLut( p, i )
        Counter += Gia_ObjLutSize(p, i);
    return Counter;
Alan Mishchenko committed
107 108 109 110
}

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

111
  Synopsis    [Prints mapping statistics.]
Alan Mishchenko committed
112 113 114 115 116 117 118 119

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
120
int Gia_ManLutSizeMax( Gia_Man_t * p )
Alan Mishchenko committed
121
{
122 123 124 125
    int i, nSizeMax = -1;
    Gia_ManForEachLut( p, i )
        nSizeMax = Abc_MaxInt( nSizeMax, Gia_ObjLutSize(p, i) );
    return nSizeMax;
Alan Mishchenko committed
126 127 128 129
}

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

130
  Synopsis    [Prints mapping statistics.]
Alan Mishchenko committed
131 132 133 134 135 136 137 138

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
139
int Gia_ManLutNum( Gia_Man_t * p )
Alan Mishchenko committed
140
{
141 142 143 144
    int i, Counter = 0;
    Gia_ManForEachLut( p, i )
        Counter ++;
    return Counter;
Alan Mishchenko committed
145 146 147 148 149 150 151 152 153 154 155 156 157
}

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

  Synopsis    [Prints mapping statistics.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
158
int Gia_ManLutLevel( Gia_Man_t * p )
Alan Mishchenko committed
159
{
160 161 162
    Gia_Obj_t * pObj;
    int i, k, iFan, Level;
    int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
163
    Gia_ManForEachLut( p, i )
Alan Mishchenko committed
164
    {
165
        Level = 0;
166
        Gia_LutForEachFanin( p, i, iFan, k )
167 168 169
            if ( Level < pLevels[iFan] )
                Level = pLevels[iFan];
        pLevels[i] = Level + 1;
Alan Mishchenko committed
170
    }
171 172 173 174
    Level = 0;
    Gia_ManForEachCo( p, pObj, k )
        if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] )
            Level = pLevels[Gia_ObjFaninId0p(p, pObj)];
Alan Mishchenko committed
175
    ABC_FREE( pLevels );
176
    return Level;
177 178 179 180
}

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

181
  Synopsis    [Assigns levels.]
182 183 184 185 186 187 188 189

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
190
void Gia_ManSetRefsMapped( Gia_Man_t * p )  
191
{
192 193 194 195 196 197
    Gia_Obj_t * pObj;
    int i, k, iFan;
    ABC_FREE( p->pRefs );
    p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
    Gia_ManForEachCo( p, pObj, i )
        Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) );
198
    Gia_ManForEachLut( p, i )
199 200
        Gia_LutForEachFanin( p, i, iFan, k )
            Gia_ObjRefInc( p, Gia_ManObj(p, iFan) );
201 202 203 204 205 206 207 208 209 210 211 212 213
}

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

  Synopsis    [Prints mapping statistics.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
214
void Gia_ManPrintMappingStats( Gia_Man_t * p )
215
{
216 217 218 219 220
    int * pLevels;
    int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0;
    if ( !p->pMapping )
        return;
    pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
221
    Gia_ManForEachLut( p, i )
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    {
        nLuts++;
        nFanins += Gia_ObjLutSize(p, i);
        nLutSize = Abc_MaxInt( nLutSize, Gia_ObjLutSize(p, i) );
        Gia_LutForEachFanin( p, i, iFan, k )
            pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] );
        pLevels[i]++;
        LevelMax = Abc_MaxInt( LevelMax, pLevels[i] );
    }
    ABC_FREE( pLevels );
    Abc_Print( 1, "mapping (K=%d)  :  ", nLutSize );
    Abc_Print( 1, "lut =%7d  ", nLuts );
    Abc_Print( 1, "edge =%8d  ", nFanins );
    Abc_Print( 1, "lev =%5d  ", LevelMax );
    Abc_Print( 1, "mem =%5.2f MB", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
    Abc_Print( 1, "\n" );
238 239
}

240 241


242 243
/**Function*************************************************************

244
  Synopsis    [Converts GIA into IF manager.]
245 246 247 248 249 250 251 252

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
253 254 255
static inline If_Obj_t * If_ManFanin0Copy( If_Man_t * pIfMan, Gia_Obj_t * pObj ) { return If_NotCond( If_ManObj(pIfMan, Gia_ObjValue(Gia_ObjFanin0(pObj))), Gia_ObjFaninC0(pObj) ); }
static inline If_Obj_t * If_ManFanin1Copy( If_Man_t * pIfMan, Gia_Obj_t * pObj ) { return If_NotCond( If_ManObj(pIfMan, Gia_ObjValue(Gia_ObjFanin1(pObj))), Gia_ObjFaninC1(pObj) ); }
If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars )
256
{
257 258 259 260 261 262 263 264 265 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 301
    If_Man_t * pIfMan;
    If_Obj_t * pIfObj;
    Gia_Obj_t * pObj;
    int i;
    // create levels with choices
    Gia_ManChoiceLevel( p );
    // mark representative nodes
    Gia_ManMarkFanoutDrivers( p );
    // start the mapping manager and set its parameters
    pIfMan = If_ManStart( pPars );
    pIfMan->pName = Abc_UtilStrsav( Gia_ManName(p) );
    // print warning about excessive memory usage
    if ( 1.0 * Gia_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 )
        printf( "Warning: The mapper will allocate %.1f GB for to represent the subject graph with %d AIG nodes.\n", 
            1.0 * Gia_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Gia_ManObjNum(p) );
    // load the AIG into the mapper
    Gia_ManFillValue( p );
    Gia_ManConst0(p)->Value = If_ObjId( If_ManConst1(pIfMan) );
    Gia_ManForEachObj1( p, pObj, i )
    {
        if ( Gia_ObjIsAnd(pObj) )
            pIfObj = If_ManCreateAnd( pIfMan, If_ManFanin0Copy(pIfMan, pObj), If_ManFanin1Copy(pIfMan, pObj) );
        else if ( Gia_ObjIsCi(pObj) )
        {
            pIfObj = If_ManCreateCi( pIfMan );
            If_ObjSetLevel( pIfObj, Gia_ObjLevel(p, pObj) );
//            Abc_Print( 1, "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
            if ( pIfMan->nLevelMax < (int)pIfObj->Level )
                pIfMan->nLevelMax = (int)pIfObj->Level;
        }
        else if ( Gia_ObjIsCo(pObj) )
        {
            pIfObj = If_ManCreateCo( pIfMan, If_NotCond( If_ManFanin0Copy(pIfMan, pObj), Gia_ObjIsConst0(Gia_ObjFanin0(pObj))) );
//            Abc_Print( 1, "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
        }
        else assert( 0 );
        assert( i == If_ObjId(pIfObj) );
        Gia_ObjSetValue( pObj, If_ObjId(pIfObj) );
        // set up the choice node
        if ( Gia_ObjSibl(p, i) && pObj->fMark0 )
        {
            Gia_Obj_t * pSibl, * pPrev;
            for ( pPrev = pObj, pSibl = Gia_ObjSiblObj(p, i); pSibl; pPrev = pSibl, pSibl = Gia_ObjSiblObj(p, Gia_ObjId(p, pSibl)) )
                If_ObjSetChoice( If_ManObj(pIfMan, Gia_ObjValue(pObj)), If_ManObj(pIfMan, Gia_ObjValue(pSibl)) );
            If_ManCreateChoice( pIfMan, If_ManObj(pIfMan, Gia_ObjValue(pObj)) );
302
            pPars->fExpRed = 0;
303 304 305 306 307
        }
//        assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) );
    }
    Gia_ManCleanMark0( p );
    return pIfMan;
308 309
}

310

311 312
/**Function*************************************************************

313
  Synopsis    [Derives node's AIG after SOP balancing]
314 315 316 317 318 319 320 321

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
322
int Gia_ManNodeIfSopToGiaInt( Gia_Man_t * pNew, Vec_Wrd_t * vAnds, int nVars, Vec_Int_t * vLeaves, int fHash )
323
{
324
    Vec_Int_t * vResults;
325
    int iRes0, iRes1, iRes = -1;
326 327 328 329 330 331 332 333 334 335 336
    If_And_t This;
    word Entry;
    int i;
    if ( Vec_WrdSize(vAnds) == 0 )
        return 0;
    if ( Vec_WrdSize(vAnds) == 1 && Vec_WrdEntry(vAnds,0) == 0 )
        return 1;
    vResults = Vec_IntAlloc( Vec_WrdSize(vAnds) );
    for ( i = 0; i < nVars; i++ )
        Vec_IntPush( vResults, Vec_IntEntry(vLeaves, i) );
    Vec_WrdForEachEntryStart( vAnds, Entry, i, nVars )
337
    {
338 339 340
        This  = If_WrdToAnd( Entry );
        iRes0 = Abc_LitNotCond( Vec_IntEntry(vResults, This.iFan0), This.fCompl0 ); 
        iRes1 = Abc_LitNotCond( Vec_IntEntry(vResults, This.iFan1), This.fCompl1 ); 
341 342 343 344
        if ( fHash )
            iRes  = Gia_ManHashAnd( pNew, iRes0, iRes1 );
        else
            iRes  = Gia_ManAppendAnd( pNew, iRes0, iRes1 );
345
        Vec_IntPush( vResults, iRes );
346
    }
347 348 349
    Vec_IntFree( vResults );
    return Abc_LitNotCond( iRes, This.fCompl );
}
350
int Gia_ManNodeIfSopToGia( Gia_Man_t * pNew, If_Man_t * p, If_Cut_t * pCut, Vec_Int_t * vLeaves, int fHash )
351 352 353 354
{
    int iResult;
    Vec_Wrd_t * vArray;
    vArray  = If_CutDelaySopArray( p, pCut );
355
    iResult = Gia_ManNodeIfSopToGiaInt( pNew, vArray, If_CutLeaveNum(pCut), vLeaves, fHash );
356 357
//    Vec_WrdFree( vArray );
    return iResult;
358 359 360 361
}

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

362
  Synopsis    [Recursively derives the local AIG for the cut.]
363 364 365 366 367 368 369 370

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
371
int Gia_ManNodeIfToGia_rec( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited, int fHash )
372
{
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
    If_Cut_t * pCut;
    If_Obj_t * pTemp;
    int iFunc, iFunc0, iFunc1;
    // get the best cut
    pCut = If_ObjCutBest(pIfObj);
    // if the cut is visited, return the result
    if ( If_CutDataInt(pCut) )
        return If_CutDataInt(pCut);
    // mark the node as visited
    Vec_PtrPush( vVisited, pCut );
    // insert the worst case
    If_CutSetDataInt( pCut, ~0 );
    // skip in case of primary input
    if ( If_ObjIsCi(pIfObj) )
        return If_CutDataInt(pCut);
    // compute the functions of the children
    for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv )
    {
391
        iFunc0 = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pTemp->pFanin0, vVisited, fHash );
392 393
        if ( iFunc0 == ~0 )
            continue;
394
        iFunc1 = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pTemp->pFanin1, vVisited, fHash );
395 396 397
        if ( iFunc1 == ~0 )
            continue;
        // both branches are solved
398 399 400 401
        if ( fHash )
            iFunc = Gia_ManHashAnd( pNew, Abc_LitNotCond(iFunc0, pTemp->fCompl0), Abc_LitNotCond(iFunc1, pTemp->fCompl1) ); 
        else
            iFunc = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iFunc0, pTemp->fCompl0), Abc_LitNotCond(iFunc1, pTemp->fCompl1) ); 
402 403 404 405 406 407 408
        if ( pTemp->fPhase != pIfObj->fPhase )
            iFunc = Abc_LitNot(iFunc);
        If_CutSetDataInt( pCut, iFunc );
        break;
    }
    return If_CutDataInt(pCut);
}
409
int Gia_ManNodeIfToGia( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vLeaves, int fHash )
410 411 412 413 414 415 416 417 418 419 420 421
{
    If_Cut_t * pCut;
    If_Obj_t * pLeaf;
    int i, iRes;
    // get the best cut
    pCut = If_ObjCutBest(pIfObj);
    assert( pCut->nLeaves > 1 );
    // set the leaf variables
    If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
        If_CutSetDataInt( If_ObjCutBest(pLeaf), Vec_IntEntry(vLeaves, i) );
    // recursively compute the function while collecting visited cuts
    Vec_PtrClear( pIfMan->vTemp );
422
    iRes = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pIfObj, pIfMan->vTemp, fHash ); 
423 424 425 426 427 428 429 430 431 432 433
    if ( iRes == ~0 )
    {
        Abc_Print( -1, "Gia_ManNodeIfToGia(): Computing local AIG has failed.\n" );
        return ~0;
    }
    // clean the cuts
    If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
        If_CutSetDataInt( If_ObjCutBest(pLeaf), 0 );
    Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i )
        If_CutSetDataInt( pCut, 0 );
    return iRes;
434 435 436 437
}

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

438
  Synopsis    [Converts IF into GIA manager.]
439 440 441 442 443 444 445 446

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
447
Gia_Man_t * Gia_ManFromIf( If_Man_t * pIfMan )
448
{
449
    int fHash = 0;
450 451 452 453
    Gia_Man_t * pNew;
    If_Obj_t * pIfObj, * pIfLeaf;
    If_Cut_t * pCutBest;
    Vec_Int_t * vLeaves;
454
    Vec_Int_t * vCover;
455
    unsigned * pTruth;
456 457 458 459 460 461
    int Counter, iOffset, nItems = 0;
    int i, k, w, GiaId;
    // create new manager
    pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
    Gia_ManHashAlloc( pNew );
    // iterate through nodes used in the mapping
462
    vCover = Vec_IntAlloc( 1 << 16 );
463 464 465
    vLeaves = Vec_IntAlloc( 16 );
    If_ManCleanCutData( pIfMan );
    If_ManForEachObj( pIfMan, pIfObj, i )
466
    {
467
        if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) )
468
            continue;
469 470 471 472 473 474 475 476
        if ( If_ObjIsAnd(pIfObj) )
        {
            pCutBest = If_ObjCutBest( pIfObj );
            // collect leaves of the best cut
            Vec_IntClear( vLeaves );
            If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
                Vec_IntPush( vLeaves, pIfLeaf->iCopy );
            // get the functionality
477 478 479 480 481 482
            if ( pIfMan->pPars->pLutStruct )
                pIfObj->iCopy = Kit_TruthToGia( pNew, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover, vLeaves, fHash );
            else if ( pIfMan->pPars->fDelayOpt )
                pIfObj->iCopy = Gia_ManNodeIfSopToGia( pNew, pIfMan, pCutBest, vLeaves, fHash );
            else if ( pIfMan->pPars->fUserRecLib )
                pIfObj->iCopy = Abc_RecToGia2( pNew, pIfMan, pCutBest, pIfObj, vLeaves, fHash );
483
            else
484 485 486 487 488
                pIfObj->iCopy = Gia_ManNodeIfToGia( pNew, pIfMan, pIfObj, vLeaves, fHash );
            // complement the node if the TT was used and the cut was complemented
            if ( pIfMan->pPars->pLutStruct )
                pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
            // count entries in the mapping array
489 490 491 492 493 494 495 496 497 498 499 500
            nItems += 2 + If_CutLeaveNum( pCutBest );
        }
        else if ( If_ObjIsCi(pIfObj) )
            pIfObj->iCopy = Gia_ManAppendCi(pNew);
        else if ( If_ObjIsCo(pIfObj) )
            pIfObj->iCopy = Gia_ManAppendCo( pNew, Abc_LitNotCond(If_ObjFanin0(pIfObj)->iCopy, If_ObjFaninC0(pIfObj)) );
        else if ( If_ObjIsConst1(pIfObj) )
        {
            pIfObj->iCopy = 1;
            nItems += 2; 
        }
        else assert( 0 );
501
    }
502
    Vec_IntFree( vCover );
503
    Vec_IntFree( vLeaves );
504 505 506 507 508 509
    Gia_ManHashStop( pNew );

    // GIA after mapping with choices may end up with dangling nodes
    // which participate as leaves of some cuts used in the mapping
    // such nodes are marked here and skipped when mapping is derived
    Counter = Gia_ManMarkDangling(pNew);
510 511
//    if ( pIfMan->pPars->fVerbose && Counter )
    if ( Counter )
512 513 514 515 516 517 518 519 520
        printf( "GIA after mapping has %d dangling nodes.\n", Counter );

    // create mapping
    iOffset = Gia_ManObjNum(pNew);
    pNew->pMapping = ABC_CALLOC( int, iOffset + nItems );
    assert( pNew->vTruths == NULL );
    if ( pIfMan->pPars->pLutStruct )
        pNew->vTruths = Vec_IntAlloc( 1000 );
    If_ManForEachObj( pIfMan, pIfObj, i )
521
    {
522
        if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) )
523
            continue;
524
        if ( If_ObjIsAnd(pIfObj) )
525
        { 
526
            GiaId = Abc_Lit2Var( pIfObj->iCopy );
527 528
            if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, GiaId)) ) // skip trivial node
                continue;
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
            assert( Gia_ObjIsAnd(Gia_ManObj(pNew, GiaId)) );
            if ( !Gia_ManObj(pNew, GiaId)->fMark0 ) // skip dangling node
                continue;
            // get the best cut
            pCutBest = If_ObjCutBest( pIfObj );
            // copy the truth tables
            pTruth = NULL;
            if ( pNew->vTruths )
            { 
                // copy truth table
                for ( w = 0; w < pIfMan->nTruthWords; w++ )
                    Vec_IntPush( pNew->vTruths, If_CutTruth(pCutBest)[w] );
                pTruth = (unsigned *)(Vec_IntArray(pNew->vTruths) + Vec_IntSize(pNew->vTruths) - pIfMan->nTruthWords);
                // complement 
                if ( pCutBest->fCompl ^ Abc_LitIsCompl(pIfObj->iCopy) )
                    for ( w = 0; w < pIfMan->nTruthWords; w++ )
                        pTruth[w] = ~pTruth[w];
            }
            // create node
            pNew->pMapping[GiaId]     = iOffset;
            pNew->pMapping[iOffset++] = If_CutLeaveNum(pCutBest);
            If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
            {
552
                int FaninId = Abc_Lit2Var(pIfLeaf->iCopy);
553 554
                if ( pTruth && Abc_LitIsCompl(pIfLeaf->iCopy) )
                    Kit_TruthChangePhase( pTruth, If_CutLeaveNum(pCutBest), k );
555
                if ( !Gia_ManObj(pNew, FaninId)->fMark0 ) // skip dangling node
556 557 558 559 560 561 562 563 564
                {
                    // update truth table
                    if ( pTruth )
                    {
                        extern void If_CluSwapVars( word * pTruth, int nVars, int * V2P, int * P2V, int iVar, int jVar );
                        if ( If_CutLeaveNum(pCutBest) >= 6 )
                            If_CluSwapVars( (word*)pTruth, If_CutLeaveNum(pCutBest), NULL, NULL, k, If_CutLeaveNum(pCutBest)-1 );
                        else
                        {
565
                            word Truth = ((word)pTruth[0] << 32) | (word)pTruth[0];
566 567 568 569 570 571 572
                            If_CluSwapVars( &Truth, 6, NULL, NULL, k, If_CutLeaveNum(pCutBest)-1 );
                            pTruth[0] = (Truth & 0xFFFFFFFF);
                        }
                    }
                    pNew->pMapping[iOffset-k-1]--;
                    continue;
                }
573
                assert( FaninId < GiaId );
574
                pNew->pMapping[iOffset++] = FaninId;
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
            }
            pNew->pMapping[iOffset++] = GiaId;
        }
        else if ( If_ObjIsConst1(pIfObj) )
        {
            // create node
            pNew->pMapping[0] = iOffset;
            pNew->pMapping[iOffset++] = 0;
            pNew->pMapping[iOffset++] = 0;
/*
            if ( pNew->vTruths )
            {
                printf( "%d ", nLeaves );
                for ( w = 0; w < pIfMan->nTruthWords; w++ )
                    Vec_IntPush( pNew->vTruths, 0 );
            }
*/
        }
593
    }
594 595 596 597 598
    Gia_ManCleanMark0( pNew );
//    assert( iOffset == Gia_ManObjNum(pNew) + nItems );
    if ( pIfMan->pManTim )
        pNew->pManTime = Tim_ManDup( pIfMan->pManTim, 0 );
    // verify that COs have mapping
599
    {
600 601
        Gia_Obj_t * pObj;
        Gia_ManForEachCo( pNew, pObj, i )
602
        {
603 604
            if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) )
                assert( pNew->pMapping[Gia_ObjFaninId0p(pNew, pObj)] != 0 );
605 606
        }
    }
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
    return pNew;
}

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

  Synopsis    [Interface of LUT mapping package.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pp )
{
    Gia_Man_t * pNew;
    If_Man_t * pIfMan;
    If_Par_t * pPars = (If_Par_t *)pp;
    // set the arrival times
    assert( pPars->pTimesArr == NULL );
    pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) );
    memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) );
    // translate into the mapper
    pIfMan = Gia_ManToIf( p, pPars );    
    if ( pIfMan == NULL )
        return NULL;
    if ( p->pManTime )
        pIfMan->pManTim = Tim_ManDup( p->pManTime, 0 );
    if ( !If_ManPerformMapping( pIfMan ) )
    {
        If_ManStop( pIfMan );
        return NULL;
    }
    // transform the result of mapping into the new network
    pNew = Gia_ManFromIf( pIfMan );
    If_ManStop( pIfMan );
    // transfer name
    assert( pNew->pName == NULL );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    // unmap in case of SOP balancing
//    if ( pIfMan->pPars->fDelayOpt )
//        Vec_IntFreeP( &pNew->vMapping );
    return pNew;
Alan Mishchenko committed
653 654 655 656 657 658 659
}

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


660 661
ABC_NAMESPACE_IMPL_END