wlcGraft.c 18.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 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 163 164 165 166 167 168 169 170 171 172 173 174 175 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
/**CFile****************************************************************

  FileName    [wlcGraft.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Verilog parser.]

  Synopsis    [Parses several flavors of word-level Verilog.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - August 22, 2014.]

  Revision    [$Id: wlcGraft.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]

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

#include "wlc.h"
#include "sat/bsat/satStore.h"

ABC_NAMESPACE_IMPL_START

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

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

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

  Synopsis    [Internal simulation APIs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj )
{
    return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
}
static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj )
{
    int w;
    word * pSim = Wlc_ObjSim( p, iObj );
    for ( w = 0; w < p->nSimWords; w++ )
        pSim[w] = Gia_ManRandomW( 0 );
    pSim[0] <<= 1;
}
static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
{
    int w;
    word * pSimRo = Wlc_ObjSim( p, iObj );
    word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
    for ( w = 0; w < p->nSimWords; w++ )
        pSimRo[w] = pSimRi[w];
}
static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
{
    int w;
    Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
    word * pSimCo  = Wlc_ObjSim( p, iObj );
    word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
    if ( Gia_ObjFaninC0(pObj) )
        for ( w = 0; w < p->nSimWords; w++ )
            pSimCo[w] = ~pSimDri[w];
    else
        for ( w = 0; w < p->nSimWords; w++ )
            pSimCo[w] =  pSimDri[w];
}
static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
{
    int w;
    Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
    word * pSim  = Wlc_ObjSim( p, iObj );
    word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
    word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
    if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
        for ( w = 0; w < p->nSimWords; w++ )
            pSim[w] = ~pSim0[w] & ~pSim1[w];
    else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
        for ( w = 0; w < p->nSimWords; w++ )
            pSim[w] = ~pSim0[w] & pSim1[w];
    else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
        for ( w = 0; w < p->nSimWords; w++ )
            pSim[w] = pSim0[w] & ~pSim1[w];
    else
        for ( w = 0; w < p->nSimWords; w++ )
            pSim[w] = pSim0[w] & pSim1[w];
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Wlc_NtkCollectObjs_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vObjs )
{
    int i, iFanin, Count = 0;
    if ( Wlc_ObjIsCi(pObj) )
        return 0;
    if ( pObj->Mark )
        return 0;
    pObj->Mark = 1;
    Wlc_ObjForEachFanin( pObj, iFanin, i )
        Count += Wlc_NtkCollectObjs_rec( p, Wlc_NtkObj(p, iFanin), vObjs );
    Vec_IntPush( vObjs, Wlc_ObjId(p, pObj) );
    return Count + (int)(pObj->Type == WLC_OBJ_ARI_MULTI);
}
Vec_Int_t * Wlc_NtkCollectObjs( Wlc_Ntk_t * p, int fEven, int * pCount )
{
    Vec_Int_t * vObjs = Vec_IntAlloc( 100 );
    Wlc_Obj_t * pObj; 
    int i, Count = 0;
    Wlc_NtkCleanMarks( p );
    Wlc_NtkForEachCo( p, pObj, i )
        if ( (i & 1) == fEven )
            Count += Wlc_NtkCollectObjs_rec( p, pObj, vObjs );
    Wlc_NtkCleanMarks( p );
    if ( pCount )
        *pCount = Count;
    return vObjs;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Wlc_NtkSaveOneNode( Wlc_Ntk_t * p, Wlc_Obj_t * pWlcObj, Gia_Man_t * pGia, Vec_Mem_t * vTtMem )
{
    int k, Entry;
    int nWords = Vec_MemEntrySize(vTtMem);
    int nBits = Wlc_ObjRange(pWlcObj);
    int iFirst = Vec_IntEntry( &p->vCopies, Wlc_ObjId(p, pWlcObj) );
    for ( k = 0; k < nBits; k++ )
    {
        int iLit = Vec_IntEntry( &p->vBits, iFirst + k );
        word * pInfoObj = Wlc_ObjSim( pGia, Abc_Lit2Var(iLit) );
        int fCompl = pInfoObj[0] & 1;
        if ( fCompl ) Abc_TtNot( pInfoObj, nWords );
        Entry = Vec_MemHashInsert( vTtMem, pInfoObj );
        if ( fCompl ) Abc_TtNot( pInfoObj, nWords );
        printf( "%2d(%d) ", Entry, fCompl ^ Abc_LitIsCompl(iLit) );
        Extra_PrintHex( stdout, (unsigned*)pInfoObj, 8 );
        printf( "\n" );
    }
    printf( "\n" );
}
void Wlc_NtkFindOneNode( Wlc_Ntk_t * p, Wlc_Obj_t * pWlcObj, Gia_Man_t * pGia, Vec_Mem_t * vTtMem )
{
    int k, Entry;
    int nWords = Vec_MemEntrySize(vTtMem);
    int nBits = Wlc_ObjRange(pWlcObj);
    int iFirst = Vec_IntEntry( &p->vCopies, Wlc_ObjId(p, pWlcObj) );
    for ( k = 0; k < nBits; k++ )
    {
        int iLit = Vec_IntEntry( &p->vBits, iFirst + k );
        word * pInfoObj = Wlc_ObjSim( pGia, Abc_Lit2Var(iLit) );
        int fCompl = pInfoObj[0] & 1;
        if ( fCompl ) Abc_TtNot( pInfoObj, nWords );
        Entry = *Vec_MemHashLookup( vTtMem, pInfoObj );
        if ( Entry > 0 )
            printf( "Obj %4d.  Range = %2d.  Bit %2d.  Entry %d(%d).  %s\n", Wlc_ObjId(p, pWlcObj), Wlc_ObjRange(pWlcObj), k, Entry, fCompl ^ Abc_LitIsCompl(iLit), Wlc_ObjName(p, Wlc_ObjId(p, pWlcObj)) );
        if ( fCompl ) Abc_TtNot( pInfoObj, nWords );
        //printf( "%2d ", Entry );
        //Extra_PrintHex( stdout, (unsigned*)pInfoObj, 8 );
        //printf( "\n" );
    }
    //printf( "\n" );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Wlc_Ntk_t * Wlc_NtkGraftMulti( Wlc_Ntk_t * p, int fVerbose )
{
    int nWords = 4;
    int i, nMultiLHS, nMultiRHS;
    word * pInfoObj;
    Wlc_Ntk_t * pNew = NULL;
    Wlc_Obj_t * pWlcObj;
    Gia_Obj_t * pObj;
    Vec_Int_t * vObjsLHS = Wlc_NtkCollectObjs( p, 0, &nMultiLHS );
    Vec_Int_t * vObjsRHS = Wlc_NtkCollectObjs( p, 1, &nMultiRHS );
213
    Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL ); //, -1, 0, 0, 0, 0, 1, 0, 0 ); // <= no cleanup
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 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
    Vec_Mem_t * vTtMem = Vec_MemAlloc( nWords, 10 );
    Vec_MemHashAlloc( vTtMem, 10000 );

    // check if there are multipliers
    if ( nMultiLHS == 0 && nMultiRHS == 0 )
    {
        printf( "No multipliers are present.\n" );
        return NULL;
    }
    // compare multipliers
    if ( nMultiLHS > 0 && nMultiRHS > 0 )
    {
        printf( "Multipliers are present in both sides of the miter.\n" );
        return NULL;
    }
    // swap if wrong side
    if ( nMultiRHS > 0 )
    {
        ABC_SWAP( Vec_Int_t *, vObjsLHS, vObjsRHS );
        ABC_SWAP( int, nMultiLHS, nMultiRHS );
    }
    assert( nMultiLHS > 0 );
    assert( nMultiRHS == 0 );

    // allocate simulation info for one timeframe
    Vec_WrdFreeP( &pGia->vSims );
    pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
    pGia->nSimWords = nWords;
    // perform simulation
    Gia_ManRandomW( 1 );
    Gia_ManForEachObj1( pGia, pObj, i )
    {
        if ( Gia_ObjIsAnd(pObj) )
            Wlc_ObjSimAnd( pGia, i );
        else if ( Gia_ObjIsCo(pObj) )
            Wlc_ObjSimCo( pGia, i );
        else if ( Gia_ObjIsCi(pObj) )
            Wlc_ObjSimPi( pGia, i );
        else assert( 0 );
    }

    // hash constant 0
    pInfoObj = Wlc_ObjSim( pGia, 0 );
    Vec_MemHashInsert( vTtMem, pInfoObj );

    // hash sim info on the multiplier boundary
    Wlc_NtkForEachObjVec( vObjsLHS, p, pWlcObj, i )
        if ( Wlc_ObjType(pWlcObj) == WLC_OBJ_ARI_MULTI )
        {
            Wlc_NtkSaveOneNode( p, Wlc_ObjFanin0(p, pWlcObj), pGia, vTtMem );
            Wlc_NtkSaveOneNode( p, Wlc_ObjFanin1(p, pWlcObj), pGia, vTtMem );
            Wlc_NtkSaveOneNode( p, pWlcObj, pGia, vTtMem );
        }

    // check if there are similar signals in LHS
    Wlc_NtkForEachObjVec( vObjsRHS, p, pWlcObj, i )
        Wlc_NtkFindOneNode( p, pWlcObj, pGia, vTtMem );

    // perform grafting


    Vec_MemHashFree( vTtMem );
    Vec_MemFreeP( &vTtMem );

    // cleanup
    Vec_WrdFreeP( &pGia->vSims );
    pGia->nSimWords = 0;

    Vec_IntFree( vObjsLHS );
    Vec_IntFree( vObjsRHS );
    Gia_ManStop( pGia );
    return pNew;
}

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304




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

  Synopsis    [Generate simulation vectors.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Sbc_Mult( word a, word b, word r[2] )
{
305 306 307 308
    word Msk = 0xFFFFFFFF;
    word pL  = (a & Msk) * (b & Msk);
    word pM1 = (a & Msk) * (b >> 32);
    word pM2 = (a >> 32) * (b & Msk);
309
    word pH  = (a >> 32) * (b >> 32);
310
    word Car = (pM1 & Msk) + (pM2 & Msk) + (pL >> 32);
311
    r[0] = a * b;
312 313
    r[1] = pH + (pM1 >> 32) + (pM2 >> 32) + (Car >> 32);
}
314
void Sbc_SimMult( word A[64], word B[64], word R[128], int nIns )
315
{
316
    word a, b, r[2], Mask = Abc_Tt6Mask(nIns); int i, k;
317
    for ( i = 0; i < 64; i++ )
318
        A[i] = B[i] = R[i] = R[i+64] = 0;
319 320 321
    Gia_ManRandom(1);
    for ( i = 0; i < 64; i++ )
    {
322 323
        a = i ? (Mask & Gia_ManRandomW(0)) : 0;
        b = i ? (Mask & Gia_ManRandomW(0)) : 0;        
324 325 326
        Sbc_Mult( a, b, r );
        for ( k = 0; k < 64; k++ )
        {
327 328 329 330
            if ( (a    >> k) & 1 )  A[k]    |= ((word)1 << i);
            if ( (b    >> k) & 1 )  B[k]    |= ((word)1 << i);
            if ( (r[0] >> k) & 1 )  R[k]    |= ((word)1 << i);
            if ( (r[1] >> k) & 1 )  R[k+64] |= ((word)1 << i);
331 332
        }
    }
333 334 335
//    for ( i = 0; i < 128; i++ )
//        for ( k = 0; k < 64; k++, printf( "\n" ) )
//            printf( "%d", (R[i] >> k) & 1 );
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns )
{
    int nWords = 1;
352
    Vec_Int_t * vGia2Out = Vec_IntStartFull( Gia_ManObjNum(p) );
353
    Gia_Obj_t * pObj; int i, Entry, nIns = Vec_IntSize(vIns)/2;
354
    word A[64], B[64], R[128], * pInfoObj; word Temp;
355

356
    // create hash table
357
    Vec_Mem_t * vTtMem = Vec_MemAlloc( nWords, 10 );
358 359 360
    Vec_MemHashAlloc( vTtMem, 1000 );
    Sbc_SimMult( A, B, R, nIns );
    for ( i = 0; i < 2*nIns; i++ )
361
    {
362
        Vec_MemHashInsert( vTtMem, R+i );
363 364 365 366
        //printf( "Out %2d : ", i );
        //Extra_PrintHex( stdout, (unsigned *)(R+i), 6 ); printf( "\n" );
    }
    assert( Vec_MemEntryNum(vTtMem) == 2*nIns );
367 368

    // alloc simulation info
369 370 371 372
    Vec_WrdFreeP( &p->vSims );
    p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
    p->nSimWords = nWords;

373 374
    // mark inputs
    Gia_ManIncrementTravId( p );
375 376
    Gia_ObjSetTravIdCurrentId( p, 0 );
    Gia_ManForEachCi( p, pObj, i )
377
    {
378
        Gia_ObjSetTravIdCurrent( p, pObj );
379 380
        //Wlc_ObjSimPi( p, Gia_ObjId(p, pObj) );
    }
381 382 383

    // assign inputs
    assert( Vec_IntSize(vIns) % 2 == 0 );
384 385 386 387
    Gia_ManForEachObjVec( vIns, p, pObj, i )
    {
        Gia_ObjSetTravIdCurrent( p, pObj );
        pInfoObj = Wlc_ObjSim( p, Gia_ObjId(p, pObj) );
388
        *pInfoObj = i < nIns ? A[i] : B[i - nIns];
389
    }
390

391 392 393 394 395
    // perform simulation
    Gia_ManForEachObj1( p, pObj, i )
    {
        if ( Gia_ObjIsTravIdCurrent(p, pObj) )
            continue;
396

397 398 399 400 401 402
        if ( Gia_ObjIsAnd(pObj) )
            Wlc_ObjSimAnd( p, i );
        else if ( Gia_ObjIsCo(pObj) )
            Wlc_ObjSimCo( p, i );
        else assert( 0 );

403
        // mark direct polarity
404 405
        pInfoObj = Wlc_ObjSim( p, i );
        Entry = *Vec_MemHashLookup( vTtMem, pInfoObj );
406
        if ( Entry >= 0 )
407
        {
408
            Vec_IntWriteEntry( vGia2Out, i, Abc_Var2Lit(Entry, 0) );
409 410
            continue;
        }
411 412 413

        // mark negated polarity
        Temp = *pInfoObj;
414 415 416
        Abc_TtNot( pInfoObj, nWords );
        Entry = *Vec_MemHashLookup( vTtMem, pInfoObj );
        Abc_TtNot( pInfoObj, nWords );
417 418
        assert( Temp == *pInfoObj );
        if ( Entry >= 0 )
419
        {
420
            Vec_IntWriteEntry( vGia2Out, i, Abc_Var2Lit(Entry, 1) );
421 422 423
            continue;
        }
    }
424 425 426 427 428 429 430 431

    Gia_ManForEachCo( p, pObj, i )
    {
        pInfoObj = Wlc_ObjSim( p, Gia_ObjId(p, pObj) );
        //printf( "Out %2d : Driver = %5d(%d)", i, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
        //Extra_PrintHex( stdout, (unsigned *)pInfoObj, 6 ); printf( "\n" );
    }

432 433 434
    // cleanup
    Vec_MemHashFree( vTtMem );
    Vec_MemFreeP( &vTtMem );
435 436 437
    //Vec_WrdFreeP( &p->vSims );
    //p->nSimWords = 0;
    return vGia2Out;
438
}
439
Vec_Int_t * Sbc_ManWlcNodes2( Wlc_Ntk_t * pNtk, Gia_Man_t * p, Vec_Int_t * vGiaLits )
440 441 442 443 444
{
    Wlc_Obj_t * pObj;  int i, k, iGiaLit, iFirst, nBits;
    Vec_Int_t * vRes = Vec_IntAlloc( 100 );
    Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
    Vec_IntForEachEntry( vGiaLits, iGiaLit, i )
445 446
        if ( iGiaLit != -1 )
            Vec_IntWriteEntry( vMap, Abc_Lit2Var(iGiaLit), Abc_Var2Lit(i, Abc_LitIsCompl(iGiaLit)) );
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    Wlc_NtkForEachObj( pNtk, pObj, i )
    {
        iFirst = Vec_IntEntry( &pNtk->vCopies, i );
        nBits  = Wlc_ObjRange(pObj);
        for ( k = 0; k < nBits; k++ )
        {
            int iLitGia = Vec_IntEntry( &pNtk->vBits, iFirst + k );
            int iLitOut = Vec_IntEntry( vMap, Abc_Lit2Var(iLitGia) );
            if ( iLitOut == -1 )
                continue;
            Vec_IntWriteEntry( vMap, Abc_Lit2Var(iLitGia), -1 );
            iLitOut = Abc_LitNotCond( iLitOut, Abc_LitIsCompl(iLitGia) );
            printf( "Matched out %d in phase %d with object %d (%s) bit %d (out of %d).\n", Abc_Lit2Var(iLitOut), Abc_LitIsCompl(iLitOut), i, Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k, nBits );
            Vec_IntPushUnique( vRes, i );
        }
    }
    Vec_IntFree( vMap );
464
    Vec_IntSort( vRes, 0 );
465 466 467 468 469 470 471 472 473 474 475
    // consider the last one
    pObj   = Wlc_NtkObj( pNtk, Vec_IntEntryLast(vRes) );
    iFirst = Vec_IntEntry( &pNtk->vCopies, Wlc_ObjId(pNtk, pObj) );
    nBits  = Wlc_ObjRange(pObj);
    printf( "Considering object %d (%s):\n", Wlc_ObjId(pNtk, pObj), Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)) );
    for ( k = 0; k < nBits; k++ )
    {
        int iLitGia  = Vec_IntEntry( &pNtk->vBits, iFirst + k );
        int iLitOutP = Vec_IntFind( vGiaLits, iLitGia );
        int iLitOutN = Vec_IntFind( vGiaLits, Abc_LitNot(iLitGia) );
        printf( "Matching bit %d with output %d / %d.\n", k, iLitOutP, iLitOutN );
476 477 478 479 480
        // print simulation signature
        {
            word * pInfoObj = Wlc_ObjSim( p, Abc_Lit2Var(iLitGia) );
            Extra_PrintHex( stdout, (unsigned *)pInfoObj, 6 ); printf( "\n" );
        }
481 482 483
    }
    return vRes;
}
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
int Sbc_ManWlcNodes( Wlc_Ntk_t * pNtk, Gia_Man_t * p, Vec_Int_t * vGia2Out, int nOuts )
{
    Wlc_Obj_t * pObj;  
    int i, k, iLitGia, iLitOut, iFirst, nBits, iObjFound = -1;
    Vec_Int_t * vMatched = Vec_IntAlloc( 100 );
    Wlc_NtkForEachObj( pNtk, pObj, i )
    {
        iFirst = Vec_IntEntry( &pNtk->vCopies, i );
        nBits  = Wlc_ObjRange(pObj);
        Vec_IntClear( vMatched );
        for ( k = 0; k < nBits; k++ )
        {
            iLitGia = Vec_IntEntry( &pNtk->vBits, iFirst + k );
            iLitOut = Vec_IntEntry( vGia2Out, Abc_Lit2Var(iLitGia) );
            if ( iLitOut == -1 )
                continue;
            iLitOut = Abc_LitNotCond( iLitOut, Abc_LitIsCompl(iLitGia) );
            printf( "Matched node %5d (%10s) bit %3d (out of %3d) with output %3d(%d).\n", 
                i, Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k, nBits, Abc_Lit2Var(iLitOut), Abc_LitIsCompl(iLitOut) );
            Vec_IntPushOrder( vMatched, Abc_Lit2Var(iLitOut) );
        }
        if ( Vec_IntSize(vMatched) > 0 )
            printf( "\n" );
        if ( Vec_IntSize(vMatched) == nOuts )
        {
            if ( iObjFound == -1 )
                iObjFound = i;
            printf( "Found object %d with all bits matched.\n", i );
            /*
            for ( k = nBits-2; k < nBits; k++ )
            {
                iLitGia = Vec_IntEntry( &pNtk->vBits, iFirst + k );
                {
                    word * pInfoObj = Wlc_ObjSim( p, Abc_Lit2Var(iLitGia) );
                    Extra_PrintHex( stdout, (unsigned *)pInfoObj, 6 ); printf( "\n" );
                }
            }
            */
            break;
        }
    }
    Vec_IntFree( vMatched );
    return iObjFound;
}
528 529 530 531 532 533 534 535 536 537 538 539

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
540
void Sbc_ManDetectMultTest( Wlc_Ntk_t * pNtk, int fVerbose )
541 542
{
    extern Vec_Int_t * Sdb_StoComputeCutsDetect( Gia_Man_t * pGia );
543
    Gia_Man_t * p = Wlc_NtkBitBlast( pNtk, NULL );//, -1, 0, 0, 0, 0, 1, 0, 0 ); // <= no cleanup
544 545
    Vec_Int_t * vIns, * vGia2Out;
    int iObjFound = -1;
546 547 548 549 550 551 552 553 554 555
//    Gia_Obj_t * pObj; int i;
//    Gia_ManForEachCo( p, pObj, i )
//        printf( "Output %2d - driver %5d (%d)\n", i, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );

    vIns = Sdb_StoComputeCutsDetect( p );
    if ( vIns == NULL || Vec_IntSize(vIns) == 0 || (Vec_IntSize(vIns) % 2) != 0 )
    {
        printf( "Input identification did not work out.\n" );
        return;
    }
556

557
    vGia2Out = Sbc_ManDetectMult( p, vIns );
558

559
    iObjFound = Sbc_ManWlcNodes( pNtk, p, vGia2Out, Vec_IntSize(vIns) );
560

561
    Vec_IntFree( vGia2Out );
562
    Vec_IntFree( vIns );
563 564

    Gia_ManStop( p );
565 566
}

567 568 569 570 571 572 573
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END