summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-08-29 16:20:39 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2012-08-29 16:20:39 -0700
commit83bfe0b1fec515d9350ebd63f07f0ed742bb4745 (patch)
tree8fcfd00de92c20fc7e07011c70c8d6ffa8d9d537 /src
parent6814c48bb4e748add7e4ebd37f0d4d00312e0c5a (diff)
downloadabc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.tar.gz
abc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.tar.bz2
abc-83bfe0b1fec515d9350ebd63f07f0ed742bb4745.zip
New package to read/write a subset of Liberty for STA.
Diffstat (limited to 'src')
-rw-r--r--src/base/abc/abc.h3
-rw-r--r--src/map/scl/scl.c65
-rw-r--r--src/map/scl/scl.h12
-rw-r--r--src/map/scl/sclBuff.c26
-rw-r--r--src/map/scl/sclFile.c50
-rw-r--r--src/map/scl/sclInt.h112
-rw-r--r--src/map/scl/sclLoad.c180
-rw-r--r--src/map/scl/sclMan.h130
-rw-r--r--src/map/scl/sclSize.c94
-rw-r--r--src/map/scl/sclTime.c290
-rw-r--r--src/map/scl/sclUtil.c31
11 files changed, 580 insertions, 413 deletions
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 );
+ }
+}
////////////////////////////////////////////////////////////////////////