/**Function************************************************************* Synopsis [Recursively collects roots of the window.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Sfm_NtkCheckRoot( Sfm_Ntk_t * p, int iNode, int nLevelMax ) { int i, iFanout; // the node is the root if one of the following is true: // (1) the node has more than fanouts than the limit or has no fanouts (should not happen in general) if ( Sfm_ObjFanoutNum(p, iNode) == 0 || Sfm_ObjFanoutNum(p, iNode) > p->pPars->nFanoutMax ) return 1; // (2) the node has CO fanouts // (3) the node has fanouts above the cutoff level Sfm_ObjForEachFanout( p, iNode, iFanout, i ) if ( Sfm_ObjIsPo(p, iFanout) || Sfm_ObjLevel(p, iFanout) > nLevelMax )//|| !Sfm_NtkCheckOverlap(p, iFanout, iNode) ) return 1; return 0; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars ) { int i, k, Counter = 0; p->timeTotal = Abc_Clock(); if ( pPars->fVerbose && Vec_StrSum(p->vFixed) > 0 ) printf( "Performing MFS with %d fixed objects.\n", Vec_StrSum(p->vFixed) ); p->pPars = pPars; Sfm_NtkPrepare( p ); // Sfm_ComputeInterpolantCheck( p ); // return 0; p->nTotalNodesBeg = Vec_WecSizeUsedLimits( &p->vFanins, Sfm_NtkPiNum(p), Vec_WecSize(&p->vFanins) - Sfm_NtkPoNum(p) ); p->nTotalEdgesBeg = Vec_WecSizeSize(&p->vFanins) - Sfm_NtkPoNum(p); Sfm_NtkForEachNode( p, i ) { if ( Sfm_ObjIsFixed( p, i ) ) continue; if ( p->pPars->nDepthMax && Sfm_ObjLevel(p, i) > p->pPars->nDepthMax ) continue; if ( Sfm_ObjFaninNum(p, i) < 2 || Sfm_ObjFaninNum(p, i) > 6 ) continue; for ( k = 0; Sfm_NodeResub(p, i); k++ ) { // Counter++; // break; } Counter += (k > 0); if ( pPars->nNodesMax && Counter >= pPars->nNodesMax ) break; } p->nTotalNodesEnd = Vec_WecSizeUsedLimits( &p->vFanins, Sfm_NtkPiNum(p), Vec_WecSize(&p->vFanins) - Sfm_NtkPoNum(p) ); p->nTotalEdgesEnd = Vec_WecSizeSize(&p->vFanins) - Sfm_NtkPoNum(p); p->timeTotal = Abc_Clock() - p->timeTotal; if ( pPars->fVerbose ) Sfm_NtkPrintStats( p ); return Counter; }
/**Function************************************************************* Synopsis [Performs resubstitution for the node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Sfm_NodeResubSolve( Sfm_Ntk_t * p, int iNode, int f, int fRemoveOnly ) { int fSkipUpdate = 0; int fVeryVerbose = 0;//p->pPars->fVeryVerbose && Vec_IntSize(p->vDivs) < 200;// || pNode->Id == 556; int i, iFanin, iVar = -1; word uTruth, uSign, uMask; abctime clk; assert( Sfm_ObjIsNode(p, iNode) ); assert( f >= 0 && f < Sfm_ObjFaninNum(p, iNode) ); p->nTryRemoves++; // report init stats if ( p->pPars->fVeryVerbose ) printf( "%5d : Lev =%3d. Leaf =%3d. Node =%3d. Div=%3d. Fanin =%4d (%d/%d). MFFC = %d\n", iNode, Sfm_ObjLevel(p, iNode), 0, Vec_IntSize(p->vNodes), Vec_IntSize(p->vDivs), Sfm_ObjFanin(p, iNode, f), f, Sfm_ObjFaninNum(p, iNode), Sfm_ObjMffcSize(p, Sfm_ObjFanin(p, iNode, f)) ); // clean simulation info p->nCexes = 0; Vec_WrdFill( p->vDivCexes, Vec_IntSize(p->vDivs), 0 ); // try removing the critical fanin Vec_IntClear( p->vDivIds ); Sfm_ObjForEachFanin( p, iNode, iFanin, i ) if ( i != f ) Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iFanin) ); clk = Abc_Clock(); uTruth = Sfm_ComputeInterpolant( p ); p->timeSat += Abc_Clock() - clk; // analyze outcomes if ( uTruth == SFM_SAT_UNDEC ) { p->nTimeOuts++; return 0; } if ( uTruth != SFM_SAT_SAT ) goto finish; if ( fRemoveOnly || p->pPars->fRrOnly || Vec_IntSize(p->vDivs) == 0 ) return 0; p->nTryResubs++; if ( fVeryVerbose ) { for ( i = 0; i < 9; i++ ) printf( " " ); for ( i = 0; i < Vec_IntSize(p->vDivs); i++ ) printf( "%d", i % 10 ); printf( "\n" ); } while ( 1 ) { if ( fVeryVerbose ) { printf( "%3d: %3d ", p->nCexes, iVar ); Vec_WrdForEachEntry( p->vDivCexes, uSign, i ) printf( "%d", Abc_InfoHasBit((unsigned *)&uSign, p->nCexes-1) ); printf( "\n" ); } // find the next divisor to try uMask = (~(word)0) >> (64 - p->nCexes); Vec_WrdForEachEntry( p->vDivCexes, uSign, iVar ) if ( uSign == uMask ) break; if ( iVar == Vec_IntSize(p->vDivs) ) return 0; // try replacing the critical fanin Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, Vec_IntEntry(p->vDivs, iVar)) ); clk = Abc_Clock(); uTruth = Sfm_ComputeInterpolant( p ); p->timeSat += Abc_Clock() - clk; // analyze outcomes if ( uTruth == SFM_SAT_UNDEC ) { p->nTimeOuts++; return 0; } if ( uTruth != SFM_SAT_SAT ) goto finish; if ( p->nCexes == 64 ) return 0; // remove the last variable Vec_IntPop( p->vDivIds ); } finish: if ( p->pPars->fVeryVerbose ) { if ( iVar == -1 ) printf( "Node %d: Fanin %d (%d) can be removed. ", iNode, f, Sfm_ObjFanin(p, iNode, f) ); else printf( "Node %d: Fanin %d (%d) can be replaced by divisor %d (%d). ", iNode, f, Sfm_ObjFanin(p, iNode, f), iVar, Vec_IntEntry(p->vDivs, iVar) ); Kit_DsdPrintFromTruth( (unsigned *)&uTruth, Vec_IntSize(p->vDivIds) ); printf( "\n" ); } if ( iVar == -1 ) p->nRemoves++; else p->nResubs++; if ( fSkipUpdate ) return 0; // update the network Sfm_NtkUpdate( p, iNode, f, (iVar == -1 ? iVar : Vec_IntEntry(p->vDivs, iVar)), uTruth ); return 1; }