sclLib.h 25.4 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
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;        }
235
static inline void        SC_PairAdd( SC_Pair * d, SC_Pair * s )    { d->rise += s->rise; d->fall += s->fall;}
236 237 238
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;    }

239
static inline int         SC_LibCellNum( SC_Lib * p )               { return Vec_PtrSize(p->vCells);                                  }
240 241 242
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;                       }
243
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; }
244
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); }
245 246
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;                                 }
247

248 249 250 251 252 253 254 255 256
#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++ )
257
#define SC_RingForEachCellRev( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pPrev, i++ )
258
#define SC_PinForEachRTiming( p, pRTime, i )     Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pRTime, i )
259

260

261 262 263 264
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Constructors of the library data-structures.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
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 323
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 );
324
    p->vTimings   = Vec_PtrAlloc( 0 );
325 326 327 328 329 330 331
    return p;
}
static inline SC_Pin * Abc_SclPinAlloc()
{
    SC_Pin * p;
    p = ABC_CALLOC( SC_Pin, 1 );
    p->max_out_slew = -1;
332 333
    p->vFunc        = Vec_WrdAlloc( 0 );
    p->vRTimings    = Vec_PtrAlloc( 0 );
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
    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;
349 350
    p->unit_cap_fst   = 1;
    p->unit_cap_snd   = 12;
351 352 353 354
    p->vWireLoads     = Vec_PtrAlloc( 0 );
    p->vWireLoadSels  = Vec_PtrAlloc( 0 );
    p->vTempls        = Vec_PtrAlloc( 0 );
    p->vCells         = Vec_PtrAlloc( 0 );
355
    p->vCellClasses   = Vec_PtrAlloc( 0 );
356 357 358 359
    return p;
}


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

  Synopsis    [Destructors of the library data-structures.]

  Description []
               
  SideEffects []

  SeeAlso     []

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


472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
/**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;

489 490 491 492 493 494 495 496 497
    // 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);
    }

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 555
    // 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*************************************************************

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

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
565
static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
566 567
{
    SC_Pin * pPin;
568 569 570 571 572
    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 );
573 574
    if ( Vec_PtrSize(pRTime->vTimings) == 0 )
        return NULL;
575
    assert( Vec_PtrSize(pRTime->vTimings) == 1 );
576 577
    return (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
}
578
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float Load )
579
{
580
    SC_Pair LoadIn = { Load, Load };
581 582 583 584
    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 };
585
//    Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
586 587 588
//    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 );
589
    return  0.5 * ArrOut.fall +  0.5 * ArrOut.rise;
590
}
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
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;
}
606

607 608 609 610 611 612 613 614
/*=== 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 ===============================================================*/
615 616
extern void          Abc_SclHashCells( SC_Lib * p );
extern int           Abc_SclCellFind( SC_Lib * p, char * pName );
617
extern int           Abc_SclClassCellNum( SC_Cell * pClass );
618
extern int           Abc_SclLibClassNum( SC_Lib * pLib );
619
extern void          Abc_SclLinkCells( SC_Lib * p );
620
extern void          Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain, int fInvOnly, int fShort );
621
extern void          Abc_SclConvertLeakageIntoArea( SC_Lib * p, float A, float B );
622
extern void          Abc_SclLibNormalize( SC_Lib * p );
623
extern SC_Cell *     Abc_SclFindInvertor( SC_Lib * p, int fFindBuff );
624
extern SC_Cell *     Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );
625
extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
626
extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );
627
extern int           Abc_SclHasDelayInfo( void * pScl );
628
extern float         Abc_SclComputeAverageSlew( SC_Lib * p );
629
extern void          Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
630
extern void          Abc_SclInstallGenlib( void * pScl, float Slew, float Gain, int nGatesMin );
631

632 633 634 635 636 637 638 639

ABC_NAMESPACE_HEADER_END

#endif

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