cecClass.c 26.9 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6
/**CFile****************************************************************

  FileName    [cecClass.c]

  SystemName  [ABC: Logic synthesis and verification system.]

Alan Mishchenko committed
7
  PackageName [Combinational equivalence checking.]
Alan Mishchenko committed
8

Alan Mishchenko committed
9
  Synopsis    [Equivalence class refinement.]
Alan Mishchenko committed
10 11 12 13 14 15 16 17 18 19 20 21 22

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "cecInt.h"

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
30 31 32 33
static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id )            { return p->pMems + p->pSimInfo[Id] + 1;   }
static inline void       Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n )  { p->pSimInfo[Id] = n;                     }

static inline float      Cec_MemUsage( Cec_ManSim_t * p )                  { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20);   }
Alan Mishchenko committed
34

Alan Mishchenko committed
35 36 37 38 39 40
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
41
  Synopsis    [Compares simulation info of one node with constant 0.]
Alan Mishchenko committed
42 43 44 45 46 47 48 49

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
50
int Cec_ManSimCompareConst( unsigned * p, int nWords )
Alan Mishchenko committed
51
{
Alan Mishchenko committed
52 53
    int w;
    if ( p[0] & 1 )
Alan Mishchenko committed
54
    {
Alan Mishchenko committed
55 56 57 58
        for ( w = 0; w < nWords; w++ )
            if ( p[w] != ~0 )
                return 0;
        return 1;
Alan Mishchenko committed
59
    }
Alan Mishchenko committed
60
    else
Alan Mishchenko committed
61
    {
Alan Mishchenko committed
62 63 64 65
        for ( w = 0; w < nWords; w++ )
            if ( p[w] != 0 )
                return 0;
        return 1;
Alan Mishchenko committed
66
    }
Alan Mishchenko committed
67 68 69 70
}

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

Alan Mishchenko committed
71
  Synopsis    [Compares simulation info of two nodes.]
Alan Mishchenko committed
72 73 74 75 76 77 78 79

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
80
int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords )
Alan Mishchenko committed
81
{
Alan Mishchenko committed
82 83
    int w;
    if ( (p0[0] & 1) == (p1[0] & 1) )
Alan Mishchenko committed
84
    {
Alan Mishchenko committed
85 86 87 88
        for ( w = 0; w < nWords; w++ )
            if ( p0[w] != p1[w] )
                return 0;
        return 1;
Alan Mishchenko committed
89
    }
Alan Mishchenko committed
90
    else
Alan Mishchenko committed
91
    {
Alan Mishchenko committed
92 93 94 95
        for ( w = 0; w < nWords; w++ )
            if ( p0[w] != ~p1[w] )
                return 0;
        return 1;
Alan Mishchenko committed
96 97 98 99 100
    }
}

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

Alan Mishchenko committed
101
  Synopsis    [Returns the number of the first non-equal bit.]
Alan Mishchenko committed
102 103 104 105 106 107 108 109

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
110
int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords )
Alan Mishchenko committed
111 112
{
    int w;
Alan Mishchenko committed
113
    if ( p[0] & 1 )
Alan Mishchenko committed
114 115
    {
        for ( w = 0; w < nWords; w++ )
Alan Mishchenko committed
116
            if ( p[w] != ~0 )
Alan Mishchenko committed
117
                return 32*w + Gia_WordFindFirstBit( ~p[w] );
Alan Mishchenko committed
118
        return -1;
Alan Mishchenko committed
119 120 121 122
    }
    else
    {
        for ( w = 0; w < nWords; w++ )
Alan Mishchenko committed
123
            if ( p[w] != 0 )
Alan Mishchenko committed
124
                return 32*w + Gia_WordFindFirstBit( p[w] );
Alan Mishchenko committed
125
        return -1;
Alan Mishchenko committed
126 127 128 129 130
    }
}

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

Alan Mishchenko committed
131
  Synopsis    [Compares simulation info of two nodes.]
Alan Mishchenko committed
132 133 134 135 136 137 138 139

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
140
int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords )
Alan Mishchenko committed
141 142
{
    int w;
Alan Mishchenko committed
143
    if ( (p0[0] & 1) == (p1[0] & 1) )
Alan Mishchenko committed
144 145
    {
        for ( w = 0; w < nWords; w++ )
Alan Mishchenko committed
146
            if ( p0[w] != p1[w] )
Alan Mishchenko committed
147
                return 32*w + Gia_WordFindFirstBit( p0[w] ^ p1[w] );
Alan Mishchenko committed
148
        return -1;
Alan Mishchenko committed
149 150 151 152
    }
    else
    {
        for ( w = 0; w < nWords; w++ )
Alan Mishchenko committed
153
            if ( p0[w] != ~p1[w] )
Alan Mishchenko committed
154
                return 32*w + Gia_WordFindFirstBit( p0[w] ^ ~p1[w] );
Alan Mishchenko committed
155
        return -1;
Alan Mishchenko committed
156 157 158 159 160
    }
}

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

Alan Mishchenko committed
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 213 214 215 216 217 218 219 220 221 222 223 224
  Synopsis    [Returns the number of the first non-equal bit.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Cec_ManSimCompareConstScore( unsigned * p, int nWords, int * pScores )
{
    int w, b;
    if ( p[0] & 1 )
    {
        for ( w = 0; w < nWords; w++ )
            if ( p[w] != ~0 )
                for ( b = 0; b < 32; b++ )
                    if ( ((~p[w]) >> b ) & 1 )
                        pScores[32*w + b]++;
    }
    else
    {
        for ( w = 0; w < nWords; w++ )
            if ( p[w] != 0 )
                for ( b = 0; b < 32; b++ )
                    if ( ((p[w]) >> b ) & 1 )
                        pScores[32*w + b]++;
    }
}

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

  Synopsis    [Compares simulation info of two nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Cec_ManSimCompareEqualScore( unsigned * p0, unsigned * p1, int nWords, int * pScores )
{
    int w, b;
    if ( (p0[0] & 1) == (p1[0] & 1) )
    {
        for ( w = 0; w < nWords; w++ )
            if ( p0[w] != p1[w] )
                for ( b = 0; b < 32; b++ )
                    if ( ((p0[w] ^ p1[w]) >> b ) & 1 )
                        pScores[32*w + b]++;
    }
    else
    {
        for ( w = 0; w < nWords; w++ )
            if ( p0[w] != ~p1[w] )
                for ( b = 0; b < 32; b++ )
                    if ( ((p0[w] ^ ~p1[w]) >> b ) & 1 )
                        pScores[32*w + b]++;
    }
}

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

Alan Mishchenko committed
225
  Synopsis    [Creates equivalence class.]
Alan Mishchenko committed
226 227 228 229 230 231 232 233

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
234
void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass )
Alan Mishchenko committed
235
{
Alan Mishchenko committed
236
    int Repr = GIA_VOID, EntPrev = -1, Ent, i;
Alan Mishchenko committed
237 238 239 240 241 242
    assert( Vec_IntSize(vClass) > 0 );
    Vec_IntForEachEntry( vClass, Ent, i )
    {
        if ( i == 0 )
        {
            Repr = Ent;
Alan Mishchenko committed
243
            Gia_ObjSetRepr( p, Ent, GIA_VOID );
Alan Mishchenko committed
244
            EntPrev = Ent;
Alan Mishchenko committed
245 246 247
        }
        else
        {
Alan Mishchenko committed
248
            assert( Repr < Ent );
Alan Mishchenko committed
249 250
            Gia_ObjSetRepr( p, Ent, Repr );
            Gia_ObjSetNext( p, EntPrev, Ent );
Alan Mishchenko committed
251
            EntPrev = Ent;
Alan Mishchenko committed
252 253
        }
    }
Alan Mishchenko committed
254
    Gia_ObjSetNext( p, EntPrev, 0 );
Alan Mishchenko committed
255 256 257 258
}

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

Alan Mishchenko committed
259
  Synopsis    [Refines one equivalence class.]
Alan Mishchenko committed
260 261 262 263 264 265 266 267

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
268
int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i )
Alan Mishchenko committed
269 270
{
    unsigned * pSim0, * pSim1;
Alan Mishchenko committed
271
    int Ent;
Alan Mishchenko committed
272 273 274
    Vec_IntClear( p->vClassOld );
    Vec_IntClear( p->vClassNew );
    Vec_IntPush( p->vClassOld, i );
Alan Mishchenko committed
275 276
    pSim0 = Cec_ObjSim(p, i);
    Gia_ClassForEachObj1( p->pAig, i, Ent )
Alan Mishchenko committed
277
    {
Alan Mishchenko committed
278 279
        pSim1 = Cec_ObjSim(p, Ent);
        if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) )
Alan Mishchenko committed
280 281
            Vec_IntPush( p->vClassOld, Ent );
        else
Alan Mishchenko committed
282
        {
Alan Mishchenko committed
283
            Vec_IntPush( p->vClassNew, Ent );
Alan Mishchenko committed
284 285 286
            if ( p->pBestState )
                Cec_ManSimCompareEqualScore( pSim0, pSim1, p->nWords, p->pScores );
        }
Alan Mishchenko committed
287
    }
Alan Mishchenko committed
288
    if ( Vec_IntSize( p->vClassNew ) == 0 )
Alan Mishchenko committed
289
        return 0;
Alan Mishchenko committed
290 291
    Cec_ManSimClassCreate( p->pAig, p->vClassOld );
    Cec_ManSimClassCreate( p->pAig, p->vClassNew );
Alan Mishchenko committed
292
    if ( Vec_IntSize(p->vClassNew) > 1 )
Alan Mishchenko committed
293
        return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) );
Alan Mishchenko committed
294 295 296 297 298
    return 1;
}

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

Alan Mishchenko committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  Synopsis    [Refines one equivalence class.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i )
{
    int iRepr, Ent;
    if ( Gia_ObjIsConst(p->pAig, i) )
    {
        Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
        return 1;
    }
    if ( !Gia_ObjIsClass(p->pAig, i) )
        return 0;
    assert( Gia_ObjIsClass(p->pAig, i) );
    iRepr = Gia_ObjRepr( p->pAig, i );
    if ( iRepr == GIA_VOID )
        iRepr = i;
    // collect nodes
    Vec_IntClear( p->vClassOld );
    Vec_IntClear( p->vClassNew );
    Gia_ClassForEachObj( p->pAig, iRepr, Ent )
    {
        if ( Ent == i )
            Vec_IntPush( p->vClassNew, Ent );
        else
            Vec_IntPush( p->vClassOld, Ent );
    }
    assert( Vec_IntSize( p->vClassNew ) == 1 );
    Cec_ManSimClassCreate( p->pAig, p->vClassOld );
    Cec_ManSimClassCreate( p->pAig, p->vClassNew );
    assert( !Gia_ObjIsClass(p->pAig, i) );
    return 1;
}

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

Alan Mishchenko committed
341
  Synopsis    [Computes hash key of the simuation info.]
Alan Mishchenko committed
342 343 344 345 346 347 348 349

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
350
int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize )
Alan Mishchenko committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
{
    static int s_Primes[16] = { 
        1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, 
        4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
    unsigned uHash = 0;
    int i;
    if ( pSim[0] & 1 )
        for ( i = 0; i < nWords; i++ )
            uHash ^= ~pSim[i] * s_Primes[i & 0xf];
    else
        for ( i = 0; i < nWords; i++ )
            uHash ^= pSim[i] * s_Primes[i & 0xf];
    return (int)(uHash % nTableSize);

}

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

Alan Mishchenko committed
369
  Synopsis    [Resets pointers to the simulation memory.]
Alan Mishchenko committed
370 371 372 373 374 375 376 377

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
378
void Cec_ManSimMemRelink( Cec_ManSim_t * p )
Alan Mishchenko committed
379 380
{
    unsigned * pPlace, Ent;
381
    pPlace = (unsigned *)&p->MemFree;
Alan Mishchenko committed
382 383 384 385 386 387 388 389
    for ( Ent = p->nMems * (p->nWords + 1); 
          Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc; 
          Ent += p->nWords + 1 )
    {
        *pPlace = Ent;
        pPlace = p->pMems + Ent;
    }
    *pPlace = 0;
Alan Mishchenko committed
390
    p->nWordsOld = p->nWords;
Alan Mishchenko committed
391 392 393 394 395 396 397 398 399 400 401 402 403
}

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

  Synopsis    [References simulation info.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
404
unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i )
Alan Mishchenko committed
405 406
{
    unsigned * pSim;
Alan Mishchenko committed
407
    assert( p->pSimInfo[i] == 0 );
Alan Mishchenko committed
408
    if ( p->MemFree == 0 )
Alan Mishchenko committed
409
    {
Alan Mishchenko committed
410
        if ( p->nWordsAlloc == 0 )
Alan Mishchenko committed
411
        {
Alan Mishchenko committed
412 413 414
            assert( p->pMems == NULL );
            p->nWordsAlloc = (1<<17); // -> 1Mb
            p->nMems = 1;
Alan Mishchenko committed
415
        }
Alan Mishchenko committed
416 417
        p->nWordsAlloc *= 2;
        p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc );
Alan Mishchenko committed
418
        Cec_ManSimMemRelink( p );
Alan Mishchenko committed
419
    }
Alan Mishchenko committed
420
    p->pSimInfo[i] = p->MemFree;
Alan Mishchenko committed
421 422 423 424 425 426 427
    pSim = p->pMems + p->MemFree;
    p->MemFree = pSim[0];
    pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) );
    p->nMems++;
    if ( p->nMemsMax < p->nMems )
        p->nMemsMax = p->nMems;
    return pSim;
Alan Mishchenko committed
428 429 430 431
}

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

Alan Mishchenko committed
432
  Synopsis    [Dereferences simulaton info.]
Alan Mishchenko committed
433 434 435 436 437 438 439 440

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
441
unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i )
Alan Mishchenko committed
442
{
Alan Mishchenko committed
443
    unsigned * pSim;
Alan Mishchenko committed
444 445
    assert( p->pSimInfo[i] > 0 );
    pSim = p->pMems + p->pSimInfo[i];
Alan Mishchenko committed
446 447 448
    if ( --pSim[0] == 0 )
    {
        pSim[0] = p->MemFree;
Alan Mishchenko committed
449 450
        p->MemFree = p->pSimInfo[i];
        p->pSimInfo[i] = 0;
Alan Mishchenko committed
451 452 453
        p->nMems--;
    }
    return pSim;
Alan Mishchenko committed
454 455 456 457
}

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

Alan Mishchenko committed
458
  Synopsis    [Refines nodes belonging to candidate constant class.]
Alan Mishchenko committed
459 460 461 462 463 464 465 466

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
467
void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined )
Alan Mishchenko committed
468 469
{
    unsigned * pSim;
Alan Mishchenko committed
470
    int * pTable, nTableSize, i, k, Key;
Alan Mishchenko committed
471 472
    if ( Vec_IntSize(vRefined) == 0 )
        return;
473
    nTableSize = Abc_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 );
Alan Mishchenko committed
474 475
    pTable = ABC_CALLOC( int, nTableSize );
    Vec_IntForEachEntry( vRefined, i, k )
Alan Mishchenko committed
476
    {
Alan Mishchenko committed
477 478 479
        pSim = Cec_ObjSim( p, i );
        assert( !Cec_ManSimCompareConst( pSim, p->nWords ) );
        Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize );
Alan Mishchenko committed
480 481
        if ( pTable[Key] == 0 )
        {
Alan Mishchenko committed
482 483 484
            assert( Gia_ObjRepr(p->pAig, i) == 0 );
            assert( Gia_ObjNext(p->pAig, i) == 0 );
            Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
Alan Mishchenko committed
485 486 487
        }
        else
        {
Alan Mishchenko committed
488 489 490 491 492
            Gia_ObjSetNext( p->pAig, pTable[Key], i );
            Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) );
            if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID )
                Gia_ObjSetRepr( p->pAig, i, pTable[Key] );
            assert( Gia_ObjRepr(p->pAig, i) > 0 );
Alan Mishchenko committed
493
        }
Alan Mishchenko committed
494
        pTable[Key] = i;
Alan Mishchenko committed
495
    }
Alan Mishchenko committed
496
    Vec_IntForEachEntry( vRefined, i, k )
Alan Mishchenko committed
497
    {
Alan Mishchenko committed
498 499
        if ( Gia_ObjIsHead( p->pAig, i ) )
            Cec_ManSimClassRefineOne( p, i );
Alan Mishchenko committed
500 501
    }
    Vec_IntForEachEntry( vRefined, i, k )
Alan Mishchenko committed
502
        Cec_ManSimSimDeref( p, i );
Alan Mishchenko committed
503 504 505 506 507 508
    ABC_FREE( pTable );
}


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

Alan Mishchenko committed
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
  Synopsis    [Saves the input pattern with the given number.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat )
{
    unsigned * pInfo;
    int i;
    assert( p->pCexComb == NULL );
    assert( iPat >= 0 && iPat < 32 * p->nWords );
524
    p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char, 
525
        sizeof(Abc_Cex_t) + sizeof(unsigned) * Abc_BitWordNum(Gia_ManCiNum(p->pAig)) );
Alan Mishchenko committed
526 527 528 529 530
    p->pCexComb->iPo = p->iOut;
    p->pCexComb->nPis = Gia_ManCiNum(p->pAig);
    p->pCexComb->nBits = Gia_ManCiNum(p->pAig);
    for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
    {
531
        pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i );
532 533
        if ( Abc_InfoHasBit( pInfo, iPat ) )
            Abc_InfoSetBit( p->pCexComb->pData, i );
Alan Mishchenko committed
534 535 536 537 538
    }
}

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

Alan Mishchenko committed
539 540 541 542 543 544 545 546 547 548
  Synopsis    [Find the best pattern using the scores.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Cec_ManSimFindBestPattern( Cec_ManSim_t * p )
Alan Mishchenko committed
549
{ 
Alan Mishchenko committed
550
    unsigned * pInfo;
Alan Mishchenko committed
551
    int i, ScoreBest = 0, iPatBest = 1; // set the first pattern
Alan Mishchenko committed
552 553 554 555 556 557 558 559 560 561 562 563 564
    // find the best pattern
    for ( i = 0; i < 32 * p->nWords; i++ )
        if ( ScoreBest < p->pScores[i] )
        {
            ScoreBest = p->pScores[i];
            iPatBest = i;
        }
    // compare this with the available patterns - and save
    if ( p->pBestState->iPo <= ScoreBest )
    {
        assert( p->pBestState->nRegs == Gia_ManRegNum(p->pAig) );
        for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
        {
565
            pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i );
566 567
            if ( Abc_InfoHasBit(p->pBestState->pData, i) != Abc_InfoHasBit(pInfo, iPatBest) )
                Abc_InfoXorBit( p->pBestState->pData, i );
Alan Mishchenko committed
568 569 570 571 572 573 574
        }
        p->pBestState->iPo = ScoreBest;
    }
}

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

Alan Mishchenko committed
575 576 577 578 579 580 581 582 583 584 585 586 587
  Synopsis    [Returns 1 if computation should stop.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p )
{
    unsigned * pInfo, * pInfo2;
    int i;
Alan Mishchenko committed
588
    if ( !p->pPars->fCheckMiter )
Alan Mishchenko committed
589
        return 0;
Alan Mishchenko committed
590
    assert( p->vCoSimInfo != NULL );
Alan Mishchenko committed
591
    // compare outputs with 0
Alan Mishchenko committed
592
    if ( p->pPars->fDualOut )
Alan Mishchenko committed
593
    {
Alan Mishchenko committed
594 595
        assert( (Gia_ManPoNum(p->pAig) & 1) == 0 );
        for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ )
Alan Mishchenko committed
596
        {
597 598
            pInfo  = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i );
            pInfo2 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, ++i );
Alan Mishchenko committed
599 600 601 602 603 604 605 606
            if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) )
            {
                if ( p->iOut == -1 )
                {
                    p->iOut = i/2;
                    Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) );
                }
                if ( p->pCexes == NULL )
Alan Mishchenko committed
607
                    p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig)/2 );
Alan Mishchenko committed
608 609 610 611 612 613 614 615 616 617
                if ( p->pCexes[i/2] == NULL )
                {
                    p->nOuts++;
                    p->pCexes[i/2] = (void *)1;
                }
            }
        }
    }
    else
    {
Alan Mishchenko committed
618
        for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ )
Alan Mishchenko committed
619
        {
620
            pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i );
Alan Mishchenko committed
621 622 623 624 625 626 627 628
            if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) )
            {
                if ( p->iOut == -1 )
                {
                    p->iOut = i;
                    Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) );
                }
                if ( p->pCexes == NULL )
Alan Mishchenko committed
629
                    p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig) );
Alan Mishchenko committed
630 631 632 633 634 635 636 637
                if ( p->pCexes[i] == NULL )
                {
                    p->nOuts++;
                    p->pCexes[i] = (void *)1;
                }
            }
        }
    }
Alan Mishchenko committed
638
    return p->pCexes != NULL;
Alan Mishchenko committed
639 640 641 642
}

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

Alan Mishchenko committed
643 644 645 646 647 648 649 650 651
  Synopsis    [Simulates one round.]

  Description [Returns the number of PO entry if failed; 0 otherwise.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
652
int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
Alan Mishchenko committed
653 654 655 656
{
    Gia_Obj_t * pObj;
    unsigned * pRes0, * pRes1, * pRes;
    int i, k, w, Ent, iCiId = 0, iCoId = 0;
Alan Mishchenko committed
657 658 659
    // prepare internal storage
    if ( p->nWordsOld != p->nWords )
        Cec_ManSimMemRelink( p );
Alan Mishchenko committed
660
    p->nMemsMax = 0;
Alan Mishchenko committed
661 662 663 664
    // allocate score counters
    ABC_FREE( p->pScores );
    if ( p->pBestState )
        p->pScores = ABC_CALLOC( int, 32 * p->nWords );
Alan Mishchenko committed
665
    // simulate nodes
Alan Mishchenko committed
666 667 668
    Vec_IntClear( p->vRefinedC );
    if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) )
    {
Alan Mishchenko committed
669
        pRes = Cec_ManSimSimRef( p, 0 );
Alan Mishchenko committed
670 671 672 673 674 675 676 677 678 679 680 681
        for ( w = 1; w <= p->nWords; w++ )
            pRes[w] = 0;
    }
    Gia_ManForEachObj1( p->pAig, pObj, i )
    {
        if ( Gia_ObjIsCi(pObj) ) 
        {
            if ( Gia_ObjValue(pObj) == 0 )
            {
                iCiId++;
                continue;
            }
Alan Mishchenko committed
682
            pRes = Cec_ManSimSimRef( p, i );
Alan Mishchenko committed
683 684
            if ( vInfoCis ) 
            {
685
                pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, iCiId++ );
Alan Mishchenko committed
686
                for ( w = 1; w <= p->nWords; w++ )
Alan Mishchenko committed
687
                    pRes[w] = pRes0[w-1];
Alan Mishchenko committed
688 689 690 691
            }
            else
            {
                for ( w = 1; w <= p->nWords; w++ )
Alan Mishchenko committed
692
                    pRes[w] = Gia_ManRandom( 0 );
Alan Mishchenko committed
693 694 695 696 697 698
            }
            // make sure the first pattern is always zero
            pRes[1] ^= (pRes[1] & 1);
            goto references;
        }
        if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin
Alan Mishchenko committed
699
        {
Alan Mishchenko committed
700
            pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
Alan Mishchenko committed
701 702
            if ( vInfoCos )
            {
703
                pRes = (unsigned *)Vec_PtrEntry( vInfoCos, iCoId++ );
Alan Mishchenko committed
704 705 706 707 708 709 710
                if ( Gia_ObjFaninC0(pObj) )
                    for ( w = 1; w <= p->nWords; w++ )
                        pRes[w-1] = ~pRes0[w];
                else 
                    for ( w = 1; w <= p->nWords; w++ )
                        pRes[w-1] = pRes0[w];
            }
Alan Mishchenko committed
711 712
            continue;
        }
Alan Mishchenko committed
713
        assert( Gia_ObjValue(pObj) );
Alan Mishchenko committed
714 715 716
        pRes  = Cec_ManSimSimRef( p, i );
        pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
        pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) );
Alan Mishchenko committed
717

718
//        Abc_Print( 1, "%d,%d  ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) );
Alan Mishchenko committed
719

Alan Mishchenko committed
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
        if ( Gia_ObjFaninC0(pObj) )
        {
            if ( Gia_ObjFaninC1(pObj) )
                for ( w = 1; w <= p->nWords; w++ )
                    pRes[w] = ~(pRes0[w] | pRes1[w]);
            else
                for ( w = 1; w <= p->nWords; w++ )
                    pRes[w] = ~pRes0[w] & pRes1[w];
        }
        else
        {
            if ( Gia_ObjFaninC1(pObj) )
                for ( w = 1; w <= p->nWords; w++ )
                    pRes[w] = pRes0[w] & ~pRes1[w];
            else
                for ( w = 1; w <= p->nWords; w++ )
                    pRes[w] = pRes0[w] & pRes1[w];
        }
Alan Mishchenko committed
738

Alan Mishchenko committed
739 740
references:
        // if this node is candidate constant, collect it
Alan Mishchenko committed
741
        if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) )
Alan Mishchenko committed
742 743 744
        {
            pRes[0]++;
            Vec_IntPush( p->vRefinedC, i );
Alan Mishchenko committed
745 746
            if ( p->pBestState )
                Cec_ManSimCompareConstScore( pRes + 1, p->nWords, p->pScores );
Alan Mishchenko committed
747 748
        }
        // if the node belongs to a class, save it
Alan Mishchenko committed
749
        if ( Gia_ObjIsClass(p->pAig, i) )
Alan Mishchenko committed
750 751
            pRes[0]++;
        // if this is the last node of the class, process it
Alan Mishchenko committed
752
        if ( Gia_ObjIsTail(p->pAig, i) )
Alan Mishchenko committed
753 754
        {
            Vec_IntClear( p->vClassTemp );
Alan Mishchenko committed
755
            Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent )
Alan Mishchenko committed
756
                Vec_IntPush( p->vClassTemp, Ent );
Alan Mishchenko committed
757
            Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) );
Alan Mishchenko committed
758
            Vec_IntForEachEntry( p->vClassTemp, Ent, k )
Alan Mishchenko committed
759
                Cec_ManSimSimDeref( p, Ent );
Alan Mishchenko committed
760
        }
Alan Mishchenko committed
761
    }
762 763 764 765 766 767 768 769 770 771 772

    if ( p->pPars->fConstCorr )
    {
        Vec_IntForEachEntry( p->vRefinedC, i, k )
        {
            Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
            Cec_ManSimSimDeref( p, i );
        }
        Vec_IntClear( p->vRefinedC );
    }

Alan Mishchenko committed
773
    if ( Vec_IntSize(p->vRefinedC) > 0 )
Alan Mishchenko committed
774
        Cec_ManSimProcessRefined( p, p->vRefinedC );
Alan Mishchenko committed
775 776 777
    assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) );
    assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) );
    assert( p->nMems == 1 );
Alan Mishchenko committed
778
    if ( p->nMems != 1 )
779
        Abc_Print( 1, "Cec_ManSimSimulateRound(): Memory management error!\n" );
Alan Mishchenko committed
780
    if ( p->pPars->fVeryVerbose )
Alan Mishchenko committed
781
        Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
Alan Mishchenko committed
782 783
    if ( p->pBestState )
        Cec_ManSimFindBestPattern( p );
Alan Mishchenko committed
784
/*
Alan Mishchenko committed
785
    if ( p->nMems > 1 ) {
Alan Mishchenko committed
786
        for ( i = 1; i < p->nObjs; i++ )
Alan Mishchenko committed
787
        if ( p->pSims[i] ) {
Alan Mishchenko committed
788 789 790 791
            int x = 0;
        }
    }
*/
Alan Mishchenko committed
792
    return Cec_ManSimAnalyzeOutputs( p );
Alan Mishchenko committed
793 794
}

Alan Mishchenko committed
795 796


Alan Mishchenko committed
797 798
/**Function*************************************************************

Alan Mishchenko committed
799
  Synopsis    [Creates simulation info for this round.]
Alan Mishchenko committed
800 801 802 803 804 805 806 807

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
808
void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
Alan Mishchenko committed
809
{
Alan Mishchenko committed
810 811 812
    unsigned * pRes0, * pRes1;
    int i, w;
    if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 )
Alan Mishchenko committed
813
    {
Alan Mishchenko committed
814 815 816
        assert( vInfoCis && vInfoCos );
        for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
        {
817
            pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i );
Alan Mishchenko committed
818
            for ( w = 0; w < p->nWords; w++ )
Alan Mishchenko committed
819
                pRes0[w] = Gia_ManRandom( 0 );
Alan Mishchenko committed
820 821 822
        }
        for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
        {
823 824
            pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i );
            pRes1 = (unsigned *)Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i );
Alan Mishchenko committed
825 826 827 828 829 830 831 832
            for ( w = 0; w < p->nWords; w++ )
                pRes0[w] = pRes1[w];
        }
    }
    else 
    {
        for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
        {
833
            pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i );
Alan Mishchenko committed
834
            for ( w = 0; w < p->nWords; w++ )
Alan Mishchenko committed
835
                pRes0[w] = Gia_ManRandom( 0 );
Alan Mishchenko committed
836
        }
Alan Mishchenko committed
837 838 839 840 841
    }
}

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

Alan Mishchenko committed
842
  Synopsis    [Returns 1 if the bug is found.]
Alan Mishchenko committed
843 844 845 846 847 848 849 850

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
851
int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax )
Alan Mishchenko committed
852
{
Alan Mishchenko committed
853 854 855 856 857 858
    Gia_Obj_t * pObj;
    int i;
    assert( p->pAig->pReprs == NULL );
    // allocate representation
    p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) );
    p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
Alan Mishchenko committed
859
    // create references
860
    Gia_ManCreateValueRefs( p->pAig );
Alan Mishchenko committed
861
    // set starting representative of internal nodes to be constant 0
Alan Mishchenko committed
862 863 864
    if ( p->pPars->fLatchCorr )
        Gia_ManForEachObj( p->pAig, pObj, i )
            Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
865
    else if ( LevelMax == -1 )
Alan Mishchenko committed
866 867
        Gia_ManForEachObj( p->pAig, pObj, i )
            Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID );
868 869 870 871 872 873 874
    else
    {
        Gia_ManLevelNum( p->pAig );
        Gia_ManForEachObj( p->pAig, pObj, i )
            Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) && Gia_ObjLevel(p->pAig,pObj) <= LevelMax) ? 0 : GIA_VOID );
        Vec_IntFreeP( &p->pAig->vLevels );
    }
Alan Mishchenko committed
875 876 877
    // if sequential simulation, set starting representative of ROs to be constant 0
    if ( p->pPars->fSeqSimulate )
        Gia_ManForEachRo( p->pAig, pObj, i )
Alan Mishchenko committed
878 879
            if ( pObj->Value )
                Gia_ObjSetRepr( p->pAig, Gia_ObjId(p->pAig, pObj), 0 );
Alan Mishchenko committed
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
    // perform simulation
    p->nWords = 1;
    do {
        if ( p->pPars->fVerbose )
            Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
        for ( i = 0; i < 4; i++ )
        {
            Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
            if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
                return 1;
        }
        p->nWords = 2 * p->nWords + 1;
    }
    while ( p->nWords <= p->pPars->nWords );
    return 0;
Alan Mishchenko committed
895 896 897 898
}

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

Alan Mishchenko committed
899
  Synopsis    [Returns 1 if the bug is found.]
Alan Mishchenko committed
900 901 902 903 904 905 906 907

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
908
int Cec_ManSimClassesRefine( Cec_ManSim_t * p )
Alan Mishchenko committed
909
{
Alan Mishchenko committed
910
    int i;
911
    Gia_ManCreateValueRefs( p->pAig );
Alan Mishchenko committed
912 913
    p->nWords = p->pPars->nWords;
    for ( i = 0; i < p->pPars->nRounds; i++ )
Alan Mishchenko committed
914
    {
Alan Mishchenko committed
915
        if ( (i % (p->pPars->nRounds / 5)) == 0 && p->pPars->fVerbose )
Alan Mishchenko committed
916 917 918 919
            Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
        Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
        if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
            return 1;
Alan Mishchenko committed
920
    }
Alan Mishchenko committed
921 922
    if ( p->pPars->fVerbose )
        Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
Alan Mishchenko committed
923
    return 0;
Alan Mishchenko committed
924 925 926 927 928 929
}
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


930 931
ABC_NAMESPACE_IMPL_END