summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2013-08-09 11:15:20 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2013-08-09 11:15:20 -0700
commit95684b044afb8f3fd1ebcc43483126c10010a353 (patch)
tree2e986c405150d9c0fbf7540aead1c77b04e6d61d /src
parent4be8eba9d91d24cc8137b895e5bf6c0ae2d354e3 (diff)
downloadabc-95684b044afb8f3fd1ebcc43483126c10010a353.tar.gz
abc-95684b044afb8f3fd1ebcc43483126c10010a353.tar.bz2
abc-95684b044afb8f3fd1ebcc43483126c10010a353.zip
Improvements to buffering and sizing.
Diffstat (limited to 'src')
-rw-r--r--src/map/scl/sclBufSize.c33
-rw-r--r--src/map/scl/sclDnsize.c6
-rw-r--r--src/map/scl/sclLib.c29
-rw-r--r--src/map/scl/sclLib.h33
-rw-r--r--src/map/scl/sclSize.c37
-rw-r--r--src/map/scl/sclSize.h157
-rw-r--r--src/map/scl/sclUpsize.c10
7 files changed, 181 insertions, 124 deletions
diff --git a/src/map/scl/sclBufSize.c b/src/map/scl/sclBufSize.c
index 47d16ba8..fd4db57b 100644
--- a/src/map/scl/sclBufSize.c
+++ b/src/map/scl/sclBufSize.c
@@ -34,6 +34,7 @@ struct Bus_Man_t_
// parameters
float Gain; // target gain
int nDegree; // max branching factor
+ int fAddBufs; // add buffers
int fBufPis; // use CI buffering
int fVerbose; // verbose
// user data
@@ -50,11 +51,11 @@ struct Bus_Man_t_
static inline Bus_Man_t * Bus_SclObjMan( Abc_Obj_t * p ) { return (Bus_Man_t *)p->pNtk->pBSMan; }
static inline float Bus_SclObjCin( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p) ); }
-static inline void Bus_SclObjSetCin( Abc_Obj_t * p, float load ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p), load ); }
+static inline void Bus_SclObjSetCin( Abc_Obj_t * p, float cap ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p), cap ); }
static inline float Bus_SclObjLoad( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p) ); }
-static inline void Bus_SclObjSetLoad( Abc_Obj_t * p, float load ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p), load ); }
+static inline void Bus_SclObjSetLoad( Abc_Obj_t * p, float cap ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p), cap ); }
static inline float Bus_SclObjDept( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); }
-static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float dept ) { float *q = Vec_FltEntryP( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); if (*q < dept) *q = dept; }
+static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float time ) { float *q = Vec_FltEntryP( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); if (*q < time) *q = time; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -71,17 +72,18 @@ static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float dept ) { f
SeeAlso []
***********************************************************************/
-Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fBufPis, int fVerbose )
+Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose )
{
Bus_Man_t * p;
p = ABC_CALLOC( Bus_Man_t, 1 );
p->Gain = 0.01 * GainRatio;
p->nDegree = nDegree;
+ p->fAddBufs = fAddBufs;
p->fBufPis = fBufPis;
p->fVerbose = fVerbose;
p->pNtk = pNtk;
p->pLib = pLib;
- p->pInv = Abc_SclFindInvertor(pLib)->pAve;
+ p->pInv = Abc_SclFindInvertor(pLib, 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) );
@@ -118,7 +120,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
{
printf( "Default input drive strength is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall );
Abc_NtkForEachPi( p->pNtk, pObj, i )
- Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
}
if ( Abc_NodeReadInputDrive(p->pNtk, 0) != NULL )
{
@@ -126,7 +128,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
Abc_NtkForEachPi( p->pNtk, pObj, i )
{
pTime = Abc_NodeReadInputDrive(p->pNtk, i);
- Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
}
}
// read output load
@@ -135,7 +137,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
{
printf( "Default output load is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall );
Abc_NtkForEachPo( p->pNtk, pObj, i )
- Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
}
if ( Abc_NodeReadOutputLoad(p->pNtk, 0) != NULL )
{
@@ -143,7 +145,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
Abc_NtkForEachPo( p->pNtk, pObj, i )
{
pTime = Abc_NodeReadOutputLoad(p->pNtk, i);
- Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
}
}
// read arrival/required times
@@ -191,7 +193,7 @@ float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj )
continue;
Load = Bus_SclObjLoad( pFanout );
Dept = Bus_SclObjDept( pFanout );
- Edge = Scl_LibPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
+ Edge = Scl_LibPinArrivalEstimate( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
Bus_SclObjUpdateDept( pObj, Dept + Edge );
assert( Edge > 0 );
assert( Load > 0 );
@@ -208,7 +210,7 @@ void Abc_NtkUpdateFaninDeparture( Bus_Man_t * p, Abc_Obj_t * pObj, float Load )
Dept = Bus_SclObjDept( pObj );
Abc_ObjForEachFanin( pObj, pFanin, i )
{
- Edge = Scl_LibPinTime( pCell, i, Load );
+ Edge = Scl_LibPinArrivalEstimate( pCell, i, Load );
Bus_SclObjUpdateDept( pFanin, Dept + Edge );
}
}
@@ -276,7 +278,7 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
{
SC_Cell * pCellNew;
Abc_Obj_t * pFanout, * pInv;
- float Target = SC_CellPinCap( p->pInv, 0 ) * Gain;
+ float Target = SC_CellPinCap(p->pInv, 0) * Gain;
float Load = 0;
int i, iStop;
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, iStop, Degree )
@@ -286,7 +288,10 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
break;
}
// create inverter
- pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
+ if ( p->fAddBufs )
+ pInv = Abc_NtkCreateNodeBuf( p->pNtk, NULL );
+ else
+ pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
assert( (int)Abc_ObjId(pInv) < Vec_FltSize(p->vDepts) );
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, iStop )
{
@@ -358,7 +363,7 @@ Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRati
if ( !Abc_SclCheckNtk( pNtk, 0 ) )
return NULL;
Abc_SclReportDupFanins( pNtk );
- p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fBufPis, fVerbose );
+ p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fAddBufs, fBufPis, fVerbose );
Bus_ManReadInOutLoads( p );
Abc_SclBufSize( p );
Bus_ManStop( p );
diff --git a/src/map/scl/sclDnsize.c b/src/map/scl/sclDnsize.c
index 50c994e9..dc0a28a0 100644
--- a/src/map/scl/sclDnsize.c
+++ b/src/map/scl/sclDnsize.c
@@ -110,6 +110,7 @@ clk = Abc_Clock();
// save old gate, timing, fanin load
pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vNodes );
+ Abc_SclEvalStore( p, vEvals );
Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node
gateBest = -1;
@@ -131,6 +132,7 @@ clk = Abc_Clock();
Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj );
// evaluate gain
+/*
dGain = 0.0;
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, k )
if ( Abc_SclObjLegal(p, pTemp, p->MaxDelay0) )
@@ -143,6 +145,10 @@ clk = Abc_Clock();
if ( k < Vec_IntSize(vEvals) )
continue;
dGain /= Vec_IntSize(vEvals);
+*/
+ dGain = Abc_SclEvalPerformLegal( p, vEvals, p->MaxDelay0 );
+ if ( dGain == -1 )
+ continue;
// save best gain
if ( dGainBest < dGain )
{
diff --git a/src/map/scl/sclLib.c b/src/map/scl/sclLib.c
index d2b3d72b..a2d5b16a 100644
--- a/src/map/scl/sclLib.c
+++ b/src/map/scl/sclLib.c
@@ -815,12 +815,13 @@ void Abc_SclLinkCells( SC_Lib * p )
SeeAlso []
***********************************************************************/
-SC_Cell * Abc_SclFindInvertor( SC_Lib * p )
+SC_Cell * Abc_SclFindInvertor( SC_Lib * p, int fFindBuff )
{
SC_Cell * pCell = NULL;
+ word Truth = fFindBuff ? ABC_CONST(0x5555555555555555) : ABC_CONST(0xAAAAAAAAAAAAAAAA);
int k;
SC_LibForEachCellClass( p, pCell, k )
- if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == ABC_CONST(0x5555555555555555) )
+ if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == Truth )
break;
// take representative
return pCell ? pCell->pRepr : NULL;
@@ -911,26 +912,16 @@ SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area )
***********************************************************************/
void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pED, float * pPD )
{
- SC_Timings * pRTime;
- SC_Timing * pTime = NULL;
- SC_Pin * pPin;
+ SC_Pair Load0, Load1, Load2;
SC_Pair ArrIn = { 0.0, 0.0 };
SC_Pair SlewIn = { Slew, Slew };
- SC_Pair Load0, Load1, Load2;
SC_Pair ArrOut0 = { 0.0, 0.0 };
SC_Pair ArrOut1 = { 0.0, 0.0 };
SC_Pair ArrOut2 = { 0.0, 0.0 };
SC_Pair SlewOut = { 0.0, 0.0 };
- Vec_Flt_t * vIndex;
- assert( iPin >= 0 && iPin < pCell->n_inputs );
- pPin = SC_CellPin( pCell, pCell->n_inputs );
- // find timing info for this pin
- assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
- pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin );
- assert( Vec_PtrSize(pRTime->vTimings) == 1 );
- pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
+ SC_Timing * pTime = Scl_CellPinTime( pCell, iPin );
+ Vec_Flt_t * vIndex = pTime->pCellRise->vIndex1; // capacitance
// get load points
- vIndex = pTime->pCellRise->vIndex1; // capacitance
Load0.rise = Load0.fall = 0.0;
Load1.rise = Load1.fall = Vec_FltEntry( vIndex, 0 );
Load2.rise = Load2.fall = Vec_FltEntry( vIndex, Vec_FltSize(vIndex) - 2 );
@@ -938,9 +929,9 @@ void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float S
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load0, &ArrOut0, &SlewOut );
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load1, &ArrOut1, &SlewOut );
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load2, &ArrOut2, &SlewOut );
- ArrOut0.rise = 0.5 * (ArrOut0.rise + ArrOut0.fall);
- ArrOut1.rise = 0.5 * (ArrOut1.rise + ArrOut1.fall);
- ArrOut2.rise = 0.5 * (ArrOut2.rise + ArrOut2.fall);
+ ArrOut0.rise = 0.5 * ArrOut0.rise + 0.5 * ArrOut0.fall;
+ 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));
// get constant
@@ -983,7 +974,7 @@ void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, fl
ED = PD = ed = pd = 0;
SC_RingForEachCell( pRepr, pCell, i )
{
- Abc_SclComputeParametersPin( p, pCell, Slew, iPin, &ed, &pd );
+ Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ed, &pd );
ED += ed; PD += pd;
Count++;
}
diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h
index 7d5964a4..fa80e1f0 100644
--- a/src/map/scl/sclLib.h
+++ b/src/map/scl/sclLib.h
@@ -213,7 +213,7 @@ struct SC_Lib_
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_CellPin(p, p->n_inputs)->vFunc; }
-static inline float SC_CellPinCap( SC_Cell * p, int i ) { return 0.5 * (SC_CellPin(p, i)->rise_cap + SC_CellPin(p, i)->fall_cap); }
+static inline float SC_CellPinCap( SC_Cell * p, int i ) { return 0.5 * SC_CellPin(p, i)->rise_cap + 0.5 * SC_CellPin(p, i)->fall_cap; }
static inline float SC_CellPinCapAve( SC_Cell * p ) { int i; float c = 0; for (i = 0; i < p->n_inputs; i++) c += SC_CellPinCap(p, i); return c / p->n_inputs; }
static inline char * SC_CellPinOutFunc( SC_Cell * p, int i ) { return SC_CellPin(p, p->n_inputs + i)->func_text; }
static inline char * SC_CellPinName( SC_Cell * p, int i ) { return SC_CellPin(p, i)->pName; }
@@ -532,30 +532,29 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
SeeAlso []
***********************************************************************/
-static inline float Scl_LibPinTime( SC_Cell * pCell, int iPin, float load )
+static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
{
SC_Pin * pPin;
SC_Timings * pRTime;
- SC_Timing * pTime;
- SC_Pair Load = { load, load };
- SC_Pair ArrIn = { 0.0, 0.0 };
- SC_Pair ArrOut = { 0.0, 0.0 };
- SC_Pair SlewIn = { 0.0, 0.0 };
- SC_Pair SlewOut = { 0.0, 0.0 };
- Vec_Flt_t * vIndex0;
assert( iPin >= 0 && iPin < pCell->n_inputs );
pPin = SC_CellPin( pCell, pCell->n_inputs );
- // find timing info for this pin
assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin );
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
- pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
- // get delay points
- vIndex0 = pTime->pCellRise->vIndex0; // slew
- SlewIn.fall = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
- SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
+ return (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
+}
+static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float load )
+{
+ SC_Pair Load = { load, load };
+ SC_Pair ArrIn = { 0.0, 0.0 };
+ SC_Pair ArrOut = { 0.0, 0.0 };
+ 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 );
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load, &ArrOut, &SlewOut );
- return 0.5 * (ArrOut.fall + ArrOut.rise);
+ return 0.5 * ArrOut.fall + 0.5 * ArrOut.rise;
}
/*=== sclLib.c ===============================================================*/
@@ -569,7 +568,7 @@ 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 SC_Cell * Abc_SclFindInvertor( SC_Lib * p );
+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 );
extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );
diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c
index 7fb80a27..e95a7336 100644
--- a/src/map/scl/sclSize.c
+++ b/src/map/scl/sclSize.c
@@ -205,16 +205,27 @@ 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 void Abc_SclDeptObj( SC_Man * p, Abc_Obj_t * pObj )
+{
+ SC_Cell * pCell;
+ SC_Timing * pTime;
+ Abc_Obj_t * pFanout;
+ int i;
+ pCell = Abc_SclObjCell( pObj );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ {
+ pTime = Scl_CellPinTime( pCell, Abc_NodeFindFanin(pFanout, pObj) );
+ Abc_SclDeptFanin( p, pTime, pFanout, pObj );
+ }
+}
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);
+ return (0.5 * Abc_SclObjLoad(p, pObj)->fall + 0.5 * Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax);
}
void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
{
- SC_Timings * pRTime;
SC_Timing * pTime;
- SC_Pin * pPin;
SC_Cell * pCell;
int k;
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
@@ -223,6 +234,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
float DeptRise = 0;
float DeptFall = 0;
float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0;
+ Abc_Obj_t * pFanin;
if ( Abc_ObjIsCo(pObj) )
{
if ( !fDept )
@@ -248,19 +260,14 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
}
// get the library cell
pCell = Abc_SclObjCell( pObj );
- // get the output pin
-// assert( pCell->n_outputs == 1 );
- pPin = SC_CellPin( pCell, pCell->n_inputs );
- // compute timing using each fanin
- assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
- SC_PinForEachRTiming( pPin, pRTime, k )
+ // compute for each fanin
+ Abc_ObjForEachFanin( pObj, pFanin, k )
{
- assert( Vec_PtrSize(pRTime->vTimings) == 1 );
- pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
+ pTime = Scl_CellPinTime( pCell, k );
if ( fDept )
- Abc_SclDeptFanin( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
+ Abc_SclDeptFanin( p, pTime, pObj, pFanin );
else
- Abc_SclTimeFanin( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
+ Abc_SclTimeFanin( p, pTime, pObj, pFanin );
}
if ( p->EstLoadMax && Value > 1 )
{
@@ -385,7 +392,7 @@ void Abc_SclManReadSlewAndLoad( SC_Man * p, Abc_Ntk_t * pNtk )
if ( p->pInDrive == NULL )
p->pInDrive = ABC_CALLOC( float, Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
- p->pInDrive[Abc_ObjId(pObj)] = 0.5 * SC_LibCapFromFf( p->pLib, pTime->Rise ) + 0.5 * SC_LibCapFromFf( p->pLib, pTime->Fall );
+ p->pInDrive[Abc_ObjId(pObj)] = SC_LibCapFromFf( p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall );
}
if ( Abc_NodeReadInputDrive(pNtk, 0) != NULL )
{
@@ -395,7 +402,7 @@ void Abc_SclManReadSlewAndLoad( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachPi( pNtk, pObj, i )
{
pTime = Abc_NodeReadInputDrive(pNtk, i);
- p->pInDrive[Abc_ObjId(pObj)] = 0.5 * SC_LibCapFromFf( p->pLib, pTime->Rise ) + 0.5 * SC_LibCapFromFf( p->pLib, pTime->Fall );
+ p->pInDrive[Abc_ObjId(pObj)] = SC_LibCapFromFf( p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall );
}
}
// read output load
diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h
index fad63243..7974c7f8 100644
--- a/src/map/scl/sclSize.h
+++ b/src/map/scl/sclSize.h
@@ -58,6 +58,8 @@ struct SC_Man_
SC_Pair * pSlews; // slews for each gate
SC_Pair * pTimes2; // arrivals for each gate
SC_Pair * pSlews2; // slews for each gate
+ Vec_Flt_t * vTimes2; // backup storage for times
+ Vec_Flt_t * vTimes3; // backup storage for slews
Vec_Flt_t * vLoads2; // backup storage for loads
Vec_Flt_t * vLoads3; // backup storage for loads
float * pSlack; // slacks for each gatt
@@ -116,11 +118,11 @@ static inline float Abc_SclObjGetSlack( SC_Man * p, Abc_Obj_t * pObj, float
static inline float Abc_SclObjGetSlackR( SC_Man * p, Abc_Obj_t * pObj, float D ){ return D - (Abc_SclObjTime(p, pObj)->rise + Abc_SclObjDept(p, pObj)->rise); }
static inline float Abc_SclObjGetSlackF( SC_Man * p, Abc_Obj_t * pObj, float D ){ return D - (Abc_SclObjTime(p, pObj)->fall + Abc_SclObjDept(p, pObj)->fall); }
static inline float Abc_SclObjSlack( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlack[Abc_ObjId(pObj)]; }
-static inline float Abc_SclObjLoadAve( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5 * (Abc_SclObjLoad(p, pObj)->rise + Abc_SclObjLoad(p, pObj)->fall); }
+static inline float Abc_SclObjLoadAve( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5 * Abc_SclObjLoad(p, pObj)->rise + 0.5 * Abc_SclObjLoad(p, pObj)->fall; }
static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj ) { assert( Abc_ObjIsCo(pObj) ); *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj)); }
static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5*((Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall)); }
-static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, D); }
+//static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, 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); }
@@ -168,6 +170,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
p->vUpdates2 = Vec_IntAlloc( 1000 );
p->vLoads2 = Vec_FltAlloc( 1000 );
p->vLoads3 = Vec_FltAlloc( 1000 );
+ p->vTimes2 = Vec_FltAlloc( 1000 );
+ p->vTimes3 = Vec_FltAlloc( 1000 );
// intermediate data
p->vNode2Gain = Vec_FltStart( p->nObjs );
p->vNode2Gate = Vec_IntStart( p->nObjs );
@@ -185,6 +189,8 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_FltFreeP( &p->vNode2Gain );
Vec_IntFreeP( &p->vNode2Gate );
// intermediate data
+ Vec_FltFreeP( &p->vTimes2 );
+ Vec_FltFreeP( &p->vTimes3 );
Vec_FltFreeP( &p->vLoads2 );
Vec_FltFreeP( &p->vLoads3 );
Vec_IntFreeP( &p->vUpdates );
@@ -233,7 +239,7 @@ static inline void Abc_SclManCleanTime( SC_Man * p )
/**Function*************************************************************
- Synopsis [Stores/retrivies timing information for the logic cone.]
+ Synopsis [Stores/retrivies information for the logic cone.]
Description []
@@ -242,26 +248,55 @@ static inline void Abc_SclManCleanTime( SC_Man * p )
SeeAlso []
***********************************************************************/
-static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
+static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj )
{
- Abc_Obj_t * pObj;
+ Abc_Obj_t * pFanin;
int i;
- Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
+ Vec_FltClear( p->vLoads2 );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
{
- *Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj);
- *Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj);
+ Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->rise );
+ Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->fall );
}
}
-static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
+static inline void Abc_SclLoadRestore( SC_Man * p, Abc_Obj_t * pObj )
{
- Abc_Obj_t * pObj;
+ Abc_Obj_t * pFanin;
+ int i, k = 0;
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ {
+ Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads2, k++);
+ Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads2, k++);
+ }
+ assert( Vec_FltSize(p->vLoads2) == k );
+}
+
+static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
int i;
- Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
+ Vec_FltClear( p->vLoads3 );
+ Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->rise );
+ Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->fall );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
{
- *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
- *Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
+ Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->rise );
+ Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->fall );
}
}
+static inline void Abc_SclLoadRestore3( SC_Man * p, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
+ int i, k = 0;
+ Abc_SclObjLoad(p, pObj)->rise = Vec_FltEntry(p->vLoads3, k++);
+ Abc_SclObjLoad(p, pObj)->fall = Vec_FltEntry(p->vLoads3, k++);
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ {
+ Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads3, k++);
+ Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads3, k++);
+ }
+ assert( Vec_FltSize(p->vLoads3) == k );
+}
static inline void Abc_SclConeClear( SC_Man * p, Vec_Int_t * vCone )
{
SC_Pair Zero = { 0.0, 0.0 };
@@ -273,66 +308,76 @@ static inline void Abc_SclConeClear( SC_Man * p, Vec_Int_t * vCone )
*Abc_SclObjSlew(p, pObj) = Zero;
}
}
-
-/**Function*************************************************************
-
- Synopsis [Stores/retrivies load information.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj )
+static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
{
- Abc_Obj_t * pFanin;
+ Abc_Obj_t * pObj;
int i;
- Vec_FltClear( p->vLoads2 );
- Abc_ObjForEachFanin( pObj, pFanin, i )
+ Vec_FltClear( p->vTimes2 );
+ Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{
- Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->rise );
- Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->fall );
+ Vec_FltPush( p->vTimes2, Abc_SclObjTime(p, pObj)->rise );
+ Vec_FltPush( p->vTimes2, Abc_SclObjTime(p, pObj)->fall );
+ Vec_FltPush( p->vTimes2, Abc_SclObjSlew(p, pObj)->rise );
+ Vec_FltPush( p->vTimes2, Abc_SclObjSlew(p, pObj)->fall );
+ *Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj);
+ *Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj);
}
}
-static inline void Abc_SclLoadRestore( SC_Man * p, Abc_Obj_t * pObj )
+static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
{
- Abc_Obj_t * pFanin;
- int i;
- assert( Vec_FltSize(p->vLoads2) == 2 * Abc_ObjFaninNum(pObj) );
- Abc_ObjForEachFanin( pObj, pFanin, i )
+ Abc_Obj_t * pObj;
+ int i, k = 0;
+ Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{
- Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads2, 2*i);
- Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads2, 2*i+1);
+ Abc_SclObjTime(p, pObj)->rise = Vec_FltEntry(p->vTimes2, k++);
+ Abc_SclObjTime(p, pObj)->fall = Vec_FltEntry(p->vTimes2, k++);
+ Abc_SclObjSlew(p, pObj)->rise = Vec_FltEntry(p->vTimes2, k++);
+ Abc_SclObjSlew(p, pObj)->fall = Vec_FltEntry(p->vTimes2, k++);
+ *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
+ *Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
}
+ assert( Vec_FltSize(p->vTimes2) == k );
}
-
-static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj )
+static inline void Abc_SclEvalStore( SC_Man * p, Vec_Int_t * vCone )
{
- Abc_Obj_t * pFanin;
+ Abc_Obj_t * pObj;
int i;
- Vec_FltClear( p->vLoads3 );
- Abc_ObjForEachFanin( pObj, pFanin, i )
+ Vec_FltClear( p->vTimes3 );
+ Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{
- Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->rise );
- Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->fall );
+ Vec_FltPush( p->vTimes3, Abc_SclObjTime(p, pObj)->rise );
+ Vec_FltPush( p->vTimes3, Abc_SclObjTime(p, pObj)->fall );
}
- Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->rise );
- Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->fall );
}
-static inline void Abc_SclLoadRestore3( SC_Man * p, Abc_Obj_t * pObj )
+static inline float Abc_SclEvalPerform( SC_Man * p, Vec_Int_t * vCone )
{
- Abc_Obj_t * pFanin;
- int i;
- assert( Vec_FltSize(p->vLoads3) == 2 * Abc_ObjFaninNum(pObj) + 2 );
- Abc_ObjForEachFanin( pObj, pFanin, i )
+ Abc_Obj_t * pObj;
+ float Diff, Multi = 2.0, Eval = 0;
+ int i, k = 0;
+ Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
+ {
+ Diff = (Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->rise);
+ Diff += (Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->fall);
+ Eval += 0.5 * (Diff > 0 ? Diff : Multi * Diff);
+ }
+ assert( Vec_FltSize(p->vTimes3) == k );
+ return Eval / Vec_IntSize(vCone);
+}
+static inline float Abc_SclEvalPerformLegal( SC_Man * p, Vec_Int_t * vCone, float D )
+{
+ Abc_Obj_t * pObj;
+ float Rise, Fall, Eval = 0;
+ int i, k = 0;
+ Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{
- Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads3, 2*i);
- Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
+ Rise = Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->rise;
+ Fall = Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->fall;
+ if ( Rise + Abc_SclObjGetSlackR(p, pObj, D) < 0 || Fall + Abc_SclObjGetSlackF(p, pObj, D) < 0 )
+ return -1;
+ Eval = 0.5 * Rise + 0.5 * Fall;
}
- Abc_SclObjLoad(p, pObj)->rise = Vec_FltEntry(p->vLoads3, 2*i);
- Abc_SclObjLoad(p, pObj)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
+ assert( Vec_FltSize(p->vTimes3) == k );
+ return Eval / Vec_IntSize(vCone);
}
/**Function*************************************************************
diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c
index 8bdc3a5d..300c3322 100644
--- a/src/map/scl/sclUpsize.c
+++ b/src/map/scl/sclUpsize.c
@@ -277,6 +277,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
// save old gate, timing, fanin load
pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vRecalcs );
+ Abc_SclEvalStore( p, vEvals );
Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node
gateBest = -1;
@@ -298,6 +299,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj );
// evaluate gain
+
dGain = 0.0;
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, n )
{
@@ -305,6 +307,8 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
dGain += (gGainCur > 0) ? gGainCur : 2.0 * gGainCur;
}
dGain /= Vec_IntSize(vEvals);
+
+// dGain = Abc_SclEvalPerform( p, vEvals );
// save best gain
if ( dGainBest < dGain )
{
@@ -461,9 +465,9 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) );
Vec_IntPush( p->vUpdates, pCellNew->Id );
// remember when this node was upsized
- Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), 0 );
- Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pBuf), 0 );
- Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), 0 );
+ Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), -1 );
+ Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pBuf), -1 );
+ Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), -1 );
// update polarity
if ( p->pNtk->vPhases && Abc_SclIsInv(pBuf) )
Abc_NodeInvUpdateObjFanoutPolarity( pFanin, pFanout );