Commit ab84c73e by Alan Mishchenko

Adding support for input slew (.input_drive) and output capacitance…

Adding support for input slew (.input_drive) and output capacitance (.output_load) in BLIF reader/writer.
parent f917de34
...@@ -124,7 +124,6 @@ struct Abc_Time_t_ ...@@ -124,7 +124,6 @@ struct Abc_Time_t_
{ {
float Rise; float Rise;
float Fall; float Fall;
float Worst;
}; };
struct Abc_Obj_t_ // 48/72 bytes (32-bits/64-bits) struct Abc_Obj_t_ // 48/72 bytes (32-bits/64-bits)
...@@ -899,16 +898,28 @@ extern ABC_DLL int Abc_NtkCleanupNodes( Abc_Ntk_t * pNtk, Vec_Ptr ...@@ -899,16 +898,28 @@ extern ABC_DLL int Abc_NtkCleanupNodes( Abc_Ntk_t * pNtk, Vec_Ptr
extern ABC_DLL int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose ); extern ABC_DLL int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose );
extern ABC_DLL int Abc_NtkSweepBufsInvs( Abc_Ntk_t * pNtk, int fVerbose ); extern ABC_DLL int Abc_NtkSweepBufsInvs( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcTiming.c ==========================================================*/ /*=== abcTiming.c ==========================================================*/
extern ABC_DLL Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
extern ABC_DLL Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
extern ABC_DLL Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
extern ABC_DLL float Abc_NodeReadArrivalAve( Abc_Obj_t * pNode ); extern ABC_DLL float Abc_NodeReadArrivalAve( Abc_Obj_t * pNode );
extern ABC_DLL float Abc_NodeReadRequiredAve( Abc_Obj_t * pNode ); extern ABC_DLL float Abc_NodeReadRequiredAve( Abc_Obj_t * pNode );
extern ABC_DLL float Abc_NodeReadArrivalWorst( Abc_Obj_t * pNode );
extern ABC_DLL float Abc_NodeReadRequiredWorst( Abc_Obj_t * pNode );
extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultInputDrive( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Time_t * Abc_NtkReadDefaultOutputLoad( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Time_t * Abc_NodeReadInputDrive( Abc_Ntk_t * pNtk, int iPi );
extern ABC_DLL Abc_Time_t * Abc_NodeReadOutputLoad( Abc_Ntk_t * pNtk, int iPo );
extern ABC_DLL float Abc_NodeReadInputDriveWorst( Abc_Ntk_t * pNtk, int iPi );
extern ABC_DLL float Abc_NodeReadOutputLoadWorst( Abc_Ntk_t * pNtk, int iPo );
extern ABC_DLL void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall ); extern ABC_DLL void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall ); extern ABC_DLL void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ); extern ABC_DLL void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ); extern ABC_DLL void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetDefaultInputDrive( Abc_Ntk_t * pNtk, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetDefaultOutputLoad( Abc_Ntk_t * pNtk, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetInputDrive( Abc_Ntk_t * pNtk, int PiNum, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeSetOutputLoad( Abc_Ntk_t * pNtk, int PoNum, float Rise, float Fall );
extern ABC_DLL void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld ); extern ABC_DLL void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld );
extern ABC_DLL void Abc_ManTimeStop( Abc_ManTime_t * p ); extern ABC_DLL void Abc_ManTimeStop( Abc_ManTime_t * p );
extern ABC_DLL void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew ); extern ABC_DLL void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew );
......
...@@ -121,11 +121,13 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) ...@@ -121,11 +121,13 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
case ABC_OBJ_CONST1: case ABC_OBJ_CONST1:
assert(0); assert(0);
break; break;
case ABC_OBJ_PI: case ABC_OBJ_PI:
pObj->iTemp = Vec_PtrSize(pNtk->vCis);
Vec_PtrPush( pNtk->vPis, pObj ); Vec_PtrPush( pNtk->vPis, pObj );
Vec_PtrPush( pNtk->vCis, pObj ); Vec_PtrPush( pNtk->vCis, pObj );
break; break;
case ABC_OBJ_PO: case ABC_OBJ_PO:
pObj->iTemp = Vec_PtrSize(pNtk->vCos);
Vec_PtrPush( pNtk->vPos, pObj ); Vec_PtrPush( pNtk->vPos, pObj );
Vec_PtrPush( pNtk->vCos, pObj ); Vec_PtrPush( pNtk->vCos, pObj );
break; break;
......
...@@ -861,7 +861,7 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListN ...@@ -861,7 +861,7 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListN
DelayInt = 0; DelayInt = 0;
else else
{ {
DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst; DelayCur = Abc_NodeReadArrivalWorst( Abc_ObjFanin0(pNode) );
DelayInt = (int)(DelayCur / DelayDelta); DelayInt = (int)(DelayCur / DelayDelta);
if ( DelayInt >= nIntervals ) if ( DelayInt >= nIntervals )
DelayInt = nIntervals - 1; DelayInt = nIntervals - 1;
......
...@@ -337,8 +337,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs ...@@ -337,8 +337,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
pNodeMin = pListDir; pNodeMin = pListDir;
for ( pNode = pListDir; pNode; pNode = pNode->pNext ) for ( pNode = pListDir; pNode; pNode = pNode->pNext )
{ {
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; Arrival1 = Abc_NodeReadArrivalWorst(pNodeMin);
Arrival2 = Abc_NodeReadArrival(pNode )->Worst; Arrival2 = Abc_NodeReadArrivalWorst(pNode );
// assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); // assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
// assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); // assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 || if ( Arrival1 > Arrival2 ||
...@@ -357,8 +357,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs ...@@ -357,8 +357,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
pNodeMin = pListInv; pNodeMin = pListInv;
for ( pNode = pListInv; pNode; pNode = pNode->pNext ) for ( pNode = pListInv; pNode; pNode = pNode->pNext )
{ {
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; Arrival1 = Abc_NodeReadArrivalWorst(pNodeMin);
Arrival2 = Abc_NodeReadArrival(pNode )->Worst; Arrival2 = Abc_NodeReadArrivalWorst(pNode );
// assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); // assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
// assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); // assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 || if ( Arrival1 > Arrival2 ||
......
...@@ -67,6 +67,10 @@ static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken ...@@ -67,6 +67,10 @@ static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken
static int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster ); static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
...@@ -276,6 +280,14 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) ...@@ -276,6 +280,14 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens ); fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_output_required" ) ) else if ( !strcmp( pDirective, ".default_output_required" ) )
fStatus = Io_ReadBlifNetworkDefaultOutputRequired( p, p->vTokens ); fStatus = Io_ReadBlifNetworkDefaultOutputRequired( p, p->vTokens );
else if ( !strcmp( pDirective, ".input_drive" ) )
fStatus = Io_ReadBlifNetworkInputDrive( p, p->vTokens );
else if ( !strcmp( pDirective, ".output_load" ) )
fStatus = Io_ReadBlifNetworkOutputLoad( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_input_drive" ) )
fStatus = Io_ReadBlifNetworkDefaultInputDrive( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_output_load" ) )
fStatus = Io_ReadBlifNetworkDefaultOutputLoad( p, p->vTokens );
else if ( !strcmp( pDirective, ".and_gate_delay" ) ) else if ( !strcmp( pDirective, ".and_gate_delay" ) )
fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens ); fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens );
// else if ( !strcmp( pDirective, ".subckt" ) ) // else if ( !strcmp( pDirective, ".subckt" ) )
...@@ -977,6 +989,181 @@ int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTok ...@@ -977,6 +989,181 @@ int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTok
return 0; return 0;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Obj_t * pNet;
char * pFoo1, * pFoo2;
double TimeRise, TimeFall;
// make sure this is indeed the .inputs line
assert( strncmp( (char *)vTokens->pArray[0], ".input_drive", 12 ) == 0 );
if ( vTokens->nSize != 4 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Wrong number of arguments on .input_drive line." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
if ( pNet == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Cannot find object corresponding to %s on .input_drive line.", (char*)vTokens->pArray[1] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_drive line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// set the arrival time
Abc_NtkTimeSetInputDrive( p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)->iTemp, (float)TimeRise, (float)TimeFall );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Obj_t * pNet;
char * pFoo1, * pFoo2;
double TimeRise, TimeFall;
// make sure this is indeed the .inputs line
assert( strncmp( (char *)vTokens->pArray[0], ".output_load", 12 ) == 0 );
if ( vTokens->nSize != 4 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Wrong number of arguments on .output_load line." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
if ( pNet == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Cannot find object corresponding to %s on .output_load line.", (char*)vTokens->pArray[1] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .output_load line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// set the arrival time
Abc_NtkTimeSetOutputLoad( p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)->iTemp, (float)TimeRise, (float)TimeFall );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
char * pFoo1, * pFoo2;
double TimeRise, TimeFall;
// make sure this is indeed the .inputs line
assert( strncmp( (char *)vTokens->pArray[0], ".default_input_drive", 21 ) == 0 );
if ( vTokens->nSize != 3 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Wrong number of arguments on .default_input_drive line." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_drive line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// set the arrival time
Abc_NtkTimeSetDefaultInputDrive( p->pNtkCur, (float)TimeRise, (float)TimeFall );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
char * pFoo1, * pFoo2;
double TimeRise, TimeFall;
// make sure this is indeed the .inputs line
assert( strncmp( (char *)vTokens->pArray[0], ".default_output_load", 21 ) == 0 );
if ( vTokens->nSize != 3 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Wrong number of arguments on .default_output_load line." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_output_load line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// set the arrival time
Abc_NtkTimeSetDefaultOutputLoad( p->pNtkCur, (float)TimeRise, (float)TimeFall );
return 0;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis []
......
...@@ -714,6 +714,30 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk ) ...@@ -714,6 +714,30 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
} }
fprintf( pFile, "\n" ); fprintf( pFile, "\n" );
pTimeDef = Abc_NtkReadDefaultInputDrive( pNtk );
if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 )
fprintf( pFile, ".default_input_drive %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
Abc_NtkForEachPi( pNtk, pNode, i )
{
pTime = Abc_NodeReadInputDrive( pNtk, i );
if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall )
continue;
fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
}
pTimeDef = Abc_NtkReadDefaultOutputLoad( pNtk );
if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 )
fprintf( pFile, ".default_output_load %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
Abc_NtkForEachPo( pNtk, pNode, i )
{
pTime = Abc_NodeReadOutputLoad( pNtk, i );
if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall )
continue;
fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
}
fprintf( pFile, "\n" );
} }
......
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