sclLib.h 25.3 KB
Newer Older
1 2
/**CFile****************************************************************

3
  FileName    [sclLib.h]
4 5 6

  SystemName  [ABC: Logic synthesis and verification system.]

7 8 9
  PackageName [Standard-cell library representation.]

  Synopsis    [Simplified library representation for STA.]
10 11 12 13 14 15 16

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

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

17
  Revision    [$Id: sclLib.h,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18 19 20

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

21 22
#ifndef ABC__map__scl__sclLib_h
#define ABC__map__scl__sclLib_h
23 24 25 26 27 28 29 30 31 32


////////////////////////////////////////////////////////////////////////
///                          INCLUDES                                ///
////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
33
#include <math.h>
34
#include "misc/vec/vec.h"
35 36 37 38 39 40 41 42

ABC_NAMESPACE_HEADER_START


////////////////////////////////////////////////////////////////////////
///                         PARAMETERS                               ///
////////////////////////////////////////////////////////////////////////

43
#define ABC_SCL_CUR_VERSION 8
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

typedef enum  
{
    sc_dir_NULL,
    sc_dir_Input,
    sc_dir_Output,
    sc_dir_InOut,
    sc_dir_Internal,
} SC_Dir;

typedef enum      // -- timing sense, positive-, negative- or non-unate
{
    sc_ts_NULL,
    sc_ts_Pos,
    sc_ts_Neg,
    sc_ts_Non,
} SC_TSense;

62 63 64 65 66 67 68
typedef struct SC_Pair_         SC_Pair;
struct SC_Pair_ 
{
    float      rise;
    float      fall;
};

69 70 71
typedef struct SC_SizePars_    SC_SizePars;
struct SC_SizePars_
{
72 73
    int        nIters;
    int        nIterNoChange;
74 75
    int        Window;           // used for upsizing
    int        Ratio;            // used for upsizing
76
    int        Notches;
77 78
    int        DelayUser;
    int        DelayGap;
79
    int        TimeOut;
80
    int        BuffTreeEst;      // ratio for buffer tree estimation
81
    int        BypassFreq;       // frequency to try bypassing
82 83
    int        fUseDept;
    int        fDumpStats;
84
    int        fUseWireLoads;
85 86 87 88
    int        fVerbose;
    int        fVeryVerbose;
};

89 90 91 92 93 94 95 96 97
typedef struct SC_BusPars_     SC_BusPars;
struct SC_BusPars_
{
    int        GainRatio;       // target gain
    int        Slew;            // target slew
    int        nDegree;         // max branching factor
    int        fSizeOnly;       // perform only sizing
    int        fAddBufs;        // add buffers
    int        fBufPis;         // use CI buffering
98
    int        fUseWireLoads;   // wire loads
99 100
    int        fVerbose;        // verbose
    int        fVeryVerbose;    // verbose
101 102
};

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
////////////////////////////////////////////////////////////////////////
///                    STRUCTURE DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

typedef struct SC_WireLoad_    SC_WireLoad;
typedef struct SC_WireLoadSel_ SC_WireLoadSel;
typedef struct SC_TableTempl_  SC_TableTempl;
typedef struct SC_Surface_     SC_Surface;
typedef struct SC_Timing_      SC_Timing;
typedef struct SC_Timings_     SC_Timings;
typedef struct SC_Pin_         SC_Pin;
typedef struct SC_Cell_        SC_Cell;
typedef struct SC_Lib_         SC_Lib;

struct SC_WireLoad_ 
{
119
    char *         pName;
120
    float          cap;            // }- multiply estimation in 'fanout_len[].snd' with this value
121
    float          slope;          // used to extrapolate wireload for large fanout count
122 123 124 125 126 127
    Vec_Int_t *    vFanout;        // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)'
    Vec_Flt_t *    vLen;
};

struct SC_WireLoadSel_
{
128
    char *         pName;
129 130 131 132 133 134 135
    Vec_Flt_t *    vAreaFrom;      // Vec<Trip<float,float,Str> > -- triplets '(from-area, upto-area, wire-load-model)'; range is [from, upto[
    Vec_Flt_t *    vAreaTo;
    Vec_Ptr_t *    vWireLoadModel;
};

struct SC_TableTempl_ 
{
136
    char *         pName;
137 138 139 140 141 142
    Vec_Ptr_t *    vVars;          // Vec<Str>         -- name of variable (numbered from 0, not 1 as in the Liberty file) 
    Vec_Ptr_t *    vIndex;         // Vec<Vec<float> > -- this is the point of measurement in table for the given variable 
};

struct SC_Surface_ 
{
143
    char *         pName;
144 145 146
    Vec_Flt_t *    vIndex0;        // Vec<float>       -- correspondes to "index_1" in the liberty file (for timing: slew)
    Vec_Flt_t *    vIndex1;        // Vec<float>       -- correspondes to "index_2" in the liberty file (for timing: load)
    Vec_Ptr_t *    vData;          // Vec<Vec<float> > -- 'data[i0][i1]' gives value at '(index0[i0], index1[i1])' 
147
    float          approx[3][6];
148 149 150 151 152 153
};

struct SC_Timing_ 
{
    char *         related_pin;    // -- related pin
    SC_TSense      tsense;         // -- timing sense (positive_unate, negative_unate, non_unate)
154
    char *         when_text;      // -- logic condition on inputs triggering this delay model for the output (currently not used)
155 156 157 158 159 160 161 162
    SC_Surface *   pCellRise;      // -- Used to compute pin-to-pin delay
    SC_Surface *   pCellFall;
    SC_Surface *   pRiseTrans;     // -- Used to compute output slew
    SC_Surface *   pFallTrans;
};

struct SC_Timings_ 
{
163
    char *         pName;          // -- the 'related_pin' field
164 165 166 167 168
    Vec_Ptr_t *    vTimings;       // structures of type SC_Timing
};

struct SC_Pin_ 
{
169
    char *         pName;
170
    SC_Dir         dir;
171
    float          cap;            // -- this value is used if 'rise_cap' and 'fall_cap' is missing (copied by 'postProcess()'). (not used)
172 173
    float          rise_cap;       // }- used for input pins ('cap' too).
    float          fall_cap;       // }
174 175
    float          max_out_cap;    // } (not used)
    float          max_out_slew;   // }- used only for output pins (max values must not be exceeded or else mapping is illegal) (not used)
176 177 178 179 180 181 182
    char *         func_text;      // }
    Vec_Wrd_t *    vFunc;          // }
    Vec_Ptr_t *    vRTimings;      // -- for output pins
};

struct SC_Cell_ 
{
183
    char *         pName;
184
    int            Id;
Alan Mishchenko committed
185
    int            fSkip;          // skip this cell during genlib computation
186 187 188
    int            seq;            // -- set to TRUE by parser if a sequential element
    int            unsupp;         // -- set to TRUE by parser if cell contains information we cannot handle
    float          area;
189
    float          leakage;
190
    int            drive_strength; // -- some library files provide this field (currently unused, but may be a good hint for sizing) (not used)
191 192 193
    Vec_Ptr_t *    vPins;          // NamedSet<SC_Pin> 
    int            n_inputs;       // -- 'pins[0 .. n_inputs-1]' are input pins
    int            n_outputs;      // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins
194 195
    SC_Cell *      pNext;          // same-functionality cells linked into a ring by area
    SC_Cell *      pPrev;          // same-functionality cells linked into a ring by area
196 197
    SC_Cell *      pRepr;          // representative of the class
    SC_Cell *      pAve;           // average size cell of this class
198
    int            Order;          // order of the gate in the list
199
    int            nGates;         // the number of gates in the list      
200 201 202 203
};

struct SC_Lib_ 
{
204
    char *         pName;
205
    char *         pFileName;
206 207
    char *         default_wire_load;
    char *         default_wire_load_sel;
208
    float          default_max_out_slew;   // -- 'default_max_transition'; this is copied to each output pin where 'max_transition' is not defined  (not used)
209
    int            unit_time;      // -- Valid 9..12. Unit is '10^(-val)' seconds (e.g. 9=1ns, 10=100ps, 11=10ps, 12=1ps)
210 211
    float          unit_cap_fst;   // -- First part is a multiplier, second either 12 or 15 for 'pf' or 'ff'.
    int            unit_cap_snd;
212 213 214
    Vec_Ptr_t *    vWireLoads;     // NamedSet<SC_WireLoad>
    Vec_Ptr_t *    vWireLoadSels;  // NamedSet<SC_WireLoadSel>
    Vec_Ptr_t *    vTempls;        // NamedSet<SC_TableTempl>  
215
    Vec_Ptr_t *    vCells;         // NamedSet<SC_Cell>
216
    Vec_Ptr_t *    vCellClasses;   // NamedSet<SC_Cell>
217 218
    int *          pBins;          // hashing gateName -> gateId
    int            nBins;
219 220 221 222 223 224 225 226 227 228
};

////////////////////////////////////////////////////////////////////////
///                       GLOBAL VARIABLES                           ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                       MACRO DEFINITIONS                          ///
////////////////////////////////////////////////////////////////////////

229 230 231 232 233 234 235 236 237
static inline void        SC_PairClean( SC_Pair * d )               { d->rise = d->fall = 0;                 }
static inline float       SC_PairMax( SC_Pair * d )                 { return Abc_MaxFloat(d->rise, d->fall); }
static inline float       SC_PairMin( SC_Pair * d )                 { return Abc_MinFloat(d->rise, d->fall); }
static inline float       SC_PairAve( SC_Pair * d )                 { return 0.5 * d->rise + 0.5 * d->fall;  }
static inline void        SC_PairDup( SC_Pair * d, SC_Pair * s )    { *d = *s;                               }
static inline void        SC_PairMove( SC_Pair * d, SC_Pair * s )   { *d = *s; s->rise = s->fall = 0;        }
static inline int         SC_PairEqual( SC_Pair * d, SC_Pair * s )  { return d->rise == s->rise && d->fall == s->fall;                }
static inline int         SC_PairEqualE( SC_Pair * d, SC_Pair * s, float E )  { return d->rise - s->rise < E && s->rise - d->rise < E &&  d->fall - s->fall < E && s->fall - d->fall < E;    }

238
static inline int         SC_LibCellNum( SC_Lib * p )               { return Vec_PtrSize(p->vCells);                                  }
239 240 241
static inline SC_Cell *   SC_LibCell( SC_Lib * p, int i )           { return (SC_Cell *)Vec_PtrEntry(p->vCells, i);                   }
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;                       }
242
static inline float       SC_CellPinCap( SC_Cell * p, int i )       { return 0.5 * SC_CellPin(p, i)->rise_cap + 0.5 * SC_CellPin(p, i)->fall_cap; }
243
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 / Abc_MaxInt(1, p->n_inputs); }
244 245
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;                                 }
246

247 248 249 250 251 252 253 254 255
#define SC_LibForEachCell( p, pCell, i )         Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
#define SC_LibForEachCellClass( p, pCell, i )    Vec_PtrForEachEntry( SC_Cell *, p->vCellClasses, pCell, i )
#define SC_LibForEachWireLoad( p, pWL, i )       Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i )
#define SC_LibForEachWireLoadSel( p, pWLS, i )   Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i )
#define SC_LibForEachTempl( p, pTempl, i )       Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTempl, i )
#define SC_CellForEachPin( p, pPin, i )          Vec_PtrForEachEntry( SC_Pin *, p->vPins, pPin, i )
#define SC_CellForEachPinIn( p, pPin, i )        Vec_PtrForEachEntryStop( SC_Pin *, p->vPins, pPin, i, p->n_inputs )
#define SC_CellForEachPinOut( p, pPin, i )       Vec_PtrForEachEntryStart( SC_Pin *, p->vPins, pPin, i, p->n_inputs )
#define SC_RingForEachCell( pRing, pCell, i )    for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ )
256
#define SC_RingForEachCellRev( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pPrev, i++ )
257
#define SC_PinForEachRTiming( p, pRTime, i )     Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pRTime, i )
258

259

260 261 262 263
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

264 265 266 267 268 269 270 271 272 273 274
/**Function*************************************************************

  Synopsis    [Constructors of the library data-structures.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
static inline SC_WireLoad * Abc_SclWireLoadAlloc()
{
    SC_WireLoad * p;
    p = ABC_CALLOC( SC_WireLoad, 1 );
    p->vFanout = Vec_IntAlloc( 0 );
    p->vLen    = Vec_FltAlloc( 0 );
    return p;
}
static inline SC_WireLoadSel * Abc_SclWireLoadSelAlloc()
{
    SC_WireLoadSel * p;
    p = ABC_CALLOC( SC_WireLoadSel, 1 );
    p->vAreaFrom      = Vec_FltAlloc( 0 );
    p->vAreaTo        = Vec_FltAlloc( 0 );
    p->vWireLoadModel = Vec_PtrAlloc( 0 );
    return p;
}
static inline SC_TableTempl * Abc_SclTableTemplAlloc()
{
    SC_TableTempl * p;
    p = ABC_CALLOC( SC_TableTempl, 1 );
    p->vVars  = Vec_PtrAlloc( 0 );
    p->vIndex = Vec_PtrAlloc( 0 );
    return p;
}
static inline SC_Surface * Abc_SclSurfaceAlloc()
{
    SC_Surface * p;
    p = ABC_CALLOC( SC_Surface, 1 );
    p->vIndex0   = Vec_FltAlloc( 0 );
    p->vIndex1   = Vec_FltAlloc( 0 );
    p->vData     = Vec_PtrAlloc( 0 );
    return p;
}
static inline SC_Timing * Abc_SclTimingAlloc()
{
    SC_Timing * p;
    p = ABC_CALLOC( SC_Timing, 1 );
    p->pCellRise  = Abc_SclSurfaceAlloc();  
    p->pCellFall  = Abc_SclSurfaceAlloc();
    p->pRiseTrans = Abc_SclSurfaceAlloc(); 
    p->pFallTrans = Abc_SclSurfaceAlloc();
    return p;
}
static inline SC_Timings * Abc_SclTimingsAlloc()
{
    SC_Timings * p;
    p = ABC_CALLOC( SC_Timings, 1 );
323
    p->vTimings   = Vec_PtrAlloc( 0 );
324 325 326 327 328 329 330
    return p;
}
static inline SC_Pin * Abc_SclPinAlloc()
{
    SC_Pin * p;
    p = ABC_CALLOC( SC_Pin, 1 );
    p->max_out_slew = -1;
331 332
    p->vFunc        = Vec_WrdAlloc( 0 );
    p->vRTimings    = Vec_PtrAlloc( 0 );
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    return p;
}
static inline SC_Cell * Abc_SclCellAlloc()
{
    SC_Cell * p;
    p = ABC_CALLOC( SC_Cell, 1 );
    p->vPins = Vec_PtrAlloc( 0 );
    return p;
}
static inline SC_Lib * Abc_SclLibAlloc()
{
    SC_Lib * p;
    p = ABC_CALLOC( SC_Lib, 1 );
    p->default_max_out_slew = -1;
    p->unit_time      = 9;
348 349
    p->unit_cap_fst   = 1;
    p->unit_cap_snd   = 12;
350 351 352 353
    p->vWireLoads     = Vec_PtrAlloc( 0 );
    p->vWireLoadSels  = Vec_PtrAlloc( 0 );
    p->vTempls        = Vec_PtrAlloc( 0 );
    p->vCells         = Vec_PtrAlloc( 0 );
354
    p->vCellClasses   = Vec_PtrAlloc( 0 );
355 356 357 358
    return p;
}


359 360 361 362 363 364 365 366 367 368 369
/**Function*************************************************************

  Synopsis    [Destructors of the library data-structures.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
370 371 372 373
static inline void Abc_SclWireLoadFree( SC_WireLoad * p )
{
    Vec_IntFree( p->vFanout );
    Vec_FltFree( p->vLen );
374
    ABC_FREE( p->pName );
375 376 377 378 379 380 381
    ABC_FREE( p );
}
static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p )
{
    Vec_FltFree( p->vAreaFrom );
    Vec_FltFree( p->vAreaTo );
    Vec_PtrFreeFree( p->vWireLoadModel );
382
    ABC_FREE( p->pName );
383 384 385 386 387 388
    ABC_FREE( p );
}
static inline void Abc_SclTableTemplFree( SC_TableTempl * p )
{
    Vec_PtrFreeFree( p->vVars );
    Vec_VecFree( (Vec_Vec_t *)p->vIndex );
389
    ABC_FREE( p->pName );
390 391 392 393 394 395 396
    ABC_FREE( p );
}
static inline void Abc_SclSurfaceFree( SC_Surface * p )
{
    Vec_FltFree( p->vIndex0 );
    Vec_FltFree( p->vIndex1 );
    Vec_VecFree( (Vec_Vec_t *)p->vData );
397
    ABC_FREE( p->pName );
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
    ABC_FREE( p );
}
static inline void Abc_SclTimingFree( SC_Timing * p )
{
    Abc_SclSurfaceFree( p->pCellRise );
    Abc_SclSurfaceFree( p->pCellFall );
    Abc_SclSurfaceFree( p->pRiseTrans );
    Abc_SclSurfaceFree( p->pFallTrans );
    ABC_FREE( p->related_pin );
    ABC_FREE( p->when_text );
    ABC_FREE( p );
}
static inline void Abc_SclTimingsFree( SC_Timings * p )
{
    SC_Timing * pTemp;
    int i;
    Vec_PtrForEachEntry( SC_Timing *, p->vTimings, pTemp, i )
        Abc_SclTimingFree( pTemp );
    Vec_PtrFree( p->vTimings );
417
    ABC_FREE( p->pName );
418 419 420 421 422 423
    ABC_FREE( p );
}
static inline void Abc_SclPinFree( SC_Pin * p )
{
    SC_Timings * pTemp;
    int i;
424
    SC_PinForEachRTiming( p, pTemp, i )
425 426 427 428
        Abc_SclTimingsFree( pTemp );
    Vec_PtrFree( p->vRTimings );
    Vec_WrdFree( p->vFunc );
    ABC_FREE( p->func_text );
429
    ABC_FREE( p->pName );
430 431 432 433 434 435
    ABC_FREE( p );
}
static inline void Abc_SclCellFree( SC_Cell * p )
{
    SC_Pin * pTemp;
    int i;
436
    SC_CellForEachPin( p, pTemp, i )
437 438
        Abc_SclPinFree( pTemp );
    Vec_PtrFree( p->vPins );
439
    ABC_FREE( p->pName );
440 441 442 443
    ABC_FREE( p );
}
static inline void Abc_SclLibFree( SC_Lib * p )
{
444 445 446 447
    SC_WireLoad * pWL;
    SC_WireLoadSel * pWLS;
    SC_TableTempl * pTempl;
    SC_Cell * pCell;
448
    int i;
449
    SC_LibForEachWireLoad( p, pWL, i )
450
        Abc_SclWireLoadFree( pWL );
451
    Vec_PtrFree( p->vWireLoads );
452
    SC_LibForEachWireLoadSel( p, pWLS, i )
453
        Abc_SclWireLoadSelFree( pWLS );
454
    Vec_PtrFree( p->vWireLoadSels );
455
    SC_LibForEachTempl( p, pTempl, i )
456
        Abc_SclTableTemplFree( pTempl );
457
    Vec_PtrFree( p->vTempls );
458
    SC_LibForEachCell( p, pCell, i )
459
        Abc_SclCellFree( pCell );
460
    Vec_PtrFree( p->vCells );
461
    Vec_PtrFree( p->vCellClasses );
462
    ABC_FREE( p->pName );
463
    ABC_FREE( p->pFileName );
464 465
    ABC_FREE( p->default_wire_load );
    ABC_FREE( p->default_wire_load_sel );
466
    ABC_FREE( p->pBins );
467 468 469 470
    ABC_FREE( p );
}


471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
/**Function*************************************************************

  Synopsis    [Lookup table delay computation.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline float Scl_LibLookup( SC_Surface * p, float slew, float load )
{
    float * pIndex0, * pIndex1, * pDataS, * pDataS1;
    float sfrac, lfrac, p0, p1;
    int s, l;

488 489 490 491 492 493 494 495 496
    // handle constant table
    if ( Vec_FltSize(p->vIndex0) == 1 && Vec_FltSize(p->vIndex1) == 1 )
    {
        Vec_Flt_t * vTemp = (Vec_Flt_t *)Vec_PtrEntry(p->vData, 0);
        assert( Vec_PtrSize(p->vData) == 1 );
        assert( Vec_FltSize(vTemp) == 1 );
        return Vec_FltEntry(vTemp, 0);
    }

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
    // Find closest sample points in surface:
    pIndex0 = Vec_FltArray(p->vIndex0);
    for ( s = 1; s < Vec_FltSize(p->vIndex0)-1; s++ )
        if ( pIndex0[s] > slew )
            break;
    s--;

    pIndex1 = Vec_FltArray(p->vIndex1);
    for ( l = 1; l < Vec_FltSize(p->vIndex1)-1; l++ )
        if ( pIndex1[l] > load )
            break;
    l--;

    // Interpolate (or extrapolate) function value from sample points:
    sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
    lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);

    pDataS  = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(p->vData, s) );
    pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(p->vData, s+1) );

    p0 = pDataS [l] + lfrac * (pDataS [l+1] - pDataS [l]);
    p1 = pDataS1[l] + lfrac * (pDataS1[l+1] - pDataS1[l]);

    return p0 + sfrac * (p1 - p0);      // <<== multiply result with K factor here 
}
static inline void Scl_LibPinArrival( SC_Timing * pTime, SC_Pair * pArrIn, SC_Pair * pSlewIn, SC_Pair * pLoad, SC_Pair * pArrOut, SC_Pair * pSlewOut )
{
    if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
    {
        pArrOut->rise  = Abc_MaxFloat( pArrOut->rise,  pArrIn->rise + Scl_LibLookup(pTime->pCellRise,  pSlewIn->rise, pLoad->rise) );
        pArrOut->fall  = Abc_MaxFloat( pArrOut->fall,  pArrIn->fall + Scl_LibLookup(pTime->pCellFall,  pSlewIn->fall, pLoad->fall) );
        pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise,                Scl_LibLookup(pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) );
        pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall,                Scl_LibLookup(pTime->pFallTrans, pSlewIn->fall, pLoad->fall) );
    }
    if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
    {
        pArrOut->rise  = Abc_MaxFloat( pArrOut->rise,  pArrIn->fall + Scl_LibLookup(pTime->pCellRise,  pSlewIn->fall, pLoad->rise) );
        pArrOut->fall  = Abc_MaxFloat( pArrOut->fall,  pArrIn->rise + Scl_LibLookup(pTime->pCellFall,  pSlewIn->rise, pLoad->fall) );
        pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise,                Scl_LibLookup(pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) );
        pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall,                Scl_LibLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) );
    }
}
static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_Pair * pSlewIn, SC_Pair * pLoad, SC_Pair * pDepOut )
{
    if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
    {
        pDepIn->rise  = Abc_MaxFloat( pDepIn->rise,  pDepOut->rise + Scl_LibLookup(pTime->pCellRise,  pSlewIn->rise, pLoad->rise) );
        pDepIn->fall  = Abc_MaxFloat( pDepIn->fall,  pDepOut->fall + Scl_LibLookup(pTime->pCellFall,  pSlewIn->fall, pLoad->fall) );
    }
    if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
    {
        pDepIn->fall  = Abc_MaxFloat( pDepIn->fall,  pDepOut->rise + Scl_LibLookup(pTime->pCellRise,  pSlewIn->fall, pLoad->rise) );
        pDepIn->rise  = Abc_MaxFloat( pDepIn->rise,  pDepOut->fall + Scl_LibLookup(pTime->pCellFall,  pSlewIn->rise, pLoad->fall) );
    }
}

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

555
  Synopsis    [Compute one timing edge.]
556 557 558 559 560 561 562 563

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
564
static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
565 566
{
    SC_Pin * pPin;
567 568 569 570 571
    SC_Timings * pRTime;
    assert( iPin >= 0 && iPin < pCell->n_inputs );
    pPin = SC_CellPin( pCell, pCell->n_inputs );
    assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
    pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin );
572 573
    if ( Vec_PtrSize(pRTime->vTimings) == 0 )
        return NULL;
574
    assert( Vec_PtrSize(pRTime->vTimings) == 1 );
575 576
    return (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
}
577
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float Load )
578
{
579
    SC_Pair LoadIn = { Load, Load };
580 581 582 583
    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 };
584
//    Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
585 586 587
//    SlewIn.fall = SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
    SlewIn.fall = SlewIn.rise = Slew; 
    Scl_LibPinArrival( Scl_CellPinTime(pCell, iPin), &ArrIn, &SlewIn, &LoadIn, &ArrOut, &SlewOut );
588
    return  0.5 * ArrOut.fall +  0.5 * ArrOut.rise;
589
}
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
static inline void Scl_LibHandleInputDriver( SC_Cell * pCell, SC_Pair * pLoadIn, SC_Pair * pArrOut, SC_Pair * pSlewOut )
{
    SC_Pair LoadIn   = { 0.0, 0.0 }; // zero input load
    SC_Pair ArrIn    = { 0.0, 0.0 }; // zero input time
    SC_Pair SlewIn   = { 0.0, 0.0 }; // zero input slew
    SC_Pair ArrOut0  = { 0.0, 0.0 }; // output time under zero load
    SC_Pair ArrOut1  = { 0.0, 0.0 }; // output time under given load
    SC_Pair SlewOut  = { 0.0, 0.0 }; // output slew under zero load 
    pSlewOut->fall = pSlewOut->rise = 0;
    assert( pCell->n_inputs == 1 );
    Scl_LibPinArrival( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, &LoadIn, &ArrOut0, &SlewOut );
    Scl_LibPinArrival( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, pLoadIn, &ArrOut1, pSlewOut );
    pArrOut->fall = ArrOut1.fall - ArrOut0.fall;
    pArrOut->rise = ArrOut1.rise - ArrOut0.rise;
}
605

606 607 608 609 610 611 612 613
/*=== sclLiberty.c ===============================================================*/
extern SC_Lib *      Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose );
/*=== sclLibScl.c ===============================================================*/
extern SC_Lib *      Abc_SclReadFromStr( Vec_Str_t * vOut );
extern SC_Lib *      Abc_SclReadFromFile( char * pFileName );
extern void          Abc_SclWriteScl( char * pFileName, SC_Lib * p );
extern void          Abc_SclWriteLiberty( char * pFileName, SC_Lib * p );
/*=== sclLibUtil.c ===============================================================*/
614 615
extern void          Abc_SclHashCells( SC_Lib * p );
extern int           Abc_SclCellFind( SC_Lib * p, char * pName );
616
extern int           Abc_SclClassCellNum( SC_Cell * pClass );
617
extern int           Abc_SclLibClassNum( SC_Lib * pLib );
618
extern void          Abc_SclLinkCells( SC_Lib * p );
619
extern void          Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain, int fInvOnly, int fShort );
620
extern void          Abc_SclConvertLeakageIntoArea( SC_Lib * p, float A, float B );
621
extern void          Abc_SclLibNormalize( SC_Lib * p );
622
extern SC_Cell *     Abc_SclFindInvertor( SC_Lib * p, int fFindBuff );
623
extern SC_Cell *     Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );
624
extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
625
extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );
626
extern int           Abc_SclHasDelayInfo( void * pScl );
627
extern float         Abc_SclComputeAverageSlew( SC_Lib * p );
628
extern void          Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
629
extern void          Abc_SclInstallGenlib( void * pScl, float Slew, float Gain, int nGatesMin );
630

631 632 633 634 635 636 637 638

ABC_NAMESPACE_HEADER_END

#endif

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