diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-02-05 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-02-05 08:01:00 -0800 |
commit | 7174787abafe80437892b55a53f994da85a37342 (patch) | |
tree | 0df4c6f35d99111d757aa9b8091853b8f88ee762 /src/opt/mfs/mfsDiv.c | |
parent | 3b790eb17e54cd922440a1a3b18a5cfdd5cbcadb (diff) | |
download | abc-7174787abafe80437892b55a53f994da85a37342.tar.gz abc-7174787abafe80437892b55a53f994da85a37342.tar.bz2 abc-7174787abafe80437892b55a53f994da85a37342.zip |
Version abc80205
Diffstat (limited to 'src/opt/mfs/mfsDiv.c')
-rw-r--r-- | src/opt/mfs/mfsDiv.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/opt/mfs/mfsDiv.c b/src/opt/mfs/mfsDiv.c new file mode 100644 index 00000000..7b156b97 --- /dev/null +++ b/src/opt/mfs/mfsDiv.c @@ -0,0 +1,303 @@ +/**CFile**************************************************************** + + FileName [mfsDiv.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [The good old minimization with complete don't-cares.] + + Synopsis [Procedures to compute candidate divisors.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: mfsDiv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "mfsInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Marks and collects the TFI cone of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MfsWinMarkTfi_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vCone ) +{ + Abc_Obj_t * pFanin; + int i; + if ( Abc_NodeIsTravIdCurrent(pObj) ) + return; + Abc_NodeSetTravIdCurrent( pObj ); + if ( Abc_ObjIsCi(pObj) ) + { + Vec_PtrPush( vCone, pObj ); + return; + } + assert( Abc_ObjIsNode(pObj) ); + // visit the fanins of the node + Abc_ObjForEachFanin( pObj, pFanin, i ) + Abc_MfsWinMarkTfi_rec( pFanin, vCone ); + Vec_PtrPush( vCone, pObj ); +} + +/**Function************************************************************* + + Synopsis [Marks and collects the TFI cone of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_MfsWinMarkTfi( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vCone; + vCone = Vec_PtrAlloc( 100 ); + Abc_MfsWinMarkTfi_rec( pNode, vCone ); + return vCone; +} + +/**Function************************************************************* + + Synopsis [Marks the TFO of the collected nodes up to the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MfsWinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit ) +{ + Abc_Obj_t * pFanout; + int i; + if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit ) + return; + if ( Abc_NodeIsTravIdCurrent(pObj) ) + return; + Abc_NodeSetTravIdCurrent( pObj ); + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_MfsWinSweepLeafTfo_rec( pFanout, nLevelLimit ); +} + +/**Function************************************************************* + + Synopsis [Dereferences the node's MFFC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_MfsNodeDeref_rec( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pFanin; + int i, Counter = 1; + if ( Abc_ObjIsCi(pNode) ) + return 0; + Abc_NodeSetTravIdCurrent( pNode ); + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( pFanin->vFanouts.nSize > 0 ); + if ( --pFanin->vFanouts.nSize == 0 ) + Counter += Abc_MfsNodeDeref_rec( pFanin ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [References the node's MFFC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_MfsNodeRef_rec( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pFanin; + int i, Counter = 1; + if ( Abc_ObjIsCi(pNode) ) + return 0; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + if ( pFanin->vFanouts.nSize++ == 0 ) + Counter += Abc_MfsNodeRef_rec( pFanin ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Labels MFFC of the node with the current trav ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_MfsWinVisitMffc( Abc_Obj_t * pNode ) +{ + int Count1, Count2; + assert( Abc_ObjIsNode(pNode) ); + // dereference the node (mark with the current trav ID) + Count1 = Abc_MfsNodeDeref_rec( pNode ); + // reference it back + Count2 = Abc_MfsNodeRef_rec( pNode ); + assert( Count1 == Count2 ); + return Count1; +} + +/**Function************************************************************* + + Synopsis [Computes divisors and add them to nodes in the window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_MfsComputeDivisors( Mfs_Man_t * p, Abc_Obj_t * pNode, int nLevDivMax ) +{ + Vec_Ptr_t * vCone, * vDivs; + Abc_Obj_t * pObj, * pFanout, * pFanin; + int k, f, m; + int nDivsPlus = 0, nTrueSupp; + assert( p->vDivs == NULL ); + + // mark the TFI with the current trav ID + Abc_NtkIncrementTravId( pNode->pNtk ); + vCone = Abc_MfsWinMarkTfi( pNode ); + + // count the number of PIs + nTrueSupp = 0; + Vec_PtrForEachEntry( vCone, pObj, k ) + nTrueSupp += Abc_ObjIsCi(pObj); +// printf( "%d(%d) ", Vec_PtrSize(p->vSupp), m ); + + // mark with the current trav ID those nodes that should not be divisors: + // (1) the node and its TFO + // (2) the MFFC of the node + // (3) the node's fanins (these are treated as a special case) + Abc_NtkIncrementTravId( pNode->pNtk ); + Abc_MfsWinSweepLeafTfo_rec( pNode, nLevDivMax ); + Abc_MfsWinVisitMffc( pNode ); + Abc_ObjForEachFanin( pNode, pObj, k ) + Abc_NodeSetTravIdCurrent( pObj ); + + // at this point the nodes are marked with two trav IDs: + // nodes to be collected as divisors are marked with previous trav ID + // nodes to be avoided as divisors are marked with current trav ID + + // start collecting the divisors + vDivs = Vec_PtrAlloc( p->pPars->nDivMax ); + Vec_PtrForEachEntry( vCone, pObj, k ) + { + if ( !Abc_NodeIsTravIdPrevious(pObj) ) + continue; + if ( (int)pObj->Level > nLevDivMax ) + continue; + Vec_PtrPush( vDivs, pObj ); + if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax ) + break; + } + Vec_PtrFree( vCone ); + + // explore the fanouts of already collected divisors + if ( Vec_PtrSize(vDivs) < p->pPars->nDivMax ) + Vec_PtrForEachEntry( vDivs, pObj, k ) + { + // consider fanouts of this node + Abc_ObjForEachFanout( pObj, pFanout, f ) + { + // stop if there are too many fanouts + if ( f > 20 ) + break; + // skip nodes that are already added + if ( Abc_NodeIsTravIdPrevious(pFanout) ) + continue; + // skip nodes in the TFO or in the MFFC of node + if ( Abc_NodeIsTravIdCurrent(pFanout) ) + continue; + // skip COs + if ( !Abc_ObjIsNode(pFanout) ) + continue; + // skip nodes with large level + if ( (int)pFanout->Level >= nLevDivMax ) + continue; + // skip nodes whose fanins are not divisors + Abc_ObjForEachFanin( pFanout, pFanin, m ) + if ( !Abc_NodeIsTravIdPrevious(pFanin) ) + break; + if ( m < Abc_ObjFaninNum(pFanout) ) + continue; + // make sure this divisor in not among the nodes +// Vec_PtrForEachEntry( p->vNodes, pFanin, m ) +// assert( pFanout != pFanin ); + // add the node to the divisors + Vec_PtrPush( vDivs, pFanout ); +// Vec_PtrPush( p->vNodes, pFanout ); + Vec_PtrPushUnique( p->vNodes, pFanout ); + Abc_NodeSetTravIdPrevious( pFanout ); + nDivsPlus++; + if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax ) + break; + } + if ( Vec_PtrSize(vDivs) >= p->pPars->nDivMax ) + break; + } + + // sort the divisors by level in the increasing order + Vec_PtrSort( vDivs, Abc_NodeCompareLevelsIncrease ); + + // add the fanins of the node + Abc_ObjForEachFanin( pNode, pFanin, k ) + Vec_PtrPush( vDivs, pFanin ); + +/* + printf( "Node level = %d. ", Abc_ObjLevel(p->pNode) ); + Vec_PtrForEachEntryStart( vDivs, pObj, k, Vec_PtrSize(vDivs)-p->nDivsPlus ) + printf( "%d ", Abc_ObjLevel(pObj) ); + printf( "\n" ); +*/ +//printf( "%d ", p->nDivsPlus ); +// printf( "(%d+%d)(%d+%d+%d) ", Vec_PtrSize(p->vSupp), Vec_PtrSize(p->vNodes), +// nTrueSupp, Vec_PtrSize(vDivs)-nTrueSupp-nDivsPlus, nDivsPlus ); + return vDivs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |