Commit 83bfe0b1 by Alan Mishchenko

New package to read/write a subset of Liberty for STA.

parent 6814c48b
...@@ -2367,6 +2367,14 @@ SOURCE=.\src\map\scl\sclInt.h ...@@ -2367,6 +2367,14 @@ SOURCE=.\src\map\scl\sclInt.h
# End Source File # End Source File
# Begin 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 SOURCE=.\src\map\scl\sclSize.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -463,6 +463,9 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At ...@@ -463,6 +463,9 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At
#define Abc_NtkForEachNode( pNtk, pNode, i ) \ #define Abc_NtkForEachNode( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else 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 ) \ #define Abc_NtkForEachGate( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsGate(pNode) ) {} else if ( (pNode) == NULL || !Abc_ObjIsGate(pNode) ) {} else
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -17,7 +19,6 @@ ...@@ -17,7 +19,6 @@
***********************************************************************/ ***********************************************************************/
#include "sclInt.h" #include "sclInt.h"
#include "scl.h"
#include "base/main/mainInt.h" #include "base/main/mainInt.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -27,15 +28,12 @@ ABC_NAMESPACE_IMPL_START ...@@ -27,15 +28,12 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); 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_CommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrint ( 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_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandGsize ( 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 ); 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 );
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
...@@ -54,12 +52,12 @@ extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerb ...@@ -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 ) void Scl_Init( Abc_Frame_t * pAbc )
{ {
Cmd_CommandAdd( pAbc, "SC mapping", "read_scl", Scl_CommandRead, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "read_scl", Scl_CommandRead, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "write_scl", Scl_CommandWrite, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "write_scl", Scl_CommandWrite, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "print_scl", Scl_CommandPrint, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_scl", Scl_CommandPrint, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "gsize", Scl_CommandGsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "gsize", Scl_CommandGsize, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "buffer", Scl_CommandBuffer, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 );
} }
void Scl_End( Abc_Frame_t * pAbc ) void Scl_End( Abc_Frame_t * pAbc )
{ {
...@@ -234,12 +232,16 @@ usage: ...@@ -234,12 +232,16 @@ usage:
int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
int c; int c;
int fShowAll = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
case 'a':
fShowAll ^= 1;
break;
case 'h': case 'h':
goto usage; goto usage;
default: default:
...@@ -268,12 +270,13 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -268,12 +270,13 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
return 1; return 1;
} }
Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc) ); Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), fShowAll );
return 0; return 0;
usage: 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 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" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" );
return 1; return 1;
} }
...@@ -291,11 +294,11 @@ usage: ...@@ -291,11 +294,11 @@ usage:
***********************************************************************/ ***********************************************************************/
int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
int c; int c, fVerbose = 0;
int nSteps = 100; int nSteps = 100000;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -310,6 +313,9 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -310,6 +313,9 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
if ( nSteps <= 0 ) if ( nSteps <= 0 )
goto usage; goto usage;
break; break;
case 'v':
fVerbose ^= 1;
break;
case 'h': case 'h':
goto usage; goto usage;
default: default:
...@@ -338,13 +344,14 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -338,13 +344,14 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
return 1; return 1;
} }
// Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps ); Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps, fVerbose );
return 0; return 0;
usage: 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 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" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" );
return 1; return 1;
} }
...@@ -366,7 +373,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -366,7 +373,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtkRes; Abc_Ntk_t * pNtkRes;
int Degree; int Degree;
int c, fVerbose; int c, fVerbose;
Degree = 3; Degree = 4;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF )
...@@ -419,8 +426,8 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -419,8 +426,8 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
usage: usage:
fprintf( pAbc->Err, "usage: buffer [-N num] [-vh]\n" ); fprintf( pAbc->Err, "usage: buffer [-N num] [-vh]\n" );
fprintf( pAbc->Err, "\t performs buffering of the mapped network\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-N <num> : the max allowed fanout count of node/buffer [default = %d]\n", Degree );
fprintf( pAbc->Err, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" ); 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"); fprintf( pAbc->Err, "\t-h : print the command usage\n");
return 1; return 1;
} }
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -46,14 +48,6 @@ ABC_NAMESPACE_HEADER_START ...@@ -46,14 +48,6 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DEFINITIONS /// /// 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 ABC_NAMESPACE_HEADER_END
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -16,9 +18,8 @@ ...@@ -16,9 +18,8 @@
***********************************************************************/ ***********************************************************************/
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "sclInt.h" #include "sclInt.h"
#include "map/mio/mio.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -33,7 +34,7 @@ ABC_NAMESPACE_IMPL_START ...@@ -33,7 +34,7 @@ ABC_NAMESPACE_IMPL_START
/**Function************************************************************* /**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.] Description [Returns 1 iff the network is fine.]
...@@ -65,7 +66,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) ...@@ -65,7 +66,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Make sure the network has no dangling nodes.] Synopsis []
Description [] Description []
...@@ -109,7 +110,7 @@ int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) ...@@ -109,7 +110,7 @@ int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
return -1; return -1;
if ( Diff > 0 ) if ( Diff > 0 )
return 1; return 1;
Diff = (*pp1)->Id - (*pp2)->Id; Diff = (*pp1)->Id - (*pp2)->Id; // needed to make qsort() platform-infependent
if ( Diff < 0 ) if ( Diff < 0 )
return -1; return -1;
if ( Diff > 0 ) if ( Diff > 0 )
...@@ -195,14 +196,25 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose ) ...@@ -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 ) Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose )
{ {
Vec_Int_t * vCiLevs;
Abc_Ntk_t * pNew; Abc_Ntk_t * pNew;
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i; int i;
assert( Abc_NtkHasMapping(p) ); 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_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
Abc_SclPerformBuffering_rec( pObj, Degree, fVerbose ); 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 // duplication in topo order
pNew = Abc_NtkDupDfs( p ); pNew = Abc_NtkDupDfs( p );
Abc_SclCheckNtk( pNew, fVerbose ); Abc_SclCheckNtk( pNew, fVerbose );
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -30,7 +32,7 @@ ...@@ -30,7 +32,7 @@
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
#include "misc/vec/vec.h" #include "base/abc/abc.h"
ABC_NAMESPACE_HEADER_START ABC_NAMESPACE_HEADER_START
...@@ -74,7 +76,7 @@ typedef struct SC_Lib_ SC_Lib; ...@@ -74,7 +76,7 @@ typedef struct SC_Lib_ SC_Lib;
struct SC_WireLoad_ struct SC_WireLoad_
{ {
char * name; char * pName;
float res; // (currently not used) float res; // (currently not used)
float cap; // }- multiply estimation in 'fanout_len[].snd' with this value float cap; // }- multiply estimation in 'fanout_len[].snd' with this value
Vec_Int_t * vFanout; // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)' Vec_Int_t * vFanout; // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)'
...@@ -83,7 +85,7 @@ struct SC_WireLoad_ ...@@ -83,7 +85,7 @@ struct SC_WireLoad_
struct SC_WireLoadSel_ 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 * vAreaFrom; // Vec<Trip<float,float,Str> > -- triplets '(from-area, upto-area, wire-load-model)'; range is [from, upto[
Vec_Flt_t * vAreaTo; Vec_Flt_t * vAreaTo;
Vec_Ptr_t * vWireLoadModel; Vec_Ptr_t * vWireLoadModel;
...@@ -91,14 +93,14 @@ struct SC_WireLoadSel_ ...@@ -91,14 +93,14 @@ struct SC_WireLoadSel_
struct SC_TableTempl_ 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 * 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 Vec_Ptr_t * vIndex; // Vec<Vec<float> > -- this is the point of measurement in table for the given variable
}; };
struct SC_Surface_ 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 * 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_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])' Vec_Ptr_t * vData; // Vec<Vec<float> > -- 'data[i0][i1]' gives value at '(index0[i0], index1[i1])'
...@@ -118,13 +120,13 @@ struct SC_Timing_ ...@@ -118,13 +120,13 @@ struct SC_Timing_
struct SC_Timings_ struct SC_Timings_
{ {
char * name; // -- the 'related_pin' field char * pName; // -- the 'related_pin' field
Vec_Ptr_t * vTimings; // structures of type SC_Timing Vec_Ptr_t * vTimings; // structures of type SC_Timing
}; };
struct SC_Pin_ struct SC_Pin_
{ {
char * name; char * pName;
SC_Dir dir; SC_Dir dir;
float cap; // -- this value is used if 'rise_cap' and 'fall_cap' is missing (copied by 'postProcess()'). (not used) 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). float rise_cap; // }- used for input pins ('cap' too).
...@@ -138,7 +140,7 @@ struct SC_Pin_ ...@@ -138,7 +140,7 @@ struct SC_Pin_
struct SC_Cell_ struct SC_Cell_
{ {
char * name; char * pName;
int seq; // -- set to TRUE by parser if a sequential element 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 int unsupp; // -- set to TRUE by parser if cell contains information we cannot handle
float area; float area;
...@@ -152,7 +154,7 @@ struct SC_Cell_ ...@@ -152,7 +154,7 @@ struct SC_Cell_
struct SC_Lib_ struct SC_Lib_
{ {
char * lib_name; char * pName;
char * default_wire_load; char * default_wire_load;
char * default_wire_load_sel; 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) 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 ...@@ -194,6 +196,17 @@ static inline double SC_LibTimePs( SC_Lib * p, double time ) { return time
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Constructors of the library data-structures.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline SC_WireLoad * Abc_SclWireLoadAlloc() static inline SC_WireLoad * Abc_SclWireLoadAlloc()
{ {
SC_WireLoad * p; SC_WireLoad * p;
...@@ -278,11 +291,22 @@ static inline SC_Lib * Abc_SclLibAlloc() ...@@ -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 ) static inline void Abc_SclWireLoadFree( SC_WireLoad * p )
{ {
Vec_IntFree( p->vFanout ); Vec_IntFree( p->vFanout );
Vec_FltFree( p->vLen ); Vec_FltFree( p->vLen );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p ) static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p )
...@@ -290,14 +314,14 @@ 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->vAreaFrom );
Vec_FltFree( p->vAreaTo ); Vec_FltFree( p->vAreaTo );
Vec_PtrFreeFree( p->vWireLoadModel ); Vec_PtrFreeFree( p->vWireLoadModel );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclTableTemplFree( SC_TableTempl * p ) static inline void Abc_SclTableTemplFree( SC_TableTempl * p )
{ {
Vec_PtrFreeFree( p->vVars ); Vec_PtrFreeFree( p->vVars );
Vec_VecFree( (Vec_Vec_t *)p->vIndex ); Vec_VecFree( (Vec_Vec_t *)p->vIndex );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclSurfaceFree( SC_Surface * p ) static inline void Abc_SclSurfaceFree( SC_Surface * p )
...@@ -305,7 +329,7 @@ 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->vIndex0 );
Vec_FltFree( p->vIndex1 ); Vec_FltFree( p->vIndex1 );
Vec_VecFree( (Vec_Vec_t *)p->vData ); Vec_VecFree( (Vec_Vec_t *)p->vData );
ABC_FREE( p->templ_name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclTimingFree( SC_Timing * p ) static inline void Abc_SclTimingFree( SC_Timing * p )
...@@ -325,7 +349,7 @@ static inline void Abc_SclTimingsFree( SC_Timings * p ) ...@@ -325,7 +349,7 @@ static inline void Abc_SclTimingsFree( SC_Timings * p )
Vec_PtrForEachEntry( SC_Timing *, p->vTimings, pTemp, i ) Vec_PtrForEachEntry( SC_Timing *, p->vTimings, pTemp, i )
Abc_SclTimingFree( pTemp ); Abc_SclTimingFree( pTemp );
Vec_PtrFree( p->vTimings ); Vec_PtrFree( p->vTimings );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclPinFree( SC_Pin * p ) static inline void Abc_SclPinFree( SC_Pin * p )
...@@ -337,7 +361,7 @@ 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_PtrFree( p->vRTimings );
Vec_WrdFree( p->vFunc ); Vec_WrdFree( p->vFunc );
ABC_FREE( p->func_text ); ABC_FREE( p->func_text );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclCellFree( SC_Cell * p ) static inline void Abc_SclCellFree( SC_Cell * p )
...@@ -347,30 +371,30 @@ 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 ) Vec_PtrForEachEntry( SC_Pin *, p->vPins, pTemp, i )
Abc_SclPinFree( pTemp ); Abc_SclPinFree( pTemp );
Vec_PtrFree( p->vPins ); Vec_PtrFree( p->vPins );
ABC_FREE( p->name ); ABC_FREE( p->pName );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Abc_SclLibFree( SC_Lib * p ) static inline void Abc_SclLibFree( SC_Lib * p )
{ {
SC_WireLoad * pTemp1; SC_WireLoad * pWL;
SC_WireLoadSel * pTemp2; SC_WireLoadSel * pWLS;
SC_TableTempl * pTemp3; SC_TableTempl * pTempl;
SC_Cell * pTemp4; SC_Cell * pCell;
int i; int i;
Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pTemp1, i ) Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i )
Abc_SclWireLoadFree( pTemp1 ); Abc_SclWireLoadFree( pWL );
Vec_PtrFree( p->vWireLoads ); Vec_PtrFree( p->vWireLoads );
Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pTemp2, i ) Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i )
Abc_SclWireLoadSelFree( pTemp2 ); Abc_SclWireLoadSelFree( pWLS );
Vec_PtrFree( p->vWireLoadSels ); Vec_PtrFree( p->vWireLoadSels );
Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTemp3, i ) Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTempl, i )
Abc_SclTableTemplFree( pTemp3 ); Abc_SclTableTemplFree( pTempl );
Vec_PtrFree( p->vTempls ); Vec_PtrFree( p->vTempls );
SC_LitForEachCell( p, pTemp4, i ) SC_LitForEachCell( p, pCell, i )
Abc_SclCellFree( pTemp4 ); Abc_SclCellFree( pCell );
Vec_PtrFree( p->vCells ); Vec_PtrFree( p->vCells );
Vec_PtrFree( p->vCellOrder ); 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 );
ABC_FREE( p->default_wire_load_sel ); ABC_FREE( p->default_wire_load_sel );
ABC_FREE( p->pBins ); ABC_FREE( p->pBins );
...@@ -378,16 +402,28 @@ static inline void Abc_SclLibFree( SC_Lib * p ) ...@@ -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 =============================================================*/ /*=== sclFile.c =============================================================*/
extern SC_Lib * Abc_SclRead( char * pFileName ); extern SC_Lib * Abc_SclRead( char * pFileName );
extern void Abc_SclWrite( char * pFileName, SC_Lib * p ); extern void Abc_SclWrite( char * pFileName, SC_Lib * p );
extern void Abc_SclWriteText( 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 =============================================================*/ /*=== sclUtil.c =============================================================*/
extern void Abc_SclHashCells( SC_Lib * p ); extern void Abc_SclHashCells( SC_Lib * p );
extern int Abc_SclCellFind( SC_Lib * p, char * pName ); extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern void Abc_SclLinkCells( SC_Lib * p ); extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( 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 ABC_NAMESPACE_HEADER_END
......
/**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
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -47,9 +49,8 @@ struct SC_Man_ ...@@ -47,9 +49,8 @@ struct SC_Man_
{ {
SC_Lib * pLib; // library SC_Lib * pLib; // library
Abc_Ntk_t * pNtk; // network Abc_Ntk_t * pNtk; // network
float SumArea; // total area
int nObjs; // allocated size
Vec_Int_t * vGates; // mapping of objId into gateId Vec_Int_t * vGates; // mapping of objId into gateId
int nObjs; // allocated size
SC_Pair * pLoads; // loads for each gate SC_Pair * pLoads; // loads for each gate
SC_Pair * pTimes; // arrivals for each gate SC_Pair * pTimes; // arrivals for each gate
SC_Pair * pSlews; // slews for each gate SC_Pair * pSlews; // slews for each gate
...@@ -57,6 +58,10 @@ struct SC_Man_ ...@@ -57,6 +58,10 @@ struct SC_Man_
SC_Pair * pSlews2; // slews for each gate SC_Pair * pSlews2; // slews for each gate
char * pWLoadUsed; // name of the used WireLoad model char * pWLoadUsed; // name of the used WireLoad model
clock_t clkStart; // starting time 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_ ...@@ -67,35 +72,67 @@ struct SC_Man_
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + 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_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_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + 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_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 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 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_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_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 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 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************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Stores/retrivies timing information for the logic cone.]
Description [] Description []
...@@ -106,12 +143,13 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return ...@@ -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 ) static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
{ {
SC_Pair Zero = { 0.0, 0.0 };
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i; int i;
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{ {
*Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj); *Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj); *Abc_SclObjTime(p, pObj) = Zero;
*Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj); *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 ) 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 ) ...@@ -127,7 +165,7 @@ static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Prepares STA manager.] Synopsis []
Description [] Description []
...@@ -136,41 +174,41 @@ static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone ) ...@@ -136,41 +174,41 @@ static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
SeeAlso [] 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; double Area = 0;
assert( Abc_NtkHasMapping(pNtk) ); Abc_Obj_t * pObj;
p = ABC_CALLOC( SC_Man, 1 ); int i;
p->pLib = pLib; Abc_NtkForEachNode( p->pNtk, pObj, i )
p->pNtk = pNtk; Area += Abc_SclObjCell( p, pObj )->area;
p->nObjs = Abc_NtkObjNumMax(pNtk); return Area;
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 ) static inline float Abc_SclGetMaxDelay( SC_Man * p )
{ {
Vec_IntFreeP( &p->vGates ); float fMaxArr = 0;
ABC_FREE( p->pLoads ); Abc_Obj_t * pObj;
ABC_FREE( p->pTimes ); SC_Pair * pArr;
ABC_FREE( p->pSlews ); int i;
ABC_FREE( p->pTimes2 ); Abc_NtkForEachCo( p->pNtk, pObj, i )
ABC_FREE( p->pSlews2 ); {
ABC_FREE( p ); pArr = Abc_SclObjTime( p, pObj );
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise;
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall;
}
return fMaxArr;
} }
/*=== sclTime.c =============================================================*/ /*=== 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 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 ); 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_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 ABC_NAMESPACE_HEADER_END
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -16,8 +18,6 @@ ...@@ -16,8 +18,6 @@
***********************************************************************/ ***********************************************************************/
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "sclInt.h" #include "sclInt.h"
#include "sclMan.h" #include "sclMan.h"
...@@ -96,6 +96,7 @@ float Abc_SclSizingGain( SC_Man * p, Abc_Obj_t * pPivot ) ...@@ -96,6 +96,7 @@ float Abc_SclSizingGain( SC_Man * p, Abc_Obj_t * pPivot )
vCone = Abc_SclCollectTfo( p->pNtk, pPivot ); vCone = Abc_SclCollectTfo( p->pNtk, pPivot );
Abc_SclConeStore( p, vCone ); Abc_SclConeStore( p, vCone );
Abc_SclTimeCone( p, vCone ); Abc_SclTimeCone( p, vCone );
//Abc_SclTimeNtkPrint( p, 1 );
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
if ( Abc_ObjIsCo(pObj) ) if ( Abc_ObjIsCo(pObj) )
dGain += Abc_SclObjGain( p, pObj ); dGain += Abc_SclObjGain( p, pObj );
...@@ -117,18 +118,16 @@ Abc_Obj_t * Abc_SclChooseBiggestGain( SC_Man * p, Vec_Int_t * vPath ) ...@@ -117,18 +118,16 @@ Abc_Obj_t * Abc_SclChooseBiggestGain( SC_Man * p, Vec_Int_t * vPath )
pNew = Abc_SclObjResiable( p, pObj ); pNew = Abc_SclObjResiable( p, pObj );
if ( pNew == NULL ) if ( pNew == NULL )
continue; 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)); 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 ); Abc_SclUpdateLoad( p, pObj, pOld, pNew );
dGain = Abc_SclSizingGain( p, pObj ); dGain = Abc_SclSizingGain( p, pObj );
Abc_SclUpdateLoad( p, pObj, pNew, pOld ); Abc_SclUpdateLoad( p, pObj, pNew, pOld );
//printf( "gain is %f\n", dGain );
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pOld->name) ); Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pOld->pName) );
assert( gateId == Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); assert( gateId == Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) );
if ( dGainBest < dGain ) if ( dGainBest < dGain )
{ {
dGainBest = dGain; dGainBest = dGain;
...@@ -137,7 +136,7 @@ printf( "changing %s for %s\n", pOld->name, pNew->name ); ...@@ -137,7 +136,7 @@ printf( "changing %s for %s\n", pOld->name, pNew->name );
} }
return pPivot; 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; Vec_Int_t * vCone;
SC_Cell * pOld, * pNew; SC_Cell * pOld, * pNew;
...@@ -146,39 +145,24 @@ void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj ) ...@@ -146,39 +145,24 @@ void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj )
pNew = Abc_SclObjResiable( p, pObj ); pNew = Abc_SclObjResiable( p, pObj );
assert( pNew != NULL ); assert( pNew != NULL );
// update gate // 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 ); Abc_SclUpdateLoad( p, pObj, pOld, pNew );
p->SumArea += pNew->area - pOld->area; p->SumArea += pNew->area - pOld->area;
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->pName) );
// update info // update info
vCone = Abc_SclCollectTfo( p->pNtk, pObj ); vCone = Abc_SclCollectTfo( p->pNtk, pObj );
Abc_SclConeStore( p, vCone );
Abc_SclTimeCone( p, vCone ); Abc_SclTimeCone( p, vCone );
Vec_IntFree( vCone ); Vec_IntFree( vCone );
} // print output
if ( fVerbose )
float Abc_SclFindMaxDelay( SC_Man * p )
{
float fMaxArr = 0;
Abc_Obj_t * pObj;
SC_Pair * pArr;
int i;
Abc_NtkForEachCo( p->pNtk, pObj, i )
{ {
pArr = Abc_SclObjTime( p, pObj ); printf( "%5d : ", iStep );
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise; printf( "%5d ", Abc_ObjId(pObj) );
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall; 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************************************************************* /**Function*************************************************************
...@@ -192,26 +176,50 @@ void Abc_SclPrintResult( SC_Man * p, int i ) ...@@ -192,26 +176,50 @@ void Abc_SclPrintResult( SC_Man * p, int i )
SeeAlso [] 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; SC_Man * p;
Abc_Ntk_t * pNtk = (Abc_Ntk_t *)pNt;
Vec_Int_t * vPath; Vec_Int_t * vPath;
Abc_Obj_t * pBest; Abc_Obj_t * pBest;
int i; int i;
p = Abc_SclManStart( pLib, pNtk ); p = Abc_SclManStart( pLib, pNtk );
Abc_SclCriticalPathPrint( p ); 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++ ) for ( i = 0; i < nSteps; i++ )
{ {
vPath = Abc_SclCriticalPathFind( p ); vPath = Abc_SclFindCriticalPath( p );
pBest = Abc_SclChooseBiggestGain( p, vPath ); pBest = Abc_SclChooseBiggestGain( p, vPath );
Vec_IntFree( vPath ); Vec_IntFree( vPath );
if ( pBest == NULL ) if ( pBest == NULL )
break; break;
Abc_SclUpdateNetwork( p, pBest ); Abc_SclUpdateNetwork( p, pBest, i+1, fVerbose );
Abc_SclPrintResult( p, i ); // 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 ); Abc_SclManFree( p );
} }
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko, Niklas Een]
...@@ -16,9 +18,8 @@ ...@@ -16,9 +18,8 @@
***********************************************************************/ ***********************************************************************/
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "sclInt.h" #include "sclInt.h"
#include "map/mio/mio.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -54,7 +55,7 @@ int * Abc_SclHashLookup( SC_Lib * p, char * pName ) ...@@ -54,7 +55,7 @@ int * Abc_SclHashLookup( SC_Lib * p, char * pName )
{ {
int i; int i;
for ( i = Abc_SclHashString(pName, p->nBins); i < p->nBins; i = (i + 1) % p->nBins ) 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; return p->pBins + i;
assert( 0 ); assert( 0 );
return NULL; return NULL;
...@@ -68,7 +69,7 @@ void Abc_SclHashCells( SC_Lib * p ) ...@@ -68,7 +69,7 @@ void Abc_SclHashCells( SC_Lib * p )
p->pBins = ABC_FALLOC( int, p->nBins ); p->pBins = ABC_FALLOC( int, p->nBins );
SC_LitForEachCell( p, pCell, i ) SC_LitForEachCell( p, pCell, i )
{ {
pPlace = Abc_SclHashLookup( p, pCell->name ); pPlace = Abc_SclHashLookup( p, pCell->pName );
assert( *pPlace == -1 ); assert( *pPlace == -1 );
*pPlace = i; *pPlace = i;
} }
...@@ -99,7 +100,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 ) ...@@ -99,7 +100,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )
return -1; return -1;
if ( (*pp1)->area > (*pp2)->area ) if ( (*pp1)->area > (*pp2)->area )
return 1; return 1;
return strcmp( (*pp1)->name, (*pp2)->name ); return strcmp( (*pp1)->pName, (*pp2)->pName );
} }
void Abc_SclLinkCells( SC_Lib * p ) void Abc_SclLinkCells( SC_Lib * p )
{ {
...@@ -153,7 +154,7 @@ void Abc_SclPrintCells( SC_Lib * p ) ...@@ -153,7 +154,7 @@ void Abc_SclPrintCells( SC_Lib * p )
SC_Cell * pCell, * pRepr; SC_Cell * pCell, * pRepr;
int i, k; int i, k;
assert( Vec_PtrSize(p->vCellOrder) > 0 ); 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", printf( "containing %d cells in %d classes.\n",
Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellOrder) ); Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellOrder) );
Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k ) Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k )
...@@ -170,7 +171,7 @@ void Abc_SclPrintCells( SC_Lib * p ) ...@@ -170,7 +171,7 @@ void Abc_SclPrintCells( SC_Lib * p )
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
{ {
printf( " %3d : ", i+1 ); printf( " %3d : ", i+1 );
printf( "%-12s ", pCell->name ); printf( "%-12s ", pCell->pName );
printf( "%2d ", pCell->drive_strength ); printf( "%2d ", pCell->drive_strength );
printf( "A =%8.3f", pCell->area ); printf( "A =%8.3f", pCell->area );
printf( "\n" ); printf( "\n" );
...@@ -180,7 +181,7 @@ void Abc_SclPrintCells( SC_Lib * p ) ...@@ -180,7 +181,7 @@ void Abc_SclPrintCells( SC_Lib * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Converts pNode->pData gates into array of SC_Lit gate IDs and back.]
Description [] Description []
...@@ -205,6 +206,18 @@ Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ) ...@@ -205,6 +206,18 @@ Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p )
} }
return vVec; 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 );
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment