summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2013-07-21 00:15:24 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2013-07-21 00:15:24 -0700
commitab84c73eb022b145faa040575d0e507e410035de (patch)
tree885985eba7b7fa679fc3fe1806807381a18946aa
parentf917de3498159ecb5816eca0c7950e4ce8d22a3f (diff)
downloadabc-ab84c73eb022b145faa040575d0e507e410035de.tar.gz
abc-ab84c73eb022b145faa040575d0e507e410035de.tar.bz2
abc-ab84c73eb022b145faa040575d0e507e410035de.zip
Adding support for input slew (.input_drive) and output capacitance (.output_load) in BLIF reader/writer.
-rw-r--r--src/base/abc/abc.h17
-rw-r--r--src/base/abc/abcObj.c4
-rw-r--r--src/base/abci/abcPrint.c2
-rw-r--r--src/base/abci/abcSweep.c8
-rw-r--r--src/base/abci/abcTiming.c260
-rw-r--r--src/base/io/ioReadBlif.c187
-rw-r--r--src/base/io/ioWriteBlif.c24
7 files changed, 387 insertions, 115 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 2ffa7de9..ffe3abd5 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -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 );
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index a2bb0380..8572d0fc 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -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;
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index 979b6f07..efeaabe9 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -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;
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
index 4b53f7e1..87c90a31 100644
--- a/src/base/abci/abcSweep.c
+++ b/src/base/abci/abcSweep.c
@@ -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 ||
diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c
index ce05e83e..3df500cd 100644
--- a/src/base/abci/abcTiming.c
+++ b/src/base/abci/abcTiming.c
@@ -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 );
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 72f5c9dc..aeb1ec3e 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -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 []
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index 692ec3bb..9ed2becb 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -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" );
}