giaAbs.c 16 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
/**CFile****************************************************************

  FileName    [giaAbs.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Scalable AIG package.]

  Synopsis    [Counter-example-guided abstraction refinement.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

***********************************************************************/
 
#include "gia.h"
#include "giaAig.h"
#include "saig.h"

ABC_NAMESPACE_IMPL_START

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

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

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

  Synopsis    [This procedure sets default parameters.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p )
{
    memset( p, 0, sizeof(Gia_ParAbs_t) );
    p->Algo        =        0;    // algorithm: CBA
    p->nFramesMax  =       10;    // timeframes for PBA
    p->nConfMax    =    10000;    // conflicts for PBA
    p->fDynamic    =        1;    // dynamic unfolding for PBA
    p->fConstr     =        0;    // use constraints
    p->nFramesBmc  =      250;    // timeframes for BMC
    p->nConfMaxBmc =     5000;    // conflicts for BMC
    p->nStableMax  =  1000000;    // the number of stable frames to quit
    p->nRatio      =       10;    // ratio of flops to quit
    p->nBobPar     =  1000000;    // the number of frames before trying to quit
    p->fUseBdds    =        0;    // use BDDs to refine abstraction
    p->fUseDprove  =        0;    // use 'dprove' to refine abstraction
    p->fUseStart   =        1;    // use starting frame
    p->fVerbose    =        0;    // verbose output
    p->fVeryVerbose=        0;    // printing additional information
    p->Status      =       -1;    // the problem status
    p->nFramesDone =       -1;    // the number of rames covered
}

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

  Synopsis    [Transform flop list into flop map.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops )
{
    Vec_Int_t * vFlopClasses;
    int i, Entry;
    vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) );
    Vec_IntForEachEntry( vFlops, Entry, i )
        Vec_IntWriteEntry( vFlopClasses, Entry, 1 );
    return vFlopClasses;
}

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

  Synopsis    [Transform flop map into flop list.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses )
{
    Vec_Int_t * vFlops;
    int i, Entry;
    vFlops = Vec_IntAlloc( 100 );
    Vec_IntForEachEntry( vFlopClasses, Entry, i )
        if ( Entry )
            Vec_IntPush( vFlops, i );
    return vFlops;
}


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

  Synopsis    [Starts abstraction by computing latch map.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
123
void Gia_ManCexAbstractionStart( Gia_Man_t * pGia, Gia_ParAbs_t * pPars )
124 125
{
    Vec_Int_t * vFlops;
126 127
    Aig_Man_t * pNew;
    if ( pGia->vFlopClasses != NULL )
128 129
    {
        printf( "Gia_ManCexAbstractionStart(): Abstraction latch map is present but will be rederived.\n" );
130
        Vec_IntFreeP( &pGia->vFlopClasses );
131
    }
132 133 134 135
    pNew = Gia_ManToAig( pGia, 0 );
    vFlops = Saig_ManCexAbstractionFlops( pNew, pPars );
    pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
    Aig_ManStop( pNew );
136 137
    if ( vFlops )
    {
138
        pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops );
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
        Vec_IntFree( vFlops );
    }
}

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

  Synopsis    [Refines abstraction using the latch map.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
154
int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose )
155 156 157 158 159 160 161 162 163 164
{
    Aig_Man_t * pNew;
    Vec_Int_t * vFlops;
    if ( pGia->vFlopClasses == NULL )
    {
        printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" );
        return -1;
    }
    pNew = Gia_ManToAig( pGia, 0 );
    vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses );
165
    if ( !Saig_ManCexRefineStep( pNew, vFlops, pGia->vFlopClasses, pCex, nFfToAddMax, fTryFour, fSensePath, fVerbose ) )
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    {
        pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
        Vec_IntFree( vFlops );
        Aig_ManStop( pNew );
        return 0;
    }
    Vec_IntFree( pGia->vFlopClasses );
    pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops );
    Vec_IntFree( vFlops );
    Aig_ManStop( pNew );
    return -1;
}



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

183
  Synopsis    [Transform flop list into flop map.]
184 185 186 187 188 189 190 191

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
192
Vec_Int_t * Gia_ManFlopsSelect( Vec_Int_t * vFlops, Vec_Int_t * vFlopsNew )
193
{
194 195 196 197 198 199
    Vec_Int_t * vSelected;
    int i, Entry;
    vSelected = Vec_IntAlloc( Vec_IntSize(vFlopsNew) );
    Vec_IntForEachEntry( vFlopsNew, Entry, i )
        Vec_IntPush( vSelected, Vec_IntEntry(vFlops, Entry) );
    return vSelected;
200 201 202 203
}

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

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  Synopsis    [Adds flops that should be present in the abstraction.]

  Description [The second argument (vAbsFfsToAdd) is the array of numbers
  of previously abstrated flops (flops replaced by PIs in the abstracted model)
  that should be present in the abstraction as real flops.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManFlopsAddToClasses( Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd )
{
    Vec_Int_t * vMapEntries;
    int i, Entry, iFlopNum;
    // map previously abstracted flops into their original numbers
    vMapEntries = Vec_IntAlloc( Vec_IntSize(vFlopClasses) );
    Vec_IntForEachEntry( vFlopClasses, Entry, i )
        if ( Entry == 0 )
            Vec_IntPush( vMapEntries, i );
    // add these flops as real flops
    Vec_IntForEachEntry( vAbsFfsToAdd, Entry, i )
    {
        iFlopNum = Vec_IntEntry( vMapEntries, Entry );
        assert( Vec_IntEntry( vFlopClasses, iFlopNum ) == 0 );
        Vec_IntWriteEntry( vFlopClasses, iFlopNum, 1 );
    }
    Vec_IntFree( vMapEntries );
}

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

236
  Synopsis    [Derive unrolled timeframes.]
237 238 239 240 241 242 243 244

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
245
int Gia_ManCbaPerform( Gia_Man_t * pGia, void * pPars )
246
{
247
    Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars;
248
    Gia_Man_t * pAbs;
249
    Aig_Man_t * pAig, * pOrig;
250
    Vec_Int_t * vAbsFfsToAdd, * vAbsFfsToAddBest;
251
    // check if flop classes are given
252
    if ( pGia->vFlopClasses == NULL )
253
    {
Alan Mishchenko committed
254
        Abc_Print( 0, "Initial flop map is not given. Trivial abstraction is assumed.\n" );
255
        pGia->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) );
256
    }
257
    // derive abstraction
258
    pAbs = Gia_ManDupAbsFlops( pGia, pGia->vFlopClasses );
259 260
    pAig = Gia_ManToAigSimple( pAbs );
    Gia_ManStop( pAbs );
261 262 263
    // refine abstraction using CBA
    vAbsFfsToAdd = Saig_ManCbaPerform( pAig, Gia_ManPiNum(pGia), p );
    if ( vAbsFfsToAdd == NULL ) // found true CEX
264
    {
265 266 267 268 269 270 271 272 273
        assert( pAig->pSeqModel != NULL );
        printf( "Refinement did not happen. Discovered a true counter-example.\n" );
        printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManPiNum(pAig), Gia_ManPiNum(pGia) );
        // derive new counter-example
        pOrig = Gia_ManToAigSimple( pGia );
        pGia->pCexSeq = Saig_ManCexRemap( pOrig, pAig, pAig->pSeqModel );
        Aig_ManStop( pOrig );
        Aig_ManStop( pAig );
        return 0;
274
    }
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    // select the most useful flops among those to be added
    if ( p->nFfToAddMax > 0 && Vec_IntSize(vAbsFfsToAdd) > p->nFfToAddMax )
    {
        // compute new flops
        Aig_Man_t * pAigBig = Gia_ManToAigSimple( pGia );
        vAbsFfsToAddBest = Saig_ManCbaFilterFlops( pAigBig, pAig->pSeqModel, pGia->vFlopClasses, vAbsFfsToAdd, p->nFfToAddMax );
        Aig_ManStop( pAigBig );
        assert( Vec_IntSize(vAbsFfsToAddBest) == p->nFfToAddMax );
        if ( p->fVerbose )
            printf( "Filtering flops based on cost (%d -> %d).\n", Vec_IntSize(vAbsFfsToAdd), Vec_IntSize(vAbsFfsToAddBest) );
        // update
        Vec_IntFree( vAbsFfsToAdd );
        vAbsFfsToAdd = vAbsFfsToAddBest;

    }
290 291 292 293 294
    Aig_ManStop( pAig );
    // update flop classes
    Gia_ManFlopsAddToClasses( pGia->vFlopClasses, vAbsFfsToAdd );
    Vec_IntFree( vAbsFfsToAdd );
    return -1;
295 296
}

Alan Mishchenko committed
297 298 299 300 301 302 303 304 305 306 307
/**Function*************************************************************

  Synopsis    [Derive unrolled timeframes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
308
int Gia_ManPbaPerform( Gia_Man_t * pGia, int nStart, int nFrames, int nConfLimit, int nTimeLimit, int fVerbose, int * piFrame )
Alan Mishchenko committed
309 310 311 312
{
    Gia_Man_t * pAbs;
    Aig_Man_t * pAig, * pOrig;
    Vec_Int_t * vFlops, * vFlopsNew, * vSelected;
Alan Mishchenko committed
313
    int RetValue;
Alan Mishchenko committed
314 315 316 317 318 319
    if ( pGia->vFlopClasses == NULL )
    {
        printf( "Gia_ManPbaPerform(): Abstraction flop map is missing.\n" );
        return 0;
    }
    // derive abstraction
320
    pAbs = Gia_ManDupAbsFlops( pGia, pGia->vFlopClasses );
Alan Mishchenko committed
321 322 323
    // refine abstraction using PBA
    pAig = Gia_ManToAigSimple( pAbs );
    Gia_ManStop( pAbs );
324
    vFlopsNew = Saig_ManPbaDerive( pAig, Gia_ManPiNum(pGia), nStart, nFrames, nConfLimit, nTimeLimit, fVerbose, piFrame );
Alan Mishchenko committed
325 326 327
    // derive new classes
    if ( pAig->pSeqModel == NULL )
    {
Alan Mishchenko committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341
        // check if there is no timeout
        if ( vFlopsNew != NULL )
        {
            // the problem is UNSAT
            vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses );
            vSelected = Gia_ManFlopsSelect( vFlops, vFlopsNew );
            Vec_IntFree( pGia->vFlopClasses );
            pGia->vFlopClasses = Saig_ManFlops2Classes( Gia_ManRegNum(pGia), vSelected );
            Vec_IntFree( vSelected );

            Vec_IntFree( vFlopsNew );
            Vec_IntFree( vFlops );
        }
        RetValue = -1;
Alan Mishchenko committed
342 343 344 345 346 347 348 349 350 351 352
    }
    else if ( vFlopsNew == NULL )
    {
        // found real counter-example
        assert( pAig->pSeqModel != NULL );
        printf( "Refinement did not happen. Discovered a true counter-example.\n" );
        printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManPiNum(pAig), Gia_ManPiNum(pGia) );
        // derive new counter-example
        pOrig = Gia_ManToAigSimple( pGia );
        pGia->pCexSeq = Saig_ManCexRemap( pOrig, pAig, pAig->pSeqModel );
        Aig_ManStop( pOrig );
Alan Mishchenko committed
353
        RetValue = 0;
Alan Mishchenko committed
354 355 356 357 358 359 360 361
    }
    else
    {
        // found counter-eample for the abstracted model
        // update flop classes
        Vec_Int_t * vAbsFfsToAdd = vFlopsNew;
        Gia_ManFlopsAddToClasses( pGia->vFlopClasses, vAbsFfsToAdd );
        Vec_IntFree( vAbsFfsToAdd );
Alan Mishchenko committed
362
        RetValue = -1;
Alan Mishchenko committed
363
    }
Alan Mishchenko committed
364 365
    Aig_ManStop( pAig );
    return RetValue;
Alan Mishchenko committed
366
}
367 368


Alan Mishchenko committed
369 370 371 372 373 374 375 376 377 378 379
/**Function*************************************************************

  Synopsis    [Derive unrolled timeframes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
380
int Gia_ManGlaCbaPerform( Gia_Man_t * pGia, void * pPars, int fNaiveCnf )
Alan Mishchenko committed
381
{
382
    extern Vec_Int_t * Aig_Gla1ManTest( Aig_Man_t * pAig, Vec_Int_t * vGateClassesOld, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fNaiveCnf, int fVerbose );
Alan Mishchenko committed
383
    Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars;
384
    Vec_Int_t * vGateClasses, * vGateClassesOld = NULL;
Alan Mishchenko committed
385
    Aig_Man_t * pAig;
386

Alan Mishchenko committed
387 388
    // check if flop classes are given
    if ( pGia->vGateClasses == NULL )
389 390
        Abc_Print( 0, "Initial gate map is not given. Abstraction begins from scratch.\n" );
    else
Alan Mishchenko committed
391
    {
392 393 394
        Abc_Print( 0, "Initial gate map is given. Abstraction refines this map.\n" );
        vGateClassesOld = pGia->vGateClasses; pGia->vGateClasses = NULL;
        fNaiveCnf = 1;
Alan Mishchenko committed
395
    }
396

Alan Mishchenko committed
397 398
    // perform abstraction
    pAig = Gia_ManToAigSimple( pGia );
399 400
    assert( vGateClassesOld == NULL || Vec_IntSize(vGateClassesOld) == Aig_ManObjNumMax(pAig) );
    vGateClasses = Aig_Gla1ManTest( pAig, vGateClassesOld, p->nStart, p->nFramesMax, p->nConfLimit, p->nTimeOut, fNaiveCnf, p->fVerbose );
401 402 403
    Aig_ManStop( pAig );

    // update the map
404
    Vec_IntFreeP( &vGateClassesOld );
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
    pGia->vGateClasses = vGateClasses;
    return 1;
}

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

  Synopsis    [Derive unrolled timeframes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Gia_ManGlaPbaPerform( Gia_Man_t * pGia, void * pPars )
{
422
    extern Vec_Int_t * Aig_Gla2ManTest( Aig_Man_t * pAig, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fVerbose );
423 424 425
    Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars;
    Vec_Int_t * vGateClasses;
    Aig_Man_t * pAig;
426

427 428 429
    // check if flop classes are given
    if ( pGia->vGateClasses == NULL )
    {
430 431
        Abc_Print( 0, "Initial gate map is not given. Abstraction begins from scratch.\n" );
        pAig = Gia_ManToAigSimple( pGia );
432
    }
433 434 435 436 437 438 439 440 441
    else
    {
        Gia_Man_t * pGiaAbs;
        Abc_Print( 0, "Initial gate map is given. Abstraction refines this map.\n" );
        pGiaAbs = Gia_ManDupAbsGates( pGia, pGia->vGateClasses );
        pAig = Gia_ManToAigSimple( pGiaAbs );
        Gia_ManStop( pGiaAbs );
    }

442
    // perform abstraction
443
    vGateClasses = Aig_Gla2ManTest( pAig, p->nStart, p->nFramesMax, p->nConfLimit, p->nTimeOut, p->fVerbose );
Alan Mishchenko committed
444 445
    Aig_ManStop( pAig );

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
    // update the BMC depth
    if ( vGateClasses )
        p->iFrame = p->nFramesMax;

    // update the abstraction map (hint: AIG and GIA have one-to-one obj ID match)
    if ( pGia->vGateClasses && vGateClasses )
    {
        Gia_Obj_t * pObj;
        int i, Counter = 0;
        Gia_ManForEachObj1( pGia, pObj, i )
        {
            if ( !~pObj->Value )
                continue;
            if ( !Vec_IntEntry(pGia->vGateClasses, i) )
                continue;
            // this obj was abstracted before
            assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(pGia, pObj) );
            // if corresponding AIG object is not abstracted, remove abstraction
            if ( !Vec_IntEntry(vGateClasses, Gia_Lit2Var(pObj->Value)) )
            {
                Vec_IntWriteEntry( pGia->vGateClasses, i, 0 );
                Counter++;
            }
        }
        Vec_IntFree( vGateClasses );
        if ( p->fVerbose )
            Abc_Print( 1, "Repetition of abstraction removed %d entries from the old abstraction map.\n", Counter );
    }
    else
    {
        Vec_IntFreeP( &pGia->vGateClasses );
        pGia->vGateClasses = vGateClasses;
    }
Alan Mishchenko committed
479 480 481
    return 1;
}

482 483 484 485 486 487 488
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END