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