From dfd6ab08234ac0cd5eec5396b87f3e57449d5253 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 25 Aug 2012 19:00:26 -0700 Subject: New package to read/write a subset of Liberty for STA. --- src/map/scl/scl.c | 68 ++++- src/map/scl/scl.h | 9 +- src/map/scl/sclFile.c | 669 +++++++++++++++++++++++++++++++++++--------------- src/map/scl/sclInt.h | 16 +- src/map/scl/sclSize.c | 1 + src/map/scl/sclTime.c | 311 +++++++++++++++++++++++ 6 files changed, 863 insertions(+), 211 deletions(-) (limited to 'src') diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index b004f526..4db37891 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -29,6 +29,7 @@ ABC_NAMESPACE_IMPL_START static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandWrite( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -49,19 +50,8 @@ void Scl_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "SC mapping", "read_scl", Scl_CommandRead, 0 ); Cmd_CommandAdd( pAbc, "SC mapping", "write_scl", Scl_CommandWrite, 0 ); + Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 ); } - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ void Scl_End( Abc_Frame_t * pAbc ) { Abc_SclLoad( NULL, &pAbc->pLibScl ); @@ -111,6 +101,7 @@ int Scl_CommandRead( Abc_Frame_t * pAbc, int argc, char ** argv ) // read new library Abc_SclLoad( pFileName, &pAbc->pLibScl ); + Abc_SclWriteText( "sizing\\scl_out.txt", pAbc->pLibScl ); return 0; usage: @@ -177,6 +168,59 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + int c; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( Abc_FrameReadNtk(pAbc) == NULL ) + { + fprintf( pAbc->Err, "There is no current network.\n" ); + return 1; + } + if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) ) + { + fprintf( pAbc->Err, "The current network is not mapped.\n" ); + return 1; + } + if ( pAbc->pLibScl == NULL ) + { + fprintf( pAbc->Err, "There is no Liberty Library available.\n" ); + return 1; + } + + Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc) ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: stime [-h]\n" ); + fprintf( pAbc->Err, "\t performs STA using Liberty library\n" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/map/scl/scl.h b/src/map/scl/scl.h index 5ce2f347..41e89e15 100644 --- a/src/map/scl/scl.h +++ b/src/map/scl/scl.h @@ -46,9 +46,12 @@ ABC_NAMESPACE_HEADER_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/*=== scl.c =============================================================*/ -extern void Abc_SclLoad( char * pFileName, void ** ppScl ); -extern void Abc_SclSave( char * pFileName, void * pScl ); +/*=== sclFile.c =============================================================*/ +extern void Abc_SclLoad( char * pFileName, void ** ppScl ); +extern void Abc_SclSave( char * pFileName, void * pScl ); +/*=== sclTime.c =============================================================*/ +extern void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk ); + ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclFile.c b/src/map/scl/sclFile.c index 4a9ad0ed..f8a360de 100644 --- a/src/map/scl/sclFile.c +++ b/src/map/scl/sclFile.c @@ -25,13 +25,15 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern void Extra_PrintHex( FILE * pFile, unsigned Sign[], int nBits ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Binary I/O for numbers (int, word, float) and strings (char *).] + Synopsis [Binary I/O for numbers (int/float/etc) and strings (char *).] Description [] @@ -40,13 +42,13 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline void Abc_SclPutI_no_enc( Vec_Str_t * vOut, int Val ) +static inline void Vec_StrPutI_ne( Vec_Str_t * vOut, int Val ) { int i; for ( i = 0; i < 4; i++ ) Vec_StrPush( vOut, (char)(Val >> (8*i)) ); } -static inline int Abc_SclGetI_no_enc( Vec_Str_t * vOut, int * pPos ) +static inline int Vec_StrGetI_ne( Vec_Str_t * vOut, int * pPos ) { int i; int Val = 0; @@ -55,13 +57,13 @@ static inline int Abc_SclGetI_no_enc( Vec_Str_t * vOut, int * pPos ) return Val; } -static inline void Abc_SclPutI( Vec_Str_t * vOut, int Val ) +static inline void Vec_StrPutI( Vec_Str_t * vOut, int Val ) { for ( ; Val >= 0x80; Val >>= 7 ) Vec_StrPush( vOut, (unsigned char)(Val | 0x80) ); Vec_StrPush( vOut, (unsigned char)Val ); } -static inline int Abc_SclGetI( Vec_Str_t * vOut, int * pPos ) +static inline int Vec_StrGetI( Vec_Str_t * vOut, int * pPos ) { unsigned char ch; int i = 0, Val = 0; @@ -70,13 +72,13 @@ static inline int Abc_SclGetI( Vec_Str_t * vOut, int * pPos ) return Val | (ch << (7 * i)); } -static inline void Abc_SclPutW( Vec_Str_t * vOut, word Val ) +static inline void Vec_StrPutW( Vec_Str_t * vOut, word Val ) { int i; for ( i = 0; i < 8; i++ ) Vec_StrPush( vOut, (char)(Val >> (8*i)) ); } -static inline word Abc_SclGetW( Vec_Str_t * vOut, int * pPos ) +static inline word Vec_StrGetW( Vec_Str_t * vOut, int * pPos ) { int i; word Val = 0; @@ -85,7 +87,7 @@ static inline word Abc_SclGetW( Vec_Str_t * vOut, int * pPos ) return Val; } -static inline void Abc_SclPutF( Vec_Str_t * vOut, float Val ) +static inline void Vec_StrPutF( Vec_Str_t * vOut, float Val ) { union { float num; unsigned char data[4]; } tmp; tmp.num = Val; @@ -94,7 +96,7 @@ static inline void Abc_SclPutF( Vec_Str_t * vOut, float Val ) Vec_StrPush( vOut, tmp.data[2] ); Vec_StrPush( vOut, tmp.data[3] ); } -static inline float Abc_SclGetF( Vec_Str_t * vOut, int * pPos ) +static inline float Vec_StrGetF( Vec_Str_t * vOut, int * pPos ) { union { float num; unsigned char data[4]; } tmp; tmp.data[0] = Vec_StrEntry( vOut, (*pPos)++ ); @@ -104,7 +106,7 @@ static inline float Abc_SclGetF( Vec_Str_t * vOut, int * pPos ) return tmp.num; } -static inline void Abc_SclPutD( Vec_Str_t * vOut, double Val ) +static inline void Vec_StrPutD( Vec_Str_t * vOut, double Val ) { union { double num; unsigned char data[8]; } tmp; int i, Lim = sizeof(double); @@ -112,7 +114,7 @@ static inline void Abc_SclPutD( Vec_Str_t * vOut, double Val ) for ( i = 0; i < Lim; i++ ) Vec_StrPush( vOut, tmp.data[i] ); } -static inline double Abc_SclGetD( Vec_Str_t * vOut, int * pPos ) +static inline double Vec_StrGetD( Vec_Str_t * vOut, int * pPos ) { union { double num; unsigned char data[8]; } tmp; int i, Lim = sizeof(double); @@ -121,19 +123,273 @@ static inline double Abc_SclGetD( Vec_Str_t * vOut, int * pPos ) return tmp.num; } -static inline void Abc_SclPutS( Vec_Str_t * vOut, char * pStr ) +static inline void Vec_StrPutS( Vec_Str_t * vOut, char * pStr ) { while ( *pStr ) Vec_StrPush( vOut, *pStr++ ); Vec_StrPush( vOut, (char)0 ); } -static inline char * Abc_SclGetS( Vec_Str_t * vOut, int * pPos ) +static inline char * Vec_StrGetS( Vec_Str_t * vOut, int * pPos ) { char * pStr = Vec_StrEntryP( vOut, *pPos ); while ( Vec_StrEntry(vOut, (*pPos)++) ); return Abc_UtilStrsav(pStr); } +static inline void Vec_StrPutC( Vec_Str_t * vOut, char c ) +{ + Vec_StrPush( vOut, c ); +} +static inline char Vec_StrGetC( Vec_Str_t * vOut, int * pPos ) +{ + return Vec_StrEntry(vOut, (*pPos)++); +} + + +/**Function************************************************************* + + Synopsis [Reading library from file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static unsigned Abc_SclHashString( char * pName, int TableSize ) +{ + static int s_Primes[10] = { 1291, 1699, 2357, 4177, 5147, 5647, 6343, 7103, 7873, 8147 }; + unsigned i, Key = 0; + for ( i = 0; pName[i] != '\0'; i++ ) + Key += s_Primes[i%10]*pName[i]*pName[i]; + return Key % TableSize; +} +int * Abc_SclHashLookup( SC_Lib * p, char * pName ) +{ + int i; + for ( i = Abc_SclHashString(pName, p->nBins); i < p->nBins; i = (i + 1) % p->nBins ) + if ( p->pBins[i] == -1 || !strcmp(pName, SC_LibCell(p, p->pBins[i])->name) ) + return p->pBins + i; + assert( 0 ); + return NULL; +} +void Abc_SclHashGates( SC_Lib * p ) +{ + SC_Cell * pCell; + int i, * pPlace; + assert( p->nBins == 0 ); + p->nBins = Abc_PrimeCudd( 5 * Vec_PtrSize(p->vCells) ); + p->pBins = ABC_FALLOC( int, p->nBins ); + Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) + { + pPlace = Abc_SclHashLookup( p, pCell->name ); + assert( *pPlace == -1 ); + *pPlace = i; + } +} +int Abc_SclCellFind( SC_Lib * p, char * pName ) +{ + return *Abc_SclHashLookup( p, pName ); +} + +/**Function************************************************************* + + Synopsis [Reading library from file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void Abc_SclReadSurface( Vec_Str_t * vOut, int * pPos, SC_Surface * p ) +{ + Vec_Flt_t * vVec; + int i, j; + + for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) + Vec_FltPush( p->vIndex0, Vec_StrGetF(vOut, pPos) ); + + for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) + Vec_FltPush( p->vIndex1, Vec_StrGetF(vOut, pPos) ); + + for ( i = 0; i < Vec_FltSize(p->vIndex0); i++ ) + { + vVec = Vec_FltAlloc( Vec_FltSize(p->vIndex1) ); + Vec_PtrPush( p->vData, vVec ); + for ( j = 0; j < Vec_FltSize(p->vIndex1); j++ ) + Vec_FltPush( vVec, Vec_StrGetF(vOut, pPos) ); + } + + for ( i = 0; i < 3; i++ ) + p->approx[0][i] = Vec_StrGetF( vOut, pPos ); + for ( i = 0; i < 4; i++ ) + p->approx[1][i] = Vec_StrGetF( vOut, pPos ); + 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 ) +{ + int i, j, k, n; + int version = Vec_StrGetI( vOut, pPos ); + assert( version == ABC_SCL_CUR_VERSION ); // wrong version of the file + + // Read non-composite fields: + p->lib_name = Vec_StrGetS(vOut, pPos); + p->default_wire_load = Vec_StrGetS(vOut, pPos); + p->default_wire_load_sel = Vec_StrGetS(vOut, pPos); + p->default_max_out_slew = Vec_StrGetF(vOut, pPos); + + p->unit_time = Vec_StrGetI(vOut, pPos); + p->unit_cap_fst = Vec_StrGetF(vOut, pPos); + p->unit_cap_snd = Vec_StrGetI(vOut, pPos); + + // Read 'wire_load' vector: + for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) + { + SC_WireLoad * pWL = Abc_SclWireLoadAlloc(); + Vec_PtrPush( p->vWireLoads, pWL ); + + pWL->name = Vec_StrGetS(vOut, pPos); + pWL->res = Vec_StrGetF(vOut, pPos); + pWL->cap = Vec_StrGetF(vOut, pPos); + + for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) + { + Vec_IntPush( pWL->vFanout, Vec_StrGetI(vOut, pPos) ); + Vec_FltPush( pWL->vLen, Vec_StrGetF(vOut, pPos) ); + } + } + + // Read 'wire_load_sel' vector: + for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) + { + SC_WireLoadSel * pWLS = Abc_SclWireLoadSelAlloc(); + Vec_PtrPush( p->vWireLoadSels, pWLS ); + + pWLS->name = Vec_StrGetS(vOut, pPos); + for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) + { + Vec_FltPush( pWLS->vAreaFrom, Vec_StrGetF(vOut, pPos) ); + Vec_FltPush( pWLS->vAreaTo, Vec_StrGetF(vOut, pPos) ); + Vec_PtrPush( pWLS->vWireLoadModel, Vec_StrGetS(vOut, pPos) ); + } + } + + for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) + { + SC_Cell * pCell = Abc_SclCellAlloc(); + Vec_PtrPush( p->vCells, pCell ); + + pCell->name = Vec_StrGetS(vOut, pPos); + pCell->area = Vec_StrGetF(vOut, pPos); + pCell->drive_strength = Vec_StrGetI(vOut, pPos); + + pCell->n_inputs = Vec_StrGetI(vOut, pPos); + pCell->n_outputs = Vec_StrGetI(vOut, pPos); + + for ( j = 0; j < pCell->n_inputs; j++ ) + { + SC_Pin * pPin = Abc_SclPinAlloc(); + Vec_PtrPush( pCell->vPins, pPin ); + + pPin->dir = sc_dir_Input; + pPin->name = Vec_StrGetS(vOut, pPos); + pPin->rise_cap = Vec_StrGetF(vOut, pPos); + pPin->fall_cap = Vec_StrGetF(vOut, pPos); + } + + for ( j = 0; j < pCell->n_outputs; j++ ) + { + SC_Pin * pPin = Abc_SclPinAlloc(); + Vec_PtrPush( pCell->vPins, pPin ); + + pPin->dir = sc_dir_Output; + pPin->name = Vec_StrGetS(vOut, pPos); + pPin->max_out_cap = Vec_StrGetF(vOut, pPos); + pPin->max_out_slew = Vec_StrGetF(vOut, pPos); + + k = Vec_StrGetI(vOut, pPos); + assert( k == pCell->n_inputs ); + + // read functions + 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) ); + + // Read 'rtiming': (pin-to-pin timing tables for this particular output) + for ( k = 0; k < pCell->n_inputs; k++ ) + { + SC_Timings * pRTime = Abc_SclTimingsAlloc(); + Vec_PtrPush( pPin->vRTimings, pRTime ); + + pRTime->name = Vec_StrGetS(vOut, pPos); + n = Vec_StrGetI(vOut, pPos); assert( n <= 1 ); + if ( n == 1 ) + { + SC_Timing * pTime = Abc_SclTimingAlloc(); + Vec_PtrPush( pRTime->vTimings, pTime ); + + pTime->tsense = (SC_TSense)Vec_StrGetI(vOut, pPos); + Abc_SclReadSurface( vOut, pPos, pTime->pCellRise ); + Abc_SclReadSurface( vOut, pPos, pTime->pCellFall ); + Abc_SclReadSurface( vOut, pPos, pTime->pRiseTrans ); + Abc_SclReadSurface( vOut, pPos, pTime->pFallTrans ); + } + else + assert( Vec_PtrSize(pPin->vRTimings) == 0 ); + } + } + } +} +SC_Lib * Abc_SclRead( char * pFileName ) +{ + SC_Lib * p; + FILE * pFile; + Vec_Str_t * vOut; + int nFileSize, Pos = 0; + + pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + rewind( pFile ); + // load the contents + vOut = Vec_StrAlloc( nFileSize ); + vOut->nSize = vOut->nCap; + assert( nFileSize == Vec_StrSize(vOut) ); + nFileSize = fread( Vec_StrArray(vOut), 1, Vec_StrSize(vOut), pFile ); + assert( nFileSize == Vec_StrSize(vOut) ); + fclose( pFile ); + // read the library + p = Abc_SclLibAlloc(); + Abc_SclReadLibrary( vOut, &Pos, p ); + assert( Pos == Vec_StrSize(vOut) ); + Vec_StrFree( vOut ); + // hash gates by name + Abc_SclHashGates( p ); + return p; +} +void Abc_SclLoad( char * pFileName, void ** ppScl ) +{ + if ( *ppScl ) + { + Abc_SclLibFree( *(SC_Lib **)ppScl ); + *ppScl = NULL; + } + assert( *ppScl == NULL ); + if ( pFileName ) + *(SC_Lib **)ppScl = Abc_SclRead( pFileName ); +} + /**Function************************************************************* @@ -152,24 +408,24 @@ static void Abc_SclWriteSurface( Vec_Str_t * vOut, SC_Surface * p ) float Entry; int i, k; - Abc_SclPutI( vOut, Vec_FltSize(p->vIndex0) ); + Vec_StrPutI( vOut, Vec_FltSize(p->vIndex0) ); Vec_FltForEachEntry( p->vIndex0, Entry, i ) - Abc_SclPutF( vOut, Entry ); + Vec_StrPutF( vOut, Entry ); - Abc_SclPutI( vOut, Vec_FltSize(p->vIndex1) ); + Vec_StrPutI( vOut, Vec_FltSize(p->vIndex1) ); Vec_FltForEachEntry( p->vIndex1, Entry, i ) - Abc_SclPutF( vOut, Entry ); + Vec_StrPutF( vOut, Entry ); Vec_PtrForEachEntry( Vec_Flt_t *, p->vData, vVec, i ) Vec_FltForEachEntry( vVec, Entry, k ) - Abc_SclPutF( vOut, Entry ); + Vec_StrPutF( vOut, Entry ); for ( i = 0; i < 3; i++ ) - Abc_SclPutF( vOut, p->approx[0][i] ); + Vec_StrPutF( vOut, p->approx[0][i] ); for ( i = 0; i < 4; i++ ) - Abc_SclPutF( vOut, p->approx[1][i] ); + Vec_StrPutF( vOut, p->approx[1][i] ); for ( i = 0; i < 6; i++ ) - Abc_SclPutF( vOut, p->approx[2][i] ); + Vec_StrPutF( vOut, p->approx[2][i] ); } static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) { @@ -180,47 +436,47 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) int n_valid_cells; int i, j, k; - Abc_SclPutI( vOut, ABC_SCL_CUR_VERSION ); + Vec_StrPutI( vOut, ABC_SCL_CUR_VERSION ); // Write non-composite fields: - Abc_SclPutS( vOut, p->lib_name ); - Abc_SclPutS( vOut, p->default_wire_load ); - Abc_SclPutS( vOut, p->default_wire_load_sel ); - Abc_SclPutF( vOut, p->default_max_out_slew ); + Vec_StrPutS( vOut, p->lib_name ); + Vec_StrPutS( vOut, p->default_wire_load ); + Vec_StrPutS( vOut, p->default_wire_load_sel ); + Vec_StrPutF( vOut, p->default_max_out_slew ); assert( p->unit_time >= 0 ); assert( p->unit_cap_snd >= 0 ); - Abc_SclPutI( vOut, p->unit_time ); - Abc_SclPutF( vOut, p->unit_cap_fst ); - Abc_SclPutI( vOut, p->unit_cap_snd ); + Vec_StrPutI( vOut, p->unit_time ); + Vec_StrPutF( vOut, p->unit_cap_fst ); + Vec_StrPutI( vOut, p->unit_cap_snd ); // Write 'wire_load' vector: - Abc_SclPutI( vOut, Vec_PtrSize(p->vWireLoads) ); + Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoads) ); Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) { - Abc_SclPutS( vOut, pWL->name ); - Abc_SclPutF( vOut, pWL->res ); - Abc_SclPutF( vOut, pWL->cap ); + Vec_StrPutS( vOut, pWL->name ); + Vec_StrPutF( vOut, pWL->res ); + Vec_StrPutF( vOut, pWL->cap ); - Abc_SclPutI( vOut, Vec_IntSize(pWL->vFanout) ); + Vec_StrPutI( vOut, Vec_IntSize(pWL->vFanout) ); for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) { - Abc_SclPutI( vOut, Vec_IntEntry(pWL->vFanout, j) ); - Abc_SclPutF( vOut, Vec_FltEntry(pWL->vLen, j) ); + Vec_StrPutI( vOut, Vec_IntEntry(pWL->vFanout, j) ); + Vec_StrPutF( vOut, Vec_FltEntry(pWL->vLen, j) ); } } // Write 'wire_load_sel' vector: - Abc_SclPutI( vOut, Vec_PtrSize(p->vWireLoadSels) ); + Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoadSels) ); Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) { - Abc_SclPutS( vOut, pWLS->name ); - Abc_SclPutI( vOut, Vec_FltSize(pWLS->vAreaFrom) ); + Vec_StrPutS( vOut, pWLS->name ); + Vec_StrPutI( vOut, Vec_FltSize(pWLS->vAreaFrom) ); for ( j = 0; j < Vec_FltSize(pWLS->vAreaFrom); j++) { - Abc_SclPutF( vOut, Vec_FltEntry(pWLS->vAreaFrom, j) ); - Abc_SclPutF( vOut, Vec_FltEntry(pWLS->vAreaTo, j) ); - Abc_SclPutS( vOut, (char *)Vec_PtrEntry(pWLS->vWireLoadModel, j) ); + Vec_StrPutF( vOut, Vec_FltEntry(pWLS->vAreaFrom, j) ); + Vec_StrPutF( vOut, Vec_FltEntry(pWLS->vAreaTo, j) ); + Vec_StrPutS( vOut, (char *)Vec_PtrEntry(pWLS->vWireLoadModel, j) ); } } @@ -230,26 +486,26 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) if ( !(pCell->seq || pCell->unsupp) ) n_valid_cells++; - Abc_SclPutI( vOut, n_valid_cells ); + Vec_StrPutI( vOut, n_valid_cells ); Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) { if ( pCell->seq || pCell->unsupp ) continue; - Abc_SclPutS( vOut, pCell->name ); - Abc_SclPutF( vOut, pCell->area ); - Abc_SclPutI( vOut, pCell->drive_strength ); + Vec_StrPutS( vOut, pCell->name ); + Vec_StrPutF( vOut, pCell->area ); + Vec_StrPutI( vOut, pCell->drive_strength ); // Write 'pins': (sorted at this point; first inputs, then outputs) - Abc_SclPutI( vOut, pCell->n_inputs); - Abc_SclPutI( vOut, pCell->n_outputs); + Vec_StrPutI( vOut, pCell->n_inputs); + Vec_StrPutI( vOut, pCell->n_outputs); Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) { assert(pPin->dir == sc_dir_Input); - Abc_SclPutS( vOut, pPin->name ); - Abc_SclPutF( vOut, pPin->rise_cap ); - Abc_SclPutF( vOut, pPin->fall_cap ); + Vec_StrPutS( vOut, pPin->name ); + Vec_StrPutF( vOut, pPin->rise_cap ); + Vec_StrPutF( vOut, pPin->fall_cap ); } Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) @@ -258,22 +514,22 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) word uWord; assert(pPin->dir == sc_dir_Output); - Abc_SclPutS( vOut, pPin->name ); - Abc_SclPutF( vOut, pPin->max_out_cap ); - Abc_SclPutF( vOut, pPin->max_out_slew ); + Vec_StrPutS( vOut, pPin->name ); + Vec_StrPutF( vOut, pPin->max_out_cap ); + Vec_StrPutF( vOut, pPin->max_out_slew ); // write function assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); - Abc_SclPutI( vOut, pCell->n_inputs ); + Vec_StrPutI( vOut, pCell->n_inputs ); Vec_WrdForEachEntry( pPin->vFunc, uWord, k ) // -- 'size = 1u << (n_vars - 6)' - Abc_SclPutW( vOut, uWord ); // -- 64-bit number, written uncompressed (low-byte first) + Vec_StrPutW( vOut, uWord ); // -- 64-bit number, written uncompressed (low-byte first) // Write 'rtiming': (pin-to-pin timing tables for this particular output) assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) { - Abc_SclPutS( vOut, pRTime->name ); - Abc_SclPutI( vOut, Vec_PtrSize(pRTime->vTimings) ); + Vec_StrPutS( vOut, pRTime->name ); + Vec_StrPutI( vOut, Vec_PtrSize(pRTime->vTimings) ); // -- NOTE! After post-processing, the size of the 'rtiming[k]' vector is either // 0 or 1 (in static timing, we have merged all tables to get the worst case). // The case with size 0 should only occur for multi-output gates. @@ -282,7 +538,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) SC_Timing * pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); // -- NOTE! We don't need to save 'related_pin' string because we have sorted // the elements on input pins. - Abc_SclPutI( vOut, (int)pTime->tsense); + Vec_StrPutI( vOut, (int)pTime->tsense); Abc_SclWriteSurface( vOut, pTime->pCellRise ); Abc_SclWriteSurface( vOut, pTime->pCellFall ); Abc_SclWriteSurface( vOut, pTime->pRiseTrans ); @@ -321,7 +577,7 @@ void Abc_SclSave( char * pFileName, void * pScl ) /**Function************************************************************* - Synopsis [Reading library from file.] + Synopsis [Writing library into text file.] Description [] @@ -330,188 +586,213 @@ void Abc_SclSave( char * pFileName, void * pScl ) SeeAlso [] ***********************************************************************/ -static void Abc_SclReadSurface( Vec_Str_t * vOut, int * pPos, SC_Surface * p ) +static void Abc_SclWriteSurfaceText( FILE * s, SC_Surface * p ) { Vec_Flt_t * vVec; - int i, j; + float Entry; + int i, k; + + fprintf( s, "Surface:\n" ); - for ( i = Abc_SclGetI(vOut, pPos); i != 0; i-- ) - Vec_FltPush( p->vIndex0, Abc_SclGetF(vOut, pPos) ); + fprintf( s, "%d", Vec_FltSize(p->vIndex0) ); + fprintf( s, "\n" ); + Vec_FltForEachEntry( p->vIndex0, Entry, i ) + fprintf( s, "%f ", Entry ); + fprintf( s, "\n" ); - for ( i = Abc_SclGetI(vOut, pPos); i != 0; i-- ) - Vec_FltPush( p->vIndex1, Abc_SclGetF(vOut, pPos) ); + fprintf( s, "%d", Vec_FltSize(p->vIndex1) ); + fprintf( s, "\n" ); + Vec_FltForEachEntry( p->vIndex1, Entry, i ) + fprintf( s, "%f ", Entry ); + fprintf( s, "\n" ); - for ( i = 0; i < Vec_FltSize(p->vIndex0); i++ ) + Vec_PtrForEachEntry( Vec_Flt_t *, p->vData, vVec, i ) { - vVec = Vec_FltAlloc( Vec_FltSize(p->vIndex1) ); - Vec_PtrPush( p->vData, vVec ); - for ( j = 0; j < Vec_FltSize(p->vIndex1); j++ ) - Vec_FltPush( vVec, Abc_SclGetF(vOut, pPos) ); + Vec_FltForEachEntry( vVec, Entry, k ) + fprintf( s, "%f ", Entry ); + fprintf( s, "\n" ); } for ( i = 0; i < 3; i++ ) - p->approx[0][i] = Abc_SclGetF( vOut, pPos ); + fprintf( s, "%f ", p->approx[0][i] ); + fprintf( s, "\n" ); for ( i = 0; i < 4; i++ ) - p->approx[1][i] = Abc_SclGetF( vOut, pPos ); + fprintf( s, "%f ", p->approx[1][i] ); + fprintf( s, "\n" ); for ( i = 0; i < 6; i++ ) - p->approx[2][i] = Abc_SclGetF( vOut, pPos ); + fprintf( s, "%f ", p->approx[2][i] ); + fprintf( s, "\n" ); } -static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) +static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) { - int i, j, k, n; - int version = Abc_SclGetI( vOut, pPos ); - assert( version == ABC_SCL_CUR_VERSION ); // wrong version of the file - - // Read non-composite fields: - p->lib_name = Abc_SclGetS(vOut, pPos); - p->default_wire_load = Abc_SclGetS(vOut, pPos); - p->default_wire_load_sel = Abc_SclGetS(vOut, pPos); - p->default_max_out_slew = Abc_SclGetF(vOut, pPos); + SC_WireLoad * pWL; + SC_WireLoadSel * pWLS; + SC_Cell * pCell; + SC_Pin * pPin; + int n_valid_cells; + int i, j, k; - p->unit_time = Abc_SclGetI(vOut, pPos); - p->unit_cap_fst = Abc_SclGetF(vOut, pPos); - p->unit_cap_snd = Abc_SclGetI(vOut, pPos); +// fprintf( s, "%d", ABC_SCL_CUR_VERSION ); + fprintf( s, "Liberty:\n" ); - // Read 'wire_load' vector: - for ( i = Abc_SclGetI(vOut, pPos); i != 0; i-- ) - { - SC_WireLoad * pWL = Abc_SclWireLoadAlloc(); - Vec_PtrPush( p->vWireLoads, pWL ); + // Write non-composite fields: + fprintf( s, "%s", p->lib_name ); + fprintf( s, "\n" ); + fprintf( s, "%s", p->default_wire_load ); + fprintf( s, "\n" ); + fprintf( s, "%s", p->default_wire_load_sel ); + fprintf( s, "\n" ); + fprintf( s, "%f", p->default_max_out_slew ); + fprintf( s, "\n" ); - pWL->name = Abc_SclGetS(vOut, pPos); - pWL->res = Abc_SclGetF(vOut, pPos); - pWL->cap = Abc_SclGetF(vOut, pPos); + assert( p->unit_time >= 0 ); + assert( p->unit_cap_snd >= 0 ); + fprintf( s, "%d", p->unit_time ); + fprintf( s, "\n" ); + fprintf( s, "%f", p->unit_cap_fst ); + fprintf( s, "\n" ); + fprintf( s, "%d", p->unit_cap_snd ); + fprintf( s, "\n" ); - for ( j = Abc_SclGetI(vOut, pPos); j != 0; j-- ) + // Write 'wire_load' vector: + fprintf( s, "\n" ); + fprintf( s, "%d", Vec_PtrSize(p->vWireLoads) ); + fprintf( s, "\n" ); + Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) + { + fprintf( s, "WireLoad:\n" ); + fprintf( s, "%s ", pWL->name ); + fprintf( s, "%f ", pWL->res ); + fprintf( s, "%f", pWL->cap ); + fprintf( s, "\n" ); + + fprintf( s, "%d", Vec_IntSize(pWL->vFanout) ); + fprintf( s, "\n" ); + for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) { - Vec_IntPush( pWL->vFanout, Abc_SclGetI(vOut, pPos) ); - Vec_FltPush( pWL->vLen, Abc_SclGetF(vOut, pPos) ); + fprintf( s, "%d ", Vec_IntEntry(pWL->vFanout, j) ); + fprintf( s, "%f ", Vec_FltEntry(pWL->vLen, j) ); } + fprintf( s, "\n" ); } + fprintf( s, "\n" ); - // Read 'wire_load_sel' vector: - for ( i = Abc_SclGetI(vOut, pPos); i != 0; i-- ) + // Write 'wire_load_sel' vector: + fprintf( s, "%d", Vec_PtrSize(p->vWireLoadSels) ); + fprintf( s, "\n" ); + Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) { - SC_WireLoadSel * pWLS = Abc_SclWireLoadSelAlloc(); - Vec_PtrPush( p->vWireLoadSels, pWLS ); - - pWLS->name = Abc_SclGetS(vOut, pPos); - for ( j = Abc_SclGetI(vOut, pPos); j != 0; j-- ) + fprintf( s, "WireLoadSel:\n" ); + fprintf( s, "%s", pWLS->name ); + fprintf( s, "\n" ); + fprintf( s, "%d", Vec_FltSize(pWLS->vAreaFrom) ); + fprintf( s, "\n" ); + for ( j = 0; j < Vec_FltSize(pWLS->vAreaFrom); j++) { - Vec_FltPush( pWLS->vAreaFrom, Abc_SclGetF(vOut, pPos) ); - Vec_FltPush( pWLS->vAreaTo, Abc_SclGetF(vOut, pPos) ); - Vec_PtrPush( pWLS->vWireLoadModel, Abc_SclGetS(vOut, pPos) ); + fprintf( s, "%f", Vec_FltEntry(pWLS->vAreaFrom, j) ); + fprintf( s, " " ); + fprintf( s, "%f", Vec_FltEntry(pWLS->vAreaTo, j) ); + fprintf( s, " " ); + fprintf( s, "%s", (char *)Vec_PtrEntry(pWLS->vWireLoadModel, j) ); + fprintf( s, "\n" ); } } + fprintf( s, "\n" ); + + // Write 'cells' vector: + n_valid_cells = 0; + Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) + if ( !(pCell->seq || pCell->unsupp) ) + n_valid_cells++; - for ( i = Abc_SclGetI(vOut, pPos); i != 0; i-- ) + fprintf( s, "%d", n_valid_cells ); + fprintf( s, "\n" ); + Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) { - SC_Cell * pCell = Abc_SclCellAlloc(); - Vec_PtrPush( p->vCells, pCell ); + if ( pCell->seq || pCell->unsupp ) + continue; - pCell->name = Abc_SclGetS(vOut, pPos); - pCell->area = Abc_SclGetF(vOut, pPos); - pCell->drive_strength = Abc_SclGetI(vOut, pPos); + fprintf( s, "\nCell:\n" ); + fprintf( s, "%s ", pCell->name ); + fprintf( s, "%f ", pCell->area ); + fprintf( s, "%d", pCell->drive_strength ); + fprintf( s, " " ); - pCell->n_inputs = Abc_SclGetI(vOut, pPos); - pCell->n_outputs = Abc_SclGetI(vOut, pPos); + // Write 'pins': (sorted at this point; first inputs, then outputs) + fprintf( s, "%d ", pCell->n_inputs); + fprintf( s, "%d", pCell->n_outputs); + fprintf( s, "\n" ); - for ( j = 0; j < pCell->n_inputs; j++ ) + Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) { - SC_Pin * pPin = Abc_SclPinAlloc(); - Vec_PtrPush( pCell->vPins, pPin ); - - pPin->dir = sc_dir_Input; - pPin->name = Abc_SclGetS(vOut, pPos); - pPin->rise_cap = Abc_SclGetF(vOut, pPos); - pPin->fall_cap = Abc_SclGetF(vOut, pPos); + assert(pPin->dir == sc_dir_Input); + fprintf( s, "Pin:\n" ); + fprintf( s, "%s ", pPin->name ); + fprintf( s, "%f ", pPin->rise_cap ); + fprintf( s, "%f", pPin->fall_cap ); + fprintf( s, "\n" ); } - for ( j = 0; j < pCell->n_outputs; j++ ) + Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) { - SC_Pin * pPin = Abc_SclPinAlloc(); - Vec_PtrPush( pCell->vPins, pPin ); - - pPin->dir = sc_dir_Output; - pPin->name = Abc_SclGetS(vOut, pPos); - pPin->max_out_cap = Abc_SclGetF(vOut, pPos); - pPin->max_out_slew = Abc_SclGetF(vOut, pPos); - - k = Abc_SclGetI(vOut, pPos); - assert( k == pCell->n_inputs ); + SC_Timings * pRTime; +// word uWord; + assert(pPin->dir == sc_dir_Output); - // read functions - 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, Abc_SclGetW(vOut, pPos) ); + fprintf( s, "Pin:\n" ); + fprintf( s, "%s ", pPin->name ); + fprintf( s, "%f ", pPin->max_out_cap ); + fprintf( s, "%f", pPin->max_out_slew ); + fprintf( s, "\n" ); +/* + // write function + assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); + fprintf( s, "%d", pCell->n_inputs ); + Vec_WrdForEachEntry( pPin->vFunc, uWord, k ) // -- 'size = 1u << (n_vars - 6)' + Vec_StrPutW( s, uWord ); // -- 64-bit number, written uncompressed (low-byte first) +*/ + Extra_PrintHex( s, (unsigned *)Vec_WrdArray(pPin->vFunc), pCell->n_inputs ); + fprintf( s, "\n" ); - // Read 'rtiming': (pin-to-pin timing tables for this particular output) - for ( k = 0; k < pCell->n_inputs; k++ ) + // Write 'rtiming': (pin-to-pin timing tables for this particular output) + assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); + Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) { - SC_Timings * pRTime = Abc_SclTimingsAlloc(); - Vec_PtrPush( pPin->vRTimings, pRTime ); - - pRTime->name = Abc_SclGetS(vOut, pPos); - n = Abc_SclGetI(vOut, pPos); assert( n <= 1 ); - if ( n == 1 ) + fprintf( s, "%s ", pRTime->name ); + fprintf( s, "%d", Vec_PtrSize(pRTime->vTimings) ); + fprintf( s, "\n" ); + // -- NOTE! After post-processing, the size of the 'rtiming[k]' vector is either + // 0 or 1 (in static timing, we have merged all tables to get the worst case). + // The case with size 0 should only occur for multi-output gates. + if ( Vec_PtrSize(pRTime->vTimings) == 1 ) { - SC_Timing * pTime = Abc_SclTimingAlloc(); - Vec_PtrPush( pRTime->vTimings, pTime ); - - pTime->tsense = (SC_TSense)Abc_SclGetI(vOut, pPos); - Abc_SclReadSurface( vOut, pPos, pTime->pCellRise ); - Abc_SclReadSurface( vOut, pPos, pTime->pCellFall ); - Abc_SclReadSurface( vOut, pPos, pTime->pRiseTrans ); - Abc_SclReadSurface( vOut, pPos, pTime->pFallTrans ); + SC_Timing * pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); + // -- NOTE! We don't need to save 'related_pin' string because we have sorted + // the elements on input pins. + fprintf( s, "%d", (int)pTime->tsense); + fprintf( s, "\n" ); + Abc_SclWriteSurfaceText( s, pTime->pCellRise ); + Abc_SclWriteSurfaceText( s, pTime->pCellFall ); + Abc_SclWriteSurfaceText( s, pTime->pRiseTrans ); + Abc_SclWriteSurfaceText( s, pTime->pFallTrans ); } else - assert( Vec_PtrSize(pPin->vRTimings) == 0 ); + assert( Vec_PtrSize(pRTime->vTimings) == 0 ); } } + fprintf( s, "\n" ); } } -SC_Lib * Abc_SclRead( char * pFileName ) +void Abc_SclWriteText( char * pFileName, SC_Lib * p ) { - SC_Lib * p; - FILE * pFile; - Vec_Str_t * vOut; - int nFileSize, Pos = 0; - - pFile = fopen( pFileName, "rb" ); + FILE * pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) + printf( "Cannot open text file \"%s\" for writing.\n", pFileName ); + else { - printf( "Cannot open file \"%s\" for reading.\n", pFileName ); - return NULL; - } - // get the file size, in bytes - fseek( pFile, 0, SEEK_END ); - nFileSize = ftell( pFile ); - rewind( pFile ); - // load the contents - vOut = Vec_StrAlloc( nFileSize ); - vOut->nSize = vOut->nCap; - assert( nFileSize == Vec_StrSize(vOut) ); - nFileSize = fread( Vec_StrArray(vOut), 1, Vec_StrSize(vOut), pFile ); - assert( nFileSize == Vec_StrSize(vOut) ); - fclose( pFile ); - // read the library - p = Abc_SclLibAlloc(); - Abc_SclReadLibrary( vOut, &Pos, p ); - assert( Pos == Vec_StrSize(vOut) ); - Vec_StrFree( vOut ); - return p; -} -void Abc_SclLoad( char * pFileName, void ** ppScl ) -{ - if ( *ppScl ) - { - Abc_SclLibFree( *(SC_Lib **)ppScl ); - *ppScl = NULL; + Abc_SclWriteLibraryText( pFile, p ); + fclose( pFile ); } - assert( *ppScl == NULL ); - if ( pFileName ) - *(SC_Lib **)ppScl = Abc_SclRead( pFileName ); } diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index b11ebc9e..192317f7 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -159,7 +159,9 @@ struct SC_Lib_ Vec_Ptr_t * vWireLoads; // NamedSet Vec_Ptr_t * vWireLoadSels; // NamedSet Vec_Ptr_t * vTempls; // NamedSet - Vec_Ptr_t * vCells; // NamedSet + Vec_Ptr_t * vCells; // NamedSet + int * pBins; // hashing gateName -> gateId + int nBins; }; //////////////////////////////////////////////////////////////////////// @@ -170,6 +172,9 @@ struct SC_Lib_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +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); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -351,11 +356,18 @@ static inline void Abc_SclLibFree( SC_Lib * p ) ABC_FREE( p->lib_name ); ABC_FREE( p->default_wire_load ); ABC_FREE( p->default_wire_load_sel ); + ABC_FREE( p->pBins ); ABC_FREE( p ); } -/*=== scl.c =============================================================*/ +/*=== sclFile.c =============================================================*/ +extern SC_Lib * Abc_SclRead( char * pFileName ); +extern void Abc_SclWrite( char * pFileName, SC_Lib * p ); +extern void Abc_SclWriteText( char * pFileName, SC_Lib * p ); + +extern int Abc_SclCellFind( SC_Lib * p, char * pName ); + ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 606ceba5..717c5ab5 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index 606ceba5..761c7eab 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -16,6 +16,8 @@ ***********************************************************************/ +#include "base/abc/abc.h" +#include "map/mio/mio.h" #include "sclInt.h" ABC_NAMESPACE_IMPL_START @@ -25,10 +27,295 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +typedef struct SC_Pair_ SC_Pair; +typedef struct SC_Man_ SC_Man; + +struct SC_Pair_ +{ + float rise; + float fall; +}; + +struct SC_Man_ +{ + SC_Lib * pLib; // library + Abc_Ntk_t * pNtk; // network + int nObjs; // allocated size + Vec_Int_t * vGates; // mapping of objId into gateId + SC_Pair * pLoads; // loads for each gate + SC_Pair * pArrs; // arrivals for each gate + SC_Pair * pSlews; // slews for each gate + char * pWireLoadUsed; // name of the used WireLoad model +}; + +static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); } +static inline SC_Pair * Abc_SclObjArr ( SC_Man * p, Abc_Obj_t * pObj ) { return p->pArrs + Abc_ObjId(pObj); } +static inline SC_Pair * Abc_SclObjSlew( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews + Abc_ObjId(pObj); } + +static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibCell( p->pLib, Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Prepares STA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclManFindGates( SC_Man * p ) +{ + Abc_Obj_t * pObj; + char * pName; + int i, gateId; + assert( p->vGates == NULL ); + p->vGates = Vec_IntStartFull( p->nObjs ); + Abc_NtkForEachNode( p->pNtk, pObj, i ) + { + pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData); + gateId = Abc_SclCellFind( p->pLib, pName ); + assert( gateId >= 0 ); + Vec_IntWriteEntry( p->vGates, i, gateId ); + } +} +SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) +{ + SC_Man * p; + assert( Abc_NtkHasMapping(pNtk) ); + p = ABC_CALLOC( SC_Man, 1 ); + p->pLib = pLib; + p->pNtk = pNtk; + p->nObjs = Abc_NtkObjNumMax(pNtk); + p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs ); + p->pArrs = ABC_CALLOC( SC_Pair, p->nObjs ); + p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs ); + Abc_SclManFindGates( p ); + return p; +} +void Abc_SclManFree( SC_Man * p ) +{ + Vec_IntFree( p->vGates ); + ABC_FREE( p->pLoads ); + ABC_FREE( p->pArrs ); + ABC_FREE( p->pSlews ); + ABC_FREE( p ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Abc_SclTotalArea( SC_Man * p, Vec_Ptr_t * vNodes ) +{ + double Area = 0; + Abc_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + Area += Abc_SclObjCell( p, pObj )->area; + return Area; +} +Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p, Vec_Ptr_t * vNodes ) +{ + Vec_Flt_t * vCaps = NULL; + SC_WireLoad * pWL; + int i, Entry, EntryPrev, EntryMax; + p->pWireLoadUsed = NULL; + if ( p->pLib->default_wire_load_sel ) + { + float Area; + SC_WireLoadSel * pWLS = NULL; + Vec_PtrForEachEntry( SC_WireLoadSel *, p->pLib->vWireLoadSels, pWLS, i ) + if ( !strcmp(pWLS->name, p->pLib->default_wire_load_sel) ) + break; + if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) + { + Abc_Print( -1, "Cannot find wire load selection model \"%s\".\n", p->pLib->default_wire_load_sel ); + exit(1); + } + Area = (float)Abc_SclTotalArea( p, vNodes ); + for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++) + if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) ) + { + p->pWireLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); + break; + } + if ( i == Vec_FltSize(pWLS->vAreaFrom) ) + p->pWireLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); + } + else if ( p->pLib->default_wire_load ) + p->pWireLoadUsed = p->pLib->default_wire_load; + else + { + Abc_Print( 0, "No wire model given.\n" ); + return NULL; + } + // Get the actual table and reformat it for 'wire_cap' output: + assert( p->pWireLoadUsed != NULL ); + Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) + if ( !strcmp(pWL->name, p->pWireLoadUsed) ) + break; + if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) + { + Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWireLoadUsed ); + exit(1); + } + // find the biggest fanout + EntryMax = 0; + Vec_IntForEachEntry( pWL->vFanout, Entry, i ) + EntryMax = Abc_MaxInt( EntryMax, Entry ); + // create the array + vCaps = Vec_FltStart( 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, Entry, i ) + { + if ( Entry ) + EntryPrev = Entry; + else + Vec_FltWriteEntry( vCaps, i, EntryPrev ); + } + return vCaps; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Abc_SclLookup( SC_Surface * p, float slew, float load ) +{ + float * pIndex0, * pIndex1, * pDataS, * pDataS1; + float sfrac, lfrac, p0, p1; + int s, l; + + // Find closest sample points in surface: + pIndex0 = Vec_FltArray(p->vIndex0); + for ( s = 1; s < Vec_FltSize(p->vIndex0)-1; s++ ) + if ( pIndex0[s] > slew ) + break; + s--; + + pIndex1 = Vec_FltArray(p->vIndex1); + for ( l = 1; l < Vec_FltSize(p->vIndex1)-1; l++ ) + if ( pIndex1[l] > load ) + break; + l--; + + // Interpolate (or extrapolate) function value from sample points: + sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]); + lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]); + + pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(p->vData, s) ); + pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(p->vData, s+1) ); + + p0 = pDataS [l] + lfrac * (pDataS [l+1] - pDataS [l]); + p1 = pDataS1[l] + lfrac * (pDataS1[l+1] - pDataS1[l]); + + return p0 + sfrac * (p1 - p0); // <<== multiply result with K factor here +} +void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) +{ + SC_Pair * pArrIn = Abc_SclObjLoad( p, pFanin ); + SC_Pair * pSlewIn = Abc_SclObjLoad( p, pFanin ); + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + SC_Pair * pArrOut = Abc_SclObjLoad( p, pObj ); // modified + SC_Pair * pSlewOut = Abc_SclObjLoad( p, pObj ); // modified + + if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non) + { + pArrOut->rise = Abc_MaxInt( pArrOut->rise, pArrIn->rise + Abc_SclLookup(pTime->pCellRise, pSlewIn->rise, pLoad->rise) ); + pArrOut->fall = Abc_MaxInt( pArrOut->fall, pArrIn->fall + Abc_SclLookup(pTime->pCellFall, pSlewIn->fall, pLoad->fall) ); + pSlewOut->rise = Abc_MaxInt( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) ); + pSlewOut->fall = Abc_MaxInt( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->fall, pLoad->fall) ); + } + if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non) + { + pArrOut->rise = Abc_MaxInt( pArrOut->rise, pArrIn->fall + Abc_SclLookup(pTime->pCellRise, pSlewIn->fall, pLoad->rise) ); + pArrOut->fall = Abc_MaxInt( pArrOut->fall, pArrIn->rise + Abc_SclLookup(pTime->pCellFall, pSlewIn->rise, pLoad->fall) ); + pSlewOut->rise = Abc_MaxInt( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) ); + pSlewOut->fall = Abc_MaxInt( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) ); + } +} +void Abc_SclComputeLoad( SC_Man * p, Vec_Ptr_t * vNodes, Vec_Flt_t * vWireCaps ) +{ + Abc_Obj_t * pObj, * pFanin; + int i, k; + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + SC_Cell * pCell = Abc_SclObjCell( p, pObj ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Pin * pPin = SC_CellPin( pCell, k ); + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + pLoad->rise += pPin->rise_cap; + pLoad->fall += pPin->fall_cap; + } + } + if ( vWireCaps ) + { + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + k = Abc_MinInt( Vec_FltSize(vWireCaps)-1, Abc_ObjFanoutNum(pObj) ); + pLoad->rise += Vec_FltEntry(vWireCaps, k); + pLoad->fall += Vec_FltEntry(vWireCaps, k); + } + } +} +void Abc_SclTimeNtk( SC_Man * p ) +{ + Vec_Flt_t * vWireCaps; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj; + int i, k; + vNodes = Abc_NtkDfs( p->pNtk, 0 ); + vWireCaps = Abc_SclFindWireCaps( p, vNodes ); + Abc_SclComputeLoad( p, vNodes, vWireCaps ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + SC_Timings * pRTime; + SC_Timing * pTime; + SC_Pin * pPin; + // get the library cell + SC_Cell * pCell = Abc_SclObjCell( p, 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 ); + Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) + { + assert( Vec_PtrSize(pRTime->vTimings) == 1 ); + pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); + Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) ); + } + } + Vec_PtrFree( vNodes ); +} + /**Function************************************************************* Synopsis [] @@ -40,6 +327,30 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Abc_SclTimeNtkPrint( SC_Man * p ) +{ +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk ) +{ + SC_Man * p; + p = Abc_SclManAlloc( pLib, (Abc_Ntk_t *)pNtk ); + Abc_SclTimeNtk( p ); + Abc_SclTimeNtkPrint( p ); + Abc_SclManFree( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -- cgit v1.2.3