/**CFile**************************************************************** FileName [giaSatLut.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Scalable AIG package.] Synopsis [] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: giaSatLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "gia.h" #include "misc/tim/tim.h" #include "sat/bsat/satStore.h" #include "misc/util/utilNam.h" #include "map/scl/sclCon.h" #include "misc/vec/vecHsh.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Sbl_Man_t_ Sbl_Man_t; struct Sbl_Man_t_ { sat_solver * pSat; // SAT solver Vec_Int_t * vCardVars; // candinality variables int nVars; // max vars int LogN; // base-2 log of max vars int Power2; // power-2 of LogN int FirstVar; // first variable to be used // statistics int nTried; // nodes tried int nImproved; // nodes improved int nRuns; // the number of runs int nHashWins; // the number of hashed windows int nSmallWins; // the number of small windows int nLargeWins; // the number of large windows int nIterOuts; // the number of iters exceeded // parameters int LutSize; // LUT size int nBTLimit; // conflicts int DelayMax; // external delay int nEdges; // the number of edges int fDelay; // delay mode int fReverse; // reverse windowing int fVerbose; // verbose int fVeryVerbose; // verbose int fVeryVeryVerbose; // verbose // window Gia_Man_t * pGia; Vec_Int_t * vLeaves; // leaf nodes Vec_Int_t * vAnds; // AND-gates Vec_Int_t * vNodes; // internal LUTs Vec_Int_t * vRoots; // driver nodes (a subset of vAnds) Vec_Int_t * vRootVars; // driver nodes (as SAT variables) Hsh_VecMan_t * pHash; // hash table for windows // timing Vec_Int_t * vArrs; // arrival times Vec_Int_t * vReqs; // required times Vec_Wec_t * vWindow; // fanins of each node in the window Vec_Int_t * vPath; // critical path (as SAT variables) Vec_Int_t * vEdges; // fanin edges // cuts Vec_Wrd_t * vCutsI1; // input bit patterns Vec_Wrd_t * vCutsI2; // input bit patterns Vec_Wrd_t * vCutsN1; // node bit patterns Vec_Wrd_t * vCutsN2; // node bit patterns Vec_Int_t * vCutsNum; // cut counts for each obj Vec_Int_t * vCutsStart; // starting cuts for each obj Vec_Int_t * vCutsObj; // object to which this cut belongs Vec_Wrd_t * vTempI1; // temporary cuts Vec_Wrd_t * vTempI2; // temporary cuts Vec_Wrd_t * vTempN1; // temporary cuts Vec_Wrd_t * vTempN2; // temporary cuts Vec_Int_t * vSolInit; // initial solution Vec_Int_t * vSolCur; // current solution Vec_Int_t * vSolBest; // best solution // temporary Vec_Int_t * vLits; // literals Vec_Int_t * vAssump; // literals Vec_Int_t * vPolar; // variables polarity // statistics abctime timeWin; // windowing abctime timeCut; // cut computation abctime timeSat; // SAT runtime abctime timeSatSat; // satisfiable time abctime timeSatUns; // unsatisfiable time abctime timeSatUnd; // undecided time abctime timeTime; // timing time abctime timeStart; // starting time abctime timeTotal; // all runtime abctime timeOther; // other time }; extern sat_solver * Sbm_AddCardinSolver( int LogN, Vec_Int_t ** pvVars ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Sbl_Man_t * Sbl_ManAlloc( Gia_Man_t * pGia, int Number ) { Sbl_Man_t * p = ABC_CALLOC( Sbl_Man_t, 1 ); p->nVars = Number; p->LogN = Abc_Base2Log(Number); p->Power2 = 1 << p->LogN; p->pSat = Sbm_AddCardinSolver( p->LogN, &p->vCardVars ); p->FirstVar = sat_solver_nvars( p->pSat ); sat_solver_bookmark( p->pSat ); // window p->pGia = pGia; p->vLeaves = Vec_IntAlloc( p->nVars ); p->vAnds = Vec_IntAlloc( p->nVars ); p->vNodes = Vec_IntAlloc( p->nVars ); p->vRoots = Vec_IntAlloc( p->nVars ); p->vRootVars = Vec_IntAlloc( p->nVars ); p->pHash = Hsh_VecManStart( 1000 ); // timing p->vArrs = Vec_IntAlloc( 0 ); p->vReqs = Vec_IntAlloc( 0 ); p->vWindow = Vec_WecAlloc( 128 ); p->vPath = Vec_IntAlloc( 32 ); p->vEdges = Vec_IntAlloc( 32 ); // cuts p->vCutsI1 = Vec_WrdAlloc( 1000 ); // input bit patterns p->vCutsI2 = Vec_WrdAlloc( 1000 ); // input bit patterns p->vCutsN1 = Vec_WrdAlloc( 1000 ); // node bit patterns p->vCutsN2 = Vec_WrdAlloc( 1000 ); // node bit patterns p->vCutsNum = Vec_IntAlloc( 64 ); // cut counts for each obj p->vCutsStart = Vec_IntAlloc( 64 ); // starting cuts for each obj p->vCutsObj = Vec_IntAlloc( 1000 ); p->vSolInit = Vec_IntAlloc( 64 ); p->vSolCur = Vec_IntAlloc( 64 ); p->vSolBest = Vec_IntAlloc( 64 ); p->vTempI1 = Vec_WrdAlloc( 32 ); p->vTempI2 = Vec_WrdAlloc( 32 ); p->vTempN1 = Vec_WrdAlloc( 32 ); p->vTempN2 = Vec_WrdAlloc( 32 ); // internal p->vLits = Vec_IntAlloc( 64 ); p->vAssump = Vec_IntAlloc( 64 ); p->vPolar = Vec_IntAlloc( 1000 ); // other Gia_ManFillValue( pGia ); return p; } void Sbl_ManClean( Sbl_Man_t * p ) { p->timeStart = Abc_Clock(); sat_solver_rollback( p->pSat ); sat_solver_bookmark( p->pSat ); // internal Vec_IntClear( p->vLeaves ); Vec_IntClear( p->vAnds ); Vec_IntClear( p->vNodes ); Vec_IntClear( p->vRoots ); Vec_IntClear( p->vRootVars ); // timing Vec_IntClear( p->vArrs ); Vec_IntClear( p->vReqs ); Vec_WecClear( p->vWindow ); Vec_IntClear( p->vPath ); Vec_IntClear( p->vEdges ); // cuts Vec_WrdClear( p->vCutsI1 ); Vec_WrdClear( p->vCutsI2 ); Vec_WrdClear( p->vCutsN1 ); Vec_WrdClear( p->vCutsN2 ); Vec_IntClear( p->vCutsNum ); Vec_IntClear( p->vCutsStart ); Vec_IntClear( p->vCutsObj ); Vec_IntClear( p->vSolInit ); Vec_IntClear( p->vSolCur ); Vec_IntClear( p->vSolBest ); Vec_WrdClear( p->vTempI1 ); Vec_WrdClear( p->vTempI2 ); Vec_WrdClear( p->vTempN1 ); Vec_WrdClear( p->vTempN2 ); // temporary Vec_IntClear( p->vLits ); Vec_IntClear( p->vAssump ); Vec_IntClear( p->vPolar ); // other Gia_ManFillValue( p->pGia ); } void Sbl_ManStop( Sbl_Man_t * p ) { sat_solver_delete( p->pSat ); Vec_IntFree( p->vCardVars ); // internal Vec_IntFree( p->vLeaves ); Vec_IntFree( p->vAnds ); Vec_IntFree( p->vNodes ); Vec_IntFree( p->vRoots ); Vec_IntFree( p->vRootVars ); Hsh_VecManStop( p->pHash ); // timing Vec_IntFree( p->vArrs ); Vec_IntFree( p->vReqs ); Vec_WecFree( p->vWindow ); Vec_IntFree( p->vPath ); Vec_IntFree( p->vEdges ); // cuts Vec_WrdFree( p->vCutsI1 ); Vec_WrdFree( p->vCutsI2 ); Vec_WrdFree( p->vCutsN1 ); Vec_WrdFree( p->vCutsN2 ); Vec_IntFree( p->vCutsNum ); Vec_IntFree( p->vCutsStart ); Vec_IntFree( p->vCutsObj ); Vec_IntFree( p->vSolInit ); Vec_IntFree( p->vSolCur ); Vec_IntFree( p->vSolBest ); Vec_WrdFree( p->vTempI1 ); Vec_WrdFree( p->vTempI2 ); Vec_WrdFree( p->vTempN1 ); Vec_WrdFree( p->vTempN2 ); // temporary Vec_IntFree( p->vLits ); Vec_IntFree( p->vAssump ); Vec_IntFree( p->vPolar ); // other ABC_FREE( p ); } /**Function************************************************************* Synopsis [For each node in the window, create fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sbl_ManGetCurrentMapping( Sbl_Man_t * p ) { Vec_Int_t * vObj; word CutI1, CutI2, CutN1, CutN2; int i, c, b, iObj; Vec_WecClear( p->vWindow ); Vec_WecInit( p->vWindow, Vec_IntSize(p->vAnds) ); assert( Vec_IntSize(p->vSolCur) > 0 ); Vec_IntForEachEntry( p->vSolCur, c, i ) { CutI1 = Vec_WrdEntry( p->vCutsI1, c ); CutI2 = Vec_WrdEntry( p->vCutsI2, c ); CutN1 = Vec_WrdEntry( p->vCutsN1, c ); CutN2 = Vec_WrdEntry( p->vCutsN2, c ); iObj = Vec_IntEntry( p->vCutsObj, c ); //iObj = Vec_IntEntry( p->vAnds, iObj ); vObj = Vec_WecEntry( p->vWindow, iObj ); Vec_IntClear( vObj ); assert( Vec_IntSize(vObj) == 0 ); for ( b = 0; b < 64; b++ ) if ( (CutI1 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vLeaves, b) ); for ( b = 0; b < 64; b++ ) if ( (CutI2 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vLeaves, 64+b) ); for ( b = 0; b < 64; b++ ) if ( (CutN1 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vAnds, b) ); for ( b = 0; b < 64; b++ ) if ( (CutN2 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vAnds, 64+b) ); } } /**Function************************************************************* Synopsis [Timing computation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Sbl_ManComputeDelay( Sbl_Man_t * p, int iLut, Vec_Int_t * vFanins ) { int k, iFan, Delay = 0; Vec_IntForEachEntry( vFanins, iFan, k ) Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vArrs, iFan) + 1 ); return Delay; } int Sbl_ManCreateTiming( Sbl_Man_t * p, int DelayStart ) { Vec_Int_t * vFanins; int DelayMax = DelayStart, Delay, iLut, iFan, k; // compute arrival times Vec_IntFill( p->vArrs, Gia_ManObjNum(p->pGia), 0 ); if ( p->pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)p->pGia->pManTime) ) { Gia_Obj_t * pObj; Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( p->pGia ); Tim_ManIncrementTravId( (Tim_Man_t*)p->pGia->pManTime ); Gia_ManForEachObjVec( vNodes, p->pGia, pObj, k ) { iLut = Gia_ObjId( p->pGia, pObj ); if ( Gia_ObjIsAnd(pObj) ) { if ( Gia_ObjIsLut2(p->pGia, iLut) ) { vFanins = Gia_ObjLutFanins2(p->pGia, iLut); Delay = Sbl_ManComputeDelay( p, iLut, vFanins ); Vec_IntWriteEntry( p->vArrs, iLut, Delay ); DelayMax = Abc_MaxInt( DelayMax, Delay ); } } else if ( Gia_ObjIsCi(pObj) ) { int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)p->pGia->pManTime, Gia_ObjCioId(pObj) ); Vec_IntWriteEntry( p->vArrs, iLut, arrTime ); } else if ( Gia_ObjIsCo(pObj) ) { int arrTime = Vec_IntEntry( p->vArrs, Gia_ObjFaninId0(pObj, iLut) ); Tim_ManSetCoArrival( (Tim_Man_t*)p->pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); } else if ( !Gia_ObjIsConst0(pObj) ) assert( 0 ); } Vec_IntFree( vNodes ); } else { Gia_ManForEachLut2( p->pGia, iLut ) { vFanins = Gia_ObjLutFanins2(p->pGia, iLut); Delay = Sbl_ManComputeDelay( p, iLut, vFanins ); Vec_IntWriteEntry( p->vArrs, iLut, Delay ); DelayMax = Abc_MaxInt( DelayMax, Delay ); } } // compute required times Vec_IntFill( p->vReqs, Gia_ManObjNum(p->pGia), ABC_INFINITY ); Gia_ManForEachCoDriverId( p->pGia, iLut, k ) Vec_IntDowndateEntry( p->vReqs, iLut, DelayMax ); if ( p->pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)p->pGia->pManTime) ) { Gia_Obj_t * pObj; Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( p->pGia ); Tim_ManIncrementTravId( (Tim_Man_t*)p->pGia->pManTime ); Tim_ManInitPoRequiredAll( (Tim_Man_t*)p->pGia->pManTime, DelayMax ); Gia_ManForEachObjVecReverse( vNodes, p->pGia, pObj, k ) { iLut = Gia_ObjId( p->pGia, pObj ); if ( Gia_ObjIsAnd(pObj) ) { if ( Gia_ObjIsLut2(p->pGia, iLut) ) { Delay = Vec_IntEntry(p->vReqs, iLut) - 1; vFanins = Gia_ObjLutFanins2(p->pGia, iLut); Vec_IntForEachEntry( vFanins, iFan, k ) Vec_IntDowndateEntry( p->vReqs, iFan, Delay ); } } else if ( Gia_ObjIsCi(pObj) ) { int reqTime = Vec_IntEntry( p->vReqs, iLut ); Tim_ManSetCiRequired( (Tim_Man_t*)p->pGia->pManTime, Gia_ObjCioId(pObj), reqTime ); } else if ( Gia_ObjIsCo(pObj) ) { int reqTime = Tim_ManGetCoRequired( (Tim_Man_t*)p->pGia->pManTime, Gia_ObjCioId(pObj) ); Vec_IntWriteEntry( p->vReqs, Gia_ObjFaninId0(pObj, iLut), reqTime ); } else if ( !Gia_ObjIsConst0(pObj) ) assert( 0 ); } Vec_IntFree( vNodes ); } else { Gia_ManForEachLut2Reverse( p->pGia, iLut ) { Delay = Vec_IntEntry(p->vReqs, iLut) - 1; vFanins = Gia_ObjLutFanins2(p->pGia, iLut); Vec_IntForEachEntry( vFanins, iFan, k ) Vec_IntDowndateEntry( p->vReqs, iFan, Delay ); } } return DelayMax; } /**Function************************************************************* Synopsis [Given mapping in p->vSolCur, check if mapping meets delay.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Sbl_ManEvaluateMappingEdge( Sbl_Man_t * p, int DelayGlo ) { abctime clk = Abc_Clock(); Vec_Int_t * vArray; int i, DelayMax; Vec_IntClear( p->vPath ); // update new timing Sbl_ManGetCurrentMapping( p ); // derive new timing DelayMax = Gia_ManEvalWindow( p->pGia, p->vLeaves, p->vAnds, p->vWindow, p->vPolar, 1 ); p->timeTime += Abc_Clock() - clk; if ( DelayMax <= DelayGlo ) return 1; // create critical path composed of all nodes Vec_WecForEachLevel( p->vWindow, vArray, i ) if ( Vec_IntSize(vArray) > 0 ) Vec_IntPush( p->vPath, Abc_Var2Lit(i, 1) ); return 0; } /**Function************************************************************* Synopsis [Given mapping in p->vSolCur, check the critical path.] Description [Returns 1 if the mapping satisfies the timing. Returns 0, if the critical path is detected.] SideEffects [] SeeAlso [] ***********************************************************************/ int Sbl_ManCriticalFanin( Sbl_Man_t * p, int iLut, Vec_Int_t * vFanins ) { int k, iFan, Delay = Vec_IntEntry(p->vArrs, iLut); Vec_IntForEachEntry( vFanins, iFan, k ) if ( Vec_IntEntry(p->vArrs, iFan) + 1 == Delay ) return iFan; return -1; } int Sbl_ManEvaluateMapping( Sbl_Man_t * p, int DelayGlo ) { abctime clk = Abc_Clock(); Vec_Int_t * vFanins; int i, iLut = -1, iAnd, Delay, Required; if ( p->pGia->vEdge1 ) return Sbl_ManEvaluateMappingEdge( p, DelayGlo ); Vec_IntClear( p->vPath ); // derive timing Sbl_ManCreateTiming( p, DelayGlo ); // update new timing Sbl_ManGetCurrentMapping( p ); Vec_IntForEachEntry( p->vAnds, iLut, i ) { vFanins = Vec_WecEntry( p->vWindow, i ); Delay = Sbl_ManComputeDelay( p, iLut, vFanins ); Vec_IntWriteEntry( p->vArrs, iLut, Delay ); } // compare timing at the root nodes Vec_IntForEachEntry( p->vRoots, iLut, i ) { Delay = Vec_IntEntry( p->vArrs, iLut ); Required = Vec_IntEntry( p->vReqs, iLut ); if ( Delay > Required ) // updated timing exceeded original timing break; } p->timeTime += Abc_Clock() - clk; if ( i == Vec_IntSize(p->vRoots) ) return 1; // derive the critical path // find SAT variable of the node whose GIA ID is "iLut" iAnd = Vec_IntFind( p->vAnds, iLut ); assert( iAnd >= 0 ); // critical path begins in node "iLut", which is i-th root of the window assert( iAnd == Vec_IntEntry(p->vRootVars, i) ); while ( 1 ) { Vec_IntPush( p->vPath, Abc_Var2Lit(iAnd, 1) ); // find fanins of this node vFanins = Vec_WecEntry( p->vWindow, iAnd ); // find critical fanin iLut = Sbl_ManCriticalFanin( p, iLut, vFanins ); assert( iLut > 0 ); // find SAT variable of the node whose GIA ID is "iLut" iAnd = Vec_IntFind( p->vAnds, iLut ); if ( iAnd == -1 ) break; } return 0; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sbl_ManUpdateMapping( Sbl_Man_t * p ) { // Gia_Obj_t * pObj; Vec_Int_t * vObj; word CutI1, CutI2, CutN1, CutN2; int i, c, b, iObj, iTemp; assert( Vec_IntSize(p->vSolBest) < Vec_IntSize(p->vSolInit) ); Vec_IntForEachEntry( p->vAnds, iObj, i ) { vObj = Vec_WecEntry(p->pGia->vMapping2, iObj); Vec_IntForEachEntry( vObj, iTemp, b ) Gia_ObjLutRefDecId( p->pGia, iTemp ); Vec_IntClear( vObj ); } Vec_IntForEachEntry( p->vSolBest, c, i ) { CutI1 = Vec_WrdEntry( p->vCutsI1, c ); CutI2 = Vec_WrdEntry( p->vCutsI2, c ); CutN1 = Vec_WrdEntry( p->vCutsN1, c ); CutN2 = Vec_WrdEntry( p->vCutsN2, c ); iObj = Vec_IntEntry( p->vCutsObj, c ); iObj = Vec_IntEntry( p->vAnds, iObj ); vObj = Vec_WecEntry( p->pGia->vMapping2, iObj ); Vec_IntClear( vObj ); assert( Vec_IntSize(vObj) == 0 ); for ( b = 0; b < 64; b++ ) if ( (CutI1 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vLeaves, b) ); for ( b = 0; b < 64; b++ ) if ( (CutI2 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vLeaves, 64+b) ); for ( b = 0; b < 64; b++ ) if ( (CutN1 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vAnds, b) ); for ( b = 0; b < 64; b++ ) if ( (CutN2 >> b) & 1 ) Vec_IntPush( vObj, Vec_IntEntry(p->vAnds, 64+b) ); Vec_IntForEachEntry( vObj, iTemp, b ) Gia_ObjLutRefIncId( p->pGia, iTemp ); } /* // verify Gia_ManForEachLut2Vec( p->pGia, vObj, i ) Vec_IntForEachEntry( vObj, iTemp, b ) Gia_ObjLutRefDecId( p->pGia, iTemp ); Gia_ManForEachCo( p->pGia, pObj, i ) Gia_ObjLutRefDecId( p->pGia, Gia_ObjFaninId0p(p->pGia, pObj) ); for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ ) if ( p->pGia->pLutRefs[i] ) printf( "Object %d has %d refs\n", i, p->pGia->pLutRefs[i] ); Gia_ManForEachCo( p->pGia, pObj, i ) Gia_ObjLutRefIncId( p->pGia, Gia_ObjFaninId0p(p->pGia, pObj) ); Gia_ManForEachLut2Vec( p->pGia, vObj, i ) Vec_IntForEachEntry( vObj, iTemp, b ) Gia_ObjLutRefIncId( p->pGia, iTemp ); */ } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static int Sbl_ManPrintCut( word CutI1, word CutI2, word CutN1, word CutN2 ) { int b, Count = 0; printf( "{ " ); for ( b = 0; b < 64; b++ ) if ( (CutI1 >> b) & 1 ) printf( "i%d ", b ), Count++; for ( b = 0; b < 64; b++ ) if ( (CutI2 >> b) & 1 ) printf( "i%d ", 64+b ), Count++; printf( " " ); for ( b = 0; b < 64; b++ ) if ( (CutN1 >> b) & 1 ) printf( "n%d ", b ), Count++; for ( b = 0; b < 64; b++ ) if ( (CutN2 >> b) & 1 ) printf( "n%d ", 64+b ), Count++; printf( "};\n" ); return Count; } static int Sbl_ManFindAndPrintCut( Sbl_Man_t * p, int c ) { return Sbl_ManPrintCut( Vec_WrdEntry(p->vCutsI1, c), Vec_WrdEntry(p->vCutsI2, c), Vec_WrdEntry(p->vCutsN1, c), Vec_WrdEntry(p->vCutsN2, c) ); } static inline int Sbl_CutIsFeasible( word CutI1, word CutI2, word CutN1, word CutN2, int LutSize ) { int Count = (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); assert( LutSize <= 6 ); CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); if ( LutSize <= 4 ) return Count <= 4; CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0); return Count <= 6; } static inline int Sbl_CutPushUncontained( Vec_Wrd_t * vCutsI1, Vec_Wrd_t * vCutsI2, Vec_Wrd_t * vCutsN1, Vec_Wrd_t * vCutsN2, word CutI1, word CutI2, word CutN1, word CutN2 ) { int i, k = 0; assert( vCutsI1->nSize == vCutsN1->nSize ); assert( vCutsI2->nSize == vCutsN2->nSize ); for ( i = 0; i < vCutsI1->nSize; i++ ) if ( (vCutsI1->pArray[i] & CutI1) == vCutsI1->pArray[i] && (vCutsI2->pArray[i] & CutI2) == vCutsI2->pArray[i] && (vCutsN1->pArray[i] & CutN1) == vCutsN1->pArray[i] && (vCutsN2->pArray[i] & CutN2) == vCutsN2->pArray[i] ) return 1; for ( i = 0; i < vCutsI1->nSize; i++ ) if ( (vCutsI1->pArray[i] & CutI1) != CutI1 || (vCutsI2->pArray[i] & CutI2) != CutI2 || (vCutsN1->pArray[i] & CutN1) != CutN1 || (vCutsN2->pArray[i] & CutN2) != CutN2 ) { Vec_WrdWriteEntry( vCutsI1, k, vCutsI1->pArray[i] ); Vec_WrdWriteEntry( vCutsI2, k, vCutsI2->pArray[i] ); Vec_WrdWriteEntry( vCutsN1, k, vCutsN1->pArray[i] ); Vec_WrdWriteEntry( vCutsN2, k, vCutsN2->pArray[i] ); k++; } Vec_WrdShrink( vCutsI1, k ); Vec_WrdShrink( vCutsI2, k ); Vec_WrdShrink( vCutsN1, k ); Vec_WrdShrink( vCutsN2, k ); Vec_WrdPush( vCutsI1, CutI1 ); Vec_WrdPush( vCutsI2, CutI2 ); Vec_WrdPush( vCutsN1, CutN1 ); Vec_WrdPush( vCutsN2, CutN2 ); return 0; } static inline void Sbl_ManComputeCutsOne( Sbl_Man_t * p, int Fan0, int Fan1, int Obj ) { word * pCutsI1 = Vec_WrdArray(p->vCutsI1); word * pCutsI2 = Vec_WrdArray(p->vCutsI2); word * pCutsN1 = Vec_WrdArray(p->vCutsN1); word * pCutsN2 = Vec_WrdArray(p->vCutsN2); int Start0 = Vec_IntEntry( p->vCutsStart, Fan0 ); int Start1 = Vec_IntEntry( p->vCutsStart, Fan1 ); int Limit0 = Start0 + Vec_IntEntry( p->vCutsNum, Fan0 ); int Limit1 = Start1 + Vec_IntEntry( p->vCutsNum, Fan1 ); int i, k; assert( Obj >= 0 && Obj < 128 ); Vec_WrdClear( p->vTempI1 ); Vec_WrdClear( p->vTempI2 ); Vec_WrdClear( p->vTempN1 ); Vec_WrdClear( p->vTempN2 ); for ( i = Start0; i < Limit0; i++ ) for ( k = Start1; k < Limit1; k++ ) if ( Sbl_CutIsFeasible(pCutsI1[i] | pCutsI1[k], pCutsI2[i] | pCutsI2[k], pCutsN1[i] | pCutsN1[k], pCutsN2[i] | pCutsN2[k], p->LutSize) ) Sbl_CutPushUncontained( p->vTempI1, p->vTempI2, p->vTempN1, p->vTempN2, pCutsI1[i] | pCutsI1[k], pCutsI2[i] | pCutsI2[k], pCutsN1[i] | pCutsN1[k], pCutsN2[i] | pCutsN2[k] ); Vec_IntPush( p->vCutsStart, Vec_WrdSize(p->vCutsI1) ); Vec_IntPush( p->vCutsNum, Vec_WrdSize(p->vTempI1) + 1 ); Vec_WrdAppend( p->vCutsI1, p->vTempI1 ); Vec_WrdAppend( p->vCutsI2, p->vTempI2 ); Vec_WrdAppend( p->vCutsN1, p->vTempN1 ); Vec_WrdAppend( p->vCutsN2, p->vTempN2 ); Vec_WrdPush( p->vCutsI1, 0 ); Vec_WrdPush( p->vCutsI2, 0 ); if ( Obj < 64 ) { Vec_WrdPush( p->vCutsN1, (((word)1) << Obj) ); Vec_WrdPush( p->vCutsN2, 0 ); } else { Vec_WrdPush( p->vCutsN1, 0 ); Vec_WrdPush( p->vCutsN2, (((word)1) << (Obj-64)) ); } for ( i = 0; i <= Vec_WrdSize(p->vTempI1); i++ ) Vec_IntPush( p->vCutsObj, Obj ); } static inline int Sbl_ManFindCut( Sbl_Man_t * p, int Obj, word CutI1, word CutI2, word CutN1, word CutN2 ) { word * pCutsI1 = Vec_WrdArray(p->vCutsI1); word * pCutsI2 = Vec_WrdArray(p->vCutsI2); word * pCutsN1 = Vec_WrdArray(p->vCutsN1); word * pCutsN2 = Vec_WrdArray(p->vCutsN2); int Start0 = Vec_IntEntry( p->vCutsStart, Obj ); int Limit0 = Start0 + Vec_IntEntry( p->vCutsNum, Obj ); int i; //printf( "\nLooking for:\n" ); //Sbl_ManPrintCut( CutI, CutN ); //printf( "\n" ); for ( i = Start0; i < Limit0; i++ ) { //Sbl_ManPrintCut( pCutsI[i], pCutsN[i] ); if ( pCutsI1[i] == CutI1 && pCutsI2[i] == CutI2 && pCutsN1[i] == CutN1 && pCutsN2[i] == CutN2 ) return i; } return -1; } int Sbl_ManComputeCuts( Sbl_Man_t * p ) { abctime clk = Abc_Clock(); Gia_Obj_t * pObj; Vec_Int_t * vFanins; int i, k, Index, Fanin, nObjs = Vec_IntSize(p->vLeaves) + Vec_IntSize(p->vAnds); assert( Vec_IntSize(p->vLeaves) <= 128 && Vec_IntSize(p->vAnds) <= p->nVars ); // assign leaf cuts Vec_IntClear( p->vCutsStart ); Vec_IntClear( p->vCutsObj ); Vec_IntClear( p->vCutsNum ); Vec_WrdClear( p->vCutsI1 ); Vec_WrdClear( p->vCutsI2 ); Vec_WrdClear( p->vCutsN1 ); Vec_WrdClear( p->vCutsN2 ); Gia_ManForEachObjVec( p->vLeaves, p->pGia, pObj, i ) { Vec_IntPush( p->vCutsStart, Vec_WrdSize(p->vCutsI1) ); Vec_IntPush( p->vCutsObj, -1 ); Vec_IntPush( p->vCutsNum, 1 ); if ( i < 64 ) { Vec_WrdPush( p->vCutsI1, (((word)1) << i) ); Vec_WrdPush( p->vCutsI2, 0 ); } else { Vec_WrdPush( p->vCutsI1, 0 ); Vec_WrdPush( p->vCutsI2, (((word)1) << (i-64)) ); } Vec_WrdPush( p->vCutsN1, 0 ); Vec_WrdPush( p->vCutsN2, 0 ); pObj->Value = i; } // assign internal cuts Gia_ManForEachObjVec( p->vAnds, p->pGia, pObj, i ) { assert( Gia_ObjIsAnd(pObj) ); assert( ~Gia_ObjFanin0(pObj)->Value ); assert( ~Gia_ObjFanin1(pObj)->Value ); Sbl_ManComputeCutsOne( p, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, i ); pObj->Value = Vec_IntSize(p->vLeaves) + i; } assert( Vec_IntSize(p->vCutsStart) == nObjs ); assert( Vec_IntSize(p->vCutsNum) == nObjs ); assert( Vec_WrdSize(p->vCutsI1) == Vec_WrdSize(p->vCutsN1) ); assert( Vec_WrdSize(p->vCutsI2) == Vec_WrdSize(p->vCutsN2) ); assert( Vec_WrdSize(p->vCutsI1) == Vec_IntSize(p->vCutsObj) ); // check that roots are mapped nodes Vec_IntClear( p->vRootVars ); Gia_ManForEachObjVec( p->vRoots, p->pGia, pObj, i ) { int Obj = Gia_ObjId(p->pGia, pObj); if ( Gia_ObjIsCi(pObj) ) continue; assert( Gia_ObjIsLut2(p->pGia, Obj) ); assert( ~pObj->Value ); Vec_IntPush( p->vRootVars, pObj->Value - Vec_IntSize(p->vLeaves) ); } // create current solution Vec_IntClear( p->vPolar ); Vec_IntClear( p->vSolInit ); Gia_ManForEachObjVec( p->vAnds, p->pGia, pObj, i ) { word CutI1 = 0, CutI2 = 0, CutN1 = 0, CutN2 = 0; int Obj = Gia_ObjId(p->pGia, pObj); if ( !Gia_ObjIsLut2(p->pGia, Obj) ) continue; assert( (int)pObj->Value == Vec_IntSize(p->vLeaves) + i ); // add node Vec_IntPush( p->vPolar, i ); Vec_IntPush( p->vSolInit, i ); // add its cut //Gia_LutForEachFaninObj( p->pGia, Obj, pFanin, k ) vFanins = Gia_ObjLutFanins2( p->pGia, Obj ); Vec_IntForEachEntry( vFanins, Fanin, k ) { Gia_Obj_t * pFanin = Gia_ManObj( p->pGia, Fanin ); assert( (int)pFanin->Value < Vec_IntSize(p->vLeaves) || Gia_ObjIsLut2(p->pGia, Fanin) ); // if ( ~pFanin->Value == 0 ) // Gia_ManPrintConeMulti( p->pGia, p->vAnds, p->vLeaves, p->vPath ); if ( ~pFanin->Value == 0 ) continue; assert( ~pFanin->Value ); if ( (int)pFanin->Value < Vec_IntSize(p->vLeaves) ) { if ( (int)pFanin->Value < 64 ) CutI1 |= ((word)1 << pFanin->Value); else CutI2 |= ((word)1 << (pFanin->Value - 64)); } else { if ( pFanin->Value - Vec_IntSize(p->vLeaves) < 64 ) CutN1 |= ((word)1 << (pFanin->Value - Vec_IntSize(p->vLeaves))); else CutN2 |= ((word)1 << (pFanin->Value - Vec_IntSize(p->vLeaves) - 64)); } } // find the new cut Index = Sbl_ManFindCut( p, Vec_IntSize(p->vLeaves) + i, CutI1, CutI2, CutN1, CutN2 ); if ( Index < 0 ) { //printf( "Cannot find the available cut.\n" ); continue; } assert( Index >= 0 ); Vec_IntPush( p->vPolar, p->FirstVar+Index ); } // clean value Gia_ManForEachObjVec( p->vLeaves, p->pGia, pObj, i ) pObj->Value = ~0; Gia_ManForEachObjVec( p->vAnds, p->pGia, pObj, i ) pObj->Value = ~0; p->timeCut += Abc_Clock() - clk; return Vec_WrdSize(p->vCutsI1); } int Sbl_ManCreateCnf( Sbl_Man_t * p ) { int i, k, c, pLits[2], value; word * pCutsN1 = Vec_WrdArray(p->vCutsN1); word * pCutsN2 = Vec_WrdArray(p->vCutsN2); assert( p->FirstVar == sat_solver_nvars(p->pSat) ); sat_solver_setnvars( p->pSat, sat_solver_nvars(p->pSat) + Vec_WrdSize(p->vCutsI1) ); //printf( "\n" ); for ( i = 0; i < Vec_IntSize(p->vAnds); i++ ) { int Start0 = Vec_IntEntry( p->vCutsStart, Vec_IntSize(p->vLeaves) + i ); int Limit0 = Start0 + Vec_IntEntry( p->vCutsNum, Vec_IntSize(p->vLeaves) + i ) - 1; // add main clause Vec_IntClear( p->vLits ); Vec_IntPush( p->vLits, Abc_Var2Lit(i, 1) ); //printf( "Node %d implies cuts: ", i ); for ( k = Start0; k < Limit0; k++ ) { Vec_IntPush( p->vLits, Abc_Var2Lit(p->FirstVar+k, 0) ); //printf( "%d ", p->FirstVar+k ); } //printf( "\n" ); value = sat_solver_addclause( p->pSat, Vec_IntArray(p->vLits), Vec_IntLimit(p->vLits) ); assert( value ); // binary clauses for ( k = Start0; k < Limit0; k++ ) { word Cut1 = pCutsN1[k]; word Cut2 = pCutsN2[k]; //printf( "Cut %d implies root node %d.\n", p->FirstVar+k, i ); // root clause pLits[0] = Abc_Var2Lit( p->FirstVar+k, 1 ); pLits[1] = Abc_Var2Lit( i, 0 ); value = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( value ); // fanin clauses for ( c = 0; c < 64 && Cut1; c++, Cut1 >>= 1 ) { if ( (Cut1 & 1) == 0 ) continue; //printf( "Cut %d implies fanin %d.\n", p->FirstVar+k, c ); pLits[1] = Abc_Var2Lit( c, 0 ); value = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( value ); } for ( c = 0; c < 64 && Cut2; c++, Cut2 >>= 1 ) { if ( (Cut2 & 1) == 0 ) continue; //printf( "Cut %d implies fanin %d.\n", p->FirstVar+k, c ); pLits[1] = Abc_Var2Lit( c+64, 0 ); value = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( value ); } } } sat_solver_set_polarity( p->pSat, Vec_IntArray(p->vPolar), Vec_IntSize(p->vPolar) ); return 1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sbl_ManWindow( Sbl_Man_t * p ) { int i, ObjId; // collect leaves Vec_IntClear( p->vLeaves ); Gia_ManForEachCiId( p->pGia, ObjId, i ) Vec_IntPush( p->vLeaves, ObjId ); // collect internal Vec_IntClear( p->vAnds ); Gia_ManForEachAndId( p->pGia, ObjId ) Vec_IntPush( p->vAnds, ObjId ); // collect roots Vec_IntClear( p->vRoots ); Gia_ManForEachCoDriverId( p->pGia, ObjId, i ) Vec_IntPush( p->vRoots, ObjId ); } int Sbl_ManWindow2( Sbl_Man_t * p, int iPivot ) { abctime clk = Abc_Clock(); Vec_Int_t * vRoots, * vNodes, * vLeaves, * vAnds; int Count = Gia_ManComputeOneWin( p->pGia, iPivot, &vRoots, &vNodes, &vLeaves, &vAnds ); p->timeWin += Abc_Clock() - clk; if ( Count == 0 ) return 0; Vec_IntClear( p->vRoots ); Vec_IntAppend( p->vRoots, vRoots ); Vec_IntClear( p->vNodes ); Vec_IntAppend( p->vNodes, vNodes ); Vec_IntClear( p->vLeaves ); Vec_IntAppend( p->vLeaves, vLeaves ); Vec_IntClear( p->vAnds ); Vec_IntAppend( p->vAnds, vAnds ); //Vec_IntPrint( vRoots ); //Vec_IntPrint( vAnds ); //Vec_IntPrint( vLeaves ); // recompute internal nodes // Gia_ManIncrementTravId( p->pGia ); // Gia_ManCollectAnds( p->pGia, Vec_IntArray(p->vRoots), Vec_IntSize(p->vRoots), p->vAnds, p->vLeaves ); return Count; } int Sbl_ManTestSat( Sbl_Man_t * p, int iPivot ) { int fKeepTrying = 1; abctime clk = Abc_Clock(), clk2; int i, status, Root, Count, StartSol, nConfTotal = 0, nIters = 0; int nEntries = Hsh_VecSize( p->pHash ); p->nTried++; Sbl_ManClean( p ); // compute one window Count = Sbl_ManWindow2( p, iPivot ); if ( Count == 0 ) { if ( p->fVeryVerbose ) printf( "Obj %d: Window with less than %d nodes does not exist.\n", iPivot, p->nVars ); p->nSmallWins++; return 0; } Hsh_VecManAdd( p->pHash, p->vAnds ); if ( nEntries == Hsh_VecSize(p->pHash) ) { if ( p->fVeryVerbose ) printf( "Obj %d: This window was already tried.\n", iPivot ); p->nHashWins++; return 0; } if ( p->fVeryVerbose ) printf( "\nObj = %6d : Leaf = %2d. AND = %2d. Root = %2d. LUT = %2d.\n", iPivot, Vec_IntSize(p->vLeaves), Vec_IntSize(p->vAnds), Vec_IntSize(p->vRoots), Vec_IntSize(p->vNodes) ); if ( Vec_IntSize(p->vLeaves) > 128 || Vec_IntSize(p->vAnds) > p->nVars ) { if ( p->fVeryVerbose ) printf( "Obj %d: Encountered window with %d inputs and %d internal nodes.\n", iPivot, Vec_IntSize(p->vLeaves), Vec_IntSize(p->vAnds) ); p->nLargeWins++; return 0; } if ( Vec_IntSize(p->vAnds) < 10 ) { if ( p->fVeryVerbose ) printf( "Skipping.\n" ); return 0; } // derive cuts Sbl_ManComputeCuts( p ); // derive SAT instance Sbl_ManCreateCnf( p ); if ( p->fVeryVeryVerbose ) printf( "All clauses = %d. Multi clauses = %d. Binary clauses = %d. Other clauses = %d.\n\n", sat_solver_nclauses(p->pSat), Vec_IntSize(p->vAnds), Vec_WrdSize(p->vCutsI1) - Vec_IntSize(p->vAnds), sat_solver_nclauses(p->pSat) - Vec_WrdSize(p->vCutsI1) ); // create assumptions // cardinality Vec_IntClear( p->vAssump ); Vec_IntPush( p->vAssump, -1 ); // unused variables for ( i = Vec_IntSize(p->vAnds); i < p->Power2; i++ ) Vec_IntPush( p->vAssump, Abc_Var2Lit(i, 1) ); // root variables Vec_IntForEachEntry( p->vRootVars, Root, i ) Vec_IntPush( p->vAssump, Abc_Var2Lit(Root, 0) ); // Vec_IntPrint( p->vAssump ); StartSol = Vec_IntSize(p->vSolInit) + 1; // StartSol = 30; while ( fKeepTrying && StartSol-fKeepTrying > 0 ) { int Count = 0, LitCount = 0; int nConfBef, nConfAft; if ( p->fVeryVerbose ) printf( "Trying to find mapping with %d LUTs.\n", StartSol-fKeepTrying ); // for ( i = Vec_IntSize(p->vSolInit)-5; i < nVars; i++ ) // Vec_IntPush( p->vAssump, Abc_Var2Lit(Vec_IntEntry(p->vCardVars, i), 1) ); Vec_IntWriteEntry( p->vAssump, 0, Abc_Var2Lit(Vec_IntEntry(p->vCardVars, StartSol-fKeepTrying), 1) ); // solve the problem clk2 = Abc_Clock(); nConfBef = (int)p->pSat->stats.conflicts; status = sat_solver_solve( p->pSat, Vec_IntArray(p->vAssump), Vec_IntLimit(p->vAssump), p->nBTLimit, 0, 0, 0 ); p->timeSat += Abc_Clock() - clk2; nConfAft = (int)p->pSat->stats.conflicts; nConfTotal += nConfAft - nConfBef; nIters++; p->nRuns++; if ( status == l_True ) p->timeSatSat += Abc_Clock() - clk2; else if ( status == l_False ) p->timeSatUns += Abc_Clock() - clk2; else p->timeSatUnd += Abc_Clock() - clk2; if ( status == l_Undef ) break; if ( status == l_True ) { if ( p->fVeryVeryVerbose ) { for ( i = 0; i < Vec_IntSize(p->vAnds); i++ ) printf( "%d", sat_solver_var_value(p->pSat, i) ); printf( "\n" ); for ( i = 0; i < Vec_IntSize(p->vAnds); i++ ) if ( sat_solver_var_value(p->pSat, i) ) { printf( "%d=%d ", i, sat_solver_var_value(p->pSat, i) ); Count++; } printf( "Count = %d\n", Count ); } // for ( i = p->FirstVar; i < sat_solver_nvars(p->pSat); i++ ) // printf( "%d", sat_solver_var_value(p->pSat, i) ); // printf( "\n" ); Count = 1; Vec_IntClear( p->vSolCur ); for ( i = p->FirstVar; i < sat_solver_nvars(p->pSat); i++ ) if ( sat_solver_var_value(p->pSat, i) ) { if ( p->fVeryVeryVerbose ) printf( "Cut %3d : Node = %3d %6d ", Count++, Vec_IntEntry(p->vCutsObj, i-p->FirstVar), Vec_IntEntry(p->vAnds, Vec_IntEntry(p->vCutsObj, i-p->FirstVar)) ); if ( p->fVeryVeryVerbose ) LitCount += Sbl_ManFindAndPrintCut( p, i-p->FirstVar ); Vec_IntPush( p->vSolCur, i-p->FirstVar ); } //Vec_IntPrint( p->vRootVars ); //Vec_IntPrint( p->vRoots ); //Vec_IntPrint( p->vAnds ); //Vec_IntPrint( p->vLeaves ); } // fKeepTrying = status == l_True ? fKeepTrying + 1 : 0; // check the timing if ( status == l_True ) { if ( p->fDelay && !Sbl_ManEvaluateMapping(p, p->DelayMax) ) { int iLit, value; if ( p->fVeryVerbose ) { printf( "Critical path of length (%d) is detected: ", Vec_IntSize(p->vPath) ); Vec_IntForEachEntry( p->vPath, iLit, i ) printf( "%d=%d ", i, Vec_IntEntry(p->vAnds, Abc_Lit2Var(iLit)) ); printf( "\n" ); } // add the clause value = sat_solver_addclause( p->pSat, Vec_IntArray(p->vPath), Vec_IntLimit(p->vPath) ); assert( value ); } else { Vec_IntClear( p->vSolBest ); Vec_IntAppend( p->vSolBest, p->vSolCur ); fKeepTrying++; } } else fKeepTrying = 0; if ( p->fVeryVerbose ) { if ( status == l_False ) printf( "UNSAT " ); else if ( status == l_True ) printf( "SAT " ); else printf( "UNDEC " ); printf( "confl =%8d. ", nConfAft - nConfBef ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk2 ); printf( "Total " ); printf( "confl =%8d. ", nConfTotal ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( p->fVeryVeryVerbose && status == l_True ) printf( "LitCount = %d.\n", LitCount ); printf( "\n" ); } if ( nIters == 10 ) { p->nIterOuts++; //printf( "Obj %d : Quitting after %d iterations.\n", iPivot, nIters ); break; } } // update solution if ( Vec_IntSize(p->vSolBest) > 0 && Vec_IntSize(p->vSolBest) < Vec_IntSize(p->vSolInit) ) { int nDelayCur, nEdgesCur = 0; Sbl_ManUpdateMapping( p ); if ( p->pGia->vEdge1 ) { nDelayCur = Gia_ManEvalEdgeDelay( p->pGia ); nEdgesCur = Gia_ManEvalEdgeCount( p->pGia ); } else nDelayCur = Sbl_ManCreateTiming( p, p->DelayMax ); if ( p->fVerbose ) printf( "Object %5d : Saved %2d nodes (Conf =%8d) Iter =%3d Delay = %d Edges = %4d\n", iPivot, Vec_IntSize(p->vSolInit)-Vec_IntSize(p->vSolBest), nConfTotal, nIters, nDelayCur, nEdgesCur ); p->timeTotal += Abc_Clock() - p->timeStart; p->nImproved++; return 2; } else { // printf( "Object %5d : Saved %2d nodes (Conf =%8d) Iter =%3d\n", iPivot, 0, nConfTotal, nIters ); } p->timeTotal += Abc_Clock() - p->timeStart; return 1; } void Sbl_ManPrintRuntime( Sbl_Man_t * p ) { printf( "Runtime breakdown:\n" ); p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeSat - p->timeTime; ABC_PRTP( "Win ", p->timeWin , p->timeTotal ); ABC_PRTP( "Cut ", p->timeCut , p->timeTotal ); ABC_PRTP( "Sat ", p->timeSat, p->timeTotal ); ABC_PRTP( " Sat ", p->timeSatSat, p->timeTotal ); ABC_PRTP( " Unsat", p->timeSatUns, p->timeTotal ); ABC_PRTP( " Undec", p->timeSatUnd, p->timeTotal ); ABC_PRTP( "Timing", p->timeTime , p->timeTotal ); ABC_PRTP( "Other ", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL ", p->timeTotal, p->timeTotal ); } void Gia_ManLutSat( Gia_Man_t * pGia, int LutSize, int nNumber, int nImproves, int nBTLimit, int DelayMax, int nEdges, int fDelay, int fReverse, int fVerbose, int fVeryVerbose ) { int iLut, nImproveCount = 0; Sbl_Man_t * p = Sbl_ManAlloc( pGia, nNumber ); p->LutSize = LutSize; // LUT size p->nBTLimit = nBTLimit; // conflicts p->DelayMax = DelayMax; // external delay p->nEdges = nEdges; // the number of edges p->fDelay = fDelay; // delay mode p->fReverse = fReverse; // reverse windowing p->fVerbose = fVerbose | fVeryVerbose; p->fVeryVerbose = fVeryVerbose; if ( p->fVerbose ) printf( "Parameters: WinSize = %d AIG nodes. Conf = %d. DelayMax = %d.\n", p->nVars, p->nBTLimit, p->DelayMax ); // determine delay limit if ( fDelay && pGia->vEdge1 && p->DelayMax == 0 ) p->DelayMax = Gia_ManEvalEdgeDelay( pGia ); // iterate through the internal nodes Gia_ManComputeOneWinStart( pGia, nNumber, fReverse ); Gia_ManForEachLut2( pGia, iLut ) { if ( Sbl_ManTestSat( p, iLut ) != 2 ) continue; if ( ++nImproveCount == nImproves ) break; } Gia_ManComputeOneWin( pGia, -1, NULL, NULL, NULL, NULL ); if ( p->fVerbose ) printf( "Tried = %d. Used = %d. HashWin = %d. SmallWin = %d. LargeWin = %d. IterOut = %d. SAT runs = %d.\n", p->nTried, p->nImproved, p->nHashWins, p->nSmallWins, p->nLargeWins, p->nIterOuts, p->nRuns ); if ( p->fVerbose ) Sbl_ManPrintRuntime( p ); Sbl_ManStop( p ); Vec_IntFreeP( &pGia->vPacking ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END