giaFalse.c 9.51 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 22
/**CFile****************************************************************

  FileName    [giaFalse.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Scalable AIG package.]

  Synopsis    [Detection and elimination of false paths.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "gia.h"
#include "misc/vec/vecQue.h"
Alan Mishchenko committed
23
#include "misc/vec/vecWec.h"
Alan Mishchenko committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#include "sat/bsat/satStore.h"

ABC_NAMESPACE_IMPL_START


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

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

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

Alan Mishchenko committed
39
  Synopsis    [Reconstruct the AIG after detecting false paths.]
Alan Mishchenko committed
40 41 42 43 44 45 46 47

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
48
void Gia_ManFalseRebuildOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vHook, int fVerbose, int fVeryVerbose )
Alan Mishchenko committed
49
{
Alan Mishchenko committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    Gia_Obj_t * pObj, * pPrev = NULL; 
    int i, iObjValue, iPrevValue = -1;
    if ( fVerbose )
    {
        printf( "Eliminating path: " );
        Vec_IntPrint( vHook );
    }
    Gia_ManForEachObjVec( vHook, p, pObj, i )
    {
        if ( fVeryVerbose )
            Gia_ObjPrint( p, pObj );
        iObjValue = pObj->Value;
        pObj->Value = i ? Gia_ManHashAnd(pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj)) : 0;
        if ( pPrev )
            pPrev->Value = iPrevValue;
        iPrevValue = iObjValue;
        pPrev = pObj;
    }
}
Gia_Man_t * Gia_ManFalseRebuild( Gia_Man_t * p, Vec_Wec_t * vHooks, int fVerbose, int fVeryVerbose )
{
    Gia_Man_t * pNew, * pTemp;
Alan Mishchenko committed
72
    Gia_Obj_t * pObj;
Alan Mishchenko committed
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
    int i, Counter = 0;
    pNew = Gia_ManStart( 4 * Gia_ManObjNum(p) / 3 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManHashAlloc( pNew );
    Gia_ManForEachObj1( p, pObj, i )
    {
        if ( Gia_ObjIsAnd(pObj) )
        {
            if ( Vec_WecLevelSize(vHooks, i) > 0 )
            {
                if ( fVerbose )
                    printf( "Path %d : ", Counter++ );
                Gia_ManFalseRebuildOne( pNew, p, Vec_WecEntry(vHooks, i), fVerbose, fVeryVerbose );
            }
            else
                pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        }
        else if ( Gia_ObjIsCi(pObj) )
            pObj->Value = Gia_ManAppendCi( pNew );
        else if ( Gia_ObjIsCo(pObj) )
            pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    }
    Gia_ManHashStop( pNew );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    pNew = Gia_ManCleanup( pTemp = pNew );
    Gia_ManStop( pTemp );
    return pNew;
Alan Mishchenko committed
102 103 104 105 106 107 108 109 110 111 112 113 114
}

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

  Synopsis    [Derive critical path by following minimum slacks.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
115
void Gia_ManCollectPath_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPath )
Alan Mishchenko committed
116 117 118
{
    if ( Gia_ObjIsAnd(pObj) )
    {
Alan Mishchenko committed
119 120 121 122 123 124 125 126
        if ( Gia_ObjLevel(p, Gia_ObjFanin0(pObj)) > Gia_ObjLevel(p, Gia_ObjFanin1(pObj)) )
            Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath );
        else if ( Gia_ObjLevel(p, Gia_ObjFanin0(pObj)) < Gia_ObjLevel(p, Gia_ObjFanin1(pObj)) )
            Gia_ManCollectPath_rec( p, Gia_ObjFanin1(pObj), vPath );
//        else if ( rand() & 1 )
//            Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath );
        else
            Gia_ManCollectPath_rec( p, Gia_ObjFanin1(pObj), vPath );
Alan Mishchenko committed
127 128 129
    }
    Vec_IntPush( vPath, Gia_ObjId(p, pObj) );
}
Alan Mishchenko committed
130
Vec_Int_t * Gia_ManCollectPath( Gia_Man_t * p, Gia_Obj_t * pObj )
Alan Mishchenko committed
131 132
{
    Vec_Int_t * vPath = Vec_IntAlloc( p->nLevels );
Alan Mishchenko committed
133
    Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath );
Alan Mishchenko committed
134 135 136 137 138 139 140 141 142 143 144 145 146 147
    return vPath;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
148
void Gia_ManCheckFalseOne( Gia_Man_t * p, int iOut, int nTimeOut, Vec_Wec_t * vHooks, int fVerbose, int fVeryVerbose )
Alan Mishchenko committed
149 150
{
    sat_solver * pSat;
Alan Mishchenko committed
151 152
    Gia_Obj_t * pObj;
    Gia_Obj_t * pPivot = Gia_ManCo( p, iOut );
Alan Mishchenko committed
153
    Vec_Int_t * vLits = Vec_IntAlloc( p->nLevels );
Alan Mishchenko committed
154 155 156
    Vec_Int_t * vPath = Gia_ManCollectPath( p, pPivot );
    int nLits = 0, * pLits = NULL;
    int i, Shift[2], status;
Alan Mishchenko committed
157 158
    abctime clkStart = Abc_Clock();
    // collect objects and assign SAT variables
Alan Mishchenko committed
159
    int iFanin = Gia_ObjFaninId0p( p, pPivot );
Alan Mishchenko committed
160 161 162
    Vec_Int_t * vObjs = Gia_ManCollectNodesCis( p, &iFanin, 1 );
    Gia_ManForEachObjVec( vObjs, p, pObj, i )
        pObj->Value = Vec_IntSize(vObjs) - 1 - i;
Alan Mishchenko committed
163
    assert( Gia_ObjIsCo(pPivot) );
Alan Mishchenko committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    // create SAT solver
    pSat = sat_solver_new();
    sat_solver_set_runtime_limit( pSat, nTimeOut ? nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0 );
    sat_solver_setnvars( pSat, Vec_IntSize(vPath) + 2 * Vec_IntSize(vObjs) );
    Shift[0] = Vec_IntSize(vPath);
    Shift[1] = Vec_IntSize(vPath) + Vec_IntSize(vObjs);
    // add CNF for the path
    Gia_ManForEachObjVec( vPath, p, pObj, i )
    {
        sat_solver_add_xor( pSat, i, pObj->Value + Shift[0], pObj->Value + Shift[1], 0 );
        Vec_IntPush( vLits, Abc_Var2Lit(i, 0) );
    }
    // add CNF for the cone
    Gia_ManForEachObjVec( vObjs, p, pObj, i )
    {
        if ( !Gia_ObjIsAnd(pObj) )
            continue;
        sat_solver_add_and( pSat, pObj->Value + Shift[0], 
            Gia_ObjFanin0(pObj)->Value + Shift[0], Gia_ObjFanin1(pObj)->Value + Shift[0], 
183
            Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 ); 
Alan Mishchenko committed
184 185
        sat_solver_add_and( pSat, pObj->Value + Shift[1], 
            Gia_ObjFanin0(pObj)->Value + Shift[1], Gia_ObjFanin1(pObj)->Value + Shift[1], 
186
            Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 ); 
Alan Mishchenko committed
187 188 189
    }
    // call the SAT solver
    status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
190
    if ( status == l_False )
Alan Mishchenko committed
191
    {
Alan Mishchenko committed
192
        int iBeg, iEnd;
Alan Mishchenko committed
193
        nLits = sat_solver_final( pSat, &pLits );
Alan Mishchenko committed
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 225 226
        iBeg  = Abc_Lit2Var(pLits[nLits-1]);
        iEnd  = Abc_Lit2Var(pLits[0]);
        if ( iEnd - iBeg < 20 )
        {
            // check if nodes on the path are already used
            for ( i = iBeg; i <= iEnd; i++ )
                if ( Vec_WecLevelSize(vHooks, Vec_IntEntry(vPath, i)) > 0 )
                    break;
            if ( i > iEnd )
            {
                Vec_Int_t * vHook = Vec_WecEntry(vHooks, Vec_IntEntry(vPath, iEnd));
                for ( i = iBeg; i <= iEnd; i++ )
                    Vec_IntPush( vHook, Vec_IntEntry(vPath, i) );
            }
        }
    }
    if ( fVerbose )
    {
        printf( "PO %6d : Level = %3d  ", iOut, Gia_ObjLevel(p, pPivot) );
        if ( status == l_Undef )
            printf( "Timeout reached after %d seconds. ", nTimeOut );
        else if ( status == l_True )
            printf( "There is no false path. " );
        else
        {
            printf( "False path contains %d nodes (out of %d):  ", nLits, Vec_IntSize(vLits) );
            printf( "top = %d  ", Vec_IntEntry(vPath, Abc_Lit2Var(pLits[0])) );
            if ( fVeryVerbose )
                for ( i = 0; i < nLits; i++ )
                    printf( "%d ", Abc_Lit2Var(pLits[i]) );
            printf( "  " );
        }
        Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
Alan Mishchenko committed
227 228 229 230 231 232
    }
    sat_solver_delete( pSat );
    Vec_IntFree( vObjs );
    Vec_IntFree( vPath );
    Vec_IntFree( vLits );
}
Alan Mishchenko committed
233
Gia_Man_t * Gia_ManCheckFalse( Gia_Man_t * p, int nSlackMax, int nTimeOut, int fVerbose, int fVeryVerbose )
Alan Mishchenko committed
234
{
Alan Mishchenko committed
235 236
    Gia_Man_t * pNew;
    Vec_Wec_t * vHooks;
Alan Mishchenko committed
237 238 239 240
    Vec_Que_t * vPrio;
    Vec_Flt_t * vWeights;
    Gia_Obj_t * pObj;
    int i;
Alan Mishchenko committed
241 242
    srand( 111 );
    Gia_ManLevelNum( p );
Alan Mishchenko committed
243 244 245
    // create PO weights
    vWeights = Vec_FltAlloc( Gia_ManCoNum(p) );
    Gia_ManForEachCo( p, pObj, i )
Alan Mishchenko committed
246
        Vec_FltPush( vWeights, Gia_ObjLevel(p, pObj) );
Alan Mishchenko committed
247 248 249 250 251 252
    // put POs into the queue
    vPrio = Vec_QueAlloc( Gia_ManCoNum(p) );
    Vec_QueSetPriority( vPrio, Vec_FltArrayP(vWeights) );
    Gia_ManForEachCo( p, pObj, i )
        Vec_QuePush( vPrio, i );
    // work on each PO in the queue
Alan Mishchenko committed
253
    vHooks = Vec_WecStart( Gia_ManObjNum(p) );
Alan Mishchenko committed
254
    while ( Vec_QueTopPriority(vPrio) >= p->nLevels - nSlackMax )
Alan Mishchenko committed
255 256 257 258 259
        Gia_ManCheckFalseOne( p, Vec_QuePop(vPrio), nTimeOut, vHooks, fVerbose, fVeryVerbose );
    if ( fVerbose )
    printf( "Collected %d non-overlapping false paths.\n", Vec_WecSizeUsed(vHooks) );
    // reconstruct the AIG
    pNew = Gia_ManFalseRebuild( p, vHooks, fVerbose, fVeryVerbose );
Alan Mishchenko committed
260
    // cleanup
Alan Mishchenko committed
261
    Vec_WecFree( vHooks );
Alan Mishchenko committed
262 263
    Vec_FltFree( vWeights );
    Vec_QueFree( vPrio );
Alan Mishchenko committed
264
    return pNew;
Alan Mishchenko committed
265 266 267 268 269 270 271 272 273
}

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


ABC_NAMESPACE_IMPL_END