diff options
-rw-r--r-- | src/aig/gia/giaSatEdge.c | 44 | ||||
-rw-r--r-- | src/base/abci/abc.c | 20 |
2 files changed, 48 insertions, 16 deletions
diff --git a/src/aig/gia/giaSatEdge.c b/src/aig/gia/giaSatEdge.c index 02b442f7..13446414 100644 --- a/src/aig/gia/giaSatEdge.c +++ b/src/aig/gia/giaSatEdge.c @@ -48,6 +48,7 @@ struct Seg_Man_t_ // window Gia_Man_t * pGia; Vec_Int_t * vPolars; // polarity + Vec_Int_t * vToSkip; // edges to skip Vec_Int_t * vEdges; // edges as fanin/fanout pairs Vec_Int_t * vFirsts; // first SAT variable Vec_Int_t * vNvars; // number of SAT variables @@ -75,20 +76,27 @@ extern sat_solver * Sbm_AddCardinSolver( int LogN, Vec_Int_t ** pvVars ); SeeAlso [] ***********************************************************************/ -Vec_Int_t * Seg_ManCountIntEdges( Gia_Man_t * p, Vec_Int_t * vPolars ) +Vec_Int_t * Seg_ManCountIntEdges( Gia_Man_t * p, Vec_Int_t * vPolars, Vec_Int_t * vToSkip, int nFanouts ) { int i, iLut, iFanin; Vec_Int_t * vEdges = Vec_IntAlloc( 1000 ); assert( Gia_ManHasMapping(p) ); Vec_IntClear( vPolars ); + Vec_IntClear( vToSkip ); + if ( nFanouts ) + Gia_ManSetLutRefs( p ); Gia_ManForEachLut( p, iLut ) Gia_LutForEachFanin( p, iLut, iFanin, i ) if ( Gia_ObjIsAnd(Gia_ManObj(p, iFanin)) ) { if ( p->vEdge1 && Gia_ObjCheckEdge(p, iFanin, iLut) ) Vec_IntPush( vPolars, Vec_IntSize(vEdges)/2 ); + if ( nFanouts && Gia_ObjLutRefNumId(p, iFanin) >= nFanouts ) + Vec_IntPush( vToSkip, Vec_IntSize(vEdges)/2 ); Vec_IntPushTwo( vEdges, iFanin, iLut ); } + if ( nFanouts ) + ABC_FREE( p->pLutRefs ); return vEdges; } Vec_Wec_t * Seg_ManCollectObjEdges( Vec_Int_t * vEdges, int nObjs ) @@ -144,12 +152,13 @@ int Seg_ManCountIntLevels( Seg_Man_t * p, int iStartVar ) SeeAlso [] ***********************************************************************/ -Seg_Man_t * Seg_ManAlloc( Gia_Man_t * pGia ) +Seg_Man_t * Seg_ManAlloc( Gia_Man_t * pGia, int nFanouts ) { int nVarsAll; Seg_Man_t * p = ABC_CALLOC( Seg_Man_t, 1 ); p->vPolars = Vec_IntAlloc( 1000 ); - p->vEdges = Seg_ManCountIntEdges( pGia, p->vPolars ); + p->vToSkip = Vec_IntAlloc( 1000 ); + p->vEdges = Seg_ManCountIntEdges( pGia, p->vPolars, p->vToSkip, nFanouts ); p->nVars = Vec_IntSize(p->vEdges)/2; p->LogN = Abc_Base2Log(p->nVars); p->Power2 = 1 << p->LogN; @@ -180,6 +189,7 @@ void Seg_ManClean( Seg_Man_t * p ) Vec_IntClear( p->vNvars ); Vec_IntClear( p->vLits ); Vec_IntClear( p->vPolars ); + Vec_IntClear( p->vToSkip ); // other Gia_ManFillValue( p->pGia ); } @@ -193,6 +203,7 @@ void Seg_ManStop( Seg_Man_t * p ) Vec_IntFree( p->vNvars ); Vec_IntFree( p->vLits ); Vec_IntFree( p->vPolars ); + Vec_IntFree( p->vToSkip ); ABC_FREE( p->pLevels ); // other ABC_FREE( p ); @@ -217,7 +228,7 @@ void Seg_ManCreateCnf( Seg_Man_t * p, int fTwo, int fVerbose ) Vec_Int_t * vLevel; int iLut, iFanin, iFirst; int pLits[3], Count = 0; - int i, k, nVars, value; + int i, k, nVars, Edge, value; abctime clk = Abc_Clock(); // edge delay constraints int nConstr = sat_solver_nclauses(p->pSat); @@ -380,6 +391,13 @@ void Seg_ManCreateCnf( Seg_Man_t * p, int fTwo, int fVerbose ) } } Vec_WecFree( vObjEdges ); + // block forbidden edges + Vec_IntForEachEntry( p->vToSkip, Edge, i ) + { + pLits[0] = Abc_Var2Lit( Edge, 1 ); + value = sat_solver_addclause( p->pSat, pLits, pLits+1 ); + assert( value ); + } if ( fVerbose ) printf( "Edge constraints = %d. ", sat_solver_nclauses(p->pSat) - nConstr ); if ( fVerbose ) @@ -418,7 +436,7 @@ Vec_Int_t * Seg_ManConvertResult( Seg_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Seg_ManComputeDelay( Gia_Man_t * pGia, int DelayInit, int fTwo, int fVerbose ) +void Seg_ManComputeDelay( Gia_Man_t * pGia, int DelayInit, int nFanouts, int fTwo, int fVerbose ) { int nBTLimit = 0; int nTimeOut = 0; @@ -428,7 +446,7 @@ void Seg_ManComputeDelay( Gia_Man_t * pGia, int DelayInit, int fTwo, int fVerbos abctime clk = Abc_Clock(); Vec_Int_t * vEdges2 = NULL; int i, iLut, iFirst, nVars, status, Delay, nConfs; - Seg_Man_t * p = Seg_ManAlloc( pGia ); + Seg_Man_t * p = Seg_ManAlloc( pGia, nFanouts ); Vec_Int_t * vVars = Vec_IntStartNatural( p->nVars ); int DelayStart = DelayInit ? DelayInit : p->DelayMax; @@ -447,16 +465,20 @@ void Seg_ManComputeDelay( Gia_Man_t * pGia, int DelayInit, int fTwo, int fVerbos // increment delay gradually for ( Delay = p->DelayMax; Delay >= 0; Delay-- ) { + // we constrain COs, although it would be fine to constrain only POs Gia_ManForEachCoDriver( p->pGia, pObj, i ) { - if ( !Gia_ObjIsAnd(pObj) ) - continue; iLut = Gia_ObjId( p->pGia, pObj ); iFirst = Vec_IntEntry( p->vFirsts, iLut ); nVars = Vec_IntEntry( p->vNvars, iLut ); - if ( Delay < nVars ) - sat_solver_push( p->pSat, Abc_Var2Lit(iFirst + Delay, 1) ); - + if ( Delay < nVars && !sat_solver_push(p->pSat, Abc_Var2Lit(iFirst + Delay, 1)) ) + break; + } + if ( i < Gia_ManCoNum(p->pGia) ) + { + printf( "Proved UNSAT for delay %d. ", Delay ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + break; } if ( Delay > DelayStart ) continue; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c0052a74..f8935902 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -34858,11 +34858,11 @@ usage: int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Edg_ManAssignEdgeNew( Gia_Man_t * p, int nEdges, int fVerbose ); - extern void Seg_ManComputeDelay( Gia_Man_t * pGia, int Delay, int fTwo, int fVerbose ); + extern void Seg_ManComputeDelay( Gia_Man_t * pGia, int Delay, int nFanouts, int fTwo, int fVerbose ); - int c, DelayMax = 0, nEdges = 1, fReverse = 0, fUsePack = 0, fUseOld = 0, fVerbose = 0; + int c, DelayMax = 0, nFanouts = 0, nEdges = 1, fReverse = 0, fUsePack = 0, fUseOld = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "DErpovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "DFErpovh" ) ) != EOF ) { switch ( c ) { @@ -34875,6 +34875,15 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) DelayMax = atoi(argv[globalUtilOptind]); globalUtilOptind++; break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a positive integer.\n" ); + goto usage; + } + nFanouts = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; case 'E': if ( globalUtilOptind >= argc ) { @@ -34934,7 +34943,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !fUseOld ) { //Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose ); - Seg_ManComputeDelay( pAbc->pGia, DelayMax, nEdges==2, fVerbose ); + Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose ); return 0; } if ( pAbc->pGia->pManTime && fReverse ) @@ -34950,9 +34959,10 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &edge [-DE num] [-rpovh]\n" ); + Abc_Print( -2, "usage: &edge [-DFE num] [-rpovh]\n" ); Abc_Print( -2, "\t find edge assignment of the LUT-mapped network\n" ); Abc_Print( -2, "\t-D num : the upper bound on delay [default = %d]\n", DelayMax ); + Abc_Print( -2, "\t-F num : skip using edge if fanout higher than this [default = %d]\n", nFanouts ); Abc_Print( -2, "\t-E num : the limit on the number of edges (1 <= num <= 2) [default = %d]\n", nEdges ); Abc_Print( -2, "\t-r : toggles using reverse order [default = %s]\n", fReverse? "yes": "no" ); Abc_Print( -2, "\t-p : toggles deriving edges from packing [default = %s]\n", fUsePack? "yes": "no" ); |