Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stm / stm_pwth.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : STM Version 1.00 */
6 /* Fichier : stm_pwl.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /****************************************************************************/
14
15 /****************************************************************************/
16 /* includes */
17 /****************************************************************************/
18
19 #include "stm.h"
20
21 /****************************************************************************/
22 /* functions */
23 /****************************************************************************/
24
25 /* Transforme une structure stm_pwl en un ensemble de tangentes hyperbolique
26 le tableau pwth doit contenir (n-1) éléments.
27 Renvoie 1 si OK, 0 si un pb est survenu.
28 ntanh contient au retour le nb d'éléments dans pwth.
29 */
30
31 int stm_pwl_to_tanh( stm_pwl *pwl,
32 double vt,
33 double vdd,
34 stm_pwth *pwth,
35 int *ntanh,
36 float oldslew
37 )
38 {
39 int i, n ;
40 double v1, v2, t1, t2 ;
41 double k1, k2 ;
42 double dt, f ;
43 double dt0 ;
44 double vm ;
45
46 if( pwl->N < 2 )
47 return 0;
48
49 vm = 2*vt - vdd ;
50 n = pwl->N-1 ;
51 *ntanh = 0;
52
53 for( i=0 ; i<n ; i++) {
54
55 t1 = pwl->TAB[ 2*i+0 ] ;
56 v1 = pwl->TAB[ 2*i+1 ] ;
57 t2 = pwl->TAB[ 2*i+2 ] ;
58 v2 = pwl->TAB[ 2*i+3 ] ;
59
60 if( v1 < vm || fabs((v2-v1)/v1) < 1.0e-6 )
61 continue ;
62
63 if( v1 > 0.99*vdd || v2 > 0.99*vdd ) {
64 /**ntanh = 0;*/
65 break;
66 }
67
68 k1 = atanh( (v1-vt)/(vdd-vt) );
69 k2 = atanh( (v2-vt)/(vdd-vt) );
70
71 dt = ( t2*k1 - t1*k2 ) / (k1-k2) ;
72 f = ( t1-t2) / ( k1-k2 );
73
74 if( i==0 )
75 dt0 = dt ;
76
77 pwth[*ntanh].F = f ;
78 pwth[*ntanh].DT = dt-dt0 ;
79 pwth[*ntanh].T = t2-pwth[*ntanh].DT ;
80 (*ntanh)++;
81 }
82
83 if( *ntanh < 1 )
84 return 0 ;
85
86 pwth[(*ntanh)-1].T = FLT_MAX ;
87
88 return 1 ;
89 }
90
91 void stm_pwl_debug_pwl_q( double vt,
92 double vdd,
93 double fin,
94 stm_pwl *pwlin,
95 dualparams *params,
96 char *filename,
97 double tp
98 )
99 {
100 char name[256] ;
101 stm_pwth tabthin[32] ;
102 int nthin ;
103 FILE *ptf ;
104 double imax, an, bn, u, f ;
105 int i ;
106 double q ;
107 double t ;
108
109 if( !pwlin )
110 return ;
111
112 sprintf( name, "%s_q.dat", filename );
113
114 if( !stm_pwl_to_tanh( pwlin, vt, vdd, tabthin, &nthin, fin ) ) {
115 printf( "error in stm_pwl_to_tanh()\n" );
116 return ;
117 }
118
119 ptf = fopen( name, "w" );
120 if( !ptf )
121 return ;
122
123 imax = params->DP[STM_IMAX];
124 an = params->DP[STM_AN];
125 bn = params->DP[STM_BN];
126 stm_modscm_dual_cal_UF( imax, an, bn, (vdd-vt), 0.0, fin, &u, &f );
127
128 for( t=0.0 ; t<=tp ; t=t+0.1 ) {
129
130 q = 0.0 ;
131
132 for( i=0 ; i<nthin && tabthin[i].T+tabthin[i].DT < t ; i++) {
133
134 q = q + stm_get_q( imax, tabthin[i].T, tabthin[i].F, bn , u)
135 - ( i>0 ? stm_get_q( imax, tabthin[i-1].T+tabthin[i-1].DT-tabthin[i].DT, tabthin[i].F, bn , u) : 0.0 );
136 }
137
138 q = q + stm_get_q( imax, t - tabthin[i].DT, tabthin[i].F, bn , u)
139 - ( i>0 ? stm_get_q( imax, tabthin[i-1].T+tabthin[i-1].DT-tabthin[i].DT, tabthin[i].F, bn , u) : 0.0 );
140
141 fprintf( ptf, "%g %g %g\n", t, q, stm_get_q( imax, t, fin, bn, u ) );
142 }
143
144 fclose( ptf );
145 }
146
147 void stm_pwl_debug_pwl_to_tanh( stm_pwl *pwl,
148 double fold,
149 dualparams *params,
150 char *filename,
151 double vt,
152 double vdd,
153 double fin,
154 stm_pwl *pwlin,
155 double load,
156 double tp,
157 char eventin,
158 char eventout
159 )
160 {
161 char filenamepwldat[256] ;
162 char filenametanhdat[256] ;
163 char filenamemccdat[256] ;
164 char filenamegpl[256] ;
165 FILE *filepwldat,
166 *filetanhdat,
167 *filemccdat,
168 *filegpl ;
169 stm_pwth tabth[32], tabthin[32];
170 int nth, nthin;
171 int i ;
172 double t,
173 tmax,
174 v ;
175 double tref_th, tref_pw, tabs=100.0, dt_th=0.0, trefthout ;
176 char *env;
177 stm_dual_param_timing paramtimingpwl ;
178 stm_dual_param_timing paramtimingtanh ;
179 float tspwl ;
180 float tstanh ;
181
182 env = getenv( "DEBUG_PWL_TE" );
183 if( env ) {
184 tabs = atof(env );
185 }
186
187 if( !pwl || !pwlin )
188 return ;
189 sprintf( filenamepwldat, "%s_pwl.dat", filename );
190 sprintf( filenametanhdat, "%s_tanh.dat", filename );
191
192 if( params )
193 sprintf( filenamemccdat, "%s_mcc.dat", filename );
194
195 sprintf( filenamegpl, "%s.gpl", filename );
196
197 filepwldat = fopen( filenamepwldat, "w" );
198 if( !filepwldat ) {
199 printf( "can't open file %s for writting\n", filenamepwldat );
200 return ;
201 }
202
203 filetanhdat = fopen( filenametanhdat, "w" );
204 if( !filetanhdat ) {
205 printf( "can't open file %s for writting\n", filenametanhdat );
206 return ;
207 }
208
209 if( params ) {
210 filemccdat = fopen( filenamemccdat, "w" );
211 if( !filemccdat ) {
212 printf( "can't open file %s for writting\n", filenamemccdat );
213 return ;
214 }
215 }
216
217 filegpl = fopen( filenamegpl, "w" );
218 if( !filegpl ) {
219 printf( "can't open file %s for writting\n", filenamegpl );
220 return ;
221 }
222
223 if( !stm_pwl_to_tanh( pwl, vt, vdd, tabth, &nth, fold ) ||
224 !stm_pwl_to_tanh( pwlin, vt, vdd, tabthin, &nthin, fin ) ) {
225 printf( "error in stm_pwl_to_tanh()\n" );
226 fclose( filetanhdat ) ;
227 fclose( filepwldat ) ;
228 fclose( filegpl ) ;
229 return ;
230 }
231
232 tref_th = tabs - stm_get_t(vdd/2.0, vt, 0.0, vdd, fin) ;
233 dt_th = stm_get_t(vt, vt, 0.0, vdd, fin) ;
234 tref_pw = tabs - stm_get_t_pwth(vdd-vt, vt, vdd/2.0, tabthin ) ;
235
236 trefthout = stm_modscm_dual_calculduts_threshold( params,
237 fin,
238 load,
239 vdd/2.0,
240 pwlin
241 )+tref_pw
242 - stm_get_t_pwth(vdd-vt, vt, vdd/2.0, tabth ) ;
243
244 for( i=0 ; i<pwl->N ; i++ ) {
245 if( eventout =='U' )
246 fprintf( filepwldat, "%g %g\n", (pwl->TAB[2*i]+tref_pw)*1e-12, pwl->TAB[2*i+1] );
247 else
248 fprintf( filepwldat, "%g %g\n", vdd - (pwl->TAB[2*i]+tref_pw)*1e-12, pwl->TAB[2*i+1] );
249 tmax = 2.0*pwl->TAB[2*i]+tref_pw ;
250 }
251
252 for( t=0.0 ; t<=tmax ; t++ ) {
253 fprintf( filetanhdat, "%g ", t*1e-12 );
254
255 if( eventout=='U' )
256 fprintf( filetanhdat, "%g ", stm_get_v_pwth( t-trefthout, vt, vdd, STM_UP, tabth ) );
257 else
258 fprintf( filetanhdat, "%g ", vdd-stm_get_v_pwth( t-trefthout, vt, vdd, STM_UP, tabth ) );
259
260 if( eventout=='U' )
261 fprintf( filetanhdat, "%g ", stm_get_v( t-tref_pw-tp, vt, 0.0, vdd, fold ) );
262 else
263 fprintf( filetanhdat, "%g ", vdd-stm_get_v( t-tref_pw-tp, vt, 0.0, vdd, fold ) );
264
265 if( eventin=='U' )
266 fprintf( filetanhdat, "%g ", stm_get_v_pwth( t-tref_pw, vt, vdd, STM_UP, tabthin ) );
267 else
268 fprintf( filetanhdat, "%g ", vdd-stm_get_v_pwth( t-tref_pw, vt, vdd, STM_UP, tabthin ) );
269
270 if( eventin=='U' )
271 fprintf( filetanhdat, "%g\n", stm_get_v( t-tref_th, vt, 0.0, vdd, fin ) );
272 else
273 fprintf( filetanhdat, "%g\n", vdd-stm_get_v( t-tref_th, vt, 0.0, vdd, fin ) );
274 }
275
276 if( params ) {
277 stm_modscm_dual_fill_param( params, fin, pwlin, NULL, load, &paramtimingpwl );
278 stm_modscm_dual_fill_param( params, fin, NULL, NULL, load, &paramtimingtanh );
279
280 for( v=0.01*vdd ; v<=0.99*vdd ; v=v+0.01*vdd ) {
281 tspwl = stm_modscm_dual_calts_with_param_timing( &paramtimingpwl, v );
282 tstanh = stm_modscm_dual_calts_with_param_timing( &paramtimingtanh, v );
283
284 fprintf( filemccdat, "%g %g %g\n", ( tspwl + tref_pw ) * 1e-12,
285 ( tstanh + tref_th + dt_th ) * 1e-12,
286 eventout=='U' ? v : vdd-v
287 );
288 }
289 }
290
291 fprintf( filegpl,
292 "set key bottom right\n"
293 );
294 if( params )
295 fprintf( filegpl,
296 "plot [0:%g] '%s' title \"pwl\" with linespoints, '%s' using 1:2 title \"pwtanh\" with lines, '%s' using 1:3 title \"old tanh\" with lines, '%s' using 1:3 title \"mcc (in=pwl)\" with lines, '%s' using 2:3 title \"mcc (in=th)\" with lines, '%s' using 1:5 title \"input old tanh\" with lines, '%s' using 1:4 title \"input pwl\" with lines\n",
297 tmax*1e-12,
298 filenamepwldat,
299 filenametanhdat,
300 filenametanhdat,
301 filenamemccdat,
302 filenamemccdat,
303 filenametanhdat,
304 filenametanhdat
305 );
306 else
307 fprintf( filegpl,
308 "plot [0:%g] '%s' title \"pwl\" with linespoints, '%s' using 1:2 title \"pwtanh\" with lines, '%s' using 1:3 title \"old tanh\" with lines\n",
309 tmax*1e-12,
310 filenamepwldat,
311 filenametanhdat,
312 filenametanhdat
313 );
314 fprintf( filegpl, "pause -1\n" );
315
316 fclose( filegpl );
317 fclose( filepwldat );
318 fclose( filetanhdat );
319 if( params )
320 fclose( filemccdat );
321 }
322
323 int stm_get_v_pwth_fn( stm_pwth_fn *args, double t, double *v )
324 {
325 *v = stm_get_v_pwth( t,
326 args->VT,
327 args->VDD,
328 STM_UP,
329 args->PWTH
330 );
331 return 1 ;
332 }
333
334 /* Renvoie la tension à l'instant t */
335 double stm_get_v_pwth (float t, float vt, float vdd, char sens, stm_pwth *pwth )
336 {
337 int i ;
338 double v ;
339
340 i=0;
341
342 if( t<0.0 ) {
343 v = vt + (vdd-vt)*t/pwth[0].F ;
344 if( v<0.0 )
345 v=0.0 ;
346 }
347 else {
348
349 while( pwth[i].DT + pwth[i].T < t )
350 i++;
351
352 v = vt + (vdd-vt)*tanh( (t - pwth[i].DT ) / pwth[i].F ) ;
353
354 }
355
356 if( sens == STM_DN ) {
357 v = vdd-v ;
358 }
359
360 return v ;
361 }
362
363 /* Renvoie l'instant t où le signal passe à v */
364 double stm_get_t_pwth (float vddin, float vt, float seuil, stm_pwth *pwth )
365 {
366 double vemax, tmax, dt, f ;
367 int i=0 ;
368 double te ;
369
370 if( seuil < vt ) {
371 te = pwth[0].F*(seuil-vt)/vddin ;
372 }
373 else {
374 do {
375 tmax = pwth[i].T ;
376 dt = pwth[i].DT ;
377 f = pwth[i].F ;
378
379 vemax = vt + vddin*tanh(tmax/f);
380 if( vemax < seuil ) {
381 i++ ;
382 }
383 }
384 while( vemax < seuil );
385
386 te = stm_modscm_dual_calte( vddin, vt, seuil, f ) + dt ;
387 }
388
389 return te ;
390 }
391
392 void stm_plot_pwth( stm_pwth *pwth, char *filename, float t0, float vddin, float vt, float vth, char sens )
393 {
394 FILE *ptf ;
395 float te ;
396 float dt ;
397 float v ;
398 float vr ;
399 float t ;
400
401 ptf = mbkfopen( filename, NULL, "w" ) ;
402 if(!ptf) {
403 printf( "can't open file \"%s\" for writting\n", filename ) ;
404 return ;
405 }
406
407 te = stm_get_t_pwth( vddin, vt, vth, pwth );
408 dt = t0-te ;
409
410 for( v=0.02*vddin ; v<=0.98*(vddin+vt) ; v=v+vddin/100 ) {
411 t = stm_get_t_pwth( vddin, vt, v, pwth );
412 if( tolower(sens)=='d' || tolower(sens)=='f' )
413 vr = 2.0*vth-v ;
414 else
415 vr = v ;
416 fprintf( ptf, "%g %g\n", (t+dt)*1e-12, vr );
417 }
418
419 fclose( ptf );
420 }