Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / sim / sim_model.c
1 /*****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : SIM Version 2.00 */
6 /* Fichier : sim_obj.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /*****************************************************************************/
14
15 #include SIM_H
16 #include "sim.h"
17
18 ht *SIM_MODEL_LIST=NULL;
19
20 void sim_init( void )
21 {
22 if( !SIM_MODEL_LIST ) {
23 SIM_MODEL_LIST = addht( 10 );
24 }
25 }
26
27 lofig_list* sim_model_get_lofig( sim_model *model )
28 {
29 if( !model ) return NULL;
30 return model->FIG;
31 }
32
33 void sim_model_set_lofig( sim_model *model, lofig_list *lofig )
34 {
35 model->FIG = lofig;
36 }
37
38 sim_model* sim_model_alloc( void )
39 {
40 sim_model *newmodel;
41
42 newmodel = (sim_model *)mbkalloc( sizeof( sim_model ) );
43 newmodel->LINPUT = NULL;
44 newmodel->LMEASURE = NULL;
45 newmodel->TRANSLATION = NULL;
46 newmodel->LIC = NULL;
47 newmodel->FIG = NULL;
48 newmodel->FIGNAME = NULL;
49 newmodel->HTINPUT = NULL;
50 newmodel->OUTPUT_FILE = NULL;
51 newmodel->OUTPUT_READ = 0;
52 // newmodel->CONTEXT_HT = NULL;
53 newmodel->USER = NULL;
54 /* extraction fields */
55 newmodel->LLABELS = NULL;
56 mfe_duprules(&(newmodel->LRULES),SIM_EXTRACT_RULE);
57 newmodel->LARGS = NULL;
58 newmodel->LPRN = NULL;
59 newmodel->NBMC = 0;
60 strcpy(newmodel->SUBCKTFILENAME,"");
61 return newmodel;
62 }
63
64 void sim_model_free( sim_model *model )
65 {
66 if( model->LINPUT || model->LMEASURE || model->HTINPUT ||
67 model->OUTPUT_FILE || model->LIC || model->TRANSLATION ||
68 model->LLABELS || model->LRULES || model->LARGS ||
69 model->LPRN)
70 sim_error( "sim_model_free() : model %s not empty.\n", model->FIGNAME );
71 mbkfree( model );
72 }
73
74 sim_model* sim_model_create_new( char *name )
75 {
76 sim_model *newmodel;
77
78 sim_init();
79
80 newmodel = sim_model_alloc();
81 newmodel->FIGNAME = name ;
82
83 sim_parameter_init( newmodel );
84 sim_input_init( newmodel );
85 return newmodel;
86 }
87
88
89 sim_model* sim_model_create( char *name, int nbmc )
90 {
91 sim_model *newmodel;
92
93 sim_init();
94
95 SIM_VT_SLOPEIN = -1.0;
96
97 if( sim_model_get( name ) ) {
98 sim_error( "sim_create_model() : model %d already declared.\n", name );
99 }
100
101 newmodel=sim_model_create_new(name);
102 addhtitem( SIM_MODEL_LIST, newmodel->FIGNAME, (long)newmodel );
103 newmodel->NBMC = nbmc ;
104
105 return newmodel;
106 }
107
108 sim_model* sim_model_get( char *name )
109 {
110 sim_model *model;
111
112 sim_init();
113
114 model = (sim_model*)gethtitem( SIM_MODEL_LIST, name );
115
116 if( model == (sim_model*)EMPTYHT )
117 return NULL;
118
119 return model;
120 }
121
122 void sim_model_clear_bypointer( sim_model *model)
123 {
124
125 sim_init();
126
127 sim_input_clean( model );
128 sim_measure_clean( model );
129 sim_ic_clean( model );
130 sim_parameter_clean( model );
131 sim_translate_clean( model);
132
133 mfe_freerules(&(model->LRULES));
134 if( model->NBMC > 0 )
135 mfe_freelabels(&(model->LLABELS),1);
136 else
137 mfe_freelabels(&(model->LLABELS),0);
138 sim_freeMeasAllArg(model);
139 sim_freePrn(model);
140
141 mbkfree( model->OUTPUT_FILE );
142 model->OUTPUT_FILE = NULL;
143
144 sim_model_free( model );
145
146 /* if (model->CONTEXT_HT!=NULL) delht(model->CONTEXT_HT);
147 model->CONTEXT_HT=NULL;*/
148 }
149
150 void sim_model_clear( char *name )
151 {
152 sim_model *model;
153
154 sim_init();
155
156 model = (sim_model*)gethtitem( SIM_MODEL_LIST, name );
157
158 if( model == (sim_model*)EMPTYHT )
159 return ;
160
161 if ( model->USER )
162 freeptype (model->USER);
163
164 sim_model_clear_bypointer(model);
165
166 delhtitem( SIM_MODEL_LIST, name );
167
168 /* if (model->CONTEXT_HT!=NULL) delht(model->CONTEXT_HT);
169 model->CONTEXT_HT=NULL;*/
170 }
171
172 void sim_set_output_file( sim_model *model, char *file )
173 {
174 if (model->OUTPUT_FILE)
175 mbkfree (model->OUTPUT_FILE);
176 model->OUTPUT_FILE = mbkstrdup(file);
177 }
178
179 char* sim_get_output_file( sim_model *model )
180 {
181 return model->OUTPUT_FILE;
182 }
183
184 /*****************************************************************************\
185 Fonction de modification des parametres d'un model sim
186 *******************************************************************************
187
188 FUNCTION : sim_update_model_interf_name
189
190 Fonction qui met a jour les noms des differents slope,init,measure ...du model
191
192 \*****************************************************************************/
193 void sim_update_model_locon_name (sim_model *model,
194 char *oldname,
195 char *newname)
196 {
197 sim_ic *ic = NULL;
198 sim_input *input = NULL;
199 sim_measure *measure = NULL;
200
201 if ((measure = sim_measure_get( model,
202 oldname,
203 SIM_MEASURE_LOCON,
204 SIM_MEASURE_VOLTAGE ))) {
205 sim_measure_clear (model,oldname,
206 SIM_MEASURE_LOCON,
207 SIM_MEASURE_VOLTAGE
208 );
209 sim_measure_set_locon (model,newname);
210 }
211
212 // update init
213 if ((ic = sim_ic_get (model, oldname, SIM_IC_LOCON)))
214 ic->WHERE.LOCON_NAME = newname;
215
216 // update input slope or out capa
217 if ((input = sim_input_get (model,oldname)))
218 input->LOCON_NAME = newname;
219 }
220
221 /*****************************************************************************\
222
223 FUNCTION : sim_update_model_signal_name
224
225 Prefixe tous les noms des signaux
226
227 \*****************************************************************************/
228 void sim_update_model_signal_name (sim_model *model, char *prefix)
229 {
230 sim_measure *measure = NULL;
231 sim_ic *ic = NULL;
232
233 // update measure
234 while( (measure = sim_measure_scan( model, measure )) ) {
235 switch( sim_measure_get_what( measure ) ) {
236 case SIM_MEASURE_VOLTAGE :
237 switch( sim_measure_get_type( measure ) ) {
238 case SIM_MEASURE_SIGNAL :
239 measure->WHERE.SIGNAL_NAME = concatname (prefix,
240 sim_measure_get_name (measure));
241 break;
242 }
243 }
244 }
245
246 // update ic
247 while( (ic = sim_ic_scan( model, ic )) ) {
248 switch( sim_ic_get_locate( ic ) ) {
249 case SIM_IC_SIGNAL :
250 ic->WHERE.SIGNAL_NAME = concatname (prefix,sim_ic_get_name (ic));
251 break;
252 }
253 }
254 }
255
256 /*****************************************************************************\
257
258 FUNCTION : sim_shift_input
259
260 Shift input start time
261
262 \*****************************************************************************/
263 void sim_shift_input (sim_model *model, SIM_FLOAT shift)
264 {
265 lofig_list *lofig;
266 locon_list *locon;
267 sim_input *input = NULL;
268 char type,level,subtype;
269 SIM_FLOAT trise, tstart;
270 SIM_FLOAT (*func)(SIM_FLOAT t, void *data);
271 void *userdata;
272 SIM_FLOAT *data,*olddata;
273
274 lofig = sim_model_get_lofig( model );
275 for( locon = lofig->LOCON ; locon ; locon = locon->NEXT ) {
276 input = sim_input_get( model, locon->NAME );
277 type = sim_input_get_type( input );
278
279 if( type == SIM_NC )
280 continue;
281
282 switch( type ) {
283 case SIM_SLOPE :
284 subtype = sim_input_get_slope_type( input );
285 switch( subtype ) {
286 case SIM_SLOPE_SINGLE :
287 sim_input_get_slope_single( input, &level, &trise, &tstart );
288 if ( tstart+shift >= 0.0 )
289 input->UINPUT.INPUT_SLOPE.MODEL.SLOPE_SINGLE.TSTART = tstart+shift;
290 else
291 input->UINPUT.INPUT_SLOPE.MODEL.SLOPE_SINGLE.TSTART = 0.0;
292 break;
293 case SIM_SLOPE_PATTERN :
294 break;
295 }
296 break;
297
298 case SIM_FUNC:
299 sim_input_get_func( input, &func, &userdata ) ;
300 data = (SIM_FLOAT*)(input->UINPUT.INPUT_FUNC.USER_DATA);
301 olddata = (SIM_FLOAT*)userdata;
302 if ( olddata[0]+shift >= 0.0 )
303 data[0] = olddata[0]+shift;
304 else
305 data[0] = 0.0;
306 break;
307 }
308 }
309 }
310
311
312 /*****************************************************************************\
313
314 FUNCTION : sim_model_merge_ic
315
316 \*****************************************************************************/
317 void sim_model_merge_ic (sim_model *srcmodel, sim_model *model)
318 {
319 sim_ic *ic = NULL;
320 char ic_locate;
321
322 while( (ic = sim_ic_scan( model, ic )) ) {
323 switch( sim_ic_get_locate( ic ) ) {
324 case SIM_IC_LOCON :
325 ic_locate = SIM_IC_LOCON;
326 break;
327 case SIM_IC_SIGNAL:
328 ic_locate = SIM_IC_SIGNAL;
329 break;
330 }
331 switch (sim_ic_get_type( ic )) {
332 case SIM_IC_VOLTAGE: sim_ic_set_voltage (srcmodel,
333 sim_ic_get_name (ic),
334 ic_locate,
335 sim_ic_get_voltage(ic));
336 break;
337 case SIM_IC_LEVEL : sim_ic_set_level (srcmodel,
338 sim_ic_get_name (ic),
339 ic_locate,
340 sim_ic_get_level(ic));
341 break;
342 }
343 }
344 }
345
346 /*****************************************************************************\
347
348 FUNCTION : sim_model_merge_measure
349
350 \*****************************************************************************/
351 void sim_model_merge_measure (sim_model *srcmodel, sim_model *model)
352 {
353 sim_measure *measure = NULL;
354
355 while( (measure = sim_measure_scan( model, measure )) ) {
356 switch( sim_measure_get_what( measure ) ) {
357 case SIM_MEASURE_VOLTAGE :
358 switch( sim_measure_get_type( measure ) ) {
359 case SIM_MEASURE_LOCON :
360 sim_measure_set_locon (srcmodel,sim_measure_get_name (measure));
361 break;
362 case SIM_MEASURE_SIGNAL:
363 sim_measure_set_signal (srcmodel,sim_measure_get_name (measure));
364 break;
365 }
366 break;
367 case SIM_MEASURE_CURRENT :
368 break;
369 }
370 }
371 }
372
373 /*****************************************************************************\
374
375 FUNCTION : sim_model_merge_input
376
377 \*****************************************************************************/
378 void sim_model_merge_input (sim_model *srcmodel, sim_model *model,char *insname)
379 {
380 lofig_list *lofig;
381 losig_list *losig;
382 sim_input *input = NULL;
383 char type,level,subtype;
384 SIM_FLOAT trise, tfall,period,tstart;
385 char *pattern;
386 SIM_FLOAT (*func)(SIM_FLOAT t, void *data);
387 void *userdata;
388 char locate;
389 char *newinputname;
390
391 lofig = sim_model_get_lofig( model );
392 for( losig = lofig->LOSIG ; losig ; losig = losig->NEXT ) {
393 input = sim_input_get( model, getsigname (losig) );
394 type = sim_input_get_type( input );
395
396 if( type == SIM_NC )
397 continue;
398 if (input->LOSIG_NAME) {
399 locate = SIM_INPUT_SIGNAL;
400 newinputname = concatname (insname,sim_input_get_name (input));
401 }
402 else {
403 locate = SIM_INPUT_LOCON;
404 newinputname = sim_input_get_name (input);
405 }
406 if (sim_input_get(srcmodel,newinputname)) {
407 sim_input_clear ( srcmodel,newinputname);
408 //continue;
409 }
410
411 switch( type ) {
412 case SIM_STUCK :
413 subtype = sim_input_get_stuck_type( input );
414 switch (subtype) {
415 case SIM_STUCK_LEVEL :
416 sim_input_set_stuck_level( srcmodel, sim_input_get_name (input),
417 sim_input_get_stuck_level( input ));
418 break;
419 case SIM_STUCK_VALUE:
420 sim_input_set_stuck_voltage ( srcmodel, sim_input_get_name(input),
421 sim_input_get_stuck_voltage( input ));
422 break;
423 }
424 break;
425 case SIM_SLOPE :
426 subtype = sim_input_get_slope_type( input );
427 switch( subtype ) {
428 case SIM_SLOPE_SINGLE :
429 sim_input_get_slope_single( input, &level, &trise, &tstart );
430 sim_input_set_slope_single( srcmodel,
431 newinputname,
432 level,
433 trise,
434 tstart,
435 locate
436 );
437 break;
438 case SIM_SLOPE_PATTERN :
439 sim_input_get_slope_pattern( input, &trise, &tfall,
440 &period, &pattern );
441 sim_input_set_slope_pattern( srcmodel, sim_input_get_name (input),
442 trise, tfall,period,pattern);
443 break;
444 }
445 break;
446
447 case SIM_FUNC:
448 sim_input_get_func( input, &func, &userdata ) ;
449 sim_input_set_func (srcmodel, newinputname, func, userdata,locate,NULL);
450 break;
451
452 }
453 }
454 }
455
456 /*****************************************************************************\
457
458 FUNCTION : sim_model_merge
459
460 Merge deux modeles sim : - measure
461 - ic
462 - input
463
464 Le modele merge est srcmodel
465
466 \*****************************************************************************/
467 void sim_model_merge (sim_model *srcmodel, sim_model *model, char *insname)
468 {
469 // merge ic
470 sim_model_merge_ic (srcmodel,model);
471
472 // merge measure
473 sim_model_merge_measure (srcmodel,model);
474
475 // merge input
476 sim_model_merge_input (srcmodel,model,insname);
477 }
478
479 void sim_clean_netlist(sim_model *model)
480 {
481 ptype_list *pt;
482 locon_list *lc;
483 if (model->FIG!=NULL)
484 {
485 for (lc=model->FIG->LOCON; lc!=NULL; lc=lc->NEXT)
486 if ((pt=getptype(lc->USER, SIM_EXT_CAPA))!=NULL) mbkfree(pt->DATA);
487 }
488 }
489
490 void sim_free_context (sim_model *model)
491 {
492 if (model->FIG!=NULL)
493 {
494 sim_clean_netlist(model);
495 freeflatmodel (model->FIG);
496 }
497
498 sim_model_clear_bypointer( model);
499 }
500
501 void sim_set_filename(sim_model *model, char *filename)
502 {
503 strcpy(model->SUBCKTFILENAME, filename);
504 }
505
506 void sim_set_external_capa(sim_model *model, char *con, SIM_FLOAT value)
507 {
508 locon_list *lc;
509 ptype_list *pt;
510 con=namealloc(con);
511
512 if (model==NULL) return;
513
514 for (lc=model->FIG->LOCON; lc!=NULL && lc->NAME!=con; lc=lc->NEXT) ;
515
516 if (lc!=NULL)
517 {
518 if ((pt=getptype(lc->USER, SIM_EXT_CAPA))==NULL)
519 pt=lc->USER=addptype(lc->USER, SIM_EXT_CAPA, mbkalloc(sizeof(SIM_FLOAT)));
520 *(SIM_FLOAT *)pt->DATA=value;
521 }
522 else
523 sim_error( "could not find connector '%s' in netlist %s\n", con, model->FIGNAME );
524 }
525
526 SIM_FLOAT sim_get_external_capa(sim_model *model, locon_list *lc)
527 {
528 ptype_list *pt;
529 if ((pt=getptype(lc->USER, SIM_EXT_CAPA))==NULL) return 0;
530
531 return *(SIM_FLOAT *)pt->DATA;
532 }
533
534 void sim_resetmeasures(sim_model *model)
535 {
536 if( model->NBMC > 0 )
537 mfe_freelabels(&(model->LLABELS),1);
538 else
539 mfe_freelabels(&(model->LLABELS),0);
540 sim_freeMeasAllArg(model);
541 sim_freePrn(model);
542 }
543