Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / mcc / mcc_curv.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : MCC Version 1 */
6 /* Fichier : mcc_curv.c */
7 /* */
8 /* (c) copyright 1991-1998 Laboratoire LIP6 equipe ASIM */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* Auteur(s) : Karim DIOURY */
13 /* */
14 /****************************************************************************/
15
16 #include "mcc_curv.h"
17 #include "mcc_util.h"
18 #include "mcc_genspi.h"
19 #include "mcc_debug.h"
20
21 char* mcc_getmccname( mcc_modellist *model )
22 {
23 char *pt ;
24 static char buf[128] ;
25
26 switch( model->MODELTYPE ) {
27 case MCC_NOMODEL :
28 case MCC_MOS2 : pt = "mos2" ; break ;
29 case MCC_BSIM3V3 : pt = "bs32" ; break ;
30 case MCC_MM9 : pt = "mm9" ; break ;
31 case MCC_MPSP: pt = "psp" ; break ;
32 case MCC_MPSPB: pt = "pspb" ; break ;
33 case MCC_EXTMOD: pt = "ext" ; break ;
34 case MCC_BSIM4 :
35 sprintf( buf, "bs%d", mcc_ftoi(10.0*mcc_getparam_quick(model,__MCC_QUICK_VERSION)) );
36 pt = buf;
37 break ;
38 default : pt = "unknown" ;
39 }
40
41 return pt ;
42 }
43 void mcc_printplot(int type, int forcecalc, float nc_vt, float pc_vt, mcc_modellist *modeln, mcc_modellist *modelp)
44 {
45 FILE *file ;
46 char *techno ;
47 char *name ;
48 char *pt ;
49 int i ;
50 int j ;
51 int e ;
52 double current = 0.0 ;
53 double ncurrent = 0.0 ;
54 double pcurrent = 0.0 ;
55 double ncurrent_vt = 0.0 ;
56 double pcurrent_vt = 0.0 ;
57 float vgsn, vgsp;
58
59 if (MCC_CALC_CUR == MCC_SIM_MODE && type == MCC_PARAM) forcecalc=1;
60
61 ncurrent = mcc_current(MCC_VDDmax,MCC_VDDmax,0.0,MCC_TRANS_N) * 1.1 ;
62 pcurrent = mcc_current(MCC_VDDmax,MCC_VDDmax,0.0,MCC_TRANS_P) * 1.1 ;
63
64 if (nc_vt>-100) ncurrent_vt=nc_vt;
65 else ncurrent_vt = mcc_spicesimcurrent(MCC_VTN,MCC_VDDmax,0.0,MCC_TRANS_N) ; // ABR
66
67 if (pc_vt>-100) pcurrent_vt=pc_vt;
68 else pcurrent_vt = mcc_spicesimcurrent(MCC_VTP,MCC_VDDmax,0.0,MCC_TRANS_P) ;
69
70 name = mbkalloc(strlen(MCC_SPICEFILE[MCC_PARAM]) + 1) ;
71 strcpy(name,MCC_SPICEFILE[MCC_PARAM]) ;
72 if((pt = strchr(name,(int)('.'))) != NULL)
73 *pt = '\0' ;
74
75 techno = mbkalloc(strlen(MCC_ELPFILE) + 1) ;
76 strcpy(techno,MCC_ELPFILE) ;
77 if((pt = strchr(techno,(int)('.'))) != NULL)
78 *pt = '\0' ;
79
80 file = mbkfopen(techno,"plt",WRITE_TEXT) ;
81 avt_printExecInfo(file, "#", "", "");
82 mcc_get_np_vgs(&vgsn, &vgsp);
83
84 e = 0 ;
85 for(i = 2 ; i < 6 ; i++)
86 {
87 if(i < 4)
88 {
89 current = ncurrent ;
90 }
91 else
92 current = pcurrent ;
93 fprintf(file,"set term %s\n", V_STR_TAB[__AVT_GNUPLOT_TERM].VALUE) ;
94 fprintf(file,"set title \"%s\"\n", current==ncurrent?"NMOS":"PMOS");
95 fprintf(file,"set grid\n");
96 if(i%2 == 0)
97 fprintf(file,"set xlabel \"VGS (V)\"\n") ;
98 else
99 fprintf(file,"set xlabel \"VDS (V)\"\n") ;
100 fprintf(file,"set ylabel \"IDS (A)\"\n") ;
101 fprintf(file,"set key top left\n") ;
102
103 if ( i == 2 || i == 4 )
104 {
105 fprintf(file,"set xrange [:%g]\n",(i<4)?MCC_VTN:MCC_VTP);
106 /*fprintf(file,"set yrange [:]\n");*/
107 fprintf(file,"plot '%s.dat' using 1:%d title 'spice Isub vds=vdd' with lines",
108 mcc_debug_prefix(name),i+e) ;
109 if ( forcecalc )
110 fprintf(file,",\\\n'%s_calc.dat' using 1:%d title '%s Isub vds=vdd' with lines",mcc_debug_prefix(name),i+e,mcc_getmccname(i<4?modeln:modelp)) ;
111 fprintf(file,"\n") ;
112 fprintf(file,"pause -1 'Hit CR to finish'\n") ;
113 fprintf(file,"set term postscript eps monochrome \"Times-Roman\" 20\n") ;
114 fprintf(file,"set output \"%s_%d.eps\"\n",techno,i) ;
115 fprintf(file,"replot\n") ;
116 }
117 fprintf(file,"set term %s\n", V_STR_TAB[__AVT_GNUPLOT_TERM].VALUE) ;
118 fprintf(file,"set xrange [0:%g]\n",MCC_VDDmax*1.05 );
119 /*fprintf(file,"set yrange [0:%e]\n",current);*/
120 fprintf(file,"plot '%s.dat' using 1:%d title 'spice' with lines,\\\n '%s.dat' using 1:%d title 'elp' with lines",
121 mcc_debug_prefix(name),i+e,techno,i+e) ;
122 if ( MCC_OPTIM_MODE && type == MCC_PARAM )
123 fprintf(file,",\\\n'%s_opt.dat' using 1:%d title '%s pwl' with lines",mcc_debug_prefix(name),i+e,mcc_getmccname(i<4?modeln:modelp)) ;
124 if ( forcecalc )
125 fprintf(file,",\\\n'%s_calc.dat' using 1:%d title '%s' with lines",mcc_debug_prefix(name),i+e,mcc_getmccname(i<4?modeln:modelp)) ;
126 if((i%2 != 0)/* &&
127 (mcc_ftol(MCC_VGS * 1000.0) != mcc_ftol(MCC_VDDmax * 1000.0))*/)
128 {
129 e++ ;
130 fprintf(file,",\\\n '%s.dat' using 1:%d title 'spice vgs=%g ' with lines ,\\\n '%s.dat' using 1:%d title 'elp vgs=%g ' with lines",
131 mcc_debug_prefix(name),i+e,i<4?vgsn:vgsp,techno,i+e,i<4?vgsn:vgsp) ;
132 if ( MCC_OPTIM_MODE && type == MCC_PARAM )
133 fprintf(file,",\\\n'%s_opt.dat' using 1:%d title '%s pwl vgs=%g' with lines",mcc_debug_prefix(name),i+e,mcc_getmccname(i<4?modeln:modelp),i<4?vgsn:vgsp) ;
134 if (forcecalc )
135 fprintf(file,",\\\n'%s_calc.dat' using 1:%d title '%s vgs=%g' with lines",mcc_debug_prefix(name),i+e,mcc_getmccname(i<4?modeln:modelp),i<4?vgsn:vgsp) ;
136 }
137
138 if(type != MCC_PARAM)
139 fprintf(file,",\\\n '%s_fit.dat' using 1:%d title 'after fit' with lines",techno,i+e) ;
140 fprintf(file,"\n") ;
141 fprintf(file,"pause -1 'Hit CR to finish'\n") ;
142 fprintf(file,"set term postscript eps monochrome \"Times-Roman\" 20\n") ;
143 fprintf(file,"set output \"%s_%d.eps\"\n",techno,i) ;
144 fprintf(file,"replot\n") ;
145 }
146
147 if(fclose(file) != 0)
148 {
149 fprintf(stderr,"\nmcc error : can't close file %s.plt\n",techno) ;
150 EXIT(1);
151 }
152
153 if(type == MCC_PARAM)
154 return ;
155
156 mbkfree(techno) ;
157 mbkfree(name) ;
158
159 techno = mbkalloc(strlen(MCC_ELPFILE) + 10) ;
160 name = mbkalloc(strlen(MCC_ELPFILE) + 10) ;
161 strcpy(name,MCC_ELPFILE) ;
162 if((pt = strchr(name,(int)('.'))) != NULL)
163 *pt = '\0' ;
164 sprintf(techno,"%s_fit",name) ;
165
166 file = mbkfopen(techno,"plt",WRITE_TEXT) ;
167 avt_printExecInfo(file, "#", "", "");
168
169 mbkfree(name) ;
170
171 for(i = 0 ; i < MCC_SPICENB - 1 ; i++)
172 {
173 name = mbkalloc(strlen(MCC_SPICEFILE[i]) + 1) ;
174 strcpy(name,MCC_SPICEFILE[i]) ;
175 if((pt = strchr(name,(int)('.'))) != NULL)
176 *pt = '\0' ;
177
178 fprintf(file,"set term %s\n", V_STR_TAB[__AVT_GNUPLOT_TERM].VALUE) ;
179 fprintf(file,"set xlabel \"TIME (PS)\"\n") ;
180 fprintf(file,"set ylabel \"VOUT (V)\"\n") ;
181 fprintf(file,"set xtics (") ;
182 j = 0 ;
183 while(j < (int)(V_FLOAT_TAB[__SIM_TIME].VALUE*1e9))
184 {
185 j+=5 ;
186 fprintf(file,"%d.0e-9,",j) ;
187 }
188 j+=5 ;
189 fprintf(file,"%d.0e-9)\n",j) ;
190 fprintf(file,"set xrange [0:%e]\n",(V_FLOAT_TAB[__SIM_TIME].VALUE*1e9 + 1)*1.0e-9) ;
191 fprintf(file,"set yrange [0:%g]\n",MCC_VDDmax*1.05) ;
192 fprintf(file,"plot ") ;
193 for(j = 0 ; j < MCC_INSNUMB ; j++)
194 fprintf(file,"'%s.dat' using 1:%d title 's%d' with lines, ",mcc_debug_prefix(name),j+2,j) ;
195 fprintf(file,"'%s.dat' using 1:%d title 's%d' with lines\n",mcc_debug_prefix(name),j+2,j) ;
196 fprintf(file,"pause -1 'Hit CR to finish'\n") ;
197 fprintf(file,"set term postscript eps monochrome \"Times-Roman\" 20\n") ;
198 fprintf(file,"set output \"%s.eps\"\n",mcc_debug_prefix(name)) ;
199 fprintf(file,"replot\n") ;
200
201 mbkfree(name) ;
202 }
203
204 if(fclose(file) != 0)
205 {
206 fprintf(stderr,"\nmcc error : can't close file %s.plt\n",techno) ;
207 EXIT(1);
208 }
209
210 mbkfree(techno) ;
211 }
212
213 void mcc_technoParameters(lotrsparam_n,lotrsparam_p)
214 elp_lotrs_param *lotrsparam_n;
215 elp_lotrs_param *lotrsparam_p;
216 {
217 elpmodel_list *modeln ;
218 elpmodel_list *modelp ;
219
220 if(MCC_ELPFILE != NULL) strcpy(elpTechnoFile,MCC_ELPFILE) ;
221
222 elpLoadOnceElp();
223 /*
224 if(elpLoadElp())
225 {
226 fprintf(stderr,"\nmcc error : bad technology file %s\n",MCC_ELPFILE) ;
227 EXIT(1) ;
228 }
229 */
230 modeln = elpGetParamModel(MCC_TNMODEL,MCC_LN,MCC_WN,TRANSN,elpGeneral[elpGVDDMAX],MCC_NCASE,lotrsparam_n) ;
231 modelp = elpGetParamModel(MCC_TPMODEL,MCC_LP,MCC_WP,TRANSP,elpGeneral[elpGVDDMAX],MCC_PCASE,lotrsparam_p) ;
232
233 MCC_VTN = modeln->elpModel[elpVT] ;
234 MCC_KTN = modeln->elpModel[elpKT] ;
235 MCC_KSN = modeln->elpModel[elpKS] ;
236 MCC_KRN = modeln->elpModel[elpKR] ;
237 MCC_AN = modeln->elpModel[elpA] ;
238 MCC_BN = modeln->elpModel[elpB] ;
239 MCC_RNT = modeln->elpModel[elpRT] ;
240 MCC_RNS = modeln->elpModel[elpRS] ;
241 MCC_DWN = modeln->elpShrink[elpDW] ;
242 MCC_DLN = modeln->elpShrink[elpDL] ;
243 MCC_XLN = modeln->elpShrink[elpLMLT] ;
244 MCC_XWN = modeln->elpShrink[elpWMLT] ;
245 MCC_VTP = modelp->elpModel[elpVT] ;
246 MCC_KTP = modelp->elpModel[elpKT] ;
247 MCC_KSP = modelp->elpModel[elpKS] ;
248 MCC_KRP = modelp->elpModel[elpKR] ;
249 MCC_AP = modelp->elpModel[elpA] ;
250 MCC_BP = modelp->elpModel[elpB] ;
251 MCC_RPT = modelp->elpModel[elpRT] ;
252 MCC_RPS = modelp->elpModel[elpRS] ;
253 MCC_DWP = modelp->elpShrink[elpDW] ;
254 MCC_DLP = modelp->elpShrink[elpDL] ;
255 MCC_XLP = modelp->elpShrink[elpLMLT] ;
256 MCC_XWP = modelp->elpShrink[elpWMLT] ;
257 MCC_WNeff = MCC_XWN*MCC_WN + MCC_DWN ;
258 MCC_LNeff = MCC_XLN*MCC_LN + MCC_DLN ;
259 MCC_WPeff = MCC_XWP*MCC_WP + MCC_DWP ;
260 MCC_LPeff = MCC_XLP*MCC_LP + MCC_DLP ;
261 MCC_VDDmax = elpGeneral[elpGVDDMAX] ;
262 }
263
264 void mcc_visu()
265 {
266 fprintf(stdout,"MCC CURRENT PARAMETERS :\n") ;
267 fprintf(stdout,"DWN = %g\n",MCC_DWN) ;
268 fprintf(stdout,"DLN = %g\n",MCC_DLN) ;
269 fprintf(stdout,"VTN = %g\n",MCC_VTN) ;
270 fprintf(stdout,"KTN = %g\n",MCC_KTN) ;
271 fprintf(stdout,"KSN = %g\n",MCC_KSN) ;
272 fprintf(stdout,"KRN = %g\n",MCC_KRN) ;
273 fprintf(stdout,"AN = %g\n",MCC_AN) ;
274 fprintf(stdout,"BN = %g\n",MCC_BN) ;
275 fprintf(stdout,"RNT = %g\n",MCC_RNT) ;
276 fprintf(stdout,"RNS = %g\n",MCC_RNS) ;
277 fprintf(stdout,"DWP = %g\n",MCC_DWP) ;
278 fprintf(stdout,"DLP = %g\n",MCC_DLP) ;
279 fprintf(stdout,"VTP = %g\n",MCC_VTP) ;
280 fprintf(stdout,"KTP = %g\n",MCC_KTP) ;
281 fprintf(stdout,"KSP = %g\n",MCC_KSP) ;
282 fprintf(stdout,"KRP = %g\n",MCC_KRP) ;
283 fprintf(stdout,"AP = %g\n",MCC_AP) ;
284 fprintf(stdout,"BP = %g\n",MCC_BP) ;
285 fprintf(stdout,"RPT = %g\n",MCC_RPT) ;
286 fprintf(stdout,"RPS = %g\n",MCC_RPS) ;
287 fprintf(stdout,"XWN = %g\n",MCC_XWN) ;
288 fprintf(stdout,"XLN = %g\n",MCC_XLN) ;
289 fprintf(stdout,"XWP = %g\n",MCC_XWP) ;
290 fprintf(stdout,"XLP = %g\n",MCC_XLP) ;
291 fprintf(stdout,"VDDmax = %g\n",MCC_VDDmax) ;
292 fprintf(stdout,"TRANSTEP = %g\n",V_FLOAT_TAB[__SIM_TRAN_STEP].VALUE*1e9) ;
293 fprintf(stdout,"DCSTEP = %g\n",V_FLOAT_TAB[__SIM_TIME].VALUE*1e9) ;
294 fprintf(stdout,"WNeff = %g\n",MCC_WNeff) ;
295 fprintf(stdout,"LNeff = %g\n",MCC_LNeff) ;
296 fprintf(stdout,"WPeff = %g\n",MCC_WPeff) ;
297 fprintf(stdout,"LPeff = %g\n",MCC_LPeff) ;
298 }
299
300 void mcc_drvmtfile(file)
301 FILE *file;
302 {
303 double var = 0.0 ;
304 double i[6];
305 int idx=0, k;
306
307 fprintf(file,"#volt ");
308 fprintf(file,"idnsat ");
309 fprintf(file,"idnres ");
310 if(mcc_ftol(MCC_VGS * 1000.0) != mcc_ftol(MCC_VDDmax * 1000.0))
311 fprintf(file,"idnvgs ");
312 fprintf(file,"idpsat ");
313 fprintf(file,"idpres ");
314 if(mcc_ftol(MCC_VGS * 1000.0) != mcc_ftol(MCC_VDDmax * 1000.0))
315 fprintf(file,"idpvgs");
316 fprintf(file,"\n");
317
318 for (k=0; k<6; k++)
319 {
320 TRS_CURVS.I_ELP[k]=mbkalloc(sizeof(double)*TRS_CURVS.nb);
321 }
322
323 while(var <= MCC_VDDmax)
324 {
325 // if(mcc_ftol(MCC_VGS * 1000.0) != mcc_ftol(MCC_VDDmax * 1000.0))
326 {
327 fprintf(file,"%.3e %.3e %.3e %.3e %.3e %.3e %.3e\n",var,
328 i[0]=mcc_current(var,MCC_VDDmax,0.0,MCC_TRANS_N),
329 i[1]=mcc_current(MCC_VDDmax,var,0.0,MCC_TRANS_N),
330 i[2]=mcc_current(MCC_VGS,var,0.0,MCC_TRANS_N),
331 i[3]=mcc_current(var,MCC_VDDmax,0.0,MCC_TRANS_P),
332 i[4]=mcc_current(MCC_VDDmax,var,0.0,MCC_TRANS_P),
333 i[5]=mcc_current(MCC_VGS,var,0.0,MCC_TRANS_P));
334 for (k=0; k<6; k++) TRS_CURVS.I_ELP[k][idx]=i[k];
335 }
336 /* else
337 {
338 fprintf(file,"%.3e %.3e %.3e %.3e %.3e\n",var,
339 mcc_current(var,MCC_VDDmax,0.0,MCC_TRANS_N),
340 mcc_current(MCC_VGS,var,0.0,MCC_TRANS_N),
341 mcc_current(var,MCC_VDDmax,0.0,MCC_TRANS_P),
342 mcc_current(MCC_VGS,var,0.0,MCC_TRANS_P));
343 }*/
344 var += MCC_DC_STEP;
345 idx++;
346 }
347 }
348
349 void mcc_gencurv(type,lotrsparam_n,lotrsparam_p)
350 int type ;
351 elp_lotrs_param *lotrsparam_n;
352 elp_lotrs_param *lotrsparam_p;
353 {
354 FILE *file ;
355 char *nomout ;
356 char *pt ;
357
358 mcc_technoParameters(lotrsparam_n,lotrsparam_p);
359
360 /* MCC_CALC_CUR=MCC_CALC_MODE;
361 printf("%g\n",mcc_spicecurrent(MCC_VDDmax, MCC_VDDmax, 0, MCC_TRANS_P, lotrsparam_p));
362 exit(1);*/
363 nomout = mbkalloc(strlen(MCC_ELPFILE) + 10) ;
364 strcpy(nomout,MCC_ELPFILE) ;
365 if((pt = strchr(nomout,(int)('.'))) != NULL)
366 *pt = '\0' ;
367
368 if(type != MCC_PARAM)
369 sprintf(nomout+strlen(nomout),"_fit") ;
370
371 file = mbkfopen(nomout,"dat",WRITE_TEXT) ;
372 avt_printExecInfo(file, "#", "", "");
373
374 if(file == NULL)
375 {
376 fprintf(stderr,"\nmcc error : can't open file %s.dat\n",nomout) ;
377 EXIT(1);
378 }
379
380 mcc_drvmtfile(file);
381
382 if(fclose(file) != 0)
383 {
384 fprintf(stderr,"\nmcc error : can't close file %s.dat\n",nomout) ;
385 EXIT(1);
386 }
387
388 mbkfree(nomout) ;
389 }