diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-11-07 10:24:47 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-11-07 10:24:47 -0800 |
commit | 4774dc56fe5a7ef6a9ae154f57b3cb2a48c4ca97 (patch) | |
tree | 67dee47389a5117d1b0057a9065c27f980e230f4 | |
parent | f29fe2d0c226b33505e544e4560f9357cfed66f0 (diff) | |
download | abc-4774dc56fe5a7ef6a9ae154f57b3cb2a48c4ca97.tar.gz abc-4774dc56fe5a7ef6a9ae154f57b3cb2a48c4ca97.tar.bz2 abc-4774dc56fe5a7ef6a9ae154f57b3cb2a48c4ca97.zip |
Fixing the wire-load approximation problem.
-rw-r--r-- | src/base/abc/abc.h | 1 | ||||
-rw-r--r-- | src/base/abc/abcUtil.c | 11 | ||||
-rw-r--r-- | src/map/scl/sclBufSize.c | 2 | ||||
-rw-r--r-- | src/map/scl/sclLib.h | 4 | ||||
-rw-r--r-- | src/map/scl/sclLibScl.c | 88 | ||||
-rw-r--r-- | src/map/scl/sclLiberty.c | 6 | ||||
-rw-r--r-- | src/map/scl/sclLoad.c | 38 | ||||
-rw-r--r-- | src/map/scl/sclSize.h | 2 |
8 files changed, 88 insertions, 64 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 5bc3e0e4..0e9199f9 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -965,6 +965,7 @@ extern ABC_DLL int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkGetBufNum( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ); +extern ABC_DLL int Abc_NtkGetFanoutMax( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkCleanData( Abc_Ntk_t * pNtk ); diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 1fb6dbab..b3b37da0 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -459,6 +459,17 @@ int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ) } return nFaninsMax; } +int Abc_NtkGetFanoutMax( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, nFaninsMax = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( nFaninsMax < Abc_ObjFanoutNum(pNode) ) + nFaninsMax = Abc_ObjFanoutNum(pNode); + } + return nFaninsMax; +} /**Function************************************************************* diff --git a/src/map/scl/sclBufSize.c b/src/map/scl/sclBufSize.c index aca87673..41db0f5a 100644 --- a/src/map/scl/sclBufSize.c +++ b/src/map/scl/sclBufSize.c @@ -94,7 +94,7 @@ Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, SC_BusPars * pPars ) p->pWLoadUsed = Abc_SclFetchWireLoadModel( pLib, pNtk->pWLoadUsed ); } if ( p->pWLoadUsed ) - p->vWireCaps = Abc_SclFindWireCaps( p->pWLoadUsed ); + p->vWireCaps = Abc_SclFindWireCaps( p->pWLoadUsed, Abc_NtkGetFanoutMax(pNtk) ); p->vFanouts = Vec_PtrAlloc( 100 ); p->vCins = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 ); p->vETimes = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 ); diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h index a4d553fa..b8ac624a 100644 --- a/src/map/scl/sclLib.h +++ b/src/map/scl/sclLib.h @@ -40,7 +40,7 @@ ABC_NAMESPACE_HEADER_START /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#define ABC_SCL_CUR_VERSION 6 +#define ABC_SCL_CUR_VERSION 7 typedef enum { @@ -117,8 +117,8 @@ typedef struct SC_Lib_ SC_Lib; struct SC_WireLoad_ { char * pName; - float res; // (currently not used) float cap; // }- multiply estimation in 'fanout_len[].snd' with this value + float slope; // used to extrapolate wireload for large fanout count Vec_Int_t * vFanout; // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)' Vec_Flt_t * vLen; }; diff --git a/src/map/scl/sclLibScl.c b/src/map/scl/sclLibScl.c index bd0bb5dc..7947d8a3 100644 --- a/src/map/scl/sclLibScl.c +++ b/src/map/scl/sclLibScl.c @@ -71,11 +71,16 @@ static void Abc_SclReadSurface( Vec_Str_t * vOut, int * pPos, SC_Surface * p ) for ( i = 0; i < 6; i++ ) p->approx[2][i] = Vec_StrGetF( vOut, pPos ); } -static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) +static int Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) { int i, j, k, n; int version = Vec_StrGetI( vOut, pPos ); - assert( version == 5 || version == ABC_SCL_CUR_VERSION ); // wrong version of the file + if ( version != ABC_SCL_CUR_VERSION ) + { + Abc_Print( -1, "Wrong version of the SCL file.\n" ); + return 0; + } + assert( version == ABC_SCL_CUR_VERSION ); // wrong version of the file // Read non-composite fields: p->pName = Vec_StrGetS(vOut, pPos); @@ -94,8 +99,8 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) Vec_PtrPush( p->vWireLoads, pWL ); pWL->pName = Vec_StrGetS(vOut, pPos); - pWL->res = Vec_StrGetF(vOut, pPos); - pWL->cap = Vec_StrGetF(vOut, pPos); + pWL->cap = Vec_StrGetF(vOut, pPos); + pWL->slope = Vec_StrGetF(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { @@ -163,9 +168,14 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) assert( k == pCell->n_inputs ); // read function - if ( version == 5 ) - { - // formula is not given + // (possibly empty) formula is always given + assert( version == ABC_SCL_CUR_VERSION ); + assert( pPin->func_text == NULL ); + pPin->func_text = Vec_StrGetS(vOut, pPos); + if ( pPin->func_text[0] == 0 ) + { + // formula is not given - read truth table + ABC_FREE( pPin->func_text ); assert( Vec_WrdSize(pPin->vFunc) == 0 ); Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) @@ -173,40 +183,24 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) } else { - // (possibly empty) formula is always given - assert( version == ABC_SCL_CUR_VERSION ); - assert( pPin->func_text == NULL ); - pPin->func_text = Vec_StrGetS(vOut, pPos); - if ( pPin->func_text[0] == 0 ) - { - // formula is not given - read truth table - ABC_FREE( pPin->func_text ); - assert( Vec_WrdSize(pPin->vFunc) == 0 ); - Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); - for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) - Vec_WrdPush( pPin->vFunc, Vec_StrGetW(vOut, pPos) ); - } - else + // formula is given - derive truth table + SC_Pin * pPin2; + Vec_Ptr_t * vNames; + // collect input names + vNames = Vec_PtrAlloc( pCell->n_inputs ); + SC_CellForEachPinIn( pCell, pPin2, n ) + Vec_PtrPush( vNames, pPin2->pName ); + // derive truth table + assert( Vec_WrdSize(pPin->vFunc) == 0 ); + Vec_WrdFree( pPin->vFunc ); + pPin->vFunc = Mio_ParseFormulaTruth( pPin->func_text, (char **)Vec_PtrArray(vNames), pCell->n_inputs ); + Vec_PtrFree( vNames ); + // skip truth table + assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); + for ( k = 0; k < Vec_WrdSize(pPin->vFunc); k++ ) { - // formula is given - derive truth table - SC_Pin * pPin2; - Vec_Ptr_t * vNames; - // collect input names - vNames = Vec_PtrAlloc( pCell->n_inputs ); - SC_CellForEachPinIn( pCell, pPin2, n ) - Vec_PtrPush( vNames, pPin2->pName ); - // derive truth table - assert( Vec_WrdSize(pPin->vFunc) == 0 ); - Vec_WrdFree( pPin->vFunc ); - pPin->vFunc = Mio_ParseFormulaTruth( pPin->func_text, (char **)Vec_PtrArray(vNames), pCell->n_inputs ); - Vec_PtrFree( vNames ); - // skip truth table - assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); - for ( k = 0; k < Vec_WrdSize(pPin->vFunc); k++ ) - { - word Value = Vec_StrGetW(vOut, pPos); - assert( Value == Vec_WrdEntry(pPin->vFunc, k) ); - } + word Value = Vec_StrGetW(vOut, pPos); + assert( Value == Vec_WrdEntry(pPin->vFunc, k) ); } } @@ -234,6 +228,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) } } } + return 1; } SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut ) { @@ -241,7 +236,8 @@ SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut ) int Pos = 0; // read the library p = Abc_SclLibAlloc(); - Abc_SclReadLibrary( vOut, &Pos, p ); + if ( !Abc_SclReadLibrary( vOut, &Pos, p ) ) + return NULL; assert( Pos == Vec_StrSize(vOut) ); // hash gates by name Abc_SclHashCells( p ); @@ -273,8 +269,10 @@ SC_Lib * Abc_SclReadFromFile( char * pFileName ) fclose( pFile ); // read the library p = Abc_SclReadFromStr( vOut ); - p->pFileName = Abc_UtilStrsav( pFileName ); - Abc_SclLibNormalize( p ); + if ( p != NULL ) + p->pFileName = Abc_UtilStrsav( pFileName ); + if ( p != NULL ) + Abc_SclLibNormalize( p ); Vec_StrFree( vOut ); return p; } @@ -343,8 +341,8 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) SC_LibForEachWireLoad( p, pWL, i ) { Vec_StrPutS( vOut, pWL->pName ); - Vec_StrPutF( vOut, pWL->res ); Vec_StrPutF( vOut, pWL->cap ); + Vec_StrPutF( vOut, pWL->slope ); Vec_StrPutI( vOut, Vec_IntSize(pWL->vFanout) ); for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) @@ -553,8 +551,8 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) SC_LibForEachWireLoad( p, pWL, i ) { fprintf( s, " wire_load(\"%s\") {\n", pWL->pName ); - fprintf( s, " resistance : %f;\n", pWL->res ); fprintf( s, " capacitance : %f;\n", pWL->cap ); + fprintf( s, " slope : %f;\n", pWL->slope ); for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) fprintf( s, " fanout_length( %d, %f );\n", Vec_IntEntry(pWL->vFanout, j), Vec_FltEntry(pWL->vLen, j) ); fprintf( s, " }\n\n" ); diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 56ff2998..7342a008 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -811,10 +811,10 @@ void Scl_LibertyReadWireLoad( Scl_Tree_t * p, Vec_Str_t * vOut ) Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load" ) { Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) ); - Scl_ItemForEachChildName( p, pItem, pChild, "resistance" ) - Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) ); Scl_ItemForEachChildName( p, pItem, pChild, "capacitance" ) Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) ); + Scl_ItemForEachChildName( p, pItem, pChild, "slope" ) + Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) ); Vec_StrPut_( vOut ); Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "fanout_length") ); Vec_StrPut_( vOut ); @@ -1575,6 +1575,8 @@ SC_Lib * Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose ) Scl_LibertyStop( p, fVeryVerbose ); // construct SCL data-structure pLib = Abc_SclReadFromStr( vStr ); + if ( pLib == NULL ) + return NULL; pLib->pFileName = Abc_UtilStrsav( pFileName ); Abc_SclLibNormalize( pLib ); Vec_StrFree( vStr ); diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c index 033750cb..f23bf7f9 100644 --- a/src/map/scl/sclLoad.c +++ b/src/map/scl/sclLoad.c @@ -42,29 +42,41 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL ) +Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL, int nFanoutMax ) { Vec_Flt_t * vCaps = NULL; - float EntryPrev, EntryCur; - int i, Entry, EntryMax; + float EntryPrev, EntryCur, Slope; + int i, iPrev, k, Entry, EntryMax; assert( pWL != NULL ); - // find the biggest fanout + // find the biggest fanout count EntryMax = 0; Vec_IntForEachEntry( pWL->vFanout, Entry, i ) EntryMax = Abc_MaxInt( EntryMax, Entry ); // create the array - vCaps = Vec_FltStart( EntryMax + 1 ); + vCaps = Vec_FltStart( Abc_MaxInt(nFanoutMax, EntryMax) + 1 ); Vec_IntForEachEntry( pWL->vFanout, Entry, i ) Vec_FltWriteEntry( vCaps, Entry, Vec_FltEntry(pWL->vLen, i) * pWL->cap ); - // reformat - EntryPrev = 0; - Vec_FltForEachEntry( vCaps, EntryCur, i ) + // interpolate between the values + assert( Vec_FltEntry(vCaps, 1) != 0 ); + iPrev = 1; + EntryPrev = Vec_FltEntry(vCaps, 1); + Vec_FltForEachEntryStart( vCaps, EntryCur, i, 2 ) { - if ( EntryCur ) - EntryPrev = EntryCur; - else - Vec_FltWriteEntry( vCaps, i, EntryPrev ); + if ( EntryCur == 0 ) + continue; + Slope = (EntryCur - EntryPrev) / (i - iPrev); + for ( k = iPrev + 1; k < i; k++ ) + Vec_FltWriteEntry( vCaps, k, EntryPrev + Slope * (k - iPrev) ); + EntryPrev = EntryCur; + iPrev = i; } + // extrapolate after the largest value + Slope = pWL->cap * pWL->slope; + for ( k = iPrev + 1; k < i; k++ ) + Vec_FltWriteEntry( vCaps, k, EntryPrev + Slope * (k - iPrev) ); + // show +// Vec_FltForEachEntry( vCaps, EntryCur, i ) +// printf( "%3d : %f\n", i, EntryCur ); return vCaps; } @@ -126,7 +138,7 @@ void Abc_SclComputeLoad( SC_Man * p ) if ( p->pWLoadUsed != NULL ) { if ( p->vWireCaps == NULL ) - p->vWireCaps = Abc_SclFindWireCaps( p->pWLoadUsed ); + p->vWireCaps = Abc_SclFindWireCaps( p->pWLoadUsed, Abc_NtkGetFanoutMax(p->pNtk) ); Abc_NtkForEachNode1( p->pNtk, pObj, i ) Abc_SclAddWireLoad( p, pObj, 0 ); Abc_NtkForEachPi( p->pNtk, pObj, i ) diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 1087651e..e635b715 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -553,7 +553,7 @@ extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax /*=== sclDnsize.c ===============================================================*/ extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); /*=== sclLoad.c ===============================================================*/ -extern Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL ); +extern Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL, int nFanoutMax ); extern float Abc_SclFindWireLoad( Vec_Flt_t * vWireCaps, int nFans ); extern void Abc_SclAddWireLoad( SC_Man * p, Abc_Obj_t * pObj, int fSubtr ); extern void Abc_SclComputeLoad( SC_Man * p ); |