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
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclLoad.c
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclMan.h
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclSize.c
# End Source File
# Begin Source File
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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 );
......
/**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 )
......
......@@ -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
......
/**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 @@
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
......
......@@ -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 );
}
......
/**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 );
}
......
......@@ -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 );
}
}
////////////////////////////////////////////////////////////////////////
......
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