diff options
Diffstat (limited to 'src/opt/res')
-rw-r--r-- | src/opt/res/res.h | 1 | ||||
-rw-r--r-- | src/opt/res/resCore.c | 14 | ||||
-rw-r--r-- | src/opt/res/resDivs.c | 7 | ||||
-rw-r--r-- | src/opt/res/resFilter.c | 209 | ||||
-rw-r--r-- | src/opt/res/resInt.h | 4 |
5 files changed, 207 insertions, 28 deletions
diff --git a/src/opt/res/res.h b/src/opt/res/res.h index 3c963e99..3c3431bf 100644 --- a/src/opt/res/res.h +++ b/src/opt/res/res.h @@ -42,6 +42,7 @@ struct Res_Par_t_ { // general parameters int nWindow; // window size + int nGrowthLevel; // the maximum allowed growth in level after one iteration of resynthesis int nSimWords; // the number of simulation words int nCands; // the number of candidates to try int fArea; // performs optimization for area diff --git a/src/opt/res/resCore.c b/src/opt/res/resCore.c index ad99829a..1d0711f6 100644 --- a/src/opt/res/resCore.c +++ b/src/opt/res/resCore.c @@ -73,6 +73,8 @@ struct Res_Man_t_ extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph ); +extern int s_ResynTime; + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -185,13 +187,14 @@ int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, Res_Par_t * pPars ) Kit_Graph_t * pGraph; Vec_Ptr_t * vFanins; unsigned * puTruth; - int i, k, RetValue, nNodesOld, nFanins; + int i, k, RetValue, nNodesOld, nFanins, nFaninsMax; int clk, clkTotal = clock(); // start the manager p = Res_ManAlloc( pPars ); p->nTotalNets = Abc_NtkGetTotalFanins(pNtk); p->nTotalNodes = Abc_NtkNodeNum(pNtk); + nFaninsMax = Abc_NtkGetFaninMax(pNtk); // perform the network sweep Abc_NtkSweep( pNtk, 0 ); @@ -236,10 +239,10 @@ p->timeWin += clock() - clk; Vec_PtrSize(p->pWin->vNodes), Vec_PtrSize(p->pWin->vRoots) ); } - + // collect the divisors clk = clock(); - Res_WinDivisors( p->pWin, pObj->Level + 2 ); //- 1 ); + Res_WinDivisors( p->pWin, pObj->Level + pPars->nGrowthLevel - 1 ); p->timeDiv += clock() - clk; p->nWins++; @@ -291,9 +294,9 @@ p->timeSim += clock() - clk; // find resub candidates for the node clk = clock(); if ( p->pPars->fArea ) - RetValue = Res_FilterCandidatesArea( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW ); + RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW, nFaninsMax, 1 ); else - RetValue = Res_FilterCandidatesNets( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW ); + RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW, nFaninsMax, 0 ); p->timeCand += clock() - clk; p->nCandSets += RetValue; if ( RetValue == 0 ) @@ -367,6 +370,7 @@ p->timeSatTotal = p->timeSatSat + p->timeSatUnsat + p->timeSatSim; p->timeTotal = clock() - clkTotal; Res_ManFree( p ); +s_ResynTime += clock() - clkTotal; // check the resulting network if ( !Abc_NtkCheck( pNtk ) ) { diff --git a/src/opt/res/resDivs.c b/src/opt/res/resDivs.c index 38294428..cc75b90f 100644 --- a/src/opt/res/resDivs.c +++ b/src/opt/res/resDivs.c @@ -124,6 +124,13 @@ void Res_WinDivisors( Res_Win_t * p, int nLevDivMax ) p->nDivsPlus++; } } +/* + printf( "Node level = %d. ", Abc_ObjLevel(p->pNode) ); + Vec_PtrForEachEntryStart( p->vDivs, pObj, k, Vec_PtrSize(p->vDivs)-p->nDivsPlus ) + printf( "%d ", Abc_ObjLevel(pObj) ); + printf( "\n" ); +*/ +//printf( "%d ", p->nDivsPlus ); } /**Function************************************************************* diff --git a/src/opt/res/resFilter.c b/src/opt/res/resFilter.c index afbbbe42..f2ca41d3 100644 --- a/src/opt/res/resFilter.c +++ b/src/opt/res/resFilter.c @@ -41,13 +41,13 @@ static int Res_FilterCriticalFanin( Abc_Obj_t * pNode ); SideEffects [] SeeAlso [] - + ***********************************************************************/ -int Res_FilterCandidatesNets( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW ) +int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax, int fArea ) { - Abc_Obj_t * pFanin, * pFanin2; - unsigned * pInfo; - int Counter, RetValue, i, k; + Abc_Obj_t * pFanin, * pFanin2, * pFaninTemp; + unsigned * pInfo, * pInfoDiv, * pInfoDiv2; + int Counter, RetValue, i, i2, d, d2, iDiv, iDiv2, k; // check that the info the node is one pInfo = Vec_PtrEntry( pSim->vOuts, 1 ); @@ -67,37 +67,159 @@ int Res_FilterCandidatesNets( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pS return 0; } - // try removing fanins + // try removing each fanin // printf( "Fanins: " ); Counter = 0; Vec_VecClear( vResubs ); Vec_VecClear( vResubsW ); Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) { + if ( fArea && Abc_ObjFanoutNum(pFanin) > 1 ) + continue; + // get simulation info without this fanin pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); if ( RetValue ) { // printf( "Node %4d. Candidate fanin %4d.\n", pWin->pNode->Id, pFanin->Id ); + // collect the nodes + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); + Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) + { + if ( k != i ) + { + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); + Vec_VecPush( vResubsW, Counter, pFaninTemp ); + } + } + Counter++; + if ( Counter == Vec_VecSize(vResubs) ) + return Counter; + } + } + // try replacing each critical fanin by a non-critical fanin + Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) + { + if ( Abc_ObjFanoutNum(pFanin) > 1 ) + continue; + // get simulation info without this fanin + pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); + // go over the set of divisors + for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) + { + pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); + iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); + if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) + continue; // collect the nodes Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - Abc_ObjForEachFanin( pWin->pNode, pFanin2, k ) + // collect the remaning fanins and the divisor + Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) { if ( k != i ) { Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFanin2 ); + Vec_VecPush( vResubsW, Counter, pFaninTemp ); } } + // collect the divisor + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); Counter++; + if ( Counter == Vec_VecSize(vResubs) ) + return Counter; + } + } + + // consider the case when two fanins can be added instead of one + if ( Abc_ObjFaninNum(pWin->pNode) < nFaninsMax ) + { + // try to replace each critical fanin by two non-critical fanins + Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) + { + if ( Abc_ObjFanoutNum(pFanin) > 1 ) + continue; + // get simulation info without this fanin + pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); + // go over the set of divisors + for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) + { + pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); + iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); + // go through the second divisor + for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ ) + { + pInfoDiv2 = Vec_PtrEntry( pSim->vOuts, d2 ); + iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2); + if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) ) + continue; + // collect the nodes + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); + // collect the remaning fanins and the divisor + Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) + { + if ( k != i ) + { + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); + Vec_VecPush( vResubsW, Counter, pFaninTemp ); + } + } + // collect the divisor + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) ); + Counter++; + if ( Counter == Vec_VecSize(vResubs) ) + return Counter; + } + } + } + } + + // try to replace two nets by one + if ( !fArea ) + { + Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) + { + for ( i2 = i + 1; i2 < Abc_ObjFaninNum(pWin->pNode); i2++ ) + { + pFanin2 = Abc_ObjFanin(pWin->pNode, i2); + // get simulation info without these fanins + pInfo = Res_FilterCollectFaninInfo( pWin, pSim, (~(1 << i)) & (~(1 << i2)) ); + // go over the set of divisors + for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) + { + pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); + iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); + if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) + continue; + // collect the nodes + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); + // collect the remaning fanins and the divisor + Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) + { + if ( k != i && k != i2 ) + { + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); + Vec_VecPush( vResubsW, Counter, pFaninTemp ); + } + } + // collect the divisor + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); + Counter++; + if ( Counter == Vec_VecSize(vResubs) ) + return Counter; + } + } } - if ( Counter == Vec_VecSize(vResubs) ) - break; -// printf( "%d", RetValue ); } -// printf( "\n\n" ); return Counter; } @@ -106,18 +228,18 @@ int Res_FilterCandidatesNets( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pS Synopsis [Finds sets of feasible candidates.] - Description [] + Description [This procedure is a special case of the above.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW ) +int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax ) { Abc_Obj_t * pFanin; - unsigned * pInfo, * pInfo2; - int Counter, RetValue, i, k, iBest; + unsigned * pInfo, * pInfoDiv, * pInfoDiv2; + int Counter, RetValue, d, d2, k, iDiv, iDiv2, iBest; // check that the info the node is one pInfo = Vec_PtrEntry( pSim->vOuts, 1 ); @@ -170,11 +292,14 @@ int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pS } // go through the divisors - for ( i = Abc_ObjFaninNum(pWin->pNode) + 2; i < Abc_NtkPoNum(pAig); i++ ) + for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) { - pInfo2 = Vec_PtrEntry( pSim->vOuts, i ); - if ( !Abc_InfoIsOrOne( pInfo, pInfo2, pSim->nWordsOut ) ) + pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); + iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); + if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) continue; +//if ( Abc_ObjLevel(pWin->pNode) <= Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) ) +// printf( "Node level = %d. Divisor level = %d.\n", Abc_ObjLevel(pWin->pNode), Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) ); // collect the nodes Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); @@ -188,13 +313,55 @@ int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pS } } // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,i) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, i-2-Abc_ObjFaninNum(pWin->pNode)) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); Counter++; if ( Counter == Vec_VecSize(vResubs) ) break; } + + if ( Counter > 0 || Abc_ObjFaninNum(pWin->pNode) >= nFaninsMax ) + return Counter; + + // try to find the node pairs + for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) + { + pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); + iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); + // go through the second divisor + for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ ) + { + pInfoDiv2 = Vec_PtrEntry( pSim->vOuts, d2 ); + iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2); + + if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) ) + continue; + // collect the nodes + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); + // collect the remaning fanins and the divisor + Abc_ObjForEachFanin( pWin->pNode, pFanin, k ) + { + if ( k != iBest ) + { + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); + Vec_VecPush( vResubsW, Counter, pFanin ); + } + } + // collect the divisor + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); + Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); + Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) ); + Counter++; + + if ( Counter == Vec_VecSize(vResubs) ) + break; + } + if ( Counter == Vec_VecSize(vResubs) ) + break; + } return Counter; } diff --git a/src/opt/res/resInt.h b/src/opt/res/resInt.h index 10e312b3..5aae46cc 100644 --- a/src/opt/res/resInt.h +++ b/src/opt/res/resInt.h @@ -105,8 +105,8 @@ extern void Res_WinDivisors( Res_Win_t * p, int nLevDivMax ); extern void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit ); extern int Res_WinVisitMffc( Abc_Obj_t * pNode ); /*=== resFilter.c ==========================================================*/ -extern int Res_FilterCandidatesNets( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW ); -extern int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW ); +extern int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax, int fArea ); +extern int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax ); /*=== resSat.c ==========================================================*/ extern void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins ); extern int Res_SatSimulate( Res_Sim_t * p, int nPats, int fOnSet ); |