saigSimExt2.c 16.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/**CFile****************************************************************

  FileName    [saigSimExt2.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Sequential AIG package.]

  Synopsis    [Extending simulation trace to contain ternary values.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "saig.h"
22
#include "proof/ssw/ssw.h"
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

ABC_NAMESPACE_IMPL_START


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

#define SAIG_ZER_NEW 0   // 0 not visited
#define SAIG_ONE_NEW 1   // 1 not visited
#define SAIG_ZER_OLD 2   // 0 visited
#define SAIG_ONE_OLD 3   // 1 visited

static inline int Saig_ManSimInfo2IsOld( int Value )
{
    return Value == SAIG_ZER_OLD || Value == SAIG_ONE_OLD;
}

static inline int Saig_ManSimInfo2SetOld( int Value )
{
    if ( Value == SAIG_ZER_NEW )
        return SAIG_ZER_OLD;
    if ( Value == SAIG_ONE_NEW )
        return SAIG_ONE_OLD;
    assert( 0 );
    return 0;
}

static inline int Saig_ManSimInfo2Not( int Value )
{
    if ( Value == SAIG_ZER_NEW )
        return SAIG_ONE_NEW;
    if ( Value == SAIG_ONE_NEW )
        return SAIG_ZER_NEW;
57 58 59 60
    if ( Value == SAIG_ZER_OLD )
        return SAIG_ONE_OLD;
    if ( Value == SAIG_ONE_OLD )
        return SAIG_ZER_OLD;
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
    assert( 0 );
    return 0;
}

static inline int Saig_ManSimInfo2And( int Value0, int Value1 )
{
    if ( Value0 == SAIG_ZER_NEW || Value1 == SAIG_ZER_NEW )
        return SAIG_ZER_NEW;
    if ( Value0 == SAIG_ONE_NEW && Value1 == SAIG_ONE_NEW )
        return SAIG_ONE_NEW;
    assert( 0 );
    return 0;
}

static inline int Saig_ManSimInfo2Get( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
{
    unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
    return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1));
}

static inline void Saig_ManSimInfo2Set( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value )
{
    unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
    Value ^= Saig_ManSimInfo2Get( vSimInfo, pObj, iFrame );
    pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1));
}

// performs ternary simulation
extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes );

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

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

  Synopsis    [Performs ternary simulation for one node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Saig_ManExtendOneEval2( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
{
    int Value0, Value1, Value;
    Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pObj), iFrame );
    if ( Aig_ObjFaninC0(pObj) )
        Value0 = Saig_ManSimInfo2Not( Value0 );
112
    if ( Aig_ObjIsCo(pObj) )
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
    {
        Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value0 );
        return Value0;
    }
    assert( Aig_ObjIsNode(pObj) );
    Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pObj), iFrame );
    if ( Aig_ObjFaninC1(pObj) )
        Value1 = Saig_ManSimInfo2Not( Value1 );
    Value = Saig_ManSimInfo2And( Value0, Value1 );
    Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value );
    return Value;
}

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

  Synopsis    [Performs sensitization analysis for one design.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Saig_ManSimDataInit2( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo )
{
    Aig_Obj_t * pObj, * pObjLi, * pObjLo;
    int i, f, iBit = 0;
    Saig_ManForEachLo( p, pObj, i )
142
        Saig_ManSimInfo2Set( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW );
143 144 145 146
    for ( f = 0; f <= pCex->iFrame; f++ )
    {
        Saig_ManSimInfo2Set( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE_NEW );
        Saig_ManForEachPi( p, pObj, i )
147
            Saig_ManSimInfo2Set( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW );
148 149
        Aig_ManForEachNode( p, pObj, i )
            Saig_ManExtendOneEval2( vSimInfo, pObj, f );
150
        Aig_ManForEachCo( p, pObj, i )
151 152 153 154 155 156 157
            Saig_ManExtendOneEval2( vSimInfo, pObj, f );
        if ( f == pCex->iFrame )
            break;
        Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
            Saig_ManSimInfo2Set( vSimInfo, pObjLo, f+1, Saig_ManSimInfo2Get(vSimInfo, pObjLi, f) );
    }
    // make sure the output of the property failed
158
    pObj = Aig_ManCo( p, pCex->iPo );
159 160 161 162 163
    return Saig_ManSimInfo2Get( vSimInfo, pObj, pCex->iFrame );
}

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

164 165 166 167 168 169 170 171 172 173 174 175
  Synopsis    [Drive implications of the given node towards primary outputs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo )
{
    Aig_Obj_t * pFanout;
176
    int k, iFanout = -1, Value0, Value1;
177 178 179
    int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f );
    assert( !Saig_ManSimInfo2IsOld( Value ) );
    Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) );
180
    if ( (Aig_ObjIsCo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) )
181 182 183 184 185 186 187 188 189 190
        return;
    if ( Saig_ObjIsLi( p, pObj ) )
    {
        assert( f < fMax );
        pFanout = Saig_ObjLiToLo(p, pObj);
        Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 );
        if ( !Saig_ManSimInfo2IsOld( Value ) )
            Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo );
        return;
    }
191
    assert( Aig_ObjIsCi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) );
192 193 194 195 196
    Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k )
    {
        Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f );
        if ( Saig_ManSimInfo2IsOld( Value ) )
            continue;
197
        if ( Aig_ObjIsCo(pFanout) )
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        {
            Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo );
            continue;
        }
        assert( Aig_ObjIsNode(pFanout) );
        Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f );
        Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f );
        if ( Aig_ObjFaninC0(pFanout) )
            Value0 = Saig_ManSimInfo2Not( Value0 );
        if ( Aig_ObjFaninC1(pFanout) )
            Value1 = Saig_ManSimInfo2Not( Value1 );
        if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD || 
            (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) )
            Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo );
    }
}

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

217 218 219 220 221 222 223 224 225
  Synopsis    [Performs recursive sensetization analysis.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
226
void Saig_ManExplorePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo )
227 228 229 230
{
    int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f );
    if ( Saig_ManSimInfo2IsOld( Value ) )
        return;
231 232 233 234 235 236 237
    Saig_ManSetAndDriveImplications_rec( p, pObj, f, fMax, vSimInfo );
    assert( !Aig_ObjIsConst1(pObj) );
    if ( Saig_ObjIsLo(p, pObj) && f == 0 )
        return;
    if ( Saig_ObjIsPi(p, pObj) )
    {
        // propagate implications of this assignment
238
        int i, iPiNum = Aig_ObjCioId(pObj);
239 240
        for ( i = fMax; i >= 0; i-- )
            if ( i != f )
241
                Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, iPiNum), i, fMax, vSimInfo );
242
        return;
243
    }
244 245 246
    if ( Saig_ObjIsLo( p, pObj ) )
    {
        assert( f > 0 );
247
        Saig_ManExplorePaths_rec( p, Saig_ObjLoToLi(p, pObj), f-1, fMax, vSimInfo );
248 249
        return;
    }
250
    if ( Aig_ObjIsCo(pObj) )
251
    {
252
        Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
253 254 255 256
        return;
    }
    assert( Aig_ObjIsNode(pObj) );
    if ( Value == SAIG_ZER_OLD )
257 258 259 260 261 262
    {
//        if ( (Aig_ObjId(pObj) & 1) == 0 )
            Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
//        else
//            Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo );
    }
263 264
    else
    {
265 266
        Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
        Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo );
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
    }
}

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

  Synopsis    [Returns the array of PIs for flops that should not be absracted.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Saig_ManProcessCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose )
{
283
    Aig_Obj_t * pObj;
284 285 286
    Vec_Int_t * vRes, * vResInv;
    int i, f, Value;
//    assert( Aig_ManRegNum(p) > 0 );
287
    assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) );
288 289 290
    // start simulation data
    Value = Saig_ManSimDataInit2( p, pCex, vSimInfo );
    assert( Value == SAIG_ONE_NEW );
291
    // derive implications of constants and primary inputs
292 293
    Saig_ManForEachLo( p, pObj, i )
        Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo );
294 295 296 297
    for ( f = pCex->iFrame; f >= 0; f-- )
    {
        Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo );
        for ( i = 0; i < iFirstFlopPi; i++ )
298
            Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo );
299
    }
300
    // recursively compute justification
301
    Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo );
302 303 304 305 306 307 308
    // select the result
    vRes = Vec_IntAlloc( 1000 );
    vResInv = Vec_IntAlloc( 1000 );
    for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ )
    {
        for ( f = pCex->iFrame; f >= 0; f-- )
        {
309
            Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f );
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
            if ( Saig_ManSimInfo2IsOld( Value ) )
                break;
        }
        if ( f >= 0 )
            Vec_IntPush( vRes, i );
        else
            Vec_IntPush( vResInv, i );
    }
    // resimulate to make sure it is valid
    Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv );
    assert( Value == SAIG_ONE );
    Vec_IntFree( vResInv );
    return vRes;
}

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

  Synopsis    [Returns the array of PIs for flops that should not be absracted.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose )
{
    Vec_Int_t * vRes;
    Vec_Ptr_t * vSimInfo;
340
    clock_t clk;
341 342 343
    if ( Saig_ManPiNum(p) != pCex->nPis )
    {
        printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", 
344
            Aig_ManCiNum(p), pCex->nPis );
345 346 347
        return NULL;
    }
    Aig_ManFanoutStart( p );
348 349
    vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) );
    Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) );
350 351 352 353 354 355 356 357 358 359 360 361 362

clk = clock();
    vRes = Saig_ManProcessCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose );
    if ( fVerbose )
    {
        printf( "Total new PIs = %3d. Non-removable PIs = %3d.  ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) );
ABC_PRT( "Time", clock() - clk );
    }
    Vec_PtrFree( vSimInfo );
    Aig_ManFanoutStop( p );
    return vRes;
}

363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384




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

  Synopsis    [Returns the array of PIs for flops that should not be absracted.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Cex_t * Saig_ManDeriveCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose )
{
    Abc_Cex_t * pCare;
    Aig_Obj_t * pObj;
    Vec_Int_t * vRes, * vResInv;
    int i, f, Value;
//    assert( Aig_ManRegNum(p) > 0 );
385
    assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) );
386 387 388 389 390 391 392 393 394 395
    // start simulation data
    Value = Saig_ManSimDataInit2( p, pCex, vSimInfo );
    assert( Value == SAIG_ONE_NEW );
    // derive implications of constants and primary inputs
    Saig_ManForEachLo( p, pObj, i )
        Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo );
    for ( f = pCex->iFrame; f >= 0; f-- )
    {
        Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo );
        for ( i = 0; i < iFirstFlopPi; i++ )
396
            Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo );
397 398
    }
    // recursively compute justification
399
    Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo );
400 401 402

    // create CEX
    pCare = Abc_CexDup( pCex, pCex->nRegs );
403
    memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) );
404 405 406 407 408 409 410 411 412

    // select the result
    vRes = Vec_IntAlloc( 1000 );
    vResInv = Vec_IntAlloc( 1000 );
    for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ )
    {
        int fFound = 0;
        for ( f = pCex->iFrame; f >= 0; f-- )
        {
413
            Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f );
414 415 416
            if ( Saig_ManSimInfo2IsOld( Value ) )
            {
                fFound = 1;
417
                Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * f + i );
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
            }
        }
        if ( fFound )
            Vec_IntPush( vRes, i );
        else
            Vec_IntPush( vResInv, i );
    }
    // resimulate to make sure it is valid
    Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv );
    assert( Value == SAIG_ONE );
    Vec_IntFree( vResInv );
    Vec_IntFree( vRes );

    return pCare;
}

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

  Synopsis    [Returns the array of PIs for flops that should not be absracted.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Cex_t * Saig_ManFindCexCareBitsSense( Aig_Man_t * p, Abc_Cex_t * pCex, int iFirstFlopPi, int fVerbose )
{
    Abc_Cex_t * pCare;
    Vec_Ptr_t * vSimInfo;
449
    clock_t clk;
450 451 452
    if ( Saig_ManPiNum(p) != pCex->nPis )
    {
        printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", 
453
            Aig_ManCiNum(p), pCex->nPis );
454 455 456
        return NULL;
    }
    Aig_ManFanoutStart( p );
457 458
    vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) );
    Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) );
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474

clk = clock();
    pCare = Saig_ManDeriveCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose );
    if ( fVerbose )
    {
//        printf( "Total new PIs = %3d. Non-removable PIs = %3d.  ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) );
Abc_CexPrintStats( pCex );
Abc_CexPrintStats( pCare );
ABC_PRT( "Time", clock() - clk );
    }

    Vec_PtrFree( vSimInfo );
    Aig_ManFanoutStop( p );
    return pCare;
}

475 476 477 478 479 480 481
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END