mirror of https://github.com/YosysHQ/abc.git
Improvements to buffering and sizing.
This commit is contained in:
parent
cb99a2212d
commit
7a6f335ea6
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
@ -1237,6 +1252,94 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
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 []
|
||||
|
|
|
|||
|
|
@ -76,6 +76,28 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**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.]
|
||||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Reference in New Issue