Commit 4774dc56 by Alan Mishchenko

Fixing the wire-load approximation problem.

parent f29fe2d0
...@@ -965,6 +965,7 @@ extern ABC_DLL int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk ); ...@@ -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_NtkGetBufNum( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkGetChoiceNum( 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_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 int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkCleanData( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkCleanData( Abc_Ntk_t * pNtk );
......
...@@ -459,6 +459,17 @@ int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ) ...@@ -459,6 +459,17 @@ int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
} }
return nFaninsMax; 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************************************************************* /**Function*************************************************************
......
...@@ -94,7 +94,7 @@ Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, SC_BusPars * pPars ) ...@@ -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 ); p->pWLoadUsed = Abc_SclFetchWireLoadModel( pLib, pNtk->pWLoadUsed );
} }
if ( p->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->vFanouts = Vec_PtrAlloc( 100 );
p->vCins = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 ); p->vCins = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 );
p->vETimes = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 ); p->vETimes = Vec_FltAlloc( 2*Abc_NtkObjNumMax(pNtk) + 1000 );
......
...@@ -40,7 +40,7 @@ ABC_NAMESPACE_HEADER_START ...@@ -40,7 +40,7 @@ ABC_NAMESPACE_HEADER_START
/// PARAMETERS /// /// PARAMETERS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define ABC_SCL_CUR_VERSION 6 #define ABC_SCL_CUR_VERSION 7
typedef enum typedef enum
{ {
...@@ -117,8 +117,8 @@ typedef struct SC_Lib_ SC_Lib; ...@@ -117,8 +117,8 @@ typedef struct SC_Lib_ SC_Lib;
struct SC_WireLoad_ struct SC_WireLoad_
{ {
char * pName; char * pName;
float res; // (currently not used)
float cap; // }- multiply estimation in 'fanout_len[].snd' with this value 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_Int_t * vFanout; // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)'
Vec_Flt_t * vLen; Vec_Flt_t * vLen;
}; };
......
...@@ -71,11 +71,16 @@ static void Abc_SclReadSurface( Vec_Str_t * vOut, int * pPos, SC_Surface * p ) ...@@ -71,11 +71,16 @@ static void Abc_SclReadSurface( Vec_Str_t * vOut, int * pPos, SC_Surface * p )
for ( i = 0; i < 6; i++ ) for ( i = 0; i < 6; i++ )
p->approx[2][i] = Vec_StrGetF( vOut, pPos ); 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 i, j, k, n;
int version = Vec_StrGetI( vOut, pPos ); 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: // Read non-composite fields:
p->pName = Vec_StrGetS(vOut, pPos); p->pName = Vec_StrGetS(vOut, pPos);
...@@ -94,8 +99,8 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) ...@@ -94,8 +99,8 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
Vec_PtrPush( p->vWireLoads, pWL ); Vec_PtrPush( p->vWireLoads, pWL );
pWL->pName = Vec_StrGetS(vOut, pPos); 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-- ) 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 ) ...@@ -163,9 +168,14 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
assert( k == pCell->n_inputs ); assert( k == pCell->n_inputs );
// read function // read function
if ( version == 5 ) // (possibly empty) formula is always given
{ assert( version == ABC_SCL_CUR_VERSION );
// formula is not given 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 ); assert( Vec_WrdSize(pPin->vFunc) == 0 );
Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) );
for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) 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 ) ...@@ -173,40 +183,24 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
} }
else else
{ {
// (possibly empty) formula is always given // formula is given - derive truth table
assert( version == ABC_SCL_CUR_VERSION ); SC_Pin * pPin2;
assert( pPin->func_text == NULL ); Vec_Ptr_t * vNames;
pPin->func_text = Vec_StrGetS(vOut, pPos); // collect input names
if ( pPin->func_text[0] == 0 ) vNames = Vec_PtrAlloc( pCell->n_inputs );
{ SC_CellForEachPinIn( pCell, pPin2, n )
// formula is not given - read truth table Vec_PtrPush( vNames, pPin2->pName );
ABC_FREE( pPin->func_text ); // derive truth table
assert( Vec_WrdSize(pPin->vFunc) == 0 ); assert( Vec_WrdSize(pPin->vFunc) == 0 );
Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); Vec_WrdFree( pPin->vFunc );
for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) pPin->vFunc = Mio_ParseFormulaTruth( pPin->func_text, (char **)Vec_PtrArray(vNames), pCell->n_inputs );
Vec_WrdPush( pPin->vFunc, Vec_StrGetW(vOut, pPos) ); Vec_PtrFree( vNames );
} // skip truth table
else 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 word Value = Vec_StrGetW(vOut, pPos);
SC_Pin * pPin2; assert( Value == Vec_WrdEntry(pPin->vFunc, k) );
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) );
}
} }
} }
...@@ -234,6 +228,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) ...@@ -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 ) SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut )
{ {
...@@ -241,7 +236,8 @@ SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut ) ...@@ -241,7 +236,8 @@ SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut )
int Pos = 0; int Pos = 0;
// read the library // read the library
p = Abc_SclLibAlloc(); p = Abc_SclLibAlloc();
Abc_SclReadLibrary( vOut, &Pos, p ); if ( !Abc_SclReadLibrary( vOut, &Pos, p ) )
return NULL;
assert( Pos == Vec_StrSize(vOut) ); assert( Pos == Vec_StrSize(vOut) );
// hash gates by name // hash gates by name
Abc_SclHashCells( p ); Abc_SclHashCells( p );
...@@ -273,8 +269,10 @@ SC_Lib * Abc_SclReadFromFile( char * pFileName ) ...@@ -273,8 +269,10 @@ SC_Lib * Abc_SclReadFromFile( char * pFileName )
fclose( pFile ); fclose( pFile );
// read the library // read the library
p = Abc_SclReadFromStr( vOut ); p = Abc_SclReadFromStr( vOut );
p->pFileName = Abc_UtilStrsav( pFileName ); if ( p != NULL )
Abc_SclLibNormalize( p ); p->pFileName = Abc_UtilStrsav( pFileName );
if ( p != NULL )
Abc_SclLibNormalize( p );
Vec_StrFree( vOut ); Vec_StrFree( vOut );
return p; return p;
} }
...@@ -343,8 +341,8 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) ...@@ -343,8 +341,8 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
SC_LibForEachWireLoad( p, pWL, i ) SC_LibForEachWireLoad( p, pWL, i )
{ {
Vec_StrPutS( vOut, pWL->pName ); Vec_StrPutS( vOut, pWL->pName );
Vec_StrPutF( vOut, pWL->res );
Vec_StrPutF( vOut, pWL->cap ); Vec_StrPutF( vOut, pWL->cap );
Vec_StrPutF( vOut, pWL->slope );
Vec_StrPutI( vOut, Vec_IntSize(pWL->vFanout) ); Vec_StrPutI( vOut, Vec_IntSize(pWL->vFanout) );
for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ )
...@@ -553,8 +551,8 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) ...@@ -553,8 +551,8 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p )
SC_LibForEachWireLoad( p, pWL, i ) SC_LibForEachWireLoad( p, pWL, i )
{ {
fprintf( s, " wire_load(\"%s\") {\n", pWL->pName ); fprintf( s, " wire_load(\"%s\") {\n", pWL->pName );
fprintf( s, " resistance : %f;\n", pWL->res );
fprintf( s, " capacitance : %f;\n", pWL->cap ); fprintf( s, " capacitance : %f;\n", pWL->cap );
fprintf( s, " slope : %f;\n", pWL->slope );
for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) 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, " fanout_length( %d, %f );\n", Vec_IntEntry(pWL->vFanout, j), Vec_FltEntry(pWL->vLen, j) );
fprintf( s, " }\n\n" ); fprintf( s, " }\n\n" );
......
...@@ -811,10 +811,10 @@ void Scl_LibertyReadWireLoad( Scl_Tree_t * p, Vec_Str_t * vOut ) ...@@ -811,10 +811,10 @@ void Scl_LibertyReadWireLoad( Scl_Tree_t * p, Vec_Str_t * vOut )
Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load" ) Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "wire_load" )
{ {
Vec_StrPutS_( vOut, Scl_LibertyReadString(p, pItem->Head) ); 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" ) Scl_ItemForEachChildName( p, pItem, pChild, "capacitance" )
Vec_StrPutF_( vOut, atof(Scl_LibertyReadString(p, pChild->Head)) ); 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_StrPut_( vOut );
Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "fanout_length") ); Vec_StrPutI_( vOut, Scl_LibertyItemNum(p, pItem, "fanout_length") );
Vec_StrPut_( vOut ); Vec_StrPut_( vOut );
...@@ -1575,6 +1575,8 @@ SC_Lib * Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose ) ...@@ -1575,6 +1575,8 @@ SC_Lib * Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose )
Scl_LibertyStop( p, fVeryVerbose ); Scl_LibertyStop( p, fVeryVerbose );
// construct SCL data-structure // construct SCL data-structure
pLib = Abc_SclReadFromStr( vStr ); pLib = Abc_SclReadFromStr( vStr );
if ( pLib == NULL )
return NULL;
pLib->pFileName = Abc_UtilStrsav( pFileName ); pLib->pFileName = Abc_UtilStrsav( pFileName );
Abc_SclLibNormalize( pLib ); Abc_SclLibNormalize( pLib );
Vec_StrFree( vStr ); Vec_StrFree( vStr );
......
...@@ -42,29 +42,41 @@ ABC_NAMESPACE_IMPL_START ...@@ -42,29 +42,41 @@ ABC_NAMESPACE_IMPL_START
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL ) Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL, int nFanoutMax )
{ {
Vec_Flt_t * vCaps = NULL; Vec_Flt_t * vCaps = NULL;
float EntryPrev, EntryCur; float EntryPrev, EntryCur, Slope;
int i, Entry, EntryMax; int i, iPrev, k, Entry, EntryMax;
assert( pWL != NULL ); assert( pWL != NULL );
// find the biggest fanout // find the biggest fanout count
EntryMax = 0; EntryMax = 0;
Vec_IntForEachEntry( pWL->vFanout, Entry, i ) Vec_IntForEachEntry( pWL->vFanout, Entry, i )
EntryMax = Abc_MaxInt( EntryMax, Entry ); EntryMax = Abc_MaxInt( EntryMax, Entry );
// create the array // create the array
vCaps = Vec_FltStart( EntryMax + 1 ); vCaps = Vec_FltStart( Abc_MaxInt(nFanoutMax, EntryMax) + 1 );
Vec_IntForEachEntry( pWL->vFanout, Entry, i ) Vec_IntForEachEntry( pWL->vFanout, Entry, i )
Vec_FltWriteEntry( vCaps, Entry, Vec_FltEntry(pWL->vLen, i) * pWL->cap ); Vec_FltWriteEntry( vCaps, Entry, Vec_FltEntry(pWL->vLen, i) * pWL->cap );
// reformat // interpolate between the values
EntryPrev = 0; assert( Vec_FltEntry(vCaps, 1) != 0 );
Vec_FltForEachEntry( vCaps, EntryCur, i ) iPrev = 1;
EntryPrev = Vec_FltEntry(vCaps, 1);
Vec_FltForEachEntryStart( vCaps, EntryCur, i, 2 )
{ {
if ( EntryCur ) if ( EntryCur == 0 )
EntryPrev = EntryCur; continue;
else Slope = (EntryCur - EntryPrev) / (i - iPrev);
Vec_FltWriteEntry( vCaps, i, EntryPrev ); 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; return vCaps;
} }
...@@ -126,7 +138,7 @@ void Abc_SclComputeLoad( SC_Man * p ) ...@@ -126,7 +138,7 @@ void Abc_SclComputeLoad( SC_Man * p )
if ( p->pWLoadUsed != NULL ) if ( p->pWLoadUsed != NULL )
{ {
if ( p->vWireCaps == 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_NtkForEachNode1( p->pNtk, pObj, i )
Abc_SclAddWireLoad( p, pObj, 0 ); Abc_SclAddWireLoad( p, pObj, 0 );
Abc_NtkForEachPi( p->pNtk, pObj, i ) Abc_NtkForEachPi( p->pNtk, pObj, i )
......
...@@ -553,7 +553,7 @@ extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax ...@@ -553,7 +553,7 @@ extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax
/*=== sclDnsize.c ===============================================================*/ /*=== sclDnsize.c ===============================================================*/
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclLoad.c ===============================================================*/ /*=== 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 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_SclAddWireLoad( SC_Man * p, Abc_Obj_t * pObj, int fSubtr );
extern void Abc_SclComputeLoad( SC_Man * p ); extern void Abc_SclComputeLoad( SC_Man * p );
......
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