bmcBmci.c 11.6 KB
Newer Older
1 2
/**CFile****************************************************************

3
  FileName    [bmcBmci.c]
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [SAT-based bounded model checking.]

  Synopsis    []

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

17
  Revision    [$Id: bmcBmci.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 19 20 21

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

#include "bmc.h"
22 23 24
#include "sat/cnf/cnf.h"
#include "sat/bsat/satStore.h"
#include "aig/gia/giaAig.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
48
static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p )
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
    Cnf_Dat_t * pCnf;
    Aig_Man_t * pAig = Gia_ManToAigSimple( p );
    pAig->nRegs = 0;
    pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
    Aig_ManStop( pAig );
    return pCnf;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline void Cnf_DataLiftGia( Cnf_Dat_t * p, Gia_Man_t * pGia, int nVarsPlus )
{
    Gia_Obj_t * pObj;
    int v;
    Gia_ManForEachObj( pGia, pObj, v )
        if ( p->pVarNums[Gia_ObjId(pGia, pObj)] >= 0 )
            p->pVarNums[Gia_ObjId(pGia, pObj)] += nVarsPlus;
    for ( v = 0; v < p->nLiterals; v++ )
        p->pClauses[0][v] += 2*nVarsPlus;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
91
void Bmc_BmciUnfold( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vFFLits, int fPiReuse )
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
{
    Gia_Obj_t * pObj;
    int i;
    assert( Gia_ManRegNum(p) == Vec_IntSize(vFFLits) );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManForEachRo( p, pObj, i )
        pObj->Value = Vec_IntEntry(vFFLits, i);
    Gia_ManForEachPi( p, pObj, i )
        pObj->Value = fPiReuse ? Gia_ObjToLit(pNew, Gia_ManPi(pNew, Gia_ManPiNum(pNew)-Gia_ManPiNum(p)+i)) : Gia_ManAppendCi(pNew);
    Gia_ManForEachAnd( p, pObj, i )
        pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    Gia_ManForEachRi( p, pObj, i )
        Vec_IntWriteEntry( vFFLits, i, Gia_ObjFanin0Copy(pObj) );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
118
int Bmc_BmciPart_rec( Gia_Man_t * pNew, Vec_Int_t * vSatMap, int iIdNew, Gia_Man_t * pPart, Vec_Int_t * vPartMap, Vec_Int_t * vCopies )
119 120
{
    Gia_Obj_t * pObj = Gia_ManObj( pNew, iIdNew ); 
121 122 123 124
    int iLitPart0, iLitPart1, iRes;
    if ( Vec_IntEntry(vCopies, iIdNew) )
        return Vec_IntEntry(vCopies, iIdNew);
    if ( Vec_IntEntry(vSatMap, iIdNew) >= 0 || Gia_ObjIsCi(pObj) )
125 126
    {
        Vec_IntPush( vPartMap, iIdNew );
127 128 129
        iRes = Gia_ManAppendCi(pPart);
        Vec_IntWriteEntry( vCopies, iIdNew, iRes );
        return iRes;
130
    }
131
    assert( Gia_ObjIsAnd(pObj) );
132 133
    iLitPart0 = Bmc_BmciPart_rec( pNew, vSatMap, Gia_ObjFaninId0(pObj, iIdNew), pPart, vPartMap, vCopies );
    iLitPart1 = Bmc_BmciPart_rec( pNew, vSatMap, Gia_ObjFaninId1(pObj, iIdNew), pPart, vPartMap, vCopies );
134 135 136
    iLitPart0 = Abc_LitNotCond( iLitPart0, Gia_ObjFaninC0(pObj) );
    iLitPart1 = Abc_LitNotCond( iLitPart1, Gia_ObjFaninC1(pObj) );
    Vec_IntPush( vPartMap, iIdNew );
137 138 139
    iRes = Gia_ManAppendAnd( pPart, iLitPart0, iLitPart1 );
    Vec_IntWriteEntry( vCopies, iIdNew, iRes );
    return iRes;
140
}
141
Gia_Man_t * Bmc_BmciPart( Gia_Man_t * pNew, Vec_Int_t * vSatMap, Vec_Int_t * vMiters, Vec_Int_t * vPartMap, Vec_Int_t * vCopies )
142 143 144
{
    Gia_Man_t * pPart;
    int i, iLit, iLitPart;
145
    Vec_IntFill( vCopies, Gia_ManObjNum(pNew), 0 );
146 147 148 149
    Vec_IntFillExtra( vSatMap, Gia_ManObjNum(pNew), -1 );
    pPart = Gia_ManStart( 1000 );
    pPart->pName = Abc_UtilStrsav( pNew->pName );
    Vec_IntClear( vPartMap );
150
    Vec_IntPush( vPartMap, 0 );
151 152 153 154
    Vec_IntForEachEntry( vMiters, iLit, i )
    {
        if ( iLit == -1 )
            continue;
155
        assert( iLit >= 2 );
156
        iLitPart = Bmc_BmciPart_rec( pNew, vSatMap, Abc_Lit2Var(iLit), pPart, vPartMap, vCopies );
157
        Gia_ManAppendCo( pPart, Abc_LitNotCond(iLitPart, Abc_LitIsCompl(iLit)) );
158
        Vec_IntPush( vPartMap, -1 );
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
    }
    assert( Gia_ManPoNum(pPart) > 0 );
    assert( Vec_IntSize(vPartMap) == Gia_ManObjNum(pPart) );
    return pPart;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
176
int Bmc_BmciPerform( Gia_Man_t * p, Vec_Int_t * vInit0, Vec_Int_t * vInit1, int nFrames, int nWords, int nTimeOut, int fVerbose )
177 178
{
    int nSatVars = 1;
179
    Vec_Int_t * vLits0, * vLits1, * vMiters, * vSatMap, * vPartMap, * vCopies;
180 181 182 183
    Gia_Man_t * pNew, * pPart;
    Gia_Obj_t * pObj;
    Cnf_Dat_t * pCnf;
    sat_solver * pSat;
184 185
    int iVar0, iVar1, iLit, iLit0, iLit1;
    int i, f, status, nChanges, nMiters, RetValue = 1;
186 187
    assert( Vec_IntSize(vInit0) == Gia_ManRegNum(p) );
    assert( Vec_IntSize(vInit1) == Gia_ManRegNum(p) );
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

    // start the SAT solver
    pSat = sat_solver_new();
    sat_solver_set_runtime_limit( pSat, nTimeOut ? nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0 );

    pNew = Gia_ManStart( 10000 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    Gia_ManHashAlloc( pNew );
    Gia_ManConst0(p)->Value = 0;

    vLits0 = Vec_IntAlloc( Gia_ManRegNum(p) );
    Vec_IntForEachEntry( vInit0, iLit, i )
        Vec_IntPush( vLits0, iLit < 2 ? iLit : Gia_ManAppendCi(pNew) );

    vLits1 = Vec_IntAlloc( Gia_ManRegNum(p) );
    Vec_IntForEachEntry( vInit1, iLit, i )
        Vec_IntPush( vLits1, iLit < 2 ? iLit : Gia_ManAppendCi(pNew) );

    vMiters  = Vec_IntAlloc( 1000 );
    vSatMap  = Vec_IntAlloc( 1000 );
    vPartMap = Vec_IntAlloc( 1000 );
209
    vCopies  = Vec_IntAlloc( 1000 );
210 211
    for ( f = 0; f < nFrames; f++ )
    {
212
        abctime clk = Abc_Clock();
213 214
        Bmc_BmciUnfold( pNew, p, vLits0, 0 );
        Bmc_BmciUnfold( pNew, p, vLits1, 1 );
215
        assert( Vec_IntSize(vLits0) == Vec_IntSize(vLits1) );
216
        nMiters  = 0;
217 218
        Vec_IntClear( vMiters );
        Vec_IntForEachEntryTwo( vLits0, vLits1, iLit0, iLit1, i )
219 220
            if ( (iLit0 >= 2 || iLit1 >= 2) && iLit0 != iLit1 )
                Vec_IntPush( vMiters, Gia_ManHashXor(pNew, iLit0, iLit1) ), nMiters++;
221 222
            else
                Vec_IntPush( vMiters, -1 );
223
        assert( Vec_IntSize(vMiters) == Gia_ManRegNum(p) );
224
        if ( Vec_IntSum(vMiters) + Vec_IntSize(vLits1) == 0 )
225 226
        {
            if ( fVerbose )
227 228
                printf( "Reached a fixed point after %d frames.  \n", f+1 );
            break;
229
        }
230
        // create new part
231
        pPart = Bmc_BmciPart( pNew, vSatMap, vMiters, vPartMap, vCopies );
232 233 234 235 236 237 238 239 240 241
        pCnf = Cnf_DeriveGiaRemapped( pPart );
        Cnf_DataLiftGia( pCnf, pPart, nSatVars );
        nSatVars += pCnf->nVars;
        sat_solver_setnvars( pSat, nSatVars );
        for ( i = 0; i < pCnf->nClauses; i++ )
            if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
                assert( 0 );
        // stitch the clauses
        Gia_ManForEachPi( pPart, pObj, i )
        {
242 243
            iVar0 = pCnf->pVarNums[Gia_ObjId(pPart, pObj)];
            iVar1 = Vec_IntEntry( vSatMap, Vec_IntEntry(vPartMap, Gia_ObjId(pPart, pObj)) );
244 245 246 247 248
            if ( iVar1 == -1 )
                continue;
            sat_solver_add_buffer( pSat, iVar0, iVar1, 0 );
        }
        // transfer variables
249
        Gia_ManForEachCand( pPart, pObj, i )
250
            if ( pCnf->pVarNums[i] >= 0 )
251 252
            {
                assert( Gia_ObjIsCi(pObj) || Vec_IntEntry( vSatMap, Vec_IntEntry(vPartMap, i) ) == -1 );
253
                Vec_IntWriteEntry( vSatMap, Vec_IntEntry(vPartMap, i), pCnf->pVarNums[i] );
254
            }
255 256 257
        Cnf_DataFree( pCnf );
        Gia_ManStop( pPart );
        // perform runs
258
        nChanges = 0;
259 260 261 262
        Vec_IntForEachEntry( vMiters, iLit, i )
        {
            if ( iLit == -1 )
                continue;
263 264
            assert( Vec_IntEntry(vSatMap, Abc_Lit2Var(iLit)) > 0 );
            iLit = Abc_Lit2LitV( Vec_IntArray(vSatMap), iLit );
265 266
            status = sat_solver_solve( pSat, &iLit, &iLit + 1, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
            if ( status == l_True )
267 268
            {
                nChanges++;
269
                continue;
270
            }
271 272 273 274 275 276 277 278 279
            if ( status == l_Undef )
            {
                printf( "Timeout reached after %d seconds.  \n", nTimeOut );
                RetValue = 0;
                goto cleanup;
            }
            assert( status == l_False );
            iLit0 = Vec_IntEntry( vLits0, i );
            iLit1 = Vec_IntEntry( vLits1, i );
280 281
            assert( (iLit0 >= 2 || iLit1 >= 2) && iLit0 != iLit1 );
            if ( iLit1 >= 2 )
282 283 284 285 286 287 288
                Vec_IntWriteEntry( vLits1, i, iLit0 );
            else
                Vec_IntWriteEntry( vLits0, i, iLit1 );
            iLit0 = Vec_IntEntry( vLits0, i );
            iLit1 = Vec_IntEntry( vLits1, i );
            assert( iLit0 == iLit1 );
        }
289 290
        if ( fVerbose )
        {
291
            printf( "Frame %4d : ",     f+1 );
292 293 294 295 296 297 298 299 300
            printf( "Vars =%7d  ",      nSatVars );
            printf( "Clause =%10d  ",   sat_solver_nclauses(pSat) );
            printf( "Conflict =%10d  ", sat_solver_nconflicts(pSat) );
            printf( "AIG =%7d  ",       Gia_ManAndNum(pNew) );
            printf( "Miters =%5d  ",    nMiters );
            printf( "SAT =%5d  ",       nChanges );
            Abc_PrintTime( 1, "Time",   Abc_Clock() - clk );
        }
        if ( nChanges == 0 )
301 302 303 304 305 306 307 308 309 310 311 312 313 314
        {
            printf( "Reached a fixed point after %d frames.  \n", f+1 );
            break;
        }
    }
cleanup:

    sat_solver_delete( pSat );
    Gia_ManStopP( &pNew );
    Vec_IntFree( vLits0 );
    Vec_IntFree( vLits1 );
    Vec_IntFree( vMiters );
    Vec_IntFree( vSatMap );
    Vec_IntFree( vPartMap );
315
    Vec_IntFree( vCopies );
316
    return RetValue;
317 318 319 320 321 322 323 324 325 326 327 328 329
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
330
int Gia_ManBmciTest( Gia_Man_t * p, Vec_Int_t * vInit, int nFrames, int nWords, int nTimeOut, int fSim, int fVerbose )
331
{
332
    Vec_Int_t * vInit0 = Vec_IntStart( Gia_ManRegNum(p) );
333
    Bmc_BmciPerform( p, vInit, vInit0, nFrames, nWords, nTimeOut, fVerbose );
334
    Vec_IntFree( vInit0 );
335
    return 1;
336 337 338 339 340 341 342 343 344
}

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


ABC_NAMESPACE_IMPL_END