diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/abc/abc.h | 3 | ||||
| -rw-r--r-- | src/base/abc/abcNtk.c | 2 | ||||
| -rw-r--r-- | src/map/scl/module.make | 1 | ||||
| -rw-r--r-- | src/map/scl/scl.c | 104 | ||||
| -rw-r--r-- | src/map/scl/sclBufSize.c | 376 | ||||
| -rw-r--r-- | src/map/scl/sclBuffer.c | 15 | ||||
| -rw-r--r-- | src/map/scl/sclDnsize.c | 23 | ||||
| -rw-r--r-- | src/map/scl/sclLib.c | 50 | ||||
| -rw-r--r-- | src/map/scl/sclLib.h | 37 | ||||
| -rw-r--r-- | src/map/scl/sclLoad.c | 6 | ||||
| -rw-r--r-- | src/map/scl/sclSize.c | 32 | ||||
| -rw-r--r-- | src/map/scl/sclSize.h | 26 | ||||
| -rw-r--r-- | src/map/scl/sclUpsize.c | 44 | ||||
| -rw-r--r-- | src/map/scl/sclUtil.c | 68 | ||||
| -rw-r--r-- | src/misc/vec/vecFlt.h | 5 | 
15 files changed, 693 insertions, 99 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index d5f55b64..b0bae148 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -204,6 +204,9 @@ struct Abc_Ntk_t_      void *            pExcare;       // the EXDC network (if given)      void *            pData;         // misc      Abc_Ntk_t *       pCopy;         // copy of this network +    void *            pBSMan;        // application manager +    void *            pSCLib;        // SC library +    Vec_Int_t *       vGates;        // SC library gates      Vec_Int_t *       vPhases;       // fanins phases in the mapped netlist      char *            pWLoadUsed;    // wire load model used      float *           pLutTimes;     // arrivals/requireds/slacks using LUT-delay model diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 39a3c9af..5631902b 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -1351,6 +1351,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )  //printf( "deleting attr\n" );              Vec_AttFree( (Vec_Att_t *)pAttrMan, 1 );          } +    assert( pNtk->pSCLib == NULL ); +    Vec_IntFreeP( &pNtk->vGates );      Vec_PtrFree( pNtk->vAttrs );      ABC_FREE( pNtk->pWLoadUsed );      ABC_FREE( pNtk->pName ); diff --git a/src/map/scl/module.make b/src/map/scl/module.make index 6063a3de..ff15f1b6 100644 --- a/src/map/scl/module.make +++ b/src/map/scl/module.make @@ -1,5 +1,6 @@  SRC +=  src/map/scl/scl.c \      src/map/scl/sclBuffer.c \ +    src/map/scl/sclBufSize.c \      src/map/scl/sclDnsize.c \      src/map/scl/sclLib.c \      src/map/scl/sclLoad.c \ diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index 1e47dba3..aa93136a 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -36,6 +36,7 @@ static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv );  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_CommandBufSize ( Abc_Frame_t * pAbc, int argc, char **argv );  static int Scl_CommandUnBuffer( 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 ); @@ -69,6 +70,7 @@ void Scl_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "SCL mapping",  "stime",       Scl_CommandStime,    0 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "topo",        Scl_CommandTopo,     1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "buffer",      Scl_CommandBuffer,   1 );  +    Cmd_CommandAdd( pAbc, "SCL mapping",  "bufsize",     Scl_CommandBufSize,  1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "unbuffer",    Scl_CommandUnBuffer, 1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "minsize",     Scl_CommandMinsize,  1 );       Cmd_CommandAdd( pAbc, "SCL mapping",  "maxsize",     Scl_CommandMaxsize,  1 );  @@ -701,6 +703,108 @@ usage:    SeeAlso     []  ***********************************************************************/ +int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); +    Abc_Ntk_t * pNtkRes; +    int c, GainRatio, nDegree, fBufPis, fAddBufs, fVerbose; +    GainRatio = 200; +    nDegree   =   4; +    fAddBufs  =   0; +    fBufPis   =   0; +    fVerbose  =   0; +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "GNbpvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'G': +            if ( globalUtilOptind >= argc ) +            { +                Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" ); +                goto usage; +            } +            GainRatio = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( GainRatio < 0 )  +                goto usage; +            break; +        case 'N': +            if ( globalUtilOptind >= argc ) +            { +                Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" ); +                goto usage; +            } +            nDegree = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( nDegree < 0 )  +                goto usage; +            break; +        case 'b': +            fAddBufs ^= 1; +            break; +        case 'p': +            fBufPis ^= 1; +            break; +        case 'v': +            fVerbose ^= 1; +            break; +        case 'h': +            goto usage; +        default: +            goto usage; +        } +    } + +    if ( pNtk == NULL ) +    { +        Abc_Print( -1, "Empty network.\n" ); +        return 1; +    } +    if ( !Abc_NtkIsLogic(pNtk) ) +    { +        Abc_Print( -1, "This command can only be applied to a logic network.\n" ); +        return 1; +    } +    if ( !fAddBufs && pNtk->vPhases == NULL ) +    { +        Abc_Print( -1, "Fanin phase information is not avaiable.\n" ); +        return 1; +    } +    // modify the current network +    pNtkRes = Abc_SclBufSizePerform( pNtk, (SC_Lib *)pAbc->pLibScl, GainRatio, nDegree, fAddBufs, fBufPis, fVerbose ); +    if ( pNtkRes == NULL ) +    { +        Abc_Print( -1, "The command has failed.\n" ); +        return 1; +    } +    // replace the current network +    Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); +    return 0; + +usage: +    fprintf( pAbc->Err, "usage: bufsize [-GM num] [-bpvh]\n" ); +    fprintf( pAbc->Err, "\t           performs buffering and sizing and mapped network\n" ); +    fprintf( pAbc->Err, "\t-G <num> : target gain percentage [default = %d]\n", GainRatio ); +    fprintf( pAbc->Err, "\t-M <num> : the maximum fanout degree [default = %d]\n", nDegree ); +    fprintf( pAbc->Err, "\t-b       : toggle using buffers instead of inverters [default = %s]\n", fAddBufs? "yes": "no" ); +    fprintf( pAbc->Err, "\t-p       : toggle buffering primary inputs [default = %s]\n", fBufPis? "yes": "no" ); +    fprintf( pAbc->Err, "\t-v       : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); +    fprintf( pAbc->Err, "\t-h       : print the command usage\n"); +    return 1; +}  + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/  int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )  {      Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); diff --git a/src/map/scl/sclBufSize.c b/src/map/scl/sclBufSize.c new file mode 100644 index 00000000..229b387a --- /dev/null +++ b/src/map/scl/sclBufSize.c @@ -0,0 +1,376 @@ +/**CFile**************************************************************** + +  FileName    [sclBufSize.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Standard-cell library representation.] + +  Synopsis    [Buffering and sizing combined.] + +  Author      [Alan Mishchenko, Niklas Een] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - August 24, 2012.] + +  Revision    [$Id: sclBufSize.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sclSize.h" +#include "map/mio/mio.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Bus_Man_t_ Bus_Man_t; +struct Bus_Man_t_ +{ +    // parameters +    float          Gain;      // target gain +    int            nDegree;   // max branching factor +    int            fBufPis;   // use CI buffering +    int            fVerbose;  // verbose +    // user data +    Abc_Ntk_t *    pNtk;      // user's network +    // library +    SC_Lib *       pLib;      // cell library +    SC_Cell *      pInv;      // base interter (largest/average/???) +    // internal +    Vec_Flt_t *    vCins;     // input cap for fanouts +    Vec_Flt_t *    vLoads;    // loads for all nodes +    Vec_Flt_t *    vDepts;    // departure times +}; + + +static inline Bus_Man_t * Bus_SclObjMan( Abc_Obj_t * p )                     { return (Bus_Man_t *)p->pNtk->pBSMan;                                  } +static inline float       Bus_SclObjCin( Abc_Obj_t * p )                     { return Vec_FltEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p) );         } +static inline void        Bus_SclObjSetCin( Abc_Obj_t * p, float load )      { Vec_FltWriteEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p), load );     } +static inline float       Bus_SclObjLoad( Abc_Obj_t * p )                    { return Vec_FltEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p) );        } +static inline void        Bus_SclObjSetLoad( Abc_Obj_t * p, float load )     { Vec_FltWriteEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p), load );    } +static inline float       Bus_SclObjDept( Abc_Obj_t * p )                    { return Vec_FltEntry( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) );        } +static inline void        Bus_SclObjUpdateDept( Abc_Obj_t * p, float dept )  { float *q = Vec_FltEntryP( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); if (*q < dept) *q = dept;  } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fBufPis, int fVerbose ) +{ +    Bus_Man_t * p; +    p = ABC_CALLOC( Bus_Man_t, 1 ); +    p->Gain     = 0.01 * GainRatio; +    p->nDegree  = nDegree; +    p->fBufPis  = fBufPis; +    p->fVerbose = fVerbose; +    p->pNtk     = pNtk; +    p->pLib     = pLib; +    p->pInv     = Abc_SclFindInvertor(pLib)->pAve; +    p->vCins    = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) ); +    p->vLoads   = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) ); +    p->vDepts   = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) ); +    pNtk->pBSMan = p; +    return p; +} +void Bus_ManStop( Bus_Man_t * p ) +{ +    Vec_FltFree( p->vCins ); +    Vec_FltFree( p->vLoads ); +    Vec_FltFree( p->vDepts ); +    ABC_FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Bus_ManReadInOutLoads( Bus_Man_t * p ) +{ +    Abc_Time_t * pTime; +    Abc_Obj_t * pObj; +    int i; +    // read input load +    pTime = Abc_NtkReadDefaultInputDrive( p->pNtk ); +    if ( Abc_MaxFloat(pTime->Rise, pTime->Fall) != 0 ) +    { +        printf( "Default input drive strength is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall ); +        Abc_NtkForEachPi( p->pNtk, pObj, i ) +            Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) ); +    } +    if ( Abc_NodeReadInputDrive(p->pNtk, 0) != NULL ) +    { +        printf( "Input drive strengths for some primary inputs are specified.\n" ); +        Abc_NtkForEachPi( p->pNtk, pObj, i ) +        { +            pTime = Abc_NodeReadInputDrive(p->pNtk, i); +            Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) ); +        } +    } +    // read output load +    pTime = Abc_NtkReadDefaultOutputLoad( p->pNtk ); +    if ( Abc_MaxFloat(pTime->Rise, pTime->Fall) != 0 ) +    { +        printf( "Default output load is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall ); +        Abc_NtkForEachPo( p->pNtk, pObj, i ) +            Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) ); +    } +    if ( Abc_NodeReadOutputLoad(p->pNtk, 0) != NULL ) +    { +        printf( "Output loads for some primary outputs are specified.\n" ); +        Abc_NtkForEachPo( p->pNtk, pObj, i ) +        { +            pTime = Abc_NodeReadOutputLoad(p->pNtk, i); +            Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) ); +        } +    } +    // read arrival/required times +} + +/**Function************************************************************* + +  Synopsis    [Compute load and departure times of the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkComputeFanoutCins( Abc_Obj_t * pObj ) +{ +    Abc_Obj_t * pFanout; +    int i; +    Abc_ObjForEachFanout( pObj, pFanout, i ) +        if ( Abc_ObjIsNode(pFanout) ) +            Bus_SclObjSetCin( pFanout, SC_CellPinCap( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj) ) ); +} +float Abc_NtkComputeNodeLoad( Abc_Obj_t * pObj ) +{ +    Abc_Obj_t * pFanout; +    float Load = 0; +    int i; +    assert( Bus_SclObjLoad(pObj) == 0 ); +    Abc_ObjForEachFanout( pObj, pFanout, i ) +        Load += Bus_SclObjCin( pFanout ); +    Bus_SclObjSetLoad( pObj, Load ); +    return Load; +} +float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj ) +{ +    Abc_Obj_t * pFanout; +    float Load, Dept, Edge; +    int i; +    assert( Bus_SclObjDept(pObj) == 0 ); +    Abc_ObjForEachFanout( pObj, pFanout, i ) +    { +        if ( Abc_ObjIsCo(pFanout) ) // add required times here +            continue; +        Load = Bus_SclObjLoad( pFanout ); +        Dept = Bus_SclObjDept( pFanout ); +        Edge = Scl_LibPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load ); +        Bus_SclObjUpdateDept( pObj, Dept + Edge ); +        assert( Edge > 0 ); +        assert( Load > 0 ); +    } +    return Bus_SclObjDept( pObj ); +} +/* +void Abc_NtkUpdateFaninDeparture( Bus_Man_t * p, Abc_Obj_t * pObj, float Load ) +{ +    SC_Cell * pCell = Abc_SclObjCell( pObj ); +    Abc_Obj_t * pFanin; +    float Dept, Edge; +    int i; +    Dept = Bus_SclObjDept( pObj ); +    Abc_ObjForEachFanin( pObj, pFanin, i ) +    { +        Edge = Scl_LibPinTime( pCell, i, Load ); +        Bus_SclObjUpdateDept( pFanin, Dept + Edge ); +    } +} +*/ + +/**Function************************************************************* + +  Synopsis    [Compare two fanouts by their departure times.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Bus_SclCompareFanouts( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) +{ +    float Espilon = 10; // 10 ps +    if ( Bus_SclObjDept(*pp1) < Bus_SclObjDept(*pp2) - Espilon ) +        return -1; +    if ( Bus_SclObjDept(*pp1) > Bus_SclObjDept(*pp2) + Espilon ) +        return 1; +    if ( Bus_SclObjCin(*pp1) > Bus_SclObjCin(*pp2) - Espilon ) +        return -1; +    if ( Bus_SclObjCin(*pp1) < Bus_SclObjCin(*pp2) + Espilon ) +        return 1; +    return -1; +} +void Bus_SclInsertFanout( Vec_Ptr_t * vFanouts, Abc_Obj_t * pObj ) +{ +    Abc_Obj_t * pCur; +    int i, k; +    assert( Bus_SclObjDept(pObj) > 0 ); +    assert( Bus_SclObjLoad(pObj) > 0 ); +    // compact array +    for ( i = k = 0; i < Vec_PtrSize(vFanouts); i++ ) +        if ( Vec_PtrEntry(vFanouts, i) != NULL ) +            Vec_PtrWriteEntry( vFanouts, k++, Vec_PtrEntry(vFanouts, i) ); +    Vec_PtrShrink( vFanouts, k ); +    // insert new entry +    Vec_PtrPush( vFanouts, pObj ); +    for ( i = Vec_PtrSize(vFanouts) - 1; i > 0; i-- ) +    { +        pCur = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, i-1); +        pObj = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, i); +        if ( Bus_SclCompareFanouts( &pCur, &pObj ) == -1 ) +            break; +        ABC_SWAP( void *, Vec_PtrArray(vFanouts)[i-1], Vec_PtrArray(vFanouts)[i] ); +    } +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFanouts, float Gain, int Degree ) +{ +    SC_Cell * pCellNew; +    Abc_Obj_t * pFanout, * pInv; +    float Target = SC_CellPinCap( p->pInv, 0 ) * Gain; +    float Load = 0; +    int i, iStop; +    Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, iStop, Degree ) +    { +        Load += Bus_SclObjCin( pFanout ); +        if ( Load > Target ) +            break; +    } +    // create inverter +    pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL ); +    assert( (int)Abc_ObjId(pInv) < Vec_FltSize(p->vDepts) ); +    Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, iStop ) +    { +        Vec_PtrWriteEntry( vFanouts, i, NULL ); +        if ( Abc_ObjFanin0(pFanout) == NULL ) +            Abc_ObjAddFanin( pFanout, pInv ); +        else +            Abc_ObjPatchFanin( pFanout, pObj, pInv ); +    } +    // set the gate +    pCellNew = Abc_SclFindSmallestGate( p->pInv, Load / Gain ); +    Vec_IntSetEntry( p->pNtk->vGates, Abc_ObjId(pInv), pCellNew->Id ); +    Bus_SclObjSetCin( pInv, SC_CellPinCap(pCellNew, 0) ); +    // update timing +    Abc_NtkComputeNodeLoad( pInv ); +    Abc_NtkComputeNodeDept( pInv ); +    // update phases +    if ( p->pNtk->vPhases && Abc_SclIsInv(pInv) ) +        Abc_NodeInvUpdateFanPolarity( pInv ); +    return pInv; +} +void Abc_SclBufSize( Bus_Man_t * p ) +{ +    SC_Cell * pCell, * pCellNew; +    Vec_Ptr_t * vFanouts; +    Abc_Obj_t * pObj, * pInv; +    float Load, Cin; +    int i; +    vFanouts = Vec_PtrAlloc( 100 ); +    Abc_SclMioGates2SclGates( p->pLib, p->pNtk ); +    Abc_NtkForEachNodeReverse( p->pNtk, pObj, i ) +    { +        // compute load +        Abc_NtkComputeFanoutCins( pObj ); +        Load = Abc_NtkComputeNodeLoad( pObj ); +        // consider the gate +        pCell = Abc_SclObjCell( pObj ); +        Cin = SC_CellPinCapAve( pCell->pAve ); +        // consider upsizing the gate +        if ( Load > p->Gain * Cin ) +        { +            // add one or more inverters +            Abc_NodeCollectFanouts( pObj, vFanouts ); +            Vec_PtrSort( vFanouts, (int(*)(const void *,const void *))Bus_SclCompareFanouts ); +            do  +            { +                pInv = Abc_SclAddOneInv( p, pObj, vFanouts, p->Gain, p->nDegree ); +                Bus_SclInsertFanout( vFanouts, pInv ); +                Load = Bus_SclObjCin( pInv ); +            } +            while ( Vec_PtrSize(vFanouts) > 1 || Load > p->Gain * Cin ); +            // connect last inverter +            assert( Abc_ObjFanin0(pInv) == NULL ); +            Abc_ObjAddFanin( pInv, pObj ); +            Bus_SclObjSetLoad( pObj, Load ); +        } +        // create cell +        pCellNew = Abc_SclFindSmallestGate( pCell, Load / p->Gain ); +        Abc_SclObjSetCell( pObj, pCellNew ); +        Abc_NtkComputeNodeDept( pObj ); +    } +    Abc_SclSclGates2MioGates( p->pLib, p->pNtk ); +    Vec_PtrFree( vFanouts ); +} +Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose ) +{ +    Abc_Ntk_t * pNtkNew; +    Bus_Man_t * p; +    if ( !Abc_SclCheckNtk( pNtk, 0 ) ) +        return NULL; +    Abc_SclReportDupFanins( pNtk ); +    p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fBufPis, fVerbose ); +    Bus_ManReadInOutLoads( p ); +    Abc_SclBufSize( p ); +    Bus_ManStop( p ); +    Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 ); +    pNtkNew = Abc_NtkDupDfs( pNtk ); +    return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c index e9060f7b..f205a0fe 100644 --- a/src/map/scl/sclBuffer.c +++ b/src/map/scl/sclBuffer.c @@ -315,7 +315,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )    SeeAlso     []  ***********************************************************************/ -void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose ) +void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj )  {      Abc_Obj_t * pFanout;      int i; @@ -323,22 +323,17 @@ void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose )      Abc_ObjForEachFanout( pObj, pFanout, i )      {          if ( Abc_SclObjIsBufInv(pFanout) ) -            Abc_NodeInvUpdateFanPolarity( pFanout, fVerbose ); +            Abc_NodeInvUpdateFanPolarity( pFanout );          else -        {              Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); -//            if ( fVerbose ) -//                printf( "Flipping fanin %d of node %d.\n", Abc_NodeFindFanin(pFanout, pObj), Abc_ObjId(pFanout) ); -        }      }  }  void Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )  {      if ( Abc_SclObjIsBufInv(pFanout) ) -        Abc_NodeInvUpdateFanPolarity( pFanout, 1 ); +        Abc_NodeInvUpdateFanPolarity( pFanout );      else          Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); -//    printf( "\n" );  }  int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )  { @@ -413,7 +408,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn      Abc_ObjAddFanin( pBuffer, pObj );      pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );      if ( fUseInvs ) -        Abc_NodeInvUpdateFanPolarity( pBuffer, 0 ); +        Abc_NodeInvUpdateFanPolarity( pBuffer );      return pBuffer;  }  void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose ) @@ -451,7 +446,7 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int          Abc_ObjAddFanin( pBuffer, pObj );          pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );          if ( fUseInvs ) -            Abc_NodeInvUpdateFanPolarity( pBuffer, 0 ); +            Abc_NodeInvUpdateFanPolarity( pBuffer );      }      // compute the new level of the node      pObj->Level = Abc_SclComputeReverseLevel( pObj ); diff --git a/src/map/scl/sclDnsize.c b/src/map/scl/sclDnsize.c index 1b21d808..50c994e9 100644 --- a/src/map/scl/sclDnsize.c +++ b/src/map/scl/sclDnsize.c @@ -102,13 +102,13 @@ int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, V  {      Abc_Obj_t * pTemp;      SC_Cell * pCellOld, * pCellNew; -    float dGain, dGainBest; +    float dGain, dGainBest, gGainCur;      int i, k, gateBest;      abctime clk;  clk = Abc_Clock();  //    printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) );      // save old gate, timing, fanin load -    pCellOld = Abc_SclObjCell( p, pObj ); +    pCellOld = Abc_SclObjCell( pObj );      Abc_SclConeStore( p, vNodes );      Abc_SclLoadStore( p, pObj );      // try different gate sizes for this node @@ -123,18 +123,21 @@ clk = Abc_Clock();          if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )              continue;          // set new cell -        Abc_SclObjSetCell( p, pObj, pCellNew ); +        Abc_SclObjSetCell( pObj, pCellNew );          Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );          // recompute timing          Abc_SclTimeCone( p, vNodes );          // set old cell -        Abc_SclObjSetCell( p, pObj, pCellOld ); +        Abc_SclObjSetCell( pObj, pCellOld );          Abc_SclLoadRestore( p, pObj );          // evaluate gain          dGain = 0.0;          Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, k )              if ( Abc_SclObjLegal(p, pTemp, p->MaxDelay0) ) -                dGain += Abc_SclObjGain( p, pTemp ); +            { +                gGainCur = Abc_SclObjGain( p, pTemp ); +                dGain += (gGainCur > 0) ? gGainCur : 1.0 * gGainCur; +            }              else                  break;          if ( k < Vec_IntSize(vEvals) ) @@ -148,13 +151,13 @@ clk = Abc_Clock();          }      }       // put back old cell and timing -    Abc_SclObjSetCell( p, pObj, pCellOld ); +    Abc_SclObjSetCell( pObj, pCellOld );      Abc_SclConeRestore( p, vNodes );  p->timeSize += Abc_Clock() - clk;      if ( gateBest >= 0 )      {          pCellNew = SC_LibCell( p->pLib, gateBest ); -        Abc_SclObjSetCell( p, pObj, pCellNew ); +        Abc_SclObjSetCell( pObj, pCellNew );          p->SumArea += pCellNew->area - pCellOld->area;  //        printf( "%f   %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea );  //        printf( "%6d  %20s -> %20s  %f -> %f\n", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName, pCellOld->area, pCellNew->area ); @@ -187,7 +190,7 @@ void Abc_NtkCollectNodesByArea( SC_Man * p, Abc_Ntk_t * pNtk )      Abc_NtkForEachNode( pNtk, pObj, i )      if ( Abc_ObjFaninNum(pObj) > 0 )      { -        Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pObj), Abc_SclObjCell(p, pObj)->area ); +        Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pObj), Abc_SclObjCell(pObj)->area );          Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );      }  } @@ -267,7 +270,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars      p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, SC_LibTimeFromPs(pLib, pPars->DelayUser), pPars->BuffTreeEst );      p->timeTotal  = Abc_Clock();      assert( p->vGatesBest == NULL ); -    p->vGatesBest = Vec_IntDup( p->vGates ); +    p->vGatesBest = Vec_IntDup( p->pNtk->vGates );      // perform upsizing      vNodes = Vec_IntAlloc( 1000 ); @@ -342,7 +345,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars          printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );      // save the result and quit -    Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers +    Abc_SclSclGates2MioGates( pLib, pNtk ); // updates gate pointers      Abc_SclManFree( p );  //    Abc_NtkCleanMarkAB( pNtk );  } diff --git a/src/map/scl/sclLib.c b/src/map/scl/sclLib.c index d3ac29df..d2b3d72b 100644 --- a/src/map/scl/sclLib.c +++ b/src/map/scl/sclLib.c @@ -749,6 +749,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )  }  void Abc_SclLinkCells( SC_Lib * p )  { +    Vec_Ptr_t * vList;      SC_Cell * pCell, * pRepr = NULL;      int i, k;      assert( Vec_PtrSize(p->vCellClasses) == 0 ); @@ -770,30 +771,69 @@ void Abc_SclLinkCells( SC_Lib * p )          pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;          pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell;      } -    // sort cells by size the then by name +    // sort cells by size then by name      qsort( (void *)Vec_PtrArray(p->vCellClasses), Vec_PtrSize(p->vCellClasses), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );      // sort cell lists +    vList = Vec_PtrAlloc( 100 );      SC_LibForEachCellClass( p, pRepr, k )      { -        Vec_Ptr_t * vList = Vec_PtrAlloc( 100 ); +        Vec_PtrClear( vList );          SC_RingForEachCell( pRepr, pCell, i )              Vec_PtrPush( vList, pCell );          qsort( (void *)Vec_PtrArray(vList), Vec_PtrSize(vList), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );          // create new representative          pRepr = (SC_Cell *)Vec_PtrEntry( vList, 0 );          pRepr->pNext = pRepr->pPrev = pRepr; +        pRepr->pRepr = pRepr; +        pRepr->pAve  = (SC_Cell *)Vec_PtrEntry( vList, Vec_PtrSize(vList)/2 );          pRepr->Order = 0; +        pRepr->nGates = Vec_PtrSize(vList);          // relink cells          Vec_PtrForEachEntryStart( SC_Cell *, vList, pCell, i, 1 )          {              pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;              pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell; +            pCell->pRepr = pRepr; +            pCell->pAve  = (SC_Cell *)Vec_PtrEntry( vList, Vec_PtrSize(vList)/2 );              pCell->Order = i; +            pCell->nGates = Vec_PtrSize(vList);          }          // update list          Vec_PtrWriteEntry( p->vCellClasses, k, pRepr ); -        Vec_PtrFree( vList );      } +    Vec_PtrFree( vList ); +} + +/**Function************************************************************* + +  Synopsis    [Returns the largest inverter.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +SC_Cell * Abc_SclFindInvertor( SC_Lib * p ) +{ +    SC_Cell * pCell = NULL; +    int k; +    SC_LibForEachCellClass( p, pCell, k ) +        if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == ABC_CONST(0x5555555555555555) ) +            break; +    // take representative +    return pCell ? pCell->pRepr : NULL; +} +SC_Cell * Abc_SclFindSmallestGate( SC_Cell * p, float CinMin ) +{ +    SC_Cell * pRes = NULL; +    int i; +    SC_RingForEachCell( p->pRepr, pRes, i ) +        if ( SC_CellPinCapAve(pRes) > CinMin ) +            return pRes; +    // take the largest gate +    return p->pRepr->pPrev;  }  /**Function************************************************************* @@ -1066,8 +1106,8 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )              printf( "D =%6.0f ps   ", 0.01 * ED * Gain + PD );              printf( "ED =%6.0f ps  ", ED );              printf( "PD =%6.0f ps  ", PD ); -            printf( "C =%5.1f ff   ", Abc_SclGatePinCapAve(p, pCell) ); -            printf( "Lm =%5.1f ff  ", 0.01 * Gain * Abc_SclGatePinCapAve(p, pCell) ); +            printf( "C =%5.1f ff   ", SC_CellPinCapAve(pCell) ); +            printf( "Lm =%5.1f ff  ", 0.01 * Gain * SC_CellPinCapAve(pCell) );  //            printf( "MaxS =%5.1f ps  ",   SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );              printf( "Lm2 =%5.0f ff ",  SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );              printf( "\n" ); diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h index 5084997e..7d5964a4 100644 --- a/src/map/scl/sclLib.h +++ b/src/map/scl/sclLib.h @@ -178,7 +178,10 @@ struct SC_Cell_      int            n_outputs;      // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins      SC_Cell *      pNext;          // same-functionality cells linked into a ring by area      SC_Cell *      pPrev;          // same-functionality cells linked into a ring by area +    SC_Cell *      pRepr;          // representative of the class +    SC_Cell *      pAve;           // average size cell of this class      int            Order;          // order of the gate in the list +    int            nGates;         // the number of gates in the list        };  struct SC_Lib_  @@ -211,6 +214,7 @@ static inline SC_Cell *   SC_LibCell( SC_Lib * p, int i )           { return (SC  static inline SC_Pin  *   SC_CellPin( SC_Cell * p, int i )          { return (SC_Pin *)Vec_PtrEntry(p->vPins, i);                     }  static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p )                { return SC_CellPin(p, p->n_inputs)->vFunc;                       }  static inline float       SC_CellPinCap( SC_Cell * p, int i )       { return 0.5 * (SC_CellPin(p, i)->rise_cap + SC_CellPin(p, i)->fall_cap); } +static inline float       SC_CellPinCapAve( SC_Cell * p )           { int i; float c = 0; for (i = 0; i < p->n_inputs; i++) c += SC_CellPinCap(p, i); return c / p->n_inputs; }  static inline char *      SC_CellPinOutFunc( SC_Cell * p, int i )   { return SC_CellPin(p, p->n_inputs + i)->func_text;               }  static inline char *      SC_CellPinName( SC_Cell * p, int i )      { return SC_CellPin(p, i)->pName;                                 } @@ -519,7 +523,7 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_  /**Function************************************************************* -  Synopsis    [Computes input capacitance.] +  Synopsis    [Compute one timing edge.]    Description [] @@ -528,17 +532,32 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_    SeeAlso     []  ***********************************************************************/ -static inline float Abc_SclGatePinCapAve( SC_Lib * p, SC_Cell * pCell ) +static inline float Scl_LibPinTime( SC_Cell * pCell, int iPin, float load )  {      SC_Pin * pPin; -    int k; -    float Cap = 0.0; -    SC_CellForEachPinIn( pCell, pPin, k ) -        Cap += 0.5 * (pPin->rise_cap + pPin->fall_cap); -    return Cap / pCell->n_inputs; +    SC_Timings * pRTime; +    SC_Timing * pTime; +    SC_Pair Load = { load, load }; +    SC_Pair ArrIn  = { 0.0, 0.0 }; +    SC_Pair ArrOut = { 0.0, 0.0 }; +    SC_Pair SlewIn = { 0.0, 0.0 }; +    SC_Pair SlewOut = { 0.0, 0.0 }; +    Vec_Flt_t * vIndex0; +    assert( iPin >= 0 && iPin < pCell->n_inputs ); +    pPin = SC_CellPin( pCell, pCell->n_inputs ); +    // find timing info for this pin +    assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); +    pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin ); +    assert( Vec_PtrSize(pRTime->vTimings) == 1 ); +    pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); +    // get delay points +    vIndex0 = pTime->pCellRise->vIndex0; // slew +    SlewIn.fall = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 ); +    SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 ); +    Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load, &ArrOut, &SlewOut ); +    return 0.5 * (ArrOut.fall + ArrOut.rise);  } -  /*=== sclLib.c ===============================================================*/  extern SC_Lib *      Abc_SclRead( char * pFileName );  extern void          Abc_SclWrite( char * pFileName, SC_Lib * p ); @@ -550,6 +569,8 @@ extern int           Abc_SclCellFind( SC_Lib * p, char * pName );  extern int           Abc_SclClassCellNum( SC_Cell * pClass );  extern void          Abc_SclLinkCells( SC_Lib * p );  extern void          Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ); +extern SC_Cell *     Abc_SclFindInvertor( SC_Lib * p ); +extern SC_Cell *     Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );  extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );  extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );  extern void          Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin ); diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c index 7ea13db2..282fd7ee 100644 --- a/src/map/scl/sclLoad.c +++ b/src/map/scl/sclLoad.c @@ -94,7 +94,7 @@ void Abc_SclComputeLoad( SC_Man * p )      // add cell load      Abc_NtkForEachNode1( p->pNtk, pObj, i )      { -        SC_Cell * pCell = Abc_SclObjCell( p, pObj ); +        SC_Cell * pCell = Abc_SclObjCell( pObj );          Abc_ObjForEachFanin( pObj, pFanin, k )          {              SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); @@ -142,7 +142,7 @@ void Abc_SclComputeLoad( SC_Man * p )          }      }      // calculate average load -    if ( p->EstLoadMax ) +//    if ( p->EstLoadMax )      {          double TotalLoad = 0;          int nObjs = 0; @@ -194,7 +194,7 @@ void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanou      int iFanin = Abc_NodeFindFanin( pFanout, pBuffer );      assert( iFanin >= 0 );      assert( Abc_ObjFaninNum(pBuffer) == 1 ); -    pPin = SC_CellPin( Abc_SclObjCell(p, pFanout), iFanin ); +    pPin = SC_CellPin( Abc_SclObjCell(pFanout), iFanin );      // update load of the buffer      pLoad = Abc_SclObjLoad( p, pBuffer );      pLoad->rise -= pPin->rise_cap; diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 18c520c3..7fb80a27 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -108,7 +108,7 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t *  ***********************************************************************/  static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise, int Length, float maxDelay )  { -    SC_Cell * pCell = Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj) : NULL; +    SC_Cell * pCell = Abc_ObjIsNode(pObj) ? Abc_SclObjCell(pObj) : NULL;      printf( "%6d : ",           Abc_ObjId(pObj) );      printf( "%d ",              Abc_ObjFaninNum(pObj) );      printf( "%4d ",             Abc_ObjFanoutNum(pObj) ); @@ -118,7 +118,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise      printf( "%5.0f",            Abc_MaxFloat(Abc_SclObjTimePs(p, pObj, 0), Abc_SclObjTimePs(p, pObj, 1)) );      printf( "%6.0f ps  ",       -Abc_AbsFloat(Abc_SclObjTimePs(p, pObj, 0) - Abc_SclObjTimePs(p, pObj, 1)) );      printf( "S =%5.0f ps  ",    Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); -    printf( "Cin =%4.0f ff  ",  pCell ? Abc_SclGatePinCapAve(p->pLib, pCell) : 0.0 ); +    printf( "Cin =%4.0f ff  ",  pCell ? SC_CellPinCapAve(pCell) : 0.0 );      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 ); @@ -132,10 +132,13 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )      float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise);      p->ReportDelay = maxDelay; -    printf( "WireLoad model = \"%s\".  ",  p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); -    printf( "Gates = %6d.  ",              Abc_NtkNodeNum(p->pNtk) ); -    printf( "Area = %12.2f.  ",            Abc_SclGetTotalArea( p ) ); -    printf( "Critical delay = %8.2f ps\n", maxDelay ); +    printf( "WireLoad model = \"%s\"   ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); +    printf( "Gates = %6d   ",             Abc_NtkNodeNum(p->pNtk) ); +    printf( "Cave = %5.1f   ",            p->EstLoadAve ); +    printf( "Min = %5.1f %%   ",          100.0 * Abc_SclCountMinSize(p->pLib, p->pNtk, 0) / Abc_NtkNodeNum(p->pNtk) ); +    printf( "Area = %12.2f   ",           Abc_SclGetTotalArea( p ) ); +    printf( "Delay = %8.2f ps  ",         maxDelay ); +    printf( "Min = %5.1f %%\n",           100.0 * Abc_SclCountNearCriticalNodes(p) / Abc_NtkNodeNum(p->pNtk) );      if ( !fPrintPath )          return; @@ -145,7 +148,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )          // find the longest cell name          Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )              if ( Abc_ObjFaninNum(pObj) > 0 ) -                nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(p, pObj)->pName) ); +                nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) );          // print timing          Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )              if ( Abc_ObjFaninNum(pObj) > 0 ) @@ -160,7 +163,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )          while ( pObj && Abc_ObjIsNode(pObj) )          {              i++; -            nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(p, pObj)->pName) ); +            nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) );              pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );          }          // print timing @@ -244,7 +247,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )          p->nEstNodes++;      }      // get the library cell -    pCell = Abc_SclObjCell( p, pObj ); +    pCell = Abc_SclObjCell( pObj );      // get the output pin  //    assert( pCell->n_outputs == 1 );      pPin = SC_CellPin( pCell, pCell->n_inputs ); @@ -287,7 +290,7 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )      Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )      {          if ( fVerbose && Abc_ObjIsNode(pObj) ) -        printf( "  Updating node %d with gate %s\n", Abc_ObjId(pObj), Abc_SclObjCell(p, pObj)->pName ); +        printf( "  Updating node %d with gate %s\n", Abc_ObjId(pObj), Abc_SclObjCell(pObj)->pName );          if ( fVerbose && Abc_ObjIsNode(pObj) )          printf( "    before (%6.1f ps  %6.1f ps)   ", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) );          Abc_SclTimeNode( p, pObj, 0 ); @@ -439,8 +442,7 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, in          p->EstLoadMax = 0.01 * nTreeCRatio;  // max ratio of Cout/Cave when the estimation is used          p->EstLinear  = 100;                  // linear coefficient      } -    assert( p->vGates == NULL ); -    p->vGates = Abc_SclManFindGates( pLib, pNtk ); +    Abc_SclMioGates2SclGates( pLib, pNtk );      Abc_SclManReadSlewAndLoad( p, pNtk );      if ( fUseWireLoads )      { @@ -605,7 +607,7 @@ float Abc_SclCountNonBufferLoadInt( SC_Man * p, Abc_Obj_t * pObj )      Abc_ObjForEachFanout( pObj, pFanout, i )          Load += Abc_SclCountNonBufferLoadInt( p, pFanout );      Load += 0.5 * Abc_SclObjLoad(p, pObj)->rise + 0.5 * Abc_SclObjLoad(p, pObj)->fall; -    Load -= 0.5 * SC_CellPin(Abc_SclObjCell(p, pObj), 0)->rise_cap + 0.5 * SC_CellPin(Abc_SclObjCell(p, pObj), 0)->fall_cap; +    Load -= 0.5 * SC_CellPin(Abc_SclObjCell(pObj), 0)->rise_cap + 0.5 * SC_CellPin(Abc_SclObjCell(pObj), 0)->fall_cap;      return Load;  }  float Abc_SclCountNonBufferLoad( SC_Man * p, Abc_Obj_t * pObj ) @@ -631,7 +633,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )          Abc_SclCountNonBufferFanouts(pObj) );      for ( ; i < 4; i++ )          printf( "    " ); -    printf( "a =%5.2f  ",      Abc_ObjIsPi(pObj) ? 0 : Abc_SclObjCell(p, pObj)->area ); +    printf( "a =%5.2f  ",      Abc_ObjIsPi(pObj) ? 0 : Abc_SclObjCell(pObj)->area );      printf( "d = (" );      printf( "%6.0f ps; ",      Abc_SclObjTimePs(p, pObj, 1) );      printf( "%6.0f ps)  ",     Abc_SclObjTimePs(p, pObj, 0) ); @@ -740,7 +742,7 @@ Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk )  /*          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( "%.1f ", SC_CellPinCapAve(Abc_SclObjCell(pFanout)) );          printf( "\n" );  */          // skip non-critical nodes diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 9660cbe9..fad63243 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -47,7 +47,7 @@ struct SC_Man_      Abc_Ntk_t *    pNtk;          // network      int            nObjs;         // allocated size      // get assignment -    Vec_Int_t *    vGates;        // mapping of objId into gateId +//    Vec_Int_t *    vGates;        // mapping of objId into gateId      Vec_Int_t *    vGatesBest;    // best gate sizes found so far      Vec_Int_t *    vUpdates;      // sizing updates in this round      Vec_Int_t *    vUpdates2;     // sizing updates in this round @@ -99,8 +99,9 @@ struct SC_Man_  ///                       MACRO DEFINITIONS                          ///  //////////////////////////////////////////////////////////////////////// -static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj )              { return SC_LibCell( p->pLib, Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) );       } -static inline void      Abc_SclObjSetCell( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ) { Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCell->Id );    } +static inline SC_Lib  * Abc_SclObjLib( Abc_Obj_t * p )                              { return (SC_Lib *)p->pNtk->pSCLib;    } +static inline SC_Cell * Abc_SclObjCell( Abc_Obj_t * p )                             { return SC_LibCell( Abc_SclObjLib(p), Vec_IntEntry(p->pNtk->vGates, Abc_ObjId(p)) ); } +static inline void      Abc_SclObjSetCell( Abc_Obj_t * p, SC_Cell * pCell )         { Vec_IntWriteEntry( p->pNtk->vGates, Abc_ObjId(p), pCell->Id );                      }  static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj )              { return p->pLoads + Abc_ObjId(pObj);  }  static inline SC_Pair * Abc_SclObjDept( SC_Man * p, Abc_Obj_t * pObj )              { return p->pDepts + Abc_ObjId(pObj);  } @@ -177,6 +178,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )  }  static inline void Abc_SclManFree( SC_Man * p )  { +    p->pNtk->pSCLib = NULL; +    Vec_IntFreeP( &p->pNtk->vGates );      Vec_IntFreeP( &p->vNodeIter );      Vec_QueFreeP( &p->vNodeByGain );      Vec_FltFreeP( &p->vNode2Gain ); @@ -191,7 +194,7 @@ static inline void Abc_SclManFree( SC_Man * p )      Vec_QueCheck( p->vQue );      Vec_QueFreeP( &p->vQue );      Vec_FltFreeP( &p->vTimesOut ); -    Vec_IntFreeP( &p->vGates ); +//    Vec_IntFreeP( &p->vGates );      Vec_IntFreeP( &p->vBestFans );      ABC_FREE( p->pLoads );      ABC_FREE( p->pDepts ); @@ -349,7 +352,7 @@ static inline float Abc_SclGetTotalArea( SC_Man * p )      Abc_Obj_t * pObj;      int i;      Abc_NtkForEachNode1( p->pNtk, pObj, i ) -        Area += Abc_SclObjCell( p, pObj )->area; +        Area += Abc_SclObjCell(pObj)->area;      return Area;  }  static inline float Abc_SclGetMaxDelay( SC_Man * p ) @@ -389,7 +392,7 @@ static inline float Abc_SclReadMaxDelay( SC_Man * p )  ***********************************************************************/  static inline SC_Cell * Abc_SclObjResiable( SC_Man * p, Abc_Obj_t * pObj, int fUpsize )  { -    SC_Cell * pOld = Abc_SclObjCell( p, pObj ); +    SC_Cell * pOld = Abc_SclObjCell(pObj);      if ( fUpsize )          return pOld->pNext->Order > pOld->Order ? pOld->pNext : NULL;      else @@ -435,10 +438,13 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time      fclose( pTable );  } - +/*=== sclBufSize.c ===============================================================*/ +extern Abc_Ntk_t *   Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose );  /*=== sclBuffer.c ===============================================================*/  extern int           Abc_SclIsInv( Abc_Obj_t * pObj ); +extern void          Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj );  extern void          Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ); +extern void          Abc_SclReportDupFanins( Abc_Ntk_t * pNtk );  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 ); @@ -462,12 +468,14 @@ extern void          Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nT  extern void          Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );  extern int           Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell );  /*=== sclUpsize.c ===============================================================*/ +extern int           Abc_SclCountNearCriticalNodes( SC_Man * p );  extern void          Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );  /*=== sclUtil.c ===============================================================*/ -extern Vec_Int_t *   Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ); -extern void          Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ); +extern void          Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p ); +extern void          Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p );  extern void          Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p );  extern void          Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose ); +extern int           Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax );  ABC_NAMESPACE_HEADER_END diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c index 9cc8d370..8bdc3a5d 100644 --- a/src/map/scl/sclUpsize.c +++ b/src/map/scl/sclUpsize.c @@ -181,6 +181,20 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )      Abc_NtkForEachObjVec( vPath, p->pNtk, pObj, i )          pObj->fMarkA = 0;  } +int Abc_SclCountNearCriticalNodes( SC_Man * p ) +{ +    int RetValue; +    Vec_Int_t * vPathPos, * vPathNodes; +    vPathPos   = Abc_SclFindCriticalCoWindow( p, 5 ); +    vPathNodes = Abc_SclFindCriticalNodeWindow( p, vPathPos, 5, 0 ); +    RetValue   = Vec_IntSize(vPathNodes); +    Abc_SclUnmarkCriticalNodeWindow( p, vPathNodes ); +    Abc_SclUnmarkCriticalNodeWindow( p, vPathPos ); +    Vec_IntFree( vPathPos ); +    Vec_IntFree( vPathNodes ); +    return RetValue; +} +  /**Function************************************************************* @@ -261,7 +275,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec      float dGain, dGainBest, gGainCur;      int k, n, gateBest;      // save old gate, timing, fanin load -    pCellOld = Abc_SclObjCell( p, pObj ); +    pCellOld = Abc_SclObjCell( pObj );      Abc_SclConeStore( p, vRecalcs );      Abc_SclLoadStore( p, pObj );      // try different gate sizes for this node @@ -276,12 +290,12 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec          if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )              continue;          // set new cell -        Abc_SclObjSetCell( p, pObj, pCellNew ); +        Abc_SclObjSetCell( pObj, pCellNew );          Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );          // recompute timing          Abc_SclTimeCone( p, vRecalcs );          // set old cell -        Abc_SclObjSetCell( p, pObj, pCellOld ); +        Abc_SclObjSetCell( pObj, pCellOld );          Abc_SclLoadRestore( p, pObj );          // evaluate gain          dGain = 0.0; @@ -299,7 +313,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec          }      }      // put back old cell and timing -    Abc_SclObjSetCell( p, pObj, pCellOld ); +    Abc_SclObjSetCell( pObj, pCellOld );      Abc_SclConeRestore( p, vRecalcs );      *pGainBest = dGainBest;      return gateBest; @@ -438,11 +452,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc          Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanin) );          Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) );          // find old and new gates -        pCellOld = Abc_SclObjCell( p, pFanin ); +        pCellOld = Abc_SclObjCell( pFanin );          pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) );          // update cell          p->SumArea += pCellNew->area - pCellOld->area; -        Abc_SclObjSetCell( p, pFanin, pCellNew ); +        Abc_SclObjSetCell( pFanin, pCellNew );          // record the update          Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) );          Vec_IntPush( p->vUpdates, pCellNew->Id ); @@ -462,7 +476,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc          // check if the node became useless          if ( Abc_ObjFanoutNum(pBuf) == 0 )          { -            pCellOld = Abc_SclObjCell( p, pBuf ); +            pCellOld = Abc_SclObjCell( pBuf );              p->SumArea -= pCellOld->area;              Abc_NtkDeleteObj_rec( pBuf, 1 );              printf( "Removed node %d.\n", iNode ); @@ -583,7 +597,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch          pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );          assert( pObj->fMarkA );          // find old and new gates -        pCellOld = Abc_SclObjCell( p, pObj ); +        pCellOld = Abc_SclObjCell( pObj );          pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );          assert( pCellNew != NULL );          //printf( "%6d  %20s -> %20s  ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); @@ -622,7 +636,7 @@ return Limit;  //        printf( "%.1f ", Vec_FltEntry(p->vNode2Gain, iNode) );          // find old and new gates -        pCellOld = Abc_SclObjCell( p, pObj ); +        pCellOld = Abc_SclObjCell( pObj );          pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );          assert( pCellNew != NULL );          //printf( "%6d  %20s -> %20s  ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); @@ -630,7 +644,7 @@ return Limit;          // update gate          Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );          p->SumArea += pCellNew->area - pCellOld->area; -        Abc_SclObjSetCell( p, pObj, pCellNew ); +        Abc_SclObjSetCell( pObj, pCellNew );          // record the update          Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );          Vec_IntPush( p->vUpdates, pCellNew->Id ); @@ -788,7 +802,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )      Abc_NtkForEachNode( pNtk, pObj, i )          if ( Abc_ObjFanoutNum(pObj) == 0 )          { -            pCell = Abc_SclObjCell( p, pObj ); +            pCell = Abc_SclObjCell( pObj );              p->SumArea -= pCell->area;              Abc_NtkDeleteObj_rec( pObj, 1 );  //            printf( "Removed node %d.\n", i ); @@ -834,7 +848,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars      p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, 0, pPars->BuffTreeEst );      p->timeTotal  = Abc_Clock();      assert( p->vGatesBest == NULL ); -    p->vGatesBest = Vec_IntDup( p->vGates ); +    p->vGatesBest = Vec_IntDup( p->pNtk->vGates );      p->BestDelay  = p->MaxDelay0;      // perform upsizing @@ -893,7 +907,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars          if ( p->BestDelay > p->MaxDelay )          {              p->BestDelay = p->MaxDelay; -            Abc_SclApplyUpdateToBest( p->vGatesBest, p->vGates, p->vUpdates ); +            Abc_SclApplyUpdateToBest( p->vGatesBest, p->pNtk->vGates, p->vUpdates );              Vec_IntClear( p->vUpdates2 );              nFramesNoChange = 0;          } @@ -920,7 +934,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars              break;      }      // update for best gates and recompute timing -    ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->vGates ); +    ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->pNtk->vGates );      if ( pPars->BypassFreq != 0 )          Abc_SclUndoRecentChanges( p->pNtk, p->vUpdates2 );      if ( pPars->BypassFreq != 0 ) @@ -947,7 +961,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars          printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );      // save the result and quit -    Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers +    Abc_SclSclGates2MioGates( pLib, pNtk ); // updates gate pointers      Abc_SclManFree( p );  //    Abc_NtkCleanMarkAB( pNtk );  } diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index a28ef0cd..45980b6f 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -44,29 +44,30 @@ ABC_NAMESPACE_IMPL_START    SeeAlso     []  ***********************************************************************/ -Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ) +void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p )  { -    Vec_Int_t * vVec;      Abc_Obj_t * pObj;      int i; -    vVec = Vec_IntStartFull( Abc_NtkObjNumMax(p) ); +    assert( p->vGates == NULL ); +    p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) );      Abc_NtkForEachNode1( p, pObj, i )      {          char * pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData);          int gateId = Abc_SclCellFind( pLib, pName );          assert( gateId >= 0 ); -        Vec_IntWriteEntry( vVec, i, gateId ); +        Vec_IntWriteEntry( p->vGates, i, gateId );  //printf( "Found gate %s\n", pName );      } -    return vVec; +    p->pSCLib = pLib;  } -void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ) +void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p )  {      Abc_Obj_t * pObj;      int i, Counter = 0, CounterAll = 0; +    assert( p->vGates != NULL );      Abc_NtkForEachNode1( p, pObj, i )      { -        SC_Cell * pCell = SC_LibCell( pLib, Vec_IntEntry(vGates, Abc_ObjId(pObj)) ); +        SC_Cell * pCell = Abc_SclObjCell(pObj);          assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) );          pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL );          Counter += (pObj->pData == NULL); @@ -76,6 +77,8 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates )      }      if ( Counter )          printf( "Could not find %d (out of %d) gates in the current library.\n", Counter, CounterAll ); +    Vec_IntFreeP( &p->vGates ); +    p->pSCLib = NULL;  }  /**Function************************************************************* @@ -119,10 +122,10 @@ void Abc_SclManPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates  }  void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p )  { -    Vec_Int_t * vGates; -    vGates = Abc_SclManFindGates( pLib, p ); -    Abc_SclManPrintGateSizes( pLib, p, vGates ); -    Vec_IntFree( vGates ); +    Abc_SclMioGates2SclGates( pLib, p ); +    Abc_SclManPrintGateSizes( pLib, p, p->vGates ); +    Vec_IntFreeP( &p->vGates ); +    p->pSCLib = NULL;  }  /**Function************************************************************* @@ -149,13 +152,12 @@ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr )          }      return pBest;  } -void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose ) +Vec_Int_t * Abc_SclFindMinAreas( SC_Lib * pLib, int fUseMax )  { -    Vec_Int_t * vMinCells, * vGates; +    Vec_Int_t * vMinCells;      SC_Cell * pCell, * pRepr = NULL, * pBest = NULL; -    Abc_Obj_t * pObj; -    int i, k, gateId; -    // map each gate in the library into its min-size prototype +    int i, k; +    // map each gate in the library into its min/max-size prototype      vMinCells = Vec_IntStartFull( Vec_PtrSize(pLib->vCells) );      SC_LibForEachCellClass( pLib, pRepr, i )      { @@ -163,21 +165,39 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb          SC_RingForEachCell( pRepr, pCell, k )              Vec_IntWriteEntry( vMinCells, pCell->Id, pBest->Id );      } -    // update each cell -    vGates = Abc_SclManFindGates( pLib, p ); +    return vMinCells; +} +void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose ) +{ +    Vec_Int_t * vMinCells; +    Abc_Obj_t * pObj; +    int i, gateId; +    vMinCells = Abc_SclFindMinAreas( pLib, fUseMax ); +    Abc_SclMioGates2SclGates( pLib, p );      Abc_NtkForEachNode1( p, pObj, i )      { -        gateId = Vec_IntEntry( vGates, i ); -//        if ( SC_LibCell(pLib, gateId)->n_outputs > 1 ) -//            continue; +        gateId = Vec_IntEntry( p->vGates, i );          assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );          gateId = Vec_IntEntry( vMinCells, gateId );          assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); -        Vec_IntWriteEntry( vGates, i, gateId ); +        Vec_IntWriteEntry( p->vGates, i, gateId ); +    } +    Abc_SclSclGates2MioGates( pLib, p ); +    Vec_IntFree( vMinCells ); +} +int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax ) +{ +    Vec_Int_t * vMinCells; +    Abc_Obj_t * pObj; +    int i, gateId, Counter = 0; +    vMinCells = Abc_SclFindMinAreas( pLib, fUseMax ); +    Abc_NtkForEachNode1( p, pObj, i ) +    { +        gateId = Vec_IntEntry( p->vGates, i ); +        Counter += ( gateId == Vec_IntEntry(vMinCells, gateId) );      } -    Abc_SclManSetGates( pLib, p, vGates );      Vec_IntFree( vMinCells ); -    Vec_IntFree( vGates ); +    return Counter;  }  /**Function************************************************************* diff --git a/src/misc/vec/vecFlt.h b/src/misc/vec/vecFlt.h index 43e34217..9eb13962 100644 --- a/src/misc/vec/vecFlt.h +++ b/src/misc/vec/vecFlt.h @@ -336,6 +336,11 @@ static inline float Vec_FltEntry( Vec_Flt_t * p, int i )      assert( i >= 0 && i < p->nSize );      return p->pArray[i];  } +static inline float * Vec_FltEntryP( Vec_Flt_t * p, int i ) +{ +    assert( i >= 0 && i < p->nSize ); +    return p->pArray + i; +}  /**Function*************************************************************  | 
