Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stm / stm_mod_eval.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : STM Version 1.00 */
6 /* Fichier : stm_mod_eval.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /****************************************************************************/
14
15 /****************************************************************************/
16 /* includes */
17 /****************************************************************************/
18
19 #include "stm.h"
20
21 /****************************************************************************/
22 /* functions */
23 /****************************************************************************/
24
25 float stm_mod_constraint (timing_model *tmodel, float inputslew, float clockslew)
26 {
27 if (tmodel) {
28 switch (tmodel->UTYPE) {
29 case STM_MOD_MODTBL:
30 return stm_modtbl_constraint (tmodel->UMODEL.TABLE, inputslew, clockslew);
31 break;
32 case STM_MOD_MODSCM:
33 avt_errmsg (STM_ERRMSG, "010", AVT_ERROR);
34 return 0.0;
35 break;
36 case STM_MOD_MODPLN:
37 return stm_modpln_constraint (tmodel->UMODEL.POLYNOM, inputslew, clockslew);
38 break;
39 case STM_MOD_MODFCT:
40 return stm_modfct_constraint (tmodel->UMODEL.FUNCTION, inputslew, clockslew);
41 break;
42 }
43 }
44
45 return 0.0;
46 }
47
48 /****************************************************************************/
49
50 float stm_mod_slew_pi (timing_model* tmodel, float c1, float c2, float r, float slew, stm_pwl *pwl, stm_pwl **ptpwl, char *signame)
51 {
52 float vth;
53 float vdd;
54 float imax;
55 float load;
56 float cconf;
57 float f = STM_DEF_SLEW;
58
59 if (tmodel) {
60 switch (tmodel->UTYPE) {
61 case STM_MOD_MODTBL:
62 load = c1 + c2;
63 f = stm_modtbl_slew (tmodel->UMODEL.TABLE, load, slew);
64 break;
65 case STM_MOD_MODSCM:
66 if( STM_IMAX_FOR_PILOAD ) {
67 vth = stm_modscm_vth (tmodel->UMODEL.SCM);
68 imax = stm_modscm_imax (tmodel->UMODEL.SCM);
69 cconf = stm_modscm_cconf (tmodel->UMODEL.SCM, slew);
70 load = stm_capaeq (imax, r, c1 + cconf, c2, vth, signame);
71 load -= cconf;
72 }
73 else {
74 //load = c1 + c2;
75 load = stm_modscm_capaeq (tmodel->UMODEL.SCM, slew, r, c1, c2, signame );
76 }
77 f = stm_modscm_slew (tmodel->UMODEL.SCM, slew, pwl, ptpwl, load);
78 break;
79 case STM_MOD_MODPLN:
80 load = c1 + c2;
81 f = stm_modpln_slew (tmodel->UMODEL.POLYNOM, slew, load);
82 break;
83 case STM_MOD_MODFCT:
84 load = c1 + c2;
85 f = stm_modfct_slew (tmodel->UMODEL.FUNCTION, slew, load);
86 break;
87 case STM_MOD_MODIV:
88 vth = stm_mod_vth(tmodel);
89 vdd = stm_mod_vdd(tmodel);
90 f = stm_modiv_slew_pi (tmodel->UMODEL.IV, slew, r, c1, c2, vth, vdd );
91 break;
92 }
93 }
94
95 if( f < 1.0 ) f = 1.0 ;
96 return f;
97 }
98
99 /****************************************************************************/
100
101 float stm_mod_delay_pi (timing_model *tmodel, float c1, float c2, float r, float slew, stm_pwl *pwl, char *signame)
102 {
103 float vth;
104 float vdd;
105 float load;
106 float imax;
107 float cconf;
108
109 if (tmodel) {
110 switch (tmodel->UTYPE) {
111 case STM_MOD_MODTBL:
112 load = c1 + c2;
113 return stm_modtbl_delay (tmodel->UMODEL.TABLE, load, slew);
114 break;
115 case STM_MOD_MODSCM:
116 if( STM_IMAX_FOR_PILOAD ) {
117 vth = stm_modscm_vth (tmodel->UMODEL.SCM);
118 imax = stm_modscm_imax (tmodel->UMODEL.SCM);
119 cconf = stm_modscm_cconf (tmodel->UMODEL.SCM, slew);
120 load = stm_capaeq (imax, r, c1 + cconf, c2, vth, signame);
121 load -= cconf;
122 }
123 else
124 load = stm_modscm_capaeq (tmodel->UMODEL.SCM, slew, r, c1, c2, signame );
125 return stm_modscm_delay (tmodel->UMODEL.SCM, slew, pwl, load);
126 break;
127 case STM_MOD_MODPLN:
128 load = c1 + c2;
129 return stm_modpln_delay (tmodel->UMODEL.POLYNOM, slew, load);
130 break;
131 case STM_MOD_MODFCT:
132 load = c1 + c2;
133 return stm_modfct_delay (tmodel->UMODEL.FUNCTION, slew, load);
134 break;
135 case STM_MOD_MODIV:
136 vth = stm_mod_vth(tmodel);
137 vdd = stm_mod_vdd(tmodel);
138 return stm_modiv_delay_pi (tmodel->UMODEL.IV, slew, r, c1, c2, vth, vdd );
139 break;
140 }
141 }
142 return 0;
143 }
144
145
146 /****************************************************************************/
147
148 float stm_mod_slew (timing_model* tmodel, float load, float slew, stm_pwl *pwl, stm_pwl **ptpwl, char *signame)
149 {
150 float vth;
151 float vdd;
152 float f = STM_DEF_SLEW;
153
154 if (tmodel) {
155 switch (tmodel->UTYPE) {
156 case STM_MOD_MODTBL:
157 f = stm_modtbl_slew (tmodel->UMODEL.TABLE, load, slew);
158 break;
159 case STM_MOD_MODSCM:
160 f = stm_modscm_slew (tmodel->UMODEL.SCM, slew, pwl, ptpwl, load);
161 break;
162 case STM_MOD_MODPLN:
163 f = stm_modpln_slew (tmodel->UMODEL.POLYNOM, slew, load);
164 break;
165 case STM_MOD_MODFCT:
166 f = stm_modfct_slew (tmodel->UMODEL.FUNCTION, slew, load);
167 break;
168 case STM_MOD_MODIV:
169 vth = stm_mod_vth(tmodel);
170 vdd = stm_mod_vdd(tmodel);
171 f = stm_modiv_slew_c (tmodel->UMODEL.IV, slew, load, vth, vdd);
172 }
173 }
174 if( f < 1.0 ) f = 1.0 ;
175 return f;
176 }
177
178 /****************************************************************************/
179
180 float stm_mod_delay (timing_model *tmodel, float load, float slew, stm_pwl *pwl, char *signame)
181 {
182 float vth;
183 float vdd;
184
185 if (tmodel) {
186 switch (tmodel->UTYPE) {
187 case STM_MOD_MODTBL:
188 return stm_modtbl_delay (tmodel->UMODEL.TABLE, load, slew);
189 break;
190 case STM_MOD_MODSCM:
191 return stm_modscm_delay (tmodel->UMODEL.SCM, slew, pwl, load);
192 break;
193 case STM_MOD_MODPLN:
194 return stm_modpln_delay (tmodel->UMODEL.POLYNOM, slew, load);
195 break;
196 case STM_MOD_MODFCT:
197 return stm_modfct_delay (tmodel->UMODEL.FUNCTION, slew, load);
198 break;
199 case STM_MOD_MODIV:
200 vth = stm_mod_vth(tmodel);
201 vdd = stm_mod_vdd(tmodel);
202 return stm_modiv_delay_c (tmodel->UMODEL.IV, slew, load, vth, vdd );
203 break;
204 }
205 }
206 return 0;
207 }
208
209 /****************************************************************************/
210
211 void stm_mod_timing_pi( timing_model *dmodel,
212 timing_model *fmodel,
213 float fin,
214 stm_pwl *pwlin,
215 stm_driver *driver,
216 float c1,
217 float c2,
218 float r,
219 float *delay,
220 float *fout,
221 stm_pwl **pwlout,
222 char *signame,
223 char *inputname,
224 char dirin,
225 char dirout
226 )
227 {
228 float vth;
229 float vdd;
230 float load;
231 float imax;
232 float cconf;
233
234 if( delay ) *delay = 0.0 ;
235 if( fout ) *fout = fin ;
236 if( pwlout ) *pwlout = NULL ;
237
238 /* Si les modèles ne sont pas les meme pour le front et le delai, il ne faut pas faire l'hypothèse
239 que la capacité equivalente à la charge en pi sera la meme */
240 if( dmodel->UTYPE == STM_MOD_MODSCM &&
241 fmodel->UTYPE == STM_MOD_MODSCM &&
242 dmodel->UMODEL.SCM == fmodel->UMODEL.SCM ) {
243
244 load = c1 + c2;
245
246 if( V_BOOL_TAB[ __AVT_PRECISE_PILOAD ].VALUE ) {
247 stm_modscm_timing (dmodel->UMODEL.SCM, fmodel->UMODEL.SCM, fin, pwlin, driver, r, c1, c2, delay, fout, pwlout, dmodel->NAME );
248 }
249 else {
250 if( STM_IMAX_FOR_PILOAD ) {
251 vth = stm_modscm_vth (dmodel->UMODEL.SCM);
252 imax = stm_modscm_imax (dmodel->UMODEL.SCM);
253 cconf = stm_modscm_cconf (dmodel->UMODEL.SCM, fin);
254 load = stm_capaeq (imax, r, c1 + cconf, c2, vth, signame);
255 load -= cconf;
256 }
257 else
258 load = stm_modscm_capaeq (dmodel->UMODEL.SCM, fin, r, c1, c2, signame );
259 stm_modscm_timing (dmodel->UMODEL.SCM, fmodel->UMODEL.SCM, fin, pwlin, driver, -1.0, load, -1.0, delay, fout, pwlout, dmodel->NAME );
260 }
261
262 }
263 else {
264 if( dmodel == fmodel && dmodel->UTYPE == STM_MOD_MODIV ) {
265 vth = stm_mod_vth(dmodel);
266 vdd = stm_mod_vdd(dmodel);
267 stm_modiv_timing_pi( dmodel->UMODEL.IV, fin, r, c1, c2, vth, vdd, delay, fout );
268 }
269 else {
270
271 if( delay && dmodel ) {
272 switch (dmodel->UTYPE) {
273 case STM_MOD_MODTBL:
274 load = c1 + c2;
275 *delay = stm_modtbl_delay (dmodel->UMODEL.TABLE, load, fin);
276 break;
277 case STM_MOD_MODSCM:
278 if( STM_IMAX_FOR_PILOAD ) {
279 vth = stm_modscm_vth (dmodel->UMODEL.SCM);
280 imax = stm_modscm_imax (dmodel->UMODEL.SCM);
281 cconf = stm_modscm_cconf (dmodel->UMODEL.SCM, fin);
282 load = stm_capaeq (imax, r, c1 + cconf, c2, vth, signame);
283 load -= cconf;
284 }
285 else
286 load = stm_modscm_capaeq (dmodel->UMODEL.SCM, fin, r, c1, c2, signame );
287 *delay = stm_modscm_delay (dmodel->UMODEL.SCM, fin, pwlin, load);
288 break;
289 case STM_MOD_MODPLN:
290 load = c1 + c2;
291 *delay = stm_modpln_delay (dmodel->UMODEL.POLYNOM, fin, load);
292 break;
293 case STM_MOD_MODFCT:
294 load = c1 + c2;
295 *delay = stm_modfct_delay (dmodel->UMODEL.FUNCTION, fin, load);
296 break;
297 case STM_MOD_MODIV:
298 load = c1 + c2;
299 vth = stm_mod_vth(dmodel);
300 vdd = stm_mod_vdd(dmodel);
301 *delay = stm_modiv_delay_c (dmodel->UMODEL.IV, fin, load, vth, vdd );
302 break;
303 }
304 }
305
306 if( fout && fmodel ) {
307 switch (fmodel->UTYPE) {
308 case STM_MOD_MODTBL:
309 load = c1 + c2;
310 *fout = stm_modtbl_slew (fmodel->UMODEL.TABLE, load, fin);
311 break;
312 case STM_MOD_MODSCM:
313 if( STM_IMAX_FOR_PILOAD ) {
314 vth = stm_modscm_vth (fmodel->UMODEL.SCM);
315 imax = stm_modscm_imax (fmodel->UMODEL.SCM);
316 cconf = stm_modscm_cconf (fmodel->UMODEL.SCM, fin);
317 load = stm_capaeq (imax, r, c1 + cconf, c2, vth, signame);
318 load -= cconf;
319 }
320 else
321 load = stm_modscm_capaeq (fmodel->UMODEL.SCM, fin, r, c1, c2, signame );
322 *fout = stm_modscm_slew (fmodel->UMODEL.SCM, fin, pwlin, pwlout, load);
323 break;
324 case STM_MOD_MODPLN:
325 load = c1 + c2;
326 *fout = stm_modpln_slew (fmodel->UMODEL.POLYNOM, fin, load);
327 break;
328 case STM_MOD_MODFCT:
329 load = c1 + c2;
330 *fout = stm_modfct_slew (fmodel->UMODEL.FUNCTION, fin, load);
331 break;
332 case STM_MOD_MODIV:
333 load = c1 + c2;
334 vth = stm_mod_vth(fmodel);
335 vdd = stm_mod_vdd(fmodel);
336 *fout = stm_modiv_slew_c (fmodel->UMODEL.IV, fin, load, vth, vdd );
337 break;
338 }
339 }
340 }
341 }
342
343 if( fout ) {
344 if( *fout < 1.0 ) *fout = 1.0 ;
345 }
346 if (delay && V_BOOL_TAB[__STM_PRECISION_WARNING].VALUE) {
347 if (fin > V_INT_TAB[__STM_PRECISION_THRESHOLD].VALUE * (*delay)) {
348 float load=0;
349 if (c1>0) load+=c1;
350 if (c2>0) load+=c2;
351 avt_errmsg(STM_ERRMSG, "052", AVT_WARNING, inputname, dirin, signame, dirout, (int)fin, (int)load);
352 }
353 }
354 }
355
356 /****************************************************************************/
357
358 void stm_mod_timing( timing_model *dmodel,
359 timing_model *fmodel,
360 float fin,
361 stm_pwl *pwlin,
362 stm_driver *driver,
363 float load,
364 float *delay,
365 float *fout,
366 stm_pwl **pwlout,
367 char *signame,
368 char *inputname,
369 char dirin,
370 char dirout
371 )
372 {
373 float vth;
374 float vdd;
375
376 if( delay ) *delay = 0.0 ;
377 if( fout ) *fout = fin ;
378 if( pwlout ) *pwlout = NULL ;
379
380 if( dmodel->UTYPE == STM_MOD_MODSCM &&
381 fmodel->UTYPE == STM_MOD_MODSCM ) {
382 stm_modscm_timing (dmodel->UMODEL.SCM, fmodel->UMODEL.SCM, fin, pwlin, driver, -1.0, load, -1.0, delay, fout, pwlout, dmodel->NAME );
383 }
384 else {
385 if( dmodel == fmodel && dmodel->UTYPE == STM_MOD_MODIV ) {
386 vth = stm_mod_vth(dmodel);
387 vdd = stm_mod_vdd(dmodel);
388 stm_modiv_timing_c( dmodel->UMODEL.IV, fin, load, vth, vdd, delay, fout );
389 }
390 else {
391
392 if( delay && dmodel ) {
393 switch (dmodel->UTYPE) {
394 case STM_MOD_MODTBL:
395 *delay = stm_modtbl_delay (dmodel->UMODEL.TABLE, load, fin);
396 break;
397 case STM_MOD_MODSCM:
398 stm_modscm_timing (dmodel->UMODEL.SCM, fmodel->UMODEL.SCM, fin, pwlin, driver, -1.0, load, -1.0, delay, fout, pwlout, dmodel->NAME );
399 break;
400 case STM_MOD_MODPLN:
401 *delay = stm_modpln_delay (dmodel->UMODEL.POLYNOM, fin, load);
402 break;
403 case STM_MOD_MODFCT:
404 *delay = stm_modfct_delay (dmodel->UMODEL.FUNCTION, fin, load);
405 break;
406 case STM_MOD_MODIV:
407 vth = stm_mod_vth(dmodel);
408 vdd = stm_mod_vdd(dmodel);
409 *delay = stm_modiv_delay_c (dmodel->UMODEL.IV, fin, load, vth, vdd );
410 break;
411 }
412 }
413
414 if( fout && fmodel ) {
415 switch (fmodel->UTYPE) {
416 case STM_MOD_MODTBL:
417 *fout = stm_modtbl_slew (fmodel->UMODEL.TABLE, load, fin);
418 break;
419 case STM_MOD_MODSCM:
420 stm_modscm_timing (dmodel->UMODEL.SCM, fmodel->UMODEL.SCM, fin, pwlin, driver, -1.0, load, -1.0, delay, fout, pwlout, dmodel->NAME );
421 break;
422 case STM_MOD_MODPLN:
423 *fout = stm_modpln_slew (fmodel->UMODEL.POLYNOM, fin, load);
424 break;
425 case STM_MOD_MODFCT:
426 *fout = stm_modfct_slew (fmodel->UMODEL.FUNCTION, fin, load);
427 break;
428 case STM_MOD_MODIV:
429 vth = stm_mod_vth(fmodel);
430 vdd = stm_mod_vdd(fmodel);
431 *fout = stm_modiv_slew_c (fmodel->UMODEL.IV, fin, load, vth, vdd );
432 break;
433 }
434 }
435 }
436 }
437
438 if( fout ) {
439 if( *fout < 1.0 ) *fout = 1.0 ;
440 }
441 if (delay && V_BOOL_TAB[__STM_PRECISION_WARNING].VALUE) {
442 if (fin > V_INT_TAB[__STM_PRECISION_THRESHOLD].VALUE * (*delay)) {
443 avt_errmsg(STM_ERRMSG, "052", AVT_WARNING, inputname, dirin, signame, dirout, (int)fin, (int)load);
444 }
445 }
446 }
447
448 /****************************************************************************/
449
450 float stm_mod_loadparam (timing_model *tmodel, float load, float slew)
451 {
452 if (tmodel)
453 switch (tmodel->UTYPE) {
454 case STM_MOD_MODTBL:
455 return stm_modtbl_loadparam (tmodel->UMODEL.TABLE, load, slew);
456 break;
457 case STM_MOD_MODSCM:
458 return stm_modscm_loadparam (tmodel->UMODEL.SCM, load, slew);
459 break;
460 case STM_MOD_MODPLN:
461 avt_errmsg (STM_ERRMSG, "013", AVT_ERROR);
462 break;
463 case STM_MOD_MODFCT:
464 avt_errmsg (STM_ERRMSG, "013", AVT_ERROR);
465 break;
466 }
467 return 0;
468 }
469
470 /****************************************************************************/
471
472 float stm_mod_clockslewparam (timing_model *tmodel, float clockslew, float slew)
473 {
474 if (tmodel)
475 switch (tmodel->UTYPE) {
476 case STM_MOD_MODTBL:
477 return stm_modtbl_clockslewparam (tmodel->UMODEL.TABLE, clockslew, slew);
478 break;
479 case STM_MOD_MODSCM:
480 avt_errmsg (STM_ERRMSG, "014", AVT_ERROR);
481 break;
482 case STM_MOD_MODPLN:
483 avt_errmsg (STM_ERRMSG, "015", AVT_ERROR);
484 break;
485 case STM_MOD_MODFCT:
486 avt_errmsg (STM_ERRMSG, "015", AVT_ERROR);
487 break;
488 }
489 return 0;
490 }
491
492 /****************************************************************************/
493
494 float stm_mod_dataslewparam (timing_model *tmodel, float clockslew, float slew)
495 {
496 if (tmodel)
497 switch (tmodel->UTYPE) {
498 case STM_MOD_MODTBL:
499 return stm_modtbl_dataslewparam (tmodel->UMODEL.TABLE, clockslew, slew);
500 break;
501 case STM_MOD_MODSCM:
502 avt_errmsg (STM_ERRMSG, "016", AVT_ERROR);
503 break;
504 case STM_MOD_MODPLN:
505 avt_errmsg (STM_ERRMSG, "017", AVT_ERROR);
506 break;
507 case STM_MOD_MODFCT:
508 avt_errmsg (STM_ERRMSG, "017", AVT_ERROR);
509 break;
510 }
511 return 0;
512 }
513
514 /****************************************************************************/
515
516 float stm_mod_imax (timing_model *model)
517 {
518 if (model)
519 switch (model->UTYPE) {
520 case STM_MOD_MODTBL:
521 avt_errmsg (STM_ERRMSG, "018", AVT_ERROR);
522 break;
523 case STM_MOD_MODSCM:
524 return stm_modscm_imax (model->UMODEL.SCM);
525 break;
526 case STM_MOD_MODPLN:
527 avt_errmsg (STM_ERRMSG, "019", AVT_ERROR);
528 break;
529 case STM_MOD_MODFCT:
530 avt_errmsg (STM_ERRMSG, "019", AVT_ERROR);
531 break;
532 }
533 return 0;
534 }
535
536 /****************************************************************************/
537
538 float stm_mod_slewparam (timing_model *tmodel, float load, float slew)
539 {
540 if (tmodel)
541 switch (tmodel->UTYPE) {
542 case STM_MOD_MODTBL:
543 return stm_modtbl_slewparam (tmodel->UMODEL.TABLE, load, slew);
544 break;
545 case STM_MOD_MODSCM:
546 return stm_modscm_slewparam (tmodel->UMODEL.SCM, load, slew);
547 break;
548 case STM_MOD_MODPLN:
549 avt_errmsg (STM_ERRMSG, "020", AVT_ERROR);
550 break;
551 case STM_MOD_MODFCT:
552 avt_errmsg (STM_ERRMSG, "020", AVT_ERROR);
553 break;
554 }
555 return 0;
556 }
557
558 /****************************************************************************/
559
560 float stm_mod_vt (timing_model *model)
561 {
562 if (!model)
563 return STM_DEFAULT_VT;
564 else {
565 if( model->UTYPE == STM_MOD_MODSCM )
566 if( model->UMODEL.SCM->TYPE == STM_MODSCM_DUAL )
567 return model->UMODEL.SCM->PARAMS.DUAL->DP[STM_VT];
568 return model->VT;
569 }
570 }
571
572 /****************************************************************************/
573
574 float stm_mod_vf (timing_model *model)
575 {
576 if (!model)
577 return STM_DEFAULT_VFU;
578 else
579 return model->VF;
580 }
581
582 /****************************************************************************/
583
584 float stm_mod_vf_input (timing_model *model)
585 {
586 float vf = -1.0;
587 if (!model)
588 vf = STM_DEFAULT_VFU;
589 else if(model->UTYPE == STM_MOD_MODSCM){
590 if((model->TTYPE == STM_HL) || (model->TTYPE == STM_HH))
591 vf = stm_modscm_vf_input (model->UMODEL.SCM);
592 else if((model->TTYPE == STM_LL) || (model->TTYPE == STM_LH))
593 vf = 0.0;
594 }
595 if(vf < 0.0){
596 if((model->TTYPE == STM_HL) || (model->TTYPE == STM_HH))
597 vf = stm_mod_vdd(model);
598 else if((model->TTYPE == STM_LL) || (model->TTYPE == STM_LH))
599 vf = 0.0;
600 }
601 return vf;
602 }
603 /****************************************************************************/
604
605 float stm_mod_default_vt (void)
606 {
607 return STM_DEFAULT_VT;
608 }
609
610 /****************************************************************************/
611
612 float stm_mod_default_vdd (void)
613 {
614 return V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
615 }
616
617 /****************************************************************************/
618
619 float stm_mod_default_vth (void)
620 {
621 return V_FLOAT_TAB[__SIM_VTH].VALUE * V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
622 }
623
624 /****************************************************************************/
625
626 float stm_mod_default_vfd (void)
627 {
628 return STM_DEFAULT_VFD;
629 }
630
631 /****************************************************************************/
632
633 float stm_mod_default_vfu (void)
634 {
635 return STM_DEFAULT_VFU;
636 }
637
638 /****************************************************************************/
639
640 float stm_mod_vth (timing_model *model)
641 {
642 if (!model)
643 return V_FLOAT_TAB[__SIM_VTH].VALUE * V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
644 else
645 return model->VTH;
646 }
647
648 /****************************************************************************/
649
650 float stm_mod_vdd (timing_model *model)
651 {
652 if (!model)
653 return V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
654 else
655 return model->VDD;
656 }
657
658 /****************************************************************************/
659
660 float stm_mod_vdd_input (timing_model *model)
661 {
662 float vdd = -1.0;
663 if (!model)
664 vdd = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
665 else if(model->UTYPE == STM_MOD_MODSCM)
666 vdd = stm_modscm_vf_input (model->UMODEL.SCM);
667 if(vdd < 0.0)
668 vdd = stm_mod_vdd(model);
669 return vdd;
670 }
671 /****************************************************************************/
672
673 void stm_mod_driver( timing_model *model, float *r, float *v )
674 {
675 if( r ) *r = -1.0 ;
676 if( v ) *v = -1.0 ;
677
678 if( model ) {
679
680 switch( model->UTYPE )
681 {
682 case STM_MOD_MODSCM:
683
684 if (model->UMODEL.SCM->TYPE == STM_MODSCM_DUAL ) {
685 if( r )
686 *r = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_RLIN] ;
687 if( v )
688 *v = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_KRT] * model->UMODEL.SCM->PARAMS.DUAL->DP[STM_VDDMAX] ;
689 }
690 break;
691 }
692 }
693 }
694 /****************************************************************************/
695
696 float stm_mod_rlin (timing_model *model)
697 {
698 float rlin;
699
700 rlin = -1.0 ;
701
702 if (model)
703 switch (model->UTYPE) {
704 case STM_MOD_MODSCM:
705 if (model->UMODEL.SCM->TYPE == STM_MODSCM_DUAL )
706 rlin = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_RLIN] ;
707 break;
708 }
709
710 return rlin ;
711 }
712
713 /****************************************************************************/
714
715 float stm_mod_default_rlin (void)
716 {
717 return STM_DEFAULT_RLIN ;
718 }
719
720 /****************************************************************************/
721
722 float stm_mod_vsat (timing_model *model)
723 {
724 float vsat ;
725 float rsat ;
726 float rsatmin ;
727 float rlin ;
728 float vddmax ;
729 float imax ;
730
731 vsat = -1.0 ;
732
733 if (model) {
734
735 switch (model->UTYPE) {
736
737 case STM_MOD_MODSCM:
738
739 if (model->UMODEL.SCM->TYPE == STM_MODSCM_DUAL ) {
740
741 rsat = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_RSAT] ;
742 rlin = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_RLIN] ;
743 imax = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_IMAX] ;
744 vddmax = model->UMODEL.SCM->PARAMS.DUAL->DP[STM_VDDMAX] ;
745
746 rsatmin = vddmax/imax ;
747
748 if( rsat > 0.0 && rsat > rsatmin && rsatmin > rlin ) {
749 vsat = vddmax -
750 ( imax - vddmax / rsat ) * rlin * rsat / ( rsat - rlin ) ;
751 }
752 }
753
754 break;
755 }
756 }
757
758 return vsat ;
759 }
760
761 /****************************************************************************/
762
763 float stm_mod_default_vsat(void)
764 {
765 return STM_DEFAULT_VSAT ;
766 }