sclLoad.c 6.26 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/**CFile****************************************************************

  FileName    [sclLoad.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Standard-cell library representation.]

  Synopsis    [Wire/gate load computations.]

  Author      [Alan Mishchenko, Niklas Een]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - August 24, 2012.]

  Revision    [$Id: sclLoad.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]

***********************************************************************/

#include "sclInt.h"
#include "sclMan.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

37
  Synopsis    [Returns the wireload model for the given area.]
38 39 40 41 42 43 44 45

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
46
SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area )
47 48
{
    SC_WireLoad * pWL = NULL;
49 50 51
    char * pWLoadUsed = NULL;
    int i;
    if ( p->default_wire_load_sel && strlen(p->default_wire_load_sel) )
52 53
    {
        SC_WireLoadSel * pWLS = NULL;
54 55
        SC_LibForEachWireLoadSel( p, pWLS, i )
            if ( !strcmp(pWLS->pName, p->default_wire_load_sel) )
56
                break;
57
        if ( i == Vec_PtrSize(p->vWireLoadSels) )
58
        {
59
            Abc_Print( -1, "Cannot find wire load selection model \"%s\".\n", p->default_wire_load_sel );
60 61 62 63 64
            exit(1);
        }
        for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++)
            if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area <  Vec_FltEntry(pWLS->vAreaTo, i) )
            {
65
                pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i);
66 67 68
                break;
            }
        if ( i == Vec_FltSize(pWLS->vAreaFrom) )
69
            pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel);
70
    }
71 72
    else if ( p->default_wire_load && strlen(p->default_wire_load) )
        pWLoadUsed = p->default_wire_load;
73 74 75 76 77 78
    else
    {
        Abc_Print( 0, "No wire model given.\n" );
        return NULL;
    }
    // Get the actual table and reformat it for 'wire_cap' output:
79 80 81
    assert( pWLoadUsed != NULL );
    SC_LibForEachWireLoad( p, pWL, i )
        if ( !strcmp(pWL->pName, pWLoadUsed) )
82
            break;
83
    if ( i == Vec_PtrSize(p->vWireLoads) )
84
    {
85
        Abc_Print( -1, "Cannot find wire load model \"%s\".\n", pWLoadUsed );
86 87
        exit(1);
    }
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
//    printf( "Using wireload model \"%s\".\n", pWL->pName );
    return pWL;
}

/**Function*************************************************************

  Synopsis    [Returns estimated wire capacitances for each fanout count.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p, SC_WireLoad * pWL )
{
    Vec_Flt_t * vCaps = NULL;
    float EntryPrev, EntryCur;
    int i, Entry, EntryMax;
    assert( pWL != NULL );
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    // find the biggest fanout
    EntryMax = 0;
    Vec_IntForEachEntry( pWL->vFanout, Entry, i )
        EntryMax = Abc_MaxInt( EntryMax, Entry );
    // create the array
    vCaps = Vec_FltStart( EntryMax + 1 );
    Vec_IntForEachEntry( pWL->vFanout, Entry, i )
        Vec_FltWriteEntry( vCaps, Entry, Vec_FltEntry(pWL->vLen, i) * pWL->cap );
    // reformat
    EntryPrev = 0;
    Vec_FltForEachEntry( vCaps, EntryCur, i )
    {
        if ( EntryCur )
            EntryPrev = EntryCur;
        else
            Vec_FltWriteEntry( vCaps, i, EntryPrev );
    }
    return vCaps;
}

/**Function*************************************************************

131
  Synopsis    [Computes load for all nodes in the network.]
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_SclComputeLoad( SC_Man * p )
{
    Vec_Flt_t * vWireCaps;
    Abc_Obj_t * pObj, * pFanin;
    int i, k;
    // clear load storage
    Abc_NtkForEachObj( p->pNtk, pObj, i )
    {
        SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
        pLoad->rise = pLoad->fall = 0.0;
    }
    // add cell load
152
    Abc_NtkForEachNode1( p->pNtk, pObj, i )
153 154 155 156 157 158 159 160 161 162
    {
        SC_Cell * pCell = Abc_SclObjCell( p, pObj );
        Abc_ObjForEachFanin( pObj, pFanin, k )
        {
            SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
            SC_Pin * pPin = SC_CellPin( pCell, k );
            pLoad->rise += pPin->rise_cap;
            pLoad->fall += pPin->fall_cap;
        }
    }
163
    if ( p->pWLoadUsed == NULL )
164
        return;
165
    // add wire load
166 167
    vWireCaps = Abc_SclFindWireCaps( p, p->pWLoadUsed );
    Abc_NtkForEachNode1( p->pNtk, pObj, i )
168
    {
169 170 171 172
        SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
        k = Abc_MinInt( Vec_FltSize(vWireCaps)-1, Abc_ObjFanoutNum(pObj) );
        pLoad->rise += Vec_FltEntry(vWireCaps, k);
        pLoad->fall += Vec_FltEntry(vWireCaps, k);
173
    }
174
    Vec_FltFree( vWireCaps );
175
}
176 177 178 179 180 181 182 183 184 185 186 187

/**Function*************************************************************

  Synopsis    [Updates load of the node's fanins.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew )
{
    Abc_Obj_t * pFanin;
    int k;
    Abc_ObjForEachFanin( pObj, pFanin, k )
    {
        SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
        SC_Pin * pPinOld = SC_CellPin( pOld, k );
        SC_Pin * pPinNew = SC_CellPin( pNew, k );
        pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap;
        pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap;
    }
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END