mirror of https://github.com/YosysHQ/abc.git
Integrated buffering and sizing.
This commit is contained in:
parent
fbdaf2075f
commit
4af5587cbf
|
|
@ -705,17 +705,20 @@ usage:
|
|||
***********************************************************************/
|
||||
int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
Abc_Ntk_t * pNtkRes;
|
||||
int c, GainRatio, nDegree, fSizeOnly, fBufPis, fAddBufs, fVerbose;
|
||||
GainRatio = 150;
|
||||
nDegree = 4;
|
||||
fSizeOnly = 0;
|
||||
fAddBufs = 0;
|
||||
fBufPis = 0;
|
||||
fVerbose = 0;
|
||||
SC_BusPars Pars, * pPars = &Pars;
|
||||
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
int c;
|
||||
memset( pPars, 0, sizeof(SC_BusPars) );
|
||||
pPars->GainRatio = 100;
|
||||
pPars->Slew = 500;
|
||||
pPars->nDegree = 4;
|
||||
pPars->fSizeOnly = 0;
|
||||
pPars->fAddBufs = 0;
|
||||
pPars->fBufPis = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "GNsbpvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "GSNsbpvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -725,9 +728,20 @@ int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
GainRatio = atoi(argv[globalUtilOptind]);
|
||||
pPars->GainRatio = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( GainRatio < 0 )
|
||||
if ( pPars->GainRatio < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'S':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-S\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->Slew = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->Slew < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'N':
|
||||
|
|
@ -736,22 +750,25 @@ int Scl_CommandBufSize( 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;
|
||||
}
|
||||
nDegree = atoi(argv[globalUtilOptind]);
|
||||
pPars->nDegree = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nDegree < 0 )
|
||||
if ( pPars->nDegree < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 's':
|
||||
fSizeOnly ^= 1;
|
||||
pPars->fSizeOnly ^= 1;
|
||||
break;
|
||||
case 'b':
|
||||
fAddBufs ^= 1;
|
||||
pPars->fAddBufs ^= 1;
|
||||
break;
|
||||
case 'p':
|
||||
fBufPis ^= 1;
|
||||
pPars->fBufPis ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
pPars->fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
|
|
@ -770,13 +787,13 @@ int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "This command can only be applied to a logic network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !fSizeOnly && !fAddBufs && pNtk->vPhases == NULL )
|
||||
if ( !pPars->fSizeOnly && !pPars->fAddBufs && pNtk->vPhases == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Fanin phase information is not avaiable.\n" );
|
||||
return 1;
|
||||
}
|
||||
// modify the current network
|
||||
pNtkRes = Abc_SclBufSizePerform( pNtk, (SC_Lib *)pAbc->pLibScl, GainRatio, nDegree, fSizeOnly, fAddBufs, fBufPis, fVerbose );
|
||||
pNtkRes = Abc_SclBufSizePerform( pNtk, (SC_Lib *)pAbc->pLibScl, pPars );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
Abc_Print( -1, "The command has failed.\n" );
|
||||
|
|
@ -787,14 +804,16 @@ int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: bufsize [-GM num] [-sbpvh]\n" );
|
||||
fprintf( pAbc->Err, "usage: bufsize [-GSM num] [-sbpvwh]\n" );
|
||||
fprintf( pAbc->Err, "\t performs buffering and sizing and mapped network\n" );
|
||||
fprintf( pAbc->Err, "\t-G <num> : target gain percentage [default = %d]\n", GainRatio );
|
||||
fprintf( pAbc->Err, "\t-M <num> : the maximum fanout degree [default = %d]\n", nDegree );
|
||||
fprintf( pAbc->Err, "\t-s : toggle performing only sizing [default = %s]\n", fSizeOnly? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-b : toggle using buffers instead of inverters [default = %s]\n", fAddBufs? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-p : toggle buffering primary inputs [default = %s]\n", fBufPis? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-G <num> : target gain percentage [default = %d]\n", pPars->GainRatio );
|
||||
fprintf( pAbc->Err, "\t-S <num> : target slew in pisoseconds [default = %d]\n", pPars->Slew );
|
||||
fprintf( pAbc->Err, "\t-M <num> : the maximum fanout degree [default = %d]\n", pPars->nDegree );
|
||||
fprintf( pAbc->Err, "\t-s : toggle performing only sizing [default = %s]\n", pPars->fSizeOnly? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-b : toggle using buffers instead of inverters [default = %s]\n", pPars->fAddBufs? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-p : toggle buffering primary inputs [default = %s]\n", pPars->fBufPis? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-w : toggle printing more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,14 +31,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
typedef struct Bus_Man_t_ Bus_Man_t;
|
||||
struct Bus_Man_t_
|
||||
{
|
||||
// parameters
|
||||
float Gain; // target gain
|
||||
int nDegree; // max branching factor
|
||||
int fSizeOnly; // perform only sizing
|
||||
int fAddBufs; // add buffers
|
||||
int fBufPis; // use CI buffering
|
||||
int fVerbose; // verbose
|
||||
// user data
|
||||
SC_BusPars * pPars; // parameters
|
||||
Abc_Ntk_t * pNtk; // user's network
|
||||
// library
|
||||
SC_Lib * pLib; // cell library
|
||||
|
|
@ -73,19 +67,14 @@ static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float time ) { f
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fSizeOnly, int fAddBufs, int fBufPis, int fVerbose )
|
||||
Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, SC_BusPars * pPars )
|
||||
{
|
||||
Bus_Man_t * p;
|
||||
p = ABC_CALLOC( Bus_Man_t, 1 );
|
||||
p->Gain = 0.01 * GainRatio;
|
||||
p->nDegree = nDegree;
|
||||
p->fSizeOnly = fSizeOnly;
|
||||
p->fAddBufs = fAddBufs;
|
||||
p->fBufPis = fBufPis;
|
||||
p->fVerbose = fVerbose;
|
||||
p->pPars = pPars;
|
||||
p->pNtk = pNtk;
|
||||
p->pLib = pLib;
|
||||
p->pInv = Abc_SclFindInvertor(pLib, fAddBufs)->pAve;
|
||||
p->pInv = Abc_SclFindInvertor(pLib, pPars->fAddBufs)->pAve;
|
||||
p->vCins = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
|
||||
p->vLoads = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
|
||||
p->vDepts = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
|
||||
|
|
@ -187,7 +176,7 @@ float Abc_NtkComputeNodeLoad( Abc_Obj_t * pObj )
|
|||
Bus_SclObjSetLoad( pObj, Load );
|
||||
return Load;
|
||||
}
|
||||
float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj )
|
||||
float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj, float Slew )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
float Load, Dept, Edge;
|
||||
|
|
@ -199,7 +188,7 @@ float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj )
|
|||
continue;
|
||||
Load = Bus_SclObjLoad( pFanout );
|
||||
Dept = Bus_SclObjDept( pFanout );
|
||||
Edge = Scl_LibPinArrivalEstimate( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
|
||||
Edge = Scl_LibPinArrivalEstimate( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Slew, Load );
|
||||
Bus_SclObjUpdateDept( pObj, Dept + Edge );
|
||||
assert( Edge > 0 );
|
||||
// assert( Load > 0 );
|
||||
|
|
@ -294,7 +283,7 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
|
|||
break;
|
||||
}
|
||||
// create inverter
|
||||
if ( p->fAddBufs )
|
||||
if ( p->pPars->fAddBufs )
|
||||
pInv = Abc_NtkCreateNodeBuf( p->pNtk, NULL );
|
||||
else
|
||||
pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
|
||||
|
|
@ -313,7 +302,7 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
|
|||
Bus_SclObjSetCin( pInv, SC_CellPinCap(pCellNew, 0) );
|
||||
// update timing
|
||||
Abc_NtkComputeNodeLoad( pInv );
|
||||
Abc_NtkComputeNodeDept( pInv );
|
||||
Abc_NtkComputeNodeDept( pInv, p->pPars->Slew );
|
||||
// update phases
|
||||
if ( p->pNtk->vPhases && Abc_SclIsInv(pInv) )
|
||||
Abc_NodeInvUpdateFanPolarity( pInv );
|
||||
|
|
@ -325,8 +314,8 @@ void Abc_SclBufSize( Bus_Man_t * p )
|
|||
Vec_Ptr_t * vFanouts;
|
||||
Abc_Obj_t * pObj, * pInv;
|
||||
abctime clk = Abc_Clock();
|
||||
float Dept, DeptMax = 0;
|
||||
float Load, Cin;
|
||||
float Gain = 0.01 * p->pPars->GainRatio;
|
||||
float Load, Cin, Dept, DeptMax = 0;
|
||||
int i;
|
||||
vFanouts = Vec_PtrAlloc( 100 );
|
||||
Abc_SclMioGates2SclGates( p->pLib, p->pNtk );
|
||||
|
|
@ -339,29 +328,29 @@ void Abc_SclBufSize( Bus_Man_t * p )
|
|||
pCell = Abc_SclObjCell( pObj );
|
||||
Cin = SC_CellPinCapAve( pCell->pAve );
|
||||
// consider upsizing the gate
|
||||
if ( !p->fSizeOnly && Load > p->Gain * Cin )
|
||||
if ( !p->pPars->fSizeOnly && Load > Gain * Cin )
|
||||
{
|
||||
// add one or more inverters
|
||||
Abc_NodeCollectFanouts( pObj, vFanouts );
|
||||
Vec_PtrSort( vFanouts, (int(*)(void))Bus_SclCompareFanouts );
|
||||
do
|
||||
{
|
||||
pInv = Abc_SclAddOneInv( p, pObj, vFanouts, p->Gain, p->nDegree );
|
||||
pInv = Abc_SclAddOneInv( p, pObj, vFanouts, Gain, p->pPars->nDegree );
|
||||
Bus_SclInsertFanout( vFanouts, pInv );
|
||||
Load = Bus_SclObjCin( pInv );
|
||||
}
|
||||
while ( Vec_PtrSize(vFanouts) > 1 || Load > p->Gain * Cin );
|
||||
while ( Vec_PtrSize(vFanouts) > 1 || Load > Gain * Cin );
|
||||
// connect last inverter
|
||||
assert( Abc_ObjFanin0(pInv) == NULL );
|
||||
Abc_ObjAddFanin( pInv, pObj );
|
||||
Bus_SclObjSetLoad( pObj, Load );
|
||||
}
|
||||
// create cell
|
||||
pCellNew = Abc_SclFindSmallestGate( pCell, Load / p->Gain );
|
||||
pCellNew = Abc_SclFindSmallestGate( pCell, Load / Gain );
|
||||
Abc_SclObjSetCell( pObj, pCellNew );
|
||||
Dept = Abc_NtkComputeNodeDept( pObj );
|
||||
Dept = Abc_NtkComputeNodeDept( pObj, p->pPars->Slew );
|
||||
DeptMax = Abc_MaxFloat( DeptMax, Dept );
|
||||
if ( p->fVerbose )
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
printf( "Node %7d : ", i );
|
||||
printf( "%12s ", pCellNew->pName );
|
||||
|
|
@ -373,20 +362,21 @@ void Abc_SclBufSize( Bus_Man_t * p )
|
|||
}
|
||||
Abc_SclSclGates2MioGates( p->pLib, p->pNtk );
|
||||
Vec_PtrFree( vFanouts );
|
||||
if ( p->fVerbose )
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
printf( "Largest departure time = %7.0f ps ", SC_LibTimePs(p->pLib, DeptMax) );
|
||||
printf( "Target gain =%5d. Target slew =%5d. Delay =%7.0f ps ",
|
||||
p->pPars->GainRatio, p->pPars->Slew, SC_LibTimePs(p->pLib, DeptMax) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
}
|
||||
Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fSizeOnly, int fAddBufs, int fBufPis, int fVerbose )
|
||||
Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, SC_BusPars * pPars )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Bus_Man_t * p;
|
||||
if ( !Abc_SclCheckNtk( pNtk, 0 ) )
|
||||
return NULL;
|
||||
Abc_SclReportDupFanins( pNtk );
|
||||
p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fSizeOnly, fAddBufs, fBufPis, fVerbose );
|
||||
p = Bus_ManStart( pNtk, pLib, pPars );
|
||||
Bus_ManReadInOutLoads( p );
|
||||
Abc_SclBufSize( p );
|
||||
Bus_ManStop( p );
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@ typedef enum // -- timing sense, positive-, negative- or non-unate
|
|||
sc_ts_Non,
|
||||
} SC_TSense;
|
||||
|
||||
typedef struct SC_Pair_ SC_Pair;
|
||||
struct SC_Pair_
|
||||
{
|
||||
float rise;
|
||||
float fall;
|
||||
};
|
||||
|
||||
typedef struct SC_SizePars_ SC_SizePars;
|
||||
struct SC_SizePars_
|
||||
{
|
||||
|
|
@ -79,11 +86,17 @@ struct SC_SizePars_
|
|||
int fVeryVerbose;
|
||||
};
|
||||
|
||||
typedef struct SC_Pair_ SC_Pair;
|
||||
struct SC_Pair_
|
||||
typedef struct SC_BusPars_ SC_BusPars;
|
||||
struct SC_BusPars_
|
||||
{
|
||||
float rise;
|
||||
float fall;
|
||||
int GainRatio; // target gain
|
||||
int Slew; // target slew
|
||||
int nDegree; // max branching factor
|
||||
int fSizeOnly; // perform only sizing
|
||||
int fAddBufs; // add buffers
|
||||
int fBufPis; // use CI buffering
|
||||
int fVerbose; // verbose
|
||||
int fVeryVerbose; // verbose
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -550,7 +563,7 @@ static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
|
|||
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
|
||||
return (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
|
||||
}
|
||||
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float load )
|
||||
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float load )
|
||||
{
|
||||
SC_Pair Load = { load, load };
|
||||
SC_Pair ArrIn = { 0.0, 0.0 };
|
||||
|
|
@ -558,8 +571,8 @@ static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float
|
|||
SC_Pair SlewIn = { 0.0, 0.0 };
|
||||
SC_Pair SlewOut = { 0.0, 0.0 };
|
||||
SC_Timing * pTime = Scl_CellPinTime( pCell, iPin );
|
||||
Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
|
||||
SlewIn.fall = SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
|
||||
// Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
|
||||
SlewIn.fall = SlewIn.rise = Slew; //Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
|
||||
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load, &ArrOut, &SlewOut );
|
||||
return 0.5 * ArrOut.fall + 0.5 * ArrOut.rise;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
|
|||
}
|
||||
|
||||
/*=== sclBufSize.c ===============================================================*/
|
||||
extern Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fSizeOnly, int fAddBufs, int fBufPis, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, SC_BusPars * pPars );
|
||||
/*=== sclBuffer.c ===============================================================*/
|
||||
extern int Abc_SclIsInv( Abc_Obj_t * pObj );
|
||||
extern void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj );
|
||||
|
|
|
|||
Loading…
Reference in New Issue