mirror of https://github.com/YosysHQ/abc.git
592 lines
18 KiB
C
592 lines
18 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [mfsCore.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [The good old minimization with complete don't-cares.]
|
|
|
|
Synopsis [Core procedures of this package.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: mfsCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "mfsInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
extern int Abc_NtkMfsSolveSatResub( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int fOnlyRemove, int fSkipUpdate );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_NtkMfsParsDefault( Mfs_Par_t * pPars )
|
|
{
|
|
memset( pPars, 0, sizeof(Mfs_Par_t) );
|
|
pPars->nWinTfoLevs = 2;
|
|
pPars->nFanoutsMax = 10;
|
|
pPars->nDepthMax = 20;
|
|
pPars->nDivMax = 250;
|
|
pPars->nWinSizeMax = 300;
|
|
pPars->nGrowthLevel = 0;
|
|
pPars->nBTLimit = 5000;
|
|
pPars->fResub = 1;
|
|
pPars->fArea = 0;
|
|
pPars->fMoreEffort = 0;
|
|
pPars->fSwapEdge = 0;
|
|
pPars->fOneHotness = 0;
|
|
pPars->fVerbose = 0;
|
|
pPars->fVeryVerbose = 0;
|
|
}
|
|
/*
|
|
int Abc_NtkMfsEdgePower( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
|
{
|
|
Abc_Obj_t * pFanin;
|
|
int i;
|
|
// try replacing area critical fanins
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
{
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.4 )
|
|
{
|
|
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
|
return 1;
|
|
} else if ( Abc_MfsObjProb(p, pFanin) >= 0.3 )
|
|
{
|
|
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 1, 0 ) )
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
int Abc_WinNode(Mfs_Man_t * p, Abc_Obj_t *pNode)
|
|
{
|
|
// int clk;
|
|
// Abc_Obj_t * pFanin;
|
|
// int i;
|
|
|
|
p->nNodesTried++;
|
|
// prepare data structure for this node
|
|
Mfs_ManClean( p );
|
|
// compute window roots, window support, and window nodes
|
|
p->vRoots = Abc_MfsComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
|
|
p->vSupp = Abc_NtkNodeSupport( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
p->vNodes = Abc_NtkDfsNodes( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
if ( p->pPars->nWinSizeMax && Vec_PtrSize(p->vNodes) > p->pPars->nWinSizeMax )
|
|
return 1;
|
|
// compute the divisors of the window
|
|
p->vDivs = Abc_MfsComputeDivisors( p, pNode, Abc_ObjRequiredLevel(pNode) - 1 );
|
|
p->nTotalDivs += Vec_PtrSize(p->vDivs);
|
|
// construct AIG for the window
|
|
p->pAigWin = Abc_NtkConstructAig( p, pNode );
|
|
// translate it into CNF
|
|
p->pCnf = Cnf_DeriveSimple( p->pAigWin, 1 + Vec_PtrSize(p->vDivs) );
|
|
// create the SAT problem
|
|
p->pSat = Abc_MfsCreateSolverResub( p, NULL, 0, 0 );
|
|
if ( p->pSat == NULL )
|
|
{
|
|
p->nNodesBad++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
int Abc_NtkMfsPowerResubNode( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
|
{
|
|
int clk;
|
|
Abc_Obj_t * pFanin;
|
|
int i;
|
|
|
|
if (Abc_WinNode(p, pNode) // something wrong
|
|
return 1;
|
|
|
|
// solve the SAT problem
|
|
// Abc_NtkMfsEdgePower( p, pNode );
|
|
// try replacing area critical fanins
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.37 && Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
|
return 1;
|
|
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.1 && Abc_NtkMfsSolveSatResub( p, pNode, i, 1, 0 ) )
|
|
return 1;
|
|
|
|
if ( Abc_ObjFaninNum(pNode) == p->nFaninMax )
|
|
return 0;
|
|
|
|
// try replacing area critical fanins while adding two new fanins
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.37 && Abc_NtkMfsSolveSatResub2( p, pNode, i, -1 ) )
|
|
return 1;
|
|
}
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
*/
|
|
|
|
void Abc_NtkMfsPowerResub( Mfs_Man_t * p, Mfs_Par_t * pPars)
|
|
{
|
|
int i, k;
|
|
Abc_Obj_t *pFanin, *pNode;
|
|
Abc_Ntk_t *pNtk = p->pNtk;
|
|
int nFaninMax = Abc_NtkGetFaninMax(p->pNtk);
|
|
|
|
Abc_NtkForEachNode( pNtk, pNode, k )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pNode->Level > p->pPars->nDepthMax )
|
|
continue;
|
|
if ( Abc_ObjFaninNum(pNode) < 2 || Abc_ObjFaninNum(pNode) > nFaninMax )
|
|
continue;
|
|
if (Abc_WinNode(p, pNode) ) // something wrong
|
|
continue;
|
|
|
|
// solve the SAT problem
|
|
// Abc_NtkMfsEdgePower( p, pNode );
|
|
// try replacing area critical fanins
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.35 && Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
|
continue;
|
|
}
|
|
|
|
Abc_NtkForEachNode( pNtk, pNode, k )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pNode->Level > p->pPars->nDepthMax )
|
|
continue;
|
|
if ( Abc_ObjFaninNum(pNode) < 2 || Abc_ObjFaninNum(pNode) > nFaninMax )
|
|
continue;
|
|
if (Abc_WinNode(p, pNode) ) // something wrong
|
|
continue;
|
|
|
|
// solve the SAT problem
|
|
// Abc_NtkMfsEdgePower( p, pNode );
|
|
// try replacing area critical fanins
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.35 && Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
|
continue;
|
|
}
|
|
|
|
Abc_NtkForEachNode( pNtk, pNode, k )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pNode->Level > p->pPars->nDepthMax )
|
|
continue;
|
|
if ( Abc_ObjFaninNum(pNode) < 2 || Abc_ObjFaninNum(pNode) > nFaninMax )
|
|
continue;
|
|
if (Abc_WinNode(p, pNode) ) // something wrong
|
|
continue;
|
|
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.2 && Abc_NtkMfsSolveSatResub( p, pNode, i, 1, 0 ) )
|
|
continue;
|
|
}
|
|
/*
|
|
Abc_NtkForEachNode( pNtk, pNode, k )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pNode->Level > p->pPars->nDepthMax )
|
|
continue;
|
|
if ( Abc_ObjFaninNum(pNode) < 2 || Abc_ObjFaninNum(pNode) > nFaninMax - 2)
|
|
continue;
|
|
if (Abc_WinNode(p, pNode) ) // something wrong
|
|
continue;
|
|
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
if ( Abc_MfsObjProb(p, pFanin) >= 0.37 && Abc_NtkMfsSolveSatResub2( p, pNode, i, -1 ) )
|
|
continue;
|
|
}
|
|
*/
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkMfsResub( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
|
{
|
|
int clk;
|
|
p->nNodesTried++;
|
|
// prepare data structure for this node
|
|
Mfs_ManClean( p );
|
|
// compute window roots, window support, and window nodes
|
|
clk = clock();
|
|
p->vRoots = Abc_MfsComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
|
|
p->vSupp = Abc_NtkNodeSupport( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
p->vNodes = Abc_NtkDfsNodes( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
p->timeWin += clock() - clk;
|
|
if ( p->pPars->nWinSizeMax && Vec_PtrSize(p->vNodes) > p->pPars->nWinSizeMax )
|
|
return 1;
|
|
// compute the divisors of the window
|
|
clk = clock();
|
|
p->vDivs = Abc_MfsComputeDivisors( p, pNode, Abc_ObjRequiredLevel(pNode) - 1 );
|
|
p->nTotalDivs += Vec_PtrSize(p->vDivs);
|
|
p->timeDiv += clock() - clk;
|
|
// construct AIG for the window
|
|
clk = clock();
|
|
p->pAigWin = Abc_NtkConstructAig( p, pNode );
|
|
p->timeAig += clock() - clk;
|
|
// translate it into CNF
|
|
clk = clock();
|
|
p->pCnf = Cnf_DeriveSimple( p->pAigWin, 1 + Vec_PtrSize(p->vDivs) );
|
|
p->timeCnf += clock() - clk;
|
|
// create the SAT problem
|
|
clk = clock();
|
|
p->pSat = Abc_MfsCreateSolverResub( p, NULL, 0, 0 );
|
|
if ( p->pSat == NULL )
|
|
{
|
|
p->nNodesBad++;
|
|
return 1;
|
|
}
|
|
//clk = clock();
|
|
// if ( p->pPars->fGiaSat )
|
|
// Abc_NtkMfsConstructGia( p );
|
|
//p->timeGia += clock() - clk;
|
|
// solve the SAT problem
|
|
if ( p->pPars->fPower )
|
|
Abc_NtkMfsEdgePower( p, pNode );
|
|
else if ( p->pPars->fSwapEdge )
|
|
Abc_NtkMfsEdgeSwapEval( p, pNode );
|
|
else
|
|
{
|
|
Abc_NtkMfsResubNode( p, pNode );
|
|
if ( p->pPars->fMoreEffort )
|
|
Abc_NtkMfsResubNode2( p, pNode );
|
|
}
|
|
p->timeSat += clock() - clk;
|
|
// if ( p->pPars->fGiaSat )
|
|
// Abc_NtkMfsDeconstructGia( p );
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkMfsNode( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
|
{
|
|
Hop_Obj_t * pObj;
|
|
int RetValue;
|
|
float dProb;
|
|
extern Hop_Obj_t * Abc_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare, float dProb );
|
|
|
|
int nGain, clk;
|
|
p->nNodesTried++;
|
|
// prepare data structure for this node
|
|
Mfs_ManClean( p );
|
|
// compute window roots, window support, and window nodes
|
|
clk = clock();
|
|
p->vRoots = Abc_MfsComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
|
|
p->vSupp = Abc_NtkNodeSupport( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
p->vNodes = Abc_NtkDfsNodes( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
|
p->timeWin += clock() - clk;
|
|
// count the number of patterns
|
|
// p->dTotalRatios += Abc_NtkConstraintRatio( p, pNode );
|
|
// construct AIG for the window
|
|
clk = clock();
|
|
p->pAigWin = Abc_NtkConstructAig( p, pNode );
|
|
p->timeAig += clock() - clk;
|
|
// translate it into CNF
|
|
clk = clock();
|
|
p->pCnf = Cnf_DeriveSimple( p->pAigWin, Abc_ObjFaninNum(pNode) );
|
|
p->timeCnf += clock() - clk;
|
|
// create the SAT problem
|
|
clk = clock();
|
|
p->pSat = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
|
|
if ( p->pSat && p->pPars->fOneHotness )
|
|
Abc_NtkAddOneHotness( p );
|
|
if ( p->pSat == NULL )
|
|
return 0;
|
|
// solve the SAT problem
|
|
RetValue = Abc_NtkMfsSolveSat( p, pNode );
|
|
p->nTotConfLevel += p->pSat->stats.conflicts;
|
|
p->timeSat += clock() - clk;
|
|
if ( RetValue == 0 )
|
|
{
|
|
p->nTimeOutsLevel++;
|
|
p->nTimeOuts++;
|
|
return 0;
|
|
}
|
|
// minimize the local function of the node using bi-decomposition
|
|
assert( p->nFanins == Abc_ObjFaninNum(pNode) );
|
|
dProb = p->pPars->fPower? ((float *)p->vProbs->pArray)[pNode->Id] : -1.0;
|
|
pObj = Abc_NodeIfNodeResyn( p->pManDec, (Hop_Man_t *)pNode->pNtk->pManFunc, (Hop_Obj_t *)pNode->pData, p->nFanins, p->vTruth, p->uCare, dProb );
|
|
nGain = Hop_DagSize((Hop_Obj_t *)pNode->pData) - Hop_DagSize(pObj);
|
|
if ( nGain >= 0 )
|
|
{
|
|
p->nNodesDec++;
|
|
p->nNodesGained += nGain;
|
|
p->nNodesGainedLevel += nGain;
|
|
pNode->pData = pObj;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
|
|
{
|
|
extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
|
|
|
|
Bdc_Par_t Pars = {0}, * pDecPars = &Pars;
|
|
ProgressBar * pProgress;
|
|
Mfs_Man_t * p;
|
|
Abc_Obj_t * pObj;
|
|
Vec_Vec_t * vLevels;
|
|
Vec_Ptr_t * vNodes;
|
|
int i, k, nNodes, nFaninMax, clk = clock(), clk2;
|
|
int nTotalNodesBeg = Abc_NtkNodeNum(pNtk);
|
|
int nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk);
|
|
|
|
assert( Abc_NtkIsLogic(pNtk) );
|
|
nFaninMax = Abc_NtkGetFaninMax(pNtk);
|
|
if ( pPars->fResub )
|
|
{
|
|
if ( nFaninMax > 8 )
|
|
{
|
|
printf( "Nodes with more than %d fanins will node be processed.\n", 8 );
|
|
nFaninMax = 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( nFaninMax > MFS_FANIN_MAX )
|
|
{
|
|
printf( "Nodes with more than %d fanins will node be processed.\n", MFS_FANIN_MAX );
|
|
nFaninMax = MFS_FANIN_MAX;
|
|
}
|
|
}
|
|
// perform the network sweep
|
|
Abc_NtkSweep( pNtk, 0 );
|
|
// convert into the AIG
|
|
if ( !Abc_NtkToAig(pNtk) )
|
|
{
|
|
fprintf( stdout, "Converting to AIGs has failed.\n" );
|
|
return 0;
|
|
}
|
|
assert( Abc_NtkHasAig(pNtk) );
|
|
|
|
// start the manager
|
|
p = Mfs_ManAlloc( pPars );
|
|
p->pNtk = pNtk;
|
|
p->nFaninMax = nFaninMax;
|
|
|
|
// precomputer power-aware metrics
|
|
if ( pPars->fPower )
|
|
{
|
|
extern Vec_Int_t * Abc_NtkPowerEstimate( Abc_Ntk_t * pNtk, int fProbOne );
|
|
if ( pPars->fResub )
|
|
p->vProbs = Abc_NtkPowerEstimate( pNtk, 0 );
|
|
else
|
|
p->vProbs = Abc_NtkPowerEstimate( pNtk, 1 );
|
|
#if 0
|
|
printf( "Total switching before = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#else
|
|
p->TotalSwitchingBeg = Abc_NtkMfsTotalSwitching(pNtk);
|
|
#endif
|
|
}
|
|
|
|
if ( pNtk->pExcare )
|
|
{
|
|
Abc_Ntk_t * pTemp;
|
|
if ( Abc_NtkPiNum((Abc_Ntk_t *)pNtk->pExcare) != Abc_NtkCiNum(pNtk) )
|
|
printf( "The PI count of careset (%d) and logic network (%d) differ. Careset is not used.\n",
|
|
Abc_NtkPiNum((Abc_Ntk_t *)pNtk->pExcare), Abc_NtkCiNum(pNtk) );
|
|
else
|
|
{
|
|
pTemp = Abc_NtkStrash( (Abc_Ntk_t *)pNtk->pExcare, 0, 0, 0 );
|
|
p->pCare = Abc_NtkToDar( pTemp, 0, 0 );
|
|
Abc_NtkDelete( pTemp );
|
|
p->vSuppsInv = Aig_ManSupportsInverse( p->pCare );
|
|
}
|
|
}
|
|
if ( p->pCare != NULL )
|
|
printf( "Performing optimization with %d external care clauses.\n", Aig_ManPoNum(p->pCare) );
|
|
// prepare the BDC manager
|
|
if ( !pPars->fResub )
|
|
{
|
|
pDecPars->nVarsMax = (nFaninMax < 3) ? 3 : nFaninMax;
|
|
pDecPars->fVerbose = pPars->fVerbose;
|
|
p->vTruth = Vec_IntAlloc( 0 );
|
|
p->pManDec = Bdc_ManAlloc( pDecPars );
|
|
}
|
|
|
|
// label the register outputs
|
|
if ( p->pCare )
|
|
{
|
|
Abc_NtkForEachCi( pNtk, pObj, i )
|
|
pObj->pData = (void *)(ABC_PTRUINT_T)i;
|
|
}
|
|
|
|
// compute levels
|
|
Abc_NtkLevel( pNtk );
|
|
Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel );
|
|
|
|
// compute don't-cares for each node
|
|
nNodes = 0;
|
|
p->nTotalNodesBeg = nTotalNodesBeg;
|
|
p->nTotalEdgesBeg = nTotalEdgesBeg;
|
|
if ( pPars->fResub )
|
|
{
|
|
#if 0
|
|
printf( "TotalSwitching (%7.2f --> ", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#endif
|
|
if (pPars->fPower)
|
|
{
|
|
Abc_NtkMfsPowerResub( p, pPars);
|
|
} else
|
|
{
|
|
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pObj->Level > p->pPars->nDepthMax )
|
|
continue;
|
|
if ( Abc_ObjFaninNum(pObj) < 2 || Abc_ObjFaninNum(pObj) > nFaninMax )
|
|
continue;
|
|
if ( !p->pPars->fVeryVerbose )
|
|
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
|
if ( pPars->fResub )
|
|
Abc_NtkMfsResub( p, pObj );
|
|
else
|
|
Abc_NtkMfsNode( p, pObj );
|
|
}
|
|
Extra_ProgressBarStop( pProgress );
|
|
#if 0
|
|
printf( " %7.2f )\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#endif
|
|
}
|
|
} else
|
|
{
|
|
#if 0
|
|
printf( "Total switching before = %7.2f, ----> ", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#endif
|
|
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
|
|
vLevels = Abc_NtkLevelize( pNtk );
|
|
Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 )
|
|
{
|
|
if ( !p->pPars->fVeryVerbose )
|
|
Extra_ProgressBarUpdate( pProgress, nNodes, NULL );
|
|
p->nNodesGainedLevel = 0;
|
|
p->nTotConfLevel = 0;
|
|
p->nTimeOutsLevel = 0;
|
|
clk2 = clock();
|
|
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
|
{
|
|
if ( p->pPars->nDepthMax && (int)pObj->Level > p->pPars->nDepthMax )
|
|
break;
|
|
if ( Abc_ObjFaninNum(pObj) < 2 || Abc_ObjFaninNum(pObj) > nFaninMax )
|
|
continue;
|
|
if ( pPars->fResub )
|
|
Abc_NtkMfsResub( p, pObj );
|
|
else
|
|
Abc_NtkMfsNode( p, pObj );
|
|
}
|
|
nNodes += Vec_PtrSize(vNodes);
|
|
if ( pPars->fVerbose )
|
|
{
|
|
/*
|
|
printf( "Lev = %2d. Node = %5d. Ave gain = %5.2f. Ave conf = %5.2f. T/o = %6.2f %% ",
|
|
k, Vec_PtrSize(vNodes),
|
|
1.0*p->nNodesGainedLevel/Vec_PtrSize(vNodes),
|
|
1.0*p->nTotConfLevel/Vec_PtrSize(vNodes),
|
|
100.0*p->nTimeOutsLevel/Vec_PtrSize(vNodes) );
|
|
ABC_PRT( "Time", clock() - clk2 );
|
|
*/
|
|
}
|
|
}
|
|
Extra_ProgressBarStop( pProgress );
|
|
Vec_VecFree( vLevels );
|
|
#if 0
|
|
printf( " %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#endif
|
|
}
|
|
Abc_NtkStopReverseLevels( pNtk );
|
|
|
|
// perform the sweeping
|
|
if ( !pPars->fResub )
|
|
{
|
|
extern void Abc_NtkBidecResyn( Abc_Ntk_t * pNtk, int fVerbose );
|
|
// Abc_NtkSweep( pNtk, 0 );
|
|
// Abc_NtkBidecResyn( pNtk, 0 );
|
|
}
|
|
|
|
p->nTotalNodesEnd = Abc_NtkNodeNum(pNtk);
|
|
p->nTotalEdgesEnd = Abc_NtkGetTotalFanins(pNtk);
|
|
|
|
// undo labesl
|
|
if ( p->pCare )
|
|
{
|
|
Abc_NtkForEachCi( pNtk, pObj, i )
|
|
pObj->pData = NULL;
|
|
}
|
|
|
|
if ( pPars->fPower )
|
|
{
|
|
#if 1
|
|
p->TotalSwitchingEnd = Abc_NtkMfsTotalSwitching(pNtk);
|
|
// printf( "Total switching after = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#else
|
|
printf( "Total switching after = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
|
#endif
|
|
}
|
|
|
|
// free the manager
|
|
p->timeTotal = clock() - clk;
|
|
Mfs_ManStop( p );
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|