1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : MCC Version 1 */
6 /* Fichier : mcc_genelp.c */
8 /* (c) copyright 1991-1998 Laboratoire LIP6 equipe ASIM */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
12 /* Auteur(s) : Karim DIOURY */
14 /****************************************************************************/
17 #include "mcc_mod_util.h"
19 #include "mcc_genspi.h"
20 #include "mcc_debug.h"
23 static int param_used
=0;
24 static float ncurrent_vt
=-1000, pcurrent_vt
=-1000;
28 float l
, w
, as
, ad
, ps
, pd
;
33 param
[0].l
=param
[0].w
=param
[0].as
=param
[0].ad
=param
[0].ps
=param
[0].pd
=0;
34 param
[1].l
=param
[1].w
=param
[1].as
=param
[1].ad
=param
[1].ps
=param
[1].pd
=0;
38 char *mcc_getline (str
)
43 sprintf (prompt
, "%s : ", str
);
48 fprintf (stdout
, "\n");
49 MCC_BUF
= readline (prompt
);
50 if ((MCC_BUF
!= NULL
) && (strcmp (MCC_BUF
, "") != 0))
51 add_history (strdup (MCC_BUF
));
58 int mcc_gettab (str
, tab
, size
, old
)
69 sprintf (strx
, "%s [", str
);
70 pt
= strx
+ strlen (strx
);
72 for (i
= 0; i
< size
- 1; i
++) {
73 sprintf (pt
, "%s ", tab
[i
]);
74 pt
= pt
+ strlen (pt
);
77 sprintf (pt
, "%s] [%s]", tab
[i
], tab
[old
]);
80 pt
= mcc_getline (strx
);
86 for (i
= 0; i
< size
; i
++) {
87 if (strcasecmp (tab
[i
], pt
) == 0)
91 fprintf (stderr
, "\nmcc error : bad string\n");
98 int mcc_getint (str
, min
, max
, old
)
109 sprintf (strx
, "%s [%d:%d] [%d]", str
, min
, max
, old
);
112 pt
= mcc_getline (strx
);
118 res
= sscanf (pt
, "%d", ¶m
);
121 if ((param
< min
) || (param
> max
) || (res
!= 1)) {
122 fprintf (stderr
, "\nmcc error : bad number\n");
130 double mcc_getdouble (str
, min
, max
, old
)
142 sprintf (strx
, "%s [%g:%g] [%g]", str
, min
, max
, old
);
145 pt
= mcc_getline (strx
);
151 res
= sscanf (pt
, "%f", ¶m
);
153 paramx
= (double)param
;
155 if ((paramx
< min
) || (paramx
> max
) || (res
!= 1)) {
156 fprintf (stderr
, "\nmcc error : bad number\n");
164 char *mcc_getstr (str
, old
)
169 int len
= (1024 - 1);
174 sprintf (strx
, "%s [%s]", str
, old
);
177 sprintf (strx
, "%s", str
);
183 pt
= mcc_getline (strx
);
185 if ((pt
== NULL
) && (old
!= NULL
)) {
188 else if (pt
== NULL
) {
189 fprintf (stderr
, "\nmcc error : bad string\n");
196 *(word
+ (len
)) = '\0';
198 pt
= strchr (word
, (int)('\n'));
204 pt
= (char *)mbkalloc (strlen (word
) + 1);
210 char *mcc_getword (str
, old
)
216 unsigned int len
= (1024 - 1);
221 sprintf (strx
, "%s [%s]", str
, old
);
224 sprintf (strx
, "%s", str
);
228 pt
= mcc_getline (strx
);
230 if ((pt
== NULL
) && (old
!= NULL
)) {
233 else if (pt
== NULL
) {
234 fprintf (stderr
, "\nmcc error : bad string\n");
238 if (strlen (pt
) > len
) {
239 fprintf (stderr
, "\nmcc error : string too long\n");
243 res
= sscanf (pt
, "%s", word
);
246 fprintf (stderr
, "\nmcc error : bad string\n");
251 *(word
+ (len
)) = '\0';
252 pt
= strchr (word
, (int)('\n'));
257 pt
= (char *)mbkalloc (strlen (word
) + 1);
265 int mcc_genelp (int spice
, int vt
, double tec
, int aut
, int fit
, mcc_modellist
**modeln
, mcc_modellist
**modelp
,elp_lotrs_param
*lotrsparam_n
,elp_lotrs_param
*lotrsparam_p
)
278 int setwn
=0, setwp
=0;
279 mcc_corner_info infon
, infop
;
282 if ((MCC_MODE
!= MCC_FAST_MODE
) && (MCC_MODE
!= MCC_NEXT_MODE
)) {
283 mcc_prsparam (lotrsparam_n
,lotrsparam_p
);
286 MCC_TECHFILE
= mcc_getword ("Transistor model file name", MCC_TECHFILE
);
287 if (pt
!= MCC_TECHFILE
) {
288 if (MCC_MODELFILE
!= NULL
)
289 mbkfree (MCC_MODELFILE
);
290 MCC_MODELFILE
= mcc_initstr (MCC_TECHFILE
);
292 MCC_MODELFILE
= mcc_getword ("model file name", MCC_MODELFILE
);
293 if (mcc_gettechnofile (MCC_MODELFILE
) != NULL
)
297 MCC_ELPFILE
= mcc_getword ("elp file name", MCC_ELPFILE
);
298 MCC_ELPVERSION
= mcc_getword ("elp version", MCC_ELPVERSION
);
299 MCC_TEMP
= mcc_getdouble ("Electrical simulation temperature (in degree)", -273.15, 1000, MCC_TEMP
);
302 MCC_SPICEMODELTYPE
= mcc_getmodeltype (MCC_MODELFILE
);
304 if (MCC_SPICEMODELTYPE
== MCC_NOMODEL
)
305 MCC_SPICEMODELTYPE
= MCC_MOS2
;
307 if ((MCC_MODE
!= MCC_FAST_MODE
) && (MCC_MODE
!= MCC_NEXT_MODE
)) {
309 MCC_TNMODEL
= mcc_getword ("N Transistor model name", MCC_TNMODEL
);
312 MCC_TPMODEL
= mcc_getword ("P Transistor model name", MCC_TPMODEL
);
314 b3
= ( MCC_SPICEMODELTYPE
== MCC_BSIM3V3
? 1 : 0 ) ;
315 b4
= ( MCC_SPICEMODELTYPE
== MCC_BSIM4
? 1 : 0 ) ;
317 MCC_SPICEMODELTYPE
= mcc_gettab ("Model type", MCC_MOD_NAME
, MCC_VALID_MOD
, MCC_SPICEMODELTYPE
);
319 MCC_SPICESTRING
= mcc_getstr ("Spice string", MCC_SPICESTRING
);
320 MCC_SPICENAME
= mcc_getfisrtarg (MCC_SPICESTRING
, MCC_SPICENAME
);
321 MCC_SPICENAME
= mcc_getword ("Spice tool name", MCC_SPICENAME
);
322 MCC_SPICESTDOUT
= mcc_getword ("Spice standard out file", MCC_SPICESTDOUT
);
323 MCC_SPICEOUT
= mcc_getword ("Spice out file", MCC_SPICEOUT
);
324 MCC_TASNAME
= mcc_getword ("Tas tool name", MCC_TASNAME
);
326 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
330 *modeln
= mcc_getnextmodel (MCC_MODELFILE
, MCC_TNMODEL
, MCC_NMOS
, MCC_NCASE
, *modeln
);
332 *modelp
= mcc_getnextmodel (MCC_MODELFILE
, MCC_TPMODEL
, MCC_PMOS
, MCC_PCASE
, *modelp
);
334 if ((*modeln
== NULL
) && (*modelp
== NULL
))
337 if (*modeln
!= NULL
) {
338 nlmax
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modeln
, __MCC_QUICK_LMAX
) * 1e06
);
339 nlmin
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modeln
, __MCC_QUICK_LMIN
) * 1e06
);
340 nwmax
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modeln
, __MCC_QUICK_WMAX
) * 1e06
);
341 nwmin
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modeln
, __MCC_QUICK_WMIN
) * 1e06
);
344 if (*modelp
!= NULL
) {
345 plmax
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modelp
, __MCC_QUICK_LMAX
) * 1e06
);
346 plmin
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modelp
, __MCC_QUICK_LMIN
) * 1e06
);
347 pwmax
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modelp
, __MCC_QUICK_WMAX
) * 1e06
);
348 pwmin
= mcc_ftol (SCALE_X
* mcc_getparam_quick(*modelp
, __MCC_QUICK_WMIN
) * 1e06
);
351 if (*modeln
== NULL
) {
358 if (*modelp
== NULL
) {
366 nlmin
= nlmax
/ (long)2;
368 plmin
= plmax
/ (long)2;
370 if ((nwmax
> ((long)1000 * nwmin
)) || (nwmax
== 0))
371 nwmax
= nwmin
* (long)10;
373 if ((pwmax
> ((long)1000 * pwmin
)) || (pwmax
== 0))
374 pwmax
= pwmin
* (long)10;
376 MCC_LN
= (double)nlmin
/ SCALE_X
;
377 MCC_LP
= (double)plmin
/ SCALE_X
;
378 MCC_WN
= ((double)nwmin
+ (double)nwmax
) / (2.0 * SCALE_X
);
379 MCC_WP
= 2.0 * MCC_WN
;
383 if (param
[0].l
!=0) MCC_LN
=param
[0].l
* 1e06
;
384 if (param
[1].l
!=0) MCC_LP
=param
[1].l
* 1e06
;
385 if (param
[0].w
!=0) MCC_WN
=param
[0].w
* 1e06
, setwn
=1;
386 if (param
[1].w
!=0) MCC_WP
=param
[1].w
* 1e06
, setwp
=1;
389 if (!setwn
&& !setwp
)
391 while ((pwmin
> (long)(MCC_WP
* SCALE_X
)) || (pwmax
<= (long)(MCC_WP
* SCALE_X
))) {
392 if (pwmin
> (long)(MCC_WP
* SCALE_X
))
393 MCC_WN
= MCC_WN
* 11.0 / 10.0;
395 MCC_WN
= MCC_WN
* 9.0 / 10.0;
397 if (nwmin
> (long)(MCC_WN
* SCALE_X
)) {
398 MCC_WN
= (double)nwmin
/ (double)SCALE_X
;
399 MCC_WP
= (double)pwmax
/ (double)SCALE_X
*0.95;
403 if (nwmax
<= (long)(MCC_WN
* SCALE_X
)) {
404 MCC_WN
= (double)nwmax
/ (double)SCALE_X
*0.95;
405 MCC_WP
= (double)pwmin
/ (double)SCALE_X
;
410 MCC_WP
= 2.0 * MCC_WN
;
414 MCC_DIF
= MCC_LN
* 2.0;
427 if (MCC_DIF
< 0.0001)
433 *modeln
= mcc_getmodel (MCC_MODELFILE
, MCC_TNMODEL
, MCC_NMOS
,
434 MCC_NCASE
, MCC_LN
* 1.0e-06, MCC_WN
* 1.0e-06,0);
439 *modelp
= mcc_getmodel (MCC_MODELFILE
, MCC_TPMODEL
, MCC_PMOS
,
440 MCC_PCASE
, MCC_LP
* 1.0e-06, MCC_WP
* 1.0e-06,0);
443 if (*modeln
==NULL
|| *modelp
==NULL
) return res
;
445 fprintf (stdout
, "Transistor size for automatic model calculation:\n");
446 fprintf (stdout
, "%s : LN=%g WN=%g %s : LP=%g WP=%g\n", (*modeln
)->NAME
,
447 MCC_LN
, MCC_WN
, (*modelp
)->NAME
, MCC_LP
, MCC_WP
);
449 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
455 *modeln
= mcc_getmodel (MCC_MODELFILE
, MCC_TNMODEL
, MCC_NMOS
,
456 MCC_NCASE
, MCC_LN
* 1.0e-06, MCC_WN
* 1.0e-06,0);
461 *modelp
= mcc_getmodel (MCC_MODELFILE
, MCC_TPMODEL
, MCC_PMOS
,
462 MCC_PCASE
, MCC_LP
* 1.0e-06, MCC_WP
* 1.0e-06,0);
465 if (*modeln
==NULL
|| *modelp
==NULL
) return res
;
466 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
469 lotrsparam_n
->SUBCKTNAME
=MCC_TN_SUBCKT
;
470 lotrsparam_p
->SUBCKTNAME
=MCC_TP_SUBCKT
;
471 memcpy(&mcc_user_lotrsparam_n
, lotrsparam_n
, sizeof(mcc_user_lotrsparam_n
));
472 memcpy(&mcc_user_lotrsparam_p
, lotrsparam_p
, sizeof(mcc_user_lotrsparam_p
));
473 mcc_check_techno_with_subckt(lotrsparam_n
,lotrsparam_p
, MCC_TN_SUBCKT
, MCC_TP_SUBCKT
);
475 if(MCC_OPTIM_MODE
== 1){
476 MCC_DEBUG_INTERNAL
= YES
;
477 mcc_spicecurrent( MCC_VDDmax
, MCC_VDDmax
, lotrsparam_n
->VBULK
, MCC_TRANS_N
, lotrsparam_n
);
478 mcc_spicecurrent( MCC_VDDmax
, MCC_VDDmax
, lotrsparam_p
->VBULK
-MCC_VDDmax
, MCC_TRANS_P
, lotrsparam_p
);
479 MCC_DEBUG_INTERNAL
= NO
;
482 if (MCC_MODE
!= MCC_FAST_MODE
) {
483 mcc_prsparam (lotrsparam_n
,lotrsparam_p
);
485 tec
= mcc_getdouble ("Technology size (in micro-meter)", 0.0, 100.0, (tec
< 0.0) ? 0.0 : tec
);
496 MCC_LN
= mcc_getdouble ("N MOS tansistor length size (in micro-meter)", 0.0, 100.00, MCC_LN
);
497 MCC_WN
= mcc_getdouble ("N MOS tansistor width size (in micro-meter)", 0.0, 1000.0, MCC_WN
);
498 MCC_LP
= mcc_getdouble ("P MOS tansistor length size (in micro-meter)", 0.0, 100.0, MCC_LP
);
499 MCC_WP
= mcc_getdouble ("P MOS tansistor width size (in micro-meter)", 0.0, 1000.0, MCC_WP
);
500 MCC_VDDmax
= mcc_getdouble ("Power supply (in Volt)", 0.1, 10.0, MCC_VDDmax
);
501 MCC_VGS
= MCC_VDDmax
/ 2.0 ;
502 if ( lotrsparam_n
->VBULK
< ELPMINVBULK
)
503 lotrsparam_n
->VBULK
= 0.0;
504 if ( lotrsparam_p
->VBULK
< ELPMINVBULK
)
505 lotrsparam_p
->VBULK
= MCC_VDDmax
;
508 lotrsparam_n
->PARAM
[elpDELVT0
] = mcc_getdouble ("N MOS transistor threshold voltage shrink (DELVT0)", -MCC_VTN
/2.0, MCC_VTN
/2.0, lotrsparam_n
->PARAM
[elpDELVT0
]);
509 lotrsparam_n
->PARAM
[elpMULU0
] = mcc_getdouble ("N MOS transistor mobility mult factor (U0)", 0.5, 1.5, lotrsparam_n
->PARAM
[elpMULU0
]);
511 lotrsparam_n
->VBULK
= mcc_getdouble ("N MOS transistor bulk voltage (in Volt)", -MCC_VDDmax
, MCC_VDDmax
, lotrsparam_n
->VBULK
);
512 MCC_VBULKN
= lotrsparam_n
->VBULK
;
515 lotrsparam_p
->PARAM
[elpDELVT0
] = mcc_getdouble ("P MOS transistor threshold voltage shrink (DELVT0)", -MCC_VTP
/2.0, MCC_VTP
/2.0, lotrsparam_p
->PARAM
[elpDELVT0
]);
516 lotrsparam_p
->PARAM
[elpMULU0
] = mcc_getdouble ("P MOS transistor mobility mult factor (U0)", 0.5, 1.5, lotrsparam_p
->PARAM
[elpMULU0
]);
518 lotrsparam_p
->VBULK
= mcc_getdouble ("P MOS transistor bulk voltage (in Volt)", -MCC_VDDmax
, 2.0*MCC_VDDmax
, lotrsparam_p
->VBULK
);
519 MCC_VBULKP
= lotrsparam_p
->VBULK
;
520 MCC_DIF
= mcc_getdouble ("Transistor diffusion width (in micro-meter)", 0.1, 100.0, MCC_DIF
);
522 if (MCC_MODE
== MCC_EXPERT_MODE
) {
523 MCC_DC_STEP
= mcc_getdouble ("Electrical simulation dc step", 0.00001, 0.100, MCC_DC_STEP
);
524 MCC_INSNUMB
= mcc_getint ("Number of instances to fit parametres", 10, 100, MCC_INSNUMB
);
525 MCC_CAPA
= mcc_getdouble ("Capacitance to fit curent parameters (in fF)", 10, 10000, MCC_CAPA
);
526 MCC_INVNUMB
= mcc_getint ("Number of inverters to fit gate capacitance", 1, 100, MCC_INVNUMB
);
527 MCC_TRANSNUMB
= mcc_getint ("Number of transistors to fit diffusion capacitance", 1, 100, MCC_TRANSNUMB
);
530 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
536 if (param
[0].l
!=0) MCC_LN
=param
[0].l
* 1e06
;
537 if (param
[1].l
!=0) MCC_LP
=param
[1].l
* 1e06
;
538 if (param
[0].w
!=0) MCC_WN
=param
[0].w
* 1e06
;
539 if (param
[1].w
!=0) MCC_WP
=param
[1].w
* 1e06
;
543 double kasn
=MCC_WN
*MCC_DIF
, kadn
=MCC_WN
*MCC_DIF
, kpsn
=(2*MCC_DIF
)+(2*MCC_WN
), kpdn
=(2*MCC_DIF
)+(2*MCC_WN
);
544 double kasp
=MCC_WP
*MCC_DIF
, kadp
=MCC_WP
*MCC_DIF
, kpsp
=(2*MCC_DIF
)+(2*MCC_WP
), kpdp
=(2*MCC_DIF
)+(2*MCC_WP
);
547 if (param
[0].as
!=0) kasn
=param
[0].as
* 1e12
/SCALE_X
;
548 if (param
[0].ad
!=0) kadn
=param
[0].ad
* 1e12
/SCALE_X
;
549 if (param
[0].ps
!=0) kpsn
=param
[0].ps
* 1e06
/SCALE_X
;
550 if (param
[0].pd
!=0) kpdn
=param
[0].pd
* 1e06
/SCALE_X
;
551 if (param
[1].as
!=0) kasp
=param
[1].as
* 1e12
/SCALE_X
;
552 if (param
[1].ad
!=0) kadp
=param
[1].ad
* 1e12
/SCALE_X
;
553 if (param
[1].ps
!=0) kpsp
=param
[1].ps
* 1e06
/SCALE_X
;
554 if (param
[1].pd
!=0) kpdp
=param
[1].pd
* 1e06
/SCALE_X
;
556 sprintf(surf_string_n
, "as=%gp ad=%gp ps=%gu pd=%gu", kasn
, kadn
, kpsn
, kpdn
);
557 sprintf(surf_string_p
, "as=%gp ad=%gp ps=%gu pd=%gu", kasp
, kadp
, kpsp
, kpdp
);
560 lotrsparam_n
= mcc_lotrsparam_set ( lotrsparam_n
,
561 lotrsparam_n
->PARAM
[elpDELVT0
],
562 lotrsparam_n
->PARAM
[elpMULU0
],
563 lotrsparam_n
->PARAM
[elpSA
],
564 lotrsparam_n
->PARAM
[elpSB
],
565 lotrsparam_n
->PARAM
[elpSD
],
566 lotrsparam_n
->PARAM
[elpNF
],
567 lotrsparam_n
->PARAM
[elpM
],
568 lotrsparam_n
->PARAM
[elpNRS
],
569 lotrsparam_n
->PARAM
[elpNRD
],
570 lotrsparam_n
->PARAM
[elpSC
],
571 lotrsparam_n
->PARAM
[elpSCA
],
572 lotrsparam_n
->PARAM
[elpSCB
],
573 lotrsparam_n
->PARAM
[elpSCC
],
574 lotrsparam_n
->VBULK
);
576 lotrsparam_p
= mcc_lotrsparam_set ( lotrsparam_p
,
577 lotrsparam_p
->PARAM
[elpDELVT0
],
578 lotrsparam_p
->PARAM
[elpMULU0
],
579 lotrsparam_p
->PARAM
[elpSA
],
580 lotrsparam_p
->PARAM
[elpSB
],
581 lotrsparam_p
->PARAM
[elpSD
],
582 lotrsparam_p
->PARAM
[elpNF
],
583 lotrsparam_p
->PARAM
[elpM
],
584 lotrsparam_p
->PARAM
[elpNRS
],
585 lotrsparam_p
->PARAM
[elpNRD
],
586 lotrsparam_p
->PARAM
[elpSC
],
587 lotrsparam_p
->PARAM
[elpSCA
],
588 lotrsparam_p
->PARAM
[elpSCB
],
589 lotrsparam_p
->PARAM
[elpSCC
],
590 lotrsparam_p
->VBULK
);
592 lotrsparam_n
->SUBCKTNAME
=MCC_TN_SUBCKT
;
593 lotrsparam_p
->SUBCKTNAME
=MCC_TP_SUBCKT
;
595 if (MCC_VBULKP
<= ELPMINVBULK
) MCC_VBULKP
=lotrsparam_p
->VBULK
;
596 if (MCC_VBULKN
<= ELPMINVBULK
) MCC_VBULKN
=lotrsparam_n
->VBULK
;
597 if (MCC_VBULKP
<= ELPMINVBULK
) MCC_VBULKP
=MCC_VDDmax
;
598 if (MCC_VBULKN
<= ELPMINVBULK
) MCC_VBULKN
=0;
600 mcc_calcspiparam (MCC_TRANS_B
,lotrsparam_n
,lotrsparam_p
);
602 mcc_genspi (fit
,lotrsparam_n
,lotrsparam_p
);
607 if ( avt_islog(2,LOGMCC
) )
609 mcc_DisplayInfos (MCC_MODELFILE
, MCC_TNMODEL
,
610 MCC_NMOS
, MCC_NCASE
, MCC_LN
*1.0e-6, MCC_WN
*1.0e-6,
611 MCC_TEMP
, MCC_VDDmax
/2.0, 0.0, MCC_VDDmax
/2.0,
612 MCC_VDDmax
,lotrsparam_n
);
613 mcc_DisplayInfos (MCC_MODELFILE
, MCC_TPMODEL
,
614 MCC_PMOS
, MCC_PCASE
, MCC_LP
*1.0e-6, MCC_WP
*1.0e-6,
615 MCC_TEMP
, MCC_VDDmax
/2.0, 0.0, MCC_VDDmax
/2.0,
616 MCC_VDDmax
,lotrsparam_p
);
620 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
622 if ( V_BOOL_TAB
[__SIM_USE_PRINT
].VALUE
)
623 mcc_readspidata (fit
,lotrsparam_n
,lotrsparam_p
);
624 if ( V_BOOL_TAB
[__SIM_USE_MEAS
].VALUE
)
625 mcc_optim_readspidata (fit
,lotrsparam_n
,lotrsparam_p
);
627 if (MCC_MODE
!= MCC_FAST_MODE
) {
628 mcc_prsparam (lotrsparam_n
,lotrsparam_p
);
630 MCC_TNMODELTYPE
= mcc_getword ("N Transistor model type name", MCC_TNMODELTYPE
);
632 MCC_NCASE
= mcc_gettab ("N transistor corner", MCC_CASE_NAME
, MCC_NB_CASE
, MCC_NCASE
);
634 MCC_TPMODELTYPE
= mcc_getword ("P Transistor model type name", MCC_TPMODELTYPE
);
636 MCC_PCASE
= mcc_gettab ("P transistor corner", MCC_CASE_NAME
, MCC_NB_CASE
, MCC_PCASE
);
638 if (MCC_SPICEMODELTYPE
== MCC_OTHER
)
639 MCC_SPICEMODELTYPE
= MCC_NOMODELTYPE
;
641 MCC_LNMIN
= mcc_getdouble ("N Transistor minimum length", 0.0, 1.0e99
, MCC_LNMIN
);
643 MCC_LNMAX
= mcc_getdouble ("N Transistor maximun length", 0.0, 1.0e99
, MCC_LNMAX
);
645 MCC_WNMIN
= mcc_getdouble ("N Transistor minimum width", 0.0, 1.0e99
, MCC_WNMIN
);
647 MCC_WNMAX
= mcc_getdouble ("N Transistor maximun width", 0.0, 1.0e99
, MCC_WNMAX
);
649 MCC_LPMIN
= mcc_getdouble ("P Transistor minimum length", 0.0, 1.0e99
, MCC_LPMIN
);
651 MCC_LPMAX
= mcc_getdouble ("P Transistor maximun length", 0.0, 1.0e99
, MCC_LPMAX
);
653 MCC_WPMIN
= mcc_getdouble ("P Transistor minimum width", 0.0, 1.0e99
, MCC_WPMIN
);
655 MCC_WPMAX
= mcc_getdouble ("P Transistor maximun width", 0.0, 1.0e99
, MCC_WPMAX
);
657 if (MCC_MODE
== MCC_EXPERT_MODE
) {
658 MCC_XWN
= mcc_getdouble ("N Transistor width scale", 0.1, 1.0, MCC_XWN
);
659 MCC_XLN
= mcc_getdouble ("N Transistor length scale", 0.1, 1.0, MCC_XLN
);
660 MCC_XWP
= mcc_getdouble ("P Transistor width scale", 0.1, 1.0, MCC_XWP
);
661 MCC_XLP
= mcc_getdouble ("P Transistor length scale", 0.1, 1.0, MCC_XLP
);
664 MCC_DWN
= mcc_getdouble ("N transistor width shrink parameter (in micro-meter)", -100.0, 100.0, MCC_DWN
);
665 MCC_DWCJN
= mcc_getdouble ("N transistor effective width shrink parameter for capacitance (in micro-meter)",
666 -100.0, 100.0, MCC_DWCJN
);
667 MCC_DLN
= mcc_getdouble ("N transistor length shrink parameter (in micro-meter)", -100.0, 100.0, MCC_DLN
);
668 MCC_DWP
= mcc_getdouble ("P transistor width shrink parameter (in micro-meter)", -100.0, 100.0, MCC_DWP
);
669 MCC_DWCJP
= mcc_getdouble ("P transistor effective width shrink parameter for capacitance (in micro-meter)",
670 -100.0, 100.0, MCC_DWCJP
);
671 MCC_DLP
= mcc_getdouble ("P transistor length shrink parameter (in micro-meter)", -100.0, 100.0, MCC_DLP
);
673 MCC_DWCN
= mcc_getdouble ("N transistor active width shrink parameter (in micro-meter)",
674 -100.0, 100.0, MCC_DWCN
);
675 MCC_DLCN
= mcc_getdouble ("N transistor active length shrink parameter (in micro-meter)",
676 -100.0, 100.0, MCC_DLCN
);
677 MCC_DWCP
= mcc_getdouble ("P transistor active width shrink parameter (in micro-meter)",
678 -100.0, 100.0, MCC_DWCP
);
679 MCC_DLCP
= mcc_getdouble ("P transistor active length shrink parameter (in micro-meter)",
680 -100.0, 100.0, MCC_DLCP
);
681 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
685 mcc_trs_corner( MCC_TRANS_N
, lotrsparam_n
, lotrsparam_p
, &infon
);
686 mcc_trs_corner( MCC_TRANS_P
, lotrsparam_n
, lotrsparam_p
, &infop
);
687 if( V_BOOL_TAB
[ __MCC_NEW_IDS_SAT
].VALUE
) {
688 mcc_calcul_sat_parameter( MCC_TRANS_N
, lotrsparam_n
, &infon
);
689 mcc_calcul_sat_parameter( MCC_TRANS_P
, lotrsparam_p
, &infop
);
692 mcc_calcul_vt (MCC_TRANS_N
,lotrsparam_n
,lotrsparam_p
,&infon
);
693 mcc_calcul_vt (MCC_TRANS_P
,lotrsparam_n
,lotrsparam_p
,&infop
);
697 if (MCC_MODE
!= MCC_FAST_MODE
) {
698 MCC_VTN
= mcc_getdouble ("N transistor threshold voltage (in volt)", 0.0, MCC_VDDmax
, MCC_VTN
);
699 MCC_VTP
= mcc_getdouble ("P transistor threshold voltage (in volt)", 0.0, MCC_VDDmax
, MCC_VTP
);
704 if( !V_BOOL_TAB
[ __MCC_NEW_IDS_SAT
].VALUE
) {
705 if ( MCC_NEW_CALC_ABR
&& MCC_OPTIM_MODE
)
707 mcc_get_best_abr_from_vt ( MCC_TRANS_N
, lotrsparam_n
,lotrsparam_p
,&infon
);
708 mcc_get_best_abr_from_vt ( MCC_TRANS_P
, lotrsparam_n
,lotrsparam_p
,&infop
);
711 mcc_calcul_abr (MCC_TRANS_N
,-1.0,-1.0,lotrsparam_n
,lotrsparam_p
);
712 mcc_calcul_abr (MCC_TRANS_P
,-1.0,-1.0,lotrsparam_n
,lotrsparam_p
);
717 if( V_BOOL_TAB
[__AVT_RST_BETTER
].VALUE
) {
718 mcc_calcul_rst_better(MCC_TRANS_N
,lotrsparam_n
,lotrsparam_p
, &infon
);
719 mcc_calcul_rst_better(MCC_TRANS_P
,lotrsparam_n
,lotrsparam_p
, &infop
);
722 mcc_calcul_rst(MCC_TRANS_N
,lotrsparam_n
,lotrsparam_p
);
723 mcc_calcul_rst(MCC_TRANS_P
,lotrsparam_n
,lotrsparam_p
);
725 mcc_calcul_k (MCC_TRANS_N
,lotrsparam_n
);
726 mcc_calcul_k (MCC_TRANS_P
,lotrsparam_p
);
727 mcc_calcul_vdeg (MCC_TRANS_B
,lotrsparam_n
,lotrsparam_p
);
728 mcc_calcul_vti (MCC_TRANS_B
,lotrsparam_n
,lotrsparam_p
);
730 if(MCC_DEBUG_MODE
> 0)
732 if(MCC_DEBUG_LEAK
== 'Y')
733 mcc_calcul_leak (lotrsparam_n
,lotrsparam_p
) ;
734 if(MCC_DEBUG_RSAT
== 'Y')
736 mcc_fill_current_for_rsat(lotrsparam_n
,lotrsparam_p
);
737 mcc_calcul_rsat(lotrsparam_n
,lotrsparam_p
) ;
739 if(MCC_DEBUG_RLIN
== 'Y')
741 mcc_calcul_rlin(lotrsparam_n
,lotrsparam_p
) ;
743 if((MCC_DEBUG_RSAT
== 'Y') && (MCC_DEBUG_RLIN
== 'Y'))
744 mcc_calcul_vsat(lotrsparam_n
,lotrsparam_p
) ;
745 if(MCC_DEBUG_VTH
== 'Y')
746 mcc_calcul_vth(lotrsparam_n
,lotrsparam_p
) ;
747 if(MCC_DEBUG_QINT
== 'Y') {
748 mcc_calcul_qint (lotrsparam_n
,lotrsparam_p
, 'G' ) ;
749 mcc_calcul_qint (lotrsparam_n
,lotrsparam_p
, 'D' ) ;
750 mcc_check_capa( lotrsparam_n
, lotrsparam_p
) ;
752 if(MCC_DEBUG_JCT_CAPA
== 'Y')
754 mcc_calc_jct_capa (lotrsparam_n
,lotrsparam_p
) ;
756 if(MCC_DEBUG_INPUTCAPA
== 'Y')
758 mcc_bilan_capa(lotrsparam_n
,lotrsparam_p
);
759 mcc_calc_coupling_capa(lotrsparam_n
,lotrsparam_p
);
761 if(MCC_DEBUG_CARAC
== 'Y') {
762 mcc_calcul_trans(lotrsparam_n
,lotrsparam_p
) ;
763 mcc_calcul_rapisat_fqmulu0 (lotrsparam_n
,lotrsparam_p
);
765 if(MCC_DEBUG_CARACNEG
== 'Y')
766 mcc_calcul_transneg(lotrsparam_n
,lotrsparam_p
) ;
767 if(MCC_DEBUG_DEG
== 'Y')
768 mcc_calcul_deg(lotrsparam_n
,lotrsparam_p
) ;
771 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
773 if (vt
==0 && MCC_CALC_CUR
== MCC_SIM_MODE
) {
774 ncurrent_vt
= mcc_spicesimcurrent(MCC_VTN
,MCC_VDDmax
,0.0,MCC_TRANS_N
) ;
775 pcurrent_vt
= mcc_spicesimcurrent(MCC_VTP
,MCC_VDDmax
,0.0,MCC_TRANS_P
) ;
777 mcc_freespidata (fit
, MCC_TRANS_B
);
779 if (MCC_MODE
!= MCC_FAST_MODE
) {
780 mcc_prsparam (lotrsparam_n
,lotrsparam_p
);
782 MCC_CGSN
= mcc_getdouble ("N tansistor gate capacitance (in pF/u2)", 0.0, 1.0, MCC_CGSN
);
783 MCC_CGSP
= mcc_getdouble ("P tansistor gate capacitance (in pF/u2)", 0.0, 1.0, MCC_CGSP
);
784 MCC_CGDN
= mcc_getdouble ("N tansistor gate/drain capacitance (in pF/u2)", 0.0, 1.0, MCC_CGDN
);
785 MCC_CGDCN
= mcc_getdouble ("N tansistor gate/drain conflict capacitance (in pF/u2)", 0.0, 1.0, MCC_CGDCN
);
786 MCC_CGDP
= mcc_getdouble ("P tansistor gate/drain capacitance (in pF/u2)", 0.0, 1.0, MCC_CGDP
);
787 MCC_CGDCP
= mcc_getdouble ("P tansistor gate/drain conflict capacitance (in pF/u2)", 0.0, 1.0, MCC_CGDCP
);
788 MCC_CGPN
= mcc_getdouble ("N tansistor gate diffusion capacitance (in pF/u)", 0.0, 1.0, MCC_CGPN
);
789 MCC_CGPP
= mcc_getdouble ("P tansistor gate diffusion capacitance (in pF/u)", 0.0, 1.0, MCC_CGPP
);
790 MCC_CDSN
= MCC_CSSN
= mcc_getdouble ("Area N transistor diffusion capacitance (in pF/u2)", 0.0, 1.0, MCC_CDSN
);
791 MCC_CDS_U_N
= MCC_CDS_D_N
= MCC_CDSN
;
792 MCC_CDSP
= MCC_CSSP
= mcc_getdouble ("Area P transistor diffusion capacitance (in pF/u2)", 0.0, 1.0, MCC_CDSP
);
793 MCC_CDS_U_P
= MCC_CDS_D_P
= MCC_CDSP
;
794 MCC_CDPN
= MCC_CSPN
= mcc_getdouble ("Perimeter N transistor diffusion capacitance (in pF/u)",
796 MCC_CDP_U_N
= MCC_CDP_D_N
= MCC_CDPN
;
797 MCC_CDPP
= MCC_CSPP
= mcc_getdouble ("Perimeter P transistor diffusion capacitance (in pF/u)",
799 MCC_CDP_U_P
= MCC_CDP_D_P
= MCC_CDPP
;
800 MCC_CDWN
= MCC_CSWN
= mcc_getdouble ("Width N transistor diffusion capacitance (in pF/u)", 0.0, 1.0, MCC_CDWN
);
801 MCC_CDW_U_N
= MCC_CDW_D_N
= MCC_CDWN
;
802 MCC_CDWP
= MCC_CSWP
= mcc_getdouble ("Width P transistor diffusion capacitance (in pF/u)", 0.0, 1.0, MCC_CDWP
);
803 MCC_CDW_U_P
= MCC_CDW_D_P
= MCC_CDWP
;
805 if (MCC_MODE
== MCC_EXPERT_MODE
) {
806 MCC_ERROR
= mcc_getdouble ("Max error to fit parameters (in %)", 0.1, 100.0, MCC_ERROR
);
807 MCC_NBMAXLOOP
= mcc_getint ("Maximun number of loop to fit parameters", 1, 100, MCC_NBMAXLOOP
);
810 mcc_drvparam (lotrsparam_n
,lotrsparam_p
);
811 pt
= mcc_initstr ("y");;
813 pt
= mcc_getword ("Do you want to characterize other models y/n", pt
);
814 if (strcmp (pt
, "n") == 0) {
817 else if (strcmp (pt
, "y") == 0) {
824 if(vt
&& MCC_DEBUG_MODE
> 0)
826 if(MCC_DEBUG_INPUTCAPA
== 'Y')
828 /* mcc_cal_con_capa ( 'n', 's') ;
829 mcc_cal_con_capa ( 'n', 'g') ;
830 mcc_cal_con_capa ( 'n', 'd') ;
831 mcc_cal_con_capa ( 'p', 's') ;
832 mcc_cal_con_capa ( 'p', 'g') ;
833 mcc_cal_con_capa ( 'p', 'd') ;
841 static void mcc_parse_instance_spec(char *str
, elp_lotrs_param
*lotrsparam_n
, int idx
)
846 chain_list
*cl
=NULL
, *ch
;
850 if (str
==NULL
) return;
853 eqt_add_spice_extension(ctx
);
864 if (strlen(buf
)!=0) cl
=addchain(cl
,mbkstrdup(buf
));
865 cl
=addchain(cl
,mbkstrdup("="));
873 if (strlen(buf
)!=0) cl
=addchain(cl
,mbkstrdup(buf
));
879 if (strlen(buf
)!=0) cl
=addchain(cl
,mbkstrdup(buf
));
884 if (ch
->NEXT
!=NULL
&& ch
->NEXT
->NEXT
!=NULL
&& strcmp((char *)ch
->NEXT
->DATA
,"=")==0)
886 var
=(char *)ch
->DATA
;
887 value
=eqt_eval (ctx
, namealloc((char *)ch
->NEXT
->NEXT
->DATA
), EQTFAST
);
888 if (eqt_resistrue (ctx
))
891 if (strcasecmp(var
, "delvto")==0) lotrsparam_n
->PARAM
[elpDELVT0
]=value
;
892 else if (strcasecmp(var
, "mulu0")==0) lotrsparam_n
->PARAM
[elpMULU0
]=value
;
893 else if (strcasecmp(var
, "sa")==0) lotrsparam_n
->PARAM
[elpSA
]=value
;
894 else if (strcasecmp(var
, "sb")==0) lotrsparam_n
->PARAM
[elpSB
]=value
;
895 else if (strcasecmp(var
, "sd")==0) lotrsparam_n
->PARAM
[elpSD
]=value
;
896 else if (strcasecmp(var
, "nf")==0) lotrsparam_n
->PARAM
[elpNF
]=value
;
897 // else if (strcasecmp(var, "m")==0) lotrsparam_n->PARAM[elpM]=value;
898 else if (strcasecmp(var
, "nrs")==0) lotrsparam_n
->PARAM
[elpNRS
]=value
;
899 else if (strcasecmp(var
, "nrd")==0) lotrsparam_n
->PARAM
[elpNRD
]=value
;
900 else if (strcasecmp(var
, "sc")==0) lotrsparam_n
->PARAM
[elpSC
]=value
;
901 else if (strcasecmp(var
, "sca")==0) lotrsparam_n
->PARAM
[elpSCA
]=value
;
902 else if (strcasecmp(var
, "scb")==0) lotrsparam_n
->PARAM
[elpSCB
]=value
;
903 else if (strcasecmp(var
, "scc")==0) lotrsparam_n
->PARAM
[elpSCC
]=value
;
904 else if (strcasecmp(var
, "vbulk")==0) lotrsparam_n
->VBULK
=value
;
905 else if (strcasecmp(var
, "l")==0) param
[idx
].l
=value
;
906 else if (strcasecmp(var
, "w")==0) param
[idx
].w
=value
;
907 else { avt_errmsg(MCC_ERRMSG
, "036", AVT_ERROR
, var
); err
=1; }
911 avt_errmsg(MCC_ERRMSG
, "037", AVT_ERROR
, (char *)ch
->DATA
, (char *)ch
->NEXT
->NEXT
->DATA
) ;
919 void mcc_CheckTechno(char *label
, char *tn
, char *tp
)
921 int aut
=0, spice
=1, fit
=1, vt
=1;
923 int res
, save_ELP_LOAD_FILE_TYPE
;
925 int save_print
, save_meas
;
926 char *cn
, *cp
, *c
, *search
;
928 char copytn
[1024], copytp
[1024];
929 char newtn
[128], newtp
[128];
931 elp_lotrs_param
*lotrsparam_n
= NULL
;
932 elp_lotrs_param
*lotrsparam_p
= NULL
;
933 mcc_modellist
*modeln
= NULL
;
934 mcc_modellist
*modelp
= NULL
;
939 sprintf(buf
,"%s_techno_check.elp",label
);
941 cp
= MCC_ELPFILE
= mbkstrdup(buf
);
942 avt_sethashvar("avtSpiKeepCards", "all");
943 avt_sethashvar("avtSpiKeepNames", "all");
944 avt_sethashvar("avtElpTechnoName", MCC_ELPFILE
);
945 avt_sethashvar("avtElpGenTechnoName", MCC_ELPFILE
);
946 avt_sethashvar("avtElpDriveFile", "yes");
947 avt_sethashvar("avtLoadSpecifiedElpFile", "no");
950 save_ELP_LOAD_FILE_TYPE
=ELP_LOAD_FILE_TYPE
;
952 // mcc_initcalcparam(0);
959 //ELP_LOAD_FILE_TYPE = ELP_LOADELP_FILE;
962 MCC_DEBUG_GATE
= NULL
;
963 MCC_DEBUG_INPUT
= -1 ;
964 MCC_DEBUG_TRANS
= -1 ;
965 MCC_DEBUG_SLOPE
= 0 ;
967 MCC_DEBUG_RSAT
= 'N' ;
968 MCC_DEBUG_LEAK
= 'N' ;
969 MCC_DEBUG_RLIN
= 'N' ;
970 MCC_DEBUG_VTH
= 'N' ;
971 MCC_DEBUG_QINT
= 'N' ;
972 MCC_DEBUG_JCT_CAPA
= 'N' ; // Junction capacitance => Cjbd, Cjbs...
973 MCC_DEBUG_INPUTCAPA
= 'N' ;
974 MCC_DEBUG_CARAC
= 'N' ;
975 MCC_DEBUG_CARACNEG
= 'N' ;
976 MCC_DEBUG_DEG
= 'N' ;
977 MCC_DEBUG_PASS_TRANS
= 'X' ; // value can be 'N' or 'P'
978 MCC_DEBUG_SWITCH
= 'X' ; // value can be 'N' or 'P'
979 MCC_DEBUG_BLEEDER
= 'N' ;
981 memset(&TRS_CURVS
, 0, sizeof(Icurvs
));
983 if (getenv("MCC_FAST")!=NULL
)
984 fit
=0, MCC_DEBUG_MODE
=0;
986 MCC_DEBUG_PREFIX
=label
;
989 MCC_TECHFILE
= V_STR_TAB
[__MCC_MODEL_FILE
].VALUE
;
991 MCC_MODE
= MCC_FAST_MODE
;
993 save_print
=V_BOOL_TAB
[__SIM_USE_PRINT
].VALUE
; V_BOOL_TAB
[__SIM_USE_PRINT
].VALUE
=1;
994 save_meas
=V_BOOL_TAB
[__SIM_USE_MEAS
].VALUE
; V_BOOL_TAB
[__SIM_USE_MEAS
].VALUE
=0;
996 if (V_FLOAT_TAB
[__SIM_TECHNO_SIZE
].SET
)
998 tec
=V_FLOAT_TAB
[__SIM_TECHNO_SIZE
].VALUE
;
1003 MCC_WP
= tec
* 12.0;
1004 MCC_DIF
= tec
* 2.0;
1008 MCC_VDDmax
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1009 elpGeneral
[elpGVDDMAX
]=MCC_VDDmax
;
1010 MCC_VGS
= MCC_VDDmax
/ 2.0 ;
1012 MCC_SLOPE
= V_FLOAT_TAB
[__SIM_INPUT_SLOPE
].VALUE
*1e12
;
1014 MCC_TEMP
= V_FLOAT_TAB
[__SIM_TEMP
].VALUE
;
1016 cn
=strchr(copytn
, ' '); if (cn
!=NULL
) *cn
='\0', cn
++;
1017 cp
=strchr(copytp
, ' '); if (cp
!=NULL
) *cp
='\0', cp
++;
1019 if ((search
=strchr(copytn
, '('))!=NULL
)
1024 if ((c
=strchr(cn
,')'))!=NULL
) *c
='\0';
1025 MCC_TN_SUBCKT
=namealloc(cn
);
1026 if (c
!= NULL
) cn
= c
+1;
1029 if ((search
=strchr(copytp
, '('))!=NULL
)
1034 if ((c
=strchr(cp
,')'))!=NULL
) *c
='\0';
1035 MCC_TP_SUBCKT
=namealloc(cp
);
1036 if (c
!= NULL
) cp
= c
+1;
1039 MCC_TNMODEL
= mcc_initstr (copytn
);
1040 MCC_TPMODEL
= mcc_initstr (copytp
);
1042 MCC_OPTIM_MODE
= 0 ;
1043 MCC_CALC_CUR
= MCC_SIM_MODE
;
1045 lotrsparam_n
= mcc_init_lotrsparam ();
1046 lotrsparam_p
= mcc_init_lotrsparam ();
1048 if ( lotrsparam_n
->VBULK
< ELPMINVBULK
)
1049 lotrsparam_n
->VBULK
= 0.0;
1050 if ( lotrsparam_p
->VBULK
< ELPMINVBULK
)
1051 lotrsparam_p
->VBULK
= MCC_VDDmax
;
1053 mcc_parse_instance_spec(cn
, lotrsparam_n
, 0);
1054 mcc_parse_instance_spec(cp
, lotrsparam_p
, 1);
1056 res
= mcc_genelp (spice
, 0, tec
, aut
,
1057 fit
, &modeln
, &modelp
,
1058 lotrsparam_n
,lotrsparam_p
);
1060 if (modeln
==NULL
&& modelp
==NULL
&& aut
==1)
1062 if (modeln
==NULL
) avt_errmsg(MCC_ERRMSG
, "027", AVT_ERROR
, copytn
) ;
1063 if (modelp
==NULL
) avt_errmsg(MCC_ERRMSG
, "027", AVT_ERROR
, copytp
) ;
1067 MCC_DEBUG_GATE
= NULL
;
1068 MCC_DEBUG_RSAT
= 'Y' ;
1069 MCC_DEBUG_LEAK
= 'N' ;
1070 MCC_DEBUG_RLIN
= 'Y' ;
1071 MCC_DEBUG_VTH
= 'Y' ;
1072 MCC_DEBUG_QINT
= 'Y' ;
1073 MCC_DEBUG_JCT_CAPA
= 'Y' ; // Junction capacitance => Cjbd, Cjbs...
1074 MCC_DEBUG_INPUTCAPA
= 'Y' ;
1075 MCC_DEBUG_CARAC
= 'Y' ;
1076 MCC_DEBUG_CARACNEG
= 'Y' ;
1077 MCC_DEBUG_DEG
= 'Y' ;
1078 MCC_DEBUG_PASS_TRANS
= 'X' ; // value can be 'N' or 'P'
1079 MCC_DEBUG_SWITCH
= 'X' ; // value can be 'N' or 'P'
1080 MCC_DEBUG_BLEEDER
= 'N' ;
1083 MCC_OPTIM_MODE
= 1 ;
1084 MCC_CALC_CUR
= MCC_CALC_MODE
;
1086 elp_lotrs_param_free ( lotrsparam_n
);
1087 elp_lotrs_param_free ( lotrsparam_p
);
1088 lotrsparam_n
= mcc_init_lotrsparam ();
1089 lotrsparam_p
= mcc_init_lotrsparam ();
1092 if ( lotrsparam_n
->VBULK
< ELPMINVBULK
)
1093 lotrsparam_n
->VBULK
= 0.0;
1094 if ( lotrsparam_p
->VBULK
< ELPMINVBULK
)
1095 lotrsparam_p
->VBULK
= MCC_VDDmax
;
1097 mcc_parse_instance_spec(cn
, lotrsparam_n
, 0);
1098 mcc_parse_instance_spec(cp
, lotrsparam_p
, 1);
1100 res
= mcc_genelp (0, vt
, tec
, aut
,
1101 0, &modeln
, &modelp
,
1102 lotrsparam_n
,lotrsparam_p
);
1104 mcc_gencurv (MCC_PARAM
,lotrsparam_n
,lotrsparam_p
);
1105 newtech
=mcc_check_subckt(newtn
, newtp
);
1109 mcc_calcul_ibranch(lotrsparam_n
, lotrsparam_p
) ;
1110 mcc_genspi_for_inverter_simulator(lotrsparam_n
,lotrsparam_p
);
1113 mcc_drvelp (MCC_PARAM
, MCC_TRANS_B
,lotrsparam_n
,lotrsparam_p
,MCC_DRV_ALL_MODEL
);
1114 // mcc_gencurv (MCC_PARAM,lotrsparam_n,lotrsparam_p);
1115 mcc_printplot (MCC_PARAM
, 1, ncurrent_vt
, pcurrent_vt
, modeln
, modelp
);
1116 if (fit
&& MCC_FLAG_FIT
==MCC_FIT_OK
)
1118 mcc_fit (lotrsparam_n
,lotrsparam_p
,1);
1122 mcc_gencurv (MCC_FIT
,lotrsparam_n
,lotrsparam_p
);
1124 // mcc_printplot (MCC_FIT, 0);
1126 mcc_drive_summary(mcc_getmccname(modeln
));
1128 if(MCC_DEBUG_MODE
> 1) mcc_genbench() ;
1132 printf("* The original technology file contains .subckt statement probably with\n"
1133 "* parameter evaluations. To ensure the correct evaluation of the parameters\n"
1134 "* a parameter-free technology file as been genereted :\n* \"%s\"\n"
1135 "* WARNING: THIS FILE CONTAINS SENSIBLE INFORMATION\n"
1143 elp_lotrs_param_free ( lotrsparam_n
);
1144 lotrsparam_n
= NULL
;
1145 elp_lotrs_param_free ( lotrsparam_p
);
1146 lotrsparam_p
= NULL
;
1147 ELP_LOAD_FILE_TYPE
=save_ELP_LOAD_FILE_TYPE
;
1148 MCC_DEBUG_PREFIX
="";
1149 V_BOOL_TAB
[__SIM_USE_PRINT
].VALUE
=save_print
;
1150 V_BOOL_TAB
[__SIM_USE_MEAS
].VALUE
=save_meas
;
1151 MCC_TN_SUBCKT
=MCC_TP_SUBCKT
=NULL
;
1155 sprintf(buf
,"%s_no_param", label
);
1157 "* Consider re-runing the techno check API with the new techno file\n"
1158 "* setting: avt_config avtTechnologyName \"%s\"\n"
1159 "* using: avt_CheckTechno \"%s\" \"%s %s\" \"%s %s\"\n"
1161 , newtech
,buf
,newtn
, cn
, newtp
, cp
1164 mcc_deltechnofile(MCC_MODELFILE);
1167 oldtech=V_STR_TAB[__MCC_MODEL_FILE].VALUE;
1168 if (oldtech!=NULL) oldtech=sensitive_namealloc(oldtech);
1169 avt_sethashvar("avtTechnologyName", newtech);
1170 mcc_CheckTechno(buf, copytn, copytp);
1171 avt_sethashvar("avtTechnologyName", oldtech);
1173 mcc_deltechnofile(MCC_MODELFILE);
1177 printf("* WARNING: A parameter-free technology file as been genereted :\n"
1178 "* WARNING: \"%s\"\n"
1179 "* WARNING: THIS FILE CONTAINS SENSIBLE INFORMATION\n"
1187 mcc_modifiedparam
* mcc_setparamlist( mcc_modellist
*model
, chain_list
*head
, double value
)
1191 mcc_modifiedparam
*param
;
1193 for( n
=0, chain
=head
; chain
; chain
=chain
->NEXT
, n
++ );
1194 param
= mbkalloc( sizeof( mcc_modifiedparam
) * (n
+1) );
1196 for( n
=0, chain
=head
; chain
; chain
=chain
->NEXT
, n
++ ) {
1197 param
[n
].LABEL
= (char*)chain
->DATA
;
1198 param
[n
].VALUE
= mcc_getparam( model
, param
[n
].LABEL
);
1199 mcc_setparam( model
, param
[n
].LABEL
, value
);
1201 param
[n
].LABEL
= NULL
;
1202 param
[n
].VALUE
= -1 ;
1207 void mcc_restoreparamlist( mcc_modellist
*model
, mcc_modifiedparam
*param
)
1215 while( param
[n
].LABEL
) {
1216 mcc_setparam( model
, param
[n
].LABEL
, param
[n
].VALUE
);
1222 void mcc_hacktechno( lofig_list
*lofig
, int whatjob
)
1228 mcc_modellist
*model
;
1231 chain_list
*headparam
;
1232 mcc_modifiedparam
*keepvalue0
;
1233 mcc_modifiedparam
*keepvalue1
;
1235 drivedmodel
= addht(2);
1236 file
= mbkfopen( "techno_hack", "spi", "w" );
1237 fprintf( file
, "* hacked model without capacitance\n" );
1239 for( lotrs
= lofig
->LOTRS
; lotrs
; lotrs
= lotrs
->NEXT
) {
1241 modelname
= getlotrsmodel( lotrs
) ;
1242 lotrstype
= MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
;
1243 l
= ((double)lotrs
->LENGTH
)/((double)SCALE_X
)*1e-6;
1244 w
= ((double)lotrs
->WIDTH
)/((double)SCALE_X
)*1e-6;
1246 model
= mcc_getmodel( MCC_MODELFILE
, modelname
, lotrstype
, MCC_TYPICAL
, l
, w
, 1 );
1248 if( gethtitem( drivedmodel
, model
)==EMPTYHT
) {
1250 addhtitem( drivedmodel
, model
, 1 );
1255 if( whatjob
== MCC_HACK_REMOVE_LOTRS_CAPA
) {
1257 /* remove intrinsic current */
1259 headparam
= addchain( headparam
, "XPART" );
1260 keepvalue0
= mcc_setparamlist( model
, headparam
, -1.0 );
1261 freechain( headparam
);
1264 /* remove gate-source overlap capacitance (doc bsim430.pdf p 85) */
1265 headparam
= addchain( headparam
, "CGSO" );
1266 headparam
= addchain( headparam
, "CGSL" );
1268 /* remove gate-drain overlap capacitance (doc bsim430.pdf p 85) */
1269 headparam
= addchain( headparam
, "CGDO" );
1270 headparam
= addchain( headparam
, "CGDL" );
1272 /* remove fringing capacitance (doc bsim430.pdf p83) */
1273 headparam
= addchain( headparam
, "CF" );
1275 /* remove source diode capacitance (doc bsim430.pdf p109) */
1276 headparam
= addchain( headparam
, "CJS" );
1277 headparam
= addchain( headparam
, "CJSWS" );
1278 headparam
= addchain( headparam
, "CJSWGS" );
1280 /* remove drain diode capacitance (doc bsim430.pdf p 109) */
1281 headparam
= addchain( headparam
, "CJD" );
1282 headparam
= addchain( headparam
, "CJSWD" );
1283 headparam
= addchain( headparam
, "CJSWGD" );
1285 /* remove common drain and source diode capacitance (doc bsim430.pdf p 125) */
1286 headparam
= addchain( headparam
, "TCJSW" );
1288 keepvalue1
= mcc_setparamlist( model
, headparam
, 0.0 );
1289 freechain( headparam
);
1292 mcc_drive_dot_model( file
, model
);
1294 /* remet le modèle en sortant dans l'état où on l'a trouvé en entrant... */
1295 mcc_restoreparamlist( model
, keepvalue0
);
1296 mcc_restoreparamlist( model
, keepvalue1
);
1300 delht( drivedmodel
);
1304 void mccHackNetlist( lofig_list
*lofig
)
1306 lofig_list
*hackedlofig
;
1314 hackedlofig
= rduplofig( lofig
);
1316 sprintf( buffer
, "%s_hack", lofig
->NAME
);
1317 hackedlofig
->NAME
= namealloc( buffer
);
1319 lofigchain( hackedlofig
);
1321 hacknetlist
= ELP_HACK_NONE
;
1322 hacktechno
= MCC_HACK_NONE
;
1325 if( V_STR_TAB
[ __AVT_HACK_NETLIST_CONFIG
].VALUE
) {
1326 strcpy( buffer
, V_STR_TAB
[ __AVT_HACK_NETLIST_CONFIG
].VALUE
) ;
1328 pt
= strtok( buffer
, " " );
1334 if( !strcasecmp( pt
, "removeresistance" ) ) {
1339 if( !strcasecmp( pt
, "fixcapa" ) ) {
1340 if( hacknetlist
!= ELP_HACK_NONE
)
1341 printf( "avtHackNetlistConfig : bad configuration\n" );
1342 hacknetlist
= ELP_HACK_FIX_CAPA
;
1343 hacktechno
= MCC_HACK_REMOVE_LOTRS_CAPA
;
1347 if( !strcasecmp( pt
, "fixcapatoground" ) ) {
1348 if( hacknetlist
!= ELP_HACK_NONE
)
1349 printf( "avtHackNetlistConfig : bad configuration\n" );
1350 hacknetlist
= ELP_HACK_FIX_CAPA_TO_GND
;
1351 hacktechno
= MCC_HACK_REMOVE_LOTRS_CAPA
;
1355 if( !strcasecmp( pt
, "removecapa" ) ) {
1356 if( hacknetlist
!= ELP_HACK_NONE
)
1357 printf( "avtHackNetlistConfig : bad configuration\n" );
1358 hacknetlist
= ELP_HACK_NONE
;
1359 hacktechno
= MCC_HACK_REMOVE_LOTRS_CAPA
;
1363 pt
= strtok( NULL
, " " );
1367 if( hacknetlist
!= ELP_HACK_NONE
)
1368 elpHackNetlistCapa( hackedlofig
, hacknetlist
);
1371 elpHackNetlistResi( hackedlofig
);
1373 mcc_hacktechno( hackedlofig
, hacktechno
);
1375 savelofig( hackedlofig
);
1376 dellofig( hackedlofig
->NAME
);