1 /**CFile****************************************************************
2 
3   FileName    [sclLib.h]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Standard-cell library representation.]
8 
9   Synopsis    [Simplified library representation for STA.]
10 
11   Author      [Alan Mishchenko, Niklas Een]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - August 24, 2012.]
16 
17   Revision    [$Id: sclLib.h,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #ifndef ABC__map__scl__sclLib_h
22 #define ABC__map__scl__sclLib_h
23 
24 
25 ////////////////////////////////////////////////////////////////////////
26 ///                          INCLUDES                                ///
27 ////////////////////////////////////////////////////////////////////////
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 #include <math.h>
34 #include "misc/vec/vec.h"
35 
36 ABC_NAMESPACE_HEADER_START
37 
38 
39 ////////////////////////////////////////////////////////////////////////
40 ///                         PARAMETERS                               ///
41 ////////////////////////////////////////////////////////////////////////
42 
43 #define ABC_SCL_CUR_VERSION 8
44 
45 typedef enum
46 {
47     sc_dir_NULL,
48     sc_dir_Input,
49     sc_dir_Output,
50     sc_dir_InOut,
51     sc_dir_Internal,
52 } SC_Dir;
53 
54 typedef enum      // -- timing sense, positive-, negative- or non-unate
55 {
56     sc_ts_NULL,
57     sc_ts_Pos,
58     sc_ts_Neg,
59     sc_ts_Non,
60 } SC_TSense;
61 
62 typedef struct SC_Pair_         SC_Pair;
63 struct SC_Pair_
64 {
65     float      rise;
66     float      fall;
67 };
68 typedef struct SC_PairI_        SC_PairI;
69 struct SC_PairI_
70 {
71     int        rise;
72     int        fall;
73 };
74 
75 typedef struct SC_SizePars_    SC_SizePars;
76 struct SC_SizePars_
77 {
78     int        nIters;
79     int        nIterNoChange;
80     int        Window;           // used for upsizing
81     int        Ratio;            // used for upsizing
82     int        Notches;
83     int        DelayUser;
84     int        DelayGap;
85     int        TimeOut;
86     int        BuffTreeEst;      // ratio for buffer tree estimation
87     int        BypassFreq;       // frequency to try bypassing
88     int        fUseDept;
89     int        fDumpStats;
90     int        fUseWireLoads;
91     int        fVerbose;
92     int        fVeryVerbose;
93 };
94 
95 typedef struct SC_BusPars_     SC_BusPars;
96 struct SC_BusPars_
97 {
98     int        GainRatio;       // target gain
99     int        Slew;            // target slew
100     int        nDegree;         // max branching factor
101     int        fSizeOnly;       // perform only sizing
102     int        fAddBufs;        // add buffers
103     int        fBufPis;         // use CI buffering
104     int        fUseWireLoads;   // wire loads
105     int        fVerbose;        // verbose
106     int        fVeryVerbose;    // verbose
107 };
108 
109 ////////////////////////////////////////////////////////////////////////
110 ///                    STRUCTURE DEFINITIONS                         ///
111 ////////////////////////////////////////////////////////////////////////
112 
113 typedef struct SC_WireLoad_    SC_WireLoad;
114 typedef struct SC_WireLoadSel_ SC_WireLoadSel;
115 typedef struct SC_TableTempl_  SC_TableTempl;
116 typedef struct SC_Surface_     SC_Surface;
117 typedef struct SC_Timing_      SC_Timing;
118 typedef struct SC_Timings_     SC_Timings;
119 typedef struct SC_Pin_         SC_Pin;
120 typedef struct SC_Cell_        SC_Cell;
121 typedef struct SC_Lib_         SC_Lib;
122 
123 struct SC_WireLoad_
124 {
125     char *         pName;
126     float          cap;            // }- multiply estimation in 'fanout_len[].snd' with this value
127     float          slope;          // used to extrapolate wireload for large fanout count
128     Vec_Int_t      vFanout;        // Vec<Pair<uint,float> > -- pairs '(#fanouts, est-wire-len)'
129     Vec_Flt_t      vLen;
130 };
131 
132 struct SC_WireLoadSel_
133 {
134     char *         pName;
135     Vec_Flt_t      vAreaFrom;      // Vec<Trip<float,float,Str> > -- triplets '(from-area, upto-area, wire-load-model)'; range is [from, upto[
136     Vec_Flt_t      vAreaTo;
137     Vec_Ptr_t      vWireLoadModel;
138 };
139 
140 struct SC_TableTempl_
141 {
142     char *         pName;
143     Vec_Ptr_t      vVars;          // Vec<Str>         -- name of variable (numbered from 0, not 1 as in the Liberty file)
144     Vec_Ptr_t      vIndex;         // Vec<Vec<float> > -- this is the point of measurement in table for the given variable
145 };
146 
147 struct SC_Surface_
148 {
149     char *         pName;
150     Vec_Flt_t      vIndex0;        // Vec<float>       -- correspondes to "index_1" in the liberty file (for timing: slew)
151     Vec_Flt_t      vIndex1;        // Vec<float>       -- correspondes to "index_2" in the liberty file (for timing: load)
152     Vec_Ptr_t      vData;          // Vec<Vec<float> > -- 'data[i0][i1]' gives value at '(index0[i0], index1[i1])'
153     Vec_Int_t      vIndex0I;       // Vec<float>       -- correspondes to "index_1" in the liberty file (for timing: slew)
154     Vec_Int_t      vIndex1I;       // Vec<float>       -- correspondes to "index_2" in the liberty file (for timing: load)
155     Vec_Ptr_t      vDataI;         // Vec<Vec<float> > -- 'data[i0][i1]' gives value at '(index0[i0], index1[i1])'
156     float          approx[3][6];
157 };
158 
159 struct SC_Timing_
160 {
161     char *         related_pin;    // -- related pin
162     SC_TSense      tsense;         // -- timing sense (positive_unate, negative_unate, non_unate)
163     char *         when_text;      // -- logic condition on inputs triggering this delay model for the output (currently not used)
164     SC_Surface     pCellRise;      // -- Used to compute pin-to-pin delay
165     SC_Surface     pCellFall;
166     SC_Surface     pRiseTrans;     // -- Used to compute output slew
167     SC_Surface     pFallTrans;
168 };
169 
170 struct SC_Timings_
171 {
172     char *         pName;          // -- the 'related_pin' field
173     Vec_Ptr_t      vTimings;       // structures of type SC_Timing
174 };
175 
176 struct SC_Pin_
177 {
178     char *         pName;
179     SC_Dir         dir;
180     float          cap;            // -- this value is used if 'rise_cap' and 'fall_cap' is missing (copied by 'postProcess()'). (not used)
181     float          rise_cap;       // }- used for input pins ('cap' too).
182     float          fall_cap;       // }
183     int            rise_capI;      // }- used for input pins ('cap' too).
184     int            fall_capI;      // }
185     float          max_out_cap;    // } (not used)
186     float          max_out_slew;   // }- used only for output pins (max values must not be exceeded or else mapping is illegal) (not used)
187     char *         func_text;      // }
188     Vec_Wrd_t      vFunc;          // }
189     Vec_Ptr_t      vRTimings;      // -- for output pins
190 //    SC_Timing      Timing;         // -- for output pins
191 };
192 
193 struct SC_Cell_
194 {
195     char *         pName;
196     int            Id;
197     int            fSkip;          // skip this cell during genlib computation
198     int            seq;            // -- set to TRUE by parser if a sequential element
199     int            unsupp;         // -- set to TRUE by parser if cell contains information we cannot handle
200     float          area;
201     float          leakage;
202     int            areaI;
203     int            leakageI;
204     int            drive_strength; // -- some library files provide this field (currently unused, but may be a good hint for sizing) (not used)
205     Vec_Ptr_t      vPins;          // NamedSet<SC_Pin>
206     int            n_inputs;       // -- 'pins[0 .. n_inputs-1]' are input pins
207     int            n_outputs;      // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins
208     SC_Cell *      pNext;          // same-functionality cells linked into a ring by area
209     SC_Cell *      pPrev;          // same-functionality cells linked into a ring by area
210     SC_Cell *      pRepr;          // representative of the class
211     SC_Cell *      pAve;           // average size cell of this class
212     int            Order;          // order of the gate in the list
213     int            nGates;         // the number of gates in the list
214 };
215 
216 struct SC_Lib_
217 {
218     char *         pName;
219     char *         pFileName;
220     char *         default_wire_load;
221     char *         default_wire_load_sel;
222     float          default_max_out_slew;   // -- 'default_max_transition'; this is copied to each output pin where 'max_transition' is not defined  (not used)
223     int            unit_time;      // -- Valid 9..12. Unit is '10^(-val)' seconds (e.g. 9=1ns, 10=100ps, 11=10ps, 12=1ps)
224     float          unit_cap_fst;   // -- First part is a multiplier, second either 12 or 15 for 'pf' or 'ff'.
225     int            unit_cap_snd;
226     Vec_Ptr_t      vWireLoads;     // NamedSet<SC_WireLoad>
227     Vec_Ptr_t      vWireLoadSels;  // NamedSet<SC_WireLoadSel>
228     Vec_Ptr_t      vTempls;        // NamedSet<SC_TableTempl>
229     Vec_Ptr_t      vCells;         // NamedSet<SC_Cell>
230     Vec_Ptr_t      vCellClasses;   // NamedSet<SC_Cell>
231     int *          pBins;          // hashing gateName -> gateId
232     int            nBins;
233 };
234 
235 ////////////////////////////////////////////////////////////////////////
236 ///                       GLOBAL VARIABLES                           ///
237 ////////////////////////////////////////////////////////////////////////
238 
239 ////////////////////////////////////////////////////////////////////////
240 ///                       MACRO DEFINITIONS                          ///
241 ////////////////////////////////////////////////////////////////////////
242 
SC_PairClean(SC_Pair * d)243 static inline void        SC_PairClean( SC_Pair * d )               { d->rise = d->fall = 0;                 }
SC_PairMax(SC_Pair * d)244 static inline float       SC_PairMax( SC_Pair * d )                 { return Abc_MaxFloat(d->rise, d->fall); }
SC_PairMin(SC_Pair * d)245 static inline float       SC_PairMin( SC_Pair * d )                 { return Abc_MinFloat(d->rise, d->fall); }
SC_PairAve(SC_Pair * d)246 static inline float       SC_PairAve( SC_Pair * d )                 { return 0.5 * d->rise + 0.5 * d->fall;  }
SC_PairDup(SC_Pair * d,SC_Pair * s)247 static inline void        SC_PairDup( SC_Pair * d, SC_Pair * s )    { *d = *s;                               }
SC_PairMove(SC_Pair * d,SC_Pair * s)248 static inline void        SC_PairMove( SC_Pair * d, SC_Pair * s )   { *d = *s; s->rise = s->fall = 0;        }
SC_PairAdd(SC_Pair * d,SC_Pair * s)249 static inline void        SC_PairAdd( SC_Pair * d, SC_Pair * s )    { d->rise += s->rise; d->fall += s->fall;}
SC_PairEqual(SC_Pair * d,SC_Pair * s)250 static inline int         SC_PairEqual( SC_Pair * d, SC_Pair * s )  { return d->rise == s->rise && d->fall == s->fall;                }
SC_PairEqualE(SC_Pair * d,SC_Pair * s,float E)251 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;    }
252 
SC_LibCellNum(SC_Lib * p)253 static inline int         SC_LibCellNum( SC_Lib * p )               { return Vec_PtrSize(&p->vCells);                                  }
SC_LibCell(SC_Lib * p,int i)254 static inline SC_Cell *   SC_LibCell( SC_Lib * p, int i )           { return (SC_Cell *)Vec_PtrEntry(&p->vCells, i);                   }
SC_CellPin(SC_Cell * p,int i)255 static inline SC_Pin  *   SC_CellPin( SC_Cell * p, int i )          { return (SC_Pin *)Vec_PtrEntry(&p->vPins, i);                     }
SC_CellFunc(SC_Cell * p)256 static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p )                { return &SC_CellPin(p, p->n_inputs)->vFunc;                       }
SC_CellPinCap(SC_Cell * p,int i)257 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; }
SC_CellPinCapAve(SC_Cell * p)258 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); }
SC_CellPinOutFunc(SC_Cell * p,int i)259 static inline char *      SC_CellPinOutFunc( SC_Cell * p, int i )   { return SC_CellPin(p, p->n_inputs + i)->func_text;               }
SC_CellPinName(SC_Cell * p,int i)260 static inline char *      SC_CellPinName( SC_Cell * p, int i )      { return SC_CellPin(p, i)->pName;                                 }
261 
262 #define SC_LibForEachCell( p, pCell, i )         Vec_PtrForEachEntry( SC_Cell *, &p->vCells, pCell, i )
263 #define SC_LibForEachCellClass( p, pCell, i )    Vec_PtrForEachEntry( SC_Cell *, &p->vCellClasses, pCell, i )
264 #define SC_LibForEachWireLoad( p, pWL, i )       Vec_PtrForEachEntry( SC_WireLoad *, &p->vWireLoads, pWL, i )
265 #define SC_LibForEachWireLoadSel( p, pWLS, i )   Vec_PtrForEachEntry( SC_WireLoadSel *, &p->vWireLoadSels, pWLS, i )
266 #define SC_LibForEachTempl( p, pTempl, i )       Vec_PtrForEachEntry( SC_TableTempl *, &p->vTempls, pTempl, i )
267 #define SC_CellForEachPin( p, pPin, i )          Vec_PtrForEachEntry( SC_Pin *, &p->vPins, pPin, i )
268 #define SC_CellForEachPinIn( p, pPin, i )        Vec_PtrForEachEntryStop( SC_Pin *, &p->vPins, pPin, i, p->n_inputs )
269 #define SC_CellForEachPinOut( p, pPin, i )       Vec_PtrForEachEntryStart( SC_Pin *, &p->vPins, pPin, i, p->n_inputs )
270 #define SC_RingForEachCell( pRing, pCell, i )    for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ )
271 #define SC_RingForEachCellRev( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pPrev, i++ )
272 #define SC_PinForEachRTiming( p, pRTime, i )     Vec_PtrForEachEntry( SC_Timings *, &p->vRTimings, pRTime, i )
273 
274 
275 ////////////////////////////////////////////////////////////////////////
276 ///                     FUNCTION DEFINITIONS                         ///
277 ////////////////////////////////////////////////////////////////////////
278 
279 /**Function*************************************************************
280 
281   Synopsis    [Constructors of the library data-structures.]
282 
283   Description []
284 
285   SideEffects []
286 
287   SeeAlso     []
288 
289 ***********************************************************************/
Abc_SclWireLoadAlloc()290 static inline SC_WireLoad * Abc_SclWireLoadAlloc()
291 {
292     SC_WireLoad * p;
293     p = ABC_CALLOC( SC_WireLoad, 1 );
294     return p;
295 }
Abc_SclWireLoadSelAlloc()296 static inline SC_WireLoadSel * Abc_SclWireLoadSelAlloc()
297 {
298     SC_WireLoadSel * p;
299     p = ABC_CALLOC( SC_WireLoadSel, 1 );
300     return p;
301 }
Abc_SclTableTemplAlloc()302 static inline SC_TableTempl * Abc_SclTableTemplAlloc()
303 {
304     SC_TableTempl * p;
305     p = ABC_CALLOC( SC_TableTempl, 1 );
306     return p;
307 }
Abc_SclSurfaceAlloc()308 static inline SC_Surface * Abc_SclSurfaceAlloc()
309 {
310     SC_Surface * p;
311     p = ABC_CALLOC( SC_Surface, 1 );
312     return p;
313 }
Abc_SclTimingAlloc()314 static inline SC_Timing * Abc_SclTimingAlloc()
315 {
316     SC_Timing * p;
317     p = ABC_CALLOC( SC_Timing, 1 );
318     return p;
319 }
Abc_SclTimingsAlloc()320 static inline SC_Timings * Abc_SclTimingsAlloc()
321 {
322     SC_Timings * p;
323     p = ABC_CALLOC( SC_Timings, 1 );
324     return p;
325 }
Abc_SclPinAlloc()326 static inline SC_Pin * Abc_SclPinAlloc()
327 {
328     SC_Pin * p;
329     p = ABC_CALLOC( SC_Pin, 1 );
330     p->max_out_slew = -1;
331     return p;
332 }
Abc_SclCellAlloc()333 static inline SC_Cell * Abc_SclCellAlloc()
334 {
335     SC_Cell * p;
336     p = ABC_CALLOC( SC_Cell, 1 );
337     return p;
338 }
Abc_SclLibAlloc()339 static inline SC_Lib * Abc_SclLibAlloc()
340 {
341     SC_Lib * p;
342     p = ABC_CALLOC( SC_Lib, 1 );
343     p->default_max_out_slew = -1;
344     p->unit_time      = 9;
345     p->unit_cap_fst   = 1;
346     p->unit_cap_snd   = 12;
347     return p;
348 }
349 
350 
351 /**Function*************************************************************
352 
353   Synopsis    [Destructors of the library data-structures.]
354 
355   Description []
356 
357   SideEffects []
358 
359   SeeAlso     []
360 
361 ***********************************************************************/
Abc_SclWireLoadFree(SC_WireLoad * p)362 static inline void Abc_SclWireLoadFree( SC_WireLoad * p )
363 {
364     Vec_IntErase( &p->vFanout );
365     Vec_FltErase( &p->vLen );
366     ABC_FREE( p->pName );
367     ABC_FREE( p );
368 }
Abc_SclWireLoadSelFree(SC_WireLoadSel * p)369 static inline void Abc_SclWireLoadSelFree( SC_WireLoadSel * p )
370 {
371     Vec_FltErase( &p->vAreaFrom );
372     Vec_FltErase( &p->vAreaTo );
373     Vec_PtrFreeData( &p->vWireLoadModel );
374     Vec_PtrErase( &p->vWireLoadModel );
375     ABC_FREE( p->pName );
376     ABC_FREE( p );
377 }
Abc_SclTableTemplFree(SC_TableTempl * p)378 static inline void Abc_SclTableTemplFree( SC_TableTempl * p )
379 {
380     Vec_PtrFreeData( &p->vVars );
381     Vec_PtrErase( &p->vVars );
382     Vec_VecErase( (Vec_Vec_t *)&p->vIndex );
383     ABC_FREE( p->pName );
384     ABC_FREE( p );
385 }
Abc_SclSurfaceFree(SC_Surface * p)386 static inline void Abc_SclSurfaceFree( SC_Surface * p )
387 {
388     Vec_FltErase( &p->vIndex0 );
389     Vec_FltErase( &p->vIndex1 );
390     Vec_IntErase( &p->vIndex0I );
391     Vec_IntErase( &p->vIndex1I );
392     Vec_VecErase( (Vec_Vec_t *)&p->vData );
393     Vec_VecErase( (Vec_Vec_t *)&p->vDataI );
394     ABC_FREE( p->pName );
395 //    ABC_FREE( p );
396 }
Abc_SclTimingFree(SC_Timing * p)397 static inline void Abc_SclTimingFree( SC_Timing * p )
398 {
399     Abc_SclSurfaceFree( &p->pCellRise );
400     Abc_SclSurfaceFree( &p->pCellFall );
401     Abc_SclSurfaceFree( &p->pRiseTrans );
402     Abc_SclSurfaceFree( &p->pFallTrans );
403     ABC_FREE( p->related_pin );
404     ABC_FREE( p->when_text );
405     ABC_FREE( p );
406 }
Abc_SclTimingsFree(SC_Timings * p)407 static inline void Abc_SclTimingsFree( SC_Timings * p )
408 {
409     SC_Timing * pTemp;
410     int i;
411     Vec_PtrForEachEntry( SC_Timing *, &p->vTimings, pTemp, i )
412         Abc_SclTimingFree( pTemp );
413     Vec_PtrErase( &p->vTimings );
414     ABC_FREE( p->pName );
415     ABC_FREE( p );
416 }
Abc_SclPinFree(SC_Pin * p)417 static inline void Abc_SclPinFree( SC_Pin * p )
418 {
419     SC_Timings * pTemp;
420     int i;
421     SC_PinForEachRTiming( p, pTemp, i )
422         Abc_SclTimingsFree( pTemp );
423     Vec_PtrErase( &p->vRTimings );
424     Vec_WrdErase( &p->vFunc );
425     ABC_FREE( p->func_text );
426     ABC_FREE( p->pName );
427     ABC_FREE( p );
428 }
Abc_SclCellFree(SC_Cell * p)429 static inline void Abc_SclCellFree( SC_Cell * p )
430 {
431     SC_Pin * pTemp;
432     int i;
433     SC_CellForEachPin( p, pTemp, i )
434         Abc_SclPinFree( pTemp );
435     Vec_PtrErase( &p->vPins );
436     ABC_FREE( p->pName );
437     ABC_FREE( p );
438 }
Abc_SclLibFree(SC_Lib * p)439 static inline void Abc_SclLibFree( SC_Lib * p )
440 {
441     SC_WireLoad * pWL;
442     SC_WireLoadSel * pWLS;
443     SC_TableTempl * pTempl;
444     SC_Cell * pCell;
445     int i;
446     SC_LibForEachWireLoad( p, pWL, i )
447         Abc_SclWireLoadFree( pWL );
448     Vec_PtrErase( &p->vWireLoads );
449     SC_LibForEachWireLoadSel( p, pWLS, i )
450         Abc_SclWireLoadSelFree( pWLS );
451     Vec_PtrErase( &p->vWireLoadSels );
452     SC_LibForEachTempl( p, pTempl, i )
453         Abc_SclTableTemplFree( pTempl );
454     Vec_PtrErase( &p->vTempls );
455     SC_LibForEachCell( p, pCell, i )
456         Abc_SclCellFree( pCell );
457     Vec_PtrErase( &p->vCells );
458     Vec_PtrErase( &p->vCellClasses );
459     ABC_FREE( p->pName );
460     ABC_FREE( p->pFileName );
461     ABC_FREE( p->default_wire_load );
462     ABC_FREE( p->default_wire_load_sel );
463     ABC_FREE( p->pBins );
464     ABC_FREE( p );
465 }
466 
467 
468 /**Function*************************************************************
469 
470   Synopsis    [Lookup table delay computation.]
471 
472   Description []
473 
474   SideEffects []
475 
476   SeeAlso     []
477 
478 ***********************************************************************/
Scl_LibLookup(SC_Surface * p,float slew,float load)479 static inline float Scl_LibLookup( SC_Surface * p, float slew, float load )
480 {
481     float * pIndex0, * pIndex1, * pDataS, * pDataS1;
482     float sfrac, lfrac, p0, p1;
483     int s, l;
484 
485     // handle constant table
486     if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) == 1 )
487     {
488         Vec_Flt_t * vTemp = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0);
489         assert( Vec_PtrSize(&p->vData) == 1 );
490         assert( Vec_FltSize(vTemp) == 1 );
491         return Vec_FltEntry(vTemp, 0);
492     }
493 
494     // Find closest sample points in surface:
495     pIndex0 = Vec_FltArray(&p->vIndex0);
496     for ( s = 1; s < Vec_FltSize(&p->vIndex0)-1; s++ )
497         if ( pIndex0[s] > slew )
498             break;
499     s--;
500 
501     pIndex1 = Vec_FltArray(&p->vIndex1);
502     for ( l = 1; l < Vec_FltSize(&p->vIndex1)-1; l++ )
503         if ( pIndex1[l] > load )
504             break;
505     l--;
506 
507     // Interpolate (or extrapolate) function value from sample points:
508     sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
509     lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);
510 
511     pDataS  = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s) );
512     pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1) );
513 
514     p0 = pDataS [l] + lfrac * (pDataS [l+1] - pDataS [l]);
515     p1 = pDataS1[l] + lfrac * (pDataS1[l+1] - pDataS1[l]);
516 
517     return p0 + sfrac * (p1 - p0);      // <<== multiply result with K factor here
518 }
Scl_LibPinArrival(SC_Timing * pTime,SC_Pair * pArrIn,SC_Pair * pSlewIn,SC_Pair * pLoad,SC_Pair * pArrOut,SC_Pair * pSlewOut)519 static inline void Scl_LibPinArrival( SC_Timing * pTime, SC_Pair * pArrIn, SC_Pair * pSlewIn, SC_Pair * pLoad, SC_Pair * pArrOut, SC_Pair * pSlewOut )
520 {
521     if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
522     {
523         pArrOut->rise  = Abc_MaxFloat( pArrOut->rise,  pArrIn->rise + Scl_LibLookup(&pTime->pCellRise,  pSlewIn->rise, pLoad->rise) );
524         pArrOut->fall  = Abc_MaxFloat( pArrOut->fall,  pArrIn->fall + Scl_LibLookup(&pTime->pCellFall,  pSlewIn->fall, pLoad->fall) );
525         pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise,                Scl_LibLookup(&pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) );
526         pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall,                Scl_LibLookup(&pTime->pFallTrans, pSlewIn->fall, pLoad->fall) );
527     }
528     if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
529     {
530         pArrOut->rise  = Abc_MaxFloat( pArrOut->rise,  pArrIn->fall + Scl_LibLookup(&pTime->pCellRise,  pSlewIn->fall, pLoad->rise) );
531         pArrOut->fall  = Abc_MaxFloat( pArrOut->fall,  pArrIn->rise + Scl_LibLookup(&pTime->pCellFall,  pSlewIn->rise, pLoad->fall) );
532         pSlewOut->rise = Abc_MaxFloat( pSlewOut->rise,                Scl_LibLookup(&pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) );
533         pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall,                Scl_LibLookup(&pTime->pFallTrans, pSlewIn->rise, pLoad->fall) );
534     }
535 }
Scl_LibPinDeparture(SC_Timing * pTime,SC_Pair * pDepIn,SC_Pair * pSlewIn,SC_Pair * pLoad,SC_Pair * pDepOut)536 static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_Pair * pSlewIn, SC_Pair * pLoad, SC_Pair * pDepOut )
537 {
538     if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
539     {
540         pDepIn->rise  = Abc_MaxFloat( pDepIn->rise,  pDepOut->rise + Scl_LibLookup(&pTime->pCellRise,  pSlewIn->rise, pLoad->rise) );
541         pDepIn->fall  = Abc_MaxFloat( pDepIn->fall,  pDepOut->fall + Scl_LibLookup(&pTime->pCellFall,  pSlewIn->fall, pLoad->fall) );
542     }
543     if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
544     {
545         pDepIn->fall  = Abc_MaxFloat( pDepIn->fall,  pDepOut->rise + Scl_LibLookup(&pTime->pCellRise,  pSlewIn->fall, pLoad->rise) );
546         pDepIn->rise  = Abc_MaxFloat( pDepIn->rise,  pDepOut->fall + Scl_LibLookup(&pTime->pCellFall,  pSlewIn->rise, pLoad->fall) );
547     }
548 }
549 
550 /**Function*************************************************************
551 
552   Synopsis    [Lookup table delay computation.]
553 
554   Description []
555 
556   SideEffects []
557 
558   SeeAlso     []
559 
560 ***********************************************************************/
Scl_LibLookupI(SC_Surface * p,int slew,int load)561 static inline int Scl_LibLookupI( SC_Surface * p, int slew, int load )
562 {
563     int * pIndex0, * pIndex1, * pDataS, * pDataS1;
564     int p0, p1, s, l;
565     iword lFrac0, lFrac1, sFrac;
566 
567     // handle constant table
568     if ( Vec_IntSize(&p->vIndex0I) == 1 && Vec_IntSize(&p->vIndex1I) == 1 )
569     {
570         Vec_Int_t * vTemp = (Vec_Int_t *)Vec_PtrEntry(&p->vDataI, 0);
571         assert( Vec_PtrSize(&p->vDataI) == 1 );
572         assert( Vec_IntSize(vTemp) == 1 );
573         return Vec_IntEntry(vTemp, 0);
574     }
575 
576     // Find closest sample points in surface:
577     pIndex0 = Vec_IntArray(&p->vIndex0I);
578     for ( s = 1; s < Vec_IntSize(&p->vIndex0I)-1; s++ )
579         if ( pIndex0[s] > slew )
580             break;
581     s--;
582 
583     pIndex1 = Vec_IntArray(&p->vIndex1I);
584     for ( l = 1; l < Vec_IntSize(&p->vIndex1I)-1; l++ )
585         if ( pIndex1[l] > load )
586             break;
587     l--;
588 
589     pDataS  = Vec_IntArray( (Vec_Int_t *)Vec_PtrEntry(&p->vDataI, s) );
590     pDataS1 = Vec_IntArray( (Vec_Int_t *)Vec_PtrEntry(&p->vDataI, s+1) );
591 
592     // Interpolate (or extrapolate) function value from sample points:
593 //    lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]);
594 //    sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]);
595 
596     lFrac0 = (iword)(pDataS [l+1] - pDataS [l]) * (iword)(load - pIndex1[l]) / (iword)(pIndex1[l+1] - pIndex1[l]);
597     lFrac1 = (iword)(pDataS1[l+1] - pDataS1[l]) * (iword)(load - pIndex1[l]) / (iword)(pIndex1[l+1] - pIndex1[l]);
598 
599 //    p0 = pDataS [l] + lfrac * (pDataS [l+1] - pDataS [l]);
600 //    p1 = pDataS1[l] + lfrac * (pDataS1[l+1] - pDataS1[l]);
601 
602     p0 = pDataS [l] + (int)lFrac0;
603     p1 = pDataS1[l] + (int)lFrac1;
604 
605     sFrac = (iword)(p1 - p0) * (iword)(slew - pIndex0[s]) / (iword)(pIndex0[s+1] - pIndex0[s]);
606 
607 //    return p0 + sfrac * (p1 - p0);
608     return p0 + (int)sFrac;
609 }
Scl_LibPinArrivalI(SC_Timing * pTime,SC_PairI * pArrIn,SC_PairI * pSlewIn,SC_PairI * pLoad,SC_PairI * pArrOut,SC_PairI * pSlewOut,int * pArray)610 static inline void Scl_LibPinArrivalI( SC_Timing * pTime, SC_PairI * pArrIn, SC_PairI * pSlewIn, SC_PairI * pLoad, SC_PairI * pArrOut, SC_PairI * pSlewOut, int * pArray )
611 {
612     if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
613     {
614         pArrOut->rise  = Abc_MaxInt( pArrOut->rise,  pArrIn->rise + (pArray[0] = Scl_LibLookupI(&pTime->pCellRise,  pSlewIn->rise, pLoad->rise)) );
615         pArrOut->fall  = Abc_MaxInt( pArrOut->fall,  pArrIn->fall + (pArray[1] = Scl_LibLookupI(&pTime->pCellFall,  pSlewIn->fall, pLoad->fall)) );
616         pSlewOut->rise = Abc_MaxInt( pSlewOut->rise,                             Scl_LibLookupI(&pTime->pRiseTrans, pSlewIn->rise, pLoad->rise) );
617         pSlewOut->fall = Abc_MaxInt( pSlewOut->fall,                             Scl_LibLookupI(&pTime->pFallTrans, pSlewIn->fall, pLoad->fall) );
618     }
619     if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
620     {
621         pArrOut->rise  = Abc_MaxInt( pArrOut->rise,  pArrIn->fall + (pArray[2] = Scl_LibLookupI(&pTime->pCellRise,  pSlewIn->fall, pLoad->rise)) );
622         pArrOut->fall  = Abc_MaxInt( pArrOut->fall,  pArrIn->rise + (pArray[3] = Scl_LibLookupI(&pTime->pCellFall,  pSlewIn->rise, pLoad->fall)) );
623         pSlewOut->rise = Abc_MaxInt( pSlewOut->rise,                             Scl_LibLookupI(&pTime->pRiseTrans, pSlewIn->fall, pLoad->rise) );
624         pSlewOut->fall = Abc_MaxInt( pSlewOut->fall,                             Scl_LibLookupI(&pTime->pFallTrans, pSlewIn->rise, pLoad->fall) );
625     }
626 }
Scl_LibPinRequiredI(SC_Timing * pTime,SC_PairI * pReqIn,SC_PairI * pReqOut,int * pArray)627 static inline void Scl_LibPinRequiredI( SC_Timing * pTime, SC_PairI * pReqIn, SC_PairI * pReqOut, int * pArray )
628 {
629     if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
630     {
631         pReqIn->rise  = Abc_MinInt( pReqIn->rise,  pReqOut->rise - pArray[0] );
632         pReqIn->fall  = Abc_MinInt( pReqIn->fall,  pReqOut->fall - pArray[1] );
633     }
634     if (pTime->tsense == sc_ts_Neg || pTime->tsense == sc_ts_Non)
635     {
636         pReqIn->fall  = Abc_MinInt( pReqIn->fall,  pReqOut->rise - pArray[2] );
637         pReqIn->rise  = Abc_MinInt( pReqIn->rise,  pReqOut->fall - pArray[3] );
638     }
639 }
640 
641 /**Function*************************************************************
642 
643   Synopsis    [Compute one timing edge.]
644 
645   Description []
646 
647   SideEffects []
648 
649   SeeAlso     []
650 
651 ***********************************************************************/
Scl_CellPinTime(SC_Cell * pCell,int iPin)652 static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
653 {
654     SC_Pin * pPin;
655     SC_Timings * pRTime;
656     assert( iPin >= 0 && iPin < pCell->n_inputs );
657     pPin = SC_CellPin( pCell, pCell->n_inputs );
658     assert( Vec_PtrSize(&pPin->vRTimings) == pCell->n_inputs );
659     pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
660     if ( Vec_PtrSize(&pRTime->vTimings) == 0 )
661         return NULL;
662     assert( Vec_PtrSize(&pRTime->vTimings) == 1 );
663     return (SC_Timing *)Vec_PtrEntry( &pRTime->vTimings, 0 );
664 }
Scl_LibPinArrivalEstimate(SC_Cell * pCell,int iPin,float Slew,float Load)665 static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float Load )
666 {
667     SC_Pair LoadIn = { Load, Load };
668     SC_Pair ArrIn  = { 0.0, 0.0 };
669     SC_Pair ArrOut = { 0.0, 0.0 };
670     SC_Pair SlewIn = { 0.0, 0.0 };
671     SC_Pair SlewOut = { 0.0, 0.0 };
672 //    Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
673 //    SlewIn.fall = SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
674     SlewIn.fall = SlewIn.rise = Slew;
675     Scl_LibPinArrival( Scl_CellPinTime(pCell, iPin), &ArrIn, &SlewIn, &LoadIn, &ArrOut, &SlewOut );
676     return  0.5 * ArrOut.fall +  0.5 * ArrOut.rise;
677 }
Scl_LibHandleInputDriver(SC_Cell * pCell,SC_Pair * pLoadIn,SC_Pair * pArrOut,SC_Pair * pSlewOut)678 static inline void Scl_LibHandleInputDriver( SC_Cell * pCell, SC_Pair * pLoadIn, SC_Pair * pArrOut, SC_Pair * pSlewOut )
679 {
680     SC_Pair LoadIn   = { 0.0, 0.0 }; // zero input load
681     SC_Pair ArrIn    = { 0.0, 0.0 }; // zero input time
682     SC_Pair SlewIn   = { 0.0, 0.0 }; // zero input slew
683     SC_Pair ArrOut0  = { 0.0, 0.0 }; // output time under zero load
684     SC_Pair ArrOut1  = { 0.0, 0.0 }; // output time under given load
685     SC_Pair SlewOut  = { 0.0, 0.0 }; // output slew under zero load
686     pSlewOut->fall = pSlewOut->rise = 0;
687     assert( pCell->n_inputs == 1 );
688     Scl_LibPinArrival( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, &LoadIn, &ArrOut0, &SlewOut );
689     Scl_LibPinArrival( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, pLoadIn, &ArrOut1, pSlewOut );
690     pArrOut->fall = ArrOut1.fall - ArrOut0.fall;
691     pArrOut->rise = ArrOut1.rise - ArrOut0.rise;
692 }
693 
694 /**Function*************************************************************
695 
696   Synopsis    [Compute one timing edge.]
697 
698   Description []
699 
700   SideEffects []
701 
702   SeeAlso     []
703 
704 ***********************************************************************/
Scl_LibPinArrivalEstimateI(SC_Cell * pCell,int iPin,int Slew,int Load)705 static inline int Scl_LibPinArrivalEstimateI( SC_Cell * pCell, int iPin, int Slew, int Load )
706 {
707     int Arrray[4];
708     SC_PairI LoadIn = { Load, Load };
709     SC_PairI ArrIn  = { 0, 0 };
710     SC_PairI ArrOut = { 0, 0 };
711     SC_PairI SlewIn = { 0, 0 };
712     SC_PairI SlewOut = { 0, 0 };
713 //    Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
714 //    SlewIn.fall = SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
715     SlewIn.fall = SlewIn.rise = Slew;
716     Scl_LibPinArrivalI( Scl_CellPinTime(pCell, iPin), &ArrIn, &SlewIn, &LoadIn, &ArrOut, &SlewOut, Arrray );
717     return (ArrOut.fall + ArrOut.rise) >> 1;
718 }
Scl_LibHandleInputDriver2(SC_Cell * pCell,SC_PairI * pLoadIn,SC_PairI * pArrOut,SC_PairI * pSlewOut)719 static inline void Scl_LibHandleInputDriver2( SC_Cell * pCell, SC_PairI * pLoadIn, SC_PairI * pArrOut, SC_PairI * pSlewOut )
720 {
721     int Arrray[4];
722     SC_PairI LoadIn   = { 0, 0 }; // zero input load
723     SC_PairI ArrIn    = { 0, 0 }; // zero input time
724     SC_PairI SlewIn   = { 0, 0 }; // zero input slew
725     SC_PairI ArrOut0  = { 0, 0 }; // output time under zero load
726     SC_PairI ArrOut1  = { 0, 0 }; // output time under given load
727     SC_PairI SlewOut  = { 0, 0 }; // output slew under zero load
728     pSlewOut->fall = pSlewOut->rise = 0;
729     assert( pCell->n_inputs == 1 );
730     Scl_LibPinArrivalI( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, &LoadIn, &ArrOut0, &SlewOut, Arrray );
731     Scl_LibPinArrivalI( Scl_CellPinTime(pCell, 0), &ArrIn, &SlewIn, pLoadIn, &ArrOut1, pSlewOut, Arrray );
732     pArrOut->fall = ArrOut1.fall - ArrOut0.fall;
733     pArrOut->rise = ArrOut1.rise - ArrOut0.rise;
734 }
735 
736 /*=== sclLiberty.c ===============================================================*/
737 extern SC_Lib *      Abc_SclReadLiberty( char * pFileName, int fVerbose, int fVeryVerbose );
738 /*=== sclLibScl.c ===============================================================*/
739 extern SC_Lib *      Abc_SclReadFromGenlib( void * pLib );
740 extern SC_Lib *      Abc_SclReadFromStr( Vec_Str_t * vOut );
741 extern SC_Lib *      Abc_SclReadFromFile( char * pFileName );
742 extern void          Abc_SclWriteScl( char * pFileName, SC_Lib * p );
743 extern void          Abc_SclWriteLiberty( char * pFileName, SC_Lib * p );
744 /*=== sclLibUtil.c ===============================================================*/
745 extern void          Abc_SclHashCells( SC_Lib * p );
746 extern int           Abc_SclCellFind( SC_Lib * p, char * pName );
747 extern int           Abc_SclClassCellNum( SC_Cell * pClass );
748 extern void          Abc_SclShortNames( SC_Lib * p );
749 extern int           Abc_SclLibClassNum( SC_Lib * pLib );
750 extern void          Abc_SclLinkCells( SC_Lib * p );
751 extern void          Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain, int fInvOnly, int fShort );
752 extern void          Abc_SclConvertLeakageIntoArea( SC_Lib * p, float A, float B );
753 extern void          Abc_SclLibNormalize( SC_Lib * p );
754 extern SC_Cell *     Abc_SclFindInvertor( SC_Lib * p, int fFindBuff );
755 extern SC_Cell *     Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );
756 extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
757 extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );
758 extern int           Abc_SclHasDelayInfo( void * pScl );
759 extern float         Abc_SclComputeAverageSlew( SC_Lib * p );
760 extern void          Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
761 extern void          Abc_SclInstallGenlib( void * pScl, float Slew, float Gain, int nGatesMin );
762 
763 
764 ABC_NAMESPACE_HEADER_END
765 
766 #endif
767 
768 ////////////////////////////////////////////////////////////////////////
769 ///                       END OF FILE                                ///
770 ////////////////////////////////////////////////////////////////////////
771