Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / mcc / mcc_mod_spice.c
1 /******************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Fichier : mcc_mod_spice.c */
6 /* */
7 /* */
8 /* (c) copyright 2001 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Marc KUOCH */
12 /*----------------------------------------------------------------------------*/
13 /* */
14 /* */
15 /*----------------------------------------------------------------------------*/
16
17 /******************************************************************************/
18 /* INCLUDE */
19 /******************************************************************************/
20
21 #include MCC_H
22 #include "mcc_util.h"
23 #include "mcc_mod_util.h"
24 #include "mcc_mod_bsim3v3.h"
25 #include "mcc_mod_bsim4.h"
26 #include "mcc_mod_psp.h"
27 #include "mcc_mod_ext.h"
28 #include "mcc_mod_mos2.h"
29 #include "mcc_mod_mm9.h"
30 #include "mcc_mod_spice.h"
31 #include "mcc_genspi.h"
32 #include "mcc_debug.h"
33 #include "mcc_curv.h"
34 #include "mcc_parse_cfg.h"
35
36 /******************************************************************************/
37 /* extern globals */
38 /******************************************************************************/
39
40 /******************************************************************************/
41 /* extern fonctions */
42 /******************************************************************************/
43
44 /******************************************************************************/
45 /* FONCTIONS */
46 /******************************************************************************/
47
48 /****************************************************************************\
49 FUNCTION : mcc_integfordw()
50 Return voltage dependant capacitance value
51 \****************************************************************************/
52
53 double mcc_integfordw_q( double c, double p, double m, double vbd )
54 {
55 double q ;
56 double epsilon = 1e-3 ;
57
58 if( vbd < 0.0 ) {
59 if( m < 1.0-epsilon || m > 1.0+epsilon )
60 q = c*p/(m-1.0) * ( pow( 1.0-vbd/p, 1.0-m ) - 1.0 );
61 else
62 q = -c*p * log( 1.0-vbd/p );
63 }
64 else
65 q = c * ( vbd + m/(p+p)*vbd*vbd );
66
67 return q ;
68 }
69
70 double mcc_integfordw( double c, double vbd0, double vbd1, double p, double m)
71 {
72 double q0 ;
73 double q1 ;
74 double cx ;
75
76 q0 = mcc_integfordw_q( c, p, m, vbd0 );
77 q1 = mcc_integfordw_q( c, p, m, vbd1 );
78 cx = fabs( (q1 - q0) / (vbd1 - vbd0) ) ;
79
80 return cx ;
81 }
82
83 /******************************************************************************/
84 /* Obtention de fichier technologique */
85 /******************************************************************************/
86 mcc_technolist *mcc_gettechnofile (char *technoname)
87 {
88 mcc_technolist *pttechnofile ;
89
90 if ((pttechnofile = mcc_gettechno(technoname)) != NULL)
91 return ( pttechnofile ) ;
92
93 if ( MCC_USE_SPI_PARSER )
94 parsespice ( technoname );
95 else
96 mcc_parserfile (technoname) ;
97
98 if ((pttechnofile = mcc_gettechno(technoname)) != NULL) {
99 mcc_initallparam ( technoname ) ;
100 return pttechnofile;
101 }
102
103 avt_errmsg(MCC_ERRMSG, "012", AVT_ERROR, technoname);
104 return NULL ;
105 }
106
107 /******************************************************************************/
108 /* Destruction de fichier technologique */
109 /******************************************************************************/
110 void mcc_deltechnofile(char *technoname)
111 {
112 mcc_technolist *pttechnofile ;
113 mcc_technolist *pttechnofileprev ;
114 mcc_technolist *pttechnofilenext ;
115
116 pttechnofile = MCC_HEADTECHNO ;
117
118 if (pttechnofile->NAME == namealloc(technoname))
119 {
120 pttechnofileprev = pttechnofile ;
121 pttechnofile = pttechnofile->NEXT ;
122 free_all_model(pttechnofileprev) ;
123 mbkfree(pttechnofileprev) ;
124 MCC_HEADTECHNO = pttechnofile ;
125 return ;
126 }
127 else
128 while (pttechnofile->NEXT != NULL)
129 {
130 pttechnofileprev = pttechnofile ;
131 pttechnofile = pttechnofile->NEXT ;
132 pttechnofilenext = pttechnofile->NEXT ;
133
134 if (pttechnofile->NAME == namealloc(technoname))
135 {
136 pttechnofileprev->NEXT = pttechnofilenext ;
137 free_all_model(pttechnofile) ;
138 mbkfree(pttechnofile) ;
139 return ;
140 }
141
142 }
143 if (pttechnofile->NAME == namealloc(technoname))
144 {
145 pttechnofileprev->NEXT = NULL ;
146 free_all_model(pttechnofile) ;
147 mbkfree(pttechnofile) ;
148 return ;
149 }
150 else
151 {
152 avt_errmsg(MCC_ERRMSG, "013", AVT_ERROR, technoname);
153 return ;
154 }
155 }
156
157 /******************************************************************************\
158
159 FUNCT mcc_get_modeltype
160
161 \******************************************************************************/
162 int mcc_get_modeltype ( mcc_modellist *ptmodel, char *name )
163 {
164 int modeltype = MCC_NOMODEL ;
165 modcfglist *m ;
166 modmodellist *md ;
167 moddeflist *d ;
168 int value ;
169
170 if( ptmodel->MODELTYPE >=0 )
171 return ptmodel->MODELTYPE ;
172
173 if( ptmodel->TYPE == MCC_DIODE )
174 return modeltype ;
175
176 for( m = mcc_getmodcfg() ; m ; m = m->NEXT ) {
177 if( strcasecmp(V_INT_TAB[__SIM_TOOLMODEL].ENUMSTR_FUNC(V_INT_TAB[__SIM_TOOLMODEL].VALUE), m->NAME ) == 0 )
178 break ;
179 }
180
181 md = NULL ;
182
183 if( m ) {
184
185 for( md = m->MODLIST ; md ; md = md->NEXT ) {
186
187 if( md->CRITERION == MCC_CRIT_PARAM ) {
188
189 if( mcc_getparamtype( ptmodel, md->VALUE.PARAM.PARAM) == MCC_SETVALUE ) {
190
191 value = (int)(mcc_getparam( ptmodel, md->VALUE.PARAM.PARAM ) + 0.5 );
192
193 if( value == (int)(md->VALUE.PARAM.VALUE+0.5) ) {
194 modeltype = md->MCCTYPE ;
195 break ;
196 }
197 }
198 }
199
200 if( md->CRITERION == MCC_CRIT_MODEL && name ) {
201
202 if( strcasecmp( md->VALUE.MODEL, name ) == 0 ) {
203 modeltype = md->MCCTYPE ;
204 break ;
205 }
206 }
207 }
208 }
209
210 if( !md ) {
211 /* cas ou on a pas trouvé : peut etre que le simtoolmodel n'est pas
212 positionné. dans ce cas on essaye de trouver une correspondance. */
213 for( m = mcc_getmodcfg() ; m ; m = m->NEXT ) {
214 for( md = m->MODLIST ; md ; md = md->NEXT ) {
215 if( md->CRITERION == MCC_CRIT_PARAM ) {
216
217 if( mcc_getparamtype( ptmodel, md->VALUE.PARAM.PARAM) == MCC_SETVALUE ) {
218
219 value = (int)(mcc_getparam( ptmodel, md->VALUE.PARAM.PARAM ) + 0.5 );
220
221 if( value == (int)(md->VALUE.PARAM.VALUE+0.5) ) {
222 modeltype = md->MCCTYPE ;
223 break ;
224 }
225 }
226 }
227
228 if( md->CRITERION == MCC_CRIT_MODEL && name ) {
229
230 if( strcasecmp( md->VALUE.MODEL, name ) == 0 ) {
231 modeltype = md->MCCTYPE ;
232 break ;
233 }
234 }
235 }
236 if( md )
237 break ;
238 }
239 if( modeltype != MCC_NOMODEL ) {
240 avt_errmsg( MCC_ERRMSG, "042", AVT_ERROR, ptmodel->NAME, V_INT_TAB[__SIM_TOOLMODEL].ENUMSTR_FUNC(V_INT_TAB[__SIM_TOOLMODEL].VALUE), MCC_MOD_NAME[modeltype], m->NAME ) ;
241 }
242 }
243
244 if( md ) {
245 if (md->EXTNAME) ptmodel->USER = addptype(ptmodel->USER, MCC_MODEL_EXTNAME, md->EXTNAME);
246 for( d = md->DEFAULT ; d ; d = d->NEXT ) {
247 if( mcc_getparamtype( ptmodel, d->NAME ) != MCC_SETVALUE )
248 mcc_addparam( ptmodel, d->NAME, d->VALUE, MCC_SETVALUE );
249 }
250 }
251
252 return modeltype ;
253 }
254
255 /******************************************************************************/
256 /* Obtention du type de modele de transistor a partir d'un technofile */
257 /* On suppose que les transistors sont tous du meme model dans le technofile */
258 /* C'est pourquoi on ne compare que le parametre LEVEL d'un seul transistor */
259 /******************************************************************************/
260 int mcc_getmodeltype(char *technoname)
261 {
262 int modeltype = MCC_NOMODEL ;
263 mcc_technolist *pttechnolist ;
264 mcc_modellist *ptmodel ;
265
266 if(!(pttechnolist = mcc_gettechnofile(technoname)))
267 return(MCC_NOMODEL) ;
268
269 ptmodel = pttechnolist->MODEL ;
270 if(ptmodel == NULL)
271 modeltype = MCC_MOS2 ;
272 else {
273 while (ptmodel) {
274 if( ptmodel->TYPE != MCC_UNKNOWN &&
275 mcc_getparamtype_quick(ptmodel, __MCC_QUICK_LEVEL) == MCC_SETVALUE )
276 break ;
277 else
278 ptmodel = ptmodel->NEXT ;
279 }
280 if (ptmodel)
281 modeltype = mcc_get_modeltype( ptmodel, NULL );
282 }
283
284 return(modeltype) ;
285 }
286
287 /******************************************************************************/
288 /* initialisation des parametres de tous les modeles d'un technofile */
289 /******************************************************************************/
290 void mcc_initallparam ( char *technoname )
291 {
292 mcc_technolist *pttechnolist ;
293 mcc_modellist *ptmodel ;
294
295 if(!(pttechnolist = mcc_gettechno(technoname)))
296 return ;
297
298 for(ptmodel = pttechnolist->MODEL ; ptmodel ; ptmodel = ptmodel->NEXT)
299 {
300 if ( ptmodel->TYPE == MCC_DIODE )
301 mcc_initparam_diode(ptmodel);
302 else
303 switch ( ptmodel->MODELTYPE ) {
304 case MCC_BSIM3V3 : mcc_initparam_bsim3v3(ptmodel) ;
305 break ;
306 case MCC_BSIM4 :
307 mcc_initparam_bsim4 (ptmodel) ;
308 break ;
309 case MCC_MM9 : mcc_initparam_mm9 (ptmodel) ;
310 break ;
311 case MCC_MOS2 : mcc_initparam_mos2 (ptmodel) ;
312 break ;
313 case MCC_MPSPB :
314 case MCC_MPSP : mcc_initparam_psp( ptmodel );
315 break ;
316 case MCC_EXTMOD : mcc_initparam_ext(ptmodel);
317 break ;
318 }
319 }
320 }
321
322 /******************************************************************************/
323 /* initialisation des parametres d'un modele d'un technofile */
324 /******************************************************************************/
325 void mcc_initmodel ( mcc_modellist *ptmodel )
326 {
327 if (ptmodel->TYPE == MCC_DIODE)
328 mcc_initparam_diode (ptmodel);
329 #ifdef MCC_RESI_CODE
330 else if (ptmodel->TYPE == MCC_MODEL_RESI)
331 mcc_initparam_resi (ptmodel);
332 #endif
333 else
334 switch ( ptmodel->MODELTYPE ) {
335 case MCC_BSIM3V3 : mcc_initparam_bsim3v3(ptmodel) ;
336 break ;
337 case MCC_BSIM4 :
338 mcc_initparam_bsim4 (ptmodel) ;
339 break ;
340 case MCC_MM9 : mcc_initparam_mm9 (ptmodel) ;
341 break ;
342 case MCC_MOS2 : mcc_initparam_mos2 (ptmodel) ;
343 break ;
344 case MCC_MPSPB :
345 case MCC_MPSP : mcc_initparam_psp( ptmodel );
346 break ;
347 case MCC_EXTMOD : mcc_initparam_ext( ptmodel );
348 break ;
349 }
350 }
351
352 /******************************************************************************/
353 /* Obtention du parametre LMIN d'un modele */
354 /******************************************************************************/
355 double mcc_getLMIN (char *technoname, char *transname,
356 int transtype, int transcase, double L, double W)
357 {
358 mcc_modellist *ptmodel ;
359 double lmin = 0.0 ;
360
361 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
362 return(0.0) ;
363 else
364 lmin = mcc_getparam_quick(ptmodel, __MCC_QUICK_LMIN) ;
365
366 return lmin ;
367 }
368
369 /******************************************************************************/
370 /* Obtention du parametre LMAX d'un modele */
371 /******************************************************************************/
372 double mcc_getLMAX (char *technoname, char *transname,
373 int transtype, int transcase, double L, double W)
374 {
375 mcc_modellist *ptmodel ;
376 double lmax = MCC_D_LWMAX ;
377
378 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
379 return(0.0) ;
380 else
381 lmax = mcc_getparam_quick(ptmodel, __MCC_QUICK_LMAX) ;
382
383 return lmax ;
384 }
385
386 /******************************************************************************/
387 /* Obtention du parametre WMIN d'un modele */
388 /******************************************************************************/
389 double mcc_getWMIN (char *technoname, char *transname,
390 int transtype, int transcase, double L, double W)
391 {
392 mcc_modellist *ptmodel ;
393 double wmin = 0.0 ;
394
395 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
396 return(0.0) ;
397 else
398 wmin = mcc_getparam_quick(ptmodel, __MCC_QUICK_WMIN) ;
399
400 return wmin ;
401 }
402
403 /******************************************************************************/
404 /* Obtention du parametre WMAX d'un modele */
405 /******************************************************************************/
406 double mcc_getWMAX (char *technoname, char *transname,
407 int transtype, int transcase, double L, double W)
408 {
409 mcc_modellist *ptmodel ;
410 double wmax = MCC_D_LWMAX ;
411
412 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
413 return(0.0) ;
414 else
415 wmax = mcc_getparam_quick(ptmodel, __MCC_QUICK_WMAX) ;
416
417 return wmax ;
418 }
419
420 /******************************************************************************/
421 /* Calcul le parametre de shrink DL d'un modele */
422 /******************************************************************************/
423 double mcc_calcDL (char *technoname, char *transname,
424 int transtype, int transcase,
425 double L, double W, elp_lotrs_param *lotrsparam)
426 {
427 mcc_modellist *ptmodel ;
428 double dl = 0.0 ;
429
430 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
431 return(0.0) ;
432 else {
433 switch(ptmodel->MODELTYPE) {
434 case MCC_BSIM4 : dl = mcc_calcDL_bsim4 (ptmodel, lotrsparam, L, W) ;
435 break;
436 case MCC_BSIM3V3 : dl = mcc_calcDL_bsim3v3(ptmodel, L, W) ;
437 break ;
438 case MCC_MM9 :
439 case MCC_MOS2 : dl = mcc_calcDL_com(ptmodel) ;
440 break ;
441 case MCC_MPSPB :
442 case MCC_MPSP : dl = 0.0 ;
443 break ;
444 case MCC_EXTMOD : dl = 0.0 ;
445 break ;
446 }
447 }
448 return(dl) ;
449 }
450
451 /******************************************************************************/
452 /* Calcul le parametre de shrink DW d'un modele */
453 /******************************************************************************/
454 double mcc_calcDW (char *technoname, char *transname,
455 int transtype, int transcase,
456 double L, double W, elp_lotrs_param *lotrsparam)
457 {
458 mcc_modellist *ptmodel ;
459 double dw = 0.0 ;
460
461 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
462 return(0.0) ;
463 else {
464 switch(ptmodel->MODELTYPE) {
465 case MCC_BSIM3V3 : dw = mcc_calcDW_bsim3v3(ptmodel, L, W) ;
466 break ;
467 case MCC_BSIM4 :
468 dw = mcc_calcDW_bsim4(ptmodel, lotrsparam, L, W) ;
469 break ;
470 case MCC_MM9 :
471 case MCC_MOS2 : dw = mcc_calcDW_com(ptmodel) ;
472 break ;
473 case MCC_MPSPB :
474 case MCC_MPSP : dw = 0.0 ;
475 break ;
476 case MCC_EXTMOD : dw = 0.0 ;
477 break ;
478 }
479 }
480 return(dw) ;
481 }
482
483 /******************************************************************************/
484 /* Calcul le parametre de shrink active DLC d'un modele */
485 /******************************************************************************/
486 double mcc_calcDLC (char *technoname, char *transname,
487 int transtype, int transcase,
488 double L, double W, elp_lotrs_param *lotrsparam)
489 {
490 mcc_modellist *ptmodel ;
491 double dlc = 0.0 ;
492
493 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
494 return(0.0) ;
495 else {
496 switch(ptmodel->MODELTYPE) {
497 case MCC_BSIM4 : dlc = mcc_calcDLC_bsim4 (ptmodel, lotrsparam, L, W) ;
498 break ;
499 case MCC_BSIM3V3 : dlc = mcc_calcDLC_bsim3v3(ptmodel, L, W) ;
500 break ;
501 case MCC_MM9 :
502 case MCC_MOS2 : dlc = mcc_calcDL_com(ptmodel) ;
503 break ;
504 case MCC_MPSPB :
505 case MCC_MPSP : dlc = 0.0 ;
506 break ;
507 case MCC_EXTMOD : dlc = 0.0 ;
508 break ;
509 }
510 }
511 return(dlc) ;
512 }
513
514 /******************************************************************************/
515 /* Calcul le parametre de shrink active DWC d'un modele */
516 /******************************************************************************/
517 double mcc_calcDWC (char *technoname, char *transname,
518 int transtype, int transcase,
519 double L, double W, elp_lotrs_param *lotrsparam)
520 {
521 mcc_modellist *ptmodel ;
522 double dwc = 0.0 ;
523
524 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
525 return(0.0) ;
526 else {
527 switch(ptmodel->MODELTYPE) {
528 case MCC_BSIM3V3 : dwc = mcc_calcDWC_bsim3v3(ptmodel, L, W) ;
529 break ;
530 case MCC_BSIM4 :
531 dwc = mcc_calcDWC_bsim4(ptmodel, lotrsparam, L, W) ;
532 break ;
533 case MCC_MM9 :
534 case MCC_MOS2 : dwc = mcc_calcDW_com(ptmodel) ;
535 break ;
536 case MCC_MPSPB :
537 case MCC_MPSP : dwc = 0.0 ;
538 break ;
539 case MCC_EXTMOD : dwc = 0.0 ;
540 break ;
541 }
542 }
543 return(dwc) ;
544 }
545
546 /******************************************************************************/
547 /* Calcul de la tension de seuil VTH d'un modele */
548 /******************************************************************************/
549 double mcc_calcVTH(char *technoname, char *transname,
550 int transtype, int transcase, double L, double W,
551 double temp, double vbs, double vds,
552 elp_lotrs_param *lotrsparam, int mcclog)
553 {
554 mcc_modellist *ptmodel ;
555 double vth = 0.0 ;
556
557 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
558 return(0.0) ;
559 else {
560 switch(ptmodel->MODELTYPE) {
561 case MCC_BSIM3V3 : vth = mcc_calcVTH_bsim3v3(ptmodel, L, W, temp,
562 vbs, vds,lotrsparam,mcclog) ;
563 break ;
564 case MCC_BSIM4 :
565 vth = mcc_calcVTH_bsim4 (ptmodel, L, W, temp,
566 vbs, vds,0,lotrsparam,mcclog) ;
567 break ;
568 case MCC_MM9 : vth = mcc_calcVTH_mm9(ptmodel, L, W, temp, vbs, vds, 0.0) ;
569 break ;
570 case MCC_MOS2 : vth = mcc_calcVTH_mos2(ptmodel) ;
571 break ;
572 case MCC_MPSPB :
573 case MCC_MPSP : vth = mcc_calcVTH_psp(ptmodel, L, W, temp, vbs, vds,lotrsparam);
574 break;
575 case MCC_EXTMOD : vth = mcc_calcVTH_ext(ptmodel, L, W, temp, vbs, vds,lotrsparam);
576 break ;
577 }
578 }
579 return vth ;
580 }
581
582 /******************************************************************************/
583 /* Calcul du courant IDS d'un modele */
584 /******************************************************************************/
585 double mcc_calcIDS(char *technoname, char *transname,
586 int transtype, int transcase, double vbs, double vgs, double vds,
587 double L, double W,
588 double temp,elp_lotrs_param *lotrsparam)
589 {
590 mcc_modellist *ptmodel ;
591 double ids = 0.0;
592
593 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
594 return(0.0) ;
595 else {
596 switch(ptmodel->MODELTYPE) {
597 case MCC_BSIM3V3 : ids = mcc_calcIDS_bsim3v3 (ptmodel, vbs, vgs,
598 vds, W, L,
599 temp,lotrsparam) ;
600 break ;
601 case MCC_BSIM4 :
602 ids = mcc_calcIDS_bsim4 (ptmodel, vbs, vgs,
603 vds, W, L,
604 temp,lotrsparam) ;
605 break ;
606 case MCC_MPSPB :
607 case MCC_MPSP :
608 ids = mcc_calcIDS_psp (ptmodel, vbs, vgs,
609 vds, W, L,
610 temp,lotrsparam) ;
611 break ;
612 case MCC_EXTMOD :
613 ids = mcc_calcIDS_ext(ptmodel, vbs, vgs,
614 vds, W, L,
615 temp,lotrsparam) ;
616 break ;
617 }
618 }
619 return ids;
620 }
621
622 /******************************************************************************/
623 /* Calcul de la tension degradee VDDDEG d'un modele de transistor */
624 /******************************************************************************/
625 double mcc_calcVDDDEG(char *technoname, char *transname,
626 int transtype, int transcase, double L, double W,
627 double vdd, double temp,
628 double step, elp_lotrs_param *lotrsparam)
629 {
630 mcc_modellist *ptmodel ;
631 double vdeg = 0.0 ;
632
633 if (!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
634 return(0.0) ;
635 else
636 vdeg = mcc_calcVDDDEG_com (ptmodel, transname, L, W,
637 vdd, temp, step,
638 lotrsparam) ;
639
640 return vdeg ;
641 }
642
643 /******************************************************************************/
644 /* Calcul de la tension degradee VSSDEG d'un modele de transistor */
645 /******************************************************************************/
646 double mcc_calcVSSDEG(char *technoname, char *transname,
647 int transtype, int transcase, double L, double W,
648 double vdd, double temp,
649 double step,elp_lotrs_param *lotrsparam)
650 {
651 mcc_modellist *ptmodel ;
652 double vdeg = 0.0 ;
653
654 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
655 return(0.0) ;
656 else
657 vdeg = mcc_calcVSSDEG_com (ptmodel, transname,L, W,
658 vdd, temp,
659 step,
660 lotrsparam) ;
661 return vdeg ;
662 }
663
664 /*******************************************************************************/
665 /* Calcul de capacite de grille CGD d'un transistor */
666 /* CGD represente la capacite d'oxyde par unite de surface */
667 /* Unite: F/m^2 */
668 /*******************************************************************************/
669 double mcc_calcCGD( char *technoname,
670 char *transname,
671 int transtype,
672 int transcase,
673 double L,
674 double W,
675 double temp,
676 double vgs0,
677 double vgs1,
678 double vbs,
679 double vds,
680 elp_lotrs_param *lotrsparam
681 )
682 {
683 mcc_modellist *ptmodel ;
684 double cgd = 0.0 ;
685
686 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
687 return(0.0) ;
688 else {
689 switch(ptmodel->MODELTYPE) {
690 case MCC_BSIM3V3 : cgd = mcc_calcCGD_bsim3v3( ptmodel, L, W, temp, vgs0, vgs1, vbs, vds,lotrsparam) ;
691 break ;
692 case MCC_BSIM4 : cgd = mcc_calcCGD_bsim4( ptmodel, L, W, temp, vgs0, vgs1, vbs, vds,lotrsparam) ;
693 break ;
694 case MCC_MM9 :
695 case MCC_MOS2 : cgd = 0.0 ;
696 break ;
697 case MCC_MPSPB :
698 case MCC_MPSP : cgd = mcc_calcCGD_psp( ptmodel, L, W, temp, vgs0, vgs1, vbs, vds,lotrsparam) ;
699 break ;
700 case MCC_EXTMOD : cgd = mcc_calcCGD_ext( ptmodel, L, W, temp, vgs0, vgs1, vbs, vds,lotrsparam) ;
701 break ;
702 }
703 }
704 return cgd ;
705 }
706
707 /*******************************************************************************\
708 Calcul de capacite de grille CGSI d'un transistor
709 lie au charges intrinseques de la source
710 Unite: F/m^2
711 \*******************************************************************************/
712 double mcc_calcCGSI(char *technoname, char *transname,
713 int transtype, int transcase, double L, double W, double temp,
714 double vgs, double vbs, double vds,elp_lotrs_param *lotrsparam)
715 {
716 mcc_modellist *ptmodel ;
717 double cgsi = 0.0 ;
718
719 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
720 return 0.0 ;
721 else {
722 switch(ptmodel->MODELTYPE) {
723 case MCC_BSIM3V3 : cgsi = mcc_calcCGSI_bsim3v3 (ptmodel, L, W, temp,
724 vgs, vbs, vds,lotrsparam) ;
725 break ;
726 case MCC_BSIM4 :
727 cgsi= mcc_calcCGSI_bsim4 (ptmodel, L, W, temp,
728 vgs, vbs, vds,lotrsparam) ;
729 break ;
730 case MCC_MM9 :
731 case MCC_MOS2 : cgsi= 0.0 ;
732 break ;
733 case MCC_MPSPB :
734 case MCC_MPSP : cgsi= mcc_calcCGSI_psp( ptmodel, L, W, temp,
735 vgs, vbs, vds,lotrsparam) ;
736 case MCC_EXTMOD : cgsi= mcc_calcCGSI_ext( ptmodel, L, W, temp,
737 vgs, vbs, vds,lotrsparam) ;
738 break ;
739 }
740 }
741 return cgsi ;
742 }
743
744 /*******************************************************************************\
745 * mcc_calcCGPU
746 \*******************************************************************************/
747 double mcc_calcCGPU (char *technoname, char *transname,
748 int transtype, int transcase,
749 double L, double W, double vdd)
750 {
751 double vg1,vg2,vd1,vd2,vs1,vs2;
752 double cgp;
753
754 vg1 = 0.0;
755 vg2 = vdd/2.0;
756 vd1 = vd2 = vdd;
757 if ( transtype == MCC_NMOS )
758 vs1 = vs2 = 0.0;
759 else
760 vs1 = vs2 = vdd;
761 mcc_GetInputCapa ( technoname, transname,
762 transtype, transcase, L, W,
763 0.0, vg1, vg2,
764 vd1, vd2, vs1, vs2,
765 NULL,
766 NULL, NULL, &cgp);
767 return cgp*1.0e6;
768 }
769
770 /*******************************************************************************\
771 * mcc_calcCGPD
772 \*******************************************************************************/
773 double mcc_calcCGPD (char *technoname, char *transname,
774 int transtype, int transcase,
775 double L, double W, double vdd)
776 {
777 double vg1,vg2,vd1,vd2,vs1,vs2;
778 double cgp;
779
780 vg1 = vdd;
781 vg2 = vdd/2.0;
782 vd1 = vd2 = 0.0;
783 if ( transtype == MCC_NMOS )
784 vs1 = vs2 = 0.0;
785 else
786 vs1 = vs2 = vdd;
787 mcc_GetInputCapa ( technoname, transname,
788 transtype, transcase, L, W,
789 0.0, vg1, vg2,
790 vd1, vd2, vs1, vs2,
791 NULL,
792 NULL, NULL, &cgp);
793 return cgp*1.0e6;
794 }
795
796 /*******************************************************************************/
797 /* Calcul de capacite de grille CGP d'un transistor */
798 /* CGP represente la capacite de recouvrement (overlap) entre G/D ou G/S */
799 /* Unite: F/m */
800 /* Methode de calcul(approximative): CGP = CGDO ou CGP = CGSO */
801 /*******************************************************************************/
802 double mcc_calcCGP(char *technoname, char *transname,
803 int transtype, int transcase,
804 double L, double W, double vgx, double *ptQov,
805 elp_lotrs_param *lotrsparam, double temp )
806 {
807 mcc_modellist *ptmodel ;
808 double cgp = 0.0 ;
809
810 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
811 return(0.0) ;
812 else {
813 switch(ptmodel->MODELTYPE) {
814 case MCC_BSIM3V3 : cgp = mcc_calcCGP_bsim3v3(ptmodel, vgx, L, W, ptQov) ;
815 break ;
816 case MCC_BSIM4 :
817 cgp = mcc_calcCGP_bsim4 (ptmodel, lotrsparam, vgx, L, W, ptQov) ;
818 break ;
819 case MCC_MM9 :
820 case MCC_MOS2 : cgp = mcc_calcCGP_com(ptmodel) ;
821 break ;
822 case MCC_MPSPB :
823 case MCC_MPSP :
824 cgp = mcc_calcCGP_psp (ptmodel, lotrsparam, vgx, L, W, temp, ptQov) ;
825 case MCC_EXTMOD :
826 cgp = mcc_calcCGP_ext(ptmodel, lotrsparam, vgx, L, W, temp, ptQov);
827 break ;
828 }
829 }
830 return cgp ;
831 }
832
833 /*******************************************************************************/
834 /* Calcul de capacite de drain CDS d'un transistor */
835 /* CDS represente la capacite de jonction par unite de surface */
836 /* Unite: F/m^2 */
837 /* Methode de calcul(approximative): CDS = CJ */
838 /*******************************************************************************/
839 double mcc_calcCDS(char *technoname, char *transname,
840 int transtype, int transcase, double L, double W, double temp,
841 double vbx1, double vbx2, elp_lotrs_param *lotrsparam)
842 {
843 mcc_modellist *ptmodel ;
844 double cds = 0.0 ;
845
846 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
847 return(0.0) ;
848 else {
849 switch(ptmodel->MODELTYPE) {
850 case MCC_BSIM3V3 :
851 case MCC_MM9 :
852 case MCC_MOS2 : cds = mcc_calcCDS_com(ptmodel, temp, vbx1, vbx2) ;
853 break ;
854 case MCC_BSIM4 : cds = mcc_calcCDS_bsim4 (ptmodel, temp, vbx1, vbx2) ;
855 break ;
856 case MCC_MPSPB :
857 case MCC_MPSP : cds = mcc_calcCDS_psp( ptmodel, lotrsparam, temp, vbx1, vbx2, L, W );
858 break ;
859 case MCC_EXTMOD : cds = mcc_calcCDS_ext( ptmodel, lotrsparam, temp, vbx1, vbx2, L, W );
860 break ;
861 }
862 }
863 return cds ;
864 }
865
866 /*******************************************************************************/
867 /* Calcul de capacite de drain CDP d'un transistor */
868 /* CDP represente la capacite de jonction (sidewall junction) */
869 /* Unite: F/m */
870 /* Methode de calcul(approximative): CDP = CJSW */
871 /*******************************************************************************/
872 double mcc_calcCDP(char *technoname, char *transname,
873 int transtype, int transcase, double L, double W,
874 double temp, double vbx1, double vbx2, elp_lotrs_param *lotrsparam)
875 {
876 mcc_modellist *ptmodel ;
877 double cdp = 0.0 ;
878
879 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
880 return(0.0) ;
881 else {
882 switch(ptmodel->MODELTYPE) {
883 case MCC_BSIM3V3 :
884 case MCC_MM9 :
885 case MCC_MOS2 : cdp = mcc_calcCDP_com(ptmodel, temp, vbx1, vbx2) ;
886 break ;
887 case MCC_BSIM4 : cdp = mcc_calcCDP_bsim4( ptmodel, lotrsparam,temp, vbx1, vbx2 );
888 break ;
889 case MCC_MPSPB :
890 case MCC_MPSP : cdp = mcc_calcCDP_psp( ptmodel, lotrsparam,temp, vbx1, vbx2, L, W );
891 break ;
892 case MCC_EXTMOD : cdp = mcc_calcCDP_ext( ptmodel, lotrsparam,temp, vbx1, vbx2, L, W );
893 break ;
894 }
895 }
896 return cdp ;
897 }
898
899 /*******************************************************************************/
900 /* Calcul de capacite de drain CDW d'un transistor */
901 /* CDW represente la capacite de jonction (sidewall junction facing gate) */
902 /* Unite: F/m */
903 /* Methode de calcul(approximative): CDW = CJSWG (bsim3v3) */
904 /* Methode de calcul(approximative): CDW = CGP (mos level 2) */
905 /*******************************************************************************/
906 double mcc_calcCDW(char *technoname, char *transname,
907 int transtype, int transcase, double L, double W, double temp,
908 double vbx1, double vbx2, double vgx, elp_lotrs_param *lotrsparam)
909 {
910 mcc_modellist *ptmodel ;
911 double cdw = 0.0 ;
912
913 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
914 return(0.0) ;
915 else {
916 switch(ptmodel->MODELTYPE) {
917 case MCC_BSIM3V3 :
918 case MCC_MM9 :
919 case MCC_MOS2 : cdw = mcc_calcCDW_com(ptmodel, temp, vbx1, vbx2, vgx, L, W) ;
920 break ;
921 case MCC_BSIM4 : cdw = mcc_calcCDW_bsim4 (ptmodel, lotrsparam,temp, vbx1, vbx2, vgx, L, W) ;
922 break ;
923 case MCC_MPSPB :
924 case MCC_MPSP : cdw = mcc_calcCDW_psp (ptmodel, lotrsparam,temp, vbx1, vbx2, L, W) ;
925 break ;
926 case MCC_EXTMOD : cdw = mcc_calcCDW_ext(ptmodel, lotrsparam,temp, vbx1, vbx2, L, W) ;
927 break ;
928 }
929 }
930 return cdw ;
931 }
932
933 /******************************************************************************\
934 Function : mcc_calcDWCJ
935 \******************************************************************************/
936 double mcc_calcDWCJ (char *technoname, char *transname,
937 int transtype, int transcase,
938 double L, double W,
939 elp_lotrs_param *lotrsparam, double temp)
940 {
941 mcc_modellist *ptmodel ;
942 double dwcj = 0.0 ;
943
944 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
945 return(0.0) ;
946 else {
947 switch(ptmodel->MODELTYPE) {
948 case MCC_BSIM3V3 : dwcj = mcc_calcDW_bsim3v3(ptmodel, L, W) ;
949 break ;
950 case MCC_BSIM4 : dwcj = mcc_calcDWCJ_bsim4(ptmodel, lotrsparam,L, W) ;
951 break ;
952 case MCC_MM9 :
953 case MCC_MOS2 : dwcj = mcc_calcDW_com(ptmodel) ;
954 break ;
955 case MCC_MPSPB :
956 case MCC_MPSP : dwcj = mcc_calcDWCJ_psp(ptmodel, lotrsparam, temp, L, W) ;
957 break ;
958 case MCC_EXTMOD : dwcj = mcc_calcDWCJ_ext(ptmodel, lotrsparam, temp, L, W) ;
959 break ;
960 }
961 }
962 return dwcj;
963 }
964
965
966 /*******************************************************************************/
967 /* Les valeurs des capacites de source sont egales aux capacites de drain */
968 /*******************************************************************************/
969 /* Calcul de capacite de source CSS d'un transistor */
970 /* CSS represente la capacite de jonction par unite de surface */
971 /* Unite: F/m^2 */
972 /* Methode de calcul(approximative): CSS = CJ = CDS */
973 /*******************************************************************************/
974 double mcc_calcCSS(char *technoname, char *transname,
975 int transtype, int transcase, double L, double W,
976 double temp, double vbx1, double vbx2, elp_lotrs_param *lotrsparam )
977 {
978 mcc_modellist *ptmodel ;
979 double css = 0.0 ;
980
981 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
982 return(0.0) ;
983 else {
984 switch(ptmodel->MODELTYPE) {
985 case MCC_BSIM3V3 :
986 case MCC_MM9 :
987 case MCC_MOS2 : css = mcc_calcCDS_com(ptmodel, temp, vbx1, vbx2) ;
988 break ;
989 case MCC_BSIM4 : css = mcc_calcCDS_bsim4 (ptmodel, temp, vbx1, vbx2) ;
990 break ;
991 case MCC_MPSPB :
992 case MCC_MPSP : css = mcc_calcCDS_psp( ptmodel, lotrsparam, temp, vbx1, vbx2, L, W );
993 break ;
994 case MCC_EXTMOD : css = mcc_calcCDS_ext( ptmodel, lotrsparam, temp, vbx1, vbx2, L, W );
995 break ;
996 }
997 }
998 return css ;
999 }
1000
1001 /*******************************************************************************/
1002 /* Calcul de capacite de source CSP d'un transistor */
1003 /* CSP represente la capacite de jonction (sidewall junction) */
1004 /* Unite: F/m */
1005 /* Methode de calcul(approximative): CSP = CJSW = CDP */
1006 /*******************************************************************************/
1007 double mcc_calcCSP(char *technoname, char *transname,
1008 int transtype, int transcase, double L, double W,
1009 double temp, double vbx1, double vbx2, elp_lotrs_param *lotrsparam)
1010 {
1011 mcc_modellist *ptmodel ;
1012 double csp = 0.0 ;
1013
1014 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
1015 return(0.0) ;
1016 else {
1017 switch(ptmodel->MODELTYPE) {
1018 case MCC_BSIM3V3 :
1019 case MCC_MM9 :
1020 case MCC_MOS2 : csp = mcc_calcCDP_com(ptmodel, temp, vbx1,vbx2) ;
1021 break ;
1022 case MCC_BSIM4 : csp = mcc_calcCDP_bsim4 (ptmodel, lotrsparam,temp, vbx1,vbx2) ;
1023 break ;
1024 case MCC_MPSPB :
1025 case MCC_MPSP : csp = mcc_calcCDP_psp( ptmodel, lotrsparam,temp, vbx1, vbx2, L, W ) ;
1026 break ;
1027 case MCC_EXTMOD : csp = mcc_calcCDP_ext( ptmodel, lotrsparam,temp, vbx1, vbx2, L, W ) ;
1028 break ;
1029 }
1030 }
1031 return csp ;
1032 }
1033
1034 /*******************************************************************************/
1035 /* Calcul de capacite de drain CSW d'un transistor */
1036 /* CSW represente la capacite de jonction (sidewall junction facing gate) */
1037 /* Unite: F/m */
1038 /* Methode de calcul(approximative): CSW = CJSWG (bsim3v3) = CDW */
1039 /* Methode de calcul(approximative): CSW = CGP = CDW (mos2) */
1040 /*******************************************************************************/
1041 double mcc_calcCSW(char *technoname, char *transname,
1042 int transtype, int transcase, double L, double W, double temp,
1043 double vbx1, double vbx2, double vgx, elp_lotrs_param *lotrsparam)
1044 {
1045 mcc_modellist *ptmodel ;
1046 double csw = 0.0 ;
1047
1048 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
1049 return(0.0) ;
1050 else {
1051 switch(ptmodel->MODELTYPE) {
1052 case MCC_BSIM3V3 :
1053 case MCC_MM9 :
1054 case MCC_MOS2 : csw = mcc_calcCDW_com(ptmodel, temp, vbx1, vbx2, vgx, L, W) ;
1055 break ;
1056 case MCC_BSIM4 : csw = mcc_calcCDW_bsim4 (ptmodel, lotrsparam, temp, vbx1, vbx2, vgx, L, W) ;
1057 break ;
1058 case MCC_MPSPB :
1059 case MCC_MPSP : csw = mcc_calcCDW_psp (ptmodel, lotrsparam, temp, vbx1, vbx2, L, W) ;
1060 break ;
1061 case MCC_EXTMOD : csw = mcc_calcCDW_ext(ptmodel, lotrsparam, temp, vbx1, vbx2, L, W);
1062 break ;
1063 }
1064 }
1065 return csw ;
1066 }
1067
1068 /******************************************************************************/
1069 /* Obtention du level du modele */
1070 /******************************************************************************/
1071 double mcc_gettechnolevel(char *technoname)
1072 {
1073 double level = 0.0 ;
1074 mcc_technolist *pttechnofile ;
1075 mcc_modellist *ptmodel ;
1076 char type = 'N';
1077
1078 if(!(pttechnofile = mcc_gettechnofile(technoname)))
1079 return(0.0) ;
1080
1081 ptmodel = pttechnofile->MODEL ;
1082 while (ptmodel) {
1083 if (ptmodel->TYPE != MCC_UNKNOWN)
1084 type = 'Y';
1085 if ((mcc_getparamtype_quick(ptmodel, __MCC_QUICK_LEVEL) == MCC_SETVALUE) &&
1086 (type == 'Y'))
1087 break ;
1088 else
1089 ptmodel = ptmodel->NEXT ;
1090 }
1091 if (ptmodel)
1092 level = mcc_getparam_quick(ptmodel, __MCC_QUICK_LEVEL) ;
1093
1094 return(level) ;
1095 }
1096
1097 /******************************************************************************/
1098 /* Obtention de l'index d'un modele */
1099 /******************************************************************************/
1100 int mcc_gettransindex(char *technoname, char *transname, int transtype,
1101 int transcase, double L, double W)
1102 {
1103 mcc_modellist *ptmodel ;
1104 char *name ;
1105
1106 if (( ptmodel = mcc_getmodel(technoname, transname, transtype,
1107 transcase, L, W, 0) )) {
1108 name = strchr(ptmodel->NAME, MCC_MOD_SEPAR) ;
1109 if(name == NULL)
1110 return (0) ;
1111 else
1112 return(atoi(name+1)) ;
1113 }
1114 avt_errmsg(MCC_ERRMSG, "014", AVT_ERROR,transname, technoname) ;
1115 return (0) ;
1116 }
1117
1118 /******************************************************************************/
1119 /* Obtention du nom complet (avec ou sans extension) d'un modele */
1120 /******************************************************************************/
1121 char *mcc_getmodelname(char *technoname, char *transname,
1122 int transtype, int transcase, double L, double W)
1123 {
1124 mcc_modellist *ptmodel ;
1125
1126 if((ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)) != NULL)
1127 return(mbkstrdup(ptmodel->NAME)) ;
1128 else
1129 avt_errmsg(MCC_ERRMSG, "015", AVT_ERROR, transname, technoname) ;
1130 return(NULL) ;
1131 }
1132
1133 /******************************************************************************/
1134 /* Calcul du parametre de XL <=> LMLT d'un modele */
1135 /******************************************************************************/
1136 double mcc_getXL (char *technoname, char *transname,
1137 int transtype, int transcase, double L, double W)
1138 {
1139 mcc_modellist *ptmodel ;
1140 double lmlt = 1.0 ;
1141
1142 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0))) {
1143 avt_errmsg(MCC_ERRMSG, "016", AVT_ERROR, transname, technoname) ;
1144 return(0.0) ;
1145 }
1146 else {
1147 switch(ptmodel->MODELTYPE) {
1148 case MCC_MM9 :
1149 case MCC_MOS2 :
1150 case MCC_BSIM3V3 :
1151 case MCC_BSIM4 :
1152 lmlt = mcc_getparam_quick(ptmodel, __MCC_QUICK_LMLT) ;
1153 break ;
1154 case MCC_MPSPB :
1155 case MCC_MPSP :
1156 case MCC_EXTMOD :
1157 lmlt = 1.0 ;
1158 break ;
1159 }
1160 }
1161
1162 return(lmlt) ;
1163 }
1164
1165 /******************************************************************************/
1166 /* Calcul du parametre de XW <=> WMLT d'un modele */
1167 /******************************************************************************/
1168 double mcc_getXW (char *technoname, char *transname,
1169 int transtype, int transcase, double L, double W)
1170 {
1171 mcc_modellist *ptmodel ;
1172 double wmlt = 1.0 ;
1173
1174 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0))) {
1175 avt_errmsg(MCC_ERRMSG, "017", AVT_ERROR, transname, technoname) ;
1176 return(0.0) ;
1177 }
1178 else {
1179 switch(ptmodel->MODELTYPE) {
1180 case MCC_MM9 :
1181 case MCC_MOS2 :
1182 case MCC_BSIM3V3 :
1183 case MCC_BSIM4 :
1184 wmlt = mcc_getparam_quick(ptmodel, __MCC_QUICK_WMLT) ;
1185 break ;
1186 case MCC_MPSPB :
1187 case MCC_MPSP :
1188 case MCC_EXTMOD :
1189 wmlt = 1.0 ;
1190 break ;
1191 }
1192 }
1193
1194 return(wmlt) ;
1195 }
1196
1197 /********************************************************************************************/
1198 /* Fonction qui calcule la capacite de grille CGS d'un transistor */
1199 /* CGS = Cox = epsox / TOX */
1200 /********************************************************************************************/
1201 double mcc_calcCGS_com(mcc_modellist *ptmodel)
1202 {
1203 double cgs ;
1204 double Cox, TOX ;
1205
1206 TOX = mcc_getparam_quick(ptmodel, __MCC_QUICK_TOX) ;
1207 Cox = MCC_EPSOX / TOX ;
1208 cgs = Cox ;
1209
1210 return(cgs) ;
1211 }
1212
1213 /********************************************************************************************/
1214 /* Fonction qui calcule la capacite de grille CGP d'un transistor */
1215 /* CGP = CGSO = CGDO */
1216 /********************************************************************************************/
1217 double mcc_calcCGP_com(mcc_modellist *ptmodel)
1218 {
1219 double cgp ;
1220 double CGDO ;
1221
1222 //CGDO = mcc_getprm(ptmodel, "CGDO") ;
1223 CGDO = mcc_getprm_quick(ptmodel, __MCC_GETPRM_CGDO) ;
1224 cgp = CGDO ;
1225
1226 return(cgp) ;
1227 }
1228
1229 /******************************************************************************\
1230 Fonction qui calcule la capacite de drain CDS d'un transistor
1231 Contribution surfacique.
1232
1233 CDS = CJ
1234 \******************************************************************************/
1235 double mcc_calcCDS_com(mcc_modellist *ptmodel, double temp, double vbx1, double vbx2)
1236 {
1237 double cds = 0.0 ;
1238 double T, Tnom, dT, VtT, VtTnom ;
1239 double Egeff_T, Egeff_Tnom ;
1240 double MJ, CJ, PB ;
1241 double CJ_T = 0.0 ;
1242 double PB_T = 0.0 ;
1243 double EG, GAP1, GAP2 ;
1244 double Dpb = 0.0 ;
1245 /* param pour diolev = 9 */
1246 double VR, VDBR, CJBR, TRDIO9 ;
1247 double VtTR = 0.0 ;
1248 double Egeff_TR = 0.0 ;
1249 double Ftd = 0.0 ;
1250 double VdbT = 0.0 ;
1251 double CjbT = 0.0 ;
1252 double Fcb = 0.0 ;
1253 double Vlb = 0.0 ;
1254 double Clb = 0.0 ;
1255
1256 if( ptmodel->TYPE == MCC_TRANS_P ) {
1257 vbx1 = -vbx1 ;
1258 vbx2 = -vbx2 ;
1259 }
1260
1261 T = temp + MCC_KELVIN ;
1262 Tnom = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM)+MCC_KELVIN ;
1263 dT = T - Tnom ;
1264 VtT = MCC_KB*T/MCC_Q ;
1265 VtTnom = MCC_KB*Tnom/MCC_Q ;
1266
1267 GAP1 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP1) ;
1268 GAP2 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP2) ;
1269 EG = mcc_getparam_quick(ptmodel, __MCC_QUICK_EG) ;
1270
1271 if((mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEV) == 0.0) ||
1272 (mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEV) == 1.0)) {
1273 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1274 Egeff_Tnom = 1.16-7.02e-4*pow(Tnom, 2.0)/(Tnom+1108.0) ;
1275 }
1276 else {
1277 Egeff_T = EG - GAP1*pow(T, 2.0)/(T+GAP2) ;
1278 Egeff_Tnom = EG - GAP1*pow(Tnom, 2.0)/(Tnom+GAP2) ;
1279 }
1280
1281
1282 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_DIOLEV) != 9.0) {
1283 CJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJ) ;
1284 MJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJ) ;
1285 PB = mcc_getparam_quick(ptmodel, __MCC_QUICK_PB) ;
1286 if((mcc_getparamtype_quick(ptmodel, __MCC_QUICK_OPTACM) == MCC_SETVALUE) &&
1287 (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) >= 10.0)){
1288 PB_T = PB ;
1289 CJ_T = CJ ;
1290 }
1291 else {
1292 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 0.0) {
1293 PB_T = PB*T/Tnom-VtT*(Egeff_Tnom/VtTnom-Egeff_T/VtT+3.0*log(T/Tnom)) ;
1294 CJ_T = CJ*(1.0+MJ*(1.0+4.0e-4*dT-PB_T/PB)) ;
1295 }
1296 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 1.0) {
1297 //PB_T = PB - mcc_getprm(ptmodel, "PTA")*dT ;
1298 //CJ_T = CJ*(1.0+mcc_getprm(ptmodel, "CTA")*dT) ;
1299 PB_T = PB - mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTA)*dT ;
1300 CJ_T = CJ*(1.0+mcc_getprm_quick(ptmodel, __MCC_GETPRM_CTA)*dT) ;
1301 }
1302 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 2.0) {
1303 //PB_T = PB - mcc_getprm(ptmodel, "PTA")*dT ;
1304 PB_T = PB - mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTA)*dT ;
1305 CJ_T = CJ*pow((PB/PB_T), MJ) ;
1306 }
1307 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 3.0) {
1308 Dpb = PB - Egeff_Tnom-3.0*VtTnom+(Egeff_Tnom-EG)*(2.0-Tnom/(Tnom+GAP2)) ;
1309 PB_T = PB + Dpb * (dT/Tnom) ;
1310 CJ_T = CJ*(1.0-0.5*(Dpb/PB)*(dT/Tnom)) ;
1311 }
1312 if ( PB_T < 0.1 )
1313 PB_T = 0.1;
1314 if ( CJ_T < 0.0 )
1315 CJ_T = 0.0;
1316 }
1317 /* influence de vbx */
1318 // seulement valable pour les vbx < 0
1319 cds = mcc_integfordw ( CJ_T, vbx1, vbx2, PB_T, MJ);
1320
1321 }
1322 else {
1323 VR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VR) ;
1324 PB = mcc_getparam_quick(ptmodel, __MCC_QUICK_PB) ;
1325 VDBR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VDBR) ;
1326 CJBR = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJBR) ;
1327 TRDIO9 = mcc_getparam_quick(ptmodel, __MCC_QUICK_TRDIO9)+MCC_KELVIN ;
1328 /* Temperature update */
1329 VtTR = MCC_KB*TRDIO9/MCC_Q ;
1330 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1331 Egeff_TR = 1.16-7.02e-4*pow(TRDIO9, 2.0)/(TRDIO9+1108.0) ;
1332 Ftd = pow((T/TRDIO9), 1.5)*exp((Egeff_TR/(2.0*VtTR))-Egeff_T/(2.0*VtT)) ;
1333
1334 VdbT = VDBR*T/TRDIO9-2.0*VtT*log(Ftd) ;
1335 CjbT = CJBR*pow(((VDBR-VR)/VdbT), PB) ;
1336
1337 Fcb = 1.0-pow(((1.0+PB)/3.0), (1.0/PB)) ;
1338 Vlb = Fcb*VdbT ;
1339 Clb = CjbT*pow((1.0-Fcb), -PB) ;
1340
1341 cds = mcc_integfordw ( CjbT, vbx1, vbx2, VdbT, PB);
1342 }
1343
1344 return cds ;
1345 }
1346
1347 /******************************************************************************\
1348 Fonction qui calcule la capacite de drain CDP d'un transistor
1349 Contribution perimetrique.
1350
1351 CDP = CJSW
1352 \******************************************************************************/
1353 double mcc_calcCDP_com(mcc_modellist *ptmodel, double temp, double vbx1, double vbx2)
1354 {
1355 double cdp = 0.0 ;
1356 double T = 0.0 ;
1357 double Tnom = 0.0 ;
1358 double dT = 0.0 ;
1359 double VtT = 0.0 ;
1360 double VtTnom = 0.0 ;
1361 double Egeff_T = 0.0 ;
1362 double Egeff_Tnom = 0.0 ;
1363 double MJSW = 0.0 ;
1364 double CJSW = 0.0 ;
1365 double PBSW = 0.0 ;
1366 double CJSW_T = 0.0 ;
1367 double PBSW_T = 0.0 ;
1368 double EG = 0.0 ;
1369 double GAP1 = 0.0 ;
1370 double GAP2 = 0.0 ;
1371 double Dpbsw = 0.0 ;
1372 /* param pour diolev = 9 */
1373 double VR, PS, VDSR, CJSR, TRDIO9 ;
1374 double VtTR = 0.0 ;
1375 double Egeff_TR = 0.0 ;
1376 double Ftd = 0.0 ;
1377 double VdsT = 0.0 ;
1378 double CjsT = 0.0 ;
1379 double Fcs = 0.0 ;
1380 double Vls = 0.0 ;
1381 double Cls = 0.0 ;
1382 int ACM;
1383
1384 if( ptmodel->TYPE == MCC_TRANS_P ) {
1385 vbx1 = -vbx1 ;
1386 vbx2 = -vbx2 ;
1387 }
1388
1389 T = temp + MCC_KELVIN ;
1390 Tnom = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM)+MCC_KELVIN ;
1391 dT = T - Tnom ;
1392 VtT = MCC_KB*T/MCC_Q ;
1393 VtTnom = MCC_KB*Tnom/MCC_Q ;
1394
1395 GAP1 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP1) ;
1396 GAP2 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP2) ;
1397 EG = mcc_getparam_quick(ptmodel, __MCC_QUICK_EG) ;
1398
1399 if((mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEV) == 0.0) ||
1400 (mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEV) == 1.0)) {
1401 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1402 Egeff_Tnom = 1.16-7.02e-4*pow(Tnom, 2.0)/(Tnom+1108.0) ;
1403 }
1404 else {
1405 Egeff_T = EG - GAP1*pow(T, 2.0)/(T+GAP2) ;
1406 Egeff_Tnom = EG - GAP1*pow(Tnom, 2.0)/(Tnom+GAP2) ;
1407 }
1408
1409 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_DIOLEV) != 9.0) {
1410 CJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJSW) ;
1411 MJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSW) ;
1412 PBSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_PBSW) ;
1413 if(ptmodel->MODELTYPE == MCC_BSIM3V3) {
1414 if ( V_INT_TAB[__SIM_TOOLMODEL].VALUE == SIM_TOOLMODEL_HSPICE ) {
1415 //ACM = mcc_check_hsp_acm_bsim3v3 (ptmodel);
1416 ACM = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_ACM));
1417 if ( ACM >= 0 && ACM <= 3 )
1418 PBSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_PHP) ;
1419 }
1420 }
1421
1422 if((mcc_getparamtype_quick(ptmodel, __MCC_QUICK_OPTACM) == MCC_SETVALUE) &&
1423 (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) >= 10.0)){
1424 PBSW_T = PBSW ;
1425 CJSW_T = CJSW ;
1426 }
1427 else {
1428 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 0.0) {
1429 PBSW_T = PBSW*T/Tnom-VtT*(Egeff_Tnom/VtTnom-Egeff_T/VtT+3.0*log(T/Tnom)) ;
1430 CJSW_T = CJSW*(1.0+MJSW*(1.0+4.0e-4*dT-PBSW_T/PBSW)) ;
1431 }
1432 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 1.0) {
1433 //PBSW_T = PBSW - mcc_getprm(ptmodel, "PTP")*dT ;
1434 //CJSW_T = CJSW*(1.0+mcc_getprm(ptmodel, "CTP")*dT) ;
1435 PBSW_T = PBSW - mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTP)*dT ;
1436 CJSW_T = CJSW*(1.0+mcc_getprm_quick(ptmodel, __MCC_GETPRM_CTP)*dT) ;
1437 }
1438 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 2.0) {
1439 //PBSW_T = PBSW-mcc_getprm(ptmodel, "PTP")*dT ;
1440 PBSW_T = PBSW-mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTP)*dT ;
1441 CJSW_T = CJSW*pow((PBSW/PBSW_T), MJSW) ;
1442 }
1443 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) == 3.0) {
1444 Dpbsw = PBSW - Egeff_Tnom-3.0*VtTnom+(Egeff_Tnom-EG)*(2.0-Tnom/(Tnom+GAP2)) ;
1445 PBSW_T = PBSW + Dpbsw*(dT/Tnom) ;
1446 CJSW_T = CJSW*(1.0-0.5*(Dpbsw/PBSW)*(dT/Tnom)) ;
1447 }
1448 if ( PBSW_T < 0.1 )
1449 PBSW_T = 0.1;
1450 if ( CJSW_T < 0.0 )
1451 CJSW_T = 0.0;
1452 }
1453 cdp = mcc_integfordw ( CJSW_T, vbx1, vbx2, PBSW_T, MJSW);
1454 }
1455 else {
1456 VR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VR) ;
1457 PS = mcc_getparam_quick(ptmodel, __MCC_QUICK_PS) ;
1458 VDSR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VDSR) ;
1459 CJSR = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJSR) ;
1460 TRDIO9 = mcc_getparam_quick(ptmodel, __MCC_QUICK_TRDIO9)+MCC_KELVIN ;
1461 /* Temperature update */
1462 VtTR = MCC_KB*TRDIO9/MCC_Q ;
1463 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1464 Egeff_TR = 1.16-7.02e-4*pow(TRDIO9, 2.0)/(TRDIO9+1108.0) ;
1465 Ftd = pow((T/TRDIO9), 1.5)*exp((Egeff_TR/(2.0*VtTR))-Egeff_T/(2.0*VtT)) ;
1466
1467 VdsT = VDSR*T/TRDIO9-2.0*VtT*log(Ftd) ;
1468 CjsT = CJSR*pow(((VDSR-VR)/VdsT), PS) ;
1469
1470 Fcs = 1.0-pow(((1.0+PS)/3.0), (1.0/PS)) ;
1471 Vls = Fcs*VdsT ;
1472 Cls = CjsT*pow((1.0-Fcs), -PS) ;
1473 /* vbx < Vls */
1474 cdp = mcc_integfordw ( CjsT, vbx1, vbx2, VdsT, PS);
1475 }
1476
1477 return cdp ;
1478 }
1479
1480 /********************************************************************************************\
1481 Fonction qui calcule la capacite de grille CDW d'un transistor
1482 CDW = CSW = CGP + Capa (contribion en largeur face a la grille)
1483
1484 \********************************************************************************************/
1485 double mcc_calcCDW_com(mcc_modellist *ptmodel, double temp, double vbx1, double vbx2, double vgx, double L, double W)
1486 {
1487 double cdw = 0.0 ;
1488 double CJSWG, CJGR , CJGATE ;
1489 double T, Tnom ;
1490 /* param pour CJGR */
1491 double VtT, VtTnom, VtTR, Egeff_T, Egeff_TR, Ftd ;
1492 double VdgT = 0.0 ;
1493 double CjgT = 0.0 ;
1494 double TRDIO9 ;
1495 double VR, VDGR, PG ;
1496 double Cjgv = 0.0 ;
1497 /* param pour CJSWG */
1498 double MJSWG, PBSWG ;
1499 double Cbxg = 0.0 ;
1500 /* param pour CJGATE */
1501 double TLEVC, MJSW, dT ;
1502 double PbswT = 0.0 ;
1503 double PBSW = 0.0 ;
1504 double CjgateT = 0.0 ;
1505 double CTP, GAP2, EG, PTP, Dpbsw, Egeff_Tnom ;
1506 /* contribution de CGP */
1507 double Cgp = 0.0 ;
1508 double Cdp = 0.0 ;
1509 int ACM;
1510
1511 T = temp + MCC_KELVIN ;
1512 Tnom = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM) + MCC_KELVIN ;
1513 dT = T - Tnom ;
1514 VtT = MCC_KB*T/MCC_Q ;
1515 VtTnom= MCC_KB*Tnom/MCC_Q ;
1516
1517 CJSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJSWG) ;
1518 CJGR = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJGR) ;
1519 CJGATE= mcc_getparam_quick(ptmodel, __MCC_QUICK_CJGATE) ;
1520 if(ptmodel->MODELTYPE == MCC_BSIM3V3) {
1521 if ( V_INT_TAB[__SIM_TOOLMODEL].VALUE == SIM_TOOLMODEL_HSPICE )
1522 //ACM = mcc_check_hsp_acm_bsim3v3 (ptmodel);
1523 ACM = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_ACM));
1524 }
1525
1526 /* Contribution de la capacite Cgp (overlap capacitance) */
1527 if( ptmodel->MODELTYPE == MCC_BSIM3V3) {
1528 // Before taking CJSWG, test if it is HSPICE models and take CJGATE instead
1529 if ( V_INT_TAB[__SIM_TOOLMODEL].VALUE == SIM_TOOLMODEL_HSPICE ) {
1530 if ( ACM >= 0 && ACM <= 3 )
1531 CJSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJGATE) ;
1532 }
1533 Cgp = mcc_calcCGP_bsim3v3(ptmodel, vgx, L, W, NULL) ;
1534 Cdp = mcc_calcCDP_com(ptmodel, temp, vbx1, vbx2 );
1535 }
1536 else
1537 Cgp = mcc_calcCGP_com(ptmodel) ;
1538
1539 if( ptmodel->TYPE == MCC_TRANS_P ) {
1540 vbx1 = -vbx1 ;
1541 vbx2 = -vbx2 ;
1542 }
1543
1544 /* Debut du calcul de la capacite cdw en fonction de diolev */
1545 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_DIOLEV) == 9.0) {
1546 /* temp effect */
1547 TRDIO9 = mcc_getparam_quick(ptmodel, __MCC_QUICK_TRDIO9)+MCC_KELVIN ;
1548 VDGR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VDGR) ;
1549 PG = mcc_getparam_quick(ptmodel, __MCC_QUICK_PG) ;
1550 VR = mcc_getparam_quick(ptmodel, __MCC_QUICK_VR) ;
1551
1552 VtTR = MCC_KB*TRDIO9/MCC_Q ;
1553 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1554 Egeff_TR = 1.16-7.02e-4*pow(TRDIO9, 2.0)/(TRDIO9+1108.0) ;
1555 Ftd = pow((T/TRDIO9), 1.5)*exp((Egeff_TR/(2.0*VtTR))-Egeff_T/(2.0*VtT)) ;
1556
1557 VdgT = VDGR*T/TRDIO9-2.0*VtT*log(Ftd) ;
1558 CjgT = CJGR*pow(((VDGR-VR)/VdgT), PG) ;
1559
1560 Cjgv = mcc_integfordw ( CjgT, vbx1, vbx2, VdgT, PG);
1561
1562 cdw = Cgp+ Cjgv ;
1563 }
1564 else if(ptmodel->MODELTYPE == MCC_BSIM3V3) {
1565 MJSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSWG);
1566 PBSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_PBSWG);
1567 if ( V_INT_TAB[__SIM_TOOLMODEL].VALUE == SIM_TOOLMODEL_HSPICE ) {
1568 if ( ACM >= 0 && ACM <= 3 ) {
1569 MJSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSW);
1570 PBSWG = mcc_getparam_quick(ptmodel, __MCC_QUICK_PHP);
1571 }
1572 }
1573 /* no temp effect */
1574
1575 /* vbx effect */
1576 Cbxg = mcc_integfordw ( CJSWG, vbx1, vbx2, PBSWG, MJSWG);
1577
1578 cdw = Cgp+ Cbxg ;
1579 }
1580 else {
1581 /* temp effect */
1582 TLEVC = mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC) ;
1583 PBSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_PBSW) ;
1584 if ( V_INT_TAB[__SIM_TOOLMODEL].VALUE == SIM_TOOLMODEL_HSPICE )
1585 if ( ACM >= 0 && ACM <= 3 )
1586 PBSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_PHP) ;
1587
1588 MJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSW) ;
1589
1590 if(TLEVC == 0.0) {
1591 Egeff_T = 1.16-7.02e-4*pow(T, 2.0)/(T+1108.0) ;
1592 Egeff_Tnom = 1.16-7.02e-4*pow(Tnom, 2.0)/(Tnom+1108.0) ;
1593 PbswT = PBSW*T/Tnom-VtT*(Egeff_Tnom/VtTnom-Egeff_T/VtT+3.0*log(T/Tnom)) ;
1594 CjgateT = CJGATE*(1.0+MJSW*(1.0+4.0e-4*dT-PbswT/PBSW)) ;
1595 }
1596 else if(TLEVC == 1.0) {
1597 //CTP = mcc_getprm(ptmodel, "CTP") ;
1598 //PTP = mcc_getprm(ptmodel, "PTP") ;
1599 CTP = mcc_getprm_quick(ptmodel, __MCC_GETPRM_CTP) ;
1600 PTP = mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTP) ;
1601 PbswT = PBSW - PTP*dT ;
1602 CjgateT = CJGATE*(1.0+CTP*dT) ;
1603 }
1604 else if(TLEVC == 2.0) {
1605 //PTP = mcc_getprm(ptmodel, "PTP") ;
1606 PTP = mcc_getprm_quick(ptmodel, __MCC_GETPRM_PTP) ;
1607 PbswT = PBSW - PTP*dT ;
1608 CjgateT = CJGATE*pow((PBSW/PbswT), MJSW) ;
1609 }
1610 else if(TLEVC == 3.0) {
1611 GAP2 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP2) ;
1612 EG = mcc_getparam_quick(ptmodel, __MCC_QUICK_EG) ;
1613 Egeff_Tnom = 1.16-7.02e-4*pow(Tnom, 2.0)/(Tnom+1108.0) ;
1614 Dpbsw = PBSW - Egeff_Tnom-3.0*VtTnom+(Egeff_Tnom-EG)
1615 *(2.0-Tnom/(Tnom+GAP2)) ;
1616 PbswT = PBSW + Dpbsw*(dT/Tnom) ;
1617 CjgateT = CJGATE*(1.0-0.5*(Dpbsw/PBSW)*(dT/Tnom)) ;
1618 }
1619 if ( PbswT < 0.1 )
1620 PbswT = 0.1;
1621 if ( CjgateT < 0.0 )
1622 CjgateT = 0.0;
1623 /* vbx effect */
1624 Cbxg = mcc_integfordw ( CjgateT, vbx1, vbx2, PBSW, MJSW);
1625
1626 cdw = Cgp+ Cbxg ;
1627 }
1628 MCC_CBXG = Cbxg;
1629 return cdw - Cdp ;
1630 }
1631
1632
1633 /**************************************************************************/
1634 /* CALCUL de DL */
1635 /**************************************************************************/
1636 double mcc_calcDL_com (mcc_modellist *ptmodel)
1637 {
1638 double XL, LD, DELL, DL ;
1639
1640 //XL = mcc_getprm(ptmodel, "XL") ;
1641 //LD = mcc_getprm(ptmodel, "LD") ;
1642 XL = mcc_getprm_quick(ptmodel, __MCC_GETPRM_XL) ;
1643 LD = mcc_getprm_quick(ptmodel, __MCC_GETPRM_LD) ;
1644
1645 DELL = mcc_getparam_quick(ptmodel, __MCC_QUICK_DELL) ;
1646
1647 DL = XL - 2.0*LD + DELL ;
1648
1649 return(DL) ;
1650 }
1651
1652 /**************************************************************************/
1653 /* CALCUL de DW */
1654 /**************************************************************************/
1655 double mcc_calcDW_com (mcc_modellist *ptmodel)
1656 {
1657 double XW, WD, DELW, DW ;
1658
1659 //XW = mcc_getprm(ptmodel, "XW") ;
1660 //WD = mcc_getprm(ptmodel, "WD") ;
1661 XW = mcc_getprm_quick(ptmodel, __MCC_GETPRM_XW) ;
1662 WD = mcc_getprm_quick(ptmodel, __MCC_GETPRM_WD) ;
1663
1664 DELW = mcc_getparam_quick(ptmodel, __MCC_QUICK_DELW) ;
1665
1666 DW = XW - 2.0*WD + DELW ;
1667
1668 return(DW) ;
1669 }
1670
1671 /********************************************************************************************/
1672 /* Fonction commune d'initialisation des parametres en commun des differents modeles */
1673 /********************************************************************************************/
1674 void mcc_initparam_com(mcc_modellist *ptmodel)
1675 {
1676 int versiond ;
1677
1678 versiond = (int)( 10.0 * mcc_getparam_quick( ptmodel, __MCC_QUICK_VERSION ) + 0.5 );
1679
1680 mcc_initparam_quick(ptmodel, __MCC_QUICK_LMIN, 0.0, NULL, MCC_INITVALUE) ;
1681 mcc_initparam_quick(ptmodel, __MCC_QUICK_LMAX, MCC_D_LWMAX, NULL, MCC_INITVALUE) ;
1682 mcc_initparam_quick(ptmodel, __MCC_QUICK_WMIN, 0.0, NULL, MCC_INITVALUE) ;
1683 mcc_initparam_quick(ptmodel, __MCC_QUICK_WMAX, MCC_D_LWMAX, NULL, MCC_INITVALUE) ;
1684 mcc_initparam_quick(ptmodel, __MCC_QUICK_LMLT, 1.0, NULL, MCC_INITVALUE) ;
1685 mcc_initparam_quick(ptmodel, __MCC_QUICK_WMLT, 1.0, NULL, MCC_INITVALUE) ;
1686
1687 mcc_initparam_quick(ptmodel, __MCC_QUICK_NJ, 1.0, NULL, MCC_INITVALUE) ;
1688 mcc_initparam_quick(ptmodel, __MCC_QUICK_JS, 1.0e-4, NULL, MCC_INITVALUE) ;
1689 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSW, 0.0, NULL, MCC_INITVALUE) ;
1690 mcc_initparam_quick(ptmodel, __MCC_QUICK_XTI, 0.0, NULL, MCC_INITVALUE) ;
1691 /* Initialisation des parametres relatifs a la temperature */
1692 mcc_initparam_quick(ptmodel, __MCC_QUICK_TNOM, V_FLOAT_TAB[__SIM_TNOM].VALUE, NULL, MCC_INITVALUE) ;
1693 mcc_initparam_quick(ptmodel, __MCC_QUICK_TMOD, mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM), NULL, MCC_INITVALUE) ;
1694 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEV, 0.0, NULL, MCC_INITVALUE) ;
1695 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEVC, 0.0, NULL, MCC_INITVALUE) ;
1696 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTA, 0.0, NULL, MCC_INITVALUE) ;
1697 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTP, 0.0, NULL, MCC_INITVALUE) ;
1698 mcc_initparam_quick(ptmodel, __MCC_QUICK_PTA, 0.0, NULL, MCC_INITVALUE) ;
1699 mcc_initparam_quick(ptmodel, __MCC_QUICK_PTP, 0.0, NULL, MCC_INITVALUE) ;
1700 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP1, 7.02e-4, NULL, MCC_INITVALUE) ;
1701 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP2, 1108.0, NULL, MCC_INITVALUE) ;
1702 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEVI, 0.0, NULL, MCC_INITVALUE) ;
1703 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISTMP, 10.0, NULL, MCC_INITVALUE) ;
1704 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEVR, 1.0, NULL, MCC_INITVALUE) ;
1705 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRD1, 0.0, NULL, MCC_INITVALUE) ;
1706 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRD2, 0.0, NULL, MCC_INITVALUE) ;
1707 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRS1, 0.0, NULL, MCC_INITVALUE) ;
1708 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRS2, 0.0, NULL, MCC_INITVALUE) ;
1709 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRSH1, 0.0, NULL, MCC_INITVALUE) ;
1710 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRSH2, 0.0, NULL, MCC_INITVALUE) ;
1711
1712 /* Initialisation des parametres en fonction de ACM */
1713 if(mcc_getparamtype_quick(ptmodel, __MCC_QUICK_OPTACM) == MCC_SETVALUE) {
1714 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 0.0) {
1715 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 0.0, NULL, MCC_INITVALUE) ;
1716 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 0.0, NULL, MCC_INITVALUE) ;
1717 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 2.0, NULL, MCC_INITVALUE) ;
1718 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 3.0, NULL, MCC_INITVALUE) ;
1719 }
1720 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 1.0) {
1721 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 1.0, NULL, MCC_INITVALUE) ;
1722 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 1.0, NULL, MCC_INITVALUE) ;
1723 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 2.0, NULL, MCC_INITVALUE) ;
1724 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 3.0, NULL, MCC_INITVALUE) ;
1725 }
1726 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 2.0) {
1727 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 2.0, NULL, MCC_INITVALUE) ;
1728 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 2.0, NULL, MCC_INITVALUE) ;
1729 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 2.0, NULL, MCC_INITVALUE) ;
1730 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 5.0, NULL, MCC_INITVALUE) ;
1731 }
1732 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 3.0) {
1733 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 3.0, NULL, MCC_INITVALUE) ;
1734 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 3.0, NULL, MCC_INITVALUE) ;
1735 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 2.0, NULL, MCC_INITVALUE) ;
1736 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 0.0, NULL, MCC_INITVALUE) ;
1737 }
1738 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 10.0) {
1739 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 0.0, NULL, MCC_INITVALUE) ;
1740 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 0.0, NULL, MCC_INITVALUE) ;
1741 if( versiond == 31 )
1742 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 6.0, NULL, MCC_INITVALUE) ;
1743 else if( versiond == 32 )
1744 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 7.0, NULL, MCC_INITVALUE) ;
1745 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 4.0, NULL, MCC_INITVALUE) ;
1746 }
1747 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 11.0) {
1748 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 0.0, NULL, MCC_INITVALUE) ;
1749 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 1.0, NULL, MCC_INITVALUE) ;
1750 if( versiond == 31 )
1751 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 6.0, NULL, MCC_INITVALUE) ;
1752 else if( versiond == 32 )
1753 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 7.0, NULL, MCC_INITVALUE) ;
1754 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 4.0, NULL, MCC_INITVALUE) ;
1755 }
1756 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 12.0) {
1757 if((mcc_getparam_quick(ptmodel, __MCC_QUICK_CALCACM) == 0.0) ||
1758 (mcc_getparamtype_quick(ptmodel, __MCC_QUICK_CALCACM) == MCC_INITVALUE))
1759 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 0.0, NULL, MCC_INITVALUE) ;
1760 else if(mcc_getparam_quick(ptmodel, __MCC_QUICK_CALCACM) == 1.0)
1761 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 2.0, NULL, MCC_INITVALUE) ;
1762
1763 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 2.0, NULL, MCC_INITVALUE) ;
1764 if( versiond == 31 )
1765 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 6.0, NULL, MCC_INITVALUE) ;
1766 else if( versiond == 32 )
1767 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 7.0, NULL, MCC_INITVALUE) ;
1768 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 4.0, NULL, MCC_INITVALUE) ;
1769 }
1770 else if (mcc_getparam_quick(ptmodel, __MCC_QUICK_ACM) == 13.0) {
1771 mcc_initparam_quick(ptmodel, __MCC_QUICK_ALEV, 0.0, NULL, MCC_INITVALUE) ;
1772 mcc_initparam_quick(ptmodel, __MCC_QUICK_RLEV, 3.0, NULL, MCC_INITVALUE) ;
1773 if( versiond == 31 )
1774 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 6.0, NULL, MCC_INITVALUE) ;
1775 else if( versiond == 32 )
1776 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 7.0, NULL, MCC_INITVALUE) ;
1777 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAPLEV, 4.0, NULL, MCC_INITVALUE) ;
1778 }
1779 }
1780
1781 /* Initialisation des parametres en fonction de DIOLEV */
1782 if(mcc_getparam_quick(ptmodel, __MCC_QUICK_DIOLEV) == 9.0) {
1783 mcc_initparam_quick(ptmodel, __MCC_QUICK_VR, 0.0, NULL, MCC_INITVALUE) ;
1784 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGBR, 1.0e-3, NULL, MCC_INITVALUE) ;
1785 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDBR, 1.0e-3, NULL, MCC_INITVALUE) ;
1786 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGSR, 1.0e-3, NULL, MCC_INITVALUE) ;
1787 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDSR, 1.0e-3, NULL, MCC_INITVALUE) ;
1788 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGGR, 1.0e-3, NULL, MCC_INITVALUE) ;
1789 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDGR, 1.0e-3, NULL, MCC_INITVALUE) ;
1790 mcc_initparam_quick(ptmodel, __MCC_QUICK_NBJ, 1.0, NULL, MCC_INITVALUE) ;
1791 mcc_initparam_quick(ptmodel, __MCC_QUICK_NSJ, 1.0, NULL, MCC_INITVALUE) ;
1792 mcc_initparam_quick(ptmodel, __MCC_QUICK_NGJ, 1.0, NULL, MCC_INITVALUE) ;
1793 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJBR, 1.0e-12, NULL, MCC_INITVALUE) ;
1794 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSR, 1.0e-12, NULL, MCC_INITVALUE) ;
1795 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJGR, 1.0e-12, NULL, MCC_INITVALUE) ;
1796 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDBR, 1.0, NULL, MCC_INITVALUE) ;
1797 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDSR, 1.0, NULL, MCC_INITVALUE) ;
1798 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDGR, 1.0, NULL, MCC_INITVALUE) ;
1799 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 0.4, NULL, MCC_INITVALUE) ;
1800 mcc_initparam_quick(ptmodel, __MCC_QUICK_PS, 0.4, NULL, MCC_INITVALUE) ;
1801 mcc_initparam_quick(ptmodel, __MCC_QUICK_PG, 0.4, NULL, MCC_INITVALUE) ;
1802 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRDIO9, mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_TNOM), MCC_INITVALUE) ;
1803 }
1804 else {
1805 mcc_initparam_quick(ptmodel, __MCC_QUICK_CBD, 0.0, NULL, MCC_INITVALUE) ;
1806 mcc_initparam_quick(ptmodel, __MCC_QUICK_CBS, 0.0, NULL, MCC_INITVALUE) ;
1807 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJGATE, 0.0, NULL, MCC_INITVALUE) ;
1808 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJ, 0.5, NULL, MCC_INITVALUE) ;
1809 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJSW, 0.33, NULL, MCC_INITVALUE) ;
1810 mcc_initparam_quick(ptmodel, __MCC_QUICK_FC, 0.5, NULL, MCC_INITVALUE) ;
1811 mcc_initparam_quick(ptmodel, __MCC_QUICK_TT, 0.0, NULL, MCC_INITVALUE) ;
1812 /* a verifier vrai dans eldo bsim3 */
1813 if(mcc_getparamtype_quick(ptmodel, __MCC_QUICK_PHP) == MCC_SETVALUE)
1814 {
1815 mcc_initparam_quick(ptmodel, __MCC_QUICK_PBSW, mcc_getparam_quick(ptmodel, __MCC_QUICK_PHP), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_PHP), MCC_INITVALUE) ;
1816 }
1817 if(versiond != 31)
1818 {
1819 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJ, 0.0, NULL, MCC_INITVALUE) ;
1820 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSW, 0.0, NULL, MCC_INITVALUE) ;
1821 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 0.8, NULL, MCC_INITVALUE) ;
1822 mcc_initparam_quick(ptmodel, __MCC_QUICK_PBSW, mcc_getparam_quick(ptmodel, __MCC_QUICK_PB), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_PB), MCC_INITVALUE) ;
1823 mcc_initparam_quick(ptmodel, __MCC_QUICK_PHP, mcc_getparam_quick(ptmodel, __MCC_QUICK_PB), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_PB), MCC_INITVALUE) ;
1824 }
1825 }
1826 }
1827
1828 /*******************************************************************************************\
1829 FUNC : mcc_initparam_diode
1830 \*******************************************************************************************/
1831 void mcc_initparam_diode (mcc_modellist *ptmodel)
1832 {
1833 int level,tlev;
1834
1835 if ( ptmodel->TYPE == MCC_DIODE ) {
1836 mcc_initparam_quick(ptmodel, __MCC_QUICK_LEVEL, 1.0, NULL, MCC_INITVALUE);
1837 level = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_LEVEL));
1838 mcc_initparam_quick(ptmodel, __MCC_QUICK_TNOM, V_FLOAT_TAB[__SIM_TNOM].VALUE, NULL, MCC_INITVALUE);
1839 mcc_initparam_quick(ptmodel, __MCC_QUICK_TREF, V_FLOAT_TAB[__SIM_TNOM].VALUE, NULL, MCC_INITVALUE);
1840 mcc_initparam_quick(ptmodel, __MCC_QUICK_TMOD, mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_TNOM), MCC_INITVALUE) ;
1841 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEV, 0.0, NULL, MCC_INITVALUE);
1842 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEVC, 0.0, NULL, MCC_INITVALUE);
1843 switch ( level ) {
1844 case 1:
1845 //---------------
1846 // LEVEL 1
1847 //---------------
1848 // Scaling factor
1849 mcc_initparam_quick(ptmodel, __MCC_QUICK_SCALEV, 2.0, NULL, MCC_INITVALUE);
1850 mcc_initparam_quick(ptmodel, __MCC_QUICK_AREA, 1.0, NULL, MCC_INITVALUE);
1851 mcc_initparam_quick(ptmodel, __MCC_QUICK_PERIM, 0.0, NULL, MCC_INITVALUE);
1852 mcc_initparam_quick(ptmodel, __MCC_QUICK_SCALM, 1.0, NULL, MCC_INITVALUE);
1853 mcc_initparam_quick(ptmodel, __MCC_QUICK_SHRINK, 1.0, NULL, MCC_INITVALUE);
1854 // DC Related model param
1855 mcc_initparam_quick(ptmodel, __MCC_QUICK_IS, 1.0e-14, NULL, MCC_INITVALUE);
1856 mcc_initparam_quick(ptmodel, __MCC_QUICK_JS, 1.0e-14, NULL, MCC_INITVALUE);
1857 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISA, 1.0e-14, NULL, MCC_INITVALUE);
1858 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISW, 0.0, NULL, MCC_INITVALUE);
1859 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSW, 0.0, NULL, MCC_INITVALUE);
1860 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISP, 0.0, NULL, MCC_INITVALUE);
1861 mcc_initparam_quick(ptmodel, __MCC_QUICK_N, 1.0, NULL, MCC_INITVALUE);
1862 mcc_initparam_quick(ptmodel, __MCC_QUICK_NF, 1.0, NULL, MCC_INITVALUE);
1863 mcc_initparam_quick(ptmodel, __MCC_QUICK_IBV, 1.0e-3, NULL, MCC_INITVALUE);
1864 mcc_initparam_quick(ptmodel, __MCC_QUICK_IK, 0.0, NULL, MCC_INITVALUE);
1865 mcc_initparam_quick(ptmodel, __MCC_QUICK_IKR, 0.0, NULL, MCC_INITVALUE);
1866 // Capacitance Related Model Parameters
1867 mcc_initparam_quick(ptmodel, __MCC_QUICK_DCAP, 1.0, NULL, MCC_INITVALUE);
1868 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJO, 0.0, NULL, MCC_INITVALUE);
1869 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJ0, 0.0, NULL, MCC_INITVALUE);
1870 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJ, 0.0, NULL, MCC_INITVALUE);
1871 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJA, 0.0, NULL, MCC_INITVALUE);
1872 mcc_initparam_quick(ptmodel, __MCC_QUICK_M, 0.5, NULL, MCC_INITVALUE);
1873 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJ, 0.5, NULL, MCC_INITVALUE);
1874 mcc_initparam_quick(ptmodel, __MCC_QUICK_EXA, 0.5, NULL, MCC_INITVALUE);
1875 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSW, 0.0, NULL, MCC_INITVALUE);
1876 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJP, 0.0, NULL, MCC_INITVALUE);
1877 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJSW, 0.33, NULL, MCC_INITVALUE);
1878 mcc_initparam_quick(ptmodel, __MCC_QUICK_EXP, 0.33, NULL, MCC_INITVALUE);
1879 mcc_initparam_quick(ptmodel, __MCC_QUICK_FC, 0.5, NULL, MCC_INITVALUE);
1880 mcc_initparam_quick(ptmodel, __MCC_QUICK_FCS, mcc_getparam_quick(ptmodel, __MCC_QUICK_FC), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_FC), MCC_INITVALUE) ;
1881 mcc_initparam_quick(ptmodel, __MCC_QUICK_KMS, 0.0, NULL, MCC_INITVALUE);
1882 mcc_initparam_quick(ptmodel, __MCC_QUICK_TT, 0.0, NULL, MCC_INITVALUE);
1883 mcc_initparam_quick(ptmodel, __MCC_QUICK_VJ, 1.0, NULL, MCC_INITVALUE);
1884 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 1.0, NULL, MCC_INITVALUE);
1885 mcc_initparam_quick(ptmodel, __MCC_QUICK_PHI, 1.0, NULL, MCC_INITVALUE);
1886 mcc_initparam_quick(ptmodel, __MCC_QUICK_PHP, mcc_getparam_quick(ptmodel, __MCC_QUICK_PB), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_PB), MCC_INITVALUE) ;
1887 // Metal and Polisillicon Capacitor Parameter
1888 mcc_initparam_quick(ptmodel, __MCC_QUICK_LM, 0.0, NULL, MCC_INITVALUE);
1889 mcc_initparam_quick(ptmodel, __MCC_QUICK_LP, 0.0, NULL, MCC_INITVALUE);
1890 mcc_initparam_quick(ptmodel, __MCC_QUICK_WM, 0.0, NULL, MCC_INITVALUE);
1891 mcc_initparam_quick(ptmodel, __MCC_QUICK_WP, 0.0, NULL, MCC_INITVALUE);
1892 mcc_initparam_quick(ptmodel, __MCC_QUICK_XM, 0.0, NULL, MCC_INITVALUE);
1893 mcc_initparam_quick(ptmodel, __MCC_QUICK_XOI, 1.0e3, NULL, MCC_INITVALUE);
1894 mcc_initparam_quick(ptmodel, __MCC_QUICK_XOM, 1.0e3, NULL, MCC_INITVALUE);
1895 mcc_initparam_quick(ptmodel, __MCC_QUICK_XP, 0.0, NULL, MCC_INITVALUE);
1896 // Parasistic Resistance Related Model Parameters
1897 mcc_initparam_quick(ptmodel, __MCC_QUICK_RS, 0.0, NULL, MCC_INITVALUE);
1898 mcc_initparam_quick(ptmodel, __MCC_QUICK_RB, 0.0, NULL, MCC_INITVALUE);
1899 // Noise Related Model Parameters
1900 mcc_initparam_quick(ptmodel, __MCC_QUICK_AF, 1.0, NULL, MCC_INITVALUE);
1901 mcc_initparam_quick(ptmodel, __MCC_QUICK_KF, 1.0, NULL, MCC_INITVALUE);
1902 // Temperature Related Model Parameters
1903 mcc_initparam_quick(ptmodel, __MCC_QUICK_EG, 1.11, NULL, MCC_INITVALUE);
1904 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTA, 0.0, NULL, MCC_INITVALUE);
1905 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTP, 0.0, NULL, MCC_INITVALUE);
1906 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP1, 7.02e-4, NULL, MCC_INITVALUE);
1907 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP2, 1108.0, NULL, MCC_INITVALUE);
1908 mcc_initparam_quick(ptmodel, __MCC_QUICK_TCV, 0.0, NULL, MCC_INITVALUE);
1909 mcc_initparam_quick(ptmodel, __MCC_QUICK_TM1, 0.0, NULL, MCC_INITVALUE);
1910 mcc_initparam_quick(ptmodel, __MCC_QUICK_TM2, 0.0, NULL, MCC_INITVALUE);
1911 mcc_initparam_quick(ptmodel, __MCC_QUICK_TPB, 0.0, NULL, MCC_INITVALUE);
1912 mcc_initparam_quick(ptmodel, __MCC_QUICK_TVJ, 0.0, NULL, MCC_INITVALUE);
1913 mcc_initparam_quick(ptmodel, __MCC_QUICK_TPHP, 0.0, NULL, MCC_INITVALUE);
1914 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRS, 0.0, NULL, MCC_INITVALUE);
1915 mcc_initparam_quick(ptmodel, __MCC_QUICK_TTT1, 0.0, NULL, MCC_INITVALUE);
1916 mcc_initparam_quick(ptmodel, __MCC_QUICK_TTT2, 0.0, NULL, MCC_INITVALUE);
1917 mcc_initparam_quick(ptmodel, __MCC_QUICK_XTI, 3.0, NULL, MCC_INITVALUE);
1918 mcc_initparam_quick(ptmodel, __MCC_QUICK_PT, 3.0, NULL, MCC_INITVALUE);
1919 break;
1920 case 2:
1921 //---------------
1922 // LEVEL 2
1923 //---------------
1924 // DC Related Model Parameters
1925 mcc_initparam_quick(ptmodel, __MCC_QUICK_IS, 1.0e-14, NULL, MCC_INITVALUE);
1926 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISR, 0.0, NULL, MCC_INITVALUE);
1927 mcc_initparam_quick(ptmodel, __MCC_QUICK_NR, 2.0, NULL, MCC_INITVALUE);
1928 mcc_initparam_quick(ptmodel, __MCC_QUICK_N, 1.0, NULL, MCC_INITVALUE);
1929 mcc_initparam_quick(ptmodel, __MCC_QUICK_NF, 1.0, NULL, MCC_INITVALUE);
1930 mcc_initparam_quick(ptmodel, __MCC_QUICK_IBV, 1.0e-3, NULL, MCC_INITVALUE);
1931 mcc_initparam_quick(ptmodel, __MCC_QUICK_IBVL, 0.0, NULL, MCC_INITVALUE);
1932 mcc_initparam_quick(ptmodel, __MCC_QUICK_NBV, 1.0, NULL, MCC_INITVALUE);
1933 mcc_initparam_quick(ptmodel, __MCC_QUICK_NBVL, 1.0, NULL, MCC_INITVALUE);
1934 // Capacitance Related Model Parameters
1935 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJO, 0.0, NULL, MCC_INITVALUE);
1936 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJ0, 0.0, NULL, MCC_INITVALUE);
1937 mcc_initparam_quick(ptmodel, __MCC_QUICK_M, 0.5, NULL, MCC_INITVALUE);
1938 mcc_initparam_quick(ptmodel, __MCC_QUICK_EG, 1.11, NULL, MCC_INITVALUE);
1939 mcc_initparam_quick(ptmodel, __MCC_QUICK_FC, 0.5, NULL, MCC_INITVALUE);
1940 mcc_initparam_quick(ptmodel, __MCC_QUICK_TT, 0.0, NULL, MCC_INITVALUE);
1941 mcc_initparam_quick(ptmodel, __MCC_QUICK_VJ, 1.0, NULL, MCC_INITVALUE);
1942 mcc_initparam_quick(ptmodel, __MCC_QUICK_RS, 0.0, NULL, MCC_INITVALUE);
1943 mcc_initparam_quick(ptmodel, __MCC_QUICK_AF, 1.0, NULL, MCC_INITVALUE);
1944 mcc_initparam_quick(ptmodel, __MCC_QUICK_KF, 0.0, NULL, MCC_INITVALUE);
1945 // Temperature Related Model Parameters
1946 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRS1, 0.0, NULL, MCC_INITVALUE);
1947 mcc_initparam_quick(ptmodel, __MCC_QUICK_TRS2, 0.0, NULL, MCC_INITVALUE);
1948 mcc_initparam_quick(ptmodel, __MCC_QUICK_TBV1, 0.0, NULL, MCC_INITVALUE);
1949 mcc_initparam_quick(ptmodel, __MCC_QUICK_TBV2, 0.0, NULL, MCC_INITVALUE);
1950 mcc_initparam_quick(ptmodel, __MCC_QUICK_TIKF, 0.0, NULL, MCC_INITVALUE);
1951 break;
1952 case 3:
1953 //---------------
1954 // LEVEL 3
1955 //---------------
1956 // DC Related Model Parameters
1957 mcc_initparam_quick(ptmodel, __MCC_QUICK_EF, 1.0e-8, NULL, MCC_INITVALUE);
1958 mcc_initparam_quick(ptmodel, __MCC_QUICK_ER, mcc_getparam_quick(ptmodel, __MCC_QUICK_EF), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_EF), MCC_INITVALUE) ;
1959 mcc_initparam_quick(ptmodel, __MCC_QUICK_JF, 1.0e-10, NULL, MCC_INITVALUE);
1960 mcc_initparam_quick(ptmodel, __MCC_QUICK_JR, mcc_getparam_quick(ptmodel, __MCC_QUICK_JF), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_JF), MCC_INITVALUE) ;
1961 mcc_initparam_quick(ptmodel, __MCC_QUICK_TOX, 100.0, NULL, MCC_INITVALUE);
1962 mcc_initparam_quick(ptmodel, __MCC_QUICK_L, 0.0, NULL, MCC_INITVALUE);
1963 mcc_initparam_quick(ptmodel, __MCC_QUICK_W, 0.0, NULL, MCC_INITVALUE);
1964 mcc_initparam_quick(ptmodel, __MCC_QUICK_XW, 0.0, NULL, MCC_INITVALUE);
1965 break;
1966 /* case 4:
1967 //---------------
1968 // LEVEL 4
1969 //---------------
1970 // DC Related Model Parameters
1971 mcc_initparam_quick(ptmodel, __MCC_QUICK_AB, 1.0e-12, NULL, MCC_INITVALUE);
1972 mcc_initparam_quick(ptmodel, __MCC_QUICK_LS, 1.0e-6, NULL, MCC_INITVALUE);
1973 mcc_initparam_quick(ptmodel, __MCC_QUICK_LG, 0.0, NULL, MCC_INITVALUE);
1974 mcc_initparam_quick(ptmodel, __MCC_QUICK_DTA, 0.0, NULL, MCC_INITVALUE);
1975 mcc_initparam_quick(ptmodel, __MCC_QUICK_TR, 25.0, NULL, MCC_INITVALUE);
1976 mcc_initparam_quick(ptmodel, __MCC_QUICK_VR, 0.0, NULL, MCC_INITVALUE);
1977 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGBR, 1.0e-3, NULL, MCC_INITVALUE);
1978 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDBR, 1.0e-3, NULL, MCC_INITVALUE);
1979 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGSR, 1.0e-3, NULL, MCC_INITVALUE);
1980 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDBR, 1.0e-3, NULL, MCC_INITVALUE);
1981 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGGR, 1.0e-3, NULL, MCC_INITVALUE);
1982 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDGR, 1.0e-3, NULL, MCC_INITVALUE);
1983 mcc_initparam_quick(ptmodel, __MCC_QUICK_NB, 1.0, NULL, MCC_INITVALUE);
1984 mcc_initparam_quick(ptmodel, __MCC_QUICK_NS, 1.0, NULL, MCC_INITVALUE);
1985 mcc_initparam_quick(ptmodel, __MCC_QUICK_NG, 1.0, NULL, MCC_INITVALUE);
1986 mcc_initparam_quick(ptmodel, __MCC_QUICK_VB, 0.9, NULL, MCC_INITVALUE);
1987 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJBR, 1.0e-12, NULL, MCC_INITVALUE);
1988 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSR, 1.0e-12, NULL, MCC_INITVALUE);
1989 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJGR, 1.0e-12, NULL, MCC_INITVALUE);
1990 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDBR, 1.0, NULL, MCC_INITVALUE);
1991 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDSR, 1.0, NULL, MCC_INITVALUE);
1992 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDGR, 1.0, NULL, MCC_INITVALUE);
1993 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 0.4, NULL, MCC_INITVALUE);
1994 mcc_initparam_quick(ptmodel, __MCC_QUICK_PS, 0.4, NULL, MCC_INITVALUE);
1995 mcc_initparam_quick(ptmodel, __MCC_QUICK_PG, 0.4, NULL, MCC_INITVALUE);
1996 break;
1997 */
1998 case 8:
1999 //---------------
2000 // LEVEL 8
2001 //---------------
2002 // DC Related Model Parameters
2003 mcc_initparam_quick(ptmodel, __MCC_QUICK_DIOLEV, 1.0, NULL, MCC_INITVALUE);
2004 mcc_initparam_quick(ptmodel, __MCC_QUICK_JS, 0.0, NULL, MCC_INITVALUE);
2005 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSW, 0.0, NULL, MCC_INITVALUE);
2006 mcc_initparam_quick(ptmodel, __MCC_QUICK_IS, 1.0e-14, NULL, MCC_INITVALUE);
2007 mcc_initparam_quick(ptmodel, __MCC_QUICK_N, 1.0, NULL, MCC_INITVALUE);
2008 mcc_initparam_quick(ptmodel, __MCC_QUICK_NDS, 1.0, NULL, MCC_INITVALUE);
2009 mcc_initparam_quick(ptmodel, __MCC_QUICK_VNDS, -1.0, NULL, MCC_INITVALUE);
2010 mcc_initparam_quick(ptmodel, __MCC_QUICK_SBTH, 0.0, NULL, MCC_INITVALUE);
2011 // Bulk Diode Capacitance Related Parameters
2012 mcc_initparam_quick(ptmodel, __MCC_QUICK_CBD, 0.0, NULL, MCC_INITVALUE);
2013 mcc_initparam_quick(ptmodel, __MCC_QUICK_CBS, 0.0, NULL, MCC_INITVALUE);
2014 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJ, 0.0, NULL, MCC_INITVALUE);
2015 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJGATE, 0.0, NULL, MCC_INITVALUE);
2016 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSW, 0.0, NULL, MCC_INITVALUE);
2017 mcc_initparam_quick(ptmodel, __MCC_QUICK_FC, 0.5, NULL, MCC_INITVALUE);
2018 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJ, 0.5, NULL, MCC_INITVALUE);
2019 mcc_initparam_quick(ptmodel, __MCC_QUICK_MJSW, 0.33, NULL, MCC_INITVALUE);
2020 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 0.8, NULL, MCC_INITVALUE);
2021 mcc_initparam_quick(ptmodel, __MCC_QUICK_PBSW, mcc_getparam_quick(ptmodel, __MCC_QUICK_PB), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_PB), MCC_INITVALUE) ;
2022 mcc_initparam_quick(ptmodel, __MCC_QUICK_TT, 0.0, NULL, MCC_INITVALUE);
2023 // Juncap Related Parameters (DIOLEV = 9)
2024 mcc_initparam_quick(ptmodel, __MCC_QUICK_VR, 0.0, NULL, MCC_INITVALUE);
2025 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGBR, 1.0e-3, NULL, MCC_INITVALUE);
2026 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDBR, 1.0e-3, NULL, MCC_INITVALUE);
2027 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGSR, 1.0e-3, NULL, MCC_INITVALUE);
2028 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDSR, 1.0e-3, NULL, MCC_INITVALUE);
2029 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSGGR, 1.0e-3, NULL, MCC_INITVALUE);
2030 mcc_initparam_quick(ptmodel, __MCC_QUICK_JSDGR, 1.0e-3, NULL, MCC_INITVALUE);
2031 mcc_initparam_quick(ptmodel, __MCC_QUICK_NBJ, 1.0, NULL, MCC_INITVALUE);
2032 mcc_initparam_quick(ptmodel, __MCC_QUICK_NSJ, 1.0, NULL, MCC_INITVALUE);
2033 mcc_initparam_quick(ptmodel, __MCC_QUICK_NGJ, 1.0, NULL, MCC_INITVALUE);
2034 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJBR, 1.0e-12, NULL, MCC_INITVALUE);
2035 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJSR, 1.0e-12, NULL, MCC_INITVALUE);
2036 mcc_initparam_quick(ptmodel, __MCC_QUICK_CJGR, 1.0e-12, NULL, MCC_INITVALUE);
2037 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDBR, 1.0, NULL, MCC_INITVALUE);
2038 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDSR, 1.0, NULL, MCC_INITVALUE);
2039 mcc_initparam_quick(ptmodel, __MCC_QUICK_VDGR, 1.0, NULL, MCC_INITVALUE);
2040 mcc_initparam_quick(ptmodel, __MCC_QUICK_PB, 0.4, NULL, MCC_INITVALUE);
2041 mcc_initparam_quick(ptmodel, __MCC_QUICK_PS, 0.4, NULL, MCC_INITVALUE);
2042 mcc_initparam_quick(ptmodel, __MCC_QUICK_PG, 0.4, NULL, MCC_INITVALUE);
2043 // Temperature Effect Related Model Parameters
2044 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTA, 0.0, NULL, MCC_INITVALUE);
2045 mcc_initparam_quick(ptmodel, __MCC_QUICK_CTP, 0.0, NULL, MCC_INITVALUE);
2046 mcc_initparam_quick(ptmodel, __MCC_QUICK_PTA, 0.0, NULL, MCC_INITVALUE);
2047 mcc_initparam_quick(ptmodel, __MCC_QUICK_PTP, 0.0, NULL, MCC_INITVALUE);
2048 tlev = MCC_ROUND(mcc_getparam_quick(ptmodel,__MCC_QUICK_TLEV));
2049 if ( tlev == 0 || tlev == 1 )
2050 mcc_initparam_quick(ptmodel, __MCC_QUICK_EG, 1.11, NULL, MCC_INITVALUE);
2051 else
2052 mcc_initparam_quick(ptmodel, __MCC_QUICK_EG, 1.16, NULL, MCC_INITVALUE);
2053 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP1, 7.02e-4, NULL, MCC_INITVALUE);
2054 mcc_initparam_quick(ptmodel, __MCC_QUICK_GAP2, 1108.0, NULL, MCC_INITVALUE);
2055 mcc_initparam_quick(ptmodel, __MCC_QUICK_TLEVI, 1.0, NULL, MCC_INITVALUE);
2056 mcc_initparam_quick(ptmodel, __MCC_QUICK_LIS, 1.0, NULL, MCC_INITVALUE);
2057 mcc_initparam_quick(ptmodel, __MCC_QUICK_ISTEMP, 10.0, NULL, MCC_INITVALUE);
2058 mcc_initparam_quick(ptmodel, __MCC_QUICK_XTI, 0.0, NULL, MCC_INITVALUE);
2059 break;
2060 default : avt_errmsg(MCC_ERRMSG, "018", AVT_ERROR,ptmodel->NAME,level) ;
2061 break;
2062
2063 }
2064 }
2065 }
2066 #ifdef MCC_RESI_CODE
2067 // zinaps
2068 void mcc_initparam_resi (mcc_modellist *ptmodel)
2069 {
2070 int level,tlev;
2071
2072 if ( ptmodel->TYPE == MCC_MODEL_RESI ) {
2073 mcc_initparam_quick(ptmodel, __MCC_QUICK_CAP, 1.0, NULL, MCC_INITVALUE);
2074 mcc_initparam_quick(ptmodel, __MCC_QUICK_CAPSW, 27.0, NULL, MCC_INITVALUE);
2075 mcc_initparam_quick(ptmodel, __MCC_QUICK_COX, 27.0, NULL, MCC_INITVALUE);
2076 mcc_initparam_quick(ptmodel, __MCC_QUICK_DI, mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM), mcc_getparamexp_quick(ptmodel, __MCC_QUICK_TNOM), MCC_INITVALUE) ;
2077 mcc_initparam_quick(ptmodel, __MCC_QUICK_DLR, 0.0, NULL, MCC_INITVALUE);
2078 mcc_initparam_quick(ptmodel, __MCC_QUICK_L, 0.0, NULL, MCC_INITVALUE);
2079 mcc_initparam_quick(ptmodel, __MCC_QUICK_W, 0.0, NULL, MCC_INITVALUE);
2080 mcc_initparam_quick(ptmodel, __MCC_QUICK_RES, 0.0, NULL, MCC_INITVALUE);
2081 mcc_initparam_quick(ptmodel, __MCC_QUICK_SHRINK, 0.0, NULL, MCC_INITVALUE);
2082 mcc_initparam_quick(ptmodel, __MCC_QUICK_L, 0.0, NULL, MCC_INITVALUE);
2083 }
2084 }
2085 #endif
2086 /********************************************************************************************/
2087 /* Les derating sont calcules en fct du rapport des courants maximums */
2088 /********************************************************************************************/
2089 /********************************************************************************************/
2090 /* Fonction de calcul du derating en temperature */
2091 /* Exemple : tpfinal = tpinitial*(1.0+dT*derate_temp) */
2092 /********************************************************************************************/
2093 double mcc_calcRapIdsTemp(char *technoname, char *transname, int transtype,
2094 int transcase, double L, double W, double vdd,
2095 double T0, double T1)
2096 {
2097 mcc_modellist *ptmodel ;
2098 double RapportIds = 1.0 ;
2099
2100 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2101 return(0.0) ;
2102 else {
2103 switch(ptmodel->MODELTYPE) {
2104 case MCC_BSIM3V3 : RapportIds = mcc_calcIDS_bsim3v3(ptmodel, 0.0, vdd, vdd, W, L, T1,NULL)
2105 /mcc_calcIDS_bsim3v3(ptmodel, 0.0, vdd, vdd, W, L, T0,NULL) ;
2106 break ;
2107 case MCC_BSIM4 : RapportIds = mcc_calcIDS_bsim4 (ptmodel, 0.0, vdd, vdd, W, L, T1,NULL)
2108 /mcc_calcIDS_bsim4 (ptmodel, 0.0, vdd, vdd, W, L, T0,NULL) ;
2109 break ;
2110 case MCC_MPSPB :
2111 case MCC_MPSP : RapportIds = mcc_calcIDS_psp (ptmodel, 0.0, vdd, vdd, W, L, T1,NULL)
2112 /mcc_calcIDS_psp (ptmodel, 0.0, vdd, vdd, W, L, T0,NULL) ;
2113 break ;
2114 case MCC_EXTMOD : RapportIds = mcc_calcIDS_ext(ptmodel, 0.0, vdd, vdd, W, L, T1,NULL)
2115 /mcc_calcIDS_ext(ptmodel, 0.0, vdd, vdd, W, L, T0,NULL) ;
2116 break ;
2117 case MCC_MM9 :
2118 case MCC_MOS2 : RapportIds = 0.0 ;
2119 break ;
2120 }
2121 }
2122 return RapportIds ;
2123 }
2124
2125 /********************************************************************************************/
2126 /* Fonction de calcul du derating en tension */
2127 /********************************************************************************************/
2128 double mcc_calcRapIdsVolt(char *technoname, char *transname, int transtype,
2129 int transcase, double L, double W, double temp, double V0, double V1)
2130 {
2131 mcc_modellist *ptmodel ;
2132 double RapportIds = 1.0 ;
2133
2134 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2135 return(0.0) ;
2136 else {
2137 switch(ptmodel->MODELTYPE) {
2138 case MCC_BSIM3V3 : RapportIds = mcc_calcIDS_bsim3v3 (ptmodel, 0.0, V1, V1, W, L, temp,NULL)
2139 /mcc_calcIDS_bsim3v3 (ptmodel, 0.0, V0, V0, W, L, temp,NULL) ;
2140 break ;
2141 case MCC_BSIM4 : RapportIds = mcc_calcIDS_bsim4 (ptmodel, 0.0, V1, V1, W, L,temp,NULL)
2142 /mcc_calcIDS_bsim4 (ptmodel, 0.0, V0, V0, W, L,temp,NULL) ;
2143 break ;
2144 case MCC_MPSPB :
2145 case MCC_MPSP : RapportIds = mcc_calcIDS_psp (ptmodel, 0.0, V1, V1, W, L,temp,NULL)
2146 /mcc_calcIDS_psp (ptmodel, 0.0, V0, V0, W, L,temp,NULL) ;
2147 break ;
2148 case MCC_EXTMOD : RapportIds = mcc_calcIDS_ext(ptmodel, 0.0, V1, V1, W, L,temp,NULL)
2149 /mcc_calcIDS_ext(ptmodel, 0.0, V0, V0, W, L,temp,NULL) ;
2150 break ;
2151 case MCC_MM9 :
2152 case MCC_MOS2 : RapportIds = 0.0 ;
2153 break ;
2154 }
2155 }
2156 return RapportIds ;
2157 }
2158
2159 /******************************************************************************\
2160
2161 Calcul des tensions degradees
2162
2163 \******************************************************************************/
2164 struct mcc_vdeg_fn {
2165 mcc_modellist *ptmodel ;
2166 char *transname ;
2167 double L, W ;
2168 double temp ;
2169 elp_lotrs_param *lotrsparam ;
2170 double vdd ;
2171 };
2172
2173 /******************************************************************************\
2174 FUNCTION : mcc_calcVDDDEG_com_fn
2175 On recherche la tension degradee (Vs) qui satisfait : VGS = VTH (vd,vbs)
2176 Vg = VDD, on obtient donc : VDD - Vs = VTH <=> VTH + Vs - VDD = 0
2177 \******************************************************************************/
2178
2179 int mcc_calcVDDDEG_com_fn( struct mcc_vdeg_fn *data, double vs, double *vth )
2180 {
2181 *vth = mcc_calcVTH( data->ptmodel->TECHNO->NAME,
2182 data->transname,
2183 data->ptmodel->TYPE,
2184 data->ptmodel->CASE,
2185 data->L,
2186 data->W,
2187 data->temp,
2188 data->lotrsparam->VBULK-vs,
2189 data->vdd-vs,
2190 data->lotrsparam,
2191 MCC_NO_LOG
2192 ) + vs - data->vdd ;
2193 return 1;
2194 }
2195
2196 double mcc_calcVDDDEG_com (mcc_modellist *ptmodel, char *transname,
2197 double L, double W,
2198 double vdd, double temp, double step,
2199 elp_lotrs_param *lotrsparam)
2200 {
2201 static int nbcall=0;
2202 struct mcc_vdeg_fn data ;
2203 double x0, x1, vdeg;
2204 int ret, it ;
2205
2206 if (ptmodel->TYPE == MCC_PMOS) {
2207 avt_errmsg(MCC_ERRMSG, "019", AVT_ERROR , ptmodel->NAME) ;
2208 return 0.0 ;
2209 }
2210 nbcall++;
2211
2212 data.ptmodel = ptmodel ;
2213 data.transname = transname ;
2214 data.L = L ;
2215 data.W = W ;
2216 data.temp = temp ;
2217 data.lotrsparam = lotrsparam ;
2218 data.vdd = vdd ;
2219
2220 x0 = 0 ;
2221 x1 = vdd ;
2222 it = 10000 ;
2223 ret = mbk_dichotomie( (int(*)(void*, double, double*)) mcc_calcVDDDEG_com_fn,
2224 NULL,
2225 &data,
2226 &x0,
2227 &x1,
2228 MBK_DICHO_EQUAL,
2229 &it,
2230 step,
2231 DBL_MAX,
2232 &vdeg
2233 );
2234
2235 if( ret != MBK_DICHO_OK ) {
2236 fflush( stdout ) ;
2237 avt_errmsg(MCC_ERRMSG, "020", AVT_ERROR , ptmodel->NAME,L,W, MCC_VDDmax,MCC_VTN,MCC_VDDmax - MCC_VTN);
2238 return MCC_VDDmax - MCC_VTN;
2239 }
2240 return vdeg ;
2241 }
2242
2243 /******************************************************************************\
2244 FUNCTION : mcc_calcVDDDEG_com_fn
2245 On recherche la tension degradee (Vs) qui satisfait : VGS = VTH (vds,vbs)
2246 Vg = 0, on obtient donc : - Vs = VTH <=> VTH + Vs = 0
2247 \******************************************************************************/
2248
2249 int mcc_calcVSSDEG_com_fn( struct mcc_vdeg_fn *data, double vgs, double *vth )
2250 {
2251 *vth = mcc_calcVTH( data->ptmodel->TECHNO->NAME,
2252 data->transname,
2253 data->ptmodel->TYPE,
2254 data->ptmodel->CASE,
2255 data->L,
2256 data->W,
2257 data->temp,
2258 data->lotrsparam->VBULK-vgs,
2259 -vgs,
2260 data->lotrsparam,
2261 MCC_NO_LOG
2262 ) + vgs ;
2263 return 1;
2264 }
2265
2266 double mcc_calcVSSDEG_com (mcc_modellist *ptmodel, char *transname,double L, double W,
2267 double vdd, double temp, double step,
2268 elp_lotrs_param *lotrsparam)
2269 {
2270 static int nbcall=0;
2271 struct mcc_vdeg_fn data ;
2272 double x0, x1, vdeg;
2273 int ret, it ;
2274
2275 if(ptmodel->TYPE == MCC_NMOS) {
2276 avt_errmsg(MCC_ERRMSG, "021", AVT_ERROR, ptmodel->NAME) ;
2277 return 0.0 ;
2278 }
2279
2280 nbcall++;
2281 data.ptmodel = ptmodel ;
2282 data.transname = transname ;
2283 data.L = L ;
2284 data.W = W ;
2285 data.temp = temp ;
2286 data.lotrsparam = lotrsparam ;
2287 data.vdd = vdd ;
2288
2289 x0 = 0 ;
2290 x1 = vdd ;
2291 it = 10000 ;
2292 ret = mbk_dichotomie( (int(*)(void*, double, double*)) mcc_calcVSSDEG_com_fn,
2293 NULL,
2294 &data,
2295 &x0,
2296 &x1,
2297 MBK_DICHO_EQUAL,
2298 &it,
2299 step,
2300 DBL_MAX,
2301 &vdeg
2302 );
2303
2304 if( ret != MBK_DICHO_OK ) {
2305 avt_errmsg(MCC_ERRMSG, "022", AVT_ERROR, ptmodel->NAME,L,W,MCC_VTP );
2306 return MCC_VTP;
2307 }
2308 return vdeg ;
2309 }
2310
2311 /******************************************************************************\
2312 Function : mcc_get_min_max ()
2313 \******************************************************************************/
2314 void mcc_get_min_max (double *max,double *min, double a, double b, double c, double d)
2315 {
2316 if ( *max < a )
2317 *max = a;
2318 if ( *max < b )
2319 *max = b;
2320 if ( *max < c )
2321 *max = c;
2322 if ( *max < d )
2323 *max = d;
2324 if ( *min > a )
2325 *min = a;
2326 if ( *min > b )
2327 *min = b;
2328 if ( *min > c )
2329 *min = c;
2330 if ( *min > d )
2331 *min = d;
2332 }
2333
2334 /******************************************************************************\
2335 Function : mcc_PrintQint ()
2336 \******************************************************************************/
2337 void mcc_PrintQint (char *technoname, char *transname,
2338 int transtype, int transcase, double L, double W,
2339 double temp, double vdd,elp_lotrs_param *lotrsparam, char *optnamevdd, char *optnamevss, int usechannel, char location )
2340 {
2341 mcc_modellist *ptmodel ;
2342 double var,vbs=0;
2343 //double max=-1.0e50,min=+1.0e50;
2344
2345 double La_Wa = 1.0 ;
2346 double Qg = 0.0 ;
2347 double Qb = 0.0 ;
2348 double Qs = 0.0 ;
2349 double Qd = 0.0 ;
2350 double Qtot = 0.0;
2351 FILE *file;
2352 char filename[1024];
2353 char spifilename[1024];
2354 double signe=1;
2355 int dec=0, decusechannel=0, j, i, k, idx, l, m;
2356 double vds, vgs, vfixe, vs ;
2357 char *nvar ;
2358
2359 if( !usechannel )
2360 decusechannel=0 ;
2361 else
2362 decusechannel=-1 ;
2363
2364 if( location=='G' )
2365 m=0 ;
2366 else
2367 m=1 ;
2368
2369 if (transtype == MCC_NMOS) j=0; else j=1;
2370 if (!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2371 return ;
2372 else {
2373 if( lotrsparam->ISVBSSET )
2374 vbs = lotrsparam->VBS ;
2375 else
2376 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
2377
2378 for (i=0; i<4; i++) for (k=0;k<2;k++) TRS_CURVS.QINT_BSIM[j][k][m][i]=mbkalloc(sizeof(double)*TRS_CURVS.nb);
2379
2380 switch(ptmodel->MODELTYPE) {
2381 case MCC_BSIM4 :
2382 case MCC_MPSPB :
2383 case MCC_MPSP :
2384 case MCC_EXTMOD :
2385 case MCC_BSIM3V3 : //=======> Influence de VGS
2386 switch( ptmodel->MODELTYPE ) {
2387 case MCC_BSIM4 :
2388 La_Wa = (L + mcc_calcDLC_bsim4 (ptmodel, lotrsparam, L, W))
2389 *(W+mcc_calcDWC_bsim4 (ptmodel, lotrsparam, L, W));
2390 break ;
2391 case MCC_BSIM3V3 :
2392 La_Wa = (L + mcc_calcDLC_bsim3v3(ptmodel, L, W))
2393 *(W+mcc_calcDWC_bsim3v3(ptmodel, L, W));
2394 break ;
2395 case MCC_MPSP:
2396 case MCC_MPSPB:
2397 case MCC_EXTMOD:
2398 La_Wa = L*W ;
2399 break ;
2400 }
2401
2402 for( l=0 ; l<=1 ; l++ ) {
2403
2404 if( l== 0 )
2405 vfixe = vdd ;
2406 else
2407 vfixe = 0 ;
2408
2409 if( !usechannel )
2410 dec=l*5+1;
2411 else
2412 dec=l*4+1;
2413
2414 sprintf (filename,"VGS_%s_L%ld_W%ld_vdd", transname,(long)(L*1.0e9+0.5),(long)(W*1.0e9+0.5));
2415 if( l == 0 && optnamevdd!=NULL )
2416 sprintf( filename, "%s_%c", mcc_debug_prefix(optnamevdd), location );
2417 if( l == 1 && optnamevss!=NULL )
2418 sprintf( filename, "%s_%c", mcc_debug_prefix(optnamevss), location );
2419
2420 if (( file = mbkfopen (filename,"dat",WRITE_TEXT))) {
2421 avt_printExecInfo(file, "#", "", "");
2422 if( location == 'G' )
2423 nvar = "vg" ;
2424 else
2425 nvar = "vd" ;
2426
2427 if( transtype==MCC_NMOS )
2428 vs = 0.0 ;
2429 else
2430 vs = vdd ;
2431
2432 if( location == 'G' ) {
2433 vds = vfixe-vs ;
2434 fprintf( file, "# vds = %g\n", vds );
2435 }
2436 else {
2437 vgs = vfixe-vs ;
2438 fprintf( file, "# vgs = %g\n", vgs );
2439 }
2440 if (!usechannel) fprintf (file,"# %s Qg Qb Qs Qd Qtot\n",nvar);
2441 else fprintf (file,"# %s Qg Qb Qd Qtot\n",nvar);
2442
2443 for (var = 0.0, i=0 ; var <= vdd ; var+=MCC_DC_STEP, i++) {
2444
2445 if( location == 'G' )
2446 vgs = var-vs ;
2447 else
2448 vds = var-vs ;
2449
2450 switch( ptmodel->MODELTYPE ) {
2451 case MCC_BSIM4 :
2452 mcc_calcQint_bsim4 (ptmodel, L, W,
2453 temp, vgs, vbs, vds,
2454 &Qg, &Qs, &Qd, &Qb,
2455 lotrsparam);
2456 break ;
2457 case MCC_MPSP:
2458 case MCC_MPSPB:
2459 mcc_calcQint_psp (ptmodel, L, W,
2460 temp, vgs, vbs, vds,
2461 &Qg, &Qs, &Qd, &Qb,
2462 lotrsparam);
2463 break ;
2464 case MCC_EXTMOD:
2465 mcc_calcQint_ext(ptmodel, L, W,
2466 temp, vgs, vbs, vds,
2467 &Qg, &Qs, &Qd, &Qb,
2468 lotrsparam);
2469 break ;
2470 default :
2471 mcc_calcQint_bsim3v3 (ptmodel, L, W,
2472 temp, vgs, vbs, vds,
2473 &Qg, &Qs, &Qd, &Qb,
2474 lotrsparam);
2475 }
2476
2477 Qg*=La_Wa;
2478 Qb*=La_Wa;
2479 Qs*=La_Wa;
2480 Qd*=La_Wa;
2481 Qtot = Qg+Qs+Qd+Qb;
2482
2483 if (transtype==MCC_NMOS) idx=i; else idx=TRS_CURVS.nb-i-1;
2484 if (idx>=0 && idx<TRS_CURVS.nb)
2485 {
2486 TRS_CURVS.QINT_BSIM[j][l][m][0][idx]=signe*Qg;
2487 TRS_CURVS.QINT_BSIM[j][l][m][1][idx]=signe*Qb;
2488 TRS_CURVS.QINT_BSIM[j][l][m][2][idx]=signe*Qs;
2489 TRS_CURVS.QINT_BSIM[j][l][m][3][idx]=signe*Qd;
2490 }
2491 if (!usechannel)
2492 fprintf (file,"%.3e %.3e %.3e %.3e %.3e %.3e\n",
2493 var,signe*Qg,signe*Qb,signe*Qs,signe*Qd,signe*Qtot);
2494 else
2495 fprintf (file,"%.3e %.3e %.3e %.3e %.3e\n",
2496 var,signe*Qg,signe*Qb,signe*Qs+signe*Qd,signe*Qtot);
2497
2498 }
2499 fclose (file);
2500 if ((file = mbkfopen (filename,"plt",WRITE_TEXT))) {
2501 avt_printExecInfo(file, "#", "", "");
2502 if ( transtype == MCC_NMOS )
2503 sprintf (spifilename,"nmos_qint_%c.spice.dat",location);
2504 else
2505 sprintf (spifilename,"pmos_qint_%c.spice.dat",location);
2506 fprintf (file,"set term %s\n", V_STR_TAB[__AVT_GNUPLOT_TERM].VALUE);
2507 if( location =='G' ) {
2508 fprintf (file,"set xlabel \"VG (V)\"\n");
2509 fprintf (file,"set title \"Intrinsic charge, VDS=%gV\"\n",vds);
2510 }
2511 else {
2512 fprintf (file,"set xlabel \"VD (V)\"\n");
2513 fprintf (file,"set title \"Intrinsic charge, VGS=%gV\"\n",vgs);
2514 }
2515 fprintf (file,"set ylabel \"Q (C)\"\n");
2516 fprintf (file,"set grid\n");
2517 fprintf(file,"plot '%s.dat' using 1:2 title 'Qg %s' with lines,\\\n", filename, mcc_getmccname(ptmodel)) ;
2518 fprintf(file,"'%s' using 1:%d title 'Qg spice' with lines,\\\n",mcc_debug_prefix(spifilename),dec+1);
2519 fprintf(file,"'%s.dat' using 1:3 title 'Qb %s' with lines,\\\n",filename, mcc_getmccname(ptmodel));
2520 fprintf(file,"'%s' using 1:%d title 'Qb spice' with lines,\\\n",mcc_debug_prefix(spifilename),dec+2);
2521 if (!usechannel)
2522 {
2523 fprintf(file,"'%s.dat' using 1:4 title 'Qs %s' with lines,\\\n", filename, mcc_getmccname(ptmodel));
2524 fprintf(file,"'%s' using 1:%d title 'Qs spice' with lines,\\\n", mcc_debug_prefix(spifilename),dec+3);
2525 }
2526 fprintf(file,"'%s.dat' using 1:%d title 'Qd %s' with lines,\\\n", filename,5+decusechannel, mcc_getmccname(ptmodel));
2527 fprintf(file,"'%s' using 1:%d title 'Qd spice' with lines,\\\n", mcc_debug_prefix(spifilename),dec+4);
2528 fprintf(file,"'%s.dat' using 1:%d title 'Qtot %s' with lines,\\\n", filename,6+decusechannel, mcc_getmccname(ptmodel));
2529 fprintf(file,"'%s' using 1:%d title 'Qtot spice' with lines\\\n\n", mcc_debug_prefix(spifilename),dec+5 );
2530 fprintf(file,"pause -1 'Hit CR to finish'");
2531 fclose(file);
2532 }
2533 }
2534 }
2535 //=======> Influence de VGS a VDS=0
2536
2537 break ;
2538 case MCC_MM9 :
2539 case MCC_MOS2 :
2540 break ;
2541 }
2542 }
2543 }
2544
2545
2546 /******************************************************************************\
2547
2548 Function :
2549
2550 \******************************************************************************/
2551 void mcc_DisplayInfos (char *technoname, char *transname,
2552 int transtype, int transcase, double L, double W,
2553 double temp, double vgs, double vbs, double vds,
2554 double vdd,elp_lotrs_param *lotrsparam)
2555 {
2556 double vbx,cgs,cgp,cgd,cgdc,cgsi,cgsic,cds,cdp,cdw,cgsu,cgsd ;
2557 double cbxgu,cbxgd;
2558 double cbxgucal,cbxgdcal;
2559 double cdsu,cdsd,cdpu,cdpd,cdwu,cdwd;
2560 double cgscal,cgpcal,cgdcal,cgdccal,cgsical,cgsiccal,cdscal,cdpcal,cdwcal ;
2561 double cdsucal,cdpucal,cdwucal;
2562 double cdsdcal,cdpdcal,cdwdcal;
2563 double cgsucal,cgsdcal;
2564 double xw,xl,Leff, Weff, La, Wa;
2565 double aire,aireScaled,perim,perimScaled,Weffcj,WeffcjScaled;
2566 double LaWa,LaWaScaled;
2567
2568 temp = temp;
2569 vgs = vgs;
2570 vdd = vdd;
2571
2572 mcc_get_area_perim();
2573
2574 //===> Dimensions
2575 aire = W*MCC_DIF*1.0e-6 ;
2576 perim = 2.0*(MCC_DIF*1.0e-6+W) ;
2577 xl = mcc_getXL (technoname, transname, transtype, transcase, L,W);
2578 xw = mcc_getXW (technoname, transname, transtype, transcase, L,W);
2579 Leff = L*xl + mcc_calcDL (technoname, transname, transtype, transcase, L, W, lotrsparam);
2580 Weff = W*xw + mcc_calcDW (technoname, transname, transtype, transcase, L, W, lotrsparam);
2581 La = L*xl + mcc_calcDLC (technoname, transname, transtype, transcase, L, W, lotrsparam);
2582 Wa = W*xw + mcc_calcDWC (technoname, transname, transtype, transcase, L, W, lotrsparam);
2583 LaWa = La*Wa;
2584 LaWaScaled = LaWa*1.0e12;
2585 Weffcj = W*xw + mcc_calcDWCJ (technoname, transname, transtype, transcase, L, W, lotrsparam, temp);
2586
2587
2588 vbx = vbs - vds;
2589 //===> Capacitances
2590 if ( transtype == MCC_NMOS ) {
2591 aire = MCC_ADN*1.0e-6;
2592 perim = MCC_PDN*1.0e-6;
2593 cgsu = MCC_CGSUN;
2594 cgsd = MCC_CGSDN;
2595 cgs = 0.5*(cgsu+cgsd);
2596 cgp = MCC_CGPN;
2597 cgd = MCC_CGDN;
2598 cgdc = MCC_CGDCN;
2599 cgsi = MCC_CGSIN;
2600 cgsic = MCC_CGSICN;
2601 cdsu = MCC_CDS_U_N;
2602 cdsd = MCC_CDS_D_N;
2603 cds = 0.5*(cdsu+cdsd);
2604 cdpu = MCC_CDP_U_N;
2605 cdpd = MCC_CDP_D_N;
2606 cdp = 0.5*(cdpu+cdpd);
2607 cdwu = MCC_CDW_U_N;
2608 cdwd = MCC_CDW_D_N;
2609 cdw = 0.5*(cdwu+cdwd);
2610 }
2611 else {
2612 aire = MCC_ADP*1.0e-6;
2613 perim = MCC_PDP*1.0e-6;
2614 cgsu = MCC_CGSUP;
2615 cgsd = MCC_CGSDP;
2616 cgs = 0.5*(cgsu+cgsd);
2617 cgp = MCC_CGPP;
2618 cgd = MCC_CGDP;
2619 cgdc = MCC_CGDCP;
2620 cgsi = MCC_CGSIP;
2621 cgsic = MCC_CGSICP;
2622 cdsu = MCC_CDS_U_P;
2623 cdsd = MCC_CDS_D_P;
2624 cds = 0.5*(cdsu+cdsd);
2625 cdpu = MCC_CDP_U_P;
2626 cdpd = MCC_CDP_D_P;
2627 cdp = 0.5*(cdpu+cdpd);
2628 cdwu = MCC_CDW_U_P;
2629 cdwd = MCC_CDW_D_P;
2630 cdw = 0.5*(cdwu+cdwd);
2631 }
2632 cbxgu = MCC_CBXGU;
2633 cbxgd = MCC_CBXGD;
2634
2635 //==> display Infos :
2636 avt_log(LOGMCC,2,"Dimensions : L = %8.3g W = %8.3g Aire = %8.3g Perim = %8.3g\n",L,W,aire,perim);
2637 avt_log(LOGMCC,2," : Leff = %8.3g Weff = %8.3g Aire (eff) = %8.3g\n",Leff,Weff,Leff*Weff);
2638 avt_log(LOGMCC,2," : Lactif = %8.3g Wactif = %8.3g Aire (active) = %8.3g\n",La,Wa,La*Wa);
2639 avt_log(LOGMCC,2," : Weffcj = %8.3g\n\n",Weffcj);
2640 WeffcjScaled = Weffcj*1.0e6;
2641 aireScaled = aire*1.0e12;
2642 perimScaled = perim*1.0e6;
2643
2644 cgscal = cgs*LaWaScaled;
2645 cgsucal = cgsu*LaWaScaled;
2646 cgsdcal = cgsd*LaWaScaled;
2647 cgpcal = cgp*WeffcjScaled;
2648 cgpcal = cgp*Wa*1.0e6;
2649 cgdcal = cgd*LaWaScaled;
2650 cgdccal = cgdc*LaWaScaled;
2651 cgsical = cgsi*LaWaScaled;
2652 cgsiccal = cgsic*LaWaScaled;
2653 cdscal = cds*aireScaled;
2654 cdsucal = cdsu*aireScaled;
2655 cdsdcal = cdsd*aireScaled;
2656 cdpcal = cdp*perimScaled;
2657 cdpucal = cdpu*perimScaled;
2658 cdpdcal = cdpd*perimScaled;
2659 cbxgucal = cbxgu*WeffcjScaled;
2660 cbxgdcal = cbxgd*WeffcjScaled;
2661 cdwcal = cdw*WeffcjScaled;
2662 cdwucal = cdwu*WeffcjScaled;
2663 cdwdcal = cdwd*WeffcjScaled;
2664 cdwcal = cdw*Weff*1.0e6;
2665
2666 avt_log(LOGMCC,2,"Capacitances (pF) : CGS = %g \n",cgscal);
2667 avt_log(LOGMCC,2," : CGSU = %g \n",cgsucal);
2668 avt_log(LOGMCC,2," : CGSD = %g \n",cgsdcal);
2669 avt_log(LOGMCC,2," : CGP (Weffcj) = %g \n",cgpcal);
2670 avt_log(LOGMCC,2," : CGP (Wactif) = %g \n",cgpcal);
2671 avt_log(LOGMCC,2," : CGD = %g \n",cgdcal);
2672 avt_log(LOGMCC,2," : CGDC = %g \n",cgdccal);
2673 avt_log(LOGMCC,2," : CGSI = %g \n",cgsical);
2674 avt_log(LOGMCC,2," : CGSIC = %g \n",cgsiccal);
2675 avt_log(LOGMCC,2," : CDS = %g \n",cdscal);
2676 avt_log(LOGMCC,2," : CDSU = %g \n",cdsucal);
2677 avt_log(LOGMCC,2," : CDSD = %g \n",cdsdcal);
2678 avt_log(LOGMCC,2," : CDP = %g \n",cdpcal);
2679 avt_log(LOGMCC,2," : CDPU = %g \n",cdpucal);
2680 avt_log(LOGMCC,2," : CDPD = %g \n",cdpdcal);
2681 avt_log(LOGMCC,2," : CBXGU (Weffcj) = %g \n",cbxgucal);
2682 avt_log(LOGMCC,2," : CBXGD (Weffcj) = %g \n",cbxgdcal);
2683 avt_log(LOGMCC,2," : CDW (Weffcj) = %g \n",cdwcal);
2684 avt_log(LOGMCC,2," : CDWU (Weffcj) = %g \n",cdwucal);
2685 avt_log(LOGMCC,2," : CDWD (Weffcj) = %g \n",cdwdcal);
2686 avt_log(LOGMCC,2," : CDW (Weff) = %g \n",cdwcal);
2687 avt_log(LOGMCC,2,"Capacitances (pF) ==> Total Grid capa : %g\n",cgscal+2.0*cgpcal);
2688 avt_log(LOGMCC,2," ==> Total Grid (UP) capa : %g\n",cgsucal+2.0*cgpcal);
2689 avt_log(LOGMCC,2," ==> Total Grid (DN) capa : %g\n",cgsdcal+2.0*cgpcal);
2690 avt_log(LOGMCC,2," ==> Total Source/Drain capa : %g\n",
2691 cdscal+cdpcal+cdwcal);
2692 avt_log(LOGMCC,2," ==> Total Source/Drain (UP) capa : %g\n",
2693 cdsucal+cdpucal+cdwucal);
2694 avt_log(LOGMCC,2," ==> Total Source/Drain (DN) capa : %g\n",
2695 cdsdcal+cdpdcal+cdwdcal);
2696 avt_log(LOGMCC,2," ==> Total Source/Drain without CGP (UP) capa : %g\n",
2697 cdsucal+cdpucal+cbxgucal);
2698 avt_log(LOGMCC,2," ==> Total Source/Drain without CGP (DN) capa : %g\n",
2699 cdsdcal+cdpdcal+cbxgdcal);
2700 // Min and Max Input Capacitances
2701 if ( transtype == MCC_NMOS ) {
2702 avt_log(LOGMCC,2,"== Model %s NMOS (L = %gU W = %gU) ==\n",MCC_TNMODEL,MCC_LN,MCC_WN);
2703 avt_log(LOGMCC,2,"*************************\n");
2704 avt_log(LOGMCC,2,"* UP transition *\n");
2705 avt_log(LOGMCC,2,"*************************\n");
2706
2707 avt_log(LOGMCC,2,"--> input capa Min = %g pF\n",MCC_CGSU_N_MIN*LaWa+MCC_CGPU_N_MIN*2.0*Wa);
2708 avt_log(LOGMCC,2,"--> input capa Max = %g pF\n",MCC_CGSU_N_MAX*LaWa+MCC_CGPU_N_MAX*2.0*Wa);
2709
2710 avt_log(LOGMCC,2,"*************************\n");
2711 avt_log(LOGMCC,2,"* DOWN transition *\n");
2712 avt_log(LOGMCC,2,"*************************\n");
2713 avt_log(LOGMCC,2,"--> input capa Min = %g pF\n",MCC_CGSD_N_MIN*LaWa+MCC_CGPD_N_MIN*2.0*Wa);
2714 avt_log(LOGMCC,2,"--> input capa Max = %g pF\n\n",MCC_CGSD_N_MAX*LaWa+MCC_CGPD_N_MAX*2.0*Wa);
2715 }
2716 else {
2717 avt_log(LOGMCC,2,"== Model %s PMOS (L = %gU W = %gU ) ==\n",MCC_TPMODEL,MCC_LP,MCC_WP);
2718 avt_log(LOGMCC,2,"*************************\n");
2719 avt_log(LOGMCC,2,"* UP transition *\n");
2720 avt_log(LOGMCC,2,"*************************\n");
2721 avt_log(LOGMCC,2,"--> input capa Min = %g pF\n",MCC_CGSU_P_MIN*LaWa+MCC_CGPU_P_MIN*2.0*Wa);
2722 avt_log(LOGMCC,2,"--> input capa Max = %g pF\n",MCC_CGSU_P_MAX*LaWa+MCC_CGPU_P_MAX*2.0*Wa);
2723
2724 avt_log(LOGMCC,2,"*************************\n");
2725 avt_log(LOGMCC,2,"* DOWN transition *\n");
2726 avt_log(LOGMCC,2,"*************************\n");
2727 avt_log(LOGMCC,2,"--> input capa Min = %g pF\n",MCC_CGSD_P_MIN*LaWa+MCC_CGPD_P_MIN*2.0*Wa);
2728 avt_log(LOGMCC,2,"--> input capa Max = %g pF\n\n",MCC_CGSD_P_MAX*LaWa+MCC_CGPD_P_MAX*2.0*Wa);
2729 }
2730 }
2731
2732 /******************************************************************************\
2733
2734 Function : mcc_calcQint
2735
2736 Compute Intrinsic Charges.
2737
2738 \******************************************************************************/
2739 void mcc_calcQint (char *technoname, char *transname,
2740 int transtype, int transcase, double L, double W,
2741 double temp, double vgs,double vbs, double vds,
2742 double *ptQg,double *ptQs, double *ptQd, double *ptQb,
2743 elp_lotrs_param *lotrsparam)
2744 {
2745 mcc_modellist *ptmodel ;
2746
2747 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2748 return ;
2749 else {
2750 switch(ptmodel->MODELTYPE) {
2751 case MCC_BSIM3V3 : mcc_calcQint_bsim3v3 (ptmodel, L, W, temp, vgs,vbs,vds,ptQg,ptQs,ptQd,ptQb,lotrsparam) ;
2752 break ;
2753 case MCC_BSIM4 : mcc_calcQint_bsim4 (ptmodel, L, W, temp, vgs,vbs,vds,ptQg,ptQs,ptQd,ptQb,lotrsparam) ;
2754 break ;
2755 case MCC_MPSPB :
2756 case MCC_MPSP : mcc_calcQint_psp (ptmodel, L, W, temp, vgs,vbs,vds,ptQg,ptQs,ptQd,ptQb,lotrsparam) ;
2757 break ;
2758 case MCC_EXTMOD : mcc_calcQint_ext(ptmodel, L, W, temp, vgs,vbs,vds,ptQg,ptQs,ptQd,ptQb,lotrsparam) ;
2759 break ;
2760 case MCC_MM9 :
2761 case MCC_MOS2 :
2762 break ;
2763 }
2764 }
2765 }
2766
2767 double mcc_calcCGS( char *technoname,
2768 char *transname,
2769 int transtype,
2770 int transcase,
2771 double L,
2772 double W,
2773 double temp,
2774 double vgsi,
2775 double vgsf,
2776 double vdsi,
2777 double vdsf,
2778 elp_lotrs_param *lotrsparam
2779 )
2780 {
2781 mcc_modellist *ptmodel ;
2782 double Qinit=0.0,Qfinal=0.0,cgs=0.0,vbs;
2783
2784 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2785 return(0.0) ;
2786 else {
2787 if( lotrsparam->ISVBSSET )
2788 vbs = lotrsparam->VBS ;
2789 else
2790 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
2791 switch(ptmodel->MODELTYPE) {
2792 case MCC_BSIM3V3 :
2793 case MCC_BSIM4 :
2794 case MCC_MPSP :
2795 case MCC_MPSPB :
2796 case MCC_EXTMOD :
2797 // DOWN transition
2798 if ( mcc_getparam_quick(ptmodel,__MCC_QUICK_XPART) < 0.0)
2799 return 1.0e-30;
2800 mcc_calcQint (technoname, transname,
2801 transtype,transcase,L, W,
2802 temp, vgsi, vbs, vdsi,
2803 &Qinit, NULL, NULL, NULL,lotrsparam);
2804 mcc_calcQint (technoname, transname,
2805 transtype,transcase,L, W,
2806 temp, vgsf, vbs, vdsf,
2807 &Qfinal, NULL, NULL, NULL,lotrsparam);
2808 cgs = fabs((Qfinal-Qinit)/(vgsf-vgsi));
2809 break ;
2810 case MCC_MM9 :
2811 case MCC_MOS2 : cgs = mcc_calcCGS_com (ptmodel) ;
2812 break ;
2813 }
2814 }
2815 return cgs;
2816 }
2817
2818 /******************************************************************************\
2819
2820 Funciton : mcc_calcCGSD
2821
2822 Compute CGS for a down transition
2823
2824 \******************************************************************************/
2825 double mcc_calcCGSD (char *technoname, char *transname,
2826 int transtype, int transcase, double L, double W,
2827 double temp, double vdd, double vfinal, int vdsnull, elp_lotrs_param *lotrsparam)
2828 {
2829 mcc_modellist *ptmodel ;
2830 double Qinit=0.0,Qfinal=0.0,cgs=0.0,vbs;
2831 double vdsi,vdsf;
2832
2833 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2834 return(0.0) ;
2835 else {
2836 if( lotrsparam->ISVBSSET )
2837 vbs = lotrsparam->VBS ;
2838 else
2839 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
2840 switch(ptmodel->MODELTYPE) {
2841 case MCC_BSIM3V3 :
2842 case MCC_BSIM4 :
2843 case MCC_MPSP :
2844 case MCC_MPSPB :
2845 case MCC_EXTMOD :
2846 // DOWN transition
2847 if ( mcc_getparam_quick(ptmodel,__MCC_QUICK_XPART) < 0.0)
2848 return 1.0e-30;
2849 if (ptmodel->TYPE == MCC_NMOS) {
2850 if ( vdsnull ) {
2851 vdsi = 0.0;
2852 vdsf = 0.0;
2853 }
2854 else {
2855 vdsi = 0.0;
2856 //vdsf = vdd/2.0 - MCC_VTN;
2857 vdsf=vdsi;
2858 }
2859 mcc_calcQint (technoname, transname,
2860 transtype,transcase,L, W,
2861 temp, vdd, vbs, vdsi,
2862 &Qinit, NULL, NULL, NULL,lotrsparam);
2863 mcc_calcQint (technoname, transname,
2864 transtype,transcase,L, W,
2865 temp, vfinal, vbs, vdsf,
2866 &Qfinal, NULL, NULL, NULL,lotrsparam);
2867 }
2868 else {
2869 if ( vdsnull ) {
2870 vdsi = 0.0;
2871 vdsf = 0.0;
2872 }
2873 else {
2874 vdsi = vdd;
2875 //vdsf = vdd/2.0 + MCC_VTP;
2876 vdsf=vdsi;
2877 }
2878 mcc_calcQint (technoname, transname,
2879 transtype,transcase,L, W,
2880 temp, 0.0, vbs, vdsi,
2881 &Qinit, NULL, NULL, NULL,
2882 lotrsparam);
2883 mcc_calcQint (technoname, transname,
2884 transtype,transcase,L, W,
2885 temp, vfinal, vbs, vdsf,
2886 &Qfinal, NULL, NULL, NULL,
2887 lotrsparam);
2888 }
2889 cgs = fabs((Qfinal-Qinit)/(vdd/2.0));
2890 break ;
2891 case MCC_MM9 :
2892 case MCC_MOS2 : cgs = mcc_calcCGS_com (ptmodel) ;
2893 break ;
2894 }
2895 }
2896 return cgs;
2897 }
2898
2899 /******************************************************************************\
2900
2901 Funciton : mcc_calcCGSU
2902
2903 Compute CGS for an up transition
2904
2905 \******************************************************************************/
2906 double mcc_calcCGSU (char *technoname, char *transname,
2907 int transtype, int transcase, double L, double W,
2908 double temp, double vdd, double vfinal, int vdsnull,elp_lotrs_param *lotrsparam)
2909 {
2910 mcc_modellist *ptmodel ;
2911 double Qinit=0.0,Qfinal=0.0,cgs=0.0,vbs;
2912 double vdsi,vdsf;
2913
2914 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
2915 return 0.0;
2916
2917 else {
2918 if( lotrsparam->ISVBSSET )
2919 vbs = lotrsparam->VBS ;
2920 else
2921 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
2922 switch(ptmodel->MODELTYPE) {
2923 case MCC_BSIM3V3 :
2924 case MCC_MPSP :
2925 case MCC_MPSPB :
2926 case MCC_EXTMOD :
2927 case MCC_BSIM4 : // UP transition
2928 if ( mcc_getparam_quick(ptmodel,__MCC_QUICK_XPART) < 0.0)
2929 return 1.0e-30;
2930 if (ptmodel->TYPE == MCC_NMOS) {
2931 if ( vdsnull ) {
2932 vdsi = 0.0;
2933 vdsf = 0.0;
2934 }
2935 else {
2936 vdsi = vdd;
2937 //vdsf = MCC_VTN + vdd/2.0;
2938 vdsf=vdsi;
2939 }
2940 mcc_calcQint (technoname, transname,
2941 transtype,transcase,L, W,
2942 temp, 0.0, vbs, vdsi,
2943 &Qinit, NULL, NULL, NULL,
2944 lotrsparam);
2945 mcc_calcQint (technoname, transname,
2946 transtype,transcase,L, W,
2947 temp, vfinal, vbs, vdsf,
2948 &Qfinal, NULL, NULL, NULL,
2949 lotrsparam);
2950 }
2951 else {
2952 if ( vdsnull ) {
2953 vdsi = 0.0;
2954 vdsf = 0.0;
2955 }
2956 else {
2957 vdsi = 0.0;
2958 //vdsf = -MCC_VTP + vdd/2.0;
2959 vdsf=vdsi;
2960 }
2961 mcc_calcQint (technoname, transname,
2962 transtype,transcase,L, W,
2963 temp, vdd, vbs, vdsi,
2964 &Qinit, NULL, NULL, NULL,
2965 lotrsparam);
2966 mcc_calcQint (technoname, transname,
2967 transtype,transcase,L, W,
2968 temp, vfinal, vbs, vdsf,
2969 &Qfinal, NULL, NULL, NULL,
2970 lotrsparam);
2971 }
2972 cgs = fabs((Qfinal-Qinit)/(vdd/2.0));
2973 break ;
2974 case MCC_MM9 :
2975 case MCC_MOS2 : cgs = mcc_calcCGS_com (ptmodel) ;
2976 break ;
2977 }
2978 }
2979 return cgs;
2980 }
2981
2982 double mcc_calcCGPO( char *technoname, char *transname,
2983 int transtype, int transcase, double L, double W,
2984 double temp, double vg,
2985 double vd1, double vd2,
2986 elp_lotrs_param *lotrsparam )
2987 {
2988 double vgd1, vgd2 ;
2989 double ptQov1, ptQov2 ;
2990 double cgpo ;
2991
2992 vgd1 = vg - vd1 ;
2993 vgd2 = vg - vd2 ;
2994 mcc_calcCGP (technoname, transname, transtype, transcase, L, W, vgd1, &ptQov1, lotrsparam, temp );
2995 mcc_calcCGP (technoname, transname, transtype, transcase, L, W, vgd2, &ptQov2, lotrsparam, temp );
2996 cgpo =fabs( ( ptQov2 - ptQov1 ) / ( vgd2 - vgd1 ) );
2997
2998 return cgpo ;
2999
3000 }
3001
3002 /******************************************************************************\
3003
3004 Function : mcc_GetInputCapa
3005
3006 CGS, CGD, CGP
3007
3008 \******************************************************************************/
3009
3010 void mcc_GetInputCapa ( char *technoname, char *transname,
3011 int transtype, int transcase, double L, double W,
3012 double temp, double vg1, double vg2,
3013 double vd1, double vd2, double vs1, double vs2,
3014 elp_lotrs_param *lotrsparam,
3015 double *ptcgs, double *ptcgd, double *ptcgp)
3016 {
3017 double delta_vg;
3018 double vgs1,vgs2,vds1,vds2,vgd1,vgd2;
3019 double ptQg1,ptQd1,ptQg2,ptQd2;
3020 double ptQov1,ptQov2;
3021 double cgp1,cgp2,cgs,cgp,cgd,vbs;
3022
3023 delta_vg = vg2-vg1;
3024 vgs1 = vg1-vs1;
3025 vgs2 = vg2-vs2;
3026 vgd1 = vg1-vd1;
3027 vgd2 = vg2-vd2;
3028 vds1 = vd1-vs1;
3029 vds2 = vd2-vs2;
3030
3031 if ( ptcgs || ptcgd ) {
3032 if ( lotrsparam ) {
3033 if( lotrsparam->ISVBSSET )
3034 vbs = lotrsparam->VBS ;
3035 else
3036 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
3037 }
3038 else
3039 vbs = 0.0;
3040
3041 // ===> initial charges
3042 mcc_calcQint (technoname, transname,
3043 transtype, transcase, L, W,
3044 temp, vgs1,vbs,vds1,
3045 &ptQg1,NULL, &ptQd1, NULL,
3046 lotrsparam);
3047
3048 // ===> final charges
3049 mcc_calcQint (technoname, transname,
3050 transtype, transcase, L, W,
3051 temp, vgs2,vbs,vds2,
3052 &ptQg2,NULL, &ptQd2, NULL,
3053 lotrsparam);
3054
3055 cgs = ( ptQg2-ptQg1 ) / delta_vg;
3056 cgd = fabs (( ptQd2-ptQd1 ) / delta_vg );
3057 }
3058
3059 if ( ptcgp ) {
3060 //===> overlap capa
3061 // drain side
3062 cgp1 = mcc_calcCGP (technoname, transname,
3063 transtype, transcase, L, W, vgd1,&ptQov1,lotrsparam,temp);
3064 cgp2 = mcc_calcCGP (technoname, transname,
3065 transtype, transcase, L, W, vgd2,&ptQov2,lotrsparam,temp);
3066 cgp = (ptQov2-ptQov1) / delta_vg;
3067 // source side
3068 cgp1 = mcc_calcCGP (technoname, transname,
3069 transtype, transcase, L, W, vgs1,&ptQov1,lotrsparam,temp);
3070 cgp2 = mcc_calcCGP (technoname, transname,
3071 transtype, transcase, L, W, vgs2,&ptQov2,lotrsparam,temp);
3072 cgp += (ptQov2-ptQov1) / delta_vg;
3073 cgp *= 0.5; // mult by 0.5 because we give the source and drain olverlap capa
3074 // cgp will be mult by 2.0 in the future to have the total overlap capa of
3075 // a transistor
3076 }
3077
3078
3079 /*--------------------------------------------------------*\
3080 Caution : cgp is taking account of drain and source ovelap charges,
3081 so we only need to mult this capa by Wa and not by 2.0*Wa.
3082 We used to approximate this capa by considering that : Qov(drain) = Qov(source)
3083 which explains the mult factor 2.0. Now, we distinguish these 2 charges
3084 \*--------------------------------------------------------*/
3085
3086 if ( ptcgs ) *ptcgs = fabs(cgs);
3087 if ( ptcgp ) *ptcgp = fabs(cgp);
3088 if ( ptcgd ) *ptcgd = fabs(cgd);
3089 }
3090
3091 /******************************************************************************\
3092 FUNCTION : mcc_calc_vt ( temp )
3093 \******************************************************************************/
3094 double mcc_calc_vt (double temp)
3095 {
3096 double T = temp + MCC_KELVIN;
3097 double VtT;
3098
3099 VtT = MCC_KB * T / MCC_Q ;
3100 return VtT;
3101 }
3102
3103 /******************************************************************************\
3104 FUNCTION : mcc_calc_eg()
3105
3106 Energy band gap of Si
3107 \******************************************************************************/
3108 double mcc_calc_eg(double temp)
3109 {
3110 double Eg = 0.0;
3111 double T = temp + MCC_KELVIN;
3112
3113 Eg = 1.16 - ((7.02e-4 * T*T) / (T+1108.0));
3114
3115 return Eg;
3116 }
3117
3118 /******************************************************************************\
3119 *
3120 * FUNC : mcc_compute_RD_RS
3121 RSeff and RDeff computation
3122 \******************************************************************************/
3123 void mcc_compute_RD_RS ( mcc_modellist *ptmodel, double Weff,
3124 double *ptRS, double *ptRD, elp_lotrs_param *lotrsparam )
3125 {
3126 int RLEV;
3127 double RSH, RSC, RDC;
3128 double RS, RD, LDscal, LDIFscal, HDIFscal;
3129 double DW,DWscal, Wj;
3130 //double LDIFeff;
3131 double scalm, LD, LDIF, HDIF, WMLT;
3132 double nrs, nrd, M;
3133
3134 if (!ptmodel || !lotrsparam) return;
3135
3136 nrs = lotrsparam->PARAM[elpNRS];
3137 nrd = lotrsparam->PARAM[elpNRD];
3138 M = lotrsparam->PARAM[elpM];
3139
3140 scalm = 1; //TODO: check how it can take other value...
3141
3142 RLEV = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_RLEV));
3143 RSH = mcc_getparam_quick(ptmodel,__MCC_QUICK_RSH);
3144 RSC = mcc_getparam_quick(ptmodel,__MCC_QUICK_RSC);
3145 RDC = mcc_getparam_quick(ptmodel,__MCC_QUICK_RDC);
3146 RS = mcc_getparam_quick(ptmodel,__MCC_QUICK_RS);
3147 RD = mcc_getparam_quick(ptmodel,__MCC_QUICK_RD);
3148 LD = mcc_getparam_quick(ptmodel,__MCC_QUICK_LD);
3149 DW = mcc_getparam_quick(ptmodel,__MCC_QUICK_DW);
3150 LDIF= mcc_getparam_quick(ptmodel,__MCC_QUICK_LDIF);
3151 HDIF= mcc_getparam_quick(ptmodel,__MCC_QUICK_HDIF);
3152 WMLT= mcc_getparam_quick(ptmodel,__MCC_QUICK_WMLT);
3153
3154 DWscal = DW*scalm;
3155
3156 switch ( RLEV ) {
3157 case 0 : if ( ptRS ) {
3158 if ( nrs > 0.0 ) *ptRS = (RSH*nrs + RSC) / M;
3159 else *ptRS = ( RS + RSC ) / M;
3160 }
3161 if ( ptRD ) {
3162 if ( nrd > 0.0 ) *ptRD = (RSH*nrd + RDC) / M;
3163 else *ptRD = ( RD + RDC ) / M;
3164 }
3165 break;
3166 case 1 : LDscal = LD*scalm;
3167 LDIFscal = LDIF*scalm;
3168 Wj = Weff+DWscal;
3169 if ( ptRS )
3170 *ptRS = (RS*(LDscal+LDIFscal)/(M*Wj)+(nrs*RSH+RSC)/M);
3171 if ( ptRD )
3172 *ptRD = (RD*(LDscal+LDIFscal)/(M*Wj)+(nrd*RSH+RDC)/M);
3173 break;
3174 case 2 :
3175 case 3 : LDscal = LD*scalm;
3176 LDIFscal = LDIF*scalm;
3177 HDIFscal = HDIF*scalm*WMLT;
3178 Wj = Weff+DWscal;
3179 if ( ptRS ) {
3180 if ( nrs > 0.0 )
3181 *ptRS = (RS*(LDscal+LDIFscal)/(M*Wj) + (RSH*nrs+RSC)/M );
3182 else
3183 *ptRS = (RS*(LDscal+LDIFscal)/(M*Wj) + (HDIFscal*RSH)/(M*Wj) + RSC/M );
3184 }
3185 if ( ptRD ) {
3186 if ( nrd > 0.0 )
3187 *ptRD = (RD*(LDscal+LDIFscal)/(M*Wj) + (RSH*nrs+RDC)/M );
3188 else
3189 *ptRD = (RD*(LDscal+LDIFscal)/(M*Wj) + (HDIFscal*RSH)/(M*Wj) + RDC/M );
3190 }
3191 break;
3192 case 4 : LDscal = LD*scalm;
3193 LDIFscal = LDIF*scalm;
3194 HDIFscal = HDIF*scalm*WMLT;
3195 Wj = Weff+DWscal;
3196 if ( ptRS ) {
3197 if ( LDIFscal < 0.0 )
3198 *ptRS = RS/M;
3199 else if ( nrs > 0.0 )
3200 *ptRS = (RS*(LDscal+LDIFscal)/(M*Weff)+(nrs*RSH)/M);
3201 else
3202 *ptRS = (RS*(LDscal+LDIFscal)+HDIFscal*RSH)/(M*Weff);
3203 }
3204 if ( ptRD ) {
3205 if ( LDIFscal < 0.0 )
3206 *ptRD = RD/M;
3207 else if ( nrd > 0.0 )
3208 *ptRD = (RD*(LDscal+LDIFscal)/(M*Weff)+(nrd*RSH)/M);
3209 else
3210 *ptRD = (RD*(LDscal+LDIFscal)+HDIFscal*RSH)/(M*Weff);
3211 }
3212 break;
3213 case 5 : if ( ptRS ) {
3214 if ( RS > 0.0 ) *ptRS = RS/M;
3215 else *ptRS = nrs*RSH/M;
3216 }
3217 if ( ptRD ) {
3218 if ( RD > 0.0 ) *ptRD = RD/M;
3219 else *ptRD = nrd*RSH/M;
3220 }
3221 break;
3222 case 6 : if ( ptRS ) {
3223 if ( nrs > 0.0 ) *ptRS = nrs*RSH/M;
3224 else *ptRS = RS/M;
3225 }
3226 if ( ptRD ) {
3227 if ( nrd > 0.0 ) *ptRD = nrd*RSH/M;
3228 else *ptRD = RD/M;
3229 }
3230 break;
3231 /*
3232 case 7 : LDIFeff =
3233 if ( ptRS ) {
3234 if ( nrs > 0.0 ) *ptRS = nrs*RSH/M;
3235 else *ptRS = LDIFeff/(M*Weff);
3236 }
3237 if ( ptRD ) {
3238 if ( nrd > 0.0 ) *ptRD = nrd*RSH/M;
3239 else *ptRD = LDIFeff/(M*Weff);
3240 }
3241 break;
3242 */
3243 default: if ( ptRS ) *ptRS = 0.0;
3244 if ( ptRD ) *ptRD = 0.0;
3245 break;
3246 }
3247 }
3248
3249 /******************************************************************************\
3250 *
3251 * FUNC : mcc_calcDioCapa
3252
3253 return the total capacitance from a diode model
3254 \******************************************************************************/
3255 double mcc_calcDioCapa ( char *technoname, char *dioname,
3256 int modtype, int modcase,
3257 double Va, double Vc, double temp,
3258 double area, double perim
3259 )
3260 {
3261 mcc_modellist *ptmodel ;
3262 double Capa = 0.0 ;
3263
3264 if ( (ptmodel = mcc_getmodel(technoname, dioname, modtype, modcase, area, perim, 0)) )
3265 Capa = mcc_dio_calcCapa ( ptmodel, Va, Vc, temp, area, perim);
3266
3267 return Capa;
3268 }
3269
3270 /******************************************************************************\
3271 *
3272 * FUNC : mcc_dio_calcCDEP
3273 * CDEP is Depletion capacitance
3274 Va: Anode Voltage
3275 Vc: Cathode Voltage
3276
3277 return the total capacitance: Capa = CDEPa + CDEPp + CIDFF + CMETAL + CPOLY
3278 \******************************************************************************/
3279 double mcc_dio_calcCapa ( mcc_modellist *ptmodel,
3280 double Va, double Vc, double temp,
3281 double area, double perim
3282 )
3283 {
3284 double capa=0.0;
3285 int LEVEL;
3286
3287 if (ptmodel->TYPE == MCC_DIODE) {
3288 LEVEL = MCC_ROUND(mcc_getparam_quick(ptmodel,__MCC_QUICK_LEVEL));
3289 switch ( LEVEL ) {
3290 case 1: capa = mcc_dio_calcCapa_l1 (ptmodel,Va,Vc,temp,area,perim);
3291 break;
3292 case 2: capa = mcc_dio_calcCapa_l2 (ptmodel,Va,Vc,temp,area);
3293 break;
3294 case 3: capa = mcc_dio_calcCapa_l3 (ptmodel,area);
3295 break;
3296 case 8: capa = mcc_dio_calcCapa_l8 (ptmodel,Va,Vc,temp,area,perim);
3297 break;
3298 }
3299 }
3300 return capa;
3301 }
3302
3303 /******************************************************************************\
3304 *
3305 * FUNC : mcc_dio_calcCapa_l1
3306 * CDEP is Depletion capacitance
3307 Va: Anode Voltage
3308 Vc: Cathode Voltage
3309
3310 return the total capacitance: Capa = CDEPa + CDEPp + CIDFF + CMETAL + CPOLY
3311 \******************************************************************************/
3312 double mcc_dio_calcCapa_l1 ( mcc_modellist *ptmodel,
3313 double Va, double Vc, double temp,
3314 double area, double perim
3315 )
3316 {
3317 double vd;
3318 double CDEPa,CDEPp;
3319 double FC,FCS,KMS,CJO,VJ,MJ;
3320 double MJSW,CJSW;
3321 double CJOeff,CJSWeff;
3322 double SHRINK,SCALE=1.0,SCALM,XOI,XOM,WP,XP,XM;
3323 double LM,WM,LP,M;
3324 double LMeff,WMeff,LPeff,WPeff,XPeff,XMeff;
3325 double CMETAL,CPOLY,Capa=0.0;
3326 double VJ_T, PHP_T, CJO_T,CJSW_T, dT,qT;
3327 double Vt_T,Vt_Tnom,Eg_T,Eg_Tnom;
3328 double dpbdt, dphpdt;
3329 double T,Tnom,TNOM;
3330 double TPB, PHP, TPHP, CTA, CTP,GAP2;
3331 double c0;
3332 int TLEVC,TLEV;
3333 int DCAP;
3334
3335 vd = Va-Vc;
3336
3337 TLEVC = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_TLEVC));
3338 TLEV = MCC_ROUND (mcc_getparam_quick(ptmodel,__MCC_QUICK_TLEV));
3339 DCAP = MCC_ROUND(mcc_getparam_quick(ptmodel, __MCC_QUICK_DCAP));
3340 FC = mcc_getparam_quick(ptmodel, __MCC_QUICK_FC);
3341 FCS = mcc_getparam_quick(ptmodel, __MCC_QUICK_FCS);
3342 KMS = mcc_getparam_quick(ptmodel, __MCC_QUICK_KMS);
3343 CJO = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJO);
3344 CJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJSW);
3345 VJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_VJ);
3346 MJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJ);
3347 MJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSW);
3348 KMS = mcc_getparam_quick(ptmodel, __MCC_QUICK_KMS);
3349 XOI = mcc_getparam_quick(ptmodel, __MCC_QUICK_XOI);
3350 XOM = mcc_getparam_quick(ptmodel, __MCC_QUICK_XOM);
3351 WP = mcc_getparam_quick(ptmodel, __MCC_QUICK_WP);
3352 XP = mcc_getparam_quick(ptmodel, __MCC_QUICK_XP);
3353 LP = mcc_getparam_quick(ptmodel, __MCC_QUICK_LP);
3354 LM = mcc_getparam_quick(ptmodel, __MCC_QUICK_LM);
3355 WM = mcc_getparam_quick(ptmodel, __MCC_QUICK_WM);
3356 WP = mcc_getparam_quick(ptmodel, __MCC_QUICK_WP);
3357 XM = mcc_getparam_quick(ptmodel, __MCC_QUICK_XM);
3358 SHRINK = mcc_getparam_quick(ptmodel, __MCC_QUICK_SHRINK);
3359 SCALM = mcc_getparam_quick(ptmodel, __MCC_QUICK_SCALM);
3360 M = mcc_getparam_quick(ptmodel, __MCC_QUICK_M);
3361 TPB = mcc_getparam_quick(ptmodel, __MCC_QUICK_TPB);
3362 PHP = mcc_getparam_quick(ptmodel, __MCC_QUICK_PHP);
3363 TPHP = mcc_getparam_quick(ptmodel, __MCC_QUICK_TPHP);
3364 CTA = mcc_getparam_quick(ptmodel, __MCC_QUICK_CTA);
3365 CTP = mcc_getparam_quick(ptmodel, __MCC_QUICK_CTP);
3366 GAP2 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP2);
3367
3368 if (DCAP == 2)
3369 FC = FCS = 0.0;
3370
3371 // Geometry
3372 LMeff = LM*SCALE*SHRINK;
3373 WMeff = WM*SCALE*SHRINK;
3374 LPeff = LP*SCALE*SHRINK;
3375 WPeff = WP*SCALE*SHRINK;
3376 XPeff = XP*SCALM;
3377 XMeff = XM*SCALM;
3378
3379 // Temperature effect
3380 T = temp + MCC_KELVIN;
3381 TNOM = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM);
3382 Tnom = TNOM + MCC_KELVIN;
3383 dT = T - Tnom;
3384 qT = T / Tnom;
3385
3386 Vt_T = mcc_calc_vt(temp);
3387 Vt_Tnom = mcc_calc_vt(TNOM);
3388 Eg_T = mcc_calc_eg (temp);
3389 Eg_Tnom = mcc_calc_eg (TNOM);
3390 switch ( TLEVC ) {
3391 case 0: c0 = (Eg_Tnom/Vt_Tnom-Eg_T/Vt_T+3.0*log(qT));
3392 VJ_T = VJ*qT-Vt_T*c0;
3393 PHP_T = PHP*qT-Vt_T*c0;
3394 CJO_T = CJO*(1.0+MJ*(1.0+4.0e-4*dT-VJ_T/VJ));
3395 CJSW_T = CJSW*(1.0+MJSW*(1.0+4.0e-4*dT-PHP_T/PHP));
3396 break;
3397 case 1: VJ_T = VJ-TPB*dT;
3398 PHP_T = PHP - TPHP*dT;
3399 CJO_T = CJO*(1.0+CTA*dT);
3400 CJSW_T = CJSW*(1.0+CTP*dT);
3401 break;
3402 case 2: VJ_T = VJ-TPB*dT;
3403 PHP_T = PHP-TPHP-dT;
3404 CJO_T = CJO*pow((VJ/VJ_T),MJ);
3405 CJSW_T = CJSW*pow((PHP/PHP_T),MJSW);
3406 break;
3407 case 3: switch (TLEV) {
3408 case 0:
3409 case 1: c0 = Eg_Tnom+3.0*Vt_Tnom+(1.16-Eg_Tnom)*(2.0-Tnom/(Tnom+1108.0));
3410 dpbdt = -(c0-VJ)/Tnom;
3411 dphpdt = -(c0-PHP)/Tnom;
3412 break;
3413 case 2: c0 = Eg_Tnom+3.0*Vt_Tnom+(1.16-Eg_Tnom)*(2.0-Tnom/(Tnom+GAP2));
3414 dpbdt = -(c0-VJ)/Tnom;
3415 dphpdt = -(c0-PHP)/Tnom;
3416 break;
3417 default : avt_errmsg(MCC_ERRMSG, "023", AVT_ERROR);
3418 c0 = Eg_Tnom+3.0*Vt_Tnom+(1.16-Eg_Tnom)*(2.0-Tnom/(Tnom+1108.0));
3419 dpbdt = -(c0-VJ)/Tnom;
3420 dphpdt = -(c0-PHP)/Tnom;
3421 break;
3422 }
3423 VJ_T = VJ+dpbdt*dT;
3424 PHP_T = PHP+dphpdt*dT;
3425 CJO_T = CJO*(1.0-0.5*dpbdt*dT/VJ);
3426 CJSW_T = CJSW*(1.0-0.5*dphpdt*dT/PHP);
3427 break;
3428 }
3429
3430 // CJOeff computation...
3431 if ( !ptmodel->SUBCKTNAME ) {
3432 // it means that CJO & CJSW haven't been updated by area & perim
3433 CJOeff = CJO_T*area;
3434 CJSWeff = CJSW_T*perim;
3435 }
3436 else {
3437 CJOeff = CJO_T;
3438 CJSWeff = CJSW_T;
3439 }
3440
3441 if ( vd < FC*VJ-KMS ) {
3442 CDEPa = CJOeff*pow((1.0-(vd+KMS)/VJ_T),-MJ);
3443 CDEPp = CJSWeff*pow((1.0-(vd+KMS)/VJ_T),-MJSW);
3444 }
3445 else {
3446 CDEPa = (CJOeff/pow((1.0-FC),1+MJ))*(1.0-FC*(1.0+MJ)+MJ*(vd+KMS)/VJ_T);
3447 CDEPp = (CJSWeff/pow((1.0-FC),1+MJSW))*(1.0-FC*(1.0+MJSW)+MJSW*(vd+KMS)/VJ_T);
3448 }
3449 // Metal & Polysilicon capacitance
3450 CMETAL = (MCC_EPSOX/XOI)*(WPeff+XPeff)*(LPeff+XPeff)*M;
3451
3452 CPOLY = (MCC_EPSOX/XOM)*(WMeff+XMeff)*(LMeff+XMeff)*M;
3453
3454 // CDIFF = TT*dId/dVd = TT*gd;
3455
3456 Capa = CDEPa+CDEPp+CMETAL+CPOLY;
3457
3458 return Capa;
3459 }
3460
3461 /******************************************************************************\
3462 *
3463 * FUNC : mcc_dio_calcCDEP_l2
3464 * CDEP is Depletion capacitance
3465 Va: Anode Voltage
3466 Vc: Cathode Voltage
3467
3468 return the total capacitance: Capa = CDEP + CDIFF
3469 \******************************************************************************/
3470 double mcc_dio_calcCapa_l2 ( mcc_modellist *ptmodel,
3471 double Va, double Vc,
3472 double temp,
3473 double area
3474 )
3475 {
3476 double vd;
3477 double CDEP;
3478 double MJ,CJO,VJ,FC;
3479 double CJOeff;
3480 double VJ_T, CJO_T, dT,qT;
3481 double Vt_T,Vt_Tnom,Eg_T,Eg_Tnom;
3482 double T,Tnom,TNOM;
3483
3484 vd = Va-Vc;
3485
3486 CJO = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJO);
3487 VJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_VJ);
3488 MJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJ);
3489 FC = mcc_getparam_quick(ptmodel, __MCC_QUICK_FC);
3490
3491 // Temperature effect
3492 T = temp + MCC_KELVIN;
3493 TNOM = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM);
3494 Tnom = TNOM + MCC_KELVIN;
3495 dT = T - Tnom;
3496 qT = T / Tnom;
3497
3498 Vt_T = mcc_calc_vt(temp);
3499 Vt_Tnom = mcc_calc_vt(TNOM);
3500 Eg_T = mcc_calc_eg (temp);
3501 Eg_Tnom = mcc_calc_eg (TNOM);
3502
3503 VJ_T = VJ*qT-Vt_T*(Eg_Tnom/Vt_Tnom-Eg_T/Vt_T+3.0*log(qT));
3504 CJO_T = CJO*(1.0+MJ*(1.0+4.0e-4*dT-VJ_T/VJ));
3505
3506
3507 // CJOeff computation...
3508 if ( !ptmodel->SUBCKTNAME ) // it means that CJO haven't been updated by area
3509 CJOeff = CJO_T*area;
3510 else
3511 CJOeff = CJO_T;
3512
3513 if ( vd < FC*VJ )
3514 CDEP = CJOeff*pow((1.0-vd/VJ),-MJ);
3515 else
3516 CDEP = (CJOeff/pow((1.0-FC),1+MJ))*(1.0-FC*(1.0+MJ)+MJ*vd/VJ);
3517
3518 return CDEP;
3519 }
3520
3521 /******************************************************************************\
3522 *
3523 * FUNC : mcc_dio_calcCapa_l3
3524 * CDEP is Depletion capacitance
3525 Va: Anode Voltage
3526 Vc: Cathode Voltage
3527
3528 return the total capacitance: Capa = Cd (constant)
3529 \******************************************************************************/
3530 double mcc_dio_calcCapa_l3 ( mcc_modellist *ptmodel,
3531 double area
3532 )
3533 {
3534 double TOX;
3535 double AREAeff;
3536 double Cd;
3537
3538 TOX = mcc_getparam_quick(ptmodel, __MCC_QUICK_TOX);
3539
3540 AREAeff = area;
3541
3542 Cd = AREAeff*MCC_EPSO/TOX;
3543
3544 return Cd;
3545 }
3546
3547 /******************************************************************************\
3548 *
3549 * FUNC : mcc_dio_calcCDEP_l8
3550 Va: Anode Voltage
3551 Vc: Cathode Voltage
3552
3553
3554 DIOLEV = 9: Cbx = Cbxbot+Cbxsid+Cbxdiff (Cbxdiff assumed to be 0)
3555 DIOLEV != 9: Cbx = AREA*Cjbv+PERI*Cjsv+PGATE*Cjgv
3556
3557 return the total capacitance: Cbx
3558 \******************************************************************************/
3559 double mcc_dio_calcCapa_l8 ( mcc_modellist *ptmodel,
3560 double Va,double Vc,
3561 double temp,
3562 double area, double perim
3563 )
3564 {
3565 double Cbx,Cbxbot,Cbxsid,Cjax,Cjpx;
3566 double JS,JSW,CJ,CJSW,CJGATE,c0;
3567 double PB,PBSW,TNOM,T,Tnom,dT,qT,FC;
3568 double CJ_T,CJSW_T,PB_T,PBSW_T,Vt_T,Vt_Tnom,Eg_T,Eg_Tnom;
3569 double vd;
3570 int M=1; //number of parallel transistor
3571 double CTA,PTA,CTP,GAP2,Dpb,Dpbsw,MJ,MJSW,PTP;
3572 int TLEVC;
3573 int DIOLEV;
3574
3575 TLEVC = MCC_ROUND(mcc_getparam_quick(ptmodel, __MCC_QUICK_TLEVC));
3576 TNOM = mcc_getparam_quick(ptmodel, __MCC_QUICK_TNOM);
3577 JS = mcc_getparam_quick(ptmodel, __MCC_QUICK_JS);
3578 JSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_JSW);
3579 CJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJ);
3580 CJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJSW);
3581 CJGATE = mcc_getparam_quick(ptmodel, __MCC_QUICK_CJGATE);
3582 DIOLEV = MCC_ROUND(mcc_getparam_quick(ptmodel, __MCC_QUICK_DIOLEV));
3583 FC = mcc_getparam_quick(ptmodel, __MCC_QUICK_FC);
3584 PB = mcc_getparam_quick(ptmodel, __MCC_QUICK_PB);
3585 PBSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_PBSW);
3586 PTA = mcc_getparam_quick(ptmodel, __MCC_QUICK_PTA);
3587 PTP = mcc_getparam_quick(ptmodel, __MCC_QUICK_PTP);
3588 CTA = mcc_getparam_quick(ptmodel, __MCC_QUICK_CTA);
3589 CTP = mcc_getparam_quick(ptmodel, __MCC_QUICK_CTP);
3590 GAP2 = mcc_getparam_quick(ptmodel, __MCC_QUICK_GAP2);
3591 MJ = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJ);
3592 MJSW = mcc_getparam_quick(ptmodel, __MCC_QUICK_MJSW);
3593
3594 T = temp+MCC_KELVIN;
3595 Tnom = TNOM+MCC_KELVIN;
3596 dT = T-Tnom;
3597 qT = T/Tnom;
3598
3599 Vt_T = mcc_calc_vt(temp);
3600 Vt_Tnom = mcc_calc_vt(TNOM);
3601 Eg_T = mcc_calc_eg (temp);
3602 Eg_Tnom = mcc_calc_eg (TNOM);
3603
3604
3605 vd = Va-Vc;
3606
3607 if ( DIOLEV != 9 ) {
3608 // Temperature update
3609 switch ( TLEVC ) {
3610 case 0: c0 = (Eg_Tnom/Vt_Tnom-Eg_T/Vt_T+3.0*log(qT));
3611 PB_T = PB*qT-Vt_T*c0;
3612 PBSW_T = PBSW*qT-Vt_T*c0;
3613 CJ_T = CJ*(1.0+MJ*(1.0+4.0e-4*dT-PB_T/PB));
3614 CJSW_T = CJSW*(1.0+MJSW*(1.0+4.0e-4*dT-PBSW_T/PBSW));
3615 break;
3616 case 1: PB_T = PTA*dT;
3617 PBSW_T = PBSW-PTP*dT;
3618 CJ_T = CJ*(1.0+CTA*dT);
3619 CJSW_T = CJSW*(1.0+CTP*dT);
3620 break;
3621 case 2: PB_T = PB-PTA*dT;
3622 PBSW_T = PBSW - PTP*dT;
3623 CJ_T = CJ*pow(PB/PB_T,MJ);
3624 CJSW_T = CJSW*pow(PBSW/PBSW_T,MJSW);
3625 break;
3626 case 3: c0 = Eg_Tnom-3.0*Vt_Tnom+(Eg_Tnom-Eg_T)*(2.0-Tnom/(Tnom+GAP2));
3627 Dpb = PB-c0;
3628 Dpbsw = PBSW-c0;
3629 PB_T = PB+Dpb*dT/Tnom;
3630 PBSW_T = PBSW+Dpbsw*dT/Tnom;
3631 CJ_T = CJ*(1.0-0.5*Dpb/PB*dT/Tnom);
3632 CJSW_T = CJSW*(1.0-0.5*Dpb/PBSW*dT/Tnom);
3633 break;
3634 }
3635 if ( CJ > 0.0 )
3636 Cjax = M*area*CJ_T;
3637 else
3638 Cjax = 0.0;
3639 if ( CJSW > 0.0 )
3640 Cjpx = M*perim*CJSW_T;
3641 else
3642 Cjpx = 0.0;
3643 if ( vd <= FC*PB )
3644 Cbxbot = Cjax*pow((1.0-vd/PB_T),-MJ);
3645 else
3646 Cbxbot = (Cjax/pow(1.0-FC,1.0+MJ))*(1.0-FC*(1.0+MJ)+MJ*vd/PB_T);
3647 if ( vd <= FC*PBSW )
3648 Cbxsid = Cjpx*pow((1.0-vd/PBSW_T),-MJSW);
3649 else
3650 Cbxsid = (Cjpx/pow(1.0-FC,1.0+MJSW))*(1.0-FC*(1.0+MJSW)+MJSW*vd/PBSW_T);
3651 // if TT>0.0 Cbxdiff = TT*dIbx/dVbx else Cbxdiff=0
3652 Cbx = Cbxbot+Cbxsid;
3653 }
3654 else {
3655 // unsupported because no info on pgate...
3656 fprintf (stderr,"[MCC ERR] Diode capacitance for level 8 and diolev = 9 is not supported yet!\n");
3657 Cbx = 0.0;
3658 }
3659
3660 return Cbx;
3661 }
3662
3663 /******************************************************************************\
3664 * Func mcc_calcIgb
3665 \******************************************************************************/
3666 double mcc_calcIgb (char *technoname, char *transname,
3667 int transtype, int transcase,
3668 double vbs, double vgs, double vds,
3669 double L, double W,
3670 double temp,elp_lotrs_param *lotrsparam)
3671 {
3672 mcc_modellist *ptmodel ;
3673 double igb = 0.0;
3674
3675 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3676 return 0.0;
3677 else {
3678 switch(ptmodel->MODELTYPE) {
3679 case MCC_BSIM3V3 : igb = 0.0;
3680 break ;
3681 case MCC_BSIM4 : igb = mcc_calcIgb_bsim4 (ptmodel, L, W, temp,
3682 vgs,vds,vbs,
3683 lotrsparam) ;
3684 break ;
3685 default : igb = 0.0;
3686 break;
3687 }
3688 }
3689 return igb;
3690 }
3691
3692 /******************************************************************************\
3693 * Func mcc_calcIgixl
3694 \******************************************************************************/
3695 void mcc_calcIgixl (char *technoname, char *transname,
3696 int transtype, int transcase,
3697 double vbs, double vgs, double vds,
3698 double L, double W, double temp,
3699 double *ptIgidl, double *ptIgisl,
3700 elp_lotrs_param *lotrsparam)
3701 {
3702 mcc_modellist *ptmodel ;
3703
3704 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3705 return;
3706 else {
3707 switch(ptmodel->MODELTYPE) {
3708 case MCC_BSIM3V3 : if ( ptIgisl ) *ptIgisl = 0.0;
3709 if ( ptIgidl ) *ptIgidl = 0.0;
3710 break ;
3711 case MCC_BSIM4 : mcc_calcIgixl_bsim4 (ptmodel, L, W,
3712 ptIgidl,ptIgisl,
3713 temp,
3714 vgs,vds,vbs,
3715 lotrsparam) ;
3716 break ;
3717 default : if ( ptIgisl ) *ptIgisl = 0.0;
3718 if ( ptIgidl ) *ptIgidl = 0.0;
3719 break;
3720 }
3721 }
3722 }
3723
3724 /******************************************************************************\
3725 * Func mcc_calcIxb
3726 \******************************************************************************/
3727 void mcc_calcIxb (char *technoname, char *transname,
3728 int transtype, int transcase,
3729 double vbs, double vds,
3730 double L, double W, double temp,
3731 double AD, double PD, double AS, double PS,
3732 double *ptIdb, double *ptIsb,
3733 elp_lotrs_param *lotrsparam)
3734 {
3735 mcc_modellist *ptmodel ;
3736
3737 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3738 return;
3739 else {
3740 switch(ptmodel->MODELTYPE) {
3741 case MCC_BSIM3V3 : if ( ptIdb ) *ptIdb = 0.0;
3742 if ( ptIsb ) *ptIsb = 0.0;
3743 break ;
3744 case MCC_BSIM4 : mcc_calcIxb_bsim4 (ptmodel, L, W,
3745 ptIdb,ptIsb,
3746 temp,vds,vbs,
3747 AD,PD,AS,PS,
3748 lotrsparam) ;
3749 break ;
3750 default : if ( ptIdb ) *ptIdb = 0.0;
3751 if ( ptIsb ) *ptIsb = 0.0;
3752 break;
3753 }
3754 }
3755 }
3756
3757 /******************************************************************************\
3758 * Func mcc_calcIgx
3759 \******************************************************************************/
3760 void mcc_calcIgx (char *technoname, char *transname,
3761 int transtype, int transcase,
3762 double vds, double vgs,
3763 double L, double W, double temp,
3764 double *ptIgd, double *ptIgs,
3765 elp_lotrs_param *lotrsparam)
3766 {
3767 mcc_modellist *ptmodel ;
3768
3769 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3770 return ;
3771 else {
3772 switch(ptmodel->MODELTYPE) {
3773 case MCC_BSIM3V3 : if ( ptIgd ) *ptIgd = 0.0;
3774 if ( ptIgs ) *ptIgs = 0.0;
3775 break ;
3776 case MCC_BSIM4 :
3777 mcc_calcIgx_bsim4 (ptmodel, L, W,
3778 ptIgd,ptIgs,
3779 temp,vds,vgs,
3780 lotrsparam) ;
3781 break ;
3782 default : if ( ptIgd ) *ptIgd = 0.0;
3783 if ( ptIgs ) *ptIgs = 0.0;
3784 break;
3785 }
3786 }
3787 }
3788
3789 /******************************************************************************\
3790 * Func mcc_calcIgcx
3791 \******************************************************************************/
3792 void mcc_calcIgcx (char *technoname, char *transname,
3793 int transtype, int transcase,
3794 double vds, double vgs, double vbs,
3795 double L, double W, double temp,
3796 double *ptIgcd, double *ptIgcs,
3797 elp_lotrs_param *lotrsparam)
3798 {
3799 mcc_modellist *ptmodel ;
3800
3801 if(!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3802 return;
3803 else {
3804 switch(ptmodel->MODELTYPE) {
3805 case MCC_BSIM3V3 : if ( ptIgcd ) *ptIgcd = 0.0;
3806 if ( ptIgcs ) *ptIgcs = 0.0;
3807 break ;
3808 case MCC_BSIM4 :
3809 mcc_calcIgcx_bsim4 (ptmodel, L, W,
3810 ptIgcd,ptIgcs,
3811 temp,vds,vgs,vbs,
3812 lotrsparam) ;
3813 break ;
3814 default : if ( ptIgcd ) *ptIgcd = 0.0;
3815 if ( ptIgcs ) *ptIgcs = 0.0;
3816 break;
3817 }
3818 }
3819 }
3820
3821 /******************************************************************************\
3822 * Func mcc_calcILeakage
3823 \******************************************************************************/
3824 double mcc_calcILeakage (char *technoname, char *transname,
3825 int transtype, int transcase,
3826 double vbs, double vds, double vgs,
3827 double L, double W, double temp,
3828 double AD, double PD, double AS, double PS,
3829 double *BLeak, double *DLeak, double *SLeak,
3830 elp_lotrs_param *lotrsparam)
3831 {
3832 double Ileak = 0.0;
3833 double Igb=0.0,Igisl=0.0,Igidl=0.0,Isb=0.0,
3834 Idb=0.0,Igs=0.0,Igd=0.0,Igcs=0.0,Igcd=0.0;
3835 double vth, Isubth=0.0;
3836
3837 Igb = mcc_calcIgb (technoname, transname,
3838 transtype, transcase,
3839 vbs, vgs, vds,
3840 L, W, temp,lotrsparam);
3841
3842 mcc_calcIgixl (technoname, transname,
3843 transtype, transcase,
3844 vbs, vgs, vds,
3845 L, W, temp,
3846 &Igidl, &Igisl,
3847 lotrsparam);
3848
3849 mcc_calcIxb (technoname, transname,
3850 transtype, transcase,
3851 vbs, vds,
3852 L, W, temp,
3853 AD, PD, AS, PS,
3854 &Idb, &Isb,
3855 lotrsparam);
3856
3857 mcc_calcIgx (technoname, transname,
3858 transtype, transcase,
3859 vds, vgs,
3860 L, W, temp,
3861 &Igd, &Igs,
3862 lotrsparam);
3863
3864 mcc_calcIgcx (technoname, transname,
3865 transtype, transcase,
3866 vds, vgs, vbs,
3867 L,W, temp,
3868 &Igcd, &Igcs,
3869 lotrsparam);
3870
3871 //----> Subthreshold current
3872
3873 vth = mcc_calcVTH (technoname, transname,
3874 transtype, transcase, L, W,
3875 temp, vbs, vds,lotrsparam,MCC_NO_LOG) ;
3876
3877 if ( fabs(vgs) < fabs(vth) ) {
3878 Isubth = mcc_calcIDS (technoname, transname,
3879 transtype, transcase, vbs, vgs,
3880 vds, L, W,
3881 temp,lotrsparam);
3882 }
3883 if ( BLeak ) *BLeak = Igb+Isb+Idb+Igisl+Igidl;
3884 if ( DLeak ) *DLeak = Igd+Igcd;
3885 if ( SLeak ) *SLeak = Igs+Igcs+Isubth;
3886
3887 Ileak = Isubth+Igb+Igisl+Igidl+Isb+Idb+Igs+Igd+Igcs+Igcd;
3888
3889 return Ileak;
3890 }
3891
3892
3893 /******************************************************************************\
3894 FUNCTION : mcc_calcVTI_nmos_com_fn
3895 Soit 2 transistors nmos mn0 et mn1 en serie:
3896 mn0 vdd vdd Vti vbulk nmos
3897 mn1 Vti 0 0 vbulk nmos
3898 On resoud Ids(mn0) = Ids(mn1) pour un Vti trouve
3899 <=> Ids_mn0(vds,vgs,vbs) - Ids_mn1(vds,vgs,vbs) = 0;
3900 \******************************************************************************/
3901
3902 int mcc_calcVTI_nmos_com_fn ( struct mcc_vdeg_fn *data, double vti, double *res )
3903 {
3904 double ids0,ids1;
3905
3906 ids0= mcc_calcIDS( data->ptmodel->TECHNO->NAME,
3907 data->transname,
3908 data->ptmodel->TYPE,
3909 data->ptmodel->CASE,
3910 data->lotrsparam->VBULK-vti,
3911 data->vdd-vti,
3912 data->vdd-vti,
3913 data->L,
3914 data->W,
3915 data->temp,
3916 data->lotrsparam
3917 ) ;
3918 ids1= mcc_calcIDS( data->ptmodel->TECHNO->NAME,
3919 data->transname,
3920 data->ptmodel->TYPE,
3921 data->ptmodel->CASE,
3922 data->lotrsparam->VBULK,
3923 0.0,
3924 vti,
3925 data->L,
3926 data->W,
3927 data->temp,
3928 data->lotrsparam
3929 ) ;
3930 *res = ids0-ids1;
3931 return 1;
3932 }
3933
3934 /******************************************************************************\
3935 FUNCTION : mcc_calcVTI_nmos_com
3936 \******************************************************************************/
3937 double mcc_calcVTI_nmos_com (mcc_modellist *ptmodel, char *transname,
3938 double L, double W,
3939 double vdd, double temp, double step,
3940 elp_lotrs_param *lotrsparam)
3941 {
3942 static int nbcall=0;
3943 struct mcc_vdeg_fn data ;
3944 double x0, x1, vti;
3945 int ret, it ;
3946
3947 if (ptmodel->TYPE == MCC_PMOS) {
3948 avt_errmsg(MCC_ERRMSG, "019", AVT_ERROR, ptmodel->NAME) ;
3949 return 0.0 ;
3950 }
3951 nbcall++;
3952
3953 data.ptmodel = ptmodel ;
3954 data.transname = transname ;
3955 data.L = L ;
3956 data.W = W ;
3957 data.temp = temp ;
3958 data.lotrsparam = lotrsparam ;
3959 data.vdd = vdd ;
3960
3961 x0 = 0 ;
3962 x1 = vdd ;
3963 it = 10000 ;
3964 ret = mbk_dichotomie( (int(*)(void*, double, double*)) mcc_calcVTI_nmos_com_fn,
3965 NULL,
3966 &data,
3967 &x0,
3968 &x1,
3969 MBK_DICHO_EQUAL,
3970 &it,
3971 step,
3972 DBL_MAX,
3973 &vti
3974 );
3975
3976 if( ret != MBK_DICHO_OK ) {
3977 //avt_errmsg(MCC_ERRMSG, "024", AVT_WARNING) ;
3978 }
3979 return vti;
3980 }
3981
3982 /******************************************************************************/
3983 /* Calcul de la tension degradee VDDDEG d'un modele de transistor */
3984 /******************************************************************************/
3985 double mcc_calcVTI_nmos (char *technoname, char *transname,
3986 int transtype, int transcase, double L, double W,
3987 double vdd, double temp,
3988 double step, elp_lotrs_param *lotrsparam)
3989 {
3990 mcc_modellist *ptmodel ;
3991 double vti = 0.0 ;
3992
3993 if (!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
3994 return 0.0;
3995 else
3996 vti = mcc_calcVTI_nmos_com(ptmodel, transname, L, W,
3997 vdd, temp, step,
3998 lotrsparam) ;
3999
4000 return vti;
4001 }
4002
4003 /******************************************************************************\
4004 FUNCTION : mcc_calcVTI_pmos_com_fn
4005 Soit 2 transistors pmos mp0 et mp1 en serie:
4006 mp0 0 0 Vti vbulk pmos
4007 mp1 Vti vdd vdd vbulk pmos
4008 On resoud Ids(mp0) = Ids(mp1) pour un Vti trouve
4009 <=> Ids_mp0(vds,vgs,vbs) - Ids_mp1(vds,vgs,vbs) = 0;
4010 \******************************************************************************/
4011
4012 int mcc_calcVTI_pmos_com_fn ( struct mcc_vdeg_fn *data, double vti, double *res )
4013 {
4014 double ids0,ids1;
4015
4016 ids0= mcc_calcIDS( data->ptmodel->TECHNO->NAME,
4017 data->transname,
4018 data->ptmodel->TYPE,
4019 data->ptmodel->CASE,
4020 data->lotrsparam->VBULK-vti, //vbs
4021 -vti, //vgs
4022 -vti, //vds
4023 data->L,
4024 data->W,
4025 data->temp,
4026 data->lotrsparam
4027 ) ;
4028 ids1= mcc_calcIDS( data->ptmodel->TECHNO->NAME,
4029 data->transname,
4030 data->ptmodel->TYPE,
4031 data->ptmodel->CASE,
4032 data->lotrsparam->VBULK-data->vdd,
4033 0.0,
4034 vti-data->vdd,
4035 data->L,
4036 data->W,
4037 data->temp,
4038 data->lotrsparam
4039 ) ;
4040 *res = ids0-ids1;
4041 return 1;
4042 }
4043
4044 /******************************************************************************\
4045 FUNCTION : mcc_calcVTI_pmos_com
4046 \******************************************************************************/
4047 double mcc_calcVTI_pmos_com (mcc_modellist *ptmodel, char *transname,
4048 double L, double W,
4049 double vdd, double temp, double step,
4050 elp_lotrs_param *lotrsparam)
4051 {
4052 static int nbcall=0;
4053 struct mcc_vdeg_fn data ;
4054 double x0, x1, vti;
4055 int ret, it ;
4056
4057 if (ptmodel->TYPE == MCC_NMOS) {
4058 return 0.0 ;
4059 }
4060 nbcall++;
4061
4062 data.ptmodel = ptmodel ;
4063 data.transname = transname ;
4064 data.L = L ;
4065 data.W = W ;
4066 data.temp = temp ;
4067 data.lotrsparam = lotrsparam ;
4068 data.vdd = vdd ;
4069
4070 x0 = 0 ;
4071 x1 = vdd ;
4072 it = 10000 ;
4073 ret = mbk_dichotomie( (int(*)(void*, double, double*)) mcc_calcVTI_pmos_com_fn,
4074 NULL,
4075 &data,
4076 &x0,
4077 &x1,
4078 MBK_DICHO_EQUAL,
4079 &it,
4080 step,
4081 DBL_MAX,
4082 &vti
4083 );
4084
4085 if( ret != MBK_DICHO_OK ) {
4086 // avt_errmsg(MCC_ERRMSG, "025", AVT_WARNING) ;
4087 }
4088 return vti;
4089 }
4090
4091 /******************************************************************************/
4092 /******************************************************************************/
4093 double mcc_calcVTI_pmos (char *technoname, char *transname,
4094 int transtype, int transcase, double L, double W,
4095 double vdd, double temp,
4096 double step, elp_lotrs_param *lotrsparam)
4097 {
4098 mcc_modellist *ptmodel ;
4099 double vti = 0.0 ;
4100
4101 if (!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
4102 return 0.0;
4103 else
4104 vti = mcc_calcVTI_pmos_com(ptmodel, transname, L, W,
4105 vdd, temp, step,
4106 lotrsparam) ;
4107
4108 return vti;
4109 }
4110
4111
4112 /******************************************************************************/
4113 void mcc_calcRACCESS( char *technoname, char *transname,
4114 int transtype, int transcase, double L, double W,
4115 elp_lotrs_param *lotrsparam,
4116 double *RS, double *RD
4117 )
4118 {
4119 mcc_modellist *ptmodel ;
4120 double Weff, xw ;
4121
4122
4123 ptmodel = mcc_getmodel( technoname, transname, transtype, transcase, L, W, 0 );
4124
4125 if( !ptmodel ) {
4126 if( RS ) *RS = 0.0 ;
4127 if( RD ) *RD = 0.0 ;
4128 return ;
4129 }
4130
4131 xw = mcc_getXW (technoname, transname, transtype, transcase, L,W);
4132 Weff = W*xw + mcc_calcDW (technoname, transname, transtype, transcase, L, W, lotrsparam);
4133 mcc_compute_RD_RS( ptmodel, Weff, RS, RD, lotrsparam );
4134 }
4135
4136 /******************************************************************************/
4137 double mcc_calcVTI (char *technoname, char *transname,
4138 int transtype, int transcase, double L, double W,
4139 double vdd, double temp,
4140 double step, elp_lotrs_param *lotrsparam)
4141 {
4142 mcc_modellist *ptmodel ;
4143 double vti = 0.0 ;
4144
4145 if (!(ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0)))
4146 return 0.0;
4147 else {
4148 if ( ptmodel->TYPE == MCC_PMOS ) {
4149 vti = mcc_calcVTI_pmos_com(ptmodel, transname, L, W,
4150 vdd, temp, step,
4151 lotrsparam) ;
4152 }
4153 else {
4154 vti = mcc_calcVTI_nmos_com(ptmodel, transname, L, W,
4155 vdd, temp, step,
4156 lotrsparam) ;
4157 }
4158 }
4159 return vti;
4160 }
4161
4162 void mcc_calcPAfromgeomod( lotrs_list *lotrs,
4163 char *modelname,
4164 int type,
4165 int lotrscase,
4166 double vdd,
4167 elp_lotrs_param *lotrsparam,
4168 double *as,
4169 double *ad,
4170 double *ps,
4171 double *pd
4172 )
4173 {
4174 double l,
4175 w ;
4176 double lscale,
4177 wscale ;
4178 mcc_modellist *model ;
4179
4180 l = ((double)lotrs->LENGTH) / ((double)SCALE_X) ;
4181 w = ((double)lotrs->WIDTH) / ((double)SCALE_X) ;
4182
4183 mcc_update_technoparams( modelname, type, l, w, lotrs, lotrscase );
4184
4185 switch( lotrscase ) {
4186 case MCC_BEST : MCC_VDDmax = MCC_VDD_BEST;
4187 MCC_VGS = MCC_VDDmax/2.0;
4188 MCC_TEMP = MCC_TEMP_BEST;
4189 break;
4190 case MCC_WORST : MCC_VDDmax = MCC_VDD_WORST;
4191 MCC_VGS = MCC_VDDmax/2.0;
4192 MCC_TEMP = MCC_TEMP_WORST;
4193 break;
4194 default : MCC_VDDmax = vdd;
4195 MCC_VGS = MCC_VDDmax/2.0;
4196 break;
4197 }
4198
4199 if(type == MCC_TRANS_N) {
4200 lscale = MCC_LN*1.0e-6 ;
4201 wscale = MCC_WN*1.0e-6 ;
4202 }
4203 else {
4204 lscale = MCC_LP*1.0e-6 ;
4205 wscale = MCC_WP*1.0e-6 ;
4206 }
4207
4208 MCC_CALC_CUR = MCC_CALC_MODE ;
4209
4210 model = mcc_getmodel( MCC_MODELFILE, modelname, type, lotrscase, lscale, wscale, 0 );
4211
4212 if( model ) {
4213
4214 switch( model->MODELTYPE ) {
4215 case MCC_BSIM4 :
4216 mcc_calcPAfromgeomod_bsim4( lotrs, model, lotrsparam, as, ad, ps, pd ) ;
4217 break ;
4218 case MCC_BSIM3V3 :
4219 mcc_calcPAfromgeomod_bsim3( lotrs, model, lotrsparam, as, ad, ps, pd ) ;
4220 break ;
4221 case MCC_EXTMOD :
4222 mcc_calcPAfromgeomod_extmod( lotrs, model, lotrsparam, as, ad, ps, pd ) ;
4223 break ;
4224 }
4225 }
4226 }
4227
4228 int mcc_getspicetechno( char *technoname, char *transname, int transtype, int transcase, double L, double W )
4229 {
4230 mcc_modellist *model ;
4231 int tectype = MCC_NOMODEL ;
4232
4233 model = mcc_getmodel( technoname, transname, transtype, transcase, L, W, 0 );
4234 if( model )
4235 tectype = model->MODELTYPE ;
4236
4237 return tectype ;
4238 }
4239
4240 void mcc_check_capa_print( char trans,
4241 char *technoname,
4242 char *transname,
4243 int transtype,
4244 int transcase,
4245 double L, double W,
4246 double temp, double vdd,
4247 elp_lotrs_param *lotrsparam
4248 )
4249 {
4250 mcc_modellist *ptmodel ;
4251 double La_Wa ;
4252 double vgs, vds, vbs, v, vi, vf, v1, v2 ;
4253 int flag, flaghalf, flagvt ;
4254 double Qg, Qb, Qs, Qd ;
4255 double Qg0, Qd0, Qde0 ;
4256 double qgs, qgs0 ;
4257 double cgs, cgsf ;
4258 double qgd, qgd0 ;
4259 double cgd, cgdf ;
4260 double qgde, qgde0 ;
4261 double cgde0, cgde1, cgde2 ;
4262 char filename[1024] ;
4263 FILE *file ;
4264 int j,n;
4265 char *label ;
4266
4267 ptmodel = mcc_getmodel(technoname, transname, transtype, transcase, L, W, 0);
4268 if( !ptmodel )
4269 return ;
4270
4271 if( lotrsparam->ISVBSSET )
4272 vbs = lotrsparam->VBS ;
4273 else
4274 vbs = ( transtype == MCC_NMOS ) ? lotrsparam->VBULK : lotrsparam->VBULK-MCC_VDDmax ;
4275
4276 switch( ptmodel->MODELTYPE ) {
4277 case MCC_BSIM4 :
4278 La_Wa = (L + mcc_calcDLC_bsim4 (ptmodel, lotrsparam, L, W)) *(W+mcc_calcDWC_bsim4 (ptmodel, lotrsparam, L, W));
4279 break ;
4280 case MCC_MPSP:
4281 case MCC_MPSPB :
4282 case MCC_EXTMOD:
4283 La_Wa = L*W ;
4284 break ;
4285 default :
4286 La_Wa = (L + mcc_calcDLC_bsim3v3(ptmodel, L, W)) *(W+mcc_calcDWC_bsim3v3(ptmodel, L, W));
4287 }
4288
4289 if( trans==1 ) {
4290 label = "ud" ;
4291 vi = 0.0 ;
4292 vf = vdd ;
4293 if( transtype == MCC_NMOS ) {
4294 cgs = MCC_CGSUN ;
4295 cgsf = MCC_CGSUFN ;
4296 cgd = MCC_CGDN ;
4297 cgdf = MCC_CGDN ;
4298 vds = vdd ;
4299
4300 if( MCC_VT0N < MCC_VDDmax/2.0 ) {
4301 v1 = MCC_VT0N ;
4302 v2 = MCC_VDDmax/2.0 ;
4303 }
4304 else {
4305 v1 = MCC_VDDmax/2.0 ;
4306 v2 = MCC_VT0N ;
4307 }
4308 cgde0 = MCC_CGD0N ;
4309 cgde1 = MCC_CGD1N ;
4310 cgde2 = MCC_CGD2N ;
4311 }
4312 else {
4313 cgs = MCC_CGSUP ;
4314 cgsf = MCC_CGSUFP ;
4315 cgd = MCC_CGDCP ;
4316 cgdf = MCC_CGDCP ;
4317 vds = 0.0 ;
4318
4319 if( MCC_VT0P < MCC_VDDmax/2.0 ) {
4320 v1 = MCC_VDDmax/2.0 ;
4321 v2 = MCC_VDDmax-MCC_VT0P ;
4322 }
4323 else {
4324 v1 = MCC_VDDmax-MCC_VT0P ;
4325 v2 = MCC_VDDmax/2.0 ;
4326 }
4327 cgde0 = MCC_CGDC2P ;
4328 cgde1 = MCC_CGDC1P ;
4329 cgde2 = MCC_CGDC0P ;
4330 }
4331 }
4332 else {
4333 label = "du" ;
4334 vi = vdd ;
4335 vf = 0.0 ;
4336 if( transtype == MCC_NMOS ) {
4337 cgs = MCC_CGSDN ;
4338 cgsf = MCC_CGSDFN ;
4339 cgd = MCC_CGDCN ;
4340 cgdf = MCC_CGDCN ;
4341 vds = 0.0 ;
4342
4343 if( MCC_VT0N < MCC_VDDmax/2.0 ) {
4344 v1 = MCC_VDDmax/2.0 ;
4345 v2 = MCC_VT0N ;
4346 }
4347 else {
4348 v1 = MCC_VT0N ;
4349 v2 = MCC_VDDmax/2.0 ;
4350 }
4351 cgde0 = MCC_CGDC2N ;
4352 cgde1 = MCC_CGDC1N ;
4353 cgde2 = MCC_CGDC0N ;
4354 }
4355 else {
4356 cgs = MCC_CGSDP ;
4357 cgsf = MCC_CGSDFP ;
4358 cgd = MCC_CGDP ;
4359 cgdf = MCC_CGDP ;
4360 vds = -vdd ;
4361
4362 if( MCC_VT0P < MCC_VDDmax/2.0 ) {
4363 v1 = MCC_VDDmax-MCC_VT0P ;
4364 v2 = MCC_VDDmax/2.0 ;
4365 }
4366 else {
4367 v1 = MCC_VDDmax/2.0 ;
4368 v2 = MCC_VDDmax-MCC_VT0P ;
4369 }
4370 cgde0 = MCC_CGD0P ;
4371 cgde1 = MCC_CGD1P ;
4372 cgde2 = MCC_CGD2P ;
4373 }
4374 }
4375
4376 sprintf( filename, "%s_%c_%s", mcc_debug_prefix( "intrinsic" ), transtype==MCC_NMOS ? 'N':'P', label ) ;
4377 file = mbkfopen( filename, "dat", "w" );
4378 if( !file )
4379 return ;
4380
4381 fprintf( file, "#vgs qg(int) qg(cgs) qd(int) qd(cgd) qd(cgde)\n" );
4382
4383 n = 30.0 ;
4384 flag = 0 ;
4385 flaghalf = 0 ;
4386 flagvt = 0 ;
4387
4388 for( j=0 ; j<=n ; j++ ) {
4389
4390 v = vi+(vf-vi)*((float)j)/((float)n);
4391
4392 if( transtype == MCC_NMOS )
4393 vgs = v ;
4394 else
4395 vgs = v-MCC_VDDmax ;
4396
4397 switch( ptmodel->MODELTYPE ) {
4398 case MCC_BSIM4 :
4399 mcc_calcQint_bsim4 (ptmodel, L, W,
4400 temp, vgs, vbs, vds,
4401 &Qg, &Qs, &Qd, &Qb,
4402 lotrsparam);
4403 break ;
4404 case MCC_MPSP:
4405 case MCC_MPSPB:
4406 mcc_calcQint_psp (ptmodel, L, W,
4407 temp, vgs, vbs, vds,
4408 &Qg, &Qs, &Qd, &Qb,
4409 lotrsparam);
4410 break ;
4411 case MCC_EXTMOD:
4412 mcc_calcQint_ext(ptmodel, L, W,
4413 temp, vgs, vbs, vds,
4414 &Qg, &Qs, &Qd, &Qb,
4415 lotrsparam);
4416 break ;
4417 default :
4418 mcc_calcQint_bsim3v3 (ptmodel, L, W,
4419 temp, vgs, vbs, vds,
4420 &Qg, &Qs, &Qd, &Qb,
4421 lotrsparam);
4422 }
4423 Qg*=La_Wa;
4424 Qb*=La_Wa;
4425 Qs*=La_Wa;
4426 Qd*=-La_Wa;
4427
4428 if( !flag ) {
4429 flag = 1 ;
4430 Qg0 = Qg - cgs * La_Wa * v ;
4431 Qd0 = Qd - cgd * La_Wa * v ;
4432 Qde0 = Qd - cgde0 * La_Wa * v ;
4433 }
4434
4435
4436 if( !flaghalf ) {
4437
4438 qgs = cgs * La_Wa * v + Qg0 ;
4439 qgd = cgd * La_Wa * v + Qd0 ;
4440
4441 if( ( vf>vi && v > MCC_VDDmax/2.0 ) || ( vf<vi && v < MCC_VDDmax/2.0 ) ) {
4442
4443 flaghalf = 1 ;
4444 qgs0 = cgs * La_Wa * MCC_VDDmax/2.0 ;
4445 qgd0 = cgd * La_Wa * MCC_VDDmax/2.0 ;
4446 }
4447 }
4448
4449 if( flaghalf ) {
4450 qgs = cgsf * La_Wa * (v-MCC_VDDmax/2.0) + qgs0 + Qg0 ;
4451 qgd = cgdf * La_Wa * (v-MCC_VDDmax/2.0) + qgd0 + Qd0 ;
4452 }
4453
4454 if( flagvt==0 ) {
4455 qgde = cgde0 * La_Wa * v + Qde0 ;
4456 if( ( vf>vi && v > v1 ) || ( vf<vi && v < v1 ) ) {
4457 flagvt = 1 ;
4458 qgde0 = cgde0 * La_Wa * v1 ;
4459 }
4460 }
4461
4462 if( flagvt==1 ) {
4463 qgde = cgde1 * La_Wa * (v-v1) + qgde0 + Qde0 ;
4464 if( ( vf>vi && v > v2 ) || ( vf<vi && v < v2 ) ) {
4465 flagvt = 2 ;
4466 qgde0 = La_Wa * ( cgde0*v1 + cgde1*(v2-v1) ) ;
4467 }
4468 }
4469
4470 if( flagvt==2 ) {
4471 qgde = cgde2 * La_Wa * (v-v2) + qgde0 + Qde0 ;
4472 }
4473
4474 fprintf( file, "%g %g %g %g %g %g\n", v, Qg, qgs, Qd, qgd, qgde );
4475 }
4476
4477 fclose( file );
4478
4479 file = mbkfopen( filename, "plt", "w" );
4480 fprintf( file, "set xlabel 'Vin'\n" );
4481 fprintf( file, "set ylabel 'Q'\n" );
4482 fprintf( file, "plot \\\n" );
4483 fprintf( file, "'%s.dat' using 1:2 title 'Qg int', \\\n", filename );
4484 fprintf( file, "'%s.dat' using 1:3 title 'Q cgs', \\\n", filename );
4485 fprintf( file, "'%s.dat' using 1:4 title 'Qd int', \\\n", filename );
4486 fprintf( file, "'%s.dat' using 1:5 title 'Q cgd', \\\n", filename );
4487 fprintf( file, "'%s.dat' using 1:6 title 'Q cgde'\n", filename );
4488 fprintf( file, "pause -1\n" );
4489 fclose( file );
4490 }
4491
4492 int mcc_get_swjuncap( char *technoname, char *transname, int transtype, int transcase, double L, double W )
4493 {
4494 mcc_modellist *model ;
4495 double swjuncap ;
4496 int i ;
4497
4498 model = mcc_getmodel( technoname, transname, transtype, transcase, L, W, 0 );
4499 swjuncap = mcc_getparam_quick(model, __MCC_QUICK_SWJUNCAP );
4500 i = ((int)( swjuncap+0.5 ));
4501
4502 return i ;
4503 }
4504
4505 void mcc_cleanmodel( mcc_modellist *model )
4506 {
4507 if (model->TYPE == MCC_DIODE) {
4508 }
4509 else
4510 switch ( model->MODELTYPE ) {
4511 case MCC_BSIM3V3 :
4512 case MCC_BSIM4 :
4513 case MCC_MM9 :
4514 case MCC_MOS2 :
4515 break ;
4516 case MCC_MPSPB:
4517 case MCC_MPSP : mcc_clean_psp( model );
4518 break ;
4519 case MCC_EXTMOD : mcc_clean_ext( model );
4520 break ;
4521 }
4522 }
4523
4524 #ifdef MCC_RESI_CODE
4525
4526 double mcc_calcResiCapa ( char *technoname, char *resiname,
4527 int modtype, int modcase,
4528 double L, double W, double R, double SCALE, double C, double CRATIO, double M,
4529 double *c1, double *c2, double *r
4530 )
4531 {
4532 mcc_modellist *ptmodel ;
4533 double Capa = 0.0, SCALM=1, RES, RSH, CAP, THICK, CAPSW ;
4534 double Lscaled, Wscaled, DWeff, DLeff, DW, DL, DI, Weff, Leff, Ceff, SHRINK, COX;
4535 *c1=*c2;
4536 *r=R;
4537
4538 if ( (ptmodel = mcc_getmodel(technoname, resiname, modtype, modcase, 0, 0, 0)) )
4539 {
4540 SHRINK=mcc_getparam_quick(ptmodel, __MCC_QUICK_SHRINK);
4541 if (L<0)
4542 {
4543 L=mcc_getparam_quick(ptmodel, __MCC_QUICK_L);
4544 Lscaled=L*SCALM*SHRINK;
4545 }
4546 else
4547 Lscaled=L*SCALE*SHRINK;
4548 if (W<0)
4549 {
4550 W=mcc_getparam_quick(ptmodel, __MCC_QUICK_W);
4551 Wscaled=W*SCALM*SHRINK;
4552 }
4553 else
4554 Wscaled=W*SCALE*SHRINK;
4555 DL=mcc_getparam_quick(ptmodel, __MCC_QUICK_DL);
4556 DW=mcc_getparam_quick(ptmodel, __MCC_QUICK_DW);
4557 DWeff=DW*SCALM;
4558 DLeff=DL*SCALM;
4559 Leff=Lscaled*SCALE*SHRINK-2*DLeff;
4560 Weff=Wscaled*SCALE*SHRINK-2*DWeff;
4561
4562 if (R>=0)
4563 *r=R*SCALE/M;
4564 else
4565 {
4566 RSH=mcc_getparam_quick(ptmodel, __MCC_QUICK_RSH);
4567 if (Weff*Leff*RSH>0)
4568 *r=Leff*RSH*SCALE/(M*Weff);
4569 else
4570 {
4571 RES=mcc_getparam_quick(ptmodel, __MCC_QUICK_RES);
4572 *r=RES*SCALE/M;
4573 }
4574 }
4575
4576 if (C>=0)
4577 {
4578 Ceff=C*SCALE*M;
4579 }
4580 else
4581 {
4582 THICK=mcc_getparam_quick(ptmodel, __MCC_QUICK_THICK);
4583 COX=mcc_getparam_quick(ptmodel, __MCC_QUICK_COX);
4584 if (!COX && THICK==0)
4585 {
4586 if (mcc_getparamtype_quick(ptmodel, __MCC_QUICK_CAP) == MCC_SETVALUE)
4587 {
4588 CAP=mcc_getparam_quick(ptmodel, __MCC_QUICK_CAP);
4589 Ceff=CAP*SCALE*M;
4590 }
4591 else
4592 Ceff=0; //error
4593 }
4594 else if (!COX && THICK!=0)
4595 {
4596 if (THICK!=0)
4597 {
4598 if (mcc_getparamtype_quick(ptmodel, __MCC_QUICK_DI) == MCC_SETVALUE)
4599 {
4600 DI=mcc_getparam_quick(ptmodel, __MCC_QUICK_DI);
4601 COX=DI*MCC_EPSO/THICK;
4602 }
4603 else
4604 COX=MCC_EPSOX/THICK;
4605 }
4606 }
4607 CAPSW=mcc_getparam_quick(ptmodel, __MCC_QUICK_CAPSW);
4608 Ceff=M*SCALE*(Leff*Weff*COX)+2*(Leff+Weff)*CAPSW;
4609 }
4610 if (CRATIO<0) CRATIO=0.5;
4611 *c1=Ceff*CRATIO;
4612 *c2=Ceff*(1-CRATIO);
4613 }
4614 }
4615
4616 #endif
4617
4618 double mcc_calcResiSimple ( double R, double TC1, double TC2, double DTEMP)
4619 {
4620 double DELTAT;
4621 DELTAT=V_FLOAT_TAB[__SIM_TEMP].VALUE+DTEMP-V_FLOAT_TAB[__SIM_TNOM].VALUE;
4622 return R*( 1 + TC1*DELTAT + TC2*DELTAT*DELTAT );
4623 }
4624