diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-06 12:22:13 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-06 12:22:13 -0700 |
commit | 7a6f335ea6c4be27479b94ac68fca57e813acd7c (patch) | |
tree | f1f32b8063caebdee521bce7fb2fab7c8a63e025 /src | |
parent | cb99a2212df80a324ffae67c804f50079336dcd4 (diff) | |
download | abc-7a6f335ea6c4be27479b94ac68fca57e813acd7c.tar.gz abc-7a6f335ea6c4be27479b94ac68fca57e813acd7c.tar.bz2 abc-7a6f335ea6c4be27479b94ac68fca57e813acd7c.zip |
Improvements to buffering and sizing.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abc.h | 4 | ||||
-rw-r--r-- | src/map/scl/scl.c | 115 | ||||
-rw-r--r-- | src/map/scl/sclBuffer.c | 76 | ||||
-rw-r--r-- | src/map/scl/sclSize.c | 112 | ||||
-rw-r--r-- | src/map/scl/sclSize.h | 3 |
5 files changed, 290 insertions, 20 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index bd0c5bba..a9178f38 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -387,8 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Ab static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); } static inline Abc_Obj_t * Abc_ObjFromLit( Abc_Ntk_t * p, int iLit ) { return Abc_ObjNotCond( Abc_NtkObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit) ); } static inline int Abc_ObjToLit( Abc_Obj_t * p ) { return Abc_Var2Lit( Abc_ObjId(Abc_ObjRegular(p)), Abc_ObjIsComplement(p) ); } -static inline int Abc_ObjFaninPhase( Abc_Obj_t * p, int i ) { assert(p->pNtk->vPhases); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1; } -static inline void Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); } +static inline int Abc_ObjFaninPhase( Abc_Obj_t * p, int i ) { assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1; } +static inline void Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); } // checking the AIG node types static inline int Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; } diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index e9c4d22c..e2b3d1ce 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -37,10 +37,11 @@ static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandUpsize ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandDnsize ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandMinsize ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandMaxsize ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandUpsize ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandDnsize ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandBsize ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv ); //////////////////////////////////////////////////////////////////////// @@ -73,6 +74,7 @@ void Scl_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "SCL mapping", "maxsize", Scl_CommandMaxsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "dnsize", Scl_CommandDnsize, 1 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "bsize", Scl_CommandBsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_buf", Scl_CommandPrintBuf, 0 ); } void Scl_End( Abc_Frame_t * pAbc ) @@ -571,17 +573,18 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtkRes; - int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis; + int FanMin, FanMax, FanMaxR, fAddInvs, fUseInvs, fBufPis; int c, fVerbose; int fOldAlgo = 0; FanMin = 6; FanMax = 14; + FanMaxR = 0; fAddInvs = 0; fUseInvs = 0; fBufPis = 0; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NMRaixpvh" ) ) != EOF ) { switch ( c ) { @@ -607,6 +610,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( FanMax < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" ); + goto usage; + } + FanMaxR = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( FanMaxR < 0 ) + goto usage; + break; case 'a': fOldAlgo ^= 1; break; @@ -649,7 +663,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fAddInvs ) pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose ); else if ( fOldAlgo ) - pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); + pNtkRes = Abc_SclPerformBuffering( pNtk, FanMaxR, FanMax, fUseInvs, fVerbose ); else pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose ); if ( pNtkRes == NULL ) @@ -662,10 +676,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pAbc->Err, "usage: buffer [-NM num] [-aixpvh]\n" ); + fprintf( pAbc->Err, "usage: buffer [-NMR num] [-aixpvh]\n" ); fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" ); 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-R <num> : the max allowed fanout count of root node [default = %d]\n", FanMaxR ); fprintf( pAbc->Err, "\t-a : toggle using old algorithm [default = %s]\n", fOldAlgo? "yes": "no" ); fprintf( pAbc->Err, "\t-i : toggle adding interters instead of buffering [default = %s]\n", fAddInvs? "yes": "no" ); fprintf( pAbc->Err, "\t-x : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" ); @@ -1248,6 +1263,94 @@ usage: SeeAlso [] ***********************************************************************/ +int Scl_CommandBsize( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + extern Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads ); + Abc_Ntk_t * pNtkRes; + int c; + int fUseWireLoads = 1; + int nTreeCRatio = 0; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Xch" ) ) != EOF ) + { + switch ( c ) + { + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" ); + goto usage; + } + nTreeCRatio = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nTreeCRatio < 0 ) + goto usage; + break; + case 'c': + fUseWireLoads ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( Abc_FrameReadNtk(pAbc) == NULL ) + { + fprintf( pAbc->Err, "There is no current network.\n" ); + return 1; + } + if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) ) + { + fprintf( pAbc->Err, "The current network is not mapped.\n" ); + return 1; + } + if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) ) + { + fprintf( pAbc->Err, "The current network is not in a topo order (run \"topo\").\n" ); + return 1; + } + if ( pAbc->pLibScl == NULL ) + { + fprintf( pAbc->Err, "There is no Liberty library available.\n" ); + return 1; + } + if ( Abc_FrameReadNtk(pAbc)->vPhases == 0 ) + { + fprintf( pAbc->Err, "There is no phases available.\n" ); + return 1; + } + pNtkRes = Abc_SclBuffSizeStep( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nTreeCRatio, fUseWireLoads ); + if ( pNtkRes == NULL ) + { + Abc_Print( -1, "The command has failed.\n" ); + return 1; + } + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: bsize [-X num] [-ch]\n" ); + fprintf( pAbc->Err, "\t performs STA using Liberty library\n" ); + fprintf( pAbc->Err, "\t-X : min Cout/Cave ratio for tree estimations [default = %d]\n", nTreeCRatio ); + fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c index 9dc43499..83a305bd 100644 --- a/src/map/scl/sclBuffer.c +++ b/src/map/scl/sclBuffer.c @@ -78,6 +78,28 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t /**Function************************************************************* + Synopsis [Make sure fanins of gates are not duplicated.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclReportDupFanins( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj, * pFanin, * pFanin2; + int i, k, k2; + Abc_NtkForEachNode( pNtk, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjForEachFanin( pObj, pFanin2, k2 ) + if ( k != k2 && pFanin == pFanin2 ) + printf( "Node %d has dup fanin %d.\n", i, Abc_ObjId(pFanin) ); +} + +/**Function************************************************************* + Synopsis [Removes buffers and inverters.] Description [] @@ -244,6 +266,7 @@ Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ) pNtkNew = Abc_NtkDupDfs( pNtk ); if ( fVerbose ) printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) ); + Abc_SclReportDupFanins( pNtkNew ); return pNtkNew; } @@ -292,6 +315,20 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) SeeAlso [] ***********************************************************************/ +void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i; + assert( Abc_SclObjIsBufInv(pObj) ); + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + if ( Abc_SclObjIsBufInv(pFanout) ) + Abc_NodeInvUpdateFanPolarity( pFanout ); + else + Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); + } +} + int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) { int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2); @@ -364,12 +401,16 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn Vec_PtrFree( vFanouts ); Abc_ObjAddFanin( pBuffer, pObj ); pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); + if ( fUseInvs ) + Abc_NodeInvUpdateFanPolarity( pBuffer ); return pBuffer; } -void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) +void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose ) { + Vec_Ptr_t * vFanouts; + Abc_Obj_t * pBuffer; Abc_Obj_t * pFanout; - int i; + int i, nOldFanNum; if ( Abc_NodeIsTravIdCurrent( pObj ) ) return; Abc_NodeSetTravIdCurrent( pObj ); @@ -379,14 +420,32 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, in 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 ); + Abc_SclPerformBuffering_rec( pFanout, DegreeR, Degree, fUseInvs, fVerbose ); // perform buffering as long as needed + nOldFanNum = Abc_ObjFanoutNum(pObj); while ( Abc_ObjFanoutNum(pObj) > Degree ) Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose ); + // add yet another level of buffers + if ( DegreeR && nOldFanNum > DegreeR ) + { + if ( fUseInvs ) + pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL ); + else + pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL ); + vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) ); + Abc_NodeCollectFanouts( pObj, vFanouts ); + Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) + Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); + Vec_PtrFree( vFanouts ); + Abc_ObjAddFanin( pBuffer, pObj ); + pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); + if ( fUseInvs ) + Abc_NodeInvUpdateFanPolarity( pBuffer ); + } // 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 ) +Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose ) { Vec_Int_t * vCiLevs; Abc_Ntk_t * pNew; @@ -394,7 +453,11 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in int i; assert( Abc_NtkHasMapping(p) ); if ( fUseInvs ) + { printf( "Warning!!! Using inverters instead of buffers.\n" ); + if ( p->vPhases == NULL ) + printf( "The phases are not given. The result will not verify.\n" ); + } // remember CI levels vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); Abc_NtkForEachCi( p, pObj, i ) @@ -402,13 +465,16 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in // perform buffering Abc_NtkIncrementTravId( p ); Abc_NtkForEachCi( p, pObj, i ) - Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose ); + Abc_SclPerformBuffering_rec( pObj, DegreeR, 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 ); + // if phases are present + if ( p->vPhases ) + Vec_IntFillExtra( p->vPhases, Abc_NtkObjNumMax(p), 0 ); // duplication in topo order pNew = Abc_NtkDupDfs( p ); Abc_SclCheckNtk( pNew, fVerbose ); diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 2efa22ee..86c81589 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -20,6 +20,7 @@ #include "sclSize.h" #include "map/mio/mio.h" +#include "misc/vec/vecWec.h" ABC_NAMESPACE_IMPL_START @@ -121,7 +122,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise printf( "Cout =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); printf( "Cmax =%5.0f ff ", pCell ? SC_CellPin(pCell, pCell->n_inputs)->max_out_cap : 0.0 ); printf( "G =%5.1f ", pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 ); - printf( "SL =%5.1f ps", Abc_SclObjSlack(p, pObj) ); + printf( "SL =%5.1f ps", Abc_SclObjSlackPs(p, pObj) ); printf( "\n" ); } void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) @@ -201,6 +202,11 @@ static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * SC_Pair * pDepOut = Abc_SclObjDept( p, pObj ); Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut ); } +static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj ) +{ +// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); + return 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax); +} void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept ) { SC_Timings * pRTime; @@ -213,8 +219,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept ) float LoadFall = pLoad->fall; float DeptRise = 0; float DeptFall = 0; -// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); - float Value = 0.5 * (pLoad->fall + pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); + float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0; if ( Abc_ObjIsCo(pObj) ) { if ( !fDept ) @@ -325,8 +330,6 @@ void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fRe p->pSlack[i] = Abc_MaxFloat( 0.0, Abc_SclObjGetSlack(p, pObj, D) ); } } - if ( p->nEstNodes ) - printf( "Estimated nodes = %d.\n", p->nEstNodes ); } /**Function************************************************************* @@ -626,7 +629,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset ) printf( "%6.0f ps) ", Abc_SclObjTimePs(p, pObj, 0) ); printf( "l =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, 0 ) ); printf( "s =%5.0f ps ", Abc_SclObjSlewPs(p, pObj, 0 ) ); - printf( "sl =%5.0f ps ", Abc_SclObjSlack(p, pObj) ); + printf( "sl =%5.0f ps ", Abc_SclObjSlackPs(p, pObj) ); if ( nOffset == 0 ) { printf( "L =%5.0f ff ", SC_LibCapFf( p->pLib, Abc_SclCountNonBufferLoad(p, pObj) ) ); @@ -698,6 +701,103 @@ int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ) return 1; } +/**Function************************************************************* + + Synopsis [Select nodes that need to be buffered.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk ) +{ + Vec_Wec_t * vSplits; + Vec_Int_t * vCrits, * vNonCrits, * vLevel; + Abc_Obj_t * pObj, * pFanout; + int i, k; + assert( p->EstLoadMax > 0 ); + vCrits = Vec_IntAlloc( 1000 ); + vNonCrits = Vec_IntAlloc( 1000 ); + vSplits = Vec_WecAlloc( 1000 ); + Abc_NtkForEachNodeCi( pNtk, pObj, i ) + { + if ( Abc_SclObjLoadValue(p, pObj) < 1 ) + { +// printf( "%d ", Abc_ObjFanoutNum(pObj) ); + continue; + } +/* + printf( "%d : %.0f ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) ); + Abc_ObjForEachFanout( pObj, pFanout, k ) + printf( "%.1f ", Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p, pFanout)) ); + printf( "\n" ); +*/ + // skip non-critical nodes +// if ( Abc_SclObjSlack(p, pObj) > 100 ) +// continue; + // collect non-critical fanouts of the node + Vec_IntClear( vCrits ); + Vec_IntClear( vNonCrits ); + Abc_ObjForEachFanout( pObj, pFanout, k ) + if ( Abc_SclObjSlack(p, pFanout) < 100 ) + Vec_IntPush( vCrits, Abc_ObjId(pFanout) ); + else + Vec_IntPush( vNonCrits, Abc_ObjId(pFanout) ); +// assert( Vec_IntSize(vNonCrits) < Abc_ObjFanoutNum(pObj) ); + // skip if there is nothing to split +// if ( Vec_IntSize(vNonCrits) < 2 ) +// continue; + // remember them + vLevel = Vec_WecPushLevel( vSplits ); + Vec_IntPush( vLevel, i ); + Vec_IntAppend( vLevel, vCrits ); + // remember them + vLevel = Vec_WecPushLevel( vSplits ); + Vec_IntPush( vLevel, i ); + Vec_IntAppend( vLevel, vNonCrits ); + } + Vec_IntFree( vCrits ); + Vec_IntFree( vNonCrits ); + // print out + printf( "Collected %d nodes to split.\n", Vec_WecSize(vSplits) ); + return vSplits; +} +void Abc_SclPerformSplit( SC_Man * p, Abc_Ntk_t * pNtk, Vec_Wec_t * vSplits ) +{ + Abc_Obj_t * pObj, * pObjInv, * pFanout; + Vec_Int_t * vLevel; + int i, k; + assert( pNtk->vPhases != NULL ); + Vec_WecForEachLevel( vSplits, vLevel, i ) + { + pObj = Abc_NtkObj( pNtk, Vec_IntEntry(vLevel, 0) ); + pObjInv = Abc_NtkCreateNodeInv( pNtk, pObj ); + Abc_NtkForEachObjVecStart( vLevel, pNtk, pFanout, k, 1 ) + { + Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); + Abc_ObjPatchFanin( pFanout, pObj, pObjInv ); + } + } + Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 ); +} +Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads ) +{ + SC_Man * p; + Vec_Wec_t * vSplits; + p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 1, 0, nTreeCRatio ); + Abc_SclTimeNtkPrint( p, 0, 0 ); + if ( p->nEstNodes ) + printf( "Estimated nodes = %d.\n", p->nEstNodes ); + vSplits = Abc_SclSelectSplitNodes( p, pNtk ); + Abc_SclPerformSplit( p, pNtk, vSplits ); + Vec_WecFree( vSplits ); + Abc_SclManFree( p ); + return Abc_NtkDupDfs( pNtk ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index c467ba1c..9656b55a 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -122,6 +122,7 @@ static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) static inline double Abc_SclObjLoadFf( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibCapFf( p->pLib, fRise ? Abc_SclObjLoad(p, pObj)->rise : Abc_SclObjLoad(p, pObj)->fall); } static inline double Abc_SclObjTimePs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjTime(p, pObj)->rise : Abc_SclObjTime(p, pObj)->fall); } static inline double Abc_SclObjSlewPs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjSlew(p, pObj)->rise : Abc_SclObjSlew(p, pObj)->fall); } +static inline double Abc_SclObjSlackPs( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibTimePs(p->pLib, Abc_SclObjSlack(p, pObj)); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -397,7 +398,7 @@ extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ); extern Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ); extern Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ); 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 ); +extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose ); extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose ); /*=== sclDnsize.c ===============================================================*/ extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); |