diff options
| -rw-r--r-- | src/base/abc/abc.h | 4 | ||||
| -rw-r--r-- | src/map/scl/scl.c | 115 | ||||
| -rw-r--r-- | src/map/scl/sclBuffer.c | 76 | ||||
| -rw-r--r-- | src/map/scl/sclSize.c | 112 | ||||
| -rw-r--r-- | src/map/scl/sclSize.h | 3 | 
5 files changed, 290 insertions, 20 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index bd0c5bba..a9178f38 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -387,8 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj )      { return Ab  static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj )      { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) );    }  static inline Abc_Obj_t * Abc_ObjFromLit( Abc_Ntk_t * p, int iLit )  { return Abc_ObjNotCond( Abc_NtkObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit) );           }  static inline int         Abc_ObjToLit( Abc_Obj_t * p )              { return Abc_Var2Lit( Abc_ObjId(Abc_ObjRegular(p)), Abc_ObjIsComplement(p) );                } -static inline int         Abc_ObjFaninPhase( Abc_Obj_t * p, int i )  { assert(p->pNtk->vPhases); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1;  }  -static inline void        Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i);      }  +static inline int         Abc_ObjFaninPhase( Abc_Obj_t * p, int i )  { assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1;  }  +static inline void        Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i);      }   // checking the AIG node types  static inline int         Abc_AigNodeIsConst( Abc_Obj_t * pNode )    { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk));  return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1;       } diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index e9c4d22c..e2b3d1ce 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -37,10 +37,11 @@ static int Scl_CommandStime   ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandTopo    ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandBuffer  ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandUpsize  ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int Scl_CommandDnsize  ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandMinsize ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandMaxsize ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandUpsize  ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandDnsize  ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int Scl_CommandBsize   ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv );  //////////////////////////////////////////////////////////////////////// @@ -73,6 +74,7 @@ void Scl_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "SCL mapping",  "maxsize",     Scl_CommandMaxsize,  1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "upsize",      Scl_CommandUpsize,   1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "dnsize",      Scl_CommandDnsize,   1 );  +    Cmd_CommandAdd( pAbc, "SCL mapping",  "bsize",       Scl_CommandBsize,    1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "print_buf",   Scl_CommandPrintBuf, 0 );   }  void Scl_End( Abc_Frame_t * pAbc ) @@ -571,17 +573,18 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )  {      Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);      Abc_Ntk_t * pNtkRes; -    int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis; +    int FanMin, FanMax, FanMaxR, fAddInvs, fUseInvs, fBufPis;      int c, fVerbose;      int fOldAlgo = 0;      FanMin   =  6;      FanMax   = 14; +    FanMaxR  =  0;      fAddInvs =  0;      fUseInvs =  0;      fBufPis  =  0;      fVerbose =  0;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "NMRaixpvh" ) ) != EOF )      {          switch ( c )          { @@ -607,6 +610,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )              if ( FanMax < 0 )                   goto usage;              break; +        case 'R': +            if ( globalUtilOptind >= argc ) +            { +                Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" ); +                goto usage; +            } +            FanMaxR = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( FanMaxR < 0 )  +                goto usage; +            break;          case 'a':              fOldAlgo ^= 1;              break; @@ -649,7 +663,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )      if ( fAddInvs )          pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose );      else if ( fOldAlgo ) -        pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); +        pNtkRes = Abc_SclPerformBuffering( pNtk, FanMaxR, FanMax, fUseInvs, fVerbose );      else          pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose );      if ( pNtkRes == NULL ) @@ -662,10 +676,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )      return 0;  usage: -    fprintf( pAbc->Err, "usage: buffer [-NM num] [-aixpvh]\n" ); +    fprintf( pAbc->Err, "usage: buffer [-NMR num] [-aixpvh]\n" );      fprintf( pAbc->Err, "\t           performs buffering of the mapped network\n" );      fprintf( pAbc->Err, "\t-N <num> : the min fanout considered by the algorithm [default = %d]\n", FanMin );      fprintf( pAbc->Err, "\t-M <num> : the max allowed fanout count of node/buffer [default = %d]\n", FanMax ); +    fprintf( pAbc->Err, "\t-R <num> : the max allowed fanout count of root node [default = %d]\n", FanMaxR );      fprintf( pAbc->Err, "\t-a       : toggle using old algorithm [default = %s]\n", fOldAlgo? "yes": "no" );      fprintf( pAbc->Err, "\t-i       : toggle adding interters instead of buffering [default = %s]\n", fAddInvs? "yes": "no" );      fprintf( pAbc->Err, "\t-x       : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" ); @@ -1248,6 +1263,94 @@ usage:    SeeAlso     []  ***********************************************************************/ +int Scl_CommandBsize( Abc_Frame_t * pAbc, int argc, char **argv ) +{ +    extern Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads ); +    Abc_Ntk_t * pNtkRes; +    int c; +    int fUseWireLoads = 1; +    int nTreeCRatio   = 0; + +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "Xch" ) ) != EOF ) +    { +        switch ( c ) +        { +            case 'X': +                if ( globalUtilOptind >= argc ) +                { +                    Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" ); +                    goto usage; +                } +                nTreeCRatio = atoi(argv[globalUtilOptind]); +                globalUtilOptind++; +                if ( nTreeCRatio < 0 )  +                    goto usage; +                break; +            case 'c': +                fUseWireLoads ^= 1; +                break; +           case 'h': +                goto usage; +            default: +                goto usage; +        } +    } + +    if ( Abc_FrameReadNtk(pAbc) == NULL ) +    { +        fprintf( pAbc->Err, "There is no current network.\n" ); +        return 1; +    } +    if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) ) +    { +        fprintf( pAbc->Err, "The current network is not mapped.\n" ); +        return 1; +    } +    if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) ) +    { +        fprintf( pAbc->Err, "The current network is not in a topo order (run \"topo\").\n" ); +        return 1; +    } +    if ( pAbc->pLibScl == NULL ) +    { +        fprintf( pAbc->Err, "There is no Liberty library available.\n" ); +        return 1; +    } +    if ( Abc_FrameReadNtk(pAbc)->vPhases == 0 ) +    { +        fprintf( pAbc->Err, "There is no phases available.\n" ); +        return 1; +    } +    pNtkRes = Abc_SclBuffSizeStep( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nTreeCRatio, fUseWireLoads ); +    if ( pNtkRes == NULL ) +    { +        Abc_Print( -1, "The command has failed.\n" ); +        return 1; +    } +    Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); +    return 0; + +usage: +    fprintf( pAbc->Err, "usage: bsize [-X num] [-ch]\n" ); +    fprintf( pAbc->Err, "\t         performs STA using Liberty library\n" ); +    fprintf( pAbc->Err, "\t-X     : min Cout/Cave ratio for tree estimations [default = %d]\n", nTreeCRatio ); +    fprintf( pAbc->Err, "\t-c     : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" ); +    fprintf( pAbc->Err, "\t-h     : print the help massage\n" ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/  int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv )  {      Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c index 9dc43499..83a305bd 100644 --- a/src/map/scl/sclBuffer.c +++ b/src/map/scl/sclBuffer.c @@ -78,6 +78,28 @@ static inline int  Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t  /**Function************************************************************* +  Synopsis    [Make sure fanins of gates are not duplicated.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_SclReportDupFanins( Abc_Ntk_t * pNtk ) +{ +    Abc_Obj_t * pObj, * pFanin, * pFanin2; +    int i, k, k2; +    Abc_NtkForEachNode( pNtk, pObj, i ) +        Abc_ObjForEachFanin( pObj, pFanin, k ) +            Abc_ObjForEachFanin( pObj, pFanin2, k2 ) +                if ( k != k2 && pFanin == pFanin2 ) +                    printf( "Node %d has dup fanin %d.\n", i, Abc_ObjId(pFanin) );     +} + +/**Function************************************************************* +    Synopsis    [Removes buffers and inverters.]    Description [] @@ -244,6 +266,7 @@ Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose )      pNtkNew = Abc_NtkDupDfs( pNtk );      if ( fVerbose )          printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) ); +    Abc_SclReportDupFanins( pNtkNew );      return pNtkNew;  } @@ -292,6 +315,20 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )    SeeAlso     []  ***********************************************************************/ +void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj ) +{ +    Abc_Obj_t * pFanout; +    int i; +    assert( Abc_SclObjIsBufInv(pObj) ); +    Abc_ObjForEachFanout( pObj, pFanout, i ) +    { +        if ( Abc_SclObjIsBufInv(pFanout) ) +            Abc_NodeInvUpdateFanPolarity( pFanout ); +        else +            Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); +    } +} +  int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )  {      int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2); @@ -364,12 +401,16 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn      Vec_PtrFree( vFanouts );      Abc_ObjAddFanin( pBuffer, pObj );      pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); +    if ( fUseInvs ) +        Abc_NodeInvUpdateFanPolarity( pBuffer );      return pBuffer;  } -void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose ) +void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose )  { +    Vec_Ptr_t * vFanouts; +    Abc_Obj_t * pBuffer;      Abc_Obj_t * pFanout; -    int i; +    int i, nOldFanNum;      if ( Abc_NodeIsTravIdCurrent( pObj ) )          return;      Abc_NodeSetTravIdCurrent( pObj ); @@ -379,14 +420,32 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, in      assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );      // buffer fanouts and collect reverse levels      Abc_ObjForEachFanout( pObj, pFanout, i ) -        Abc_SclPerformBuffering_rec( pFanout, Degree, fUseInvs, fVerbose ); +        Abc_SclPerformBuffering_rec( pFanout, DegreeR, Degree, fUseInvs, fVerbose );      // perform buffering as long as needed +    nOldFanNum = Abc_ObjFanoutNum(pObj);      while ( Abc_ObjFanoutNum(pObj) > Degree )          Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose ); +    // add yet another level of buffers +    if ( DegreeR && nOldFanNum > DegreeR ) +    { +        if ( fUseInvs ) +            pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL ); +        else +            pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL ); +        vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) ); +        Abc_NodeCollectFanouts( pObj, vFanouts ); +        Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) +            Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); +        Vec_PtrFree( vFanouts ); +        Abc_ObjAddFanin( pBuffer, pObj ); +        pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); +        if ( fUseInvs ) +            Abc_NodeInvUpdateFanPolarity( pBuffer ); +    }      // compute the new level of the node      pObj->Level = Abc_SclComputeReverseLevel( pObj );  } -Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ) +Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose )  {      Vec_Int_t * vCiLevs;      Abc_Ntk_t * pNew; @@ -394,7 +453,11 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in      int i;      assert( Abc_NtkHasMapping(p) );      if ( fUseInvs ) +    {          printf( "Warning!!! Using inverters instead of buffers.\n" ); +        if ( p->vPhases == NULL ) +            printf( "The phases are not given. The result will not verify.\n" ); +    }      // remember CI levels      vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) );      Abc_NtkForEachCi( p, pObj, i ) @@ -402,13 +465,16 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in      // perform buffering      Abc_NtkIncrementTravId( p );              Abc_NtkForEachCi( p, pObj, i ) -        Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose ); +        Abc_SclPerformBuffering_rec( pObj, DegreeR, Degree, fUseInvs, fVerbose );      // recompute logic levels      Abc_NtkForEachCi( p, pObj, i )          pObj->Level = Vec_IntEntry( vCiLevs, i );      Abc_NtkForEachNode( p, pObj, i )          Abc_ObjLevelNew( pObj );      Vec_IntFree( vCiLevs ); +    // if phases are present +    if ( p->vPhases ) +        Vec_IntFillExtra( p->vPhases, Abc_NtkObjNumMax(p), 0 );      // duplication in topo order      pNew = Abc_NtkDupDfs( p );      Abc_SclCheckNtk( pNew, fVerbose ); diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 2efa22ee..86c81589 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -20,6 +20,7 @@  #include "sclSize.h"  #include "map/mio/mio.h" +#include "misc/vec/vecWec.h"  ABC_NAMESPACE_IMPL_START @@ -121,7 +122,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise      printf( "Cout =%5.0f ff  ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) );      printf( "Cmax =%5.0f ff  ", pCell ? SC_CellPin(pCell, pCell->n_inputs)->max_out_cap : 0.0 );      printf( "G =%5.1f  ",       pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 ); -    printf( "SL =%5.1f ps",     Abc_SclObjSlack(p, pObj) ); +    printf( "SL =%5.1f ps",     Abc_SclObjSlackPs(p, pObj) );      printf( "\n" );  }  void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) @@ -201,6 +202,11 @@ static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t *      SC_Pair * pDepOut  = Abc_SclObjDept( p, pObj );      Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut );  } +static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj ) +{ +//    float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); +    return 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax); +}  void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )  {      SC_Timings * pRTime; @@ -213,8 +219,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )      float LoadFall = pLoad->fall;      float DeptRise = 0;      float DeptFall = 0; -//    float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); -    float Value = 0.5 * (pLoad->fall + pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); +    float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0;      if ( Abc_ObjIsCo(pObj) )      {          if ( !fDept ) @@ -325,8 +330,6 @@ void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fRe              p->pSlack[i] = Abc_MaxFloat( 0.0, Abc_SclObjGetSlack(p, pObj, D) );          }      } -    if ( p->nEstNodes ) -        printf( "Estimated nodes = %d.\n", p->nEstNodes );  }  /**Function************************************************************* @@ -626,7 +629,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )      printf( "%6.0f ps)  ",     Abc_SclObjTimePs(p, pObj, 0) );      printf( "l =%5.0f ff  ",   Abc_SclObjLoadFf(p, pObj, 0 ) );      printf( "s =%5.0f ps   ",  Abc_SclObjSlewPs(p, pObj, 0 ) ); -    printf( "sl =%5.0f ps   ", Abc_SclObjSlack(p, pObj) ); +    printf( "sl =%5.0f ps   ", Abc_SclObjSlackPs(p, pObj) );      if ( nOffset == 0 )      {      printf( "L =%5.0f ff   ",  SC_LibCapFf( p->pLib, Abc_SclCountNonBufferLoad(p, pObj) ) ); @@ -698,6 +701,103 @@ int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell )      return 1;  } +/**Function************************************************************* + +  Synopsis    [Select nodes that need to be buffered.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk ) +{ +    Vec_Wec_t * vSplits; +    Vec_Int_t * vCrits, * vNonCrits, * vLevel; +    Abc_Obj_t * pObj, * pFanout; +    int i, k; +    assert( p->EstLoadMax > 0 ); +    vCrits = Vec_IntAlloc( 1000 ); +    vNonCrits = Vec_IntAlloc( 1000 ); +    vSplits = Vec_WecAlloc( 1000 ); +    Abc_NtkForEachNodeCi( pNtk, pObj, i ) +    { +        if ( Abc_SclObjLoadValue(p, pObj) < 1 ) +        { +//            printf( "%d ", Abc_ObjFanoutNum(pObj) ); +            continue; +        } +/* +        printf( "%d : %.0f   ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) ); +        Abc_ObjForEachFanout( pObj, pFanout, k ) +            printf( "%.1f ", Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p, pFanout)) ); +        printf( "\n" ); +*/ +        // skip non-critical nodes +//        if ( Abc_SclObjSlack(p, pObj) > 100 ) +//            continue; +        // collect non-critical fanouts of the node +        Vec_IntClear( vCrits ); +        Vec_IntClear( vNonCrits ); +        Abc_ObjForEachFanout( pObj, pFanout, k ) +            if ( Abc_SclObjSlack(p, pFanout) < 100 ) +                Vec_IntPush( vCrits, Abc_ObjId(pFanout) ); +            else +                Vec_IntPush( vNonCrits, Abc_ObjId(pFanout) ); +//        assert( Vec_IntSize(vNonCrits) < Abc_ObjFanoutNum(pObj) ); +        // skip if there is nothing to split +//        if ( Vec_IntSize(vNonCrits) < 2 ) +//            continue; +        // remember them +        vLevel = Vec_WecPushLevel( vSplits ); +        Vec_IntPush( vLevel, i ); +        Vec_IntAppend( vLevel, vCrits ); +        // remember them +        vLevel = Vec_WecPushLevel( vSplits ); +        Vec_IntPush( vLevel, i ); +        Vec_IntAppend( vLevel, vNonCrits ); +    } +    Vec_IntFree( vCrits ); +    Vec_IntFree( vNonCrits ); +    // print out +    printf( "Collected %d nodes to split.\n", Vec_WecSize(vSplits) ); +    return vSplits; +} +void Abc_SclPerformSplit( SC_Man * p, Abc_Ntk_t * pNtk, Vec_Wec_t * vSplits ) +{ +    Abc_Obj_t * pObj, * pObjInv, * pFanout; +    Vec_Int_t * vLevel; +    int i, k; +    assert( pNtk->vPhases != NULL ); +    Vec_WecForEachLevel( vSplits, vLevel, i ) +    { +        pObj = Abc_NtkObj( pNtk, Vec_IntEntry(vLevel, 0) ); +        pObjInv = Abc_NtkCreateNodeInv( pNtk, pObj ); +        Abc_NtkForEachObjVecStart( vLevel, pNtk, pFanout, k, 1 ) +        { +            Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); +            Abc_ObjPatchFanin( pFanout, pObj, pObjInv ); +        } +    } +    Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 ); +} +Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads ) +{ +    SC_Man * p; +    Vec_Wec_t * vSplits; +    p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 1, 0, nTreeCRatio ); +    Abc_SclTimeNtkPrint( p, 0, 0 ); +    if ( p->nEstNodes ) +        printf( "Estimated nodes = %d.\n", p->nEstNodes ); +    vSplits = Abc_SclSelectSplitNodes( p, pNtk ); +    Abc_SclPerformSplit( p, pNtk, vSplits ); +    Vec_WecFree( vSplits ); +    Abc_SclManFree( p ); +    return Abc_NtkDupDfs( pNtk ); +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index c467ba1c..9656b55a 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -122,6 +122,7 @@ static inline int       Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D )  static inline double    Abc_SclObjLoadFf( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibCapFf( p->pLib, fRise ? Abc_SclObjLoad(p, pObj)->rise : Abc_SclObjLoad(p, pObj)->fall); }  static inline double    Abc_SclObjTimePs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjTime(p, pObj)->rise : Abc_SclObjTime(p, pObj)->fall); }  static inline double    Abc_SclObjSlewPs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjSlew(p, pObj)->rise : Abc_SclObjSlew(p, pObj)->fall); } +static inline double    Abc_SclObjSlackPs( SC_Man * p, Abc_Obj_t * pObj )           { return SC_LibTimePs(p->pLib, Abc_SclObjSlack(p, pObj));                        }  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -397,7 +398,7 @@ extern Abc_Ntk_t *   Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose );  extern Abc_Ntk_t *   Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );  extern Abc_Ntk_t *   Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );  extern int           Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); -extern Abc_Ntk_t *   Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ); +extern Abc_Ntk_t *   Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose );  extern Abc_Ntk_t *   Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose );  /*=== sclDnsize.c ===============================================================*/  extern void          Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );  | 
