diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-09 11:15:20 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-09 11:15:20 -0700 |
commit | 95684b044afb8f3fd1ebcc43483126c10010a353 (patch) | |
tree | 2e986c405150d9c0fbf7540aead1c77b04e6d61d | |
parent | 4be8eba9d91d24cc8137b895e5bf6c0ae2d354e3 (diff) | |
download | abc-95684b044afb8f3fd1ebcc43483126c10010a353.tar.gz abc-95684b044afb8f3fd1ebcc43483126c10010a353.tar.bz2 abc-95684b044afb8f3fd1ebcc43483126c10010a353.zip |
Improvements to buffering and sizing.
-rw-r--r-- | src/map/scl/sclBufSize.c | 33 | ||||
-rw-r--r-- | src/map/scl/sclDnsize.c | 6 | ||||
-rw-r--r-- | src/map/scl/sclLib.c | 29 | ||||
-rw-r--r-- | src/map/scl/sclLib.h | 33 | ||||
-rw-r--r-- | src/map/scl/sclSize.c | 37 | ||||
-rw-r--r-- | src/map/scl/sclSize.h | 157 | ||||
-rw-r--r-- | src/map/scl/sclUpsize.c | 10 |
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 ); |