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_
{
float Rise;
float Fall;
float Worst;
};
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
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 );
/*=== 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_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_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_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_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_ManTimeStop( Abc_ManTime_t * p );
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 )
case ABC_OBJ_CONST1:
assert(0);
break;
case ABC_OBJ_PI:
case ABC_OBJ_PI:
pObj->iTemp = Vec_PtrSize(pNtk->vCis);
Vec_PtrPush( pNtk->vPis, pObj );
Vec_PtrPush( pNtk->vCis, pObj );
break;
case ABC_OBJ_PO:
pObj->iTemp = Vec_PtrSize(pNtk->vCos);
Vec_PtrPush( pNtk->vPos, pObj );
Vec_PtrPush( pNtk->vCos, pObj );
break;
......
......@@ -861,7 +861,7 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListN
DelayInt = 0;
else
{
DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst;
DelayCur = Abc_NodeReadArrivalWorst( Abc_ObjFanin0(pNode) );
DelayInt = (int)(DelayCur / DelayDelta);
if ( DelayInt >= nIntervals )
DelayInt = nIntervals - 1;
......
......@@ -337,8 +337,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
pNodeMin = pListDir;
for ( pNode = pListDir; pNode; pNode = pNode->pNext )
{
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
Arrival1 = Abc_NodeReadArrivalWorst(pNodeMin);
Arrival2 = Abc_NodeReadArrivalWorst(pNode );
// assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
// assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 ||
......@@ -357,8 +357,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
pNodeMin = pListInv;
for ( pNode = pListInv; pNode; pNode = pNode->pNext )
{
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
Arrival1 = Abc_NodeReadArrivalWorst(pNodeMin);
Arrival2 = Abc_NodeReadArrivalWorst(pNode );
// assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
// assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 ||
......
......@@ -35,6 +35,10 @@ struct Abc_ManTime_t_
Abc_Time_t tReqDef;
Vec_Ptr_t * vArrs;
Vec_Ptr_t * vReqs;
Abc_Time_t tInDriveDef;
Abc_Time_t tOutLoadDef;
Abc_Time_t * tInDrive;
Abc_Time_t * tOutLoad;
};
// static functions
......@@ -51,7 +55,7 @@ static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return (Abc_
/**Function*************************************************************
Synopsis [Reads the arrival time of the node.]
Synopsis [Reads the arrival.required time of the node.]
Description []
......@@ -60,32 +64,46 @@ static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return (Abc_
SeeAlso []
***********************************************************************/
Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk )
{
assert( pNtk->pManTime );
return &pNtk->pManTime->tArrDef;
}
Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
{
assert( pNtk->pManTime );
return &pNtk->pManTime->tReqDef;
}
Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode )
{
assert( pNode->pNtk->pManTime );
return Abc_NodeArrival(pNode);
}
/**Function*************************************************************
Synopsis [Reads the arrival time of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode )
{
assert( pNode->pNtk->pManTime );
return Abc_NodeRequired(pNode);
}
float Abc_NodeReadArrivalAve( Abc_Obj_t * pNode )
{
return 0.5 * Abc_NodeArrival(pNode)->Rise + 0.5 * Abc_NodeArrival(pNode)->Fall;
}
float Abc_NodeReadRequiredAve( Abc_Obj_t * pNode )
{
return 0.5 * Abc_NodeReadRequired(pNode)->Rise + 0.5 * Abc_NodeReadRequired(pNode)->Fall;
}
float Abc_NodeReadArrivalWorst( Abc_Obj_t * pNode )
{
return Abc_MaxFloat( Abc_NodeArrival(pNode)->Rise, Abc_NodeArrival(pNode)->Fall );
}
float Abc_NodeReadRequiredWorst( Abc_Obj_t * pNode )
{
return Abc_MaxFloat( Abc_NodeReadRequired(pNode)->Rise, Abc_NodeReadRequired(pNode)->Fall );
}
/**Function*************************************************************
Synopsis [Reads the arrival time of the node.]
Synopsis [Reads the input drive / output load of the node.]
Description []
......@@ -94,59 +112,33 @@ Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk )
Abc_Time_t * Abc_NtkReadDefaultInputDrive( Abc_Ntk_t * pNtk )
{
assert( pNtk->pManTime );
return &pNtk->pManTime->tArrDef;
return &pNtk->pManTime->tInDriveDef;
}
/**Function*************************************************************
Synopsis [Reads the arrival time of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
Abc_Time_t * Abc_NtkReadDefaultOutputLoad( Abc_Ntk_t * pNtk )
{
assert( pNtk->pManTime );
return &pNtk->pManTime->tReqDef;
return &pNtk->pManTime->tOutLoadDef;
}
/**Function*************************************************************
Synopsis [Reads average arrival time of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Abc_NodeReadArrivalAve( Abc_Obj_t * pNode )
Abc_Time_t * Abc_NodeReadInputDrive( Abc_Ntk_t * pNtk, int iPi )
{
return 0.5 * Abc_NodeArrival(pNode)->Rise + 0.5 * Abc_NodeArrival(pNode)->Fall;
assert( pNtk->pManTime );
return pNtk->pManTime->tInDrive + iPi;
}
/**Function*************************************************************
Synopsis [Reads average required time of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Abc_NodeReadRequiredAve( Abc_Obj_t * pNode )
Abc_Time_t * Abc_NodeReadOutputLoad( Abc_Ntk_t * pNtk, int iPo )
{
return 0.5 * Abc_NodeReadRequired(pNode)->Rise + 0.5 * Abc_NodeReadRequired(pNode)->Fall;
assert( pNtk->pManTime );
return pNtk->pManTime->tOutLoad + iPo;
}
float Abc_NodeReadInputDriveWorst( Abc_Ntk_t * pNtk, int iPi )
{
return Abc_MaxFloat( Abc_NodeReadInputDrive(pNtk, iPi)->Rise, Abc_NodeReadInputDrive(pNtk, iPi)->Fall );
}
float Abc_NodeReadOutputLoadWorst( Abc_Ntk_t * pNtk, int iPo )
{
return Abc_MaxFloat( Abc_NodeReadOutputLoad(pNtk, iPo)->Rise, Abc_NodeReadOutputLoad(pNtk, iPo)->Fall );
}
/**Function*************************************************************
......@@ -168,20 +160,7 @@ void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall )
pNtk->pManTime = Abc_ManTimeStart();
pNtk->pManTime->tArrDef.Rise = Rise;
pNtk->pManTime->tArrDef.Fall = Fall;
pNtk->pManTime->tArrDef.Worst = Abc_MaxFloat( Rise, Fall );
}
/**Function*************************************************************
Synopsis [Sets the default arrival time for the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
{
if ( Rise == 0.0 && Fall == 0.0 )
......@@ -190,7 +169,6 @@ void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
pNtk->pManTime = Abc_ManTimeStart();
pNtk->pManTime->tReqDef.Rise = Rise;
pNtk->pManTime->tReqDef.Fall = Fall;
pNtk->pManTime->tReqDef.Worst = Abc_MaxFloat( Rise, Fall );
}
/**Function*************************************************************
......@@ -218,7 +196,51 @@ void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall
pTime = (Abc_Time_t *)vTimes->pArray[ObjId];
pTime->Rise = Rise;
pTime->Fall = Fall;
pTime->Worst = Abc_MaxFloat( Rise, Fall );
}
void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
{
Vec_Ptr_t * vTimes;
Abc_Time_t * pTime;
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart();
if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall )
return;
Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
// set the required time
vTimes = pNtk->pManTime->vReqs;
pTime = (Abc_Time_t *)vTimes->pArray[ObjId];
pTime->Rise = Rise;
pTime->Fall = Fall;
}
/**Function*************************************************************
Synopsis [Sets the default arrival time for the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkTimeSetDefaultInputDrive( Abc_Ntk_t * pNtk, float Rise, float Fall )
{
if ( Rise == 0.0 && Fall == 0.0 )
return;
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart();
pNtk->pManTime->tInDriveDef.Rise = Rise;
pNtk->pManTime->tInDriveDef.Fall = Fall;
}
void Abc_NtkTimeSetDefaultOutputLoad( Abc_Ntk_t * pNtk, float Rise, float Fall )
{
if ( Rise == 0.0 && Fall == 0.0 )
return;
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart();
pNtk->pManTime->tOutLoadDef.Rise = Rise;
pNtk->pManTime->tOutLoadDef.Fall = Fall;
}
/**Function*************************************************************
......@@ -232,21 +254,33 @@ void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall
SeeAlso []
***********************************************************************/
void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
void Abc_NtkTimeSetInputDrive( Abc_Ntk_t * pNtk, int PiNum, float Rise, float Fall )
{
Vec_Ptr_t * vTimes;
Abc_Time_t * pTime;
assert( PiNum >= 0 && PiNum < Abc_NtkCiNum(pNtk) );
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart();
if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall )
if ( pNtk->pManTime->tInDriveDef.Rise == Rise && pNtk->pManTime->tInDriveDef.Fall == Fall )
return;
Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
// set the required time
vTimes = pNtk->pManTime->vReqs;
pTime = (Abc_Time_t *)vTimes->pArray[ObjId];
if ( pNtk->pManTime->tInDrive == NULL )
pNtk->pManTime->tInDrive = ABC_CALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) );
pTime = pNtk->pManTime->tInDrive + PiNum;
pTime->Rise = Rise;
pTime->Fall = Fall;
}
void Abc_NtkTimeSetOutputLoad( Abc_Ntk_t * pNtk, int PoNum, float Rise, float Fall )
{
Abc_Time_t * pTime;
assert( PoNum >= 0 && PoNum < Abc_NtkCoNum(pNtk) );
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart();
if ( pNtk->pManTime->tOutLoadDef.Rise == Rise && pNtk->pManTime->tOutLoadDef.Fall == Fall )
return;
if ( pNtk->pManTime->tOutLoad == NULL )
pNtk->pManTime->tOutLoad = ABC_CALLOC( Abc_Time_t, Abc_NtkCoNum(pNtk) );
pTime = pNtk->pManTime->tOutLoad + PoNum;
pTime->Rise = Rise;
pTime->Fall = Fall;
pTime->Worst = Abc_MaxFloat( Rise, Fall );
}
/**Function*************************************************************
......@@ -283,7 +317,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
Abc_NtkForEachPi( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
if ( pTime->Worst != -ABC_INFINITY )
if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != -ABC_INFINITY )
continue;
*pTime = pNtkOld ? *Abc_NodeReadArrival(Abc_NtkPi(pNtkOld, i)) : pNtk->pManTime->tArrDef;
}
......@@ -292,7 +326,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
Abc_NtkForEachPo( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
if ( pTime->Worst != -ABC_INFINITY )
if ( Abc_MaxFloat(pTime->Fall, pTime->Rise) != -ABC_INFINITY )
continue;
*pTime = pNtkOld ? *Abc_NodeReadRequired(Abc_NtkPo(pNtkOld, i)) : pNtk->pManTime->tReqDef;
}
......@@ -301,7 +335,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
Abc_NtkForEachLatchOutput( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
pTime->Fall = pTime->Rise = 0.0;
}
}
......@@ -335,24 +369,24 @@ void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
pTime->Fall = pTime->Rise = -ABC_INFINITY;
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
pTime->Fall = pTime->Rise = -ABC_INFINITY;
}
// clean required except for POs
ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray;
Abc_NtkForEachNode( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
pTime->Fall = pTime->Rise = -ABC_INFINITY;
}
Abc_NtkForEachPi( pNtk, pObj, i )
{
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
pTime->Fall = pTime->Rise = -ABC_INFINITY;
}
}
......@@ -393,6 +427,10 @@ Abc_ManTime_t * Abc_ManTimeStart()
***********************************************************************/
void Abc_ManTimeStop( Abc_ManTime_t * p )
{
if ( p->tInDrive )
ABC_FREE( p->tInDrive );
if ( p->tOutLoad )
ABC_FREE( p->tOutLoad );
if ( p->vArrs->nSize > 0 )
{
ABC_FREE( p->vArrs->pArray[0] );
......@@ -424,8 +462,8 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
int i;
if ( pNtkOld->pManTime == NULL )
return;
assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) );
assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) );
assert( Abc_NtkCiNum(pNtkOld) == Abc_NtkCiNum(pNtkNew) );
assert( Abc_NtkCoNum(pNtkOld) == Abc_NtkCoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) );
// create the new timing manager
pNtkNew->pManTime = Abc_ManTimeStart();
......@@ -443,6 +481,19 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray;
Abc_NtkForEachCo( pNtkOld, pObj, i )
*ppTimesNew[ Abc_NtkCo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
// duplicate input drive
pNtkNew->pManTime->tInDriveDef = pNtkOld->pManTime->tInDriveDef;
pNtkNew->pManTime->tOutLoadDef = pNtkOld->pManTime->tOutLoadDef;
if ( pNtkOld->pManTime->tInDrive )
{
pNtkNew->pManTime->tInDrive = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) );
memcpy( pNtkNew->pManTime->tInDrive, pNtkOld->pManTime->tInDrive, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtkOld) );
}
if ( pNtkOld->pManTime->tOutLoad )
{
pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) );
memcpy( pNtkNew->pManTime->tOutLoad, pNtkOld->pManTime->tOutLoad, sizeof(Abc_Time_t) * Abc_NtkCoNum(pNtkOld) );
}
}
/**Function*************************************************************
......@@ -481,7 +532,6 @@ void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
pTime = (Abc_Time_t *)vTimes->pArray[i];
pTime->Rise = -ABC_INFINITY;
pTime->Fall = -ABC_INFINITY;
pTime->Worst = -ABC_INFINITY;
}
vTimes = p->vReqs;
......@@ -496,7 +546,6 @@ void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
pTime = (Abc_Time_t *)vTimes->pArray[i];
pTime->Rise = -ABC_INFINITY;
pTime->Fall = -ABC_INFINITY;
pTime->Worst = -ABC_INFINITY;
}
}
......@@ -529,7 +578,7 @@ void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
{
pNodeNew = pNodeOld->pCopy;
pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay);
pNodeNew->Level = (int)(Abc_NodeReadArrivalWorst(pNodeOld) / tAndDelay);
}
}
......@@ -593,7 +642,7 @@ float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
return p;
// set the PI arrival times
Abc_NtkForEachPi( pNtk, pNode, i )
p[i] = Abc_NodeArrival(pNode)->Worst;
p[i] = Abc_NodeReadArrivalWorst(pNode);
return p;
}
float * Abc_NtkGetCoRequiredFloats( Abc_Ntk_t * pNtk )
......@@ -606,7 +655,7 @@ float * Abc_NtkGetCoRequiredFloats( Abc_Ntk_t * pNtk )
// set the PO required times
p = ABC_CALLOC( float, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pNode, i )
p[i] = Abc_NodeRequired(pNode)->Worst;
p[i] = Abc_NodeReadRequiredWorst(pNode);
return p;
}
......@@ -772,7 +821,6 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode, Vec_Int_t * vSlacks )
}
pPin = Mio_PinReadNext(pPin);
}
pTimeOut->Worst = Abc_MaxFloat( pTimeOut->Rise, pTimeOut->Fall );
// compute edge slacks
if ( vSlacks )
......@@ -858,8 +906,8 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, in
{
pDriver = Abc_ObjFanin0(pNode);
pTime = Abc_NodeArrival(pDriver);
if ( tArrivalMax < pTime->Worst )
tArrivalMax = pTime->Worst;
if ( tArrivalMax < Abc_MaxFloat(pTime->Fall, pTime->Rise) )
tArrivalMax = Abc_MaxFloat(pTime->Fall, pTime->Rise);
}
// determine the output to print
......@@ -869,7 +917,7 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, in
{
pDriver = Abc_ObjFanin0(pNode);
pTime = Abc_NodeArrival(pDriver);
if ( tArrivalMax == pTime->Worst )
if ( tArrivalMax == Abc_MaxFloat(pTime->Fall, pTime->Rise) )
pOut = pNode;
}
assert( pOut != NULL );
......@@ -894,7 +942,7 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, in
int k, iFanin, Length = 0;
Abc_Obj_t * pFanin;
// check the additional slack
SlackAdd = Abc_NodeRequired(pOut)->Worst - Abc_NodeArrival(Abc_ObjFanin0(pOut))->Worst;
SlackAdd = Abc_NodeReadRequiredWorst(pOut) - Abc_NodeReadArrivalWorst(Abc_ObjFanin0(pOut));
// collect the critical path
Abc_NtkDelayTraceCritPathCollect_rec( vSlacks, Abc_ObjFanin0(pOut), vBest, vPath );
if ( pIn == NULL )
......@@ -912,14 +960,14 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, in
if ( Abc_ObjIsCi(pNode) )
{
printf( "Primary input \"%s\". ", Abc_ObjName(pNode) );
printf( "Arrival time =%6.1f. ", Abc_NodeReadArrival(pNode)->Worst );
printf( "Arrival time =%6.1f. ", Abc_NodeReadArrivalWorst(pNode) );
printf( "\n" );
continue;
}
if ( Abc_ObjIsCo(pNode) )
{
printf( "Primary output \"%s\". ", Abc_ObjName(pNode) );
printf( "Arrival =%6.1f. ", Abc_NodeReadArrival(pNode)->Worst );
printf( "Arrival =%6.1f. ", Abc_NodeReadArrivalWorst(pNode) );
}
else
{
......@@ -932,18 +980,18 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, in
for ( k = strlen(Mio_GateReadName((Mio_Gate_t *)pNode->pData)); k < Length; k++ )
printf( " " );
printf( " " );
printf( "Arrival =%6.1f. ", Abc_NodeReadArrival(pNode)->Worst );
printf( "Arrival =%6.1f. ", Abc_NodeReadArrivalWorst(pNode) );
printf( "I/O times: (" );
Abc_ObjForEachFanin( pNode, pFanin, k )
printf( "%s%.1f", (k? ", ":""), Abc_NodeReadArrival(pFanin)->Worst );
printf( "%s%.1f", (k? ", ":""), Abc_NodeReadArrivalWorst(pFanin) );
// printf( " -> %.1f)", Abc_NodeReadArrival(pNode)->Worst + Slack + SlackAdd );
printf( " -> %.1f)", Abc_NodeReadArrival(pNode)->Worst );
printf( " -> %.1f)", Abc_NodeReadArrivalWorst(pNode) );
}
printf( "\n" );
}
printf( "Level %3d : ", Abc_ObjLevel(Abc_ObjFanin0(pOut)) + 1 );
printf( "Primary output \"%s\". ", Abc_ObjName(pOut) );
printf( "Required time = %6.1f. ", Abc_NodeRequired(pOut)->Worst );
printf( "Required time = %6.1f. ", Abc_NodeReadRequiredWorst(pOut) );
printf( "Path slack = %6.1f.\n", SlackAdd );
}
Vec_PtrFree( vPath );
......
......@@ -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_ReadBlifNetworkDefaultInputArrival( 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_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
......@@ -276,6 +280,14 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_output_required" ) )
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" ) )
fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens );
// else if ( !strcmp( pDirective, ".subckt" ) )
......@@ -977,6 +989,181 @@ int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTok
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*************************************************************
Synopsis []
......
......@@ -714,6 +714,30 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
}
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