diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-08-29 16:20:39 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-08-29 16:20:39 -0700 |
commit | 83bfe0b1fec515d9350ebd63f07f0ed742bb4745 (patch) | |
tree | 8fcfd00de92c20fc7e07011c70c8d6ffa8d9d537 | |
parent | 6814c48bb4e748add7e4ebd37f0d4d00312e0c5a (diff) | |
download | abc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.tar.gz abc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.tar.bz2 abc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.zip |
New package to read/write a subset of Liberty for STA.
-rw-r--r-- | abclib.dsp | 8 | ||||
-rw-r--r-- | src/base/abc/abc.h | 3 | ||||
-rw-r--r-- | src/map/scl/scl.c | 65 | ||||
-rw-r--r-- | src/map/scl/scl.h | 12 | ||||
-rw-r--r-- | src/map/scl/sclBuff.c | 26 | ||||
-rw-r--r-- | src/map/scl/sclFile.c | 50 | ||||
-rw-r--r-- | src/map/scl/sclInt.h | 112 | ||||
-rw-r--r-- | src/map/scl/sclLoad.c | 180 | ||||
-rw-r--r-- | src/map/scl/sclMan.h | 130 | ||||
-rw-r--r-- | src/map/scl/sclSize.c | 94 | ||||
-rw-r--r-- | src/map/scl/sclTime.c | 290 | ||||
-rw-r--r-- | src/map/scl/sclUtil.c | 31 |
12 files changed, 588 insertions, 413 deletions
@@ -2367,6 +2367,14 @@ SOURCE=.\src\map\scl\sclInt.h # End Source File # Begin Source File +SOURCE=.\src\map\scl\sclLoad.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\scl\sclMan.h +# End Source File +# Begin Source File + SOURCE=.\src\map\scl\sclSize.c # End Source File # Begin Source File diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 0d34ef2f..d123514a 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -463,6 +463,9 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At #define Abc_NtkForEachNode( pNtk, pNode, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else +#define Abc_NtkForEachNodeReverse( pNtk, pNode, i ) \ + for ( i = Vec_PtrSize((pNtk)->vObjs) - 1; (i >= 0) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i-- ) \ + if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else #define Abc_NtkForEachGate( pNtk, pNode, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pNode) == NULL || !Abc_ObjIsGate(pNode) ) {} else diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index 91aaac5e..56fdd7ea 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Relevant command handlers.] Author [Alan Mishchenko, Niklas Een] @@ -17,7 +19,6 @@ ***********************************************************************/ #include "sclInt.h" -#include "scl.h" #include "base/main/mainInt.h" ABC_NAMESPACE_IMPL_START @@ -27,15 +28,12 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -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_CommandPrint ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandGsize ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char **argv ); - -extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); -extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ); +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_CommandPrint ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandGsize ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char **argv ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -54,12 +52,12 @@ extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerb ***********************************************************************/ 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", "print_scl", Scl_CommandPrint, 0 ); - Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 ); - Cmd_CommandAdd( pAbc, "SC mapping", "gsize", Scl_CommandGsize, 1 ); - Cmd_CommandAdd( pAbc, "SC mapping", "buffer", Scl_CommandBuffer, 1 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "read_scl", Scl_CommandRead, 0 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "write_scl", Scl_CommandWrite, 0 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "print_scl", Scl_CommandPrint, 0 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "gsize", Scl_CommandGsize, 1 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 ); } void Scl_End( Abc_Frame_t * pAbc ) { @@ -234,12 +232,16 @@ usage: int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) { int c; + int fShowAll = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) { switch ( c ) { + case 'a': + fShowAll ^= 1; + break; case 'h': goto usage; default: @@ -268,12 +270,13 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) return 1; } - Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc) ); + Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), fShowAll ); return 0; usage: - fprintf( pAbc->Err, "usage: stime [-h]\n" ); + fprintf( pAbc->Err, "usage: stime [-ah]\n" ); fprintf( pAbc->Err, "\t performs STA using Liberty library\n" ); + fprintf( pAbc->Err, "\t-a : display timing information for all nodes [default = %s]\n", fShowAll? "yes": "no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); return 1; } @@ -291,11 +294,11 @@ usage: ***********************************************************************/ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) { - int c; - int nSteps = 100; + int c, fVerbose = 0; + int nSteps = 100000; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF ) { switch ( c ) { @@ -310,6 +313,9 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) if ( nSteps <= 0 ) goto usage; break; + case 'v': + fVerbose ^= 1; + break; case 'h': goto usage; default: @@ -338,13 +344,14 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) return 1; } -// Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps ); + Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps, fVerbose ); return 0; usage: - fprintf( pAbc->Err, "usage: gsize [-N num] [-h]\n" ); + fprintf( pAbc->Err, "usage: gsize [-N num] [-vh]\n" ); fprintf( pAbc->Err, "\t performs gate sizing using Liberty library\n" ); - fprintf( pAbc->Err, "\t-N <num> : the number of refinement iterations [default = %d]\n", nSteps ); + fprintf( pAbc->Err, "\t-N <num> : the number of gate-sizing steps performed [default = %d]\n", nSteps ); + fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); return 1; } @@ -366,7 +373,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtkRes; int Degree; int c, fVerbose; - Degree = 3; + Degree = 4; fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF ) @@ -419,8 +426,8 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: fprintf( pAbc->Err, "usage: buffer [-N num] [-vh]\n" ); fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" ); - fprintf( pAbc->Err, "\t-N <num> : the number of refinement iterations [default = %d]\n", Degree ); - fprintf( pAbc->Err, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pAbc->Err, "\t-N <num> : the max allowed fanout count of node/buffer [default = %d]\n", Degree ); + fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : print the command usage\n"); return 1; } diff --git a/src/map/scl/scl.h b/src/map/scl/scl.h index c87fd42b..3109c0b1 100644 --- a/src/map/scl/scl.h +++ b/src/map/scl/scl.h @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [External declarations.] Author [Alan Mishchenko, Niklas Een] @@ -46,14 +48,6 @@ ABC_NAMESPACE_HEADER_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/*=== sclFile.c =============================================================*/ -extern void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl ); -extern void Abc_SclSave( char * pFileName, SC_Lib * pScl ); -/*=== sclTime.c =============================================================*/ -extern void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk ); -/*=== sclSize.c =============================================================*/ -extern void Abc_SclSizingPerform( SC_Lib * pLib, void * pNtk, int nSteps ); - ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclBuff.c b/src/map/scl/sclBuff.c index 915daf7f..641bddb2 100644 --- a/src/map/scl/sclBuff.c +++ b/src/map/scl/sclBuff.c @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Buffering algorithms.] Author [Alan Mishchenko, Niklas Een] @@ -16,9 +18,8 @@ ***********************************************************************/ -#include "base/abc/abc.h" -#include "map/mio/mio.h" #include "sclInt.h" +#include "map/mio/mio.h" ABC_NAMESPACE_IMPL_START @@ -33,7 +34,7 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Make sure the network has no dangling nodes.] + Synopsis [Make sure the network is in topo order without dangling nodes.] Description [Returns 1 iff the network is fine.] @@ -65,7 +66,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) /**Function************************************************************* - Synopsis [Make sure the network has no dangling nodes.] + Synopsis [] Description [] @@ -109,7 +110,7 @@ int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) return -1; if ( Diff > 0 ) return 1; - Diff = (*pp1)->Id - (*pp2)->Id; + Diff = (*pp1)->Id - (*pp2)->Id; // needed to make qsort() platform-infependent if ( Diff < 0 ) return -1; if ( Diff > 0 ) @@ -195,14 +196,25 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose ) } Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ) { + Vec_Int_t * vCiLevs; Abc_Ntk_t * pNew; Abc_Obj_t * pObj; int i; assert( Abc_NtkHasMapping(p) ); + // remember CI levels + vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); + Abc_NtkForEachCi( p, pObj, i ) + Vec_IntPush( vCiLevs, Abc_ObjLevel(pObj) ); + // perform buffering Abc_NtkIncrementTravId( p ); Abc_NtkForEachCi( p, pObj, i ) Abc_SclPerformBuffering_rec( pObj, Degree, fVerbose ); - Abc_NtkLevel( p ); + // recompute logic levels + Abc_NtkForEachCi( p, pObj, i ) + pObj->Level = Vec_IntEntry( vCiLevs, i ); + Abc_NtkForEachNode( p, pObj, i ) + Abc_ObjLevelNew( pObj ); + Vec_IntFree( vCiLevs ); // duplication in topo order pNew = Abc_NtkDupDfs( p ); Abc_SclCheckNtk( pNew, fVerbose ); diff --git a/src/map/scl/sclFile.c b/src/map/scl/sclFile.c index 71e06e28..97990233 100644 --- a/src/map/scl/sclFile.c +++ b/src/map/scl/sclFile.c @@ -1,10 +1,12 @@ /**CFile**************************************************************** - FileName [sclIo.c] + FileName [sclFile.c] SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Input/output procedures for simplified library representation.] Author [Alan Mishchenko, Niklas Een] @@ -12,7 +14,7 @@ Date [Ver. 1.0. Started - August 24, 2012.] - Revision [$Id: sclIo.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] + Revision [$Id: sclFile.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -190,7 +192,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) assert( version == ABC_SCL_CUR_VERSION ); // wrong version of the file // Read non-composite fields: - p->lib_name = Vec_StrGetS(vOut, pPos); + p->pName = 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); @@ -205,7 +207,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) SC_WireLoad * pWL = Abc_SclWireLoadAlloc(); Vec_PtrPush( p->vWireLoads, pWL ); - pWL->name = Vec_StrGetS(vOut, pPos); + pWL->pName = Vec_StrGetS(vOut, pPos); pWL->res = Vec_StrGetF(vOut, pPos); pWL->cap = Vec_StrGetF(vOut, pPos); @@ -222,7 +224,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) SC_WireLoadSel * pWLS = Abc_SclWireLoadSelAlloc(); Vec_PtrPush( p->vWireLoadSels, pWLS ); - pWLS->name = Vec_StrGetS(vOut, pPos); + pWLS->pName = Vec_StrGetS(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { Vec_FltPush( pWLS->vAreaFrom, Vec_StrGetF(vOut, pPos) ); @@ -236,7 +238,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) SC_Cell * pCell = Abc_SclCellAlloc(); Vec_PtrPush( p->vCells, pCell ); - pCell->name = Vec_StrGetS(vOut, pPos); + pCell->pName = Vec_StrGetS(vOut, pPos); pCell->area = Vec_StrGetF(vOut, pPos); pCell->drive_strength = Vec_StrGetI(vOut, pPos); @@ -249,7 +251,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Input; - pPin->name = Vec_StrGetS(vOut, pPos); + pPin->pName = Vec_StrGetS(vOut, pPos); pPin->rise_cap = Vec_StrGetF(vOut, pPos); pPin->fall_cap = Vec_StrGetF(vOut, pPos); } @@ -260,7 +262,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Output; - pPin->name = Vec_StrGetS(vOut, pPos); + pPin->pName = Vec_StrGetS(vOut, pPos); pPin->max_out_cap = Vec_StrGetF(vOut, pPos); pPin->max_out_slew = Vec_StrGetF(vOut, pPos); @@ -279,7 +281,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) SC_Timings * pRTime = Abc_SclTimingsAlloc(); Vec_PtrPush( pPin->vRTimings, pRTime ); - pRTime->name = Vec_StrGetS(vOut, pPos); + pRTime->pName = Vec_StrGetS(vOut, pPos); n = Vec_StrGetI(vOut, pPos); assert( n <= 1 ); if ( n == 1 ) { @@ -393,7 +395,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_StrPutI( vOut, ABC_SCL_CUR_VERSION ); // Write non-composite fields: - Vec_StrPutS( vOut, p->lib_name ); + 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 ); @@ -408,7 +410,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoads) ); Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) { - Vec_StrPutS( vOut, pWL->name ); + Vec_StrPutS( vOut, pWL->pName ); Vec_StrPutF( vOut, pWL->res ); Vec_StrPutF( vOut, pWL->cap ); @@ -424,7 +426,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoadSels) ); Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) { - Vec_StrPutS( vOut, pWLS->name ); + Vec_StrPutS( vOut, pWLS->pName ); Vec_StrPutI( vOut, Vec_FltSize(pWLS->vAreaFrom) ); for ( j = 0; j < Vec_FltSize(pWLS->vAreaFrom); j++) { @@ -446,7 +448,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) if ( pCell->seq || pCell->unsupp ) continue; - Vec_StrPutS( vOut, pCell->name ); + Vec_StrPutS( vOut, pCell->pName ); Vec_StrPutF( vOut, pCell->area ); Vec_StrPutI( vOut, pCell->drive_strength ); @@ -457,7 +459,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) { assert(pPin->dir == sc_dir_Input); - Vec_StrPutS( vOut, pPin->name ); + Vec_StrPutS( vOut, pPin->pName ); Vec_StrPutF( vOut, pPin->rise_cap ); Vec_StrPutF( vOut, pPin->fall_cap ); } @@ -468,7 +470,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) word uWord; assert(pPin->dir == sc_dir_Output); - Vec_StrPutS( vOut, pPin->name ); + Vec_StrPutS( vOut, pPin->pName ); Vec_StrPutF( vOut, pPin->max_out_cap ); Vec_StrPutF( vOut, pPin->max_out_slew ); @@ -482,7 +484,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) { - Vec_StrPutS( vOut, pRTime->name ); + Vec_StrPutS( vOut, pRTime->pName ); 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). @@ -596,7 +598,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) int i, j, k; // fprintf( s, "%d", ABC_SCL_CUR_VERSION ); - fprintf( s, "library(%s) {\n\n", p->lib_name ); + fprintf( s, "library(%s) {\n\n", p->pName ); if ( p->default_wire_load && strlen(p->default_wire_load) ) fprintf( s, " default_wire_load : \"%s\";\n", p->default_wire_load ); if ( p->default_wire_load_sel && strlen(p->default_wire_load_sel) ) @@ -618,7 +620,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) // Write 'wire_load' vector: Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) { - fprintf( s, " wire_load(\"%s\") {\n", pWL->name ); + fprintf( s, " wire_load(\"%s\") {\n", pWL->pName ); fprintf( s, " capacitance : %f;\n", pWL->cap ); fprintf( s, " resistance : %f;\n", pWL->res ); for ( j = 0; j < Vec_IntSize(pWL->vFanout); j++ ) @@ -629,7 +631,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) // Write 'wire_load_sel' vector: Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) { - fprintf( s, " wire_load_selection(\"%s\") {\n", pWLS->name ); + fprintf( s, " wire_load_selection(\"%s\") {\n", pWLS->pName ); for ( j = 0; j < Vec_FltSize(pWLS->vAreaFrom); j++) fprintf( s, " wire_load_from_area( %f, %f, \"%s\" );\n", Vec_FltEntry(pWLS->vAreaFrom, j), @@ -650,7 +652,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) continue; fprintf( s, "\n" ); - fprintf( s, " cell(%s) {\n", pCell->name ); + fprintf( s, " cell(%s) {\n", pCell->pName ); fprintf( s, " /* n_inputs = %d n_outputs = %d */\n", pCell->n_inputs, pCell->n_outputs ); fprintf( s, " area : %f;\n", pCell->area ); fprintf( s, " drive_strength : %d;\n", pCell->drive_strength ); @@ -658,7 +660,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) { assert(pPin->dir == sc_dir_Input); - fprintf( s, " pin(%s) {\n", pPin->name ); + fprintf( s, " pin(%s) {\n", pPin->pName ); fprintf( s, " direction : %s;\n", "input" ); fprintf( s, " fall_capacitance : %f;\n", pPin->fall_cap ); fprintf( s, " rise_capacitance : %f;\n", pPin->rise_cap ); @@ -670,7 +672,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) SC_Timings * pRTime; // word uWord; assert(pPin->dir == sc_dir_Output); - fprintf( s, " pin(%s) {\n", pPin->name ); + fprintf( s, " pin(%s) {\n", pPin->pName ); fprintf( s, " direction : %s;\n", "output" ); fprintf( s, " max_capacitance : %f;\n", pPin->max_out_cap ); fprintf( s, " max_transition : %f;\n", pPin->max_out_slew ); @@ -687,7 +689,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) { SC_Timing * pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); fprintf( s, " timing() {\n" ); - fprintf( s, " related_pin : \"%s\"\n", pRTime->name ); + fprintf( s, " related_pin : \"%s\"\n", pRTime->pName ); if ( pTime->tsense == sc_ts_Pos ) fprintf( s, " timing_sense : positive_unate;\n" ); else if ( pTime->tsense == sc_ts_Neg ) diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index 034308b5..6796c601 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Simplified library representation for STA.] Author [Alan Mishchenko, Niklas Een] @@ -30,7 +32,7 @@ #include <assert.h> #include <math.h> -#include "misc/vec/vec.h" +#include "base/abc/abc.h" ABC_NAMESPACE_HEADER_START @@ -74,7 +76,7 @@ typedef struct SC_Lib_ SC_Lib; struct SC_WireLoad_ { - char * name; + char * pName; float res; // (currently not used) float cap; // }- multiply estimation in 'fanout_len[].snd' with this value Vec_Int_t * vFanout; // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)' @@ -83,7 +85,7 @@ struct SC_WireLoad_ struct SC_WireLoadSel_ { - char * name; + char * pName; Vec_Flt_t * vAreaFrom; // Vec<Trip<float,float,Str> > -- triplets '(from-area, upto-area, wire-load-model)'; range is [from, upto[ Vec_Flt_t * vAreaTo; Vec_Ptr_t * vWireLoadModel; @@ -91,14 +93,14 @@ struct SC_WireLoadSel_ struct SC_TableTempl_ { - char * name; + char * pName; Vec_Ptr_t * vVars; // Vec<Str> -- name of variable (numbered from 0, not 1 as in the Liberty file) Vec_Ptr_t * vIndex; // Vec<Vec<float> > -- this is the point of measurement in table for the given variable }; struct SC_Surface_ { - char * templ_name; + char * pName; Vec_Flt_t * vIndex0; // Vec<float> -- correspondes to "index_1" in the liberty file (for timing: slew) Vec_Flt_t * vIndex1; // Vec<float> -- correspondes to "index_2" in the liberty file (for timing: load) Vec_Ptr_t * vData; // Vec<Vec<float> > -- 'data[i0][i1]' gives value at '(index0[i0], index1[i1])' @@ -118,13 +120,13 @@ struct SC_Timing_ struct SC_Timings_ { - char * name; // -- the 'related_pin' field + char * pName; // -- the 'related_pin' field Vec_Ptr_t * vTimings; // structures of type SC_Timing }; struct SC_Pin_ { - char * name; + char * pName; SC_Dir dir; float cap; // -- this value is used if 'rise_cap' and 'fall_cap' is missing (copied by 'postProcess()'). (not used) float rise_cap; // }- used for input pins ('cap' too). @@ -138,7 +140,7 @@ struct SC_Pin_ struct SC_Cell_ { - char * name; + char * pName; int seq; // -- set to TRUE by parser if a sequential element int unsupp; // -- set to TRUE by parser if cell contains information we cannot handle float area; @@ -152,7 +154,7 @@ struct SC_Cell_ struct SC_Lib_ { - char * lib_name; + char * pName; char * default_wire_load; char * default_wire_load_sel; float default_max_out_slew; // -- 'default_max_transition'; this is copied to each output pin where 'max_transition' is not defined (not used) @@ -194,6 +196,17 @@ static inline double SC_LibTimePs( SC_Lib * p, double time ) { return time /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Constructors of the library data-structures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ static inline SC_WireLoad * Abc_SclWireLoadAlloc() { SC_WireLoad * p; @@ -278,11 +291,22 @@ static inline SC_Lib * Abc_SclLibAlloc() } +/**Function************************************************************* + + Synopsis [Destructors of the library data-structures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ static inline void Abc_SclWireLoadFree( SC_WireLoad * p ) { Vec_IntFree( p->vFanout ); Vec_FltFree( p->vLen ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p ) @@ -290,14 +314,14 @@ static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p ) Vec_FltFree( p->vAreaFrom ); Vec_FltFree( p->vAreaTo ); Vec_PtrFreeFree( p->vWireLoadModel ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclTableTemplFree( SC_TableTempl * p ) { Vec_PtrFreeFree( p->vVars ); Vec_VecFree( (Vec_Vec_t *)p->vIndex ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclSurfaceFree( SC_Surface * p ) @@ -305,7 +329,7 @@ static inline void Abc_SclSurfaceFree( SC_Surface * p ) Vec_FltFree( p->vIndex0 ); Vec_FltFree( p->vIndex1 ); Vec_VecFree( (Vec_Vec_t *)p->vData ); - ABC_FREE( p->templ_name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclTimingFree( SC_Timing * p ) @@ -325,7 +349,7 @@ static inline void Abc_SclTimingsFree( SC_Timings * p ) Vec_PtrForEachEntry( SC_Timing *, p->vTimings, pTemp, i ) Abc_SclTimingFree( pTemp ); Vec_PtrFree( p->vTimings ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclPinFree( SC_Pin * p ) @@ -337,7 +361,7 @@ static inline void Abc_SclPinFree( SC_Pin * p ) Vec_PtrFree( p->vRTimings ); Vec_WrdFree( p->vFunc ); ABC_FREE( p->func_text ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclCellFree( SC_Cell * p ) @@ -347,30 +371,30 @@ static inline void Abc_SclCellFree( SC_Cell * p ) Vec_PtrForEachEntry( SC_Pin *, p->vPins, pTemp, i ) Abc_SclPinFree( pTemp ); Vec_PtrFree( p->vPins ); - ABC_FREE( p->name ); + ABC_FREE( p->pName ); ABC_FREE( p ); } static inline void Abc_SclLibFree( SC_Lib * p ) { - SC_WireLoad * pTemp1; - SC_WireLoadSel * pTemp2; - SC_TableTempl * pTemp3; - SC_Cell * pTemp4; + SC_WireLoad * pWL; + SC_WireLoadSel * pWLS; + SC_TableTempl * pTempl; + SC_Cell * pCell; int i; - Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pTemp1, i ) - Abc_SclWireLoadFree( pTemp1 ); + Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) + Abc_SclWireLoadFree( pWL ); Vec_PtrFree( p->vWireLoads ); - Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pTemp2, i ) - Abc_SclWireLoadSelFree( pTemp2 ); + Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) + Abc_SclWireLoadSelFree( pWLS ); Vec_PtrFree( p->vWireLoadSels ); - Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTemp3, i ) - Abc_SclTableTemplFree( pTemp3 ); + Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTempl, i ) + Abc_SclTableTemplFree( pTempl ); Vec_PtrFree( p->vTempls ); - SC_LitForEachCell( p, pTemp4, i ) - Abc_SclCellFree( pTemp4 ); + SC_LitForEachCell( p, pCell, i ) + Abc_SclCellFree( pCell ); Vec_PtrFree( p->vCells ); Vec_PtrFree( p->vCellOrder ); - ABC_FREE( p->lib_name ); + ABC_FREE( p->pName ); ABC_FREE( p->default_wire_load ); ABC_FREE( p->default_wire_load_sel ); ABC_FREE( p->pBins ); @@ -378,16 +402,28 @@ static inline void Abc_SclLibFree( SC_Lib * p ) } +/*=== sclBuff.c =============================================================*/ +extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); +extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ); /*=== 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 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 void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl ); +extern void Abc_SclSave( char * pFileName, SC_Lib * pScl ); +/*=== sclTime.c =============================================================*/ +extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fShowAll ); +/*=== sclSize.c =============================================================*/ +extern void Abc_SclSizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nSteps, int fVerbose ); /*=== sclUtil.c =============================================================*/ -extern void Abc_SclHashCells( SC_Lib * p ); -extern int Abc_SclCellFind( SC_Lib * p, char * pName ); -extern void Abc_SclLinkCells( SC_Lib * p ); -extern void Abc_SclPrintCells( SC_Lib * p ); +extern void Abc_SclHashCells( SC_Lib * p ); +extern int Abc_SclCellFind( SC_Lib * p, char * pName ); +extern void Abc_SclLinkCells( SC_Lib * p ); +extern void Abc_SclPrintCells( SC_Lib * p ); +extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ); +extern void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ); + + ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c new file mode 100644 index 00000000..686000a9 --- /dev/null +++ b/src/map/scl/sclLoad.c @@ -0,0 +1,180 @@ +/**CFile**************************************************************** + + FileName [sclLoad.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Standard-cell library representation.] + + Synopsis [Wire/gate load computations.] + + Author [Alan Mishchenko, Niklas Een] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 24, 2012.] + + Revision [$Id: sclLoad.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sclInt.h" +#include "sclMan.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns estimated wire capacitances for each fanout count.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) +{ + Vec_Flt_t * vCaps = NULL; + SC_WireLoad * pWL = NULL; + int i, Entry, EntryMax; + float EntryPrev, EntryCur; + p->pWLoadUsed = NULL; + if ( p->pLib->default_wire_load_sel && strlen(p->pLib->default_wire_load_sel) ) + { + float Area; + SC_WireLoadSel * pWLS = NULL; + Vec_PtrForEachEntry( SC_WireLoadSel *, p->pLib->vWireLoadSels, pWLS, i ) + if ( !strcmp(pWLS->pName, 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_SclGetTotalArea( p ); + for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++) + if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) ) + { + p->pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); + break; + } + if ( i == Vec_FltSize(pWLS->vAreaFrom) ) + p->pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); + } + else if ( p->pLib->default_wire_load && strlen(p->pLib->default_wire_load) ) + p->pWLoadUsed = 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->pWLoadUsed != NULL ); + Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) + if ( !strcmp(pWL->pName, p->pWLoadUsed) ) + break; + if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) + { + Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWLoadUsed ); + 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, EntryCur, i ) + { + if ( EntryCur ) + EntryPrev = EntryCur; + else + Vec_FltWriteEntry( vCaps, i, EntryPrev ); + } + return vCaps; +} + +/**Function************************************************************* + + Synopsis [Computes/updates load for all nodes in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclComputeLoad( SC_Man * p ) +{ + Vec_Flt_t * vWireCaps; + Abc_Obj_t * pObj, * pFanin; + int i, k; + // clear load storage + Abc_NtkForEachObj( p->pNtk, pObj, i ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + pLoad->rise = pLoad->fall = 0.0; + } + // add cell load + Abc_NtkForEachNode( p->pNtk, pObj, i ) + { + SC_Cell * pCell = Abc_SclObjCell( p, pObj ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPin = SC_CellPin( pCell, k ); + pLoad->rise += pPin->rise_cap; + pLoad->fall += pPin->fall_cap; + } + } + // add wire load + vWireCaps = Abc_SclFindWireCaps( p ); + if ( vWireCaps ) + { + Abc_NtkForEachNode( p->pNtk, 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); + } + } + Vec_FltFree( vWireCaps ); +} +void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ) +{ + Abc_Obj_t * pFanin; + int k; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPinOld = SC_CellPin( pOld, k ); + SC_Pin * pPinNew = SC_CellPin( pNew, k ); + pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap; + pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap; + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/map/scl/sclMan.h b/src/map/scl/sclMan.h index 6dd24ac1..7d49c773 100644 --- a/src/map/scl/sclMan.h +++ b/src/map/scl/sclMan.h @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Timing/gate-sizing manager.] Author [Alan Mishchenko, Niklas Een] @@ -47,9 +49,8 @@ struct SC_Man_ { SC_Lib * pLib; // library Abc_Ntk_t * pNtk; // network - float SumArea; // total area - int nObjs; // allocated size Vec_Int_t * vGates; // mapping of objId into gateId + int nObjs; // allocated size SC_Pair * pLoads; // loads for each gate SC_Pair * pTimes; // arrivals for each gate SC_Pair * pSlews; // slews for each gate @@ -57,6 +58,10 @@ struct SC_Man_ SC_Pair * pSlews2; // slews for each gate char * pWLoadUsed; // name of the used WireLoad model clock_t clkStart; // starting time + float SumArea; // total area + float MaxDelay; // max delay + float SumArea0; // total area at the begining + float MaxDelay0; // max delay at the begining }; //////////////////////////////////////////////////////////////////////// @@ -67,35 +72,67 @@ struct SC_Man_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); } -static inline SC_Pair * Abc_SclObjTime( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes + 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)) ); } -static inline SC_Pair * Abc_SclObjTime2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes2 + Abc_ObjId(pObj); } -static inline SC_Pair * Abc_SclObjSlew2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews2 + Abc_ObjId(pObj); } +static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); } +static inline SC_Pair * Abc_SclObjTime( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes + 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_Pair * Abc_SclObjTime2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes2 + Abc_ObjId(pObj); } +static inline SC_Pair * Abc_SclObjSlew2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews2 + Abc_ObjId(pObj); } -static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return (Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(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 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 (Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall); } 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); } static inline double Abc_SclObjSlewPs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjSlew(p, pObj)->rise : Abc_SclObjSlew(p, pObj)->fall); } -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 [Constructor/destructor of STA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline 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->pTimes = ABC_CALLOC( SC_Pair, p->nObjs ); + p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs ); + p->pTimes2 = ABC_CALLOC( SC_Pair, p->nObjs ); + p->pSlews2 = ABC_CALLOC( SC_Pair, p->nObjs ); + p->clkStart = clock(); + return p; +} +static inline void Abc_SclManFree( SC_Man * p ) +{ + Vec_IntFreeP( &p->vGates ); + ABC_FREE( p->pLoads ); + ABC_FREE( p->pTimes ); + ABC_FREE( p->pSlews ); + ABC_FREE( p->pTimes2 ); + ABC_FREE( p->pSlews2 ); + ABC_FREE( p ); +} + /**Function************************************************************* - Synopsis [] + Synopsis [Stores/retrivies timing information for the logic cone.] Description [] @@ -106,12 +143,13 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return ***********************************************************************/ static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone ) { + SC_Pair Zero = { 0.0, 0.0 }; Abc_Obj_t * pObj; int i; Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) { - *Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj); - *Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj); + *Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj); *Abc_SclObjTime(p, pObj) = Zero; + *Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj); *Abc_SclObjSlew(p, pObj) = Zero; } } static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone ) @@ -127,7 +165,7 @@ static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone ) /**Function************************************************************* - Synopsis [Prepares STA manager.] + Synopsis [] Description [] @@ -136,41 +174,41 @@ static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone ) SeeAlso [] ***********************************************************************/ -static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) +static inline float Abc_SclGetTotalArea( SC_Man * p ) { - 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->pTimes = ABC_CALLOC( SC_Pair, p->nObjs ); - p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs ); - p->pTimes2 = ABC_CALLOC( SC_Pair, p->nObjs ); - p->pSlews2 = ABC_CALLOC( SC_Pair, p->nObjs ); - p->clkStart = clock(); - return p; + double Area = 0; + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachNode( p->pNtk, pObj, i ) + Area += Abc_SclObjCell( p, pObj )->area; + return Area; } -static inline void Abc_SclManFree( SC_Man * p ) +static inline float Abc_SclGetMaxDelay( SC_Man * p ) { - Vec_IntFreeP( &p->vGates ); - ABC_FREE( p->pLoads ); - ABC_FREE( p->pTimes ); - ABC_FREE( p->pSlews ); - ABC_FREE( p->pTimes2 ); - ABC_FREE( p->pSlews2 ); - ABC_FREE( p ); + float fMaxArr = 0; + Abc_Obj_t * pObj; + SC_Pair * pArr; + int i; + Abc_NtkForEachCo( p->pNtk, pObj, i ) + { + pArr = Abc_SclObjTime( p, pObj ); + if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise; + if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall; + } + return fMaxArr; } /*=== sclTime.c =============================================================*/ +extern Vec_Int_t * Abc_SclFindCriticalPath( SC_Man * p ); +extern Abc_Obj_t * Abc_SclFindCriticalCo( SC_Man * p, int * pfRise ); +extern void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll ); extern SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise ); -extern Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p ); extern void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ); +/*=== sclTime.c =============================================================*/ +extern void Abc_SclComputeLoad( SC_Man * p ); extern void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ); -extern void Abc_SclCriticalPathPrint( SC_Man * p ); + ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 4b7ef595..3ec885a3 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Gate sizing algorithms.] Author [Alan Mishchenko, Niklas Een] @@ -16,8 +18,6 @@ ***********************************************************************/ -#include "base/abc/abc.h" -#include "map/mio/mio.h" #include "sclInt.h" #include "sclMan.h" @@ -96,6 +96,7 @@ float Abc_SclSizingGain( SC_Man * p, Abc_Obj_t * pPivot ) vCone = Abc_SclCollectTfo( p->pNtk, pPivot ); Abc_SclConeStore( p, vCone ); Abc_SclTimeCone( p, vCone ); +//Abc_SclTimeNtkPrint( p, 1 ); Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) if ( Abc_ObjIsCo(pObj) ) dGain += Abc_SclObjGain( p, pObj ); @@ -117,18 +118,16 @@ Abc_Obj_t * Abc_SclChooseBiggestGain( SC_Man * p, Vec_Int_t * vPath ) pNew = Abc_SclObjResiable( p, pObj ); if ( pNew == NULL ) continue; -printf( "changing %s for %s\n", pOld->name, pNew->name ); - +//printf( "changing %s for %s at node %d ", pOld->pName, pNew->pName, Abc_ObjId(pObj) ); gateId = Vec_IntEntry(p->vGates, Abc_ObjId(pObj)); - Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->name) ); + Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->pName) ); Abc_SclUpdateLoad( p, pObj, pOld, pNew ); dGain = Abc_SclSizingGain( p, pObj ); Abc_SclUpdateLoad( p, pObj, pNew, pOld ); - - Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pOld->name) ); +//printf( "gain is %f\n", dGain ); + Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pOld->pName) ); assert( gateId == Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); - if ( dGainBest < dGain ) { dGainBest = dGain; @@ -137,7 +136,7 @@ printf( "changing %s for %s\n", pOld->name, pNew->name ); } return pPivot; } -void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj ) +void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj, int iStep, int fVerbose ) { Vec_Int_t * vCone; SC_Cell * pOld, * pNew; @@ -146,39 +145,24 @@ void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj ) pNew = Abc_SclObjResiable( p, pObj ); assert( pNew != NULL ); // update gate - Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->name) ); - pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pNtk->pManFunc, pNew->name ); Abc_SclUpdateLoad( p, pObj, pOld, pNew ); p->SumArea += pNew->area - pOld->area; + Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->pName) ); // update info vCone = Abc_SclCollectTfo( p->pNtk, pObj ); + Abc_SclConeStore( p, vCone ); Abc_SclTimeCone( p, vCone ); Vec_IntFree( vCone ); -} - -float Abc_SclFindMaxDelay( SC_Man * p ) -{ - float fMaxArr = 0; - Abc_Obj_t * pObj; - SC_Pair * pArr; - int i; - Abc_NtkForEachCo( p->pNtk, pObj, i ) + // print output + if ( fVerbose ) { - pArr = Abc_SclObjTime( p, pObj ); - if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise; - if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall; + printf( "%5d : ", iStep ); + printf( "%5d ", Abc_ObjId(pObj) ); + printf( "%-12s-> %-12s ", pOld->pName, pNew->pName ); + printf( "delay =%8.2f ps ", SC_LibTimePs(p->pLib, Abc_SclGetMaxDelay(p)) ); + printf( "area =%10.2f ", p->SumArea ); + Abc_PrintTime( 1, "Time", clock() - p->clkStart ); } - return fMaxArr; -} - -void Abc_SclPrintResult( SC_Man * p, int i ) -{ - int fRise = 0; - Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise ); - printf( "%5d : ", i ); - printf( "area =%10.2f ", p->SumArea ); - printf( "delay =%8.2f ps ", Abc_SclObjTimePs(p, pPivot, fRise) ); - Abc_PrintTime( 1, "time", clock() - p->clkStart ); } /**Function************************************************************* @@ -192,26 +176,50 @@ void Abc_SclPrintResult( SC_Man * p, int i ) SeeAlso [] ***********************************************************************/ -void Abc_SclSizingPerform( SC_Lib * pLib, void * pNt, int nSteps ) +void Abc_SclSizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nSteps, int fVerbose ) { SC_Man * p; - Abc_Ntk_t * pNtk = (Abc_Ntk_t *)pNt; Vec_Int_t * vPath; Abc_Obj_t * pBest; int i; - p = Abc_SclManStart( pLib, pNtk ); - Abc_SclCriticalPathPrint( p ); + p = Abc_SclManStart( pLib, pNtk ); + if ( fVerbose ) + Abc_SclTimeNtkPrint( p, 0 ); + if ( fVerbose ) + printf( "Iterating gate sizing of network \"%s\" with library \"%s\":\n", Abc_NtkName(pNtk), pLib->pName ); + if ( fVerbose ) + { + printf( "%5d : ", 0 ); + printf( "delay =%8.2f ps ", SC_LibTimePs(p->pLib, Abc_SclGetMaxDelay(p)) ); + printf( "area =%10.2f ", p->SumArea ); + Abc_PrintTime( 1, "Time", clock() - p->clkStart ); + } for ( i = 0; i < nSteps; i++ ) { - vPath = Abc_SclCriticalPathFind( p ); + vPath = Abc_SclFindCriticalPath( p ); pBest = Abc_SclChooseBiggestGain( p, vPath ); Vec_IntFree( vPath ); if ( pBest == NULL ) break; - Abc_SclUpdateNetwork( p, pBest ); - Abc_SclPrintResult( p, i ); + Abc_SclUpdateNetwork( p, pBest, i+1, fVerbose ); + // recompute loads every 100 steps + if ( i && i % 100 == 0 ) + Abc_SclComputeLoad( p ); } - Abc_SclCriticalPathPrint( p ); + p->MaxDelay = Abc_SclGetMaxDelay(p); + if ( fVerbose ) + Abc_SclTimeNtkPrint( p, 0 ); + // print cumulative statistics + printf( "Resized: %d. ", i ); + printf( "Delay: " ); + printf( "%.2f -> %.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay0), SC_LibTimePs(p->pLib, p->MaxDelay) ); + printf( "(%+.1f %%). ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 ); + printf( "Area: " ); + printf( "%.2f -> %.2f ", p->SumArea0, p->SumArea ); + printf( "(%+.1f %%). ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 ); + Abc_PrintTime( 1, "Time", clock() - p->clkStart ); + // save the result and quit + Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers Abc_SclManFree( p ); } diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index 55ff7efb..4d62866b 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -1,10 +1,12 @@ /**CFile**************************************************************** - FileName [sclIo.c] + FileName [sclTime.c] SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Static timing analysis using Liberty delay model.] Author [Alan Mishchenko, Niklas Een] @@ -12,12 +14,10 @@ Date [Ver. 1.0. Started - August 24, 2012.] - Revision [$Id: sclIo.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] + Revision [$Id: sclTime.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "base/abc/abc.h" -#include "map/mio/mio.h" #include "sclInt.h" #include "sclMan.h" @@ -34,28 +34,7 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Abc_SclTotalArea( SC_Man * p ) -{ - double Area = 0; - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachNode( p->pNtk, pObj, i ) - Area += Abc_SclObjCell( p, pObj )->area; - return Area; -} - -/**Function************************************************************* - - Synopsis [] + Synopsis [Finding most critical nodes/fanins/path.] Description [] @@ -64,25 +43,7 @@ float Abc_SclTotalArea( SC_Man * p ) SeeAlso [] ***********************************************************************/ -void Abc_SclTimeNtkPrint( SC_Man * p ) -{ - Abc_Obj_t * pObj; - int i; - printf( "Total area = %f.\n", Abc_SclTotalArea( p ) ); - printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed ); - Abc_NtkForEachNode( p->pNtk, pObj, i ) - { - printf( "Node %6d : ", Abc_ObjId(pObj) ); - printf( "TimeR = %f. ", Abc_SclObjTime(p, pObj)->rise ); - printf( "RimeF = %f. ", Abc_SclObjTime(p, pObj)->fall ); - printf( "SlewR = %f. ", Abc_SclObjSlew(p, pObj)->rise ); - printf( "SlewF = %f. ", Abc_SclObjSlew(p, pObj)->fall ); - printf( "LoadR = %f. ", Abc_SclObjLoad(p, pObj)->rise ); - printf( "LoadF = %f. ", Abc_SclObjLoad(p, pObj)->fall ); - printf( "\n" ); - } -} -Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise ) +Abc_Obj_t * Abc_SclFindCriticalCo( SC_Man * p, int * pfRise ) { Abc_Obj_t * pObj, * pPivot = NULL; float fMaxArr = 0; @@ -109,10 +70,10 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * } return pPivot; } -Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p ) +Vec_Int_t * Abc_SclFindCriticalPath( SC_Man * p ) { int fRise = 0; - Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise ); + Abc_Obj_t * pPivot = Abc_SclFindCriticalCo( p, &fRise ); Vec_Int_t * vPath = Vec_IntAlloc( 100 ); Vec_IntPush( vPath, Abc_ObjId(pPivot) ); pPivot = Abc_ObjFanin0(pPivot); @@ -121,37 +82,13 @@ Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p ) Vec_IntPush( vPath, Abc_ObjId(pPivot) ); pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot ); } + Vec_IntReverseOrder( vPath ); return vPath; } -void Abc_SclCriticalPathPrint( SC_Man * p ) -{ - int fRise = 0; - Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise ); - - printf( "Total area = %10.2f.\n", Abc_SclTotalArea( p ) ); - printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed ); - printf( "Critical delay = %.1f ps\n", Abc_SclObjTimePs(p, pPivot, fRise) ); - - printf( "Critical path: \n" ); - pPivot = Abc_ObjFanin0(pPivot); - while ( pPivot && Abc_ObjIsNode(pPivot) ) - { - printf( "%5d : ", Abc_ObjId(pPivot) ); - printf( "%-10s ", Abc_SclObjCell(p, pPivot)->name ); - printf( "(%s) ", fRise ? "rise" : "fall" ); - printf( "delay =%6.1f ps ", Abc_SclObjTimePs(p, pPivot, fRise) ); - printf( "load =%6.2f ff ", Abc_SclObjLoadFf(p, pPivot, fRise) ); - printf( "slew =%6.1f ps ", Abc_SclObjSlewPs(p, pPivot, fRise) ); - printf( "\n" ); - - pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot ); - } -} - /**Function************************************************************* - Synopsis [] + Synopsis [Printing timing information for the node/network.] Description [] @@ -160,117 +97,50 @@ void Abc_SclCriticalPathPrint( SC_Man * p ) SeeAlso [] ***********************************************************************/ -Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) +static inline void Abc_SclTimeGatePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { - Vec_Flt_t * vCaps = NULL; - SC_WireLoad * pWL = NULL; - int i, Entry, EntryMax; - float EntryPrev, EntryCur; - p->pWLoadUsed = NULL; - if ( p->pLib->default_wire_load_sel && strlen(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 ); - for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++) - if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) ) - { - p->pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); - break; - } - if ( i == Vec_FltSize(pWLS->vAreaFrom) ) - p->pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); - } - else if ( p->pLib->default_wire_load && strlen(p->pLib->default_wire_load) ) - p->pWLoadUsed = 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->pWLoadUsed != NULL ); - Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) - if ( !strcmp(pWL->name, p->pWLoadUsed) ) - break; - if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) - { - Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWLoadUsed ); - 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, EntryCur, i ) - { - if ( EntryCur ) - EntryPrev = EntryCur; - else - Vec_FltWriteEntry( vCaps, i, EntryPrev ); - } - return vCaps; + printf( "%5d : ", Abc_ObjId(pObj) ); + printf( "%-10s ", Abc_SclObjCell(p, pObj)->pName ); + if ( fRise >= 0 ) + printf( "(%s) ", fRise ? "rise" : "fall" ); + printf( "delay = (" ); + printf( "%7.1f ps ", Abc_SclObjTimePs(p, pObj, 1) ); + printf( "%7.1f ps ) ", Abc_SclObjTimePs(p, pObj, 0) ); + printf( "load =%6.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); + printf( "slew =%6.1f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); + printf( "\n" ); } -void Abc_SclComputeLoad( SC_Man * p ) +void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll ) { - Vec_Flt_t * vWireCaps; - Abc_Obj_t * pObj, * pFanin; - int i, k; - Abc_NtkForEachNode( p->pNtk, pObj, i ) + int i, fRise = 0; + Abc_Obj_t * pObj = Abc_SclFindCriticalCo( p, &fRise ); + + printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ); + printf( "Total area = %10.2f. ", Abc_SclGetTotalArea( p ) ); + printf( "Critical delay = %.1f ps\n", Abc_SclObjTimePs(p, pObj, fRise) ); + + if ( fShowAll ) { - SC_Cell * pCell = Abc_SclObjCell( p, pObj ); - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); - SC_Pin * pPin = SC_CellPin( pCell, k ); - pLoad->rise += pPin->rise_cap; - pLoad->fall += pPin->fall_cap; - } +// printf( "Timing information for all nodes: \n" ); + Abc_NtkForEachNodeReverse( p->pNtk, pObj, i ) + Abc_SclTimeGatePrint( p, pObj, -1 ); } - vWireCaps = Abc_SclFindWireCaps( p ); - if ( vWireCaps ) + else { - Abc_NtkForEachNode( p->pNtk, pObj, i ) +// printf( "Critical path: \n" ); + pObj = Abc_ObjFanin0(pObj); + while ( pObj && Abc_ObjIsNode(pObj) ) { - 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); + printf( "Critical path -- " ); + Abc_SclTimeGatePrint( p, pObj, fRise ); + pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); } } - Vec_FltFree( vWireCaps ); -} -void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ) -{ - Abc_Obj_t * pFanin; - int k; - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); - SC_Pin * pPinOld = SC_CellPin( pOld, k ); - SC_Pin * pPinNew = SC_CellPin( pNew, k ); - pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap; - pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap; - } } /**Function************************************************************* - Synopsis [] + Synopsis [Timing computation for pin/gate/cone/network.] Description [] @@ -310,30 +180,30 @@ static inline float Abc_SclLookup( SC_Surface * p, float slew, float load ) return p0 + sfrac * (p1 - p0); // <<== multiply result with K factor here } -static inline void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) +void Abc_SclTimePin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) { - SC_Pair * pArrIn = Abc_SclObjTime ( p, pFanin ); + SC_Pair * pArrIn = Abc_SclObjTime( p, pFanin ); SC_Pair * pSlewIn = Abc_SclObjSlew( p, pFanin ); SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); - SC_Pair * pArrOut = Abc_SclObjTime ( p, pObj ); // modified - SC_Pair * pSlewOut = Abc_SclObjSlew( p, pObj ); // modified + SC_Pair * pArrOut = Abc_SclObjTime( p, pObj ); // modified + SC_Pair * pSlewOut = Abc_SclObjSlew( p, pObj ); // modified if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non) { - pArrOut->rise = Abc_MaxFloat( pArrOut->rise, pArrIn->rise + Abc_SclLookup(pTime->pCellRise, pSlewIn->rise, pLoad->rise) ); - pArrOut->fall = Abc_MaxFloat( pArrOut->fall, pArrIn->fall + Abc_SclLookup(pTime->pCellFall, pSlewIn->fall, pLoad->fall) ); - pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) ); - pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->fall, pLoad->fall) ); + pArrOut->rise = Abc_MaxFloat( pArrOut->rise, pArrIn->rise + Abc_SclLookup(pTime->pCellRise, pSlewIn->rise, pLoad->rise) ); + pArrOut->fall = Abc_MaxFloat( pArrOut->fall, pArrIn->fall + Abc_SclLookup(pTime->pCellFall, pSlewIn->fall, pLoad->fall) ); + pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) ); + pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->fall, pLoad->fall) ); } if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non) { - pArrOut->rise = Abc_MaxFloat( pArrOut->rise, pArrIn->fall + Abc_SclLookup(pTime->pCellRise, pSlewIn->fall, pLoad->rise) ); - pArrOut->fall = Abc_MaxFloat( pArrOut->fall, pArrIn->rise + Abc_SclLookup(pTime->pCellFall, pSlewIn->rise, pLoad->fall) ); - pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) ); - pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) ); + pArrOut->rise = Abc_MaxFloat( pArrOut->rise, pArrIn->fall + Abc_SclLookup(pTime->pCellRise, pSlewIn->fall, pLoad->rise) ); + pArrOut->fall = Abc_MaxFloat( pArrOut->fall, pArrIn->rise + Abc_SclLookup(pTime->pCellFall, pSlewIn->rise, pLoad->fall) ); + pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise, Abc_SclLookup(pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) ); + pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) ); } } -void Abc_SclTimeObj( SC_Man * p, Abc_Obj_t * pObj ) +void Abc_SclTimeGate( SC_Man * p, Abc_Obj_t * pObj ) { SC_Timings * pRTime; SC_Timing * pTime; @@ -357,36 +227,41 @@ void Abc_SclTimeObj( SC_Man * p, Abc_Obj_t * pObj ) { assert( Vec_PtrSize(pRTime->vTimings) == 1 ); pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); - Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) ); + Abc_SclTimePin( p, pTime, pObj, Abc_ObjFanin(pObj, k) ); } } -void Abc_SclTimeNtk( SC_Man * p ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachNode( p->pNtk, pObj, i ) - Abc_SclTimeObj( p, pObj ); - Abc_NtkForEachCo( p->pNtk, pObj, i ) - Abc_SclObjDupFanin( p, pObj ); -} void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ) { + int fVerbose = 0; Abc_Obj_t * pObj; int i; Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) { - if ( Abc_ObjIsNode(pObj) ) - printf( " Updating node with gate %s\n", Abc_SclObjCell(p, pObj)->name ); + if ( fVerbose && Abc_ObjIsNode(pObj) ) + printf( " Updating node %d with gate %s\n", Abc_ObjId(pObj), Abc_SclObjCell(p, pObj)->pName ); + + if ( fVerbose && Abc_ObjIsNode(pObj) ) + printf( " before (%6.1f ps %6.1f ps) ", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) ); - printf( " before %6.1f ps ", Abc_SclObjTimePs(p, pObj, 0) ); - Abc_SclTimeObj( p, pObj ); - printf( "after %6.1f ps\n", Abc_SclObjTimePs(p, pObj, 0) ); + Abc_SclTimeGate( p, pObj ); + + if ( fVerbose && Abc_ObjIsNode(pObj) ) + printf( "after (%6.1f ps %6.1f ps)\n", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) ); } } +void Abc_SclTimeNtk( SC_Man * p ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachNode( p->pNtk, pObj, i ) + Abc_SclTimeGate( p, pObj ); + Abc_NtkForEachCo( p->pNtk, pObj, i ) + Abc_SclObjDupFanin( p, pObj ); +} /**Function************************************************************* - Synopsis [] + Synopsis [Prepare timing manager.] Description [] @@ -397,20 +272,19 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ) ***********************************************************************/ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk ) { - extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ); - // prepare timing manager SC_Man * p = Abc_SclManAlloc( pLib, pNtk ); assert( p->vGates == NULL ); p->vGates = Abc_SclManFindGates( pLib, pNtk ); - p->SumArea = Abc_SclTotalArea( p ); Abc_SclComputeLoad( p ); Abc_SclTimeNtk( p ); + p->SumArea = p->SumArea0 = Abc_SclGetTotalArea( p ); + p->MaxDelay0 = Abc_SclGetMaxDelay( p ); return p; } /**Function************************************************************* - Synopsis [] + Synopsis [Printing out timing information for the network.] Description [] @@ -419,11 +293,11 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk ) +void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fShowAll ) { SC_Man * p; - p = Abc_SclManStart( pLib, (Abc_Ntk_t *)pNtk ); - Abc_SclCriticalPathPrint( p ); + p = Abc_SclManStart( pLib, pNtk ); + Abc_SclTimeNtkPrint( p, fShowAll ); Abc_SclManFree( p ); } diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index d1eb2869..e6b98fa2 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -4,7 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - Synopsis [Standard-cell library representation.] + PackageName [Standard-cell library representation.] + + Synopsis [Various utilities.] Author [Alan Mishchenko, Niklas Een] @@ -16,9 +18,8 @@ ***********************************************************************/ -#include "base/abc/abc.h" -#include "map/mio/mio.h" #include "sclInt.h" +#include "map/mio/mio.h" ABC_NAMESPACE_IMPL_START @@ -54,7 +55,7 @@ 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) ) + if ( p->pBins[i] == -1 || !strcmp(pName, SC_LibCell(p, p->pBins[i])->pName) ) return p->pBins + i; assert( 0 ); return NULL; @@ -68,7 +69,7 @@ void Abc_SclHashCells( SC_Lib * p ) p->pBins = ABC_FALLOC( int, p->nBins ); SC_LitForEachCell( p, pCell, i ) { - pPlace = Abc_SclHashLookup( p, pCell->name ); + pPlace = Abc_SclHashLookup( p, pCell->pName ); assert( *pPlace == -1 ); *pPlace = i; } @@ -99,7 +100,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 ) return -1; if ( (*pp1)->area > (*pp2)->area ) return 1; - return strcmp( (*pp1)->name, (*pp2)->name ); + return strcmp( (*pp1)->pName, (*pp2)->pName ); } void Abc_SclLinkCells( SC_Lib * p ) { @@ -153,7 +154,7 @@ void Abc_SclPrintCells( SC_Lib * p ) SC_Cell * pCell, * pRepr; int i, k; assert( Vec_PtrSize(p->vCellOrder) > 0 ); - printf( "Library \"%s\" ", p->lib_name ); + printf( "Library \"%s\" ", p->pName ); printf( "containing %d cells in %d classes.\n", Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellOrder) ); Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k ) @@ -170,7 +171,7 @@ void Abc_SclPrintCells( SC_Lib * p ) SC_RingForEachCell( pRepr, pCell, i ) { printf( " %3d : ", i+1 ); - printf( "%-12s ", pCell->name ); + printf( "%-12s ", pCell->pName ); printf( "%2d ", pCell->drive_strength ); printf( "A =%8.3f", pCell->area ); printf( "\n" ); @@ -180,7 +181,7 @@ void Abc_SclPrintCells( SC_Lib * p ) /**Function************************************************************* - Synopsis [] + Synopsis [Converts pNode->pData gates into array of SC_Lit gate IDs and back.] Description [] @@ -205,6 +206,18 @@ Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ) } return vVec; } +void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachNode( p, pObj, i ) + { + SC_Cell * pCell = SC_LibCell( pLib, Vec_IntEntry(vGates, Abc_ObjId(pObj)) ); + assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) ); + pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName ); +//printf( "Found gate %s\n", pCell->name ); + } +} //////////////////////////////////////////////////////////////////////// |