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 | |
| 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.
| -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" );  } | 
