diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-07-29 18:55:13 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-07-29 18:55:13 -0700 |
commit | 1dca7458f3739ec6e2af7670cc340794c28b747d (patch) | |
tree | 3b09cf0da63eb3a5bc6271644d948765b7ab2953 | |
parent | 4c6804c3aea08f6aec693c686ec409191e983ca4 (diff) | |
download | abc-1dca7458f3739ec6e2af7670cc340794c28b747d.tar.gz abc-1dca7458f3739ec6e2af7670cc340794c28b747d.tar.bz2 abc-1dca7458f3739ec6e2af7670cc340794c28b747d.zip |
Improved buffering.
-rw-r--r-- | abclib.dsp | 4 | ||||
-rw-r--r-- | src/map/mapper/mapperMatch.c | 2 | ||||
-rw-r--r-- | src/map/scl/module.make | 1 | ||||
-rw-r--r-- | src/map/scl/scl.c | 35 | ||||
-rw-r--r-- | src/map/scl/sclBuff.c | 238 | ||||
-rw-r--r-- | src/map/scl/sclBuffer.c | 301 | ||||
-rw-r--r-- | src/map/scl/sclLib.c | 55 | ||||
-rw-r--r-- | src/map/scl/sclLib.h | 1 | ||||
-rw-r--r-- | src/map/scl/sclSize.h | 34 |
9 files changed, 334 insertions, 337 deletions
@@ -2451,10 +2451,6 @@ SOURCE=.\src\map\scl\scl.h # End Source File # Begin Source File -SOURCE=.\src\map\scl\sclBuff.c -# End Source File -# Begin Source File - SOURCE=.\src\map\scl\sclBuffer.c # End Source File # Begin Source File diff --git a/src/map/mapper/mapperMatch.c b/src/map/mapper/mapperMatch.c index a59af3d3..f062e4da 100644 --- a/src/map/mapper/mapperMatch.c +++ b/src/map/mapper/mapperMatch.c @@ -200,7 +200,7 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase ) for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext ) { // limit gate sizes based on fanout count - if ( (pNode->nRefs > 8 && pCut->nLeaves > 2) || (pNode->nRefs > 4 && pCut->nLeaves > 3) ) + if ( (pNode->nRefs > 3 && pCut->nLeaves > 2) || (pNode->nRefs > 1 && pCut->nLeaves > 3) ) continue; pMatch = pCut->M + fPhase; if ( pMatch->pSupers == NULL ) diff --git a/src/map/scl/module.make b/src/map/scl/module.make index 12f30ae1..6063a3de 100644 --- a/src/map/scl/module.make +++ b/src/map/scl/module.make @@ -1,5 +1,4 @@ SRC += src/map/scl/scl.c \ - src/map/scl/sclBuff.c \ src/map/scl/sclBuffer.c \ src/map/scl/sclDnsize.c \ src/map/scl/sclLib.c \ diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index ea8731c4..23457f7c 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -554,14 +554,15 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtkRes; - int Degree, fUseInvs; + int FanMin, FanMax, fUseInvs; int c, fVerbose; int fOldAlgo = 0; - Degree = 4; - fUseInvs = 0; - fVerbose = 0; + FanMin = 6; + FanMax = 14; + fUseInvs = 0; + fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Naivh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NMaivh" ) ) != EOF ) { switch ( c ) { @@ -571,9 +572,20 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" ); goto usage; } - Degree = atoi(argv[globalUtilOptind]); + FanMin = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( Degree < 0 ) + if ( FanMin < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by a positive integer.\n" ); + goto usage; + } + FanMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( FanMax < 0 ) goto usage; break; case 'a': @@ -605,9 +617,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) // modify the current network if ( fOldAlgo ) - pNtkRes = Abc_SclPerformBuffering( pNtk, Degree, fUseInvs, fVerbose ); + pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); else - pNtkRes = Abc_SclBufPerform( pNtk, fVerbose ); + pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fVerbose ); if ( pNtkRes == NULL ) { Abc_Print( -1, "The command has failed.\n" ); @@ -618,9 +630,10 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pAbc->Err, "usage: buffer [-N num] [-aivh]\n" ); + fprintf( pAbc->Err, "usage: buffer [-NM num] [-aivh]\n" ); fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" ); - fprintf( pAbc->Err, "\t-N <num> : the max allowed fanout count of node/buffer [default = %d]\n", Degree ); + fprintf( pAbc->Err, "\t-N <num> : the min fanout considered by the algorithm [default = %d]\n", FanMin ); + fprintf( pAbc->Err, "\t-M <num> : the max allowed fanout count of node/buffer [default = %d]\n", FanMax ); fprintf( pAbc->Err, "\t-a : toggle using old algorithm [default = %s]\n", fOldAlgo? "yes": "no" ); fprintf( pAbc->Err, "\t-i : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); diff --git a/src/map/scl/sclBuff.c b/src/map/scl/sclBuff.c deleted file mode 100644 index a26b0f87..00000000 --- a/src/map/scl/sclBuff.c +++ /dev/null @@ -1,238 +0,0 @@ -/**CFile**************************************************************** - - FileName [sclBuff.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Standard-cell library representation.] - - Synopsis [Buffering algorithms.] - - Author [Alan Mishchenko, Niklas Een] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - August 24, 2012.] - - Revision [$Id: sclBuff.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "sclSize.h" -#include "map/mio/mio.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Make sure the network is in topo order without dangling nodes.] - - Description [Returns 1 iff the network is fine.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) -{ - Abc_Obj_t * pObj, * pFanin; - int i, k, fFlag = 1; - Abc_NtkIncrementTravId( p ); - Abc_NtkForEachCi( p, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - Abc_NtkForEachNode( p, pObj, i ) - { - Abc_ObjForEachFanin( pObj, pFanin, k ) - if ( !Abc_NodeIsTravIdCurrent( pFanin ) ) - printf( "obj %d and its fanin %d are not in the topo order\n", Abc_ObjId(pObj), Abc_ObjId(pFanin) ), fFlag = 0; - Abc_NodeSetTravIdCurrent( pObj ); - if ( Abc_ObjFanoutNum(pObj) == 0 ) - printf( "node %d has no fanout\n", Abc_ObjId(pObj) ), fFlag = 0; - if ( !fFlag ) - break; - } - if ( fFlag && fVerbose ) - printf( "The network is in topo order and no dangling nodes.\n" ); - return fFlag; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_SclCheckNtk2( Abc_Ntk_t * p ) -{ - Abc_Obj_t * pObj, * pFanout; - int i, k; - Abc_NtkStartReverseLevels( p, 0 ); - Abc_NtkForEachNode( p, pObj, i ) - { - if ( Abc_ObjFanoutNum(pObj) <= 3 ) - continue; - printf( "Node %5d (%2d) : fans = %3d ", i, Abc_ObjLevel(pObj), Abc_ObjFanoutNum(pObj) ); - Abc_ObjForEachFanout( pObj, pFanout, k ) - printf( "%d ", Abc_ObjReverseLevel(pFanout) ); - printf( "\n" ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs buffering of the mapped network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) -{ - int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2); - if ( Diff < 0 ) - return -1; - if ( Diff > 0 ) - return 1; - Diff = (*pp1)->Id - (*pp2)->Id; // needed to make qsort() platform-infependent - if ( Diff < 0 ) - return -1; - if ( Diff > 0 ) - return 1; - return 0; -} -int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, Level = 0; - Abc_ObjForEachFanout( pObj, pFanout, i ) - Level = Abc_MaxInt( Level, pFanout->Level ); - return Level + 1; -} -Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) -{ - Vec_Ptr_t * vFanouts; - Abc_Obj_t * pBuffer, * pFanout; - int i, Degree0 = Degree; - assert( Abc_ObjFanoutNum(pObj) > Degree ); - // collect fanouts and sort by reverse level - vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) ); - Abc_NodeCollectFanouts( pObj, vFanouts ); - Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels ); - // select the first Degree fanouts - if ( fUseInvs ) - pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL ); - else - pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL ); - // check if it is possible to not increase level - if ( Vec_PtrSize(vFanouts) < 2 * Degree ) - { - Abc_Obj_t * pFanPrev = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Vec_PtrSize(vFanouts)-1-Degree); - Abc_Obj_t * pFanThis = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Degree-1); - Abc_Obj_t * pFanLast = (Abc_Obj_t *)Vec_PtrEntryLast(vFanouts); - if ( Abc_ObjLevel(pFanThis) == Abc_ObjLevel(pFanLast) && - Abc_ObjLevel(pFanPrev) < Abc_ObjLevel(pFanThis) ) - { - // find the first one whose level is the same as last - Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) - if ( Abc_ObjLevel(pFanout) == Abc_ObjLevel(pFanLast) ) - break; - assert( i < Vec_PtrSize(vFanouts) ); - if ( i > 1 ) - Degree = i; - } - // make the last two more well-balanced - if ( Degree == Degree0 && Degree > Vec_PtrSize(vFanouts) - Degree ) - Degree = Vec_PtrSize(vFanouts)/2 + (Vec_PtrSize(vFanouts) & 1); - assert( Degree <= Degree0 ); - } - // select fanouts - Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, Degree ) - Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); - if ( fVerbose ) - { - printf( "%5d : ", Abc_ObjId(pObj) ); - Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) - printf( "%d%s ", Abc_ObjLevel(pFanout), i == Degree-1 ? " " : "" ); - printf( "\n" ); - } - Vec_PtrFree( vFanouts ); - Abc_ObjAddFanin( pBuffer, pObj ); - pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); - return pBuffer; -} -void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) -{ - Abc_Obj_t * pFanout; - int i; - if ( Abc_NodeIsTravIdCurrent( pObj ) ) - return; - Abc_NodeSetTravIdCurrent( pObj ); - pObj->Level = 0; - if ( Abc_ObjIsCo(pObj) ) - return; - assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) ); - // buffer fanouts and collect reverse levels - Abc_ObjForEachFanout( pObj, pFanout, i ) - Abc_SclPerformBuffering_rec( pFanout, Degree, fUseInvs, fVerbose ); - // perform buffering as long as needed - while ( Abc_ObjFanoutNum(pObj) > Degree ) - Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose ); - // compute the new level of the node - pObj->Level = Abc_SclComputeReverseLevel( pObj ); -} -Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ) -{ - Vec_Int_t * vCiLevs; - Abc_Ntk_t * pNew; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkHasMapping(p) ); - if ( fUseInvs ) - printf( "Warning!!! Using inverters instead of buffers.\n" ); - // remember CI levels - vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); - Abc_NtkForEachCi( p, pObj, i ) - Vec_IntPush( vCiLevs, Abc_ObjLevel(pObj) ); - // perform buffering - Abc_NtkIncrementTravId( p ); - Abc_NtkForEachCi( p, pObj, i ) - Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose ); - // recompute logic levels - Abc_NtkForEachCi( p, pObj, i ) - pObj->Level = Vec_IntEntry( vCiLevs, i ); - Abc_NtkForEachNode( p, pObj, i ) - Abc_ObjLevelNew( pObj ); - Vec_IntFree( vCiLevs ); - // duplication in topo order - pNew = Abc_NtkDupDfs( p ); - Abc_SclCheckNtk( pNew, fVerbose ); -// Abc_NtkDelete( pNew ); - return pNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c index f25ea277..d9afdbe5 100644 --- a/src/map/scl/sclBuffer.c +++ b/src/map/scl/sclBuffer.c @@ -59,6 +59,7 @@ struct Buf_Man_t_ int nDuplicate; int nBranch0; int nBranch1; + int nBranchCrit; }; static inline int Abc_BufNodeArr( Buf_Man_t * p, Abc_Obj_t * pObj ) { return Vec_IntEntry( p->vArr, Abc_ObjId(pObj) ); } @@ -76,6 +77,177 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t /**Function************************************************************* + Synopsis [Make sure the network is in topo order without dangling nodes.] + + Description [Returns 1 iff the network is fine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) +{ + Abc_Obj_t * pObj, * pFanin; + int i, k, fFlag = 1; + Abc_NtkIncrementTravId( p ); + Abc_NtkForEachCi( p, pObj, i ) + Abc_NodeSetTravIdCurrent( pObj ); + Abc_NtkForEachNode( p, pObj, i ) + { + Abc_ObjForEachFanin( pObj, pFanin, k ) + if ( !Abc_NodeIsTravIdCurrent( pFanin ) ) + printf( "obj %d and its fanin %d are not in the topo order\n", Abc_ObjId(pObj), Abc_ObjId(pFanin) ), fFlag = 0; + Abc_NodeSetTravIdCurrent( pObj ); + if ( Abc_ObjFanoutNum(pObj) == 0 ) + printf( "node %d has no fanout\n", Abc_ObjId(pObj) ), fFlag = 0; + if ( !fFlag ) + break; + } + if ( fFlag && fVerbose ) + printf( "The network is in topo order and no dangling nodes.\n" ); + return fFlag; +} + +/**Function************************************************************* + + Synopsis [Performs buffering of the mapped network (old code).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) +{ + int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2); + if ( Diff < 0 ) + return -1; + if ( Diff > 0 ) + return 1; + Diff = (*pp1)->Id - (*pp2)->Id; // needed to make qsort() platform-infependent + if ( Diff < 0 ) + return -1; + if ( Diff > 0 ) + return 1; + return 0; +} +int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, Level = 0; + Abc_ObjForEachFanout( pObj, pFanout, i ) + Level = Abc_MaxInt( Level, pFanout->Level ); + return Level + 1; +} +Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) +{ + Vec_Ptr_t * vFanouts; + Abc_Obj_t * pBuffer, * pFanout; + int i, Degree0 = Degree; + assert( Abc_ObjFanoutNum(pObj) > Degree ); + // collect fanouts and sort by reverse level + vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) ); + Abc_NodeCollectFanouts( pObj, vFanouts ); + Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels ); + // select the first Degree fanouts + if ( fUseInvs ) + pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL ); + else + pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL ); + // check if it is possible to not increase level + if ( Vec_PtrSize(vFanouts) < 2 * Degree ) + { + Abc_Obj_t * pFanPrev = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Vec_PtrSize(vFanouts)-1-Degree); + Abc_Obj_t * pFanThis = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Degree-1); + Abc_Obj_t * pFanLast = (Abc_Obj_t *)Vec_PtrEntryLast(vFanouts); + if ( Abc_ObjLevel(pFanThis) == Abc_ObjLevel(pFanLast) && + Abc_ObjLevel(pFanPrev) < Abc_ObjLevel(pFanThis) ) + { + // find the first one whose level is the same as last + Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) + if ( Abc_ObjLevel(pFanout) == Abc_ObjLevel(pFanLast) ) + break; + assert( i < Vec_PtrSize(vFanouts) ); + if ( i > 1 ) + Degree = i; + } + // make the last two more well-balanced + if ( Degree == Degree0 && Degree > Vec_PtrSize(vFanouts) - Degree ) + Degree = Vec_PtrSize(vFanouts)/2 + (Vec_PtrSize(vFanouts) & 1); + assert( Degree <= Degree0 ); + } + // select fanouts + Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, Degree ) + Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); + if ( fVerbose ) + { + printf( "%5d : ", Abc_ObjId(pObj) ); + Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) + printf( "%d%s ", Abc_ObjLevel(pFanout), i == Degree-1 ? " " : "" ); + printf( "\n" ); + } + Vec_PtrFree( vFanouts ); + Abc_ObjAddFanin( pBuffer, pObj ); + pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); + return pBuffer; +} +void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) +{ + Abc_Obj_t * pFanout; + int i; + if ( Abc_NodeIsTravIdCurrent( pObj ) ) + return; + Abc_NodeSetTravIdCurrent( pObj ); + pObj->Level = 0; + if ( Abc_ObjIsCo(pObj) ) + return; + assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) ); + // buffer fanouts and collect reverse levels + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_SclPerformBuffering_rec( pFanout, Degree, fUseInvs, fVerbose ); + // perform buffering as long as needed + while ( Abc_ObjFanoutNum(pObj) > Degree ) + Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose ); + // compute the new level of the node + pObj->Level = Abc_SclComputeReverseLevel( pObj ); +} +Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ) +{ + Vec_Int_t * vCiLevs; + Abc_Ntk_t * pNew; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkHasMapping(p) ); + if ( fUseInvs ) + printf( "Warning!!! Using inverters instead of buffers.\n" ); + // remember CI levels + vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); + Abc_NtkForEachCi( p, pObj, i ) + Vec_IntPush( vCiLevs, Abc_ObjLevel(pObj) ); + // perform buffering + Abc_NtkIncrementTravId( p ); + Abc_NtkForEachCi( p, pObj, i ) + Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose ); + // recompute logic levels + Abc_NtkForEachCi( p, pObj, i ) + pObj->Level = Vec_IntEntry( vCiLevs, i ); + Abc_NtkForEachNode( p, pObj, i ) + Abc_ObjLevelNew( pObj ); + Vec_IntFree( vCiLevs ); + // duplication in topo order + pNew = Abc_NtkDupDfs( p ); + Abc_SclCheckNtk( pNew, fVerbose ); +// Abc_NtkDelete( pNew ); + return pNew; +} + + + +/**Function************************************************************* + Synopsis [] Description [] @@ -134,8 +306,10 @@ void Abc_BufAddToQue( Buf_Man_t * p, Abc_Obj_t * pObj ) if ( Abc_ObjFanoutNum(pObj) < p->nFanMin ) return; Vec_FltWriteEntry( p->vCounts, Abc_ObjId(pObj), Abc_ObjFanoutNum(pObj) ); - assert( !Vec_QueIsMember(p->vQue, Abc_ObjId(pObj)) ); - Vec_QuePush( p->vQue, Abc_ObjId(pObj) ); + if ( Vec_QueIsMember(p->vQue, Abc_ObjId(pObj)) ) + Vec_QueUpdate( p->vQue, Abc_ObjId(pObj) ); + else + Vec_QuePush( p->vQue, Abc_ObjId(pObj) ); } @@ -241,7 +415,7 @@ void Abc_BufUpdateDep( Buf_Man_t * p, Abc_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk ) +Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk, int FanMin, int FanMax ) { Buf_Man_t * p; Abc_Obj_t * pObj; @@ -249,8 +423,8 @@ Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk ) int i; p = ABC_CALLOC( Buf_Man_t, 1 ); p->pNtk = pNtk; - p->nFanMin = 6; -// p->nFanMax = 16; + p->nFanMin = FanMin; + p->nFanMax = FanMax; // allocate arrays p->nObjStart = Abc_NtkObjNumMax(p->pNtk); p->nObjAlloc = (6 * Abc_NtkObjNumMax(p->pNtk) / 3) + 100; @@ -279,15 +453,14 @@ Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk ) Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pObj, i ) Abc_BufComputeDep( p, pObj ); Abc_BufUpdateGlobal( p ); +// Abc_NtkForEachNode( p->pNtk, pObj, i ) +// printf( "%4d : %4d %4d\n", i, Abc_BufNodeArr(p, pObj), Abc_BufNodeDep(p, pObj) ); // create fanout queue Abc_NtkForEachCi( p->pNtk, pObj, i ) Abc_BufAddToQue( p, pObj ); Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) Abc_BufAddToQue( p, pObj ); Vec_PtrFree( vNodes ); - // print everything -// Abc_NtkForEachNode( p->pNtk, pObj, i ) -// printf( "%4d : %4d %4d\n", i, Abc_BufNodeArr(p, pObj), Abc_BufNodeDep(p, pObj) ); p->vDelays = Vec_IntAlloc( 100 ); p->vOrder = Vec_IntAlloc( 100 ); p->vNonCrit = Vec_IntAlloc( 100 ); @@ -297,8 +470,8 @@ Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk ) } void Buf_ManStop( Buf_Man_t * p ) { - printf( "Sep = %d. Dup = %d. Br0 = %d. Br1 = %d. ", - p->nSeparate, p->nDuplicate, p->nBranch0, p->nBranch1 ); + printf( "Sep = %d. Dup = %d. Br0 = %d. Br1 = %d. BrC = %d. ", + p->nSeparate, p->nDuplicate, p->nBranch0, p->nBranch1, p->nBranchCrit ); printf( "Orig = %d. Add = %d. Rem = %d.\n", p->nObjStart, Abc_NtkObjNumMax(p->pNtk) - p->nObjStart, p->nObjAlloc - Abc_NtkObjNumMax(p->pNtk) ); @@ -337,17 +510,14 @@ Vec_Int_t * Abc_BufSortByDelay( Buf_Man_t * p, int iPivot ) Abc_ObjForEachFanout( pObj, pFanout, i ) { int Slack = Abc_BufEdgeSlack(p, pObj, pFanout); - if ( Slack < 0 ) - printf( "%d ", Slack ); + assert( Slack >= 0 ); Vec_IntPush( p->vDelays, Abc_MaxInt(0, Slack) ); } pOrder = Abc_QuickSortCost( Vec_IntArray(p->vDelays), Vec_IntSize(p->vDelays), 0 ); -//Vec_IntPrint( p->vDelays ); Vec_IntClear( p->vOrder ); for ( i = 0; i < Vec_IntSize(p->vDelays); i++ ) Vec_IntPush( p->vOrder, Abc_ObjId(Abc_ObjFanout(pObj, pOrder[i])) ); ABC_FREE( pOrder ); - // print // for ( i = 0; i < Vec_IntSize(p->vDelays); i++ ) // printf( "%5d - %5d ", Vec_IntEntry(p->vOrder, i), Abc_BufEdgeSlack(p, pObj, Abc_NtkObj(p->pNtk, Vec_IntEntry(p->vOrder, i))) ); return p->vOrder; @@ -379,6 +549,34 @@ void Abc_BufPrintOne( Buf_Man_t * p, int iPivot ) SeeAlso [] ***********************************************************************/ +void Abc_BufReplaceBufsByInvs( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj, * pInv; + int i, Counter = 0; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( !Abc_NodeIsBuf(pObj) ) + continue; + assert( pObj->pData == Mio_LibraryReadBuf((Mio_Library_t *)pNtk->pManFunc) ); + pObj->pData = Mio_LibraryReadInv((Mio_Library_t *)pNtk->pManFunc); + pInv = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanin0(pObj) ); + Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), pInv ); + Counter++; + } + printf( "Replaced %d buffers by invertor pairs.\n", Counter ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_BufComputeAverage( Buf_Man_t * p, int iPivot, Vec_Int_t * vOrder ) { Abc_Obj_t * pObj, * pFanout; @@ -388,17 +586,6 @@ int Abc_BufComputeAverage( Buf_Man_t * p, int iPivot, Vec_Int_t * vOrder ) Average += Abc_BufEdgeSlack( p, pObj, pFanout ); return Average / Vec_IntSize(vOrder); } -int Abc_BufCountNonCritical_( Buf_Man_t * p, int iPivot, Vec_Int_t * vOrder ) -{ - Abc_Obj_t * pObj, * pFanout; - int i; - Vec_IntClear( p->vNonCrit ); - pObj = Abc_NtkObj( p->pNtk, iPivot ); - Abc_NtkForEachObjVec( vOrder, p->pNtk, pFanout, i ) - if ( Abc_BufEdgeSlack( p, pObj, pFanout ) > 5*BUF_SCALE/2 ) - Vec_IntPush( p->vNonCrit, Abc_ObjId(pFanout) ); - return Vec_IntSize(p->vNonCrit); -} Abc_Obj_t * Abc_BufFindNonBuffDriver( Buf_Man_t * p, Abc_Obj_t * pObj ) { return (Abc_ObjIsNode(pObj) && Abc_NodeIsBuf(pObj)) ? Abc_BufFindNonBuffDriver(p, Abc_ObjFanin0(pObj)) : pObj; @@ -421,35 +608,30 @@ int Abc_BufCountNonCritical( Buf_Man_t * p, Abc_Obj_t * pObj ) int i; Vec_IntClear( p->vNonCrit ); Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( Abc_BufEdgeSlack( p, pObj, pFanout ) > 3*BUF_SCALE ) + if ( Abc_BufEdgeSlack( p, pObj, pFanout ) > 5*BUF_SCALE/2 ) Vec_IntPush( p->vNonCrit, Abc_ObjId(pFanout) ); return Vec_IntSize(p->vNonCrit); } void Abc_BufPerformOne( Buf_Man_t * p, int iPivot, int fVerbose ) { Abc_Obj_t * pObj, * pFanout; - Vec_Int_t * vOrder; - int Fastest, Slowest, Average; int i, j, nCrit, nNonCrit; int DelayMax = p->DelayMax; + assert( Abc_NtkObjNumMax(p->pNtk) + 30 < p->nObjAlloc ); pObj = Abc_NtkObj( p->pNtk, iPivot ); +// assert( Vec_FltEntry(p->vCounts, iPivot) == (float)Abc_ObjFanoutNum(pObj) ); nNonCrit = Abc_BufCountNonCritical( p, pObj ); nCrit = Abc_ObjFanoutNum(pObj) - nNonCrit; if ( fVerbose ) { -vOrder = Abc_BufSortByDelay( p, iPivot ); //Abc_BufPrintOne( p, iPivot ); -Fastest = Abc_BufEdgeSlack( p, pObj, Abc_NtkObj(p->pNtk, Vec_IntEntry(vOrder,0)) ); -Slowest = Abc_BufEdgeSlack( p, pObj, Abc_NtkObj(p->pNtk, Vec_IntEntryLast(vOrder)) ); -Average = Abc_BufComputeAverage( p, iPivot, vOrder ); -printf( "FI =%2d. FO =%4d. ", Abc_ObjFaninNum(pObj), Abc_ObjFanoutNum(pObj) ); -printf( "Fastest =%5d. Slowest =%5d. Ave =%5d. Crit =%3d. NonCrit =%3d. ", Fastest, Slowest, Average, nCrit, nNonCrit ); +printf( "ObjId = %6d : %-10s FI = %d. FO =%4d. Crit =%4d. ", + Abc_ObjId(pObj), Mio_GateReadName((Mio_Gate_t *)pObj->pData), Abc_ObjFaninNum(pObj), Abc_ObjFanoutNum(pObj), nCrit ); } - // decide based on these - assert( Abc_NtkObjNumMax(p->pNtk) + 30 < p->nObjAlloc ); + // consider three cases if ( nCrit > 0 && nNonCrit > 1 ) { - // separate using buffer + // (1) both critical and non-critical are present - split them by adding buffer Abc_Obj_t * pBuffer = Abc_NtkCreateNodeBuf( p->pNtk, pObj ); Abc_NtkForEachObjVec( p->vNonCrit, p->pNtk, pFanout, i ) Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); @@ -463,10 +645,9 @@ printf( "Fastest =%5d. Slowest =%5d. Ave =%5d. Crit =%3d. NonCrit =%3d. ", Fas if ( fVerbose ) printf( "Adding buffer\n" ); } - - else if ( nNonCrit < 2 && Abc_ObjFanoutNum(pObj) > 4 && Abc_ObjFanoutNum(pObj) < 12 && Abc_ObjIsNode(pObj) ) + else if ( nCrit > 0 && Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > p->nFanMin )//&& Abc_ObjFaninNum(pObj) < 2 ) { - // duplicate + // (2) only critical are present - duplicate Abc_Obj_t * pClone = Abc_NtkDupObj( p->pNtk, pObj, 0 ); Abc_ObjForEachFanin( pObj, pFanout, i ) Abc_ObjAddFanin( pClone, pFanout ); @@ -480,26 +661,24 @@ printf( "Adding buffer\n" ); Abc_BufUpdateDep( p, pClone ); Abc_BufAddToQue( p, pObj ); Abc_BufAddToQue( p, pClone ); + Abc_ObjForEachFanin( pObj, pFanout, i ) + Abc_BufAddToQue( p, pFanout ); p->nDuplicate++; - // add fanins to queue if ( fVerbose ) printf( "Duplicating node\n" ); } - - else if ( Abc_ObjFanoutNum(pObj) >= 12 ) + else if ( (nCrit > 0 && Abc_ObjFanoutNum(pObj) > 8) || Abc_ObjFanoutNum(pObj) > p->nFanMax ) { - // branch (consider buffer) -// int nFan = Abc_ObjFanoutNum(pObj); - int nFan = 64; - double Res = pow(nFan, 0.34); - int Temp = (int)pow(Abc_ObjFanoutNum(pObj), 0.34); - int nDegree = Abc_MinInt( 4, (int)pow(Abc_ObjFanoutNum(pObj), 0.34) ); - int n1Degree = Abc_ObjFanoutNum(pObj) / nDegree + 1; - int n1Number = Abc_ObjFanoutNum(pObj) % nDegree; - int nFirst = n1Degree * n1Number; -// Abc_Obj_t * pNonBuff = Abc_BufFindNonBuffDriver( p, pObj ); - // create inverters + // (2) only critical or only non-critical - add buffer/inverter tree + int nDegree, n1Degree, n1Number, nFirst; int iFirstBuf = Abc_NtkObjNumMax( p->pNtk ); +// nDegree = Abc_MinInt( 3, (int)pow(Abc_ObjFanoutNum(pObj), 0.34) ); + nDegree = Abc_MinInt( 10, (int)pow(Abc_ObjFanoutNum(pObj), 0.5) ); + n1Degree = Abc_ObjFanoutNum(pObj) / nDegree + 1; + n1Number = Abc_ObjFanoutNum(pObj) % nDegree; + nFirst = n1Degree * n1Number; + p->nBranchCrit += (nCrit > 0); + // create inverters Abc_NodeCollectFanouts( pObj, p->vFanouts ); if ( Abc_ObjIsNode(pObj) && Abc_NodeIsBuf(pObj) ) { @@ -520,16 +699,13 @@ printf( "Adding %d inverters\n", nDegree ); if ( fVerbose ) printf( "Adding %d buffers\n", nDegree ); } - // create inverters + // connect inverters Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanouts, pFanout, i ) { j = (i < nFirst) ? i/n1Degree : n1Number + ((i - nFirst)/(n1Degree - 1)); assert( j >= 0 && j < nDegree ); Abc_ObjPatchFanin( pFanout, pObj, Abc_NtkObj(p->pNtk, iFirstBuf + j) ); } - // remove node -// if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 ) -// Abc_NtkDeleteObj_rec( pObj, 1 ); // update timing for ( i = 0; i < nDegree; i++ ) Abc_BufCreateEdges( p, Abc_NtkObj(p->pNtk, iFirstBuf + i) ); @@ -548,19 +724,18 @@ printf( "Doing nothing\n" ); // if ( DelayMax != p->DelayMax ) // printf( "%d (%.2f) ", p->DelayMax, 1.0 * p->DelayMax * p->DelayInv / BUF_SCALE ); } -Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int fVerbose ) +Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fVerbose ) { Abc_Ntk_t * pNew; - Buf_Man_t * p = Buf_ManStart( pNtk ); + Buf_Man_t * p = Buf_ManStart( pNtk, FanMin, FanMax ); int i, Limit = ABC_INFINITY; -// int i, Limit = 3; for ( i = 0; i < Limit && Vec_QueSize(p->vQue); i++ ) Abc_BufPerformOne( p, Vec_QuePop(p->vQue), fVerbose ); Buf_ManStop( p ); - // duplication in topo order +// Abc_BufReplaceBufsByInvs( pNtk ); + // duplicate network in topo order pNew = Abc_NtkDupDfs( pNtk ); Abc_SclCheckNtk( pNew, fVerbose ); -// Abc_NtkDelete( pNew ); return pNew; } diff --git a/src/map/scl/sclLib.c b/src/map/scl/sclLib.c index 3e6f330f..a1572095 100644 --- a/src/map/scl/sclLib.c +++ b/src/map/scl/sclLib.c @@ -711,14 +711,16 @@ void Abc_SclHashCells( SC_Lib * p ) } int Abc_SclCellFind( SC_Lib * p, char * pName ) { - return *Abc_SclHashLookup( p, pName ); + int *pPlace = Abc_SclHashLookup( p, pName ); + return pPlace ? *pPlace : -1; } int Abc_SclClassCellNum( SC_Cell * pClass ) { SC_Cell * pCell; int i, Count = 0; SC_RingForEachCell( pClass, pCell, i ) - Count++; + if ( !pCell->fSkip ) + Count++; return Count; } @@ -955,14 +957,15 @@ float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float float Delay = 0; int i, Count = 0; SC_RingForEachCell( pRepr, pCell, i ) - Count++; - SC_RingForEachCell( pRepr, pCell, i ) { - if ( pRepr == pCell && Count > 1 ) // skip the first gate + if ( pCell->fSkip ) continue; +// if ( pRepr == pCell ) // skip the first gate +// continue; Delay += Abc_SclComputeDelayCellPin( p, pCell, iPin, Slew, Gain ); + Count++; } - return Delay / Abc_MaxInt(1, Count-1); + return Delay / Abc_MaxInt(1, Count); } float Abc_SclComputeAreaClass( SC_Cell * pRepr ) { @@ -971,6 +974,8 @@ float Abc_SclComputeAreaClass( SC_Cell * pRepr ) int i, Count = 0; SC_RingForEachCell( pRepr, pCell, i ) { + if ( pCell->fSkip ) + continue; Area += pCell->area; Count++; } @@ -988,6 +993,35 @@ float Abc_SclComputeAreaClass( SC_Cell * pRepr ) SeeAlso [] ***********************************************************************/ +void Abc_SclMarkSkippedCells( SC_Lib * p ) +{ + char FileName[1000]; + char Buffer[1000], * pName; + SC_Cell * pCell; + FILE * pFile; + int CellId, nSkipped = 0; + sprintf( FileName, "%s.skip", p->pName ); + pFile = fopen( FileName, "rb" ); + if ( pFile == NULL ) + return; + while ( fgets( Buffer, 999, pFile ) != NULL ) + { + pName = strtok( Buffer, "\r\n\t " ); + if ( pName == NULL ) + continue; + CellId = Abc_SclCellFind( p, pName ); + if ( CellId == -1 ) + { + printf( "Cannot find cell \"%s\" in the library \"%s\".\n", pName, p->pName ); + continue; + } + pCell = SC_LibCell( p, CellId ); + pCell->fSkip = 1; + nSkipped++; + } + fclose( pFile ); + printf( "Marked %d cells for skipping in the library \"%s\".\n", nSkipped, p->pName ); +} void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ) { SC_Cell * pCell, * pRepr; @@ -998,6 +1032,7 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ) printf( "has %d cells in %d classes. ", Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellClasses) ); printf( "Delay estimate is based on slew %.2f and gain %.2f.\n", Slew, Gain ); + Abc_SclMarkSkippedCells( p ); // find the longest name SC_LibForEachCellClass( p, pRepr, k ) SC_RingForEachCell( pRepr, pCell, i ) @@ -1017,7 +1052,9 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ) SC_RingForEachCell( pRepr, pCell, i ) { Abc_SclComputeParametersCell( p, pCell, Slew, &ED, &PD ); - printf( " %3d : ", i+1 ); + printf( " %3d ", i+1 ); + printf( "%s", pCell->fSkip ? "s" : " " ); + printf( " : " ); printf( "%-*s ", nLength, pCell->pName ); printf( "%2d ", pCell->drive_strength ); printf( "A =%8.2f ", pCell->area ); @@ -1027,7 +1064,7 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ) printf( "C =%5.1f ff ", Abc_SclGatePinCapAve(p, pCell) ); printf( "Lm =%5.1f ff ", 0.01 * Gain * Abc_SclGatePinCapAve(p, pCell) ); // printf( "MaxS =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew ); - printf( "Lm2 =%5.0f ff", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap ); + printf( "Lm2 =%5.0f ff ", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap ); printf( "\n" ); } } @@ -1052,6 +1089,7 @@ Vec_Str_t * Abc_SclDeriveGenlibStr( SC_Lib * p, float Slew, float Gain, int nGat SC_Cell * pRepr; SC_Pin * pPin; int i, k, Count = 2; + Abc_SclMarkSkippedCells( p ); vStr = Vec_StrAlloc( 1000 ); Vec_StrPrintStr( vStr, "GATE _const0_ 0.00 z=CONST0;\n" ); Vec_StrPrintStr( vStr, "GATE _const1_ 0.00 z=CONST1;\n" ); @@ -1078,6 +1116,7 @@ Vec_Str_t * Abc_SclDeriveGenlibStr( SC_Lib * p, float Slew, float Gain, int nGat SC_CellForEachPinIn( pRepr, pPin, k ) { float Delay = Abc_SclComputeDelayClassPin( p, pRepr, k, Slew, Gain ); + assert( Delay > 0 ); Vec_StrPrintStr( vStr, " PIN " ); sprintf( Buffer, "%-4s", pPin->pName ); Vec_StrPrintStr( vStr, Buffer ); diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h index a087f124..08433f8f 100644 --- a/src/map/scl/sclLib.h +++ b/src/map/scl/sclLib.h @@ -166,6 +166,7 @@ struct SC_Cell_ { char * pName; int Id; + int fSkip; // skip this cell during genlib computation int seq; // -- set to TRUE by parser if a sequential element int unsupp; // -- set to TRUE by parser if cell contains information we cannot handle float area; diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 0dad7ddb..f8d5fcbe 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -358,25 +358,37 @@ static inline SC_Cell * Abc_SclObjResiable( SC_Man * p, Abc_Obj_t * pObj, int fU ***********************************************************************/ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time ) { + static char FileNameOld[1000] = {0}; + static int nNodesOld, nAreaOld, nDelayOld; FILE * pTable; pTable = fopen( pFileName, "a+" ); - fprintf( pTable, "%s ", p->pNtk->pName ); - fprintf( pTable, "%d ", Abc_NtkPiNum(p->pNtk) ); - fprintf( pTable, "%d ", Abc_NtkPoNum(p->pNtk) ); - fprintf( pTable, "%d ", Abc_NtkNodeNum(p->pNtk) ); - fprintf( pTable, "%d ", (int)p->SumArea ); - fprintf( pTable, "%d ", (int)p->ReportDelay ); -// fprintf( pTable, "%.2f ", 1.0*Time/CLOCKS_PER_SEC ); - fprintf( pTable, "\n" ); + if ( strcmp( FileNameOld, p->pNtk->pName ) ) + { + sprintf( FileNameOld, "%s", p->pNtk->pName ); + fprintf( pTable, "\n" ); + fprintf( pTable, "%s ", p->pNtk->pName ); + fprintf( pTable, "%d ", Abc_NtkPiNum(p->pNtk) ); + fprintf( pTable, "%d ", Abc_NtkPoNum(p->pNtk) ); + fprintf( pTable, "%d ", (nNodesOld = Abc_NtkNodeNum(p->pNtk)) ); + fprintf( pTable, "%d ", (nAreaOld = (int)p->SumArea) ); + fprintf( pTable, "%d ", (nDelayOld = (int)p->ReportDelay) ); + } + else + { + fprintf( pTable, " " ); + fprintf( pTable, "%.1f ", 100.0 * Abc_NtkNodeNum(p->pNtk) / nNodesOld ); + fprintf( pTable, "%.1f ", 100.0 * (int)p->SumArea / nAreaOld ); + fprintf( pTable, "%.1f ", 100.0 * (int)p->ReportDelay / nDelayOld ); + } + // fprintf( pTable, "%.2f ", 1.0*Time/CLOCKS_PER_SEC ); fclose( pTable ); } -/*=== sclBuff.c ===============================================================*/ +/*=== sclBuffer.c ===============================================================*/ extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ); -/*=== sclBuffer.c ===============================================================*/ -extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int fVerbose ); +extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fVerbose ); /*=== sclDnsize.c ===============================================================*/ extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); /*=== sclLoad.c ===============================================================*/ |