From 0c719ab69ef8a0cdbb618b2fd6de2c85fd46accb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 8 Sep 2023 14:23:14 +0700 Subject: [PATCH] Adding procedure to merge two libraries. --- src/base/io/io.c | 2 +- src/map/scl/scl.c | 72 +++++++++++++----- src/map/scl/sclLib.h | 1 + src/map/scl/sclLibScl.c | 160 +++++++++++++++++++++++++--------------- 4 files changed, 155 insertions(+), 80 deletions(-) diff --git a/src/base/io/io.c b/src/base/io/io.c index ae2f210bb..7b8ca184e 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1542,7 +1542,7 @@ int IoCommandWrite( Abc_Frame_t * pAbc, int argc, char **argv ) if ( !strcmp( Extra_FileNameExtension(pFileName), "genlib" ) ) sprintf( Command, "write_genlib %s", pFileName ); else if ( !strcmp( Extra_FileNameExtension(pFileName), "lib" ) ) - sprintf( Command, "write_liberty %s", pFileName ); + sprintf( Command, "write_lib %s", pFileName ); else if ( !strcmp( Extra_FileNameExtension(pFileName), "dsd" ) ) sprintf( Command, "dsd_save %s", pFileName ); if ( Command[0] ) diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index 6ebc52f8b..3a82280dc 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -130,7 +130,36 @@ void Scl_End( Abc_Frame_t * pAbc ) Scl_ConUpdateMan( pAbc, NULL ); } +/**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +SC_Lib * Scl_ReadLibraryFile( Abc_Frame_t * pAbc, char * pFileName, int fVerbose, int fVeryVerbose, SC_DontUse dont_use ) +{ + SC_Lib * pLib; + FILE * pFile; + if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + fprintf( pAbc->Err, "Cannot open input file \"%s\". \n", pFileName ); + return NULL; + } + fclose( pFile ); + // read new library + pLib = Abc_SclReadLiberty( pFileName, fVerbose, fVeryVerbose, dont_use); + if ( pLib == NULL ) + { + fprintf( pAbc->Err, "Reading SCL library from file \"%s\" has failed. \n", pFileName ); + return NULL; + } + return pLib; +} /**Function************************************************************* @@ -145,8 +174,6 @@ void Scl_End( Abc_Frame_t * pAbc ) ***********************************************************************/ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv ) { - char * pFileName; - FILE * pFile; SC_Lib * pLib; int c, fDump = 0; float Slew = 0; @@ -230,25 +257,29 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - goto usage; - // get the input file name - pFileName = argv[globalUtilOptind]; - if ( (pFile = fopen( pFileName, "rb" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". \n", pFileName ); + if ( argc == globalUtilOptind + 2 ) { // expecting two files + SC_Lib * pLib1 = Scl_ReadLibraryFile( pAbc, argv[globalUtilOptind], fVerbose, fVeryVerbose, dont_use ); + SC_Lib * pLib2 = Scl_ReadLibraryFile( pAbc, argv[globalUtilOptind+1], fVerbose, fVeryVerbose, dont_use ); ABC_FREE(dont_use.dont_use_list); - return 1; + if ( pLib1 == NULL || pLib2 == NULL ) { + if (pLib1) Abc_SclLibFree(pLib1); + if (pLib2) Abc_SclLibFree(pLib2); + return 1; + } + pLib = Abc_SclMergeLibraries( pLib1, pLib2 ); + Abc_SclLibFree(pLib1); + Abc_SclLibFree(pLib2); } - fclose( pFile ); - // read new library - pLib = Abc_SclReadLiberty( pFileName, fVerbose, fVeryVerbose, dont_use); - ABC_FREE(dont_use.dont_use_list); - if ( pLib == NULL ) - { - fprintf( pAbc->Err, "Reading SCL library from file \"%s\" has failed. \n", pFileName ); - return 1; + else if ( argc == globalUtilOptind + 1 ) { // expecting one file + pLib = Scl_ReadLibraryFile( pAbc, argv[globalUtilOptind], fVerbose, fVeryVerbose, dont_use ); + ABC_FREE(dont_use.dont_use_list); } + else { + ABC_FREE(dont_use.dont_use_list); + goto usage; + } + if ( pLib == NULL ) + return 1; if ( Abc_SclLibClassNum(pLib) < 3 ) { fprintf( pAbc->Err, "Library with only %d cell classes cannot be used.\n", Abc_SclLibClassNum(pLib) ); @@ -261,7 +292,7 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_SclShortNames( pLib ); // dump the resulting library if ( fDump && pAbc->pLibScl ) - Abc_SclWriteLiberty( Extra_FileNameGenericAppend(pFileName, "_temp.lib"), (SC_Lib *)pAbc->pLibScl ); + Abc_SclWriteLiberty( Extra_FileNameGenericAppend(argv[globalUtilOptind], "_temp.lib"), (SC_Lib *)pAbc->pLibScl ); if ( fUnit ) { SC_Cell * pCell; int i; @@ -277,7 +308,7 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnuvwh] [-X cell_name] \n" ); + fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnuvwh] [-X cell_name] \n" ); fprintf( pAbc->Err, "\t reads Liberty library from file\n" ); fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew ); fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain ); @@ -290,6 +321,7 @@ usage: fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\t : the name of a file to read\n" ); + fprintf( pAbc->Err, "\t : the name of a file to read (optional)\n" ); return 1; } diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h index 46fb8da6f..08a9066a5 100644 --- a/src/map/scl/sclLib.h +++ b/src/map/scl/sclLib.h @@ -748,6 +748,7 @@ extern SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut ); extern SC_Lib * Abc_SclReadFromFile( char * pFileName ); extern void Abc_SclWriteScl( char * pFileName, SC_Lib * p ); extern void Abc_SclWriteLiberty( char * pFileName, SC_Lib * p ); +extern SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2 ); /*=== sclLibUtil.c ===============================================================*/ extern void Abc_SclHashCells( SC_Lib * p ); extern int Abc_SclCellFind( SC_Lib * p, char * pName ); diff --git a/src/map/scl/sclLibScl.c b/src/map/scl/sclLibScl.c index a06d01343..e13a746e6 100644 --- a/src/map/scl/sclLibScl.c +++ b/src/map/scl/sclLibScl.c @@ -483,71 +483,22 @@ static void Abc_SclWriteSurface( Vec_Str_t * vOut, SC_Surface * p ) for ( i = 0; i < 6; i++ ) Vec_StrPutF( vOut, p->approx[2][i] ); } -static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) +static void Abc_SclWriteLibraryCellsOnly( Vec_Str_t * vOut, SC_Lib * p, int fAddOn ) { - SC_WireLoad * pWL; - SC_WireLoadSel * pWLS; SC_Cell * pCell; SC_Pin * pPin; - int n_valid_cells; - int i, j, k; - - Vec_StrPutI( vOut, ABC_SCL_CUR_VERSION ); - - // Write non-composite fields: - Vec_StrPutS( vOut, p->pName ); - 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 ); - Vec_StrPutI( vOut, p->unit_time ); - Vec_StrPutF( vOut, p->unit_cap_fst ); - Vec_StrPutI( vOut, p->unit_cap_snd ); - - // Write 'wire_load' vector: - Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoads) ); - SC_LibForEachWireLoad( p, pWL, i ) - { - Vec_StrPutS( vOut, pWL->pName ); - 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++ ) - { - Vec_StrPutI( vOut, Vec_IntEntry(&pWL->vFanout, j) ); - Vec_StrPutF( vOut, Vec_FltEntry(&pWL->vLen, j) ); - } - } - - // Write 'wire_load_sel' vector: - Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoadSels) ); - SC_LibForEachWireLoadSel( p, pWLS, i ) - { - Vec_StrPutS( vOut, pWLS->pName ); - Vec_StrPutI( vOut, Vec_FltSize(&pWLS->vAreaFrom) ); - for ( j = 0; j < Vec_FltSize(&pWLS->vAreaFrom); 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) ); - } - } - - // Write 'cells' vector: - n_valid_cells = 0; - SC_LibForEachCell( p, pCell, i ) - if ( !(pCell->seq || pCell->unsupp) ) - n_valid_cells++; - - Vec_StrPutI( vOut, n_valid_cells ); + int i, j, k; SC_LibForEachCell( p, pCell, i ) { if ( pCell->seq || pCell->unsupp ) continue; + if ( fAddOn ) { + Vec_StrPush( vOut, 'L' ); + Vec_StrPush( vOut, '0'+(char)fAddOn ); + Vec_StrPush( vOut, '_' ); + } + Vec_StrPutS( vOut, pCell->pName ); Vec_StrPutF( vOut, pCell->area ); Vec_StrPutF( vOut, pCell->leakage ); @@ -608,13 +559,78 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) assert( Vec_PtrSize(&pRTime->vTimings) == 0 ); } } + } +} +int Abc_SclCountValidCells( SC_Lib * p ) +{ + SC_Cell * pCell; + int i, n_valid_cells = 0; + SC_LibForEachCell( p, pCell, i ) + if ( !(pCell->seq || pCell->unsupp) ) + n_valid_cells++; + return n_valid_cells; +} +static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra ) +{ + SC_WireLoad * pWL; + SC_WireLoadSel * pWLS; + int n_valid_cells; + int i, j; + + Vec_StrPutI( vOut, ABC_SCL_CUR_VERSION ); + + // Write non-composite fields: + Vec_StrPutS( vOut, p->pName ); + 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 ); + Vec_StrPutI( vOut, p->unit_time ); + Vec_StrPutF( vOut, p->unit_cap_fst ); + Vec_StrPutI( vOut, p->unit_cap_snd ); + + // Write 'wire_load' vector: + Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoads) ); + SC_LibForEachWireLoad( p, pWL, i ) + { + Vec_StrPutS( vOut, pWL->pName ); + 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++ ) + { + Vec_StrPutI( vOut, Vec_IntEntry(&pWL->vFanout, j) ); + Vec_StrPutF( vOut, Vec_FltEntry(&pWL->vLen, j) ); + } } + + // Write 'wire_load_sel' vector: + Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoadSels) ); + SC_LibForEachWireLoadSel( p, pWLS, i ) + { + Vec_StrPutS( vOut, pWLS->pName ); + Vec_StrPutI( vOut, Vec_FltSize(&pWLS->vAreaFrom) ); + for ( j = 0; j < Vec_FltSize(&pWLS->vAreaFrom); 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) ); + } + } + + // Write 'cells' vector: + n_valid_cells = Abc_SclCountValidCells( p ); + Vec_StrPutI( vOut, n_valid_cells + nExtra ); + Abc_SclWriteLibraryCellsOnly( vOut, p, (int)(nExtra > 0) ); } void Abc_SclWriteScl( char * pFileName, SC_Lib * p ) { Vec_Str_t * vOut; vOut = Vec_StrAlloc( 10000 ); - Abc_SclWriteLibrary( vOut, p ); + Abc_SclWriteLibrary( vOut, p, 0 ); if ( Vec_StrSize(vOut) > 0 ) { FILE * pFile = fopen( pFileName, "wb" ); @@ -835,10 +851,36 @@ void Abc_SclWriteLiberty( char * pFileName, SC_Lib * p ) { Abc_SclWriteLibraryText( pFile, p ); fclose( pFile ); - printf( "Dumped internal library into Liberty file \"%s\".\n", pFileName ); + printf( "Dumped internal library with %d cells into Liberty file \"%s\".\n", SC_LibCellNum(p), pFileName ); } } +/**Function************************************************************* + + Synopsis [Appends cells of pLib2 to those of pLib1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2 ) +{ + Vec_Str_t * vOut = Vec_StrAlloc( 10000 ); + int n_valid_cells2 = Abc_SclCountValidCells( pLib2 ); + Abc_SclWriteLibrary( vOut, pLib1, n_valid_cells2 ); + Abc_SclWriteLibraryCellsOnly( vOut, pLib2, 2 ); + SC_Lib * p = Abc_SclReadFromStr( vOut ); + p->pFileName = Abc_UtilStrsav( pLib1->pFileName ); + p->pName = ABC_ALLOC( char, strlen(pLib1->pName) + strlen(pLib2->pName) + 10 ); + sprintf( p->pName, "%s__and__%s", pLib1->pName, pLib2->pName ); + Vec_StrFree( vOut ); + printf( "Updated library \"%s\" with additional %d cells from library \"%s\".\n", pLib1->pName, n_valid_cells2, pLib2->pName ); + return p; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// ////////////////////////////////////////////////////////////////////////