Commit 84c0b9d6 by Alan Mishchenko

Tuning standard-cell mapping flow.

parent 038f2964
...@@ -398,13 +398,12 @@ Vec_Ptr_t * Aig_ManDfsChoices( Aig_Man_t * p ) ...@@ -398,13 +398,12 @@ Vec_Ptr_t * Aig_ManDfsChoices( Aig_Man_t * p )
{ {
if ( Aig_ObjEquiv(p, pObj) == NULL ) if ( Aig_ObjEquiv(p, pObj) == NULL )
continue; continue;
Counter = 0; Counter = 0;
for ( pObj = Aig_ObjEquiv(p, pObj) ; pObj; pObj = Aig_ObjEquiv(p, pObj) ) for ( pObj = Aig_ObjEquiv(p, pObj) ; pObj; pObj = Aig_ObjEquiv(p, pObj) )
Counter++; Counter++;
printf( "%d ", Counter ); // printf( "%d ", Counter );
} }
printf( "\n" ); // printf( "\n" );
assert( p->pEquivs != NULL ); assert( p->pEquivs != NULL );
Aig_ManIncrementTravId( p ); Aig_ManIncrementTravId( p );
......
...@@ -300,8 +300,8 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld ) ...@@ -300,8 +300,8 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
Abc_Time_t ** ppTimes, * pTime; Abc_Time_t ** ppTimes, * pTime;
int i; int i;
assert( pNtkOld == NULL || pNtkOld->pManTime != NULL ); assert( pNtkOld == NULL || pNtkOld->pManTime != NULL );
assert( pNtkOld == NULL || Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkOld) ); assert( pNtkOld == NULL || Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkOld) );
assert( pNtkOld == NULL || Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkOld) ); assert( pNtkOld == NULL || Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkOld) );
if ( pNtk->pManTime == NULL ) if ( pNtk->pManTime == NULL )
return; return;
Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 ); Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 );
...@@ -314,7 +314,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld ) ...@@ -314,7 +314,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
} }
// set the default timing // set the default timing
ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachCi( pNtk, pObj, i )
{ {
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != -ABC_INFINITY ) if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != -ABC_INFINITY )
...@@ -323,10 +323,10 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld ) ...@@ -323,10 +323,10 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
} }
// set the default timing // set the default timing
ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray; ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray;
Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkForEachCo( pNtk, pObj, i )
{ {
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != -ABC_INFINITY ) if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != ABC_INFINITY )
continue; continue;
*pTime = pNtkOld ? *Abc_NodeReadRequired(Abc_NtkPo(pNtkOld, i)) : pNtk->pManTime->tReqDef; *pTime = pNtkOld ? *Abc_NodeReadRequired(Abc_NtkPo(pNtkOld, i)) : pNtk->pManTime->tReqDef;
} }
...@@ -371,7 +371,7 @@ void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ) ...@@ -371,7 +371,7 @@ void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = -ABC_INFINITY; pTime->Fall = pTime->Rise = -ABC_INFINITY;
} }
Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkForEachCo( pNtk, pObj, i )
{ {
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = -ABC_INFINITY; pTime->Fall = pTime->Rise = -ABC_INFINITY;
...@@ -381,12 +381,12 @@ void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ) ...@@ -381,12 +381,12 @@ void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i ) Abc_NtkForEachNode( pNtk, pObj, i )
{ {
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = -ABC_INFINITY; pTime->Fall = pTime->Rise = ABC_INFINITY;
} }
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachCi( pNtk, pObj, i )
{ {
pTime = ppTimes[pObj->Id]; pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = -ABC_INFINITY; pTime->Fall = pTime->Rise = ABC_INFINITY;
} }
} }
...@@ -411,6 +411,8 @@ Abc_ManTime_t * Abc_ManTimeStart() ...@@ -411,6 +411,8 @@ Abc_ManTime_t * Abc_ManTimeStart()
memset( p, 0, sizeof(Abc_ManTime_t) ); memset( p, 0, sizeof(Abc_ManTime_t) );
p->vArrs = Vec_PtrAlloc( 0 ); p->vArrs = Vec_PtrAlloc( 0 );
p->vReqs = Vec_PtrAlloc( 0 ); p->vReqs = Vec_PtrAlloc( 0 );
p->tReqDef.Rise = ABC_INFINITY;
p->tReqDef.Fall = ABC_INFINITY;
return p; return p;
} }
...@@ -540,8 +542,8 @@ void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ) ...@@ -540,8 +542,8 @@ void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
for ( i = nSizeOld; i < nSizeNew; i++ ) for ( i = nSizeOld; i < nSizeNew; i++ )
{ {
pTime = (Abc_Time_t *)vTimes->pArray[i]; pTime = (Abc_Time_t *)vTimes->pArray[i];
pTime->Rise = -ABC_INFINITY; pTime->Rise = ABC_INFINITY;
pTime->Fall = -ABC_INFINITY; pTime->Fall = ABC_INFINITY;
} }
} }
...@@ -571,7 +573,7 @@ void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld ) ...@@ -571,7 +573,7 @@ void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
if ( Abc_FrameReadLibGen() == NULL || Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen()) == NULL ) if ( Abc_FrameReadLibGen() == NULL || Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen()) == NULL )
return; return;
tAndDelay = Mio_LibraryReadDelayNand2Max((Mio_Library_t *)Abc_FrameReadLibGen()); tAndDelay = Mio_LibraryReadDelayNand2Max((Mio_Library_t *)Abc_FrameReadLibGen());
Abc_NtkForEachPi( pNtkOld, pNodeOld, i ) Abc_NtkForEachCi( pNtkOld, pNodeOld, i )
{ {
pNodeNew = pNodeOld->pCopy; pNodeNew = pNodeOld->pCopy;
pNodeNew->Level = (int)(Abc_NodeReadArrivalWorst(pNodeOld) / tAndDelay); pNodeNew->Level = (int)(Abc_NodeReadArrivalWorst(pNodeOld) / tAndDelay);
...@@ -598,7 +600,7 @@ Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk ) ...@@ -598,7 +600,7 @@ Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk )
if ( pNtk->pManTime == NULL ) if ( pNtk->pManTime == NULL )
return p; return p;
// set the PI arrival times // set the PI arrival times
Abc_NtkForEachPi( pNtk, pNode, i ) Abc_NtkForEachCi( pNtk, pNode, i )
p[i] = *Abc_NodeArrival(pNode); p[i] = *Abc_NodeArrival(pNode);
return p; return p;
} }
...@@ -611,7 +613,7 @@ Abc_Time_t * Abc_NtkGetCoRequiredTimes( Abc_Ntk_t * pNtk ) ...@@ -611,7 +613,7 @@ Abc_Time_t * Abc_NtkGetCoRequiredTimes( Abc_Ntk_t * pNtk )
if ( pNtk->pManTime == NULL ) if ( pNtk->pManTime == NULL )
return p; return p;
// set the PO required times // set the PO required times
Abc_NtkForEachPo( pNtk, pNode, i ) Abc_NtkForEachCo( pNtk, pNode, i )
p[i] = *Abc_NodeRequired(pNode); p[i] = *Abc_NodeRequired(pNode);
return p; return p;
} }
...@@ -636,8 +638,13 @@ float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk ) ...@@ -636,8 +638,13 @@ float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
p = ABC_CALLOC( float, Abc_NtkCiNum(pNtk) ); p = ABC_CALLOC( float, Abc_NtkCiNum(pNtk) );
if ( pNtk->pManTime == NULL ) if ( pNtk->pManTime == NULL )
return p; return p;
Abc_NtkForEachCi( pNtk, pNode, i )
if ( Abc_NodeReadArrivalWorst(pNode) != 0 )
break;
if ( i == Abc_NtkCiNum(pNtk) )
return NULL;
// set the PI arrival times // set the PI arrival times
Abc_NtkForEachPi( pNtk, pNode, i ) Abc_NtkForEachCi( pNtk, pNode, i )
p[i] = Abc_NodeReadArrivalWorst(pNode); p[i] = Abc_NodeReadArrivalWorst(pNode);
return p; return p;
} }
...@@ -648,9 +655,14 @@ float * Abc_NtkGetCoRequiredFloats( Abc_Ntk_t * pNtk ) ...@@ -648,9 +655,14 @@ float * Abc_NtkGetCoRequiredFloats( Abc_Ntk_t * pNtk )
int i; int i;
if ( pNtk->pManTime == NULL ) if ( pNtk->pManTime == NULL )
return NULL; return NULL;
Abc_NtkForEachCo( pNtk, pNode, i )
if ( Abc_NodeReadRequiredWorst(pNode) != ABC_INFINITY )
break;
if ( i == Abc_NtkCoNum(pNtk) )
return NULL;
// set the PO required times // set the PO required times
p = ABC_CALLOC( float, Abc_NtkCoNum(pNtk) ); p = ABC_CALLOC( float, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pNode, i ) Abc_NtkForEachCo( pNtk, pNode, i )
p[i] = Abc_NodeReadRequiredWorst(pNode); p[i] = Abc_NodeReadRequiredWorst(pNode);
return p; return p;
} }
......
...@@ -703,7 +703,7 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk ) ...@@ -703,7 +703,7 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
} }
pTimeDef = Abc_NtkReadDefaultRequired( pNtk ); pTimeDef = Abc_NtkReadDefaultRequired( pNtk );
if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 ) if ( pTimeDef->Rise != ABC_INFINITY || pTimeDef->Fall != ABC_INFINITY )
fprintf( pFile, ".default_output_required %g %g\n", pTimeDef->Rise, pTimeDef->Fall ); fprintf( pFile, ".default_output_required %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
Abc_NtkForEachPo( pNtk, pNode, i ) Abc_NtkForEachPo( pNtk, pNode, i )
{ {
......
...@@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START ...@@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START
static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrint ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandPrintScl( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv ); static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv );
...@@ -60,7 +60,8 @@ void Scl_Init( Abc_Frame_t * pAbc ) ...@@ -60,7 +60,8 @@ void Scl_Init( Abc_Frame_t * pAbc )
{ {
Cmd_CommandAdd( pAbc, "SCL mapping", "read_scl", Scl_CommandRead, 0 ); 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", "write_scl", Scl_CommandWrite, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "print_scl", Scl_CommandPrint, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_scl", Scl_CommandPrintScl, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "dump_genlib", Scl_CommandDumpGen, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "print_gs", Scl_CommandPrintGS, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_gs", Scl_CommandPrintGS, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 );
...@@ -69,7 +70,6 @@ void Scl_Init( Abc_Frame_t * pAbc ) ...@@ -69,7 +70,6 @@ void Scl_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "dnsize", Scl_CommandDnsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "dnsize", Scl_CommandDnsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "print_buf", Scl_CommandPrintBuf, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_buf", Scl_CommandPrintBuf, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "dump_genlib", Scl_CommandDumpGen, 0 );
} }
void Scl_End( Abc_Frame_t * pAbc ) void Scl_End( Abc_Frame_t * pAbc )
{ {
...@@ -203,15 +203,38 @@ usage: ...@@ -203,15 +203,38 @@ usage:
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandPrintScl( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
float Slew = 200;
float Gain = 100;
int c; int c;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "SGh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a floating point number.\n" );
goto usage;
}
Slew = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Slew <= 0.0 )
goto usage;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a floating point number.\n" );
goto usage;
}
Gain = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Gain <= 0.0 )
goto usage;
break;
case 'h': case 'h':
goto usage; goto usage;
default: default:
...@@ -225,12 +248,14 @@ int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -225,12 +248,14 @@ int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv )
} }
// save current library // save current library
Abc_SclPrintCells( (SC_Lib *)pAbc->pLibScl ); Abc_SclPrintCells( (SC_Lib *)pAbc->pLibScl, Slew, Gain );
return 0; return 0;
usage: usage:
fprintf( pAbc->Err, "usage: print_scl [-h]\n" ); fprintf( pAbc->Err, "usage: print_scl [-SG float] [-h]\n" );
fprintf( pAbc->Err, "\t prints statistics of Liberty library\n" ); fprintf( pAbc->Err, "\t prints statistics of Liberty library\n" );
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" );
return 1; return 1;
} }
...@@ -246,6 +271,93 @@ usage: ...@@ -246,6 +271,93 @@ usage:
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Scl_CommandDumpGen( Abc_Frame_t * pAbc, int argc, char **argv )
{
char * pFileName = NULL;
float Slew = 100;
float Gain = 2;
int nGatesMin = 4;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "SGMvh" ) ) != EOF )
{
switch ( c )
{
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a floating point number.\n" );
goto usage;
}
Slew = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Slew <= 0.0 )
goto usage;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a floating point number.\n" );
goto usage;
}
Gain = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Gain <= 0.0 )
goto usage;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by a positive integer.\n" );
goto usage;
}
nGatesMin = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nGatesMin < 0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pLibScl == NULL )
{
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
goto usage;
}
if ( argc == globalUtilOptind + 1 )
pFileName = argv[globalUtilOptind];
Abc_SclDumpGenlib( pFileName, (SC_Lib *)pAbc->pLibScl, Slew, Gain, nGatesMin );
return 0;
usage:
fprintf( pAbc->Err, "usage: dump_genlib [-SG float] [-M num] [-vh] <file>\n" );
fprintf( pAbc->Err, "\t writes GENLIB file for SCL library\n" );
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
fprintf( pAbc->Err, "\t-M num : skip gate classes whose size is less than this [default = %d]\n", nGatesMin );
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the command usage\n");
fprintf( pAbc->Err, "\t<file> : optional GENLIB file name\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Scl_CommandPrintGS( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandPrintGS( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
int c; int c;
...@@ -304,11 +416,11 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -304,11 +416,11 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
int c; int c;
int fShowAll = 0; int fShowAll = 0;
int fUseWireLoads = 1; int fUseWireLoads = 1;
int fShort = 1; int fPrintPath = 0;
int fDumpStats = 0; int fDumpStats = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "casdh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "capdh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -318,8 +430,8 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -318,8 +430,8 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
case 'a': case 'a':
fShowAll ^= 1; fShowAll ^= 1;
break; break;
case 's': case 'p':
fShort ^= 1; fPrintPath ^= 1;
break; break;
case 'd': case 'd':
fDumpStats ^= 1; fDumpStats ^= 1;
...@@ -352,15 +464,15 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -352,15 +464,15 @@ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv )
return 1; return 1;
} }
Abc_SclTimePerform( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), fUseWireLoads, fShowAll, fShort, fDumpStats ); Abc_SclTimePerform( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), fUseWireLoads, fShowAll, fPrintPath, fDumpStats );
return 0; return 0;
usage: usage:
fprintf( pAbc->Err, "usage: stime [-casdh]\n" ); fprintf( pAbc->Err, "usage: stime [-capdh]\n" );
fprintf( pAbc->Err, "\t performs STA using Liberty library\n" ); fprintf( pAbc->Err, "\t performs STA using Liberty library\n" );
fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" ); fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" );
fprintf( pAbc->Err, "\t-a : display timing information for all nodes [default = %s]\n", fShowAll? "yes": "no" ); fprintf( pAbc->Err, "\t-a : display timing information for all nodes [default = %s]\n", fShowAll? "yes": "no" );
fprintf( pAbc->Err, "\t-s : display timing information for critical path [default = %s]\n", fShort? "yes": "no" ); fprintf( pAbc->Err, "\t-p : display timing information for critical path [default = %s]\n", fPrintPath? "yes": "no" );
fprintf( pAbc->Err, "\t-d : toggle dumping statistics into a file [default = %s]\n", fDumpStats? "yes": "no" ); fprintf( pAbc->Err, "\t-d : toggle dumping statistics into a file [default = %s]\n", fDumpStats? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" );
return 1; return 1;
...@@ -442,12 +554,13 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -442,12 +554,13 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Ntk_t * pNtkRes; Abc_Ntk_t * pNtkRes;
int Degree; int Degree, fUseInvs;
int c, fVerbose; int c, fVerbose;
Degree = 4; Degree = 4;
fUseInvs = 0;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Nivh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -462,6 +575,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -462,6 +575,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Degree < 0 ) if ( Degree < 0 )
goto usage; goto usage;
break; break;
case 'i':
fUseInvs ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
break; break;
...@@ -484,7 +600,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -484,7 +600,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
// modify the current network // modify the current network
pNtkRes = Abc_SclPerformBuffering( pNtk, Degree, fVerbose ); pNtkRes = Abc_SclPerformBuffering( pNtk, Degree, fUseInvs, fVerbose );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
Abc_Print( -1, "The command has failed.\n" ); Abc_Print( -1, "The command has failed.\n" );
...@@ -495,9 +611,10 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -495,9 +611,10 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pAbc->Err, "usage: buffer [-N num] [-vh]\n" ); fprintf( pAbc->Err, "usage: buffer [-N num] [-ivh]\n" );
fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" ); fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" );
fprintf( pAbc->Err, "\t-N <num> : the max allowed fanout count of node/buffer [default = %d]\n", Degree ); fprintf( pAbc->Err, "\t-N <num> : the max allowed fanout count of node/buffer [default = %d]\n", Degree );
fprintf( pAbc->Err, "\t-i : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" );
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the command usage\n"); fprintf( pAbc->Err, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -979,80 +1096,6 @@ usage: ...@@ -979,80 +1096,6 @@ usage:
return 1; return 1;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Scl_CommandDumpGen( Abc_Frame_t * pAbc, int argc, char **argv )
{
char * pFileName;
float Slew = 100;
float Gain = 2;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "SGvh" ) ) != EOF )
{
switch ( c )
{
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a floating point number.\n" );
goto usage;
}
Slew = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Slew <= 0.0 )
goto usage;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a floating point number.\n" );
goto usage;
}
Gain = (float)atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Gain <= 0.0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pLibScl == NULL )
{
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
goto usage;
}
if ( argc != globalUtilOptind + 1 )
goto usage;
pFileName = argv[globalUtilOptind];
Abc_SclDumpGenlib( pFileName, (SC_Lib *)pAbc->pLibScl, Slew, Gain );
return 0;
usage:
fprintf( pAbc->Err, "usage: dump_genlib [-SG float] [-vh]\n" );
fprintf( pAbc->Err, "\t writes GENLIB file for SCL library\n" );
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
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;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -127,7 +127,7 @@ int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj ) ...@@ -127,7 +127,7 @@ int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj )
Level = Abc_MaxInt( Level, pFanout->Level ); Level = Abc_MaxInt( Level, pFanout->Level );
return Level + 1; return Level + 1;
} }
Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbose ) Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose )
{ {
Vec_Ptr_t * vFanouts; Vec_Ptr_t * vFanouts;
Abc_Obj_t * pBuffer, * pFanout; Abc_Obj_t * pBuffer, * pFanout;
...@@ -138,6 +138,9 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbo ...@@ -138,6 +138,9 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbo
Abc_NodeCollectFanouts( pObj, vFanouts ); Abc_NodeCollectFanouts( pObj, vFanouts );
Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels ); Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels );
// select the first Degree fanouts // select the first Degree fanouts
if ( fUseInvs )
pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL );
else
pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL ); pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL );
// check if it is possible to not increase level // check if it is possible to not increase level
if ( Vec_PtrSize(vFanouts) < 2 * Degree ) if ( Vec_PtrSize(vFanouts) < 2 * Degree )
...@@ -176,7 +179,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbo ...@@ -176,7 +179,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbo
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
return pBuffer; return pBuffer;
} }
void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose ) void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose )
{ {
Abc_Obj_t * pFanout; Abc_Obj_t * pFanout;
int i; int i;
...@@ -189,20 +192,22 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose ) ...@@ -189,20 +192,22 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose )
assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) ); assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
// buffer fanouts and collect reverse levels // buffer fanouts and collect reverse levels
Abc_ObjForEachFanout( pObj, pFanout, i ) Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_SclPerformBuffering_rec( pFanout, Degree, fVerbose ); Abc_SclPerformBuffering_rec( pFanout, Degree, fUseInvs, fVerbose );
// perform buffering as long as needed // perform buffering as long as needed
while ( Abc_ObjFanoutNum(pObj) > Degree ) while ( Abc_ObjFanoutNum(pObj) > Degree )
Abc_SclPerformBufferingOne( pObj, Degree, fVerbose ); Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose );
// compute the new level of the node // compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj ); pObj->Level = Abc_SclComputeReverseLevel( pObj );
} }
Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ) Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose )
{ {
Vec_Int_t * vCiLevs; Vec_Int_t * vCiLevs;
Abc_Ntk_t * pNew; Abc_Ntk_t * pNew;
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i; int i;
assert( Abc_NtkHasMapping(p) ); assert( Abc_NtkHasMapping(p) );
if ( fUseInvs )
printf( "Warning!!! Using inverters instead of buffers.\n" );
// remember CI levels // remember CI levels
vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) );
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
...@@ -210,7 +215,7 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ) ...@@ -210,7 +215,7 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose )
// perform buffering // perform buffering
Abc_NtkIncrementTravId( p ); Abc_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
Abc_SclPerformBuffering_rec( pObj, Degree, fVerbose ); Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose );
// recompute logic levels // recompute logic levels
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
pObj->Level = Vec_IntEntry( vCiLevs, i ); pObj->Level = Vec_IntEntry( vCiLevs, i );
......
...@@ -713,6 +713,14 @@ int Abc_SclCellFind( SC_Lib * p, char * pName ) ...@@ -713,6 +713,14 @@ int Abc_SclCellFind( SC_Lib * p, char * pName )
{ {
return *Abc_SclHashLookup( p, pName ); return *Abc_SclHashLookup( p, pName );
} }
int Abc_SclClassCellNum( SC_Cell * pClass )
{
SC_Cell * pCell;
int i, Count = 0;
SC_RingForEachCell( pClass, pCell, i )
Count++;
return Count;
}
/**Function************************************************************* /**Function*************************************************************
...@@ -854,7 +862,7 @@ SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area ) ...@@ -854,7 +862,7 @@ SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pLD, float * pPD ) void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pED, float * pPD )
{ {
SC_Timings * pRTime; SC_Timings * pRTime;
SC_Timing * pTime = NULL; SC_Timing * pTime = NULL;
...@@ -887,59 +895,59 @@ void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float S ...@@ -887,59 +895,59 @@ void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float S
ArrOut1.rise = 0.5 * (ArrOut1.rise + ArrOut1.fall); ArrOut1.rise = 0.5 * (ArrOut1.rise + ArrOut1.fall);
ArrOut2.rise = 0.5 * (ArrOut2.rise + ArrOut2.fall); ArrOut2.rise = 0.5 * (ArrOut2.rise + ArrOut2.fall);
// get tangent // get tangent
*pLD = (ArrOut2.rise - ArrOut1.rise) / ((Load2.rise - Load1.rise) / SC_CellPinCap(pCell, iPin)); *pED = (ArrOut2.rise - ArrOut1.rise) / ((Load2.rise - Load1.rise) / SC_CellPinCap(pCell, iPin));
// get constant // get constant
*pPD = ArrOut0.rise; *pPD = ArrOut0.rise;
} }
void Abc_SclComputeParametersCell( SC_Lib * p, SC_Cell * pCell, float Slew, float * pLD, float * pPD ) void Abc_SclComputeParametersCell( SC_Lib * p, SC_Cell * pCell, float Slew, float * pED, float * pPD )
{ {
SC_Pin * pPin; SC_Pin * pPin;
float LD, PD, ld, pd; float ED, PD, ed, pd;
int i; int i;
LD = PD = ld = pd = 0; ED = PD = ed = pd = 0;
SC_CellForEachPinIn( pCell, pPin, i ) SC_CellForEachPinIn( pCell, pPin, i )
{ {
Abc_SclComputeParametersPin( p, pCell, i, Slew, &ld, &pd ); Abc_SclComputeParametersPin( p, pCell, i, Slew, &ed, &pd );
LD += ld; PD += pd; ED += ed; PD += pd;
} }
*pLD = LD / pCell->n_inputs; *pED = ED / pCell->n_inputs;
*pPD = PD / pCell->n_inputs; *pPD = PD / pCell->n_inputs;
} }
void Abc_SclComputeParametersClass( SC_Lib * p, SC_Cell * pRepr, float Slew, float * pLD, float * pPD ) void Abc_SclComputeParametersClass( SC_Lib * p, SC_Cell * pRepr, float Slew, float * pED, float * pPD )
{ {
SC_Cell * pCell; SC_Cell * pCell;
float LD, PD, ld, pd; float ED, PD, ed, pd;
int i, Count = 0; int i, Count = 0;
LD = PD = ld = pd = 0; ED = PD = ed = pd = 0;
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
{ {
Abc_SclComputeParametersCell( p, pCell, Slew, &ld, &pd ); Abc_SclComputeParametersCell( p, pCell, Slew, &ed, &pd );
LD += ld; PD += pd; ED += ed; PD += pd;
Count++; Count++;
} }
*pLD = LD / Count; *pED = ED / Count;
*pPD = PD / Count; *pPD = PD / Count;
} }
void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float * pLD, float * pPD ) void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float * pED, float * pPD )
{ {
SC_Cell * pCell; SC_Cell * pCell;
float LD, PD, ld, pd; float ED, PD, ed, pd;
int i, Count = 0; int i, Count = 0;
LD = PD = ld = pd = 0; ED = PD = ed = pd = 0;
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
{ {
Abc_SclComputeParametersPin( p, pCell, Slew, iPin, &ld, &pd ); Abc_SclComputeParametersPin( p, pCell, Slew, iPin, &ed, &pd );
LD += ld; PD += pd; ED += ed; PD += pd;
Count++; Count++;
} }
*pLD = LD / Count; *pED = ED / Count;
*pPD = PD / Count; *pPD = PD / Count;
} }
float Abc_SclComputeDelayCellPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float Gain ) float Abc_SclComputeDelayCellPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float Gain )
{ {
float LD = 0, PD = 0; float ED = 0, PD = 0;
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &LD, &PD ); Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ED, &PD );
return LD * Gain + PD; return 0.01 * ED * Gain + PD;
} }
float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float Gain ) float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float Slew, float Gain )
{ {
...@@ -947,11 +955,14 @@ float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float ...@@ -947,11 +955,14 @@ float Abc_SclComputeDelayClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, float
float Delay = 0; float Delay = 0;
int i, Count = 0; int i, Count = 0;
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
Count++;
SC_RingForEachCell( pRepr, pCell, i )
{ {
if ( pRepr == pCell && Count > 1 ) // skip the first gate
continue;
Delay += Abc_SclComputeDelayCellPin( p, pCell, iPin, Slew, Gain ); Delay += Abc_SclComputeDelayCellPin( p, pCell, iPin, Slew, Gain );
Count++;
} }
return Delay / Count; return Delay / Abc_MaxInt(1, Count-1);
} }
float Abc_SclComputeAreaClass( SC_Cell * pRepr ) float Abc_SclComputeAreaClass( SC_Cell * pRepr )
{ {
...@@ -977,16 +988,16 @@ float Abc_SclComputeAreaClass( SC_Cell * pRepr ) ...@@ -977,16 +988,16 @@ float Abc_SclComputeAreaClass( SC_Cell * pRepr )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclPrintCells( SC_Lib * p ) void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )
{ {
SC_Cell * pCell, * pRepr; SC_Cell * pCell, * pRepr;
int i, k, nLength = 0; int i, k, nLength = 0;
float LD = 0, PD = 0; float ED = 0, PD = 0;
float SlewDef = 100;
assert( Vec_PtrSize(p->vCellClasses) > 0 ); assert( Vec_PtrSize(p->vCellClasses) > 0 );
printf( "Library \"%s\" ", p->pName ); printf( "Library \"%s\" ", p->pName );
printf( "containing %d cells in %d classes.\n", printf( "has %d cells in %d classes. ",
Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellClasses) ); Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellClasses) );
printf( "Delay estimate is based on slew %.2f and gain %.2f.\n", Slew, Gain );
// find the longest name // find the longest name
SC_LibForEachCellClass( p, pRepr, k ) SC_LibForEachCellClass( p, pRepr, k )
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
...@@ -1005,14 +1016,18 @@ void Abc_SclPrintCells( SC_Lib * p ) ...@@ -1005,14 +1016,18 @@ void Abc_SclPrintCells( SC_Lib * p )
printf( "\n" ); printf( "\n" );
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
{ {
Abc_SclComputeParametersCell( p, pCell, SlewDef, &LD, &PD ); Abc_SclComputeParametersCell( p, pCell, Slew, &ED, &PD );
printf( " %3d : ", i+1 ); printf( " %3d : ", i+1 );
printf( "%-*s ", nLength, pCell->pName ); printf( "%-*s ", nLength, pCell->pName );
printf( "%2d ", pCell->drive_strength ); printf( "%2d ", pCell->drive_strength );
printf( "A =%8.2f ", pCell->area ); printf( "A =%8.2f ", pCell->area );
printf( "C =%6.2f ff ", Abc_SclGatePinCapAve(p, pCell) ); printf( "D =%6.0f ps ", 0.01 * ED * Gain + PD );
printf( "LD =%8.2f ps ", LD ); printf( "ED =%6.0f ps ", ED );
printf( "PD =%8.2f ps", PD ); printf( "PD =%6.0f ps ", PD );
printf( "C =%5.1f ff ", Abc_SclGatePinCapAve(p, pCell) );
printf( "Lm =%5.1f ff ", 0.01 * Gain * Abc_SclGatePinCapAve(p, pCell) );
// printf( "MaxS =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );
printf( "Lm2 =%5.0f ff", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );
printf( "\n" ); printf( "\n" );
} }
} }
...@@ -1029,21 +1044,23 @@ void Abc_SclPrintCells( SC_Lib * p ) ...@@ -1029,21 +1044,23 @@ void Abc_SclPrintCells( SC_Lib * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Str_t * Abc_SclDeriveGenlib( SC_Lib * p, float Slew, float Gain ) Vec_Str_t * Abc_SclDeriveGenlib( SC_Lib * p, float Slew, float Gain, int nGatesMin, int * pnCellCount )
{ {
extern char * Abc_SclFindGateFormula( char * pGateName, char * pOutName ); extern char * Abc_SclFindGateFormula( char * pGateName, char * pOutName );
char Buffer[200]; char Buffer[200];
Vec_Str_t * vStr; Vec_Str_t * vStr;
SC_Cell * pRepr; SC_Cell * pRepr;
SC_Pin * pPin; SC_Pin * pPin;
int i, k, Count = 0; int i, k, Count = 2;
vStr = Vec_StrAlloc( 1000 ); vStr = Vec_StrAlloc( 1000 );
Vec_StrPrintStr( vStr, "GATE _const0_ 0.000000 z=CONST0;\n" ); Vec_StrPrintStr( vStr, "GATE _const0_ 0.00 z=CONST0;\n" );
Vec_StrPrintStr( vStr, "GATE _const1_ 0.000000 z=CONST1;\n" ); Vec_StrPrintStr( vStr, "GATE _const1_ 0.00 z=CONST1;\n" );
SC_LibForEachCellClass( p, pRepr, i ) SC_LibForEachCellClass( p, pRepr, i )
{ {
if ( pRepr->n_outputs > 1 ) if ( pRepr->n_outputs > 1 )
continue; continue;
if ( Abc_SclClassCellNum(pRepr) < nGatesMin )
continue;
assert( strlen(pRepr->pName) < 200 ); assert( strlen(pRepr->pName) < 200 );
Vec_StrPrintStr( vStr, "GATE " ); Vec_StrPrintStr( vStr, "GATE " );
sprintf( Buffer, "%-16s", pRepr->pName ); sprintf( Buffer, "%-16s", pRepr->pName );
...@@ -1071,22 +1088,31 @@ Vec_Str_t * Abc_SclDeriveGenlib( SC_Lib * p, float Slew, float Gain ) ...@@ -1071,22 +1088,31 @@ Vec_Str_t * Abc_SclDeriveGenlib( SC_Lib * p, float Slew, float Gain )
Vec_StrPrintStr( vStr, "\n.end\n" ); Vec_StrPrintStr( vStr, "\n.end\n" );
Vec_StrPush( vStr, '\0' ); Vec_StrPush( vStr, '\0' );
// printf( "%s", Vec_StrArray(vStr) ); // printf( "%s", Vec_StrArray(vStr) );
printf( "GENLIB library with %d gates is produced.\n", Count ); // printf( "GENLIB library with %d gates is produced.\n", Count );
*pnCellCount = Count;
return vStr; return vStr;
} }
void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain ) void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin )
{ {
char FileName[1000];
int nCellCount = 0;
Vec_Str_t * vStr; Vec_Str_t * vStr;
FILE * pFile = fopen( pFileName, "wb" ); FILE * pFile;
if ( pFileName == NULL )
sprintf( FileName, "%s_s%03d_g%03d_m%d.genlib", p->pName, (int)Slew, (int)Gain, nGatesMin, &nCellCount );
else
sprintf( FileName, "%s", pFileName );
pFile = fopen( FileName, "wb" );
if ( pFile == NULL ) if ( pFile == NULL )
{ {
printf( "Cannot open file \"%s\" for writing.\n", pFileName ); printf( "Cannot open file \"%s\" for writing.\n", FileName );
return; return;
} }
vStr = Abc_SclDeriveGenlib( p, Slew, Gain ); vStr = Abc_SclDeriveGenlib( p, Slew, Gain, nGatesMin, &nCellCount );
fprintf( pFile, "%s", Vec_StrArray(vStr) ); fprintf( pFile, "%s", Vec_StrArray(vStr) );
Vec_StrFree( vStr ); Vec_StrFree( vStr );
fclose( pFile ); fclose( pFile );
printf( "Written GENLIB library with %d gates into file \"%s\".\n", nCellCount, FileName );
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -544,10 +544,11 @@ extern void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl ); ...@@ -544,10 +544,11 @@ extern void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl );
extern void Abc_SclSave( char * pFileName, SC_Lib * pScl ); extern void Abc_SclSave( char * pFileName, SC_Lib * pScl );
extern void Abc_SclHashCells( SC_Lib * p ); extern void Abc_SclHashCells( SC_Lib * p );
extern int Abc_SclCellFind( SC_Lib * p, char * pName ); extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern int Abc_SclClassCellNum( SC_Cell * pClass );
extern void Abc_SclLinkCells( SC_Lib * p ); extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( SC_Lib * p ); extern void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain );
extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area ); extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
extern void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain ); extern void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
ABC_NAMESPACE_HEADER_END ABC_NAMESPACE_HEADER_END
......
...@@ -112,19 +112,19 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise ...@@ -112,19 +112,19 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise
printf( "%d ", Abc_ObjFaninNum(pObj) ); printf( "%d ", Abc_ObjFaninNum(pObj) );
printf( "%2d ", Abc_ObjFanoutNum(pObj) ); printf( "%2d ", Abc_ObjFanoutNum(pObj) );
printf( "%-*s ", Length, pCell ? pCell->pName : "pi" ); printf( "%-*s ", Length, pCell ? pCell->pName : "pi" );
if ( fRise >= 0 )
printf( "(%s) ", fRise ? "rise" : "fall" );
printf( "A =%7.2f ", pCell ? pCell->area : 0.0 ); printf( "A =%7.2f ", pCell ? pCell->area : 0.0 );
printf( "D = (" ); printf( "D%s =", fRise ? "r" : "f" );
printf( "%8.2f ps", Abc_SclObjTimePs(p, pObj, 1) ); printf( "%5.0f ", Abc_MaxFloat(Abc_SclObjTimePs(p, pObj, 0), Abc_SclObjTimePs(p, pObj, 1)) );
printf( "%8.2f ps ) ", Abc_SclObjTimePs(p, pObj, 0) ); printf( "%4.0f ps ", -Abc_AbsFloat(Abc_SclObjTimePs(p, pObj, 0) - Abc_SclObjTimePs(p, pObj, 1)) );
printf( "L =%7.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); printf( "S =%5.0f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "G =%5.2f ", pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 ); printf( "Cin =%4.0f ff ", pCell ? Abc_SclGatePinCapAve(p->pLib, pCell) : 0.0 );
printf( "S =%7.2f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); printf( "Cout =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "SL =%6.2f ps", Abc_SclObjSlack(p, pObj) ); printf( "Cmax =%5.0f ff ", pCell ? SC_CellPin(pCell, pCell->n_inputs)->max_out_cap : 0.0 );
printf( "G =%4.1f ", pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 );
printf( "SL =%5.1f ps", Abc_SclObjSlack(p, pObj) );
printf( "\n" ); printf( "\n" );
} }
void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ) void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
{ {
int i, nLength = 0, fRise = 0; int i, nLength = 0, fRise = 0;
Abc_Obj_t * pObj, * pPivot = Abc_SclFindCriticalCo( p, &fRise ); Abc_Obj_t * pObj, * pPivot = Abc_SclFindCriticalCo( p, &fRise );
...@@ -134,7 +134,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ) ...@@ -134,7 +134,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort )
printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) ); printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) );
printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) ); printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) );
printf( "Critical delay = %8.2f ps\n", maxDelay ); printf( "Critical delay = %8.2f ps\n", maxDelay );
if ( fShort ) if ( !fPrintPath )
return; return;
if ( fShowAll ) if ( fShowAll )
...@@ -165,7 +165,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ) ...@@ -165,7 +165,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort )
pObj = Abc_ObjFanin0(pPivot); pObj = Abc_ObjFanin0(pPivot);
while ( pObj )//&& Abc_ObjIsNode(pObj) ) while ( pObj )//&& Abc_ObjIsNode(pObj) )
{ {
printf( "C-path %3d -- ", i-- ); printf( "Path%3d -- ", i-- );
Abc_SclTimeNodePrint( p, pObj, fRise, nLength, maxDelay ); Abc_SclTimeNodePrint( p, pObj, fRise, nLength, maxDelay );
pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );
} }
...@@ -380,11 +380,11 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, in ...@@ -380,11 +380,11 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, in
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fShort, int fDumpStats ) void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fPrintPath, int fDumpStats )
{ {
SC_Man * p; SC_Man * p;
p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 1, 0 ); p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 1, 0 );
Abc_SclTimeNtkPrint( p, fShowAll, fShort ); Abc_SclTimeNtkPrint( p, fShowAll, fPrintPath );
if ( fDumpStats ) if ( fDumpStats )
Abc_SclDumpStats( p, "stats.txt", 0 ); Abc_SclDumpStats( p, "stats.txt", 0 );
Abc_SclManFree( p ); Abc_SclManFree( p );
......
...@@ -373,7 +373,7 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time ...@@ -373,7 +373,7 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
/*=== sclBuff.c ===============================================================*/ /*=== sclBuff.c ===============================================================*/
extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose );
extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ); extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose );
/*=== sclDnsize.c ===============================================================*/ /*=== sclDnsize.c ===============================================================*/
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclLoad.c ===============================================================*/ /*=== sclLoad.c ===============================================================*/
...@@ -382,11 +382,11 @@ extern void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * ...@@ -382,11 +382,11 @@ extern void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell *
/*=== sclSize.c ===============================================================*/ /*=== sclSize.c ===============================================================*/
extern Abc_Obj_t * Abc_SclFindCriticalCo( SC_Man * p, int * pfRise ); extern Abc_Obj_t * Abc_SclFindCriticalCo( SC_Man * p, int * pfRise );
extern Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode ); extern Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode );
extern void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ); extern void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath );
extern SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fDept, float DUser ); extern SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fDept, float DUser );
extern void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ); extern void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone );
extern void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fReverse, float DUser ); extern void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fReverse, float DUser );
extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fShort, int fDumpStats ); extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fPrintPath, int fDumpStats );
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ); extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
/*=== sclUpsize.c ===============================================================*/ /*=== sclUpsize.c ===============================================================*/
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
......
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