Commit ae27704c by Alan Mishchenko

Integrated buffering and sizing.

parent ec4804aa
......@@ -215,9 +215,10 @@ int Scl_CommandPrintScl( Abc_Frame_t * pAbc, int argc, char **argv )
{
float Slew = 200;
float Gain = 100;
int fInvOnly = 0;
int c;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "SGh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "SGih" ) ) != EOF )
{
switch ( c )
{
......@@ -243,6 +244,9 @@ int Scl_CommandPrintScl( Abc_Frame_t * pAbc, int argc, char **argv )
if ( Gain <= 0.0 )
goto usage;
break;
case 'i':
fInvOnly ^= 1;
break;
case 'h':
goto usage;
default:
......@@ -256,14 +260,15 @@ int Scl_CommandPrintScl( Abc_Frame_t * pAbc, int argc, char **argv )
}
// save current library
Abc_SclPrintCells( (SC_Lib *)pAbc->pLibScl, Slew, Gain );
Abc_SclPrintCells( (SC_Lib *)pAbc->pLibScl, Slew, Gain, fInvOnly );
return 0;
usage:
fprintf( pAbc->Err, "usage: print_scl [-SG float] [-h]\n" );
fprintf( pAbc->Err, "usage: print_scl [-SG float] [-ih]\n" );
fprintf( pAbc->Err, "\t prints statistics of Liberty library\n" );
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
fprintf( pAbc->Err, "\t-i : toggle printing invs/bufs only [default = %s]\n", fInvOnly? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
return 1;
}
......
......@@ -236,18 +236,25 @@ void Abc_NtkPrintFanoutProfile( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i;
printf( "Obj %6d fanouts (%d): ", Abc_ObjId(pObj), Abc_ObjFanoutNum(pObj) );
printf( "Obj %6d fanouts (%d):\n", Abc_ObjId(pObj), Abc_ObjFanoutNum(pObj) );
Abc_ObjForEachFanout( pObj, pFanout, i )
printf( "%3d : time = %7.2f ps load = %7.2f ff\n", i, Bus_SclObjETime(pFanout), Bus_SclObjCin(pFanout) );
{
printf( "%3d : time = %7.2f ps load = %7.2f ff ", i, Bus_SclObjETime(pFanout), Bus_SclObjCin(pFanout) );
printf( "%s\n", Abc_ObjFaninPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ) ? "*" : " " );
}
printf( "\n" );
}
void Abc_NtkPrintFanoutProfileVec( Vec_Ptr_t * vFanouts )
void Abc_NtkPrintFanoutProfileVec( Abc_Obj_t * pObj, Vec_Ptr_t * vFanouts )
{
Abc_Obj_t * pFanout;
int i;
printf( "Fanout profile (%d):\n", Vec_PtrSize(vFanouts) );
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
printf( "%3d : time = %7.2f ps load = %7.2f ff\n", i, Bus_SclObjETime(pFanout), Bus_SclObjCin(pFanout) );
{
printf( "%3d : time = %7.2f ps load = %7.2f ff ", i, Bus_SclObjETime(pFanout), Bus_SclObjCin(pFanout) );
printf( "%s\n", (pObj && Abc_ObjFanoutNum(pObj) == Vec_PtrSize(vFanouts) && Abc_ObjFaninPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) )) ? "*" : " " );
}
printf( "\n" );
}
/**Function*************************************************************
......@@ -305,7 +312,7 @@ void Bus_SclCheckSortedFanout( Vec_Ptr_t * vFanouts )
if ( Bus_SclCompareFanouts( &pObj, &pNext ) != -1 )
{
printf( "Fanouts %d and %d are out of order.\n", i, i+1 );
Abc_NtkPrintFanoutProfileVec( vFanouts );
Abc_NtkPrintFanoutProfileVec( NULL, vFanouts );
return;
}
}
......@@ -344,8 +351,8 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
Bus_SclCheckSortedFanout( vFanouts );
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, iStop, Limit )
{
LoadWirePrev = p->vWireCaps ? Vec_FltEntry(p->vWireCaps, iStop) : 0;
LoadWireThis = p->vWireCaps ? Vec_FltEntry(p->vWireCaps, iStop+1) : 0;
LoadWirePrev = Abc_SclFindWireLoad( p->vWireCaps, iStop );
LoadWireThis = Abc_SclFindWireLoad( p->vWireCaps, iStop+1 );
Load += Bus_SclObjCin( pFanout ) - LoadWirePrev + LoadWireThis;
if ( Load > Target )
{
......@@ -406,13 +413,14 @@ void Abc_SclBufSize( Bus_Man_t * p )
if ( !p->pPars->fSizeOnly && (Abc_ObjFanoutNum(pObj) > p->pPars->nDegree || Load > GainGate * Cin) )
{
// add one or more inverters
// Abc_NtkPrintFanoutProfile( pObj );
Abc_NodeCollectFanouts( pObj, p->vFanouts );
Vec_PtrSort( p->vFanouts, (int(*)(void))Bus_SclCompareFanouts );
do
{
Abc_Obj_t * pInv;
if ( p->pPars->fVeryVerbose )
Abc_NtkPrintFanoutProfileVec( p->vFanouts );
if ( p->pPars->fVeryVerbose )//|| Vec_PtrSize(p->vFanouts) == Abc_ObjFanoutNum(pObj) )
Abc_NtkPrintFanoutProfileVec( pObj, p->vFanouts );
pInv = Abc_SclAddOneInv( p, pObj, p->vFanouts, GainInv );
if ( p->pPars->fVeryVerbose )
Abc_SclOneNodePrint( p, pInv );
......
......@@ -856,7 +856,7 @@ 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 ) > 5*BUF_SCALE/2 )
if ( Abc_BufEdgeSlack( p, pObj, pFanout ) > 7*BUF_SCALE/2 )
Vec_IntPush( p->vNonCrit, Abc_ObjId(pFanout) );
return Vec_IntSize(p->vNonCrit);
}
......@@ -983,8 +983,8 @@ Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBu
Buf_Man_t * p = Buf_ManStart( pNtk, FanMin, FanMax, fBufPis );
int i, Limit = ABC_INFINITY;
Abc_NtkLevel( pNtk );
if ( Abc_NtkNodeNum(pNtk) < 1000 )
fSkipDup = 1;
// if ( Abc_NtkNodeNum(pNtk) < 1000 )
// fSkipDup = 1;
for ( i = 0; i < Limit && Vec_QueSize(p->vQue); i++ )
Abc_BufPerformOne( p, Vec_QuePop(p->vQue), fSkipDup, fVerbose );
Buf_ManStop( p );
......
......@@ -914,7 +914,7 @@ SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area )
SeeAlso []
***********************************************************************/
void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pED, float * pPD )
void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pLD, float * pPD )
{
SC_Pair Load0, Load1, Load2;
SC_Pair ArrIn = { 0.0, 0.0 };
......@@ -937,59 +937,59 @@ void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float S
ArrOut1.rise = 0.5 * ArrOut1.rise + 0.5 * ArrOut1.fall;
ArrOut2.rise = 0.5 * ArrOut2.rise + 0.5 * ArrOut2.fall;
// get tangent
*pED = (ArrOut2.rise - ArrOut1.rise) / ((Load2.rise - Load1.rise) / SC_CellPinCap(pCell, iPin));
*pLD = (ArrOut2.rise - ArrOut1.rise) / ((Load2.rise - Load1.rise) / SC_CellPinCap(pCell, iPin));
// get constant
*pPD = ArrOut0.rise;
}
void Abc_SclComputeParametersCell( SC_Lib * p, SC_Cell * pCell, float Slew, float * pED, float * pPD )
void Abc_SclComputeParametersCell( SC_Lib * p, SC_Cell * pCell, float Slew, float * pLD, float * pPD )
{
SC_Pin * pPin;
float ED, PD, ed, pd;
float LD, PD, ld, pd;
int i;
ED = PD = ed = pd = 0;
LD = PD = ld = pd = 0;
SC_CellForEachPinIn( pCell, pPin, i )
{
Abc_SclComputeParametersPin( p, pCell, i, Slew, &ed, &pd );
ED += ed; PD += pd;
Abc_SclComputeParametersPin( p, pCell, i, Slew, &ld, &pd );
LD += ld; PD += pd;
}
*pED = ED / pCell->n_inputs;
*pLD = LD / pCell->n_inputs;
*pPD = PD / pCell->n_inputs;
}
void Abc_SclComputeParametersClass( SC_Lib * p, SC_Cell * pRepr, float Slew, float * pED, float * pPD )
void Abc_SclComputeParametersClass( SC_Lib * p, SC_Cell * pRepr, float Slew, float * pLD, float * pPD )
{
SC_Cell * pCell;
float ED, PD, ed, pd;
float LD, PD, ld, pd;
int i, Count = 0;
ED = PD = ed = pd = 0;
LD = PD = ld = pd = 0;
SC_RingForEachCell( pRepr, pCell, i )
{
Abc_SclComputeParametersCell( p, pCell, Slew, &ed, &pd );
ED += ed; PD += pd;
Abc_SclComputeParametersCell( p, pCell, Slew, &ld, &pd );
LD += ld; PD += pd;
Count++;
}
*pED = ED / Count;
*pLD = LD / Count;
*pPD = PD / Count;
}
void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float * pED, float * pPD )
void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float * pLD, float * pPD )
{
SC_Cell * pCell;
float ED, PD, ed, pd;
float LD, PD, ld, pd;
int i, Count = 0;
ED = PD = ed = pd = 0;
LD = PD = ld = pd = 0;
SC_RingForEachCell( pRepr, pCell, i )
{
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ed, &pd );
ED += ed; PD += pd;
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ld, &pd );
LD += ld; PD += pd;
Count++;
}
*pED = ED / Count;
*pLD = LD / Count;
*pPD = PD / Count;
}
float Abc_SclComputeDelayCellPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float Gain )
{
float ED = 0, PD = 0;
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ED, &PD );
return 0.01 * ED * Gain + PD;
float LD = 0, PD = 0;
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &LD, &PD );
return 0.01 * LD * Gain + PD;
}
float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float Gain )
{
......@@ -1062,11 +1062,11 @@ void Abc_SclMarkSkippedCells( SC_Lib * p )
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 )
void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain, int fInvOnly )
{
SC_Cell * pCell, * pRepr;
int i, k, nLength = 0;
float ED = 0, PD = 0;
float LD = 0, PD = 0;
assert( Vec_PtrSize(p->vCellClasses) > 0 );
printf( "Library \"%s\" ", p->pName );
printf( "has %d cells in %d classes. ",
......@@ -1080,6 +1080,8 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )
// print cells
SC_LibForEachCellClass( p, pRepr, k )
{
if ( fInvOnly && pRepr->n_inputs != 1 )
continue;
printf( "Class%3d : ", k );
printf( "Ins = %d ", pRepr->n_inputs );
printf( "Outs = %d", pRepr->n_outputs );
......@@ -1091,19 +1093,19 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )
printf( "\n" );
SC_RingForEachCell( pRepr, pCell, i )
{
Abc_SclComputeParametersCell( p, pCell, Slew, &ED, &PD );
printf( " %3d ", i+1 );
printf( "%s", pCell->fSkip ? "s" : " " );
Abc_SclComputeParametersCell( p, pCell, Slew, &LD, &PD );
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 );
printf( "D =%6.0f ps ", 0.01 * ED * Gain + PD );
printf( "ED =%6.0f ps ", ED );
printf( "PD =%6.0f ps ", PD );
printf( "C =%5.1f ff ", SC_CellPinCapAve(pCell) );
printf( "Cm =%5.0f ff ", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );
printf( "Sm =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );
printf( "%-*s ", nLength, pCell->pName );
printf( "%2d ", pCell->drive_strength );
printf( "A =%8.2f ", pCell->area );
printf( "D =%5.0f ps ", 0.01 * LD * Gain + PD );
printf( "LD =%5.0f ps ", LD );
printf( "PD =%5.0f ps ", PD );
printf( "C =%5.1f ff ", SC_CellPinCapAve(pCell) );
printf( "Cm =%5.0f ff ", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );
printf( "Sm =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );
printf( "\n" );
}
}
......
......@@ -588,7 +588,7 @@ extern void Abc_SclHashCells( SC_Lib * p );
extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern int Abc_SclClassCellNum( SC_Cell * pClass );
extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain );
extern void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain, int fInvOnly );
extern SC_Cell * Abc_SclFindInvertor( SC_Lib * p, int fFindBuff );
extern SC_Cell * Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );
extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
......
......@@ -132,15 +132,16 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise);
p->ReportDelay = maxDelay;
printf( "WireLoad model = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
printf( "Gates =%7d ", Abc_NtkNodeNum(p->pNtk) );
printf( "(%5.1f %%) ", Abc_SclGetAverageSize(p->pNtk) );
printf( "Cave =%5.1f ff ", p->EstLoadAve );
printf( "Area =%12.2f ", Abc_SclGetTotalArea(p->pNtk) );
printf( "(%5.1f %%) ", 100.0 * Abc_SclCountMinSize(p->pLib, p->pNtk, 0) / Abc_NtkNodeNum(p->pNtk) );
printf( "Delay =%9.2f ps ", maxDelay );
printf( "(%5.1f %%) ", 100.0 * Abc_SclCountNearCriticalNodes(p) / Abc_NtkNodeNum(p->pNtk) );
printf( " \n" );
printf( "WireLoad = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
printf( "Gates =%7d ", Abc_NtkNodeNum(p->pNtk) );
printf( "(%5.1f %%) ", 100.0 * Abc_SclGetBufInvCount(p->pNtk) / Abc_NtkNodeNum(p->pNtk) );
printf( "Cap =%5.1f ff ", p->EstLoadAve );
printf( "(%5.1f %%) ", Abc_SclGetAverageSize(p->pNtk) );
printf( "Area =%12.2f ", Abc_SclGetTotalArea(p->pNtk) );
printf( "(%5.1f %%) ", 100.0 * Abc_SclCountMinSize(p->pLib, p->pNtk, 0) / Abc_NtkNodeNum(p->pNtk) );
printf( "Delay =%9.2f ps ", maxDelay );
printf( "(%5.1f %%) ", 100.0 * Abc_SclCountNearCriticalNodes(p) / Abc_NtkNodeNum(p->pNtk) );
printf( " \n" );
if ( fShowAll )
{
// printf( "Timing information for all nodes: \n" );
......
......@@ -400,6 +400,14 @@ static inline void Abc_SclConeClean( SC_Man * p, Vec_Int_t * vCone )
SeeAlso []
***********************************************************************/
static inline int Abc_SclGetBufInvCount( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, Count = 0;
Abc_NtkForEachNode( pNtk, pObj, i )
Count += (Abc_ObjFaninNum(pObj) == 1);
return Count;
}
static inline float Abc_SclGetAverageSize( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
......@@ -477,6 +485,7 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
{
static char FileNameOld[1000] = {0};
static int nNodesOld, nAreaOld, nDelayOld;
static abctime clk = 0;
FILE * pTable;
pTable = fopen( pFileName, "a+" );
if ( strcmp( FileNameOld, p->pNtk->pName ) )
......@@ -489,6 +498,7 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
fprintf( pTable, "%d ", (nNodesOld = Abc_NtkNodeNum(p->pNtk)) );
fprintf( pTable, "%d ", (nAreaOld = (int)p->SumArea) );
fprintf( pTable, "%d ", (nDelayOld = (int)p->ReportDelay) );
clk = Abc_Clock();
}
else
{
......@@ -496,8 +506,8 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
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*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
}
// fprintf( pTable, "%.2f ", 1.0*Time/CLOCKS_PER_SEC );
fclose( pTable );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment