diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-07-21 00:15:24 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-07-21 00:15:24 -0700 |
commit | ab84c73eb022b145faa040575d0e507e410035de (patch) | |
tree | 885985eba7b7fa679fc3fe1806807381a18946aa /src | |
parent | f917de3498159ecb5816eca0c7950e4ce8d22a3f (diff) | |
download | abc-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abc.h | 17 | ||||
-rw-r--r-- | src/base/abc/abcObj.c | 4 | ||||
-rw-r--r-- | src/base/abci/abcPrint.c | 2 | ||||
-rw-r--r-- | src/base/abci/abcSweep.c | 8 | ||||
-rw-r--r-- | src/base/abci/abcTiming.c | 260 | ||||
-rw-r--r-- | src/base/io/ioReadBlif.c | 187 | ||||
-rw-r--r-- | src/base/io/ioWriteBlif.c | 24 |
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" ); } |