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

  FileName    [sswLcorr.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Inductive prover with constraints.]

  Synopsis    [Latch correspondence.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - September 1, 2008.]

  Revision    [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]

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

#include "sswInt.h"
Alan Mishchenko committed
22
//#include "bar.h"
Alan Mishchenko committed
23

24 25 26
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
27 28 29 30 31 32 33 34 35 36
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

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

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

Alan Mishchenko committed
37
  Synopsis    [Tranfers simulation information from FRAIG to AIG.]
Alan Mishchenko committed
38 39 40 41 42 43 44 45

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
46
void Ssw_ManSweepTransfer( Ssw_Man_t * p )
Alan Mishchenko committed
47
{
Alan Mishchenko committed
48 49
    Aig_Obj_t * pObj, * pObjFraig;
    unsigned * pInfo;
Alan Mishchenko committed
50
    int i;
Alan Mishchenko committed
51
    // transfer simulation information
52
    Aig_ManForEachCi( p->pAig, pObj, i )
Alan Mishchenko committed
53 54 55 56 57 58 59 60
    {
        pObjFraig = Ssw_ObjFrame( p, pObj, 0 );
        if ( pObjFraig == Aig_ManConst0(p->pFrames) )
        {
            Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 );
            continue;
        }
        assert( !Aig_IsComplement(pObjFraig) );
61
        assert( Aig_ObjIsCi(pObjFraig) );
62
        pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjCioId(pObjFraig) );
Alan Mishchenko committed
63 64
        Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 );
    }
Alan Mishchenko committed
65 66 67 68
}

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

Alan Mishchenko committed
69
  Synopsis    [Performs one round of simulation with counter-examples.]
Alan Mishchenko committed
70 71 72 73 74 75 76 77

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
78 79
int Ssw_ManSweepResimulate( Ssw_Man_t * p )
{
80 81
    int RetValue1, RetValue2;
    clock_t clk = clock();
Alan Mishchenko committed
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
    // transfer PI simulation information from storage
    Ssw_ManSweepTransfer( p );
    // simulate internal nodes
    Ssw_SmlSimulateOneFrame( p->pSml );
    // check equivalence classes
    RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
    RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
    // prepare simulation info for the next round
    Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
    p->nPatterns = 0;
    p->nSimRounds++;
p->timeSimSat += clock() - clk;
    return RetValue1 > 0 || RetValue2 > 0;
}

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

  Synopsis    [Saves one counter-example into internal storage.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand )
Alan Mishchenko committed
109 110
{
    Aig_Obj_t * pObj;
Alan Mishchenko committed
111 112
    unsigned * pInfo;
    int i, nVarNum, Value;
113
    Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i )
Alan Mishchenko committed
114
    {
Alan Mishchenko committed
115
        nVarNum = Ssw_ObjSatNum( p->pMSat, pObj );
Alan Mishchenko committed
116
        assert( nVarNum > 0 );
Alan Mishchenko committed
117
        Value = sat_solver_var_value( p->pMSat->pSat, nVarNum );
Alan Mishchenko committed
118 119
        if ( Value == 0 )
            continue;
120
        pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjCioId(pObj) );
121
        Abc_InfoSetBit( pInfo, p->nPatterns );
Alan Mishchenko committed
122
    }
Alan Mishchenko committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
}

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

  Synopsis    [Builds fraiged logic cone of the node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj )
{
    Aig_Obj_t * pObjNew;
    assert( !Aig_IsComplement(pObj) );
Alan Mishchenko committed
140
    if ( Ssw_ObjFrame( p, pObj, 0 ) )
Alan Mishchenko committed
141 142 143 144 145
        return;
    assert( Aig_ObjIsNode(pObj) );
    Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) );
    Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) );
    pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
Alan Mishchenko committed
146
    Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
Alan Mishchenko committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
}

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

  Synopsis    [Recycles the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj )
{
Alan Mishchenko committed
162
    Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi;
163 164
    int RetValue;
    clock_t clk;
165 166
    assert( Aig_ObjIsCi(pObj) );
    assert( Aig_ObjIsCi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) );
Alan Mishchenko committed
167 168 169 170 171 172 173 174
    // check if it makes sense to skip some calls
    if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat )
    {
        if ( ++p->nCallsDelta < 0 )
            return;
    }
    p->nCallsDelta = 0;
clk = clock();
Alan Mishchenko committed
175 176 177 178 179
    // get the fraiged node
    pObjLi = Saig_ObjLoToLi( p->pAig, pObj ); 
    Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
    pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
    // get the fraiged representative
180
    if ( Aig_ObjIsCi(pObjRepr) )
Alan Mishchenko committed
181 182 183 184 185 186
    {
        pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr ); 
        Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
        pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
    }
    else 
Alan Mishchenko committed
187 188
        pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 );
p->timeReduce += clock() - clk;
Alan Mishchenko committed
189 190 191
    // if the fraiged nodes are the same, return
    if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
        return;
Alan Mishchenko committed
192 193 194
    p->nRecycleCalls++;
    p->nCallsCount++;

Alan Mishchenko committed
195 196 197
    // check equivalence of the two nodes
    if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
    {
Alan Mishchenko committed
198
        p->nPatterns++;
Alan Mishchenko committed
199
        p->nStrangers++;
Alan Mishchenko committed
200
        p->fRefined = 1;
Alan Mishchenko committed
201 202 203 204
    }
    else
    { 
        RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
Alan Mishchenko committed
205
        if ( RetValue == 1 )  // proved equivalence
Alan Mishchenko committed
206
        {
Alan Mishchenko committed
207
            p->nCallsUnsat++;
Alan Mishchenko committed
208 209
            return;
        }
Alan Mishchenko committed
210
        if ( RetValue == -1 ) // timed out
Alan Mishchenko committed
211 212
        {
            Ssw_ClassesRemoveNode( p->ppClasses, pObj );
Alan Mishchenko committed
213
            p->nCallsUnsat++;
Alan Mishchenko committed
214 215 216
            p->fRefined = 1;
            return;
        }
Alan Mishchenko committed
217
        else // disproved equivalence
Alan Mishchenko committed
218
        {       
Alan Mishchenko committed
219 220 221 222
            Ssw_SmlAddPattern( p, pObjRepr, pObj );
            p->nPatterns++;
            p->nCallsSat++;
            p->fRefined = 1;
Alan Mishchenko committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
        }
    }
}

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

  Synopsis    [Performs one iteration of sweeping latches.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_ManSweepLatch( Ssw_Man_t * p )
{
Alan Mishchenko committed
240
//    Bar_Progress_t * pProgress = NULL;
Alan Mishchenko committed
241 242 243 244 245 246 247
    Vec_Ptr_t * vClass;
    Aig_Obj_t * pObj, * pRepr, * pTemp;
    int i, k;

    // start the timeframe
    p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
    // map constants and PIs
Alan Mishchenko committed
248
    Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) );
Alan Mishchenko committed
249
    Saig_ManForEachPi( p->pAig, pObj, i )
250
        Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreateCi(p->pFrames) );
Alan Mishchenko committed
251 252 253 254 255 256

    // implement equivalence classes
    Saig_ManForEachLo( p->pAig, pObj, i )
    {
        pRepr = Aig_ObjRepr( p->pAig, pObj );
        if ( pRepr == NULL )
Alan Mishchenko committed
257
        {
258
            pTemp = Aig_ObjCreateCi(p->pFrames);
Alan Mishchenko committed
259 260
            pTemp->pData = pObj;
        }
Alan Mishchenko committed
261
        else
Alan Mishchenko committed
262 263
            pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase );
        Ssw_ObjSetFrame( p, pObj, 0, pTemp );
Alan Mishchenko committed
264
    }
265
    Aig_ManSetCioIds( p->pFrames );
Alan Mishchenko committed
266 267 268

    // prepare simulation info
    assert( p->vSimInfo == NULL );
269
    p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManCiNum(p->pFrames), 1 );
Alan Mishchenko committed
270
    Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
Alan Mishchenko committed
271 272

    // go through the registers
Alan Mishchenko committed
273 274
//    if ( p->pPars->fVerbose )
//        pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) );
Alan Mishchenko committed
275 276
    vClass = Vec_PtrAlloc( 100 );
    p->fRefined = 0;
Alan Mishchenko committed
277
    p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0;
Alan Mishchenko committed
278 279
    Saig_ManForEachLo( p->pAig, pObj, i )
    {
Alan Mishchenko committed
280 281
//        if ( p->pPars->fVerbose )
//            Bar_ProgressUpdate( pProgress, i, NULL );
Alan Mishchenko committed
282 283 284 285 286 287 288 289 290 291
        // consider the case of constant candidate
        if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
            Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj );
        else
        {
            // consider the case of equivalence class
            Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass );
            if ( Vec_PtrSize(vClass) == 0 )
                continue;
            // try to prove equivalences in this class
292
            Vec_PtrForEachEntry( Aig_Obj_t *, vClass, pTemp, k )
Alan Mishchenko committed
293
                if ( Aig_ObjRepr(p->pAig, pTemp) == pObj )
Alan Mishchenko committed
294
                {
Alan Mishchenko committed
295
                    Ssw_ManSweepLatchOne( p, pObj, pTemp );
Alan Mishchenko committed
296 297 298
                    if ( p->nPatterns == 32 )
                        break;
                }
Alan Mishchenko committed
299
        }
Alan Mishchenko committed
300 301 302
        // resimulate
        if ( p->nPatterns == 32 )
            Ssw_ManSweepResimulate( p );
Alan Mishchenko committed
303 304
        // attempt recycling the SAT solver
        if ( p->pPars->nSatVarMax && 
Alan Mishchenko committed
305
             p->pMSat->nSatVars > p->pPars->nSatVarMax &&
Alan Mishchenko committed
306
             p->nRecycleCalls > p->pPars->nRecycleCalls )
Alan Mishchenko committed
307
        {
308 309
            p->nVarsMax  = Abc_MaxInt( p->nVarsMax,  p->pMSat->nSatVars );
            p->nCallsMax = Abc_MaxInt( p->nCallsMax, p->pMSat->nSolverCalls );
Alan Mishchenko committed
310 311 312 313 314
            Ssw_SatStop( p->pMSat );
            p->pMSat = Ssw_SatStart( 0 );
            p->nRecycles++;
            p->nRecycleCalls = 0;
        }
Alan Mishchenko committed
315
    }
Alan Mishchenko committed
316 317 318
//    ABC_PRT( "reduce", p->timeReduce );
//    Aig_TableProfile( p->pFrames );
//    printf( "And gates = %d\n", Aig_ManNodeNum(p->pFrames) );
Alan Mishchenko committed
319 320 321 322
    // resimulate
    if ( p->nPatterns > 0 )
        Ssw_ManSweepResimulate( p );
    // cleanup
Alan Mishchenko committed
323
    Vec_PtrFree( vClass );
Alan Mishchenko committed
324 325
//    if ( p->pPars->fVerbose )
//        Bar_ProgressStop( pProgress );
Alan Mishchenko committed
326 327

    // cleanup
Alan Mishchenko committed
328
//    Ssw_ClassesCheck( p->ppClasses );
Alan Mishchenko committed
329 330 331 332 333 334 335 336
    return p->fRefined;
}

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


337 338
ABC_NAMESPACE_IMPL_END