mirror of https://github.com/YosysHQ/abc.git
New package to read/write a subset of Liberty for STA.
This commit is contained in:
parent
6814c48bb4
commit
83bfe0b1fe
|
|
@ -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,81 +232,15 @@ 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 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Abc_FrameReadNtk(pAbc) == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "There is no current network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) )
|
||||
{
|
||||
fprintf( pAbc->Err, "The current network is not mapped.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) )
|
||||
{
|
||||
fprintf( pAbc->Err, "The current networks is not in a topo order (run \"buffer -N 1000\").\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pAbc->pLibScl == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc) );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: stime [-h]\n" );
|
||||
fprintf( pAbc->Err, "\t performs STA using Liberty library\n" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
int c;
|
||||
int nSteps = 100;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nSteps = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nSteps <= 0 )
|
||||
goto usage;
|
||||
case 'a':
|
||||
fShowAll ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
|
|
@ -338,13 +270,88 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps );
|
||||
Abc_SclTimePerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), fShowAll );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: gsize [-N num] [-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;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
int c, fVerbose = 0;
|
||||
int nSteps = 100000;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nSteps = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nSteps <= 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Abc_FrameReadNtk(pAbc) == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "There is no current network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) )
|
||||
{
|
||||
fprintf( pAbc->Err, "The current network is not mapped.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) )
|
||||
{
|
||||
fprintf( pAbc->Err, "The current networks is not in a topo order (run \"buffer -N 1000\").\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pAbc->pLibScl == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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,67 +72,28 @@ 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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
|
||||
*Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares STA manager.]
|
||||
Synopsis [Constructor/destructor of STA manager.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -164,13 +130,85 @@ static inline void Abc_SclManFree( SC_Man * p )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stores/retrivies timing information for the logic cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
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_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 )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
|
||||
*Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Abc_SclGetTotalArea( 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;
|
||||
}
|
||||
static inline float Abc_SclGetMaxDelay( SC_Man * p )
|
||||
{
|
||||
float fMaxArr = 0;
|
||||
Abc_Obj_t * pObj;
|
||||
SC_Pair * pArr;
|
||||
int i;
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
{
|
||||
pArr = Abc_SclObjTime( p, pObj );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,7 +34,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Finding most critical nodes/fanins/path.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -43,46 +43,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
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) )
|
||||
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_SclTimeNtkPrint( SC_Man * p, int fShowAll )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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);
|
||||
// printf( "Timing information for all nodes: \n" );
|
||||
Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
|
||||
Abc_SclTimeGatePrint( p, pObj, -1 );
|
||||
}
|
||||
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;
|
||||
}
|
||||
void Abc_SclComputeLoad( SC_Man * p )
|
||||
{
|
||||
Vec_Flt_t * vWireCaps;
|
||||
Abc_Obj_t * pObj, * pFanin;
|
||||
int i, k;
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
{
|
||||
SC_Cell * pCell = Abc_SclObjCell( p, pObj );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
// printf( "Critical path: \n" );
|
||||
pObj = Abc_ObjFanin0(pObj);
|
||||
while ( pObj && Abc_ObjIsNode(pObj) )
|
||||
{
|
||||
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( "Critical path -- " );
|
||||
Abc_SclTimeGatePrint( p, pObj, fRise );
|
||||
pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**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,7 +227,26 @@ 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_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 ( 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) );
|
||||
|
||||
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 )
|
||||
|
|
@ -365,28 +254,14 @@ void Abc_SclTimeNtk( SC_Man * p )
|
|||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
Abc_SclTimeObj( p, pObj );
|
||||
Abc_SclTimeGate( p, pObj );
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
Abc_SclObjDupFanin( p, pObj );
|
||||
}
|
||||
void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
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 );
|
||||
|
||||
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) );
|
||||
}
|
||||
}
|
||||
|
||||
/**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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue